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