Passed
Pull Request — master (#175)
by
unknown
10:56
created

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