Connecting a Rasa Chatbot to Facebook Messenger

Recently, I was curious about what kind of messaging apps/interfaces would ultimately work with a rasa chatbot. While any front-end would technically work as long as there’s an api for that front-end to access text to be fed directly to the Rasa chatbot server, there are other chat bot features that are not as simple as feeding plain text across apis. One example is the button, which lets users click on a button to select an option to direct the conversation further. A chat application such as Facebook Messenger with its own Rasa-created channel connector supports these buttons without manual coding on the part of the developer. However, even for an application like discord that supports buttons beneath messages in the form of “reactions”, since it doesn’t have its own dedicated channel connector, it’s more to get buttons to work as they should and connect to the chatbot appropriately. This post will be about connecting to Facebook Messenger as, even though the process is simpler than creating a custom channel connector (Discord, for example), there are still some specific things to keep in mind and a resource like this would have saved me quite a bit of time. An alternate explanation, the one I followed, is provided by Rasa here.

The first step is installing ngrok. At least during development, this is necessary to forward your rasa bot on your localhost to an accessible web address. In addition, ngrok automatically ensures that your web connection is https instead of the default http connection with rasa (it gives you both http and https addresses), which is important since Messenger only works with https connections. To install ngrok, simply download it here and run the commands listed on the page. For the port number to forward, forward whichever port number Rasa uses for webhooks, which is normally 5005. If your chatbot is in production and has a non-localhost web location, you can skip this step and instead, just check if yourrasahostname.com:5005 returns anything.

Next, create a facebook page. As I learned, it has to be published and publicly available for messenger to work at all, even for testers in the development phase of the chatbot. It can be named whatever, and by default, messenger should be enabled on the page. Then, go to Facebook for Developers and click add a new app. Find messenger in the products section and set it up. Scrolling down the settings, the first section you should see is access tokens. Click add or remove pages and add the page you just made. It will give you a warning most likely concerning authorization or approval. While this would be pertinent for your chatbot to be publicly accessible, if you are just testing it out like me, this isn’t an issue for now. Ignore the warning and give it the permissions it needs. Click on the generate token button and record the token since it is needed later. Open a new tab for the settings of your app and record the app secret found there. You can close the app settings after that.

Locate your app’s credentials.yml file. Add the following to the end, with verify equalling any string you like, secret being the string you got from app secret, and page-access-token being the token you got from generate token.

facebook:
  verify: "rasa-bot"
  secret: "7e238b451c238ad8375923vm27542f9"
  page-access-token: "EBXS9I0Uvj53BAJ0fNl4yzz81KiYnsiZC8x29fZBGsdfWwceITcOu6RkDuVqf53CWefsdfEGGfWFxB3EchxJZCtvlL3SFwerfSDFEtZBUGMgfHWFUohJZCJej5BdjJjw3eoJojeJJA1FlXLU0CEUIHppsRQTq96L9I5UagAD43dgfwOe"

Go back to the settings for the messenger app specifically. The next section you will see on the same messenger settings page is labelled webhooks. In callback url, put

https://[yourngrokurl]/webhooks/facebook/webhook

and for the verify token, put whatever string you put for “verify” in your credentials.yml file. After starting up your rasa bot, you should be able to talk with your bot via messenger (visit your page for the link). Without going through the approval process, you can also add testers to allow them to also use your bot through the roles page.

Building a Docker Instance for a Rasa Chatbot

I recently started the development of my chatbot through Rasa, a framework that provides a pipeline combining existing Natural Language Processing (NLP) technologies and Rasa Core, which determines how the chat bot should respond. The installation of Rasa itself is relatively straightforward. However, in the course of my development, I want to use a tool called Rasa X, which lets me generate and annotate training data for my chat bot by chatting with it without having to input the data manually into the file. Setting up Rasa X to train and run a chat bot is more complicated in that the default installation process would most likely result in errors, as it did for me. It requires several tweaks and specific instructions that can only be found through trial and error, and works better in a Linux environment. To ensure that I wouldn’t have to reproduce these steps every single time I want to set up Rasa, and for the aforementioned Linux reason I decided to set up a Docker container, substituting these steps with a command or two instead. Here’s how I did it:

First, I pulled a base docker image for python on Linux and ran it (note that you have to install Docker Desktop and WSL 2 beforehand if you haven’t done so).

docker pull jupyter/base-notebook:python-3.8.6

docker run -p 5005:5005 -p 5002:5002 -p 80:80 -p 8888:8888 --name rasa -e GRANT_SUDO=yes --user root -e JUPYTER_ENABLE_LAB=yes -v %cd%:/home/jovyan jupyter/base-notebook:python-3.8.6

Then, I ran the following commands inside the CLI prompt of the container to install specific versions of packages that work. The first two lines are critical since installing rasa-x normally with the default dependencies would otherwise lead to a lot of library conflicts. It also installs spaCy, an open source natural language processing library that will be used with Rasa.

pip3 install --upgrade pip==20.2
conda install ujson==1.35 -y
pip3 install rasa-x==0.39.3 --extra-index-url https://pypi.rasa.com/simple
pip3 install spacy==3.0.6 PyDictionary bs4 lxml mathparse discord click==7.1.1
spacy download en_core_web_md

Finally, all that’s left to do is push your own container to Docker hub, replacing julianweng/cory with [yourdockerusername]/[anyprojectname]. On your host (Windows CMD), run the following.

docker commit rasa julianweng/cory:v1.0 
docker tag julianweng/cory:v1.0 julianweng/cory:latest
docker push julianweng/cory:v1.0
docker push julianweng/cory:latest

The final product that I produced can be found at https://hub.docker.com/repository/docker/julianweng/cory. With this, you can quickly set up a Rasa project with Rasa X with all needed dependencies. If you just want to use the docker image and get started with Rasa instead, CD to the directory you want your bot to be in and run these commands instead.

docker run -d -p 5005:5005 -p 5002:5002 -p 80:80 -p 8888:8888 --name rasa -e GRANT_SUDO=yes --user root -e JUPYTER_ENABLE_LAB=yes -v %cd%:/home/jovyan julianweng/cory

rasa init --no-prompt