15 Agent Integration

If you have an Oracle Service Cloud call center, your agents might spend the bulk of their time handling tasks that a skill can handle easily, such as changing a password or checking opening times. In this situation, you can create skills to handle these customer tasks and hand off only the tasks that require human intervention, thus reducing customer wait times and enabling your agents to provide more value.

Or perhaps your agents are spending the bulk of their time just gathering the essential information. Your skill can gather those details before handing off to an agent, thereby reducing live chat time and enabling your agents to handle more traffic. The conversation transfers seamlessly to the live agent in real time without any context switching, and the agent can view the whole conversation history.

Last, you might want to enhance your skills to offer the choice of escalating the conversation to an agent whenever the skill senses that the customer is stuck or frustrated, thus increasing customer satisfaction.

Note:

Oracle Digital Assistant supports integration with Version 18C (and later) of Oracle Service Cloud.

The Agent Integration Framework in Action

If a skill determines that the customer wants or needs to speak to a person, the skill connects to Oracle Service Cloud and then displays a message that it's waiting for the agent to join the conversation. Oracle Service Cloud sends a chat request to one of the live agents who are monitoring an agent chat console. After the agent accepts the request, the agent integration framework sends the customer's chat history and, optionally, a list of supported actions that the agent can send back to the bot. After the agent connects with the customer, the skill passes the messages between the customer and the agent until the user or agent terminates the session or the session expires.

How the Agent Integration Framework Works

The Agent Integration channel, along with the System.AgentInitiation and System.AgentConversation components allow you integrate your skill with a live-agent system like Oracle Service Cloud. The following sections describe how to configure these (and provide some other details for using Oracle Service Cloud as well), but here's a brief introduction:
  • You configure an Agent Integration channel using the credentials provided to you by an Oracle Service Cloud administrator, and you reference this channel from the System.AgentInitiation and System.AgentConversation components in your skill.
  • The System.AgentInitiation component connects the skill's conversation to Oracle Service Cloud. Optionally, the component can provide a list of supported actions that an agent can send to the System.AgentConversation component.
  • The System.AgentConversation component initiates a chat request with Oracle Service Cloud, which, in turn, sends the request to an agent's chat console. After the agent accepts the chat request, the component sends subject text, the conversation history, and, if specified in the System.AgentInitiation component, the supported actions. The component then manages the interchange between the skill and the agent.
  • The session can end in one of the following ways:
    • The agent terminates the session.
    • The agent sends one of the supported actions, the skill terminates the session, and the skill transitions to the state that corresponds with the action.
    • The customer enters one of the specified exit keywords, such as bye or goodbye.
    • The session expires after a period of inactivity.

    Tip:

    If the customer leaves the conversation by closing the messaging platform, such as by closing the chat window in a browser, then neither the skill nor the agent will know that the customer left. Oracle Service Cloud session charges will incur until the session expires due to inactivity. Web channels can add a custom CloseYes() function that calls Bots.sendMessage("<exit keyword>"), which sends a message to the skill to close the live-chat session if it is still active. Call CloseYes() when the user clicks the Close icon. The <exit keyword> value must be one of the words specified in the skill's System.AgentConversation component's exitKeywords property. For example:
    function CloseYes()
    {
        Bots.sendMessage("bye");
    
        // The timeout ensures that the message is sent to the bot successfully
        // before the rest of the close function wraps up the conversation.
        setTimeout(function() {
            Bots.destroy();
            clearChat();
            var appId = window.localStorage.getItem("appId");
    
            initBots(appId)
                .then(function () {
                    window.sessionStorage.setItem('chatEnabled', 'true');
                })
                .catch(function(err) {
                    console.log(err);
                })
        }, 3000);
    }

Integrate a Skill with a Live Agent

Here are the high-level steps for integrating a skill with an existing Oracle Service Cloud interface. The next topics describe each step in more detail.

  1. Create an Agent Integration channel: The channel allows the skill to communicate with Oracle Service Cloud.

  2. Enable Conversation History Transfer: In the skill's Settings Settings icon page, switch the Skill Conversation logging option to On to enable the framework to pass the conversation history to the live agent.

  3. Configure the Agent Integration Dialog Flow: Add the System.AgentInitiation and System.AgentConversation components to the dialog flow.

    • The System.AgentInitiation component initiates the handoff to Oracle Service Cloud
    • The System.AgentConversation handles the interaction between the skill and the agent.

    You can find templates for these components from the Flow Flow icon page by clicking + Components, and then clicking User Interface.


    An image of the Agent initiation component in the Add Components menu.

Create an Agent Integration Channel

You use an Agent Integration channel to configure the connections between skills and the live-agent system.

Before you begin, obtain the credentials of an Oracle Service Cloud staff member who's associated with a profile that has the following permissions:

  • Access to the desired Oracle Service Cloud interface
  • Account Authentication and Session Authentication for Public SOAP API
  • Account Authentication for Agent Browser User Interface

Contact an Oracle Service Cloud administrator if you don't have this information.

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.

  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 Service Cloud from the Integration Type menu.

  5. Enter the user name and password for an Oracle Service Cloud staff member who has the necessary profile permissions.

  6. Define the domain name and host name prefix.

    If you have access to Oracle Service Cloud, you can derive these values from the URL that you use to launch the Agent Browser User Interface. For example, if the URL is sitename.exampledomain.com, then the host name prefix is sitename and the domain name is exampledomain.com.

  7. Click Create.

  8. To enable the skill to interact with the agent framework, enable the channel by switching Interaction Enabled to On.

Enable Conversation History Transfer

You must turn on skill conversation logging to enable the agent integration framework to pass the conversation history to a live agent. When you enable this option, the agent's chat console displays the customer's conversation that occurred before the handoff to the agent.

  1. In the skill's left navbar, click Settings Settings icon .
  2. In the Enable Conversation Logging section, Set the Skill Conversation switch to On.

Configure the Agent Integration Dialog Flow

There are several ways that your dialog flow can direct customers to a live agent. For example:

  • You can provide a specific option for talking with an agent.
  • You can execute a path that gathers necessary customer information before handing someone off to an agent.
  • You can create a handler for unresolved intents that tranfers the customer to an agent.
  • You can create an agent-transfer intent.
In this example, the GetAgent intent is trained to understand distress calls like help me please!
intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
    transitions:
      actions:
        OrderPizza: "resolvesize"
        CancelPizza: "cancelorder"
        GetAgent: "agentInitiation"
        unresolvedIntent: "agentInitiation"

Regardless of you approach, your dialog needs to connect to the live-agent system and maintain the session using the System.AgentInitiation and System.AgentConversation components. Here are some basic guidelines:

  1. To initiate the live-agent handoff:

    1. Add a state for the System.AgentInitiation component.

    2. Set the agentChannel property to the name of the Agent Integration channel that you configured for the live-agent system.

    3. Set the customProperties property to the name of a map variable that specifies the Oracle Service Cloud interface ID. You can omit customProperties if the interface ID is 1, which is the default. Note that agent integration requires that the interface is chat-enabled. You can use the Oracle Service Cloud Configuration Assistant, which you access from My Services, to see if an interface is enabled for chat.

      See The customerInformation Object to learn how to get and specify this ID.

    After the Agent Integration channel establishes a connection and Oracle Service Cloud sends the chat request to its queue (that is, after it creates a help ticket), the System.AgentInitiation component allows the transition to the next state, which is typically defined for the System.AgentConversation component (agentConversation in the following example).
    
      setCustomFields:
        component: "System.SetVariable"
        properties:
          variable: "liveChatInfo"
          value:
            customerInformation:
              interfaceID:
                id:
                  id: "${interfaceId}"
      ...
      agentInitiation:
        component: "System.AgentInitiation"
        properties:
          agentChannel: "ServiceCloudIntegration"
          customProperties: "${liveChatInfo.value}"
          nlpResultVariable: "iResult"
          waitingMessage: "Waiting for an agent..."
          rejectedMessage: "Agents are not available right now."
          resumedMessage: "We're connecting you to an agent..."
          errorMessage: "Oops! We're having system issues. We're sorry, but we can't connect you with an agent right now."
        transitions:
          actions:
            accepted: "agentConversation"
            rejected: "tryAgain"
            error: "tryAgain"
      tryAgain:
        component: "System.Output"
        properties:
          text: "Please try again later."
        transitions:
          return: "tryAgain"

    Tip:

    Customers may repeatedly request a live chat even though their requests have already been queued in the agent's chat console. Add a resumedMessage property to the System.AgentInitiation state to prevent such customers from receiving a misleading Resuming chat with agent message.
  2. Configure the System.AgentConversation component. While the dialog engine is in the state defined for this component, the skill passes messages back and forth between the customer and the agent. The skill listens for exit keywords in the customer input, like bye. When the skill detects one of these keywords, the System.AgentConversation component ends the live-chat session and triggers its next transition.

    Here's an example:

      agentConversation:
        component: "System.AgentConversation"
        properties:
          agentChannel: "ServiceCloudIntegration"
          nlpResultVariable: "iResult"
          exitKeywords: "bye, exit, take care, goodbye, quit"
          expiryMessage: "Your chat with the agent timed out."
          conclusionMessage: "Your chat with the agent has ended."
          waitMessage: "You are number ${system.message.messagePayload.position} in the queue. Your waiting time is ${(system.message.messagePayload.waitTime>60)?then('${(system.message.messagePayload.waitTime/60)?int} mins','${system.message.messagePayload.waitTime} seconds')}."
        transitions:
          next: "endPrompt"
          actions:
            agentLeft: "endPrompt"
            expired: "endPrompt"
      endPrompt:
        component: "System.Output"
        properties:
          text: "Returning you to your bot."
        transitions:
          return: "endPrompt"
