Transfer Users from a Skill Bot to a Live Agent

Transferring users to live agents can be as simple as adding an agent-integration channel and adding two components to a skill bot's dialog flow. However, you'll likely want to improve the chat experience by giving your users the option to speak with an agent when certain events happen.

  • The user asks to speak to someone.
  • The skill bot can't discern what the user wants to do.
  • The user keeps answering the same question incorrectly.
  • The user is frustrated.

Before You Begin

Before you begin working on your skill bot, you need:

  • The Oracle Service Cloud interface ID. This is a numeric value. You can see the ID in the Agent Desktop console under Site Configuration when you hover your pointer over an interface name.
  • The field names and values that are used to route the chat session to the agents with the appropriate expertise. You can get these names and values from the chat rule. See Create a Chat Rule.

  • The user name and password for an agent who's associated with an agent profile that:

    • Has access to Chat in the Agent Browser UI (BUI) or the Agent Console in Oracle Service Cloud.

    • Has account authentication and session authentication enabled for the Public SOAP API.

    • Includes the queue that you configured for agent transfer.

    This information lets you add the agent-integration channel, which enables Oracle Digital Assistant to communicate with Oracle Service Cloud Chat. You also need it to test the interaction between the skill bot and an agent.

Configure the Agent Integration Channel

Create the channel that connects the skill to the agent platform.

Before you begin, confirm with the Oracle Service Cloud administrator that the profile associated with the user name has access to the correct interface and that the profile's Public SOAP API account authentication is enabled. You also need to confirm that your Oracle Service Cloud Account Manager has enabled the Chat Custom Interface API and the Chat Third-Party Queue Integration API.

If you have access to Oracle Service Cloud, you can derive the Domain Name and Hostname Prefix from the URL that you use to launch the Agent Browser User Interface. For example, if this URL is sitename.exampledomain.com, then the Hostname Prefix is sitename and the Domain Name is exampledomain.com.

  1. Click Icon to open the side menu to open the side menu, select Development, and then select Channels.
  2. Click Agent Integrations, and then click + Agent Integration.
  3. Enter a name and an optional description for this channel. When you use the System.AgentInitiation and System.AgentConversation components in your dialog flow to enable the transition to, and from, Oracle Service Cloud, you must use this name for their agentChannel properties.
  4. Choose the agent system (Service Cloud) from the Integration Type menu.
  5. Define the Domain Name, Hostname Prefix, Username, and Password, which are provided by the Oracle Service Cloud administrator. The user name must be for a user who has access to the Agent Browser UI (BUI) in Oracle Service Cloud.
  6. Click Create.
  7. To enable the skill to interact with the agent framework, enable the channel by switching on the Interaction Enabled toggle.

Create a Skill Bot

If you aren't enhancing an existing skill bot to integrate with Oracle Service Cloud Chat, then you can create one from scratch or clone an existing skill bot.

The PizzaBot sample is a good choice for cloning because it's short and basic.

  1. Click icon to open the side menu, select Development, and then select Skills.
  2. In the skill bot catalog, enter pizzabot in the filter field.
  3. On the PizzaBot card, click Options Options, and then select Clone.
  4. Enter a display name, name, and version, select Open cloned skill bot afterwards, and click Clone.
You now have a skill bot for making or cancelling a pizza order.

Define an Intent to Transfer to a Live Agent

An intent represents an action that the user wants to do, such as speak to a live agent. You add example utterances to an intent to enable your skill bot to recognize when a user wants to do that action.

When the user types something (an utterance) at the start of a conversation, the skill bot parses the utterance and then looks at the set of example utterances in each intent to identify what a user wants to do.

You can create intents and add utterances manually, or by importing the values from a CSV file.

  1. Create a .csv file with query and topIntent columns and add utterances.

    As shown in this example, the first row in the file must provide the query and topIntent column names. In the subsequent rows, list each example utterance and the name of the intent to add it to. This example creates an intent named TransferToAgent and adds the example utterances in the first column to that intent.

    query,topIntent
    have a live conversation,TransferToAgent
    chat with an agent,TransferToAgent
    speak with an agent,TransferToAgent
    transfer me to an agent,TransferToAgent
    talk to an agent,TransferToAgent

    Think of phrases that your users might say when they want to talk to an agent, including slang. You should list a minimum of 5 utterances, but ideally, you want about 25 utterances. You can add to the list after the skill bot is used and you identity other utterances from your users.

    Most of the utterances in the previous example refer to an agent. Later, you can add synonyms that people might use when asking for an agent, such as customer representative.

  2. To open your skill bot, click icon to open the side menu, select Development, select Skills, and then click your skill bot.
  3. Click Intents Intents.
  4. Click More, click Import intents, and then import your .csv file.
  5. (Optional) Add a description.
  6. To teach your skill bot to recognize and resolve these utterances, click Train, select Trainer Ht, and then click Submit.

