Zendesk: Handover Webchat Conversations to Agent Workspace

zendesk-chat-handover-agent-workspace-webchat-header.png

Modified from https://web-assets.zendesk.com/images/p-self-guided-tour/intro.png 

When it comes to Zendesk handover scenarios in Cognigy.AI, one has two different options. On the one hand, the Sunshine Conversations Endpoint could be used. On the other hand, the entire handover and live chat conversation can be handled through the Cognigy Webchat. This tutorial explains how to add the Zendesk Agent Workspace as a live chat tool to a Cognigy.AI conversation -- using the Webchat.


Table of Contents

  1. Overview
  2. Technical Components
  3. Download the Zendesk Web SDK
  4. Trigger the Handover event
  5. How to embed the required Webchat
    1. Forward user messages to Zendesk Agent Workspace
    2. Display Zendesk Agent messages in the Webchat
    3. Try to start the live chat session
    4. Notify Cognigy.AI about the available live agent
    5. Listen to agent messages and display them inside of the Webchat window
      1. If a new agent joined the chat session
      2. If the agent left or ended the chat session
  6. The final source code

Overview

Before implementing everything in Cognigy.AI and an example Webchat, the architecture of this integration needs to be explained. Please have a look at the figure below:

zendeskAgentWorkspaceWebchatHandoverArchitecture__1_.png

Generally speaking, the Cognigy.AI Virtual Agent is handling the entire conversation between the user and itself through the Webchat Endpoint. As soon as this user wants to talk with a human agent, the handover process will be executed. This means, that the Flow sends a so-called DATA_ONLY message (Say Node) to the Webchat in order to inform the client-side about the requested handover. Last but not least, the whole live chat conversation is controlled and established through the Cognigy Webchat.

Technical Components

The reason for this client-side implementation is the Zendesk Chat Web SDK which provides multiple, easy-to-use functions for the expected behavior. However,  in order to use the Cognigy Webchat as a logical live chat handler, the standard Webchat Embedding must be extended to include the Webchat Analytics API. This Application Programming Interface (API) checks all incoming and outgoing messages for specific, pre-configured, data. On the one hand, it forwards messages to the Zendesk Agent Workspace and, on the other hand, it displays the agents' answers in the Webchat window.

Therefore, one needs to use

  1. A Cognigy.AI Flow,
  2. the Cognigy Webchat Endpoint
  3. and the Zendesk Chat Web SDK

for this handover scenario.

Download the Zendesk Web SDK

Before implementing the live chat logic, the Zendesk Web SDK must be added to the directory of the target website:

  1. Navigate to https://api.zopim.com/web-sdk/#downloads and download the latest SDK version
  2. Navigate to your website's root folder and add the web-sdk.js file
  3. Add the following <script> block to the website's index.html file:
<script src="web-sdk.js"></script>

Trigger the Handover event

In order to start the integration from a logical point of view, the Cognigy.AI Flow has to hand over the control to the Webchat (Analytics Service):

  1. As soon as the user wants to talk to an agent, the Webchat needs to be informed and "configured", such as displayed in this example:

    configure-webchat-for-handover-to-zendesk.PNG

  2. The Configure Webchat Say Node only contains data while it acts as a so-called DATA_ONLY message:
    configure-webchat-say-edit-menu.PNG

    Data:
    {
        "handover": "start",
        "accountKey": "...",
        "displayName": "Laura Wilson",
        "transcript": "{{context.transcript}}"
    }
  3. From now on, the Webchat is ready to handle all upcoming messages.

How to embed the required Webchat

Info

Please read the comments included in the code blocks below for more information. A comment starts with // or <!--

On the Webchat side, the minimal required JavaScript code for embedding the Webchat to a website is the following:

<!-- 1. Load the webchat.js bundle via a script tag -->
<script src="webchat.js"></script>

<!-- Initialize the Webchat towards a Cogngiy Endpoint via initWebchat() -->

<script>
initWebchat("https://endpoint-trial.cognigy.ai/");
</script>

Now, the mentioned Analytics API needs to be added, while it consists of two different parts -- in this case:

  1. Forward user messages to Zendesk Agent Workspace
  2. Display Zendesk Agent messages in the Webchat

Forward user messages to Zendesk Agent Workspace

For this functionality, only the second <script> block of the code above needs to be extended. First, the available webchat object has to be extracted from the initWebchat() callback:

initWebchat("https://endpoint-trial.cognigy.ai/").then(webchat => {

// TODO: Use the Webchat API
}

Then, the Analytics service can be registered in order to process incoming and outgoing chat messages:

initWebchat("https://endpoint-trial.cognigy.ai/").then(webchat => {

// Register the Analyics Service
webchat.registerAnalyticsService(event => {

// Check the event types
if (event.type === "webchat/outgoing-message") { }

if (event.type === "webchat/incoming-message") { }
}
}

Now, all outgoing messages (the user sends a message in the Webchat window) can be processed:

initWebchat("https://endpoint-trial.cognigy.ai/").then(webchat => {

// Register the Analyics Service
webchat.registerAnalyticsService(event => {

// Whether to forward all messages to Zendesk Chat or not
let forwardToZendeskChat = false;

// Check if the current event is a user message
if (event.type === "webchat/outgoing-message") {

// Every event consists of the message text and data stored in the payload object
const { payload } = event;
const { text, data } = payload;

// Check if all Webchat user messages should be forwarded to Zendesk Chat
if (forwardToZendeskChat) {

// Check if the current event contains a text message
if (text) {

// Use the SDK to send a chat message to the Zendesk agent
// including the user's text
zChat.sendChatMsg(text, function (err) { });
} else {

// If there is no text in the current event,
// send the word "Handover" to the agent
zChat.sendChatMsg("Handover", function (err) { });
}
}
}
}
}

If the current event, e.g. a user message, contains a text, this text will be forwarded to the Zendesk Agent Workspace.

Important

All upcoming text messages will be forwarded to Zendesk directly and not processed by Cognigy.AI anymore. This client-side "Is Handover" state is controlled by the boolean variable called forwardToZendeskChat that is used in the code above as well.

Display Zendesk Agent messages in the Webchat

Instead of processing all outgoing user messages, all incoming events need to be checked -- in order to display agent messages. However, the first step is to start the live chat session while the previously sent DATA_ONLY message must be extracted for further use:

initWebchat("https://endpoint-trial.cognigy.ai/").then(webchat => {

// Register the Analyics Service
webchat.registerAnalyticsService(event => {

// Check all "bot" messages that are incoming from Cognigy.AI
if (event.type === "webchat/incoming-message") {

// Extract the text and data again from the payload object
const { payload } = event;
const { text, data } = payload;

// In this case, the DATA_ONLY message needs to be extracted from the data object as well
const { handover, displayName, transcript, accountKey } = data;
}
}
}

The following code block is separated into two main parts again:

  1. Try to start the live chat session
  2. Listen to agent messages and display them inside of the Webchat window

Try to start the live chat session

initWebchat("https://endpoint-trial.cognigy.ai/").then(webchat => {

// Register the Analyics Service
webchat.registerAnalyticsService(event => {

// Check all "bot" messages that are incoming from Cognigy.AI
if (event.type === "webchat/incoming-message") {

// Extract the text and data again from the payload object
const { payload } = event;
const { text, data } = payload;

// In this case, the DATA_ONLY message needs to be extracted from the data object as well
const { handover, displayName, transcript, accountKey } = data;

// If the user wants to hand over the conversation to an agent
// and the required accountKey is provided
if (data.handover == "start" && data.accountKey) {

// Then initialize the Zendesk Chat
// Source: https://api.zopim.com/web-sdk/#introduction
zChat.init({ account_key: accountKey, suppress_console_error: false });

// Set Visitor information of current Cognigy Webchat user
zChat.setVisitorInfo({ display_name: displayName }, function (err) { console.log(err); });

// Check Live Agent Availability
// 'online', 'offline', 'away'
const accountStatus = zChat.getAccountStatus();

// If there is no online live agent, inform Cognigy.AI and pass over the control again
if (["offline", "away"].includes(accountStatus)) {
webchat.sendMessage("", {
liveAgentAvailable: false
});
} else {

// TODO: Display agent messages of the successfully started live chat session
}
}
}

As soon as the Webchat received a message from Cognigy.AI, it checks if it contains the required data information:

  1. Whether to handover
    1. "handover": "start"
  2. The display name for the current user in the live chat session
    1. "displayName": "Laura Wilson"
  3. The transcript of the virtual agent conversation
    1. "transcript": "..."
  4. The Zendesk account key for authentication
    1. "accountKey": "..."

Therefore, the logic can check as well if the user wants to hand over the conversation and, afterward, try to establish the connection by looking for available agents. If there is no live agent available at the moment, the Cognigy.AI Flow will be informed in order to pass over the control to the virtual agent again.

Notify Cognigy.AI about the available live agent

Without thinking about upcoming code in the next section, two missing things can be added already to the, yet empty, else {} code block:

if (transcript) {
// Send the Transcript of the previous bot conversation to the Zendesk agent
zChat.sendChatMsg(transcript, function (err) { });
}

// If the live agent is online, inform Cognigy.AI
webchat.sendMessage("", {
liveAgentAvailable: true,
queuePosition: queuePosition
});

The first one checks if Cognigy.AI sent a transcript of the previous chat conversation between the user and the virtual agent and the second one informs Cognigy.AI about the live agent availability and current queue position of the user (more about this in the next section).

Listen to agent messages and display them inside of the Webchat window

However, if there is a live agent online, the Webchat needs to listen to upcoming Zendesk events. Inside of the else {} block, the following code should be added:

// Get the current queue position of the user
const queuePosition = zChat.getQueuePosition();

// Define that all upcoming user messages should be sent to Zendesk
forwardToZendeskChat = true;

zChat.on("chat", function (zendeskChatEvent) {

// Extract the message and type from Zendesk event response
const { msg, type } = zendeskChatEvent;

// Agent sent a text message
if (type === "chat.msg") {

// Display the agent message in the Webchat window
webchat.store.dispatch( { type: "ADD_MESSAGE", message: { source: "agent", text: msg } } );
}

// Agent joined the chat session
if (type === "chat.memberjoin") {

// If the new memeber if of type 'agent'
if (zendeskChatEvent.nick?.includes("agent")) {

// Send the agent information to Cognigy.AI
webchat.sendMessage("", {
liveAgent: {
displayName: zendeskChatEvent.display_name
}
});
}
}

// Agent left/ended the chat session
if (type === "chat.memberleave") {
if (zendeskChatEvent.nick?.includes("agent")) {

// Notify Cognigy.AI that the live chat session ended
webchat.sendMessage("", {
handover: false
});
}
}
});

First, the current queue position of the user could be requested for further use. More important is the second statement where the forwardToZendeskChat variable is set to true -- it is used by Forward user messages to Zendesk Agent Workspace section. After this configuration, another event listener is started, namely the Zendesk Chat Messages Event Listener. It checks and processes the following three events:

  1. Incoming agent messages
  2. If a new agent joined the chat session
  3. If the agent left or ended the chat session

While the first handler simply displays the agent message in the Webchat window, handlers 2 and three send DATA_ONLY messages to the Cognigy.AI Flow.

If a new agent joined the chat session

In this case, the agent's display name is sent in the following format:

{
"liveAgent": {
"displayName": "Peter Parker"
}
}

Inside of Cognigy.AI, one can use CognigyScript in order to extract the name in a Say Node -- for example:

{{input.data.liveAgent.displayName}}

and inside of a Say Node text:

"You are now talking to {{input.data.liveAgent.displayName}}"

which results in

"You are now talking to Peter Parker"

If the agent left or ended the chat session

In the case of leaving or ending the chat, the Webchat sends a "handover is false" message to the Cognigy.AI Flow:

{
"handover": false
}

Inside of Cognigy.AI, one could now use an If Node, for example, and handle this escalation

zendesk-agent-chat-ended-if-node.PNG

while the If Node consists of the following statement:

If

input.data.handover === false

Then

....

The final source code

initWebchat("https://endpoint-trial.cognigy.ai/").then(webchat => {

  // Whether to forward all messages to Zendesk Chat or not
  let forwardToZendeskChat = false;

  webchat.registerAnalyticsService(event => {

    if (event.type === "webchat/outgoing-message") {
      const { payload } = event;
      const { text, data } = payload;

      // Forward all Webchat user messages to Zendesk Chat
      if (forwardToZendeskChat) {
        if (text) {
          zChat.sendChatMsg(text, function (err) { });
        } else {
          zChat.sendChatMsg("Handover", function (err) { });
        }
      }
    }

    if (event.type === "webchat/incoming-message") {
      const { payload } = event;
      const { text, data } = payload;
      const { handover, displayName, transcript, accountKey } = data;

      if (data.handover == "start" && data.accountKey) {

        // Initialize the Zendesk Chat
        // Source: https://api.zopim.com/web-sdk/#introduction
        zChat.init({
          account_key: accountKey,
          suppress_console_error: false
        });

        // Set Visitor information of current Cognigy Webchat user
        zChat.setVisitorInfo({
          display_name: displayName
        }, function (err) {
          console.log(err);
        });

        // Check Live Agent Availability
        // 'online', 'offline', 'away'
        const accountStatus = zChat.getAccountStatus();

        if (["offline", "away"].includes(accountStatus)) {
          webchat.sendMessage("", {
            liveAgentAvailable: false
          });
        } else {
                            
// Get the current queue position of the user const queuePosition = zChat.getQueuePosition(); forwardToZendeskChat = true; zChat.on("chat", function (zendeskChatEvent) { const { msg, type } = zendeskChatEvent; if (type === "chat.msg") { webchat.store.dispatch( { type: "ADD_MESSAGE", message: { source: "agent", text: msg } } ) } // Agent joined the chat session if (type === "chat.memberjoin") { if (zendeskChatEvent.nick?.includes("agent")) { webchat.sendMessage("", { liveAgent: { displayName: zendeskChatEvent.display_name } }); } } // Agent left/ended the chat session if (type === "chat.memberleave") { if (zendeskChatEvent.nick?.includes("agent")) { webchat.sendMessage("", { handover: false }); } } }); if (transcript) { // Send the Transcript of the previous bot conversation to the Zendesk agent zChat.sendChatMsg(transcript, function (err) { }); } webchat.sendMessage("", { liveAgentAvailable: true, queuePosition: queuePosition, }); } } } }); });

 

 

 

 


Comments

0 comments

Article is closed for comments.

Was this article helpful?
0 out of 0 found this helpful