This tutorial is a step-by-step guide to create a simple Facebook Messenger bot using node.js on the localhost. For testing the bot, No need to upload on a cloud server.

For understanding purposes, we’ll keep it simple and will reply with a greeting message when a user sends a hello message on messenger chat.

What is Webhook?

webhook is an HTTP API to send real-time information to other applications.

When a user type ‘Hello’ and enter, This message will be sent to our website via a webhook. A webhook can be programmed using any server-side programming languages. In this tutorial, we’ll use node.js to write this webhook.

FB Page & App Setup

Go to the Facebook login page and log in using your credentials. Click here to create a new Facebook page and follow the wizard to finish.

Go to Facebook Developer account. and click on “My Apps” and then “Create App” link and follow the wizard to finish.

Facebook App

On the app dashboard page, scroll to Messenger and click on Set Up and you’ll be landed on Messenger Setting page. Here first you need to assign a Facebook page to access messenger data and then set up the webhook URL to send the data.

To assign a Facebook page, Go to Access Tokens section and click on Add or Remove Pages. Select the Facebook page and give the required access.

Now generate an access token to be used in our code for authentication. Go to Access token section and click on Generate Token next to the selected page and copy the generated token at the safe place.

To setup webhook, Go to Webhooks section and click on Add Callback URL. Right now we don’t have callback URL so let’s create it first.

Webhook Using Node.js

Create a folder samplebot and go into the folder.

mkdir samplebot
cd samplebot

Initialize node package and enter project details.

npm init

First, install Node Packages required for this project.

npm install request --save
npm install express --save
npm install body-parser --save
npm install crypto --save

Create an app.js file and we’ll write node.js code into this file.

Load Packages

express = require('express');
body_parser = require('body-parser');
request = require('request');
crypto = require('crypto');
app = express();
port = process.env.PORT || 5000

Use BodyParser

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}))

Setup Config

We need 3 things to verify the Facebook signature and send a response back to Facebook.

  • Page Access Token – You have already created this on the Facebook App setting page.
  • Verify Token – This can be any string. This is used to verify the webhook URL.
  • FB App Secret – Go to App Dashboard, click on Settings -> Basic and copy the App Secret.
FB_ACCESS_TOKEN = 'Paste Here';
FB_VERIFY_TOKEN = '123456';
FB_APP_SECRET   = 'Paste Here';

Check Facebook Signature

To make sure that FB requests are coming from our Facebook page, we need to check Facebook signature.

// Check Facebook Signature
app.use(body_parser.json({
    verify: check_fb_signature
}));

function check_fb_signature(req, res, buf) {
    console.log('Check facebook signature step.')
    var fb_signature = req.headers["x-hub-signature"];
    if (!fb_signature) {
        throw new Error('Signature ver failed.');
    } else {
        var sign_splits = signature.split('=');
        var method = sign_splits[0];
        var sign_hash = sign_splits[1];

        var real_hash = crypto.createHmac('sha1', FB_APP_SECRET)
            .update(buf)
            .digest('hex');

        if (sign_hash != real_hash) {
            throw new Error('Signature ver failed.');
        }
    }
}

Verify Webhook URL

A GET request will be triggered to verify the callback URL at the time of adding a webhook.

// Verify Webhook URL
app.get('/webhook/', function (req, res) {
    console.log('Webhook verification step.')
    if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === FB_VERIFY_TOKEN) {
        res.status(200).send(req.query['hub.challenge']);
    } else {
        console.error("Authentication Failed!.");
        res.sendStatus(403);
    }
})

Get User Message

The Facebook app sends a POST request with chat data to the callback URL.

// Handle Post Request to receive messages.
app.post('/webhook/', function (req, res) {
    console.log('Webhook messaging step.')
    var chat_data = req.body;
    // Make sure this is a page subscription
    if (chat_data.object == 'page') {
        // Iterate over each entry
        chat_data.entry.forEach(function (page_body) {
            // Iterate over each message
            page_body.messaging.forEach(function (message_obj) {
                console.log(message_obj)
                if (message_obj.message) {
                    getMessage(message_obj);
                    sendMessage(message_obj.sender.id,"Greeting from Aitude!")
                }
            });
        });

        // Indicate all went well.
        res.sendStatus(200);
    }
});

// Get Message
function getMessage(message_obj) {
    var message = message_obj.message.text;
    console.log(message)
}

// Send Message
function sendMessage(recipient_id, message) {
    var messageData = {
        recipient: {
            id: recipient_id
        },
        message: {
            text: message
        }
    }
    request({
        uri: 'https://graph.facebook.com/v3.2/me/messages',
        qs: {
            access_token: FB_ACCESS_TOKEN
        },
        method: 'POST',
        json: messageData

    }, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log("Messeage sent successsfully.");
        } else {
            console.log("Message failed - " + response.statusMessage);
        }
    });
}

Listen to Server

In the end, Start listening at the server on a specific port.

// Listen Requests
app.listen(port, function () {
    console.log('webhook is running on port', port)
})

Download Code

Fork the GitHub repository here and enter your config details. And get ready to test the script.

Run Code

To start the server, run the following code and hit localhost:5000/webhook/ in the browser.

node app.js

So callback URL is localhost:5000/webhook/ but we need a live public URL to set up a webhook on Facebook app setting.

Use ngrok

ngrok exposes local servers behind NATs and firewalls to the public internet over secure tunnels.

To create a public URL, download the ngrok tool. Start a new terminal and run below command to start an HTTP tunnel on port 5000. Read ngrok documentation here.

ngrok http 5000

Now copy the public URL and go back to the Facebook App dashboard to set up a webhook.

And click on Verify and Save. If there an error then make sure your server is started and public URL is working. Verify Token should be the same as FB_VERIFY_TOKEN.

Next, we need to give permission to access messages and postbacks. Go to the Webhooks section and click on the Add Subscription button next to the selected page.

And choose messages and messaging_postbacks subscription fields and click on the Save button.

Test Chatbot

It’s time to test the chatbot and get a greeting message from our chatbot. Go to your Facebook Page as a visitor and click on Send Message and your Facebook messenger chat window will be opened up and you can type here “Hello”.

This chatbot will receive the message via the webhook and a greeting message will be sent back.