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