Completed
Push — master ( 6cc94b...6ea9f5 )
by Gusev
49s
created

BotApi::sendPhoto()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 10
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 10
loc 10
ccs 0
cts 8
cp 0
rs 9.4285
cc 2
eloc 7
nc 1
nop 5
crap 6
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
    const FILE_URL_PREFIX = 'https://api.telegram.org/file/bot';
112
113
    /**
114
     * CURL object
115
     *
116
     * @var
117
     */
118
    protected $curl;
119
120
    /**
121
     * Bot token
122
     *
123
     * @var string
124
     */
125
    protected $token;
126
127
    /**
128
     * Botan tracker
129
     *
130
     * @var \TelegramBot\Api\Botan
131
     */
132
    protected $tracker;
133
134
    /**
135
     * list of event ids
136
     *
137
     * @var array
138
     */
139
    protected $trackedEvents = [];
140
141
    /**
142
     * Check whether return associative array
143
     *
144
     * @var bool
145
     */
146
    protected $returnArray = true;
147
148
149
    /**
150
     * Constructor
151
     *
152
     * @param string $token Telegram Bot API token
153
     * @param string|null $trackerToken Yandex AppMetrica application api_key
154
     */
155 9
    public function __construct($token, $trackerToken = null)
156
    {
157 9
        $this->curl = curl_init();
158 9
        $this->token = $token;
159
160 9
        if ($trackerToken) {
161
            $this->tracker = new Botan($trackerToken);
162
        }
163 9
    }
164
165
    /**
166
     * Set return array
167
     *
168
     * @param bool $mode
169
     *
170
     * @return $this
171
     */
172
    public function setModeObject($mode = true)
173
    {
174
        $this->returnArray = !$mode;
175
176
        return $this;
177
    }
178
179
180
    /**
181
     * Call method
182
     *
183
     * @param string $method
184
     * @param array|null $data
185
     *
186
     * @return mixed
187
     * @throws \TelegramBot\Api\Exception
188
     * @throws \TelegramBot\Api\HttpException
189
     * @throws \TelegramBot\Api\InvalidJsonException
190
     */
191
    public function call($method, array $data = null)
192
    {
193
        $options = [
194
            CURLOPT_URL => $this->getUrl() . '/' . $method,
195
            CURLOPT_RETURNTRANSFER => true,
196
            CURLOPT_POST => null,
197
            CURLOPT_POSTFIELDS => null
198
        ];
199
200
        if ($data) {
201
            $options[CURLOPT_POST] = true;
202
            $options[CURLOPT_POSTFIELDS] = http_build_query($data);
203
        }
204
205
        $response = self::jsonValidate($this->executeCurl($options), $this->returnArray);
206
207
        if ($this->returnArray) {
208
            if (!isset($response['ok'])) {
209
                throw new Exception($response['description'], $response['error_code']);
210
            }
211
212
            return $response['result'];
213
        }
214
215
        if (!$response->ok) {
216
            throw new Exception($response->description, $response->error_code);
217
        }
218
219
        return $response->result;
220
    }
221
222
    /**
223
     * curl_exec wrapper for response validation
224
     *
225
     * @param array $options
226
     *
227
     * @return string
228
     *
229
     * @throws \TelegramBot\Api\HttpException
230
     */
231
    protected function executeCurl(array $options)
232
    {
233
        curl_setopt_array($this->curl, $options);
234
235
        $result = curl_exec($this->curl);
236
        self::curlValidate($this->curl);
237
238
        return $result;
239
    }
240
241
    /**
242
     * Response validation
243
     *
244
     * @param resource $curl
245
     *
246
     * @throws \TelegramBot\Api\HttpException
247
     */
248
    public static function curlValidate($curl)
249
    {
250
        if (($httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE))
251
            && !in_array($httpCode, [self::DEFAULT_STATUS_CODE, self::NOT_MODIFIED_STATUS_CODE])
252
        ) {
253
            throw new HttpException(self::$codes[$httpCode], $httpCode);
254
        }
255
    }
256
257
    /**
258
     * JSON validation
259
     *
260
     * @param string $jsonString
261
     * @param boolean $asArray
262
     *
263
     * @return object|array
264
     * @throws \TelegramBot\Api\InvalidJsonException
265
     */
266
    public static function jsonValidate($jsonString, $asArray)
