Completed
Push — master ( ab2d26...c692a8 )
by Irfaq
02:26
created

Api::unbanChatMember()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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