Passed
Pull Request — master (#146)
by
unknown
03:06
created

BotApi::sendAudio()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 23
Code Lines 20

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