Enable Agents to Specify the Transition Action

If you want enable the agent to specify which state to transition to after the live-chat session ends, use the agentActions property in the System.AgentInitiation component to list the supported actions that the agent can send, and then use the System.AgentConversation component to map the actions to states.

When the agent accepts the chat request, the chat console displays the supported actions, each of which is preceded by a slash (these are referred to as slash actions).

Agent console displaying list of supported actions.

If the agent sends any of the slash actions, the action is sent to the agent-integration framework, and the skill terminates the live chat. If the System.AgentConversation has a transition for that action, the flow transitions to the named state. Note that the conclusionMessage isn't output if the agent sends a slash action.

Chat console showing that the agent has sent /Order and the chat has terminated.
  1. Add an agentActions property to the System.AgentInitiation component, and list the supported actions.

    You can define the agentActions list elements in several ways:

    • As a list of maps, where each map must contain an action property, a label property, and optionally, a description property. For example:
            - action: "action1"
              label: "label1"
              description: "description1"
            - action: "action2" 
              label: "label2"
              description: "description2"
    • As a JSON array, where each object in the array must contain an action property, a label property, and optionally, a description property. For example:
            [
            {action: "action1",
            label: "label1",
            description: "description1"},
            {action: "action2",
            label: "label2",
            description: "description2"}      
            ]
    • As a comma-delimited string of action values. The label and description are the same as the action value. For example:
      "action1, action2"
  2. (Optional) Add the agentActionsMessage property to specify a message for the live chat console to display before it lists the supported actions. For example:
      agentInitiation:
        component: "System.AgentInitiation"
        properties:
          agentChannel: "ServiceCloudIntegration"
          nlpResultVariable: "iResult"
          waitingMessage: "Let me connect you with someone who can further assist you."
          rejectedMessage: "Sorry, but no one's available now."
          resumedMessage: "Please wait, someone will be with you shortly."
          errorMessage: "Oops! We're having system issues. We're sorry, but we can't connect you with an agent right now."
          agentActionsMessage: "\nYou can terminate when done or send one of these actions.\n"
          agentActions: [{
            action: "Order",
            label: "Order",
            description: "Initiate dialog in the bot to order a pizza."},
            {action: "Cancel",
            label: "Cancel",
            description: "Initiate dialog in the bot to cancel an order."}]     
        transitions:
          actions:
            accepted: "agentConversation"
            rejected: "initiationRejected"
            error: "tryAgain"
      initiationRejected:
        component: "System.Output"
        properties:
          text: "Perhaps it's outside their working hours or it's a holiday."
        transitions:
          return: "tryAgain"
      tryAgain:
        component: "System.Output"
        properties:
          text: "Please try again later."
        transitions:
          return: "tryAgain"
    If you don't set this property, then the default message is Here are the available actions that you can send to transfer the conversation back to the bot. Prepend the action with a forward slash (for example, /actionName).
  3. Add a next transition for when the user terminates the conversation by using an exit keyword, and then add these transition actions:
    • An action for each supported action that's listed in the agentActions property in the System.AgentConversation component.
    • An agentLeft action for when the agent terminates the live chat without using a slash action.
    • An expired action for when a session expires after 15 minutes or the number of minutes specified by the System channel's Session Expiration value, whichever comes first.
      agentConversation:
        component: "System.AgentConversation"
        properties:
          agentChannel: "ServiceCloudIntegration"
          nlpResultVariable: "iResult"
          exitKeywords: "bye, exit, take care, goodbye, quit"
          expiryMessage: "Your chat with the agent timed out."
          conclusionMessage: "Your chat with the agent has ended."
          waitMessage: "You are number ${system.message.messagePayload.position} in the queue. Your waiting time is ${(system.message.messagePayload.waitTime>60)?then('${(system.message.messagePayload.waitTime/60)?int} mins','${system.message.messagePayload.waitTime} seconds')}."
        transitions:
          next: "endPrompt"
          actions:
            agentLeft: "endPrompt"
            expired: "endPrompt"
            Order: "resolvesize"
            Cancel: "cancelorder"
      endPrompt:
        component: "System.Output"
        properties:
          text: "Returning you to your bot."
        transitions:
          return: "endPrompt"
