@artemis-prime/facebook-messenger-bot

1.0.9 • Public • Published

Facebook Messenger Bot


The purpose of this library is to offer a simple, light-weight Facebook Messenger Bot API for Node with ES6 support. Internally, it uses Promises to ensure compatibility with async/await.

Objective: Given a set of inputs, the library automatically selects the optimal message format to display this data.

Install

npm install facebook-messenger-bot --save -E

Example

import {Bot, Elements} from 'facebook-messenger-bot';

const bot = new Bot(myPageAccessToken, myVerification);

bot.on('message', async message => {
    const {sender} = message;
    await sender.fetch('first_name');

    const out = new Elements();
    out.add({text: `hey ${sender.first_name}, how are you!`});

    await bot.send(sender.id, out);
});

const app = express();
app.use('/facebook', bot.router());
app.listen(3000);

Demo

I am a chatbot that helps you find free food. Find me on Facebook Messenger.

API By Example

Attach Express Router for Verification and Receiving Messages

import express from 'express';
import {Bot} from 'facebook-messenger-bot'; // import Bot class

const app = express();
const bot = new Bot(myPageAccessToken, myVerification); // create bot instance

app.use('/facebook', bot.router()); // use the router
app.listen(3000);

Receive Messages

import {Elements} from 'facebook-messenger-bot';

bot.on('message', async message => {
    const {sender} = message;

    // get sender id
    console.log(`Received a message from ${sender.id}`);

    // fetch additional user properties
    await sender.fetch(`first_name,last_name,profile_pic`, true); // true: use cache

    console.log(`Fetched ${sender.first_name}, ${sender.last_name}, ${sender.profile_pic}`);

    const {text, images, videos, location, audio} = message;

    if (text) {
        console.log(text);      // 'hey'
    }

    if (images) {
        console.log(images);    // ['http://...', 'http://...']
    }

    if (videos) {
        console.log(videos);    // ['http://...', 'http://...']
    }

    if (location) {
        console.log(location);  // {title, long, lat, url}
    }

    if (audio) {
        console.log(audio);     // url
    }

    console.log(message);       // log the message to learn about all the attributes
});

Send Responses

import {Bot, Elements} from 'facebook-messenger-bot'; // import Bot class

bot.on('message', async message => {
    const {sender} = message;

    let out, buttons;

    // ---- send text
    out = new Elements();
    out.add({text: 'hey! what up'});
    await bot.send(sender.id, out);

    // wait for 1s
    await Bot.wait(1000);

    // ---- send image
    const out = new Elements();
    out.add({image: 'https://developers.facebook.com/images/devsite/fb4d_logo-2x.png'});
    await bot.send(sender.id, out);

    await Bot.wait(1000);

    // ---- send buttons (single card)
    buttons = new Buttons();
    buttons.add({text: 'Google', url: 'http://google.com'});
    buttons.add({text: 'Yahoo', url: 'http://yahoo.com'});
    buttons.add({text: 'Bing', url: 'http://bing.com'});
    out = new Elements();
    out.add({text: 'search engines', subtext: 'click to get redirected', buttons}); // add a card
    await bot.send(to, out);

    // ---- send share/call buttons
    buttons = new Buttons();
    buttons.add({text: 'Call us', phone: '+808 863718243'});
    buttons.add({share: true});
    out = new Elements();
    out.add({text: 'ABC Flower shop', subtext: 'Office hours 10am - 6pm', buttons}); // add a card
    await bot.send(to, out);

    await Bot.wait(2000);

  	// ---- send list
  	out = new Elements();
    out.setListStyle('compact'); // or 'large'
  	out.add({text: 'Item 1', subtext: 'Subtitle'}); // add list item
  	out.add({text: 'Item 2', subtext: 'Subtitle'}); // add list item
  	await bot.send(sender.id, out);

    // ---- send image + buttons (multiple cards)
    buttons = new Buttons();
    buttons.add({text: 'Google', url: 'http://google.com'});
    buttons.add({text: 'Yahoo', url: 'http://yahoo.com'});
    out = new Elements();
    out.add({image: 'http://google.com/logo.png', text: 'hey', buttons}); // first card
    out.add({image: 'http://yahoo.com/logo.png', text: 'hey', buttons}); // second card
    await bot.send(to, out);

    // ---- send call button
    buttons = new Buttons();
    buttons.add({text: 'Call us now', phone: '+16505551234'});
    out = new Elements();
    out.add({text: 'Contact us', subtext: 'click to start a phone call', buttons});
    await bot.send(to, out);

    // ---- send quick reply for location
    let replies = new QuickReplies();
    replies.add({text: 'location', isLocation: true});
    out = new Elements();
    out.add({text: 'Send us your location'});
    out.setQuickReplies(replies);
    await bot.send(to, out);
});

Handle Postbacks

bot.on('message', async message => {
    const {sender} = message;

    let out, buttons;

    // ---- send buttons
    buttons = new Buttons();
    buttons.add({text: 'Google', data: 'google', event: 'search-engine'});
    buttons.add({text: 'Bing', data: 'bing', event: 'search-engine'});
    buttons.add({text: 'Yahoo', data: 'yahoo', event: 'search-engine'});
    out = new Elements();
    out.add({image: 'http://someimage.com', text: 'hey', buttons});
    await bot.send(to, out);
    await Bot.wait(2000);
});

bot.on('search-engine', async (data, message) => {
    console.log(data); // google, bing, or yahoo
});

// all postbacks are emitted via 'postback'
bot.on('postback', async (event, message, data) => {
    assert(data === message.data);
    assert(event === message.event);

    console.log(event, message, data);
});

// if the data cannot be parsed, an 'invalid-postback' is emitted
bot.on('invalid-postback', async (message) => {
    console.log(message);
});

Delivery and Optin

bot.on('optin', async (message, param) => {
    assert(param === message.param);
    assert(param === message.optin);

    console.log(message, param);
});

bot.on('delivery', async (message, mids) => {
    assert(mids === message.delivered);

    console.log(message, mids);
});

Set/Delete Greeting and Set Get Started

(async function () {
  console.log(await bot.setGreeting('Hi my name is Freedaa, I can help find free food around and share the free food you find!'));
  console.log(await bot.setGetStarted({data: {action: 'GET_STARTED'}}));

  // console.log(await bot.setGetStarted(null)); // DELETE greeting
})();

Set/Delete persistent menu

(async function () {
  // use postback buttons for the menu, other buttons are not supported by facebook
  menuButtons = new Buttons();

  menuButtons.add({text: 'Google', data: 'google', event: 'search-engine'});
  menuButtons.add({text: 'Bing', data: 'bing', event: 'search-engine'});
  menuButtons.add({text: 'Yahoo', data: 'yahoo', event: 'search-engine'});

  console.log(await bot.setPersistentMenu(menuButtons));

  // console.log(await bot.setPersistentMenu(null)); // DELETE Persisten menu
})();

Sender Actions

Sender actions allow you to mark messages as read, and set the typing indicator on or off.

  // Show the typing indicator. to is a sender id.
  await Bot.startTyping(to);

  // Hide the typing indicator. to is a sender id.
  await Bot.stopTyping(to);

  // Show or hide the typing indicator. to is a sender id. showTypingIndicator is a boolean. True shows the indicator, false hides it.
  await Bot.setTyping(to, showTypingIndicator);

  // generic senderAction function, can be used to set all options.
  await Bot.senderAction(to, 'mark_read');
})();

Pipe Messages into Bot (i.e. I don't use Express!)

bot.handleMessage(req.body);

Debugging

buttons = new Buttons();
out = new Elements();

...

// you can compare these output with the ones provided on the Facebook website
console.log(buttons.toJSON());
console.log(out.toJSON());

// access raw parsed object via 'message' event
bot.on('message', message => {
    console.log(message.raw);
});

Extras: Fetch User

const user = await bot.fetchUser(id, 'first_name,last_name', true);   // true for cache

Next Release (very soon)

  • Create receipt messages

Maintainers

Looking for additional maintainers this repo. Let me know if you are interested.

Readme

Keywords

none

Package Sidebar

Install

npm i @artemis-prime/facebook-messenger-bot

Weekly Downloads

10

Version

1.0.9

License

ISC

Last publish

Collaborators

  • artemis-prime