Passed
Pull Request — master (#408)
by Alexander
02:08 queued 28s
created

BotApi::getChatMember()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 5
ccs 0
cts 3
cp 0
rs 10
cc 1
nc 1
nop 2
crap 2
1
<?php
2
3
namespace TelegramBot\Api;
4
5
use TelegramBot\Api\Types\ArrayOfBotCommand;
6
use TelegramBot\Api\Types\ArrayOfChatMemberEntity;
7
use TelegramBot\Api\Types\ArrayOfMessageEntity;
8
use TelegramBot\Api\Types\ArrayOfMessages;
9
use TelegramBot\Api\Types\ArrayOfSticker;
10
use TelegramBot\Api\Types\ArrayOfUpdates;
11
use TelegramBot\Api\Types\BotCommand;
12
use TelegramBot\Api\Types\Chat;
13
use TelegramBot\Api\Types\ChatMember;
14
use TelegramBot\Api\Types\File;
15
use TelegramBot\Api\Types\ForceReply;
16
use TelegramBot\Api\Types\ForumTopic;
17
use TelegramBot\Api\Types\Inline\QueryResult\AbstractInlineQueryResult;
18
use TelegramBot\Api\Types\InputMedia\ArrayOfInputMedia;
19
use TelegramBot\Api\Types\InputMedia\InputMedia;
20
use TelegramBot\Api\Types\MaskPosition;
21
use TelegramBot\Api\Types\Message;
22
use TelegramBot\Api\Types\Poll;
23
use TelegramBot\Api\Types\ReplyKeyboardHide;
24
use TelegramBot\Api\Types\ReplyKeyboardMarkup;
25
use TelegramBot\Api\Types\ReplyKeyboardRemove;
26
use TelegramBot\Api\Types\Sticker;
27
use TelegramBot\Api\Types\StickerSet;
28
use TelegramBot\Api\Types\Update;
29
use TelegramBot\Api\Types\User;
30
use TelegramBot\Api\Types\UserProfilePhotos;
31
use TelegramBot\Api\Types\WebhookInfo;
32
33
/**
34
 * Class BotApi
35
 *
36
 * @package TelegramBot\Api
37
 */
38
class BotApi
39
{
40
    /**
41
     * HTTP codes
42
     *
43
     * @var array
44
     */
45
    public static $codes = [
46
        // Informational 1xx
47
        100 => 'Continue',
48
        101 => 'Switching Protocols',
49
        102 => 'Processing',            // RFC2518
50
        // Success 2xx
51
        200 => 'OK',
52
        201 => 'Created',
53
        202 => 'Accepted',
54
        203 => 'Non-Authoritative Information',
55
        204 => 'No Content',
56
        205 => 'Reset Content',
57
        206 => 'Partial Content',
58
        207 => 'Multi-Status',          // RFC4918
59
        208 => 'Already Reported',      // RFC5842
60
        226 => 'IM Used',               // RFC3229
61
        // Redirection 3xx
62
        300 => 'Multiple Choices',
63
        301 => 'Moved Permanently',
64
        302 => 'Found', // 1.1
65
        303 => 'See Other',
66
        304 => 'Not Modified',
67
        305 => 'Use Proxy',
68
        // 306 is deprecated but reserved
69
        307 => 'Temporary Redirect',
70
        308 => 'Permanent Redirect',    // RFC7238
71
        // Client Error 4xx
72
        400 => 'Bad Request',
73
        401 => 'Unauthorized',
74
        402 => 'Payment Required',
75
        403 => 'Forbidden',
76
        404 => 'Not Found',
77
        405 => 'Method Not Allowed',
78
        406 => 'Not Acceptable',
79
        407 => 'Proxy Authentication Required',
80
        408 => 'Request Timeout',
81
        409 => 'Conflict',
82
        410 => 'Gone',
83
        411 => 'Length Required',
84
        412 => 'Precondition Failed',
85
        413 => 'Payload Too Large',
86
        414 => 'URI Too Long',
87
        415 => 'Unsupported Media Type',
88
        416 => 'Range Not Satisfiable',
89
        417 => 'Expectation Failed',
90
        422 => 'Unprocessable Entity',                                        // RFC4918
91
        423 => 'Locked',                                                      // RFC4918
92
        424 => 'Failed Dependency',                                           // RFC4918
93
        425 => 'Reserved for WebDAV advanced collections expired proposal',   // RFC2817
94
        426 => 'Upgrade Required',                                            // RFC2817
95
        428 => 'Precondition Required',                                       // RFC6585
96
        429 => 'Too Many Requests',                                           // RFC6585
97
        431 => 'Request Header Fields Too Large',                             // RFC6585
98
        // Server Error 5xx
99
        500 => 'Internal Server Error',
100
        501 => 'Not Implemented',
101
        502 => 'Bad Gateway',
102
        503 => 'Service Unavailable',
103
        504 => 'Gateway Timeout',
104
        505 => 'HTTP Version Not Supported',
105
        506 => 'Variant Also Negotiates (Experimental)',                      // RFC2295
106
        507 => 'Insufficient Storage',                                        // RFC4918
107
        508 => 'Loop Detected',                                               // RFC5842
108
        510 => 'Not Extended',                                                // RFC2774
109
        511 => 'Network Authentication Required',                             // RFC6585
110
    ];
111
112
    private $proxySettings = [];
113
114
    /**
115
     * Default http status code
116
     */
117
    const DEFAULT_STATUS_CODE = 200;
118
119
    /**
120
     * Not Modified http status code
121
     */
122
    const NOT_MODIFIED_STATUS_CODE = 304;
123
124
    /**
125
     * Limits for tracked ids
126
     */
127
    const MAX_TRACKED_EVENTS = 200;
128
129
    /**
130
     * Url prefixes
131
     */
132
    const URL_PREFIX = 'https://api.telegram.org/bot';
133
134
    /**
135
     * Url prefix for files
136
     */
137
    const FILE_URL_PREFIX = 'https://api.telegram.org/file/bot';
138
139
    /**
140
     * CURL object
141
     *
142
     * @var
143
     */
144
    protected $curl;
145
146
    /**
147
     * CURL custom options
148
     *
149
     * @var array
150
     */
151
    protected $customCurlOptions = [];
152
153
    /**
154
     * Bot token
155
     *
156
     * @var string
157
     */
158
    protected $token;
159
160
    /**
161
     * Botan tracker
162
     *
163
     * @var Botan
164
     */
165
    protected $tracker;
166
167
    /**
168
     * list of event ids
169
     *
170
     * @var array
171
     */
172
    protected $trackedEvents = [];
173
174
    /**
175
     * Check whether return associative array
176
     *
177
     * @var bool
178
     */
179
    protected $returnArray = true;
180
181
    /**
182
     * Constructor
183
     *
184
     * @param string $token Telegram Bot API token
185
     * @param string|null $trackerToken Yandex AppMetrica application api_key
186
     * @throws \Exception
187
     */
188 9
    public function __construct($token, $trackerToken = null)
189
    {
190 9
        $this->curl = curl_init();
191 9
        $this->token = $token;
192
193 9
        if ($trackerToken) {
194
            $this->tracker = new Botan($trackerToken);
195
        }
196 9
    }
197
198
    /**
199
     * Set return array
200
     *
201
     * @param bool $mode
202
     *
203
     * @return $this
204
     */
205
    public function setModeObject($mode = true)
206
    {
207
        $this->returnArray = !$mode;
208
209
        return $this;
210
    }
211
212
213
    /**
214
     * Call method
215
     *
216
     * @param string $method
217
     * @param array|null $data
218
     *
219
     * @return mixed
220
     * @throws Exception
221
     * @throws HttpException
222
     * @throws InvalidJsonException
223
     */
224
    public function call($method, array $data = null, $timeout = 10)
225
    {
226
        $options = $this->proxySettings + [
227
            CURLOPT_URL => $this->getUrl().'/'.$method,
228
            CURLOPT_RETURNTRANSFER => true,
229
            CURLOPT_POST => null,
230
            CURLOPT_POSTFIELDS => null,
231
            CURLOPT_TIMEOUT => $timeout,
232
        ];
233
234
        if ($data) {
235
            $options[CURLOPT_POST] = true;
236
            $options[CURLOPT_POSTFIELDS] = $data;
237
        }
238
239
        if (!empty($this->customCurlOptions) && is_array($this->customCurlOptions)) {
240
            $options = $this->customCurlOptions + $options;
241
        }
242
243
        $response = self::jsonValidate($this->executeCurl($options), $this->returnArray);
244
245
        if ($this->returnArray) {
246
            if (!isset($response['ok']) || !$response['ok']) {
247
                throw new Exception($response['description'], $response['error_code']);
248
            }
249
250
            return $response['result'];
251
        }
252
253
        if (!$response->ok) {
254
            throw new Exception($response->description, $response->error_code);
255
        }
256
257
        return $response->result;
258
    }
259
260
    /**
261
     * curl_exec wrapper for response validation
262
     *
263
     * @param array $options
264
     *
265
     * @return string
266
     *
267
     * @throws HttpException
268
     */
269
    protected function executeCurl(array $options)
270
    {
271
        curl_setopt_array($this->curl, $options);
272
273
        $result = curl_exec($this->curl);
274
        self::curlValidate($this->curl, $result);
0 ignored issues
show
Bug introduced by
It seems like $this->curl can also be of type CurlHandle; however, parameter $curl of TelegramBot\Api\BotApi::curlValidate() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

274
        self::curlValidate(/** @scrutinizer ignore-type */ $this->curl, $result);
Loading history...
Bug introduced by
It seems like $result can also be of type true; however, parameter $response of TelegramBot\Api\BotApi::curlValidate() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

274
        self::curlValidate($this->curl, /** @scrutinizer ignore-type */ $result);
Loading history...
275
        if ($result === false) {
276
            throw new HttpException(curl_error($this->curl), curl_errno($this->curl));
277
        }
278
279
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result also could return the type true which is incompatible with the documented return type string.
Loading history...
280
    }
281
282
    /**
283
     * Response validation
284
     *
285
     * @param resource $curl
286
     * @param string $response
287
     * @throws HttpException
288
     */
289
    public static function curlValidate($curl, $response = null)
290
    {
291
        $json = json_decode($response, true)?: [];
0 ignored issues
show
Bug introduced by
It seems like $response can also be of type null; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

291
        $json = json_decode(/** @scrutinizer ignore-type */ $response, true)?: [];
Loading history...
292
        if (($httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE))
293
            && !in_array($httpCode, [self::DEFAULT_STATUS_CODE, self::NOT_MODIFIED_STATUS_CODE])
294
        ) {
295
            $errorDescription = array_key_exists('description', $json) ? $json['description'] : self::$codes[$httpCode];
296
            $errorParameters = array_key_exists('parameters', $json) ? $json['parameters'] : [];
297
            throw new HttpException($errorDescription, $httpCode, null, $errorParameters);
298
        }
299
    }
300
301
    /**
302
     * JSON validation
303
     *
304
     * @param string $jsonString
305
     * @param boolean $asArray
306
     *
307
     * @return object|array
308
     * @throws InvalidJsonException
309
     */
310
    public static function jsonValidate($jsonString, $asArray)
311
    {
312
        $json = json_decode($jsonString, $asArray);
313
314
        if (json_last_error() != JSON_ERROR_NONE) {
315
            throw new InvalidJsonException(json_last_error_msg(), json_last_error());
316
        }
317
318
        return $json;
319
    }
320
321
    /**
322
     * Use this method to send text messages. On success, the sent \TelegramBot\Api\Types\Message is returned.
323
     *
324
     * @param int|string $chatId
325
     * @param string $text
326
     * @param string|null $parseMode
327
     * @param bool $disablePreview
328
     * @param int|null $messageThreadId
329
     * @param int|null $replyToMessageId
330
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
331
     * @param bool $disableNotification
332
     *
333
     * @return Message
334
     * @throws InvalidArgumentException
335
     * @throws Exception
336
     */
337
    public function sendMessage(
338
        $chatId,
339
        $text,
340
        $parseMode = null,
341
        $disablePreview = false,
342
        $messageThreadId = null,
343
        $replyToMessageId = null,
344
        $replyMarkup = null,
345
        $disableNotification = false
346
    ) {
347
        return Message::fromResponse($this->call('sendMessage', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...$disableNotification))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
348
            'chat_id' => $chatId,
349
            'text' => $text,
350
            'message_thread_id' => $messageThreadId,
351
            'parse_mode' => $parseMode,
352
            'disable_web_page_preview' => $disablePreview,
353
            'reply_to_message_id' => (int)$replyToMessageId,
354
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
355
            'disable_notification' => (bool)$disableNotification,
356
        ]));
357
    }
358
359
    /**
360
     * @param int|string $chatId
361
     * @param int|string $fromChatId
362
     * @param int $messageId
363
     * @param string|null $caption
364
     * @param string|null $parseMode
365
     * @param ArrayOfMessageEntity|null $captionEntities
366
     * @param bool $disableNotification
367
     * @param int|null $messageThreadId
368
     * @param int|null $replyToMessageId
369
     * @param bool $allowSendingWithoutReply
370
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
371
     *
372
     * @return Message
373
     * @throws Exception
374
     * @throws HttpException
375
     * @throws InvalidJsonException
376
     */
377
    public function copyMessage(
378
        $chatId,
379
        $fromChatId,
380
        $messageId,
381
        $caption = null,
382
        $parseMode = null,
383
        $captionEntities = null,
384
        $disableNotification = false,
385
        $messageThreadId = null,
386
        $replyToMessageId = null,
387
        $allowSendingWithoutReply = false,
388
        $replyMarkup = null
389
    ) {
390
        return Message::fromResponse($this->call('copyMessage', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...eplyMarkup->toJson()))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
391
            'chat_id' => $chatId,
392
            'from_chat_id' => $fromChatId,
393
            'message_id' => (int)$messageId,
394
            'caption' => $caption,
395
            'parse_mode' => $parseMode,
396
            'caption_entities' => $captionEntities,
397
            'disable_notification' => (bool)$disableNotification,
398
            'message_thread_id' => $messageThreadId,
399
            'reply_to_message_id' => (int)$replyToMessageId,
400
            'allow_sending_without_reply' => (bool)$allowSendingWithoutReply,
401
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
402
        ]));
403
    }
404
405
    /**
406
     * Use this method to send phone contacts
407
     *
408
     * @param int|string $chatId chat_id or @channel_name
409
     * @param string $phoneNumber
410
     * @param string $firstName
411
     * @param string $lastName
412
     * @param int|null $messageThreadId
413
     * @param int|null $replyToMessageId
414
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
415
     * @param bool $disableNotification
416
     *
417
     * @return Message
418
     * @throws Exception
419
     */
420
    public function sendContact(
421
        $chatId,
422
        $phoneNumber,
423
        $firstName,
424
        $lastName = null,
425
        $messageThreadId = null,
426
        $replyToMessageId = null,
427
        $replyMarkup = null,
428
        $disableNotification = false
429
    ) {
430
        return Message::fromResponse($this->call('sendContact', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...$disableNotification))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
431
            'chat_id' => $chatId,
432
            'phone_number' => $phoneNumber,
433
            'first_name' => $firstName,
434
            'last_name' => $lastName,
435
            'message_thread_id' => $messageThreadId,
436
            'reply_to_message_id' => $replyToMessageId,
437
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
438
            'disable_notification' => (bool)$disableNotification,
439
        ]));
440
    }
441
442
    /**
443
     * Use this method when you need to tell the user that something is happening on the bot's side.
444
     * The status is set for 5 seconds or less (when a message arrives from your bot,
445
     * Telegram clients clear its typing status).
446
     *
447
     * We only recommend using this method when a response from the bot will take a noticeable amount of time to arrive.
448
     *
449
     * Type of action to broadcast. Choose one, depending on what the user is about to receive:
450
     * `typing` for text messages, `upload_photo` for photos, `record_video` or `upload_video` for videos,
451
     * `record_audio` or upload_audio for audio files, `upload_document` for general files,
452
     * `find_location` for location data.
453
     *
454
     * @param int $chatId
455
     * @param string $action
456
     *
457
     * @return bool
458
     * @throws Exception
459
     */
460
    public function sendChatAction($chatId, $action)
461
    {
462
        return $this->call('sendChatAction', [
463
            'chat_id' => $chatId,
464
            'action' => $action,
465
        ]);
466
    }
467
468
    /**
469
     * Use this method to get a list of profile pictures for a user.
470
     *
471
     * @param int $userId
472
     * @param int $offset
473
     * @param int $limit
474
     *
475
     * @return UserProfilePhotos
476
     * @throws Exception
477
     */
478
    public function getUserProfilePhotos($userId, $offset = 0, $limit = 100)
479
    {
480
        return UserProfilePhotos::fromResponse($this->call('getUserProfilePhotos', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...imit' => (int)$limit))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\UserProfilePhotos.
Loading history...
481
            'user_id' => (int)$userId,
482
            'offset' => (int)$offset,
483
            'limit' => (int)$limit,
484
        ]));
485
    }
486
487
    /**
488
     * Use this method to specify a url and receive incoming updates via an outgoing webhook.
489
     * Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url,
490
     * containing a JSON-serialized Update.
491
     * In case of an unsuccessful request, we will give up after a reasonable amount of attempts.
492
     *
493
     * @param string $url HTTPS url to send updates to. Use an empty string to remove webhook integration
494
     * @param \CURLFile|string $certificate Upload your public key certificate
495
     *                                      so that the root certificate in use can be checked
496
     * @param string|null $ip_address The fixed IP address which will be used to send webhook requests
497
     *                                instead of the IP address resolved through DNS
498
     * @param int|null $max_connections The maximum allowed number of simultaneous HTTPS connections to the webhook
499
     *                                  for update delivery, 1-100. Defaults to 40. Use lower values to limit
500
     *                                  the load on your bot's server, and higher values to increase your bot's throughput.
501
     * @param array|null $allowed_updates A JSON-serialized list of the update types you want your bot to receive.
502
     *                                    For example, specify [“message”, “edited_channel_post”, “callback_query”]
503
     *                                   to only receive updates of these types. See Update for a complete list of available update types.
504
     *                                   Specify an empty list to receive all update types except chat_member (default).
505
     *                                   If not specified, the previous setting will be used.
506
     *                                   Please note that this parameter doesn't affect updates created before the call to the setWebhook,
507
     *                                   so unwanted updates may be received for a short period of time.
508
     * @param bool|null $drop_pending_updates Pass True to drop all pending updates
509
     * @param string|null $secret_token A secret token to be sent in a header “X-Telegram-Bot-Api-Secret-Token” in every webhook request,
510
     *                                  1-256 characters. Only characters A-Z, a-z, 0-9, _ and - are allowed.
511
     *                                  The header is useful to ensure that the request comes from a webhook set by you.
512
     *
513
     * @return string
514
     *
515
     * @throws Exception
516
     */
517
    public function setWebhook(
518
        $url = '',
519
        $certificate = null,
520
        $ip_address = null,
521
        $max_connections = 40,
522
        $allowed_updates = null,
523
        $drop_pending_updates = false,
524
        $secret_token = null
525
    ) {
526
        return $this->call('setWebhook', [
527
            'url' => $url,
528
            'certificate' => $certificate,
529
            'ip_address' => $ip_address,
530
            'max_connections' => $max_connections,
531
            'allowed_updates' => $allowed_updates,
532
            'drop_pending_updates' => $drop_pending_updates,
533
            'secret_token' => $secret_token
534
        ]);
535
    }
536
537
538
    /**
539
     * Use this method to clear webhook and use getUpdates again!
540
     *
541
     * @param bool $drop_pending_updates Pass True to drop all pending updates
542
     *
543
     * @return mixed
544
     *
545
     * @throws Exception
546
     */
547
    public function deleteWebhook($drop_pending_updates = false)
548
    {
549
        return $this->call('deleteWebhook', ['drop_pending_updates' => $drop_pending_updates]);
550
    }
551
552
    /**
553
     * Use this method to get current webhook status. Requires no parameters.
554
     * On success, returns a WebhookInfo object. If the bot is using getUpdates,
555
     * will return an object with the url field empty.
556
     *
557
     * @return WebhookInfo
558
     * @throws Exception
559
     * @throws InvalidArgumentException
560
     */
561
    public function getWebhookInfo()
562
    {
563
        return WebhookInfo::fromResponse($this->call('getWebhookInfo'));
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...call('getWebhookInfo')) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\WebhookInfo.
Loading history...
564
    }
565
566
    /**
567
     * A simple method for testing your bot's auth token.Requires no parameters.
568
     * Returns basic information about the bot in form of a User object.
569
     *
570
     * @return User
571
     * @throws Exception
572
     * @throws InvalidArgumentException
573
     */
574
    public function getMe()
575
    {
576
        return User::fromResponse($this->call('getMe'));
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...e($this->call('getMe')) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\User.
Loading history...
577
    }
578
579
    /**
580
     * Use this method to receive incoming updates using long polling.
581
     * An Array of Update objects is returned.
582
     *
583
     * Notes
584
     * 1. This method will not work if an outgoing webhook is set up.
585
     * 2. In order to avoid getting duplicate updates, recalculate offset after each server response.
586
     *
587
     * @param int $offset
588
     * @param int $limit
589
     * @param int $timeout
590
     *
591
     * @return Update[]
592
     * @throws Exception
593
     * @throws InvalidArgumentException
594
     */
595 2
    public function getUpdates($offset = 0, $limit = 100, $timeout = 0)
596
    {
597 2
        $updates = ArrayOfUpdates::fromResponse($this->call('getUpdates', [
598 2
            'offset' => $offset,
599 2
            'limit' => $limit,
600 2
            'timeout' => $timeout,
601 2
        ]));
602
603 2
        if ($this->tracker instanceof Botan) {
0 ignored issues
show
introduced by
$this->tracker is always a sub-type of TelegramBot\Api\Botan.
Loading history...
604
            foreach ($updates as $update) {
605
                $this->trackUpdate($update);
606
            }
607
        }
608
609 2
        return $updates;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $updates returns an array which contains values of type true which are incompatible with the documented value type TelegramBot\Api\Types\Update.
Loading history...
610
    }
611
612
    /**
613
     * Use this method to send point on the map. On success, the sent Message is returned.
614
     *
615
     * @param int|string $chatId
616
     * @param float $latitude
617
     * @param float $longitude
618
     * @param int|null $messageThreadId
619
     * @param int|null $replyToMessageId
620
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
621
     * @param bool $disableNotification
622
     *
623
     * @param null|int $livePeriod
624
     *
625
     * @return Message
626
     *
627
     * @throws Exception
628
     */
629
    public function sendLocation(
630
        $chatId,
631
        $latitude,
632
        $longitude,
633
        $messageThreadId = null,
634
        $replyToMessageId = null,
635
        $replyMarkup = null,
636
        $disableNotification = false,
637
        $livePeriod = null
638
    ) {
639
        return Message::fromResponse($this->call('sendLocation', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...$disableNotification))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
640
            'chat_id'              => $chatId,
641
            'latitude'             => $latitude,
642
            'longitude'            => $longitude,
643
            'live_period'          => $livePeriod,
644
            'message_thread_id'    => $messageThreadId,
645
            'reply_to_message_id'  => $replyToMessageId,
646
            'reply_markup'         => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
647
            'disable_notification' => (bool)$disableNotification,
648
        ]));
649
    }