Override Queue Position and Wait Time Message

By default, when a chat request is submitted, the service returns message about the queue position and wait time, which the skill outputs. For example, the message might be:

You are in position {0} in our queue. Expected wait time is {1} minute(s) {2} second(s)
You can use System.AgentConversation component's waitMessage property to define your own custom message. As illustrated by the following snippet, you can create a message that returns the queue and wait time status using our system.message.messagePayload.position and system.messagePayload.waitTime properties, respectively:
"You are at number ${system.message.messagePayload.position} in the queue. Your wait time is ${system.message.messagePayload.waitTime}."
You can tailor the message content by combining these properties with built-in Apache FreeMarker operations, such as the then operation in the following snippet. Here, it allows the skill to output content that's specific to either minutes or seconds. For wait times of 60 seconds or longer (waitTime>60), the skill outputs You are at number 9 in the queue. Your wait time is 1 mins. Otherwise, it outputs You are at number 9 in the queue. Your wait time is 55 seconds.
    waitMessage: "You are at number ${system.message.messagePayload.position} in the queue. Your wait time is ${(system.message.messagePayload.waitTime>60)?then('${(system.message.messagePayload.waitTime/60)?int} mins','${system.message.messagePayload.waitTime} seconds')}"
Handle Agent Initiation Rejection and System Errors

When the System.AgentInitiation component tries to initiate a connection with the live-agent system, it might return an error or rejected action .

A rejected action means that Oracle Service Cloud has rejected the connection request. Some of the reasons for rejecting a connection request are:
  • No agents are available
  • It's outside of the configured operating hours
  • It's a holiday
  • There's a problem with the chat server

When Oracle Service Cloud rejects a connection request, the skill displays a rejected message, which is Agent rejected by default. Then it transitions to the state that's mapped to the rejected action. You can use the rejectedMessage property in the System.AgentInitiation component to provide a custom message.

Tip:

If you have admin access to the Oracle Service Cloud desktop service console, you can view the operating hours and holidays. From the navigation pane, click Configuration, click Site Configuration, double-click Interfaces, and then click Chat Hours.

An error action means that there's a problem on the Digital Assistant side. This might be due to a problem with the Agent Integration channel. Perhaps the channel isn't enabled or the user's password changed.

When an error occurs, the skill displays the following message by default, and then transitions to the state that's mapped to the error action.

Error transferring to agent, the reason is: <reason>, Please contact
your system administrator to resolve this error.

You can use the errorMessage property in the System.AgentInitiation component to override the default message.

Here's an example of handling the error and rejected actions.

  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      agentChannel: "ServiceCloudIntegration"
      nlpResultVariable: "iResult"
      waitingMessage: "Let me connect you with someone who can further assist you."
      resumedMessage: "Please wait, someone will be with you shortly."
      errorMessage: "Oops! We're having system issues. We're sorry, but we can't connect you with an agent right now."
      rejectedMessage: "Sorry, but no one's available now."     
    transitions:
      actions:
        accepted: "agentConversation"
        rejected: "initiationRejected"
        error: "tryAgain"
  initiationRejected:
    component: "System.Output"
    properties:
      text: "Perhaps it's outside their working hours or it's a holiday."
    transitions:
      return: "tryAgain"
  tryAgain:
    component: "System.Output"
    properties:
      text: "Please try again later."
    transitions:
      return: "tryAgain"

