8
When pizza is one message away: Chatbots

This chapter covers

  • Building a serverless chatbot
  • How serverless chatbots work, and how Claudia Bot Builder helps
  • Using a third-party chatbot platform (Facebook Messenger)

Serverless applications aren’t always APIs or simple processing microservices. Software is evolving, and people are finding different ways to use it. We’ve come a long way from isolated desktop applications to websites and mobile apps, and recently we’re starting to see an expansion of chatbots and voice assistants.

This chapter shows how you can interact with your users even more by building a serverless chatbot on Facebook Messenger and integrating it with your Pizza API. You’ll also learn how chatbots work and how to easily implement them in a serverless way using Claudia.

8.1 Pizza ordering beyond the browser

While you were working on Aunt Maria’s Pizza API, her niece Julia dropped by the pizzeria a few times to say hi. Julia is in high school and, of course, spends lots of time on her phone. Even though she’s happy that you helped the pizzeria set up an online ordering service, she complains that it’s not cool enough. You’re way behind Aunt Maria’s main competitor, Chess’s pizzeria, which has a Facebook Messenger chatbot that helps their customers order pizzas without leaving Facebook. Because Julia’s classmates are always chatting on Facebook Messenger, they use it all the time. Having a chatbot would definitely help Aunt Maria reach more young customers, so she asks if you could help with that.

8.2 Hello from Facebook Messenger

Because you are going to build a pizza chatbot on Facebook Messenger, it’s important to understand how users will send messages to your chatbot and how a Facebook chatbot works.

Facebook chatbots are support applications for Facebook pages, meaning that they aren’t independent, separate applications, like games. Building a Facebook chatbot is done in four steps:

  1. Set up a Facebook page for your chatbot.
  2. Create a Facebook application that will serve your chatbot and connect it to your page.
  3. Implement your chatbot and deploy it.
  4. Connect your chatbot to your Facebook application.

To start interacting with your chatbot, users will need to open your Facebook page and send it a message. The page’s Facebook application receives the message and sends a request to your chatbot with the user’s message. Your chatbot receives and processes the message and returns a response to your Facebook application, which in turn responds in your Facebook page’s message box.

A detailed visual overview of this messaging process is shown in figure 8.1.

figure-8.1.eps

Figure 8.1 Chatbot message and reply flow

Before you jump into thinking about how to implement your chatbot service, there is some good news. Besides its API Builder, Claudia also has a Bot Builder.

Claudia Bot Builder is a thin library that wraps Claudia API Builder. It abstracts away the various messaging platform APIs and provides a simple, unified API for building your chatbots. Claudia Bot Builder’s purpose is to help you build chatbots on various messaging platforms, such as Facebook, Slack, Viber, and many more.

To start, you’ll need to create a new folder at the same directory level as your pizza-api and pizza-image-processing folders. A good folder name would be pizza-fb-chatbot. After creating the folder, open it and initiate a new NPM project. Then you need to install Claudia Bot Builder as a project dependency. To do that, see appendix A.

After installing the Bot Builder you’ll need to set up your Facebook page and its Facebook application and connect them. For instructions on how to do that, see appendix B.

Now that you have the project set up, you can start with the actual implementation. You’ll need to create an initial file for your chatbot, so create a bot.js file in the root of your pizza-fb-bot folder and open the newly created file in your favorite code editor.

At the top of the bot.js file, require Claudia Bot Builder.

The Bot Builder, module is a function that requires a message handler function as its first argument and returns an instance of Claudia API Builder. The message handler function is the function that will be invoked when your chatbot receives a message. The easiest way to reply from your chatbot is to return a text message. Claudia Bot Builder will format this text message in the template required by the chat platform you are answering to—in your case, Facebook Messenger.

Because Claudia Bot Builder returns an instance of Claudia API Builder, as the last step you’ll need to export the API Builder instance returned to you by the Bot Builder function.

Your bot.js file should look like the following listing.

Listing 8.1 A simple chatbot that says hello

'use strict'
const botBuilder = require('claudia-bot-builder')    ①  

const api = botBuilder(() => {    ②  
  return `Hello from Aunt Maria's pizzeria!`    ③  
})

module.exports = api

Deploying your chatbot is similar to deploying your Pizza API. As shown in listing 8.2, you need to run the claudia create command and provide your region and the --api-module option with the path to your initial file (without the extension). Your initial file is the bot.js file, so you need to provide bot as the API’s module path. In addition to the region and the API module, you also need to provide the --configure-fb-bot option. This option will set up the Facebook Messenger chatbot configuration for you. Let’s see it in action first, and we’ll explain what happens in the background when you use this option later in this chapter.

Listing 8.2 Deploying your chatbot and setting up the Facebook Messenger configuration

claudia create 
  --region eu-central-1 
  --api-module bot     ①  
  --configure-fb-bot    ②  

Running the claudia create command with the --configure-fb-bot option will make the command interactive. If the deployment of your API was executed successfully, this command will then ask you to provide your Facebook page access token and then print out the webhook URL with your verification token. (For a detailed explanation of the Facebook setup process, see appendix B.)

When you provide the Facebook page access token, your bot will be ready and immediately available for testing. To test your bot, go to your Facebook page and send a message to it. Your bot currently always replies with the static text “Hello from Aunt Maria’s pizzeria!,” as shown in figure 8.2.

figure-8.2.tif

Figure 8.2 The first message from your chatbot

8.3 What kinds of pizzas do you have?

Building a chatbot in a few minutes is satisfying, but at this point your chatbot is pretty useless. To make it useful, you should allow customers to see all the available pizzas and place an order. Let’s start with showing customers the list of pizzas.

If you remember from chapter 2, the currently available pizzas are stored in a static JSON file. As a temporary solution, copy that JSON file to your new project. First create the data folder, and then copy the pizzas.json file from your pizza-api folder to the data folder in the pizza-fb-chatbot project you created.

The next thing you want to do is show the pizza list as a chatbot reply. Defining the appropriate attitude and tone for your chatbot is beyond the scope of this book, so for now try to come up with some friendly message before you list the pizzas, such as “Hello, here’s our pizza menu,” and then ask users which one they want. To do this, you’ll need to update your bot.js file.

First, import the list of pizzas from the pizzas.json file, which is in the data folder. Then update the botBuilder message handler function to return the pizza list and ask the user to pick one.

With Claudia Bot Builder, you can send multiple messages as responses to the user. To enable this capability, you need to return an array of messages instead of a single static text. Each message in the array will be sent separately, with the order determined by the order of the messages in the array.

Now you want to get the list of pizzas from the JSON file and convert each one to a string. To do so, you can map through the array of pizzas, get the name of each one, and then convert the array to a string using the Array.join function.

The updated bot.js code should look like the following listing.

Listing 8.3 Your chatbot replying with a pizza list

'use strict'
const pizzas = require('./data/pizzas.json')    ①  

const botBuilder = require('claudia-bot-builder')

const api = botBuilder(() => {
  return [    ②  
    `Hello, here's our pizza menu: ` + pizzas.map(pizza => pizza.name).join(', '),    ③  
    'Which one do you want?'    ④  
  ]
})

module.exports = api

Deploy the updated bot with the claudia update command—no arguments needed. After a minute or so, your update command finishes and returns output similar to that in the following listing.

Listing 8.4 Response for the claudia update command

{
  "FunctionName": "pizza-fb-bot",    ①  
  "FunctionArn": "arn:aws:lambda:eu-central-1:721177882564:function:pizza-fb-bot:2",    ②  
  "Runtime": "nodejs6.10",    ③  
  "Role": "arn:aws:iam::721177882564:role/pizza-fb-bot-executor",    ④  
  "url": "https://wvztkdiz8c.execute-api.eu-central-1.amazonaws.com/latest",    ⑤  
  "deploy": {    ⑥  
    "facebook": "https://wvztkdiz8c.execute-api.eu-central-1.amazonaws.com/latest/facebook",
    "slackSlashCommand": "https://wvztkdiz8c.execute-api.eu-central-1.amazonaws.com/latest/slack/slash-command",
    "telegram": "https://wvztkdiz8c.execute-api.eu-central-1.amazonaws.com/latest/telegram",
    ...
  }
}

Try to send a new message to your chatbot and you’ll see the updated answer, as shown in figure 8.3.

figure-8.3.tif

Figure 8.3 The updated response from your chatbot

8.4 Speeding up the deployment

As you probably noticed, updating your chatbot takes a bit more time than updating your API. That’s because Claudia Bot Builder doesn’t know if you changed the API configuration, so it rebuilds the webhook routes for all supported platforms. A detailed explanation of how Claudia Bot Builder works under the hood is given in section 8.6.

Fortunately, there is a way to skip the rebuilding step and speed up the deployment process. To do so, you can use the --cache-api-config option, which requires a stage variable name. When this option is provided, Claudia will create a hash of your API Gateway configuration and store it in a stage variable with the name you provided as the next argument in the update command. Each subsequent deployment will check if that variable exists, and compare the hash to see if the API Gateway configuration should be updated. This process speeds up the deployment, unless you add a new API route.

We recommend adding the claudia update command with the --cache-api-config option as an NPM script in your package.json file. If you do that, you should also install Claudia as a dev dependency, as explained in appendix A. Your package.json file should then look similar to the next listing.

Listing 8.5 package.json file with the updated script

{
  "name": "pizza-fb-chatbot",
  "version": "1.0.0",
  "description": "A pizzeria chatbot",
  "main": "bot.js",
  "scripts": {
    "update": "claudia update --cache-api-config apiConfig"    ①  
  },
  "license": "MIT",
  "dependencies": {
    "claudia-bot-builder": "^2.15.0"
  },
  "devDependencies": {
    "claudia": "^2.13.0"    ②  
  }
}

The --cache-api-config option is useful when you aren’t updating the API definition often, and it speeds up the deployment significantly. But Claudia Bot Builder creates webhooks for all platforms, and if you are building a chatbot for a single platform only, you don’t need the webhooks for other platforms. From version 2.7.0, Claudia Bot Builder allows you to enable only the platforms you are using. To do so, you’ll need to provide the options as the second argument to the botBuilder function. Claudia Bot Builder expects the options, if provided, to be an object. To enable only the Facebook Messenger platform, you need to add the platforms key in the options object, with an array with the string "facebook" as a value, as shown in the next listing.

To read more about selecting the platform, see https://github.com/claudiajs/claudia-bot-builder/blob/master/docs/API.md.

Listing 8.6 A chatbot with Facebook Messenger as the only enabled platform

'use strict'
const pizzas = require('./data/pizzas.json')
const botBuilder = require('claudia-bot-builder')
const api = botBuilder(() => {
  return [
    'Hello, here's our pizza menu: ' + pizzas.map(pizza => pizza.name).join(', '),
    'Which one do you want?'
  ]
}, {    ①  
  platforms: ['facebook']    ②  
})

module.exports = api

If you run the npm run update command from your project directory now, you’ll see that the deployment is significantly faster.

8.5 Messenger templates

Aunt Maria’s chatbot is now capable of showing customers the available pizza list. But even though it does the job, customers may not understand what to do next.

Building a good chatbot experience is hard. Most users aren’t accustomed to a textual interface, and a chatbot often requires some natural language processing and artificial intelligence—both are hard to set up correctly. For some spoken languages, it is almost impossible at the moment. Many chatbot platforms have acknowledged those problems and have simplified development and improved the user experience by adding support for some application-like interfaces, such as buttons and lists.

