Bots as Chat Agents, with Escalation to Live Agents


Bots offer organizations a means of scaling customer service and customer engagement through natural and intuitive conversational experiences, as we’ve seen in some of our earlier posts. But bots will not always be able to meet all of our customers’ needs during an interaction. Being able to seamlessly transition a customer from a conversation with a bot to an actual live agent can be a key capability in realizing scale while also ensuring high-quality customer engagements.

In this post, we will see how we can implement seamless escalations from bots to live agents leveraging the capabilities of Live Assist from Microsoft partner CafeX.

This one-minute video (no sound) shows our intended functionality in action:

 

Escalation Options with Live Assist

With the latest release of Live Assist for Dynamics 365, we have two options available to us in implementing Bot to Agent escalations:

  1. Create a bot and enable it as an agent in Live Assist, with the ability to transfer/escalate to other agents; this is enabled through the Live Assist Bot Agent Connector, and will enable end users to engage with your bot via the Live Assist end-user interface, just as if engaging via Live Assist chat with a Live Agent
  2. Create a bot and enable it on the Bot Framework channels of your choice, adding the ability for chats to be escalated to Live Assist agents via the Live Assist Escalation SDK; this option will enable end users to engage with your bot on the Bot Framework channels of your choice, though not through the Live Assist end-user chat experience

In this post, we will implement the first option: a bot that is enabled as a Live Assist agent, with the ability to transfer or escalate to other “real” agents in Live Assist.

We will create a bot that can:

  • be accessed via the standard Live Assist end-user chat interface
  • provide answers to customer questions via the Cognitive Services QnA Maker API
  • detect the sentiment of all customer input via the Cognitive Services Text Analytics API
  • initiate a transfer to other agents or skills when negative sentiment is detected

Note that we will be building our bot using the Bot Builder SDK for .NET. If you are working with Node.js, CafeX offers sample code for enabling a Bot Agent that can provide answers via QnA Maker here.

 

Prerequisites

The prerequisites for building and deploying our escalation bot include:

 

Setting Up our QnA Maker Service

Microsoft's Cognitive Services QnA Maker provides an easy-to-use tool for the ingestion of "Frequently Asked Questions" (questions and answers), making them available via a service that can be readily consumed within the Bot Framework. Bots can provide answers to end-user questions through the use of a Bot Framework dialog that we will leverage later in our post.

The QnA Maker documentation provides a brief video walkthrough of how to access the QnA Maker service on https://qnamaker.ai, and to create and publish a question and answer service. Rather than recreate the documentation, follow along with the steps seen in the video here.

While following along with the quick-start video, we obtain our credentials for accessing the knowledge base service we have created, including our:

  • QnA Maker Subscription Key
  • The Knowledge Base ID

 

Save these credentials for use later in our setup process.

Optional: If you wish to populate your QnA Maker service with the articles from your Dynamics 365 knowledgebase, you can export your articles from Dynamics 365 to Excel, then format the articles in the tab-separated Question, Answer and Source format outlined in the QnA Maker documentation, for upload into your QnA Maker knowledge base.

 

Obtaining our Text Analytics Endpoint and Key

To enable our bot to escalate to an agent when the end user expresses negative sentiment, we will leverage the Cognitive Services Text Analytics API, which is able to be provisioned from the Azure Portal with an Azure subscription.

This deep link will take you to the Text Analytics API resource creation blade in the Azure Portal. Complete the required details, providing your desired resource name, subscription, location, pricing tier, and resource group (either a new or existing one). Accept the terms, and click the Create button:

 

 

You can then view details of the Text Analytics API resource that you have created, to obtain your endpoint based on the region you selected, and copy one of the two keys that were created for you:

 

 

Save the endpoint and key for later use.

Important Note: When we insert the endpoint into our app configurations later on in the post, we will append '/sentiment' to the endpoint copied from the Azure portal. More details found below.

 

Building our Bot

We will now start putting together the code for our bot, using steps found in the Create a bot with the Bot Builder SDK for .NET quickstart.

We Open Visual Studio, and create a new project using the Bot Application template that we downloaded as a part of our prerequisites:

 

 

In our Project Properties, on the Application tab, we specify .NET Framework 4.6.1 as the target framework.

 

Installing Packages and Adding References

We need install several packages that we will leverage as a part of our bot code, and ensure our project is referencing the latest version of the Bot Builder SDK. We can do this via NuGet:

 

Adding a Data Contract for the Text Analytics API

To facilitate interacting with the Cognitive Services Text Analytics API, we add a new item to our project: a Visual C# class which we will name TextAnalytics.JSON.cs. We will populate this file with the JSON data contracts for the REST Services outlined in the Text Analytics API documentation.

using System.Runtime.Serialization;

namespace TextAnalytics.JSON
{
    [DataContract]
    public class Response
    {
        [DataMember(Name = "documents")]
        public Document[] Documents { get; set; }

        [DataMember(Name = "errors")]
        public Error[] Errors { get; set; }
    }
    [DataContract]
    public class Document
    {
        [DataMember(Name = "score")]
        public double Score { get; set; }

        [DataMember(Name = "id")]
        public string ID { get; set; }

    }

    [DataContract]
    public class Error
    {
        [DataMember(Name = "id")]
        public string ID { get; set; }

        [DataMember(Name = "message")]
        public string Message { get; set; }
    }

}

 

Adding our QnA Maker Dialog

To our project, we will add a Bot Framework dialog to manage the interaction with our QnA Maker knowledge base. We right-click on our Dialogs folder in our project, and choose to Add New Item. We will add a C# Class that we name QnAMakerDialog.cs.

We will add code to our class using the Basic QnA Maker template found in the Bot Framework documentation here. The dialog will inherit from the QnAMakerDialog object, and calls the QnA Maker service with the following parameters:

  • Subscription Key: this key was obtained earlier, when setting up our QnA Maker service; we will populate this from application configuration parameters in a subsequent step
  • Knowledge Base ID: this ID was also obtained while setting up our service; we will populate this from application configuration parameters in a subsequent step
  • Default Message: this optional parameter allows us to specify the message to return to the user when no answer has been found with a sufficient match
  • Score Threshold: this optional value between 0 and 1 allows us to specify the threshold of the match that must be found from our knowledgebase in order to return an answer to the user

 

We add the following code to our new class, to allow the calling of the QnA Maker Service we created:

using System;
using Microsoft.Bot.Builder.CognitiveServices.QnAMaker;
using System.Web.Configuration;

namespace QnAEscalationBot.Dialogs
{
    // For more information about this template visit http://aka.ms/azurebots-csharp-qnamaker
    [Serializable]
    public class BasicQnAMakerDialog : QnAMakerDialog
    {
        // Go to https://qnamaker.ai and feed data, train & publish your QnA Knowledgebase.
        //Parameters to QnAMakerService are:
        //Required: subscriptionKey, knowledgebaseId, 
        //Optional: defaultMessage, scoreThreshold[Range 0.0 – 1.0]
        public BasicQnAMakerDialog() : base(new QnAMakerService(new QnAMakerAttribute(
            WebConfigurationManager.AppSettings["QnASubscriptionKey"],
            WebConfigurationManager.AppSettings["QnAKnowledgebaseId"],
            "Sorry, I'm having trouble finding an answer to that.", 0.3)))
        {
        }

    }

}

 

Adding our Escalation Dialog

We will also add a simple dialog that will handle escalation scenarios, by confirming that the user wishes to be transferred to an agent, and executing the transfer.

We right-click on our Dialogs folder in our project, and choose to Add New Item. We will add a C# Class that we name Escalation.cs.

Our Escalation dialog will initiate with the StartAsync method by requesting confirmation from the user on whether they would like to be transferred to a live agent. The response that the user provides is managed by the AfterEscalationConfirmation method. If the user wishes to be transferred (which we test by looking for a response that begins with a ‘y’), a transfer message is constructed and sent, using the transfer message format as outlined in the Live Assist Bot Agent Connector documentation. The key information about the transfer is included in the ChannelData property of the message, including the skill or agent that the chat should be transferred to. In our code, we are transferring the chat to a Skill that will be configured in Live Assist called BotEscalation. We could also adapt the code to transfer to an agent, by replacing our skill attribute with 'agent':'AgentNickname' in our JObject. Our Escalation.cs code is shown below:

using System;
using System.Threading.Tasks;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Builder.Dialogs;
using Newtonsoft.Json.Linq;

namespace QnAEscalationBot.Dialogs
{
    [Serializable]
    public class Escalation : IDialog<object>
    {
        public async Task StartAsync(IDialogContext context)
        {
            // ask user to confirm escalation to live agent:
            string message = "I'm sorry, would you like to speak with a live agent?";
            await context.PostAsync(message);
            context.Wait<IMessageActivity>(AfterEscalationConfirmation);
        }

        // escalate, if appropriate:
        public async Task AfterEscalationConfirmation(IDialogContext context, IAwaitable<IMessageActivity> argument)
        {
            var option = await argument;
            if (option.Text.ToLower().StartsWith("y"))
            {
                // Confirm the transfer:
                await context.PostAsync("I'm transferring you to an agent now...");

                // Transfer to the BotEscalation skill
                IMessageActivity transferMsg = context.MakeMessage();
                JObject transferChannelData = JObject.Parse(@"{'type':'transfer','skill':'BotEscalation'}");
                transferMsg.ChannelData = transferChannelData;
                transferMsg.Text = "";
                transferMsg.Type = ActivityTypes.Message;
                await context.PostAsync(transferMsg);
            }
            else
            {
                // if user does not want to escalate, close the dialog.
                await context.PostAsync("How else can I help you?");
                context.Done<bool>(true);
            }

        }
    }
}

 

Adapting our Root Dialog

We will now adapt our RootDialog.cs class to examine incoming messages, and respond appropriately depending on the type of Live Assist message it is, and the sentiment expressed if it is a message from the user.

Our Root Dialog will:

  • Respond with a greeting on initial connection to the user
  • Check the sentiment of all user messages
  • Route messages with a sentiment score of less than a nominal value of 0.2 to our escalation dialog
  • Route messages that don’t have negative sentiment to the QnA Maker dialog

Our Root Dialog class also includes methods to call the Text Analytics API to determine the sentiment of user messages, as used in previous posts leveraging the API via .NET.

using System;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using System.Net.Http.Headers;
using System.Text;
using System.Runtime.Serialization.Json;
using Newtonsoft.Json.Linq;
using System.Web.Configuration;
using System.Net.Http;
using System.Threading;

namespace QnAEscalationBot.Dialogs
{
    [Serializable]
    public class RootDialog : IDialog<object>
    {

        public Task StartAsync(IDialogContext context)
        {
            context.Wait(MessageReceivedAsync);
            return Task.CompletedTask;
        }

        private async Task MessageReceivedAsync(
            IDialogContext context, IAwaitable<object> result)
        {
            var activity = await result as Activity;
            JObject channelData = (JObject)activity.ChannelData;
            string messageType = (string)channelData["type"];

            // Initial message on connection to the end user:
            if (messageType == "visitorContextData")
            {
                ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

                // Greet the user
                Activity greet = activity.CreateReply("Hi there, how can I help you?");
                connector.Conversations.ReplyToActivity(greet);
            }
            else if (messageType == "transferFailed")
            {
                ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

                // Inform user we will transfer them to an agent:
                Activity notifyFail = activity.CreateReply("I'm sorry, it appears the transfer failed.");
                await connector.Conversations.ReplyToActivityAsync(notifyFail);
            }
            else if (messageType == "otherAgentMessage")
            {
                // handle messages from other agents here, if desired
            }
            // message that is coming from the end user
            else if (messageType == "visitorMessage")
            {
                // Check to see if we need to transfer the chat to an agent, based on sentiment:
                if (GetSentiment(activity.Text, WebConfigurationManager.AppSettings["cogTextAnalyticsSubscriptionKey"], WebConfigurationManager.AppSettings["cogTextAnalyticsEndpoint"]) < 0.2)
                {
                    // Add an escalation dialog to the dialog stack:
                    Escalation escalationDialog = new Escalation();
                    context.Call(escalationDialog, AfterChildDialog);
                }
                else
                {
                    // Chats from Live Assist Bot Agent will be handled by QnA maker:
                    BasicQnAMakerDialog qnaDialog = new BasicQnAMakerDialog();
                    // we use context.Forward to send the user's message through to the QnA Maker dialog:
                    await context.Forward(qnaDialog, AfterChildDialog, activity, CancellationToken.None);
                }
            }

        }
        private async Task AfterChildDialog(IDialogContext context, IAwaitable<object> result)
        {
            context.Wait(MessageReceivedAsync);
        }

