Application-Initiated Conversations
In cases where you want a skill to initiate a chat with your customers, you can use the application-initiated conversation feature in Oracle Digital Assistant to start conversations with users. For example, you can use this feature to send an appointment reminder, a traffic alert, or flight status.
Application-initiated conversations are conversations that Digital Assistant initiates in response to an event it receives from an external app. Digital Assistant uses the contents of the app's event message to trigger one of its skills to first notify a user and then begin a conversation at the state in the dialog flow that's applicable to the event. You can trigger the conversation through a digital assistant or through a stand-alone skill.
This feature works on the following platforms:
- Twilio/SMS
- MS Teams
- Slack
Application-initiated conversations are currently not supported for skills that have dialog flows built with the Visual Flow Designer. For skills developed using the Visual dialog flow mode, use External Events.
Use Case: An Expense Reporting App
To get an idea of the initial user notification and the subsequent event-specific actions, consider a digital assistant that reacts to events that are sent by an expense reporting app. This app sends messages to the digital assistant whenever an expense report is approved or rejected and when more information is required. In turn, the digital assistant starts a conversation with the user.
You can create a skill that has start states for each of the events (approve, reject, and more information required). The start state can output a message about the event and then begin a flow that enables the user to take the applicable action:
- Confirm that they’ve seen the approval
- Resubmit the expense report
- Complete the expense report by adding missing information
How Application-Initiated Conversations Work
An application-initiated conversations is a conversation that appears as if the skill started the conversation, instead of the user. It can be a conversation with a skill that a user has previously interacted with or not (in the case where user-authentication isn't required).
The setup for an application-initiated conversation includes these artifacts:
-
Messaging platform: An external channel through which the user converses with the skill or digital assistant. The user must have access to the messaging platform, such as a Twilio account, or a bot-embedded app installed in their Slack workspace or for their MS Team.
-
Skill: The skill can be standalone or part of a digital assistant, and can require user authentication or not.
-
Notification event: A POST request that triggers the conversation.
-
External app: An application that sends the POST request to Digital Assistant.
-
Application channel: A channel that you create in Digital Assistant to allow the external app to send messages to your instance. You also use this channel to set whether to require authenticated users.
-
User channel: A channel for the messaging platform, which you create in Digital Assistant to route a notification event from an external app to a digital assistant or skill. Messages to and from the user are sent through this channel.
Here's the overall flow of how a skill-initiated conversation works. Details for each step in the flow follows.
![Description of aic-flow.png follows Description of aic-flow.png follows](img/aic-flow.png)
-
The flow begins when an external app sends a POST request to the application channel's inbound URL. The request's payload contains the information that's necessary to authenticate the request, identify the user channel by name, and determine the target skill and it's start state.
-
The application channel verifies that the secret key that the external app sent matches the application channel's secret key.
-
Digital Assistant then looks up the user channel for the name that's passed in the request body.
-
To find the target skill, Digital Assistant looks at the route-to in the user channel. The target can be either a digital assistant or a skill. When the target is a digital assistant, then Digital Assistant expects to find the skill name and version in the request body. Next, Digital Assistant looks at the skill's payload-to-state mappings to find an entry that matches the payload type in the request body. The matched entry points to the state with which to start the conversation flow.
If the application channel has Use Authenticated User ID switched to On, then the user must have interacted with the skill within the last 14 days. Otherwise the skill won't recognize the authenticated user.
-
Digital Assistant transmits and receives messages through the user channel that handles the traffic between Digital Assistant and the messaging platform. First, the skill sends a notification that the skill wants to initiate a conversation, then it starts the conversation flow.
If a user gets a notification while they’re in mid-conversation with another skill, it asks if they want to switch conversations to take action on the notification.
If the user answers “Yes” (which often means switching between skills):-
The user is placed at the state in the dialog flow that starts them on the conversation flow.
-
After the user completes this flow, they are asked if they want to resume the prior conversation. If the user answers "Yes", they’re returned to the point where they left off.
-
They’ll continue with their current skill.
-
When they’ve finished the transaction, they are prompted to take action on the notification.
-
Tutorial: Application-Initiated Conversations
You can get a hands-on look at application-initiated conversations by walking through this tutorial: Send Reminders Using Application-Initiated Conversations.
Implementing Application-Initiated Conversations
You enable application-initiated conversations by configuring a skill, a user channel, an application channel, and an external app. Optionally, you can add the skill to a digital assistant and configure the digital assistant for the application-initiated conversation features in the skill.
Configure the Skill
An application-initiated conversation begins when an external app sends an event to the skill or to the digital assistant that it belongs to. There are a few changes that you need to make to your skill so that the conversation begins in the right place and displays the desired values.
An event that is sent from an external app must include a payload type, which uniquely identifies the event to the skill. Typically, the payload type indicates what the skill is supposed to do, such as msgReminder
or cancelAppointment
. The event can also include parameters in its variables
JSON object, such as a patient's name or an appointment time.
In your skill, you must ensure that there's a start state in the dialog flow for every event (multiple events can have the same start state). You also need to add flow-level variables to hold the parameter values, if any. Then, you need to map the event's payload type to the start state.
For each event, do the following steps:
-
If your external app will pass a
variables
object in the event's message payload, then add flow-level variables to hold the values of the object's properties.The flow-level variable name must match the property name in the
variables
object. Say, for example, that the external app will send a request body like this for an appointment-reminder event:{ "userId": "16035550100", "messagePayload": { "type": "application", "payloadType": "msgReminder", "channelName": "AppointmentUserChannel", "variables": { "patientName": "Joe Doe", "appointmentTime": "5:00 pm" } } }
-
Ensure that your dialog flow has a start state for the event.
Tip:
If the messaging platform is text-only, consider making user input less error-prone by configuring autonumbering in the skill’s dialog flow. Also consider showing or hiding text based on the messaging platform. See Text-Only Channels. -
To map the event to the start state, click Settings
, click Events, and click + Add Mapping. Then enter these fields:
-
Payload type: A name that uniquely identifies the event. The external app must use this name to direct the message to the applicable state.
You use the payload type from the external app rather than the actual state name because payload type is a constant, whereas the name of the state could change if the dialog flow is revised.
-
State name: The start state for the event in the dialog flow.
In this screenshot, the
msgReminder
payload type maps to theremindermessage
state in the dialog flow.When you add a skill to a digital assistant, the skill's event-to-state mappings are added to the digital assistant's Events page automatically. You access this page from the digital assistant's Settings page.
-
Configure a User-Authenticated Skill
If your skill requires users to authenticate with Oracle Identity Cloud Service or Oracle Access Manager, then you must configure the application channel, skill, and external app to enable the skill to associate the authenticated user ID with the bot user ID.
For events that are sent to a user-authenticated skill to work, the user must have already signed into the identity provider from the skill. For example, let's say that Deva is using a skill to create an expense report. Before she can do anything in the skill, the skill asks her to sign in. The skill then associates her authenticated user ID with her user ID for the messaging platform and the messaging platform parameters that are cached in the user's profile.
After she completes her report, she asks to be notified when the expense is approved. Her company uses an external app to send the notification event to the same skill. In order for the app to send the event to a user-authenticated skill, it must send Deva's authenticated user ID instead of the messaging platform's user ID. Given the authenticated user ID, the skill can look up platform's user ID and the information from the cached profile that it obtained when Deva originally signed in.
If Deva never signed in from the skill, her authentication expired, or the profile cache expired, then Digital Assistant responds to the event request with a 500 error.
In addition to the steps in Configure the Skill, you must complete the following steps to configure application-initiated conversations for user-authenticated skills:
-
If your skill has already enabled user authentication, go to Settings > Authentication Services, open the service and ensure that the Refresh Token Retention Period is set to 14 days, which matches the user profile cache expiry duration. These values must be synchronized.
-
If your skill hasn't enabled user authentication yet, complete these steps:
-
Ensure that an administrator has completed the steps in Identity Provider Registration.
-
Create an authentication service for the identity provider as described in Authentication Services.
-
Ensure that the authentication service's Refresh Token Retention Period is set to
14
days, which matches the user profile cache expiry duration. These values must be synchronized. -
To enable users to sign in from the skill, add a state for the OAuth 2.0 Account Link component to the dialog flow as described in OAuth 2.0 Account Link.
-
-
When you create the application channel, switch Use Authenticated User ID to On. Or, if it's already created, open the channel and switch it to On.
In the request body that your external app sends to Digital Assistant, remember to set the userId
property to the authenticated user ID as described in Configure the External App.
Create a User Channel for the Messaging Platform
For application-initiated conversations to work, you'll need to create a user channel to link the skill with your messaging platform account. See these topics for the steps to create a user channel for the specific platform.
Note that if you select a skill from the channel's Route to list, then all external app messages that are sent to this channel are routed to the selected skill. However, if you select a digital assistant, then you'll need to specify the target skill in the external app's message payload.
Create a Channel for the External App
You need to create an application channel to allow the external app to send messages to Digital Assistant. After you create the channel, Digital Assistant assigns a secret key. You need to use this secret key in your external app.
-
From the left navbar, click Channels, click Applications, and then click + Application Configuration.
-
Enter a name and optionally enter a description.
-
(Optional) All channel-related error messages are logged to the server log file. If you also want Digital Assistant to send these error messages to an external web service, enter the web service's URL in the Outbound Application URL field.
If an error occurs, such as a problem with initiating a conversation through the user channel, then Digital Assistant sends an error message as a JSON object with the
botId
,sessionId
, andmessage
properties. -
(Optional) If the targeted skill requires authentication using the OAuth 2.0 Account Link component, and your external app will send the authenticated user ID instead of the messaging platform's user ID, then switch Use Authenticated User ID to On.
When this is switched on, Digital Assistant will look up the messaging platform's user ID for the specified authenticated user ID. Note that the user must have signed in through the skill for the look up to complete successfully. For further details, see Configure a User-Authenticated Skill.
-
Click Create.
-
Switch Application Enabled to On.
-
Make a note of the secret key and inbound URL. These will be used by the external app.
- It sends messages by sending POST request to the inbound URL.
- It uses the secret key to authenticate its POST requests.
Configure the Digital Assistant
If your skill supports application-initiated conversations and you add it to a digital assistant, you might want to adjust these configuration parameters in the digital assistant's Settings page:
- Interrupt Prompt: This prompt is displayed when interrupting a flow to start a new flow.
- Enable Auto Numbering on Postback Actions: It's good practice to make sure that this setting is
true
for all text-only channels so that the user input is less error-prone. By default, this setting istrue
for all Twilio channels:${(system.channelType=='twilio')?then('true','false')}
Configure the External App
The external app initiates an event by sending a POST request to an application channel's inbound URL. Here are the things the app must do to prepare and send the request.
-
Include these properties in the request body (examples follow):
-
userId
: This must be one of the following IDs:-
Microsoft Bot User ID: The bot user ID for the Microsoft Bot channel. This ID is specific to each Microsoft Bot channel. The skill saves this value in the
profile.msBotUserId
variable. -
Slack User ID: The Slack user's member ID. The skill saves this value in
system.message.channelConversation.userId
. -
Twilio/SMS Channel ID: The user's mobile phone number. This must be one of the numbers that are associated with the Twilio account's phone number that's specified in the Digital Assistant user-channel configuration. The skill saves this value in the
profile.firstName
variable. -
System-Generated User ID: If you are testing your skill from Preview, then this must be the system-generated user ID for the session in Preview. See Testing Application-Initiated Conversations from Preview.
-
Authenticated User ID: If the associated application channel has Use Authenticated User ID switched to On, then this must be the authenticated user ID. The user with this authenticated user ID must already be signed in to the targeted skill through the OAuth 2.0 Account Link component. See Configure a User-Authenticated Skill.
-
-
messagePayload
: This object contains:-
type
: Set this toapplication
. -
payloadType
: The name of the event (payload type) that’s mapped to the desired start state in the dialog flow. See Configure the Skill. -
skillName
andversion
: (Optional) If the messaging platform's user channel routes to a digital assistant, then you must include the skill'sskillName
andversion
so that the digital assistant knows which skill and version to send the event to. -
channelName
: The name of the messaging platform's user channel that’s configured for the skill or digital assistant.If you are testing your skill from Preview, then you need to set
channelName
to the name of the System channel. See Testing Application-Initiated Conversations from Preview. -
variables
: (Optional) Key-value pairs to pass to the dialog flow’s variables. If the corresponding flow variables are defined in the dialog flow, then they're populated with the values passed from this object.
-
-
channelProperties
: This object is for MS Teams and Slack. You don't need to include this object in the request body if Use Authenticated User ID is switched on for the user channel.MS Teams
channelProperties
ObjectThis object is required if the user hasn't interacted with the conversation within 14 days. Its properties are:
-
botName
: This is the bot handle that you specified when you created the bot channel registration as described in Step 1: Create a Bot. This value is saved in theprofile.botName
variable. -
tenantId
: The ID of the Microsoft Teams tenant. This value is saved in theprofile.tenantId
variable. -
serviceUrl
: The service URL for the bot. This value is saved in theprofile.serviceUrl
variable.
When the Microsoft Teams user converses with the skill, Digital Assistant captures and stores these values in the profile cache. If an event's request payload doesn't include the
channelProperties
object, then the skill will use the values from the profile cache, if available (the cache expires after 14 days). The skill uses the cached profile values only if they are missing from the request body.When your dialog flow sends a request for notification to the backend, such as through a custom component, it should pass those profile values to the backend. The external app can then use those values in the
channelProperties
object in the case where the profile cache might have expired. Here's a snippet of custom component code that gets the values to send to the back end.let serviceUrl = conversation.variable('profile.serviceUrl') ? conversation.variable('profile.serviceUrl') : ""; let tenantId = conversation.variable('profile.tenantId') ? conversation.variable('profile.tenantId') : ""; let botName = conversation.variable('profile.botName') ? conversation.variable('profile.botName') : ""; let msBotUserId = conversation.variable('profile.msBotUserId') ? conversation.variable('profile.msBotUserId') : "";
Slack
channelProperties
ObjectFor Slack, include these properties in the
channelProperties
object:-
teamId
: Slack workspace ID. This value is saved in theprofile.team_id
variable. -
channel
: ID of the channel in the workspace. That is, the user's channel. This value is saved in theprofile.channel
variable.
You can get the team ID and channel from the Slack web URL. For example, if the URL is
https://app.slack.com/client/ABCDEFG/HIJKLMNOP
, then the team ID isABCDEFG
, and the channel isHIJKLMNOP
. -
Here are examples for the different messaging platforms for skills that don't use authenticated user IDs.
Slack example:
{ "userId": "ABCDE712A3", "messagePayload": { "type": "application", "payloadType": "msgReminder", "channelName": "AppointmentUserChannel", "variables": { "patientName": "Joe Doe", "appointmentTime": "5:00 pm" }, "channelProperties": { "teamId": "ABCDEFG", "channel":"HIJKLMNOP" } } }
MS Teams example:
{ "userId": "12:1A2B3C3d....", "messagePayload": { "type": "application", "payloadType": "msgReminder", "channelName": "AppointmentUserChannel", "variables": { "patientName": "Joe Doe", "appointmentTime": "5:00 pm" }, "channelProperties": { "tenantId": "ab12c34d-e56...", "botName":"my-bot", "serviceUrl":"https://example.com/path/" } } }
Twilio example:
{ "userId": "1234567890", "messagePayload": { "type": "application", "payloadType": "msgReminder", "channelName": "AppointmentUserChannel", "variables": { "patientName": "Joe Doe", "appointmentTime": "5:00 pm" } } }
This example shows how to send an event to a channel that's routed to a digital assistant. When the channel routes to a digital assistant, you must include the skill name and version.
{ "userId": "1234567890", "messagePayload": { "type": "application", "payloadType": "msgReminder", "channelName": "AppointmentUserChannel", "skillName": "myBot", "version": "1.0", "variables": { "patientName": "Joe Doe", "appointmentTime": "5:00 pm" } } }
Here's an example for a user-authenticated skill (that is, the associated application channel has Use Authenticated User ID switched to On). This example applies to MS Teams, Slack, and Twilio. Note that for MS Teams and Slack, you don't include the
channelProperties
object when you route to a user-authenticated skill.{ "userId": "first.last@example.com", "messagePayload": { "type": "application", "payloadType": "msgReminder", "channelName": "AppointmentUserChannel", "variables": { "patientName": "Joe Doe", "appointmentTime": "5:00 pm" } } }
-
-
To authenticate the request, add an
X-Hub-Signature
header with a SHA256 hash of the body using the application channel's secret key. For example:X-Hub-Signature: sha256={{HMAC SHA-256 signature of body}}
The Use Postman as an External Application section in the Send Reminders Using Application-Initiated Conversations tutorial shows an example of setting this header.
-
Send the POST request to the application channel's inbound URL. It should look something like this:
POST https://<host>:<port>/connectors/v2/listeners/application/channels/4E09-42F7-ECB7A7F18F62
Testing Application-Initiated Conversations from Preview
You can use Preview to test your application-initiated conversation. To do this, you need to get the System channel name and the skill tester's user ID, and then configure the external app to send messages to that channel and user.
Get the System Channel Name and Preview User ID
You'll need the System channel name and the Preview's user ID to send your external app's messages to the Preview. When an external app sends a message to the System channel, Oracle Digital Assistant routes the message to the Preview that has the specified user ID.
-
To get the name of the System channel, from the left navbar, click Channels, click System, and then look at the name.
The name will be either
System_Bot_Test
orSystem_Global_Test
. - To get the Preview's user ID, open the skill and click Preview
.
-
Open Network Monitor by first selecting Web Developer in the browser menu, and then click Network.
-
Select XHR to display only REST requests.
-
Enter a message in the Preview.
-
After the skill outputs some text, go to the the Network Monitor, and then look at the Response tab.
Select each response until you find one that contains a
messagePayload
. -
Enter
userId
in the Filter Properties field to display the value for theuserId
. -
Leave the Preview active and don't click Reset.
If you reset or close the Preview then the user ID changes.
Send a Notification to the Skill Preview
After you get the name of the System channel and the system's user ID, you can send messages from your external app to the skill's Preview.
To use the Preview instead of the messaging service, set userId
to the Preview's user ID and set channelName
to the name of the System channel, as shown here:
{
"userId": "7319408",
"messagePayload": {
"type": "application",
"payloadType": "msgReminder",
"channelName": "System_Global_Test",
"variables": {
"patientName": "Joe Doe",
"appointmentTime": "5:00 pm"
}
}
}