Completed
Push — master ( 6a7f3a...a2dffe )
by
unknown
07:50
created

BotApi::sendAudio()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 21
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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