Developing Facebook Messenger chatbots using Wit.ai, Node.js, Elasticsearch, Redis and MongoDB
In this post we’ll look at how we developed our first production ready chatbot, the Oor bot, focusing particularly on the building blocks, their role and how all of them are connected. So this post will be more or less technical.
Oor is a Facebook Messenger bot that helps to find the best places around for different activities including eating, working, hanging out with friends and a lot more. You can read more about features of Oor here.
The choice of the platform
The idea of creating a chatbot came to me right after I heard about the Messenger Platform beta at F8 conference early this year. I remember being so excited that you can finally talk to a non-human being in the Facebook Messenger that I had decided to try it out immediately.
So the choice of the bot platform was obvious, it was going to be Facebook Messenger Platform. Luckily, previous dev experience with Facebook APIs, like the Graph API, make it easy to understand.
Last but not least, Messenger's massive reach is decisive - more than a billion users are on the platform. More than billion users are in Messenger. If you're developing a bot for teams, Slack could be a better fit.
Natural Language Processing
It was the first time I or anyone in our company developed a chatbot, so we didn't have experience with what to use for what and so I just followed the recommendation from the Messenger Platform page to use wit.ai. Later I realized how immature wit.ai was at that time, but it actually helped me a lot to dig deeper into the bot development. Then at a tech summit, a couple folks suggested I try api.ai and other services which have more accuracy and fewer surprises. The Oor bot was already working at that time and since wit.ai is backed by Facebook it seemed like a good investment of time and knowledge, so I stuck with it. Now while wit.ai is still under heavy development and the main feature of stories is still in beta, it seems to be very good choice to develop a chat bot especially for Messenger - it has exclusive features for that.
Wit.ai is able to do two very important things - understand the intent of the message and extract structured data from it. While constructing stories seems like a cool feature Oor is not really using it.
The data storage choice was made on a bit later stages of the development of the bot, and it was mainly driven by the logical and functional reasons. We are using MongoDB, Elasticsearch and Redis with Oor, but I will answer to the "why?" question later.
This is the overview of the Oor bot technologies and actually this model could be used for many other bot types. To understand why do we need each of these elements let’s consider a typical case when user sends a message to the Facebook page with a chat bot behind.
This is what's happening step by step
- User sends a message to the Facebook page
- The webhook of Facebook application(s) subscribed to the page messages event being called
- The server (Node.js) receives a post request with the event data
- The server gets existing or create a new session by the sender ID
- Depending on the type of the event received the server decides should it be processed internally (like when user sends a location, a postback or an attachment) or it should be forwarded to the NLP service (wit.ai in our case)
- After forwarding the message to the wit.ai API some action will be called, either wit.ai will propose some reply message or it will invoke a custom action that we have defined. Anyway this part is heavily depends on the business logic of the chat bot application and here is where in case of Oor MongoDB and Elasticsearch are used.
- At the end of this cycle we get a message to reply to the user and to do that the server performs an API call to the Graph API
- User finally gets the reply.
This is a simplified version of what is happening, but it's quite enough to understand the main principles.
Lets consider each module from the diagram separately with its responsibilities.
Messenger Platform behaves as a link between Facebook page, Facebook application and the server. The connection with the server is made by using web-hooks. There are several different event types including user sending a message or an attachment, quick replies, post-backs and even typing events. To fully understand the capabilities of the Messenger Platform please visit https://developers.facebook.com/docs/messenger-platform
The Server - Node.js Instances
The server handles all webhook requests from the Messenger Platform and implements the business logic of the application itself by using all necessary external services. This is where you define what your application should do for the different use case scenarios.
NLP Service - Wit.ai
Once there is something to say to the user, or maybe send some attachment the server performs an API call to the Graph API, sending a message data, including the sender ID, Facebook user's ID associated with the page he/she is talking to. To perform the call we need a access_token. The sender ID also could be used to get user's public profile data from the Graph API, like name, picture, gender, time zone.
Redis - Session Storage
To have a chat bot that is capable of talking to more than one user, and where it should distinguish the context of chats, you have to have a session and store it somewhere. Session storage is responsible for tracking the context of the conversation with each user. There can be many different ways of implementing a session store. The simplest way is to store it in the run-time of the server, though this is limited only to single instance server applications, not scalable and is not reliable at all. Redis is a very good solution for implementing a session store, it's fast, robust and easily shareable among many instances of the server nodes.
Data Storage - MongoDB and Elasticsearch
Oor chat bot uses MongoDB for data persistence. It includes the user data, preferences, the database of places and some other information. Elasticsearch here is used for full text search and for filtering places and sorting them based on more than 35 different criteria like type of the place, kitchens, main dishes and drinks, music type, location, working hours and etc. It allows to find the best match for almost any kind of complex request.
I hope this introduction to the architecture of the Oor chat bot was useful and gave you some idea how you should start building your chat bot. As you can see this technology stack is quite simple, though capable to solve many different issues while building intellectual artificial beings in the Facebook Messenger. As further steps of the Oor development we think about integration of spaCy, that will allow more deeper processing of text sentences. spaCy is able to solve many very serious tasks like extracting entities, dependency tracking, sentence segmentation. This will allow us to improve Oor bot to understand phrases like "cold dark beer", or "pizza with anchovies" and in general solve many difficult tasks.
Thanks for reading, will be happy to hear your comments and learn about what kind of bot do you develop and what is your technology stack.
P.S. Soon we will share on github the chat bot application code boilerplate based on the described technology stack. I think it will be very helpful to quick start messenger bot development.