Facebook Messenger for NodeJS

I've recently been building various chatbots for the Facebook Messenger platform and as they don't have any SDK's or libraries just yet I created my own.

I'm going to show you an example of how to use it with ExpressJS to create a personal chatbot.

Create a project directory

mkdir me-bot && cd me-bot  

Create a package.json

We will create this using default values which we can update later.

npm init --yes  

Install dependencies

We need to install some node modules to use with the app

npm install --save express fbmessenger body-parser dotenv  

As we'll be using some new ES6 features we need to install babel

npm install --save-dev babel-cli babel-preset-es2015  

and create a .babelrc file

echo '{ "presets": ["es2015"] }' > .babelrc  

Create a simple server with Express

Create an entrypoint

touch main.js  

Open main.js in your text editor and add the following

'use strict';

import dotenv from 'dotenv';  
import express from 'express';  
import bodyParser from 'body-parser';

dotenv.config();

let app = express();

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

app.get('/webhook', (req, res) => {  
  res.send('It Works!');
});

app.listen(3000, () => {  
  console.log('Bot listening on port 3000!');
});

Setting up environment variables

We will need to use some environment variables later on, an easy way to do this is with dotenv

Create the .env file

touch .env  

Add the following line

PAGE_ACCESS_TOKEN=<your page access token>  

We will replace this with the correct value once we setup the Facebook app.

Add a start script

Add the following to your package.json

{
...
    "scripts": {
        "start": "babel-node main.js",
        ...
    }
...
}

We can now use npm start to run the server.
If you open http://localhost:3000 you should see the message It Works!.

Setting up the webhook

We can start to add some fbmessenger code to main.js now.

import {  
  Messenger,
  Text,
  Button,
  Element,
  GenericTemplate,
} from 'fbmessenger';

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


// Setup the Messenger client
let messenger = new Messenger({  
  pageAccessToken: process.env.PAGE_ACCESS_TOKEN
});

// Listen for the message event
messenger.on('message', (message) => {  
    console.log(message);
});

// Webhook validation callback
app.get('/webhook', (req, res) => {  
  if (req.query['hub.mode'] === 'subscribe' &&
    req.query['hub.verify_token'] === process.env.VERIFY_TOKEN) {
    res.send(req.query['hub.challenge']);
  } else {
    res.sendStatus(400);
  }
});

// Webhook callback
app.post('/webhook', (req, res) => {  
  res.sendStatus(200);
  messenger.handle(req.body);
});


app.listen(3000, () => {  
...

Create a verification token

The verification token can be anything you like. Try to use a long, high-quality random string.

Then add the verification token to the .env file

VERIFY_TOKEN=<your token>  

Make the app public

In order to setup an app with Facebook we need our app to be available publicly.
There's multiple ways of doing this like uploading it to your web host or using a tool like ngrok to create a proxy to your localhost. If you're just testing this out then ngrok is probably the easiest.

Setting up a Facebook app

Follow the steps in the Quickstart section of the Facebook Developer docs.

The callback url for the webhook should be the one you created in the previous step with the path /webhook appended.
e.g. http://mysite.com/webhook

Enter your url and your verification token and select the messages subscription field when setting up the webhook.

You need to attach your bot to a page, you can create one or use an existing one. Once setup generate the page access token and enter it into the .env file.

PAGE_ACCESS_TOKEN=<your token>  

We should now be able to send/receive messages to our bot.

If you go to your page and click on message which is just below the header image it will open up a message dialog (on desktop).

Send a message and then check your server logs to see if it received it. If using ngrok then it should print out into the terminal.

Responding to messages

Let's update the bot to respond with a structured message containing a button.

messenger.on('message', (message) => {  
  messenger.send(new GenericTemplate(
    [
      new Element({
        title: 'Title',
        item_url: 'http://www.example.com',
        image_url: 'http://www.example.com',
        subtitle: 'Subtitle',
        buttons: [
          new Button({ type: 'web_url', title: 'Button', url: 'http://example.com' })
        ]
      })
    ]
  ));
});

Now the bot should send you a response which will contain a button that opens example.com.

To take this further you can process the message in the event and decide how you want to respond to it.

Some suggestions would be to use Api.ai or Wit.ai to add artificial intelligence to your bot.

You would send the message text to the API and it would return an intent and a response which opens up a whole world of possibilities.

See the fbmessenger docs for more info.

Links