Define Synonyms for Agent

When users want to talk to an agent, they might use words like live person, human, and representative. Rather than create a set of utterances for each possible term, you can use an entity to define synonyms for agent, and then associate the entity with your intent.

You can add an entity manually, or you can add it by importing the values from a CSV file.

  1. Create a .csv file with entity, value, and synonyms columns, and add a row for your entity.

    As shown in this example, the first row in the file must provide the entity, value, and synonyms column names. In the second row, the first column is the name of the entity. The second column is the word that the synonyms are for. The third column is a colon-separated list of synonyms.

    entity,value,synonyms
    AgentSynonyms,agent,live person:human:customer service:customer service agent:customer service representative:CSR:representative:person:somebody:someone:chat person
  2. In your skill bot, click Entities Entities.
  3. Click More, click Import 'value list' entities, and then import your .csv file.
  4. (Optional) Add a description.
  5. Click Intents Intents.
  6. Select your intent.
  7. Click + Entity and select the entity that you just created.
  8. To teach your skill bot to recognize the synonyms, click Train, select Trainer Ht, and then click Submit.
  9. To verify whether the intent's example set and synonyms are sufficient for identifying when users want the skill bot to perform this intent's action, click Try It Out!, and then enter various phrases that aren't in the set of example utterances. For example, enter I need to talk to someone.
  10. As you enter each phrase, examine the confidence level that's shown for each of the skill bot's intents. Ideally, the confidence level for the intent to transfer to a live agent (the intent that you just created) is higher than the confidence levels for the other intents.
  11. If the confidence level isn't higher, then you can add the phrase to the set of example utterances by selecting the intent in the Try Out Intents/Q&A window, and then clicking Add Example.
  12. If you added phrases to the set of example utterances, click Train to retrain the intent.

Add Dialog Flow for Transferring to an Agent

