Completed
Push — master ( c1766c...380288 )
by Gusev
14:27 queued 12:09
created

BotApi::sendVenue()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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