Botact enables developers to focus on writing reusable application logic instead of spending time building infrastructure.
via npm:
$ npm i botact -S
via yarn:
$ yarn add botact
express:
const express = require('express')
const bodyParser = require('body-parser')
const { Botact } = require('botact')
const app = express()
const bot = new Botact({
confirmation: process.env.CONFIRMATION,
token: process.env.TOKEN
})
// User wrote command 'start'
bot.command('start', ({ reply }) => {
reply('This is start!')
})
// User wrote message which contains 'car' or 'tesla'
bot.hears(/(car|tesla)/, ({ reply }) => {
reply('I love Tesla!')
})
// User joined in the group
bot.event('group_join', ({ reply }) => {
reply('Thanks!')
})
// User wrote any message
bot.on(({ reply }) => {
reply('What?')
})
// Parser request body
app.use(bodyParser.json())
// Bot's endpoint
app.post('/', bot.listen)
// Start listen on 3000
app.listen(process.env.PORT)
koa:
const Koa = require('koa')
const Router = require('koa-router')
const bodyParser = require('koa-bodyparser')
const { Botact } = require('botact')
const app = new Koa()
const router = new Router()
const bot = new Botact({
confirmation: process.env.CONFIRMATION,
token: process.env.TOKEN,
framework: 'koa'
})
// User wrote command 'start'
bot.command('start', ({ reply }) => {
reply('This is start!')
})
// User wrote message which contains 'car' or 'tesla'
bot.hears(/(car|tesla)/, ({ reply }) => {
reply('I love Tesla!')
})
// User joined in the group
bot.event('group_join', ({ reply }) => {
reply('Thanks!')
})
// User wrote any message
bot.on(({ reply }) => {
reply('What?')
})
// Bot's endpoint
router.post('/', bot.listen)
// Parser request body
app.use(bodyParser())
// Connect routes
app.use(router.routes())
// Start listen on 3000
app.listen(3000)
- constructor(settings)
- .api(method, settings)
- .execute(method, settings, callback)
- .reply(userId, message, attachment, keyboard)
- .listen(...args)
- .command(command, callback)
- .event(event, callback)
- .hears(command, callback)
- .on(type, callback)
- .use(callback)
Botact API: Core ↑
Create bot.
Definition:
constructor (settings: {
confirmation: string; // required
token: string; // required
group_id?: number;
framework?: string; // Server framework (express/koa)
// Flow Settings
flowTimeout?: number; // Document expire time, in seconds
redis?: boolean; // false by default
redisConfig?: object; // {} by default
})
Usage:
const { Botact } = require('botact')
const bot = new Botact({
confirmation: process.env.CONFIRMATION,
token: process.env.TOKEN
})
Call API method (https://vk.com/dev/methods).
Definition:
async api (
method: string, // required
options?: object, // api call parameters
): Promise<any>; // Promise with response/error
Usage:
const data = await bot.api('users.get', {
user_ids: 1
})
Call API by execute.
Definition:
async execute (
method: string, // required
options?: object, // api call parameters
callback?: function
): Promise<any>; // Promise with response/error
Usage:
bot.execute('users.get', {
user_ids: 1
}, (body) => {
// {
// response: [{
// id: 1,
// first_name: 'Павел',
// last_name: 'Дуров'
// }]
// }
})
Sends message to user
Definition:
async reply (
userId: number,
message: string, // required, if attachment not setten
attachment: string, // required, if message not setten
keyboard: Object // optional
): Promise<any> // Promise with response/error
Usage:
bot.command('start', (ctx) => {
// via shortcut from context
ctx.reply('Hi, this is start!')
// via shortcut with keyboard
ctx.reply('Yo, this is keyboard?', null, {
one_time: false,
buttons: [
[
{
action: {
type: 'text',
payload: {
button: 'Hello, world!'
},
label: 'Hello, world!'
},
color: 'primary'
}
]
]
})
// via function from context
ctx.sendMessage(ctx.user_id, 'Hi, this is start!')
// via function from instance
bot.reply(ctx.user_id, 'Hi, this is start!')
// to multiple users
bot.reply([ ctx.user_id, 1 ], 'Hi, this is start!')
})
Start listen.
Definition:
express:
listen (
req: any, // Express request, required
res: any // Express response, required
callback: function // Callback for errors
)
koa:
listen (
ctx: object, // Koa object, required
callback: function // Callback for errors
)
Usage:
// express
bot.listen(req, res, (error) => {
res.status(500).json({
error: 'Server error'
})
})
// koa
bot.listen(ctx, (error) => {
ctx.throw(500, 'Server error')
})
Botact API: Actions ↑
Add command w/ strict match.
Definition:
command (
command: string | string[],
callback: function
): Botact
Usage:
bot.command('start', ({ reply }) => reply('This is start!'))
Add event handler .
Definition:
event (
event: string | string[],
callback: function
): Botact;
Usage:
bot.event('group_join', ({ reply }) => reply('Thanks!'))
Add command w/ match like RegEx.
Definition:
hears (
hear: string | RegExp | (string | RegExp)[],
callback: function
): Botact;
Usage:
bot.hears(/(car|tesla)/, ({ reply }) => reply('I love Tesla!'))
Add reserved callback.
Definition:
on (
type: string,
callback: function
): Botact;
OR
on (
callback: function
): Botact;
Usage:
bot.on(({ reply }) => reply('What?'))
bot.on('audio', ({ reply }) => reply('Great music!'))
Add middleware.
Definition:
use (
callback: function
): Botact
Usage:
bot.use(ctx => ctx.date = new Date())
bot.on(({ date }) => {
// Fri Nov 24 2017 16:00:21 GMT+0300 (MSK)
})
Botact API: Options ↑
Get options.
bot.options
// {
// confirmation: '12345',
// token: 'abcde...'
// }
Set options.
bot.options = { foo: 'bar' }
// {
// confirmation: '12345',
// token: 'abcde...',
// foo: 'bar'
// }
Botact API: Upload helpers ↑
Upload and save cover. See detailed settings here.
Definition:
async uploadCover (
filepath: string, // Path to file with cover
settings?: object
): Promise<any> // Promise with response/error
Usage:
await bot.uploadCover('./cover.jpg', { crop_x2: 1590 })
// {
// images: [
// {
// url: "URL",
// width: 1920,
// height: 1080
// },
// [Object],
// [Object],
// [Object],
// [Object]
// ]
// }
Uploads document to peer.
Definition:
async uploadDocument (
filepath: string, // Path to file
peer_id: number,
type: 'doc' | 'audio_message' // 'doc' by default
): Promise<any>; // Promise with response/error
Usage:
await bot.uploadDocument('./book.pdf', 1234)
// {
// response:
// [{
// id: 1234,
// owner_id: 1234,
// title: "",
// ...
// }]
// }
Uploads photo to peer.
Definition:
async uploadPhoto (
filepath: string, // Path to picture
peer_id: number
): Promise<any> // Promise with response/error
Usage:
await bot.uploadPhoto('./picture.png', 1234)
// {
// id: 1234,
// album_id: 1234,
// owner_id: 1234,
// ...
// }
Botact API: Error Handling ↑
Add catch handler for errors.
Default handler:
console.error(`❌ Botact Error: ${typeof err === 'object' ? JSON.stringify(err) : err}`)
Usage:
// Handle all botact errors here
bot.catch((ctx, err) => {
// ctx - user's context
// err - throwed error
console.error(ctx, err)
})
bot.on((ctx) => {
if (ctx.peer_id !== 1) {
// Throw error to the .catch handler
return ctx.throw('User is not Pavel Durov')
}
})
Throw error.
Usage:
bot.catch((ctx, err) => {
console.error(ctx, err)
})
bot.command('start', (ctx) => {
if (ctx.peer_id === 301361473) {
return ctx.throw('User is blocked')
}
ctx.reply('Hello, how are you?')
})
Helper method to throw an error similar to .throw() when !value.
bot.catch((ctx, err) => {
console.error(ctx, err)
})
bot.command('start', (ctx) => {
ctx.assert(ctx.peer_id !== 301361473, 'User is blocked')
ctx.reply('Hello, how are you?')
})
const bot = new Botact({
...,
redis: true // enable redis
flowTimeout: 20 // timeout for delete documents
redisConfig: { // redis config
port: 1234
}
})
$ redis-server
- .addScene(name, ...callbacks)
- .joinScene(ctx, scene, session, step, now)
- .nextScene(ctx, body)
- .leaveScene(ctx)
const bodyParser = require('body-parser')
const express = require('express')
const { Botact } = require('botact')
const app = express()
const bot = new Botact({
confirmation: process.env.CONFIRMATION,
token: process.env.TOKEN,
redis: true,
flowTimeout: 20, // document will be deleted after 20 secs
redisConfig: {
host: '127.0.0.1', // default host for redis
port: 8080 // custom port for redis
},
})
bot.addScene('wizard',
({ reply, scene: { next } }) => {
next()
reply('Write me something!')
},
({ reply, body, scene: { leave } }) => {
leave()
reply(`You wrote: ${body}`)
}
)
bot.command('join', ({ scene: { join } }) => join('wizard'))
app.use(bodyParser.json())
app.post('/', bot.listen)
app.listen(process.env.PORT)
Add scene.
Definition:
addScene (
name: string,
...args: function[]
): Botact;
Usage:
bot.addScene('wizard',
({ reply, scene: { next } }) => {
next()
reply('Write me something!')
},
({ reply, body, scene: { leave } }) => {
leave()
reply(`You wrote: ${body}`)
}
)
Enter scene.
Definition:
async joinScene (
ctx: object,
scene: string,
session?: object, // {} by default
step?: number, // 0 by default
instantly?: boolean // true by default
): Promise<Botact>;
Usage:
bot.command('join', (ctx) => {
// with shortcut without additional settings
ctx.scene.join('wizard')
// simple usage with additional settings
bot.joinScene(ctx, 'wizard', { foo: 'bar' })
})
Navigate scene.
Definition:
async nextScene (
ctx: object,
session?: object, // {} by default
): Promise<Botact>;
Usage:
bot.addScene('wizard',
(ctx) => {
// with shortcut without additional settings
ctx.scene.next({ foo: 'bar' })
// simple usage with additional settings
bot.nextScene(ctx, { foo: 'bar' })
}
)
Leave scene.
Definition:
async leaveScene(
ctx: object
): Promise<Botact>;
Usage:
bot.addScene('wizard',
(ctx) => {
// with shortcut
ctx.scene.leave()
// simple usage
bot.leaveScene(ctx)
}
)
Botact includes TypeScript definitions.
via npm:
$ npm test
via yarn:
$ yarn test
MIT.