Passed
Push — master ( 6a77fc...87dba9 )
by Eldar
01:57 queued 13s
created

BotApi::sendAudio()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 23

Duplication

Lines 23
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 23
loc 23
ccs 0
cts 0
cp 0
rs 9.552
c 0
b 0
f 0
cc 2
nc 1
nop 9
crap 6

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace TelegramBot\Api;
4
5
use TelegramBot\Api\Types\ArrayOfChatMemberEntity;
6
use TelegramBot\Api\Types\ArrayOfMessageEntity;
7
use TelegramBot\Api\Types\ArrayOfMessages;
8
use TelegramBot\Api\Types\ArrayOfUpdates;
9
use TelegramBot\Api\Types\Chat;
10
use TelegramBot\Api\Types\ChatMember;
11
use TelegramBot\Api\Types\File;
12
use TelegramBot\Api\Types\Inline\QueryResult\AbstractInlineQueryResult;
13
use TelegramBot\Api\Types\InputMedia\ArrayOfInputMedia;
14
use TelegramBot\Api\Types\InputMedia\InputMedia;
15
use TelegramBot\Api\Types\Message;
16
use TelegramBot\Api\Types\Poll;
17
use TelegramBot\Api\Types\Update;
18
use TelegramBot\Api\Types\User;
19
use TelegramBot\Api\Types\UserProfilePhotos;
20
use TelegramBot\Api\Types\WebhookInfo;
21
22
/**
23
 * Class BotApi
24
 *
25
 * @package TelegramBot\Api
26
 */
27
class BotApi
28
{
29
    /**
30
     * HTTP codes
31
     *
32
     * @var array
33
     */
34
    public static $codes = [
35
        // Informational 1xx
36
        100 => 'Continue',
37
        101 => 'Switching Protocols',
38
        102 => 'Processing',            // RFC2518
39
        // Success 2xx
40
        200 => 'OK',
41
        201 => 'Created',
42
        202 => 'Accepted',
43
        203 => 'Non-Authoritative Information',
44
        204 => 'No Content',
45
        205 => 'Reset Content',
46
        206 => 'Partial Content',
47
        207 => 'Multi-Status',          // RFC4918
48
        208 => 'Already Reported',      // RFC5842
49
        226 => 'IM Used',               // RFC3229
50
        // Redirection 3xx
51
        300 => 'Multiple Choices',
52
        301 => 'Moved Permanently',
53
        302 => 'Found', // 1.1
54
        303 => 'See Other',
55
        304 => 'Not Modified',
56
        305 => 'Use Proxy',
57
        // 306 is deprecated but reserved
58
        307 => 'Temporary Redirect',
59
        308 => 'Permanent Redirect',    // RFC7238
60
        // Client Error 4xx
61
        400 => 'Bad Request',
62
        401 => 'Unauthorized',
63
        402 => 'Payment Required',
64
        403 => 'Forbidden',
65
        404 => 'Not Found',
66
        405 => 'Method Not Allowed',
67
        406 => 'Not Acceptable',
68
        407 => 'Proxy Authentication Required',
69
        408 => 'Request Timeout',
70
        409 => 'Conflict',
71
        410 => 'Gone',
72
        411 => 'Length Required',
73
        412 => 'Precondition Failed',
74
        413 => 'Payload Too Large',
75
        414 => 'URI Too Long',
76
        415 => 'Unsupported Media Type',
77
        416 => 'Range Not Satisfiable',
78
        417 => 'Expectation Failed',
79
        422 => 'Unprocessable Entity',                                        // RFC4918
80
        423 => 'Locked',                                                      // RFC4918
81
        424 => 'Failed Dependency',                                           // RFC4918
82
        425 => 'Reserved for WebDAV advanced collections expired proposal',   // RFC2817
83
        426 => 'Upgrade Required',                                            // RFC2817
84
        428 => 'Precondition Required',                                       // RFC6585
85
        429 => 'Too Many Requests',                                           // RFC6585
86
        431 => 'Request Header Fields Too Large',                             // RFC6585
87
        // Server Error 5xx
88
        500 => 'Internal Server Error',
89
        501 => 'Not Implemented',
90
        502 => 'Bad Gateway',
91
        503 => 'Service Unavailable',
92
        504 => 'Gateway Timeout',
93
        505 => 'HTTP Version Not Supported',
94
        506 => 'Variant Also Negotiates (Experimental)',                      // RFC2295
95
        507 => 'Insufficient Storage',                                        // RFC4918
96
        508 => 'Loop Detected',                                               // RFC5842
97
        510 => 'Not Extended',                                                // RFC2774
98
        511 => 'Network Authentication Required',                             // RFC6585
99
    ];
100
101
    private $proxySettings = [];
102
103
    /**
104
     * Default http status code
105
     */
106
    const DEFAULT_STATUS_CODE = 200;
107
108
    /**
109
     * Not Modified http status code
110
     */
111
    const NOT_MODIFIED_STATUS_CODE = 304;
112
113
    /**
114
     * Limits for tracked ids
115
     */
116
    const MAX_TRACKED_EVENTS = 200;
117
118
    /**
119
     * Url prefixes
120
     */
121
    const URL_PREFIX = 'https://api.telegram.org/bot';
122
123
    /**
124
     * Url prefix for files
125
     */
126
    const FILE_URL_PREFIX = 'https://api.telegram.org/file/bot';
127
128
    /**
129
     * CURL object
130
     *
131
     * @var
132
     */
133
    protected $curl;
134
135
    /**
136
     * CURL custom options
137
     *
138
     * @var array
139
     */
140
    protected $customCurlOptions = [];
141
142
    /**
143
     * Bot token
144
     *
145
     * @var string
146
     */
147
    protected $token;
148
149
    /**
150
     * Botan tracker
151
     *
152
     * @var \TelegramBot\Api\Botan
153
     */
154
    protected $tracker;
155
156
    /**
157
     * list of event ids
158
     *
159
     * @var array
160
     */
161
    protected $trackedEvents = [];
162
163
    /**
164
     * Check whether return associative array
165
     *
166
     * @var bool
167
     */
168
    protected $returnArray = true;
169
170
    /**
171
     * Constructor
172
     *
173
     * @param string $token Telegram Bot API token
174
     * @param string|null $trackerToken Yandex AppMetrica application api_key
175
     */
176 9
    public function __construct($token, $trackerToken = null)
177
    {
178 9
        $this->curl = curl_init();
179 9
        $this->token = $token;
180
181 9
        if ($trackerToken) {
182
            $this->tracker = new Botan($trackerToken);
183
        }
184 9
    }
185
186
    /**
187
     * Set return array
188
     *
189
     * @param bool $mode
190
     *
191
     * @return $this
192
     */
193
    public function setModeObject($mode = true)
194
    {
195
        $this->returnArray = !$mode;
196
197
        return $this;
198
    }
199
200
201
    /**
202
     * Call method
203
     *
204
     * @param string $method
205
     * @param array|null $data
206
     *
207
     * @return mixed
208
     * @throws \TelegramBot\Api\Exception
209
     * @throws \TelegramBot\Api\HttpException
210
     * @throws \TelegramBot\Api\InvalidJsonException
211
     */
212
    public function call($method, array $data = null)
213
    {
214
        $options = $this->proxySettings + [
215
            CURLOPT_URL => $this->getUrl().'/'.$method,
216
            CURLOPT_RETURNTRANSFER => true,
217
            CURLOPT_POST => null,
218
            CURLOPT_POSTFIELDS => null,
219
            CURLOPT_TIMEOUT => 5,
220
        ];
221
222
        if ($data) {
223
            $options[CURLOPT_POST] = true;
224
            $options[CURLOPT_POSTFIELDS] = $data;
225
        }
226
227
        if (!empty($this->customCurlOptions) && is_array($this->customCurlOptions)) {
228
            $options = $this->customCurlOptions + $options;
229
        }
230
231
        $response = self::jsonValidate($this->executeCurl($options), $this->returnArray);
232
233
        if ($this->returnArray) {
234
            if (!isset($response['ok']) || !$response['ok']) {
235
                throw new Exception($response['description'], $response['error_code']);
236
            }
237
238
            return $response['result'];
239
        }
240
241
        if (!$response->ok) {
242
            throw new Exception($response->description, $response->error_code);
243
        }
244
245
        return $response->result;
246
    }
247
248
    /**
249
     * curl_exec wrapper for response validation
250
     *
251
     * @param array $options
252
     *
253
     * @return string
254
     *
255
     * @throws \TelegramBot\Api\HttpException
256
     */
257
    protected function executeCurl(array $options)
258
    {
259
        curl_setopt_array($this->curl, $options);
260
261
        $result = curl_exec($this->curl);
262
        self::curlValidate($this->curl, $result);
263
        if ($result === false) {
264
            throw new HttpException(curl_error($this->curl), curl_errno($this->curl));
265
        }
266
267
        return $result;
268
    }
269
270
    /**
271
     * Response validation
272
     *
273
     * @param resource $curl
274
     * @param string $response
275
     * @throws HttpException
276
     */
277
    public static function curlValidate($curl, $response = null)
278
    {
279
        $json = json_decode($response, true)?: [];
280
        if (($httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE))
281
            && !in_array($httpCode, [self::DEFAULT_STATUS_CODE, self::NOT_MODIFIED_STATUS_CODE])
282
        ) {
283
            $errorDescription = array_key_exists('description', $json) ? $json['description'] : self::$codes[$httpCode];
284
            $errorParameters = array_key_exists('parameters', $json) ? $json['parameters'] : [];
285
            throw new HttpException($errorDescription, $httpCode, null, $errorParameters);
286
        }
287
    }
