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