Tutorial: Live Agent Integration

You can get a hands-on look at live agent integration by walking through this tutorial: Integrate a Skill with Oracle Service Cloud Live Chat.

Passing Customer Information to a Live Chat

When conversation logging is enabled for a skill, it passes the whole chat history to Oracle Service Cloud automatically. In addition to the chat history, you also can send some specific customer information.

  • Incident ID
  • Chat Customer Information: Skills can pass the following chat customer information to Oracle Service Cloud.
    • E-mail address
    • First Name
    • Last Name
    • Interface
    • Contact
    • Organization
    • Category

    The skill uses the profile values to populate and send these chat customer fields automatically, you don't need to do anything to set these values:

    • E-Mail address

    • First Name

    • Last Name

  • Incident Custom Fields: You can pass values for any Oracle Service Cloud custom field of type Incident.

To send this information to the live agent, you pass a map in the System.AgentInitiation component's customProperties property. Here's the top-level structure of the map:

incidentID: # type int
customerInformation: # chat customer information object
customFields: # incident custom fields object

The incidentID Property

You can pass an Incident ID to the live agent by adding an incidentID property to the customProperties map.

Here's an example:

context:
  variables:
    liveChatInfo: "map"
    customerTicketId: "int"
...
  setCustomFields:
    component: "System.SetVariable"
    properties:
      variable: "liveChatInfo"
      value:
        incidentID: "${customerTicketId}" # long value
  ...
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      ...
      customProperties: "${liveChatInfo.value}"

The customerInformation Object

You use the customerInformation object in the customProperties map to pass chat customer information, such as the Interface ID, Contact ID, or Category ID. The customerInformation object can contain the fields that are defined in the Chat Customer Information section in the Oracle Service Cloud WSDL at http://<sitename.domain>/services/soap/connect/chat_soap?wsdl=server.

For objects, change the initial character in the name to lower case, and change the names of simple fields to all lower case.

If you don't pass the interfaceID object, the skill uses a default of id:{id: 1}. Note that if the interface isn't chat enabled, then the initiation handshake will fail. You can use the Oracle Service Cloud Configuration Assistant, which you access from My Services, to verify if an interface is enabled for chat.

This example sets the interfaceID and contactID.

Tip:

Because the WSDL specifies that interfaceID is of type NamedID, we could've used name: "myInterfaceName" instead of id: id: "${interfaceId}".
context:
  variables:
    liveChatInfo: "map"
    interfaceId: "int"
    contactId: "int"
...
  setCustomFields:
    component: "System.SetVariable"
    properties:
      variable: "liveChatInfo"
      value:
        customerInformation:
          interfaceID:
            id:
              id: "${interfaceId}"
          contactID:
            id: "${customerId}"
  ...
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      ...
      customProperties: "${liveChatInfo.value}"

While you can define the EMailAddress, FirstName, and LastName fields that are described in the WSDL’s Chat Customer Information section, your skill automatically sets these values from the corresponding .profile properties (described in User Context).

Tip:

You can use the Oracle Service Cloud REST API to view the valid values for customer information fields. For example, this GET request lists interface IDs and names:
curl --request GET \
--url https://<sitename.domain>/services/rest/connect/latest/siteInterfaces \
--header 'authorization: Basic <base64-encoded-username+:+password>' \
--header 'osvc-crest-application-context: <some-comment>'

This GET request lists the categories:

curl --request GET \
--url https://<sitename.domain>/services/rest/connect/latest/serviceCategories \
--header 'authorization: Basic <base64-encoded-username+:+password>' \
--header 'osvc-crest-application-context: <some-comment>'

As mentioned earlier, the customerInformation map structure must conform to the Chat Customer Information structure that's shown in the WSDL at the following address:

http://<sitename.domain>/services/soap/connect/chat_soap?wsdl=server

Here's an excerpt from the WSDL:

<!--  ============================== -->
<!--    Chat Customer Information    -->
<!--  ============================== -->

