message should listen on replys instead of general messages

This commit is contained in:
Mahdi Dibaiee 2015-06-27 03:03:30 +04:30
parent cf6c79e1e3
commit 9440d8be48
3 changed files with 95 additions and 41 deletions

View File

@ -1,34 +1,38 @@
# Telegram Bots # Telegram Bots
Control Telegram bots easily. Create and control [Telegram bots](https://core.telegram.org/bots) easily
using the new [Telegram API](https://core.telegram.org/bots/api).
``` ```
npm install telegram-bots npm install telegram-api
``` ```
# Example # Example
```javascript ```javascript
let Bot = require('telegram-bots'); var Bot = require('./index');
let smartBot = new Bot({ var smartBot = new Bot({
token: 'YOUR_TOKEN' token: 'YOUR_KEY'
}); });
// update is an Update object as described in Telegram Bots API documentation smartBot.start();
smartBot.on('Hi', update => {
const message = update.message, // You can use regular expressions, too
id = message.chat.id; smartBot.get('Hi', function(update) {
const message = update.message;
const id = message.chat.id;
const question = 'How should I greet you?', const question = 'How should I greet you?',
answers = ['Hi', 'Hello, Sir', 'Yo bro']; answers = ['Hi', 'Hello, Sir', 'Yo bro'];
smartBot.askQuestion(id, question, answers) smartBot.askQuestion(id, question, answers)
.then(answer => { .then(answer => {
smartBot.message(id, `Your answer: ${answer}`); smartBot.message(id, 'Your answer: ' + answer);
}, () => { }, () => {
smartBot.message(id, 'Invalid answer'); smartBot.message(id, 'Invalid answer');
}); });
}); });
// Commands are in format `/command` or `/command@botusername` in groups
smartBot.command('test', update => { smartBot.command('test', update => {
const message = update.message; const message = update.message;
const id = message.chat.id; const id = message.chat.id;
@ -39,6 +43,10 @@ smartBot.command('test', update => {
smartBot.command('start', update => { smartBot.command('start', update => {
smartBot.message(update.message.chat.id, 'Hello!'); smartBot.message(update.message.chat.id, 'Hello!');
}); });
// You can access all API methods through the api property until we implement
// easier methods
smartBot.api.getUserProfilePhotos
``` ```
This will result in: This will result in:

View File

@ -7,6 +7,7 @@ export default function(path, data) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let res = ''; let res = '';
console.log('sending request for', path);
const req = https.request({ const req = https.request({
hostname: 'api.telegram.org', hostname: 'api.telegram.org',
method: data ? 'POST' : 'GET', method: data ? 'POST' : 'GET',
@ -15,6 +16,7 @@ export default function(path, data) {
'Content-Type': 'application/x-www-form-urlencoded' 'Content-Type': 'application/x-www-form-urlencoded'
} }
}, response => { }, response => {
console.log('response');
response.on('data', chunk => { response.on('data', chunk => {
res += chunk; res += chunk;
}); });

View File

@ -20,14 +20,17 @@ export default class Bot {
this.api = new API(this.token); this.api = new API(this.token);
this.msg = {};
// EventEmitter // EventEmitter
this._events = {}; this._events = {};
this._userEvents = [];
} }
start() { start() {
(function poll() { let poll = function() {
this.api.getUpdates(this.update).then(response => { this.api.getUpdates(this.update).then(response => {
setTimeout(poll.bind(this), this.update.timeout * 1000); setTimeout(poll, this.update.timeout * 1000);
const result = response.result; const result = response.result;
if (!result.length) { if (!result.length) {
@ -44,37 +47,68 @@ export default class Bot {
this.emit('update', response.result); this.emit('update', response.result);
result.forEach(res => { result.forEach(res => {
const text = res.message.text; let text = res.message.text;
if (text.indexOf('/') === 0) { if (text.indexOf('/') === 0) {
this.emit('command:' + text.slice(1), res); // Commands are sent in format /command@botusername format
} else { const regex = new RegExp(`@${this.info.username}$`);
this.emit(text, res); text = text.replace(regex, '');
} }
let ev = this._userEvents.find(({message}) => message.test(text));
ev.listener(res);
}); });
}); });
}.bind(this)()); }.bind(this);
this.api.getMe().then(response => {
this.info = response.result;
poll();
});
}
get(message, listener) {
if (typeof message === 'string') {
message = new RegExp(`^${message}`);
}
this._userEvents.push({
message, listener
});
} }
command(cmd, listener) { command(cmd, listener) {
return this.on(`command:${cmd}`, listener); this._userEvents.push({
message: new RegExp(`/${cmd}`),
listener
});
} }
message(chat, text, options) { message(chat, text, options = {}) {
return new Promise(resolve => { return new Promise(resolve => {
console.log(this.keyboard); let messageId;
this.api.sendMessage(Object.assign({
const params = Object.assign({
chat_id: chat, chat_id: chat,
text, text,
reply_markup: this.keyboard reply_markup: this._replyMarkup
}, options)); }, this.msg, options);
if (JSON.parse(this.keyboard).one_time_keyboard) { this.api.sendMessage(params).then(response => {
this.keyboard = ''; messageId = response.result.message_id;
});
this.msg = {};
if (this.replyMarkup.one_time_keyboard) {
this.replyMarkup = '';
} }
this.on('update', function listener(result) { this.on('update', function listener(result) {
console.log(result);
console.log(messageId);
const update = result.find(({message}) => { const update = result.find(({message}) => {
return message.chat.id === chat; return message.chat.id === chat &&
message.reply_to_message.message_id === messageId;
}); });
if (update) { if (update) {
@ -86,15 +120,17 @@ export default class Bot {
}); });
} }
askQuestion(chat, title, answers = []) { replyTo(reply) {
const text = title + '\n\n' + answers.reduce((a, b, i) => { this.msg.reply_to_message_id = reply;
return a + `${i}. ${b}\n`;
}, '');
return this;
}
askQuestion(chat, title, answers = []) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const rows = [answers]; const rows = [answers];
this.keyboard(rows, false, true).force() this.keyboard(rows, false, true).force()
.message(chat, text).then(update => { .message(chat, title).then(update => {
const message = update.message; const message = update.message;
let answer; let answer;
@ -113,35 +149,43 @@ export default class Bot {
}); });
} }
keyboard(rows, resize = false, oneTime = false, selective) { keyboard(rows, resize = false, oneTime = false, selective = true) {
this.keyboard = JSON.stringify({ this.replyMarkup = {
keyboard: rows, keyboard: rows,
resize_keyboard: resize, resize_keyboard: resize,
one_time_keyboard: oneTime, one_time_keyboard: oneTime,
selective selective
}); };
return this; return this;
} }
hideKeyboard(selective) { hideKeyboard(selective = true) {
this.keyboard = JSON.stringify({ this.replyMarkup = {
hide_keyboard: true, hide_keyboard: true,
selective selective
}); };
return this; return this;
} }
force(enable = true, selective) { force(enable = true, selective) {
const keyboard = JSON.parse(this.keyboard); this.replyMarkup.force_reply = enable;
keyboard.force_reply = enable; if (selective) {
keyboard.selective = selective; this.replyMarkup.selective = selective;
}
this.keyboard = JSON.stringify(keyboard);
return this; return this;
} }
set replyMarkup(json) {
this._replyMarkup = JSON.stringify(json);
}
get replyMarkup() {
return JSON.parse(this._replyMarkup);
}
wait(miliseconds) { wait(miliseconds) {
const self = this; const self = this;