Completed
Push — master ( 645e8e...c5a554 )
by Gusev
03:42 queued 37s
created

BotApi::sendAudio()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 21
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 5
Bugs 2 Features 2
Metric Value
c 5
b 2
f 2
dl 0
loc 21
ccs 0
cts 0
cp 0
rs 9.3142
cc 2
eloc 18
nc 1
nop 8
crap 6

How to fix   Many Parameters   

Many Parameters

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

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace TelegramBot\Api;
4
5
use TelegramBot\Api\Types\ArrayOfUpdates;
6
use TelegramBot\Api\Types\File;
7
use TelegramBot\Api\Types\Message;
8
use TelegramBot\Api\Types\Update;
9
use TelegramBot\Api\Types\User;
10
use TelegramBot\Api\Types\UserProfilePhotos;
11
12
/**
13
 * Class BotApi
14
 *
15
 * @package TelegramBot\Api
16
 */
17
class BotApi
18
{
19
    /**
20
     * HTTP codes
21
     *
22
     * @var array
23
     */
24
    public static $codes = [
25
        // Informational 1xx
26
        100 => 'Continue',
27
        101 => 'Switching Protocols',
28
        102 => 'Processing',            // RFC2518
29
        // Success 2xx
30
        200 => 'OK',
31
        201 => 'Created',
32
        202 => 'Accepted',
33
        203 => 'Non-Authoritative Information',
34
        204 => 'No Content',
35
        205 => 'Reset Content',
36
        206 => 'Partial Content',
37
        207 => 'Multi-Status',          // RFC4918
38
        208 => 'Already Reported',      // RFC5842
39
        226 => 'IM Used',               // RFC3229
40
        // Redirection 3xx
41
        300 => 'Multiple Choices',
42
        301 => 'Moved Permanently',
43
        302 => 'Found', // 1.1
44
        303 => 'See Other',
45
        304 => 'Not Modified',
46
        305 => 'Use Proxy',
47
        // 306 is deprecated but reserved
48
        307 => 'Temporary Redirect',
49
        308 => 'Permanent Redirect',    // RFC7238
50
        // Client Error 4xx
51
        400 => 'Bad Request',
52
        401 => 'Unauthorized',
53
        402 => 'Payment Required',
54
        403 => 'Forbidden',
55
        404 => 'Not Found',
56
        405 => 'Method Not Allowed',
57
        406 => 'Not Acceptable',
58
        407 => 'Proxy Authentication Required',
59
        408 => 'Request Timeout',
60
        409 => 'Conflict',
61
        410 => 'Gone',
62
        411 => 'Length Required',
63
        412 => 'Precondition Failed',
64
        413 => 'Payload Too Large',
65
        414 => 'URI Too Long',
66
        415 => 'Unsupported Media Type',
67
        416 => 'Range Not Satisfiable',
68
        417 => 'Expectation Failed',
69
        422 => 'Unprocessable Entity',                                        // RFC4918
70
        423 => 'Locked',                                                      // RFC4918
71
        424 => 'Failed Dependency',                                           // RFC4918
72
        425 => 'Reserved for WebDAV advanced collections expired proposal',   // RFC2817
73
        426 => 'Upgrade Required',                                            // RFC2817
74
        428 => 'Precondition Required',                                       // RFC6585
75
        429 => 'Too Many Requests',                                           // RFC6585
76
        431 => 'Request Header Fields Too Large',                             // RFC6585
77
        // Server Error 5xx
78
        500 => 'Internal Server Error',
79
        501 => 'Not Implemented',
80
        502 => 'Bad Gateway',
81
        503 => 'Service Unavailable',
82
        504 => 'Gateway Timeout',
83
        505 => 'HTTP Version Not Supported',
84
        506 => 'Variant Also Negotiates (Experimental)',                      // RFC2295
85
        507 => 'Insufficient Storage',                                        // RFC4918
86
        508 => 'Loop Detected',                                               // RFC5842
87
        510 => 'Not Extended',                                                // RFC2774
88
        511 => 'Network Authentication Required',                             // RFC6585
89
    ];
90
91
92
    /**
93
     * Default http status code
94
     */
95
    const DEFAULT_STATUS_CODE = 200;
96
97
    /**
98
     * Not Modified http status code
99
     */
100
    const NOT_MODIFIED_STATUS_CODE = 304;
101
102
    /**
103
     * Limits for tracked ids
104
     */
105
    const MAX_TRACKED_EVENTS = 200;
106
107
    /**
108
     * Url prefixes
109
     */
110
    const URL_PREFIX = 'https://api.telegram.org/bot';
111
112
    /**
113
     * Url prefix for files
114
     */
115
    const FILE_URL_PREFIX = 'https://api.telegram.org/file/bot';
116
117
    /**
118
     * CURL object
119
     *
120
     * @var
121
     */
122
    protected $curl;
123
124
    /**
125
     * Bot token
126
     *
127
     * @var string
128
     */
129
    protected $token;
130
131
    /**
132
     * Botan tracker
133
     *
134
     * @var \TelegramBot\Api\Botan
135
     */
136
    protected $tracker;
137
138
    /**
139
     * list of event ids
140
     *
141
     * @var array
142
     */
143
    protected $trackedEvents = [];
144
145
    /**
146
     * Check whether return associative array
147
     *
148
     * @var bool
149
     */
150
    protected $returnArray = true;
151
152
153
    /**
154
     * Constructor
155
     *
156
     * @param string $token Telegram Bot API token
157
     * @param string|null $trackerToken Yandex AppMetrica application api_key
158
     */
159 9
    public function __construct($token, $trackerToken = null)
160
    {
161 9
        $this->curl = curl_init();
162 9
        $this->token = $token;
163
164 9
        if ($trackerToken) {
165
            $this->tracker = new Botan($trackerToken);
166
        }
167 9
    }
168
169
    /**
170
     * Set return array
171
     *
172
     * @param bool $mode
173
     *
174
     * @return $this
175
     */
176
    public function setModeObject($mode = true)
177
    {
178
        $this->returnArray = !$mode;
179
180
        return $this;
181
    }
182
183
184
    /**
185
     * Call method
186
     *
187
     * @param string $method
188
     * @param array|null $data
189
     *
190
     * @return mixed
191
     * @throws \TelegramBot\Api\Exception
192
     * @throws \TelegramBot\Api\HttpException
193
     * @throws \TelegramBot\Api\InvalidJsonException
194
     */
195
    public function call($method, array $data = null)
196
    {
197
        $options = [
198
            CURLOPT_URL => $this->getUrl().'/'.$method,
199
            CURLOPT_RETURNTRANSFER => true,
200
            CURLOPT_POST => null,
201
            CURLOPT_POSTFIELDS => null,
202
        ];
203
204
        if ($data) {
205
            $options[CURLOPT_POST] = true;
206
            $options[CURLOPT_POSTFIELDS] = $data;
207
        }
208
209
        $response = self::jsonValidate($this->executeCurl($options), $this->returnArray);
210
211
        if ($this->returnArray) {
212
            if (!isset($response['ok'])) {
213
                throw new Exception($response['description'], $response['error_code']);
214
            }
215
216
            return $response['result'];
217
        }
218
219
        if (!$response->ok) {
220
            throw new Exception($response->description, $response->error_code);
221
        }
222
223
        return $response->result;
224
    }
225
226
    /**
227
     * curl_exec wrapper for response validation
228
     *
229
     * @param array $options
230
     *
231
     * @return string
232
     *
233
     * @throws \TelegramBot\Api\HttpException
234
     */
235
    protected function executeCurl(array $options)
236
    {
237
        curl_setopt_array($this->curl, $options);
238
239
        $result = curl_exec($this->curl);
240
        self::curlValidate($this->curl);
241
242
        return $result;
243
    }
244
245
    /**
246
     * Response validation
247
     *
248
     * @param resource $curl
249
     *
250
     * @throws \TelegramBot\Api\HttpException
251
     */
252
    public static function curlValidate($curl)
253
    {
254
        if (($httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE))
255
            && !in_array($httpCode, [self::DEFAULT_STATUS_CODE, self::NOT_MODIFIED_STATUS_CODE])
256
        ) {
257
            throw new HttpException(self::$codes[$httpCode], $httpCode);
258
        }
259
    }
260
261
    /**
262
     * JSON validation
263
     *
264
     * @param string $jsonString
265
     * @param boolean $asArray
266
     *
267
     * @return object|array
268
     * @throws \TelegramBot\Api\InvalidJsonException
269
     */
270
    public static function jsonValidate($jsonString, $asArray)
271
    {
272
        $json = json_decode($jsonString, $asArray);
273
274
        if (json_last_error() != JSON_ERROR_NONE) {
275
            throw new InvalidJsonException(json_last_error_msg(), json_last_error());
276
        }
277
278
        return $json;
279
    }
280
281
    /**
282
     * Use this method to send text messages. On success, the sent \TelegramBot\Api\Types\Message is returned.
283
     *
284
     * @param int|string $chatId
285
     * @param string $text
286
     * @param string|null $parseMode
287
     * @param bool $disablePreview
288
     * @param int|null $replyToMessageId
289
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
290
     * @param bool $disableNotification
291
     *
292
     * @return \TelegramBot\Api\Types\Message
293
     * @throws \TelegramBot\Api\InvalidArgumentException
294
     * @throws \TelegramBot\Api\Exception
295
     */
296
    public function sendMessage(
297
        $chatId,
298
        $text,
299
        $parseMode = null,
300
        $disablePreview = false,
301
        $replyToMessageId = null,
302
        $replyMarkup = null,
303
        $disableNotification = false
304
    ) {
305
        return Message::fromResponse($this->call('sendMessage', [
306
            'chat_id' => $chatId,
307
            'text' => $text,
308
            'parse_mode' => $parseMode,
309
            'disable_web_page_preview' => $disablePreview,
310
            'reply_to_message_id' => (int)$replyToMessageId,
311
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
312
            'disable_notification' => (bool)$disableNotification,
313
        ]));
314
    }
315
316
    /**
317
     * Use this method to send phone contacts
318
     *
319
     * @param int $chatId
320
     * @param string $phoneNumber
321
     * @param string $firstName
322
     * @param string $lastName
323
     * @param int|null $replyToMessageId
324
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
325
     * @param bool $disableNotification
326
     *
327
     * @return \TelegramBot\Api\Types\Message
328
     * @throws \TelegramBot\Api\Exception
329
     */
330 View Code Duplication
    public function sendContact(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
331
        $chatId,
332
        $phoneNumber,
333
        $firstName,
334
        $lastName = null,
335
        $replyToMessageId = null,
336
        $replyMarkup = null,
337
        $disableNotification = false
338
    ) {
339
        return Message::fromResponse($this->call('sendContact', [
340
            'chat_id' => $chatId,
341
            'phone_number' => $phoneNumber,
342
            'first_name' => $firstName,
343
            'last_name' => $lastName,
344
            'reply_to_message_id' => $replyToMessageId,
345
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
346
            'disable_notification' => (bool)$disableNotification,
347
        ]));
348
    }
349
350
    /**
351
     * Use this method when you need to tell the user that something is happening on the bot's side.
352
     * The status is set for 5 seconds or less (when a message arrives from your bot,
353
     * Telegram clients clear its typing status).
354
     *
355
     * We only recommend using this method when a response from the bot will take a noticeable amount of time to arrive.
356
     *
357
     * Type of action to broadcast. Choose one, depending on what the user is about to receive:
358
     * `typing` for text messages, `upload_photo` for photos, `record_video` or `upload_video` for videos,
359
     * `record_audio` or upload_audio for audio files, `upload_document` for general files,
360
     * `find_location` for location data.
361
     *
362
     * @param int $chatId
363
     * @param string $action
364
     *
365
     * @return bool
366
     * @throws \TelegramBot\Api\Exception
367
     */
368
    public function sendChatAction($chatId, $action)
369
    {
370
        return $this->call('sendChatAction', [
371
            'chat_id' => $chatId,
372
            'action' => $action,
373
        ]);
374
    }
375
376
    /**
377
     * Use this method to get a list of profile pictures for a user.
378
     *
379
     * @param int $userId
380
     * @param int $offset
381
     * @param int $limit
382
     *
383
     * @return \TelegramBot\Api\Types\UserProfilePhotos
384
     * @throws \TelegramBot\Api\Exception
385
     */
386
    public function getUserProfilePhotos($userId, $offset = 0, $limit = 100)
387
    {
388
        return UserProfilePhotos::fromResponse($this->call('getUserProfilePhotos', [
389
            'user_id' => (int)$userId,
390
            'offset' => (int)$offset,
391
            'limit' => (int)$limit,
392
        ]));
393
    }
394
395
    /**
396
     * Use this method to specify a url and receive incoming updates via an outgoing webhook.
397
     * Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url,
398
     * containing a JSON-serialized Update.
399
     * In case of an unsuccessful request, we will give up after a reasonable amount of attempts.
400
     *
401
     * @param string $url HTTPS url to send updates to. Use an empty string to remove webhook integration
402
     * @param \CURLFile|string $certificate Upload your public key certificate
403
     *                                      so that the root certificate in use can be checked
404
     *
405
     * @return string
406
     *
407
     * @throws \TelegramBot\Api\Exception
408
     */
409
    public function setWebhook($url = '', $certificate = null)
410
    {
411
        return $this->call('setWebhook', ['url' => $url, 'certificate' => $certificate]);
412
    }
413
414
    /**
415
     * A simple method for testing your bot's auth token.Requires no parameters.
416
     * Returns basic information about the bot in form of a User object.
417
     *
418
     * @return \TelegramBot\Api\Types\User
419
     * @throws \TelegramBot\Api\Exception
420
     * @throws \TelegramBot\Api\InvalidArgumentException
421
     */
422
    public function getMe()
423
    {
424
        return User::fromResponse($this->call('getMe'));
425
    }
426
427
    /**
428
     * Use this method to receive incoming updates using long polling.
429
     * An Array of Update objects is returned.
430
     *
431
     * Notes
432
     * 1. This method will not work if an outgoing webhook is set up.
433
     * 2. In order to avoid getting duplicate updates, recalculate offset after each server response.
434
     *
435
     * @param int $offset
436
     * @param int $limit
437
     * @param int $timeout
438
     *
439
     * @return Update[]
440
     * @throws \TelegramBot\Api\Exception
441
     * @throws \TelegramBot\Api\InvalidArgumentException
442
     */
443 2
    public function getUpdates($offset = 0, $limit = 100, $timeout = 0)
444
    {
445 2
        $updates = ArrayOfUpdates::fromResponse($this->call('getUpdates', [
446 2
            'offset' => $offset,
447 2
            'limit' => $limit,
448 2
            'timeout' => $timeout,
449 2
        ]));
450
451 2
        if ($this->tracker instanceof Botan) {
452
            foreach ($updates as $update) {
453
                $this->trackUpdate($update);
454
            }
455
        }
456
457 2
        return $updates;
458
    }
459
460
    /**
461
     * Use this method to send point on the map. On success, the sent Message is returned.
462
     *
463
     * @param int $chatId
464
     * @param float $latitude
465
     * @param float $longitude
466
     * @param int|null $replyToMessageId
467
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
468
     * @param bool $disableNotification
469
     *
470
     * @return \TelegramBot\Api\Types\Message
471
     * @throws \TelegramBot\Api\Exception
472
     */
473 View Code Duplication
    public function sendLocation(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
474
        $chatId,
475
        $latitude,
476
        $longitude,
477
        $replyToMessageId = null,
478
        $replyMarkup = null,
479
        $disableNotification = false
480
    ) {
481
        return Message::fromResponse($this->call('sendLocation', [
482
            'chat_id' => $chatId,
483
            'latitude' => $latitude,
484
            'longitude' => $longitude,
485
            'reply_to_message_id' => $replyToMessageId,
486
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
487
            'disable_notification' => (bool)$disableNotification,
488
        ]));
489
    }
490
491
    /**
492
     * Use this method to send information about a venue. On success, the sent Message is returned.
493
     *
494
     * @param int|string $chatId
495
     * @param float $latitude
496
     * @param float $longitude
497
     * @param string $title
498
     * @param string $address
499
     * @param string|null $foursquareId
500
     * @param int|null $replyToMessageId
501
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
502
     * @param bool $disableNotification
503
     *
504
     * @return \TelegramBot\Api\Types\Message
505
     * @throws \TelegramBot\Api\Exception
506
     */
507
    public function sendVenue(
508
        $chatId,
509
        $latitude,
510
        $longitude,
511
        $title,
512
        $address,
513
        $foursquareId = null,
514
        $replyToMessageId = null,
515
        $replyMarkup = null,
516
        $disableNotification = false
517
    ) {
518
        return Message::fromResponse($this->call('sendVenue', [
519
            'chat_id' => $chatId,
520
            'latitude' => $latitude,
521
            'longitude' => $longitude,
522
            'title' => $title,
523
            'address' => $address,
524
            'foursquare_id' => $foursquareId,
525
            'reply_to_message_id' => $replyToMessageId,
526
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
527
            'disable_notification' => (bool)$disableNotification,
528
        ]));
529
    }
530
531
    /**
532
     * Use this method to send .webp stickers. On success, the sent Message is returned.
533
     *
534
     * @param int $chatId
535
     * @param \CURLFile|string $sticker
536
     * @param int|null $replyToMessageId
537
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
538
     * @param bool $disableNotification
539
     *
540
     * @return \TelegramBot\Api\Types\Message
541
     * @throws \TelegramBot\Api\InvalidArgumentException
542
     * @throws \TelegramBot\Api\Exception
543
     */
544 View Code Duplication
    public function sendSticker(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
545
        $chatId,
546
        $sticker,
547
        $replyToMessageId = null,
548
        $replyMarkup = null,
549
        $disableNotification = false
550
    ) {
551
        return Message::fromResponse($this->call('sendSticker', [
552
            'chat_id' => $chatId,
553
            'sticker' => $sticker,
554
            'reply_to_message_id' => $replyToMessageId,
555
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
556
            'disable_notification' => (bool)$disableNotification,
557
        ]));
558
    }
559
560
    /**
561
     * Use this method to send video files,
562
     * Telegram clients support mp4 videos (other formats may be sent as Document).
563
     * On success, the sent Message is returned.
564
     *
565
     * @param int $chatId
566
     * @param \CURLFile|string $video
567
     * @param int|null $duration
568
     * @param string|null $caption
569
     * @param int|null $replyToMessageId
570
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
571
     * @param bool $disableNotification
572
     *
573
     * @return \TelegramBot\Api\Types\Message
574
     * @throws \TelegramBot\Api\InvalidArgumentException
575
     * @throws \TelegramBot\Api\Exception
576
     */
577
    public function sendVideo(
578
        $chatId,
579
        $video,
580
        $duration = null,
581
        $caption = null,
582
        $replyToMessageId = null,
583
        $replyMarkup = null,
584
        $disableNotification = false
585
    ) {
586
        return Message::fromResponse($this->call('sendVideo', [
587
            'chat_id' => $chatId,
588
            'video' => $video,
589
            'duration' => $duration,
590
            'caption' => $caption,
591
            'reply_to_message_id' => $replyToMessageId,
592
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
593
            'disable_notification' => (bool)$disableNotification,
594
        ]));
595
    }
596
597
    /**
598
     * Use this method to send audio files,
599
     * if you want Telegram clients to display the file as a playable voice message.
600
     * For this to work, your audio must be in an .ogg file encoded with OPUS
601
     * (other formats may be sent as Audio or Document).
602
     * On success, the sent Message is returned.
603
     * Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future.
604
     *
605
     * @param int $chatId
606
     * @param \CURLFile|string $voice
607
     * @param int|null $duration
608
     * @param int|null $replyToMessageId
609
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
610
     * @param bool $disableNotification
611
     *
612
     * @return \TelegramBot\Api\Types\Message
613
     * @throws \TelegramBot\Api\InvalidArgumentException
614
     * @throws \TelegramBot\Api\Exception
615
     */
616 View Code Duplication
    public function sendVoice(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
617
        $chatId,
618
        $voice,
619
        $duration = null,
620
        $replyToMessageId = null,
621
        $replyMarkup = null,
622
        $disableNotification = false
623
    ) {
624
        return Message::fromResponse($this->call('sendVoice', [
625
            'chat_id' => $chatId,
626
            'voice' => $voice,
627
            'duration' => $duration,
628
            'reply_to_message_id' => $replyToMessageId,
629
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
630
            'disable_notification' => (bool)$disableNotification,
631
        ]));
632
    }
633
634
    /**
635
     * Use this method to forward messages of any kind. On success, the sent Message is returned.
636
     *
637
     * @param int $chatId
638
     * @param int $fromChatId
639
     * @param int $messageId
640
     * @param bool $disableNotification
641
     *
642
     * @return \TelegramBot\Api\Types\Message
643
     * @throws \TelegramBot\Api\InvalidArgumentException
644
     * @throws \TelegramBot\Api\Exception
645
     */
646
    public function forwardMessage($chatId, $fromChatId, $messageId, $disableNotification = false)
647
    {
648
        return Message::fromResponse($this->call('forwardMessage', [
649
            'chat_id' => $chatId,
650
            'from_chat_id' => $fromChatId,
651
            'message_id' => (int)$messageId,
652
            'disable_notification' => (bool)$disableNotification,
653
        ]));
654
    }
655
656
    /**
657
     * Use this method to send audio files,
658
     * if you want Telegram clients to display them in the music player.
659
     * Your audio must be in the .mp3 format.
660
     * On success, the sent Message is returned.
661
     * Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future.
662
     *
663
     * For backward compatibility, when the fields title and performer are both empty
664
     * and the mime-type of the file to be sent is not audio/mpeg, the file will be sent as a playable voice message.
665
     * For this to work, the audio must be in an .ogg file encoded with OPUS.
666
     * This behavior will be phased out in the future. For sending voice messages, use the sendVoice method instead.
667
     *
668
     * @deprecated since 20th February. Removed backward compatibility from the method sendAudio.
669
     * Voice messages now must be sent using the method sendVoice.
670
     * There is no more need to specify a non-empty title or performer while sending the audio by file_id.
671
     *
672
     * @param int $chatId
673
     * @param \CURLFile|string $audio
674
     * @param int|null $duration
675
     * @param string|null $performer
676
     * @param string|null $title
677
     * @param int|null $replyToMessageId
678
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
679
     * @param bool $disableNotification
680
     *
681
     * @return \TelegramBot\Api\Types\Message
682
     * @throws \TelegramBot\Api\InvalidArgumentException
683
     * @throws \TelegramBot\Api\Exception
684
     */
685
    public function sendAudio(
686
        $chatId,
687
        $audio,
688
        $duration = null,
689
        $performer = null,
690
        $title = null,
691
        $replyToMessageId = null,
692
        $replyMarkup = null,
693
        $disableNotification = false
694
    ) {
695
        return Message::fromResponse($this->call('sendAudio', [
696
            'chat_id' => $chatId,
697
            'audio' => $audio,
698
            'duration' => $duration,
699
            'performer' => $performer,
700
            'title' => $title,
701
            'reply_to_message_id' => $replyToMessageId,
702
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
703
            'disable_notification' => (bool)$disableNotification,
704
        ]));
705
    }
706
707
    /**
708
     * Use this method to send photos. On success, the sent Message is returned.
709
     *
710
     * @param int $chatId
711
     * @param \CURLFile|string $photo
712
     * @param string|null $caption
713
     * @param int|null $replyToMessageId
714
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
715
     * @param bool $disableNotification
716
     *
717
     * @return \TelegramBot\Api\Types\Message
718
     * @throws \TelegramBot\Api\InvalidArgumentException
719
     * @throws \TelegramBot\Api\Exception
720
     */
721 View Code Duplication
    public function sendPhoto(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
722
        $chatId,
723
        $photo,
724
        $caption = null,
725
        $replyToMessageId = null,
726
        $replyMarkup = null,
727
        $disableNotification = false
728
    ) {
729
        return Message::fromResponse($this->call('sendPhoto', [
730
            'chat_id' => $chatId,
731
            'photo' => $photo,
732
            'caption' => $caption,
733
            'reply_to_message_id' => $replyToMessageId,
734
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
735
            'disable_notification' => (bool)$disableNotification,
736
        ]));
737
    }
738
739
    /**
740
     * Use this method to send general files. On success, the sent Message is returned.
741
     * Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
742
     *
743
     * @param int $chatId
744
     * @param \CURLFile|string $document
745
     * @param int|null $replyToMessageId
746
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
747
     * @param bool $disableNotification
748
     *
749
     * @return \TelegramBot\Api\Types\Message
750
     * @throws \TelegramBot\Api\InvalidArgumentException
751
     * @throws \TelegramBot\Api\Exception
752
     */
753 View Code Duplication
    public function sendDocument(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
754
        $chatId,
755
        $document,
756
        $replyToMessageId = null,
757
        $replyMarkup = null,
758
        $disableNotification = false
759
    ) {
760
        return Message::fromResponse($this->call('sendDocument', [
761
            'chat_id' => $chatId,
762
            'document' => $document,
763
            'reply_to_message_id' => $replyToMessageId,
764
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
765
            'disable_notification' => (bool)$disableNotification,
766
        ]));
767
    }
768
769
    /**
770
     * Use this method to get basic info about a file and prepare it for downloading.
771
     * For the moment, bots can download files of up to 20MB in size.
772
     * On success, a File object is returned.
773
     * The file can then be downloaded via the link https://api.telegram.org/file/bot<token>/<file_path>,
774
     * where <file_path> is taken from the response.
775
     * It is guaranteed that the link will be valid for at least 1 hour.
776
     * When the link expires, a new one can be requested by calling getFile again.
777
     *
778
     * @param $fileId
779
     *
780
     * @return \TelegramBot\Api\Types\File
781
     * @throws \TelegramBot\Api\InvalidArgumentException
782
     * @throws \TelegramBot\Api\Exception
783
     */
784
    public function getFile($fileId)
785
    {
786
        return File::fromResponse($this->call('getFile', ['file_id' => $fileId]));
787
    }
788
789
    /**
790
     * Get file contents via cURL
791
     *
792
     * @param $fileId
793
     *
794
     * @return string
795
     *
796
     * @throws \TelegramBot\Api\HttpException
797
     */
798
    public function downloadFile($fileId)
799
    {
800
        $file = $this->getFile($fileId);
801
        $options = [
802
            CURLOPT_HEADER => 0,
803
            CURLOPT_HTTPGET => 1,
804
            CURLOPT_RETURNTRANSFER => 1,
805
            CURLOPT_URL => $this->getFileUrl().'/'.$file->getFilePath(),
806
        ];
807
808
        return $this->executeCurl($options);
809
    }
810
811
    /**
812
     * Use this method to send answers to an inline query. On success, True is returned.
813
     * No more than 50 results per query are allowed.
814
     *
815
     * @param string $inlineQueryId
816
     * @param \TelegramBot\Api\Types\Inline\AbstractInlineQueryResult[] $results
817
     * @param int $cacheTime
818
     * @param bool $isPersonal
819
     * @param string $nextOffset
820
     *
821
     * @return mixed
822
     * @throws Exception
823
     */
824
    public function answerInlineQuery($inlineQueryId, $results, $cacheTime = 300, $isPersonal = false, $nextOffset = '')
825
    {
826
        $results = array_map(function ($item) {
827
            /* @var \TelegramBot\Api\Types\Inline\AbstractInlineQueryResult $item */
828
829
            return json_decode($item->toJson(), true);
830
        }, $results);
831
832
        return $this->call('answerInlineQuery', [
833
            'inline_query_id' => $inlineQueryId,
834
            'results' => json_encode($results),
835
            'cache_time' => $cacheTime,
836
            'is_personal' => $isPersonal,
837
            'next_offset' => $nextOffset,
838
        ]);
839
    }
840
841
    /**
842
     * Use this method to kick a user from a group or a supergroup.
843
     * In the case of supergroups, the user will not be able to return to the group
844
     * on their own using invite links, etc., unless unbanned first.
845
     * The bot must be an administrator in the group for this to work. Returns True on success.
846
     *
847
     * @param int|string $chatId Unique identifier for the target group
848
     * or username of the target supergroup (in the format @supergroupusername)
849
     * @param int $userId Unique identifier of the target user
850
     *
851
     * @return bool
852
     */
853
    public function kickChatMember($chatId, $userId)
854
    {
855
        return $this->call('kickChatMember', [
856
            'chat_id' => $chatId,
857
            'user_id' => $userId,
858
        ]);
859
    }
860
861
    /**
862
     * Use this method to unban a previously kicked user in a supergroup.
863
     * The user will not return to the group automatically, but will be able to join via link, etc.
864
     * The bot must be an administrator in the group for this to work. Returns True on success.
865
     *
866
     * @param int|string $chatId Unique identifier for the target group
867
     * or username of the target supergroup (in the format @supergroupusername)
868
     * @param int $userId Unique identifier of the target user
869
     *
870
     * @return bool
871
     */
872
    public function unbanChatMember($chatId, $userId)
873
    {
874
        return $this->call('unbanChatMember', [
875
            'chat_id' => $chatId,
876
            'user_id' => $userId,
877
        ]);
878
    }
879
880
    /**
881
     * Use this method to send answers to callback queries sent from inline keyboards.
882
     * The answer will be displayed to the user as a notification at the top of the chat screen or as an alert.
883
     *
884
     * @param $callbackQueryId
885
     * @param null $text
886
     * @param bool $showAlert
887
     *
888
     * @return bool
889
     */
890
    public function answerCallbackQuery($callbackQueryId, $text = null, $showAlert = false)
891
    {
892
        return $this->call('answerCallbackQuery', [
893
            'callback_query_id' => $callbackQueryId,
894
            'text' => $text,
895
            'show_alert' => (bool)$showAlert,
896
        ]);
897
    }
898
899
900
    /**
901
     * Use this method to edit text messages sent by the bot or via the bot
902
     *
903
     * @param int|string $chatId
904
     * @param int $messageId
905
     * @param string $text
906
     * @param string|null $parseMode
907
     * @param bool $disablePreview
908
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
909
     *
910
     * @return \TelegramBot\Api\Types\Message
911
     * @throws \TelegramBot\Api\InvalidArgumentException
912
     * @throws \TelegramBot\Api\Exception
913
     */
914 View Code Duplication
    public function editMessageText(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
915
        $chatId,
916
        $messageId,
917
        $text,
918
        $parseMode = null,
919
        $disablePreview = false,
920
        $replyMarkup = null
921
    ) {
922
        return Message::fromResponse($this->call('editMessageText', [
923
            'chat_id' => $chatId,
924
            'message_id' => $messageId,
925
            'text' => $text,
926
            'parse_mode' => $parseMode,
927
            'disable_web_page_preview' => $disablePreview,
928
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
929
        ]));
930
    }
931
932
    /**
933
     * Use this method to edit text messages sent by the bot or via the bot
934
     *
935
     * @param int|string $chatId
936
     * @param int $messageId
937
     * @param string|null $caption
938
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
939
     *
940
     * @return \TelegramBot\Api\Types\Message
941
     * @throws \TelegramBot\Api\InvalidArgumentException
942
     * @throws \TelegramBot\Api\Exception
943
     */
944 View Code Duplication
    public function editMessageCaption(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
945
        $chatId,
946
        $messageId,
947
        $caption = null,
948
        $replyMarkup = null
949
    ) {
950
        return Message::fromResponse($this->call('editMessageText', [
951
            'chat_id' => $chatId,
952
            'message_id' => $messageId,
953
            'caption' => $caption,
954
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
955
        ]));
956
    }
957
958
    /**
959
     * Use this method to edit only the reply markup of messages sent by the bot or via the bot
960
     *
961
     * @param int|string $chatId
962
     * @param int $messageId
963
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
964
     *
965
     * @return \TelegramBot\Api\Types\Message
966
     * @throws \TelegramBot\Api\InvalidArgumentException
967
     * @throws \TelegramBot\Api\Exception
968
     */
969 View Code Duplication
    public function editMessageReplyMarkup(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
970
        $chatId,
971
        $messageId,
972
        $replyMarkup = null
973
    ) {
974
        return Message::fromResponse($this->call('editMessageText', [
975
            'chat_id' => $chatId,
976
            'message_id' => $messageId,
977
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson(),
978
        ]));
979
    }
980
981
    /**
982
     * Close curl
983
     */
984 9
    public function __destruct()
985
    {
986 9
        $this->curl && curl_close($this->curl);
987 9
    }
988
989
    /**
990
     * @return string
991
     */
992
    public function getUrl()
993
    {
994
        return self::URL_PREFIX.$this->token;
995
    }
996
997
    /**
998
     * @return string
999
     */
1000
    public function getFileUrl()
1001
    {
1002
        return self::FILE_URL_PREFIX.$this->token;
1003
    }
1004
1005
    /**
1006
     * @param \TelegramBot\Api\Types\Update $update
1007
     * @param string $eventName
1008
     *
1009
     * @throws \TelegramBot\Api\Exception
1010
     */
1011
    public function trackUpdate(Update $update, $eventName = 'Message')
1012
    {
1013
        if (!in_array($update->getUpdateId(), $this->trackedEvents)) {
1014
            $this->trackedEvents[] = $update->getUpdateId();
1015
1016
            $this->track($update->getMessage(), $eventName);
1017
1018
            if (count($this->trackedEvents) > self::MAX_TRACKED_EVENTS) {
1019
                $this->trackedEvents = array_slice($this->trackedEvents, round(self::MAX_TRACKED_EVENTS / 4));
1020
            }
1021
        }
1022
    }
1023
1024
    /**
1025
     * Wrapper for tracker
1026
     *
1027
     * @param \TelegramBot\Api\Types\Message $message
1028
     * @param string $eventName
1029
     *
1030
     * @throws \TelegramBot\Api\Exception
1031
     */
1032
    public function track(Message $message, $eventName = 'Message')
1033
    {
1034
        if ($this->tracker instanceof Botan) {
1035
            $this->tracker->track($message, $eventName);
1036
        }
1037
    }
1038
}
1039