1 | # Mainframe JavaScript SDK for bots
|
2 |
|
3 | This documentation only covers the JavaScript SDK, see the [Mainframe bots documentation](http://developer.mainframe.com/) for more information about creating Mainframe bots, and the [bots UI framework repository](https://github.com/thusfresh/bot-ui-js) for a complementary tool to create bot UIs.
|
4 |
|
5 | - [Installation](#installation)
|
6 | - [Example](#example)
|
7 | - [Data types](#types)
|
8 | - [API](#api)
|
9 | - [`createConfig`](#createconfig)
|
10 | - [`createContext`](#createcontext)
|
11 | - [`createRouter`](#createrouter)
|
12 | - [`createServer`](#createserver)
|
13 | - [`log`](#log)
|
14 | - [`startServer`](#startserver)
|
15 | - [Usage](#usage)
|
16 | - [Basic usage](#basic-usage) - the easiest way to get started
|
17 | - [With custom route handlers](#adding-custom-route-handlers) - when you need custom routes
|
18 | - [Using an existing Koa app](#using-an-existing-koa-app) - giving you the flexibility to implement what you need
|
19 | - [License](#license)
|
20 |
|
21 | ## Installation
|
22 |
|
23 | ```sh
|
24 | npm install @mainframe/bot-sdk # npm
|
25 | yarn add @mainframe/bot-sdk # Yarn
|
26 | ```
|
27 |
|
28 | ## Example
|
29 |
|
30 | ```js
|
31 | const { startServer } = require('@mainframe/bot-sdk')
|
32 |
|
33 | startServer(
|
34 | {
|
35 | conversation_added({ conversation_id }, { sendMessage }) {
|
36 | sendMessage({ conversation_id, message: 'Hello world' })
|
37 | },
|
38 | },
|
39 | {
|
40 | mainframe_secret: '<my bot secret>',
|
41 | port: 3000,
|
42 | },
|
43 | )
|
44 | ```
|
45 |
|
46 | ## Types
|
47 |
|
48 | The SDK uses the following [Flow types](https://flow.org/en/docs/types/):
|
49 |
|
50 | ```js
|
51 | type PartialConfig = {
|
52 | +mainframe_secret?: string,
|
53 | +mainframe_url?: string,
|
54 | +port?: number,
|
55 | }
|
56 |
|
57 | type Config = {|
|
58 | +mainframe_secret: string,
|
59 | +mainframe_url: string,
|
60 | +port: number,
|
61 | |}
|
62 |
|
63 | type ServerContext = {|
|
64 | +user_id: string,
|
65 | +conversation_id?: string,
|
66 | +subscription_id?: string,
|
67 | +subscription_token?: string,
|
68 | |}
|
69 |
|
70 | type PostPayload = {|
|
71 | +data: Object,
|
72 | +context: ServerContext,
|
73 | |}
|
74 |
|
75 | type SendMessagePayload = {
|
76 | conversation_id: string,
|
77 | message?: string,
|
78 | data?: Object,
|
79 | }
|
80 |
|
81 | type SubscriptionResponse = {|
|
82 | +subscription_id: string,
|
83 | |}
|
84 |
|
85 | type BotContext = {|
|
86 | +config: Config,
|
87 | +callMainframe: (endpoint: string, data?: Object) => Promise<void | Object>,
|
88 | +sendMessage: (payload: SendMessagePayload) => Promise<void>,
|
89 | +setupSubscription: (payload: {
|
90 | subscription_token: string,
|
91 | label: string,
|
92 | }) => Promise<SubscriptionResponse>,
|
93 | +editSubscription: (payload: {
|
94 | subscription_token: string,
|
95 | label?: string,
|
96 | }) => Promise<SubscriptionResponse>,
|
97 | |}
|
98 |
|
99 | type BotResponse = {|
|
100 | success: boolean,
|
101 | message?: string,
|
102 | data?: Object,
|
103 | |}
|
104 |
|
105 | type Handlers = {|
|
106 | +enable?: (payload: { user_id: string }, context: BotContext) => void,
|
107 | +disable?: (payload: { user_id: string }, context: BotContext) => void,
|
108 | +conversation_added?: (
|
109 | payload: {|
|
110 | +user_id: string,
|
111 | +conversation_id: string,
|
112 | |},
|
113 | context: BotContext,
|
114 | ) => void,
|
115 | +conversation_removed?: (
|
116 | payload: {|
|
117 | +user_id: string,
|
118 | +conversation_id: string,
|
119 | |},
|
120 | context: BotContext,
|
121 | ) => void,
|
122 | +edit_subscription?: (
|
123 | payload: {|
|
124 | +user_id: string,
|
125 | +conversation_id: string,
|
126 | +subscription_id: string,
|
127 | |},
|
128 | context: BotContext,
|
129 | ) => void,
|
130 | +delete_subscription?: (
|
131 | payload: {|
|
132 | +subscription_id: string,
|
133 | |},
|
134 | context: BotContext,
|
135 | ) => void,
|
136 | +mention?: (
|
137 | payload: {|
|
138 | +user_id: string,
|
139 | +conversation_id: string,
|
140 | +text: string,
|
141 | |},
|
142 | context: BotContext,
|
143 | ) => void,
|
144 | +post?: (
|
145 | payload: PostPayload,
|
146 | context: BotContext,
|
147 | ) => BotResponse | Promise<BotResponse>,
|
148 | +preview?: (
|
149 | payload: {|
|
150 | +user_id: string,
|
151 | +link: string,
|
152 | |},
|
153 | context: BotContext,
|
154 | ) => BotResponse | Promise<BotResponse>,
|
155 | |}
|
156 | ```
|
157 |
|
158 | ## API
|
159 |
|
160 | ### createConfig
|
161 |
|
162 | `createConfig (parameters?: PartialConfig): Config`
|
163 |
|
164 | Creates the configuration using the provided parameters, environment variables or defaults.
|
165 |
|
166 | ### createContext
|
167 |
|
168 | `createContext (config: Config): BotContext`
|
169 |
|
170 | Creates a bot context provided to the handlers, notably to allow to communicate with Mainframe.
|
171 |
|
172 | ### createRouter
|
173 |
|
174 | `createRouter (handlers: Handlers, context: BotContext): Router`
|
175 |
|
176 | Creates a [Koa Router](https://github.com/alexmingoia/koa-router#exp_module_koa-router--Router) implementing HTTP endpoints for the provided handlers.
|
177 |
|
178 | ### createServer
|
179 |
|
180 | `createServer (handlers: Handlers, config: Config): koa$Application`
|
181 |
|
182 | Creates a [Koa Application](http://koajs.com/#application) implementing HTTP endpoints for the provided handlers.
|
183 |
|
184 | ### log
|
185 |
|
186 | `log (...args: Array<mixed>): void`
|
187 |
|
188 | Logs using [debug](https://github.com/visionmedia/debug) with the `mainframe-bot` namespace.
|
189 |
|
190 | ### startServer
|
191 |
|
192 | `startServer (handlers: Handlers, parameters?: PartialConfig): void`
|
193 |
|
194 | Creates a [Koa Application](http://koajs.com/#application) implementing HTTP endpoints for the provided handlers and start listening using the `port` provided in `parameters`, defaulting to `4000`.
|
195 |
|
196 | ## Usage
|
197 |
|
198 | ### Basic usage
|
199 |
|
200 | This SDK uses the [Koa framework](http://koajs.com/) to handle routing the provided handlers to the corresponding [HTTP endpoints used by the Mainframe server](http://developer.mainframe.com/#bot-api).
|
201 | All of these handlers are optional by default and you'll only need to implement them according to the needs of your bot.
|
202 |
|
203 | The simplest way to get started it to call `startServer(handlers)`, for example:
|
204 | ```js
|
205 | const { startServer } = require('@mainframe/bot-sdk')
|
206 |
|
207 | startServer({
|
208 | conversation_added(payload, context) {
|
209 | context.sendMessage({
|
210 | conversation_id: payload.conversation_id,
|
211 | message: 'Hello world',
|
212 | })
|
213 | },
|
214 | })
|
215 | ```
|
216 |
|
217 | All handlers will be called with two arguments: an Object containing the request payload, and the [`BotContext`](types) notably allowing to make requests to Mainframe.
|
218 |
|
219 | `startServer()` also supports providing a configuration Object as second argument, used to create the context. When not provided, the configuration will use the environment variables `MAINFRAME_SECRET`, `MAINFRAME_URL` and `PORT`.
|
220 | The configuration will by default use `https://api.mainframe.com/bots/v1` as Mainframe's API URL and listen on port `4000`.
|
221 | Your bot's `secret` **must be** provided, either directly as `mainframe_secret` in the configuration object, or in the `MAINFRAME_SECRET` environment variable.
|
222 |
|
223 | ### Adding custom route handlers
|
224 |
|
225 | For more advanced use cases, you may want to create the Koa application without listening right-away, this is possible using the `createServer(handlers, config)` function, that will return an [`Application instance`](http://koajs.com/#application).
|
226 | This function expects a `config` Object providing all the configuration values. If you want to automatically use the environment variables or default configuration values, you can use `createConfig(optionalConfig)` that will use the values provided in `optionalConfig`, or default to the environment variables or predefined values.
|
227 |
|
228 | Example:
|
229 |
|
230 | ```js
|
231 | const { createConfig, createServer, log } = require('@mainframe/bot-sdk')
|
232 |
|
233 | const config = createConfig({ mainframe_secret: '<your bot secret>' })
|
234 | const server = createServer(
|
235 | {
|
236 | enable(payload) {
|
237 | log('enabled by user %s', payload.user_id)
|
238 | },
|
239 | },
|
240 | config,
|
241 | )
|
242 |
|
243 | server.use(ctx => {
|
244 | ctx.body = 'Hello'
|
245 | })
|
246 |
|
247 | server.listen(3000)
|
248 | ```
|
249 |
|
250 | ### Using an existing Koa app
|
251 |
|
252 | If you are already using Koa and want to integrate the bot API with even more control, you can do so by using the `createRouter(handlers, context)`, that will return a [`Router instance`](https://github.com/alexmingoia/koa-router#exp_module_koa-router--Router).
|
253 | This function requires a [`BotContext`](#types) to be provided as the second argument, that will be injected to the handlers when called. You can provide a custom implementation of the `context` if you have specific needs, or use `createContext(config)` to create it.
|
254 |
|
255 | Example:
|
256 |
|
257 | ```js
|
258 | const { createConfig, createContext, createRouter, log } = require('@mainframe/bot-sdk')
|
259 | const Koa = require('koa')
|
260 |
|
261 | const app = new Koa()
|
262 |
|
263 | const config = createConfig() // Will use MAINFRAME_SECRET from the environment
|
264 | const context = createContext(config)
|
265 |
|
266 | const api = createRouter(
|
267 | {
|
268 | enable(payload) {
|
269 | log('enabled by user %s', payload.user_id)
|
270 | },
|
271 | },
|
272 | context,
|
273 | )
|
274 |
|
275 | app.use(api.routes())
|
276 |
|
277 | app.listen(3000)
|
278 | ```
|
279 |
|
280 | ## License
|
281 |
|
282 | MIT
|
283 | See [LICENSE](LICENSE) file
|