288
289
    /**
290
     * JSON validation
291
     *
292
     * @param string $jsonString
293
     * @param boolean $asArray
294
     *
295
     * @return object|array
296
     * @throws \TelegramBot\Api\InvalidJsonException
297
     */
298
    public static function jsonValidate($jsonString, $asArray)
299
    {
300
        $json = json_decode($jsonString, $asArray);
301
302
        if (json_last_error() != JSON_ERROR_NONE) {
303
            throw new InvalidJsonException(json_last_error_msg(), json_last_error());
304
        }
305
306
        return $json;
307
    }
308
309
    /**
310
     * Use this method to send text messages. On success, the sent \TelegramBot\Api\Types\Message is returned.
311
     *
312
     * @param int|string $chatId
313
     * @param string $text
314
     * @param string|null $parseMode
315
     * @param bool $disablePreview
316
     * @param int|null $replyToMessageId
317
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
318
     *        Types\ReplyKeyboardRemove|null $replyMarkup
319
     * @param bool $disableNotification
320
     *
321
     * @return \TelegramBot\Api\Types\Message
322
     * @throws \TelegramBot\Api\InvalidArgumentException
323
     * @throws \TelegramBot\Api\Exception
324
     */
325
    public function sendMessage(
326
        $chatId,
327
        $text,
328
        $parseMode = null,
329
        $disablePreview = false,
330
        $replyToMessageId = null,
331
        $replyMarkup = null,
332
        $disableNotification = false
333
    ) {
334
        return Message::fromResponse($this->call('sendMessage', [
335
            'chat_id' => $chatId,
336
            'text' => $text,
337
            'parse_mode' => $parseMode,
338
            'disable_web_page_preview' => $disablePreview,
339
            'reply_to_message_id' => (int)$replyToMessageId,
340
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
341
            'disable_notification' => (bool)$disableNotification,
342
        ]));
343
    }
344
345
    /**
346
     * @param int|string $chatId
347
     * @param int|string $fromChatId
348
     * @param int $messageId
349
     * @param string|null $caption
350
     * @param string|null $parseMode
351
     * @param ArrayOfMessageEntity|null $captionEntities
352
     * @param bool $disableNotification
353
     * @param int|null $replyToMessageId
354
     * @param bool $allowSendingWithoutReply
355
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
356
     *        Types\ReplyKeyboardRemove|null $replyMarkup
357
     *
358
     * @return Message
359
     * @throws Exception
360
     * @throws HttpException
361
     * @throws InvalidJsonException
362
     */
363 View Code Duplication
    public function copyMessage(
364
        $chatId,
365
        $fromChatId,
366
        $messageId,
367
        $caption = null,
368
        $parseMode = null,
369
        $captionEntities = null,
370
        $disableNotification = false,
371
        $replyToMessageId = null,
372
        $allowSendingWithoutReply = false,
373
        $replyMarkup = null
374
    ) {
375
        return Message::fromResponse($this->call('sendMessage', [
376
            'chat_id' => $chatId,
377
            'from_chat_id' => $fromChatId,
378
            'message_id' => (int)$messageId,
379
            'caption' => $caption,
380
            'parse_mode' => $parseMode,
381
            'caption_entities' => $captionEntities,
382
            'disable_notification' => (bool)$disableNotification,
383
            'reply_to_message_id' => (int)$replyToMessageId,
384
            'allow_sending_without_reply' => (bool)$allowSendingWithoutReply,
385
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
386
        ]));
387
    }
388
389
    /**
390
     * Use this method to send phone contacts
391
     *
392
     * @param int|string $chatId chat_id or @channel_name
393
     * @param string $phoneNumber
394
     * @param string $firstName
395
     * @param string $lastName
396
     * @param int|null $replyToMessageId
397
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
398
     *        Types\ReplyKeyboardRemove|null $replyMarkup
399
     * @param bool $disableNotification
400
     *
401
     * @return \TelegramBot\Api\Types\Message
402
     * @throws \TelegramBot\Api\Exception
403
     */
404
    public function sendContact(
405
        $chatId,
406
        $phoneNumber,
407
        $firstName,
408
        $lastName = null,
409
        $replyToMessageId = null,
410
        $replyMarkup = null,
411
        $disableNotification = false
412
    ) {
413
        return Message::fromResponse($this->call('sendContact', [
414
            'chat_id' => $chatId,
415
            'phone_number' => $phoneNumber,
416
            'first_name' => $firstName,
417
            'last_name' => $lastName,
418
            'reply_to_message_id' => $replyToMessageId,
419
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
420
            'disable_notification' => (bool)$disableNotification,
421
        ]));
422
    }
423
424
    /**
425
     * Use this method when you need to tell the user that something is happening on the bot's side.
426
     * The status is set for 5 seconds or less (when a message arrives from your bot,
427
     * Telegram clients clear its typing status).
428
     *
429
     * We only recommend using this method when a response from the bot will take a noticeable amount of time to arrive.
430
     *
431
     * Type of action to broadcast. Choose one, depending on what the user is about to receive:
432
     * `typing` for text messages, `upload_photo` for photos, `record_video` or `upload_video` for videos,
433
     * `record_audio` or upload_audio for audio files, `upload_document` for general files,
434
     * `find_location` for location data.
435
     *
436
     * @param int $chatId
437
     * @param string $action
438
     *
439
     * @return bool
440
     * @throws \TelegramBot\Api\Exception
441
     */
442
    public function sendChatAction($chatId, $action)
443
    {
444
        return $this->call('sendChatAction', [
445
            'chat_id' => $chatId,
446
            'action' => $action,
447
        ]);
448
    }
449
450
    /**
451
     * Use this method to get a list of profile pictures for a user.
452
     *
453
     * @param int $userId
454
     * @param int $offset
455
     * @param int $limit
456
     *
457
     * @return \TelegramBot\Api\Types\UserProfilePhotos
458
     * @throws \TelegramBot\Api\Exception
459
     */
460
    public function getUserProfilePhotos($userId, $offset = 0, $limit = 100)
461
    {
462
        return UserProfilePhotos::fromResponse($this->call('getUserProfilePhotos', [
463
            'user_id' => (int)$userId,
464
            'offset' => (int)$offset,
465
            'limit' => (int)$limit,
466
        ]));
467
    }
468
469
    /**
470
     * Use this method to specify a url and receive incoming updates via an outgoing webhook.
471
     * Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url,
472
     * containing a JSON-serialized Update.
473
     * In case of an unsuccessful request, we will give up after a reasonable amount of attempts.
474
     *
475
     * @param string $url HTTPS url to send updates to. Use an empty string to remove webhook integration
476
     * @param \CURLFile|string $certificate Upload your public key certificate
477
     *                                      so that the root certificate in use can be checked
478
     *
479
     * @return string
480
     *
481
     * @throws \TelegramBot\Api\Exception
482
     */
483
    public function setWebhook($url = '', $certificate = null)
484
    {
485
        return $this->call('setWebhook', ['url' => $url, 'certificate' => $certificate]);
486
    }
487
488
489
    /**
490
     * Use this method to clear webhook and use getUpdates again!
491
     *
492
     * @return mixed
493
     *
494
     * @throws \TelegramBot\Api\Exception
495
     */
496
    public function deleteWebhook()
497
    {
498
        return $this->call('deleteWebhook');
499
    }
500
501
    /**
502
     * Use this method to get current webhook status. Requires no parameters.
503
     * On success, returns a WebhookInfo object. If the bot is using getUpdates,
504
     * will return an object with the url field empty.
505
     *
506
     * @return \TelegramBot\Api\Types\WebhookInfo
507
     * @throws \TelegramBot\Api\Exception
508
     * @throws \TelegramBot\Api\InvalidArgumentException
509
     */
510
    public function getWebhookInfo()
511
    {
512
        return WebhookInfo::fromResponse($this->call('getWebhookInfo'));
513
    }
514
515
    /**
516
     * A simple method for testing your bot's auth token.Requires no parameters.
517
     * Returns basic information about the bot in form of a User object.
518
     *
519
     * @return \TelegramBot\Api\Types\User
520
     * @throws \TelegramBot\Api\Exception
521
     * @throws \TelegramBot\Api\InvalidArgumentException
522
     */
523
    public function getMe()
524
    {
525
        return User::fromResponse($this->call('getMe'));
526
    }
527
528
    /**
529
     * Use this method to receive incoming updates using long polling.
530
     * An Array of Update objects is returned.
531
     *
532
     * Notes
533
     * 1. This method will not work if an outgoing webhook is set up.
534
     * 2. In order to avoid getting duplicate updates, recalculate offset after each server response.
535
     *
536
     * @param int $offset
537
     * @param int $limit
538
     * @param int $timeout
539
     *
540
     * @return Update[]
541
     * @throws \TelegramBot\Api\Exception
542
     * @throws \TelegramBot\Api\InvalidArgumentException
543
     */
544 2
    public function getUpdates($offset = 0, $limit = 100, $timeout = 0)
545
    {
546 2
        $updates = ArrayOfUpdates::fromResponse($this->call('getUpdates', [
547 2
            'offset' => $offset,
548 2
            'limit' => $limit,
549 2
            'timeout' => $timeout,
550 2
        ]));
551
552 2
        if ($this->tracker instanceof Botan) {
553
            foreach ($updates as $update) {
554
                $this->trackUpdate($update);
555
            }
556
        }
557
558 2
        return $updates;
559
    }
560
561
    /**
562
     * Use this method to send point on the map. On success, the sent Message is returned.
563
     *
564
     * @param int|string                                                              $chatId
565
     * @param float                                                                   $latitude
566
     * @param float                                                                   $longitude
567
     * @param int|null                                                                $replyToMessageId
568
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
569
     *        Types\ReplyKeyboardRemove|null $replyMarkup
570
     * @param bool                                                                    $disableNotification
571
     *
572
     * @param null|int                                                                $livePeriod
573
     * @return \TelegramBot\Api\Types\Message
574
     */
575
    public function sendLocation(
576
        $chatId,
577
        $latitude,
578
        $longitude,
579
        $replyToMessageId = null,
580
        $replyMarkup = null,
581
        $disableNotification = false,
582
        $livePeriod = null
583
    ) {
584
        return Message::fromResponse($this->call('sendLocation', [
585
            'chat_id'              => $chatId,
586
            'latitude'             => $latitude,
587
            'longitude'            => $longitude,
588
            'live_period'          => $livePeriod,
589
            'reply_to_message_id'  => $replyToMessageId,
590
            'reply_markup'         => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
591
            'disable_notification' => (bool)$disableNotification,
592
        ]));
593
    }
594
595
    /**
596
     * Use this method to edit live location messages sent by the bot or via the bot (for inline bots).
597
     *
598
     * @param int|string                                                              $chatId
599
     * @param int                                                                     $messageId
600
     * @param string                                                                  $inlineMessageId
601
     * @param float                                                                   $latitude
602
     * @param float                                                                   $longitude
603
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
604
     *        Types\ReplyKeyboardRemove|null $replyMarkup
605
     * @return \TelegramBot\Api\Types\Message
606
     */
607
    public function editMessageLiveLocation(
608
        $chatId,
609
        $messageId,
610
        $inlineMessageId,
611
        $latitude,
612
        $longitude,
613
        $replyMarkup = null
614
    ) {
615
        return Message::fromResponse($this->call('sendLocation', [
616
            'chat_id'           => $chatId,
617
            'message_id'        => $messageId,
618
            'inline_message_id' => $inlineMessageId,
619
            'latitude'          => $latitude,
620
            'longitude'         => $longitude,
621
            'reply_markup'      => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
622
        ]));
623
    }
624
625
    /**
626
     * Use this method to stop updating a live location message sent by the bot or via the bot (for inline bots) before
627
     * live_period expires.
628
     *
629
     * @param int|string                                                              $chatId
630
     * @param int                                                                     $messageId
631
     * @param string                                                                  $inlineMessageId
632
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
633
     *        Types\ReplyKeyboardRemove|null $replyMarkup
634
     * @return \TelegramBot\Api\Types\Message
635
     */
636
    public function stopMessageLiveLocation(
637
        $chatId,
638
        $messageId,
639
        $inlineMessageId,
640
        $replyMarkup = null
641
    ) {
642
        return Message::fromResponse($this->call('sendLocation', [
643
            'chat_id'           => $chatId,
644
            'message_id'        => $messageId,
645
            'inline_message_id' => $inlineMessageId,
646
            'reply_markup'      => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
647
        ]));
648
    }
649
650
    /**
651
     * Use this method to send information about a venue. On success, the sent Message is returned.
652
     *
653
     * @param int|string $chatId chat_id or @channel_name
654
     * @param float $latitude
655
     * @param float $longitude
656
     * @param string $title
657
     * @param string $address
658
     * @param string|null $foursquareId
659
     * @param int|null $replyToMessageId
660
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
661
     *        Types\ReplyKeyboardRemove|null $replyMarkup
662
     * @param bool $disableNotification
663
     *
664
     * @return \TelegramBot\Api\Types\Message
665
     * @throws \TelegramBot\Api\Exception
666
     */
667
    public function sendVenue(
668
        $chatId,
669
        $latitude,
670
        $longitude,
671
        $title,
672
        $address,
673
        $foursquareId = null,
674
        $replyToMessageId = null,
675
        $replyMarkup = null,
676
        $disableNotification = false
677
    ) {
678
        return Message::fromResponse($this->call('sendVenue', [
679
            'chat_id' => $chatId,
680
            'latitude' => $latitude,
681
            'longitude' => $longitude,
682
            'title' => $title,
683
            'address' => $address,
684
            'foursquare_id' => $foursquareId,
685
            'reply_to_message_id' => $replyToMessageId,
686
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
687
            'disable_notification' => (bool)$disableNotification,
688
        ]));
689
    }
690
691
    /**
692
     * Use this method to send .webp stickers. On success, the sent Message is returned.
693
     *
694
     * @param int|string $chatId chat_id or @channel_name
695
     * @param \CURLFile|string $sticker
696
     * @param int|null $replyToMessageId
697
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
698
     *        Types\ReplyKeyboardRemove|null $replyMarkup
699
     * @param bool $disableNotification
700
     *
701
     * @return \TelegramBot\Api\Types\Message
702
     * @throws \TelegramBot\Api\InvalidArgumentException
703
     * @throws \TelegramBot\Api\Exception
704
     */
705 View Code Duplication
    public function sendSticker(
706
        $chatId,
707
        $sticker,
708
        $replyToMessageId = null,
709
        $replyMarkup = null,
710
        $disableNotification = false
711
    ) {
712
        return Message::fromResponse($this->call('sendSticker', [
713
            'chat_id' => $chatId,
714
            'sticker' => $sticker,
715
            'reply_to_message_id' => $replyToMessageId,
716
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
717
            'disable_notification' => (bool)$disableNotification,
718
        ]));
719
    }
720
721
    /**
722
     * Use this method to send video files,
723
     * Telegram clients support mp4 videos (other formats may be sent as Document).
724
     * On success, the sent Message is returned.
725
     *
726
     * @param int|string $chatId chat_id or @channel_name
727
     * @param \CURLFile|string $video
728
     * @param int|null $duration
729
     * @param string|null $caption
730
     * @param int|null $replyToMessageId
731
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
732
     *        Types\ReplyKeyboardRemove|null $replyMarkup
733
     * @param bool $disableNotification
734
     * @param bool $supportsStreaming Pass True, if the uploaded video is suitable for streaming
735
     * @param string|null $parseMode
736
     *
737
     * @return \TelegramBot\Api\Types\Message
738
     * @throws \TelegramBot\Api\InvalidArgumentException
739
     * @throws \TelegramBot\Api\Exception
740
     */
741 View Code Duplication
    public function sendVideo(
742
        $chatId,
743
        $video,
744
        $duration = null,
745
        $caption = null,
746
        $replyToMessageId = null,
747
        $replyMarkup = null,
748
        $disableNotification = false,
749
        $supportsStreaming = false,
750
        $parseMode = null
751
    ) {
752
        return Message::fromResponse($this->call('sendVideo', [
753
            'chat_id' => $chatId,
754
            'video' => $video,
755
            'duration' => $duration,
756
            'caption' => $caption,
757
            'reply_to_message_id' => $replyToMessageId,
758
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
759
            'disable_notification' => (bool)$disableNotification,
760
            'supports_streaming' => (bool)$supportsStreaming,
761
            'parse_mode' => $parseMode
762
        ]));
763
    }
764
765
    /**
766
     * Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound),
767
     * On success, the sent Message is returned.
768
     * Bots can currently send animation files of up to 50 MB in size, this limit may be changed in the future.
769
     *
770
     * @param int|string $chatId chat_id or @channel_name
771
     * @param \CURLFile|string $animation
772
     * @param int|null $duration
773
     * @param string|null $caption
774
     * @param int|null $replyToMessageId
775
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
776
     *        Types\ReplyKeyboardRemove|null $replyMarkup
777
     * @param bool $disableNotification
778
     * @param string|null $parseMode
779
     *
780
     * @return \TelegramBot\Api\Types\Message
781
     * @throws \TelegramBot\Api\InvalidArgumentException
782
     * @throws \TelegramBot\Api\Exception
783
     */
