Facebook Chatbot Example: Learn to Build a Todo Bot Using Javascript

Detailed Tutorial for Beginners to Learn Chatbot Development with Node.js and Bottender Framework

Cheng-Wei Hu | 胡程維
The Startup
9 min readJan 12, 2020

--

In this tutorial, we will learn how to build a Facebook Messenger Bot step by step using Node.js. We will understand how to utilize some features of the Messenger Platform by developing a Todo Bot from scratch.

I have already built a Todo Bot online. Therefore, you can play with the Bot right now through this link:

This chatbot is a minimalist Todo Tool that helps you handle todos and will remind you of your todos through messaging. I personally use its reminder feature every day to help myself remember some trivial tasks.

To make the tutorial more beginner-friendly, we will build a simple version of this bot in the tutorial. Still, you can access the source code of both the simple and live version at the end of this tutorial.

Let’s start and do it together.

Catalog

  1. Setup Chatbot for Hello World
  2. Connect Our Bot to Facebook Messenger
  3. Learn the Basics
  4. Add a Todo
  5. List all Todos
  6. Delete a Todo
  7. Refactor with Router
  8. Add an Introduction

Setup Chatbot for Hello World

What is Bottender?

In this tutorial, we will use the Bottender chatbot framework to make our development easier. This framework is a flexible Node.js chatbot application framework, providing a robust set of features for building a chatbot application. It supports multiple platforms such as Messenger, Telegram, Slack, LINE, and Viber.

For further information about Bottender, check out their Website and Github.

Setup Using create-bottender-app

First, we should create our bot project using create-bottender-app. This script is the easiest way to initialize an environment for chatbot development.

To create our Todo Bot, run:

npx create-bottender-app todo-bot

After running this script, we will have to go through an interactive process. We use space to choose messenger as our platform and press enter to get to the next step.

Next, we press enter to choose memory as our store session.

After that, create-bottender-app will start to create our development environment and install dependencies. When the installation is finished, you will see a directory named nba-scores-bot.

The directory structure will look like:

.
├── .env
├── .env.example
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── README.md
├── bottender.config.js
├── index.js
├── jest.config.js
├── node_modules
├── package.json
├── src
└── yarn.lock

Now, we can test whether our bot is set up correctly. To test the bot, the easiest way is to run it in the Console Mode.

cd todo-bot
npm run dev -- --console

We now get a bot that replies Welcome to Bottender in the console. That means we just finish the bot setup and it's time to connect our bot to Facebook Messenger Platform.

Connect Our Bot to Facebook Messenger

To connect our bot to messenger, we have to check our config file first. Open bottender.config.js and find the following code inside:

To complete our Messenger connection, we have to set up the following 5 values in the .env file.

  • Messenger Page ID
  • Messenger Access Token
  • Messenger App ID
  • Messenger App Secret
  • Messenger Verify Token

We can get these five values by following the third section of this detailed tutorial step by step.

By following the tutorial, our bot should be connected to the Facebook Page. You can then go to the fan page and test it. Now, the bot will reply to you with Welcome to Bottender every time you send a message.

Learn the Basics

context and event

Now, we can learn how the bot actually works. In the src/index.js file, we will see the following code:

Every time when our chatbot receives a message, our App will get an object called context. This object encapsulates many methods and attributes for our chatbot development. We can check a user's input and reply with a response through this object. For example:

To send a text to the user:

context.sendText(text)

To access the state of a user:

context.state

To set a state for a user:

context.setState({
stateKey: value,
});

You can check this official document for all of its methods.

Furthermore, to check a user’s input, we should use context.event. For example:

To determine if an input is a text:

context.event.isText

To access a user’s text input:

context.event.text

Again, you can check this official document for all of its methods.

Build an Echo Bot

Now, since we have learned about context and event, we can build a simple chatbot that echoes user’s text input by the following code:

When our bot receives a message, it will first check whether the message is a text message or not. If the message is a text message, then our bot will send what we just received back to the user by using the method context.sendText().

Manage State

State is an object that enables us to store and retrieve data of a user. For example, we can use it to maintain a counter that increments whenever it receives a message from a user.

