14 Agent Integration

You can augment the chat enabled in Oracle Service Cloud interface with a skill, one that gathers customer information for the customer service representative (CSR) who's operating through Oracle Service Cloud. Because skills can answer basic questions, or even complete a task for a customer, coupling them with Oracle Service Cloud simultaneously reduces the chat flowing to the CSRs and provides them with the context they need to complete a session quickly.

Note:

We support Version 18C (and later) of Oracle Service Cloud.

The Agent Integration Framework in Action

The skill, which has screened the customer for information, asks the customer if he needs help. By clicking yes, the skill connects to the agent system and returns a Waiting for the agent message to the customer. The live agent, or customer service representative (CSR), monitoring an agent console in Oracle Service Cloud, gets notified of the request and accepts it. The Agent Integration framework provides the user’s chat history. Once the customer connects with the CSR, the skill passes the messages between the customer and the CSR and listens for the termination of the session by either the customer or the CSR. A customer can end the session at any point by entering closing words like bye or goodbye.

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 an 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:
  • The Agent Integration channel connects the skill to the Agent Browser UI (BUI) in Oracle Service Cloud. You configure this channel using the credentials provided to you by the Oracle Service Cloud administrator.
  • The System.AgentInitiation and the System.AgentConversation components initiate a request to a live agent and then manage the resulting interaction. The System.AgentInitiation component makes the handshake by naming the Agent Integration channel. Once the System.AgentInitiation component has made contact (and the customer service representative has accepted the request), the System.AgentConversation component passes the user chat to the live agent and manages the interchange between the skill and the customer service representative.

How to Integrate the Skill with a Live Agent

To add a skill on top of an existing Oracle Service Cloud interface:

  1. Create the Agent Integration channel that allows the skill to communicate with Oracle Service Cloud. You need to get the credentials for this channel from the Oracle Service Cloud administrator.
  2. To post the conversation history to the live agent, enable the Skill Conversation logging option that's located in the Skill Builder’s Settings page (This is an image of the left navbar's Settings icon.).
  3. Update the dialog using the System.AgentInitiation and System.AgentConversation components. The System.AgentInitiation component executes the hand off to the agent while System.AgentConversation handles the interaction between the skill and the customer service representative.

    You can find templates for these components by clicking User Interface in the Add Components dialog. To find out how to route to a user agent subflow, see Configure the Dialog Flow for User Agents.

    Contact the Oracle Service Cloud administrator for queue names and other routing-related information.

Configure the Agent Integration Channel

  1. Click icon to open the side menu to open the side menu, then select Development > Channels.
  2. Choose Agent Integrations > + 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.

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

  6. Click Create.
  7. To enable the skill to interact with the agent framework, enable the channel by switching on the Interaction Enabled toggle.

Configure the Dialog Flow for User Agents

Your dialog flow can route customers to the agent system through specific options, execution paths that gather customer information, or as illustrated by the following example, through an intent (getAgent) that's 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: "unresolved"
You can also route to the user agent state with an unresolvedIntent action (unresolvedIntent: "agentInitiation", for example).

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

  1. Configure the handshake with the agent system that's conducted by the Agent Integration channel by adding a state for the System.AgentInitiation component.

    The System.AgentInitiation component initiates the request through its agentChannel property that names the Agent Integration channel.

    Once the request is queued (that is, a help ticket has been created), the System.AgentInitiation component allows the transition to the next state, one typically defined for the System.AgentConversation component (agentConversation in the following example).
      agentInitiation:
        component: "System.AgentInitiation"
        properties:
          agentChannel: "MyServiceCloudAgent"
          nlpResultVariable: "iResult"
          waitingMessage: "Waiting for an agent..."
          rejectedMessage: "Custom: Sorry we're not available right now."
          resumedMessage: "Just a second...we're connecting you to an agent."
        transitions:
          actions:
            accepted: "agentConversation"
            rejected: "reject"

    Note:

    Customers may repeatedly request a live chat even though their requests may have already been queued in the CSR's console. Adding a resumedMessage property prevents such customers from receiving a misleading agent rejected message.
  2. Configure the System.AgentConversation component. While the Dialog Engine is in the state defined for this component, the skill passes messages sent back and forth between the customer and the CSR. The skill listens for the slash commands (reflected as its actions properties) or for exit words in the customer input, like bye.
      agentConversation:
        component: "System.AgentConversation"
        properties:
          agentChannel: "MyServiceCloudAgent"
          nlpResultVariable: "iResult"
          exitKeywords: "bye, adios, take care, goodbye"
          conclusionMessage: "Custom: The agent has exited."
          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')}"
          expiryMessage: "Chat session expired. Thanks for chatting with us." 
        transitions:
           next: "endPrompt"
      endPrompt:
        component: "System.Output"
        properties:
          text: "Returning you to your bot."
        transitions:
          return: "endPrompt"
      reject:
        component: "System.Output"
        properties:
          text: "We're busy. Try again later."
        transitions:
          return: "done"
