new version

This commit is contained in:
Mahdi Dibaiee 2015-06-28 05:34:18 +04:30
parent a05b17db70
commit 4d72d21c13
6 changed files with 208 additions and 132 deletions

36
demo.js
View File

@ -1,7 +1,15 @@
var Bot = require('./index'); var Bot = require('./index');
var Message = require('./lib/classes/Message');
var Question = require('./lib/classes/Question');
process.on('uncaughtException', function (err) {
console.error((new Date()).toUTCString() + ' uncaughtException:', err.message);
console.error(err.stack);
process.exit(1);
});
var smartBot = new Bot({ var smartBot = new Bot({
token: 'YOUR_KEY' token: '121143906:AAE6pcpBoARNZZjr3fUpvKuLInJ5Eee5Ajk'
}); });
// getMe is called before polling starts, setting info property of bot // getMe is called before polling starts, setting info property of bot
@ -14,16 +22,17 @@ smartBot.get('Hi', function(update) {
const message = update.message; const message = update.message;
const id = message.chat.id; const id = message.chat.id;
// answers is in format of keyboard rows var question = new Question().to(id)
const question = 'How should I greet you?', .text('How should I greet you?')
answers = [['Hi'], ['Hello, Sir'], ['Yo bro']]; .answers([['Hi'], ['Hello, Sir'], ['Yo bro']])
.reply(message.message_id);
smartBot.replyTo(message.message_id) smartBot.send(question).then(answer => {
.askQuestion(id, question, answers) const msg = new Message().to(id).text('Your answer: ' + answer);
.then(answer => { smartBot.send(msg);
smartBot.message(id, 'Your answer: ' + answer);
}, () => { }, () => {
smartBot.message(id, 'Invalid answer'); const msg = new Message().to(id).text('Invalid answer');
smartBot.send(msg);
}); });
}); });
@ -32,9 +41,14 @@ smartBot.command('test', update => {
const message = update.message; const message = update.message;
const id = message.chat.id; const id = message.chat.id;
smartBot.message(id, 'Test command'); // options object => Telegram API
smartBot.send(new Message({
chat_id: id,
text: 'Test Command'
}));
}); });
smartBot.command('start', update => { smartBot.command('start', update => {
smartBot.message(update.message.chat.id, 'Hello!'); // chainable methods => easier
smartBot.send(new Message().to(update.message.chat.id).text('Hello'));
}); });

61
lib/classes/Keyboard.js Normal file
View File

@ -0,0 +1,61 @@
export default class Keyboard {
constructor(message, options = {}) {
this.message = message;
this.replyMarkup = options;
}
keys(keys) {
this.setProperties({
keyboard: keys,
hide_keyboard: false
});
return this;
}
force(enable = true) {
this.setProperties({
force_keyboard: enable
});
return this;
}
resize(enable = true) {
this.setProperties({
resize: enable
});
return this;
}
oneTime(enable = true) {
this.setProperties({
one_time_keyboard: enable
});
return this;
}
selective(enable = true) {
this.setProperties({
selective: enable
});
return this;
}
hide() {
this.replyMarkup = {
hide_keyboard: true
};
return this;
}
get replyMarkup() {
return JSON.parse(this.message.params.reply_markup);
}
set replyMarkup(json) {
this.message.params.reply_markup = JSON.stringify(json);
}
setProperties(object) {
this.replyMarkup = Object.assign(this.replyMarkup, object);
}
}

77
lib/classes/Message.js Normal file
View File

@ -0,0 +1,77 @@
import {EventEmitter} from 'events';
import Keyboard from './Keyboard';
export default class Message extends EventEmitter {
constructor(options = {}) {
super();
this.params = options;
}
to(chat) {
this.params.chat_id = chat;
return this;
}
text(text) {
this.params.text = text;
return this;
}
reply(chat) {
this.params.reply_to_message_id = chat;
return this;
}
keyboard(options) {
let params;
if (this._keyboard && !options) {
return this._keyboard;
}
if (this._keyboard) {
params = Object.assign(this._keyboard.replyMarkup, options);
} else {
params = options;
}
this._keyboard = new Keyboard(this, params);
return this._keyboard;
}
send(bot) {
let messageId;
return new Promise(resolve => {
bot.api.sendMessage(this.params).then(response => {
messageId = response.result.message_id;
this.emit('message:sent', response);
});
if (this.keyboard().replyMarkup.one_time_keyboard) {
this.keyboard().replyMarkup = '';
}
const chat = this.params.chat_id;
bot.on('update', function listener(result) {
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;
} else {
return message.chat.id === chat;
}
});
if (update) {
resolve(update);
this.emit('message:answer', update);
bot.removeListener('update', listener);
}
});
});
}
}

43
lib/classes/Question.js Normal file
View File

@ -0,0 +1,43 @@
import Message from './Message';
export default class Question extends Message {
constructor(options = {}) {
super(options);
this.keyboard().force().oneTime().selective();
}
answers(answers) {
this.answers = answers;
this.keyboard().keys(answers);
return this;
}
send(bot) {
const answers = this.answers;
return new Promise((resolve, reject) => {
super.send(bot).then(update => {
const message = update.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);
}
});
});
}
}

View File

@ -7,7 +7,6 @@ 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',
@ -16,7 +15,6 @@ 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

@ -82,125 +82,8 @@ export default class Bot {
}); });
} }
message(chat, text, options = {}) { send(message) {
return new Promise(resolve => { return message.send(this);
let messageId;
const params = Object.assign({
chat_id: chat,
text,
reply_markup: this._replyMarkup
}, this.msg, options);
this.api.sendMessage(params).then(response => {
messageId = response.result.message_id;
});
this.msg = {};
if (this.replyMarkup.one_time_keyboard) {
this.replyMarkup = '';
}
this.on('update', function listener(result) {
const update = result.find(({message}) => {
// if in a group, there will be a reply to this message
console.log(message.chat.id, chat);
if (chat < 0) {
return message.chat.id === chat &&
message.reply_to_message.message_id === messageId;
} else {
return message.chat.id === chat;
}
});
console.log(text, '=>', update);
if (update) {
resolve(update);
this.removeListener('update', listener);
}
});
});
}
replyTo(reply) {
this.msg.reply_to_message_id = reply;
return this;
}
askQuestion(chat, title, answers = []) {
return new Promise((resolve, reject) => {
this.keyboard(answers, false, true).force()
.message(chat, title).then(update => {
const message = update.message;
let answer;
console.log(message);
answers.forEach(function find(a) {
if (Array.isArray(a)) {
a.forEach(find);
}
if (a === message.text) {
answer = a;
}
});
console.log(title, '=', answer);
if (answer) {
resolve(answer, update);
} else {
reject(update);
}
});
});
}
keyboard(rows, resize = false, oneTime = false, selective = true) {
this.replyMarkup = {
keyboard: rows,
resize_keyboard: resize,
one_time_keyboard: oneTime,
selective
};
return this;
}
hideKeyboard(selective = true) {
this.replyMarkup = {
hide_keyboard: true,
selective
};
return this;
}
force(enable = true, selective) {
this.replyMarkup.force_reply = enable;
if (selective) {
this.replyMarkup.selective = selective;
}
return this;
}
set replyMarkup(json) {
this._replyMarkup = JSON.stringify(json);
}
get replyMarkup() {
return JSON.parse(this._replyMarkup);
}
wait(miliseconds) {
const self = this;
return function(resolve) {
setTimeout(resolve.bind(self), miliseconds);
};
} }
} }