Skip to content

Latest commit

 

History

History
113 lines (78 loc) · 5.99 KB

middlewares.md

File metadata and controls

113 lines (78 loc) · 5.99 KB

Introduction to Middleware

Middleware is a critical component of botpress. Simply put, it is a collection of functions that process messages. Think of it this way: everything that enters or leaves your bot is coming in to (or out from) the middleware.

If you have used Express before, botpress middleware is very similar to express's middleware.

Botpress has two middleware chains: incoming and outgoing

To receive messages: An installed module must send messages into the incoming middleware chain

To send messages: You (or a module) must send messages into the outgoing middleware chain and have a module able to send it to the right platform

Example

Incoming: botpress-messenger connects to Facebook and receives messages from its built-in Webhook. It then sends messages into the incoming middleware, which your bot can process.

Outgoing: botpress-messenger listens (through a middleware function) for messages it can process on the outgoing middleware and sends them to Facebook through the Messenger Send API.

Middleware Chain

A middleware chain is simply a collection of middleware functions that are called in a predertermined order. Each middleware function in the chain has the freedom to:

  • execute arbitrary code
  • mutate the event
  • call the next middleware
  • interrupt the chain by never calling the next middleware (what we call swallowing the event)
  • interrupt the chain by throwing an error

A simple middleware function

A middleware function is simply a function that takes an event as the first parameter and a next function as the second parameter.

Here's an example of the 5 possible cases:

var middleware = function(event, next) {
    // chain interruption (error)
    if (internetDisconnected())
        return next(new Error('Not connected'))

    if (isUserBanned(event.user.id))
        return // swallow the event

    // arbitraty code execution
    var translation = Translator.translate(event.text)

    // event mutation
    event.text = translation

    // call next middleware function
    next()
}

The return value of the middleware function can be anything or nothing, it isn't used.

Registering middlewares

You need to register a middleware function for botpress to know about it and use it. You may do so with the bp.middlewares.register method:

// ** code taken from botpress-messenger **
bp.middlewares.register({
    name: 'messenger.sendMessages', // friendly name
    type: 'outgoing', // either incoming or outgoing
    order: 100, // arbitrary number
    handler: outgoingMiddleware, // the middleware function
    module: 'botpress-messenger', // the name of the module, if any
    description: 'Sends out messages that targets platform = '
    + 'messenger. This middleware should be placed at the end as it swallows events once sent.'
})

Once all middleware functions have been registered (usually modules should register middleware functions immediatly in their initialization), you must load them using bp.middlewares.load(), which will create the incoming and outgoing chains automatically.

Once middleware functions are loaded, you'll see them displayed in your bot's interface:

Ordering middleware functions

By default, middleware functions are ordered by ascending order according to their order property set on registration. The order can then be manually overwritten:

You can also re-order them programmatically using middleware function customizations.

Full Messages Lifecycle Example

Imagine you have a travel bot that is available on Facebook Messenger and Slack and that can handle many languages.

Your bot's installed modules would probably look a bit like:

  • botpress-messenger for I/O with Facebook Messenger
  • botpress-slack for I/O with Slack
  • botpress-analytics to have an overview of how people use your bot
  • botpress-translate (fictive) to translate incoming and outgoing messages
  • ~/my-bot/private_modules/botpress-travel (fictive) your bot's travel logic goes here

Now lets look at how a complete interaction might be handled by your bot.

  1. A user types a message in French to your bot in Facebook Messenger
  2. Facebook pushes the message to your bot via the built-in botpress-messenger's Webhook
  3. botpress-messenger retrieves the user information and stores it in the built-in database
  4. botpress-messenger parses the message and calls the first incoming middleware function (botpress-analytics)
  5. botpress-analytics tracks the message then calls the next middleware function in the chain (botpress-translate)
  6. botpress-translate translates the message from French to English (by mutating it) then calls the next middleware function in the chain (botpress-travel)
  7. botpress-travel processes the message and responds by calling the bp.messenger.sendText method
  8. botpress-messenger takes the response and calls the outgoing middlewares chain
  9. botpress-translate translates the message from English to French (by mutating it) then calls the next middleware function in the outgoing chain (botpress-analytics)
  10. botpress-analytics tracks the message then calls the next middleware function (botpress-messenger)
  11. botpress-slack will ignore the message because it doesn't know how to process messages with type: facebook
  12. botpress-messenger sends the message to Facebook Messenger through the Send API

All of this happens behind the scene and is handled by the modules middleware. As a bot developer, all you have to worry about is writing the bot's logic.