Route Support Tickets by Language Using TaskRouter & IBM Watson

October 04, 2016
Written by

usecase-contact-center

Serving your customers well gets harder as our world gets smaller and the ways customers want to reach you increases.  The IBM Watson Message Insights Add-On from the Twilio Add-Ons Marketplace detects the language of a text message, so that you can step up your support game and serve your customers in their native language.

Let’s see how you can combine Watson, Programmable SMS, and TaskRouter with a dash of ASP.NET and C# to seamlessly route incoming SMS messages to the most appropriate agent on your team.

If you want to play along and don’t yet have a Twilio account, it’s quick to get one.  If you want to jump ahead check out the completed code on Github otherwise let’s get started!

Installing Message Add-Ons

The Twilio Add-Ons marketplace lets you add third-party functionality to your voice and messaging apps simply by flipping a switch in your Twilio console. Let’s enable the IBM Watson Message Insights Add-on in the Programmable SMS Add-ons Dashboard.

Click the Install button, then check the “Use In: Incoming SMS Messages” checkbox and boom! Just like that every inbound message you receive to your Twilio account will be processed by Message Insights. The resulting data, which includes, among other things, the language of the message text, is automatically included in the webhook request Twilio makes to your application. Pretty cool, right?

Localizing SMS Responses

With Message Insights installed let’s build a simple web application that can receive an inbound SMS message and use the Message Insights data to return a response in the same language as the incoming message.

In Visual Studio create a new ASP.NET MVC project and add the Twilio.Mvc Nuget package to it.  Add a new Controller file to the project and change it to derive from the TwilioController base class.  Next add an action method that has two string parameters: Body and AddOns.

public class PhoneController : TwilioController 
{
    public ActionResult Message(string body, string AddOns)
    {
        var response = new TwilioResponse();
        return TwiML(response);
    }
}

The Body parameter contains the text sent in the SMS message. The AddOns parameter contains a JSON serialized object that holds data appended to the webhook request by any SMS Add-On you have installed, including the data from Messaging Insights.

Deserialize the Add-On JSON content to a dynamic type using Json.NET:

public ActionResult Message(string body, string AddOns)
{
    dynamic addons = JsonConvert.DeserializeObject(AddOns);

    var response = new TwilioResponse();
    return TwiML(response);
}

Check to make sure that all of the SMS Add-Ons executed successfully and, just in case, respond to SMS letting the user know something went wrong:

public ActionResult Message(string body, string AddOns)
{
    dynamic addons = JsonConvert.DeserializeObject(AddOns);

    var response = new TwilioResponse();
    
    if (addons["status"] == "successful")
    {
    }
    else
    {                              
        response.Message("We're really sorry but something seems to have gone wrong when we tried to read your message.  Can you try sending it again?  If it keeps happening us, try giving us a call at <a href="https://www.twilio.com/console/phone-numbers/PN990d3383608b38d6803cfb158342d2fd"> 1 704-275-3976 </a>");
    }

    return TwiML(response);
}

If the Add-Ons succeeded, grab the language of the message text as reported by Message Insights and use it to select the appropriate language response:

if (addons["status"] == "successful")
{
    var language = addons["results"]["ibm_watson_insights"]["result"]["language"].Value;

    if (language =="spanish")
    {
        response.Message("Gracias por contactar con nuestro equipo de soporte. Uno de nuestros agentes de soporte estará con usted pronto.");
    }
    else if (language == "french")
    {
        response.Message("Merci de contacter notre équipe d’assistance. Un de nos agents de soutien fera avec vous sous peu.");
    }
    else
    {
        response.Message("Thank you for contacting our support team.  One of our support agents will be with you shortly.");
    }
}

That’s all the code we need for now.  Before we test the app we need to deploy it to a host like Azure or use a tool like ngrok to expose the app through a public URL.  Assign that URL as the Message Request URL for a Twilio phone number making sure to append the Message action method route to your ngrok URL:

To test the app, send a text message to your Twilio number in Spanish and see which response you get.  

"Hey allí. Estoy teniendo un problema con mi widget. ¿Alguien que me puedeayudar?"

You should get a response in Spanish.  Try sending the same message this time in English.

"Hey there.  I'm having a problem with my widget.  Can someone there help me out?"

This time you should get a response in English.

Setting Up TaskRouter

Awesome!  Now that we can accept an inbound SMS message and determine the language of the message text, we can use that information to route those messages to an appropriate worker using TaskRouter.

Let’s start by setting a simple TaskRouter configuration.  Log into the Twilio Console and open the TaskRouter Dashboard.  Create a new Workspace:

A Workspace is a container for all of the pieces of TaskRouter.  Open the Workspace you just created and select TaskQueues.  Create a new TaskQueue for each language you want to support.  In my application I created two, one for English and one for Spanish.

For each TaskQueue configure the Target Workers property with a rule the queue can use to find Workers that have the language skills needed to help customers in that queue.

Next, click Workflows and create a new Workflow.  

As part of the Workflow we’ll define Filters that tell TaskRouter which TaskQueue to place an incoming Task into based on data we include in the Task. For our app, that data is the language of the incoming text message so we’ll create two filters: one for English and one for Spanish.

A Filter Expression allows you to define a set of rules that TaskRouter uses to determine if a Task should be placed into a specific TaskQueue.  In our case the English Language filter uses the expression

language == "english"

and sets the Target TaskQueue to “Customer Care Requests – English”.  The Spanish Language filter uses the expression:

language == "spanish"

and sets the Target TaskQueue to “Customer Care Requests – Spanish”.

We’ll configure the default TaskQueue for the whole Workflow.  Any Task whose language does not match either of the Filters defined will be queued into this TaskQueue:


Finally, we need to create some Workers who can accept and process tasks from our TaskQueues.  For each worker we define as a JSON object a set of attributes that TaskRouter uses to determine whether or not that Worker is eligible to accept tasks for a given TaskQueue.  In our scenario one of those skills is languages:

Because Alice speaks both English and Spanish, she is eligible to accept tasks from either of our two TaskQueues.

Create another Worker “Bob” and configure him to support English only:

{"languages":["en"]}

Great!  We’re done configuring a TaskRouter.  Let’s look at how to create new Tasks when we receive an inbound SMS message and then use the language data from Message Insights to route the task to the appropriately skilled Worker.

Creating Tasks from Messages

Create TaskRouter Tasks in our ASP.NET application by first installing the Twilio.TaskRouter Nuget package.  In the Message action method, create an instance of a TaskRouterClient object, passing in your Twilio AccountSid and AuthToken as parameters.  Next, call the AddTask method:

if (addons["status"] == "successful")
{
    var language = addons["results"]["ibm_watson_insights"]["result"]["language"].Value;

    var client = new TaskRouterClient("YOUR_ACCOUNT_SID", "YOUR_AUTH_TOKEN");
    var result = client.AddTask(
         "YOUR_WORKSPACE_SID",
         JsonConvert.SerializeObject(new { language = language, body = body }),
         "YOUR_WORKFLOW_SID", 
         null, null);

    if (result.RestException != null)
    {
        throw new HttpException(result.RestException.Message);
    }
}

Notice that the AddTask method accepts as its second parameter a JSON formatted string of attributes. The Workflow we created uses those attributes to determine which TaskQueue to place the Task into. Here we are including an attribute named language and setting the value of that attribute to the language given to us by Messaging Insights.

With TaskRouter configured, let’s try sending some messages starting with some Spanish.

"Hey allí. Estoy teniendo un problema con mi widget. ¿Alguien que me puedeayudar?"

You should see that TaskRouter has correctly routed the new Task into the Spanish Language TaskQueue and set its Assignment Status to “Reserved”:

Switch over to look at the Workers and you can see that Alice, our only Spanish speaking worker, has an Activity of “Reserved” so we know she was assigned that Task.

Try sending the same message this time in English.

"Hey there.  I'm having a problem with my widget.  Can someone there help me out?"

TaskRouter should correctly route the Task into the English Language TaskQueue and assign it task to Bob because he speaks English.

Wrapping Up

There are a bunch of other really cool Add-Ons available that make adding additional metadata to messages and phone numbers quick and painless.  For example, check out my friend Phil’s on  performing sentiment analysis on SMS messages.

On top of that, TaskRouter makes it super simple to route tasks based on the skills of your available resources — and it’s not just for SMS messages.  You can queue and route calls, tweets, Facebook messages or just about any other form of digital customer communication using TaskRouter.

Let me know how you are using Add-Ons or TaskRouter in your own apps.  Leave a comment below, hit me up on Twitter or drop me an email.