https://github.com/bifot/botact
π€ A library for creating VK bots on Node.js
https://github.com/bifot/botact
bot bot-framework callback vk vk-api vkontakte vkontakte-api
Last synced: 4 months ago
JSON representation
π€ A library for creating VK bots on Node.js
- Host: GitHub
- URL: https://github.com/bifot/botact
- Owner: bifot
- License: mit
- Created: 2017-04-28T13:52:26.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2018-07-31T02:30:22.000Z (over 7 years ago)
- Last Synced: 2025-01-30T17:38:25.209Z (about 1 year ago)
- Topics: bot, bot-framework, callback, vk, vk-api, vkontakte, vkontakte-api
- Language: JavaScript
- Homepage: https://npmjs.com/package/botact
- Size: 1.51 MB
- Stars: 19
- Watchers: 3
- Forks: 5
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
[](https://www.npmjs.com/package/botact/) [](https://nodejs.org/en/) [](https://www.npmjs.com/package/botact/) [](https://travis-ci.org/bifot/botact/) [](http://standardjs.com/)
# botact.js
Botact enables developers to focus on writing reusable application logic instead of spending time building infrastructure.
## Table of content
- [Install](#install)
- [Usage](#usage)
- [Botact API](#botact-api)
- [Botact Flow API](#botact-flow-api)
- [TypeScript](#typescript)
- [Tests](#tests)
- [License](#license)
## Install
**via npm:**
```sh
$ npm i botact -S
```
**via yarn:**
```sh
$ yarn add botact
```
## Examples
**express:**
```javascript
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:**
```js
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)
```
## Botact API
## Methods
### Core
- [constructor(settings)](#constructorsettings)
- [.api(method, settings)](#apimethod-settings)
- [.execute(method, settings, callback)](#executemethod-settings-callback)
- [.reply(userId, message, attachment, keyboard)](#replyuserid-message-attachment-keyboard)
- [.listen(...args)](#listenargs)
### Actions
- [.command(command, callback)](#commandcommand-callback)
- [.event(event, callback)](#eventevent-callback)
- [.hears(command, callback)](#hearscommand-callback)
- [.on(type, callback)](#ontype-callback)
- [.use(callback)](#usecallback)
### Options
- [[getter] options](#getter-options)
- [[setter] options](#setter-options)
### Upload helpers
- [.uploadCover(file, settings)](#uploadcoverfile-settings)
- [.uploadDocument(file, peerId, type)](#uploaddocumentfile-peerid-type)
- [.uploadPhoto(file, peerId)](#uploadphotofile-peerid)
### Error Handling
- [.catch(handler)](#catchhandler)
- [.throw(error)](#throwerror)
- [.assert(value, message)](#assertvalue-message)
--------------------------------------------------------------------------------
## Botact API: Core [β](#botact-api)
### constructor(settings)
Create bot.
**Definition:**
```typescript
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:**
```javascript
const { Botact } = require('botact')
const bot = new Botact({
confirmation: process.env.CONFIRMATION,
token: process.env.TOKEN
})
```
### .api(method, settings)
Call API method ().
**Definition:**
```typescript
async api (
method: string, // required
options?: object, // api call parameters
): Promise; // Promise with response/error
```
**Usage:**
```javascript
const data = await bot.api('users.get', {
user_ids: 1
})
```
### .execute(method, settings, callback)
Call API by [execute](https://vk.com/dev/execute).
**Definition:**
```typescript
async execute (
method: string, // required
options?: object, // api call parameters
callback?: function
): Promise; // Promise with response/error
```
**Usage:**
```javascript
bot.execute('users.get', {
user_ids: 1
}, (body) => {
// {
// response: [{
// id: 1,
// first_name: 'ΠΠ°Π²Π΅Π»',
// last_name: 'ΠΡΡΠΎΠ²'
// }]
// }
})
```
### .reply(userId, message, attachment, keyboard)
Sends message to user
**Definition:**
```typescript
async reply (
userId: number,
message: string, // required, if attachment not setten
attachment: string, // required, if message not setten
keyboard: Object // optional
): Promise // Promise with response/error
```
**Usage:**
```javascript
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!')
})
```
### .listen(...args)
Start listen.
**Definition:**
express:
```typescript
listen (
req: any, // Express request, required
res: any // Express response, required
callback: function // Callback for errors
)
```
koa:
```typescript
listen (
ctx: object, // Koa object, required
callback: function // Callback for errors
)
```
**Usage:**
```javascript
// 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 [β](#botact-api)
### .command(command, callback)
Add command w/ strict match.
**Definition:**
```typescript
command (
command: string | string[],
callback: function
): Botact
```
**Usage:**
```javascript
bot.command('start', ({ reply }) => reply('This is start!'))
```
### .event(event, callback)
Add [event](https://vk.com/dev/groups_events) handler .
**Definition:**
```typescript
event (
event: string | string[],
callback: function
): Botact;
```
**Usage:**
```javascript
bot.event('group_join', ({ reply }) => reply('Thanks!'))
```
### .hears(command, callback)
Add command w/ match like RegEx.
**Definition:**
```typescript
hears (
hear: string | RegExp | (string | RegExp)[],
callback: function
): Botact;
```
**Usage:**
```javascript
bot.hears(/(car|tesla)/, ({ reply }) => reply('I love Tesla!'))
```
### .on(type, callback)
Add reserved callback.
**Definition:**
```typescript
on (
type: string,
callback: function
): Botact;
OR
on (
callback: function
): Botact;
```
**Usage:**
```javascript
bot.on(({ reply }) => reply('What?'))
bot.on('audio', ({ reply }) => reply('Great music!'))
```
### .use(callback)
Add middleware.
**Definition:**
```typescript
use (
callback: function
): Botact
```
**Usage:**
```javascript
bot.use(ctx => ctx.date = new Date())
bot.on(({ date }) => {
// Fri Nov 24 2017 16:00:21 GMT+0300 (MSK)
})
```
## Botact API: Options [β](#botact-api)
### [getter] options
Get options.
```javascript
bot.options
// {
// confirmation: '12345',
// token: 'abcde...'
// }
```
### [setter] options
Set options.
```javascript
bot.options = { foo: 'bar' }
// {
// confirmation: '12345',
// token: 'abcde...',
// foo: 'bar'
// }
```
## Botact API: Upload helpers [β](#botact-api)
### .uploadCover(file, settings)
Upload and save cover. See detailed settings [here](https://vk.com/dev/photos.getOwnerCoverPhotoUploadServer).
**Definition:**
```typescript
async uploadCover (
filepath: string, // Path to file with cover
settings?: object
): Promise // Promise with response/error
```
**Usage:**
```javascript
await bot.uploadCover('./cover.jpg', { crop_x2: 1590 })
// {
// images: [
// {
// url: "URL",
// width: 1920,
// height: 1080
// },
// [Object],
// [Object],
// [Object],
// [Object]
// ]
// }
```
### .uploadDocument(file, peer_id, type)
Uploads document to peer.
**Definition:**
```typescript
async uploadDocument (
filepath: string, // Path to file
peer_id: number,
type: 'doc' | 'audio_message' // 'doc' by default
): Promise; // Promise with response/error
```
**Usage:**
```javascript
await bot.uploadDocument('./book.pdf', 1234)
// {
// response:
// [{
// id: 1234,
// owner_id: 1234,
// title: "",
// ...
// }]
// }
```
### .uploadPhoto(file, peer_id)
Uploads photo to peer.
**Definition:**
```typescript
async uploadPhoto (
filepath: string, // Path to picture
peer_id: number
): Promise // Promise with response/error
```
**Usage:**
```javascript
await bot.uploadPhoto('./picture.png', 1234)
// {
// id: 1234,
// album_id: 1234,
// owner_id: 1234,
// ...
// }
```
## Botact API: Error Handling [β](#botact-api)
### .catch(handler)
Add catch handler for errors.
**Default handler:**
```js
console.error(`β Botact Error: ${typeof err === 'object' ? JSON.stringify(err) : err}`)
```
**Usage:**
```js
// 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)
Throw error.
**Usage:**
```js
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?')
})
```
### .assert(value, message)
Helper method to throw an error similar to .throw() when !value.
```js
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?')
})
```
--------------------------------------------------------------------------------
## Botact Flow API
### Usage
```javascript
const bot = new Botact({
...,
redis: true // enable redis
flowTimeout: 20 // timeout for delete documents
redisConfig: { // redis config
port: 1234
}
})
```
```sh
$ redis-server
```
### Methods
- [.addScene(name, ...callbacks)](#addscenename-callbacks)
- [.joinScene(ctx, scene, session, step, now)](#joinscenectx-scene-session-step-now)
- [.nextScene(ctx, body)](#nextscenectx-body)
- [.leaveScene(ctx)](#leavescenectx)
### Example
```javascript
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)
```
## Botact Flow API: Methods
### .addScene(name, ...callbacks)
Add scene.
**Definition:**
```typescript
addScene (
name: string,
...args: function[]
): Botact;
```
**Usage:**
```javascript
bot.addScene('wizard',
({ reply, scene: { next } }) => {
next()
reply('Write me something!')
},
({ reply, body, scene: { leave } }) => {
leave()
reply(`You wrote: ${body}`)
}
)
```
### .joinScene(ctx, scene, session, step, now)
Enter scene.
**Definition:**
```typescript
async joinScene (
ctx: object,
scene: string,
session?: object, // {} by default
step?: number, // 0 by default
instantly?: boolean // true by default
): Promise;
```
**Usage:**
```javascript
bot.command('join', (ctx) => {
// with shortcut without additional settings
ctx.scene.join('wizard')
// simple usage with additional settings
bot.joinScene(ctx, 'wizard', { foo: 'bar' })
})
```
### .nextScene(ctx, body)
Navigate scene.
**Definition:**
```typescript
async nextScene (
ctx: object,
session?: object, // {} by default
): Promise;
```
**Usage:**
```javascript
bot.addScene('wizard',
(ctx) => {
// with shortcut without additional settings
ctx.scene.next({ foo: 'bar' })
// simple usage with additional settings
bot.nextScene(ctx, { foo: 'bar' })
}
)
```
### .leaveScene(ctx)
Leave scene.
**Definition:**
```typescript
async leaveScene(
ctx: object
): Promise;
```
**Usage:**
```javascript
bot.addScene('wizard',
(ctx) => {
// with shortcut
ctx.scene.leave()
// simple usage
bot.leaveScene(ctx)
}
)
```
--------------------------------------------------------------------------------
## TypeScript
Botact includes [TypeScript](https://www.typescriptlang.org/) definitions.
## Tests
**via npm:**
```sh
$ npm test
```
**via yarn:**
```sh
$ yarn test
```
## License
MIT.