launch-vehicle-fbm v1.10.0
Facebook Messenger Chat Kit
An event driven SDK for Facebook Messenger chat bots.
FBM is a full-featured, opinionated Facebook Messenger SDK for writing bots. In addition to wrappers around the Messenger API, you get:
- A session store for storing state between messages
- Auto-populated profile information so you can address by name from anywhere
- Listeners for greetings and help text to follow best practices
- Easy to add metrics to your bot
- Support for deployment on multiple pages
Usage
const { Messenger } = require('launch-vehicle-fbm');
const messenger = new Messenger(options);
messenger.start(); // Start listeningOptions
cache(default: cacheman memory cache) See Session cachehookPath(default:/webhook)pages: A map of page ids to page access tokens{1029384756: 'ThatsAReallyLongStringYouGotThere'}. Currently optional but config will migrate to this in the futureport(default:3000)emitGreetings(default: true) When enabled, emits common greetings astext.greetingevents. When disabled, no check is run andtextevents will be emitted. Optionally, can be set to aRexExpobject which will enable the option and use the specified expression instead of the built-in default.
Additional options are set via environment variables. See example.env for an
example.
Endpoints
/webhook(override withoptions.hookPath) -- The Messenger webbhook/pause-- Dashbot compatible pause for live person takeovers. See Dashbot's docs for usage. Currently, pauses only last for 12 hours in case the operator forgets to unpause
Responding to events
We emit a variety of events. Attach listeners like:
// General form
// messenger.on(eventName, ({dataItem1, dataItem2}) => {});
const { Messenger, Text, Image } = require('launch-vehicle-fbm');
const messenger = new Messenger();
messenger.on('text', ({reply, text}) => {
if (text.includes('corgis')) {
reply(new Text('aRf aRf!'))
.then(() => reply(new Image('https://i.imgur.com/izwcQLS.jpg')));
}
});
messenger.start();Event data
All events contain the following attributes in the data:
eventThe raw eventreply: FunctionReply back to the user with the argumentssenderIdThe ID of the sendersessionA Session object you can mutate
In addition, data contains these attributes on specific events:
textText messagesourceOne ofquickReply,postback,texttextOriginal message content:event.message.textfor text events andpayloadforpostbackandquickReplyeventsnormalizedTextNormalized message content
text.greeting(optional, defaults to enabled) Text messages that match common greetingsfirstNameTrimmed first name from the user's public Facebook profilefullNameConcatenating offirstNameandsurNamewith a single, separating spacesurNameTrimmed first name from the user's public Facebook profile
text.help(optional, defaults to enabled) Text messages that match requests for assistance- no additional attributes provided
messageAny kind of message event. This is sent in addition to the events for specific message types.messageDirect access toevent.message
message.imageImage (both attached and from user's camera)urlDirect access toevent.message.attachments[0].payload.urlfor the url of the image
message.quickReplyFor conversation, use thetextevent, this is for the raw message sent via a quick reply buttonpayloadQuick reply content,event.quick_reply.payload
message.thumbsupUser clicked the "thumbsup"/"like" button- no additional attributes provided
message.stickerSticker- no additional attributes provided
message.textFor conversation, use thetexteventtextMessage content:event.message.text
message.quickReplyFor conversation, use thetextevent, this is for the raw message sent via a quick reply buttonpayloadQuick reply content:event.quick_reply.payload
postbackFor conversation, use thetextevent, this is for the raw message sent via a postbackpayloadPostback content:event.postback.payload
referralFires when a user scans your Messenger codereferralReferral content (from Facebook):referral.refA customreffor a parametric codereferral.sourceMESSENGER_CODEreferral.typeOPEN_THREAD
Other Events
app.startingsignal that theMessenger.starthas been called and the application is in the process of coming onlineapp.startedsignal that the SDK's Express server is now listening on the specifiedportand ready for requestsfinish(optional) Signal that you're done processing. This is mostly useful for your tests when you have Promise chains. The SDK currently does nothing with this event.postback: https://developers.facebook.com/docs/messenger-platform/webhook-reference/postback-received
Normalized message content
To help keep application code simple, the SDK makes these guarantees about normalized text:
- it will be lowercase
- it will be stripped of leading and trailing whitespace
A special note about echo events
If you enable message_echoes in your Messenger webhooks, you'll get bot
messages too. You'll need to examine event.message.is_echo in your handlers.
The session object
The SDK uses cacheman to maintain session data per user. The session object is passed through each event
and can be read from or written to as needed. While the session is automatically saved in routeEachMessage,
there are instances where it may be advantageous to manually trigger a save; this can be accomplished by using
messenger.saveSession. The session object has a copy of its own session key (pro tip: do not modify or remove
_key) so the session object is the only parameter that needs to be passed into saveSession.
The SDK sets some values in the session:
count:inthow many events have been received from this userlastSeen:intThe time (in milliseconds since epoch time) we last saw activityprofile:Object, the profile as retrieved from Facebook Messenger. See the docs for the most up to date information. If a profile can't be pulled, it's{}, otherwise, here are some of the more useful fields for quick reference:profile.first_name: first nameprofile.last_name: last nameprofile.profile_pic: profile picture
source:string|undefinedA guess of where the user came from for this session:directTODO, not implemented yetreturnA returning visitorwebCame from a "Send to Messenger" button on a websiteundefinedUnknown
Session cache
If you want to customize the cache, you can supply your own cache in the
Messenger constructor. By default, it uses the cacheman memory cache, but
any cache that follows these simple patterns will work:
cache.get(key: string): ?Promise<Object>cache.set(key: string, value: Object): Promise<Object>
We strongly suggest using something like Redis that will persist across restarts. There are examples in the wiki.
Other APIs
require('launch-vehicle-fbm').SESSION_TIMEOUT_MS: This constant is available if you need some sort of magic number for what to consider a session lengthMessenger.app: The base Express app is available for you here
Logging and metrics
- debug is for a firehose of data sent to stdout/stderr
- dashbot is a service we're trying that gives us analytics tailored for bots.
- winston is like dashbot and a subset of debug, but it's designed specifically to let us recreate/monitor conversations.
Optional environment variables:
DASHBOT_KEY- If this is present, dashbot integration will be onLOG_FILE– winston will log conversations to this file. It should be an absolute pathSLACK_CHANNEL- The Slack channel winston should use, can be a name or an idSLACK_WEBHOOK_URL– The webhook url is required for winston to send to Slackdebug: https://github.com/visionmedia/debug
dashbot: https://www.dashbot.io/
Prior art
There are many other Messenger Node packages; we made a page to help you decide if this is the appropriate one for your project: https://github.com/CondeNast/launch-vehicle-fbm/wiki/Prior-art