        public static double GetSentiment(string docSentiment, string subscriptionKey, string endpoint)
        {
            var client = new HttpClient();

            // Request headers
            client.DefaultRequestHeaders
                    .Accept
                    .Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);

            // Request parameters
            var uri = endpoint;

            HttpResponseMessage response;

            // Create a basic JSON request body, with a single text 'document'
            //  Note that the Action could be adapted to accept multiple input strings, and detect sentiment
            //  across all documents.
            string jsonEncodedDoc = cleanStringForJson(docSentiment);
            byte[] byteData = Encoding.UTF8.GetBytes("{\"documents\": [{\"id\": \"1\",\"text\": \"" + jsonEncodedDoc + "\"}]}");

            using (var content = new ByteArrayContent(byteData))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                response = client.PostAsync(uri, content).Result;

                using (var stream = response.Content.ReadAsStreamAsync().Result)
                {
                    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(TextAnalytics.JSON.Response));
                    TextAnalytics.JSON.Response jsonResponse = ser.ReadObject(stream) as TextAnalytics.JSON.Response;
                    // Check for errors in the response:
                    if (jsonResponse.Errors != null && jsonResponse.Errors.Length > 0)
                    {
                        return -1;
                    }
                    // Ensure we have some results:
                    else if (jsonResponse.Documents != null && jsonResponse.Documents.Length > 0 && jsonResponse.Documents[0].Score >= 0)
                    {
                        // return the results:
                        return jsonResponse.Documents[0].Score;
                    }
                    else
                    {
                        return -1;
                    }
                }
            }
        }

        public static string cleanStringForJson(string stringToClean)
        {
            // To-do: consider adapting the string cleaning methodology:
            var cleanerstring = new StringBuilder(stringToClean.Length);
            foreach (char chr in stringToClean)
            {
                if (chr == '\\')
                {
                    cleanerstring.Append('\\' + '\\');
                }
                else if (chr == '/')
                {
                    cleanerstring.Append('\\' + '/');
                }
                else if (chr == '"')
                {
                    cleanerstring.Append('\\' + '"');
                }
                else
                {
                    cleanerstring.Append(chr);
                }
            }

            return cleanerstring.ToString();
        }

    }
}

 

Adapting our Message Controller

We also make minor updates to our MessageController.cs class, which controls the flow of incoming user messages. We check to see if our incoming message is on the Direct Line channel (which Live Assist agent bots use), and if so, we direct it to our Root Dialog. Otherwise, we direct it straight to the QnA Maker dialog, so that other channels can still benefit from the QnA Maker knowledge base:

using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using QnAEscalationBot.Dialogs;

namespace QnAEscalationBot
{
    [BotAuthentication]
    public class MessagesController : ApiController
    {
        /// <summary>
        /// POST: api/Messages
        /// Receive a message from a user and reply to it
        /// </summary>
        public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
        {
            if (activity.Type == ActivityTypes.Message)
            {
                // Check if message is coming from DirectLine
                // If so, we assume this is a Live Assist Agent Bot:
                if (activity.ChannelId == "directline")
                {
                    await Conversation.SendAsync(activity, () => new RootDialog());
                }
                else
                {
                    // This is not a Live Assist Message; go straight to QnA Maker Dialog:
                    await Conversation.SendAsync(activity, () => new BasicQnAMakerDialog());
                }
            }
            else
            {
                HandleSystemMessage(activity);
            }
            var response = Request.CreateResponse(HttpStatusCode.OK);
            return response;
        }

        private Activity HandleSystemMessage(Activity message)
        {
            if (message.Type == ActivityTypes.DeleteUserData)
            {
                // Implement user deletion here
                // If we handle user deletion, return a real message
            }
            else if (message.Type == ActivityTypes.ConversationUpdate)
            {
                // Handle conversation state changes, like members being added and removed
                // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
                // Not available in all channels
            }
            else if (message.Type == ActivityTypes.ContactRelationUpdate)
            {
                // Handle add/remove from contact lists
                // Activity.From + Activity.Action represent what happened
            }
            else if (message.Type == ActivityTypes.Typing)
            {
                // Handle knowing tha the user is typing
            }
            else if (message.Type == ActivityTypes.Ping)
            {
            }

            return null;
        }
    }
}

 

