Completed
Push — master ( 3ba296...5d6a10 )
by Irfaq
10:32
created

Api::setConnectTimeOut()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4286
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Telegram\Bot;
4
5
use Illuminate\Contracts\Container\Container;
6
use Telegram\Bot\Commands\CommandBus;
7
use Telegram\Bot\Commands\CommandInterface;
8
use Telegram\Bot\Exceptions\TelegramSDKException;
9
use Telegram\Bot\FileUpload\InputFile;
10
use Telegram\Bot\HttpClients\GuzzleHttpClient;
11
use Telegram\Bot\HttpClients\HttpClientInterface;
12
use Telegram\Bot\Objects\File;
13
use Telegram\Bot\Objects\Message;
14
use Telegram\Bot\Objects\Update;
15
use Telegram\Bot\Objects\User;
16
use Telegram\Bot\Objects\UserProfilePhotos;
17
18
/**
19
 * Class Api.
20
 */
21
class Api
22
{
23
    /**
24
     * @var string Version number of the Telegram Bot PHP SDK.
25
     */
26
    const VERSION = '2.0.0';
27
28
    /**
29
     * @var string The name of the environment variable that contains the Telegram Bot API Access Token.
30
     */
31
    const BOT_TOKEN_ENV_NAME = 'TELEGRAM_BOT_TOKEN';
32
33
    /**
34
     * @var TelegramClient The Telegram client service.
35
     */
36
    protected $client;
37
38
    /**
39
     * @var string Telegram Bot API Access Token.
40
     */
41
    protected $accessToken = null;
42
43
    /**
44
     * @var TelegramResponse|null Stores the last request made to Telegram Bot API.
45
     */
46
    protected $lastResponse;
47
48
    /**
49
     * @var bool Indicates if the request to Telegram will be asynchronous (non-blocking).
50
     */
51
    protected $isAsyncRequest = false;
52
53
    /**
54
     * @var CommandBus|null Telegram Command Bus.
55
     */
56
    protected $commandBus = null;
57
58
    /**
59
     * @var Container IoC Container
60
     */
61
    protected static $container = null;
62
63
    /**
64
     * Timeout of the request in seconds.
65
     *
66
     * @var int
67
     */
68
    protected $timeOut = 30;
69
70
    /**
71
     * Connection timeout of the request in seconds.
72
     *
73
     * @var int
74
     */
75
    protected $connectTimeOut = 10;
76
77
    /**
78
     * Instantiates a new Telegram super-class object.
79
     *
80
     *
81
     * @param string                     $token               The Telegram Bot API Access Token.
82
     * @param bool                       $async               (Optional) Indicates if the request to Telegram
83
     *                                                        will be asynchronous (non-blocking).
84
     * @param string|HttpClientInterface $http_client_handler (Optional) Custom HTTP Client Handler.
85
     *
86
     * @throws TelegramSDKException
87
     */
88 74
    public function __construct($token = null, $async = false, $http_client_handler = null)
89
    {
90 74
        $this->accessToken = isset($token) ? $token : getenv(static::BOT_TOKEN_ENV_NAME);
91 74
        if (!$this->accessToken) {
92 2
            throw new TelegramSDKException('Required "token" not supplied in config and could not find fallback environment variable "'.static::BOT_TOKEN_ENV_NAME.'"');
93
        }
94
95 74
        $httpClientHandler = null;
96 74
        if (isset($http_client_handler)) {
97 46
            if ($http_client_handler instanceof HttpClientInterface) {
98 42
                $httpClientHandler = $http_client_handler;
99 46
            } elseif ($http_client_handler === 'guzzle') {
100 2
                $httpClientHandler = new GuzzleHttpClient();
101 2
            } else {
102 2
                throw new \InvalidArgumentException('The HTTP Client Handler must be set to "guzzle", or be an instance of Telegram\Bot\HttpClients\HttpClientInterface');
103
            }
104 44
        }
105
106 74
        if (isset($async)) {
107 74
            $this->setAsyncRequest($async);
108 74
        }
109
110 74
        $this->client = new TelegramClient($httpClientHandler);
111 74
    }
112
113
    /**
114
     * Returns the TelegramClient service.
115
     *
116
     * @return TelegramClient
117
     */
118 6
    public function getClient()
119
    {
120 6
        return $this->client;
121
    }
122
123
    /**
124
     * Returns Telegram Bot API Access Token.
125
     *
126
     * @return string
127
     */
128 42
    public function getAccessToken()
129
    {
130 42
        return $this->accessToken;
131
    }
132
133
    /**
134
     * Returns the last response returned from API request.
135
     *
136
     * @return TelegramResponse
137
     */
138 2
    public function getLastResponse()
139
    {
140 2
        return $this->lastResponse;
141
    }
142
143
    /**
144
     * Sets the bot access token to use with API requests.
145
     *
146
     * @param string $accessToken The bot access token to save.
147
     *
148
     * @throws \InvalidArgumentException
149
     *
150
     * @return Api
151
     */
152 8
    public function setAccessToken($accessToken)
153
    {
154 8
        if (is_string($accessToken)) {
155 2
            $this->accessToken = $accessToken;
156
157 2
            return $this;
158
        }
159
160 6
        throw new \InvalidArgumentException('The Telegram bot access token must be of type "string"');
161
    }
162
163
    /**
164
     * Make this request asynchronous (non-blocking).
165
     *
166
     * @param bool $isAsyncRequest
167
     *
168
     * @return Api
169
     */
170 74
    public function setAsyncRequest($isAsyncRequest)
171
    {
172 74
        $this->isAsyncRequest = $isAsyncRequest;
173
174 74
        return $this;
175
    }
176
177
    /**
178
     * Check if this is an asynchronous request (non-blocking).
179
     *
180
     * @return bool
181
     */
182 42
    public function isAsyncRequest()
183
    {
184 42
        return $this->isAsyncRequest;
185
    }
186
187
    /**
188
     * Returns SDK's Command Bus.
189
     *
190
     * @return CommandBus
191
     */
192 8
    public function getCommandBus()
193
    {
194 8
        if (is_null($this->commandBus)) {
195 8
            return $this->commandBus = new CommandBus($this);
196
        }
197
198 2
        return $this->commandBus;
199
    }
200
201
    /**
202
     * Add Telegram Command to the Command Bus.
203
     *
204
     * @param CommandInterface|string $command
205
     *
206
     * @return CommandBus
207
     */
208
    public function addCommand($command)
209
    {
210
        return $this->getCommandBus()->addCommand($command);
211
    }
212
213
    /**
214
     * Add Telegram Commands to the Command Bus.
215
     *
216
     * @param array $commands
217
     *
218
     * @return CommandBus
219
     */
220 2
    public function addCommands(array $commands)
221
    {
222 2
        return $this->getCommandBus()->addCommands($commands);
223
    }
224
225
    /**
226
     * Remove Telegram Command to the Command Bus.
227
     *
228
     * @param string $name
229
     *
230
     * @return CommandBus
231
     */
232
    public function removeCommand($name)
233
    {
234
        return $this->getCommandBus()->removeCommand($name);
235
    }
236
237
    /**
238
     * Remove Telegram Commands from the Command Bus.
239
     *
240
     * @param array $names
241
     *
242
     * @return CommandBus
243
     */
244
    public function removeCommands(array $names)
245
    {
246
        return $this->getCommandBus()->removeCommands($names);
247
    }
248
249
    /**
250
     * Returns list of available commands.
251
     *
252
     * @return Commands\Command[]
253
     */
254
    public function getCommands()
255
    {
256
        return $this->getCommandBus()->getCommands();
257
    }
258
259
    /**
260
     * A simple method for testing your bot's auth token.
261
     * Returns basic information about the bot in form of a User object.
262
     *
263
     * @link https://core.telegram.org/bots/api#getme
264
     *
265
     * @return User
266
     */
267 4
    public function getMe()
268
    {
269 4
        $response = $this->post('getMe');
270
271 2
        return new User($response->getDecodedBody());
272
    }
273
274
    /**
275
     * Send text messages.
276
     *
277
     * <code>
278
     * $params = [
279
     *   'chat_id'                  => '',
280
     *   'text'                     => '',
281
     *   'parse_mode'               => '',
282
     *   'disable_web_page_preview' => '',
283
     *   'reply_to_message_id'      => '',
284
     *   'reply_markup'             => '',
285
     * ];
286
     * </code>
287
     *
288
     * @link https://core.telegram.org/bots/api#sendmessage
289
     *
290
     * @param array    $params
291
     *
292
     * @var int|string $params ['chat_id']
293
     * @var string     $params ['text']
294
     * @var string     $params ['parse_mode']
295
     * @var bool       $params ['disable_web_page_preview']
296
     * @var int        $params ['reply_to_message_id']
297
     * @var string     $params ['reply_markup']
298
     *
299
     * @return Message
300
     */
301 4
    public function sendMessage(array $params)
302
    {
303 4
        $response = $this->post('sendMessage', $params);
304
305 4
        return new Message($response->getDecodedBody());
306
    }
307
308
    /**
309
     * Forward messages of any kind.
310
     *
311
     * <code>
312
     * $params = [
313
     *   'chat_id'      => '',
314
     *   'from_chat_id' => '',
315
     *   'message_id'   => '',
316
     * ];
317
     * </code>
318
     *
319
     * @link https://core.telegram.org/bots/api#forwardmessage
320
     *
321
     * @param array    $params
322
     *
323
     * @var int|string $params ['chat_id']
324
     * @var int        $params ['from_chat_id']
325
     * @var int        $params ['message_id']
326
     *
327
     * @return Message
328
     */
329 2
    public function forwardMessage(array $params)
330
    {
331 2
        $response = $this->post('forwardMessage', $params);
332
333 2
        return new Message($response->getDecodedBody());
334
    }
335
336
    /**
337
     * Send Photos.
338
     *
339
     * <code>
340
     * $params = [
341
     *   'chat_id'             => '',
342
     *   'photo'               => '',
343
     *   'caption'             => '',
344
     *   'reply_to_message_id' => '',
345
     *   'reply_markup'        => '',
346
     * ];
347
     * </code>
348
     *
349
     * @link https://core.telegram.org/bots/api#sendphoto
350
     *
351
     * @param array    $params
352
     *
353
     * @var int|string $params ['chat_id']
354
     * @var string     $params ['photo']
355
     * @var string     $params ['caption']
356
     * @var int        $params ['reply_to_message_id']
357
     * @var string     $params ['reply_markup']
358
     *
359
     * @return Message
360
     */
361 4
    public function sendPhoto(array $params)
362
    {
363 4
        return $this->uploadFile('sendPhoto', $params);
364
    }
365
366
    /**
367
     * Send regular audio files.
368
     *
369
     * <code>
370
     * $params = [
371
     *   'chat_id'             => '',
372
     *   'audio'               => '',
373
     *   'duration'            => '',
374
     *   'performer'           => '',
375
     *   'title'               => '',
376
     *   'reply_to_message_id' => '',
377
     *   'reply_markup'        => '',
378
     * ];
379
     * </code>
380
     *
381
     * @link https://core.telegram.org/bots/api#sendaudio
382
     *
383
     * @param array    $params
384
     *
385
     * @var int|string $params ['chat_id']
386
     * @var string     $params ['audio']
387
     * @var int        $params ['duration']
388
     * @var string     $params ['performer']
389
     * @var string     $params ['title']
390
     * @var int        $params ['reply_to_message_id']
391
     * @var string     $params ['reply_markup']
392
     *
393
     * @return Message
394
     */
395 2
    public function sendAudio(array $params)
396
    {
397 2
        return $this->uploadFile('sendAudio', $params);
398
    }
399
400
    /**
401
     * Send general files.
402
     *
403
     * <code>
404
     * $params = [
405
     *   'chat_id'             => '',
406
     *   'document'            => '',
407
     *   'reply_to_message_id' => '',
408
     *   'reply_markup'        => '',
409
     * ];
410
     * </code>
411
     *
412
     * @link https://core.telegram.org/bots/api#senddocument
413
     *
414
     * @param array    $params
415
     *
416
     * @var int|string $params ['chat_id']
417
     * @var string     $params ['document']
418
     * @var int        $params ['reply_to_message_id']
419
     * @var string     $params ['reply_markup']
420
     *
421
     * @return Message
422
     */
423 2
    public function sendDocument(array $params)
424
    {
425 2
        return $this->uploadFile('sendDocument', $params);
426
    }
427
428
    /**
429
     * Send .webp stickers.
430
     *
431
     * <code>
432
     * $params = [
433
     *   'chat_id' => '',
434
     *   'sticker' => '',
435
     *   'reply_to_message_id' => '',
436
     *   'reply_markup' => '',
437
     * ];
438
     * </code>
439
     *
440
     * @link https://core.telegram.org/bots/api#sendsticker
441
     *
442
     * @param array    $params
443
     *
444
     * @var int|string $params ['chat_id']
445
     * @var string     $params ['sticker']
446
     * @var int        $params ['reply_to_message_id']
447
     * @var string     $params ['reply_markup']
448
     *
449
     * @throws TelegramSDKException
450
     *
451
     * @return Message
452
     */
453 2
    public function sendSticker(array $params)
454
    {
455 2
        if (is_file($params['sticker']) && (pathinfo($params['sticker'], PATHINFO_EXTENSION) !== 'webp')) {
456
            throw new TelegramSDKException('Invalid Sticker Provided. Supported Format: Webp');
457
        }
458
459 2
        return $this->uploadFile('sendSticker', $params);
460
    }
461
462
    /**
463
     * Send Video File, Telegram clients support mp4 videos (other formats may be sent as Document).
464
     *
465
     * <code>
466
     * $params = [
467
     *   'chat_id'             => '',
468
     *   'video'               => '',
469
     *   'duration'            => '',
470
     *   'caption'             => '',
471
     *   'reply_to_message_id' => '',
472
     *   'reply_markup'        => '',
473
     * ];
474
     * </code>
475
     *
476
     * @see  sendDocument
477
     * @link https://core.telegram.org/bots/api#sendvideo
478
     *
479
     * @param array    $params
480
     *
481
     * @var int|string $params ['chat_id']
482
     * @var string     $params ['video']
483
     * @var int        $params ['duration']
484
     * @var string     $params ['caption']
485
     * @var int        $params ['reply_to_message_id']
486
     * @var string     $params ['reply_markup']
487
     *
488
     * @return Message
489
     */
490 2
    public function sendVideo(array $params)
491
    {
492 2
        return $this->uploadFile('sendVideo', $params);
493
    }
494
495
    /**
496
     * Send voice audio files.
497
     *
498
     * <code>
499
     * $params = [
500
     *   'chat_id'             => '',
501
     *   'voice'               => '',
502
     *   'duration'            => '',
503
     *   'reply_to_message_id' => '',
504
     *   'reply_markup'        => '',
505
     * ];
506
     * </code>
507
     *
508
     * @link https://core.telegram.org/bots/api#sendaudio
509
     *
510
     * @param array    $params
511
     *
512
     * @var int|string $params ['chat_id']
513
     * @var string     $params ['voice']
514
     * @var int        $params ['duration']
515
     * @var int        $params ['reply_to_message_id']
516
     * @var string     $params ['reply_markup']
517
     *
518
     * @return Message
519
     */
520 2
    public function sendVoice(array $params)
521
    {
522 2
        return $this->uploadFile('sendVoice', $params);
523
    }
524
525
    /**
526
     * Send point on the map.
527
     *
528
     * <code>
529
     * $params = [
530
     *   'chat_id'             => '',
531
     *   'latitude'            => '',
532
     *   'longitude'           => '',
533
     *   'reply_to_message_id' => '',
534
     *   'reply_markup'        => '',
535
     * ];
536
     * </code>
537
     *
538
     * @link https://core.telegram.org/bots/api#sendlocation
539
     *
540
     * @param array    $params
541
     *
542
     * @var int|string $params ['chat_id']
543
     * @var float      $params ['latitude']
544
     * @var float      $params ['longitude']
545
     * @var int        $params ['reply_to_message_id']
546
     * @var string     $params ['reply_markup']
547
     *
548
     * @return Message
549
     */
550 2
    public function sendLocation(array $params)
551
    {
552 2
        $response = $this->post('sendLocation', $params);
553
554 2
        return new Message($response->getDecodedBody());
555
    }
556
557
    /**
558
     * Broadcast a Chat Action.
559
     *
560
     * <code>
561
     * $params = [
562
     *   'chat_id' => '',
563
     *   'action'  => '',
564
     * ];
565
     * </code>
566
     *
567
     * @link https://core.telegram.org/bots/api#sendchataction
568
     *
569
     * @param array    $params
570
     *
571
     * @var int|string $params ['chat_id']
572
     * @var string     $params ['action']
573
     *
574
     * @throws TelegramSDKException
575
     *
576
     * @return TelegramResponse
577
     */
578 4
    public function sendChatAction(array $params)
579
    {
580
        $validActions = [
581 4
            'typing',
582 4
            'upload_photo',
583 4
            'record_video',
584 4
            'upload_video',
585 4
            'record_audio',
586 4
            'upload_audio',
587 4
            'upload_document',
588 4
            'find_location',
589 4
        ];
590
591 4
        if (isset($params['action']) && in_array($params['action'], $validActions)) {
592 2
            return $this->post('sendChatAction', $params);
593
        }
594
595 2
        throw new TelegramSDKException('Invalid Action! Accepted value: '.implode(', ', $validActions));
596
    }
597
598
    /**
599
     * Returns a list of profile pictures for a user.
600
     *
601
     * <code>
602
     * $params = [
603
     *   'user_id' => '',
604
     *   'offset'  => '',
605
     *   'limit'   => '',
606
     * ];
607
     * </code>
608
     *
609
     * @link https://core.telegram.org/bots/api#getuserprofilephotos
610
     *
611
     * @param array $params
612
     *
613
     * @var int     $params ['user_id']
614
     * @var int     $params ['offset']
615
     * @var int     $params ['limit']
616
     *
617
     * @return UserProfilePhotos
618
     */
619
    public function getUserProfilePhotos(array $params)
620
    {
621
        $response = $this->post('getUserProfilePhotos', $params);
622
623
        return new UserProfilePhotos($response->getDecodedBody());
624
    }
625
626
    /**
627
     * Returns basic info about a file and prepare it for downloading.
628
     *
629
     * <code>
630
     * $params = [
631
     *   'file_id' => '',
632
     * ];
633
     * </code>
634
     *
635
     * The file can then be downloaded via the link
636
     * https://api.telegram.org/file/bot<token>/<file_path>,
637
     * where <file_path> is taken from the response.
638
     *
639
     * @link https://core.telegram.org/bots/api#getFile
640
     *
641
     * @param array $params
642
     *
643
     * @var string  $params ['file_id']
644
     *
645
     * @return File
646
     */
647 2
    public function getFile(array $params)
648
    {
649 2
        $response = $this->post('getFile', $params);
650
651 2
        return new File($response->getDecodedBody());
652
    }
653
654
    /**
655
     * Set a Webhook to receive incoming updates via an outgoing webhook.
656
     *
657
     * <code>
658
     * $params = [
659
     *   'url'         => '',
660
     *   'certificate' => '',
661
     * ];
662
     * </code>
663
     *
664
     * @link https://core.telegram.org/bots/api#setwebhook
665
     *
666
     * @param array $params
667
     *
668
     * @var string  $params ['url']         HTTPS url to send updates to.
669
     * @var string  $params ['certificate'] Upload your public key certificate so that the root certificate in
670
     *                                      use can be checked.
671
     *
672
     * @throws TelegramSDKException
673
     *
674
     * @return TelegramResponse
675
     */
676 6
    public function setWebhook(array $params)
677
    {
678 6
        if (filter_var($params['url'], FILTER_VALIDATE_URL) === false) {
679 2
            throw new TelegramSDKException('Invalid URL Provided');
680
        }
681
682 4
        if (parse_url($params['url'], PHP_URL_SCHEME) !== 'https') {
683 2
            throw new TelegramSDKException('Invalid URL, should be a HTTPS url.');
684
        }
685
686 2
        return $this->uploadFile('setWebhook', $params);
687
    }
688
689
    /**
690
     * Returns webhook updates sent by Telegram.
691
     * Works only if you set a webhook.
692
     *
693
     * @see setWebhook
694
     *
695
     * @return Update
696
     */
697
    public function getWebhookUpdates()
698
    {
699
        $body = json_decode(file_get_contents('php://input'), true);
700
701
        return new Update($body);
702
    }
703
704
    /**
705
     * Removes the outgoing webhook (if any).
706
     *
707
     * @return TelegramResponse
708
     */
709 2
    public function removeWebhook()
710
    {
711 2
        $url = '';
712
713 2
        return $this->post('setWebhook', compact('url'));
714
    }
715
716
    /**
717
     * Use this method to receive incoming updates using long polling.
718
     *
719
     * <code>
720
     * $params = [
721
     *   'offset'  => '',
722
     *   'limit'   => '',
723
     *   'timeout' => '',
724
     * ];
725
     * </code>
726
     *
727
     * @link https://core.telegram.org/bots/api#getupdates
728
     *
729
     * @param array  $params
730
     *
731
     * @var int|null $params ['offset']
732
     * @var int|null $params ['limit']
733
     * @var int|null $params ['timeout']
734
     *
735
     * @return Update[]
736
     */
737 6
    public function getUpdates(array $params = [])
738
    {
739 6
        $response = $this->post('getUpdates', $params);
740 6
        $updates = $response->getDecodedBody();
741
742 6
        $data = [];
743 6
        foreach ($updates['result'] as $update) {
744 6
            $data[] = new Update($update);
745 6
        }
746
747 6
        return $data;
748
    }
749
750
    /**
751
     * Builds a custom keyboard markup.
752
     *
753
     * <code>
754
     * $params = [
755
     *   'keyboard'          => '',
756
     *   'resize_keyboard'   => '',
757
     *   'one_time_keyboard' => '',
758
     *   'selective'         => '',
759
     * ];
760
     * </code>
761
     *
762
     * @link https://core.telegram.org/bots/api#replykeyboardmarkup
763
     *
764
     * @param array $params
765
     *
766
     * @var array   $params ['keyboard']
767
     * @var bool    $params ['resize_keyboard']
768
     * @var bool    $params ['one_time_keyboard']
769
     * @var bool    $params ['selective']
770
     *
771
     * @return string
772
     */
773 2
    public function replyKeyboardMarkup(array $params)
774
    {
775 2
        return json_encode($params);
776
    }
777
778
    /**
779
     * Hide the current custom keyboard and display the default letter-keyboard.
780
     *
781
     * <code>
782
     * $params = [
783
     *   'hide_keyboard' => true,
784
     *   'selective'     => false,
785
     * ];
786
     * </code>
787
     *
788
     * @link https://core.telegram.org/bots/api#replykeyboardhide
789
     *
790
     * @param array $params
791
     *
792
     * @var bool    $params ['hide_keyboard']
793
     * @var bool    $params ['selective']
794
     *
795
     * @return string
796
     */
797 2
    public static function replyKeyboardHide(array $params = [])
798
    {
799 2
        return json_encode(array_merge(['hide_keyboard' => true, 'selective' => false], $params));
800
    }
801
802
    /**
803
     * Display a reply interface to the user (act as if the user has selected the bot‘s message and tapped ’Reply').
804
     *
805
     * <code>
806
     * $params = [
807
     *   'force_reply' => true,
808
     *   'selective'   => false,
809
     * ];
810
     * </code>
811
     *
812
     * @link https://core.telegram.org/bots/api#forcereply
813
     *
814
     * @param array $params
815
     *
816
     * @var bool    $params ['force_reply']
817
     * @var bool    $params ['selective']
818
     *
819
     * @return string
820
     */
821 2
    public static function forceReply(array $params = [])
822
    {
823 2
        return json_encode(array_merge(['force_reply' => true, 'selective' => false], $params));
824
    }
825
826
    /**
827
     * Processes Inbound Commands.
828
     *
829
     * @param bool $webhook
830
     *
831
     * @return Update|Update[]
832
     */
833 6
    public function commandsHandler($webhook = false)
834
    {
835 6
        if ($webhook) {
836
            $update = $this->getWebhookUpdates();
837
            $this->processCommand($update);
838
839
            return $update;
840
        }
841
842 6
        $updates = $this->getUpdates();
843 6
        $highestId = -1;
844
845 6
        foreach ($updates as $update) {
846 6
            $highestId = $update->getUpdateId();
847 6
            $this->processCommand($update);
848 6
        }
849
850
        //An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id.
851 6
        if ($highestId != -1) {
852 6
            $params = [];
853 6
            $params['offset'] = $highestId + 1;
854 6
            $params['limit'] = 1;
855 6
            $this->getUpdates($params);
856 6
        }
857
858 6
        return $updates;
859
    }
860
861
    /**
862
     * Check update object for a command and process.
863
     *
864
     * @param Update $update
865
     */
866 6
    protected function processCommand(Update $update)
867
    {
868 6
        $message = $update->getMessage();
869
870 6
        if ($message->has('text')) {
871 6
            $this->getCommandBus()->handler($message->getText(), $update);
872 6
        }
873 6
    }
874
875
    /**
876
     * Determine if a given type is the message.
877
     *
878
     * @param string         $type
879
     * @param Update|Message $object
880
     *
881
     * @return bool
882
     */
883
    public function isMessageType($type, $object)
884
    {
885
        if ($object instanceof Update) {
886
            $object = $object->getMessage();
887
        }
888
889
        if ($object->has(strtolower($type))) {
890
            return true;
891
        }
892
893
        return $this->detectMessageType($object) === $type;
894
    }
895
896
    /**
897
     * Detect Message Type Based on Update or Message Object.
898
     *
899
     * @param Update|Message $object
900
     *
901
     * @return string|null
902
     */
903
    public function detectMessageType($object)
904
    {
905
        if ($object instanceof Update) {
906
            $object = $object->getMessage();
907
        }
908
909
        $types = ['audio', 'document', 'photo', 'sticker', 'video', 'voice', 'contact', 'location', 'text'];
910
911
        return $object->keys()
912
            ->intersect($types)
913
            ->pop();
914
    }
915
916
    /**
917
     * Sends a GET request to Telegram Bot API and returns the result.
918
     *
919
     * @param string $endpoint
920
     * @param array  $params
921
     *
922
     * @throws TelegramSDKException
923
     *
924
     * @return TelegramResponse
925
     */
926
    protected function get($endpoint, $params = [])
927
    {
928
        return $this->sendRequest(
929
            'GET',
930
            $endpoint,
931
            $params
932
        );
933
    }
934
935
    /**
936
     * Sends a POST request to Telegram Bot API and returns the result.
937
     *
938
     * @param string $endpoint
939
     * @param array  $params
940
     * @param bool   $fileUpload Set true if a file is being uploaded.
941
     *
942
     * @return TelegramResponse
943
     */
944 40
    protected function post($endpoint, array $params = [], $fileUpload = false)
945
    {
946 40
        if ($fileUpload) {
947 16
            $params = ['multipart' => $params];
948 16
        } else {
949 24
            $params = ['form_params' => $params];
950
        }
951
952 40
        return $this->sendRequest(
953 40
            'POST',
954 40
            $endpoint,
955
            $params
956 40
        );
957
    }
958
959
    /**
960
     * Sends a multipart/form-data request to Telegram Bot API and returns the result.
961
     * Used primarily for file uploads.
962
     *
963
     * @param string $endpoint
964
     * @param array  $params
965
     *
966
     * @throws TelegramSDKException
967
     *
968
     * @return Message
969
     */
970 16
    protected function uploadFile($endpoint, array $params = [])
971
    {
972 16
        $i = 0;
973 16
        $multipart_params = [];
974 16
        foreach ($params as $name => $contents) {
975 16
            if (is_null($contents)) {
976
                continue;
977
            }
978
979 16
            if (!is_resource($contents) && $name !== 'url') {
980 14
                $validUrl = filter_var($contents, FILTER_VALIDATE_URL);
981 14
                $contents = (is_file($contents) || $validUrl) ? (new InputFile($contents))->open() : (string)$contents;
982 14
            }
983
984 16
            $multipart_params[$i]['name'] = $name;
985 16
            $multipart_params[$i]['contents'] = $contents;
986 16
            ++$i;
987 16
        }
988
989 16
        $response = $this->post($endpoint, $multipart_params, true);
990
991 16
        return new Message($response->getDecodedBody());
992
    }
993
994
    /**
995
     * Sends a request to Telegram Bot API and returns the result.
996
     *
997
     * @param string $method
998
     * @param string $endpoint
999
     * @param array  $params
1000
     *
1001
     * @throws TelegramSDKException
1002
     *
1003
     * @return TelegramResponse
1004
     */
1005 40
    protected function sendRequest(
1006
        $method,
1007
        $endpoint,
1008
        array $params = []
1009
    ) {
1010 40
        $request = $this->request($method, $endpoint, $params);
1011
1012 40
        return $this->lastResponse = $this->client->sendRequest($request);
1013
    }
1014
1015
    /**
1016
     * Instantiates a new TelegramRequest entity.
1017
     *
1018
     * @param string $method
1019
     * @param string $endpoint
1020
     * @param array  $params
1021
     *
1022
     * @return TelegramRequest
1023
     */
1024 40
    protected function request(
1025
        $method,
1026
        $endpoint,
1027
        array $params = []
1028
    ) {
1029 40
        return new TelegramRequest(
1030 40
            $this->getAccessToken(),
1031 40
            $method,
1032 40
            $endpoint,
1033 40
            $params,
1034 40
            $this->isAsyncRequest(),
1035 40
            $this->getTimeOut(),
1036 40
            $this->getConnectTimeOut()
1037 40
        );
1038
    }
1039
1040
    /**
1041
     * Magic method to process any "get" requests.
1042
     *
1043
     * @param $method
1044
     * @param $arguments
1045
     *
1046
     * @return bool|TelegramResponse
1047
     */
1048
    public function __call($method, $arguments)
1049
    {
1050
        $action = substr($method, 0, 3);
1051
        if ($action === 'get') {
1052
            /* @noinspection PhpUndefinedFunctionInspection */
1053
            $class_name = studly_case(substr($method, 3));
1054
            $class = 'Telegram\Bot\Objects\\'.$class_name;
1055
            $response = $this->post($method, $arguments[0] ?: []);
1056
1057
            if (class_exists($class)) {
1058
                return new $class($response->getDecodedBody());
1059
            }
1060
1061
            return $response;
1062
        }
1063
1064
        return false;
1065
    }
1066
1067
    /**
1068
     * Set the IoC Container.
1069
     *
1070
     * @param $container Container instance
1071
     *
1072
     * @return void
1073
     */
1074
    public static function setContainer(Container $container)
1075
    {
1076
        self::$container = $container;
1077
    }
1078
1079
    /**
1080
     * Get the IoC Container.
1081
     *
1082
     * @return Container
1083
     */
1084
    public function getContainer()
1085
    {
1086
        return self::$container;
1087
    }
1088
1089
    /**
1090
     * Check if IoC Container has been set.
1091
     *
1092
     * @return boolean
1093
     */
1094
    public function hasContainer()
1095
    {
1096
        return self::$container !== null;
1097
    }
1098
1099
    /**
1100
     * @return int
1101
     */
1102 40
    public function getTimeOut()
1103
    {
1104 40
        return $this->timeOut;
1105
    }
1106
1107
    /**
1108
     * @param int $timeOut
1109
     *
1110
     * @return $this
1111
     */
1112 2
    public function setTimeOut($timeOut)
1113
    {
1114 2
        $this->timeOut = $timeOut;
1115
1116 2
        return $this;
1117
    }
1118
1119
    /**
1120
     * @return int
1121
     */
1122 40
    public function getConnectTimeOut()
1123
    {
1124 40
        return $this->connectTimeOut;
1125
    }
1126
1127
    /**
1128
     * @param int $connectTimeOut
1129
     *
1130
     * @return $this
1131
     */
1132 2
    public function setConnectTimeOut($connectTimeOut)
1133
    {
1134 2
        $this->connectTimeOut = $connectTimeOut;
1135
1136 2
        return $this;
1137
    }
1138
}
1139