Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

prg-chatbot

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prg-chatbot

Facebook Messenger Chatbot Framework

  • 0.10.6
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
3
Maintainers
1
Weekly downloads
 
Created
Source

Prg-chatbot - Facebook Messenger platform framework

CircleCI

Framework for building reusable chatbot components. Routing, Keyword recognition is built-in.

Requirements and installation

  • requires mongoose > 4.0
  • requires nodejs > 6.0
  • requires express > 4.0
  • requires body-parser > 1.10
$ npm i -S prg-chatbot

Basic setup with Express

It's easy. This basic example can handle everything. Note, that the handler is STRICTLY SYNCHRONOUS.

const express = require('express');
const bodyParser = require('body-parser');
const { createRouter, createProcessor } = require('prg-chatbot/express');

const handler = (req, res, postBack) => {
    res.typingOn()
        .wait();

    switch (req.action()) {
        case 'hello':
            res.text('Hello world');
            return;
        default:
            // send one quick reply
            res.text('What you want?', {
                hello: 'Say hello world'
            })
    }
};

const processor = createProcessor(handler, {
    pageToken: 'stringhere',
    appSecret: 'botappsecret'
});

// app = express();

app.use('/bot', createRouter(processor));

Processing asynchronous actions

How to deal with asynchronous action, when handlers are synchronous? Use postBack(action[, data])).

const handler = (req, res, postBack) => {
    switch (req.action()) {
        case 'downloaded':
            const { data, err } = req.action(true);

            if (err && err.code === 400) {
                res.text('Image size exceeded');
            } else if (err) {
                res.text('Upload failed');
            } else {
                res.text('Hello world');
            }
            return;
        default:
            if (req.isImage()) {
                const resolve = postBack.wait(); // usefull for tests
                bufferloader(req.attachmentUrl(), 1000000)
                    .then(buffer => resolve('downloaded', { data: buffer }))
                    .catch(err => resolve('donwloaded', { err }))
            }
    }
};

Experimental: Router

Router is the way to handle strucured complex bots

const { Router } = require('prg-chatbot');

const app = new Router();

// middleware
app.use('*', (req, res, postBack, next) => {
    res.typingOn()
        .wait();
    next();
});

app.use('actionName', (req, res) => {
    if (req.state.secondAttempt) {
        res.text('hello again');
    } else {
        res.text('hello')
            .setState({ secondAttempt: true });
    }
});

app.use('textAction', /keyword|two-words?/, (req, res) => {
    res.text('Welcome', {
        actionName: 'Say hello' // quick reply
    })
});


API

Classes

Request
Responder
ButtonTemplateBaseTemplate
ReceiptTemplateBaseTemplate
GenericTemplateButtonTemplate
RouterReducerWrapper
ReducerWrapperEventEmitter
Tester
ResponseAssert
AnyResponseAssert
Settings

Functions

bufferloader(url, [limit], [limitJustByBody], [redirCount])

Downloads a file from url into a buffer. Supports size limits and redirects.

attachmentType(response, type, [message])boolean

Checks attachment type

isText(response, [message])boolean

Checks, that response is a text

contains(response, search, [message])boolean

Checks, that text contain a message

quickReplyAction(response, action, [message])boolean

Checks quick response action

templateType(response, expectedType, [message])boolean

Checks template type

waiting(response, [message])boolean

Looks for waiting message

Request

Kind: global class

new Request()

Instance of {Request} class is passed as first parameter of handler (req)

request.senderId

Kind: instance property of Request
Properties

NameTypeDescription
senderIdstringsender.id from the event

request.recipientId

Kind: instance property of Request
Properties

NameTypeDescription
recipientIdstringrecipient.id from the event

request.pageId

Kind: instance property of Request
Properties

NameTypeDescription
pageIdstringpage identifier from the event

request.state

Kind: instance property of Request
Properties

NameTypeDescription
stateobjectcurrent state of the conversation

request.isAttachment() ⇒ boolean

Checks, when message contains an attachment (file, image or location)

Kind: instance method of Request

request.isImage([attachmentIndex]) ⇒ boolean

Checks, when the attachment is an image

Kind: instance method of Request

ParamTypeDefaultDescription
[attachmentIndex]number0use, when user sends more then one attachment

