Socket
Socket
Sign inDemoInstall

node-vk-bot

Package Overview
Dependencies
51
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.3.1 to 1.0.0

.travis.yml

19

build/functions/poll.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var rq = require("request-promise-native");
var DEFAULT_DELAY = 334;
var DEFAULT_DELAY = 1000 / 3;
var LOST_HISTORY_ERROR = 1;

@@ -9,6 +9,6 @@ var sleep = function (ms) { return new Promise(function (resolve) { return setTimeout(resolve, ms); }); };

if (delay === void 0) { delay = DEFAULT_DELAY; }
return bot.api('messages.getLongPollServer')
return bot.api('groups.getLongPollServer', { group_id: bot.options.group_id })
.then(function (res) {
return request("https://" + res.server + "?act=a_check&key=" + res.key +
("&wait=25&mode=2&version=1&ts=" + res.ts), delay);
return request(res.server + "?act=a_check&key=" + res.key +
("&wait=25&version=1&ts=" + res.ts), delay);
})

@@ -23,12 +23,11 @@ .catch(function (error) {

if (!res || !res.ts || (res.failed && res.failed !== LOST_HISTORY_ERROR))
throw new Error("response of the Long Poll server isn't valid " +
throw new Error('response of the Long Poll server isn\'t valid ' +
("(" + JSON.stringify(res) + ")"));
if (res.failed && res.failed === LOST_HISTORY_ERROR)
bot.emit('poll-error', new Error('event history went out of date ' +
'or was partially lost'));
bot.emit('poll-error', new Error('event history went out of date or was partially lost'));
url = url.replace(/ts=.*/, "ts=" + res.ts);
if (!res.failed && res.updates && res.updates.length > 0) {
for (var i = 0; i < res.updates.length; i++) {
var update = res.updates[i];
if (update[0] === 4)
for (var _i = 0, _a = res.updates; _i < _a.length; _i++) {
var update = _a[_i];
if (update.type === 'message_new')
bot.emit('update', update);

@@ -35,0 +34,0 @@ }

@@ -10,9 +10,7 @@ /// <reference types="node" />

token: string;
prefix?: RegExp;
prefixOnlyInChats?: boolean;
chats?: number[];
api?: {
lang?: string;
v?: number;
v?: string;
};
group_id: number;
}

@@ -19,0 +17,0 @@ export declare class Bot extends EventEmitter {

@@ -16,3 +16,2 @@ "use strict";

var fs = require("fs");
var UpdateToObj_1 = require("./functions/UpdateToObj");
var poll_1 = require("./functions/poll");

@@ -28,3 +27,7 @@ var Bot = (function (_super) {

if (!options.token)
throw new Error('Token can\'t be empty');
throw new Error('token can\'t be empty');
if (!options.group_id)
throw new Error('group_id can\'t be empty');
if (options.api && Number(options.api.v) < 5.80)
throw new Error('API version must be > 5.80');
return _this;

@@ -36,3 +39,3 @@ }

if (o.api) {
params.v = params.v || o.api.v || 5.62;
params.v = params.v || o.api.v || 5.80;
params.lang = params.lang || o.api.lang;

@@ -43,3 +46,3 @@ if (params.lang == null)

else
params.v = params.v || 5.62;
params.v = params.v || 5.80;
params.access_token = this.options.token;

@@ -69,34 +72,4 @@ return rq({

Bot.prototype.processUpdate = function (res) {
if (res.type === 'message_new') {
var msg = res.object;
var text_1 = msg.body;
var peer = msg.user_id;
var hasAttachments = !!msg.attachments;
var message = {
id: msg.id,
peer_id: peer,
date: msg.date,
title: msg.title,
body: text_1,
user_id: peer,
attachments: msg.attachments || []
};
if (hasAttachments && msg.attachments[0].type === 'sticker')
return this.emit('sticker', message);
if (hasAttachments && msg.attachments[0].type === 'doc' && msg.attachments[0].doc.preview.audio_msg)
return this.emit('voice', message);
if (!text_1 && !hasAttachments)
return;
if (this.options.chats && this.options.chats.length && !this.options.chats.includes(peer))
return;
var ev = this._userEvents.find(function (_a) {
var pattern = _a.pattern;
return pattern.test(text_1);
});
if (!ev) {
this.emit('command-notfound', message);
return;
}
ev.listener(message, ev.pattern.exec(text_1));
}
if (res.type === 'message_new')
return this._update(res);
};

@@ -139,38 +112,30 @@ Bot.prototype.start = function (poll_delay) {

Bot.prototype._update = function (update) {
var text = update[6];
var peer = update[3];
var flag = update[2];
var isChat = peer > 2e9;
var isOutcoming = flag & 2;
var hasAttachments = !!Object.keys(update[7]).length;
if (hasAttachments && update[7].attach1_type === 'sticker')
return this.emit('sticker', UpdateToObj_1.default(update));
if (hasAttachments && update[7].attach1_type === 'doc' && update[7].attach1_kind === 'audiomsg')
return this.emit('voice', UpdateToObj_1.default(update));
if (!text && !hasAttachments)
var msg = update.object;
var hasAttachments = msg.attachments.length;
var message = {
id: msg.id,
peer_id: msg.peer_id,
from_id: msg.from_id,
date: msg.date,
text: msg.text,
attachments: msg.attachments,
important: msg.important,
conversation_message_id: msg.conversation_message_id,
fwd_messages: msg.fwd_messages
};
if (hasAttachments && msg.attachments[0].type === 'sticker')
return this.emit('sticker', message);
if (hasAttachments && msg.attachments[0].type === 'doc' && msg.attachments[0].doc.preview.audio_msg)
return this.emit('voice', message);
if (!message.text && !hasAttachments)
return;
if (this.options.chats && this.options.chats.length && !this.options.chats.includes(peer))
return;
if (this.options.prefix) {
var p = this.options.prefix;
if (text.search(p) !== 0) {
if (!this.options.prefixOnlyInChats)
return;
if (this.options.prefixOnlyInChats && (isChat || isOutcoming))
return;
}
}
else {
if (isOutcoming)
return;
}
var ev = this._userEvents.find(function (_a) {
var pattern = _a.pattern;
return pattern.test(text);
return pattern.test(message.text);
});
if (!ev) {
this.emit('command-notfound', UpdateToObj_1.default(update));
this.emit('command-notfound', message);
return;
}
ev.listener(UpdateToObj_1.default(update), ev.pattern.exec(text));
ev.listener(message, ev.pattern.exec(message.text));
};

@@ -177,0 +142,0 @@ return Bot;

@@ -5,6 +5,8 @@ export interface Message {

date: number;
title: string;
body: string;
user_id: number;
text: string;
from_id: number;
attachments: any;
important: boolean;
conversation_message_id: number;
fwd_messages: any;
}

@@ -32,2 +32,3 @@ module.exports = function (grunt) {

grunt.registerTask('default', ['clean', 'ts'])
grunt.registerTask('test', ['tslint'])
}
{
"name": "node-vk-bot",
"version": "0.3.1",
"version": "1.0.0",
"description": "Create and control VK bots easily.",

@@ -8,3 +8,3 @@ "main": "./build/index.js",

"scripts": {
"test": "grunt && ./node_modules/mocha/bin/mocha"
"test": "grunt test"
},

@@ -28,7 +28,6 @@ "repository": {

"@types/request-promise": "*",
"grunt": "^1.0.2",
"grunt": "^1.0.3",
"grunt-contrib-clean": "^1.0.0",
"grunt-ts": "^6.0.0-beta.17",
"grunt-tslint": "^4.0.0",
"mocha": "^5.2.0",
"tslint": "^4.4.2",

@@ -35,0 +34,0 @@ "typescript": "^2.7.2"

@@ -1,8 +0,6 @@

[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a0950ccdf7b54dd7a7b7bc23fa7e7123)](https://www.codacy.com/app/Eblonko/node-vk-bot?utm_source=github.com&utm_medium=referral&utm_content=Eblonko/node-vk-bot&utm_campaign=badger)
[![CircleCI](https://circleci.com/gh/vitalyavolyn/node-vk-bot.svg?style=shield)](https://circleci.com/gh/vitalyavolyn/node-vk-bot)
[![Build Status](https://travis-ci.org/vitalyavolyn/node-vk-bot.svg?branch=master)](https://travis-ci.org/vitalyavolyn/node-vk-bot)
# Боты ВКонтакте
Библиотека для создания чат-ботов ВК.
Поддерживает создание ботоов и на страницах пользователей, и в сообществах.
Для получения новых сообщений используется LongPoll, для сообществ также можно использовать Callback API.
Для получения новых сообщений используется LongPoll или Callback API.

@@ -25,3 +23,3 @@ ```sh

token: 'YOUR TOKEN',
prefix: /^Bot[\s,]/
group_id: 123456
}).start()

@@ -36,33 +34,9 @@

Тот же пример, используя webhook:
```javascript
const express = require('express');
const bodyParser = require('body-parser');
const { Bot } = require('node-vk-bot');
const bot = new Bot({
token: 'Community API token'
})
[Больше примеров](https://github.com/vitalyavolyn/node-vk-bot/tree/master/examples) (как использовать вебхуки, загружать фото, ...)
const port = 8000
const app = express();
# Боты, созданные с помощью этой библиотеки
если вы хотите добавить своего в этот список, просто сделайте pull request
app.use(bodyParser.json());
- [**GitHub Events**](https://vk.com/githubbot) - Оповещения о новых коммитах, issues и т.д. в сообщения ВК _by [@vitalyavolyn](https://github.com/vitalyavolyn)_
app.post('/bot', (req, res) => {
if (req.body.type == 'confirmation') res.send('CONFIRMATION CODE')
bot.processUpdate(req.body);
res.sendStatus(200);
});
app.listen(port, () => {
console.log(`Express server is listening on ${port}`);
});
bot.get(/Hi|Hello|Hey/i, message => {
bot.send('Hello!', message.peer_id)
})
```
Настройте адрес сервера в настройках сообщества
# Содержание

@@ -91,9 +65,3 @@ - [Начало работы](#getting-started)

Разберем код примера c LongPoll
1. Создаем бота, используя класс `Bot` c [токеном доступа](https://vk.com/dev/access_token).
Получить токен:
```
https://oauth.vk.com/authorize?client_id= АЙДИ ПРИЛОЖЕНИЯ ВК &scope=photos,messages,offline&display=touch&response_type=token
```
1. Создаем бота, используя класс `Bot`.
2. Вызов `bot.start()` начинает получение новых сообщений.

@@ -109,11 +77,6 @@ 3. Затем мы тестируем каждое входящее сообщение с помощью `/Hi|Hello|Hey/i`, и если сообщеине подходит, отвечаем на него.

new Bot({
token: '5a9bdc30ea18ab4a685a8f773642ba0d', // Нет, этот токен не работает
prefix: /^Bot[\s,]/,
prefixOnlyInChats: true,
chats: [
1,
2e9 + 12
],
token: 'TOKEN',
group_id: 123456,
api: {
v: 5.62, // >= 5.38
v: 5.62, // >= 5.80
lang: 'ru'

@@ -127,12 +90,7 @@ }

| token | String | Да |
| prefix | RexExp | Нет |
| prefixOnlyInChats | Boolean | Нет |
| chats | Array | Нет |
| group_id | Number | Да |
| api | Object| Нет |
Если `prefix` установлен, бот будет работать только с сообщениями, в начале которых есть префикс. (если `prefixOnlyInChats` = `true`, префикс будет проверен только для сообщений из групповых чатов). `prefix` не проверяется, если используется Callback API<br>
Если указать `chats`, бот будет работать только с сообщениями из этих чатов
`api` - объект с настройками API: **v**ersion и **lang**uage. (и то, и то - строки) ([узнать больше](https://vk.com/dev/api_requests))
`api` - объект с настройками API: **v**ersion и **lang**uage. ([узнать больше](https://vk.com/dev/api_requests))
-------

@@ -196,3 +154,3 @@

Функция для использования Callback API.
[Пример](#example)
Пример в папке `examples`

@@ -216,3 +174,3 @@ -------

bot.on('update', update => {
if (update[7].from === 1) {
if (update.from_id === 1) {
console.log('Got a message from Pavel Durov!');

@@ -260,10 +218,14 @@ }

interface Message {
id: number, // message id
peer_id: number, // message's chat peer_id
date: number, // time (in Unixtime format)
title: string, // chat title
body: string, // message text
user_id: number, // sender's ID
attachments: Object // vk.com/dev/using_longpoll - see the attachments section
id: number,
peer_id: number,
date: number,
text: string,
from_id: number,
attachments: any,
important: boolean,
conversation_message_id: number,
fwd_messages: any
}
// https://vk.com/dev/objects/message
```

@@ -1,3 +0,2 @@

[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a0950ccdf7b54dd7a7b7bc23fa7e7123)](https://www.codacy.com/app/Eblonko/node-vk-bot?utm_source=github.com&utm_medium=referral&utm_content=Eblonko/node-vk-bot&utm_campaign=badger)
[![CircleCI](https://circleci.com/gh/vitalyavolyn/node-vk-bot.svg?style=shield)](https://circleci.com/gh/vitalyavolyn/node-vk-bot)
[![Build Status](https://travis-ci.org/vitalyavolyn/node-vk-bot.svg?branch=master)](https://travis-ci.org/vitalyavolyn/node-vk-bot)

@@ -7,6 +6,4 @@ [README на русском](https://github.com/vitalyavolyn/node-vk-bot/blob/master/README_ru.md)

# VK BOTS
Create and control VK bots easily.
Works with both profile and group tokens!
Uses LongPoll to get new messages
Supports Callback API for communities
- Create and control VK bots easily.
- Uses LongPoll or Callback API to get new messages

@@ -29,3 +26,3 @@ ```sh

token: 'YOUR TOKEN',
prefix: /^Bot[\s,]/
group_id: 123456
}).start()

@@ -40,33 +37,9 @@

Using webhook:
```javascript
const express = require('express');
const bodyParser = require('body-parser');
const { Bot } = require('node-vk-bot');
const bot = new Bot({
token: 'Community API token'
})
[More examples](https://github.com/vitalyavolyn/node-vk-bot/tree/master/examples) (how to use webhooks, upload pictures, ...)
const port = 8000
const app = express();
# Bots created with this library
if you want your bot to be in this list, just make a pull request
app.use(bodyParser.json());
- [**GitHub Events**](https://vk.com/githubbot) - Notifies you about new issues, commits, etc. in private messages _by [@vitalyavolyn](https://github.com/vitalyavolyn)_
app.post('/bot', (req, res) => {
if (req.body.type == 'confirmation') res.send('CONFIRMATION CODE')
bot.processUpdate(req.body);
res.sendStatus(200);
});
app.listen(port, () => {
console.log(`Express server is listening on ${port}`);
});
bot.get(/Hi|Hello|Hey/i, message => {
bot.send('Hello!', message.peer_id)
})
```
Set up webhook URL in community settings
# Table of contents

@@ -96,9 +69,3 @@ - [Getting Started](#getting-started)

1. Then I create a bot instance, with my [token](https://vk.com/dev/access_token).
get yourself one:
```
https://oauth.vk.com/authorize?client_id= YOUR APP ID &scope=photos,messages,offline&display=touch&response_type=token
```
1. Then I create a bot instance with my group's token.
2. By calling `bot.start()` the bot starts polling updates from the server.

@@ -114,11 +81,6 @@ 3. Then I simply listen on messages which pass the RegExp test, when I get such message, Then I send a new message with text 'Hello' to that chat with a forwarded message.

new Bot({
token: '5a9bdc30ea18ab4a685a8f773642ba0d', // don't even try to use this token
prefix: /^Bot[\s,]/,
prefixOnlyInChats: true,
chats: [
1,
2e9 + 12
],
token: 'TOKEN',
group_id: 123456
api: {
v: 5.62, // >= 5.38
v: 5.80, // >= 5.80
lang: 'ru'

@@ -132,12 +94,7 @@ }

| token | String | Yes |
| prefix | RexExp | No |
| prefixOnlyInChats | Boolean | No |
| chats | Array | No |
| group_id | Number | Yes
| api | Object| No |
If `prefix` is set, the bot will work only with messages with prefix match. (if `prefixOnlyInChats` is `true`, then prefix will be checked only for messages from group chats). `prefix` isn't chacked if using Callback API.<br>
If `chats` is set, the bot will work only with messages from these chats
`api` is object with API settings: **v**ersion and **lang**uage. (both strings) ([Read more](https://vk.com/dev/api_requests))
`api` is object with API settings: **v**ersion and **lang**uage. ([Read more](https://vk.com/dev/api_requests))
-------

@@ -201,3 +158,3 @@

Process an update from Callback API.
[Example](#example)
Example of usage may be found in `examples` folder

@@ -221,3 +178,3 @@ -------

bot.on('update', update => {
if (update[7].from === 1) {
if (update.from_id === 1) {
console.log('Got a message from Pavel Durov!');

@@ -265,10 +222,14 @@ }

interface Message {
id: number, // message id
peer_id: number, // message's chat peer_id
date: number, // time (in Unixtime format)
title: string, // chat title
body: string, // message text
user_id: number, // sender's ID
attachments: Object // vk.com/dev/using_longpoll - see the attachments section
id: number,
peer_id: number,
date: number,
text: string,
from_id: number,
attachments: any,
important: boolean,
conversation_message_id: number,
fwd_messages: any
}
// Reference: https://vk.com/dev/objects/message
```
import * as rq from 'request-promise-native'
const DEFAULT_DELAY = 334 // 1/3 of a second
const DEFAULT_DELAY = 1000 / 3 // 1/3 of a second
const LOST_HISTORY_ERROR = 1

@@ -9,6 +9,6 @@

export default function poll (bot, delay: number = DEFAULT_DELAY) {
return bot.api('messages.getLongPollServer')
return bot.api('groups.getLongPollServer', { group_id: bot.options.group_id })
.then(res => {
return request(`https://${res.server}?act=a_check&key=${res.key}` +
`&wait=25&mode=2&version=1&ts=${res.ts}`, delay)
return request(`${res.server}?act=a_check&key=${res.key}` +
`&wait=25&version=1&ts=${res.ts}`, delay)
})

@@ -26,13 +26,13 @@ .catch(error => {

if (!res || !res.ts || (res.failed && res.failed !== LOST_HISTORY_ERROR))
throw new Error("response of the Long Poll server isn't valid " +
throw new Error('response of the Long Poll server isn\'t valid ' +
`(${JSON.stringify(res)})`)
if (res.failed && res.failed === LOST_HISTORY_ERROR)
bot.emit('poll-error', new Error('event history went out of date ' +
'or was partially lost'))
bot.emit('poll-error', new Error('event history went out of date or was partially lost'))
url = url.replace(/ts=.*/, `ts=${res.ts}`) // ставим новое время
if (!res.failed && res.updates && res.updates.length > 0) {
for (let i = 0; i < res.updates.length; i++) {
let update = res.updates[i]
if (update[0] === 4) bot.emit('update', update)
for (let update of res.updates) {
if (update.type === 'message_new') bot.emit('update', update)
}

@@ -39,0 +39,0 @@ }

@@ -5,3 +5,2 @@ import { EventEmitter } from 'events'

import UpdateToObj from './functions/UpdateToObj'
import poll from './functions/poll'

@@ -17,6 +16,4 @@

token: string,
prefix?: RegExp,
prefixOnlyInChats?: boolean,
chats?: number[],
api?: { lang?: string, v?: number}
api?: { lang?: string, v?: string},
group_id: number
}

@@ -32,3 +29,5 @@

if (!options.token) throw new Error('Token can\'t be empty')
if (!options.token) throw new Error('token can\'t be empty')
if (!options.group_id) throw new Error('group_id can\'t be empty')
if (options.api && Number(options.api.v) < 5.80) throw new Error('API version must be > 5.80')
}

@@ -46,6 +45,6 @@

if (o.api) {
params.v = params.v || o.api.v || 5.62
params.v = params.v || o.api.v || 5.80
params.lang = params.lang || o.api.lang
if (params.lang == null) delete params.lang
} else params.v = params.v || 5.62
} else params.v = params.v || 5.80

@@ -88,34 +87,3 @@ params.access_token = this.options.token

processUpdate (res: any) {
if (res.type === 'message_new') {
let msg = res.object
const text : string = msg.body
const peer : number = msg.user_id
const hasAttachments : boolean = !!msg.attachments
const message : Message = {
id: msg.id,
peer_id: peer,
date: msg.date,
title: msg.title,
body: text,
user_id: peer,
attachments: msg.attachments || []
}
if (hasAttachments && msg.attachments[0].type === 'sticker') return this.emit('sticker', message)
if (hasAttachments && msg.attachments[0].type === 'doc' && msg.attachments[0].doc.preview.audio_msg) return this.emit('voice', message)
if (!text && !hasAttachments) return
if (this.options.chats && this.options.chats.length && !this.options.chats.includes(peer)) return
const ev = this._userEvents.find(({ pattern }) => pattern.test(text))
if (!ev) {
this.emit('command-notfound', message)
return
}
ev.listener(message, ev.pattern.exec(text))
}
if (res.type === 'message_new') return this._update(res)
}

@@ -183,32 +151,31 @@

private _update (update) {
const text : string = update[6]
const peer : number = update[3]
const flag : number = update[2]
const isChat = peer > 2e9
const isOutcoming = flag & 2
const hasAttachments : boolean = !!Object.keys(update[7]).length
let msg = update.object
if (hasAttachments && update[7].attach1_type === 'sticker') return this.emit('sticker', UpdateToObj(update))
if (hasAttachments && update[7].attach1_type === 'doc' && update[7].attach1_kind === 'audiomsg') return this.emit('voice', UpdateToObj(update))
const hasAttachments : boolean = msg.attachments.length
if (!text && !hasAttachments) return
if (this.options.chats && this.options.chats.length && !this.options.chats.includes(peer)) return
if (this.options.prefix) {
const p = this.options.prefix
if (text.search(p) !== 0) { // not starts with prefix
if (!this.options.prefixOnlyInChats) return
if (this.options.prefixOnlyInChats && (isChat || isOutcoming)) return
}
} else {
if (isOutcoming) return
const message : Message = {
id: msg.id,
peer_id: msg.peer_id,
from_id: msg.from_id,
date: msg.date,
text: msg.text,
attachments: msg.attachments,
important: msg.important,
conversation_message_id: msg.conversation_message_id,
fwd_messages: msg.fwd_messages
}
const ev = this._userEvents.find(({ pattern }) => pattern.test(text))
if (hasAttachments && msg.attachments[0].type === 'sticker') return this.emit('sticker', message)
if (hasAttachments && msg.attachments[0].type === 'doc' && msg.attachments[0].doc.preview.audio_msg) return this.emit('voice', message)
if (!message.text && !hasAttachments) return
const ev = this._userEvents.find(({ pattern }) => pattern.test(message.text))
if (!ev) {
this.emit('command-notfound', UpdateToObj(update))
this.emit('command-notfound', message)
return
}
ev.listener(UpdateToObj(update), ev.pattern.exec(text))
ev.listener(message, ev.pattern.exec(message.text))
}

@@ -215,0 +182,0 @@ }

@@ -5,6 +5,8 @@ export interface Message {

date: number,
title: string,
body: string,
user_id: number,
attachments: any
text: string,
from_id: number,
attachments: any,
important: boolean,
conversation_message_id: number,
fwd_messages: any
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc