Bottender

October 31, 2017 by C.T. Lin and Dung-Ie Wu

We're very proud to open-source Bottender, a JavaScript framework for cross-platform bots, built on top of Messaging-APIs and lots of great tools from the JavaScript community!

bottender logo

To begin with, install bottender globally from the npm registry:

npm install -g bottender

And enter interactive bot creation process with:

bottender init

After answering a few questions, a new bot will be created for you.

bottender init screenshot


Motivation

We are eager to envision a future of modern and friendly bot development, because we believe bots are the next big thing in terms of impact, scale and complexity.

Bot development should benefit from the latest improvements in JavaScript. Thanks to Babel, Node.js and the V8 engine, modern developers have escaped from call-back hell, but still have full access to the power of asynchronous error handling and state maintenance.

Also, bot development should be friendly. That is, developing bots on multiple messaging platforms should imply a consistent development experience without losing any of the characteristics or features of each platform.

Here comes Bottender, our proposal of modern and friendly bot development.


Only JavaScript. Handler is a function

The advantages of this approach over similar models is that you can do whatever you want in your function. And because of that, your entire system remains highly composable and testable.

bot.onEvent(context => {
  if (context.event.isText) {
    console.log('Cool. You sent a text to me.');
  } 
});

Furthermore, this handler function are fully testable without pain. Your test suite can simply import and test it.


Control Asynchronous Flow using Async Functions

When it comes to database queries or asynchronous API calls, modern async/await syntax give you great advantage to control your logic. Bottender's first class async/await support let you simply pass in any async handler. Farewell to callback hells.

bot.onEvent(async context => {
  if (context.event.text === 'you shoull call api') {
    const result = await callSomeAsyncAPI(context.event.text);
    await context.sendText(result);
  } 
});

Keep Conversation State at Session Store

Conversation state can be initially defined with bot.setInitialState(), and can be modified during conversation using context.setState(). The state control is handled by underlying session store.

bot.setInitialState({
  todos: [],
});

bot.onEvent(context => {
  if (context.event.isText) {
    context.setState({
      todos: context.state.todos.concat(
        context.event.text
      ),
    });
  }
});

You can use memory session store in development, and replace it with persistence session stores on production.

const { FileSessionStore } = require('bottender');

const bot = new MessengerBot({
  sessionStore: new FileSessionStore(),
});

We provide not only file session store but also redis and mongo session stores. You can even submit your session store by following the interface implementation.


Simple deployment

To put your bot logic online, you need a HTTP server. Bottender provides simple createServer() function that do the trick for you, the server created can be extended as well.

const createServer = require('bottender/express');

const server = createServer(bot);

server.listen(3000, () => {
  console.log('bot server is running on 3000 port');
});

Bottender supports four Node.js server frameworks, simply require corresponding createServer() from submodules.

// import from express
const createServer = require('bottender/express');

// import from koa
const createServer = require('bottender/koa');

// import from micro
const createServer = require('bottender/micro');

// import from restify
const createServer = require('bottender/restify');

Since Bottender works as a Node.js HTTP server, you can easily deploy your bots to PaaS like Heroku or Now. For more details, check out the Deployment guide.