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