var _ = require('lomath');
35 | var fs = require('fs');
├── .dokker.json
├── .env
├── .gitignore
├── .npmignore
├── .travis.yml
├── API.js
├── LICENSE
├── Procfile
├── README.md
├── app.json
├── bot.js
├── docs
├── README.md
├── annotated
│ ├── API.html
│ ├── docco.css
│ └── public
│ │ ├── fonts
│ │ ├── aller-bold.eot
│ │ ├── aller-bold.ttf
│ │ ├── aller-bold.woff
│ │ ├── aller-light.eot
│ │ ├── aller-light.ttf
│ │ ├── aller-light.woff
│ │ ├── roboto-black.eot
│ │ ├── roboto-black.ttf
│ │ └── roboto-black.woff
│ │ └── stylesheets
│ │ └── normalize.css
├── demo-kb.jpg
├── demo-pic.jpg
├── index.html
├── styles.css
└── tests.html
├── herokucmds.txt
├── index.js
├── package.json
├── public
└── node.svg
├── test
└── test.js
├── testbot.js
└── views
├── bootstrap.min.css
├── index.html
└── js
├── angular.min.js
├── bootstrap.min.js
├── jquery-2.1.4.min.js
└── ui.js
/.dokker.json:
--------------------------------------------------------------------------------
1 | {
2 | "dir": "docs",
3 | "literate": {
4 | "source": "API.js",
5 | "dir": "annotated"
6 | },
7 | "jsdoc": {
8 | "title": "Telegram Bot Bootstrap",
9 | "source": "API.js",
10 | "markdown": "README.md",
11 | "html": "index.html",
12 | "readme": "README.md",
13 | "template": "templates/index.ejs.html",
14 | "github": "https://github.com/kengz/telegram-bot-bootstrap",
15 | "site": "http://kengz.github.io/telegram-bot-bootstrap/"
16 | },
17 | "mocha": {
18 | "command": "mocha -u tdd --reporter doc",
19 | "test": "test/test.js",
20 | "path": "tests.html",
21 | "template": "templates/tests.ejs.html"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | PORT=8443
2 | TOKEN=your-Telegram-bot-token
3 | WEBHOOK=your-webhook-url
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build and Release Folders
2 | bin/
3 | bin-debug/
4 | bin-release/
5 | node_modules/
6 | templates/
7 | .tmp/
8 |
9 | # Other files and folders
10 | .settings/
11 |
12 | # System files
13 | npm-debug.log
14 | .DS_Store
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Build and Release Folders
2 | bin/
3 | bin-debug/
4 | bin-release/
5 | node_modules/
6 | templates/
7 | .tmp/
8 |
9 | # Other files and folders
10 | .settings/
11 |
12 | # System files
13 | npm-debug.log
14 | .DS_Store
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.12"
4 | - "0.11"
5 | install:
6 | - npm install
7 | matrix:
8 | fast_finish: true
9 | allow_failures:
10 | - node_js: 0.10
11 |
--------------------------------------------------------------------------------
/API.js:
--------------------------------------------------------------------------------
1 | // dependencies
2 | var _ = require('lomath');
3 | var fs = require('fs');
4 |
5 | // imports
6 | var req = require('reqscraper').req;
7 |
8 | // The API object prototype
9 | /**
10 | * The API bot constructor.
11 | *
12 | * @category Telegram API
13 | * @param {string} token Your Telegram bot token.
14 | * @returns {Bot} The bot able to call methods.
15 | *
16 | * @example
17 | *
18 | * var fs = require('fs');
19 | * var bot = require('telegram-bot-bootstrap');
20 | * var Alice = new bot(your_bot_token);
21 | *
22 | * Alice.sendMessage(user_chat_id, 'Hey wanna see some cool art?');
23 | *
24 | * Alice.sendPhoto(user_chat_id, fs.createReadStream(__dirname+'/alexiuss.jpg'), * 'Chronoscape by Alexiuss').then(console.log)
25 | *
26 | * var kb = {
27 | * keyboard: [
28 | * ['one'],
29 | * ['two', 'three'],
30 | * ['four', 'five', 'six']
31 | * ],
32 | * one_time_keyboard: true
33 | * };
34 | * Alice.sendMessage(user_chat_id, "Choose a lucky number", undefined, undefined, * kb)
35 | *
36 | * // → The messages and photos are sent to user.
37 | *
38 | */
39 | var API = function(token) {
40 | this.token = token;
41 | this.baseUrl = 'https://api.telegram.org/bot' + this.token;
42 |
43 | // A sample Telegram bot JSON data, for req options
44 | this.formData = {
45 | chat_id: "87654321",
46 | text: "Hello there"
47 | };
48 |
49 | // template options for req the Telegram Bot API
50 | this.baseoptions = {
51 | method: 'POST',
52 | baseUrl: this.baseUrl,
53 | url: "sendMessage",
54 | formData: this.formData
55 | };
56 |
57 | ///////////////////////////////
58 | // Internal, private methods //
59 | ///////////////////////////////
60 |
61 | // Convert an data to format proper for HTTP methods
62 | this.toHTTPProper = function(data) {
63 | // currently serialize Array now, leave stream/string
64 | return _.isArray(data) ? JSON.stringify(data) : data;
65 | // return data;
66 | }
67 |
68 | // serialize a whole object proper for HTTP methods
69 | // discard key-value pair if value is undefined
70 | // only returns non-empty JSON
71 | this.serialize = function(obj) {
72 | // var ser = _.omit(
73 | // _.mapValues(_.flattenJSON(obj), this.toHTTPProper)
74 | // , _.isUndefined);
75 | var ser = _.omit(
76 | _.mapValues(obj, this.toHTTPProper)
77 | , _.isUndefined);
78 | if (!_.isEmpty(ser)) return ser;
79 | }
80 |
81 | // properly set req as its method
82 | this.req = req;
83 |
84 | // Extends the options for req for the Telegram Bot.
85 | // @param {string} botMethod Telegram bot API method.
86 | // @param {JSON} JSONdata A JSON object with the required fields (see API).
87 | // @param {string} [HTTPMethod=POST] Optionally change method if need to.
88 | // @returns {JSON} option The extended option.
89 | //
90 | // @example
91 | // extOpt('sendMessage', {chat_id: 123456, text: 'hello world'})
92 | // → {
93 | // method: 'POST',
94 | // baseUrl: 'https://api.telegram.org/bot...',
95 | // url: 'sendMessage',
96 | // formData: {chat_id: 123456, text: 'hello world'} }
97 | this.extOpt = function(botMethod, JSONdata, HTTPMethod) {
98 | var opt = _.clone({
99 | method: 'POST',
100 | baseUrl: this.baseUrl,
101 | url: "sendMessage",
102 | formData: this.formData
103 | });
104 | _.assign(opt, {
105 | url: botMethod
106 | })
107 | if (JSONdata) _.assign(opt, {
108 | formData: this.serialize(JSONdata)
109 | })
110 | if (HTTPMethod) _.assign(opt, {
111 | botMethod: HTTPMethod
112 | });
113 |
114 | return opt;
115 | }
116 |
117 | // shorthand composition: bot's HTTP request
118 | this.reqBot = _.flow(this.extOpt, this.req)
119 |
120 | }
121 |
122 |
123 | //////////////////////////
124 | // Telegram API methods //
125 | //////////////////////////
126 | // All the methods below return a promise form the `q` library (see https://github.com/kriskowal/q) for chaining, thus can be called by: samplemethod().then(handlerfunction).then(handler2)
127 | // You can:
128 | // pass a single JSON object as the 'first' argument (see the Telegram API), or
129 | // pass multiple parameters in the order listed on Telegram bot API page; the 'first' is always the 'chat_id' in this case.
130 | // Note that the response from the HTTP call is always a string (we denote as HTTPres for clarity), thus you might wish to JSON.parse it.
131 |
132 | /**
133 | * Use this method to receive incoming updates using long polling (wiki).
134 | *
135 | * @category Telegram API
136 | * @param {JSON|integer} [first|offset] An optional JSON object with the parameters, or the offset integer
137 | * @param {integer} [limit]
138 | * @param {integer} [timeout]
139 | * @returns {string} HTTPres An Array of Update objects is returned.
140 | *
141 | * @example
142 | * Alice.getUpdates().then(console.log)
143 | * // → {"ok":true,"result":[{"update_id":1234567, "message":{"message_id":1,"from":{"id":87654321, ...}}]
144 | *
145 | */
146 | API.prototype.getUpdates = function(first, limit, timeout) {
147 | var options = _.isObject(first) ?
148 | first : {
149 | offset: first,
150 | limit: limit,
151 | timeout: timeout
152 | };
153 | return this.reqBot('getUpdates', options)
154 | }
155 |
156 | /**
157 | * Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update. In case of an unsuccessful request, we will give up after a reasonable amount of attempts.
158 | *
159 | * @category Telegram API
160 | * @param {string} url A JSON object with the parameters, or the HTTPS url to send updates to. Use an empty string to remove webhook integration.
161 | * @returns {string} HTTPres An Array of Update objects is returned.
162 | *
163 | * @xample
164 | * setWebhook('') // empty string to unset webhook
165 | *
166 | * setWebhook('http://yoururl.com') // to set webhook
167 | */
168 | API.prototype.setWebhook = function(first) {
169 | var options = _.isObject(first) ?
170 | first : {
171 | url: first
172 | };
173 | return this.reqBot('setWebhook', options);
174 | }
175 |
176 | /**
177 | * A simple method for testing your bot's auth token. Requires no parameters.
178 | *
179 | * @category Telegram API
180 | * @returns {string} HTTPres Basic information about the bot in form of a User object.
181 | */
182 | API.prototype.getMe = function() {
183 | return this.reqBot('getMe');
184 | }
185 |
186 | /**
187 | * Use this method to send text messages.
188 | *
189 | * @category Telegram API
190 | * @param {JSON|integer} first Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
191 | * @param {string} text Text of the message to be sent.
192 | * @param {boolean} [disable_web_page_preview] Disables link previews for links in this message.
193 | * @param {integer} [reply_to_message_id] If the message is a reply, ID of the original message.
194 | * @param {KeyboardMarkup} [reply_markup] Additional interface options. A JSON object (don't worry about serializing; it's handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
195 | * @returns {string} HTTPres On success, the sent Message is returned.
196 | *
197 | * @example
198 | * Alice.sendMessage({chat_id: 87654321, text: 'hello world'})
199 | * Alice.sendMessage(87654321, 'hello world') // equivalent, cleaner
200 | * // → 'hello world' is sent to the user with the id.
201 | *
202 | * // var kb = {
203 | * // keyboard: [
204 | * // ['one'],
205 | * // ['two', 'three'],
206 | * // ['four', 'five', 'six']
207 | * // ],
208 | * // one_time_keyboard: true
209 | * // };
210 | * Alice.sendMessage(87654321, "Choose a lucky number", undefined, undefined, kb)
211 | * // → 'Choose a lucky number' is sent, with custom reply keyboard
212 | *
213 | */
214 | API.prototype.sendMessage = function(first, text, disable_web_page_preview, reply_to_message_id, reply_markup) {
215 | var options = _.isObject(first) ?
216 | first : {
217 | chat_id: first,
218 | text: text || 'null-guarded; Your method is sending empty text.',
219 | disable_web_page_preview: disable_web_page_preview,
220 | reply_to_message_id: reply_to_message_id,
221 | reply_markup: JSON.stringify(reply_markup)
222 | };
223 | return this.reqBot('sendMessage', options);
224 | }
225 |
226 | /**
227 | * Use this method to forward messages of any kind.
228 | *
229 | * @category Telegram API
230 | * @param {JSON|integer} first Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
231 | * @param {integer} from_chat_id Unique identifier for the chat where the original message was sent — User or GroupChat id.
232 | * @param {integer} message_id Unique message identifier
233 | * @returns {string} HTTPres On success, the sent Message is returned.
234 | *
235 | * @example
236 | * Alice.forwardMessage(87654321, 12345678, 87654356)
237 | * // → Message is forwarded
238 | *
239 | */
240 | API.prototype.forwardMessage = function(first, from_chat_id, message_id) {
241 | var options = _.isObject(first) ?
242 | first : {
243 | chat_id: first,
244 | from_chat_id: from_chat_id,
245 | message_id: message_id
246 | };
247 | return this.reqBot('forwardMessage', options);
248 | }
249 |
250 | /**
251 | * Use this method to send photos.
252 | *
253 | * @category Telegram API
254 | * @param {JSON|integer} first Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
255 | * @param {inputFile|string} photo Photo to send. You can either pass a file_id as String to resend a photo that is already on the Telegram servers, or upload a new photo using multipart/form-data.
256 | * @param {string} [caption]
257 | * @param {integer} [reply_to_message_id] If the message is a reply, ID of the original message.
258 | * @param {KeyboardMarkup} [reply_markup] Additional interface options. A JSON object (don't worry about serializing; it's handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
259 | * @returns {string} HTTPres On success, the sent Message is returned.
260 | *
261 | * @example
262 | * Alice.sendMessage(87654321, fs.createReadStream('localpath/to/photo.jpg'), 'cool caption')
263 | * // → The photo on local system is sent to the id.
264 | *
265 | */
266 | API.prototype.sendPhoto = function(first, photo, caption, reply_to_message_id, reply_markup) {
267 | var options = _.isObject(first) ?
268 | first : {
269 | chat_id: first,
270 | photo: photo,
271 | caption: caption,
272 | reply_to_message_id: reply_to_message_id,
273 | reply_markup: JSON.stringify(reply_markup)
274 | };
275 | return this.reqBot('sendPhoto', options);
276 | }
277 |
278 | /**
279 | * Use this method to send audio files, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent as Document). On success, the sent Message is returned. Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future.
280 | *
281 | * @category Telegram API
282 | * @param {JSON|integer} first Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
283 | * @param {inputFile|string} audio Audio file to send. You can either pass a file_id as String to resend an audio that is already on the Telegram servers, or upload a new audio file using multipart/form-data.
284 | * @param {integer} [reply_to_message_id] If the message is a reply, ID of the original message.
285 | * @param {KeyboardMarkup} [reply_markup] Additional interface options. A JSON object (don't worry about serializing; it's handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
286 | * @returns {string} HTTPres On success, the sent Message is returned.
287 | *
288 | */
289 | API.prototype.sendAudio = function(first, audio, reply_to_message_id, reply_markup) {
290 | var options = _.isObject(first) ?
291 | first : {
292 | chat_id: first,
293 | audio: audio,
294 | reply_to_message_id: reply_to_message_id,
295 | reply_markup: JSON.stringify(reply_markup)
296 | };
297 | return this.reqBot('sendAudio', options);
298 | }
299 |
300 | /**
301 | * Use this method to send general files. On success, the sent Message is returned. Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
302 | *
303 | * @category Telegram API
304 | * @param {JSON|integer} first Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
305 | * @param {inputFile|string} document File to send. You can either pass a file_id as String to resend a file that is already on the Telegram servers, or upload a new file using multipart/form-data.
306 | * @param {integer} [reply_to_message_id] If the message is a reply, ID of the original message.
307 | * @param {KeyboardMarkup} [reply_markup] Additional interface options. A JSON object (don't worry about serializing; it's handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
308 | * @returns {string} HTTPres On success, the sent Message is returned.
309 | *
310 | */
311 | API.prototype.sendDocument = function(first, document, reply_to_message_id, reply_markup) {
312 | var options = _.isObject(first) ?
313 | first : {
314 | chat_id: first,
315 | document: document,
316 | reply_to_message_id: reply_to_message_id,
317 | reply_markup: JSON.stringify(reply_markup)
318 | };
319 | return this.reqBot('sendDocument', options);
320 | }
321 |
322 | /**
323 | * Use this method to send .webp stickers.
324 | *
325 | * @category Telegram API
326 | * @param {JSON|integer} first Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
327 | * @param {inputFile|string} sticker Sticker to send. You can either pass a file_id as String to resend a sticker that is already on the Telegram servers, or upload a new sticker using multipart/form-data.
328 | * @param {integer} [reply_to_message_id] If the message is a reply, ID of the original message.
329 | * @param {KeyboardMarkup} [reply_markup] Additional interface options. A JSON object (don't worry about serializing; it's handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
330 | * @returns {string} HTTPres On success, the sent Message is returned.
331 | *
332 | */
333 | API.prototype.sendSticker = function(first, sticker, reply_to_message_id, reply_markup) {
334 | var options = _.isObject(first) ?
335 | first : {
336 | chat_id: first,
337 | sticker: sticker,
338 | reply_to_message_id: reply_to_message_id,
339 | reply_markup: JSON.stringify(reply_markup)
340 | };
341 | return this.reqBot('sendSticker', options);
342 | }
343 |
344 | /**
345 | * Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document). On success, the sent Message is returned. Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future.
346 | *
347 | * @category Telegram API
348 | * @param {JSON|integer} first Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
349 | * @param {inputFile|string} video Video to send. You can either pass a file_id as String to resend a video that is already on the Telegram servers, or upload a new video file using multipart/form-data.
350 | * @param {integer} [reply_to_message_id] If the message is a reply, ID of the original message.
351 | * @param {KeyboardMarkup} [reply_markup] Additional interface options. A JSON object (don't worry about serializing; it's handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
352 | * @returns {string} HTTPres On success, the sent Message is returned.
353 | *
354 | */
355 | API.prototype.sendVideo = function(first, video, reply_to_message_id, reply_markup) {
356 | var options = _.isObject(first) ?
357 | first : {
358 | chat_id: first,
359 | video: video,
360 | reply_to_message_id: reply_to_message_id,
361 | reply_markup: JSON.stringify(reply_markup)
362 | };
363 | return this.reqBot('sendVideo', options);
364 | }
365 |
366 | /**
367 | * Use this method to send point on the map.
368 | *
369 | * @category Telegram API
370 | * @param {JSON|integer} first Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
371 | * @param {number} latitude Latitude of location
372 | * @param {number} longitude Longitude of location
373 | * @param {integer} [reply_to_message_id] If the message is a reply, ID of the original message.
374 | * @param {KeyboardMarkup} [reply_markup] Additional interface options. A JSON object (don't worry about serializing; it's handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
375 | * @returns {string} HTTPres On success, the sent Message is returned.
376 | *
377 | */
378 | API.prototype.sendLocation = function(first, latitude, longitude, reply_to_message_id, reply_markup) {
379 | var options = _.isObject(first) ?
380 | first : {
381 | chat_id: first,
382 | longitude: longitude,
383 | latitude: latitude,
384 | reply_to_message_id: reply_to_message_id,
385 | reply_markup: JSON.stringify(reply_markup)
386 | };
387 | return this.reqBot('sendLocation', options);
388 | }
389 |
390 | /**
391 | * Use this method when you need to tell the user that something is happening on the bot's side. The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear its typing status).
392 | *
393 | * @category Telegram API
394 | * @param {JSON|integer} first Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id..
395 | * @param {string} action Type of action to broadcast. Choose one, depending on what the user is about to receive: typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_audio or upload_audio for audio files, upload_document for general files, find_location for location data.
396 | * @returns {string} HTTPres On success, the sent Message is returned.
397 | *
398 | */
399 | API.prototype.sendChatAction = function(first, action) {
400 | var options = _.isObject(first) ?
401 | first : {
402 | chat_id: first,
403 | action: action
404 | };
405 | return this.reqBot('sendChatAction', options);
406 | }
407 |
408 | /**
409 | * Use this method to get a list of profile pictures for a user.
410 | *
411 | * @category Telegram API
412 | * @param {JSON|integer} first Your own JSON object, or user_id: Unique identifier of the target user.
413 | * @param {integer} [offset] Sequential number of the first photo to be returned. By default, all photos are returned.
414 | * @param {integer} [limit] Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100.
415 | * @returns {string} HTTPres Returns a UserProfilePhotos object.
416 | *
417 | */
418 | API.prototype.getUserProfilePhotos = function(first, offset, limit) {
419 | var options = _.isObject(first) ?
420 | first : {
421 | user_id: first,
422 | offset: offset,
423 | limit: limit
424 | };
425 | return this.reqBot('getUserProfilePhotos', options);
426 | }
427 |
428 | /**
429 | * Handles a Telegram Update object sent from the server. Extend this method for your bot.
430 | *
431 | * @category Bot
432 | * @param {Object} req The incoming HTTP request.
433 | * @param {Object} res The HTTP response in return.
434 | * @returns {Promise} promise A promise returned from calling Telegram API method(s) for chaining.
435 | *
436 | * @example
437 | * var bot1 = new bot('yourtokenhere');
438 | * ...express server setup
439 | * app.route('/')
440 | * // robot API as middleware
441 | * .post(function(req, res) {
442 | * bot1.handle(req, res)
443 | * })
444 | * // Then bot will handle the incoming Update from you, routed from Telegram!
445 | *
446 | */
447 | function handle(req, res) {
448 | }
449 |
450 |
451 | // export constructor
452 | module.exports = API;
453 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Wah Loon Keng
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: node index.js
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # telegram-bot-bootstrap
2 | [](http://badge.fury.io/js/telegram-bot-bootstrap) [](https://travis-ci.org/kengz/telegram-bot-bootstrap) [](https://gemnasium.com/kengz/telegram-bot-bootstrap)
3 |
4 | **NOTICE**: *I've generalized this and built a much bigger bot, [AIVA](http://kengz.me/aiva/). Go check it out!*
5 |
6 |
7 | A bootstrap for Telegram bot with directly deployable sample bot and JS-wrapped API methods. You can use all methods available in the Telegram API directly, and send any supported media (we serialize the formData for you to send over HTTP).
8 |
9 | See the full [API documentation](http://kengz.github.io/telegram-bot-bootstrap/) of this project.
10 |
11 |
12 |
13 | ## Installation
14 | Do either of
15 |
16 | ```
17 | npm install telegram-bot-bootstrap
18 | git clone https://github.com/kengz/telegram-bot-bootstrap.git
19 | ```
20 |
21 | Either way you'll get a module with the Telegram bot API wrapped in Node, and a bootstrapped, deploy-ready project.
22 |
23 | If you haven't already, get a bot from [BotFather](https://core.telegram.org/bots) and remember your bot *token*!
24 |
25 |
26 | ## Features
27 | - Wrapped API methods take either a JSON object or multiple parameters.
28 | - Auto serialization for HTTP formData: send photos/keyboards/media directly.
29 | - API methods return `promises` (uses [q](https://github.com/kriskowal/q)) for easy chaining and flow control.
30 | - Complete documentation and examples usages.
31 | - Bootstrapped and directly deployable bot.
32 |
33 |
34 | ## Usage: only the API
35 | See the full [API documentation](http://kengz.github.io/telegram-bot-bootstrap/) of this project.
36 |
37 | `API.js` contains the [Telegram Bot API](https://core.telegram.org/bots/api) wrapped in Node. The methods will return a promise for easy chaining, and will take either a whole JSON, or multiple parameters for convenience. For the latter, everything will be auto-serialized for HTTP so you don't have to deal with any of the nasty HTTP protocol stuff.
38 |
39 | If you wish to use just the API or test the bot methods, here's an example
40 |
41 | #### Local(not deployed yet) test bot constructor
42 | See `testbot.js` for functional example.
43 |
44 | ```Javascript
45 | // testbot.js
46 | var bot = require('telegram-bot-bootstrap');
47 | var fs = require('fs');
48 |
49 | var Alice = new bot(your-token);
50 |
51 | Alice.getUpdates().then(console.log)
52 | // → you'll see an update message. Look for your user_id in "message.from.id"
53 |
54 | // Once you get your id to message yourself, you may:
55 | Alice.sendMessage(your-id, "Hello there")
56 | // → you'll receive a message from Alice.
57 | .then(console.log)
58 | // → optional, will log the successful message sent over HTTP
59 | ```
60 |
61 | #### Sending Message, Photo and all media
62 |
63 | ```
64 | Alice.sendMessage(86953862, 'Hey wanna see some cool art?');
65 |
66 | Alice.sendPhoto(86953862, fs.createReadStream(__dirname+'/alexiuss.jpg'), 'Chronoscape by Alexiuss').then(console.log)
67 | ```
68 |
69 | You'll receive this:
70 |
71 |
72 |
73 | #### Custom keyboard
74 |
75 | ```
76 | var kb = {
77 | keyboard: [
78 | ['one'],
79 | ['two', 'three'],
80 | ['four', 'five', 'six']
81 | ],
82 | one_time_keyboard: true
83 | };
84 | Alice.sendMessage(86953862, "Choose a lucky number", undefined, undefined, kb)
85 | ```
86 |
87 | You'll get this:
88 |
89 |
90 |
91 |
92 | ## Usage: Bootstrapped, Deployable Bot
93 | See `index.js` for deployable app, and `bot.js` to customize bot commands.
94 |
95 | We distinguish the bot from the API: `bot.js` extends `API.js`, and will be the deployed component.
96 |
97 | This whole project is bootstrapped and deploy-ready: all the details of HTTP and server stuff taken care of for you. I deploy this git project onto my Heroku and voila, my bot is alive.
98 |
99 | #### Setup
100 | In addition to the *token*, you'll need a *webhookUrl*. If you deploy your Node app to *Heroku*, then the *webhookUrl* is simply your Heroku site url. Set both of them in the `.env` file:
101 |
102 | ```Javascript
103 | PORT=8443
104 | TOKEN=your-Telegram-bot-token
105 | WEBHOOK=your-webhook-url
106 | ```
107 |
108 | The sample available is an echo-bot. To make your bot do interesting stuff, head over to `bot.js`, under the `handle` method, start writing your own from below the *Extend from here* comment.
109 |
110 | The bot inherits all the API methods, so you can simply call them for example by `this.sendMessage`.
111 |
112 | #### Deployment
113 | The server is deployed in `index.js`, and a bot is constructed to handle all *HTTP POST* calls from Telegram.
114 |
115 | I use *Heroku*. This shall work for any other services too. Once I'm done setting up, I do:
116 |
117 | ```
118 | git push heroku master
119 | ```
120 |
121 | And done. Start talking to the bot.
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Telegram bot bootstrap",
3 | "description": "A barebones Node.js app using Express 4",
4 | "repository": "https://github.com/kengz/telegram-bot-bootstrap",
5 | "logo": "http://node-js-sample.herokuapp.com/node.svg",
6 | "keywords": ["Telegram", "bot", "bootstrap", "node", "express", "static"]
7 | }
8 |
--------------------------------------------------------------------------------
/bot.js:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////
2 | // Safety: Uncomment everything to use //
3 | /////////////////////////////////////////
4 |
5 | // // dependencies
6 | // var _ = require('lomath');
7 |
8 | // // API as superclass that bot inherits methods from
9 | // var API = require(__dirname + '/API.js')
10 |
11 | // // The bot object prototype
12 | // // bot extends and inherits methods of API
13 | // var bot = function(token, webhookUrl) {
14 | // API.apply(this, arguments);
15 | // // set webhook on construction: override the old webhook
16 | // this.setWebhook(webhookUrl || '');
17 |
18 | // }
19 |
20 | // // set prototype to API
21 | // bot.prototype = API.prototype;
22 | // // set constructor back to bot
23 | // bot.prototype.constructor = bot;
24 |
25 |
26 | /**
27 | * Handles a Telegram Update object sent from the server. Extend this method for your bot.
28 | *
29 | * @category Bot
30 | * @param {Object} req The incoming HTTP request.
31 | * @param {Object} res The HTTP response in return.
32 | * @returns {Promise} promise A promise returned from calling Telegram API method(s) for chaining.
33 | *
34 | * @example
35 | * var bot1 = new bot('yourtokenhere');
36 | * ...express server setup
37 | * app.route('/')
38 | * // robot API as middleware
39 | * .post(function(req, res) {
40 | * bot1.handle(req, res)
41 | * })
42 | * // Then bot will handle the incoming Update from you, routed from Telegram!
43 | *
44 | */
45 | // bot.prototype.handle = function(req, res) {
46 | // // the Telegram Update object. Useful shits
47 | // var Update = req.body,
48 | // // the telegram Message object
49 | // Message = Update.message,
50 | // // the user who sent it
51 | // user_id = Message.from.id,
52 | // // id of the chat(room)
53 | // chat_id = Message.chat.id;
54 |
55 | // ////////////////////////
56 | // // Extend from here: //
57 | // ////////////////////////
58 | // // you may call the methods from API.js, which are all inherited by this bot class
59 |
60 | // // echo
61 | // this.sendMessage(chat_id, "you said: " + Message.text);
62 |
63 | // }
64 |
65 | // export the bot class
66 | // module.exports = bot;
67 |
68 | // sample keyboard
69 | // var kb = {
70 | // keyboard: [
71 | // ['one', 'two'],
72 | // ['three'],
73 | // ['four']
74 | // ],
75 | // one_time_keyboard: true
76 | // }
77 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # API.js API documentation
2 |
3 |
4 |
5 |
6 |
7 | ## `Bot`
8 | * `handle`
9 |
10 |
11 |
12 |
13 |
14 | ## `Telegram API`
15 | * `API`
16 | * `forwardMessage`
17 | * `getMe`
18 | * `getUpdates`
19 | * `getUserProfilePhotos`
20 | * `sendAudio`
21 | * `sendChatAction`
22 | * `sendDocument`
23 | * `sendLocation`
24 | * `sendMessage`
25 | * `sendPhoto`
26 | * `sendSticker`
27 | * `sendVideo`
28 | * `setWebhook`
29 |
30 |
31 |
32 |
33 |
34 | ## `Methods`
35 |
36 |
37 |
38 |
39 |
40 | ## `Properties`
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | ## `“Bot” Methods`
51 |
52 |
53 |
54 | ### `handle(req, res)`
55 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L395 "View in source") [Ⓣ][1]
56 |
57 | Handles a Telegram Update object sent from the server. Extend this method for your bot.
58 |
59 | #### Arguments
60 | 1. `req` *(Object)*: The incoming HTTP request.
61 | 2. `res` *(Object)*: The HTTP response in return.
62 |
63 | #### Returns
64 | *(Promise)*: promise A promise returned from calling Telegram API method(s) for chaining.
65 |
66 | #### Example
67 | ```js
68 | var bot1 = new bot('yourtokenhere');
69 | ...express server setup
70 | app.route('/')
71 | // robot API as middleware
72 | .post(function(req, res) {
73 | bot1.handle(req, res)
74 | })
75 | // Then bot will handle the incoming Update from you, routed from Telegram!
76 | ```
77 | * * *
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | ## `“Telegram API” Methods`
86 |
87 |
88 |
89 | ### `API(token)`
90 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L34 "View in source") [Ⓣ][1]
91 |
92 | The API bot constructor.
93 |
94 | #### Arguments
95 | 1. `token` *(string)*: Your Telegram bot token.
96 |
97 | #### Returns
98 | *(Bot)*: The bot able to call methods.
99 |
100 | #### Example
101 | ```js
102 | var fs = require('fs');
103 | var bot = require('telegram-bot-bootstrap');
104 | var Alice = new bot(your_bot_token);
105 |
106 | Alice.sendMessage(user_chat_id, 'Hey wanna see some cool art?');
107 |
108 | Alice.sendPhoto(user_chat_id, fs.createReadStream(__dirname+'/alexiuss.jpg'), * 'Chronoscape by Alexiuss').then(console.log)
109 |
110 | var kb = {
111 | keyboard: [
112 | ['one'],
113 | ['two', 'three'],
114 | ['four', 'five', 'six']
115 | ],
116 | one_time_keyboard: true
117 | };
118 | Alice.sendMessage(user_chat_id, "Choose a lucky number", undefined, undefined, * kb)
119 |
120 | // → The messages and photos are sent to user.
121 | ```
122 | * * *
123 |
124 |
125 |
126 |
127 |
128 | ### `forwardMessage(first, from_chat_id, message_id)`
129 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L188 "View in source") [Ⓣ][1]
130 |
131 | Use this method to forward messages of any kind.
132 |
133 | #### Arguments
134 | 1. `first` *(JSON|integer)*: Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
135 | 2. `from_chat_id` *(integer)*: Unique identifier for the chat where the original message was sent — User or GroupChat id.
136 | 3. `message_id` *(integer)*: Unique message identifier
137 |
138 | #### Returns
139 | *(string)*: HTTPres On success, the sent Message is returned.
140 |
141 | #### Example
142 | ```js
143 | Alice.forwardMessage(87654321, 12345678, 87654356)
144 | // → Message is forwarded
145 | ```
146 | * * *
147 |
148 |
149 |
150 |
151 |
152 | ### `getMe()`
153 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L130 "View in source") [Ⓣ][1]
154 |
155 | A simple method for testing your bot's auth token. Requires no parameters.
156 |
157 | #### Returns
158 | *(string)*: HTTPres Basic information about the bot in form of a User object.
159 |
160 | * * *
161 |
162 |
163 |
164 |
165 |
166 | ### `getUpdates([first|offset], [limit], [timeout])`
167 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L94 "View in source") [Ⓣ][1]
168 |
169 | Use this method to receive incoming updates using long polling (wiki).
170 |
171 | #### Arguments
172 | 1. `[first|offset]` *(JSON|integer)*: An optional JSON object with the parameters, or the offset integer
173 | 2. `[limit]` *(integer)*:
174 | 3. `[timeout]` *(integer)*:
175 |
176 | #### Returns
177 | *(string)*: HTTPres An Array of Update objects is returned.
178 |
179 | #### Example
180 | ```js
181 | Alice.getUpdates().then(console.log)
182 | // → {"ok":true,"result":[{"update_id":1234567, "message":{"message_id":1,"from":{"id":87654321, ...}}]
183 | ```
184 | * * *
185 |
186 |
187 |
188 |
189 |
190 | ### `getUserProfilePhotos(first, [offset], [limit])`
191 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L366 "View in source") [Ⓣ][1]
192 |
193 | Use this method to get a list of profile pictures for a user.
194 |
195 | #### Arguments
196 | 1. `first` *(JSON|integer)*: Your own JSON object, or user_id: Unique identifier of the target user.
197 | 2. `[offset]` *(integer)*: Sequential number of the first photo to be returned. By default, all photos are returned.
198 | 3. `[limit]` *(integer)*: Limits the number of photos to be retrieved. Values between `1—100` are accepted. Defaults to `10`0.
199 |
200 | #### Returns
201 | *(string)*: HTTPres Returns a UserProfilePhotos object.
202 |
203 | * * *
204 |
205 |
206 |
207 |
208 |
209 | ### `sendAudio(first, audio, [reply_to_message_id], [reply_markup])`
210 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L237 "View in source") [Ⓣ][1]
211 |
212 | Use this method to send audio files, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent as Document). On success, the sent Message is returned. Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future.
213 |
214 | #### Arguments
215 | 1. `first` *(JSON|integer)*: Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
216 | 2. `audio` *(inputFile|string)*: Audio file to send. You can either pass a file_id as String to resend an audio that is already on the Telegram servers, or upload a new audio file using multipart/form-data.
217 | 3. `[reply_to_message_id]` *(integer)*: If the message is a reply, ID of the original message.
218 | 4. `[reply_markup]` *(KeyboardMarkup)*: Additional interface options. A JSON object *(don't worry about serializing; it's handled)* for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
219 |
220 | #### Returns
221 | *(string)*: HTTPres On success, the sent Message is returned.
222 |
223 | * * *
224 |
225 |
226 |
227 |
228 |
229 | ### `sendChatAction(first, action)`
230 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L347 "View in source") [Ⓣ][1]
231 |
232 | Use this method when you need to tell the user that something is happening on the bot's side. The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear its typing status).
233 |
234 | #### Arguments
235 | 1. `first` *(JSON|integer)*: Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id..
236 | 2. `action` *(string)*: Type of action to broadcast. Choose one, depending on what the user is about to receive: typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_audio or upload_audio for audio files, upload_document for general files, find_location for location data.
237 |
238 | #### Returns
239 | *(string)*: HTTPres On success, the sent Message is returned.
240 |
241 | * * *
242 |
243 |
244 |
245 |
246 |
247 | ### `sendDocument(first, document, [reply_to_message_id], [reply_markup])`
248 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L259 "View in source") [Ⓣ][1]
249 |
250 | Use this method to send general files. On success, the sent Message is returned. Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
251 |
252 | #### Arguments
253 | 1. `first` *(JSON|integer)*: Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
254 | 2. `document` *(inputFile|string)*: File to send. You can either pass a file_id as String to resend a file that is already on the Telegram servers, or upload a new file using multipart/form-data.
255 | 3. `[reply_to_message_id]` *(integer)*: If the message is a reply, ID of the original message.
256 | 4. `[reply_markup]` *(KeyboardMarkup)*: Additional interface options. A JSON object *(don't worry about serializing; it's handled)* for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
257 |
258 | #### Returns
259 | *(string)*: HTTPres On success, the sent Message is returned.
260 |
261 | * * *
262 |
263 |
264 |
265 |
266 |
267 | ### `sendLocation(first, latitude, longitude, [reply_to_message_id], [reply_markup])`
268 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L326 "View in source") [Ⓣ][1]
269 |
270 | Use this method to send point on the map.
271 |
272 | #### Arguments
273 | 1. `first` *(JSON|integer)*: Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
274 | 2. `latitude` *(number)*: Latitude of location
275 | 3. `longitude` *(number)*: Longitude of location
276 | 4. `[reply_to_message_id]` *(integer)*: If the message is a reply, ID of the original message.
277 | 5. `[reply_markup]` *(KeyboardMarkup)*: Additional interface options. A JSON object *(don't worry about serializing; it's handled)* for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
278 |
279 | #### Returns
280 | *(string)*: HTTPres On success, the sent Message is returned.
281 |
282 | * * *
283 |
284 |
285 |
286 |
287 |
288 | ### `sendMessage(first, text, [disable_web_page_preview], [reply_to_message_id], [reply_markup])`
289 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L162 "View in source") [Ⓣ][1]
290 |
291 | Use this method to send text messages.
292 |
293 | #### Arguments
294 | 1. `first` *(JSON|integer)*: Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
295 | 2. `text` *(string)*: Text of the message to be sent.
296 | 3. `[disable_web_page_preview]` *(boolean)*: Disables link previews for links in this message.
297 | 4. `[reply_to_message_id]` *(integer)*: If the message is a reply, ID of the original message.
298 | 5. `[reply_markup]` *(KeyboardMarkup)*: Additional interface options. A JSON object *(don't worry about serializing; it's handled)* for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
299 |
300 | #### Returns
301 | *(string)*: HTTPres On success, the sent Message is returned.
302 |
303 | #### Example
304 | ```js
305 | Alice.sendMessage({chat_id: 87654321, text: 'hello world'})
306 | Alice.sendMessage(87654321, 'hello world') // equivalent, cleaner
307 | // → 'hello world' is sent to the user with the id.
308 |
309 | // var kb = {
310 | // keyboard: [
311 | // ['one'],
312 | // ['two', 'three'],
313 | // ['four', 'five', 'six']
314 | // ],
315 | // one_time_keyboard: true
316 | // };
317 | Alice.sendMessage(87654321, "Choose a lucky number", undefined, undefined, kb)
318 | // → 'Choose a lucky number' is sent, with custom reply keyboard
319 | ```
320 | * * *
321 |
322 |
323 |
324 |
325 |
326 | ### `sendPhoto(first, photo, [caption], [reply_to_message_id], [reply_markup])`
327 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L214 "View in source") [Ⓣ][1]
328 |
329 | Use this method to send photos.
330 |
331 | #### Arguments
332 | 1. `first` *(JSON|integer)*: Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
333 | 2. `photo` *(inputFile|string)*: Photo to send. You can either pass a file_id as String to resend a photo that is already on the Telegram servers, or upload a new photo using multipart/form-data.
334 | 3. `[caption]` *(string)*:
335 | 4. `[reply_to_message_id]` *(integer)*: If the message is a reply, ID of the original message.
336 | 5. `[reply_markup]` *(KeyboardMarkup)*: Additional interface options. A JSON object *(don't worry about serializing; it's handled)* for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
337 |
338 | #### Returns
339 | *(string)*: HTTPres On success, the sent Message is returned.
340 |
341 | #### Example
342 | ```js
343 | Alice.sendMessage(87654321, fs.createReadStream('localpath/to/photo.jpg'), 'cool caption')
344 | // → The photo on local system is sent to the id.
345 | ```
346 | * * *
347 |
348 |
349 |
350 |
351 |
352 | ### `sendSticker(first, sticker, [reply_to_message_id], [reply_markup])`
353 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L281 "View in source") [Ⓣ][1]
354 |
355 | Use this method to send .webp stickers.
356 |
357 | #### Arguments
358 | 1. `first` *(JSON|integer)*: Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
359 | 2. `sticker` *(inputFile|string)*: Sticker to send. You can either pass a file_id as String to resend a sticker that is already on the Telegram servers, or upload a new sticker using multipart/form-data.
360 | 3. `[reply_to_message_id]` *(integer)*: If the message is a reply, ID of the original message.
361 | 4. `[reply_markup]` *(KeyboardMarkup)*: Additional interface options. A JSON object *(don't worry about serializing; it's handled)* for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
362 |
363 | #### Returns
364 | *(string)*: HTTPres On success, the sent Message is returned.
365 |
366 | * * *
367 |
368 |
369 |
370 |
371 |
372 | ### `sendVideo(first, video, [reply_to_message_id], [reply_markup])`
373 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L303 "View in source") [Ⓣ][1]
374 |
375 | Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document). On success, the sent Message is returned. Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future.
376 |
377 | #### Arguments
378 | 1. `first` *(JSON|integer)*: Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.
379 | 2. `video` *(inputFile|string)*: Video to send. You can either pass a file_id as String to resend a video that is already on the Telegram servers, or upload a new video file using multipart/form-data.
380 | 3. `[reply_to_message_id]` *(integer)*: If the message is a reply, ID of the original message.
381 | 4. `[reply_markup]` *(KeyboardMarkup)*: Additional interface options. A JSON object *(don't worry about serializing; it's handled)* for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.
382 |
383 | #### Returns
384 | *(string)*: HTTPres On success, the sent Message is returned.
385 |
386 | * * *
387 |
388 |
389 |
390 |
391 |
392 | ### `setWebhook(url)`
393 | # [Ⓢ](https://github.com/kengz/telegram-bot-bootstrap#L116 "View in source") [Ⓣ][1]
394 |
395 | Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update. In case of an unsuccessful request, we will give up after a reasonable amount of attempts.
396 |
397 | #### Arguments
398 | 1. `url` *(string)*: A JSON object with the parameters, or the HTTPS url to send updates to. Use an empty string to remove webhook integration.
399 |
400 | #### Returns
401 | *(string)*: HTTPres An Array of Update objects is returned.
402 |
403 | * * *
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 | ## `Methods`
412 |
413 |
414 |
415 |
416 |
417 | ## `Properties`
418 |
419 |
420 |
421 |
422 |
423 | [1]: #bot "Jump back to the TOC."
424 |
--------------------------------------------------------------------------------
/docs/annotated/API.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
dependencies
31 | 32 |var _ = require('lomath');
35 | var fs = require('fs');
imports
47 | 48 |var req = require(__dirname + '/scraper.js').req;
The API object prototype
62 | 63 |var API = function(token) {
66 | this.token = token;
67 | this.baseUrl = 'https://api.telegram.org/bot' + this.token;
A sample Telegram bot JSON data, for req options
79 | 80 | this.formData = {
83 | chat_id: "87654321",
84 | text: "Hello there"
85 | };
template options for req the Telegram Bot API
97 | 98 | this.baseoptions = {
101 | method: 'POST',
102 | baseUrl: this.baseUrl,
103 | url: "sendMessage",
104 | formData: this.formData
105 | };
///////////////////////////// 117 | Internal, private methods // 118 | /////////////////////////////
119 | 120 |Convert an data to format proper for HTTP methods
132 | 133 | this.toHTTPProper = function(data) {
currently serialize Array now, leave stream/string
147 | 148 | return _.isArray(data) ? JSON.stringify(data) : data;
return data;
162 | 163 | }
serialize a whole object proper for HTTP methods 177 | discard key-value pair if value is undefined 178 | only returns non-empty JSON
179 | 180 | this.serialize = function(obj) {
var ser = .omit( 194 | .mapValues(.flattenJSON(obj), this.toHTTPProper) 195 | , .isUndefined);
196 | 197 | var ser = _.omit(
200 | _.mapValues(obj, this.toHTTPProper)
201 | , _.isUndefined);
202 | if (!_.isEmpty(ser)) return ser;
203 | }
properly set req as its method
215 | 216 | this.req = req;
Extends the options for req for the Telegram Bot. 230 | @param {string} botMethod Telegram bot API method. 231 | @param {JSON} JSONdata A JSON object with the required fields (see API). 232 | @param {string} [HTTPMethod=POST] Optionally change method if need to. 233 | @returns {JSON} option The extended option.
234 |@example 235 | extOpt(‘sendMessage’, {chat_id: 123456, text: ‘hello world’}) 236 | → { 237 | method: ‘POST’, 238 | baseUrl: ‘https://api.telegram.org/bot…’, 239 | url: ‘sendMessage’, 240 | formData: {chat_id: 123456, text: ‘hello world’} }
241 | 242 | this.extOpt = function(botMethod, JSONdata, HTTPMethod) {
245 | var opt = _.clone({
246 | method: 'POST',
247 | baseUrl: this.baseUrl,
248 | url: "sendMessage",
249 | formData: this.formData
250 | });
251 | _.assign(opt, {
252 | url: botMethod
253 | })
254 | if (JSONdata) _.assign(opt, {
255 | formData: this.serialize(JSONdata)
256 | })
257 | if (HTTPMethod) _.assign(opt, {
258 | botMethod: HTTPMethod
259 | });
260 |
261 | return opt;
262 | }
shorthand composition: bot’s HTTP request
274 | 275 | this.reqBot = _.flow(this.extOpt, this.req)
278 |
279 | }
////////////////////////
291 | Telegram API methods //
292 | ////////////////////////
293 | All the methods below return a promise form the q
library (see https://github.com/kriskowal/q) for chaining, thus can be called by: samplemethod().then(handlerfunction).then(handler2)
294 | You can:
295 | pass a single JSON object as the ‘first’ argument (see the Telegram API), or
296 | pass multiple parameters in the order listed on Telegram bot API page; the ‘first’ is always the ‘chat_id’ in this case.
297 | Note that the response from the HTTP call is always a string (we denote as HTTPres for clarity), thus you might wish to JSON.parse it.
API.prototype.getUpdates = function(first, limit, timeout) {
302 | var options = _.isObject(first) ?
303 | first : {
304 | offset: first,
305 | limit: limit,
306 | timeout: timeout
307 | };
308 | return this.reqBot('getUpdates', options)
309 | }
310 | API.prototype.setWebhook = function(first) {
311 | var options = _.isObject(first) ?
312 | first : {
313 | url: first
314 | };
315 | return this.reqBot('setWebhook', options);
316 | }
317 | API.prototype.getMe = function() {
318 | return this.reqBot('getMe');
319 | }
320 | API.prototype.sendMessage = function(first, text, disable_web_page_preview, reply_to_message_id, reply_markup) {
321 | var options = _.isObject(first) ?
322 | first : {
323 | chat_id: first,
324 | text: text,
325 | disable_web_page_preview: disable_web_page_preview,
326 | reply_to_message_id: reply_to_message_id,
327 | reply_markup: JSON.stringify(reply_markup)
328 | };
329 | return this.reqBot('sendMessage', options);
330 | }
331 | API.prototype.forwardMessage = function(first, from_chat_id, message_id) {
332 | var options = _.isObject(first) ?
333 | first : {
334 | chat_id: first,
335 | from_chat_id: from_chat_id,
336 | message_id: message_id
337 | };
338 | return this.reqBot('forwardMessage', options);
339 | }
340 | API.prototype.sendPhoto = function(first, photo, caption, reply_to_message_id, reply_markup) {
341 | var options = _.isObject(first) ?
342 | first : {
343 | chat_id: first,
344 | photo: photo,
345 | caption: caption,
346 | reply_to_message_id: reply_to_message_id,
347 | reply_markup: JSON.stringify(reply_markup)
348 | };
349 | return this.reqBot('sendPhoto', options);
350 | }
351 | API.prototype.sendAudio = function(first, audio, reply_to_message_id, reply_markup) {
352 | var options = _.isObject(first) ?
353 | first : {
354 | chat_id: first,
355 | audio: audio,
356 | reply_to_message_id: reply_to_message_id,
357 | reply_markup: JSON.stringify(reply_markup)
358 | };
359 | return this.reqBot('sendAudio', options);
360 | }
361 | API.prototype.sendDocument = function(first, document, reply_to_message_id, reply_markup) {
362 | var options = _.isObject(first) ?
363 | first : {
364 | chat_id: first,
365 | document: document,
366 | reply_to_message_id: reply_to_message_id,
367 | reply_markup: JSON.stringify(reply_markup)
368 | };
369 | return this.reqBot('sendDocument', options);
370 | }
371 | API.prototype.sendSticker = function(first, sticker, reply_to_message_id, reply_markup) {
372 | var options = _.isObject(first) ?
373 | first : {
374 | chat_id: first,
375 | sticker: sticker,
376 | reply_to_message_id: reply_to_message_id,
377 | reply_markup: JSON.stringify(reply_markup)
378 | };
379 | return this.reqBot('sendSticker', options);
380 | }
381 | API.prototype.sendVideo = function(first, video, reply_to_message_id, reply_markup) {
382 | var options = _.isObject(first) ?
383 | first : {
384 | chat_id: first,
385 | video: video,
386 | reply_to_message_id: reply_to_message_id,
387 | reply_markup: JSON.stringify(reply_markup)
388 | };
389 | return this.reqBot('sendVideo', options);
390 | }
391 | API.prototype.sendLocation = function(first, latitude, longitude, reply_to_message_id, reply_markup) {
392 | var options = _.isObject(first) ?
393 | first : {
394 | chat_id: first,
395 | longitude: longitude,
396 | latitude: latitude,
397 | reply_to_message_id: reply_to_message_id,
398 | reply_markup: JSON.stringify(reply_markup)
399 | };
400 | return this.reqBot('sendLocation', options);
401 | }
402 | API.prototype.sendChatAction = function(first, action) {
403 | var options = _.isObject(first) ?
404 | first : {
405 | chat_id: first,
406 | action: action
407 | };
408 | return this.reqBot('sendChatAction', options);
409 | }
410 | API.prototype.getUserProfilePhotos = function(first, offset, limit) {
411 | var options = _.isObject(first) ?
412 | first : {
413 | user_id: first,
414 | offset: offset,
415 | limit: limit
416 | };
417 | return this.reqBot('getUserProfilePhotos', options);
418 | }
419 | function handle(req, res) {
420 | }
export constructor
432 | 433 |module.exports = API;
Telegram Bot Bootstrap
Bot
handle
Telegram API
API
forwardMessage
getMe
getUpdates
getUserProfilePhotos
sendAudio
sendChatAction
sendDocument
sendLocation
sendMessage
sendPhoto
sendSticker
sendVideo
setWebhook
Methods
Properties
A bootstrap for Telegram bot with directly deployable sample bot and JS-wrapped API methods. You can use all methods available in the Telegram API directly, and send any supported media (we serialize the formData for you to send over HTTP).
61 |See the full API documentation of this project.
62 |
Do either of
65 |npm install telegram-bot-bootstrap
66 | git clone https://github.com/kengz/telegram-bot-bootstrap.git
67 |
Either way you’ll get a module with the Telegram bot API wrapped in Node, and a bootstrapped, deploy-ready project.
68 |If you haven’t already, get a bot from BotFather and remember your bot token!
69 |promises
(uses q) for easy chaining and flow control.See the full API documentation of this project.
79 |API.js
contains the Telegram Bot API wrapped in Node. The methods will return a promise for easy chaining, and will take either a whole JSON, or multiple parameters for convenience. For the latter, everything will be auto-serialized for HTTP so you don’t have to deal with any of the nasty HTTP protocol stuff.
If you wish to use just the API or test the bot methods, here’s an example
81 |See testbot.js
for functional example.
// testbot.js
84 | var bot = require('telegram-bot-bootstrap');
85 | var fs = require('fs');
86 |
87 | var Alice = new bot(your-token);
88 |
89 | Alice.getUpdates().then(console.log)
90 | // → you'll see an update message. Look for your user_id in "message.from.id"
91 |
92 | // Once you get your id to message yourself, you may:
93 | Alice.sendMessage(your-id, "Hello there")
94 | // → you'll receive a message from Alice.
95 | .then(console.log)
96 | // → optional, will log the successful message sent over HTTP
97 |
98 | Alice.sendMessage(86953862, 'Hey wanna see some cool art?');
100 |
101 | Alice.sendPhoto(86953862, fs.createReadStream(__dirname+'/alexiuss.jpg'), 'Chronoscape by Alexiuss').then(console.log)
102 |
You’ll receive this:
103 |
var kb = {
106 | keyboard: [
107 | ['one'],
108 | ['two', 'three'],
109 | ['four', 'five', 'six']
110 | ],
111 | one_time_keyboard: true
112 | };
113 | Alice.sendMessage(86953862, "Choose a lucky number", undefined, undefined, kb)
114 |
You’ll get this:
115 |See index.js
for deployable app, and bot.js
to customize bot commands.
We distinguish the bot from the API: bot.js
extends API.js
, and will be the deployed component.
This whole project is bootstrapped and deploy-ready: all the details of HTTP and server stuff taken care of for you. I deploy this git project onto my Heroku and voila, my bot is alive.
120 |In addition to the token, you’ll need a webhookUrl. If you deploy your Node app to Heroku, then the webhookUrl is simply your Heroku site url. Set both of them in the .env
file:
PORT=8443
123 | TOKEN=your-Telegram-bot-token
124 | WEBHOOK=your-webhook-url
125 |
126 | The sample available is an echo-bot. To make your bot do interesting stuff, head over to bot.js
, under the handle
method, start writing your own from below the Extend from here comment.
The bot inherits all the API methods, so you can simply call them for example by this.sendMessage
.
The server is deployed in index.js
, and a bot is constructed to handle all HTTP POST calls from Telegram.
I use Heroku. This shall work for any other services too. Once I’m done setting up, I do:
131 |git push heroku master
132 |
And done. Start talking to the bot.
133 | 134 |“Bot” Methods
handle(req, res)
Handles a Telegram Update object sent from the server. Extend this method for your bot.
142 |req
(Object): The incoming HTTP request.res
(Object): The HTTP response in return.(Promise): promise A promise returned from calling Telegram API method(s) for chaining.
149 |var bot1 = new bot('yourtokenhere');
151 | ...express server setup
152 | app.route('/')
153 | // robot API as middleware
154 | .post(function(req, res) {
155 | bot1.handle(req, res)
156 | })
157 | // Then bot will handle the incoming Update from you, routed from Telegram!
158 |
159 | “Telegram API” Methods
API(token)
The API bot constructor.
168 |token
(string): Your Telegram bot token.(Bot): The bot able to call methods.
174 |var fs = require('fs');
176 | var bot = require('telegram-bot-bootstrap');
177 | var Alice = new bot(your_bot_token);
178 |
179 | Alice.sendMessage(user_chat_id, 'Hey wanna see some cool art?');
180 |
181 | Alice.sendPhoto(user_chat_id, fs.createReadStream(__dirname+'/alexiuss.jpg'), * 'Chronoscape by Alexiuss').then(console.log)
182 |
183 | var kb = {
184 | keyboard: [
185 | ['one'],
186 | ['two', 'three'],
187 | ['four', 'five', 'six']
188 | ],
189 | one_time_keyboard: true
190 | };
191 | Alice.sendMessage(user_chat_id, "Choose a lucky number", undefined, undefined, * kb)
192 |
193 | // → The messages and photos are sent to user.
194 |
195 | forwardMessage(first, from_chat_id, message_id)
Use this method to forward messages of any kind.
201 |first
(JSON|integer): Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.from_chat_id
(integer): Unique identifier for the chat where the original message was sent — User or GroupChat id.message_id
(integer): Unique message identifier(string): HTTPres On success, the sent Message is returned.
209 |Alice.forwardMessage(87654321, 12345678, 87654356)
211 | // → Message is forwarded
212 |
213 | getMe()
A simple method for testing your bot’s auth token. Requires no parameters.
219 |(string): HTTPres Basic information about the bot in form of a User object.
221 |getUpdates([first|offset], [limit], [timeout])
Use this method to receive incoming updates using long polling (wiki).
227 |[first|offset]
(JSON|integer): An optional JSON object with the parameters, or the offset integer[limit]
(integer):[timeout]
(integer):(string): HTTPres An Array of Update objects is returned.
235 |Alice.getUpdates().then(console.log)
237 | // → {"ok":true,"result":[{"update_id":1234567, "message":{"message_id":1,"from":{"id":87654321, ...}}]
238 |
239 | getUserProfilePhotos(first, [offset], [limit])
Use this method to get a list of profile pictures for a user.
245 |first
(JSON|integer): Your own JSON object, or user_id: Unique identifier of the target user.[offset]
(integer): Sequential number of the first photo to be returned. By default, all photos are returned.[limit]
(integer): Limits the number of photos to be retrieved. Values between 1—100
are accepted. Defaults to 10
0.(string): HTTPres Returns a UserProfilePhotos object.
253 |sendAudio(first, audio, [reply_to_message_id], [reply_markup])
Use this method to send audio files, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent as Document). On success, the sent Message is returned. Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future.
259 |first
(JSON|integer): Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.audio
(inputFile|string): Audio file to send. You can either pass a file_id as String to resend an audio that is already on the Telegram servers, or upload a new audio file using multipart/form-data.[reply_to_message_id]
(integer): If the message is a reply, ID of the original message.[reply_markup]
(KeyboardMarkup): Additional interface options. A JSON object (don’t worry about serializing; it’s handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.(string): HTTPres On success, the sent Message is returned.
268 |sendChatAction(first, action)
Use this method when you need to tell the user that something is happening on the bot’s side. The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear its typing status).
274 |first
(JSON|integer): Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id..action
(string): Type of action to broadcast. Choose one, depending on what the user is about to receive: typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_audio or upload_audio for audio files, upload_document for general files, find_location for location data.(string): HTTPres On success, the sent Message is returned.
281 |sendDocument(first, document, [reply_to_message_id], [reply_markup])
Use this method to send general files. On success, the sent Message is returned. Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
287 |first
(JSON|integer): Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.document
(inputFile|string): File to send. You can either pass a file_id as String to resend a file that is already on the Telegram servers, or upload a new file using multipart/form-data.[reply_to_message_id]
(integer): If the message is a reply, ID of the original message.[reply_markup]
(KeyboardMarkup): Additional interface options. A JSON object (don’t worry about serializing; it’s handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.(string): HTTPres On success, the sent Message is returned.
296 |sendLocation(first, latitude, longitude, [reply_to_message_id], [reply_markup])
Use this method to send point on the map.
302 |first
(JSON|integer): Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.latitude
(number): Latitude of locationlongitude
(number): Longitude of location[reply_to_message_id]
(integer): If the message is a reply, ID of the original message.[reply_markup]
(KeyboardMarkup): Additional interface options. A JSON object (don’t worry about serializing; it’s handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.(string): HTTPres On success, the sent Message is returned.
312 |sendMessage(first, text, [disable_web_page_preview], [reply_to_message_id], [reply_markup])
Use this method to send text messages.
318 |first
(JSON|integer): Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.text
(string): Text of the message to be sent.[disable_web_page_preview]
(boolean): Disables link previews for links in this message.[reply_to_message_id]
(integer): If the message is a reply, ID of the original message.[reply_markup]
(KeyboardMarkup): Additional interface options. A JSON object (don’t worry about serializing; it’s handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.(string): HTTPres On success, the sent Message is returned.
328 |Alice.sendMessage({chat_id: 87654321, text: 'hello world'})
330 | Alice.sendMessage(87654321, 'hello world') // equivalent, cleaner
331 | // → 'hello world' is sent to the user with the id.
332 |
333 | // var kb = {
334 | // keyboard: [
335 | // ['one'],
336 | // ['two', 'three'],
337 | // ['four', 'five', 'six']
338 | // ],
339 | // one_time_keyboard: true
340 | // };
341 | Alice.sendMessage(87654321, "Choose a lucky number", undefined, undefined, kb)
342 | // → 'Choose a lucky number' is sent, with custom reply keyboard
343 |
344 | sendPhoto(first, photo, [caption], [reply_to_message_id], [reply_markup])
Use this method to send photos.
350 |first
(JSON|integer): Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.photo
(inputFile|string): Photo to send. You can either pass a file_id as String to resend a photo that is already on the Telegram servers, or upload a new photo using multipart/form-data.[caption]
(string):[reply_to_message_id]
(integer): If the message is a reply, ID of the original message.[reply_markup]
(KeyboardMarkup): Additional interface options. A JSON object (don’t worry about serializing; it’s handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.(string): HTTPres On success, the sent Message is returned.
360 |Alice.sendMessage(87654321, fs.createReadStream('localpath/to/photo.jpg'), 'cool caption')
362 | // → The photo on local system is sent to the id.
363 |
364 | sendSticker(first, sticker, [reply_to_message_id], [reply_markup])
Use this method to send .webp stickers.
370 |first
(JSON|integer): Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.sticker
(inputFile|string): Sticker to send. You can either pass a file_id as String to resend a sticker that is already on the Telegram servers, or upload a new sticker using multipart/form-data.[reply_to_message_id]
(integer): If the message is a reply, ID of the original message.[reply_markup]
(KeyboardMarkup): Additional interface options. A JSON object (don’t worry about serializing; it’s handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.(string): HTTPres On success, the sent Message is returned.
379 |sendVideo(first, video, [reply_to_message_id], [reply_markup])
Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document). On success, the sent Message is returned. Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future.
385 |first
(JSON|integer): Your own JSON object, or chat_id: Unique identifier for the message recipient — User or GroupChat id.video
(inputFile|string): Video to send. You can either pass a file_id as String to resend a video that is already on the Telegram servers, or upload a new video file using multipart/form-data.[reply_to_message_id]
(integer): If the message is a reply, ID of the original message.[reply_markup]
(KeyboardMarkup): Additional interface options. A JSON object (don’t worry about serializing; it’s handled) for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.(string): HTTPres On success, the sent Message is returned.
394 |setWebhook(url)
Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update. In case of an unsuccessful request, we will give up after a reasonable amount of attempts.
400 |url
(string): A JSON object with the parameters, or the HTTPS url to send updates to. Use an empty string to remove webhook integration.(string): HTTPres An Array of Update objects is returned.
406 |Methods
Properties
Alice.token.should.equal(123456);
This is a deployment test using Angular and Bootstrap. You may create your bot interface here if you wish.
24 |