Skip to content
Fawwaz Muhammad edited this page Nov 11, 2017 · 1 revision

Welcome to the line-chatbot-boilerplate wiki!

This boilerplate based on my several Line chatbots projects, so don't hesitate to contact me if you found something that can be improved from this repo.

General Requirement

When you fork this repo, I assume that you have :

Folder Structure

Basically my code hierarchy is something like this :

.
├── app.json                             : Used for heroku deployment
├── LineMockServer.js                    : A simple Line Mock server
├── package.json                         : Manage your dependency
├── Procfile                             : Used for heroku deployment
├── readme.md                            : readme
├── src                                  
│   ├── constants.js                     : Any constant variable you might use in entire chatbot
│   ├── controllers                      
│   │   ├── CommonController.js          : A controller that always executed regardless the chat state
│   │   ├── DefaultStateController.js    : A default controller that executed for default chat state/condition
│   │   └── MainController.js            : Main controller that loads another controller
│   ├── index.js                         : NodeJS Http server, that use express configuration in server.js
│   ├── models
│   │   └── ReduxWrapper.js              : Redux Wrapper (will explain this later)
│   ├── server.js                        : A plain ExpressJS file.
│   └── utils
│       └── LineWrapper.js               : Common Line message wrapper (will explain this later)
├── webpack-dev.config.js                : Webpack config for development
└── webpack-prod.config.js               : Webpack config for production

This boilerplate utilize Redux principle to hold application state. Mostly you just need to modify/add some code inside controllers folder. If you have some complex state management, you can simply add it inside models directory.

How My ReduxWrapper store the data

My redux wrapper store the data using the following format :

{
  [user_id_or_group_or_multi_chat_id] : {
    stateId: [any state id in constant.js]
    ... another key-value data
  }
}

With the format above, you can simply scope a data into whom the bot is talking. It might be a user_id for 1 to 1 chat, or Group/Multichat id for 1 to many chat. You may add your own key-value data. The only reserved key is stateId, it will be used to track chat state so the app can distinguish which chat in what state.

What is LineWrapper ?

Line wrapper is used to encapsulate low level Line messaging api into a simple function that can be called in other files. Mainly it has 3 parts, a wrapper for Line's replyMessage and pushMessage function, Line Message Selector, and Line Message Formatter. The first part literally wrap Line replyMessage and pushMessage function from it's official API. The second part (selector) can be viewed as a parser for Line Message data structure, please read their docs to get better understanding how their data structure looks like. The last part compose your message before you can send it using The first part (replyMessage or pushMessage).

General Guideline

Before writing any code, you need to design your chat state. You need to question yourself what are your chat states ? What user action that triggers transition between each state. What are some valid and invalid triggers for each state ? Once you know each of them, you can start writing your bots using this guideline :

  1. For each state you have, add it to constants.js use a friendly name
  2. Add new [Your FriendlyName]Controller.js to handle your state
  3. Import your controller inside MainController.js put in the suitable location.

Example code / Showcase

It is very hard to explain abstract concept without example. So, go through read the code of several bots that use this boilerplate (Feel free to submit your own bot):