First, we have to set the initial state in the bottender.config.js file:

Next, we use context.state to retrieve data and use context.setState to store data:

Finally, we understand all the basics we should know to build the bot. It’s time to build the functionality of our bot.

Add a Todo

The first feature of our bot is enabling a user to add a todo. Therefore, we have to define the initial state of a user’s todos in the bottender.config.js:

As we can see, todos is an empty array that will store our user’s todo item. We define a single todo item like this:

{
title: myTodoTitle
}

Next, we need to lay down the rules of how a user can add a todo item. Here we can use a simple rule that whenever a user sends a message that starts with “/a “, we add the following text as a todo.

For example, when a user sends “/a Do Homework”, we add “Do Homework” as a todo of our user. Therefore, the state of the user will become:

// context.state
{
todo:[
{
title: "Do Homework"
}
]
}

We can implement this feature by the following code in src/index.js:

Now, when we enter something like /a Do Homework , our bot will reply with a message that tells us it has added our todo item!

List all Todos

How can we know a todo has been successfully added to a user’s todo list? Now, we should support the feature that enables a user to list their todos. Here we define the rule that whenever a user sends a message /l, we reply with a list of the user’s todos.

Now our code in src/index.js will be like:

In the above code, we list all of a users todo from its state and send it to the user with an index of each item.

Delete a Todo

Next, it’s time to enable a user to delete a todo when the user finishes one. However, to use the same method for a user to type something like /d myTodoTitle is quite inconvenient since the user may have typos in their todo name. Therefore, we are going to use one feature from Facebook Messenger: GenericTemplate.

A single generic template is structured as:

We can send generic template to a user with the method context.sendGenericTemplate(). Therefore, to send a carousel of generic templates, we can use the following code:

We can utilize this feature and use generic template to list our todo. By doing so, we can simply add a delete button under each todo item to make deletion easier. We replace the code of listing todos with the following:

Now, when the user sends/l, we will reply with:

Next, what will happen when the user click a delete button? Our App will get another message with the type named postback. We can use context.event.isPostback to determine whether a message is a postback one or not.

Therefore, we can use the following code to handle the deletion of a todo:

When a user clicks a delete button, the user will automatically send a postback message with Delete as its title and the Todo Title as its payload.

And here we are. Our App now has basic functionality as a todo app.

Refactor with Router

Introduce Routing

Although we have implemented the basic functionality, our code seems to be a little bit hard to maintain and its readability should be improved. We can utilize a feature named routing from Bottender to help us organize our code.

Here’s a simple example from the official document about how routing works:

router is consist of an array of routes. It returns the function of the first matched route. text is a type of route that will check whether a text message is matched with the route's rule.

Refactor the Todo Bot

By leveraging the design pattern of Routing, we now can organize our code as:

First, we use the regular expression /^\/a/ to handle text message that starts with /a. Meanwhile, as you can see, we use route to define a more complex rule that handles todo deletion.

With router, we can make our code more maintainable when the rules become more complicated. The last thing we are going to do is to add an introduction to our bot. We can teach the user how to use our bot in the introduction.

Add an Introduction

To give a user an introduction, we have to add a Get Started button to our bot. This button will show up whenever a new user trying to interact with the bot.

To achieve this, we have to revise our code in the bottender.config.js to:

After that, we run the command in our project folder:

npx bottender messenger profile set

By doing so, whenever a new user click the button, we will get a postpack event with a GET_STARTED payload. Therefore, we can handle it with a router and function.

Here we use another router called payload. When we get a postpack event with payload GET_STARTED, we send our introduction to the user.

That’s it. We just built a Facebook Messenger Chatbot that can help us handle todos with maintainable code!

Hope you found this post useful!

Want to Learn More? Weekly I/O!

Weekly I/O is a project where I share my learning Input/Output. Every Sunday, I write an email newsletter with five things I discovered and learned that week.

Sign up here and let me share a curated list of learning Input/Output with you 🎉

--

--

Cheng-Wei Hu | 胡程維
The Startup

Subscribe to chengweihu.com for new article and newsletter! 新的文章還有電子報可以在 chengweihu.com 訂閱