Passed
Push — master ( 6140a2...ff30ae )
by
unknown
09:50
created

BotApi::sendVenue()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 23
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 23
c 0
b 0
f 0
ccs 0
cts 12
cp 0
rs 9.0856
cc 2
eloc 20
nc 1
nop 9
crap 6

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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