267
    {
268
        $json = json_decode($jsonString, $asArray);
269
270
        if (json_last_error() != JSON_ERROR_NONE) {
271
            throw new InvalidJsonException(json_last_error_msg(), json_last_error());
272
        }
273
274
        return $json;
275
    }
276
277
    /**
278
     * Use this method to send text messages. On success, the sent \TelegramBot\Api\Types\Message is returned.
279
     *
280
     * @param int|string $chatId
281
     * @param string $text
282
     * @param string|null $parseMode
283
     * @param bool $disablePreview
284
     * @param int|null $replyToMessageId
285
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
286
     *
287
     * @return \TelegramBot\Api\Types\Message
288
     * @throws \TelegramBot\Api\InvalidArgumentException
289
     * @throws \TelegramBot\Api\Exception
290
     */
291 View Code Duplication
    public function sendMessage(
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...
292
        $chatId,
293
        $text,
294
        $parseMode = null,
295
        $disablePreview = false,
296
        $replyToMessageId = null,
297
        $replyMarkup = null
298
    ) {
299
        return Message::fromResponse($this->call('sendMessage', [
300
            'chat_id' => $chatId,
301
            'text' => $text,
302
            'parse_mode' => $parseMode,
303
            'disable_web_page_preview' => $disablePreview,
304
            'reply_to_message_id' => (int) $replyToMessageId,
305
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson()
306
        ]));
307
    }
308
309
    /**
310
     * Use this method when you need to tell the user that something is happening on the bot's side.
311
     * The status is set for 5 seconds or less (when a message arrives from your bot,
312
     * Telegram clients clear its typing status).
313
     *
314
     * We only recommend using this method when a response from the bot will take a noticeable amount of time to arrive.
315
     *
316
     * Type of action to broadcast. Choose one, depending on what the user is about to receive:
317
     * `typing` for text messages, `upload_photo` for photos, `record_video` or `upload_video` for videos,
318
     * `record_audio` or upload_audio for audio files, `upload_document` for general files,
319
     * `find_location` for location data.
320
     *
321
     * @param int $chatId
322
     * @param string $action
323
     *
324
     * @return bool
325
     * @throws \TelegramBot\Api\Exception
326
     */
327
    public function sendChatAction($chatId, $action)
328
    {
329
        return $this->call('sendChatAction', [
330
            'chat_id' => $chatId,
331
            'action' => $action
332
        ]);
333
    }
334
335
    /**
336
     * Use this method to get a list of profile pictures for a user.
337
     *
338
     * @param int $userId
339
     * @param int $offset
340
     * @param int $limit
341
     *
342
     * @return \TelegramBot\Api\Types\UserProfilePhotos
343
     * @throws \TelegramBot\Api\Exception
344
     */
345
    public function getUserProfilePhotos($userId, $offset = 0, $limit = 100)
346
    {
347
        return UserProfilePhotos::fromResponse($this->call('getUserProfilePhotos', [
348
            'user_id' => (int) $userId,
349
            'offset' => (int) $offset,
350
            'limit' => (int) $limit,
351
        ]));
352
    }
353
354
    /**
355
     * Use this method to specify a url and receive incoming updates via an outgoing webhook.
356
     * Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url,
357
     * containing a JSON-serialized Update.
358
     * In case of an unsuccessful request, we will give up after a reasonable amount of attempts.
359
     *
360
     * @param string $url HTTPS url to send updates to. Use an empty string to remove webhook integration
361
     * @param \CURLFile|string $certificate Upload your public key certificate
362
     *                                      so that the root certificate in use can be checked
363
     *
364
     * @return string
365
     *
366
     * @throws \TelegramBot\Api\Exception
367
     */
368
    public function setWebhook($url = '', $certificate = null)
369
    {
370
        return $this->call('setWebhook', ['url' => $url, 'certificate' => $certificate]);
371
    }
372
373
    /**
374
     * A simple method for testing your bot's auth token.Requires no parameters.
375
     * Returns basic information about the bot in form of a User object.
376
     *
377
     * @return \TelegramBot\Api\Types\User
378
     * @throws \TelegramBot\Api\Exception
379
     * @throws \TelegramBot\Api\InvalidArgumentException
380
     */
381
    public function getMe()
382
    {
383
        return User::fromResponse($this->call('getMe'));
384
    }
385
386
    /**
387
     * Use this method to receive incoming updates using long polling.
388
     * An Array of Update objects is returned.
389
     *
390
     * Notes
391
     * 1. This method will not work if an outgoing webhook is set up.
392
     * 2. In order to avoid getting duplicate updates, recalculate offset after each server response.
393
     *
394
     * @param int $offset
395
     * @param int $limit
396
     * @param int $timeout
397
     *
398
     * @return Update[]
399
     * @throws \TelegramBot\Api\Exception
400
     * @throws \TelegramBot\Api\InvalidArgumentException
401
     */
402 2
    public function getUpdates($offset = 0, $limit = 100, $timeout = 0)
403
    {
404 2
        $updates = ArrayOfUpdates::fromResponse($this->call('getUpdates', [
405 2
            'offset' => $offset,
406 2
            'limit' => $limit,
407
            'timeout' => $timeout
408 2
        ]));
409
410 2
        if ($this->tracker instanceof Botan) {
411
            foreach ($updates as $update) {
412
                $this->trackUpdate($update);
413
            }
414
        }
415
416 2
        return $updates;
417
    }
418
419
    /**
420
     * Use this method to send point on the map. On success, the sent Message is returned.
421
     *
422
     * @param int $chatId
423
     * @param float $latitude
424
     * @param float $longitude
425
     * @param int|null $replyToMessageId
426
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
427
     *
428
     * @return \TelegramBot\Api\Types\Message
429
     * @throws \TelegramBot\Api\Exception
430
     */
431
    public function sendLocation($chatId, $latitude, $longitude, $replyToMessageId = null, $replyMarkup = null)
432
    {
433
        return Message::fromResponse($this->call('sendLocation', [
434
            'chat_id' => $chatId,
435
            'latitude' => $latitude,
436
            'longitude' => $longitude,
437
            'reply_to_message_id' => $replyToMessageId,
438
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson()
439
        ]));
440
    }
441
442
    /**
443
     * Use this method to send .webp stickers. On success, the sent Message is returned.
444
     *
445
     * @param int $chatId
446
     * @param \CURLFile|string $sticker
447
     * @param int|null $replyToMessageId
448
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
449
     *
450
     * @return \TelegramBot\Api\Types\Message
451
     * @throws \TelegramBot\Api\InvalidArgumentException
452
     * @throws \TelegramBot\Api\Exception
453
     */
454
    public function sendSticker($chatId, $sticker, $replyToMessageId = null, $replyMarkup = null)
455
    {
456
        return Message::fromResponse($this->call('sendSticker', [
457
            'chat_id' => $chatId,
458
            'sticker' => $sticker,
459
            'reply_to_message_id' => $replyToMessageId,
460
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson()
461
        ]));
462
    }
463
464
    /**
465
     * Use this method to send video files,
466
     * Telegram clients support mp4 videos (other formats may be sent as Document).
467
     * On success, the sent Message is returned.
468
     *
469
     * @param int $chatId
470
     * @param \CURLFile|string $video
471
     * @param int|null $duration
472
     * @param string|null $caption
473
     * @param int|null $replyToMessageId
474
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
475
     *
476
     * @return \TelegramBot\Api\Types\Message
477
     * @throws \TelegramBot\Api\InvalidArgumentException
478
     * @throws \TelegramBot\Api\Exception
479
     */
480 View Code Duplication
    public function sendVideo(
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...
481
        $chatId,
482
        $video,
483
        $duration = null,
484
        $caption = null,
485
        $replyToMessageId = null,
486
        $replyMarkup = null
487
    ) {
488
        return Message::fromResponse($this->call('sendVideo', [
489
            'chat_id' => $chatId,
490
            'video' => $video,
491
            'duration' => $duration,
492
            'caption' => $caption,
493
            'reply_to_message_id' => $replyToMessageId,
494
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson()
495
        ]));
496
    }
497
498
    /**
499
     * Use this method to send audio files,
500
     * if you want Telegram clients to display the file as a playable voice message.
501
     * For this to work, your audio must be in an .ogg file encoded with OPUS
502
     * (other formats may be sent as Audio or Document).
503
     * On success, the sent Message is returned.
504
     * Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future.
505
     *
506
     * @param int $chatId
507
     * @param \CURLFile|string $voice
508
     * @param int|null $duration
509
     * @param int|null $replyToMessageId
510
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
511
     *
512
     * @return \TelegramBot\Api\Types\Message
513
     * @throws \TelegramBot\Api\InvalidArgumentException
514
     * @throws \TelegramBot\Api\Exception
515
     */
516 View Code Duplication
    public function sendVoice($chatId, $voice, $duration = null, $replyToMessageId = null, $replyMarkup = null)
517
    {
518
        return Message::fromResponse($this->call('sendVoice', [
519
            'chat_id' => $chatId,
520
            'voice' => $voice,
521
            'duration' => $duration,
522
            'reply_to_message_id' => $replyToMessageId,
523
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson()
524
        ]));
525
    }
526
527
    /**
528
     * Use this method to forward messages of any kind. On success, the sent Message is returned.
529
     *
530
     * @param int $chatId
531
     * @param int $fromChatId
532
     * @param int $messageId
533
     *
534
     * @return \TelegramBot\Api\Types\Message
535
     * @throws \TelegramBot\Api\InvalidArgumentException
536
     * @throws \TelegramBot\Api\Exception
537
     */
538
    public function forwardMessage($chatId, $fromChatId, $messageId)
539
    {
540
        return Message::fromResponse($this->call('forwardMessage', [
541
            'chat_id' => $chatId,
542
            'from_chat_id' => $fromChatId,
543
            'message_id' => (int) $messageId,
544
        ]));
545
    }
546
547
    /**
548
     * Use this method to send audio files,
549
     * if you want Telegram clients to display them in the music player.
550
     * Your audio must be in the .mp3 format.
551
     * On success, the sent Message is returned.
552
     * Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future.
553
     *
554
     * For backward compatibility, when the fields title and performer are both empty
555
     * and the mime-type of the file to be sent is not audio/mpeg, the file will be sent as a playable voice message.
556
     * For this to work, the audio must be in an .ogg file encoded with OPUS.
557
     * This behavior will be phased out in the future. For sending voice messages, use the sendVoice method instead.
558
     *
559
     * @param int $chatId
560
     * @param \CURLFile|string $audio
561
     * @param int|null $duration
562
     * @param string|null $performer
563
     * @param string|null $title
564
     * @param int|null $replyToMessageId
565
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
566
     *
567
     * @return \TelegramBot\Api\Types\Message
568
     * @throws \TelegramBot\Api\InvalidArgumentException
569
     * @throws \TelegramBot\Api\Exception
570
     */
571 View Code Duplication
    public function sendAudio(
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...
572
        $chatId,
573
        $audio,
574
        $duration = null,
575
        $performer = null,
576
        $title = null,
577
        $replyToMessageId = null,
578
        $replyMarkup = null
579
    ) {
580
        return Message::fromResponse($this->call('sendAudio', [
581
            'chat_id' => $chatId,
582
            'audio' => $audio,
583
            'duration' => $duration,
584
            'performer' => $performer,
585
            'title' => $title,
586
            'reply_to_message_id' => $replyToMessageId,
587
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson()
588
        ]));
589
    }
590
591
    /**
592
     * Use this method to send photos. On success, the sent Message is returned.
593
     *
594
     * @param int $chatId
595
     * @param \CURLFile|string $photo
596
     * @param string|null $caption
597
     * @param int|null $replyToMessageId
598
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
599
     *
600
     * @return \TelegramBot\Api\Types\Message
601
     * @throws \TelegramBot\Api\InvalidArgumentException
602
     * @throws \TelegramBot\Api\Exception
603
     */
604 View Code Duplication
    public function sendPhoto($chatId, $photo, $caption = null, $replyToMessageId = null, $replyMarkup = null)
605
    {
606
        return Message::fromResponse($this->call('sendPhoto', [
607
            'chat_id' => $chatId,
608
            'photo' => $photo,
609
            'caption' => $caption,
610
            'reply_to_message_id' => $replyToMessageId,
611
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson()
612
        ]));
613
    }
614
615
    /**
616
     * Use this method to send general files. On success, the sent Message is returned.
617
     * Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
618
     *
619
     * @param int $chatId
620
     * @param \CURLFile|string $document
621
     * @param int|null $replyToMessageId
622
     * @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup
623
     *
624
     * @return \TelegramBot\Api\Types\Message
625
     * @throws \TelegramBot\Api\InvalidArgumentException
626
     * @throws \TelegramBot\Api\Exception
627
     */
628
    public function sendDocument($chatId, $document, $replyToMessageId = null, $replyMarkup = null)
629
    {
630
        return Message::fromResponse($this->call('sendDocument', [
631
            'chat_id' => $chatId,
632
            'document' => $document,
633
            'reply_to_message_id' => $replyToMessageId,
634
            'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson()
635
        ]));
636
    }
