chore(lint): update eslint configuration, re-lint
chore(gitignore): don't ignore src/types
This commit is contained in:
parent
a357cd7368
commit
c76eb0c64d
60
.eslintrc
60
.eslintrc
@ -1,59 +1,13 @@
|
|||||||
{
|
{
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
"extends": "airbnb/base",
|
||||||
|
"root": true,
|
||||||
"env": {
|
"env": {
|
||||||
"es6": true,
|
"node": true
|
||||||
"browser": true
|
|
||||||
},
|
|
||||||
"ecmaFeatures": {
|
|
||||||
"modules": true
|
|
||||||
},
|
|
||||||
"globals": {
|
|
||||||
"exports": true,
|
|
||||||
"require": true,
|
|
||||||
"ViewHelpers": true,
|
|
||||||
"is": true,
|
|
||||||
"Components": true,
|
|
||||||
"XPCOMUtils": true,
|
|
||||||
"EventEmitter": true,
|
|
||||||
"add_task": true,
|
|
||||||
"info": true,
|
|
||||||
"createHost": true,
|
|
||||||
"promiseTab": true,
|
|
||||||
"ok": true,
|
|
||||||
"TEST_URI_ROOT": true,
|
|
||||||
"TargetFactory": true,
|
|
||||||
"gBrowser": true,
|
|
||||||
"gDevTools": true
|
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"comma-dangle": [2, "never"],
|
"comma-dangle": 0,
|
||||||
"no-underscore-dangle": 0,
|
"no-param-reassign": 0,
|
||||||
"no-cond-assign": 0,
|
"no-console": 0
|
||||||
"no-undef": 0,
|
|
||||||
"no-console": 0,
|
|
||||||
"no-reserved-keys": 2,
|
|
||||||
"valid-jsdoc": [2, {
|
|
||||||
"requireReturn": false,
|
|
||||||
"requireParamDescription": false,
|
|
||||||
"requireReturnDescription": false
|
|
||||||
}],
|
|
||||||
"max-len": [1, 80],
|
|
||||||
"no-use-before-define": 0,
|
|
||||||
"no-self-compare": 1,
|
|
||||||
"no-sequences": 0,
|
|
||||||
"radix": 2,
|
|
||||||
"wrap-iife": 2,
|
|
||||||
"indent": [2, 2],
|
|
||||||
"brace-style": [2, "1tbs"],
|
|
||||||
"comma-style": [2, "last"],
|
|
||||||
"no-lonely-if": 2,
|
|
||||||
"no-multiple-empty-lines": [2, {"max": 2}],
|
|
||||||
"quotes": 0,
|
|
||||||
"space-after-keywords": [2, "always"],
|
|
||||||
"space-before-blocks": [2, "always"],
|
|
||||||
"space-infix-ops": [2, { "int32Hint": false }],
|
|
||||||
"strict": 0,
|
|
||||||
"global-strict": 0,
|
|
||||||
"no-new": 0,
|
|
||||||
"camelcase": 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,3 +1,7 @@
|
|||||||
|
build
|
||||||
|
types
|
||||||
|
!src/types
|
||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
@ -30,6 +34,3 @@ node_modules
|
|||||||
test.js
|
test.js
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
build
|
|
||||||
types
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "telegram-api",
|
"name": "telegram-api",
|
||||||
"version": "0.7.0",
|
"version": "0.7.1",
|
||||||
"description": "Control Telegram bots easily using the new Telegram API",
|
"description": "Control Telegram bots easily using the new Telegram API",
|
||||||
"main": "build/index.js",
|
"main": "build/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -39,13 +39,16 @@
|
|||||||
"unirest": "0.4.2"
|
"unirest": "0.4.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"babel-eslint": "6.0.0",
|
||||||
"babel-plugin-add-module-exports": "^0.1.2",
|
"babel-plugin-add-module-exports": "^0.1.2",
|
||||||
"babel-preset-es2015": "^6.6.0",
|
"babel-preset-es2015": "^6.6.0",
|
||||||
|
"eslint-config-airbnb": "6.2.0",
|
||||||
"grunt": "^0.4.5",
|
"grunt": "^0.4.5",
|
||||||
"grunt-babel": "^6.0.0",
|
"grunt-babel": "^6.0.0",
|
||||||
"grunt-contrib-clean": "^1.0.0",
|
"grunt-contrib-clean": "^1.0.0",
|
||||||
"grunt-contrib-copy": "^1.0.0",
|
"grunt-contrib-copy": "^1.0.0",
|
||||||
"grunt-contrib-watch": "^1.0.0",
|
"grunt-contrib-watch": "^1.0.0",
|
||||||
"grunt-copy": "^0.1.0"
|
"grunt-copy": "^0.1.0",
|
||||||
|
"grunt-eslint": "18.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ export default class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
API.prototype.request = function request(method, data) {
|
API.prototype.request = function request(method, data) {
|
||||||
return fetch(this.token + '/' + method, data);
|
return fetch(`${this.token}/${method}`, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const methods = ['getMe', 'sendMessage', 'forwardMessage', 'sendPhoto',
|
const methods = ['getMe', 'sendMessage', 'forwardMessage', 'sendPhoto',
|
||||||
@ -29,7 +29,7 @@ const methods = ['getMe', 'sendMessage', 'forwardMessage', 'sendPhoto',
|
|||||||
'getUpdates', 'setWebhook'];
|
'getUpdates', 'setWebhook'];
|
||||||
|
|
||||||
methods.forEach(method => {
|
methods.forEach(method => {
|
||||||
API.prototype[method] = function(data) {
|
API.prototype[method] = function(data) { //eslint-disable-line
|
||||||
return this.request(method, data);
|
return this.request(method, data);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -8,6 +8,32 @@ const REQUIRED = 0;
|
|||||||
const OPTIONAL = 1;
|
const OPTIONAL = 1;
|
||||||
const REST = 2;
|
const REST = 2;
|
||||||
|
|
||||||
|
function escape(symbols, append = '') {
|
||||||
|
return symbols.split('').map(symbol =>
|
||||||
|
(ESCAPABLE.indexOf(symbol) ? `\\${symbol}` : symbol) + append
|
||||||
|
).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
const TYPES = {
|
||||||
|
number: '\\d',
|
||||||
|
word: '\\S'
|
||||||
|
};
|
||||||
|
|
||||||
|
function getFormat(type = 'word', param = 'required') {
|
||||||
|
const t = TYPES[type];
|
||||||
|
|
||||||
|
switch (param) { // eslint-disable-line
|
||||||
|
case 'required':
|
||||||
|
return `(${t}+)`;
|
||||||
|
case 'optional':
|
||||||
|
return `(${t}+)?`;
|
||||||
|
case 'rest':
|
||||||
|
return '(.*)';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a message for arguments, based on format
|
* Parses a message for arguments, based on format
|
||||||
*
|
*
|
||||||
@ -41,74 +67,49 @@ export default function argumentParser(format, string) {
|
|||||||
format = format.replace(/[^\s]+/, '').trim();
|
format = format.replace(/[^\s]+/, '').trim();
|
||||||
|
|
||||||
if (!format) {
|
if (!format) {
|
||||||
return {args: {}, params: {}};
|
return { args: {}, params: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
let indexes = [],
|
let indexes = [];
|
||||||
params = {};
|
const params = {};
|
||||||
|
|
||||||
format = format.replace(/\s/g, '\\s*');
|
format = format.replace(/\s/g, '\\s*');
|
||||||
format = format.replace(FORMAT_REQUIRED,
|
format = format.replace(FORMAT_REQUIRED,
|
||||||
(f, symbols, arg, type = 'word', offset) => {
|
(f, symbols, arg, type = 'word', offset) => {
|
||||||
indexes.push({arg, offset});
|
indexes.push({ arg, offset });
|
||||||
params[arg] = REQUIRED;
|
params[arg] = REQUIRED;
|
||||||
return (escape(symbols) + getFormat(type, 'required')).trim();
|
return (escape(symbols) + getFormat(type, 'required')).trim();
|
||||||
});
|
});
|
||||||
format = format.replace(FORMAT_OPTIONAL,
|
format = format.replace(FORMAT_OPTIONAL,
|
||||||
(f, symbols, arg, type = 'word', offset) => {
|
(f, symbols, arg, type = 'word', offset) => {
|
||||||
indexes.push({arg, offset});
|
indexes.push({ arg, offset });
|
||||||
params[arg] = OPTIONAL;
|
params[arg] = OPTIONAL;
|
||||||
return (escape(symbols, '?') + getFormat(type, 'optional')).trim();
|
return (escape(symbols, '?') + getFormat(type, 'optional')).trim();
|
||||||
});
|
});
|
||||||
format = format.replace(FORMAT_REST, (full, arg, offset) => {
|
format = format.replace(FORMAT_REST, (full, arg, offset) => {
|
||||||
indexes.push({offset, arg});
|
indexes.push({ offset, arg });
|
||||||
params[arg] = REST;
|
params[arg] = REST;
|
||||||
return getFormat(null, 'rest');
|
return getFormat(null, 'rest');
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!string) {
|
if (!string) {
|
||||||
return {args: {}, params};
|
return { args: {}, params };
|
||||||
}
|
}
|
||||||
|
|
||||||
indexes = indexes.sort((a, b) => {
|
indexes = indexes.sort((a, b) =>
|
||||||
return a.offset < b.offset ? -1 : 1;
|
(a.offset < b.offset ? -1 : 1)
|
||||||
});
|
);
|
||||||
|
|
||||||
const regex = new RegExp(format);
|
const regex = new RegExp(format);
|
||||||
|
|
||||||
const matched = regex.exec(string).slice(1);
|
const matched = regex.exec(string).slice(1);
|
||||||
|
|
||||||
const object = {};
|
const object = {};
|
||||||
for (let [index, match] of matched.entries()) {
|
for (const [index, match] of matched.entries()) {
|
||||||
const argument = indexes[index];
|
const argument = indexes[index];
|
||||||
|
|
||||||
object[argument.arg] = match;
|
object[argument.arg] = match;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {args: object, params};
|
return { args: object, params };
|
||||||
}
|
|
||||||
|
|
||||||
function escape(symbols, append = '') {
|
|
||||||
return symbols.split('').map(symbol => {
|
|
||||||
return (ESCAPABLE.indexOf(symbol) ? `\\${symbol}` : symbol) + append;
|
|
||||||
}).join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const TYPES = {
|
|
||||||
'number': '\\d',
|
|
||||||
'word': '\\S'
|
|
||||||
};
|
|
||||||
|
|
||||||
function getFormat(type = 'word', param = 'required') {
|
|
||||||
const t = TYPES[type];
|
|
||||||
|
|
||||||
switch (param) {
|
|
||||||
case 'required':
|
|
||||||
return `(${t}+)`;
|
|
||||||
case 'optional':
|
|
||||||
return `(${t}+)?`;
|
|
||||||
case 'rest':
|
|
||||||
return `(.*)`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,14 @@ export default function fetch(path, data = {}) {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const files = {};
|
const files = {};
|
||||||
|
|
||||||
for (let key of Object.keys(data)) {
|
for (const key of Object.keys(data)) {
|
||||||
if (data[key].file) {
|
if (data[key].file) {
|
||||||
files[key] = data[key].file;
|
files[key] = data[key].file;
|
||||||
delete data[key];
|
delete data[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unirest.post('https://api.telegram.org/bot' + path)
|
unirest.post(`https://api.telegram.org/bot${path}`)
|
||||||
.field(data)
|
.field(data)
|
||||||
.attach(files)
|
.attach(files)
|
||||||
.end(response => {
|
.end(response => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import https from 'http';
|
import https from 'http';
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
import {getBody} from './fetch';
|
import { getBody } from './fetch';
|
||||||
|
|
||||||
const DEFAULTS = {
|
const DEFAULTS = {
|
||||||
server: {},
|
server: {},
|
||||||
@ -11,14 +11,12 @@ export default function webhook(options = {}, bot) {
|
|||||||
options = Object.assign(DEFAULTS, options);
|
options = Object.assign(DEFAULTS, options);
|
||||||
|
|
||||||
return bot.api.setWebhook(options.url).then(() => {
|
return bot.api.setWebhook(options.url).then(() => {
|
||||||
|
bot._webhookServer = https.createServer(options.server, (req, res) =>
|
||||||
bot._webhookServer = https.createServer(options.server, (req, res) => {
|
getBody(req).then(data => {
|
||||||
return getBody(req).then(data => {
|
|
||||||
bot.emit('update', qs.parse(data).result);
|
bot.emit('update', qs.parse(data).result);
|
||||||
|
|
||||||
res.end('OK');
|
res.end('OK');
|
||||||
});
|
})
|
||||||
}).listen(options.port);
|
).listen(options.port);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
20
src/index.js
20
src/index.js
@ -3,7 +3,7 @@ import API from './functions/api';
|
|||||||
import webhook from './functions/webhook';
|
import webhook from './functions/webhook';
|
||||||
import poll from './functions/poll';
|
import poll from './functions/poll';
|
||||||
import argumentParser from './functions/argument-parser';
|
import argumentParser from './functions/argument-parser';
|
||||||
import {EventEmitter} from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import Message from './types/Message';
|
import Message from './types/Message';
|
||||||
import File from './types/File';
|
import File from './types/File';
|
||||||
import Keyboard from './types/Keyboard';
|
import Keyboard from './types/Keyboard';
|
||||||
@ -31,7 +31,7 @@ export default class Bot extends EventEmitter {
|
|||||||
* Create and connect to a new bot
|
* Create and connect to a new bot
|
||||||
* @param {object} options Bot properties.
|
* @param {object} options Bot properties.
|
||||||
*/
|
*/
|
||||||
constructor(options = {update: {}}) {
|
constructor(options = { update: {} }) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
if (!options.token) {
|
if (!options.token) {
|
||||||
@ -80,9 +80,9 @@ export default class Bot extends EventEmitter {
|
|||||||
|
|
||||||
if (hook) {
|
if (hook) {
|
||||||
return webhook(hook, this);
|
return webhook(hook, this);
|
||||||
} else {
|
|
||||||
return poll(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return poll(this);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ export default class Bot extends EventEmitter {
|
|||||||
res.message.text = text;
|
res.message.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ev = this._userEvents.find(({pattern}) => pattern.test(text));
|
const ev = this._userEvents.find(({ pattern }) => pattern.test(text));
|
||||||
|
|
||||||
if (!ev) {
|
if (!ev) {
|
||||||
this.emit('command-notfound', res.message);
|
this.emit('command-notfound', res.message);
|
||||||
@ -194,12 +194,12 @@ export default class Bot extends EventEmitter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {params, args} = ev.parse(res.message.text);
|
const { params, args } = ev.parse(res.message.text);
|
||||||
res.message.args = args;
|
res.message.args = args;
|
||||||
|
|
||||||
const requiredParams = Object.keys(params).filter(param => {
|
const requiredParams = Object.keys(params).filter(param =>
|
||||||
return params[param] === REQUIRED && !args[param];
|
params[param] === REQUIRED && !args[param]
|
||||||
});
|
);
|
||||||
|
|
||||||
if (!requiredParams.length) {
|
if (!requiredParams.length) {
|
||||||
ev.listener(res.message);
|
ev.listener(res.message);
|
||||||
@ -208,7 +208,7 @@ export default class Bot extends EventEmitter {
|
|||||||
|
|
||||||
const bot = this;
|
const bot = this;
|
||||||
function* getAnswer() {
|
function* getAnswer() {
|
||||||
for (let param of requiredParams) {
|
for (const param of requiredParams) {
|
||||||
const msg = new Message().to(res.message.chat.id)
|
const msg = new Message().to(res.message.chat.id)
|
||||||
.text(`Enter value for ${param}`);
|
.text(`Enter value for ${param}`);
|
||||||
yield bot.send(msg).then(answer => {
|
yield bot.send(msg).then(answer => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {EventEmitter} from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
|
||||||
const ANSWER_THRESHOLD = 10;
|
const ANSWER_THRESHOLD = 10;
|
||||||
|
|
||||||
@ -29,8 +29,8 @@ export default class Base extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
send(bot) {
|
send(bot) {
|
||||||
if (this._keyboard) {
|
if (this._keyboard) {
|
||||||
const reply_markup = JSON.stringify(this._keyboard.getProperties());
|
const replyMarkup = JSON.stringify(this._keyboard.getProperties());
|
||||||
this.properties.reply_markup = reply_markup;
|
this.properties.reply_markup = replyMarkup;
|
||||||
}
|
}
|
||||||
|
|
||||||
let messageId;
|
let messageId;
|
||||||
@ -49,15 +49,15 @@ export default class Base extends EventEmitter {
|
|||||||
bot.on('update', function listener(result) {
|
bot.on('update', function listener(result) {
|
||||||
answers += result.length;
|
answers += result.length;
|
||||||
|
|
||||||
const update = result.find(({message}) => {
|
const update = result.find(({ message }) => {
|
||||||
// if in a group, there will be a reply to this message
|
// if in a group, there will be a reply to this message
|
||||||
if (chat < 0) {
|
if (chat < 0) {
|
||||||
return message.chat.id === chat
|
return message.chat.id === chat
|
||||||
&& message.reply_to_message
|
&& message.reply_to_message
|
||||||
&& message.reply_to_message.message_id === messageId;
|
&& message.reply_to_message.message_id === messageId;
|
||||||
} else {
|
|
||||||
return message.chat.id === chat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return message.chat.id === chat;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (update) {
|
if (update) {
|
||||||
|
@ -20,9 +20,7 @@ export default class BulkMessage extends Message {
|
|||||||
* @return {object} returns the message object
|
* @return {object} returns the message object
|
||||||
*/
|
*/
|
||||||
to(...args) {
|
to(...args) {
|
||||||
const chats = args.reduce((a, b) => {
|
const chats = args.reduce((a, b) => a.concat(b), []);
|
||||||
return a.concat(b);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
this.chats = chats;
|
this.chats = chats;
|
||||||
return this;
|
return this;
|
||||||
|
@ -37,12 +37,12 @@ export default class File extends Base {
|
|||||||
*/
|
*/
|
||||||
file(file, fileType) {
|
file(file, fileType) {
|
||||||
if (fileType) {
|
if (fileType) {
|
||||||
this.properties[fileType] = {file: file};
|
this.properties[fileType] = { file };
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
let [type, extension] = mime.lookup(file).split('/');
|
let [type, extension] = mime.lookup(file).split('/'); // eslint-disable-line
|
||||||
if (type === 'image') {
|
if (type === 'image') {
|
||||||
type = 'photo';
|
type = 'photo';
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ export default class File extends Base {
|
|||||||
type = 'document';
|
type = 'document';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.properties[type] = {file: file};
|
this.properties[type] = { file };
|
||||||
|
|
||||||
this.method = `send${type[0].toUpperCase() + type.slice(1)}`;
|
this.method = `send${type[0].toUpperCase() + type.slice(1)}`;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ export default class Question extends Message {
|
|||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
let kb = new Keyboard().force().oneTime().selective();
|
const kb = new Keyboard().force().oneTime().selective();
|
||||||
this.keyboard(kb);
|
this.keyboard(kb);
|
||||||
|
|
||||||
this.answers(options.answers);
|
this.answers(options.answers);
|
||||||
@ -60,10 +60,10 @@ export default class Question extends Message {
|
|||||||
if (answer) {
|
if (answer) {
|
||||||
this.emit('question:answer', answer, message);
|
this.emit('question:answer', answer, message);
|
||||||
return message;
|
return message;
|
||||||
} else {
|
|
||||||
this.emit('question:invalid', message);
|
|
||||||
throw message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.emit('question:invalid', message);
|
||||||
|
throw message;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user