650
651
    /**
652
     * Use this method to edit live location messages sent by the bot or via the bot (for inline bots).
653
     *
654
     * @param int|string                                                              $chatId
655
     * @param int                                                                     $messageId
656
     * @param string                                                                  $inlineMessageId
657
     * @param float                                                                   $latitude
658
     * @param float                                                                   $longitude
659
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
660
     *
661
     * @return Message
662
     *
663
     * @throws Exception
664
     */
665
    public function editMessageLiveLocation(
666
        $chatId,
667
        $messageId,
668
        $inlineMessageId,
669
        $latitude,
670
        $longitude,
671
        $replyMarkup = null
672
    ) {
673
        return Message::fromResponse($this->call('sendLocation', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...eplyMarkup->toJson()))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
674
            'chat_id'           => $chatId,
675
            'message_id'        => $messageId,
676
            'inline_message_id' => $inlineMessageId,
677
            'latitude'          => $latitude,
678
            'longitude'         => $longitude,
679
            'reply_markup'      => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
680
        ]));
681
    }
682
683
    /**
684
     * Use this method to stop updating a live location message sent by the bot or via the bot (for inline bots) before
685
     * live_period expires.
686
     *
687
     * @param int|string                                                              $chatId
688
     * @param int                                                                     $messageId
689
     * @param string                                                                  $inlineMessageId
690
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
691
     *
692
     * @return Message
693
     *
694
     * @throws Exception
695
     */
696
    public function stopMessageLiveLocation(
697
        $chatId,
698
        $messageId,
699
        $inlineMessageId,
700
        $replyMarkup = null
701
    ) {
702
        return Message::fromResponse($this->call('sendLocation', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...eplyMarkup->toJson()))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
703
            'chat_id'           => $chatId,
704
            'message_id'        => $messageId,
705
            'inline_message_id' => $inlineMessageId,
706
            'reply_markup'      => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
707
        ]));
708
    }
709
710
    /**
711
     * Use this method to send information about a venue. On success, the sent Message is returned.
712
     *
713
     * @param int|string $chatId chat_id or @channel_name
714
     * @param float $latitude
715
     * @param float $longitude
716
     * @param string $title
717
     * @param string $address
718
     * @param string|null $foursquareId
719
     * @param int|null $messageThreadId
720
     * @param int|null $replyToMessageId
721
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
722
     * @param bool $disableNotification
723
     *
724
     * @return Message
725
     * @throws Exception
726
     */
727
    public function sendVenue(
728
        $chatId,
729
        $latitude,
730
        $longitude,
731
        $title,
732
        $address,
733
        $foursquareId = null,
734
        $messageThreadId = null,
735
        $replyToMessageId = null,
736
        $replyMarkup = null,
737
        $disableNotification = false
738
    ) {
739
        return Message::fromResponse($this->call('sendVenue', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...$disableNotification))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
740
            'chat_id' => $chatId,
741
            'latitude' => $latitude,
742
            'longitude' => $longitude,
743
            'title' => $title,
744
            'address' => $address,
745
            'foursquare_id' => $foursquareId,
746
            'message_thread_id' => $messageThreadId,
747
            'reply_to_message_id' => $replyToMessageId,
748
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
749
            'disable_notification' => (bool)$disableNotification,
750
        ]));
751
    }
752
753
    /**
754
     * Use this method to send .webp stickers. On success, the sent Message is returned.
755
     *
756
     * @param int|string $chatId chat_id or @channel_name
757
     * @param \CURLFile|string $sticker
758
     * @param int|null $replyToMessageId
759
     * @param null $replyMarkup
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $replyMarkup is correct as it would always require null to be passed?
Loading history...
760
     * @param bool $disableNotification Sends the message silently. Users will receive a notification with no sound.
761
     * @param bool $protectContent Protects the contents of the sent message from forwarding and saving
762
     * @param bool $allowSendingWithoutReply Pass True if the message should be sent even if the specified replied-to message is not found
763
     *
764
     * @return Message
765
     * @throws InvalidArgumentException
766
     * @throws Exception
767
     */
768
    public function sendSticker(
769
        $chatId,
770
        $sticker,
771
        $messageThreadId = null,
772
        $replyToMessageId = null,
773
        $replyMarkup = null,
774
        $disableNotification = false,
775
        $protectContent = false,
776
        $allowSendingWithoutReply = false
777
    ) {
778
        return Message::fromResponse($this->call('sendSticker', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...wSendingWithoutReply))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
779
            'chat_id' => $chatId,
780
            'sticker' => $sticker,
781
            'message_thread_id' => $messageThreadId,
782
            'reply_to_message_id' => $replyToMessageId,
783
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
0 ignored issues
show
introduced by
The condition is_null($replyMarkup) is always true.
Loading history...
784
            'disable_notification' => (bool)$disableNotification,
785
            'protect_content' => (bool)$protectContent,
786
            'allow_sending_without_reply' => (bool)$allowSendingWithoutReply,
787
        ]));
788
    }
789
790
    /**
791
     * @param string $name Name of the sticker set
792
     *
793
     * @throws InvalidArgumentException
794
     * @throws Exception
795
     */
796
    public function getStickerSet($name)
797
    {
798
        return StickerSet::fromResponse($this->call('getStickerSet', [
799
            'name' => $name,
800
        ]));
801
    }
802
803
    /**
804
     * @param array[] $customEmojiIds List of custom emoji identifiers.
805
     *                                  At most 200 custom emoji identifiers can be specified.
806
     *
807
     * @throws InvalidArgumentException
808
     * @throws Exception
809
     *
810
     * @author bernard-ng <[email protected]>
811
     */
812
    public function getCustomEmojiStickers($customEmojiIds = [])
813
    {
814
        return StickerSet::fromResponse($this->call('getCustomEmojiStickers', [
815
            'custom_emoji_ids' => $customEmojiIds,
816
        ]));
817
    }
818
819
    /**
820
     * Use this method to create a new sticker set owned by a user.
821
     * The bot will be able to edit the sticker set thus created.
822
     * You must use exactly one of the fields png_sticker, tgs_sticker, or webm_sticker.
823
     * Returns True on success.
824
     *
825
     * @param int $userId User identifier of created sticker set owner
826
     * @param string $pngSticker PNG image with the sticker, must be up to 512 kilobytes in size,
827
     *                           dimensions must not exceed 512px, and either width or height must be exactly 512px.
828
     *
829
     * @return File
830
     *
831
     * @throws InvalidArgumentException
832
     * @throws Exception
833
     */
834
    public function uploadStickerFile($userId, $pngSticker)
835
    {
836
        return File::fromResponse($this->call('uploadStickerFile', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...cker' => $pngSticker))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\File.
Loading history...
837
            'user_id' => $userId,
838
            'png_sticker' => $pngSticker,
839
        ]));
840
    }
841
842
    /**
843
     * Use this method to create a new sticker set owned by a user.
844
     * The bot will be able to edit the sticker set thus created.
845
     * You must use exactly one of the fields png_sticker, tgs_sticker, or webm_sticker. Returns True on success.
846
     *
847
     * @param int $userId User identifier of created sticker set owner
848
     * @param string $name Short name of sticker set, to be used in t.me/addstickers/ URLs (e.g., animals).
849
     *                     Can contain only english letters, digits and underscores. Must begin with a letter,
850
     *                     can't contain consecutive underscores and must end in “_by_<bot username>”.
851
     *                     <bot_username> is case insensitive. 1-64 characters.
852
     * @param string $title Sticker set title, 1-64 characters
853
     * @param string $pngSticker PNG image with the sticker, must be up to 512 kilobytes in size,
854
     *                           dimensions must not exceed 512px, and either width or height must be exactly 512px.
855
     *                           Pass a file_id as a String to send a file that already exists on the Telegram servers,
856
     *                           pass an HTTP URL as a String for Telegram to get a file from the Internet,
857
     *                           or upload a new one using multipart/form-data.
858
     * @param string $tgsSticker TGS animation with the sticker, uploaded using multipart/form-data.
859
     *                           See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements
860
     * @param string $webmSticker WebP animation with the sticker, uploaded using multipart/form-data.
861
     *                            See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements
862
     * @param string $stickerType Sticker type, one of “png”, “tgs”, or “webp”
863
     * @param string $emojis One or more emoji corresponding to the sticker
864
     * @param MaskPosition|null $maskPosition A JSON-serialized object for position where the mask should be placed on faces
865
     *
866
     * @throws InvalidArgumentException
867
     * @throws Exception
868
     *
869
     * @author bernard-ng <[email protected]>
870
     */
871
    public function createNewStickerSet(
872
        $userId,
873
        $name,
874
        $title,
875
        $emojis,
876
        $pngSticker,
877
        $tgsSticker = null,
878
        $webmSticker = null,
879
        $stickerType = null,
880
        $maskPosition = null
881
    ) {
882
        return $this->call('createNewStickerSet', [
883
            'user_id' => $userId,
884
            'name' => $name,
885
            'title' => $title,
886
            'png_sticker' => $pngSticker,
887
            'tgs_sticker' => $tgsSticker,
888
            'webm_sticker' => $webmSticker,
889
            'sticker_type' => $stickerType,
890
            'emojis' => $emojis,
891
            'mask_position' => is_null($maskPosition) ? $maskPosition : $maskPosition->toJson(),
892
        ]);
893
    }
894
895
    /**
896
     * Use this method to add a new sticker to a set created by the bot.
897
     * You must use exactly one of the fields png_sticker, tgs_sticker, or webm_sticker.
898
     * Animated stickers can be added to animated sticker sets and only to them.
899
     * Animated sticker sets can have up to 50 stickers.
900
     * Static sticker sets can have up to 120 stickers. Returns True on success.
901
     *
902
     * @throws InvalidArgumentException
903
     * @throws Exception
904
     */
905
    public function addStickerToSet(
906
        $userId,
907
        $name,
908
        $emojis,
909
        $pngSticker,
910
        $tgsSticker = null,
911
        $webmSticker = null,
912
        $maskPosition = null
913
    ) {
914
        return $this->call('addStickerToSet', [
915
            'user_id' => $userId,
916
            'name' => $name,
917
            'png_sticker' => $pngSticker,
918
            'tgs_sticker' => $tgsSticker,
919
            'webm_sticker' => $webmSticker,
920
            'emojis' => $emojis,
921
            'mask_position' => is_null($maskPosition) ? $maskPosition : $maskPosition->toJson(),
922
        ]);
923
    }
924
925
    /**
926
     * Use this method to move a sticker in a set created by the bot to a specific position.
927
     * Returns True on success.
928
     *
929
     * @param string $sticker File identifier of the sticker
930
     * @param int $position New sticker position in the set, zero-based
931
     *
932
     * @return bool
933
     *
934
     * @throws InvalidArgumentException
935
     * @throws Exception
936
     */
937
    public function setStickerPositionInSet($sticker, $position)
938
    {
939
        return $this->call('setStickerPositionInSet', [
940
            'sticker' => $sticker,
941
            'position' => $position,
942
        ]);
943
    }
944
945
    /**
946
     * Use this method to delete a sticker from a set created by the bot.
947
     * Returns True on success.
948
     *
949
     * @param string $name Sticker set name
950
     * @param string $userId User identifier of sticker set owner
951
     * @param File|null $thumb A PNG image with the thumbnail,
952
     *                         must be up to 128 kilobytes in size and have width and height exactly 100px,
953
     *                         or a TGS animation with the thumbnail up to 32 kilobytes in size
954
     *
955
     * @return bool
956
     *
957
     * @throws InvalidArgumentException
958
     * @throws Exception
959
     */
960
    public function setStickerSetThumb($name, $userId, $thumb = null)
961
    {
962
        return $this->call('setStickerSetThumb', [
963
            'name' => $name,
964
            'user_id' => $userId,
965
            'thumb' => $thumb,
966
        ]);
967
    }