Facebook Messenger is one of those platforms, and its user interface elements are called templates. It offers several different templates, such as the following:

  • Generic—Sends a message in the form of a carousel, or horizontally scrollable list, with cards that can have a title, subtitle/description, image, and up to three buttons
  • Button—Sends a message with simple buttons (up to three) below the text
  • List—Sends a message in the form of a vertical item list with names, descriptions, and images, and a call-to-action button
  • Receipt—Sends an order confirmation or receipt to the user after a transaction

For the full list of supported templates, visit https://developers.facebook.com/docs/messenger-platform/send-messages/templates/.

For your case, the generic or list templates seem like potential solutions. But the list template has a limitation on the list size—it needs at least two items and can display four at most. The generic template is more flexible; it can display 1 item, or up to 10. Because you want to display more than four pizzas, you should use the generic template.

To return a template instead of a text with the pizza list, you need to reply with a JSON object that has a specific structure. Doing so sounds simple enough, but these JSON objects can be quite big, and because you are going to display up to 10 pizzas, the readability of your code will be affected.

To improve the readability and simplify working with templates, Claudia Bot Builder has wrapped templates for some of its supported platforms (including Facebook, Telegram, and Viber) into template message builder classes. For Facebook, the template message builder is available through the botBuilder.fbTemplate object, which is a collection of classes for each of the supported templates.

As mentioned earlier, the generic template displays a horizontal scrollable carousel of items or elements. Each element is composed of an image attachment, title, optional description, and buttons to request user input. The generic template buttons can have different actions, such as opening a URL or sending a postback to your webhook. For the full list of button actions and more details about the generic template, visit https://developers.facebook.com/docs/messenger-platform/send-messages/template/generic.

In Claudia Bot Builder, the generic template is exposed through the botBuilder.fbTemplate.Generic class. You need to initialize the class without arguments and save the instance to the message constant.

Then you should add a carousel item, also known as a bubble, for each pizza. To do so, loop through the array of pizzas and for each one add a button using the message.addButton method of the fbTemplate.Generic class. This method requires the bubble title as an argument.

Then you’ll add an image and a button for each pizza, which you can do via the addImage and addButton methods, respectively. For the addImage method, you need to provide a valid image URL, and the addButton method requires a button name and a value that will be passed when the button is tapped. For now, add a “Details” button and send the pizza ID as a value. You’ll implement the button logic in the next chapter.

All class methods allow chaining, so you can chain them as follows:

message.addBubble(pizza.name).addImage(pizza.image).addButton('Details', pizza.id)

At the chain’s end, you need to use the message.get method to convert the button to the JSON response Facebook expects. Because users will use the template button to order pizzas (you will implement this capability in the next chapter), you can replace the label with a "Which one do you want?" message with message.get.

The updated code for your bot.js file should look like the next listing.

Listing 8.7 The Bot Builder function that answers with the generic template

'use strict'
const pizzas = require('./data/pizzas.json')
const botBuilder = require('claudia-bot-builder')
const fbTemplate = botBuilder.fbTemplate    ①  

const api = botBuilder(() => {
  const message = new fbTemplate.Generic()    ②  

  pizzas.forEach(pizza => {    ③  
    message.addBubble(pizza.name)    ④  
      .addImage(pizza.image)    ⑤  
      .addButton('Details', pizza.id)    ⑥  
  })

  return [
    'Hello, here's our pizza menu:',
    message.get() 
  ]
}, {
  platforms: ['facebook']
})

module.exports = api

After updating your bot.js file, run the npm run update command. As soon as it’s finished, you can send a new message to your chatbot. The reply should look similar to the one in figure 8.4.

figure-8.4.tif

Figure 8.4 A chatbot response with the generic template

8.6 How does Claudia Bot Builder work?

Now that you have a nice-looking chatbot, it’s time to see what Claudia Bot Builder did for you under the hood.

