UNPKG

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