A library to integrate with the Facebook Messenger Platform.
Notice: Please read the CHANGELOG if upgrading to v4. Every message you send must pass the recipients id
- Installation
- Express.js (example usage)
- Events
- Sending messages
- Catching errors
- Getting user details
- Elements
- Attachments
- Templates
- Thread settings
- Sender Actions
- Quick Replies
- Whitelisted domains
- Subscribing an app to a page
- Account linking
- Sending raw payloads
Execute this line in your app directory:
yarn add fbmessenger
or for npm
npm install --save fbmessenger
Import library into your app:
import { Messenger } from 'fbmessenger';
Initialize it:
const messenger = new Messenger({
pageAccessToken: '<PAGE_ACCESS_TOKEN>'
});
First of all visit the official tutorial and make sure you complete these 3 steps:
Steps:
-
Create page on Facebook or use existing one if you already have it
-
Create app on Facebook or use existing one if you already have it
-
Visit your developer account and get the
PAGE_ACCESS_TOKEN
-
Subscribe the app to a page
This is basic usage within an express.js application. For more detailed example look here.
import bodyParser from 'body-parser';
import { Messenger } from 'fbmessenger';
// Configuring Body Parser middleware to parse the incoming JSON and Url-encoded data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Initialize Messenger
const messenger = new Messenger({
pageAccessToken: '<PAGE_ACCESS_TOKEN>'
});
// here we define some listeners:
messenger.on('message', (event) => {
// put your logic here
});
messenger.on('postback', (event) => {
// put your logic here
});
// This example shows how to setup verification using express
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);
}
});
// This route handles the webhook callbacks from Facebook
app.post('/webhook', (req, res) => {
res.sendStatus(200);
messenger.handle(req.body);
});
It's important but not fundamental to verify each request that your application receives to make sure that who is calling your /webhook
endpoint is Facebook and not some other person. That could be done by through verifying the Signature Hash that Facebook sends on every request. You will need to have your APP_SECRET
in hands for performing such verification.
// Function that verifies the signature hash
const verifyRequestSignature = (req, res, buf) => {
const signature = req.headers['x-hub-signature'];
if (!signature) {
throw new Error('Couldn\'t validate the signature.');
} else {
const elements = signature.split('=');
const signatureHash = elements[1];
const expectedHash = crypto.createHmac('sha1', process.env.APP_SECRET).update(buf).digest('hex');
if (signatureHash !== expectedHash) {
throw new Error('Couldn\'t validate the request signature.');
}
}
};
// Pass a function that verifies the signature instead of just calling app.use(bodyParser.json())
app.use(bodyParser.json({ verify: verifyRequestSignature });
Events are triggered when Facebook posts to your webhook url. The following events can be listened for:
- message
- delivery
- optin
- read
- account_linking
- postback
- referral
- checkout_update
- payment
messenger.on(<event>, (message) => {
console.log(message);
});
example console output
{
sender: {
id: 1234,
},
recipient: {
id: 1234,
},
timestamp: 1457764197627,
message: {
text: 'Hello World!'
}
}
Messages are sent using the send(message, recipient)
method.
It returns a Promise (from node-fetch).
If replying to a user, the recipient can be obtained from message.sender.id
in the event listener. Otherwise it should be a Facebook page scope ID from a database or other data store.
messenger.on('message', (message) => {
messenger.send({ text: 'Hello' }, message.sender.id);
});
You can add a catch
to get errors from the request.
messenger.send({ text: "Hello" })
.then(console.log(res))
.catch(err => console.log(err));
or if using async/await you can wrap your code in a try/catch block
messenger.on('message', async (message) => {
try {
await messenger.send({ text: 'Hello' }, message.sender.id);
} catch (err) {
console.error(err);
}
});
Example usage:
messenger.getUser()
.then((user) => {
messenger.send({
text: `Hey ${user.first_name} ${user.last_name}`
}, message.sender.id);
});
Returns object with user data:
first_name
last_name
profile_pic
locale
timezone
gender
is_payment_enabled
https://developers.facebook.com/docs/messenger-platform/send-api-reference/text-message
Example usage:
import { Text } from 'fbmessenger';
messenger.send(new Text('Hello World!'), message.sender.id);
you can also just pass an object to the send
method like this
{ text: 'Hello World!' }
https://developers.facebook.com/docs/messenger-platform/send-api-reference/buttons
import {
Button,
ButtonTemplate
} from 'fbmessenger';
messenger.send(new ButtonTemplate(
'Hey user! Watch these buttons:',
[
new Button({
type: 'web_url',
title: 'Web Url Button',
url: 'http://www.example.com',
}),
new Button({
type: 'postback',
title: 'Postback Button',
payload: 'POSTBACK_INFO',
}),
]
), message.sender.id);
For more examples, check out the tests.
https://developers.facebook.com/docs/messenger-platform/send-api-reference/generic-template
import {
Button,
Element,
} from 'fbmessenger';
...
new Element({
itle: 'Title',
item_url: 'http://www.example.com',
image_url: 'http://www.example.com',
subtitle: 'Subtitle',
buttons: [
new Button({
type: 'web_url',
title: 'Web Url Button',
url: 'http://www.example.com',
}),
new Button({
type: 'postback',
title: 'Postback Button',
payload: 'POSTBACK_INFO',
})
]
});
...
https://developers.facebook.com/docs/messenger-platform/send-api-reference/receipt-template
This element must be used with the Receipt template.
import { Address } from 'fbmessenger';
...
new Address({
street_1: '1 Hacker Way',
street_2: '',
city: 'Menlo Park',
postal_code: '94025',
state: 'CA',
country: 'US'
});
...
https://developers.facebook.com/docs/messenger-platform/send-api-reference/receipt-template
This element must be used with the Receipt template.
import { Summary } from 'fbmessenger';
...
new Summary({
subtotal: 75.00,
shipping_cost: 4.95,
total_tax: 6.19,
total_cost: 56.14
});
...
https://developers.facebook.com/docs/messenger-platform/send-api-reference/receipt-template
This element must be used with the Receipt template.
import { Adjustment } from 'fbmessenger';
...
new Adjustment({
name: 'Adjustment',
amount: 20
});
...
https://developers.facebook.com/docs/messenger-platform/send-api-reference/image-attachment
import { Image } from 'fbmessenger';
messenger.send(new Image({
url: 'http://lorempixel.com/400/400/sports/1/',
}), message.sender.id);
https://developers.facebook.com/docs/messenger-platform/send-api-reference/audio-attachment
import { Audio } from 'fbmessenger';
messenger.send(new Audio({
url: 'http://example.com/audio.mp3',
}), message.sender.id);
https://developers.facebook.com/docs/messenger-platform/send-api-reference/video-attachment
import { Video } from 'fbmessenger';
messenger.send(new Video({
url: 'http://example.com/video.mp4',
}), message.sender.id);
https://developers.facebook.com/docs/messenger-platform/send-api-reference/file-attachment
import { File } from 'fbmessenger';
messenger.send(new File({
url: 'http://example.com/file.txt',
}), message.sender.id);
Attachments can be reused by passing true
as the second parameter. This sets the is_reusable
flag.
const image = new Image({
url: 'http://lorempixel.com/400/400/sports/1/',
is_reusable: true
});
messenger.send(image, message.sender.id);
You can then use the attachment_id
from the response to send the same attachment again
messenger.send(new Image({ attachment_id: 12345 }, message.sender.id);
https://developers.facebook.com/docs/messenger-platform/send-api-reference/button-template
import {
Button,
ButtonTemplate
} from 'fbmessenger';
messenger.send(new ButtonTemplate(
'Hey user! Watch these buttons:',
[
new Button({
type: 'web_url',
title: 'Web Url Button',
url: 'http://www.example.com',
}),
new Button({
type: 'postback',
title: 'Postback Button',
payload: 'POSTBACK_INFO',
})
]
), message.sender.id);
https://developers.facebook.com/docs/messenger-platform/send-api-reference/generic-template
import {
Button,
Element
GenericTemplate
} from 'fbmessenger';
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://www.example.com',
}),
]
}),
...
]
), message.sender.id);
https://developers.facebook.com/docs/messenger-platform/send-api-reference/receipt-template
import {
Button,
Element,
Address,
Summary,
Adjustment,
ReceiptTemplate
} from 'fbmessenger';
messenger.send(new ReceiptTemplate({
recipient_name: 'Name',
order_number: '123',
currency: 'USD',
payment_method: 'Visa',
order_url: 'http://www.example.com',
timestamp: '123123123',
elements: [
new Element({
title: 'Title',
image_url: 'http://www.example.com',
subtitle: 'Subtitle',
currency: 'USD',
quantity: 1,
price: 15
})
],
address: new Address({
street_1: '1 Hacker Way',
street_2: '',
city: 'Menlo Park',
postal_code: '94025',
state: 'CA',
country: 'US'
}),
summary: new Summary({
subtotal: 75.00,
shipping_cost: 4.95,
total_tax: 6.19,
total_cost: 56.14
}),
adjustments: [
new Adjustment('Adjustment', 20)
]
}), message.sender.id);
https://developers.facebook.com/docs/messenger-platform/thread-settings/greeting-text
import { GreetingText } from fbmessenger
const greeting = new GreetingText('Hello');
messenger.setThreadSetting(greeting);
There is also a method to delete the greeting text called deleteGreetingText
https://developers.facebook.com/docs/messenger-platform/thread-settings/get-started-button
import { GetStartedButton } from 'fbmessenger';
const getStarted = new GetStartedButton('start');
messenger.setThreadSetting(getStarted);
When someone first interacts with your bot they will see a Get Started
button. When this is clicked it will send a postback
to your server with the value of start
.
There is also a method to delete the Get Started Button called deleteGetStarted
https://developers.facebook.com/docs/messenger-platform/thread-settings/persistent-menu
import {
PersistentMenu,
PersistentMenuItem
} from 'fbmessenger';
const item_1 = new PersistentMenuItem({
item_type: 'web_url',
title: 'Menu button 1',
url: 'http://facebook.com'
});
const item_2 = new PersistentMenuItem({
item_type: 'payload',
title: 'Menu button 2',
payload: 'menu_button_2'
});
const item_3 = new PersistentMenuItem({
item_type: 'web_url',
title: 'Menu button 3',
url: 'http://facebook.com',
webview_height_ratio: 'tall',
messenger_extensions: true
});
const menu = new PersistentMenu([item_1, item_2, item_3]);
messenger.setThreadSetting(menu);
You can delete the Persistent Menu using the deletePersistentMenu
method
Available actions are
typing_on
typing_off
mark_seen
messenger.senderAction('typing_on', message.sender.id);
Quick Replies work with all message types including text message, image and template attachments.
const reply1 = new QuickReply({
title: 'Example',
payload: 'payload',
});
const reply2 = new QuickReply({
title: 'Location',
content_type: 'location',
});
const quick_replies = new QuickReplies([reply1, reply2]);
const text = new Text('A simple text message')
const payload = Object.assign(text, quick_replies)
messenger.send(payload, message.sender.id)
// Single
messenger.addWhitelistedDomain('http://example.com');
// Multiple
messenger.addWhitelistedDomains(['http://example.com', 'http://example2.com']);
// Single
messenger.removeWhitelistedDomain('http://example.com');
// Multiple
messenger.removeWhitelistedDomains(['http://example.com', 'http://example2.com']);
The easiest way to do this is now through the Facebook developer site. If you need to do this progamatically you can use subscribeAppToPage
You can link and unlink accounts with linkAccount
and unlinkAccount
messenger.linkAccount('ACCOUNT_LINKING_TOKEN');
messenger.unlinkAccount('PSID');
You can also send raw payloads with send
. This lets you use any new features from Facebook while waiting for support to be added to this library.
messenger.on('message', () => {
messenger.send({
"attachment":{
"type":"template",
"payload":{
"template_type":"button",
"text":"What do you want to do next?",
"buttons":[
{
"type":"web_url",
"url":"https://petersapparel.parseapp.com",
"title":"Show Website"
}
]
}
}
}, message.sender.id);
});