Most of the popular chatbot platforms use webhooks to notify your server that a new message was received. But each platform sends the data with a different structure, and also expects you to answer in a platform-specific way.

The main goal of Claudia Bot Builder is to abstract away the receiving and sending messages' platform-specific structure to a simple API. It uses Claudia API Builder to create webhooks for each supported platform. At the time of writing, Claudia Bot Builder supports 10 platforms (including Facebook Messenger, Slack, Amazon Alexa, and Telegram).

As shown in figure 8.5, the Claudia Bot Builder message-reply lifecycle looks like this:

  1. The user sends a message via a messenger platform.
  2. The platform API hits API Gateway via the webhook you provided in the platform settings.
  3. API Gateway triggers your Lambda function, where the request is routed to the platform-specific API endpoint.
  4. The request is parsed to a common format using the platform-specific message parser.
  5. The parsed message is passed to your chatbot logic.
  6. The answer from your chatbot logic is wrapped in a platform-specific format.
  7. Claudia Bot Builder invokes the platform API with a wrapped reply.
  8. The platform API sends the reply back to the user’s messenger application.
figure-8.5.eps

Figure 8.5 Claudia Bot Builder conversation flow

You saw that the botBuilder function expects a message handler function, and you can also pass it an object with options as an extra parameter. The handler function is your chatbot logic, and the options object is used only for specifying the platforms used, to speed up the deployment.

The handler function is invoked with two arguments: the message object and the original Claudia API Builder request object.

The parsed message object contains the following properties:

  • text—The text of the received message, extracted from a platform-specific message format. In most cases, if you want to reply to text messages, this is the only piece of information you’ll need.
  • type—The platform that received the message. For list of platforms, see https://github.com/claudiajs/claudia-bot-builder/blob/master/docs/API.md.
  • sender—The identifier of the sender. It depends on the platform, but it is the user ID in most cases.
  • postback—A Boolean property. This will be true if the message is the result of a Facebook postback (for example, tapping a generic template button). It will be undefined (falsy) for completely new messages or platforms that don’t support postbacks.
  • originalRequest—The original message object received by your webhook. This is useful if you want to do some platform-specific actions that are not provided by Claudia Bot Builder.

Finally, replying to a message from Claudia Bot Builder is as simple as replying from Claudia API Builder—if you want to reply with a text message, you need to return the string. You can also reply with a platform-specific template, either by using the message template builder or by returning a JSON object. To reply asynchronously, return text or an object at the end of the promise chain.

8.7 Taste it!

You’ve now seen the basics of implementing Facebook Messenger chatbots with AWS Lambda. It’s not enough to win the Loebner Prize, but it’s enough to have some fun. As in all the previous chapters, we’ve prepared an exercise for you.

8.7.1 Exercise

The goal of your first chatbot exercise is to show you how easy it is to create a chatbot.

Using the same Facebook page and application, create a chatbot that will echo the message text it received, in reverse.

Here are a few tips:

  • Inspect the message parameter to get all its attributes and return the same text message the user sent.
  • Use the built-in methods to reverse a string.

8.7.2 Solution

The solution, shown in the following listing, is simple and obvious.

Listing 8.8 A simple reverse echo chatbot

'use strict'
const botBuilder = require('claudia-bot-builder')    ①  

const api = botBuilder((message) => {    ②  
  return message.text.split('').reverse().join('')    ③  
}, {    ④  
  platforms: ['facebook']
})

module.exports = api    ⑤  

This Reverse-O chatbot is easy, but don’t think future ones will be, too!

Summary

  • Claudia enables you to deploy a chatbot for a few different platforms in a single command.
  • Claudia Bot Builder is a wrapper around Claudia API Builder that returns an API instance.
  • Claudia Bot Builder wraps the text reply in a format required by the platform you are answering to.
  • You can build platform-specific template messages using Bot Builder templates.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset