Building a Serverless Facebook messenger chatbot
You may have heard about “the next big thing”: Chatbots!
But how do you develop your own chatbot? What do you need to know to join the hype? You may think that it’s rather difficult to program your own chatbot. But that’s not the case.
This tutorial will show you how you’ll develop your first chatbot for the Facebook messenger platform.
We’ll build it with the help of the Serverless framework which is a perfect fit for an application like a chat bot.
Let’s dive right into it!
What are chatbots?
Today, more and more people use chat application such as WhatsApp, Facebook messenger or even Slack when they’re working to communicate and plan their lives.
You’re chat application of choice is probably the most used app on your smartphone. Why should you be restricted talking to humans only? What about if you could book your next hotel room or even vacation with the help of a quick chat with your vacation planner? What if you could chat about the shoes you need rather than surfing through the webshop without guidance.
Chatbots are a way to fill those gaps. They’re small computer programs which chat with you in a way like a human would talk to you.
Microsoft is one of the companies which is sold on chatbots. More and more messenger companies open APIs so that you can develop your own chatbot based on their platform. Telegram has even started a challenge where they’ll give away 1 Million $ to chatbot devs.
Now is the right time to jump into chatbot development and join the fun. Let’s build our own!
Why Serverless?
Serverless is the perfect fit for a chatbot scenario. Serverless is a framework which helps you to deploy so called Lambda functions on the AWS (Amazon web services) architecture.
What’s so cool about that? The Lambda function includes your code which should be run. The Lambda function is run every time a user uses your chatbot. After that it’s turned off and waiting for a new request. Lambda takes care that your code will run smoothly and takes care of your server setup. You basically don’t need to think about servers at all (therefore serverless) it will just work.
Lambdas can be written in a variety of different languages (such as Node.js, Java, Python, …).
Additional it’s great because you just pay for what you use. You won’t get charged if no-one uses your bot.
Sounds interesting and you want to learn more? Just read our blog post why you should learn Serverless now!
What we’ll build
We’ll build a Serverless Facebook messenger chatbot which will search GitHub repositories for us.
Here’s a demonstration how this will look like once we’re finished:

Take a look at our GitHub repository to read through the source code.
Creating a new Serverless project
At first we need to create our new Serverless project.
If you’re not familiar with Serverless yet you might want to check out our blog post to get started with Serverless.
Run serverless project create to start the interactive command prompt and create the serverless application with the name serverless-facebook-messenger-chatbot.
Next up we open the newly created Serverless application in our favorite editor.
Create a new function with an endpoint
The first thing we want to do is to create a new function called webhook with a corresponding endpoint. Run serverless function create webhook in the terminal and choose the nodejs4.3 (We’ll use the latest and greatest JavaScript :-)) runtime as well as Create a new endpoint.
Serverless will create a Lambda scaffold for use with a corresponding API Gateway endpoint.
Let’s test if everything works as expected. Run serverless dash deploy which will open up our deployment dashboard. Select the function and the endpoint. Move the cursor to the entry deploy and hit enter. The function and the endpoint will now be deployed for us. You’ll receive a URL you can copy and paste into your browser. You should see a message that the Lambda function executed successfully. Great. Now we have everything in place to implement our chatbot!
Create a new Facebook app
Header over to https://developers.facebook.com/apps/ and create a new app called Serverless Chatbot.
After that click on Add product in the Product settings of your previously created application. Click on Get started next to the messenger entry.
Setting up the applications webhook
Facebook messenger will send all the messages of your Facebook application to your /webhook route of your application.
We need to write some code so that we can add the webhook to our Facebook application.
At first we need to update the s-function.json file like this:
{
"name": "webhook",
"runtime": "nodejs4.3",
"description": "Serverless Lambda function for project: serverless-facebook-messenger-chatbot",
"customName": false,
"customRole": false,
"handler": "handler.handler",
"timeout": 6,
"memorySize": 1024,
"authorizer": {},
"custom": {
"excludePatterns": []
},
"endpoints": [
{
"path": "webhook",
"method": "GET",
"type": "AWS",
"authorizationType": "none",
"authorizerFunction": false,
"apiKeyRequired": false,
"requestParameters": {},
"requestTemplates": {
"application/json": {
"hubChallenge": "$input.params('hub.challenge')",
"hubVerifyToken": "$input.params('hub.verify_token')",
"method": "$context.httpMethod"
}
},
"responses": {
"400": {
"statusCode": "400"
},
"default": {
"statusCode": "200",
"responseParameters": {},
"responseModels": {},
"responseTemplates": {
"application/json": ""
}
}
}
}
],
"events": [],
"environment": {
"SERVERLESS_PROJECT": "${project}",
"SERVERLESS_STAGE": "${stage}",
"SERVERLESS_REGION": "${region}"
},
"vpc": {
"securityGroupIds": [],
"subnetIds": []
}
}
We’ve added the request mapping in the requestTemplates section. This way we can access and process the incoming bot requests parameters and get the HTTP method which is used.
After that we need to update our handler.js file as follows:
'use strict';
module.exports.handler = function(event, context, callback) {
if (event.method === 'GET') {
// facebook app verification
if (event.hubVerifyToken === 'STRONGTOKEN' && event.hubChallenge) {
return callback(null, parseInt(event.hubChallenge));
} else {
return callback('Invalid token');
}
}
};
Here we simply check if we have an incoming GET request and the request made by the chatbot contains the token STRONGTOKEN (you should move this into environment variables later on).
We need this functionality soon so that we can verify that our bot is the correct bot which wants to talk to our application.
Done. Redeploy the function and the endpoint with serverless dash deploy.
Now we go back to the app settings page.
Click on Setup webhooks. Paste the API URL from the console into the Callback URL field. Enter STRONGTOKEN into the Verify token field. Check all checkboxes and click on verify and save.
Now Facebook will send a request to our Serverless application. it will check if the token we’ve entered in the app settings is the one of our application. It will setup the webhook if this is correct.
Create a new Facebook page
Every messenger application needs a corresponding Facebook page. Go to https://www.facebook.com/business/products/pages and create a new Facebook page. We’ll name it “Serverless Chatbot” (the same name as our application).
Creating an authentication token
Great. Now you need to connect the application with the Facebook page. Go to the app settings and select the previously created Serverless Chatbot page in the Token Generation section. Accept that the app will interact with the page. After that a token will be generated.
Open up a terminal and run this code:
curl -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=<PAGE_ACCESS_TOKEN>"
Replace the PAGE_ACCESS_TOKEN with your page access token you’ve just generated.
You should see the message {“success”: true}
We’ve successfully setup everything so that all parts can communicate.
Replying to user messages
Let’s react on messages which a user might send.
At first we need to add another endpoint to our s-function.json file. This endpoint is a POST endpoint because messages will arrive via POST
{
"name": "webhook",
"runtime": "nodejs4.3",
"description": "Serverless Lambda function for project: serverless-facebook-messenger-chatbot",
"customName": false,
"customRole": false,
"handler": "handler.handler",
"timeout": 6,
"memorySize": 1024,
"authorizer": {},
"custom": {
"excludePatterns": []
},
"endpoints": [
{
"path": "webhook",
"method": "GET",
"type": "AWS",
"authorizationType": "none",
"authorizerFunction": false,
"apiKeyRequired": false,
"requestParameters": {},
"requestTemplates": {
"application/json": {
"hubChallenge": "$input.params('hub.challenge')",
"hubVerifyToken": "$input.params('hub.verify_token')",
"method": "$context.httpMethod"
}
},
"responses": {
"400": {
"statusCode": "400"
},
"default": {
"statusCode": "200",
"responseParameters": {},
"responseModels": {},
"responseTemplates": {
"application/json": ""
}
}
}
},
{
"path": "webhook",
"method": "POST",
"type": "AWS",
"authorizationType": "none",
"authorizerFunction": false,
"apiKeyRequired": false,
"requestParameters": {},
"requestTemplates": {
"application/json": {
"payload": "$input.json('$')",
"method": "$context.httpMethod"
}
},
"responses": {
"400": {
"statusCode": "400"
},
"default": {
"statusCode": "200",
"responseParameters": {},
"responseModels": {},
"responseTemplates": {
"application/json": ""
}
}
}
}
],
"events": [],
"environment": {
"SERVERLESS_PROJECT": "${project}",
"SERVERLESS_STAGE": "${stage}",
"SERVERLESS_REGION": "${region}"
},
"vpc": {
"securityGroupIds": [],
"subnetIds": []
}
}
The request template implements the httpMethod detection and parses the JSON which arrives so that we can use those two values inside our handler.
Next up we need a way to communicate with GitHub and send a response back to Facebook. We do this via HTTP requests. There a built in Node.js HTTP(S) libraries but we’ll use axios as it’s Promise based and makes HTTP requests handling easy.
Create a package.json file inside the webhook directory (on the same level where your s-function.json file lives) and paste in the following content:
{
"name": "webhook",
"version": "0.1.0",
"dependencies": {
"axios": "^0.11.0"
}
}
After that run npm install inside the webhook folder to install axios. Now we can use the axios package inside our handler function.
The last part is our handler function. Open up handler.js and update it as follows:
'use strict';
let axios = require('axios');
module.exports.handler = function(event, context, callback) {
let accessToken = 'ACCESSTOKEN';
if (event.method === 'GET') {
// facebook app verification
if (event.hubVerifyToken === 'STRONGTOKEN' && event.hubChallenge) {
return callback(null, parseInt(event.hubChallenge));
} else {
return callback('Invalid token');
}
}
if (event.method === 'POST') {
event.payload.entry.map((entry) => {
entry.messaging.map((messagingItem) => {
if (messagingItem.message && messagingItem.message.text) {
axios.get('https://api.github.com/search/repositories?q=' + messagingItem.message.text + '&sort=stars&order=desc')
.then((response) => {
let message = `Sorry, I found no repositories for your query "${messagingItem.message.text}"`;
if (response.data.items.length > 0) {
let repositories = response.data.items.map((repository, index) => `${index + 1}: ${repository.html_url}`);
message = `Here are some repositories which might be interesting:\n\n${repositories.slice(0, 5).join('\n')}`;
}
let payload = {
recipient: {
id: messagingItem.sender.id
},
message: {
text: message
}
};
let url = `https://graph.facebook.com/v2.6/me/messages?access_token=${accessToken}`;
axios.post(url, payload)
.then((response) => {
return callback(null, response);
})
});
}
});
});
}
};
Replace the accessToken variable with the value you’ve created when connecting your Facebook app to your page.
What’s happening here?
At first we imported axios so that we can use it inside our handler function. After that we’ve added a check if the incoming request is a POST request. After that we extract the Facebook users id and the message.
We issue a GET request to the GitHub API to search for repositories based on the message the user gave us.
After that we create an array with the 5 most starred repositories.
This array get’s appended to the message we send back to the user.
Nest up we issue a POST request to the Facebook API and send the message with the 5 most starred GitHub repositories back to the user.
A final deploy
Run serverless dash deploy and deploy your endpoint and function.
Finished. Now you can open up the Facebook page of your bot and start chatting! Great.
Releasing your chatbot to the public
You might want to share your chatbot with your friends so that they can use it to search for GitHub repositories as well. That won’t work for now. You need to get your chatbot approved by Facebook beforehand so that others can use it.
You can start the approval of your chatbot in your Facebook app settings page.
A more feature rich example
This is a basic Facebook messenger chatbot implementation. You might want to check out Michael Sangers Facebook messenger bot which has a more feature rich implementation.
Conclusion
Chatbots are really easy and fun to develop. Serverless is a perfect fit for a chatbot application as it only runs our code if a user uses our chatbot. Furthermore it scales infinitely. So you’re all set to develop the next chatbot unicorn and don’t need to care about scalability and server administration.