request.isFile([attachmentIndex]) ⇒ boolean

Checks, when the attachment is a file

Kind: instance method of Request

ParamTypeDefaultDescription
[attachmentIndex]number0use, when user sends more then one attachment

request.attachment([attachmentIndex]) ⇒ object | null

Returns whole attachment or null

Kind: instance method of Request

ParamTypeDefaultDescription
[attachmentIndex]number0use, when user sends more then one attachment

request.attachmentUrl([attachmentIndex]) ⇒ string | null

Returns attachment URL

Kind: instance method of Request

ParamTypeDefaultDescription
[attachmentIndex]number0use, when user sends more then one attachment

request.isMessage() ⇒ boolean

Returns true, when the request is text message, quick reply or attachment

Kind: instance method of Request

request.text([tokenized]) ⇒ string

Returns text of the message

Kind: instance method of Request

ParamTypeDefaultDescription
[tokenized]booleanfalsewhen true, message is normalized to lowercase with -

Example

console.log(req.text(true)) // "can-you-help-me"

request.quickReply([getData]) ⇒ null | string | object

Returns action or data of quick reply When getData is true, object will be returned. Otherwise string or null.

Kind: instance method of Request

ParamTypeDefault
[getData]booleanfalse

Example

typeof res.quickReply() === 'string' || res.quickReply() === null;
typeof res.quickReply(true) === 'object';

request.isPostBack() ⇒ boolean

Returns true, if request is the postback

Kind: instance method of Request

request.isReferral() ⇒ boolean

Returns true, if request is the referral

Kind: instance method of Request

request.isOptin() ⇒ boolean

Returns true, if request is the optin

Kind: instance method of Request

request.action([getData]) ⇒ null | string | object

Returns action of the postback or quickreply When getData is true, object will be returned. Otherwise string or null.

  1. the postback is checked
  2. the referral is checked
  3. the quick reply is checked
  4. expected keywords are checked
  5. expected state is checked

Kind: instance method of Request

ParamTypeDefault
[getData]booleanfalse

Example

typeof res.action() === 'string' || res.action() === null;
typeof res.action(true) === 'object';

request.postBack([getData]) ⇒ null | string | object

Returns action or data of postback When getData is true, object will be returned. Otherwise string or null.

Kind: instance method of Request

ParamTypeDefault
[getData]booleanfalse

Example

typeof res.postBack() === 'string' || res.postBack() === null;
typeof res.postBack(true) === 'object';

Responder

Kind: global class

new Responder()

Instance of responder is passed as second parameter of handler (res)

responder.text(text, [quickReplys]) ⇒ this

Send text as a response

Kind: instance method of Responder

ParamTypeDescription
textstringtext to send to user, can contain placeholders (%s)
[quickReplys]object.<string, string>

Example

res.text('Hello %s', name, {
    action: 'Quick reply',
    complexAction: {
        title: 'Another quick reply', // required
        match: 'string' || /regexp/, // optional
        someData: 'Will be included in payload data' // optional
    }
})

responder.setState(object) ⇒ this

Sets new attributes to state (with Object.assign())

Kind: instance method of Responder

ParamType
objectobject

Example

res.setState({ visited: true });

responder.expected(action) ⇒ this

When user writes some text as reply, it will be processed as action

Kind: instance method of Responder

ParamTypeDescription
actionstringdesired action

responder.image(imageUrl) ⇒ this

Sends image as response. Requires appUrl option to send images from server

Kind: instance method of Responder

ParamTypeDescription
imageUrlstringrelative or absolute url

Example

// image on same server (appUrl option)
res.image('/img/foo.png');

// image at url
res.image('https://google.com/img/foo.png');

responder.wait([ms]) ⇒ this

Sets delay between two responses

Kind: instance method of Responder

ParamTypeDefault
[ms]number600

responder.typingOn() ⇒ this

Sends "typing..." information

Kind: instance method of Responder

responder.typingOff() ⇒ this

Stops "typing..." information

Kind: instance method of Responder

responder.seen() ⇒ this

Reports last message from user as seen

Kind: instance method of Responder

responder.receipt(recipientName, [paymentMethod], [currency], [uniqueCode]) ⇒ ReceiptTemplate

Sends Receipt template

Kind: instance method of Responder

ParamTypeDefaultDescription
recipientNamestring
[paymentMethod]string"'Cash'"should not contain more then 4 numbers
[currency]string"'USD'"sets right currency
[uniqueCode]stringnullwhen omitted, will be generated randomly

Example

res.receipt('Name', 'Cash', 'CZK', '1')
    .addElement('Element name', 1, 2, '/inside.png', 'text')
    .send();

responder.button(text) ⇒ ButtonTemplate

Sends nice button template. It can redirect user to server with token in url

Kind: instance method of Responder

ParamType
textstring

Example

res.button('Hello')
    .postBackButton('Text', 'action')
    .urlButton('Url button', '/internal', true) // opens webview with token
    .urlButton('Other button', 'https://goo.gl') // opens in internal browser
    .send();

responder.genericTemplate() ⇒ GenericTemplate

Creates a generic template

Kind: instance method of Responder
Example

res.genericTemplate()
    .addElement('title', 'subtitle')
        .setElementImage('/local.png')
        .setElementUrl('https://www.seznam.cz')
        .postBackButton('Button title', 'action', { actionData: 1 })
    .addElement('another', 'subtitle')
        .setElementImage('https://goo.gl/image.png')
        .setElementAction('action', { actionData: 1 })
        .urlButton('Local link with extension', '/local/path', true, 'compact')
    .send();

ButtonTemplate ⇐ BaseTemplate

Kind: global class
Extends: BaseTemplate

new ButtonTemplate()

Helps with creating of button template Instance of button template is returned by {Responder}

buttonTemplate.urlButton(title, url, hasExtension, [webviewHeight]) ⇒ this

Adds button. When hasExtension is set to true, url will contain hash like: #token=foo&senderId=23344

Kind: instance method of ButtonTemplate

ParamTypeDefaultDescription
titlestringbutton text
urlstringbutton url
hasExtensionbooleanincludes token in url
[webviewHeight]stringnullcompact

buttonTemplate.postBackButton(title, action, [data]) ⇒ this

Adds button, which makes another action

Kind: instance method of ButtonTemplate

ParamTypeDefaultDescription
titlestringButton title
actionstringButton action (can be absolute or relative)
[data]object{}Action data

ReceiptTemplate ⇐ BaseTemplate

Kind: global class
Extends: BaseTemplate

new ReceiptTemplate()

Provides fluent interface to make nice Receipts Instance of button template is returned by {Responder}

receiptTemplate.addElement(title, [price], [quantity], [image], [subtitle]) ⇒ this

Adds item to receipt

Kind: instance method of ReceiptTemplate

ParamTypeDefaultDescription
titlestring
[price]number0a item price
[quantity]numberamount of items
[image]stringnullimage of item
[subtitle]stringnulloptional subtitle

GenericTemplate ⇐ ButtonTemplate

Kind: global class
Extends: ButtonTemplate

new GenericTemplate()

Generic template utility

genericTemplate.addElement(title, [subtitle], [dontTranslate]) ⇒ this

Adds element to generic template

Kind: instance method of GenericTemplate

ParamTypeDefault
titlestring
[subtitle]stringnull
[dontTranslate]booleanfalse

genericTemplate.setElementUrl(url, [hasExtension]) ⇒ this

Sets url of recently added element

Kind: instance method of GenericTemplate

ParamTypeDefault
urlany
[hasExtension]booleanfalse

genericTemplate.setElementImage(image) ⇒ this

Sets image of recently added element

Kind: instance method of GenericTemplate

ParamType
imagestring

genericTemplate.setElementAction(url, hasExtension, [webviewHeight])

Sets default action of recently added element

Kind: instance method of GenericTemplate

ParamTypeDefaultDescription
urlstringbutton url
hasExtensionbooleanfalseincludes token in url
[webviewHeight]stringnullcompact

genericTemplate.urlButton(title, url, hasExtension, [webviewHeight]) ⇒ this

Adds button. When hasExtension is set to true, url will contain hash like: #token=foo&senderId=23344

Kind: instance method of GenericTemplate

ParamTypeDefaultDescription
titlestringbutton text
urlstringbutton url
hasExtensionbooleanincludes token in url
[webviewHeight]stringnullcompact

genericTemplate.postBackButton(title, action, [data]) ⇒ this

Adds button, which makes another action

Kind: instance method of GenericTemplate

ParamTypeDefaultDescription
titlestringButton title
actionstringButton action (can be absolute or relative)
[data]object{}Action data

Router ⇐ ReducerWrapper

Kind: global class
Extends: ReducerWrapper

new Router()

Cascading router

router.use([action], [pattern], reducer) ⇒ Object

Appends middleware, action handler or another router

Kind: instance method of Router

ParamTypeDescription
[action]stringname of the action
[pattern]RegExp | string | function
reducerfunction | Router

Example

// middleware
router.use((req, res, postBack, next) => {
    next(); // strictly synchronous
});

// route with matching regexp
router.use('action', /help/, (req, res) => {
    res.text('Hello!');
});

// route with matching function
router.use('action', req => req.text() === 'a', (req, res) => {
    res.text('Hello!');
});

// append router with exit action
router.use('/path', subRouter)
   .next('exitAction', (data, req, res, postBack, next) => {
       postBack('anotherAction', { someData: true })
   });

router.reduce(req, res, postBack)

Reducer function

Kind: instance method of Router
Overrides: reduce

ParamType
reqRequest
resResponder
postBackfunction

ReducerWrapper ⇐ EventEmitter

Kind: global class
Extends: EventEmitter
Emits: ReducerWrapper#event:action

new ReducerWrapper()

Solution for catching events. This is useful for analytics.

Example

const reducer = new ReducerWrapper((req, res) => {
    res.text('Hello');
});

reducer.on('action', (senderId, processedAction, text, req) => {
    // log action
});

reducerWrapper.reduce(req, res, postBack)

Reducer function

Kind: instance method of ReducerWrapper

ParamType
reqRequest
resResponder
postBackfunction

ReducerWrapper.ReducerWrapper

Kind: static class of ReducerWrapper

new ReducerWrapper([reduce])

Creates an instance of ReducerWrapper.

ParamTypeDefaultDescription
[reduce]functiono => othe handler function

Tester

Kind: global class

new Tester()

Utility for testing requests

tester.res([index]) ⇒ ResponseAssert

Returns single response asserter

Kind: instance method of Tester

ParamTypeDefaultDescription
[index]number0response index

tester.any() ⇒ AnyResponseAssert

Returns any response asserter

Kind: instance method of Tester

tester.lastRes() ⇒ ResponseAssert

Returns last response asserter

Kind: instance method of Tester

tester.passedAction(path) ⇒ this

Checks, that app past the action

Kind: instance method of Tester

ParamType
pathstring

tester.getState() ⇒ object

Returns state

Kind: instance method of Tester

tester.setState([state])

Sets state with Object.assign()

Kind: instance method of Tester

ParamTypeDefault
[state]object{}

tester.text(text) ⇒ Promise

Makes text request

Kind: instance method of Tester

ParamType
textstring

tester.optin(action, [data]) ⇒ Promise

Make optin call

Kind: instance method of Tester

ParamTypeDefault
actionstring
[data]object{}

tester.quickReply(action, [data]) ⇒ Promise

Send quick reply

Kind: instance method of Tester

ParamTypeDefault
actionstring
[data]object{}

tester.postBack(action, [data]) ⇒ Promise

Sends postback

Kind: instance method of Tester

ParamTypeDefault
actionstring
[data]object{}

Tester.Tester

Kind: static class of Tester

new Tester(reducer, [senderId], [processorOptions], [storage])

Creates an instance of Tester.

ParamTypeDefaultDescription
reducerRouter | ReducerWrapper | function
[senderId]stringnull
[processorOptions]object{}options for Processor
[storage]MemoryStateStorageplace to override the storage

ResponseAssert

Kind: global class

new ResponseAssert()

Utility for asserting single response

responseAssert.contains(search) ⇒ this

Checks, that response contains text

Kind: instance method of ResponseAssert

ParamType
searchstring

responseAssert.quickReplyAction(action) ⇒ this

Checks quick response action

Kind: instance method of ResponseAssert

ParamType
actionstring

responseAssert.templateType(type) ⇒ this

Checks template type

Kind: instance method of ResponseAssert

ParamType
typestring

responseAssert.attachmentType(type) ⇒ this

Checks attachment type

