@zero-bot.net/tg-bot-api 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3119 @@
1
+ // shims
2
+ require('array.prototype.findindex').shim(); // for Node.js v0.x
3
+
4
+ const errors = require('./errors');
5
+ const TelegramBotWebHook = require('./telegramWebHook');
6
+ const TelegramBotPolling = require('./telegramPolling');
7
+ const debug = require('debug')('@zero-bot.net/tg-bot-api');
8
+ const EventEmitter = require('eventemitter3');
9
+ const fileType = require('file-type');
10
+ const requestBase = require('@zero-bot.net/request');
11
+ const request = (options) => new Promise((resolve, reject) => {
12
+ requestBase(options, (err, response) => {
13
+ if (err) reject(err);
14
+ else resolve(response);
15
+ });
16
+ });
17
+ const streamedRequest = requestBase;
18
+ const qs = require('querystring');
19
+ const stream = require('stream');
20
+ const mime = require('mime');
21
+ const path = require('path');
22
+ const URL = require('url');
23
+ const fs = require('fs');
24
+ const pump = require('pump');
25
+ const deprecate = require('./utils').deprecate;
26
+
27
+ const _messageTypes = [
28
+ 'text',
29
+ 'animation',
30
+ 'audio',
31
+ 'channel_chat_created',
32
+ 'contact',
33
+ 'delete_chat_photo',
34
+ 'dice',
35
+ 'document',
36
+ 'game',
37
+ 'group_chat_created',
38
+ 'invoice',
39
+ 'left_chat_member',
40
+ 'location',
41
+ 'migrate_from_chat_id',
42
+ 'migrate_to_chat_id',
43
+ 'new_chat_members',
44
+ 'new_chat_photo',
45
+ 'new_chat_title',
46
+ 'passport_data',
47
+ 'photo',
48
+ 'pinned_message',
49
+ 'poll',
50
+ 'sticker',
51
+ 'successful_payment',
52
+ 'supergroup_chat_created',
53
+ 'video',
54
+ 'video_note',
55
+ 'voice',
56
+ 'video_chat_started',
57
+ 'video_chat_ended',
58
+ 'video_chat_participants_invited',
59
+ 'video_chat_scheduled',
60
+ 'message_auto_delete_timer_changed',
61
+ 'chat_invite_link',
62
+ 'chat_member_updated',
63
+ 'web_app_data',
64
+ 'message_reaction'
65
+ ];
66
+
67
+ const _deprecatedMessageTypes = [
68
+ 'new_chat_participant', 'left_chat_participant'
69
+ ];
70
+
71
+ /**
72
+ * JSON-serialize data. If the provided data is already a String,
73
+ * return it as is.
74
+ * @private
75
+ * @param {*} data
76
+ * @return {String}
77
+ */
78
+ function stringify(data) {
79
+ if (typeof data === 'string') {
80
+ return data;
81
+ }
82
+ return JSON.stringify(data);
83
+ }
84
+
85
+
86
+ class TelegramBot extends EventEmitter {
87
+ /**
88
+ * The different errors the library uses.
89
+ * @type {Object}
90
+ */
91
+ static get errors() {
92
+ return errors;
93
+ }
94
+
95
+ /**
96
+ * The types of message updates the library handles.
97
+ * @type {String[]}
98
+ */
99
+ static get messageTypes() {
100
+ return _messageTypes;
101
+ }
102
+
103
+ /**
104
+ * Add listener for the specified [event](https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#events).
105
+ * This is the usual `emitter.on()` method.
106
+ * @param {String} event
107
+ * @param {Function} listener
108
+ * @see {@link https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#events|Available events}
109
+ * @see https://nodejs.org/api/events.html#events_emitter_on_eventname_listener
110
+ */
111
+ on(event, listener) {
112
+ if (_deprecatedMessageTypes.indexOf(event) !== -1) {
113
+ const url = 'https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#events';
114
+ deprecate(`Events ${_deprecatedMessageTypes.join(',')} are deprecated. See the updated list of events: ${url}`);
115
+ }
116
+ super.on(event, listener);
117
+ }
118
+
119
+ /**
120
+ * Both request method to obtain messages are implemented. To use standard polling, set `polling: true`
121
+ * on `options`. Notice that [webHook](https://core.telegram.org/bots/api#setwebhook) will need a SSL certificate.
122
+ * Emits `message` when a message arrives.
123
+ *
124
+ * @class TelegramBot
125
+ * @constructor
126
+ * @param {String} token Bot Token
127
+ * @param {Object} [options]
128
+ * @param {Boolean|Object} [options.polling=false] Set true to enable polling or set options.
129
+ * If a WebHook has been set, it will be deleted automatically.
130
+ * @param {String|Number} [options.polling.timeout=10] *Deprecated. Use `options.polling.params` instead*.
131
+ * Timeout in seconds for long polling.
132
+ * @param {Boolean} [options.testEnvironment=false] Set true to work with test enviroment.
133
+ * When working with the test environment, you may use HTTP links without TLS to test your Web App.
134
+ * @param {String|Number} [options.polling.interval=300] Interval between requests in miliseconds
135
+ * @param {Boolean} [options.polling.autoStart=true] Start polling immediately
136
+ * @param {Object} [options.polling.params] Parameters to be used in polling API requests.
137
+ * See https://core.telegram.org/bots/api#getupdates for more information.
138
+ * @param {Number} [options.polling.params.timeout=10] Timeout in seconds for long polling.
139
+ * @param {Boolean|Object} [options.webHook=false] Set true to enable WebHook or set options
140
+ * @param {String} [options.webHook.host="0.0.0.0"] Host to bind to
141
+ * @param {Number} [options.webHook.port=8443] Port to bind to
142
+ * @param {String} [options.webHook.key] Path to file with PEM private key for webHook server.
143
+ * The file is read **synchronously**!
144
+ * @param {String} [options.webHook.cert] Path to file with PEM certificate (public) for webHook server.
145
+ * The file is read **synchronously**!
146
+ * @param {String} [options.webHook.pfx] Path to file with PFX private key and certificate chain for webHook server.
147
+ * The file is read **synchronously**!
148
+ * @param {Boolean} [options.webHook.autoOpen=true] Open webHook immediately
149
+ * @param {Object} [options.webHook.https] Options to be passed to `https.createServer()`.
150
+ * Note that `options.webHook.key`, `options.webHook.cert` and `options.webHook.pfx`, if provided, will be
151
+ * used to override `key`, `cert` and `pfx` in this object, respectively.
152
+ * See https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener for more information.
153
+ * @param {String} [options.webHook.healthEndpoint="/healthz"] An endpoint for health checks that always responds with 200 OK
154
+ * @param {Boolean} [options.onlyFirstMatch=false] Set to true to stop after first match. Otherwise, all regexps are executed
155
+ * @param {Object} [options.request] Options which will be added for all requests to telegram api.
156
+ * See https://github.com/request/request#requestoptions-callback for more information.
157
+ * @param {String} [options.baseApiUrl="https://api.telegram.org"] API Base URl; useful for proxying and testing
158
+ * @param {Boolean} [options.filepath=true] Allow passing file-paths as arguments when sending files,
159
+ * such as photos using `TelegramBot#sendPhoto()`. See [usage information][usage-sending-files-performance]
160
+ * for more information on this option and its consequences.
161
+ * @param {Boolean} [options.badRejection=false] Set to `true`
162
+ * **if and only if** the Node.js version you're using terminates the
163
+ * process on unhandled rejections. This option is only for
164
+ * *forward-compatibility purposes*.
165
+ * @see https://core.telegram.org/bots/api
166
+ */
167
+ constructor(token, options = {}) {
168
+ super();
169
+ this.token = token;
170
+ this.options = options;
171
+ this.options.polling = (typeof options.polling === 'undefined') ? false : options.polling;
172
+ this.options.webHook = (typeof options.webHook === 'undefined') ? false : options.webHook;
173
+ this.options.baseApiUrl = options.baseApiUrl || 'https://api.telegram.org';
174
+ this.options.filepath = (typeof options.filepath === 'undefined') ? true : options.filepath;
175
+ this.options.badRejection = (typeof options.badRejection === 'undefined') ? false : options.badRejection;
176
+ this._textRegexpCallbacks = [];
177
+ this._replyListenerId = 0;
178
+ this._replyListeners = [];
179
+ this._polling = null;
180
+ this._webHook = null;
181
+
182
+ if (options.polling) {
183
+ const autoStart = options.polling.autoStart;
184
+ if (typeof autoStart === 'undefined' || autoStart === true) {
185
+ this.startPolling();
186
+ }
187
+ }
188
+
189
+ if (options.webHook) {
190
+ const autoOpen = options.webHook.autoOpen;
191
+ if (typeof autoOpen === 'undefined' || autoOpen === true) {
192
+ this.openWebHook();
193
+ }
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Generates url with bot token and provided path/method you want to be got/executed by bot
199
+ * @param {String} path
200
+ * @return {String} url
201
+ * @private
202
+ * @see https://core.telegram.org/bots/api#making-requests
203
+ */
204
+ _buildURL(_path) {
205
+ return `${this.options.baseApiUrl}/bot${this.token}${this.options.testEnvironment ? '/test' : ''}/${_path}`;
206
+ }
207
+
208
+ /**
209
+ * Fix 'reply_markup' parameter by making it JSON-serialized, as
210
+ * required by the Telegram Bot API
211
+ * @param {Object} obj Object; either 'form' or 'qs'
212
+ * @private
213
+ * @see https://core.telegram.org/bots/api#sendmessage
214
+ */
215
+ _fixReplyMarkup(obj) {
216
+ const replyMarkup = obj.reply_markup;
217
+ if (replyMarkup && typeof replyMarkup !== 'string') {
218
+ obj.reply_markup = stringify(replyMarkup);
219
+ }
220
+ }
221
+
222
+ /**
223
+ * Fix 'entities' or 'caption_entities' or 'explanation_entities' parameter by making it JSON-serialized, as
224
+ * required by the Telegram Bot API
225
+ * @param {Object} obj Object;
226
+ * @private
227
+ * @see https://core.telegram.org/bots/api#sendmessage
228
+ * @see https://core.telegram.org/bots/api#copymessage
229
+ * @see https://core.telegram.org/bots/api#sendpoll
230
+ */
231
+ _fixEntitiesField(obj) {
232
+ const entities = obj.entities;
233
+ const captionEntities = obj.caption_entities;
234
+ const explanationEntities = obj.explanation_entities;
235
+ if (entities && typeof entities !== 'string') {
236
+ obj.entities = stringify(entities);
237
+ }
238
+
239
+ if (captionEntities && typeof captionEntities !== 'string') {
240
+ obj.caption_entities = stringify(captionEntities);
241
+ }
242
+
243
+ if (explanationEntities && typeof explanationEntities !== 'string') {
244
+ obj.explanation_entities = stringify(explanationEntities);
245
+ }
246
+ }
247
+
248
+ _fixAddFileThumbnail(options, opts) {
249
+ if (options.thumb) {
250
+ if (opts.formData === null) {
251
+ opts.formData = {};
252
+ }
253
+
254
+ const attachName = 'photo';
255
+ const [formData] = this._formatSendData(attachName, options.thumb.replace('attach://', ''));
256
+
257
+ if (formData) {
258
+ opts.formData[attachName] = formData[attachName];
259
+ opts.qs.thumbnail = `attach://${attachName}`;
260
+ }
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Fix 'reply_parameters' parameter by making it JSON-serialized, as
266
+ * required by the Telegram Bot API
267
+ * @param {Object} obj Object; either 'form' or 'qs'
268
+ * @private
269
+ * @see https://core.telegram.org/bots/api#sendmessage
270
+ */
271
+ _fixReplyParameters(obj) {
272
+ if (obj.hasOwnProperty('reply_parameters') && typeof obj.reply_parameters !== 'string') {
273
+ obj.reply_parameters = stringify(obj.reply_parameters);
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Make request against the API
279
+ * @param {String} _path API endpoint
280
+ * @param {Object} [options]
281
+ * @private
282
+ * @return {Promise}
283
+ */
284
+ _request(_path, options = {}) {
285
+ if (!this.token) {
286
+ return Promise.reject(new errors.FatalError('Telegram Bot Token not provided!'));
287
+ }
288
+
289
+ if (this.options.request) {
290
+ Object.assign(options, this.options.request);
291
+ }
292
+
293
+ if (options.form) {
294
+ this._fixReplyMarkup(options.form);
295
+ this._fixEntitiesField(options.form);
296
+ this._fixReplyParameters(options.form);
297
+ }
298
+ if (options.qs) {
299
+ this._fixReplyMarkup(options.qs);
300
+ this._fixReplyParameters(options.qs);
301
+ }
302
+
303
+ options.method = 'POST';
304
+ options.url = this._buildURL(_path);
305
+ options.simple = false;
306
+ options.resolveWithFullResponse = true;
307
+ options.forever = true;
308
+ debug('HTTP request: %j', options);
309
+ return request(options)
310
+ .then(resp => {
311
+ let data;
312
+ try {
313
+ data = resp.body = JSON.parse(resp.body);
314
+ } catch (err) {
315
+ throw new errors.ParseError(`Error parsing response: ${resp.body}`, resp);
316
+ }
317
+
318
+ if (data.ok) {
319
+ return data.result;
320
+ }
321
+
322
+ throw new errors.TelegramError(`${data.error_code} ${data.description}`, resp);
323
+ }).catch(error => {
324
+ // TODO: why can't we do `error instanceof errors.BaseError`?
325
+ if (error.response) throw error;
326
+ throw new errors.FatalError(error);
327
+ });
328
+ }
329
+
330
+ /**
331
+ * Format data to be uploaded; handles file paths, streams and buffers
332
+ * @param {String} type
333
+ * @param {String|stream.Stream|Buffer} data
334
+ * @param {Object} fileOptions File options
335
+ * @param {String} [fileOptions.filename] File name
336
+ * @param {String} [fileOptions.contentType] Content type (i.e. MIME)
337
+ * @return {Array} formatted
338
+ * @return {Object} formatted[0] formData
339
+ * @return {String} formatted[1] fileId
340
+ * @throws Error if Buffer file type is not supported.
341
+ * @see https://npmjs.com/package/file-type
342
+ * @private
343
+ */
344
+ _formatSendData(type, data, fileOptions = {}) {
345
+ const deprecationMessage =
346
+ 'See https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#sending-files' +
347
+ ' for more information on how sending files has been improved and' +
348
+ ' on how to disable this deprecation message altogether.';
349
+ let filedata = data;
350
+ let filename = fileOptions.filename;
351
+ let contentType = fileOptions.contentType;
352
+
353
+ if (data instanceof stream.Stream) {
354
+ if (!filename && data.path) {
355
+ // Will be 'null' if could not be parsed.
356
+ // For example, 'data.path' === '/?id=123' from 'request("https://example.com/?id=123")'
357
+ const url = URL.parse(path.basename(data.path.toString()));
358
+ if (url.pathname) {
359
+ filename = qs.unescape(url.pathname);
360
+ }
361
+ }
362
+ } else if (Buffer.isBuffer(data)) {
363
+ if (!filename && !process.env.NTBA_FIX_350) {
364
+ deprecate(`Buffers will have their filenames default to "filename" instead of "data". ${deprecationMessage}`);
365
+ filename = 'data';
366
+ }
367
+ if (!contentType) {
368
+ const filetype = fileType(data);
369
+ if (filetype) {
370
+ contentType = filetype.mime;
371
+ const ext = filetype.ext;
372
+ if (ext && !process.env.NTBA_FIX_350) {
373
+ filename = `${filename}.${ext}`;
374
+ }
375
+ } else if (!process.env.NTBA_FIX_350) {
376
+ deprecate(`An error will no longer be thrown if file-type of buffer could not be detected. ${deprecationMessage}`);
377
+ throw new errors.FatalError('Unsupported Buffer file-type');
378
+ }
379
+ }
380
+ } else if (data) {
381
+ if (this.options.filepath && fs.existsSync(data)) {
382
+ filedata = fs.createReadStream(data);
383
+ if (!filename) {
384
+ filename = path.basename(data);
385
+ }
386
+ } else {
387
+ return [null, data];
388
+ }
389
+ } else {
390
+ return [null, data];
391
+ }
392
+
393
+ filename = filename || 'filename';
394
+ contentType = contentType || mime.lookup(filename);
395
+ if (process.env.NTBA_FIX_350) {
396
+ contentType = contentType || 'application/octet-stream';
397
+ } else {
398
+ deprecate(`In the future, content-type of files you send will default to "application/octet-stream". ${deprecationMessage}`);
399
+ }
400
+
401
+ // TODO: Add missing file extension.
402
+
403
+ return [{
404
+ [type]: {
405
+ value: filedata,
406
+ options: {
407
+ filename,
408
+ contentType,
409
+ },
410
+ },
411
+ }, null];
412
+ }
413
+
414
+ /**
415
+ * Start polling.
416
+ * Rejects returned promise if a WebHook is being used by this instance.
417
+ * @param {Object} [options]
418
+ * @param {Boolean} [options.restart=true] Consecutive calls to this method causes polling to be restarted
419
+ * @return {Promise}
420
+ */
421
+ startPolling(options = {}) {
422
+ if (this.hasOpenWebHook()) {
423
+ return Promise.reject(new errors.FatalError('Polling and WebHook are mutually exclusive'));
424
+ }
425
+ options.restart = typeof options.restart === 'undefined' ? true : options.restart;
426
+ if (!this._polling) {
427
+ this._polling = new TelegramBotPolling(this);
428
+ }
429
+ return this._polling.start(options);
430
+ }
431
+
432
+ /**
433
+ * Alias of `TelegramBot#startPolling()`. This is **deprecated**.
434
+ * @param {Object} [options]
435
+ * @return {Promise}
436
+ * @deprecated
437
+ */
438
+ initPolling() {
439
+ deprecate('TelegramBot#initPolling() is deprecated. Use TelegramBot#startPolling() instead.');
440
+ return this.startPolling();
441
+ }
442
+
443
+ /**
444
+ * Stops polling after the last polling request resolves.
445
+ * Multiple invocations do nothing if polling is already stopped.
446
+ * Returning the promise of the last polling request is **deprecated**.
447
+ * @param {Object} [options] Options
448
+ * @param {Boolean} [options.cancel] Cancel current request
449
+ * @param {String} [options.reason] Reason for stopping polling
450
+ * @return {Promise}
451
+ */
452
+ stopPolling(options) {
453
+ if (!this._polling) {
454
+ return Promise.resolve();
455
+ }
456
+ return this._polling.stop(options);
457
+ }
458
+
459
+ /**
460
+ * Get link for file.
461
+ * Use this method to get link for file for subsequent use.
462
+ * Attention: link will be valid for 1 hour.
463
+ *
464
+ * This method is a sugar extension of the (getFile)[#getfilefileid] method,
465
+ * which returns just path to file on remote server (you will have to manually build full uri after that).
466
+ *
467
+ * @param {String} fileId File identifier to get info about
468
+ * @param {Object} [options] Additional Telegram query options
469
+ * @return {Promise} Promise which will have *fileURI* in resolve callback
470
+ * @see https://core.telegram.org/bots/api#getfile
471
+ */
472
+ getFileLink(fileId, form = {}) {
473
+ return this.getFile(fileId, form)
474
+ .then(resp => `${this.options.baseApiUrl}/file/bot${this.token}/${resp.file_path}`);
475
+ }
476
+
477
+ /**
478
+ * Return a readable stream for file.
479
+ *
480
+ * `fileStream.path` is the specified file ID i.e. `fileId`.
481
+ * `fileStream` emits event `info` passing a single argument i.e.
482
+ * `info` with the interface `{ uri }` where `uri` is the URI of the
483
+ * file on Telegram servers.
484
+ *
485
+ * This method is a sugar extension of the [getFileLink](#TelegramBot+getFileLink) method,
486
+ * which returns the full URI to the file on remote server.
487
+ *
488
+ * @param {String} fileId File identifier to get info about
489
+ * @param {Object} [options] Additional Telegram query options
490
+ * @return {stream.Readable} fileStream
491
+ */
492
+ getFileStream(fileId, form = {}) {
493
+ const fileStream = new stream.PassThrough();
494
+ fileStream.path = fileId;
495
+ this.getFileLink(fileId, form)
496
+ .then((fileURI) => {
497
+ fileStream.emit('info', {
498
+ uri: fileURI,
499
+ });
500
+ pump(streamedRequest(Object.assign({ uri: fileURI }, this.options.request)), fileStream);
501
+ })
502
+ .catch((error) => {
503
+ fileStream.emit('error', error);
504
+ });
505
+ return fileStream;
506
+ }
507
+
508
+ /**
509
+ * Downloads file in the specified folder.
510
+ *
511
+ * This method is a sugar extension of the [getFileStream](#TelegramBot+getFileStream) method,
512
+ * which returns a readable file stream.
513
+ *
514
+ * @param {String} fileId File identifier to get info about
515
+ * @param {String} downloadDir Absolute path to the folder in which file will be saved
516
+ * @param {Object} [options] Additional Telegram query options
517
+ * @return {Promise} Promise, which will have *filePath* of downloaded file in resolve callback
518
+ */
519
+ downloadFile(fileId, downloadDir, form = {}) {
520
+ let resolve;
521
+ let reject;
522
+ const promise = new Promise((a, b) => {
523
+ resolve = a;
524
+ reject = b;
525
+ });
526
+ const fileStream = this.getFileStream(fileId, form);
527
+ fileStream.on('info', (info) => {
528
+ const fileName = info.uri.slice(info.uri.lastIndexOf('/') + 1);
529
+ // TODO: Ensure fileName doesn't contains slashes
530
+ const filePath = path.join(downloadDir, fileName);
531
+ pump(fileStream, fs.createWriteStream(filePath), (error) => {
532
+ if (error) { return reject(error); }
533
+ return resolve(filePath);
534
+ });
535
+ });
536
+ fileStream.on('error', (err) => {
537
+ reject(err);
538
+ });
539
+ return promise;
540
+ }
541
+
542
+ /**
543
+ * Register a RegExp to test against an incomming text message.
544
+ * @param {RegExp} regexpRexecuted with `exec`.
545
+ * @param {Function} callback Callback will be called with 2 parameters,
546
+ * the `msg` and the result of executing `regexp.exec` on message text.
547
+ */
548
+ onText(regexp, callback) {
549
+ this._textRegexpCallbacks.push({ regexp, callback });
550
+ }
551
+
552
+ /**
553
+ * Remove a listener registered with `onText()`.
554
+ * @param {RegExp} regexp RegExp used previously in `onText()`
555
+ * @return {Object} deletedListener The removed reply listener if
556
+ * found. This object has `regexp` and `callback`
557
+ * properties. If not found, returns `null`.
558
+ */
559
+ removeTextListener(regexp) {
560
+ const index = this._textRegexpCallbacks.findIndex((textListener) => {
561
+ return String(textListener.regexp) === String(regexp);
562
+ });
563
+ if (index === -1) {
564
+ return null;
565
+ }
566
+ return this._textRegexpCallbacks.splice(index, 1)[0];
567
+ }
568
+
569
+ /**
570
+ * Remove all listeners registered with `onText()`.
571
+ */
572
+ clearTextListeners() {
573
+ this._textRegexpCallbacks = [];
574
+ }
575
+
576
+ /**
577
+ * Register a reply to wait for a message response.
578
+ *
579
+ * @param {Number|String} chatId The chat id where the message cames from.
580
+ * @param {Number|String} messageId The message id to be replied.
581
+ * @param {Function} callback Callback will be called with the reply
582
+ * message.
583
+ * @return {Number} id The ID of the inserted reply listener.
584
+ */
585
+ onReplyToMessage(chatId, messageId, callback) {
586
+ const id = ++this._replyListenerId;
587
+ this._replyListeners.push({
588
+ id,
589
+ chatId,
590
+ messageId,
591
+ callback
592
+ });
593
+ return id;
594
+ }
595
+
596
+ /**
597
+ * Removes a reply that has been prev. registered for a message response.
598
+ * @param {Number} replyListenerId The ID of the reply listener.
599
+ * @return {Object} deletedListener The removed reply listener if
600
+ * found. This object has `id`, `chatId`, `messageId` and `callback`
601
+ * properties. If not found, returns `null`.
602
+ */
603
+ removeReplyListener(replyListenerId) {
604
+ const index = this._replyListeners.findIndex((replyListener) => {
605
+ return replyListener.id === replyListenerId;
606
+ });
607
+ if (index === -1) {
608
+ return null;
609
+ }
610
+ return this._replyListeners.splice(index, 1)[0];
611
+ }
612
+
613
+ /**
614
+ * Removes all replies that have been prev. registered for a message response.
615
+ *
616
+ * @return {Array} deletedListeners An array of removed listeners.
617
+ */
618
+ clearReplyListeners() {
619
+ this._replyListeners = [];
620
+ }
621
+
622
+ /**
623
+ * Return true if polling. Otherwise, false.
624
+ *
625
+ * @return {Boolean}
626
+ */
627
+ isPolling() {
628
+ return this._polling ? this._polling.isPolling() : false;
629
+ }
630
+
631
+ /**
632
+ * Open webhook.
633
+ * Multiple invocations do nothing if webhook is already open.
634
+ * Rejects returned promise if Polling is being used by this instance.
635
+ *
636
+ * @return {Promise}
637
+ */
638
+ openWebHook() {
639
+ if (this.isPolling()) {
640
+ return Promise.reject(new errors.FatalError('WebHook and Polling are mutually exclusive'));
641
+ }
642
+ if (!this._webHook) {
643
+ this._webHook = new TelegramBotWebHook(this);
644
+ }
645
+ return this._webHook.open();
646
+ }
647
+
648
+ /**
649
+ * Close webhook after closing all current connections.
650
+ * Multiple invocations do nothing if webhook is already closed.
651
+ *
652
+ * @return {Promise} Promise
653
+ */
654
+ closeWebHook() {
655
+ if (!this._webHook) {
656
+ return Promise.resolve();
657
+ }
658
+ return this._webHook.close();
659
+ }
660
+
661
+ /**
662
+ * Return true if using webhook and it is open i.e. accepts connections.
663
+ * Otherwise, false.
664
+ *
665
+ * @return {Boolean}
666
+ */
667
+ hasOpenWebHook() {
668
+ return this._webHook ? this._webHook.isOpen() : false;
669
+ }
670
+
671
+
672
+ /**
673
+ * Process an update; emitting the proper events and executing regexp
674
+ * callbacks. This method is useful should you be using a different
675
+ * way to fetch updates, other than those provided by TelegramBot.
676
+ *
677
+ * @param {Object} update
678
+ * @see https://core.telegram.org/bots/api#update
679
+ */
680
+ processUpdate(update) {
681
+ debug('Process Update %j', update);
682
+ const message = update.message;
683
+ const editedMessage = update.edited_message;
684
+ const channelPost = update.channel_post;
685
+ const editedChannelPost = update.edited_channel_post;
686
+ const businessConnection = update.business_connection;
687
+ const businesssMessage = update.business_message;
688
+ const editedBusinessMessage = update.edited_business_message;
689
+ const deletedBusinessMessage = update.deleted_business_messages;
690
+ const messageReaction = update.message_reaction;
691
+ const messageReactionCount = update.message_reaction_count;
692
+ const inlineQuery = update.inline_query;
693
+ const chosenInlineResult = update.chosen_inline_result;
694
+ const callbackQuery = update.callback_query;
695
+ const shippingQuery = update.shipping_query;
696
+ const preCheckoutQuery = update.pre_checkout_query;
697
+ const poll = update.poll;
698
+ const pollAnswer = update.poll_answer;
699
+ const myChatMember = update.my_chat_member;
700
+ const chatMember = update.chat_member;
701
+ const chatJoinRequest = update.chat_join_request;
702
+ const chatBoost = update.chat_boost;
703
+ const removedChatBoost = update.removed_chat_boost;
704
+
705
+
706
+ if (message) {
707
+ debug('Process Update message %j', message);
708
+ const metadata = {};
709
+ metadata.type = TelegramBot.messageTypes.find((messageType) => {
710
+ return message[messageType];
711
+ });
712
+ this.emit('message', message, metadata);
713
+ if (metadata.type) {
714
+ debug('Emitting %s: %j', metadata.type, message);
715
+ this.emit(metadata.type, message, metadata);
716
+ }
717
+ if (message.text) {
718
+ debug('Text message');
719
+ this._textRegexpCallbacks.some(reg => {
720
+ debug('Matching %s with %s', message.text, reg.regexp);
721
+
722
+ if (!(reg.regexp instanceof RegExp)) {
723
+ reg.regexp = new RegExp(reg.regexp);
724
+ }
725
+
726
+ const result = reg.regexp.exec(message.text);
727
+ if (!result) {
728
+ return false;
729
+ }
730
+ // reset index so we start at the beginning of the regex each time
731
+ reg.regexp.lastIndex = 0;
732
+ debug('Matches %s', reg.regexp);
733
+ reg.callback(message, result);
734
+ // returning truthy value exits .some
735
+ return this.options.onlyFirstMatch;
736
+ });
737
+ }
738
+ if (message.reply_to_message) {
739
+ // Only callbacks waiting for this message
740
+ this._replyListeners.forEach(reply => {
741
+ // Message from the same chat
742
+ if (reply.chatId === message.chat.id) {
743
+ // Responding to that message
744
+ if (reply.messageId === message.reply_to_message.message_id) {
745
+ // Resolve the promise
746
+ reply.callback(message);
747
+ }
748
+ }
749
+ });
750
+ }
751
+ } else if (editedMessage) {
752
+ debug('Process Update edited_message %j', editedMessage);
753
+ this.emit('edited_message', editedMessage);
754
+ if (editedMessage.text) {
755
+ this.emit('edited_message_text', editedMessage);
756
+ }
757
+ if (editedMessage.caption) {
758
+ this.emit('edited_message_caption', editedMessage);
759
+ }
760
+ } else if (channelPost) {
761
+ debug('Process Update channel_post %j', channelPost);
762
+ this.emit('channel_post', channelPost);
763
+ } else if (editedChannelPost) {
764
+ debug('Process Update edited_channel_post %j', editedChannelPost);
765
+ this.emit('edited_channel_post', editedChannelPost);
766
+ if (editedChannelPost.text) {
767
+ this.emit('edited_channel_post_text', editedChannelPost);
768
+ }
769
+ if (editedChannelPost.caption) {
770
+ this.emit('edited_channel_post_caption', editedChannelPost);
771
+ }
772
+ } else if (businessConnection) {
773
+ debug('Process Update business_connection %j', businessConnection);
774
+ this.emit('business_connection', businessConnection);
775
+ } else if (businesssMessage) {
776
+ debug('Process Update business_message %j', businesssMessage);
777
+ this.emit('business_message', businesssMessage);
778
+ } else if (editedBusinessMessage) {
779
+ debug('Process Update edited_business_message %j', editedBusinessMessage);
780
+ this.emit('edited_business_message', editedBusinessMessage);
781
+ } else if (deletedBusinessMessage) {
782
+ debug('Process Update deleted_business_messages %j', deletedBusinessMessage);
783
+ this.emit('deleted_business_messages', deletedBusinessMessage);
784
+ } else if (messageReaction) {
785
+ debug('Process Update message_reaction %j', messageReaction);
786
+ this.emit('message_reaction', messageReaction);
787
+ } else if (messageReactionCount) {
788
+ debug('Process Update message_reaction_count %j', messageReactionCount);
789
+ this.emit('message_reaction_count', messageReactionCount);
790
+ } else if (inlineQuery) {
791
+ debug('Process Update inline_query %j', inlineQuery);
792
+ this.emit('inline_query', inlineQuery);
793
+ } else if (chosenInlineResult) {
794
+ debug('Process Update chosen_inline_result %j', chosenInlineResult);
795
+ this.emit('chosen_inline_result', chosenInlineResult);
796
+ } else if (callbackQuery) {
797
+ debug('Process Update callback_query %j', callbackQuery);
798
+ this.emit('callback_query', callbackQuery);
799
+ } else if (shippingQuery) {
800
+ debug('Process Update shipping_query %j', shippingQuery);
801
+ this.emit('shipping_query', shippingQuery);
802
+ } else if (preCheckoutQuery) {
803
+ debug('Process Update pre_checkout_query %j', preCheckoutQuery);
804
+ this.emit('pre_checkout_query', preCheckoutQuery);
805
+ } else if (poll) {
806
+ debug('Process Update poll %j', poll);
807
+ this.emit('poll', poll);
808
+ } else if (pollAnswer) {
809
+ debug('Process Update poll_answer %j', pollAnswer);
810
+ this.emit('poll_answer', pollAnswer);
811
+ } else if (chatMember) {
812
+ debug('Process Update chat_member %j', chatMember);
813
+ this.emit('chat_member', chatMember);
814
+ } else if (myChatMember) {
815
+ debug('Process Update my_chat_member %j', myChatMember);
816
+ this.emit('my_chat_member', myChatMember);
817
+ } else if (chatJoinRequest) {
818
+ debug('Process Update my_chat_member %j', chatJoinRequest);
819
+ this.emit('chat_join_request', chatJoinRequest);
820
+ } else if (chatBoost) {
821
+ debug('Process Update chat_boost %j', chatBoost);
822
+ this.emit('chat_boost', chatBoost);
823
+ } else if (removedChatBoost) {
824
+ debug('Process Update removed_chat_boost %j', removedChatBoost);
825
+ this.emit('removed_chat_boost', removedChatBoost);
826
+ }
827
+ }
828
+
829
+ /** Start Telegram Bot API methods */
830
+
831
+ /**
832
+ * Use this method to receive incoming updates using long polling.
833
+ * This method has an [older, compatible signature][getUpdates-v0.25.0]
834
+ * that is being deprecated.
835
+ *
836
+ * @param {Object} [options] Additional Telegram query options
837
+ * @return {Promise}
838
+ * @see https://core.telegram.org/bots/api#getupdates
839
+ */
840
+ getUpdates(form = {}) {
841
+ /* The older method signature was getUpdates(timeout, limit, offset).
842
+ * We need to ensure backwards-compatibility while maintaining
843
+ * consistency of the method signatures throughout the library */
844
+ if (typeof form !== 'object') {
845
+ /* eslint-disable no-param-reassign, prefer-rest-params */
846
+ deprecate('The method signature getUpdates(timeout, limit, offset) has been deprecated since v0.25.0');
847
+ form = {
848
+ timeout: arguments[0],
849
+ limit: arguments[1],
850
+ offset: arguments[2],
851
+ };
852
+ /* eslint-enable no-param-reassign, prefer-rest-params */
853
+ }
854
+
855
+ return this._request('getUpdates', { form });
856
+ }
857
+
858
+ /**
859
+ * Specify an url to receive incoming updates via an outgoing webHook.
860
+ * This method has an [older, compatible signature][setWebHook-v0.25.0]
861
+ * that is being deprecated.
862
+ *
863
+ * @param {String} url URL where Telegram will make HTTP Post. Leave empty to
864
+ * delete webHook.
865
+ * @param {Object} [options] Additional Telegram query options
866
+ * @param {String|stream.Stream} [options.certificate] PEM certificate key (public).
867
+ * @param {String} [options.secret_token] Optional secret token to be sent in a header `X-Telegram-Bot-Api-Secret-Token` in every webhook request.
868
+ * @param {Object} [fileOptions] Optional file related meta-data
869
+ * @return {Promise}
870
+ * @see https://core.telegram.org/bots/api#setwebhook
871
+ * @see https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#sending-files
872
+ */
873
+ setWebHook(url, options = {}, fileOptions = {}) {
874
+ /* The older method signature was setWebHook(url, cert).
875
+ * We need to ensure backwards-compatibility while maintaining
876
+ * consistency of the method signatures throughout the library */
877
+ let cert;
878
+ // Note: 'options' could be an object, if a stream was provided (in place of 'cert')
879
+ if (typeof options !== 'object' || options instanceof stream.Stream) {
880
+ deprecate('The method signature setWebHook(url, cert) has been deprecated since v0.25.0');
881
+ cert = options;
882
+ options = {}; // eslint-disable-line no-param-reassign
883
+ } else {
884
+ cert = options.certificate;
885
+ }
886
+
887
+ const opts = {
888
+ qs: options,
889
+ };
890
+ opts.qs.url = url;
891
+
892
+ if (cert) {
893
+ try {
894
+ const sendData = this._formatSendData('certificate', cert, fileOptions);
895
+ opts.formData = sendData[0];
896
+ opts.qs.certificate = sendData[1];
897
+ } catch (ex) {
898
+ return Promise.reject(ex);
899
+ }
900
+ }
901
+
902
+ return this._request('setWebHook', opts);
903
+ }
904
+
905
+ /**
906
+ * Use this method to remove webhook integration if you decide to
907
+ * switch back to getUpdates. Returns True on success.
908
+ * @param {Object} [options] Additional Telegram query options
909
+ * @return {Promise}
910
+ * @see https://core.telegram.org/bots/api#deletewebhook
911
+ */
912
+ deleteWebHook(form = {}) {
913
+ return this._request('deleteWebhook', { form });
914
+ }
915
+
916
+ /**
917
+ * Use this method to get current webhook status.
918
+ * On success, returns a [WebhookInfo](https://core.telegram.org/bots/api#webhookinfo) object.
919
+ * If the bot is using getUpdates, will return an object with the
920
+ * url field empty.
921
+ * @param {Object} [options] Additional Telegram query options
922
+ * @return {Promise}
923
+ * @see https://core.telegram.org/bots/api#getwebhookinfo
924
+ */
925
+ getWebHookInfo(form = {}) {
926
+ return this._request('getWebhookInfo', { form });
927
+ }
928
+
929
+ /**
930
+ * A simple method for testing your bot's authentication token. Requires no parameters.
931
+ *
932
+ * @param {Object} [options] Additional Telegram query options
933
+ * @return {Promise} basic information about the bot in form of a [User](https://core.telegram.org/bots/api#user) object.
934
+ * @see https://core.telegram.org/bots/api#getme
935
+ */
936
+ getMe(form = {}) {
937
+ return this._request('getMe', { form });
938
+ }
939
+
940
+ /**
941
+ * This method log out your bot from the cloud Bot API server before launching the bot locally.
942
+ * You must log out the bot before running it locally, otherwise there is no guarantee that the bot will receive updates.
943
+ * After a successful call, you will not be able to log in again using the same token for 10 minutes.
944
+ *
945
+ * @param {Object} [options] Additional Telegram query options
946
+ * @return {Promise} True on success
947
+ * @see https://core.telegram.org/bots/api#logout
948
+ */
949
+ logOut(form = {}) {
950
+ return this._request('logOut', { form });
951
+ }
952
+
953
+ /**
954
+ * This method close the bot instance before moving it from one local server to another.
955
+ * This method will return error 429 in the first 10 minutes after the bot is launched.
956
+ *
957
+ * @param {Object} [options] Additional Telegram query options
958
+ * @return {Promise} True on success
959
+ * @see https://core.telegram.org/bots/api#close
960
+ */
961
+ close(form = {}) {
962
+ return this._request('close', { form });
963
+ }
964
+
965
+ /**
966
+ * Send text message.
967
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
968
+ * @param {String} text Text of the message to be sent
969
+ * @param {Object} [options] Additional Telegram query options
970
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
971
+ * @see https://core.telegram.org/bots/api#sendmessage
972
+ */
973
+ sendMessage(chatId, text, form = {}) {
974
+ form.chat_id = chatId;
975
+ form.text = text;
976
+ return this._request('sendMessage', { form });
977
+ }
978
+
979
+ /**
980
+ * Forward messages of any kind.
981
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
982
+ * or username of the target channel (in the format `@channelusername`)
983
+ * @param {Number|String} fromChatId Unique identifier for the chat where the
984
+ * original message was sent (or channel username in the format `@channelusername`)
985
+ * @param {Number|String} messageId Unique message identifier in the chat specified in fromChatId
986
+ * @param {Object} [options] Additional Telegram query options
987
+ * @return {Promise}
988
+ * @see https://core.telegram.org/bots/api#forwardmessage
989
+ */
990
+ forwardMessage(chatId, fromChatId, messageId, form = {}) {
991
+ form.chat_id = chatId;
992
+ form.from_chat_id = fromChatId;
993
+ form.message_id = messageId;
994
+ return this._request('forwardMessage', { form });
995
+ }
996
+
997
+ /**
998
+ * Use this method to forward multiple messages of any kind.
999
+ * If some of the specified messages can't be found or forwarded, they are skipped.
1000
+ *
1001
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1002
+ * or username of the target channel (in the format `@channelusername`)
1003
+ * @param {Number|String} fromChatId Unique identifier for the chat where the
1004
+ * original message was sent (or channel username in the format `@channelusername`)
1005
+ * @param {Array<Number|String>} messageIds Identifiers of 1-100 messages in the chat from_chat_id to forward.
1006
+ * The identifiers must be specified in a strictly increasing order.
1007
+ * @param {Object} [options] Additional Telegram query options
1008
+ * @return {Promise} An array of MessageId of the sent messages on success
1009
+ * @see https://core.telegram.org/bots/api#forwardmessages
1010
+ */
1011
+ forwardMessages(chatId, fromChatId, messageIds, form = {}) {
1012
+ form.chat_id = chatId;
1013
+ form.from_chat_id = fromChatId;
1014
+ form.message_ids = messageIds;
1015
+ return this._request('forwardMessages', { form });
1016
+ }
1017
+
1018
+ /**
1019
+ * Copy messages of any kind. **Service messages and invoice messages can't be copied.**
1020
+ * The method is analogous to the method forwardMessages, but the copied message doesn't
1021
+ * have a link to the original message.
1022
+ * Returns the MessageId of the sent message on success.
1023
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1024
+ * @param {Number|String} fromChatId Unique identifier for the chat where the
1025
+ * original message was sent
1026
+ * @param {Number|String} messageId Unique message identifier
1027
+ * @param {Object} [options] Additional Telegram query options
1028
+ * @return {Promise} The [MessageId](https://core.telegram.org/bots/api#messageid) of the sent message on success
1029
+ * @see https://core.telegram.org/bots/api#copymessage
1030
+ */
1031
+ copyMessage(chatId, fromChatId, messageId, form = {}) {
1032
+ form.chat_id = chatId;
1033
+ form.from_chat_id = fromChatId;
1034
+ form.message_id = messageId;
1035
+ return this._request('copyMessage', { form });
1036
+ }
1037
+
1038
+ /**
1039
+ * Use this method to copy messages of any kind. If some of the specified messages can't be found or copied, they are skipped.
1040
+ * Service messages, giveaway messages, giveaway winners messages, and invoice messages can't be copied.
1041
+ * Returns the MessageId of the sent message on success.
1042
+ * @param {Number|String} chatId Unique identifier for the target chat
1043
+ * @param {Number|String} fromChatId Unique identifier for the chat where the
1044
+ * original message was sent
1045
+ * @param {Array} messageIds Identifiers of 1-100 messages in the chat from_chat_id to copy.
1046
+ * The identifiers must be specified in a strictly increasing order.
1047
+ * @param {Object} [options] Additional Telegram query options
1048
+ * @return {Promise} An array of MessageId of the sent messages
1049
+ * @see https://core.telegram.org/bots/api#copymessages
1050
+ */
1051
+ copyMessages(chatId, fromChatId, messageIds, form = {}) {
1052
+ form.chat_id = chatId;
1053
+ form.from_chat_id = fromChatId;
1054
+ form.message_ids = stringify(messageIds);
1055
+ return this._request('copyMessages', { form });
1056
+ }
1057
+
1058
+ /**
1059
+ * Send photo
1060
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1061
+ * @param {String|stream.Stream|Buffer} photo A file path or a Stream. Can
1062
+ * also be a `file_id` previously uploaded
1063
+ * @param {Object} [options] Additional Telegram query options
1064
+ * @param {Object} [fileOptions] Optional file related meta-data
1065
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1066
+ * @see https://core.telegram.org/bots/api#sendphoto
1067
+ * @see https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#sending-files
1068
+ */
1069
+ sendPhoto(chatId, photo, options = {}, fileOptions = {}) {
1070
+ const opts = {
1071
+ qs: options,
1072
+ };
1073
+ opts.qs.chat_id = chatId;
1074
+ try {
1075
+ const sendData = this._formatSendData('photo', photo, fileOptions);
1076
+ opts.formData = sendData[0];
1077
+ opts.qs.photo = sendData[1];
1078
+ } catch (ex) {
1079
+ return Promise.reject(ex);
1080
+ }
1081
+ return this._request('sendPhoto', opts);
1082
+ }
1083
+
1084
+ /**
1085
+ * Send audio
1086
+ *
1087
+ * **Your audio must be in the .MP3 or .M4A format.**
1088
+ *
1089
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1090
+ * @param {String|stream.Stream|Buffer} audio A file path, Stream or Buffer.
1091
+ * Can also be a `file_id` previously uploaded.
1092
+ * @param {Object} [options] Additional Telegram query options
1093
+ * @param {Object} [fileOptions] Optional file related meta-data
1094
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1095
+ * @see https://core.telegram.org/bots/api#sendaudio
1096
+ * @see https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#sending-files
1097
+ */
1098
+ sendAudio(chatId, audio, options = {}, fileOptions = {}) {
1099
+ const opts = {
1100
+ qs: options
1101
+ };
1102
+
1103
+ opts.qs.chat_id = chatId;
1104
+
1105
+ try {
1106
+ const sendData = this._formatSendData('audio', audio, fileOptions);
1107
+ opts.formData = sendData[0];
1108
+ opts.qs.audio = sendData[1];
1109
+ this._fixAddFileThumbnail(options, opts);
1110
+ } catch (ex) {
1111
+ return Promise.reject(ex);
1112
+ }
1113
+
1114
+ return this._request('sendAudio', opts);
1115
+ }
1116
+
1117
+ /**
1118
+ * Send Document
1119
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1120
+ * @param {String|stream.Stream|Buffer} doc A file path, Stream or Buffer.
1121
+ * Can also be a `file_id` previously uploaded.
1122
+ * @param {Object} [options] Additional Telegram query options
1123
+ * @param {Object} [fileOptions] Optional file related meta-data
1124
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1125
+ * @see https://core.telegram.org/bots/api#sendDocument
1126
+ * @see https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#sending-files
1127
+ */
1128
+ sendDocument(chatId, doc, options = {}, fileOptions = {}) {
1129
+ const opts = {
1130
+ qs: options
1131
+ };
1132
+ opts.qs.chat_id = chatId;
1133
+ try {
1134
+ const sendData = this._formatSendData('document', doc, fileOptions);
1135
+ opts.formData = sendData[0];
1136
+ opts.qs.document = sendData[1];
1137
+ this._fixAddFileThumbnail(options, opts);
1138
+ } catch (ex) {
1139
+ return Promise.reject(ex);
1140
+ }
1141
+
1142
+ return this._request('sendDocument', opts);
1143
+ }
1144
+
1145
+ /**
1146
+ * Use this method to send video files, **Telegram clients support mp4 videos** (other formats may be sent as Document).
1147
+ *
1148
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1149
+ * @param {String|stream.Stream|Buffer} video A file path or Stream.
1150
+ * Can also be a `file_id` previously uploaded.
1151
+ * @param {Object} [options] Additional Telegram query options
1152
+ * @param {Object} [fileOptions] Optional file related meta-data
1153
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1154
+ * @see https://core.telegram.org/bots/api#sendvideo
1155
+ * @see https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#sending-files
1156
+ */
1157
+ sendVideo(chatId, video, options = {}, fileOptions = {}) {
1158
+ const opts = {
1159
+ qs: options
1160
+ };
1161
+ opts.qs.chat_id = chatId;
1162
+ try {
1163
+ const sendData = this._formatSendData('video', video, fileOptions);
1164
+ opts.formData = sendData[0];
1165
+ opts.qs.video = sendData[1];
1166
+ this._fixAddFileThumbnail(options, opts);
1167
+ } catch (ex) {
1168
+ return Promise.reject(ex);
1169
+ }
1170
+ return this._request('sendVideo', opts);
1171
+ }
1172
+
1173
+ /**
1174
+ * Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound).
1175
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1176
+ * @param {String|stream.Stream|Buffer} animation A file path, Stream or Buffer.
1177
+ * Can also be a `file_id` previously uploaded.
1178
+ * @param {Object} [options] Additional Telegram query options
1179
+ * @param {Object} [fileOptions] Optional file related meta-data
1180
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1181
+ * @see https://core.telegram.org/bots/api#sendanimation
1182
+ * @see https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#sending-files
1183
+ */
1184
+ sendAnimation(chatId, animation, options = {}, fileOptions = {}) {
1185
+ const opts = {
1186
+ qs: options
1187
+ };
1188
+ opts.qs.chat_id = chatId;
1189
+ try {
1190
+ const sendData = this._formatSendData('animation', animation, fileOptions);
1191
+ opts.formData = sendData[0];
1192
+ opts.qs.animation = sendData[1];
1193
+ } catch (ex) {
1194
+ return Promise.reject(ex);
1195
+ }
1196
+ return this._request('sendAnimation', opts);
1197
+ }
1198
+
1199
+ /**
1200
+ * Send voice
1201
+ *
1202
+ * **Your audio must be in an .OGG file encoded with OPUS**, or in .MP3 format, or in .M4A format (other formats may be sent as Audio or Document)
1203
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1204
+ * @param {String|stream.Stream|Buffer} voice A file path, Stream or Buffer.
1205
+ * Can also be a `file_id` previously uploaded.
1206
+ * @param {Object} [options] Additional Telegram query options
1207
+ * @param {Object} [fileOptions] Optional file related meta-data
1208
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1209
+ * @see https://core.telegram.org/bots/api#sendvoice
1210
+ * @see https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#sending-files
1211
+ */
1212
+ sendVoice(chatId, voice, options = {}, fileOptions = {}) {
1213
+ const opts = {
1214
+ qs: options
1215
+ };
1216
+ opts.qs.chat_id = chatId;
1217
+ try {
1218
+ const sendData = this._formatSendData('voice', voice, fileOptions);
1219
+ opts.formData = sendData[0];
1220
+ opts.qs.voice = sendData[1];
1221
+ } catch (ex) {
1222
+ return Promise.reject(ex);
1223
+ }
1224
+ return this._request('sendVoice', opts);
1225
+ }
1226
+
1227
+ /**
1228
+ * Use this method to send video messages
1229
+ * Telegram clients support **rounded square MPEG4 videos** of up to 1 minute long.
1230
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1231
+ * @param {String|stream.Stream|Buffer} videoNote A file path or Stream.
1232
+ * Can also be a `file_id` previously uploaded.
1233
+ * @param {Object} [options] Additional Telegram query options
1234
+ * @param {Object} [fileOptions] Optional file related meta-data
1235
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1236
+ * @info The length parameter is actually optional. However, the API (at time of writing) requires you to always provide it until it is fixed.
1237
+ * @see https://core.telegram.org/bots/api#sendvideonote
1238
+ * @see https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#sending-files
1239
+ */
1240
+ sendVideoNote(chatId, videoNote, options = {}, fileOptions = {}) {
1241
+ const opts = {
1242
+ qs: options
1243
+ };
1244
+ opts.qs.chat_id = chatId;
1245
+ try {
1246
+ const sendData = this._formatSendData('video_note', videoNote, fileOptions);
1247
+ opts.formData = sendData[0];
1248
+ opts.qs.video_note = sendData[1];
1249
+ this._fixAddFileThumbnail(options, opts);
1250
+ } catch (ex) {
1251
+ return Promise.reject(ex);
1252
+ }
1253
+ return this._request('sendVideoNote', opts);
1254
+ }
1255
+
1256
+ /**
1257
+ * Use this method to send a group of photos or videos as an album.
1258
+ *
1259
+ * **Documents and audio files can be only grouped in an album with messages of the same type**
1260
+ *
1261
+ * If you wish to [specify file options](https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#sending-files),
1262
+ * add a `fileOptions` property to the target input in `media`.
1263
+ *
1264
+ * @param {String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1265
+ * @param {Array} media A JSON-serialized array describing photos and videos to be sent, must include 2–10 items
1266
+ * @param {Object} [options] Additional Telegram query options
1267
+ * @return {Promise} On success, an array of the sent [Messages](https://core.telegram.org/bots/api#message)
1268
+ * is returned.
1269
+ * @see https://core.telegram.org/bots/api#sendmediagroup
1270
+ * @see https://github.com/ZeroBot-net/@zero-bot.net/tg-bot-api/blob/master/doc/usage.md#sending-files
1271
+ */
1272
+ sendMediaGroup(chatId, media, options = {}) {
1273
+ const opts = {
1274
+ qs: options,
1275
+ };
1276
+ opts.qs.chat_id = chatId;
1277
+
1278
+ opts.formData = {};
1279
+ const inputMedia = [];
1280
+ let index = 0;
1281
+ for (const input of media) {
1282
+ const payload = Object.assign({}, input);
1283
+ delete payload.media;
1284
+ delete payload.fileOptions;
1285
+ try {
1286
+ const attachName = String(index);
1287
+ const [formData, fileId] = this._formatSendData(attachName, input.media, input.fileOptions);
1288
+ if (formData) {
1289
+ opts.formData[attachName] = formData[attachName];
1290
+ payload.media = `attach://${attachName}`;
1291
+ } else {
1292
+ payload.media = fileId;
1293
+ }
1294
+ } catch (ex) {
1295
+ return Promise.reject(ex);
1296
+ }
1297
+ inputMedia.push(payload);
1298
+ index++;
1299
+ }
1300
+ opts.qs.media = stringify(inputMedia);
1301
+
1302
+ return this._request('sendMediaGroup', opts);
1303
+ }
1304
+
1305
+
1306
+ /**
1307
+ * Send location.
1308
+ * Use this method to send point on the map.
1309
+ *
1310
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1311
+ * @param {Float} latitude Latitude of location
1312
+ * @param {Float} longitude Longitude of location
1313
+ * @param {Object} [options] Additional Telegram query options
1314
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1315
+ * @see https://core.telegram.org/bots/api#sendlocation
1316
+ */
1317
+ sendLocation(chatId, latitude, longitude, form = {}) {
1318
+ form.chat_id = chatId;
1319
+ form.latitude = latitude;
1320
+ form.longitude = longitude;
1321
+ return this._request('sendLocation', { form });
1322
+ }
1323
+
1324
+ /**
1325
+ * Use this method to edit live location messages sent by
1326
+ * the bot or via the bot (for inline bots).
1327
+ *
1328
+ * A location **can be edited until its live_period expires or editing is explicitly disabled by a call to [stopMessageLiveLocation](https://core.telegram.org/bots/api#stopmessagelivelocation)**
1329
+ *
1330
+ * Note that you must provide one of chat_id, message_id, or
1331
+ * inline_message_id in your request.
1332
+ *
1333
+ * @param {Float} latitude Latitude of location
1334
+ * @param {Float} longitude Longitude of location
1335
+ * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here)
1336
+ * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned.
1337
+ * @see https://core.telegram.org/bots/api#editmessagelivelocation
1338
+ */
1339
+ editMessageLiveLocation(latitude, longitude, form = {}) {
1340
+ form.latitude = latitude;
1341
+ form.longitude = longitude;
1342
+ return this._request('editMessageLiveLocation', { form });
1343
+ }
1344
+
1345
+ /**
1346
+ * Use this method to stop updating a live location message sent by
1347
+ * the bot or via the bot (for inline bots) before live_period expires.
1348
+ *
1349
+ * Note that you must provide one of chat_id, message_id, or
1350
+ * inline_message_id in your request.
1351
+ *
1352
+ * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here)
1353
+ * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned.
1354
+ * @see https://core.telegram.org/bots/api#stopmessagelivelocation
1355
+ */
1356
+ stopMessageLiveLocation(form = {}) {
1357
+ return this._request('stopMessageLiveLocation', { form });
1358
+ }
1359
+
1360
+ /**
1361
+ * Send venue.
1362
+ * Use this method to send information about a venue.
1363
+ *
1364
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1365
+ * @param {Float} latitude Latitude of location
1366
+ * @param {Float} longitude Longitude of location
1367
+ * @param {String} title Name of the venue
1368
+ * @param {String} address Address of the venue
1369
+ * @param {Object} [options] Additional Telegram query options
1370
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned.
1371
+ * @see https://core.telegram.org/bots/api#sendvenue
1372
+ */
1373
+ sendVenue(chatId, latitude, longitude, title, address, form = {}) {
1374
+ form.chat_id = chatId;
1375
+ form.latitude = latitude;
1376
+ form.longitude = longitude;
1377
+ form.title = title;
1378
+ form.address = address;
1379
+ return this._request('sendVenue', { form });
1380
+ }
1381
+
1382
+ /**
1383
+ * Send contact.
1384
+ * Use this method to send phone contacts.
1385
+ *
1386
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1387
+ * @param {String} phoneNumber Contact's phone number
1388
+ * @param {String} firstName Contact's first name
1389
+ * @param {Object} [options] Additional Telegram query options
1390
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1391
+ * @see https://core.telegram.org/bots/api#sendcontact
1392
+ */
1393
+ sendContact(chatId, phoneNumber, firstName, form = {}) {
1394
+ form.chat_id = chatId;
1395
+ form.phone_number = phoneNumber;
1396
+ form.first_name = firstName;
1397
+ return this._request('sendContact', { form });
1398
+ }
1399
+
1400
+ /**
1401
+ * Send poll.
1402
+ * Use this method to send a native poll.
1403
+ *
1404
+ * @param {Number|String} chatId Unique identifier for the group/channel
1405
+ * @param {String} question Poll question, 1-300 characters
1406
+ * @param {Array} pollOptions Poll options, between 2-10 options (only 1-100 characters each)
1407
+ * @param {Object} [options] Additional Telegram query options
1408
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1409
+ * @see https://core.telegram.org/bots/api#sendpoll
1410
+ */
1411
+ sendPoll(chatId, question, pollOptions, form = {}) {
1412
+ form.chat_id = chatId;
1413
+ form.question = question;
1414
+ form.options = stringify(pollOptions);
1415
+ return this._request('sendPoll', { form });
1416
+ }
1417
+
1418
+ /**
1419
+ * Send Dice
1420
+ * Use this method to send an animated emoji that will display a random value.
1421
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1422
+ * @param {Object} [options] Additional Telegram query options
1423
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned
1424
+ * @see https://core.telegram.org/bots/api#senddice
1425
+ */
1426
+ sendDice(chatId, options = {}) {
1427
+ const opts = {
1428
+ qs: options,
1429
+ };
1430
+ opts.qs.chat_id = chatId;
1431
+ try {
1432
+ const sendData = this._formatSendData('dice');
1433
+ opts.formData = sendData[0];
1434
+ } catch (ex) {
1435
+ return Promise.reject(ex);
1436
+ }
1437
+ return this._request('sendDice', opts);
1438
+ }
1439
+
1440
+
1441
+ /**
1442
+ * Send chat action.
1443
+ *
1444
+ * Use this method when you need to tell the user that something is happening on the bot's side.
1445
+ * **The status is set for 5 seconds or less** (when a message arrives from your bot, Telegram clients clear its typing status).
1446
+ *
1447
+ * Action `typing` for [text messages](https://core.telegram.org/bots/api#sendmessage),
1448
+ * `upload_photo` for [photos](https://core.telegram.org/bots/api#sendphoto), `record_video` or `upload_video` for [videos](https://core.telegram.org/bots/api#sendvideo),
1449
+ * `record_voice` or `upload_voice` for [voice notes](https://core.telegram.org/bots/api#sendvoice), `upload_document` for [general files](https://core.telegram.org/bots/api#senddocument),
1450
+ * `choose_sticker` for [stickers](https://core.telegram.org/bots/api#sendsticker), `find_location` for [location data](https://core.telegram.org/bots/api#sendlocation),
1451
+ * `record_video_note` or `upload_video_note` for [video notes](https://core.telegram.org/bots/api#sendvideonote).
1452
+ *
1453
+ *
1454
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1455
+ * @param {String} action Type of action to broadcast.
1456
+ * @param {Object} [options] Additional Telegram query options
1457
+ * @return {Promise} True on success
1458
+ * @see https://core.telegram.org/bots/api#sendchataction
1459
+ */
1460
+ sendChatAction(chatId, action, form = {}) {
1461
+ form.chat_id = chatId;
1462
+ form.action = action;
1463
+ return this._request('sendChatAction', { form });
1464
+ }
1465
+
1466
+ /**
1467
+ * Use this method to change the chosen reactions on a message.
1468
+ * - Service messages can't be reacted to.
1469
+ * - Automatically forwarded messages from a channel to its discussion group have the same available reactions as messages in the channel.
1470
+ * - In albums, bots must react to the first message.
1471
+ *
1472
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format @channelusername)
1473
+ * @param {Number} messageId Unique identifier of the target message
1474
+ * @param {Object} [options] Additional Telegram query options
1475
+ * @return {Promise<Boolean>} True on success
1476
+ * @see https://core.telegram.org/bots/api#setmessagereaction
1477
+ */
1478
+ setMessageReaction(chatId, messageId, form = {}) {
1479
+ form.chat_id = chatId;
1480
+ form.message_id = messageId;
1481
+ if (form.reaction) {
1482
+ form.reaction = stringify(form.reaction);
1483
+ }
1484
+ return this._request('setMessageReaction', { form });
1485
+ }
1486
+
1487
+ /**
1488
+ * Use this method to get a list of profile pictures for a user.
1489
+ * Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephotos) object.
1490
+ * This method has an [older, compatible signature][getUserProfilePhotos-v0.25.0]
1491
+ * that is being deprecated.
1492
+ *
1493
+ * @param {Number} userId Unique identifier of the target user
1494
+ * @param {Object} [options] Additional Telegram query options
1495
+ * @return {Promise} Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephotos) object
1496
+ * @see https://core.telegram.org/bots/api#getuserprofilephotos
1497
+ */
1498
+ getUserProfilePhotos(userId, form = {}) {
1499
+ /* The older method signature was getUserProfilePhotos(userId, offset, limit).
1500
+ * We need to ensure backwards-compatibility while maintaining
1501
+ * consistency of the method signatures throughout the library */
1502
+ if (typeof form !== 'object') {
1503
+ /* eslint-disable no-param-reassign, prefer-rest-params */
1504
+ deprecate('The method signature getUserProfilePhotos(userId, offset, limit) has been deprecated since v0.25.0');
1505
+ form = {
1506
+ offset: arguments[1],
1507
+ limit: arguments[2],
1508
+ };
1509
+ /* eslint-enable no-param-reassign, prefer-rest-params */
1510
+ }
1511
+ form.user_id = userId;
1512
+ return this._request('getUserProfilePhotos', { form });
1513
+ }
1514
+
1515
+ /**
1516
+ * Get file.
1517
+ * Use this method to get basic info about a file and prepare it for downloading.
1518
+ *
1519
+ * Attention: **link will be valid for 1 hour.**
1520
+ *
1521
+ * @param {String} fileId File identifier to get info about
1522
+ * @param {Object} [options] Additional Telegram query options
1523
+ * @return {Promise} On success, a [File](https://core.telegram.org/bots/api#file) object is returned
1524
+ * @see https://core.telegram.org/bots/api#getfile
1525
+ */
1526
+ getFile(fileId, form = {}) {
1527
+ form.file_id = fileId;
1528
+ return this._request('getFile', { form });
1529
+ }
1530
+
1531
+ /**
1532
+ * Use this method to ban a user in a group, a supergroup or a channel.
1533
+ * In the case of supergroups and channels, the user will not be able to
1534
+ * return to the chat on their own using invite links, etc., unless unbanned first..
1535
+ *
1536
+ * The **bot must be an administrator in the group, supergroup or a channel** for this to work.
1537
+ *
1538
+ *
1539
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1540
+ * @param {Number} userId Unique identifier of the target user
1541
+ * @param {Object} [options] Additional Telegram query options
1542
+ * @return {Promise} True on success.
1543
+ * @see https://core.telegram.org/bots/api#banchatmember
1544
+ */
1545
+ banChatMember(chatId, userId, form = {}) {
1546
+ form.chat_id = chatId;
1547
+ form.user_id = userId;
1548
+ return this._request('banChatMember', { form });
1549
+ }
1550
+
1551
+ /**
1552
+ * Use this method to unban a previously kicked user in a supergroup.
1553
+ * The user will not return to the group automatically, but will be
1554
+ * able to join via link, etc.
1555
+ *
1556
+ * The **bot must be an administrator** in the supergroup or channel for this to work.
1557
+ *
1558
+ * **By default**, this method guarantees that after the call the user is not a member of the chat, but will be able to join it.
1559
+ * So **if the user is a member of the chat they will also be removed from the chat**. If you don't want this, use the parameter *only_if_banned*
1560
+ *
1561
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1562
+ * @param {Number} userId Unique identifier of the target user
1563
+ * @param {Object} [options] Additional Telegram query options
1564
+ * @return {Promise} True on success
1565
+ * @see https://core.telegram.org/bots/api#unbanchatmember
1566
+ */
1567
+ unbanChatMember(chatId, userId, form = {}) {
1568
+ form.chat_id = chatId;
1569
+ form.user_id = userId;
1570
+ return this._request('unbanChatMember', { form });
1571
+ }
1572
+
1573
+ /**
1574
+ * Use this method to restrict a user in a supergroup.
1575
+ * The bot **must be an administrator in the supergroup** for this to work
1576
+ * and must have the appropriate admin rights. Pass True for all boolean parameters
1577
+ * to lift restrictions from a user. Returns True on success.
1578
+ *
1579
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1580
+ * @param {Number} userId Unique identifier of the target user
1581
+ * @param {Object} [options] Additional Telegram query options
1582
+ * @return {Promise} True on success
1583
+ * @see https://core.telegram.org/bots/api#restrictchatmember
1584
+ */
1585
+ restrictChatMember(chatId, userId, form = {}) {
1586
+ form.chat_id = chatId;
1587
+ form.user_id = userId;
1588
+ return this._request('restrictChatMember', { form });
1589
+ }
1590
+
1591
+ /**
1592
+ * Use this method to promote or demote a user in a supergroup or a channel.
1593
+ * The bot **must be an administrator** in the chat for this to work
1594
+ * and must have the appropriate admin rights. Pass False for all boolean parameters to demote a user.
1595
+ *
1596
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1597
+ * @param {Number} userId
1598
+ * @param {Object} [options] Additional Telegram query options
1599
+ * @return {Promise} True on success.
1600
+ * @see https://core.telegram.org/bots/api#promotechatmember
1601
+ */
1602
+ promoteChatMember(chatId, userId, form = {}) {
1603
+ form.chat_id = chatId;
1604
+ form.user_id = userId;
1605
+ return this._request('promoteChatMember', { form });
1606
+ }
1607
+
1608
+ /**
1609
+ * Use this method to set a custom title for an administrator in a supergroup promoted by the bot.
1610
+ *
1611
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1612
+ * @param {Number} userId Unique identifier of the target user
1613
+ * @param {String} customTitle New custom title for the administrator; 0-16 characters, emoji are not allowed
1614
+ * @param {Object} [options] Additional Telegram query options
1615
+ * @return {Promise} True on success
1616
+ * @see https://core.telegram.org/bots/api#setchatadministratorcustomtitle
1617
+ */
1618
+ setChatAdministratorCustomTitle(chatId, userId, customTitle, form = {}) {
1619
+ form.chat_id = chatId;
1620
+ form.user_id = userId;
1621
+ form.custom_title = customTitle;
1622
+ return this._request('setChatAdministratorCustomTitle', { form });
1623
+ }
1624
+
1625
+
1626
+ /**
1627
+ * Use this method to ban a channel chat in a supergroup or a channel.
1628
+ *
1629
+ * Until the chat is [unbanned](https://core.telegram.org/bots/api#unbanchatsenderchat), the owner of the banned chat won't be able to send messages on behalf of any of their channels.
1630
+ * The bot **must be an administrator in the supergroup or channel** for this to work and must have the appropriate administrator rights
1631
+ *
1632
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1633
+ * @param {Number} senderChatId Unique identifier of the target user
1634
+ * @param {Object} [options] Additional Telegram query options
1635
+ * @return {Promise} True on success.
1636
+ * @see https://core.telegram.org/bots/api#banchatsenderchat
1637
+ */
1638
+ banChatSenderChat(chatId, senderChatId, form = {}) {
1639
+ form.chat_id = chatId;
1640
+ form.sender_chat_id = senderChatId;
1641
+ return this._request('banChatSenderChat', { form });
1642
+ }
1643
+
1644
+ /**
1645
+ * Use this method to unban a previously banned channel chat in a supergroup or channel.
1646
+ *
1647
+ * The bot **must be an administrator** for this to work and must have the appropriate administrator rights.
1648
+ *
1649
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1650
+ * @param {Number} senderChatId Unique identifier of the target user
1651
+ * @param {Object} [options] Additional Telegram query options
1652
+ * @return {Promise} True on success
1653
+ * @see https://core.telegram.org/bots/api#unbanchatsenderchat
1654
+ */
1655
+ unbanChatSenderChat(chatId, senderChatId, form = {}) {
1656
+ form.chat_id = chatId;
1657
+ form.sender_chat_id = senderChatId;
1658
+ return this._request('unbanChatSenderChat', { form });
1659
+ }
1660
+
1661
+ /**
1662
+ * Use this method to set default chat permissions for all members.
1663
+ *
1664
+ * The bot **must be an administrator in the group or a supergroup** for this to
1665
+ * work and **must have the `can_restrict_members` admin rights.**
1666
+ *
1667
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1668
+ * @param {Array} chatPermissions New default chat permissions
1669
+ * @param {Object} [options] Additional Telegram query options
1670
+ * @return {Promise} True on success
1671
+ * @see https://core.telegram.org/bots/api#setchatpermissions
1672
+ */
1673
+ setChatPermissions(chatId, chatPermissions, form = {}) {
1674
+ form.chat_id = chatId;
1675
+ form.permissions = stringify(chatPermissions);
1676
+ return this._request('setChatPermissions', { form });
1677
+ }
1678
+
1679
+ /**
1680
+ * Use this method to generate a new primary invite link for a chat. **Any previously generated primary link is revoked**.
1681
+ *
1682
+ * The bot **must be an administrator in the chat** for this to work and must have the appropriate administrator rights.
1683
+ *
1684
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1685
+ * @param {Object} [options] Additional Telegram query options
1686
+ * @return {Promise} Exported invite link as String on success.
1687
+ * @see https://core.telegram.org/bots/api#exportchatinvitelink
1688
+ */
1689
+ exportChatInviteLink(chatId, form = {}) {
1690
+ form.chat_id = chatId;
1691
+ return this._request('exportChatInviteLink', { form });
1692
+ }
1693
+
1694
+ /**
1695
+ * Use this method to create an additional invite link for a chat.
1696
+ *
1697
+ * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights.
1698
+ *
1699
+ * The link generated with this method can be revoked using the method [revokeChatInviteLink](https://core.telegram.org/bots/api#revokechatinvitelink)
1700
+ *
1701
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1702
+ * @param {Object} [options] Additional Telegram query options
1703
+ * @return {Object} The new invite link as [ChatInviteLink](https://core.telegram.org/bots/api#chatinvitelink) object
1704
+ * @see https://core.telegram.org/bots/api#createchatinvitelink
1705
+ */
1706
+ createChatInviteLink(chatId, form = {}) {
1707
+ form.chat_id = chatId;
1708
+ return this._request('createChatInviteLink', { form });
1709
+ }
1710
+
1711
+ /**
1712
+ * Use this method to edit a non-primary invite link created by the bot.
1713
+ *
1714
+ * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights.
1715
+ *
1716
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1717
+ * @param {String} inviteLink Text with the invite link to edit
1718
+ * @param {Object} [options] Additional Telegram query options
1719
+ * @return {Promise} The edited invite link as a [ChatInviteLink](https://core.telegram.org/bots/api#chatinvitelink) object
1720
+ * @see https://core.telegram.org/bots/api#editchatinvitelink
1721
+ */
1722
+ editChatInviteLink(chatId, inviteLink, form = {}) {
1723
+ form.chat_id = chatId;
1724
+ form.invite_link = inviteLink;
1725
+ return this._request('editChatInviteLink', { form });
1726
+ }
1727
+
1728
+ /**
1729
+ * Use this method to revoke an invite link created by the bot.
1730
+ * Note: If the primary link is revoked, a new link is automatically generated
1731
+ *
1732
+ * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights.
1733
+ *
1734
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1735
+ * @param {String} inviteLink The invite link to revoke
1736
+ * @param {Object} [options] Additional Telegram query options
1737
+ * @return {Promise} The revoked invite link as [ChatInviteLink](https://core.telegram.org/bots/api#chatinvitelink) object
1738
+ * @see https://core.telegram.org/bots/api#revokechatinvitelink
1739
+ */
1740
+ revokeChatInviteLink(chatId, inviteLink, form = {}) {
1741
+ form.chat_id = chatId;
1742
+ form.invite_link = inviteLink;
1743
+ return this._request('revokeChatInviteLink', { form });
1744
+ }
1745
+
1746
+ /**
1747
+ * Use this method to approve a chat join request.
1748
+ *
1749
+ * The bot **must be an administrator in the chat** for this to work and **must have the `can_invite_users` administrator right.**
1750
+ *
1751
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1752
+ * @param {Number} userId Unique identifier of the target user
1753
+ * @param {Object} [options] Additional Telegram query options
1754
+ * @return {Promise} True on success
1755
+ * @see https://core.telegram.org/bots/api#approvechatjoinrequest
1756
+ */
1757
+ approveChatJoinRequest(chatId, userId, form = {}) {
1758
+ form.chat_id = chatId;
1759
+ form.user_id = userId;
1760
+ return this._request('approveChatJoinRequest', { form });
1761
+ }
1762
+
1763
+ /**
1764
+ * Use this method to decline a chat join request.
1765
+ *
1766
+ * The bot **must be an administrator in the chat** for this to work and **must have the `can_invite_users` administrator right**.
1767
+ *
1768
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1769
+ * @param {Number} userId Unique identifier of the target user
1770
+ * @param {Object} [options] Additional Telegram query options
1771
+ * @return {Promise} True on success
1772
+ * @see https://core.telegram.org/bots/api#declinechatjoinrequest
1773
+ */
1774
+ declineChatJoinRequest(chatId, userId, form = {}) {
1775
+ form.chat_id = chatId;
1776
+ form.user_id = userId;
1777
+ return this._request('declineChatJoinRequest', { form });
1778
+ }
1779
+
1780
+ /**
1781
+ * Use this method to set a new profile photo for the chat. **Photos can't be changed for private chats**.
1782
+ *
1783
+ * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights.
1784
+ *
1785
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1786
+ * @param {stream.Stream|Buffer} photo A file path or a Stream.
1787
+ * @param {Object} [options] Additional Telegram query options
1788
+ * @param {Object} [fileOptions] Optional file related meta-data
1789
+ * @return {Promise} True on success
1790
+ * @see https://core.telegram.org/bots/api#setchatphoto
1791
+ */
1792
+ setChatPhoto(chatId, photo, options = {}, fileOptions = {}) {
1793
+ const opts = {
1794
+ qs: options,
1795
+ };
1796
+ opts.qs.chat_id = chatId;
1797
+ try {
1798
+ const sendData = this._formatSendData('photo', photo, fileOptions);
1799
+ opts.formData = sendData[0];
1800
+ opts.qs.photo = sendData[1];
1801
+ } catch (ex) {
1802
+ return Promise.reject(ex);
1803
+ }
1804
+ return this._request('setChatPhoto', opts);
1805
+ }
1806
+
1807
+ /**
1808
+ * Use this method to delete a chat photo. **Photos can't be changed for private chats**.
1809
+ *
1810
+ * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights.
1811
+ *
1812
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1813
+ * @param {Object} [options] Additional Telegram query options
1814
+ * @return {Promise} True on success
1815
+ * @see https://core.telegram.org/bots/api#deletechatphoto
1816
+ */
1817
+ deleteChatPhoto(chatId, form = {}) {
1818
+ form.chat_id = chatId;
1819
+ return this._request('deleteChatPhoto', { form });
1820
+ }
1821
+
1822
+ /**
1823
+ * Use this method to change the title of a chat. **Titles can't be changed for private chats**.
1824
+ *
1825
+ * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights.
1826
+ *
1827
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1828
+ * @param {String} title New chat title, 1-255 characters
1829
+ * @param {Object} [options] Additional Telegram query options
1830
+ * @return {Promise} True on success
1831
+ * @see https://core.telegram.org/bots/api#setchattitle
1832
+ */
1833
+ setChatTitle(chatId, title, form = {}) {
1834
+ form.chat_id = chatId;
1835
+ form.title = title;
1836
+ return this._request('setChatTitle', { form });
1837
+ }
1838
+
1839
+ /**
1840
+ * Use this method to change the description of a group, a supergroup or a channel.
1841
+ *
1842
+ * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights.
1843
+ *
1844
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1845
+ * @param {String} description New chat title, 0-255 characters
1846
+ * @param {Object} [options] Additional Telegram query options
1847
+ * @return {Promise} True on success
1848
+ * @see https://core.telegram.org/bots/api#setchatdescription
1849
+ */
1850
+ setChatDescription(chatId, description, form = {}) {
1851
+ form.chat_id = chatId;
1852
+ form.description = description;
1853
+ return this._request('setChatDescription', { form });
1854
+ }
1855
+
1856
+ /**
1857
+ * Use this method to pin a message in a supergroup.
1858
+ *
1859
+ * If the chat is not a private chat, the **bot must be an administrator in the chat** for this to work and must have the `can_pin_messages` administrator
1860
+ * right in a supergroup or `can_edit_messages` administrator right in a channel.
1861
+ *
1862
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1863
+ * @param {Number} messageId Identifier of a message to pin
1864
+ * @param {Object} [options] Additional Telegram query options
1865
+ * @return {Promise} True on success
1866
+ * @see https://core.telegram.org/bots/api#pinchatmessage
1867
+ */
1868
+ pinChatMessage(chatId, messageId, form = {}) {
1869
+ form.chat_id = chatId;
1870
+ form.message_id = messageId;
1871
+ return this._request('pinChatMessage', { form });
1872
+ }
1873
+
1874
+ /**
1875
+ * Use this method to remove a message from the list of pinned messages in a chat
1876
+ *
1877
+ * If the chat is not a private chat, the **bot must be an administrator in the chat** for this to work and must have the `can_pin_messages` administrator
1878
+ * right in a supergroup or `can_edit_messages` administrator right in a channel.
1879
+ *
1880
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1881
+ * @param {Object} [options] Additional Telegram query options
1882
+ * @return {Promise} True on success
1883
+ * @see https://core.telegram.org/bots/api#unpinchatmessage
1884
+ */
1885
+ unpinChatMessage(chatId, form = {}) {
1886
+ form.chat_id = chatId;
1887
+ return this._request('unpinChatMessage', { form });
1888
+ }
1889
+
1890
+ /**
1891
+ * Use this method to clear the list of pinned messages in a chat.
1892
+ *
1893
+ * If the chat is not a private chat, the **bot must be an administrator in the chat** for this to work and must have the `can_pin_messages` administrator
1894
+ * right in a supergroup or `can_edit_messages` administrator right in a channel.
1895
+ *
1896
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1897
+ * @param {Object} [options] Additional Telegram query options
1898
+ * @return {Promise} True on success
1899
+ * @see https://core.telegram.org/bots/api#unpinallchatmessages
1900
+ */
1901
+ unpinAllChatMessages(chatId, form = {}) {
1902
+ form.chat_id = chatId;
1903
+ return this._request('unpinAllChatMessages', { form });
1904
+ }
1905
+
1906
+ /**
1907
+ * Use this method for your bot to leave a group, supergroup or channel
1908
+ *
1909
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1910
+ * @param {Object} [options] Additional Telegram query options
1911
+ * @return {Promise} True on success
1912
+ * @see https://core.telegram.org/bots/api#leavechat
1913
+ */
1914
+ leaveChat(chatId, form = {}) {
1915
+ form.chat_id = chatId;
1916
+ return this._request('leaveChat', { form });
1917
+ }
1918
+
1919
+ /**
1920
+ * Use this method to get up to date information about the chat
1921
+ * (current name of the user for one-on-one conversations, current
1922
+ * username of a user, group or channel, etc.).
1923
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) or channel
1924
+ * @param {Object} [options] Additional Telegram query options
1925
+ * @return {Promise} [ChatFullInfo](https://core.telegram.org/bots/api#chatfullinfo) object on success
1926
+ * @see https://core.telegram.org/bots/api#getchat
1927
+ */
1928
+ getChat(chatId, form = {}) {
1929
+ form.chat_id = chatId;
1930
+ return this._request('getChat', { form });
1931
+ }
1932
+
1933
+ /**
1934
+ * Use this method to get a list of administrators in a chat
1935
+ *
1936
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup
1937
+ * @param {Object} [options] Additional Telegram query options
1938
+ * @return {Promise} On success, returns an Array of [ChatMember](https://core.telegram.org/bots/api#chatmember) objects that contains information about all chat administrators except other bots.
1939
+ * If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned
1940
+ * @see https://core.telegram.org/bots/api#getchatadministrators
1941
+ */
1942
+ getChatAdministrators(chatId, form = {}) {
1943
+ form.chat_id = chatId;
1944
+ return this._request('getChatAdministrators', { form });
1945
+ }
1946
+
1947
+ /**
1948
+ * Use this method to get the number of members in a chat.
1949
+ *
1950
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup
1951
+ * @param {Object} [options] Additional Telegram query options
1952
+ * @return {Promise} Int on success
1953
+ * @see https://core.telegram.org/bots/api#getchatmembercount
1954
+ */
1955
+ getChatMemberCount(chatId, form = {}) {
1956
+ form.chat_id = chatId;
1957
+ return this._request('getChatMemberCount', { form });
1958
+ }
1959
+
1960
+ /**
1961
+ * Use this method to get information about a member of a chat.
1962
+ *
1963
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup
1964
+ * @param {Number} userId Unique identifier of the target user
1965
+ * @param {Object} [options] Additional Telegram query options
1966
+ * @return {Promise} [ChatMember](https://core.telegram.org/bots/api#chatmember) object on success
1967
+ * @see https://core.telegram.org/bots/api#getchatmember
1968
+ */
1969
+ getChatMember(chatId, userId, form = {}) {
1970
+ form.chat_id = chatId;
1971
+ form.user_id = userId;
1972
+ return this._request('getChatMember', { form });
1973
+ }
1974
+
1975
+ /**
1976
+ * Use this method to set a new group sticker set for a supergroup.
1977
+ *
1978
+ * The bot **must be an administrator in the chat** for this to work and must have the appropriate administrator rights.
1979
+ *
1980
+ * **Note:** Use the field `can_set_sticker_set` optionally returned in [getChat](https://core.telegram.org/bots/api#getchat) requests to check if the bot can use this method.
1981
+ *
1982
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
1983
+ * @param {String} stickerSetName Name of the sticker set to be set as the group sticker set
1984
+ * @param {Object} [options] Additional Telegram query options
1985
+ * @return {Promise} True on success
1986
+ * @see https://core.telegram.org/bots/api#setchatstickerset
1987
+ */
1988
+ setChatStickerSet(chatId, stickerSetName, form = {}) {
1989
+ form.chat_id = chatId;
1990
+ form.sticker_set_name = stickerSetName;
1991
+ return this._request('setChatStickerSet', { form });
1992
+ }
1993
+
1994
+
1995
+ /**
1996
+ * Use this method to delete a group sticker set from a supergroup.
1997
+ *
1998
+ * Use the field `can_set_sticker_set` optionally returned in [getChat](https://core.telegram.org/bots/api#getchat) requests to check if the bot can use this method.
1999
+ *
2000
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2001
+ * @param {Object} [options] Additional Telegram query options
2002
+ * @return {Promise} True on success
2003
+ * @see https://core.telegram.org/bots/api#deletechatstickerset
2004
+ */
2005
+ deleteChatStickerSet(chatId, form = {}) {
2006
+ form.chat_id = chatId;
2007
+ return this._request('deleteChatStickerSet', { form });
2008
+ }
2009
+
2010
+ /**
2011
+ * Use this method to get custom emoji stickers, which can be used as a forum topic icon by any user.
2012
+ *
2013
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2014
+ * @param {Object} [options] Additional Telegram query options
2015
+ * @return {Promise} Array of [Sticker](https://core.telegram.org/bots/api#sticker) objects
2016
+ * @see https://core.telegram.org/bots/api#getforumtopiciconstickers
2017
+ */
2018
+ getForumTopicIconStickers(chatId, form = {}) {
2019
+ form.chat_id = chatId;
2020
+ return this._request('getForumTopicIconStickers', { form });
2021
+ }
2022
+
2023
+ /**
2024
+ * Use this method to create a topic in a forum supergroup chat.
2025
+ * The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights.
2026
+ *
2027
+ * Returns information about the created topic as a [ForumTopic](https://core.telegram.org/bots/api#forumtopic) object.
2028
+ *
2029
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2030
+ * @param {String} name Topic name, 1-128 characters
2031
+ * @param {Object} [options] Additional Telegram query options
2032
+ * @see https://core.telegram.org/bots/api#createforumtopic
2033
+ */
2034
+ createForumTopic(chatId, name, form = {}) {
2035
+ form.chat_id = chatId;
2036
+ form.name = name;
2037
+ return this._request('createForumTopic', { form });
2038
+ }
2039
+
2040
+ /**
2041
+ * Use this method to edit name and icon of a topic in a forum supergroup chat.
2042
+ * The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights, unless it is the creator of the topic.
2043
+ *
2044
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2045
+ * @param {Number} messageThreadId Unique identifier for the target message thread of the forum topic
2046
+ * @param {Object} [options] Additional Telegram query options
2047
+ * @return {Promise} True on success
2048
+ * @see https://core.telegram.org/bots/api#editforumtopic
2049
+ */
2050
+ editForumTopic(chatId, messageThreadId, form = {}) {
2051
+ form.chat_id = chatId;
2052
+ form.message_thread_id = messageThreadId;
2053
+ return this._request('editForumTopic', { form });
2054
+ }
2055
+
2056
+ /**
2057
+ * Use this method to close an open topic in a forum supergroup chat.
2058
+ * The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights, unless it is the creator of the topic.
2059
+ *
2060
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2061
+ * @param {Number} messageThreadId Unique identifier for the target message thread of the forum topic
2062
+ * @param {Object} [options] Additional Telegram query options
2063
+ * @return {Promise} True on success
2064
+ * @see https://core.telegram.org/bots/api#closeforumtopic
2065
+ */
2066
+ closeForumTopic(chatId, messageThreadId, form = {}) {
2067
+ form.chat_id = chatId;
2068
+ form.message_thread_id = messageThreadId;
2069
+ return this._request('closeForumTopic', { form });
2070
+ }
2071
+
2072
+ /**
2073
+ * Use this method to reopen a closed topic in a forum supergroup chat.
2074
+ * The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights, unless it is the creator of the topic.
2075
+ *
2076
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2077
+ * @param {Number} messageThreadId Unique identifier for the target message thread of the forum topic
2078
+ * @param {Object} [options] Additional Telegram query options
2079
+ * @return {Promise} True on success
2080
+ * @see https://core.telegram.org/bots/api#reopenforumtopic
2081
+ */
2082
+ reopenForumTopic(chatId, messageThreadId, form = {}) {
2083
+ form.chat_id = chatId;
2084
+ form.message_thread_id = messageThreadId;
2085
+ return this._request('reopenForumTopic', { form });
2086
+ }
2087
+
2088
+ /**
2089
+ * Use this method to delete a forum topic along with all its messages in a forum supergroup chat.
2090
+ * The bot must be an administrator in the chat for this to work and must have the can_delete_messages administrator rights.
2091
+ *
2092
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2093
+ * @param {Number} messageThreadId Unique identifier for the target message thread of the forum topic
2094
+ * @param {Object} [options] Additional Telegram query options
2095
+ * @return {Promise} True on success
2096
+ * @see https://core.telegram.org/bots/api#deleteforumtopic
2097
+ */
2098
+ deleteForumTopic(chatId, messageThreadId, form = {}) {
2099
+ form.chat_id = chatId;
2100
+ form.message_thread_id = messageThreadId;
2101
+ return this._request('deleteForumTopic', { form });
2102
+ }
2103
+
2104
+ /**
2105
+ * Use this method to clear the list of pinned messages in a forum topic.
2106
+ * The bot must be an administrator in the chat for this to work and must have the can_pin_messages administrator right in the supergroup.
2107
+ *
2108
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2109
+ * @param {Number} messageThreadId Unique identifier for the target message thread of the forum topic
2110
+ * @param {Object} [options] Additional Telegram query options
2111
+ * @return {Promise} True on success
2112
+ * @see https://core.telegram.org/bots/api#unpinallforumtopicmessages
2113
+ */
2114
+ unpinAllForumTopicMessages(chatId, messageThreadId, form = {}) {
2115
+ form.chat_id = chatId;
2116
+ form.message_thread_id = messageThreadId;
2117
+ return this._request('unpinAllForumTopicMessages', { form });
2118
+ }
2119
+
2120
+ /**
2121
+ * Use this method to edit the name of the 'General' topic in a forum supergroup chat.
2122
+ * The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights.
2123
+ * The topic will be automatically unhidden if it was hidden.
2124
+ *
2125
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2126
+ * @param {String} name New topic name, 1-128 characters
2127
+ * @param {Object} [options] Additional Telegram query options
2128
+ * @return {Promise} True on success
2129
+ * @see https://core.telegram.org/bots/api#editgeneralforumtopic
2130
+ */
2131
+ editGeneralForumTopic(chatId, name, form = {}) {
2132
+ form.chat_id = chatId;
2133
+ form.name = name;
2134
+ return this._request('editGeneralForumTopic', { form });
2135
+ }
2136
+
2137
+ /**
2138
+ * Use this method to close an open 'General' topic in a forum supergroup chat.
2139
+ * The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights.
2140
+ * The topic will be automatically unhidden if it was hidden.
2141
+ *
2142
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2143
+ * @param {Object} [options] Additional Telegram query options
2144
+ * @return {Promise} True on success
2145
+ * @see https://core.telegram.org/bots/api#closegeneralforumtopic
2146
+ */
2147
+ closeGeneralForumTopic(chatId, form = {}) {
2148
+ form.chat_id = chatId;
2149
+ return this._request('closeGeneralForumTopic', { form });
2150
+ }
2151
+
2152
+ /**
2153
+ * Use this method to reopen a closed 'General' topic in a forum supergroup chat.
2154
+ * The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights.
2155
+ * The topic will be automatically unhidden if it was hidden.
2156
+ *
2157
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2158
+ * @param {Object} [options] Additional Telegram query options
2159
+ * @return {Promise} True on success
2160
+ * @see https://core.telegram.org/bots/api#reopengeneralforumtopic
2161
+ */
2162
+ reopenGeneralForumTopic(chatId, form = {}) {
2163
+ form.chat_id = chatId;
2164
+ return this._request('reopenGeneralForumTopic', { form });
2165
+ }
2166
+
2167
+ /**
2168
+ * Use this method to hide the 'General' topic in a forum supergroup chat.
2169
+ * The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights.
2170
+ * The topic will be automatically closed if it was open.
2171
+ *
2172
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2173
+ * @param {Object} [options] Additional Telegram query options
2174
+ * @return {Promise} True on success
2175
+ * @see https://core.telegram.org/bots/api#hidegeneralforumtopic
2176
+ */
2177
+ hideGeneralForumTopic(chatId, form = {}) {
2178
+ form.chat_id = chatId;
2179
+ return this._request('hideGeneralForumTopic', { form });
2180
+ }
2181
+
2182
+ /**
2183
+ * Use this method to unhide the 'General' topic in a forum supergroup chat.
2184
+ * The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights
2185
+ *
2186
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2187
+ * @param {Object} [options] Additional Telegram query options
2188
+ * @return {Promise} True on success
2189
+ * @see https://core.telegram.org/bots/api#unhidegeneralforumtopic
2190
+ */
2191
+ unhideGeneralForumTopic(chatId, form = {}) {
2192
+ form.chat_id = chatId;
2193
+ return this._request('unhideGeneralForumTopic', { form });
2194
+ }
2195
+
2196
+ /**
2197
+ * Use this method to clear the list of pinned messages in a General forum topic.
2198
+ * The bot must be an administrator in the chat for this to work and must have the can_pin_messages administrator right in the supergroup.
2199
+ *
2200
+ * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername)
2201
+ * @param {Object} [options] Additional Telegram query options
2202
+ * @return {Promise} True on success
2203
+ * @see https://core.telegram.org/bots/api#unpinallgeneralforumtopicmessages
2204
+ */
2205
+ unpinAllGeneralForumTopicMessages(chatId, form = {}) {
2206
+ form.chat_id = chatId;
2207
+ return this._request('unhideGeneralForumTopic', { form });
2208
+ }
2209
+
2210
+ /**
2211
+ * Use this method to send answers to callback queries sent from
2212
+ * [inline keyboards](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
2213
+ *
2214
+ * The answer will be displayed to the user as a notification at the top of the chat screen or as an alert.
2215
+ *
2216
+ * This method has **older, compatible signatures ([1][answerCallbackQuery-v0.27.1])([2][answerCallbackQuery-v0.29.0])**
2217
+ * that are being deprecated.
2218
+ *
2219
+ * @param {String} callbackQueryId Unique identifier for the query to be answered
2220
+ * @param {Object} [options] Additional Telegram query options
2221
+ * @return {Promise} True on success
2222
+ * @see https://core.telegram.org/bots/api#answercallbackquery
2223
+ */
2224
+ answerCallbackQuery(callbackQueryId, form = {}) {
2225
+ /* The older method signature (in/before v0.27.1) was answerCallbackQuery(callbackQueryId, text, showAlert).
2226
+ * We need to ensure backwards-compatibility while maintaining
2227
+ * consistency of the method signatures throughout the library */
2228
+ if (typeof form !== 'object') {
2229
+ /* eslint-disable no-param-reassign, prefer-rest-params */
2230
+ deprecate('The method signature answerCallbackQuery(callbackQueryId, text, showAlert) has been deprecated since v0.27.1');
2231
+ form = {
2232
+ callback_query_id: arguments[0],
2233
+ text: arguments[1],
2234
+ show_alert: arguments[2],
2235
+ };
2236
+ /* eslint-enable no-param-reassign, prefer-rest-params */
2237
+ }
2238
+ /* The older method signature (in/before v0.29.0) was answerCallbackQuery([options]).
2239
+ * We need to ensure backwards-compatibility while maintaining
2240
+ * consistency of the method signatures throughout the library. */
2241
+ if (typeof callbackQueryId === 'object') {
2242
+ /* eslint-disable no-param-reassign, prefer-rest-params */
2243
+ deprecate('The method signature answerCallbackQuery([options]) has been deprecated since v0.29.0');
2244
+ form = callbackQueryId;
2245
+ /* eslint-enable no-param-reassign, prefer-rest-params */
2246
+ } else {
2247
+ form.callback_query_id = callbackQueryId;
2248
+ }
2249
+ return this._request('answerCallbackQuery', { form });
2250
+ }
2251
+
2252
+ /**
2253
+ * Use this method to get the list of boosts added to a chat by a use.
2254
+ * Requires administrator rights in the chat
2255
+ *
2256
+ * @param {Number|String} chatId Unique identifier for the group/channel
2257
+ * @param {Number} user_id Unique identifier of the target user
2258
+ * @param {Object} [options] Additional Telegram query options
2259
+ * @return {Promise} On success, returns a [UserChatBoosts](https://core.telegram.org/bots/api#userchatboosts) object
2260
+ * @see https://core.telegram.org/bots/api#getuserchatboosts
2261
+ */
2262
+ getUserChatBoosts(chatId, pollId, form = {}) {
2263
+ form.chat_id = chatId;
2264
+ form.message_id = pollId;
2265
+ return this._request('getUserChatBoosts', { form });
2266
+ }
2267
+
2268
+ /**
2269
+ * Use this method to get information about the connection of the bot with a business account
2270
+ *
2271
+ * @param {Number|String} businessConnectionId Unique identifier for the group/channel
2272
+ * @param {Object} [options] Additional Telegram query options
2273
+ * @return {Promise} On success, returns [BusinessConnection](https://core.telegram.org/bots/api#businessconnection) object
2274
+ * @see https://core.telegram.org/bots/api#getbusinessconnection
2275
+ */
2276
+ getBusinessConnection(businessConnectionId, form = {}) {
2277
+ form.business_connection_id = businessConnectionId;
2278
+ return this._request('getBusinessConnection', { form });
2279
+ }
2280
+
2281
+ /**
2282
+ * Use this method to change the list of the bot's commands.
2283
+ *
2284
+ * See https://core.telegram.org/bots#commands for more details about bot commands
2285
+ *
2286
+ * @param {Array} commands List of bot commands to be set as the list of the [bot's commands](https://core.telegram.org/bots/api#botcommand). At most 100 commands can be specified.
2287
+ * @param {Object} [options] Additional Telegram query options
2288
+ * @return {Promise} True on success
2289
+ * @see https://core.telegram.org/bots/api#setmycommands
2290
+ */
2291
+ setMyCommands(commands, form = {}) {
2292
+ form.commands = stringify(commands);
2293
+
2294
+ if (form.scope) {
2295
+ form.scope = stringify(form.scope);
2296
+ }
2297
+
2298
+ return this._request('setMyCommands', { form });
2299
+ }
2300
+
2301
+ /**
2302
+ * Use this method to delete the list of the bot's commands for the given scope and user language.
2303
+ *
2304
+ * After deletion, [higher level commands](https://core.telegram.org/bots/api#determining-list-of-commands) will be shown to affected users.
2305
+ *
2306
+ * @param {Object} [options] Additional Telegram query options
2307
+ * @return {Promise} True on success
2308
+ * @see https://core.telegram.org/bots/api#deletemycommands
2309
+ */
2310
+ deleteMyCommands(form = {}) {
2311
+ return this._request('deleteMyCommands', { form });
2312
+ }
2313
+
2314
+
2315
+ /**
2316
+ * Use this method to get the current list of the bot's commands for the given scope and user language.
2317
+ *
2318
+ * @param {Object} [options] Additional Telegram query options
2319
+ * @return {Promise} Array of [BotCommand](https://core.telegram.org/bots/api#botcommand) on success. If commands aren't set, an empty list is returned.
2320
+ * @see https://core.telegram.org/bots/api#getmycommands
2321
+ */
2322
+ getMyCommands(form = {}) {
2323
+ if (form.scope) {
2324
+ form.scope = stringify(form.scope);
2325
+ }
2326
+ return this._request('getMyCommands', { form });
2327
+ }
2328
+
2329
+ /**
2330
+ * Use this method to change the bot's name.
2331
+ *
2332
+ * @param {Object} [options] Additional Telegram query options
2333
+ * @return {Promise} True on success
2334
+ * @see https://core.telegram.org/bots/api#setmyname
2335
+ */
2336
+ setMyName(form = {}) {
2337
+ return this._request('setMyName', { form });
2338
+ }
2339
+
2340
+ /**
2341
+ * Use this method to get the current bot name for the given user language.
2342
+ *
2343
+ * @param {Object} [options] Additional Telegram query options
2344
+ * @return {Promise} [BotName](https://core.telegram.org/bots/api#botname) on success
2345
+ * @see https://core.telegram.org/bots/api#getmyname
2346
+ */
2347
+ getMyName(form = {}) {
2348
+ return this._request('getMyName', { form });
2349
+ }
2350
+
2351
+ /**
2352
+ * Use this method to change the bot's description, which is shown in the chat with the bot if the chat is empty.
2353
+ *
2354
+ * Returns True on success.
2355
+ *
2356
+ * @param {Object} [options] Additional Telegram query options
2357
+ * @return {Promise} True on success
2358
+ * @see https://core.telegram.org/bots/api#setmydescription
2359
+ */
2360
+ setMyDescription(form = {}) {
2361
+ return this._request('setMyDescription', { form });
2362
+ }
2363
+
2364
+ /**
2365
+ * Use this method to get the current bot description for the given user language.
2366
+ *
2367
+ * @param {Object} [options] Additional Telegram query options
2368
+ * @return {Promise} Returns [BotDescription](https://core.telegram.org/bots/api#botdescription) on success.
2369
+ * @see https://core.telegram.org/bots/api#getmydescription
2370
+ */
2371
+ getMyDescription(form = {}) {
2372
+ return this._request('getMyDescription', { form });
2373
+ }
2374
+
2375
+ /**
2376
+ * Use this method to change the bot's short description, which is shown on the bot's profile page
2377
+ * and is sent together with the link when users share the bot.
2378
+ *
2379
+ * @param {Object} [options] Additional Telegram query options
2380
+ * @return {Promise} Returns True on success.
2381
+ * @see https://core.telegram.org/bots/api#setmyshortdescription
2382
+ */
2383
+ setMyShortDescription(form = {}) {
2384
+ return this._request('setMyShortDescription', { form });
2385
+ }
2386
+
2387
+ /**
2388
+ * Use this method to get the current bot short description for the given user language.
2389
+ *
2390
+ * @param {Object} [options] Additional Telegram query options
2391
+ * @return {Promise} Returns [BotShortDescription](https://core.telegram.org/bots/api#botshortdescription) on success.
2392
+ * @see https://core.telegram.org/bots/api#getmyshortdescription
2393
+ */
2394
+ getMyShortDescription(form = {}) {
2395
+ return this._request('getMyShortDescription', { form });
2396
+ }
2397
+
2398
+ /**
2399
+ * Use this method to change the bot's menu button in a private chat, or the default menu button.
2400
+ *
2401
+ * @param {Object} [options] Additional Telegram query options
2402
+ * @return {Promise} True on success
2403
+ * @see https://core.telegram.org/bots/api#setchatmenubutton
2404
+ */
2405
+ setChatMenuButton(form = {}) {
2406
+ return this._request('setChatMenuButton', { form });
2407
+ }
2408
+
2409
+ /**
2410
+ * Use this method to get the current value of the bot's menu button in a private chat, or the default menu button.
2411
+ *
2412
+ * @param {Object} [options] Additional Telegram query options
2413
+ * @return {Promise} [MenuButton](https://core.telegram.org/bots/api#menubutton) on success
2414
+ * @see https://core.telegram.org/bots/api#getchatmenubutton
2415
+ */
2416
+ getChatMenuButton(form = {}) {
2417
+ return this._request('getChatMenuButton', { form });
2418
+ }
2419
+
2420
+ /**
2421
+ * Use this method to change the default administrator rights requested by the bot when it's added as an administrator to groups or channels.
2422
+ *
2423
+ * These rights will be suggested to users, but they are are free to modify the list before adding the bot.
2424
+ *
2425
+ * @param {Object} [options] Additional Telegram query options
2426
+ * @return {Promise} True on success
2427
+ * @see https://core.telegram.org/bots/api#getchatmenubutton
2428
+ */
2429
+ setMyDefaultAdministratorRights(form = {}) {
2430
+ return this._request('setMyDefaultAdministratorRights', { form });
2431
+ }
2432
+
2433
+ /**
2434
+ * Use this method to get the current default administrator rights of the bot.
2435
+ *
2436
+ * @param {Object} [options] Additional Telegram query options
2437
+ * @return {Promise} [ChatAdministratorRights](https://core.telegram.org/bots/api#chatadministratorrights) on success
2438
+ * @see https://core.telegram.org/bots/api#getmydefaultadministratorrights
2439
+ */
2440
+ getMyDefaultAdministratorRights(form = {}) {
2441
+ return this._request('getMyDefaultAdministratorRights', { form });
2442
+ }
2443
+
2444
+ /**
2445
+ * Use this method to edit text or [game](https://core.telegram.org/bots/api#games) messages sent by the bot or via the bot (for inline bots).
2446
+ *
2447
+ * Note: that **you must provide one of chat_id, message_id, or inline_message_id** in your request.
2448
+ *
2449
+ * @param {String} text New text of the message
2450
+ * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here)
2451
+ * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned
2452
+ * @see https://core.telegram.org/bots/api#editmessagetext
2453
+ */
2454
+ editMessageText(text, form = {}) {
2455
+ form.text = text;
2456
+ return this._request('editMessageText', { form });
2457
+ }
2458
+
2459
+ /**
2460
+ * Use this method to edit captions of messages sent by the bot or via the bot (for inline bots).
2461
+ *
2462
+ * Note: You **must provide one of chat_id, message_id, or inline_message_id** in your request.
2463
+ *
2464
+ * @param {String} caption New caption of the message
2465
+ * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here)
2466
+ * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned
2467
+ * @see https://core.telegram.org/bots/api#editmessagecaption
2468
+ */
2469
+ editMessageCaption(caption, form = {}) {
2470
+ form.caption = caption;
2471
+ return this._request('editMessageCaption', { form });
2472
+ }
2473
+
2474
+ /**
2475
+ * Use this method to edit animation, audio, document, photo, or video messages.
2476
+ *
2477
+ * If a message is a part of a message album, then it can be edited only to a photo or a video.
2478
+ *
2479
+ * Otherwise, message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded.
2480
+ * Use previously uploaded file via its file_id or specify a URL.
2481
+ *
2482
+ * Note: You **must provide one of chat_id, message_id, or inline_message_id** in your request.
2483
+ *
2484
+ * @param {Object} media A JSON-serialized object for a new media content of the message
2485
+ * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here)
2486
+ * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned
2487
+ * @see https://core.telegram.org/bots/api#editmessagemedia
2488
+ */
2489
+ editMessageMedia(media, form = {}) {
2490
+ const regexAttach = /attach:\/\/.+/;
2491
+
2492
+ if (typeof media.media === 'string' && regexAttach.test(media.media)) {
2493
+ const opts = {
2494
+ qs: form,
2495
+ };
2496
+
2497
+ opts.formData = {};
2498
+
2499
+ const payload = Object.assign({}, media);
2500
+ delete payload.media;
2501
+
2502
+ try {
2503
+ const attachName = String(0);
2504
+ const [formData] = this._formatSendData(
2505
+ attachName,
2506
+ media.media.replace('attach://', ''),
2507
+ media.fileOptions
2508
+ );
2509
+
2510
+ if (formData) {
2511
+ opts.formData[attachName] = formData[attachName];
2512
+ payload.media = `attach://${attachName}`;
2513
+ } else {
2514
+ throw new errors.FatalError(`Failed to process the replacement action for your ${media.type}`);
2515
+ }
2516
+ } catch (ex) {
2517
+ return Promise.reject(ex);
2518
+ }
2519
+
2520
+ opts.qs.media = stringify(payload);
2521
+
2522
+ return this._request('editMessageMedia', opts);
2523
+ }
2524
+
2525
+ form.media = stringify(media);
2526
+
2527
+ return this._request('editMessageMedia', { form });
2528
+ }
2529
+
2530
+ /**
2531
+ * Use this method to edit only the reply markup of messages sent by the bot or via the bot (for inline bots).
2532
+ *
2533
+ * Note: You **must provide one of chat_id, message_id, or inline_message_id** in your request.
2534
+ *
2535
+ * @param {Object} replyMarkup A JSON-serialized object for an inline keyboard.
2536
+ * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here)
2537
+ * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned
2538
+ * @see https://core.telegram.org/bots/api#editmessagetext
2539
+ */
2540
+ editMessageReplyMarkup(replyMarkup, form = {}) {
2541
+ form.reply_markup = replyMarkup;
2542
+ return this._request('editMessageReplyMarkup', { form });
2543
+ }
2544
+
2545
+
2546
+ /**
2547
+ * Use this method to stop a poll which was sent by the bot.
2548
+ *
2549
+ * @param {Number|String} chatId Unique identifier for the group/channel
2550
+ * @param {Number} pollId Identifier of the original message with the poll
2551
+ * @param {Object} [options] Additional Telegram query options
2552
+ * @return {Promise} On success, the stopped [Poll](https://core.telegram.org/bots/api#poll) is returned
2553
+ * @see https://core.telegram.org/bots/api#stoppoll
2554
+ */
2555
+ stopPoll(chatId, pollId, form = {}) {
2556
+ form.chat_id = chatId;
2557
+ form.message_id = pollId;
2558
+ return this._request('stopPoll', { form });
2559
+ }
2560
+
2561
+ /**
2562
+ * Use this method to send static .WEBP, [animated](https://telegram.org/blog/animated-stickers) .TGS,
2563
+ * or [video](https://telegram.org/blog/video-stickers-better-reactions) .WEBM stickers.
2564
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
2565
+ * @param {String|stream.Stream|Buffer} sticker A file path, Stream or Buffer.
2566
+ * Can also be a `file_id` previously uploaded. Stickers are WebP format files.
2567
+ * @param {Object} [options] Additional Telegram query options
2568
+ * @param {Object} [fileOptions] Optional file related meta-data
2569
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned
2570
+ * @see https://core.telegram.org/bots/api#sendsticker
2571
+ */
2572
+ sendSticker(chatId, sticker, options = {}, fileOptions = {}) {
2573
+ const opts = {
2574
+ qs: options
2575
+ };
2576
+ opts.qs.chat_id = chatId;
2577
+ try {
2578
+ const sendData = this._formatSendData('sticker', sticker, fileOptions);
2579
+ opts.formData = sendData[0];
2580
+ opts.qs.sticker = sendData[1];
2581
+ } catch (ex) {
2582
+ return Promise.reject(ex);
2583
+ }
2584
+ return this._request('sendSticker', opts);
2585
+ }
2586
+
2587
+ /**
2588
+ * Use this method to get a sticker set.
2589
+ *
2590
+ * @param {String} name Name of the sticker set
2591
+ * @param {Object} [options] Additional Telegram query options
2592
+ * @return {Promise} On success, a [StickerSet](https://core.telegram.org/bots/api#stickerset) object is returned
2593
+ * @see https://core.telegram.org/bots/api#getstickerset
2594
+ */
2595
+ getStickerSet(name, form = {}) {
2596
+ form.name = name;
2597
+ return this._request('getStickerSet', { form });
2598
+ }
2599
+
2600
+ /**
2601
+ * Use this method to get information about custom emoji stickers by their identifiers.
2602
+ *
2603
+ * @param {Array} custom_emoji_ids List of custom emoji identifiers. At most 200 custom emoji identifiers can be specified.
2604
+ * @param {Object} [options] Additional Telegram query options
2605
+ * @return {Promise} Array of [Sticker](https://core.telegram.org/bots/api#sticker) objects.
2606
+ * @see https://core.telegram.org/bots/api#getcustomemojistickers
2607
+ */
2608
+ getCustomEmojiStickers(customEmojiIds, form = {}) {
2609
+ form.custom_emoji_ids = stringify(customEmojiIds);
2610
+ return this._request('getCustomEmojiStickers', { form });
2611
+ }
2612
+
2613
+ /**
2614
+ * Use this method to upload a file with a sticker for later use in *createNewStickerSet* and *addStickerToSet* methods (can be used multiple
2615
+ * times).
2616
+ *
2617
+ * @param {Number} userId User identifier of sticker file owner
2618
+ * @param {String|stream.Stream|Buffer} sticker A file path or a Stream with the sticker in .WEBP, .PNG, .TGS, or .WEBM format. Can also be a `file_id` previously uploaded.
2619
+ * @param {String} stickerFormat Allow values: `static`, `animated` or `video`
2620
+ * @param {Object} [options] Additional Telegram query options
2621
+ * @param {Object} [fileOptions] Optional file related meta-data
2622
+ * @return {Promise} On success, a [File](https://core.telegram.org/bots/api#file) object is returned
2623
+ * @see https://core.telegram.org/bots/api#uploadstickerfile
2624
+ */
2625
+ uploadStickerFile(userId, sticker, stickerFormat = 'static', options = {}, fileOptions = {}) {
2626
+ const opts = {
2627
+ qs: options,
2628
+ };
2629
+ opts.qs.user_id = userId;
2630
+ opts.qs.sticker_format = stickerFormat;
2631
+
2632
+ try {
2633
+ const sendData = this._formatSendData('sticker', sticker, fileOptions);
2634
+ opts.formData = sendData[0];
2635
+ opts.qs.sticker = sendData[1];
2636
+ } catch (ex) {
2637
+ return Promise.reject(ex);
2638
+ }
2639
+ return this._request('uploadStickerFile', opts);
2640
+ }
2641
+
2642
+ /**
2643
+ * Use this method to create new sticker set owned by a user.
2644
+ *
2645
+ * The bot will be able to edit the created sticker set.
2646
+ *
2647
+ * You must use exactly one of the fields *png_sticker*, *tgs_sticker*, or *webm_sticker*
2648
+ *
2649
+ * @param {Number} userId User identifier of created sticker set owner
2650
+ * @param {String} name Short name of sticker set, to be used in `t.me/addstickers/` URLs (e.g., *"animals"*). Can contain only english letters, digits and underscores.
2651
+ * Must begin with a letter, can't contain consecutive underscores and must end in `"_by_<bot_username>"`. `<bot_username>` is case insensitive. 1-64 characters.
2652
+ * @param {String} title Sticker set title, 1-64 characters
2653
+ * @param {String|stream.Stream|Buffer} pngSticker Png image with the sticker, must be up to 512 kilobytes in size,
2654
+ * dimensions must not exceed 512px, and either width or height must be exactly 512px.
2655
+ * @param {String} emojis One or more emoji corresponding to the sticker
2656
+ * @param {Object} [options] Additional Telegram query options
2657
+ * @param {Object} [fileOptions] Optional file related meta-data
2658
+ * @return {Promise} True on success
2659
+ * @see https://core.telegram.org/bots/api#createnewstickerset
2660
+ */
2661
+ createNewStickerSet(userId, name, title, pngSticker, emojis, options = {}, fileOptions = {}) {
2662
+ const opts = {
2663
+ qs: options,
2664
+ };
2665
+ opts.qs.user_id = userId;
2666
+ opts.qs.name = name;
2667
+ opts.qs.title = title;
2668
+ opts.qs.emojis = emojis;
2669
+ opts.qs.mask_position = stringify(options.mask_position);
2670
+ try {
2671
+ const sendData = this._formatSendData('png_sticker', pngSticker, fileOptions);
2672
+ opts.formData = sendData[0];
2673
+ opts.qs.png_sticker = sendData[1];
2674
+ } catch (ex) {
2675
+ return Promise.reject(ex);
2676
+ }
2677
+ return this._request('createNewStickerSet', opts);
2678
+ }
2679
+
2680
+ /**
2681
+ * Use this method to add a new sticker to a set created by the bot.
2682
+ *
2683
+ * You must use exactly one of the fields *png_sticker*, *tgs_sticker*, or *webm_sticker*
2684
+ *
2685
+ * Animated stickers can be added to animated sticker sets and only to them
2686
+ *
2687
+ * Note:
2688
+ * - Emoji sticker sets can have up to 200 sticker
2689
+ * - Static or Animated sticker sets can have up to 120 stickers
2690
+ *
2691
+ * @param {Number} userId User identifier of sticker set owner
2692
+ * @param {String} name Sticker set name
2693
+ * @param {String|stream.Stream|Buffer} sticker Png image with the sticker (must be up to 512 kilobytes in size,
2694
+ * dimensions must not exceed 512px, and either width or height must be exactly 512px, [TGS animation](https://core.telegram.org/stickers#animated-sticker-requirements)
2695
+ * with the sticker or [WEBM video](https://core.telegram.org/stickers#video-sticker-requirements) with the sticker.
2696
+ * @param {String} emojis One or more emoji corresponding to the sticker
2697
+ * @param {String} stickerType Allow values: `png_sticker`, `tgs_sticker`, or `webm_sticker`.
2698
+ * @param {Object} [options] Additional Telegram query options
2699
+ * @param {Object} [fileOptions] Optional file related meta-data
2700
+ * @return {Promise} True on success
2701
+ * @see https://core.telegram.org/bots/api#addstickertoset
2702
+ */
2703
+ addStickerToSet(userId, name, sticker, emojis, stickerType = 'png_sticker', options = {}, fileOptions = {}) {
2704
+ const opts = {
2705
+ qs: options,
2706
+ };
2707
+ opts.qs.user_id = userId;
2708
+ opts.qs.name = name;
2709
+ opts.qs.emojis = emojis;
2710
+ opts.qs.mask_position = stringify(options.mask_position);
2711
+
2712
+ if (typeof stickerType !== 'string' || ['png_sticker', 'tgs_sticker', 'webm_sticker'].indexOf(stickerType) === -1) {
2713
+ return Promise.reject(new Error('stickerType must be a string and the allow types is: png_sticker, tgs_sticker, webm_sticker'));
2714
+ }
2715
+
2716
+ try {
2717
+ const sendData = this._formatSendData(stickerType, sticker, fileOptions);
2718
+ opts.formData = sendData[0];
2719
+ opts.qs[stickerType] = sendData[1];
2720
+ } catch (ex) {
2721
+ return Promise.reject(ex);
2722
+ }
2723
+ return this._request('addStickerToSet', opts);
2724
+ }
2725
+
2726
+ /**
2727
+ * Use this method to move a sticker in a set created by the bot to a specific position.
2728
+ *
2729
+ * @param {String} sticker File identifier of the sticker
2730
+ * @param {Number} position New sticker position in the set, zero-based
2731
+ * @param {Object} [options] Additional Telegram query options
2732
+ * @return {Promise} True on success
2733
+ * @see https://core.telegram.org/bots/api#setstickerpositioninset
2734
+ */
2735
+ setStickerPositionInSet(sticker, position, form = {}) {
2736
+ form.sticker = sticker;
2737
+ form.position = position;
2738
+ return this._request('setStickerPositionInSet', { form });
2739
+ }
2740
+
2741
+ /**
2742
+ * Use this method to delete a sticker from a set created by the bot.
2743
+ *
2744
+ * @param {String} sticker File identifier of the sticker
2745
+ * @param {Object} [options] Additional Telegram query options
2746
+ * @return {Promise} True on success
2747
+ * @see https://core.telegram.org/bots/api#deletestickerfromset
2748
+ * @todo Add tests for this method!
2749
+ */
2750
+ deleteStickerFromSet(sticker, form = {}) {
2751
+ form.sticker = sticker;
2752
+ return this._request('deleteStickerFromSet', { form });
2753
+ }
2754
+
2755
+ /**
2756
+ * Use this method to replace an existing sticker in a sticker set with a new one
2757
+ *
2758
+ * @param {Number} user_id User identifier of the sticker set owner
2759
+ * @param {String} name Sticker set name
2760
+ * @param {String} sticker File identifier of the sticker
2761
+ * @param {Object} [options] Additional Telegram query options
2762
+ * @return {Promise} True on success
2763
+ * @see https://core.telegram.org/bots/api#replacestickerinset
2764
+ * @todo Add tests for this method!
2765
+ */
2766
+ replaceStickerInSet(userId, name, oldSticker, form = {}) {
2767
+ form.user_id = userId;
2768
+ form.name = name;
2769
+ form.old_sticker = oldSticker;
2770
+ return this._request('deleteStickerFromSet', { form });
2771
+ }
2772
+
2773
+
2774
+ /**
2775
+ * Use this method to change the list of emoji assigned to a regular or custom emoji sticker.
2776
+ *
2777
+ * The sticker must belong to a sticker set created by the bot.
2778
+ *
2779
+ * @param {String} sticker File identifier of the sticker
2780
+ * @param { Array } emojiList A JSON-serialized list of 1-20 emoji associated with the sticker
2781
+ * @param {Object} [options] Additional Telegram query options
2782
+ * @return {Promise} True on success
2783
+ * @see https://core.telegram.org/bots/api#setstickeremojilist
2784
+ */
2785
+ setStickerEmojiList(sticker, emojiList, form = {}) {
2786
+ form.sticker = sticker;
2787
+ form.emoji_list = stringify(emojiList);
2788
+ return this._request('setStickerEmojiList', { form });
2789
+ }
2790
+
2791
+ /**
2792
+ * Use this method to change the list of emoji assigned to a `regular` or `custom emoji` sticker.
2793
+ *
2794
+ * The sticker must belong to a sticker set created by the bot.
2795
+ *
2796
+ * @param {String} sticker File identifier of the sticker
2797
+ * @param {Object} [options] Additional Telegram query options
2798
+ * @return {Promise} True on success
2799
+ * @see https://core.telegram.org/bots/api#setstickerkeywords
2800
+ */
2801
+ setStickerKeywords(sticker, form = {}) {
2802
+ form.sticker = sticker;
2803
+ if (form.keywords) {
2804
+ form.keywords = stringify(form.keywords);
2805
+ }
2806
+ return this._request('setStickerKeywords', { form });
2807
+ }
2808
+
2809
+ /**
2810
+ * Use this method to change the [mask position](https://core.telegram.org/bots/api#maskposition) of a mask sticker.
2811
+ *
2812
+ * The sticker must belong to a sticker set created by the bot.
2813
+ *
2814
+ * @param {String} sticker File identifier of the sticker
2815
+ * @param {Object} [options] Additional Telegram query options
2816
+ * @return {Promise} True on success
2817
+ * @see https://core.telegram.org/bots/api#setstickermaskposition
2818
+ */
2819
+ setStickerMaskPosition(sticker, form = {}) {
2820
+ form.sticker = sticker;
2821
+ if (form.mask_position) {
2822
+ form.mask_position = stringify(form.mask_position);
2823
+ }
2824
+ return this._request('setStickerMaskPosition', { form });
2825
+ }
2826
+
2827
+ /**
2828
+ * Use this method to set the title of a created sticker set.
2829
+ *
2830
+ * The sticker must belong to a sticker set created by the bot.
2831
+ *
2832
+ * @param {String} name Sticker set name
2833
+ * @param {String} title Sticker set title, 1-64 characters
2834
+ * @param {Object} [options] Additional Telegram query options
2835
+ * @return {Promise} True on success
2836
+ * @see https://core.telegram.org/bots/api#setstickersettitle
2837
+ */
2838
+ setStickerSetTitle(name, title, form = {}) {
2839
+ form.name = name;
2840
+ form.title = title;
2841
+ return this._request('setStickerSetTitle', { form });
2842
+ }
2843
+
2844
+ /**
2845
+ * Use this method to add a thumb to a set created by the bot.
2846
+ *
2847
+ * Animated thumbnails can be set for animated sticker sets only. Video thumbnails can be set only for video sticker sets only
2848
+ *
2849
+ * @param {Number} userId User identifier of sticker set owner
2850
+ * @param {String} name Sticker set name
2851
+ * @param {String|stream.Stream|Buffer} thumbnail A .WEBP or .PNG image with the thumbnail,
2852
+ * must be up to 128 kilobytes in size and have width and height exactly 100px,
2853
+ * a TGS animation with the thumbnail up to 32 kilobytes in size or a WEBM video with the thumbnail up to 32 kilobytes in size.
2854
+ *
2855
+ * Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram
2856
+ * to get a file from the Internet, or upload a new one. Animated sticker set thumbnails can't be uploaded via HTTP URL.
2857
+ * @param {Object} [options] Additional Telegram query options
2858
+ * @param {Object} [fileOptions] Optional file related meta-data
2859
+ * @return {Promise} True on success
2860
+ * @see https://core.telegram.org/bots/api#setstickersetthumbnail
2861
+ */
2862
+ setStickerSetThumbnail(userId, name, thumbnail, options = {}, fileOptions = {}) {
2863
+ const opts = {
2864
+ qs: options,
2865
+ };
2866
+ opts.qs.user_id = userId;
2867
+ opts.qs.name = name;
2868
+ opts.qs.mask_position = stringify(options.mask_position);
2869
+ try {
2870
+ const sendData = this._formatSendData('thumbnail', thumbnail, fileOptions);
2871
+ opts.formData = sendData[0];
2872
+ opts.qs.thumbnail = sendData[1];
2873
+ } catch (ex) {
2874
+ return Promise.reject(ex);
2875
+ }
2876
+ return this._request('setStickerSetThumbnail', opts);
2877
+ }
2878
+
2879
+
2880
+ /**
2881
+ * Use this method to set the thumbnail of a custom emoji sticker set.
2882
+ *
2883
+ * The sticker must belong to a sticker set created by the bot.
2884
+ *
2885
+ * @param {String} name Sticker set name
2886
+ * @param {Object} [options] Additional Telegram query options
2887
+ * @return {Promise} True on success
2888
+ * @see https://core.telegram.org/bots/api#setcustomemojistickersetthumbnail
2889
+ */
2890
+ setCustomEmojiStickerSetThumbnail(name, form = {}) {
2891
+ form.name = name;
2892
+ return this._request('setCustomEmojiStickerSetThumbnail', { form });
2893
+ }
2894
+
2895
+ /**
2896
+ * Use this method to delete a sticker set that was created by the bot.
2897
+ *
2898
+ * The sticker must belong to a sticker set created by the bot.
2899
+ *
2900
+ * @param {String} name Sticker set name
2901
+ * @param {Object} [options] Additional Telegram query options
2902
+ * @return {Promise} True on success
2903
+ * @see https://core.telegram.org/bots/api#deletestickerset
2904
+ */
2905
+ deleteStickerSet(name, form = {}) {
2906
+ form.name = name;
2907
+ return this._request('deleteStickerSet', { form });
2908
+ }
2909
+
2910
+ /**
2911
+ * Send answers to an inline query.
2912
+ *
2913
+ * Note: No more than 50 results per query are allowed.
2914
+ *
2915
+ * @param {String} inlineQueryId Unique identifier of the query
2916
+ * @param {InlineQueryResult[]} results An array of results for the inline query
2917
+ * @param {Object} [options] Additional Telegram query options
2918
+ * @return {Promise} On success, True is returned
2919
+ * @see https://core.telegram.org/bots/api#answerinlinequery
2920
+ */
2921
+ answerInlineQuery(inlineQueryId, results, form = {}) {
2922
+ form.inline_query_id = inlineQueryId;
2923
+ form.results = stringify(results);
2924
+ return this._request('answerInlineQuery', { form });
2925
+ }
2926
+
2927
+ /**
2928
+ * Use this method to set the result of an interaction with a [Web App](https://core.telegram.org/bots/webapps)
2929
+ * and send a corresponding message on behalf of the user to the chat from which the query originated.
2930
+ *
2931
+ * @param {String} webAppQueryId Unique identifier for the query to be answered
2932
+ * @param {InlineQueryResult} result object that represents one result of an inline query
2933
+ * @param {Object} [options] Additional Telegram query options
2934
+ * @return {Promise} On success, a [SentWebAppMessage](https://core.telegram.org/bots/api#sentwebappmessage) object is returned
2935
+ * @see https://core.telegram.org/bots/api#answerwebappquery
2936
+ */
2937
+ answerWebAppQuery(webAppQueryId, result, form = {}) {
2938
+ form.web_app_query_id = webAppQueryId;
2939
+ form.result = stringify(result);
2940
+ return this._request('answerWebAppQuery', { form });
2941
+ }
2942
+
2943
+ /**
2944
+ * Use this method to send an invoice.
2945
+ *
2946
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
2947
+ * @param {String} title Product name, 1-32 characters
2948
+ * @param {String} description Product description, 1-255 characters
2949
+ * @param {String} payload Bot defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes.
2950
+ * @param {String} providerToken Payments provider token, obtained via `@BotFather`
2951
+ * @param {String} currency Three-letter ISO 4217 currency code
2952
+ * @param {Array} prices Breakdown of prices
2953
+ * @param {Object} [options] Additional Telegram query options
2954
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned
2955
+ * @see https://core.telegram.org/bots/api#sendinvoice
2956
+ */
2957
+ sendInvoice(chatId, title, description, payload, providerToken, currency, prices, form = {}) {
2958
+ form.chat_id = chatId;
2959
+ form.title = title;
2960
+ form.description = description;
2961
+ form.payload = payload;
2962
+ form.provider_token = providerToken;
2963
+ form.currency = currency;
2964
+ form.prices = stringify(prices);
2965
+ form.provider_data = stringify(form.provider_data);
2966
+ if (form.suggested_tip_amounts) {
2967
+ form.suggested_tip_amounts = stringify(form.suggested_tip_amounts);
2968
+ }
2969
+ return this._request('sendInvoice', { form });
2970
+ }
2971
+
2972
+ /**
2973
+ * Use this method to create a link for an invoice.
2974
+ *
2975
+ * @param {String} title Product name, 1-32 characters
2976
+ * @param {String} description Product description, 1-255 characters
2977
+ * @param {String} payload Bot defined invoice payload
2978
+ * @param {String} providerToken Payment provider token
2979
+ * @param {String} currency Three-letter ISO 4217 currency code
2980
+ * @param {Array} prices Breakdown of prices
2981
+ * @param {Object} [options] Additional Telegram query options
2982
+ * @returns {Promise} The created invoice link as String on success.
2983
+ * @see https://core.telegram.org/bots/api#createinvoicelink
2984
+ */
2985
+ createInvoiceLink(title, description, payload, providerToken, currency, prices, form = {}) {
2986
+ form.title = title;
2987
+ form.description = description;
2988
+ form.payload = payload;
2989
+ form.provider_token = providerToken;
2990
+ form.currency = currency;
2991
+ form.prices = stringify(prices);
2992
+ return this._request('createInvoiceLink', { form });
2993
+ }
2994
+
2995
+ /**
2996
+ * Use this method to reply to shipping queries.
2997
+ *
2998
+ * If you sent an invoice requesting a shipping address and the parameter is_flexible was specified,
2999
+ * the Bot API will send an [Update](https://core.telegram.org/bots/api#update) with a shipping_query field to the bot
3000
+ *
3001
+ * @param {String} shippingQueryId Unique identifier for the query to be answered
3002
+ * @param {Boolean} ok Specify if delivery of the product is possible
3003
+ * @param {Object} [options] Additional Telegram query options
3004
+ * @return {Promise} On success, True is returned
3005
+ * @see https://core.telegram.org/bots/api#answershippingquery
3006
+ */
3007
+ answerShippingQuery(shippingQueryId, ok, form = {}) {
3008
+ form.shipping_query_id = shippingQueryId;
3009
+ form.ok = ok;
3010
+ form.shipping_options = stringify(form.shipping_options);
3011
+ return this._request('answerShippingQuery', { form });
3012
+ }
3013
+
3014
+ /**
3015
+ * Use this method to respond to such pre-checkout queries
3016
+ *
3017
+ * Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation in the form of
3018
+ * an [Update](https://core.telegram.org/bots/api#update) with the field *pre_checkout_query*.
3019
+ *
3020
+ * **Note:** The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent.
3021
+ *
3022
+ * @param {String} preCheckoutQueryId Unique identifier for the query to be answered
3023
+ * @param {Boolean} ok Specify if every order details are ok
3024
+ * @param {Object} [options] Additional Telegram query options
3025
+ * @return {Promise} On success, True is returned
3026
+ * @see https://core.telegram.org/bots/api#answerprecheckoutquery
3027
+ */
3028
+ answerPreCheckoutQuery(preCheckoutQueryId, ok, form = {}) {
3029
+ form.pre_checkout_query_id = preCheckoutQueryId;
3030
+ form.ok = ok;
3031
+ return this._request('answerPreCheckoutQuery', { form });
3032
+ }
3033
+
3034
+ /**
3035
+ * Use this method to send a game.
3036
+ *
3037
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
3038
+ * @param {String} gameShortName name of the game to be sent. Set up your games via `@BotFather`.
3039
+ * @param {Object} [options] Additional Telegram query options
3040
+ * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned
3041
+ * @see https://core.telegram.org/bots/api#sendgame
3042
+ */
3043
+ sendGame(chatId, gameShortName, form = {}) {
3044
+ form.chat_id = chatId;
3045
+ form.game_short_name = gameShortName;
3046
+ return this._request('sendGame', { form });
3047
+ }
3048
+
3049
+ /**
3050
+ * Use this method to set the score of the specified user in a game message.
3051
+ *
3052
+ * @param {Number} userId Unique identifier of the target user
3053
+ * @param {Number} score New score value, must be non-negative
3054
+ * @param {Object} [options] Additional Telegram query options
3055
+ * @return {Promise} On success, if the message is not an inline message, the [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned
3056
+ * @see https://core.telegram.org/bots/api#setgamescore
3057
+ */
3058
+ setGameScore(userId, score, form = {}) {
3059
+ form.user_id = userId;
3060
+ form.score = score;
3061
+ return this._request('setGameScore', { form });
3062
+ }
3063
+
3064
+ /**
3065
+ * Use this method to get data for high score tables.
3066
+ *
3067
+ * Will return the score of the specified user and several of their neighbors in a game.
3068
+ *
3069
+ * @param {Number} userId Unique identifier of the target user
3070
+ * @param {Object} [options] Additional Telegram query options
3071
+ * @return {Promise} On success, returns an Array of [GameHighScore](https://core.telegram.org/bots/api#gamehighscore) objects
3072
+ * @see https://core.telegram.org/bots/api#getgamehighscores
3073
+ */
3074
+ getGameHighScores(userId, form = {}) {
3075
+ form.user_id = userId;
3076
+ return this._request('getGameHighScores', { form });
3077
+ }
3078
+
3079
+
3080
+ /**
3081
+ * Use this method to delete a message, including service messages, with the following limitations:
3082
+ * - A message can only be deleted if it was sent less than 48 hours ago.
3083
+ * - A dice message can only be deleted if it was sent more than 24 hours ago.
3084
+ * - Bots can delete outgoing messages in groups and supergroups.
3085
+ * - Bots can delete incoming messages in groups, supergroups and channels.
3086
+ * - Bots granted `can_post_messages` permissions can delete outgoing messages in channels.
3087
+ * - If the bot is an administrator of a group, it can delete any message there.
3088
+ * - If the bot has `can_delete_messages` permission in a supergroup, it can delete any message there.
3089
+ *
3090
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format @channelusername)
3091
+ * @param {Number} messageId Unique identifier of the target message
3092
+ * @param {Object} [options] Additional Telegram query options
3093
+ * @return {Promise} True on success
3094
+ * @see https://core.telegram.org/bots/api#deletemessage
3095
+ */
3096
+ deleteMessage(chatId, messageId, form = {}) {
3097
+ form.chat_id = chatId;
3098
+ form.message_id = messageId;
3099
+ return this._request('deleteMessage', { form });
3100
+ }
3101
+
3102
+ /**
3103
+ * Use this method to delete multiple messages simultaneously. If some of the specified messages can't be found, they are skipped.
3104
+ *
3105
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format @channelusername)
3106
+ * @param {Array<Number|String>} messageIds Identifiers of 1-100 messages to delete. See deleteMessage for limitations on which messages can be deleted
3107
+ * @param {Object} [options] Additional Telegram query options
3108
+ * @return {Promise<Boolean>} True on success
3109
+ * @see https://core.telegram.org/bots/api#deletemessages
3110
+ */
3111
+ deleteMessages(chatId, messageIds, form = {}) {
3112
+ form.chat_id = chatId;
3113
+ form.message_ids = stringify(messageIds);
3114
+ return this._request('deleteMessages', { form });
3115
+ }
3116
+
3117
+ }
3118
+
3119
+ module.exports = TelegramBot;