Later on we will also update our Web.config file with necessary configurations and credentials, but first we need to obtain our Bot Framework credentials, by registering our bot.

 

Registering our Bot with the Bot Framework

We will now register our bot with the Bot Framework, basing our process on the documentation found here. First, we access the Bot Framework Portal, on https://dev.botframework.com, and authenticate with either a Microsoft account, or our Office 365 credentials.

Once authenticated, we click on My Bots, then Create a Bot, and then hit the Create button. Choose the Register an existing bot built using Bot Builder SDK option:

 

 

We can now provide Bot Profile details for our bot. Taken from the documentation, we can supply information including:

  1. an icon that will represent your bot in the conversation
  2. your bot's Display Name; When users search for this bot, this is the name that will appear in the search results
  3. your bot's Handle; This value will be used in the URL for your bot and cannot be changed after registration
  4. a Description of your bot; This is the description that will appear in search results, so it should accurately describe what the bot does

 

 

We now scroll down to the Configuration section. We can bypass the Messaging endpoint for the time being. Click on the Create Microsoft App ID and Password button. A new browser tab should open, enabling us to retrieve an App ID, and to click the Generate an app password to continue button:

 

We save the App ID and Password for use later in our process, and then click the Finish and go back to the bot framework button. Our App ID should now be populated in our bot configurations.

We can bypass the Analytics section for the time being, click to agree to the Bot Framework Terms and Conditions, and click the Register button:

 

 

Later in the process, we will return and update our registered bot with the Messaging endpoint.

 

Updating our Web.config Configurations

We will now update our project's Web.config file with various authentication and configuration values that we have collected.

We add the following appSettings settings:

  • BotId: our bot’s handle as created during Bot Registration
  • MicrosoftAppId: our bot’s App ID as obtained during Bot Registration
  • MicrosoftAppPassword: our bot’s App Password, as obtained during Bot Registration
  • cogTextAnalyticsSubscriptionKey: our Text Analytics API key, as obtained during the provisioning of our resource in the Azure Portal
  • cogTextAnalyticsEndpoint: the endpoint for the Text Analytics API, based on the region we selected during resource provisioning in the Azure Portal. Important Note: When we insert the endpoint value into our app configurations, we will append '/sentiment' to the endpoint copied from the Azure portal. For example, if you selected the West US region when provisioning your Text Analytics resource, the full value to insert in this appSetting would be https://westus.api.cognitive.microsoft.com/text/analytics/v2.0/sentiment
  • QnASubscriptionKey: the QnA Maker subscription key that we obtained while Setting Up our QnA Maker Service
  • QnAKnowledgebaseId: the QnA Maker knowledge base ID that we obtained while Setting Up our QnA Maker Service

...
  <appSettings>
    <!-- update these with your own credentials -->
    <add key="BotId" value="Enter your Bot ID here" />
    <add key="MicrosoftAppId" value="Enter your Bot App ID here" />
    <add key="MicrosoftAppPassword" value="Enter your Bot App Password here" />
    <add key="cogTextAnalyticsSubscriptionKey" value="Enter your Text Analytics Key here" />
    <add key="cogTextAnalyticsEndpoint" value="https://Enter your region prefix here.api.cognitive.microsoft.com/text/analytics/v2.0/sentiment" />
    <add key="QnASubscriptionKey" value="enter your QnA Maker Subscription Key here" />
    <add key="QnAKnowledgebaseId" value="Enter your QnA Maker Knowledge base ID here" />
  </appSettings>
...

 

Deploying our Bot to Azure from Visual Studio

We will now deploy our bot to a Microsoft Azure App Service, based on the documentation steps outlined here. We right-click on our project in the Visual Studio Solution Explorer, and select Publish:

 

We select Microsoft Azure App Service as the project type and click Publish:

 

Next to App Name, we click Change Type and change the service's type to Web App. We enter our desired app name, Azure subscription, Resource Group (new or existing) and App Service Plan (new or existing), and click the Create button:

 

The creation of the needed resources, and the publishing of our bot to the App Service, should now be initiated. Upon completion, we can obtain the Site URL for our bot endpoint, which we can save for later use:

 

Updating our Messaging Endpoint

Returning to the Bot Framework Portal, we can now update our Messaging endpoint, based on the Site URL we obtained during the publishing process.

Note that we must replace http with https, and we must append /api/messages to our Site URL:

 

We can then save the update by clicking the Save Changes button at the bottom of the page.

 

Setting up the Direct Line Connection

We will now enable the Direct Line channel for our bot, which is the channel that Live Assist leverages to enable the bot as a Live Assist agent. Still in the Bot Framework Portal, we click on the Channels tab for our bot, and choose to add the Direct Line channel:

 

We then show, copy and save our first Secret key. Leaving all Version options selected, we then click the Done button:

 

 

Adding our Bot as an Agent in Live Assist

CafeX has provided instructional steps for adding a bot as an agent in a quick-start guide, and we will add our bot as an agent based on those steps.

First, we log into the Live Assist Administration Portal for the Live Assist-enabled Dynamics 365 organization that we are adding our agent to. The URL for the portal is different for each organization, but you can find your URL either in the “Welcome email” you received upon enabling Live Assist, or from within the Dynamics 365 web client, under Service > Live Assist Administration.

We navigate to USERS > Bots, and then click the ADD button:

 

In the resulting form, we enter:

  • Nickname: our desired name for our bot, as displayed to end users
  • Licenses: the number of Live Assist licenses to allocate to our bot; for every license, three concurrent chats can be handled by our bot
  • Connection Type: we leave this as Ms
  • Connection Key: we enter the Direct Line Secret key that we obtained earlier when configuring the Direct Line channel

 

We then click the SAVE button to save our bot.

 

Updating Live Assist Skills and Engagement

We will now assign appropriate skills to our bot agent and our live escalation agents, along with updating our chat engagement to direct chats to our bot.

We open up our Live Assist Engagement Administration URL, which can be found in the Dynamics 365 Web Client, under Service > Live Assist Supervisor.

We navigate to USERS, and select our newly created bot:

 

We add a new Skill to our bot user, which we are calling Bot. We then click the Save button:

 

We now select a different “live” agent user who will receive escalations from the bot, and add a Skill which we call BotEscalation. We then Save the updates to our live agent user:

 

We now navigate to the CAMPAIGNS tab, and open up our default campaign (typically named Live Chat on your site).

 

We click the Edit button next to our default engagement:

 

We are brought to the ENGAGEMENT step in the Engagement studio process. We click Next in the bottom-right to take us to the WINDOW step. While on the WINDOW step, we click the Add New button:

 

We provide our new window with a name and description:

 

In our Views dropdown, we enable the Pre-chat survey by clicking the toggle, and then edit the pre-chat survey in the resulting window. We will use the pre-chat survey to determine what type of issue the user wishes to get help on, and direct specific types of issues to our bot agent:

 

We use the Trash icon to delete any existing questions, then add a new question of type Routing. We add our desired question text, and add as many options as desired. For our first option, we add option text, and specify that the option will route to our Bot skill. We can add other options that will route to other skills, including directly to the BotEscalation skill, if desired:

 

We then click the Done button in the Pre-chat survey, and click the Save button in the bottom-right to save our window.

With our window now saved and selected, we click the Publish button in the bottom-right of the page, to publish our changes.

 

Testing our Bot

We should now be able to chat with our bot agent from any sites that we have enabled Live Assist chat on, or via the Demo Site that CafeX makes available for testing in the Live Assist Administration Portal (to open portal, go to Dynamics 365 Web Client under Service > Live Assist Administration).

We will test using the Demo Site. While in the Live Assist Administration Portal, navigate to GET STARTED, use the right chevron to navigate to the Open Live Assist for Dynamics 365 panel, then click the DEMO SITE button:

 

In the resulting sample website, you should see your chat engagement. If you elect to chat, and select the appropriate Routing Question option, you should be able to engage in a conversation with your bot that will be answered via QnA Maker. If sufficiently negative sentiment is expressed by you during the chat, you should be able to escalate to a live agent.

 

Notes: Make sure you are logged into Live Assist with a user that has the appropriate BotEscalation skill. In addition, if you are still authenticated in the Live Assist Engagement Administration portal, you may find that escalated chats will be directed there.

You can download the full Visual Studio solution code here.

Comments (0)

Skip to main content