Kind: instance method of ResponseAssert

ParamType
typestring

ResponseAssert.AnyResponseAssert#contains(search) ⇒ this

Checks, that response contains text

Kind: static method of ResponseAssert

ParamType
searchstring

ResponseAssert.AnyResponseAssert#quickReplyAction(action) ⇒ this

Checks quick response action

Kind: static method of ResponseAssert

ParamType
actionstring

ResponseAssert.AnyResponseAssert#templateType(type) ⇒ this

Checks template type

Kind: static method of ResponseAssert

ParamType
typestring

ResponseAssert.AnyResponseAssert#attachmentType(type) ⇒ this

Checks attachment type

Kind: static method of ResponseAssert

ParamType
typestring

AnyResponseAssert

Kind: global class

new AnyResponseAssert()

Utility for searching among responses

Settings

Kind: global class

new Settings()

Utility, which helps us to set up chatbot behavior

settings.greeting([text]) ⇒ this

Sets or clears bot's greeting

Kind: instance method of Settings

ParamTypeDefaultDescription
[text]stringfalseleave empty to clear

settings.getStartedButton([payload]) ⇒ this

Sets up the Get Started Button

Kind: instance method of Settings

ParamTypeDefaultDescription
[payload]string | objectfalseleave blank to remove button, or provide the action

Example

const settings = new Settings(config.facebook.pageToken);
settings.getStartedButton('/start'); // just an action

settings.whitelistDomain(domain, [remove]) ⇒ this

Useful for using facebook extension in webviews

Kind: instance method of Settings

ParamTypeDefault
domainstring | Array.<string>
[remove]booleanfalse

settings.menu([locale], [inputDisabled]) ⇒ MenuComposer

Sets up the persistent menu

Kind: instance method of Settings

ParamTypeDefault
[locale]string"default"
[inputDisabled]booleanfalse

Example

const { Settings } = require('prg-chatbot');

const settings = new Settings('page-token-string');

settings.menu()
    .addNested('Nested Menu')
        .addUrl('Go to google', 'https://google.com')
        .done()
    .addPostBack('Do something', '/the/action')
    .done();

Settings.Settings

Kind: static class of Settings

new Settings(token, [log])

Creates an instance of Settings.

ParamType
tokenstring
[log]Object

bufferloader(url, [limit], [limitJustByBody], [redirCount]) ⇒

Downloads a file from url into a buffer. Supports size limits and redirects.

Kind: global function
Returns: Promise.

ParamTypeDefaultDescription
urlstring
[limit]number0limit in bytes
[limitJustByBody]booleanfalsewhen true, content size in header is ignored
[redirCount]number3maximmum amount of redirects

Example

router.use('*', (req, res, postBack) => {
    if (req.isFile()) {
        bufferloader(req.attachmentUrl())
            .then(buffer => postBack('downloaded', { data: buffer }))
            .catch(err => postBack('donwloaded', { err }))
    }
});

attachmentType(response, type, [message]) ⇒ boolean

Checks attachment type

Kind: global function

ParamTypeDefaultDescription
responseobject
typestring
[message]string | false"'Attachment type does not match'"use false for no asserts

isText(response, [message]) ⇒ boolean

Checks, that response is a text

Kind: global function

ParamTypeDefaultDescription
responseobject
[message]string | false"'Should be a text'"use false for no asserts

contains(response, search, [message]) ⇒ boolean

Checks, that text contain a message

Kind: global function

ParamTypeDefaultDescription
responseobject
searchstring
[message]string | false"'Should contain a text'"use false for no asserts

quickReplyAction(response, action, [message]) ⇒ boolean

Checks quick response action

Kind: global function

ParamTypeDefaultDescription
responseobject
actionstring
[message]string | false"'Should contain the action'"use false for no asserts

templateType(response, expectedType, [message]) ⇒ boolean

Checks template type

Kind: global function

ParamTypeDefaultDescription
responseobject
expectedTypestring
[message]string | false"'Template type does not match'"use false for no asserts

waiting(response, [message]) ⇒ boolean

Looks for waiting message

Kind: global function

ParamTypeDefaultDescription
responseobject
[message]string | false"'Should be waiting placeholder'"use false for no asserts

Keywords

FAQs

Package last updated on 23 Mar 2017

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc