From 714ffa94586f8bd1029c620599ebb91618c14543 Mon Sep 17 00:00:00 2001 From: Mahdi Dibaiee Date: Mon, 29 Jun 2015 05:30:29 +0430 Subject: [PATCH] Fix promises getting rejected silently - Thanks to @joepie91 Fix bot not working properly in groups Fix bot not answering properly Bump to version 0.2.2 --- build/fetch.js | 2 +- build/index.js | 28 +++++++++++++++++++++------ build/types/Message.js | 9 +++++---- build/types/Question.js | 42 ++++++++++++++++++++-------------------- demo.js | 8 ++++---- lib/fetch.js | 2 ++ lib/index.js | 28 +++++++++++++++++++++------ lib/types/Message.js | 10 ++++++---- lib/types/Question.js | 43 ++++++++++++++++++++--------------------- package.json | 2 +- 10 files changed, 105 insertions(+), 69 deletions(-) diff --git a/build/fetch.js b/build/fetch.js index 134a2b5..ad8506a 100644 --- a/build/fetch.js +++ b/build/fetch.js @@ -47,7 +47,7 @@ function fetch(path, data) { req.write(post); } req.end(); - }); + })['catch'](console.error); } module.exports = exports['default']; diff --git a/build/index.js b/build/index.js index aa4b9bc..5021ed8 100644 --- a/build/index.js +++ b/build/index.js @@ -30,6 +30,10 @@ var DEFAULTS = { } }; +process.on('uncaughtException', function (err) { + console.error(err.stack); +}); + /** * Bot class used to connect to a new bot * Bots have an api property which gives access to all Telegram API methods, @@ -83,12 +87,12 @@ var Bot = (function (_EventEmitter) { var poll = (function () { var _this = this; - this.api.getUpdates(this.update).then(function (response) { - setTimeout(poll, _this.update.timeout * 1000); + return this.api.getUpdates(this.update).then(function (response) { + var again = wait(_this.update.timeout * 1000).then(poll); var result = response.result; if (!result.length) { - return; + return again; } if (!_this.update.offset) { @@ -99,6 +103,8 @@ var Bot = (function (_EventEmitter) { _this.update.offset += 1; } + _this.emit('update', result); + result.forEach(function (res) { var text = res.message.text; if (text.startsWith('/')) { @@ -111,16 +117,20 @@ var Bot = (function (_EventEmitter) { var pattern = _ref.pattern; return pattern.test(text); }); + + if (!ev) { + return; + } ev.listener(res.message); }); - _this.emit('update', result); + return again; }); }).bind(this); return this.api.getMe().then(function (response) { _this2.info = response.result; - poll(); + return poll(); }); } }, { @@ -174,7 +184,7 @@ var Bot = (function (_EventEmitter) { * @return {unknown} returns the result of calling message's send method */ value: function send(message) { - return message.send(this); + return message.send(this)['catch'](console.error); } }]); @@ -182,4 +192,10 @@ var Bot = (function (_EventEmitter) { })(_events.EventEmitter); exports['default'] = Bot; + +var wait = function wait(miliseconds) { + return new Promise(function (resolve) { + setTimeout(resolve, miliseconds); + }); +}; module.exports = exports['default']; diff --git a/build/types/Message.js b/build/types/Message.js index 0bd6b9a..40edf76 100644 --- a/build/types/Message.js +++ b/build/types/Message.js @@ -134,20 +134,21 @@ var Message = (function (_Base) { // if in a group, there will be a reply to this message if (chat < 0) { - return message.chat.id === chat && message.reply_to_message.message_id === messageId; + return message.chat.id === chat && message.reply_to_message && message.reply_to_message.message_id === messageId; } else { return message.chat.id === chat; } }); if (update) { - resolve(update); - this.emit('message:answer', update); + resolve(update.message); + + this.emit('message:answer', update.message); bot.removeListener('update', listener); } }); - }); + })['catch'](console.error); } }]); diff --git a/build/types/Question.js b/build/types/Question.js index 9553f71..a909a8f 100644 --- a/build/types/Question.js +++ b/build/types/Question.js @@ -42,8 +42,10 @@ var Question = (function (_Message) { _get(Object.getPrototypeOf(Question.prototype), 'constructor', this).call(this, options); - var kb = new _Keyboard2['default']().force().oneTime().selective().keys(this.properties.answers); + var kb = new _Keyboard2['default']().force().oneTime().selective(); this.keyboard(kb); + + this.answers(options.answers); } _inherits(Question, _Message); @@ -58,7 +60,7 @@ var Question = (function (_Message) { * @return {object} returns the question object */ value: function answers(_answers) { - this.answers = _answers; + this._answers = _answers; this._keyboard.keys(_answers); return this; } @@ -77,29 +79,27 @@ var Question = (function (_Message) { value: function send(bot) { var _this = this; - var answers = this.answers; + var answers = this._answers; - return new Promise(function (resolve, reject) { - _get(Object.getPrototypeOf(Question.prototype), 'send', _this).call(_this, bot).then(function (message) { - var answer = undefined; + return _get(Object.getPrototypeOf(Question.prototype), 'send', this).call(this, bot).then(function (message) { + var answer = undefined; - answers.forEach(function find(a) { - if (Array.isArray(a)) { - a.forEach(find); - } - if (a === message.text) { - answer = a; - } - }); - - if (answer) { - resolve(answer, update); - _this.emit('question:answer', answer, update); - } else { - reject(update); - _this.emit('question:invalid', update); + answers.forEach(function find(a) { + if (Array.isArray(a)) { + a.forEach(find); + } + if (a === message.text) { + answer = a; } }); + + if (answer) { + _this.emit('question:answer', answer, message); + return message; + } else { + _this.emit('question:invalid', message); + throw update; + } }); } }]); diff --git a/demo.js b/demo.js index 1bee99f..a4527dc 100644 --- a/demo.js +++ b/demo.js @@ -5,11 +5,11 @@ var Message = require('telegram-api/types/Message'); var Question = require('telegram-api/types/Question'); var bot = new Bot({ - token: 'YOUR_KEY' + token: '121143906:AAE6pcpBoARNZZjr3fUpvKuLInJ5Eee5Ajk' }); -bot.start().then(() => { - console.log(bot.info); +bot.start().catch(err => { + console.error(err, '\n', err.stack); }); // polling @@ -28,7 +28,7 @@ bot.get(/Hi\sBot/, message => { question.to(id).reply(message.message_id); bot.send(question).then(answer => { - const msg = new Message().to(id).text('Your answer: ' + answer); + const msg = new Message().to(id).text('Your answer: ' + answer.text); bot.send(msg); }, () => { const msg = new Message().to(id).text('Invalid answer'); diff --git a/lib/fetch.js b/lib/fetch.js index 0642ae4..3f4eafc 100644 --- a/lib/fetch.js +++ b/lib/fetch.js @@ -33,5 +33,7 @@ export default function fetch(path, data) { req.write(post); } req.end(); + }).catch(err => { + console.error('Error sending request', err); }); } diff --git a/lib/index.js b/lib/index.js index d563cef..ceeef42 100644 --- a/lib/index.js +++ b/lib/index.js @@ -10,6 +10,10 @@ const DEFAULTS = { } }; +process.on('uncaughtException', function(err) { + console.error(err.stack); +}); + /** * Bot class used to connect to a new bot * Bots have an api property which gives access to all Telegram API methods, @@ -48,12 +52,12 @@ export default class Bot extends EventEmitter { */ start() { let poll = function() { - this.api.getUpdates(this.update).then(response => { - setTimeout(poll, this.update.timeout * 1000); + return this.api.getUpdates(this.update).then(response => { + const again = wait(this.update.timeout * 1000).then(poll); const result = response.result; if (!result.length) { - return; + return again; } if (!this.update.offset) { @@ -64,6 +68,8 @@ export default class Bot extends EventEmitter { this.update.offset += 1; } + this.emit('update', result); + result.forEach(res => { let text = res.message.text; if (text.startsWith('/')) { @@ -73,16 +79,20 @@ export default class Bot extends EventEmitter { } let ev = this._userEvents.find(({pattern}) => pattern.test(text)); + + if (!ev) { + return; + } ev.listener(res.message); }); - this.emit('update', result); + return again; }); }.bind(this); return this.api.getMe().then(response => { this.info = response.result; - poll(); + return poll(); }); } @@ -130,6 +140,12 @@ export default class Bot extends EventEmitter { * @return {unknown} returns the result of calling message's send method */ send(message) { - return message.send(this); + return message.send(this).catch(console.error); } } + +const wait = (miliseconds) => { + return new Promise(resolve => { + setTimeout(resolve, miliseconds); + }); +}; diff --git a/lib/types/Message.js b/lib/types/Message.js index f94b230..8862593 100644 --- a/lib/types/Message.js +++ b/lib/types/Message.js @@ -93,16 +93,18 @@ export default class Message extends Base { const update = result.find(({message}) => { // if in a group, there will be a reply to this message if (chat < 0) { - return message.chat.id === chat && - message.reply_to_message.message_id === messageId; + return message.chat.id === chat + && message.reply_to_message + && message.reply_to_message.message_id === messageId; } else { return message.chat.id === chat; } }); if (update) { - resolve(update); - this.emit('message:answer', update); + resolve(update.message); + + this.emit('message:answer', update.message); bot.removeListener('update', listener); } diff --git a/lib/types/Question.js b/lib/types/Question.js index 3a8068f..1673a8c 100644 --- a/lib/types/Question.js +++ b/lib/types/Question.js @@ -15,9 +15,10 @@ export default class Question extends Message { constructor(options = {}) { super(options); - let kb = new Keyboard().force().oneTime().selective() - .keys(this.properties.answers); + let kb = new Keyboard().force().oneTime().selective(); this.keyboard(kb); + + this.answers(options.answers); } /** @@ -27,7 +28,7 @@ export default class Question extends Message { * @return {object} returns the question object */ answers(answers) { - this.answers = answers; + this._answers = answers; this._keyboard.keys(answers); return this; } @@ -42,29 +43,27 @@ export default class Question extends Message { * rejected in case of invalid answer */ send(bot) { - const answers = this.answers; + const answers = this._answers; - return new Promise((resolve, reject) => { - super.send(bot).then(message => { - let answer; + return super.send(bot).then(message => { + let answer; - answers.forEach(function find(a) { - if (Array.isArray(a)) { - a.forEach(find); - } - if (a === message.text) { - answer = a; - } - }); - - if (answer) { - resolve(answer, update); - this.emit('question:answer', answer, update); - } else { - reject(update); - this.emit('question:invalid', update); + answers.forEach(function find(a) { + if (Array.isArray(a)) { + a.forEach(find); + } + if (a === message.text) { + answer = a; } }); + + if (answer) { + this.emit('question:answer', answer, message); + return message; + } else { + this.emit('question:invalid', message); + throw update; + } }); } } diff --git a/package.json b/package.json index 8d12491..2f6672c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "telegram-api", - "version": "0.2.1", + "version": "0.2.2", "description": "Control Telegram bots easily using the new Telegram API", "main": "index.js", "scripts": {