968
969
    /**
970
     * Use this method to send video files,
971
     * Telegram clients support mp4 videos (other formats may be sent as Document).
972
     * On success, the sent Message is returned.
973
     *
974
     * @param int|string $chatId chat_id or @channel_name
975
     * @param \CURLFile|string $video
976
     * @param int|null $duration
977
     * @param string|null $caption
978
     * @param int|null $messageThreadId
979
     * @param int|null $replyToMessageId
980
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
981
     * @param bool $disableNotification
982
     * @param bool $supportsStreaming Pass True, if the uploaded video is suitable for streaming
983
     * @param string|null $parseMode
984
     *
985
     * @return Message
986
     * @throws InvalidArgumentException
987
     * @throws Exception
988
     */
989
    public function sendVideo(
990
        $chatId,
991
        $video,
992
        $duration = null,
993
        $caption = null,
994
        $messageThreadId = null,
995
        $replyToMessageId = null,
996
        $replyMarkup = null,
997
        $disableNotification = false,
998
        $supportsStreaming = false,
999
        $parseMode = null
1000
    ) {
1001
        return Message::fromResponse($this->call('sendVideo', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T..._mode' => $parseMode))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
1002
            'chat_id' => $chatId,
1003
            'video' => $video,
1004
            'duration' => $duration,
1005
            'caption' => $caption,
1006
            'message_thread_id' => $messageThreadId,
1007
            'reply_to_message_id' => $replyToMessageId,
1008
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1009
            'disable_notification' => (bool)$disableNotification,
1010
            'supports_streaming' => (bool)$supportsStreaming,
1011
            'parse_mode' => $parseMode
1012
        ]));
1013
    }
1014
1015
    /**
1016
     * Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound),
1017
     * On success, the sent Message is returned.
1018
     * Bots can currently send animation files of up to 50 MB in size, this limit may be changed in the future.
1019
     *
1020
     * @param int|string $chatId chat_id or @channel_name
1021
     * @param \CURLFile|string $animation
1022
     * @param int|null $duration
1023
     * @param string|null $caption
1024
     * @param int|null $messageThreadId
1025
     * @param int|null $replyToMessageId
1026
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
1027
     * @param bool $disableNotification
1028
     * @param string|null $parseMode
1029
     *
1030
     * @return Message
1031
     * @throws InvalidArgumentException
1032
     * @throws Exception
1033
     */
1034
    public function sendAnimation(
1035
        $chatId,
1036
        $animation,
1037
        $duration = null,
1038
        $caption = null,
1039
        $messageThreadId = null,
1040
        $replyToMessageId = null,
1041
        $replyMarkup = null,
1042
        $disableNotification = false,
1043
        $parseMode = null
1044
    ) {
1045
        return Message::fromResponse($this->call('sendAnimation', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T..._mode' => $parseMode))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
1046
            'chat_id' => $chatId,
1047
            'animation' => $animation,
1048
            'duration' => $duration,
1049
            'caption' => $caption,
1050
            'message_thread_id' => $messageThreadId,
1051
            'reply_to_message_id' => $replyToMessageId,
1052
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1053
            'disable_notification' => (bool)$disableNotification,
1054
            'parse_mode' => $parseMode
1055
        ]));
1056
    }
1057
1058
    /**
1059
     * Use this method to send audio files,
1060
     * if you want Telegram clients to display the file as a playable voice message.
1061
     * For this to work, your audio must be in an .ogg file encoded with OPUS
1062
     * (other formats may be sent as Audio or Document).
1063
     * On success, the sent Message is returned.
1064
     * Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future.
1065
     *
1066
     * @param int|string $chatId chat_id or @channel_name
1067
     * @param \CURLFile|string $voice
1068
     * @param string $caption Voice message caption, 0-1024 characters after entities parsing
1069
     * @param int|null $duration
1070
     * @param int|null $messageThreadId
1071
     * @param int|null $replyToMessageId
1072
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
1073
     * @param bool $disableNotification
1074
     * @param bool $allowSendingWithoutReply Pass True, if the message should be sent even if the specified
1075
     *     replied-to message is not found
1076
     * @param string|null $parseMode
1077
     *
1078
     * @return Message
1079
     * @throws InvalidArgumentException
1080
     * @throws Exception
1081
     */
1082
    public function sendVoice(
1083
        $chatId,
1084
        $voice,
1085
        $caption = null,
1086
        $duration = null,
1087
        $messageThreadId = null,
1088
        $replyToMessageId = null,
1089
        $replyMarkup = null,
1090
        $disableNotification = false,
1091
        $allowSendingWithoutReply = false,
1092
        $parseMode = null
1093
    ) {
1094
        return Message::fromResponse($this->call('sendVoice', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T..._mode' => $parseMode))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
1095
            'chat_id' => $chatId,
1096
            'voice' => $voice,
1097
            'caption' => $caption,
1098
            'duration' => $duration,
1099
            'message_thread_id' => $messageThreadId,
1100
            'reply_to_message_id' => $replyToMessageId,
1101
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1102
            'disable_notification' => (bool)$disableNotification,
1103
            'allow_sending_without_reply' => $allowSendingWithoutReply,
1104
            'parse_mode' => $parseMode
1105
        ]));
1106
    }
1107
1108
    /**
1109
     * Use this method to forward messages of any kind. Service messages can't be forwarded.
1110
     * On success, the sent Message is returned.
1111
     *
1112
     * @param int|string $chatId Unique identifier for the target chat or username of the target channel (in the format @channelusername)
1113
     * @param int $fromChatId Unique identifier for the chat where the original message was sent (or channel username in the format @channelusername)
1114
     * @param $messageId Message identifier in the chat specified in from_chat_id
1115
     * @param int|null $messageThreadId Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
1116
     * @param bool $protectContent Protects the contents of the forwarded message from forwarding and saving
1117
     * @param bool $disableNotification Sends the message silently. Users will receive a notification with no sound.
1118
     *
1119
     * @return Message
1120
     * @throws Exception
1121
     * @throws HttpException
1122
     * @throws InvalidJsonException
1123
     */
1124
    public function forwardMessage(
1125
        $chatId,
1126
        $fromChatId,
1127
        $messageId,
1128
        $messageThreadId = null,
1129
        $protectContent = false,
1130
        $disableNotification = false
1131
    ) {
1132
        return Message::fromResponse($this->call('forwardMessage', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...$disableNotification))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
1133
            'chat_id' => $chatId,
1134
            'from_chat_id' => $fromChatId,
1135
            'message_id' => $messageId,
1136
            'message_thread_id' => $messageThreadId,
1137
            'protect_content' => $protectContent,
1138
            'disable_notification' => (bool)$disableNotification,
1139
        ]));
1140
    }
1141
1142
    /**
1143
     * Use this method to send audio files,
1144
     * if you want Telegram clients to display them in the music player.
1145
     * Your audio must be in the .mp3 format.
1146
     * On success, the sent Message is returned.
1147
     * Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future.
1148
     *
1149
     * For backward compatibility, when the fields title and performer are both empty
1150
     * and the mime-type of the file to be sent is not audio/mpeg, the file will be sent as a playable voice message.
1151
     * For this to work, the audio must be in an .ogg file encoded with OPUS.
1152
     * This behavior will be phased out in the future. For sending voice messages, use the sendVoice method instead.
1153
     *
1154
     * @param int|string $chatId chat_id or @channel_name
1155
     * @param \CURLFile|string $audio
1156
     * @param int|null $duration
1157
     * @param string|null $performer
1158
     * @param string|null $title
1159
     * @param int|null $replyToMessageId
1160
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
1161
     * @param bool $disableNotification
1162
     * @param string|null $parseMode
1163
     *
1164
     * @return Message
1165
     * @throws InvalidArgumentException
1166
     * @throws Exception
1167
     * @deprecated since 20th February. Removed backward compatibility from the method sendAudio.
1168
     * Voice messages now must be sent using the method sendVoice.
1169
     * There is no more need to specify a non-empty title or performer while sending the audio by file_id.
1170
     *
1171
     */
1172
    public function sendAudio(
1173
        $chatId,
1174
        $audio,
1175
        $duration = null,
1176
        $performer = null,
1177
        $title = null,
1178
        $replyToMessageId = null,
1179
        $replyMarkup = null,
1180
        $disableNotification = false,
1181
        $parseMode = null
1182
    ) {
1183
        return Message::fromResponse($this->call('sendAudio', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T..._mode' => $parseMode))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
1184
            'chat_id' => $chatId,
1185
            'audio' => $audio,
1186
            'duration' => $duration,
1187
            'performer' => $performer,
1188
            'title' => $title,
1189
            'reply_to_message_id' => $replyToMessageId,
1190
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1191
            'disable_notification' => (bool)$disableNotification,
1192
            'parse_mode' => $parseMode
1193
        ]));
1194
    }
1195
1196
    /**
1197
     * Use this method to send photos. On success, the sent Message is returned.
1198
     *
1199
     * @param int|string $chatId chat_id or @channel_name
1200
     * @param \CURLFile|string $photo
1201
     * @param string|null $caption
1202
     * @param int|null $messageThreadId
1203
     * @param int|null $replyToMessageId
1204
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
1205
     * @param bool $disableNotification
1206
     * @param string|null $parseMode
1207
     *
1208
     * @return Message
1209
     * @throws InvalidArgumentException
1210
     * @throws Exception
1211
     */
1212
    public function sendPhoto(
1213
        $chatId,
1214
        $photo,
1215
        $caption = null,
1216
        $messageThreadId = null,
1217
        $replyToMessageId = null,
1218
        $replyMarkup = null,
1219
        $disableNotification = false,
1220
        $parseMode = null
1221
    ) {
1222
        return Message::fromResponse($this->call('sendPhoto', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T..._mode' => $parseMode))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
1223
            'chat_id' => $chatId,
1224
            'photo' => $photo,
1225
            'caption' => $caption,
1226
            'message_thread_id' => $messageThreadId,
1227
            'reply_to_message_id' => $replyToMessageId,
1228
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1229
            'disable_notification' => (bool)$disableNotification,
1230
            'parse_mode' => $parseMode
1231
        ]));
1232
    }
1233
1234
    /**
1235
     * Use this method to send general files. On success, the sent Message is returned.
1236
     * Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
1237
     *
1238
     * @param int|string $chatId chat_id or @channel_name
1239
     * @param \CURLFile|string $document
1240
     * @param string|null $caption
1241
     * @param int|null $messageThreadId
1242
     * @param int|null $replyToMessageId
1243
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
1244
     * @param bool $disableNotification
1245
     * @param string|null $parseMode
1246
     *
1247
     * @return Message
1248
     * @throws InvalidArgumentException
1249
     * @throws Exception
1250
     */
1251
    public function sendDocument(
1252
        $chatId,
1253
        $document,
1254
        $caption = null,
1255
        $messageThreadId = null,
1256
        $replyToMessageId = null,
1257
        $replyMarkup = null,
1258
        $disableNotification = false,
1259
        $parseMode = null
1260
    ) {
1261
        return Message::fromResponse($this->call('sendDocument', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T..._mode' => $parseMode))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
1262
            'chat_id' => $chatId,
1263
            'document' => $document,
1264
            'caption' => $caption,
1265
            'message_thread_id' => $messageThreadId,
1266
            'reply_to_message_id' => $replyToMessageId,
1267
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1268
            'disable_notification' => (bool)$disableNotification,
1269
            'parse_mode' => $parseMode
1270
        ]));
1271
    }
1272
1273
    /**
1274
     * Use this method to get basic info about a file and prepare it for downloading.
1275
     * For the moment, bots can download files of up to 20MB in size.
1276
     * On success, a File object is returned.
1277
     * The file can then be downloaded via the link https://api.telegram.org/file/bot<token>/<file_path>,
1278
     * where <file_path> is taken from the response.
1279
     * It is guaranteed that the link will be valid for at least 1 hour.
1280
     * When the link expires, a new one can be requested by calling getFile again.
1281
     *
1282
     * @param $fileId
1283
     *
1284
     * @return File
1285
     * @throws InvalidArgumentException
1286
     * @throws Exception
1287
     */
1288
    public function getFile($fileId)
1289
    {
1290
        return File::fromResponse($this->call('getFile', ['file_id' => $fileId]));
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...'file_id' => $fileId))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\File.
Loading history...
1291
    }
1292
1293
    /**
1294
     * Get file contents via cURL
1295
     *
1296
     * @param $fileId
1297
     *
1298
     * @return string
1299
     *
1300
     * @throws HttpException
1301
     * @throws Exception
1302
     */
1303
    public function downloadFile($fileId)
1304
    {
1305
        $file = $this->getFile($fileId);
1306
        $options = [
1307
            CURLOPT_HEADER => 0,
1308
            CURLOPT_HTTPGET => 1,
1309
            CURLOPT_RETURNTRANSFER => 1,
1310
            CURLOPT_URL => $this->getFileUrl().'/'.$file->getFilePath(),
1311
        ];
1312
1313
        return $this->executeCurl($options);
1314
    }
1315
1316
    /**
1317
     * Use this method to send answers to an inline query. On success, True is returned.
1318
     * No more than 50 results per query are allowed.
1319
     *
1320
     * @param string $inlineQueryId
1321
     * @param AbstractInlineQueryResult[] $results
1322
     * @param int $cacheTime
1323
     * @param bool $isPersonal
1324
     * @param string $nextOffset
1325
     * @param string $switchPmText
1326
     * @param string $switchPmParameter
1327
     *
1328
     * @return mixed
1329
     * @throws Exception
1330
     */
1331
    public function answerInlineQuery(
1332
        $inlineQueryId,
1333
        $results,
1334
        $cacheTime = 300,
1335
        $isPersonal = false,
1336
        $nextOffset = '',
1337
        $switchPmText = null,
1338
        $switchPmParameter = null
1339
    ) {
1340
        $results = array_map(function ($item) {
1341
            /* @var AbstractInlineQueryResult $item */
1342
            return json_decode($item->toJson(), true);
1343
        }, $results);
1344
1345
        return $this->call('answerInlineQuery', [
1346
            'inline_query_id' => $inlineQueryId,
1347
            'results' => json_encode($results),
1348
            'cache_time' => $cacheTime,
1349
            'is_personal' => $isPersonal,
1350
            'next_offset' => $nextOffset,
1351
            'switch_pm_text' => $switchPmText,
1352
            'switch_pm_parameter' => $switchPmParameter,
1353
        ]);
1354
    }
1355
1356
    /**
1357
     * Use this method to kick a user from a group or a supergroup.
1358
     * In the case of supergroups, the user will not be able to return to the group
1359
     * on their own using invite links, etc., unless unbanned first.
1360
     * The bot must be an administrator in the group for this to work. Returns True on success.
1361
     *
1362
     * @param int|string $chatId Unique identifier for the target group
1363
     * or username of the target supergroup (in the format @supergroupusername)
1364
     * @param int $userId Unique identifier of the target user
1365
     * @param null|int $untilDate Date when the user will be unbanned, unix time.
1366
     *                            If user is banned for more than 366 days or less than 30 seconds from the current time
1367
     *                            they are considered to be banned forever
1368
     *
1369
     * @return bool
1370
     * @throws Exception
1371
     */
1372
    public function kickChatMember($chatId, $userId, $untilDate = null)
1373
    {
1374
        return $this->call('kickChatMember', [
1375
            'chat_id' => $chatId,
1376
            'user_id' => $userId,
1377
            'until_date' => $untilDate
1378
        ]);
1379
    }
1380
1381
    /**
1382
     * Use this method to unban a previously kicked user in a supergroup.
1383
     * The user will not return to the group automatically, but will be able to join via link, etc.
1384
     * The bot must be an administrator in the group for this to work. Returns True on success.
1385
     *
1386
     * @param int|string $chatId Unique identifier for the target group
1387
     * or username of the target supergroup (in the format @supergroupusername)
1388
     * @param int $userId Unique identifier of the target user
1389
     *
1390
     * @return bool
1391
     * @throws Exception
1392
     */
1393
    public function unbanChatMember($chatId, $userId)
1394
    {
1395
        return $this->call('unbanChatMember', [
1396
            'chat_id' => $chatId,
1397
            'user_id' => $userId,
1398
        ]);
1399
    }
1400
1401
    /**
1402
     * Use this method to send answers to callback queries sent from inline keyboards.
1403
     * The answer will be displayed to the user as a notification at the top of the chat screen or as an alert.
1404
     *
1405
     * @param $callbackQueryId
1406
     * @param string|null $text
1407
     * @param bool $showAlert
1408
     * @param string|null $url
1409
     * @param int $cacheTime
1410
     *
1411
     * @return bool
1412
     * @throws Exception
1413
     */
1414
    public function answerCallbackQuery($callbackQueryId, $text = null, $showAlert = false, $url = null, $cacheTime = 0)
1415
    {
1416
        return $this->call('answerCallbackQuery', [
1417
            'callback_query_id' => $callbackQueryId,
1418
            'text' => $text,
1419
            'show_alert' => (bool)$showAlert,
1420
            'url' => $url,
1421
            'cache_time' => $cacheTime
1422
        ]);
1423
    }
1424
1425
    /**
1426
     * Use this method to change the list of the bot's commands. Returns True on success.
1427
     *
1428
     * @param $commands
1429
     *
1430
     * @return mixed
1431
     * @throws Exception
1432
     * @throws HttpException
1433
     * @throws InvalidJsonException
1434
     */
1435
    public function setMyCommands($commands)
1436
    {
1437
        return $this->call(
1438
            'setMyCommands',
1439
            [
1440
                'commands' => json_encode($commands)
1441
            ]
1442
        );
1443
    }
1444
1445
    /**
1446
     * Use this method to get the current list of the bot's commands. Requires no parameters.
1447
     * Returns Array of BotCommand on success.
1448
     *
1449
     * @return BotCommand[]
1450
     *
1451
     * @throws Exception
1452
     * @throws HttpException
1453
     * @throws InvalidJsonException
1454
     */
1455
    public function getMyCommands()
1456
    {
1457
        return ArrayOfBotCommand::fromResponse($this->call('getMyCommands'));
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...>call('getMyCommands')) returns an array which contains values of type true which are incompatible with the documented value type TelegramBot\Api\Types\BotCommand.
Loading history...
1458
    }
1459
1460
    /**
1461
     * Use this method to edit text messages sent by the bot or via the bot
1462
     *
1463
     * @param int|string $chatId
1464
     * @param int $messageId
1465
     * @param string $text
1466
     * @param string $inlineMessageId
1467
     * @param string|null $parseMode
1468
     * @param bool $disablePreview
1469
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
1470
     *
1471
     * @return Message
1472
     * @throws Exception
1473
     */
1474
    public function editMessageText(
1475
        $chatId,
1476
        $messageId,
1477
        $text,
1478
        $parseMode = null,
1479
        $disablePreview = false,
1480
        $replyMarkup = null,
1481
        $inlineMessageId = null
1482
    ) {
1483
        return Message::fromResponse($this->call('editMessageText', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...eplyMarkup->toJson()))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
1484
            'chat_id' => $chatId,
1485
            'message_id' => $messageId,
1486
            'text' => $text,
1487
            'inline_message_id' => $inlineMessageId,
1488
            'parse_mode' => $parseMode,
1489
            'disable_web_page_preview' => $disablePreview,
1490
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1491
        ]));
1492
    }
1493
1494
    /**
1495
     * Use this method to edit text messages sent by the bot or via the bot
1496
     *
1497
     * @param int|string $chatId
1498
     * @param int $messageId
1499
     * @param string|null $caption
1500
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
1501
     * @param string $inlineMessageId
1502
     * @param string|null $parseMode
1503
     *
1504
     * @return Message
1505
     * @throws InvalidArgumentException
1506
     * @throws Exception
1507
     */
1508
    public function editMessageCaption(
1509
        $chatId,
1510
        $messageId,
1511
        $caption = null,
1512
        $replyMarkup = null,
1513
        $inlineMessageId = null,
1514
        $parseMode = null
1515
    ) {
1516
        return Message::fromResponse($this->call('editMessageCaption', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T..._mode' => $parseMode))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
1517
            'chat_id' => $chatId,
1518
            'message_id' => $messageId,
1519
            'inline_message_id' => $inlineMessageId,
1520
            'caption' => $caption,
1521
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1522
            'parse_mode' => $parseMode
1523
        ]));
1524
    }
1525
1526
    /**
1527
     * Use this method to edit animation, audio, document, photo, or video messages.
1528
     * If a message is a part of a message album, then it can be edited only to a photo or a video.
1529
     * Otherwise, message type can be changed arbitrarily.
1530
     * When inline message is edited, new file can't be uploaded.
1531
     * Use previously uploaded file via its file_id or specify a URL.
1532
     * On success, if the edited message was sent by the bot, the edited Message is returned, otherwise True is returned
1533
     *
1534
     * @param $chatId
1535
     * @param $messageId
1536
     * @param InputMedia $media
1537
     * @param string|null $inlineMessageId
1538
     * @param string|null $replyMarkup
1539
     * @return bool|Message
1540
     *
1541
     * @throws Exception
1542
     * @throws HttpException
1543
     * @throws InvalidJsonException
1544
     */
1545
    public function editMessageMedia(
1546
        $chatId,
1547
        $messageId,
1548
        InputMedia $media,
1549
        $inlineMessageId = null,
1550
        $replyMarkup = null
1551
    ) {
1552
        return Message::fromResponse($this->call('editMessageMedia', [
1553
            'chat_id' => $chatId,
1554
            'message_id' => $messageId,
1555
            'inline_message_id' => $inlineMessageId,
1556
            'media' => $media->toJson(),
1557
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1558
        ]));
1559
    }
1560
1561
    /**
1562
     * Use this method to edit only the reply markup of messages sent by the bot or via the bot
1563
     *
1564
     * @param int|string $chatId
1565
     * @param int $messageId
1566
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
1567
     * @param string $inlineMessageId
1568
     *
1569
     * @return Message
1570
     * @throws Exception
1571
     */
1572
    public function editMessageReplyMarkup(
1573
        $chatId,
1574
        $messageId,
1575
        $replyMarkup = null,
1576
        $inlineMessageId = null
1577
    ) {
1578
        return Message::fromResponse($this->call('editMessageReplyMarkup', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...eplyMarkup->toJson()))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
1579
            'chat_id' => $chatId,
1580
            'message_id' => $messageId,
1581
            'inline_message_id' => $inlineMessageId,
1582
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1583
        ]));
1584
    }
1585
1586
    /**
1587
     * Use this method to delete a message, including service messages, with the following limitations:
1588
     *  - A message can only be deleted if it was sent less than 48 hours ago.
1589
     *  - Bots can delete outgoing messages in groups and supergroups.
1590
     *  - Bots granted can_post_messages permissions can delete outgoing messages in channels.
1591
     *  - If the bot is an administrator of a group, it can delete any message there.
1592
     *  - If the bot has can_delete_messages permission in a supergroup or a channel, it can delete any message there.
1593
     *
1594
     * @param int|string $chatId
1595
     * @param int $messageId
1596
     *
1597
     * @return bool
1598
     * @throws Exception
1599
     */
1600
    public function deleteMessage($chatId, $messageId)
1601
    {
1602
        return $this->call('deleteMessage', [
1603
            'chat_id' => $chatId,
1604
            'message_id' => $messageId,
1605
        ]);
1606
    }
1607
1608
    /**
1609
     * Close curl
1610
     */
1611 9
    public function __destruct()
1612
    {
1613 9
        $this->curl && curl_close($this->curl);
1614 9
    }
1615
1616
    /**
1617
     * @return string
1618
     */
1619
    public function getUrl()
1620
    {
1621
        return self::URL_PREFIX.$this->token;
1622
    }
1623
1624
    /**
1625
     * @return string
1626
     */
1627
    public function getFileUrl()
1628
    {
1629
        return self::FILE_URL_PREFIX.$this->token;
1630
    }
1631
1632
    /**
1633
     * @param Update $update
1634
     * @param string $eventName
1635
     *
1636
     * @throws Exception
1637
     */
1638
    public function trackUpdate(Update $update, $eventName = 'Message')
1639
    {
1640
        if (!in_array($update->getUpdateId(), $this->trackedEvents)) {
1641
            $this->trackedEvents[] = $update->getUpdateId();
1642
1643
            $this->track($update->getMessage(), $eventName);
1644
1645
            if (count($this->trackedEvents) > self::MAX_TRACKED_EVENTS) {
1646
                $this->trackedEvents = array_slice($this->trackedEvents, round(self::MAX_TRACKED_EVENTS / 4));
0 ignored issues
show
Bug introduced by
round(self::MAX_TRACKED_EVENTS / 4) of type double is incompatible with the type integer expected by parameter $offset of array_slice(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1646
                $this->trackedEvents = array_slice($this->trackedEvents, /** @scrutinizer ignore-type */ round(self::MAX_TRACKED_EVENTS / 4));
Loading history...
1647
            }
1648
        }
1649
    }
1650
1651
    /**
1652
     * Wrapper for tracker
1653
     *
1654
     * @param Message $message
1655
     * @param string $eventName
1656
     *
1657
     * @throws Exception
1658
     */
1659
    public function track(Message $message, $eventName = 'Message')
1660
    {
1661
        if ($this->tracker instanceof Botan) {
0 ignored issues
show
introduced by
$this->tracker is always a sub-type of TelegramBot\Api\Botan.
Loading history...
1662
            $this->tracker->track($message, $eventName);
1663
        }
1664
    }
1665
1666
    /**
1667
     * Use this method to send invoices. On success, the sent Message is returned.
1668
     *
1669
     * @param int|string $chatId
1670
     * @param string $title
1671
     * @param string $description
1672
     * @param string $payload
1673
     * @param string $providerToken
1674
     * @param string $startParameter
1675
     * @param string $currency
1676
     * @param array $prices
1677
     * @param bool $isFlexible
1678
     * @param string|null $photoUrl
1679
     * @param int|null $photoSize
1680
     * @param int|null $photoWidth
1681
     * @param int|null $photoHeight
1682
     * @param bool $needName
1683
     * @param bool $needPhoneNumber
1684
     * @param bool $needEmail
1685
     * @param bool $needShippingAddress
1686
     * @param int|null $messageThreadId
1687
     * @param int|null $replyToMessageId
1688
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
1689
     * @param bool $disableNotification
1690
     * @param string|null $providerData
1691
     * @param bool $sendPhoneNumberToProvider
1692
     * @param bool $sendEmailToProvider
1693
     *
1694
     * @return Message
1695
     * @throws Exception
1696
     */
1697
    public function sendInvoice(
1698
        $chatId,
1699
        $title,
1700
        $description,
1701
        $payload,
1702
        $providerToken,
1703
        $startParameter,
1704
        $currency,
1705
        $prices,
1706
        $isFlexible = false,
1707
        $photoUrl = null,
1708
        $photoSize = null,
1709
        $photoWidth = null,
1710
        $photoHeight = null,
1711
        $needName = false,
1712
        $needPhoneNumber = false,
1713
        $needEmail = false,
1714
        $needShippingAddress = false,
1715
        $messageThreadId = null,
1716
        $replyToMessageId = null,
1717
        $replyMarkup = null,
1718
        $disableNotification = false,
1719
        $providerData = null,
1720
        $sendPhoneNumberToProvider = false,
1721
        $sendEmailToProvider = false
1722
    ) {
1723
        return Message::fromResponse($this->call('sendInvoice', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...$sendEmailToProvider))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
1724
            'chat_id' => $chatId,
1725
            'title' => $title,
1726
            'description' => $description,
1727
            'payload' => $payload,
1728
            'provider_token' => $providerToken,
1729
            'start_parameter' => $startParameter,
1730
            'currency' => $currency,
1731
            'prices' => json_encode($prices),
1732
            'is_flexible' => $isFlexible,
1733
            'photo_url' => $photoUrl,
1734
            'photo_size' => $photoSize,
1735
            'photo_width' => $photoWidth,
1736
            'photo_height' => $photoHeight,
1737
            'need_name' => $needName,
1738
            'need_phone_number' => $needPhoneNumber,
1739
            'need_email' => $needEmail,
1740
            'need_shipping_address' => $needShippingAddress,
1741
            'reply_to_message_id' => $replyToMessageId,
1742
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1743
            'disable_notification' => (bool)$disableNotification,
1744
            'provider_data' => $providerData,
1745
            'send_phone_number_to_provider' => (bool)$sendPhoneNumberToProvider,
1746
            'send_email_to_provider' => (bool)$sendEmailToProvider
1747
        ]));
1748
    }
1749
1750
    /**
1751
     * If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, the Bot API
1752
     * will send an Update with a shipping_query field to the bot. Use this method to reply to shipping queries.
1753
     * On success, True is returned.
1754
     *
1755
     * @param string $shippingQueryId
1756
     * @param bool $ok
1757
     * @param array $shipping_options
1758
     * @param null|string $errorMessage
1759
     *
1760
     * @return bool
1761
     * @throws Exception
1762
     */
1763
    public function answerShippingQuery($shippingQueryId, $ok = true, $shipping_options = [], $errorMessage = null)
1764
    {
1765
        return $this->call('answerShippingQuery', [
1766
            'shipping_query_id' => $shippingQueryId,
1767
            'ok' => (bool)$ok,
1768
            'shipping_options' => json_encode($shipping_options),
1769
            'error_message' => $errorMessage
1770
        ]);
1771
    }
1772
1773
    /**
1774
     * Use this method to respond to such pre-checkout queries. On success, True is returned.
1775
     * Note: The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent.
1776
     *
1777
     * @param string $preCheckoutQueryId
1778
     * @param bool $ok
1779
     * @param null|string $errorMessage
1780
     *
1781
     * @return mixed
1782
     * @throws Exception
1783
     */
1784
    public function answerPreCheckoutQuery($preCheckoutQueryId, $ok = true, $errorMessage = null)
1785
    {
1786
        return $this->call('answerPreCheckoutQuery', [
1787
            'pre_checkout_query_id' => $preCheckoutQueryId,
1788
            'ok' => (bool)$ok,
1789
            'error_message' => $errorMessage
1790
        ]);
1791
    }
1792
1793
    /**
1794
     * Use this method to restrict a user in a supergroup.
1795
     * The bot must be an administrator in the supergroup for this to work and must have the appropriate admin rights.
1796
     * Pass True for all boolean parameters to lift restrictions from a user.
1797
     *
1798
     * @param string|int $chatId Unique identifier for the target chat or username of the target supergroup
1799
     *                   (in the format @supergroupusername)
1800
     * @param int $userId Unique identifier of the target user
1801
     * @param null|integer $untilDate Date when restrictions will be lifted for the user, unix time.
1802
     *                     If user is restricted for more than 366 days or less than 30 seconds from the current time,
1803
     *                     they are considered to be restricted forever
1804
     * @param bool $canSendMessages Pass True, if the user can send text messages, contacts, locations and venues
1805
     * @param bool $canSendMediaMessages No Pass True, if the user can send audios, documents, photos, videos,
1806
     *                                   video notes and voice notes, implies can_send_messages
1807
     * @param bool $canSendOtherMessages Pass True, if the user can send animations, games, stickers and
1808
     *                                   use inline bots, implies can_send_media_messages
1809
     * @param bool $canAddWebPagePreviews Pass True, if the user may add web page previews to their messages,
1810
     *                                    implies can_send_media_messages
1811
     *
1812
     * @return bool
1813
     * @throws Exception
1814
     */
1815
    public function restrictChatMember(
1816
        $chatId,
1817
        $userId,
1818
        $untilDate = null,
1819
        $canSendMessages = false,
1820
        $canSendMediaMessages = false,
1821
        $canSendOtherMessages = false,
1822
        $canAddWebPagePreviews = false
1823
    ) {
1824
        return $this->call('restrictChatMember', [
1825
            'chat_id' => $chatId,
1826
            'user_id' => $userId,
1827
            'until_date' => $untilDate,
1828
            'can_send_messages' => $canSendMessages,
1829
            'can_send_media_messages' => $canSendMediaMessages,
1830
            'can_send_other_messages' => $canSendOtherMessages,
1831
            'can_add_web_page_previews' => $canAddWebPagePreviews
1832
        ]);
1833
    }
1834
1835
    /**
1836
     * Use this method to promote or demote a user in a supergroup or a channel.
1837
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1838
     * Pass False for all boolean parameters to demote a user.
1839
     *
1840
     * @param string|int $chatId Unique identifier for the target chat or username of the target supergroup
1841
     *                   (in the format @supergroupusername)
1842
     * @param int $userId Unique identifier of the target user
1843
     * @param bool $canChangeInfo Pass True, if the administrator can change chat title, photo and other settings
1844
     * @param bool $canPostMessages Pass True, if the administrator can create channel posts, channels only
1845
     * @param bool $canEditMessages Pass True, if the administrator can edit messages of other users, channels only
1846
     * @param bool $canDeleteMessages Pass True, if the administrator can delete messages of other users
1847
     * @param bool $canInviteUsers Pass True, if the administrator can invite new users to the chat
1848
     * @param bool $canRestrictMembers Pass True, if the administrator can restrict, ban or unban chat members
1849
     * @param bool $canPinMessages Pass True, if the administrator can pin messages, supergroups only
1850
     * @param bool $canPromoteMembers Pass True, if the administrator can add new administrators with a subset of his
1851
     *                                own privileges or demote administrators that he has promoted,directly or
1852
     *                                indirectly (promoted by administrators that were appointed by him)
1853
     * @param bool $canManageTopics Pass True if the user is allowed to create, rename, close, and reopen forum topics, supergroups only
1854
     * @param bool $isAnonymous Pass True if the administrator's presence in the chat is hidden
1855
     * @return bool
1856
     *
1857
     * @throws Exception
1858
     * @throws HttpException
1859
     * @throws InvalidJsonException
1860
     */
1861
    public function promoteChatMember(
1862
        $chatId,
1863
        $userId,
1864
        $canChangeInfo = true,
1865
        $canPostMessages = true,
1866
        $canEditMessages = true,
1867
        $canDeleteMessages = true,
1868
        $canInviteUsers = true,
1869
        $canRestrictMembers = true,
1870
        $canPinMessages = true,
1871
        $canPromoteMembers = true,
1872
        $canManageTopics = true,
1873
        $isAnonymous = false
1874
    ) {
1875
        return $this->call('promoteChatMember', [
1876
            'chat_id' => $chatId,
1877
            'user_id' => $userId,
1878
            'is_anonymous' => $isAnonymous,
1879
            'can_change_info' => $canChangeInfo,
1880
            'can_post_messages' => $canPostMessages,
1881
            'can_edit_messages' => $canEditMessages,
1882
            'can_delete_messages' => $canDeleteMessages,
1883
            'can_invite_users' => $canInviteUsers,
1884
            'can_restrict_members' => $canRestrictMembers,
1885
            'can_pin_messages' => $canPinMessages,
1886
            'can_promote_members' => $canPromoteMembers,
1887
            'can_manage_topics' => $canManageTopics
1888
        ]);
1889
    }
1890
1891
    /**
1892
     * Use this method to export an invite link to a supergroup or a channel.
1893
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1894
     *
1895
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1896
     *                           (in the format @channelusername)
1897
     * @return string
1898
     * @throws Exception
1899
     */
1900
    public function exportChatInviteLink($chatId)
1901
    {
1902
        return $this->call('exportChatInviteLink', [
1903
            'chat_id' => $chatId
1904
        ]);
1905
    }
1906
1907
    /**
1908
     * Use this method to set a new profile photo for the chat. Photos can't be changed for private chats.
1909
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1910
     *
1911
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1912
     *                           (in the format @channelusername)
1913
     * @param \CURLFile|string $photo New chat photo, uploaded using multipart/form-data
1914
     *
1915
     * @return bool
1916
     * @throws Exception
1917
     */
1918
    public function setChatPhoto($chatId, $photo)
1919
    {
1920
        return $this->call('setChatPhoto', [
1921
            'chat_id' => $chatId,
1922
            'photo' => $photo
1923
        ]);
1924
    }
1925
1926
    /**
1927
     * Use this method to delete a chat photo. Photos can't be changed for private chats.
1928
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1929
     *
1930
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1931
     *                           (in the format @channelusername)
1932
     *
1933
     * @return bool
1934
     * @throws Exception
1935
     */
1936
    public function deleteChatPhoto($chatId)
1937
    {
1938
        return $this->call('deleteChatPhoto', [
1939
            'chat_id' => $chatId
1940
        ]);
1941
    }
1942
1943
    /**
1944
     * Use this method to change the title of a chat. Titles can't be changed for private chats.
1945
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1946
     *
1947
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1948
     *                           (in the format @channelusername)
1949
     * @param string $title New chat title, 1-255 characters
1950
     *
1951
     * @return bool
1952
     * @throws Exception
1953
     */
1954
    public function setChatTitle($chatId, $title)
1955
    {
1956
        return $this->call('setChatTitle', [
1957
            'chat_id' => $chatId,
1958
            'title' => $title
1959
        ]);
1960
    }
1961
1962
    /**
1963
     * Use this method to change the description of a supergroup or a channel.
1964
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1965
     *
1966
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1967
     *                   (in the format @channelusername)
1968
     * @param string|null $description New chat description, 0-255 characters
1969
     *
1970
     * @return bool
1971
     * @throws Exception
1972
     */
1973
    public function setChatDescription($chatId, $description = null)
1974
    {
1975
        return $this->call('setChatDescription', [
1976
            'chat_id' => $chatId,
1977
            'title' => $description
1978
        ]);
1979
    }
1980
1981
    /**
1982
     * Use this method to pin a message in a supergroup.
1983
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1984
     *
1985
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1986
     *                   (in the format @channelusername)
1987
     * @param int $messageId Identifier of a message to pin
1988
     * @param bool $disableNotification
1989
     *
1990
     * @return bool
1991
     * @throws Exception
1992
     */
1993
    public function pinChatMessage($chatId, $messageId, $disableNotification = false)
1994
    {
1995
        return $this->call('pinChatMessage', [
1996
            'chat_id' => $chatId,
1997
            'message_id' => $messageId,
1998
            'disable_notification' => $disableNotification
1999
        ]);
2000
    }
2001
2002
    /**
2003
     * Use this method to unpin a message in a supergroup chat.
2004
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
2005
     *
2006
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
2007
     *                   (in the format @channelusername)
2008
     *
2009
     * @return bool
2010
     * @throws Exception
2011
     */
2012
    public function unpinChatMessage($chatId)
2013
    {
2014
        return $this->call('unpinChatMessage', [
2015
            'chat_id' => $chatId
2016
        ]);
2017
    }
2018
2019
    /**
2020
     * Use this method to get up to date information about the chat
2021
     * (current name of the user for one-on-one conversations, current username of a user, group or channel, etc.).
2022
     *
2023
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
2024
     *                   (in the format @channelusername)
2025
     *
2026
     * @return Chat
2027
     * @throws Exception
2028
     */
2029
    public function getChat($chatId)
2030
    {
2031
        return Chat::fromResponse($this->call('getChat', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...'chat_id' => $chatId))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Chat.
Loading history...
2032
            'chat_id' => $chatId
2033
        ]));
2034
    }
2035
2036
    /**
2037
     * Use this method to get information about a member of a chat.
2038
     *
2039
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
2040
     *                   (in the format @channelusername)
2041
     * @param int $userId
2042
     *
2043
     * @return ChatMember
2044
     * @throws Exception
2045
     */
2046
    public function getChatMember($chatId, $userId)
2047
    {
2048
        return ChatMember::fromResponse($this->call('getChatMember', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...'user_id' => $userId))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\ChatMember.
Loading history...
2049
            'chat_id' => $chatId,
2050
            'user_id' => $userId
2051
        ]));
2052
    }
2053
2054
    /**
2055
     * Use this method for your bot to leave a group, supergroup or channel.
2056
     *
2057
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
2058
     *                   (in the format @channelusername)
2059
     *
2060
     * @return bool
2061
     * @throws Exception
2062
     */
2063
    public function leaveChat($chatId)
2064
    {
2065
        return $this->call('leaveChat', [
2066
            'chat_id' => $chatId
2067
        ]);
2068
    }
2069
2070
    /**
2071
     * Use this method to get the number of members in a chat.
2072
     *
2073
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
2074
     *                   (in the format @channelusername)
2075
     *
2076
     * @return int
2077
     * @throws Exception
2078
     */
2079
    public function getChatMembersCount($chatId)
2080
    {
2081
        return $this->call(
2082
            'getChatMembersCount',
2083
            [
2084
                'chat_id' => $chatId
2085
            ]
2086
        );
2087
    }
2088
2089
    /**
2090
     * Use this method to get a list of administrators in a chat.
2091
     *
2092
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
2093
     *                   (in the format @channelusername)
2094
     *
2095
     * @return ChatMember[]
2096
     * @throws InvalidArgumentException
2097
     * @throws Exception
2098
     */
2099
    public function getChatAdministrators($chatId)
2100
    {
2101
        return ArrayOfChatMemberEntity::fromResponse(
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...'chat_id' => $chatId))) returns an array which contains values of type true which are incompatible with the documented value type TelegramBot\Api\Types\ChatMember.
Loading history...
2102
            $this->call(
2103
                'getChatAdministrators',
2104
                [
2105
                    'chat_id' => $chatId
2106
                ]
2107
            )
2108
        );
2109
    }
2110
2111
    /**
2112
     * As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long.
2113
     * Use this method to send video messages.
2114
     * On success, the sent Message is returned.
2115
     *
2116
     * @param int|string $chatId chat_id or @channel_name
2117
     * @param \CURLFile|string $videoNote
2118
     * @param int|null $duration
2119
     * @param int|null $length
2120
     * @param int|null $messageThreadId
2121
     * @param int|null $replyToMessageId
2122
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
2123
     * @param bool $disableNotification
2124
     *
2125
     * @return Message
2126
     * @throws InvalidArgumentException
2127
     * @throws Exception
2128
     */
2129
    public function sendVideoNote(
2130
        $chatId,
2131
        $videoNote,
2132
        $duration = null,
2133
        $length = null,
2134
        $messageThreadId = null,
2135
        $replyToMessageId = null,
2136
        $replyMarkup = null,
2137
        $disableNotification = false
2138
    ) {
2139
        return Message::fromResponse($this->call('sendVideoNote', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...$disableNotification))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
2140
            'chat_id' => $chatId,
2141
            'video_note' => $videoNote,
2142
            'duration' => $duration,
2143
            'length' => $length,
2144
            'message_thread_id' => $messageThreadId,
2145
            'reply_to_message_id' => $replyToMessageId,
2146
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
2147
            'disable_notification' => (bool)$disableNotification
2148
        ]));
2149
    }
2150
2151
    /**
2152
     * Use this method to send a group of photos or videos as an album.
2153
     * On success, the sent \TelegramBot\Api\Types\Message is returned.
2154
     *
2155
     * @param int|string $chatId
2156
     * @param ArrayOfInputMedia $media
2157
     * @param bool $disableNotification
2158
     * @param int|null $messageThreadId
2159
     * @param int|null $replyToMessageId
2160
     *
2161
     * @return Message[]
2162
     * @throws Exception
2163
     */
2164
    public function sendMediaGroup(
2165
        $chatId,
2166
        $media,
2167
        $disableNotification = false,
2168
        $messageThreadId = null,
2169
        $replyToMessageId = null
2170
    ) {
2171
        return ArrayOfMessages::fromResponse($this->call('sendMediaGroup', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...$disableNotification))) returns an array which contains values of type true which are incompatible with the documented value type TelegramBot\Api\Types\Message.
Loading history...
2172
            'chat_id' => $chatId,
2173
            'media' => $media->toJson(),
2174
            'message_thread_id' => $messageThreadId,
2175
            'reply_to_message_id' => (int)$replyToMessageId,
2176
            'disable_notification' => (bool)$disableNotification
2177
        ]));
2178
    }
2179
2180
    /**
2181
     * Enable proxy for curl requests. Empty string will disable proxy.
2182
     *
2183
     * @param string $proxyString
2184
     *
2185
     * @return BotApi
2186
     */
2187
    public function setProxy($proxyString = '', $socks5 = false)
2188
    {
2189
        if (empty($proxyString)) {
2190
            $this->proxySettings = [];
2191
            return $this;
2192
        }
2193
2194
        $this->proxySettings = [
2195
            CURLOPT_PROXY => $proxyString,
2196
            CURLOPT_HTTPPROXYTUNNEL => true,
2197
        ];
2198
2199
        if ($socks5) {
2200
            $this->proxySettings[CURLOPT_PROXYTYPE] = CURLPROXY_SOCKS5;
2201
        }
2202
        return $this;
2203
    }
2204
2205
2206
    /**
2207
     * Use this method to send a native poll. A native poll can't be sent to a private chat.
2208
     * On success, the sent \TelegramBot\Api\Types\Message is returned.
2209
     *
2210
     * @param $chatId string|int Unique identifier for the target chat or username of the target channel
2211
     *                (in the format @channelusername)
2212
     * @param string $question Poll question, 1-255 characters
2213
     * @param array $options A JSON-serialized list of answer options, 2-10 strings 1-100 characters each
2214
     * @param bool $isAnonymous True, if the poll needs to be anonymous, defaults to True
2215
     * @param string|null $type Poll type, “quiz” or “regular”, defaults to “regular”
2216
     * @param bool $allowsMultipleAnswers True, if the poll allows multiple answers,
2217
     *                          ignored for polls in quiz mode, defaults to False
2218
     * @param string|null $correctOptionId 0-based identifier of the correct answer option, required for polls in quiz mode
2219
     * @param bool $isClosed Pass True, if the poll needs to be immediately closed. This can be useful for poll preview.
2220
     * @param int|null $messageThreadId Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
2221
     * @param bool $disableNotification Sends the message silently. Users will receive a notification with no sound.
2222
     * @param int|null $replyToMessageId If the message is a reply, ID of the original message
2223
     * @param object|null $replyMarkup Additional interface options. A JSON-serialized object for an inline keyboard,
2224
     *                          custom reply keyboard, instructions to remove reply
2225
     *                          keyboard or to force a reply from the user.
2226
     * @return Message
2227
     * @throws Exception
2228
     * @throws HttpException
2229
     * @throws InvalidJsonException
2230
     */
2231
    public function sendPoll(
2232
        $chatId,
2233
        $question,
2234
        $options,
2235
        $isAnonymous = false,
2236
        $type = null,
2237
        $allowsMultipleAnswers = false,
2238
        $correctOptionId = null,
2239
        $isClosed = false,
2240
        $messageThreadId = null,
2241
        $disableNotification = false,
2242
        $replyToMessageId = null,
2243
        $replyMarkup = null
2244
    ) {
2245
        return Message::fromResponse($this->call('sendPoll', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...eplyMarkup->toJson()))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Message.
Loading history...
2246
            'chat_id' => $chatId,
2247
            'question' => $question,
2248
            'options' => json_encode($options),
2249
            'is_anonymous' => (bool) $isAnonymous,
2250
            'type' => (string) $type,
2251
            'allows_multiple_answers' => (bool) $allowsMultipleAnswers,
2252
            'correct_option_id' => (int) $correctOptionId,
2253
            'is_closed' => (bool) $isClosed,
2254
            'disable_notification' => (bool) $disableNotification,
2255
            'message_thread_id' => $messageThreadId,
2256
            'reply_to_message_id' => (int) $replyToMessageId,
2257
            'reply_markup' => $replyMarkup === null ? $replyMarkup : $replyMarkup->toJson(),
2258
        ]));
2259
    }
2260
2261
    /**
2262
     * Use this method to send a dice, which will have a random value from 1 to 6.
2263
     * On success, the sent Message is returned. (Yes, we're aware of the “proper” singular of die.
2264
     * But it's awkward, and we decided to help it change. One dice at a time!)
2265
     *
2266
     * @param      $chatId string|int Unique identifier for the target chat or username of the target channel
2267
     *                (in the format @channelusername)
2268
     * @param      $emoji string Emoji on which the dice throw animation is based. Currently, must be one of “🎲”,
2269
     *     “🎯”, “🏀”, “⚽”, or “🎰”. Dice can have values 1-6 for “🎲” and “🎯”, values 1-5 for “🏀” and “⚽”, and
2270
     *     values 1-64 for “🎰”. Defaults to “🎲
2271
     * @param bool $disableNotification Sends the message silently. Users will receive a notification with no sound.
2272
     * @param int|null $messageThreadId
2273
     * @param string|null $replyToMessageId If the message is a reply, ID of the original message
2274
     * @param bool $allowSendingWithoutReply Pass True, if the message should be sent even if the specified replied-to
2275
     *     message is not found,
2276
     * @param object|null $replyMarkup Additional interface options. A JSON-serialized object for an inline keyboard,
2277
     *                          custom reply keyboard, instructions to remove reply
2278
     *                          keyboard or to force a reply from the user.
2279
     *
2280
     * @return bool|Message
2281
     * @throws Exception
2282
     * @throws HttpException
2283
     * @throws InvalidJsonException
2284
     */
2285
    public function sendDice(
2286
        $chatId,
2287
        $emoji,
2288
        $disableNotification = false,
2289
        $messageThreadId = null,
2290
        $replyToMessageId = null,
2291
        $allowSendingWithoutReply = false,
2292
        $replyMarkup = null
2293
    ) {
2294
        return Message::fromResponse($this->call('sendDice', [
2295
            'chat_id' => $chatId,
2296
            'emoji' => $emoji,
2297
            'disable_notification' => (bool) $disableNotification,
2298
            'message_thread_id' => $messageThreadId,
2299
            'reply_to_message_id' => (int) $replyToMessageId,
2300
            'allow_sending_without_reply' => (bool) $allowSendingWithoutReply,
2301
            'reply_markup' => $replyMarkup === null ? $replyMarkup : $replyMarkup->toJson(),
2302
        ]));
2303
    }
2304
2305
    /**
2306
     * Use this method to stop a poll which was sent by the bot.
2307
     * On success, the stopped \TelegramBot\Api\Types\Poll with the final results is returned.
2308
     *
2309
     * @param int|string $chatId
2310
     * @param int $messageId
2311
     * @param ReplyKeyboardMarkup|ReplyKeyboardHide|ForceReply|ReplyKeyboardRemove|null $replyMarkup
2312
     * @return Poll
2313
     * @throws InvalidArgumentException
2314
     * @throws Exception
2315
     */
2316
    public function stopPoll(
2317
        $chatId,
2318
        $messageId,
2319
        $replyMarkup = null
2320
    ) {
2321
        return Poll::fromResponse($this->call('stopPoll', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...eplyMarkup->toJson()))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\Poll.
Loading history...
2322
            'chat_id' => $chatId,
2323
            'message_id' => $messageId,
2324
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
2325
        ]));
2326
    }
2327
2328
    /**
2329
     * Use this method to create a topic in a forum supergroup chat.
2330
     * The bot must be an administrator in the chat for this to work
2331
     * and must have the can_manage_topics administrator rights.
2332
     * Returns information about the created topic as a ForumTopic object.
2333
     *
2334
     * @param int|string $chatId Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)
2335
     * @param string $name Topic name, 1-128 characters
2336
     * @param int $iconColor Color of the topic icon in RGB format.
2337
     *                       Currently, must be one of 7322096 (0x6FB9F0), 16766590 (0xFFD67E), 13338331 (0xCB86DB),
2338
     *                       9367192 (0x8EEE98), 16749490 (0xFF93B2), or 16478047 (0xFB6F5F)
2339
     * @param int|null $iconCustomEmojiId Unique identifier of the custom emoji shown as the topic icon.
2340
     *                                    Use getForumTopicIconStickers to get all allowed custom emoji identifiers.
2341
     *
2342
     * @return ForumTopic
2343
     *
2344
     * @throws Exception
2345
     *
2346
     * @author bernard-ng <[email protected]>
2347
     */
2348
    public function createForumTopic(
2349
        $chatId,
2350
        $name,
2351
        $iconColor,
2352
        $iconCustomEmojiId = null
2353
    )
2354
    {
2355
        return ForumTopic::fromResponse($this->call('createForumTopic', [
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...> $iconCustomEmojiId))) also could return the type true which is incompatible with the documented return type TelegramBot\Api\Types\ForumTopic.
Loading history...
2356
            'chat_id' => $chatId,
2357
            'name' => $name,
2358
            'icon_color' => $iconColor,
2359
            'icon_custom_emoji_id' => $iconCustomEmojiId,
2360
        ]));
2361
    }
2362
2363
    /**
2364
     * Use this method to edit name and icon of a topic in a forum supergroup chat.
2365
     * The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights,
2366
     * unless it is the creator of the topic. Returns True on success.
2367
     *
2368
     * @param int|string $chatId Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)
2369
     * @param int $messageThreadId Unique identifier for the target message thread of the forum topic
2370
     * @param string $name Topic name, 1-128 characters
2371
     * @param int|null $iconCustomEmojiId Unique identifier of the custom emoji shown as the topic icon.
2372
     *                                    Use getForumTopicIconStickers to get all allowed custom emoji identifiers.
2373
     *
2374
     * @return bool
2375
     * @throws Exception
2376
     *
2377
     * @author bernard-ng <[email protected]>
2378
     */
2379
    public function editForumTopic(
2380
        $chatId,
2381
        $messageThreadId,
2382
        $name,
2383
        $iconCustomEmojiId = null
2384
    )
2385
    {
2386
        return $this->call('editForumTopic', [
2387
            'chat_id' => $chatId,
2388
            'message_thread_id' => $messageThreadId,
2389
            'name' => $name,
2390
            'icon_custom_emoji_id' => $iconCustomEmojiId,
2391
        ]);
2392
    }
2393
2394
    /**
2395
     * Use this method to delete a topic in a forum supergroup chat.
2396
     * The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights,
2397
     * unless it is the creator of the topic. Returns True on success.
2398
     *
2399
     * @param int|string $chatId Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)
2400
     * @param int $messageThreadId Unique identifier for the target message thread of the forum topic
2401
     *
2402
     * @return bool
2403
     * @throws Exception
2404
     *
2405
     * @author bernard-ng <[email protected]>
2406
     */
2407
    public function closeForumTopic($chatId, $messageThreadId)
2408
    {
2409
        return $this->call('closeForumTopic', [
2410
            'chat_id' => $chatId,
2411
            'message_thread_id' => $messageThreadId,
2412
        ]);
2413
    }
2414
2415
    /**
2416
     * Use this method to reopen a closed topic in a forum supergroup chat.
2417
     * The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights,
2418
     * unless it is the creator of the topic. Returns True on success.
2419
     *
2420
     * @param int|string $chatId Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)
2421
     * @param int $messageThreadId Unique identifier for the target message thread of the forum topic
2422
     *
2423
     * @return bool
2424
     * @throws Exception
2425
     *
2426
     * @author bernard-ng <[email protected]>
2427
     */
2428
    public function reopenForumTopic($chatId, $messageThreadId)
2429
    {
2430
        return $this->call('reopenForumTopic', [
2431
            'chat_id' => $chatId,
2432
            'message_thread_id' => $messageThreadId,
2433
        ]);
2434
    }
2435
2436
    /**
2437
     * Use this method to delete a forum topic along with all its messages in a forum supergroup chat.
2438
     * The bot must be an administrator in the chat for this to work and must have the can_delete_messages administrator rights.
2439
     * Returns True on success.
2440
     *
2441
     * @param int|string $chatId Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)
2442
     * @param int $messageThreadId Unique identifier for the target message thread of the forum topic
2443
     *
2444
     * @return bool
2445
     * @throws Exception
2446
     *
2447
     * @author bernard-ng <[email protected]>
2448
     */
2449
    public function deleteForumTopic($chatId, $messageThreadId)
2450
    {
2451
        return $this->call('deleteForumTopic', [
2452
            'chat_id' => $chatId,
2453
            'message_thread_id' => $messageThreadId,
2454
        ]);
2455
    }
2456
2457
    /**
2458
     * Use this method to clear the list of pinned messages in a forum topic.
2459
     * 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.
2460
     * Returns True on success.
2461
     *
2462
     * @param int|string $chatId Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)
2463
     * @param int $messageThreadId Unique identifier for the target message thread of the forum topic
2464
     *
2465
     * @return bool
2466
     * @throws Exception
2467
     *
2468
     * @author bernard-ng <[email protected]>
2469
     */
2470
    public function unpinAllForumTopicMessages($chatId, $messageThreadId)
2471
    {
2472
        return $this->call('unpinAllForumTopicMessages', [
2473
            'chat_id' => $chatId,
2474
            'message_thread_id' => $messageThreadId,
2475
        ]);
2476
    }
2477
2478
    /**
2479
     * Use this method to get custom emoji stickers, which can be used as a forum topic icon by any user.
2480
     * Requires no parameters. Returns an Array of Sticker objects.
2481
     *
2482
     * @return Sticker[]
2483
     * @throws Exception
2484
     *
2485
     * @author bernard-ng <[email protected]>
2486
     */
2487
    public function getForumTopicIconStickers()
2488
    {
2489
        return ArrayOfSticker::fromResponse($this->call('getForumTopicIconStickers'));
0 ignored issues
show
Bug Best Practice introduced by
The expression return TelegramBot\Api\T...rumTopicIconStickers')) returns an array which contains values of type true which are incompatible with the documented value type TelegramBot\Api\Types\Sticker.
Loading history...
2490
    }
2491
2492
    /**
2493
     * Set an option for a cURL transfer
2494
     *
2495
     * @param int $option The CURLOPT_XXX option to set
2496
     * @param mixed $value The value to be set on option
2497
     */
2498
    public function setCurlOption($option, $value)
2499
    {
2500
        $this->customCurlOptions[$option] = $value;
2501
    }
2502
2503
    /**
2504
     * Unset an option for a cURL transfer
2505
     *
2506
     * @param int $option The CURLOPT_XXX option to unset
2507
     */
2508
    public function unsetCurlOption($option)
2509
    {
2510
        unset($this->customCurlOptions[$option]);
2511
    }
2512
2513
    /**
2514
     * Clean custom options
2515
     */
2516
    public function resetCurlOptions()
2517
    {
2518
        $this->customCurlOptions = [];
2519
    }
2520
}
2521