784
    public function sendAnimation(
785
        $chatId,
786
        $animation,
787
        $duration = null,
788
        $caption = null,
789
        $replyToMessageId = null,
790
        $replyMarkup = null,
791
        $disableNotification = false,
792
        $parseMode = null
793
    ) {
794
        return Message::fromResponse($this->call('sendAnimation', [
795
            'chat_id' => $chatId,
796
            'animation' => $animation,
797
            'duration' => $duration,
798
            'caption' => $caption,
799
            'reply_to_message_id' => $replyToMessageId,
800
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
801
            'disable_notification' => (bool)$disableNotification,
802
            'parse_mode' => $parseMode
803
        ]));
804
    }
805
806
    /**
807
     * Use this method to send audio files,
808
     * if you want Telegram clients to display the file as a playable voice message.
809
     * For this to work, your audio must be in an .ogg file encoded with OPUS
810
     * (other formats may be sent as Audio or Document).
811
     * On success, the sent Message is returned.
812
     * Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future.
813
     *
814
     * @param int|string $chatId chat_id or @channel_name
815
     * @param \CURLFile|string $voice
816
     * @param int|null $duration
817
     * @param int|null $replyToMessageId
818
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
819
     *        Types\ReplyKeyboardRemove|null $replyMarkup
820
     * @param bool $disableNotification
821
     * @param string|null $parseMode
822
     *
823
     * @return \TelegramBot\Api\Types\Message
824
     * @throws \TelegramBot\Api\InvalidArgumentException
825
     * @throws \TelegramBot\Api\Exception
826
     */
827
    public function sendVoice(
828
        $chatId,
829
        $voice,
830
        $duration = null,
831
        $replyToMessageId = null,
832
        $replyMarkup = null,
833
        $disableNotification = false,
834
        $parseMode = null
835
    ) {
836
        return Message::fromResponse($this->call('sendVoice', [
837
            'chat_id' => $chatId,
838
            'voice' => $voice,
839
            'duration' => $duration,
840
            'reply_to_message_id' => $replyToMessageId,
841
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
842
            'disable_notification' => (bool)$disableNotification,
843
            'parse_mode' => $parseMode
844
        ]));
845
    }
846
847
    /**
848
     * Use this method to forward messages of any kind. On success, the sent Message is returned.
849
     *
850
     * @param int|string $chatId chat_id or @channel_name
851
     * @param int $fromChatId
852
     * @param int $messageId
853
     * @param bool $disableNotification
854
     *
855
     * @return \TelegramBot\Api\Types\Message
856
     * @throws \TelegramBot\Api\InvalidArgumentException
857
     * @throws \TelegramBot\Api\Exception
858
     */
859
    public function forwardMessage($chatId, $fromChatId, $messageId, $disableNotification = false)
860
    {
861
        return Message::fromResponse($this->call('forwardMessage', [
862
            'chat_id' => $chatId,
863
            'from_chat_id' => $fromChatId,
864
            'message_id' => (int)$messageId,
865
            'disable_notification' => (bool)$disableNotification,
866
        ]));
867
    }
868
869
    /**
870
     * Use this method to send audio files,
871
     * if you want Telegram clients to display them in the music player.
872
     * Your audio must be in the .mp3 format.
873
     * On success, the sent Message is returned.
874
     * Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future.
875
     *
876
     * For backward compatibility, when the fields title and performer are both empty
877
     * and the mime-type of the file to be sent is not audio/mpeg, the file will be sent as a playable voice message.
878
     * For this to work, the audio must be in an .ogg file encoded with OPUS.
879
     * This behavior will be phased out in the future. For sending voice messages, use the sendVoice method instead.
880
     *
881
     * @deprecated since 20th February. Removed backward compatibility from the method sendAudio.
882
     * Voice messages now must be sent using the method sendVoice.
883
     * There is no more need to specify a non-empty title or performer while sending the audio by file_id.
884
     *
885
     * @param int|string $chatId chat_id or @channel_name
886
     * @param \CURLFile|string $audio
887
     * @param int|null $duration
888
     * @param string|null $performer
889
     * @param string|null $title
890
     * @param int|null $replyToMessageId
891
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
892
     *        Types\ReplyKeyboardRemove|null $replyMarkup
893
     * @param bool $disableNotification
894
     * @param string|null $parseMode
895
     *
896
     * @return \TelegramBot\Api\Types\Message
897
     * @throws \TelegramBot\Api\InvalidArgumentException
898
     * @throws \TelegramBot\Api\Exception
899
     */
900 View Code Duplication
    public function sendAudio(
901
        $chatId,
902
        $audio,
903
        $duration = null,
904
        $performer = null,
905
        $title = null,
906
        $replyToMessageId = null,
907
        $replyMarkup = null,
908
        $disableNotification = false,
909
        $parseMode = null
910
    ) {
911
        return Message::fromResponse($this->call('sendAudio', [
912
            'chat_id' => $chatId,
913
            'audio' => $audio,
914
            'duration' => $duration,
915
            'performer' => $performer,
916
            'title' => $title,
917
            'reply_to_message_id' => $replyToMessageId,
918
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
919
            'disable_notification' => (bool)$disableNotification,
920
            'parse_mode' => $parseMode
921
        ]));
922
    }
923
924
    /**
925
     * Use this method to send photos. On success, the sent Message is returned.
926
     *
927
     * @param int|string $chatId chat_id or @channel_name
928
     * @param \CURLFile|string $photo
929
     * @param string|null $caption
930
     * @param int|null $replyToMessageId
931
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
932
     *        Types\ReplyKeyboardRemove|null $replyMarkup
933
     * @param bool $disableNotification
934
     * @param string|null $parseMode
935
     *
936
     * @return \TelegramBot\Api\Types\Message
937
     * @throws \TelegramBot\Api\InvalidArgumentException
938
     * @throws \TelegramBot\Api\Exception
939
     */
940
    public function sendPhoto(
941
        $chatId,
942
        $photo,
943
        $caption = null,
944
        $replyToMessageId = null,
945
        $replyMarkup = null,
946
        $disableNotification = false,
947
        $parseMode = null
948
    ) {
949
        return Message::fromResponse($this->call('sendPhoto', [
950
            'chat_id' => $chatId,
951
            'photo' => $photo,
952
            'caption' => $caption,
953
            'reply_to_message_id' => $replyToMessageId,
954
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
955
            'disable_notification' => (bool)$disableNotification,
956
            'parse_mode' => $parseMode
957
        ]));
958
    }
959
960
    /**
961
     * Use this method to send general files. On success, the sent Message is returned.
962
     * Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
963
     *
964
     * @param int|string $chatId chat_id or @channel_name
965
     * @param \CURLFile|string $document
966
     * @param string|null $caption
967
     * @param int|null $replyToMessageId
968
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
969
     *        Types\ReplyKeyboardRemove|null $replyMarkup
970
     * @param bool $disableNotification
971
     * @param string|null $parseMode
972
     *
973
     * @return \TelegramBot\Api\Types\Message
974
     * @throws \TelegramBot\Api\InvalidArgumentException
975
     * @throws \TelegramBot\Api\Exception
976
     */
977
    public function sendDocument(
978
        $chatId,
979
        $document,
980
        $caption = null,
981
        $replyToMessageId = null,
982
        $replyMarkup = null,
983
        $disableNotification = false,
984
        $parseMode = null
985
    ) {
986
        return Message::fromResponse($this->call('sendDocument', [
987
            'chat_id' => $chatId,
988
            'document' => $document,
989
            'caption' => $caption,
990
            'reply_to_message_id' => $replyToMessageId,
991
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
992
            'disable_notification' => (bool)$disableNotification,
993
            'parse_mode' => $parseMode
994
        ]));
995
    }
996
997
    /**
998
     * Use this method to get basic info about a file and prepare it for downloading.
999
     * For the moment, bots can download files of up to 20MB in size.
1000
     * On success, a File object is returned.
1001
     * The file can then be downloaded via the link https://api.telegram.org/file/bot<token>/<file_path>,
1002
     * where <file_path> is taken from the response.
1003
     * It is guaranteed that the link will be valid for at least 1 hour.
1004
     * When the link expires, a new one can be requested by calling getFile again.
1005
     *
1006
     * @param $fileId
1007
     *
1008
     * @return \TelegramBot\Api\Types\File
1009
     * @throws \TelegramBot\Api\InvalidArgumentException
1010
     * @throws \TelegramBot\Api\Exception
1011
     */
1012
    public function getFile($fileId)
1013
    {
1014
        return File::fromResponse($this->call('getFile', ['file_id' => $fileId]));
1015
    }
1016
1017
    /**
1018
     * Get file contents via cURL
1019
     *
1020
     * @param $fileId
1021
     *
1022
     * @return string
1023
     *
1024
     * @throws \TelegramBot\Api\HttpException
1025
     */