Messages intended for the customer representative have the Custom: prefix. It confirms that this message was sent from the skill.
Queue and Wait Time Status Messages
By default, the skill outputs a status message that's formatted as You are in position {0} in our queue. Expected wait time is {1} minute(s) {2} second(s). You can customize this message by defining the waitMessage property. 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')}"
    transitions:
      next: "exit"

How to Specify Oracle Service Cloud Queues

Defining the customProperties property for the System.AgentInitiation component enables your Agent Systems to route the customer (and the chat history) to a specific agent queue in Oracle Service Cloud.

By default, all agent chats are routed to default queue. When the System.AgentInitiation component initiates the interaction with the Oracle Service Cloud using the customProperties property, however, it’s passing additional information that identifies a particular interface on the Oracle Service Cloud instance and the customer contact. It also passes custom information, such as membership status or a ZIP code, that the chat rules in Oracle Service Cloud use to ultimately connect the user to a live agent who monitors a dedicated queue.

To define this property, you'll need values for the interface ID, customer contact IDs, and the names for the custom fields that have been defined for the chat rules in Oracle Service Cloud. Check with your Oracle Service Cloud administrator to get these, or if you have access to Oracle Service Cloud instance, you can obtain these through the REST API for Oracle Service Cloud.

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 customProperties Variable
In the context node, define a map variable for the customProperties property. It’s a JSON object that holds the custom, interface, and customer contact values. Later in the dialog flow, you’ll use this variable name within the customProperties definition. In the following example, this variable is declared as myCustomProps:
context:
  variables:
    greeting: "string"
    name: "string"
    sessionId: "string"
    interfaceId : "int"
    customerId : "int"
    agentIncidentIntentName: "string"
    myCustomProps : "map"
…
  startContactAgent:
    component: "System.AgentInitiation"
    properties:
      subject: "A customer needs help regarding ${agentIncidentIntentName.value}"
      agentChannel: "svc"
      waitingMessage: "Chat accepted, waiting for agent to join."
      rejectedMessage: "Sorry we are not available now."
      customProperties: "${myCustomProps.value}"
Step 2: Set the Values for the customProperties Map Variable
Between declaring the map variable and the System.AgentInitation component definition, you need to set the values that enable the Oracle Service Cloud queue routing. 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, where the setCustomFields state stores all the values previously set in the map variable, myCustomProps. We’ll look this state in more detail in a subsequent step.
states:

  start:
    component: "System.Text"
    properties:     
      prompt: "How can I help you today?"
      variable: "name"

  setUserEmail:
    component: "System.SetVariable"
    properties:
      value: "joe.smith@example.com"
      variable: "profile.email"
    transitions: {}
  
  setInterface:
    component: "System.SetVariable"
    properties:
      value: "3" 
      variable: "interfaceId"
    transitions: {}
    
  setAgentIncidentIntentName:
    component: "System.SetVariable"
    properties:
      value: "membership" 
      variable: "agentIncidentIntentName"
    transitions: {}
    
  setCustomerId:
    component: "System.SetVariable"
    properties:
      value: "604"
      variable: "customerId"
    transitions: {}
            
  setCustomFields:
    component: "System.SetVariable"
    properties:
      variable: "myCustomProps"
      value:
        customerInformation: 
          interfaceID:
            id:
              id: "${interfaceId}" 
          contactID:
            id: "${customerId}" 
            
        customFields: 
          - name: "c$intent"
            dataType: "STRING"
            dataValue:
              stringValue: "${agentIncidentIntentName}"
          - name: "c$vipStatus" 
            dataType: "STRING"
            dataValue:
              stringValue: "BRONZE"
              
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 to include two top-level fields: customerInformation and customFields.

The customerInformation Fields
For the customerInformation field, include inferfaceID, which specifies the particular interface on the Oracle Service Cloud instance. You can also include the contactID, which identifies the user’s contact record in Oracle Service Cloud. For both of these fields, you must define an id property as follows:
  setCustomFields:
    component: "System.SetVariable"
    properties:
      variable: "myCustomProps"
      value:
        customerInformation:
          interfaceID:
            id:
              id: "${interfaceId}”
          contactID:
            id: "${customerId}"
