Passed
Push — master ( 58897c...6910c8 )
by Alexander
06:09 queued 12s
created

BotApi::createForumTopic()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 12
ccs 0
cts 6
cp 0
rs 10
cc 1
nc 1
nop 4
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;
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', [
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', [
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', [
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', [
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'));
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'));
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;
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', [
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', [
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', [
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', [
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', [
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', [
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', [
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', [
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', [
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', [
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', [
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', [
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|\CURLStringFile|string $document
0 ignored issues
show
Bug introduced by
The type CURLStringFile was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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', [
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]));
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'));
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', [
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', [
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', [
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', [
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', [
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', [
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(
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', [
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', [
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', [
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', [
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', [
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'));
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