1026
    public function downloadFile($fileId)
1027
    {
1028
        $file = $this->getFile($fileId);
1029
        $options = [
1030
            CURLOPT_HEADER => 0,
1031
            CURLOPT_HTTPGET => 1,
1032
            CURLOPT_RETURNTRANSFER => 1,
1033
            CURLOPT_URL => $this->getFileUrl().'/'.$file->getFilePath(),
1034
        ];
1035
1036
        return $this->executeCurl($options);
1037
    }
1038
1039
    /**
1040
     * Use this method to send answers to an inline query. On success, True is returned.
1041
     * No more than 50 results per query are allowed.
1042
     *
1043
     * @param string $inlineQueryId
1044
     * @param AbstractInlineQueryResult[] $results
1045
     * @param int $cacheTime
1046
     * @param bool $isPersonal
1047
     * @param string $nextOffset
1048
     * @param string $switchPmText
1049
     * @param string $switchPmParameter
1050
     *
1051
     * @return mixed
1052
     * @throws Exception
1053
     */
1054
    public function answerInlineQuery(
1055
        $inlineQueryId,
1056
        $results,
1057
        $cacheTime = 300,
1058
        $isPersonal = false,
1059
        $nextOffset = '',
1060
        $switchPmText = null,
1061
        $switchPmParameter = null
1062
    ) {
1063
        $results = array_map(function ($item) {
1064
            /* @var AbstractInlineQueryResult $item */
1065
            return json_decode($item->toJson(), true);
1066
        }, $results);
1067
1068
        return $this->call('answerInlineQuery', [
1069
            'inline_query_id' => $inlineQueryId,
1070
            'results' => json_encode($results),
1071
            'cache_time' => $cacheTime,
1072
            'is_personal' => $isPersonal,
1073
            'next_offset' => $nextOffset,
1074
            'switch_pm_text' => $switchPmText,
1075
            'switch_pm_parameter' => $switchPmParameter,
1076
        ]);
1077
    }
1078
1079
    /**
1080
     * Use this method to kick a user from a group or a supergroup.
1081
     * In the case of supergroups, the user will not be able to return to the group
1082
     * on their own using invite links, etc., unless unbanned first.
1083
     * The bot must be an administrator in the group for this to work. Returns True on success.
1084
     *
1085
     * @param int|string $chatId Unique identifier for the target group
1086
     * or username of the target supergroup (in the format @supergroupusername)
1087
     * @param int $userId Unique identifier of the target user
1088
     * @param null|int $untilDate Date when the user will be unbanned, unix time.
1089
     *                            If user is banned for more than 366 days or less than 30 seconds from the current time
1090
     *                            they are considered to be banned forever
1091
     *
1092
     * @return bool
1093
     */
1094
    public function kickChatMember($chatId, $userId, $untilDate = null)
1095
    {
1096
        return $this->call('kickChatMember', [
1097
            'chat_id' => $chatId,
1098
            'user_id' => $userId,
1099
            'until_date' => $untilDate
1100
        ]);
1101
    }
1102
1103
    /**
1104
     * Use this method to unban a previously kicked user in a supergroup.
1105
     * The user will not return to the group automatically, but will be able to join via link, etc.
1106
     * The bot must be an administrator in the group for this to work. Returns True on success.
1107
     *
1108
     * @param int|string $chatId Unique identifier for the target group
1109
     * or username of the target supergroup (in the format @supergroupusername)
1110
     * @param int $userId Unique identifier of the target user
1111
     *
1112
     * @return bool
1113
     */
1114
    public function unbanChatMember($chatId, $userId)
1115
    {
1116
        return $this->call('unbanChatMember', [
1117
            'chat_id' => $chatId,
1118
            'user_id' => $userId,
1119
        ]);
1120
    }
1121
1122
    /**
1123
     * Use this method to send answers to callback queries sent from inline keyboards.
1124
     * The answer will be displayed to the user as a notification at the top of the chat screen or as an alert.
1125
     *
1126
     * @param $callbackQueryId
1127
     * @param null $text
1128
     * @param bool $showAlert
1129
     *
1130
     * @return bool
1131
     */
1132
    public function answerCallbackQuery($callbackQueryId, $text = null, $showAlert = false)
1133
    {
1134
        return $this->call('answerCallbackQuery', [
1135
            'callback_query_id' => $callbackQueryId,
1136
            'text' => $text,
1137
            'show_alert' => (bool)$showAlert,
1138
        ]);
1139
    }
1140
1141
1142
    /**
1143
     * Use this method to edit text messages sent by the bot or via the bot
1144
     *
1145
     * @param int|string $chatId
1146
     * @param int $messageId
1147
     * @param string $text
1148
     * @param string $inlineMessageId
1149
     * @param string|null $parseMode
1150
     * @param bool $disablePreview
1151
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
1152
     *        Types\ReplyKeyboardRemove|null $replyMarkup
1153
     * @return Message
1154
     */
1155
    public function editMessageText(
1156
        $chatId,
1157
        $messageId,
1158
        $text,
1159
        $parseMode = null,
1160
        $disablePreview = false,
1161
        $replyMarkup = null,
1162
        $inlineMessageId = null
1163
    ) {
1164
        return Message::fromResponse($this->call('editMessageText', [
1165
            'chat_id' => $chatId,
1166
            'message_id' => $messageId,
1167
            'text' => $text,
1168
            'inline_message_id' => $inlineMessageId,
1169
            'parse_mode' => $parseMode,
1170
            'disable_web_page_preview' => $disablePreview,
1171
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1172
        ]));
1173
    }
1174
1175
    /**
1176
     * Use this method to edit text messages sent by the bot or via the bot
1177
     *
1178
     * @param int|string $chatId
1179
     * @param int $messageId
1180
     * @param string|null $caption
1181
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
1182
     *        Types\ReplyKeyboardRemove|null $replyMarkup
1183
     * @param string $inlineMessageId
1184
     * @param string|null $parseMode
1185
     *
1186
     * @return \TelegramBot\Api\Types\Message
1187
     * @throws \TelegramBot\Api\InvalidArgumentException
1188
     * @throws \TelegramBot\Api\Exception
1189
     */
1190 View Code Duplication
    public function editMessageCaption(
1191
        $chatId,
1192
        $messageId,
1193
        $caption = null,
1194
        $replyMarkup = null,
1195
        $inlineMessageId = null,
1196
        $parseMode = null
1197
    ) {
1198
        return Message::fromResponse($this->call('editMessageCaption', [
1199
            'chat_id' => $chatId,
1200
            'message_id' => $messageId,
1201
            'inline_message_id' => $inlineMessageId,
1202
            'caption' => $caption,
1203
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1204
            'parse_mode' => $parseMode
1205
        ]));
1206
    }
1207
1208
    /**
1209
     * Use this method to edit animation, audio, document, photo, or video messages.
1210
     * If a message is a part of a message album, then it can be edited only to a photo or a video.
1211
     * Otherwise, message type can be changed arbitrarily.
1212
     * When inline message is edited, new file can't be uploaded.
1213
     * Use previously uploaded file via its file_id or specify a URL.
1214
     * On success, if the edited message was sent by the bot, the edited Message is returned, otherwise True is returned
1215
     *
1216
     * @param $chatId
1217
     * @param $messageId
1218
     * @param InputMedia $media
1219
     * @param null $inlineMessageId
1220
     * @param null $replyMarkup
1221
     * @return bool|Message
1222
     * @throws Exception
1223
     * @throws HttpException
1224
     * @throws InvalidJsonException
1225
     */
1226 View Code Duplication
    public function editMessageMedia(
1227
        $chatId,
1228
        $messageId,
1229
        InputMedia $media,
1230
        $inlineMessageId = null,
1231
        $replyMarkup = null
1232
    ) {
1233
        return Message::fromResponse($this->call('editMessageMedia', [
1234
            'chat_id' => $chatId,
1235
            'message_id' => $messageId,
1236
            'inline_message_id' => $inlineMessageId,
1237
            'media' => $media->toJson(),
1238
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1239
        ]));
1240
    }
1241
1242
    /**
1243
     * Use this method to edit only the reply markup of messages sent by the bot or via the bot
1244
     *
1245
     * @param int|string $chatId
1246
     * @param int $messageId
1247
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
1248
     *        Types\ReplyKeyboardRemove|null $replyMarkup
1249
     * @param string $inlineMessageId
1250
     *
1251
     * @return Message
1252
     */
1253
    public function editMessageReplyMarkup(
1254
        $chatId,
1255
        $messageId,
1256
        $replyMarkup = null,
1257
        $inlineMessageId = null
1258
    ) {
1259
        return Message::fromResponse($this->call('editMessageReplyMarkup', [
1260
            'chat_id' => $chatId,
1261
            'message_id' => $messageId,
1262
            'inline_message_id' => $inlineMessageId,
1263
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1264
        ]));
1265
    }