Define these required fields along with optional ones using the Chat Customer Information that’s specified by the WSDL for your instance (https://<hostname><domain>/services/soap/connect/chat_soap?wsdl=server).
<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"/>

You can reference an example of this WSDL at https://solo-financial-1.rightnowdemo.com/services/soap/connect/chat_soap?wsdl=server.

While you can define the EMailAddress, FirstName, and LastName fields that are described in the WSDL’s Chat Customer Information section, your skill can instead obtain these values using the .profile properties (described in User Context). For example:
setUserEmail:
    component: "System.SetVariable"
    properties:
      value: "joe.smith@example.com"
      variable: "profile.email"
    transitions: {}
As mentioned previously, both of these fields require id properties. The WSDL describes these as well. For interfaceID, the WSDL defines this as one of the NamedID properties:
<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>
You can optionally define a name property.
For contactID, the WSDL specifies ID as the only property:
<xs:element name="ID" type="ID"/>
			<xs:complexType name="ID">
				<xs:attribute name="id" type="xs:long" use="optional"/>

Note:

The casing differs between the WSDL and the dialog flow definition. In the dialog flow definition, the first letter for these fields is in lowercase (Pascal case). For example, ProductID in the WSDL would be productID in the dialog flow definition. The individual field properties are all in lower case in the dialog flow definition (Name becomes name in the dialog flow definition, for example).
The customFields Property
The name property enables your skill to route to a specific queue in Oracle Service Cloud because its name property identifies a custom field that's used by a Incident-based chat rule that has been defined in Oracle Service Cloud. Specifically, this property identifies the field's Column Name attribute, which is the name of the custom field as it appears in the database. Following Oracle Service Cloud convention, you prefix this name with c$. Ask your Oracle Service Cloud administrator to provide you with the Column Name and the required value for each custom field that you need. If you have access to Oracle Service Cloud, you can find out about the custom fields, their values, and column names by viewing the chat rule that defines the queue routing.
In the following example, c$vipStatus corresponds to the VipStatus Column Name. In this case, when the chat gets passed to the specified Oracle Service Cloud interface, the live agent sees BRONZE as the queue in the Incoming Chat dialog. (User information, such an a customer email address, that you configured using the .profile properties would also display in this dialog.)

        customFields: 
          - name: "c$vipStatus" 
            dataType: "STRING"
            dataValue:
              stringValue: "BRONZE"
You can add a series of name entries to the customFields property. For each of them, you define the dataType and dataValue properties that are described by the WSDL’s GenericField definition. Like the customerInformation fields, the same casing applies to the dialog definition counterparts (the WSDL’s DataValue is dataValue in the dialog flow, for example).
<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"/>
This example illustrates the stringValue as a hard-coded value, but as illustrated by the custom column called c$intent in the following snippet, you can also access the value with a value expression that’s formatted as ${variableName}:
customFields:
          - name: "c$intent"
            dataType: "STRING"
            dataValue:
              stringValue: "${intentName}"
Obtain Values from the Oracle Service Cloud REST API

While you can find out the values that you need to define the values for the customerId, interfaceId, and columnName from the Oracle Service Cloud administrator, you can also obtain them from the endpoints of the Oracle Service Cloud REST API Each endpoint represents a table in the Oracle Service Cloud database.

Use siteInterfaces endpoint to return the values for the interfaceId:
mysite.example.com/services/rest/connect/v1.3/siteInterfaces
Use the contacts endpoint for the customerID:
mysite.example.com/services/rest/connect/v1.3/contacts
These endpoints return collections for all of the site's interfaces and customers, respectively. The response body for both of these endpoints has an items array. Each customer or interface object within this array has lookupName and id (an integer) strings. Use the id value to set the value for the interfaceId and customerId variables.
To find the columnName and its corresponding value, first run a RightNow Object Query Language (ROQL) query against the queryResults endpoint for a particular object type, such as Incidents or Contacts, and include the CustomFields.c dot notation in the SELECT clause. The following example illustrates a query that returns two custom fields, Intent and VipStatus, from the Incidents table. In the dot notation, these fields are specified in lower case (CustomFields.c.intent and CustomFields.c.vipstatus).
mysite.example.com/services/rest/connect/v1.3/queryResults/?query=select CustomFields.c.* from Incidents where (CustomFields.c.intent IS NOT NULL AND CustomFields.c.vipstatus IS NOT NULL)
In the returned document, the items array includes two nested arrays, ColumnNames and rows, that you cross-reference to define the name value for the customFields property and the corresponding stringValue value (if you're hard coding the value). For example, in the JSON returned by the above query, the column number for vipstatus is 23 in the ColumnNames array. This means its corresponding value, BRONZE, is the 23rd row within each of the items in the rows array.
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.
startContactAgent:
    component: "System.AgentInitiation"
    properties:
      subject: "A customer needs help regarding ${agentIncidentIntentName.value}"
      agentChannel: "svc"
      waitingMessage: "Chat accepted, waiting for agent to join"
      rejectedMessage: "Sorry we are not available now."
      customProperties: "${myCustomProps.value}"
    transitions:
      actions:
        accepted: "agentConversation"
        rejected: "rejected"