637
638
    /**
639
     * Use this method to get basic info about a file and prepare it for downloading.
640
     * For the moment, bots can download files of up to 20MB in size.
641
     * On success, a File object is returned.
642
     * The file can then be downloaded via the link https://api.telegram.org/file/bot<token>/<file_path>,
643
     * where <file_path> is taken from the response.
644
     * It is guaranteed that the link will be valid for at least 1 hour.
645
     * When the link expires, a new one can be requested by calling getFile again.
646
     *
647
     * @param $fileId
648
     *
649
     * @return \TelegramBot\Api\Types\File
650
     * @throws \TelegramBot\Api\InvalidArgumentException
651
     * @throws \TelegramBot\Api\Exception
652
     */
653
    public function getFile($fileId)
654
    {
655
        return File::fromResponse($this->call('getFile', ['file_id' => $fileId]));
656
    }
657
658
    /**
659
     * Get file contents via cURL
660
     *
661
     * @param $fileId
662
     *
663
     * @return string
664
     *
665
     * @throws \TelegramBot\Api\HttpException
666
     */
667
    public function downloadFile($fileId)
668
    {
669
        $file = $this->getFile($fileId);
670
        $options = [
671
            CURLOPT_HEADER => 0,
672
            CURLOPT_HTTPGET => 1,
673
            CURLOPT_RETURNTRANSFER => 1,
674
            CURLOPT_URL => $this->getFileUrl() . '/' . $file->getFilePath()
675
        ];
676
677
        return $this->executeCurl($options);
678
    }
679
680
    /**
681
     * Use this method to send answers to an inline query. On success, True is returned.
682
     * No more than 50 results per query are allowed.
683
     *
684
     * @param string $inlineQueryId
685
     * @param \TelegramBot\Api\Types\Inline\AbstractInlineQueryResult[] $results
686
     * @param int $cacheTime
687
     * @param bool $isPersonal
688
     * @param string $nextOffset
689
     *
690
     * @return mixed
691
     * @throws Exception
692
     */
693
    public function answerInlineQuery($inlineQueryId, $results, $cacheTime = 300, $isPersonal = false, $nextOffset = '')
694
    {
695
        $results = array_map(function ($item) {
696
            /* @var \TelegramBot\Api\Types\Inline\AbstractInlineQueryResult $item */
697
698
            return json_decode($item->toJson(), true);
699
        }, $results);
700
701
        return $this->call('answerInlineQuery', [
702
            'inline_query_id' => $inlineQueryId,
703
            'results' => json_encode($results),
704
            'cache_time' => $cacheTime,
705
            'is_personal' => $isPersonal,
706
            'next_offset' => $nextOffset,
707
        ]);
708
    }
709
710
    /**
711
     * Close curl
712
     */
713 9
    public function __destruct()
714
    {
715 9
        $this->curl && curl_close($this->curl);
716 9
    }
717
718
    /**
719
     * @return string
720
     */
721
    public function getUrl()
722
    {
723
        return self::URL_PREFIX . $this->token;
724
    }
725
726
    /**
727
     * @return string
728
     */
729
    public function getFileUrl()
730
    {
731
        return self::FILE_URL_PREFIX . $this->token;
732
    }
733
734
    /**
735
     * @param \TelegramBot\Api\Types\Update $update
736
     * @param string $eventName
737
     *
738
     * @throws \TelegramBot\Api\Exception
739
     */
740
    public function trackUpdate(Update $update, $eventName = 'Message')
741
    {
742
        if (!in_array($update->getUpdateId(), $this->trackedEvents)) {
743
            $this->trackedEvents[] = $update->getUpdateId();
744
745
            $this->track($update->getMessage(), $eventName);
746
747
            if (count($this->trackedEvents) > self::MAX_TRACKED_EVENTS) {
748
                $this->trackedEvents = array_slice($this->trackedEvents, round(self::MAX_TRACKED_EVENTS / 4));
749
            }
750
        }
751
    }
752
753
    /**
754
     * Wrapper for tracker
755
     *
756
     * @param \TelegramBot\Api\Types\Message $message
757
     * @param string $eventName
758
     *
759
     * @throws \TelegramBot\Api\Exception
760
     */
761
    public function track(Message $message, $eventName = 'Message')
762
    {
763
        if ($this->tracker instanceof Botan) {
764
            $this->tracker->track($message, $eventName);
765
        }
766
    }
767
}
768