1266
1267
    /**
1268
     * Use this method to delete a message, including service messages, with the following limitations:
1269
     *  - A message can only be deleted if it was sent less than 48 hours ago.
1270
     *  - Bots can delete outgoing messages in groups and supergroups.
1271
     *  - Bots granted can_post_messages permissions can delete outgoing messages in channels.
1272
     *  - If the bot is an administrator of a group, it can delete any message there.
1273
     *  - If the bot has can_delete_messages permission in a supergroup or a channel, it can delete any message there.
1274
     *
1275
     * @param int|string $chatId
1276
     * @param int $messageId
1277
     *
1278
     * @return bool
1279
     */
1280
    public function deleteMessage($chatId, $messageId)
1281
    {
1282
        return $this->call('deleteMessage', [
1283
            'chat_id' => $chatId,
1284
            'message_id' => $messageId,
1285
        ]);
1286
    }
1287
1288
    /**
1289
     * Close curl
1290
     */
1291 9
    public function __destruct()
1292
    {
1293 9
        $this->curl && curl_close($this->curl);
1294 9
    }
1295
1296
    /**
1297
     * @return string
1298
     */
1299
    public function getUrl()
1300
    {
1301
        return self::URL_PREFIX.$this->token;
1302
    }
1303
1304
    /**
1305
     * @return string
1306
     */
1307
    public function getFileUrl()
1308
    {
1309
        return self::FILE_URL_PREFIX.$this->token;
1310
    }
1311
1312
    /**
1313
     * @param \TelegramBot\Api\Types\Update $update
1314
     * @param string $eventName
1315
     *
1316
     * @throws \TelegramBot\Api\Exception
1317
     */
1318
    public function trackUpdate(Update $update, $eventName = 'Message')
1319
    {
1320
        if (!in_array($update->getUpdateId(), $this->trackedEvents)) {
1321
            $this->trackedEvents[] = $update->getUpdateId();
1322
1323
            $this->track($update->getMessage(), $eventName);
1324
1325
            if (count($this->trackedEvents) > self::MAX_TRACKED_EVENTS) {
1326
                $this->trackedEvents = array_slice($this->trackedEvents, round(self::MAX_TRACKED_EVENTS / 4));
1327
            }
1328
        }
1329
    }
1330
1331
    /**
1332
     * Wrapper for tracker
1333
     *
1334
     * @param \TelegramBot\Api\Types\Message $message
1335
     * @param string $eventName
1336
     *
1337
     * @throws \TelegramBot\Api\Exception
1338
     */
1339
    public function track(Message $message, $eventName = 'Message')
1340
    {
1341
        if ($this->tracker instanceof Botan) {
1342
            $this->tracker->track($message, $eventName);
1343
        }
1344
    }
1345
1346
    /**
1347
     * Use this method to send invoices. On success, the sent Message is returned.
1348
     *
1349
     * @param int|string $chatId
1350
     * @param string $title
1351
     * @param string $description
1352
     * @param string $payload
1353
     * @param string $providerToken
1354
     * @param string $startParameter
1355
     * @param string $currency
1356
     * @param array $prices
1357
     * @param string|null $photoUrl
1358
     * @param int|null $photoSize
1359
     * @param int|null $photoWidth
1360
     * @param int|null $photoHeight
1361
     * @param bool $needName
1362
     * @param bool $needPhoneNumber
1363
     * @param bool $needEmail
1364
     * @param bool $needShippingAddress
1365
     * @param bool $isFlexible
1366
     * @param int|null $replyToMessageId
1367
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
1368
     *        Types\ReplyKeyboardRemove|null $replyMarkup
1369
     * @param bool $disableNotification
1370
     * @param string|null $providerData
1371
     * @param bool $sendPhoneNumberToProvider
1372
     * @param bool $sendEmailToProvider
1373
     *
1374
     * @return Message
1375
     */
1376
    public function sendInvoice(
1377
        $chatId,
1378
        $title,
1379
        $description,
1380
        $payload,
1381
        $providerToken,
1382
        $startParameter,
1383
        $currency,
1384
        $prices,
1385
        $isFlexible = false,
1386
        $photoUrl = null,
1387
        $photoSize = null,
1388
        $photoWidth = null,
1389
        $photoHeight = null,
1390
        $needName = false,
1391
        $needPhoneNumber = false,
1392
        $needEmail = false,
1393
        $needShippingAddress = false,
1394
        $replyToMessageId = null,
1395
        $replyMarkup = null,
1396
        $disableNotification = false,
1397
        $providerData = null,
1398
        $sendPhoneNumberToProvider = false,
1399
        $sendEmailToProvider = false
1400
    ) {
1401
        return Message::fromResponse($this->call('sendInvoice', [
1402
            'chat_id' => $chatId,
1403
            'title' => $title,
1404
            'description' => $description,
1405
            'payload' => $payload,
1406
            'provider_token' => $providerToken,
1407
            'start_parameter' => $startParameter,
1408
            'currency' => $currency,
1409
            'prices' => json_encode($prices),
1410
            'is_flexible' => $isFlexible,
1411
            'photo_url' => $photoUrl,
1412
            'photo_size' => $photoSize,
1413
            'photo_width' => $photoWidth,
1414
            'photo_height' => $photoHeight,
1415
            'need_name' => $needName,
1416
            'need_phone_number' => $needPhoneNumber,
1417
            'need_email' => $needEmail,
1418
            'need_shipping_address' => $needShippingAddress,
1419
            'reply_to_message_id' => $replyToMessageId,
1420
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1421
            'disable_notification' => (bool)$disableNotification,
1422
            'provider_data' => $providerData,
1423
            'send_phone_number_to_provider' => (bool)$sendPhoneNumberToProvider,
1424
            'send_email_to_provider' => (bool)$sendEmailToProvider
1425
        ]));
1426
    }
1427
1428
    /**
1429
     * If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, the Bot API
1430
     * will send an Update with a shipping_query field to the bot. Use this method to reply to shipping queries.
1431
     * On success, True is returned.
1432
     *
1433
     * @param string $shippingQueryId
1434
     * @param bool $ok
1435
     * @param array $shipping_options
1436
     * @param null|string $errorMessage
1437
     *
1438
     * @return bool
1439
     *
1440
     */
1441
    public function answerShippingQuery($shippingQueryId, $ok = true, $shipping_options = [], $errorMessage = null)
1442
    {
1443
        return $this->call('answerShippingQuery', [
1444
            'shipping_query_id' => $shippingQueryId,
1445
            'ok' => (bool)$ok,
1446
            'shipping_options' => json_encode($shipping_options),
1447
            'error_message' => $errorMessage
1448
        ]);
1449
    }
1450
1451
    /**
1452
     * Use this method to respond to such pre-checkout queries. On success, True is returned.
1453
     * Note: The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent.
1454
     *
1455
     * @param string $preCheckoutQueryId
1456
     * @param bool $ok
1457
     * @param null|string $errorMessage
1458
     *
1459
     * @return mixed
1460
     */
1461
    public function answerPreCheckoutQuery($preCheckoutQueryId, $ok = true, $errorMessage = null)
1462
    {
1463
        return $this->call('answerPreCheckoutQuery', [
1464
            'pre_checkout_query_id' => $preCheckoutQueryId,
1465
            'ok' => (bool)$ok,
1466
            'error_message' => $errorMessage
1467
        ]);
1468
    }
1469
1470
    /**
1471
     * Use this method to restrict a user in a supergroup.
1472
     * The bot must be an administrator in the supergroup for this to work and must have the appropriate admin rights.
1473
     * Pass True for all boolean parameters to lift restrictions from a user.
1474
     *
1475
     * @param string|int $chatId Unique identifier for the target chat or username of the target supergroup
1476
     *                   (in the format @supergroupusername)
1477
     * @param int $userId Unique identifier of the target user
1478
     * @param null|integer $untilDate Date when restrictions will be lifted for the user, unix time.
1479
     *                     If user is restricted for more than 366 days or less than 30 seconds from the current time,
1480
     *                     they are considered to be restricted forever
1481
     * @param bool $canSendMessages Pass True, if the user can send text messages, contacts, locations and venues
1482
     * @param bool $canSendMediaMessages No Pass True, if the user can send audios, documents, photos, videos,
1483
     *                                   video notes and voice notes, implies can_send_messages
1484
     * @param bool $canSendOtherMessages Pass True, if the user can send animations, games, stickers and
1485
     *                                   use inline bots, implies can_send_media_messages
1486
     * @param bool $canAddWebPagePreviews Pass True, if the user may add web page previews to their messages,
1487
     *                                    implies can_send_media_messages
1488
     *
1489
     * @return bool
1490
     */
1491
    public function restrictChatMember(
1492
        $chatId,
1493
        $userId,
1494
        $untilDate = null,
1495
        $canSendMessages = false,
1496
        $canSendMediaMessages = false,
1497
        $canSendOtherMessages = false,
1498
        $canAddWebPagePreviews = false
1499
    ) {
1500
        return $this->call('restrictChatMember', [
1501
            'chat_id' => $chatId,
1502
            'user_id' => $userId,
1503
            'until_date' => $untilDate,
1504
            'can_send_messages' => $canSendMessages,
1505
            'can_send_media_messages' => $canSendMediaMessages,
1506
            'can_send_other_messages' => $canSendOtherMessages,
1507
            'can_add_web_page_previews' => $canAddWebPagePreviews
1508
        ]);
1509
    }
1510
1511
    /**
1512
     * Use this method to promote or demote a user in a supergroup or a channel.
1513
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1514
     * Pass False for all boolean parameters to demote a user.
1515
     *
1516
     * @param string|int $chatId Unique identifier for the target chat or username of the target supergroup
1517
     *                   (in the format @supergroupusername)
1518
     * @param int $userId Unique identifier of the target user
1519
     * @param bool $canChangeInfo Pass True, if the administrator can change chat title, photo and other settings
1520
     * @param bool $canPostMessages Pass True, if the administrator can create channel posts, channels only
1521
     * @param bool $canEditMessages Pass True, if the administrator can edit messages of other users, channels only
1522
     * @param bool $canDeleteMessages Pass True, if the administrator can delete messages of other users
1523
     * @param bool $canInviteUsers Pass True, if the administrator can invite new users to the chat
1524
     * @param bool $canRestrictMembers Pass True, if the administrator can restrict, ban or unban chat members
1525
     * @param bool $canPinMessages Pass True, if the administrator can pin messages, supergroups only
1526
     * @param bool $canPromoteMembers Pass True, if the administrator can add new administrators with a subset of his
1527
     *                                own privileges or demote administrators that he has promoted,directly or
1528
     *                                indirectly (promoted by administrators that were appointed by him)
1529
     *
1530
     * @return bool
1531
     */
1532
    public function promoteChatMember(
1533
        $chatId,
1534
        $userId,
1535
        $canChangeInfo = true,
1536
        $canPostMessages = true,
1537
        $canEditMessages = true,
1538
        $canDeleteMessages = true,
1539
        $canInviteUsers = true,
1540
        $canRestrictMembers = true,
1541
        $canPinMessages = true,
1542
        $canPromoteMembers = true
1543
    ) {
1544
        return $this->call('promoteChatMember', [
1545
            'chat_id' => $chatId,
1546
            'user_id' => $userId,
1547
            'can_change_info' => $canChangeInfo,
1548
            'can_post_messages' => $canPostMessages,
1549
            'can_edit_messages' => $canEditMessages,
1550
            'can_delete_messages' => $canDeleteMessages,
1551
            'can_invite_users' => $canInviteUsers,
1552
            'can_restrict_members' => $canRestrictMembers,
1553
            'can_pin_messages' => $canPinMessages,
1554
            'can_promote_members' => $canPromoteMembers
1555
        ]);
1556
    }
1557
1558
    /**
1559
     * Use this method to export an invite link to a supergroup or a channel.
1560
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1561
     *
1562
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1563
     *                           (in the format @channelusername)
1564
     * @return string
1565
     */
1566
    public function exportChatInviteLink($chatId)
1567
    {
1568
        return $this->call('exportChatInviteLink', [
1569
            'chat_id' => $chatId
1570
        ]);
1571
    }
1572
1573
    /**
1574
     * Use this method to set a new profile photo for the chat. Photos can't be changed for private chats.
1575
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1576
     *
1577
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1578
     *                           (in the format @channelusername)
1579
     * @param \CURLFile|string $photo New chat photo, uploaded using multipart/form-data
1580
     *
1581
     * @return bool
1582
     */
1583
    public function setChatPhoto($chatId, $photo)
1584
    {
1585
        return $this->call('setChatPhoto', [
1586
            'chat_id' => $chatId,
1587
            'photo' => $photo
1588
        ]);
1589
    }
1590
1591
    /**
1592
     * Use this method to delete a chat photo. Photos can't be changed for private chats.
1593
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1594
     *
1595
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1596
     *                           (in the format @channelusername)
1597
     *
1598
     * @return bool
1599
     */
1600
    public function deleteChatPhoto($chatId)
1601
    {
1602
        return $this->call('deleteChatPhoto', [
1603
            'chat_id' => $chatId
1604
        ]);
1605
    }
1606
1607
    /**
1608
     * Use this method to change the title of a chat. Titles can't be changed for private chats.
1609
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1610
     *
1611
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1612
     *                           (in the format @channelusername)
1613
     * @param string $title New chat title, 1-255 characters
1614
     *
1615
     * @return bool
1616
     */
1617
    public function setChatTitle($chatId, $title)
1618
    {
1619
        return $this->call('setChatTitle', [
1620
            'chat_id' => $chatId,
1621
            'title' => $title
1622
        ]);
1623
    }
1624
1625
    /**
1626
     * Use this method to change the description of a supergroup or a channel.
1627
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1628
     *
1629
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1630
     *                   (in the format @channelusername)
1631
     * @param string|null $description New chat description, 0-255 characters
1632
     *
1633
     * @return bool
1634
     */
1635
    public function setChatDescription($chatId, $description = null)
1636
    {
1637
        return $this->call('setChatDescription', [
1638
            'chat_id' => $chatId,
1639
            'title' => $description
1640
        ]);
1641
    }
1642
1643
    /**
1644
     * Use this method to pin a message in a supergroup.
1645
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1646
     *
1647
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1648
     *                   (in the format @channelusername)
1649
     * @param int $messageId Identifier of a message to pin
1650
     * @param bool $disableNotification
1651
     *
1652
     * @return bool
1653
     */
1654
    public function pinChatMessage($chatId, $messageId, $disableNotification = false)
1655
    {
1656
        return $this->call('pinChatMessage', [
1657
            'chat_id' => $chatId,
1658
            'message_id' => $messageId,
1659
            'disable_notification' => $disableNotification
1660
        ]);
1661
    }
1662
1663
    /**
1664
     * Use this method to unpin a message in a supergroup chat.
1665
     * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1666
     *
1667
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1668
     *                   (in the format @channelusername)
1669
     *
1670
     * @return bool
1671
     */
1672
    public function unpinChatMessage($chatId)
1673
    {
1674
        return $this->call('unpinChatMessage', [
1675
            'chat_id' => $chatId
1676
        ]);
1677
    }
1678
1679
    /**
1680
     * Use this method to get up to date information about the chat
1681
     * (current name of the user for one-on-one conversations, current username of a user, group or channel, etc.).
1682
     *
1683
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1684
     *                   (in the format @channelusername)
1685
     *
1686
     * @return Chat
1687
     */
1688
    public function getChat($chatId)
1689
    {
1690
        return Chat::fromResponse($this->call('getChat', [
1691
            'chat_id' => $chatId
1692
        ]));
1693
    }
1694
1695
    /**
1696
     * Use this method to get information about a member of a chat.
1697
     *
1698
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1699
     *                   (in the format @channelusername)
1700
     * @param int $userId
1701
     *
1702
     * @return ChatMember
1703
     */
1704
    public function getChatMember($chatId, $userId)
1705
    {
1706
        return ChatMember::fromResponse($this->call('getChatMember', [
1707
            'chat_id' => $chatId,
1708
            'user_id' => $userId
1709
        ]));
1710
    }
1711
1712
    /**
1713
     * Use this method for your bot to leave a group, supergroup or channel.
1714
     *
1715
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1716
     *                   (in the format @channelusername)
1717
     *
1718
     * @return bool
1719
     */
1720
    public function leaveChat($chatId)
1721
    {
1722
        return $this->call('leaveChat', [
1723
            'chat_id' => $chatId
1724
        ]);
1725
    }
1726
1727
    /**
1728
     * Use this method to get the number of members in a chat.
1729
     *
1730
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1731
     *                   (in the format @channelusername)
1732
     *
1733
     * @return int
1734
     */
1735
    public function getChatMembersCount($chatId)
1736
    {
1737
        return $this->call(
1738
            'getChatMembersCount',
1739
            [
1740
                'chat_id' => $chatId
1741
            ]
1742
        );
1743
    }
1744
1745
    /**
1746
     * Use this method to get a list of administrators in a chat.
1747
     *
1748
     * @param string|int $chatId Unique identifier for the target chat or username of the target channel
1749
     *                   (in the format @channelusername)
1750
     *
1751
     * @return array
1752
     */
1753
    public function getChatAdministrators($chatId)
1754
    {
1755
        return ArrayOfChatMemberEntity::fromResponse(
1756
            $this->call(
1757
                'getChatAdministrators',
1758
                [
1759
                    'chat_id' => $chatId
1760
                ]
1761
            )
1762
        );
1763
    }
1764
1765
    /**
1766
     * As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long.
1767
     * Use this method to send video messages.
1768
     * On success, the sent Message is returned.
1769
     *
1770
     * @param int|string $chatId chat_id or @channel_name
1771
     * @param \CURLFile|string $videoNote
1772
     * @param int|null $duration
1773
     * @param int|null $length
1774
     * @param int|null $replyToMessageId
1775
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
1776
     *        Types\ReplyKeyboardRemove|null $replyMarkup
1777
     * @param bool $disableNotification
1778
     *
1779
     * @return \TelegramBot\Api\Types\Message
1780
     * @throws \TelegramBot\Api\InvalidArgumentException
1781
     * @throws \TelegramBot\Api\Exception
1782
     */
1783
    public function sendVideoNote(
1784
        $chatId,
1785
        $videoNote,
1786
        $duration = null,
1787
        $length = null,
1788
        $replyToMessageId = null,
1789
        $replyMarkup = null,
1790
        $disableNotification = false
1791
    ) {
1792
        return Message::fromResponse($this->call('sendVideoNote', [
1793
            'chat_id' => $chatId,
1794
            'video_note' => $videoNote,
1795
            'duration' => $duration,
1796
            'length' => $length,
1797
            'reply_to_message_id' => $replyToMessageId,
1798
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1799
            'disable_notification' => (bool)$disableNotification
1800
        ]));
1801
    }
1802
1803
    /**
1804
     * Use this method to send a group of photos or videos as an album.
1805
     * On success, the sent \TelegramBot\Api\Types\Message is returned.
1806
     *
1807
     * @param int|string $chatId
1808
     * @param ArrayOfInputMedia $media
1809
     * @param int|null $replyToMessageId
1810
     * @param bool $disableNotification
1811
     *
1812
     * @return array
1813
     * @throws \TelegramBot\Api\Exception
1814
     */
1815
    public function sendMediaGroup(
1816
        $chatId,
1817
        $media,
1818
        $disableNotification = false,
1819
        $replyToMessageId = null
1820
    ) {
1821
        return ArrayOfMessages::fromResponse($this->call('sendMediaGroup', [
1822
            'chat_id' => $chatId,
1823
            'media' => $media->toJson(),
1824
            'reply_to_message_id' => (int)$replyToMessageId,
1825
            'disable_notification' => (bool)$disableNotification
1826
        ]));
1827
    }
1828
1829
    /**
1830
     * Enable proxy for curl requests. Empty string will disable proxy.
1831
     *
1832
     * @param string $proxyString
1833
     *
1834
     * @return BotApi
1835
     */
1836
    public function setProxy($proxyString = '', $socks5 = false)
1837
    {
1838
        if (empty($proxyString)) {
1839
            $this->proxySettings = [];
1840
            return $this;
1841
        }
1842
1843
        $this->proxySettings = [
1844
            CURLOPT_PROXY => $proxyString,
1845
            CURLOPT_HTTPPROXYTUNNEL => true,
1846
        ];
1847
1848
        if ($socks5) {
1849
            $this->proxySettings[CURLOPT_PROXYTYPE] = CURLPROXY_SOCKS5;
1850
        }
1851
        return $this;
1852
    }
1853
1854
1855
    /**
1856
     * Use this method to send a native poll. A native poll can't be sent to a private chat.
1857
     * On success, the sent \TelegramBot\Api\Types\Message is returned.
1858
     *
1859
     * @param $chatId string|int Unique identifier for the target chat or username of the target channel
1860
     *                (in the format @channelusername)
1861
     * @param string $question Poll question, 1-255 characters
1862
     * @param array $options A JSON-serialized list of answer options, 2-10 strings 1-100 characters each
1863
     * @param bool $isAnonymous True, if the poll needs to be anonymous, defaults to True
1864
     * @param null $type Poll type, “quiz” or “regular”, defaults to “regular”
1865
     * @param bool $allowsMultipleAnswers True, if the poll allows multiple answers,
1866
     *                          ignored for polls in quiz mode, defaults to False
1867
     * @param null $correctOptionId 0-based identifier of the correct answer option, required for polls in quiz mode
1868
     * @param bool $isClosed Pass True, if the poll needs to be immediately closed. This can be useful for poll preview.
1869
     * @param bool $disableNotification Sends the message silently. Users will receive a notification with no sound.
1870
     * @param int|null $replyToMessageId If the message is a reply, ID of the original message
1871
     * @param null $replyMarkup Additional interface options. A JSON-serialized object for an inline keyboard,
1872
     *                          custom reply keyboard, instructions to remove reply
1873
     *                          keyboard or to force a reply from the user.
1874
     * @return \TelegramBot\Api\Types\Message
1875
     * @throws Exception
1876
     * @throws HttpException
1877
     * @throws InvalidJsonException
1878
     */
1879
    public function sendPoll(
1880
        $chatId,
1881
        $question,
1882
        $options,
1883
        $isAnonymous = false,
1884
        $type = null,
1885
        $allowsMultipleAnswers = false,
1886
        $correctOptionId = null,
1887
        $isClosed = false,
1888
        $disableNotification = false,
1889
        $replyToMessageId = null,
1890
        $replyMarkup = null
1891
    ) {
1892
        return Message::fromResponse($this->call('sendPoll', [
1893
            'chat_id' => $chatId,
1894
            'question' => $question,
1895
            'options' => json_encode($options),
1896
            'is_anonymous' => (bool) $isAnonymous,
1897
            'type' => (string) $type,
1898
            'allows_multiple_answers' => (bool) $allowsMultipleAnswers,
1899
            'correct_option_id' => (int) $correctOptionId,
1900
            'is_closed' => (bool) $isClosed,
1901
            'disable_notification' => (bool) $disableNotification,
1902
            'reply_to_message_id' => (int) $replyToMessageId,
1903
            'reply_markup' => $replyMarkup === null ? $replyMarkup : $replyMarkup->toJson(),
0 ignored issues
show
Bug introduced by
The method toJson cannot be called on $replyMarkup (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1904
        ]));
1905
    }
1906
1907
    /**
1908
     * Use this method to send a dice, which will have a random value from 1 to 6.
1909
     * On success, the sent Message is returned. (Yes, we're aware of the “proper” singular of die.
1910
     * But it's awkward, and we decided to help it change. One dice at a time!)
1911
     *
1912
     * @param $chatId string|int Unique identifier for the target chat or username of the target channel
1913
     *                (in the format @channelusername)
1914
     * @param bool $disableNotification Sends the message silently. Users will receive a notification with no sound.
1915
     * @param null $replyToMessageId If the message is a reply, ID of the original message
1916
     * @param null $replyMarkup Additional interface options. A JSON-serialized object for an inline keyboard,
1917
     *                          custom reply keyboard, instructions to remove reply
1918
     *                          keyboard or to force a reply from the user.
1919
     * @return bool|Message
1920
     * @throws Exception
1921
     * @throws HttpException
1922
     * @throws InvalidJsonException
1923
     */
1924 View Code Duplication
    public function sendDice(
1925
        $chatId,
1926
        $disableNotification = false,
1927
        $replyToMessageId = null,
1928
        $replyMarkup = null
1929
    ) {
1930
        return Message::fromResponse($this->call('sendDice', [
1931
            'chat_id' => $chatId,
1932
            'disable_notification' => (bool) $disableNotification,
1933
            'reply_to_message_id' => (int) $replyToMessageId,
1934
            'reply_markup' => $replyMarkup === null ? $replyMarkup : $replyMarkup->toJson(),
0 ignored issues
show
Bug introduced by
The method toJson cannot be called on $replyMarkup (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1935
        ]));
1936
    }
1937
1938
    /**
1939
     * Use this method to stop a poll which was sent by the bot.
1940
     * On success, the stopped \TelegramBot\Api\Types\Poll with the final results is returned.
1941
     *
1942
     * @param int|string $chatId
1943
     * @param int $messageId
1944
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|
1945
     *        Types\ReplyKeyboardRemove|null $replyMarkup
1946
     * @return Poll
1947
     * @throws \TelegramBot\Api\InvalidArgumentException
1948
     * @throws \TelegramBot\Api\Exception
1949
     */
1950
    public function stopPoll(
1951
        $chatId,
1952
        $messageId,
1953
        $replyMarkup = null
1954
    ) {
1955
        return Poll::fromResponse($this->call('stopPoll', [
1956
            'chat_id' => $chatId,
1957
            'message_id' => $messageId,
1958
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
1959
        ]));
1960
    }
1961
1962
    /**
1963
     * Set an option for a cURL transfer
1964
     *
1965
     * @param int $option The CURLOPT_XXX option to set
1966
     * @param mixed $value The value to be set on option
1967
     */
1968
    public function setCurlOption($option, $value)
1969
    {
1970
        $this->customCurlOptions[$option] = $value;
1971
    }
1972
1973
    /**
1974
     * Unset an option for a cURL transfer
1975
     *
1976
     * @param int $option The CURLOPT_XXX option to unset
1977
     */
1978
    public function unsetCurlOption($option)
1979
    {
1980
        unset($this->customCurlOptions[$option]);
1981
    }
1982
1983
    /**
1984
     * Clean custom options
1985
     */
1986
    public function resetCurlOptions()
1987
    {
1988
        $this->customCurlOptions = [];
1989
    }
1990
}
1991