Develop a Facebook Messenger Bot via Lambda/Api Gateway

Muhammet Arslan
Muhammet Arslan
Published in
7 min readOct 18, 2016
AWS Lambda

Recently Facebook has announced its Messenger Api’s to build chat bots to reach “1 Billion People” around the world. And now we will implement this api’s with our aws stack to make our Serverless, Fully-Scale, Fault-Tolerant and Secure Messenger Chat Bot.

So lets start..

First of all, we should create our Lambda function, contains the bot codes.

STEP 1: Create Lambda Function

Go to AWS Console > Lambda > Create new function

With blueprints you can start from a sample app, pre-defined by AWS

For now, pass the integration section. We will define it later.

Simply click “next” button
I’m using Node.js 4.3, and i this tutorial will code with NodeJS but of course you can set your favourite language as well

set the following fields:

  • Name: a name of your function, for example facebookTestChatBox
  • Description: leave as is, not important at this stage
  • Runtime: Your favorite language, i will select nodeJS
  • Lambda function code: leave as is for now, not important at this stage
  • Handler: leave as is, not important at this stage
  • Role: create a basic execution role and set it
  • Memory(MIB): leave as is(128), not important at this stage
  • Timeout: leave as is(10 seconds), not important at this stage

and then simply click Next button to review your function codes.

If everything is OKEY for you, then click Create Function to finish setup.

Alright, now we have a so simple lambda function. We can proceed to API Gateway setup now.

On this step, our mision is create a simple secure routing to provide a rest api for Facebook web hooks. And this api methods will trigger our lambda function.

Okey lets hands on keyboards!

STEP 2: Create API

Browswe to AWS Console > API Gateway > Create API

set the following fields:

  • Name: a name of your api name, for example testMessengerChatAPI
  • Description: leave as is, not important at this stage

And then click Create API button.

And now lets return the Lambda screen and create the trigger with API

In the Triggers tab, click Add Trigger to implement our API with lambda

Click on the Dotted Square and select API Gateway

Select the API, was created step 2, in the API name field and leave the rest as is. And click Submit button.

And now, return the API Gateway section to create new GET/POST method.

Lambda automaticaly create new resource with the name of Lambda function and a new method with ANY type. Now click Actions dropdown and click Create method with GET type.

Integrate this method with lambda function, and find your lambda function in field. After that click save.

On Integration Request settings, expand the Body Mapping Templates section, add new mapping template with value application/json, and in Generate template select box choose the Method Request passthrough value and click on Save button:

Okay, GET method has finished. Now lets implement POST method.

After completed your edits, click Save and of course DEPLOY API in actions pane.

Okay, our API GATEWAY implementation has finished. Now lets turn the Lambda panel to edit our codes.

Step 3: Creating a Facebook APP

Browse to http://developer.facebook.com and click create new app button in apps pane

After that, click “Basic Setup” and filled the below form

Set the following fields:

  • Display Name: a name of your facebook application, for example messenger chat bot (dont need to be a slug)
  • Contact E-Mail: It’s important when time to publish your app
  • Category: It’s important when time to publish your app

On the redirected page, click GET Started, on the row of MESSENGER and proceed to settings of it.

On the messenger settings, first we should create a webhook to trigger our api gateway. To do that, click setup webhook button in webhooks section.

Fill the form as below

Set the following fields:

  • Callback URL: Url endpoint of your api gateway. You got this url on 2. step. You should add your resource name at the end of url
  • Verify Token: Give a secure & random token to match with your lambda function & facebook app
  • Subscription Fields: You can select whatever you want, but messages, message_deliveries, message_read is important.

After you’ve filled required fields, click verify and save button to complete webhook setup

But! There will be a problem while verifying our callback url, because Facebook trying to send an http GET method to this url and verify_token and waiting for a match in your endpoint.

What we should do ? Yes! Lets develop a Lambda Code (Don’t close facebook app pane, we will return this page)

STEP 4 : Implementing “verify” code in Lambda

Go to your lambda function and implement below code in the code tab.

'use strict';var VERIFY_TOKEN = "muhammet_arslan_will_provide_this_token_with_lambda_code";exports.handler = (event, context, callback) => {

// process GET request
if(event.params && event.params.querystring){
var queryParams = event.params.querystring;

var rVerifyToken = queryParams['hub.verify_token']

if (rVerifyToken === VERIFY_TOKEN) {
var challenge = queryParams['hub.challenge']
callback(null, parseInt(challenge))
}else{
callback(null, 'Error, wrong validation token');
}
}
}

Alright, after you have save the Lambda code, turn the STEP 3, and retry to click verify and save button in facebook webhook setup modal.

After that you will redirected to dashboard with “completed” text in webhook section. And now, you can attach your app to your pages. But to this, first you can allow this app to your page and copy your Accesskey to use in lambda function. To to this, click Select a page, and choose a page.

COPY YOUR PAGE ACCESS TOKEN, You cannot get this access token again, you should create new one!

After this, on the settings panel and in webhooks section, we should attach our app to our page. To do that, click Select a Page in this section, and simply select a page :)

Okay! All of the things are completed but only lambda function. Lets go on with lambda function to get the message and send a message.

Step 5 : Implementing messaging codes in Lambda

First we should create else in below of our verify code, and should say to our lambda get the message and echo this message to user again.

'use strict';var https = require('https');var PAGE_TOKEN = "EAAFKwxIr....VtgZDZD";var VERIFY_TOKEN = "muhammet_arslan_will_provide_this_token_with_lambda_code";exports.handler = (event, context, callback) => {// process GET request
if(event.params && event.params.querystring){
var queryParams = event.params.querystring;

var rVerifyToken = queryParams['hub.verify_token']

if (rVerifyToken === VERIFY_TOKEN) {
var challenge = queryParams['hub.challenge']
callback(null, parseInt(challenge))
}else{
callback(null, 'Error, wrong validation token');
}

// process POST request
}else{

var messagingEvents = event.entry[0].messaging;
for (var i = 0; i < messagingEvents.length; i++) {
var messagingEvent = messagingEvents[i];

var sender = messagingEvent.sender.id;
if (messagingEvent.message && messagingEvent.message.text) {
var text = messagingEvent.message.text;
console.log("Receive a message: " + text);

sendTextMessage(sender, "Text received, and you wrote: "+ text.substring(0, 200));

callback(null, "Done")
}
}

callback(null, event);
}
};
function sendTextMessage(senderFbId, text) {var json = {
recipient: {id: senderFbId},
message: {text: text},
};
var body = JSON.stringify(json);var path = '/v2.6/me/messages?access_token=' + PAGE_TOKEN;var options = {
host: "graph.facebook.com",
path: path,
method: 'POST',
headers: {'Content-Type': 'application/json'}
};
var callback = function(response) {var str = ''
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {

});
}
var req = https.request(options, callback);
req.on('error', function(e) {
console.log('problem with request: '+ e);
});

req.write(body);
req.end();
}

Superb! Click save, and test it on your page. But be careful with below:

Make sure the Facebook user from which you’re sending the message is listed as the Admin or Developer or Tester in your app roles (https://developers.facebook.com/apps/YOUR_APP_ID/roles/). Messages from other users won’t work unless your app is approved and publicly released.

Aha! Works as a charm!

Troubleshooting ?

Please simply investigate your cloudwatch logs, and send a webhook from your terminal like :

curl -i -X POST -H 'Content-Type: application/json' -d '{"object":"page","entry":[{"id":43674671559,"time":1460620433256,"messaging":[{"sender":{"id":123456789},"recipient":{"id":987654321},"timestamp":1460620433123,"message":{"mid":"mid.1460620432888:f8e3412003d2d1cd93","seq":12604,"text":"Testing Chat Bot .."}}]}]}' https://www.YOUR_WEBHOOK_URL_HERE

More:

http://github.com/geass

Best,

Muhammet Arslan

--

--