Building a Great Multi-Channel Chatbot

Creating a system for managing data structures required by different channels

It is important to engage with customers where they are, it ensures you stay relevant and accessible in today’s on-demand world. If you decide to be available to your customers through a chatbot, it’s probably a good idea to reach them in their preferred mode of communication — whatever that might be.

So what are the various channels that you should consider for a chatbot? Top of mind, there’s your chat functionality on your website or app (from a provider or proprietarily built), sms/text, Facebook Messenger, Instagram, WeChat, Skype, Email, Twitter, and even Slack. These are just a few of the options, but you get the point.

Various engagement channels — note: not all of these are “chatbot” ready

There are lot of communication methods and the ones you choose to use depends on many factors; what type of brand you are, your customer demographics and preferences, and what is possible from a business case perspective. Irrespective of which channels you use, you need to set up a system for your bot to handle each type of communication. That’s what we’re going to explore in this post.

The unfortunate fact of that matter is that digital communication channels, like many things in life, are not standardized. Like the wall sockets across countries or micro-usb vs lightning phone charging cords, different chat channels require different inputs.

Here’s an example of the data structure the Facebook Messaging Platform requires for a simple message:

"message": {
"text": "hello, world!"
}

And here’s the basic format for Slack:

{
"text": "hello, world!"
}

Not that bad! Besides the message destination formatting (who it’s getting delivered to), you basically just need to modify the text. What’s great is there’s a number of bot frameworks out there that can handle multi-channel integration with simple text chatbots. Check out BotMaster AI, BotKit Middleware for Watson, or my colleagues Conversation Extension Framework for examples. But what if we add buttons?

Facebook structure for message with button:

"message":{
"attachment":{
"type":"template",
"payload":{
"template_type":"button",
"text":"
Would you like to play a game? Choose a game to play",
"buttons":[
{
"type":"postback",
"title":"Chess",
"payload":"chess"
},
{
"type":"postback",
"title":"Falken's Maze",
"payload":"
maze"
}
]
}
}
}

Slack structure for message with button:

{
"attachments": [
{
"text": "Would you like to play a game?",
"callback_id": "wopr_game",
"color": "#3AA3E3",
"attachment_type": "default",
"actions": [
{
"name": "game",
"text": "Chess",
"type": "button",
"value": "chess"
},
{
"name": "game",
"text": "Falken's Maze",
"type": "button",
"value": "maze"
}
]
}
]
}

Very different. Unfortunately, I haven’t come across any framework that can handle different data structures across channels. But it’s not impossible to map — each message has the text field and a general structure for a button. In Facebook there is an array of buttons with a type postback, whereas Slack has an array of actions with type button. Maybe you’re starting to see what you have to do here from a programming stance; you need to map each type of output from your chatbot to the necessary data structure. We can do this through a middle-layer, architected as such:

Middle Layer Architecture for a Multi-Channel Chatbot

Each chat channel will require specific setup code to convert the output structure to the correct format. They will also require specific code to interpret the various response structures. Furthermore, each message type will require a separate structure for each channel. This gets complex and reliant on lots of code rather quickly.

With one channel, you can add the necessary data structure directly into the response. Here’s a Watson Conversation Service (WCS) response specifically for a LiveEngage chat channel as an example:

Example hardcoded JSON response for a LiveEngage channel response

Great if you’re using a single channel, but not scalable to other channels; two or more and you’ll need that middle-layer.

So how do you design that middle-layer?

First let’s figure out how many and what message types we’re going to need.

Facebook Messenger has these top level message types:
  • simple text
  • generic template (title, subtitle, image, and up to three buttons)
  • list template
  • button template
  • open graph template (used send an Open Graph URL)
  • receipt template
  • airline template (structured content for airline use cases)
  • media template (images, GIFs, and video)
Twilio (for sms/text) has these:
  • simple text
  • simple text with an image URL
And Slack has these:
  • simple text
  • formatted attachments (slack offers a multitude of formatting options)
  • message buttons

Definitely check out the Slack Message Builder to get a sense of what you can do.

These are just a few channels that we can use, but we need to find a common set of message types that are useful. Unless you’re building a chatbot for the airline industry, you likely won’t need to use the airline template from Facebook.

Message Types

So what message types will be common and useful? Here’s a few that might make sense:

Simple text

Important because it’s the simplest form of chat communication and is accepted across channels.

Buttons

Buttons help guide users down certain paths — an important part of chatbot design. Buttons aren’t available in sms/text however, so we’ll need to build in a modification to simulate the guiding effect of buttons through sms/text. In place of an actual button, you can list off the option and prompt the user to respond with one. Something like this:

Simple text for sms/text, but modified to simulate buttons
Lists
Attachments in Slack can create lists

Lists provide an easier way to differentiate between options, steps, requirements, or anything else that can be put in a series. Again, with sms/text we’d use a similar strategy to simulate a list. In Slack, we’d use formatting with attachments to achieve a list. Facebook, on the other hand, defines a list data structure.

Images

Images might be important for consumer brands as they can be used to display products for purchase or even help users troubleshoot how to accomplish a task online:

Image used to provide visual guidance to a user

The message types you use will of course be dependent on your business and communication needs, but these four are a good start for most interactions.

Channels

Next you’ll need to decide which channels you want your chatbot to participate in.

Most brands should have a website where their customers can reach them via chat — a lot of companies may use a provider such as Intercom or LivePerson. You’ll want your chatbot working on your site as this is likely the first place your customers will go when they want to get in touch with you.

You’ll also want to be accessible where your customers are, and that definitely depends on the type of customers you have. Millennials that are pretty active on social media? Maybe Facebook messenger. Chinese white-collar workers? Try WeChat. Have all sorts of demographics and want a channel to engage with all of them? SMS/text is widely used and email is still the gold-standard for customer communication.

Middle-Layer

Once you’ve picked the channels you want to start with, you can start building out the middle-layer to handle each channel and message type. Let’s say we’ve picked Intercom, Facebook Messenger, and sms/text, we’d need to build out 12 different handling functions (4 message types x 3 channels). This work quickly adds up.

An example WCS output with a button message

But you also need to marry the output from your chatbot to the middle-layer. This is so the middle-layer can know what type of message you want displayed. In WCS you can do this through the JSON output by adding an element message with our required information.

In this example we’re outputting a regular text along with a message of type button and a series of buttons. This will signify the message type and required properties to middle-layer — the interpreter. We could similarly indicate message of type list and add a series of lists.

Note, this format is just one way to accomplish the task of communicating message type between the middle-layer and WCS. You just need some baseline format that is understood by the middle-layer.

With this setup, you should be able to build one chatbot for all your communication channels. Start small with your most critical channels and message types, then expand from there.

Conclusion

Do you want a multi-channel chat framework out of the box?

We shouldn’t have to rebuild a middle-layer for each chatbot — so I’m working on a small node package that others can use. I’m starting with channels that I’m more familiar with (Facebook messenger, Twilio), but am certainly open to reprioritizing. If you’d find a framework like this useful, please give this article a clap or drop a comment — I might be more motivated if I know other people will use it too!