<xs:complexType name="ChatCustomerInformation">
    <xs:sequence>
        <xs:element name="EMailAddress" minOccurs="0" maxOccurs="1">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:maxLength value="80"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:element>

        <xs:element name="FirstName" minOccurs="0" maxOccurs="1">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:maxLength value="80"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:element>

        <xs:element name="LastName" minOccurs="0" maxOccurs="1">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:maxLength value="80"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:element>

        <xs:element name="InterfaceID" type="rnccm:NamedID" minOccurs="1" maxOccurs="1"/>
        <xs:element name="ContactID" type="rnccm:ID" minOccurs="0" maxOccurs="1" />
        <xs:element name="OrganizationID" type="rnccm:ID" minOccurs="0" maxOccurs="1" />
        <xs:element name="Question" type="xs:string" minOccurs="0" maxOccurs="1"/>
        <xs:element name="ProductID" type="rnccm:ID" minOccurs="0" maxOccurs="1"/>
        <xs:element name="CategoryID" type="rnccm:ID" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
</xs:complexType> 

Some objects are of type rnccm:ID, which is defined in the next excerpt. Notice that the object contains an id field of type long.

<xs:element name="ID" type="ID"/>
<xs:complexType name="ID">
    <xs:attribute name="id" type="xs:long" use="optional"/>
</xs:complexType> 

InterfaceID is of type rnccm:NamedID. Notice that this object can contain an ID (long), a Name (string), or both.

<xs:element name="NamedID" type="NamedID"/>
<xs:complexType name="NamedID">
    <xs:sequence>
        <xs:element name="ID" type="ID" minOccurs="0" maxOccurs="1"/>
        <xs:element name="Name" type="xs:string" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
</xs:complexType>

The casing differs between the WSDL and the customProperties map. In the map, the first letter for an object name is lower case (Pascal case). For example, ProductID in the WSDL would be productID for the map object. The simple field names are all lower case (Name becomes name, for example).

The customFields Object

You use the customFields object in the customProperties map to pass values for any Oracle Service Cloud custom field of type Incident.

The customFields object is an array of maps that contain name, dataType, and dataValue properties, as shown in the following example. The name property names the custom field, which is the lower-case custom field name preceded by c$.

context:
  variables:
    liveChatInfo: "map"
    skillType: "string"
...
  setupCustomFields:
    component: "System.SetVariable"
    properties:
      variable: "liveChatInfo"
      value:
        customerInformation: 
          interfaceID:
            id:
              id: 1     
        customFields:
# Text Field
          - name: "c$da_text_field"
            dataType: "STRING"
            dataValue:
              stringValue: "SILVER"
# Text Area
          - name: "c$da_text_area"
            dataType: "STRING"
            dataValue:
              stringValue: "This is a very long string that is more than 32 characters."
# Integer
          - name: "c$da_integer"
            dataType: "INTEGER"
            dataValue:
              integerValue: 21
# Menu
          - name: "c$da_menu"
            dataType: "NAMED_ID"
            dataValue: 
              namedIDValue:
                name: "Item 1"
# Instead of name, you can use
#                id:
#                  id: 1
#
# Yes/No
          - name: "c$da_is_from_skill"
            dataType: "BOOLEAN"
            dataValue:
              booleanValue: true
# Date (XML Schema Date)
          - name: "c$da_date"
            dataType: "DATE"
            dataValue:
              dateValue: "2019-10-26" 
# DateTime (XML Schema DateTime)
          - name: "c$da_datetime"
            dataType: "DATETIME"
            dataValue:
              dateTimeValue: "2019-10-26T21:32:52"               
    transitions: {}
  ...
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      ...
      customProperties: "${liveChatInfo.value}"

Tip:

You can send the following GET request, which uses RightNow Object Query (ROQL), to obtain a list of the custom field names:
curl --request GET \
--url https://<site.domain>/services/rest/connect/latest/queryResults/?query=select%20CustomFields.c.*%20from%20Incidents \
--header 'authorization: Basic <base64-encoded-username+:+password>' \
--header 'osvc-crest-application-context: <some-comment>'

To get the valid values for a custom field, send a GET request that uses RightNow Object Query (ROQL) like this:

curl --request GET \
--url https://<site.domain>/services/rest/connect/latest/queryResults/?query=select%20CustomFields.c.skillType%20from%20Incidents%20where%20CustomFields.c.skillType%20IS%20NOT%20NULL \
--header 'authorization: Basic <base64-encoded-username+:+password>' \
--header 'osvc-crest-application-context: <some-comment>'

The GenericField definition in the Oracle Service Cloud WSDL at http://<sitename.domain>/services/soap/connect/chat_soap?wsdl=server describes the dataType and dataValue structure:

<xs:element name="GenericField" type="GenericField"/>
  <xs:complexType name="GenericField">
    <xs:sequence>
      <xs:element name="DataValue" type="DataValue" minOccurs="1" maxOccurs="1" nillable="true"/>
    </xs:sequence>
  <xs:attribute name="dataType" type="DataTypeEnum" use="optional"/>
  <xs:attribute name="name" type="xs:string" use="required"/>

Like the customerInformation fields, the same casing applies to the customProperties map counterparts (the WSDL’s DataValue is dataValue in the map, for example).

Configuring the Dialog Flow

These steps describe the dialog flow configuration process for declaring the customProperties object and setting its various values.

Step 1: Declare the Custom Properties Variable
In the context node, define a map variable for the customProperties property in the System.AgentInitiation component. It’s a JSON object that can hold the chat customer information and custom field values. In the following example, this variable is declared as liveChatInfo:
context:
  variables:
    size: "PizzaSize"
    type: "PizzaType"
    crust: "PizzaCrust"
    iResult: "nlpresult"
    interfaceId: "string"
    categoryId: "string"
    skillType: "string"
    liveChatInfo: "map"
Step 2: Set the Values for the customProperties Map Variable
Between the start state and the System.AgentInitation component definition, you need to set the values that you need for the custom property map variable. You can set them through a custom component, or through a series of value-setting components in the dialog flow definition. Here’s an example of the latter approach.
states:
  ...

  setInterface:
    component: "System.SetVariable"
    properties:
      value: "3" 
      variable: "interfaceId"
    transitions:
      next: "setSkillType"
    
  setSkillType:
    component: "System.SetVariable"
    properties:
      value: "pizza" 
      variable: "skillType"
    transitions:
      next: "setCategory"
    
  setCategory:
    component: "System.SetVariable"
    properties:
      value: "604"
      variable: "categoryId"
    transitions:
      next: "setLiveChatInfo"
 
Step 3: Define the Fields for the customProperties Map Variable
Whether you set the map values through a custom component or through the dialog flow, you need to structure the map object as described in The customerInformation Object and The customFields Object. Here's an example:

  setLiveChatInfo:
    component: "System.SetVariable"
    properties:
      variable: "liveChatInfo"
      value:
        customerInformation: 
          interfaceID:
            id:
              id: "${interfaceId}" 
          categoryId:
            id: "${categoryId}"             
        customFields: 
          - name: "c$skilltype"
            dataType: "STRING"
            dataValue:
              stringValue: "${skillType}"
    transitions:
      next: "agentInitiation"
Step 4: Add the customProperties to the System.AgentInitiation Component
Finally, add the customProperties property to the System.AgentInitiation component and define it using an expression that accesses the map variable value.
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      subject: "A customer needs help regarding ${skillType}."
      agentChannel: "ServiceCloudIntegration"
      waitingMessage: "Let me connect you with someone who can further assist you."
      resumedMessage: "Please wait, someone will be with you shortly."
      rejectedMessage: "Sorry no one is available now."
      errorMessage: "We're sorry! We're having system issues and we can't connect you with an agent."
      customProperties: "${liveChatInfo.value}"
    transitions:
      actions:
        accepted: "agentConversation"
        rejected: "initiationRejected"
        error: "tryAgain"
  initiationRejected:
    component: "System.Output"
    properties:
      text: "Perhaps it's outside their working hours or it's a holiday."
    transitions:
      return: "tryAgain"
  tryAgain:
    component: "System.Output"
    properties:
      text: "Please try again later."
    transitions:
      return: "tryAgain"

Tutorial: Pass Customer Information to a Live Chat

You can get a hands-on look at passing information to a live chat by walking through this tutorial, which is part 2 of a series: Pass Customer Information to a Live Chat.

Get Survey Information

If you want to ask the customer to fill out a survey about the conversation with the agent, you can get the conversation's session ID and engagement ID when the chat session is established, and then pass those values to a survey service when the conversation ends.

Let's say, for example, that you used a survey service such as Oracle Feedback Cloud Service to develop a survey which takes session and engagement parameters. When the agent conversation ends, you can display a link to the survey form, such as https://example.com?session=12345&surveyid=12345. Here's how to use the System.AgentInitiation component's chatResponseVariable property to get the IDs that you need, and then use the System.AgentConversation.conclusionMessage property to pass them in a link to a survey service.

