initial commit
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -25,3 +25,6 @@ build/Release | ||||
| # Dependency directory | ||||
| # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git | ||||
| node_modules | ||||
|  | ||||
| # Test file I use to test my module | ||||
| test.js | ||||
|   | ||||
							
								
								
									
										46
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,2 +1,44 @@ | ||||
| # node-telegram-bots | ||||
| Control Telegram bots easily | ||||
| # Telegram Bots | ||||
| Control Telegram bots easily. | ||||
|  | ||||
| ``` | ||||
| npm install telegram-bots | ||||
| ``` | ||||
|  | ||||
| # Example | ||||
| ```javascript | ||||
| let Bot = require('telegram-bots'); | ||||
|  | ||||
| let smartBot = new Bot({ | ||||
|   token: 'YOUR_TOKEN' | ||||
| }); | ||||
|  | ||||
| // update is an Update object as described in Telegram Bots API documentation | ||||
| smartBot.on('Hi', update => { | ||||
|   const message = update.message, | ||||
|         id = message.chat.id; | ||||
|  | ||||
|   const question = 'How should I greet you?', | ||||
|         answers = ['Hi', 'Hello, Sir', 'Yo bro']; | ||||
|  | ||||
|   smartBot.askQuestion(id, question, answers) | ||||
|   .then(answer => { | ||||
|     smartBot.message(id, `Your answer: ${answer}`); | ||||
|   }, () => { | ||||
|     smartBot.message(id, 'Invalid answer'); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| smartBot.command('test', update => { | ||||
|   const message = update.message; | ||||
|   const id = message.chat.id; | ||||
|  | ||||
|   smartBot.message(id, 'Test command'); | ||||
| }); | ||||
|  | ||||
| smartBot.command('start', update => { | ||||
|   smartBot.message(update.message.chat.id, 'Hello!'); | ||||
| }); | ||||
| ``` | ||||
|  | ||||
| This will result in: | ||||
|   | ||||
							
								
								
									
										2
									
								
								index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| require('babel/register'); | ||||
| module.exports = require('./lib/index'); | ||||
							
								
								
									
										5
									
								
								lib/.eslintrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								lib/.eslintrc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| { | ||||
|   "rules": { | ||||
|     "camelcase": 0 | ||||
|   } | ||||
| } | ||||
							
								
								
									
										21
									
								
								lib/api.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								lib/api.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| // API methods | ||||
| import fetch from './fetch'; | ||||
|  | ||||
| export default function API(token) { | ||||
|   this.token = token; | ||||
| } | ||||
|  | ||||
| API.prototype.request = function request(method, data) { | ||||
|   return fetch(this.token + '/' + method, data); | ||||
| }; | ||||
|  | ||||
| const methods = ['getMe', 'sendMessage', 'forwardMessage', 'sendPhoto', | ||||
| 'sendAudio', 'sendDocument', 'sendSticker', 'sendVideo', | ||||
| 'sendLocation', 'sendChatAction', 'getUserProfilePhotos', | ||||
| 'getUpdates']; | ||||
|  | ||||
| methods.forEach(method => { | ||||
|   API.prototype[method] = function(data) { | ||||
|     return this.request(method, data); | ||||
|   }; | ||||
| }); | ||||
							
								
								
									
										37
									
								
								lib/fetch.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/fetch.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| import https from 'https'; | ||||
| import qs from 'qs'; | ||||
|  | ||||
| export default function(path, data) { | ||||
|   const post = qs.stringify(data); | ||||
|  | ||||
|   return new Promise((resolve, reject) => { | ||||
|     let res = ''; | ||||
|  | ||||
|     const req = https.request({ | ||||
|       hostname: 'api.telegram.org', | ||||
|       method: data ? 'POST' : 'GET', | ||||
|       path: '/bot' + path, | ||||
|       headers: { | ||||
|         'Content-Type': 'application/x-www-form-urlencoded' | ||||
|       } | ||||
|     }, response => { | ||||
|       response.on('data', chunk => { | ||||
|         res += chunk; | ||||
|       }); | ||||
|  | ||||
|       response.on('end', () => { | ||||
|         try { | ||||
|           let json = JSON.parse(res); | ||||
|           resolve(json); | ||||
|         } catch(e) { | ||||
|           reject(e); | ||||
|         } | ||||
|       }); | ||||
|     }).on('error', reject); | ||||
|  | ||||
|     if (post) { | ||||
|       req.write(post); | ||||
|     } | ||||
|     req.end(); | ||||
|   }); | ||||
| } | ||||
							
								
								
									
										154
									
								
								lib/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								lib/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | ||||
| import API from './api'; | ||||
| import * as _ from './utils'; | ||||
| import {EventEmitter} from 'events'; | ||||
|  | ||||
| const DEFAULTS = { | ||||
|   update: { | ||||
|     offset: 0, | ||||
|     timeout: 0.5, | ||||
|     limit: 100 | ||||
|   } | ||||
| }; | ||||
|  | ||||
| export default class Bot { | ||||
|   constructor(options = {update: {}}) { | ||||
|     if (!options.token) { | ||||
|       throw new Error('Token cannot be empty'); | ||||
|     } | ||||
|     this.token = options.token; | ||||
|     this.update = Object.assign(options.update || {}, DEFAULTS.update); | ||||
|  | ||||
|     this.api = new API(this.token); | ||||
|  | ||||
|     // EventEmitter | ||||
|     this._events = {}; | ||||
|   } | ||||
|  | ||||
|   start() { | ||||
|     (function poll() { | ||||
|       this.api.getUpdates(this.update).then(response => { | ||||
|         setTimeout(poll.bind(this), this.update.timeout * 1000); | ||||
|  | ||||
|         const result = response.result; | ||||
|         if (!result.length) { | ||||
|           return; | ||||
|         } | ||||
|  | ||||
|         if (!this.update.offset) { | ||||
|           const updateId = result[result.length - 1].update_id; | ||||
|           this.update.offset = updateId; | ||||
|         } | ||||
|         if (this.update) { | ||||
|           this.update.offset += 1; | ||||
|         } | ||||
|  | ||||
|         this.emit('update', response.result); | ||||
|         result.forEach(res => { | ||||
|           const text = res.message.text; | ||||
|           if (text.indexOf('/') === 0) { | ||||
|             this.emit('command:' + text.slice(1), res); | ||||
|           } else { | ||||
|             this.emit(text, res); | ||||
|           } | ||||
|         }); | ||||
|       }); | ||||
|     }.bind(this)()); | ||||
|   } | ||||
|  | ||||
|   command(cmd, listener) { | ||||
|     return this.on(`command:${cmd}`, listener); | ||||
|   } | ||||
|  | ||||
|   message(chat, text, options) { | ||||
|     return new Promise(resolve => { | ||||
|       console.log(this.keyboard); | ||||
|       this.api.sendMessage(Object.assign({ | ||||
|         chat_id: chat, | ||||
|         text, | ||||
|         reply_markup: this.keyboard | ||||
|       }, options)); | ||||
|  | ||||
|       if (JSON.parse(this.keyboard).one_time_keyboard) { | ||||
|         this.keyboard = ''; | ||||
|       } | ||||
|  | ||||
|       this.on('update', function listener(result) { | ||||
|         const update = result.find(({message}) => { | ||||
|           return message.chat.id === chat; | ||||
|         }); | ||||
|  | ||||
|         if (update) { | ||||
|           resolve(update); | ||||
|  | ||||
|           this.removeListener('update', listener); | ||||
|         } | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   askQuestion(chat, title, answers = []) { | ||||
|     const text = title + '\n\n' + answers.reduce((a, b, i) => { | ||||
|       return a + `${i}. ${b}\n`; | ||||
|     }, ''); | ||||
|  | ||||
|     return new Promise((resolve, reject) => { | ||||
|       const rows = [answers]; | ||||
|       this.keyboard(rows, false, true).force() | ||||
|       .message(chat, text).then(update => { | ||||
|         const message = update.message; | ||||
|         let answer; | ||||
|  | ||||
|         if (_.isNumber(message.text)) { | ||||
|           answer = answers[+message.text]; | ||||
|         } else { | ||||
|           answer = answers.find(a => a === message.text); | ||||
|         } | ||||
|  | ||||
|         if (answer) { | ||||
|           resolve(answer, update); | ||||
|         } else { | ||||
|           reject(update); | ||||
|         } | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   keyboard(rows, resize = false, oneTime = false, selective) { | ||||
|     this.keyboard = JSON.stringify({ | ||||
|       keyboard: rows, | ||||
|       resize_keyboard: resize, | ||||
|       one_time_keyboard: oneTime, | ||||
|       selective | ||||
|     }); | ||||
|  | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   hideKeyboard(selective) { | ||||
|     this.keyboard = JSON.stringify({ | ||||
|       hide_keyboard: true, | ||||
|       selective | ||||
|     }); | ||||
|  | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   force(enable = true, selective) { | ||||
|     const keyboard = JSON.parse(this.keyboard); | ||||
|     keyboard.force_reply = enable; | ||||
|     keyboard.selective = selective; | ||||
|  | ||||
|     this.keyboard = JSON.stringify(keyboard); | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   wait(miliseconds) { | ||||
|     const self = this; | ||||
|  | ||||
|     return function(resolve) { | ||||
|       setTimeout(resolve.bind(self), miliseconds); | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | ||||
| Bot.prototype = Object.assign(Bot.prototype, EventEmitter.prototype); | ||||
							
								
								
									
										3
									
								
								lib/utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								lib/utils.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| export function isNumber(string) { | ||||
|   return !isNaN(parseFloat(string)); | ||||
| } | ||||
							
								
								
									
										29
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| { | ||||
|   "name": "telegram-bots", | ||||
|   "version": "0.1.0", | ||||
|   "description": "Control Telegram bots easily", | ||||
|   "main": "index.js", | ||||
|   "scripts": { | ||||
|     "test": "grunt test" | ||||
|   }, | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|     "url": "https://github.com/mdibaiee/node-telegram-bots" | ||||
|   }, | ||||
|   "keywords": [ | ||||
|     "Telegram", | ||||
|     "bot", | ||||
|     "node", | ||||
|     "module" | ||||
|   ], | ||||
|   "author": "Mahdi Dibaiee", | ||||
|   "license": "MIT", | ||||
|   "bugs": { | ||||
|     "url": "https://github.com/mdibaiee/node-telegram-bots/issues" | ||||
|   }, | ||||
|   "homepage": "https://github.com/mdibaiee/node-telegram-bots", | ||||
|   "dependencies": { | ||||
|     "babel": "^5.6.8", | ||||
|     "qs": "^3.1.0" | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user