After you define an agent transfer intent, you can add the dialog flow for handling the transfer. Then you can update your System.Intent component to direct the conversation to the start of that dialog flow whenever the component resolves to your agent transfer intent.

  1. To make a conversation available for transfer to a live agent, enable skill logging.
    1. Click Settings Settings.
    2. Set the Skill Conversation switch to On.
  2. To modify the dialog flow, click Flows Flows.
  3. To pass the Oracle Service Cloud Chat interface ID and the custom field values for the queue's chat rule, add a map context variable to hold the values (for example, agentProperties).
    context:
      variables:
        size: "PizzaSize"
        type: "PizzaType"
        crust: "PizzaCrust"
        iResult: "nlpresult"
        agentProperties: "map"
  4. After the last state in the dialog flow, add states to set profile values. In a real implementation, the messaging platform populates the profile values. Hard code the values now for testing purposes, and remove the states after you complete your tests.
    Profile values are passed to the live agent automatically.
    #		
    # Transfer to a live agent
    #		
    # The profile values are passed to the agent automatically.
    #
    # This example hard codes the profile values. In a real implementation, 
    # the messaging platform populates the profile values.
      setupProfileFirstName:
        component: "System.SetVariable"
        properties:
          variable: "profile.firstName"
          value: "Joe"
        transitions:
          next: "setupProfileLastName"
      setupProfileLastName:
        component: "System.SetVariable"
        properties:
          variable: "profile.lastName"
          value: "Doe"
        transitions:
          next: "setupProfileEmail"
      setupProfileEmail:
        component: "System.SetVariable"
        properties:
          value: "joe.doe@example.com"
          variable: "profile.email"
        transitions:
          next: "setAgentProperties"        
  5. Add a state at the end of the dialog flow to set the agentProperties values. In the following example, the custom field that's used in the chat rule is botsubject, and the rule assigns the chat request to the Order Support queue if the value is order.

    Note that:

    • The interfaceID.id.id value is required.
    • The customFields property must provide values for all the custom fields in the chat rule that you created to route to your queue.
    • You must prepend the custom field names with c$.
      setAgentProperties:
        component: "System.SetVariable"
        properties:
          variable: "agentProperties"
          value:   
            customerInformation:
              interfaceID:
                id:
                  id: 1    
            customFields: 
              - name: "c$botsubject"
                dataType: "STRING"
                dataValue:
                  stringValue: "order"                                
        transitions:
          next: "agentInitiation"         
  6. Add a state after setAgentProperties to initiate the handshake with the agent-integration channel that you created for Oracle Service Cloud Chat.
    1. Click + Components, click User Interface, and then click Agent initiation.
    2. From the Insert After drop-down list, select setAgentProperties.
    3. (Optional) Set the Remove Comments switch to On.
    4. Click Apply.
  7. Set the agentChannel property to the name of the agent-integration channel.
  8. Add a customProperties property, set the value to "${<name of map property>.value}" as shown in the following example, and ensure that the property indentation matches the indentation of the other properties, .
          customProperties: "${agentProperties.value}"
  9. (Optional) Use the waitingMessage, rejectedMessage, and resumedMessage properties to override the default messages with your own text.
  10. (Optional) By default, the subject line that the live agent sees is the last user query. You can use the subject property to change this text.
  11. (Optional) Set the nlpResultVariable property to the name of the variable that you are using to store the natural-language processing result (for example, iResult).
  12. Remove any optional properties that you don't need.
  13. Add a transitions key and map the accepted, rejected, and error actions to the appropriate states as shown in this example:
      agentInitiation:
        component: "System.AgentInitiation"
        properties:
          agentChannel: "ServiceCloudIntegration"
          nlpResultVariable: "iResult"
          waitingMessage: "Let me connect you with someone."
          rejectedMessage: "We aren't able to help you at this time."
          resumedMessage: "Please wait, someone will be with you shortly."
          customProperties: "${agentProperties.value}"
        transitions:
          actions:
            accepted: "agentConversation"
            rejected: "rejected"
            error: "agentSystemError"
  14. Click + Components, click User Interface, click Agent conversation, and then add the component after the agentInitiation state.
    This component passes the user to a live agent and manages the interchange between the skill bot and the live agent.
  15. Set the agentChannel property to the same value that you used for the agentInitiation state.
  16. (Optional) Use the conclusionMessage and expiryMessage properties to override the default messages with your own text.
  17. (Optional) Set the nlpResultVariable property to the name of the variable that you are using to store the natural-language processing result (for example, iResult).
  18. Remove any optional properties that you don't need.
  19. Add a transitions key to the state to trigger the next state.
        transitions:
          next: "endPrompt"

    Here's an example of a completed agentConversation state:

      agentConversation:
        component: "System.AgentConversation"
        properties:
          agentChannel: "ServiceCloudIntegration"
          nlpResultVariable: "iResult"
          conclusionMessage: "Have a good rest of the day."
          expiryMessage: "Your chat session has expired due to inactivity."
          exitKeywords: "bye, good night, goodbye, good bye, end, quit, no bye, ok bye"
        transitions:
          next: "endPrompt"
  20. Add states that correspond to the rejected, agentSystemError, and next transitions from the agentInititation and agentConversation states, as shown in this example.
      endPrompt:  
        component: "System.Output"
        properties:
          text: "Connecting you back to the skill bot. What do you want to do next?"
          keepTurn: false
        transitions:
          next: "endPrompt"        
      rejected:  
        component: "System.Output"
        properties:
          text: "We're sorry, no one's available now. Try again later."
        transitions:
          return: "rejected"
     agentSystemError:      
        component: "System.Output"
        properties:
          text: "Oops! We are having system issues. We're sorry, but we can't connect you with an agent right now. Please try again later."
        transitions:
          return: "agentSystemError"
  21. Modify the System.Intent state to add an action for your agent transfer intent and map it to the start state of your agent transfer flow, as shown in the following example:
      intent:
        component: "System.Intent"
        properties:
          variable: "iResult"
        transitions:
          actions:
            OrderPizza: "resolvesize"
            CancelPizza: "cancelorder"
            TransferToAgent: "setupProfileFirstName"
            unresolvedIntent: "unresolved"
  22. Click Validate to ensure that your flow doesn't have any errors.

Transfer a Chat Session to an Agent When the User is Stuck

If the user is having problems using the skill bot, you can give them the opportunity to speak to a live agent so that the user can complete the task successfully.

One way to discover user problems is to create an intent for utterances that indicate user frustration. You can also enhance your dialog flow to handle unresolved intents and unanswered questions by asking the users if they want to speak to someone.

  1. Create a .csv file with query and topIntent columns and add utterances that you would expect the user to enter if they are frustrated or angry.

    As shown in this example, the first row in the file must provide the query and topIntent column names. In the subsequent rows, list each example utterance and the name of the intent to add it to. This example creates an intent named HandleProblems and adds the example utterances in the first column to that intent.

    query,topIntent
    argh,HandleProblems
    I'm mad,HandleProblems
    this sucks,HandleProblems
    why don't you understand me,HandleProblems
    you are stupid,HandleProblems
  2. From the Intents page, import your .csv file.
  3. From the Flows page, add a flow to handle this intent, as shown in this example:
    #
    # Handle problems
    #        
      handleProblems:
        component: "System.List"
        properties: 
          prompt: "I don't seem to be able to help you. Would you like to speak with someone?"
          options: 
          - label: "Yes"
            value: "SpeakToAgent" 
          - label: "No"
            value: "StartOver" 
          autoNumberPostbackActions: true
        transitions:
          actions:
            SpeakToAgent: "setupProfileFirstName"
            StartOver: "startOver"
      startOver:  
        component: "System.Output"
        properties:
          text: "I can help you order a pizza, cancel your order, or let you speak to someone. What would you like to do?"
          keepTurn: false
        transitions:
          next: "intent"
  4. Add an action to the System.Intent component for the intent that you just created, such as the HandleProblems action, as shown in the following example:
      intent:
        component: "System.Intent"
        properties:
          variable: "iResult"
        transitions:
          actions:
            OrderPizza: "resolvesize"
            CancelPizza: "cancelorder"
            TransferToAgent: "setupProfileFirstName"
            HandleProblems: "handleProblems"
            unresolvedIntent: "unresolved"
  5. (Optional) You can call the same flow if the user has too many unresolved intents.
    1. Add a context variable to count the number of unresolved intents (for example, unresolvedIntentCount):
      context:
        variables:
          size: "PizzaSize"
          type: "PizzaType"
          crust: "PizzaCrust"
          iResult: "nlpresult"
          agentProperties: "map"
          unresolvedIntentCount: "int"
    2. Add a flow that counts the unresolved intents and transitions to the flow that transfers to an agent if the unresolved intent count matches a certain value, as shown in this example:
      #
      # Handle unresolved intents
      # 
        handleUnresolvedIntent:
          component: "System.ConditionEquals"
          properties:
            variable: "unresolvedIntentCount"
            value: "3"
          transitions:
            actions:
              equal: "resetUnresolvedIntentCount"
              notequal: "incrementUnresolvedIntent"
        resetUnresolvedIntentCount:
          component: "System.ResetVariables"
          properties:
            variableList: "unresolvedIntentCount"  
          transitions:
            next: "handleProblems"    
        incrementUnresolvedIntent:
          component: "System.SetVariable"
          properties:
            variable: "unresolvedIntentCount"
            value: "<#if unresolvedIntentCount.value??>${unresolvedIntentCount.value?number+1}<#else>1</#if>"
          transitions:
            next: "tryAgain"
        tryAgain:
          component: "System.Output"
          properties:
            text: "I don't understand that."
          transitions:
            next: "intent"
    3. Modify the unresolvedIntent action in the System.Intent component to transition to the start state for your new flow (for example, handleUnresolvedIntent). Here's an example:
          component: "System.Intent"
          properties:
            variable: "iResult"
          transitions:
            actions:
              OrderPizza: "resolvesize"
              CancelPizza: "cancelorder"
              TransferToAgent: "setupProfileFirstName"
              HandleProblems: "handleProblems"
              unresolvedIntent: "handleUnresolvedIntent"
  6. (Optional) To enable the user to transfer to an agent if they are not able to answer a question, add a state after the user input to validate the input and transition to the handleProblems state if the input is invalid.
    In the following example, the type state accepts input for the variable named type, which is a PizzaType entity for which there's a set of valid values. The state has been modified to specify that the user has only three tries to enter a valid value, and it now transitions to checkType. If the user doesn't enter a valid value after three tries, as specified by maxPrompts, then the user now has the option of transferring to a live agent.
      type:
        component: "System.Text"
        properties:
          prompt: "What Type of Pizza do you want?"      
          maxPrompts: 3
          variable: "type"
        transitions:
          next: "checkType"
      checkType:
        component: "System.ConditionEquals"
        properties:
          variable: "type"
          value: null
        transitions:
          actions:
            equal: "handleProblems"
            notequal: "done" 
  7. Click Validate to verify your syntax.