





















































One of the trending topics in the tech world this year is conversational interfaces. Everyone from big tech companies to start-ups are putting their bets on it. There is an explosion of virtual assistants and chat bots, and the number is increasing every week.
What is conversational interface and why are companies investing in it? In this post we will learn about it and build a simple bot using the Facebook Messenger Platform.
A conversational interface is an interface that allows the users to interact with computers using natural language, instead of commands or clicks and taps. It can be voice-based like Siri, Ok Google, or Microsoft's Cortana, or it can be text-based like many Slack or Facebook Messenger bots.
Instead of building apps for different platforms, device types, and sizes, companies can now provide a way to interact with their services using voice or text, without the need to download an app or learn how to use it.
Many apps like Slack, Telegraph, and Skype now offer platforms to build virtual assistants or bots. But with more than 1 billion users, Facebook Messenger is definitely the most popular choice.
A Facebook Messenger bot works in the following way:
Let's build a simple Facebook Messenger Bot.
First we need to create a Facebook Page and a Facebook app:
You can use any language or framework to build the bot server. For this example, I am using Node.js.
Let's start by creating an Express.js hello world app. Before we start, we need Node.js and npm installed. Follow the instructions on the Node.js website if you do not have these installed already:
const app = require('express')();
app.set('port', (process.env.PORT || 5000));
app.get('/', function (req, res) {
res.send('Helle World');
});
app.listen(app.get('port'), function () {
console.log('App running on port', app.get('port'))
});
Our hello world app is done. Run the node index.js command and open http://localhost:5000 in your browser. If all is good, you will see 'Hello World' text on the page.
Now that we have the basic app set up, let's add the code to be able to communicate with the Facebook Messenger Platform:
'use strict'
const app = require('express')();
const bodyParser = require('body-parser');
const request = require('request');
const VALIDATION_TOKEN = 'super_secret_validation_token';
const PAGE_ACCESS_TOKEN = '<fb-page-access-token>'; // replace <fb-page-access-token> with your page access token
app.set('port', (process.env.PORT || 5000));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get('/', function (req, res) {
res.send('Helle World');
});
app.get('/webhook', function (req, res) {
if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === VALIDATION_TOKEN) {
res.status(200).send(req.query['hub.challenge']);
} else {
res.sendStatus(403);
}
});
app.post('/webhook/', function (req, res) {
// Iterate over each entry
req.body.entry.forEach(function (entry) {
// Iterate over each messaging event
entry.messaging.forEach(function (event) {
let sender = event.sender.id
if (event.message && event.message.text) {
callSendAPI(sender, `Message received ${event.message.text}`);
}
});
res.sendStatus(200); // Respond with 200 to notify the message is received by the webhook successfully
});
});
function callSendAPI(sender, text) {
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: PAGE_ACCESS_TOKEN },
method: 'POST',
json: {
recipient: { id: sender },
message: { text: text },
}
}, function (error, response, body) {
if (error) {
console.error('Unable to send message', error);
}
});
}
app.listen(app.get('port'), function () {
console.log('App running on port', app.get('port'))
});
Here we have defined two new service endpoints. The first one responds to the GET request and will be used for verification when we set up the webhook. The second endpoint will respond to the POST request. This will process the incoming message and send a response using the callSendAPI method. For now, the server will simply send back the message received from the user.
You can deploy the server anywhere you like. Because of its simplicity, I am going to use Heroku for this tutorial.
Now that the server is ready, we can set up the webhook:
We are ready to test our bot. Go to the Facebook page you created, click on message, and send a message to the bot. If everything is good, you will see a response from the bot.
The bot is working, but we can update it to send a different response based on the user message. Let's create a simple bot for Game of Thrones fans, where if a user types in one of the great house's names, the bot will respond with their house words.
Update index.js with the following code:
'use strict'
const app = require('express')();
const bodyParser = require('body-parser');
const request = require('request');
const VALIDATION_TOKEN = 'super_secret_validation_token';
const PAGE_ACCESS_TOKEN = '<fb-page-access-token>'; // replace <fb-page-access-token> with your page access token
const HOUSE_WORDS = {
STARK: 'Winter is Coming',
LANNISTER: 'Hear Me Roar!',
BARATHEON: 'Ours is the Fury',
TULLY: 'Family, Duty, Honor',
GREYJOY: 'We Do Not Sow',
MARTELL: 'Unbowed, Unbent, Unbroken',
TYRELL: 'Growing Strong',
FREY: 'We Stand Together',
}
app.set('port', (process.env.PORT || 5000));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get('/', function (req, res) {
res.send('Helle World');
});
app.get('/webhook', function (req, res) {
if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === VALIDATION_TOKEN) {
res.status(200).send(req.query['hub.challenge']);
} else {
res.sendStatus(403);
}
});
app.post('/webhook/', function (req, res) {
// Iterate over each entry
req.body.entry.forEach(function (entry) {
// Iterate over each messaging event
entry.messaging.forEach(function (event) {
let sender = event.sender.id
if (event.message && event.message.text) {
callSendAPI(sender, getHouseWord(event.message.text));
}
});
res.sendStatus(200); // Respond with 200 to notify the message is received by the webhook successfully
});
});
function callSendAPI(sender, text) {
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: PAGE_ACCESS_TOKEN },
method: 'POST',
json: {
recipient: { id: sender },
message: { text: text },
}
}, function (error, response, body) {
if (error) {
console.error('Unable to send message', error);
}
});
}
function getHouseWord(text) {
const house = Object.keys(HOUSE_WORDS)
.find(function (houseName) {
return text.toUpperCase().indexOf(houseName) !== -1;
});
return house ? HOUSE_WORDS[house] : 'No house word found :(';
}
app.listen(app.get('port'), function () {
console.log('App running on port', app.get('port'))
});
Now if you type one of the family names defined in our code, the bot will respond with the family words. So if you type 'stark', the bot will respond 'Winter is Coming'.
While you and other page admins can chat with the bot, to make it publicly available, you have to submit the bot for review. This can be done from the app page's 'App Review' option. Fill out the form, and once approved, your bot will be accessible by all Facebook Messenger users.
Although our bot is working, it is not truly conversational. It only responds to a fix set of commands. To build a smarter bot, we need natural language processing. Natural language processors convert natural language text or audio to a format that computers can understand. There are many services that allow us to write smarter bot engines, and one of them is Wit. Wit was acquired by Facebook in 2015. You can read more about Wit and how to integrate it with your bot here.
I hope you enjoyed this post. If you have built any bot on Facebook or any other platform, please share it with us in the comment section below.
Amit Kothari is a full-stack software developer based in Melbourne, Australia. He has 10+ years experience in designing and implementing software, mainly in Java/JEE. His recent experience is in building web applications using JavaScript frameworks like React and AngularJS, and backend micro services / REST API in Java. He is passionate about lean software development and continuous delivery.