Completed
Push — master ( 8ba284...6140a2 )
by
unknown
04:16
created

BotApi::sendInvoice()   B

Complexity

Conditions 2
Paths 1

Size

Total Lines 45
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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