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
Note

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

  1. 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.

  2. The application channel verifies that the secret key that the external app sent matches the application channel's secret key.

  3. Digital Assistant then looks up the user channel for the name that's passed in the request body.

  4. 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.

  5. 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.

    If the user answers answer “No”:
    • 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:

  1. 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"
            }
        }
    }
  2. 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.
  3. To map the event to the start state, click Settings Settings icon, 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 the remindermessage state in the dialog flow.


    Description of event-map.png follows

    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:

  1. 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.

  2. If your skill hasn't enabled user authentication yet, complete these steps:

    1. Ensure that an administrator has completed the steps in Identity Provider Registration.

    2. Create an authentication service for the identity provider as described in Authentication Services.

    3. 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.

    4. 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.

  3. 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.

  1. From the left navbar, click Channels, click Applications, and then click + Application Configuration.

  2. Enter a name and optionally enter a description.

  3. (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, and message properties.

  4. (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.

  5. Click Create.

  6. Switch Application Enabled to On.

  7. 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 Settings icon 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 is true 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 to application.

      • 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 and version: (Optional) If the messaging platform's user channel routes to a digital assistant, then you must include the skill's skillName and version 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 Object

      This 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 the profile.botName variable.

      • tenantId: The ID of the Microsoft Teams tenant. This value is saved in the profile.tenantId variable.

      • serviceUrl: The service URL for the bot. This value is saved in the profile.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 Object

      For Slack, include these properties in the channelProperties object:

      • teamId: Slack workspace ID. This value is saved in the profile.team_id variable.

      • channel: ID of the channel in the workspace. That is, the user's channel. This value is saved in the profile.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 is ABCDEFG, and the channel is HIJKLMNOP.

    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 PreviewPreview icon. 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.

  1. 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 or System_Global_Test.

  2. To get the Preview's user ID, open the skill and click Preview Preview icon.
  3. Open Network Monitor by first selecting Web Developer in the browser menu, and then click Network.

  4. Select XHR to display only REST requests.

  5. Enter a message in the Preview.

  6. 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.

  7. Enter userId in the Filter Properties field to display the value for the userId.

  8. 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"
        }
    }
}