Completed
Push — master ( efbfdb...641f39 )
by Irfaq
03:41
created

Api::removeCommand()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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