When the chat session is established with the live agent, Oracle Service Cloud sends the following payload.

{
  "sessionID": "string", // agent session id

  "completedSurveyID": {
    "id": "int"
  },

  "engagementID": { // survey id
    "id": "int"
  },

  "cancelledSurveyID": {
    "id": "int"
  }
}

The dialog engine stores this payload in the map variable that's referenced by the System.AgentInitiation.chatResponseVariable property. (If System.AgentInitiation.chatResponseVariable isn't defined, then the payload is discarded.)

In the following example, the System.AgentConversation component outputs a survey link after the agent conversation ends. The link includes the session and engagement ID from the map that was named by the chatResponseVariable property.

context:
  variables:
    agentSystemResponse: "map" # chat request response is stored in this variable.
    ...
states:
  ...
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      agentChannel: "ServiceCloudIntegration"
      nlpResultVariable: "iResult"
      chatResponseVariable: "agentSystemResponse"  
    transitions:
      actions:
        accepted: "agentConversation"
        rejected: "tryAgain"
        error: "tryAgain"
  agentConversation:
    component: "System.AgentConversation"
    properties:
      agentChannel: "ServiceCloudIntegration"
      nlpResultVariable: "iResult"
      exitKeywords: "bye, exit, take care, goodbye, quit"
      expiryMessage: "Your chat with the agent timed out."
      conclusionMessage: "Can you please fill out this survey: <PUT SURVEY URL HERE>?session=${agentSystemResponse.value.sessionID}&surveyid=${agentSystemResponse.value.engagementID.id}"
    transitions:
      next: "endPrompt"
      actions:
        agentLeft: "endPrompt"
        expired: "sessionExpired"

Tip:

You can configure the survey to take other parameters, such as the user's name and email address.

Transfer the Chat to a Specific Oracle Service Cloud Queue

Oracle Service Cloud uses chat rules and queues to sort incoming chat requests based on Chat Customer Information and Incident custom field values.

For example, the Oracle Service Cloud interface might have a chat rule that if the fromBot custom field is set to Yes, then add the chat request to the Bot queue. When its rule base doesn't have a rule for an incoming chat, then it sends the chat request to a default queue.

By default, the skill routes all agent chats to the default queue. However, you can take advantage of the System.AgentInitiation component's customProperties property to pass in the values for a specific rule that will filter the chat request to the desired queue.

Before you begin, you'll need the names and valid values of the custom fields or customer information (or both) that have been defined for the queue's chat rule. If you have admin access to the Oracle Service Cloud desktop Service Console, then you can see the chat rules from the Configuration > Site Configuration > Rules > Chat page. Otherwise, ask your Oracle Service Cloud administrator to provide this information.

You'll also need to understand how to structure the map object that you use with the customProperties property. See Passing Customer Information to a Live Chat.

  1. If you haven't already, in the context node, define a map variable to use with the System.AgentInitiation component's customProperties property. For example:

    context:
      variables:
        greeting: "string"
        name: "string"
        liveChatInfo: "map"
    
  2. Define the fields for the map variable. For example:

      setLiveChatInfo:
        component: "System.SetVariable"
        properties:
          variable: "liveChatInfo"
          value:
            customFields: 
              - name: "c$frombot"
                dataType: "BOOLEAN"
                dataValue:
                  booleanValue: true
        transitions:
          next: "agentInitiation"
  3. Add the customProperties property to the System.AgentInitiation component, and set it to the value of your map variable. For example:

      agentInitiation:
        component: "System.AgentInitiation"
        properties:
          agentChannel: "ServiceCloudIntegration"
          nlpResultVariable: "iResult"
          customProperties: "${liveChatInfo.value}"
          waitingMessage: "Waiting for an agent..."
          rejectedMessage: "Agents are not available right now."
          resumedMessage: "We're connecting you to an agent..."
          errorMessage: "Oops! We're having system issues. We're sorry, but we can't connect you with an agent right now."
        transitions:
          actions:
            accepted: "agentConversation"
            rejected: "tryAgain"
            error: "tryAgain"
      tryAgain:
        component: "System.Output"
        properties:
          text: "Please try again later."
        transitions:
          return: "tryAgain"

Tutorial: Transfer to a Live Chat Queue

You can get a hands-on look at transferring to a live chat queue by walking through this tutorial, which is part 3 of a series: Transfer a Chat Session to a Live Chat Queue.