Completed
Push — master ( 4f81cd...7d8814 )
by Irfaq
14:25 queued 11:56
created

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

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

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

Loading history...
1263
    {
1264
        if ($object === null) {
1265
            return null;
1266
        }
1267
        
1268
        if ($object instanceof Update) {
1269
            if ($object->has('message')) {
1270
                $object = $object->getMessage();
1271
            }else{
1272
                throw new \InvalidArgumentException('The object must be or contain a message');
1273
            }
1274
        }
1275
        
1276
        return $object->isType($type);
1277
    }
1278
1279
    /**
1280
     * Detect Message Type Based on Update or Message Object.
1281
     *
1282
     * @deprecated Call method detectType directly on Message object
1283
     *             To be removed in next major version.
1284
     *
1285
     * @param Update|Message $object
1286
     *
1287
     * @throws \InvalidArgumentException
1288
     *
1289
     * @return string|null
1290
     */
1291 View Code Duplication
    public function detectMessageType($object)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1292
    {
1293
        if ($object === null) {
1294
            return null;
1295
        }
1296
        
1297
        if ($object instanceof Update) {
1298
            if ($object->has('message')) {
1299
                $object = $object->getMessage();
1300
            } else {
1301
                throw new \InvalidArgumentException('The object must be or contain a message');
1302
            }
1303
        }
1304
1305
        return $object->detectType();
1306
    }
1307
1308
    /**
1309
     * Sends a GET request to Telegram Bot API and returns the result.
1310
     *
1311
     * @param string $endpoint
1312
     * @param array  $params
1313
     *
1314
     * @throws TelegramSDKException
1315
     *
1316
     * @return TelegramResponse
1317
     */
1318
    protected function get($endpoint, $params = [])
1319
    {
1320
        if (array_key_exists('reply_markup', $params)) {
1321
            $params['reply_markup'] = (string)$params['reply_markup'];
1322
        }
1323
1324
        return $this->sendRequest(
1325
            'GET',
1326
            $endpoint,
1327
            $params
1328
        );
1329
    }
1330
1331
    /**
1332
     * Sends a POST request to Telegram Bot API and returns the result.
1333
     *
1334
     * @param string $endpoint
1335
     * @param array  $params
1336
     * @param bool   $fileUpload Set true if a file is being uploaded.
1337
     *
1338
     * @return TelegramResponse
1339
     */
1340 40
    protected function post($endpoint, array $params = [], $fileUpload = false)
1341
    {
1342 40
        if ($fileUpload) {
1343 16
            $params = ['multipart' => $params];
1344 16
        } else {
1345
1346 24
            if (array_key_exists('reply_markup', $params)) {
1347
                $params['reply_markup'] = (string)$params['reply_markup'];
1348
            }
1349
1350 24
            $params = ['form_params' => $params];
1351
        }
1352
1353 40
        return $this->sendRequest(
1354 40
            'POST',
1355 40
            $endpoint,
1356
            $params
1357 40
        );
1358
    }
1359
1360
    /**
1361
     * Sends a multipart/form-data request to Telegram Bot API and returns the result.
1362
     * Used primarily for file uploads.
1363
     *
1364
     * @param string $endpoint
1365
     * @param array  $params
1366
     *
1367
     * @throws TelegramSDKException
1368
     *
1369
     * @return Message
1370
     */
1371 16
    protected function uploadFile($endpoint, array $params = [])
1372
    {
1373 16
        $i = 0;
1374 16
        $multipart_params = [];
1375 16
        foreach ($params as $name => $contents) {
1376 16
            if (is_null($contents)) {
1377
                continue;
1378
            }
1379
1380 16
            if (!is_resource($contents) && $name !== 'url') {
1381 14
                $validUrl = filter_var($contents, FILTER_VALIDATE_URL);
1382 14
                $contents = (is_file($contents) || $validUrl) ? (new InputFile($contents))->open() : (string)$contents;
1383 14
            }
1384
1385 16
            $multipart_params[$i]['name'] = $name;
1386 16
            $multipart_params[$i]['contents'] = $contents;
1387 16
            ++$i;
1388 16
        }
1389
1390 16
        $response = $this->post($endpoint, $multipart_params, true);
1391
1392 16
        return new Message($response->getDecodedBody());
1393
    }
1394
1395
    /**
1396
     * Sends a request to Telegram Bot API and returns the result.
1397
     *
1398
     * @param string $method
1399
     * @param string $endpoint
1400
     * @param array  $params
1401
     *
1402
     * @throws TelegramSDKException
1403
     *
1404
     * @return TelegramResponse
1405
     */
1406 40
    protected function sendRequest(
1407
        $method,
1408
        $endpoint,
1409
        array $params = []
1410
    ) {
1411 40
        $request = $this->request($method, $endpoint, $params);
1412
1413 40
        return $this->lastResponse = $this->client->sendRequest($request);
1414
    }
1415
1416
    /**
1417
     * Instantiates a new TelegramRequest entity.
1418
     *
1419
     * @param string $method
1420
     * @param string $endpoint
1421
     * @param array  $params
1422
     *
1423
     * @return TelegramRequest
1424
     */
1425 40
    protected function request(
1426
        $method,
1427
        $endpoint,
1428
        array $params = []
1429
    ) {
1430 40
        return new TelegramRequest(
1431 40
            $this->getAccessToken(),
1432 40
            $method,
1433 40
            $endpoint,
1434 40
            $params,
1435 40
            $this->isAsyncRequest(),
1436 40
            $this->getTimeOut(),
1437 40
            $this->getConnectTimeOut()
1438 40
        );
1439
    }
1440
1441
    /**
1442
     * Magic method to process any "get" requests.
1443
     *
1444
     * @param $method
1445
     * @param $arguments
1446
     *
1447
     * @return bool|TelegramResponse|UnknownObject
1448
     */
1449 2
    public function __call($method, $arguments)
1450
    {
1451 2
        if (preg_match('/^\w+Commands?/', $method, $matches)) {
1452 2
            return call_user_func_array([$this->getCommandBus(), $matches[0]], $arguments);
1453
        }
1454
1455
        $action = substr($method, 0, 3);
1456
        if ($action === 'get') {
1457
            /* @noinspection PhpUndefinedFunctionInspection */
1458
            $class_name = studly_case(substr($method, 3));
1459
            $class = 'Telegram\Bot\Objects\\'.$class_name;
1460
            $response = $this->post($method, $arguments[0] ?: []);
1461
1462
            if (class_exists($class)) {
1463
                return new $class($response->getDecodedBody());
1464
            }
1465
1466
            return $response;
1467
        }
1468
        $response = $this->post($method, $arguments[0]);
1469
1470
        return new UnknownObject($response->getDecodedBody());
1471
    }
1472
1473
    /**
1474
     * Set the IoC Container.
1475
     *
1476
     * @param $container Container instance
1477
     *
1478
     * @return void
1479
     */
1480 2
    public static function setContainer(Container $container)
1481
    {
1482 2
        self::$container = $container;
1483 2
    }
1484
1485
    /**
1486
     * Get the IoC Container.
1487
     *
1488
     * @return Container
1489
     */
1490 2
    public function getContainer()
1491
    {
1492 2
        return self::$container;
1493
    }
1494
1495
    /**
1496
     * Check if IoC Container has been set.
1497
     *
1498
     * @return boolean
1499
     */
1500
    public function hasContainer()
1501
    {
1502
        return self::$container !== null;
1503
    }
1504
1505
    /**
1506
     * @return int
1507
     */
1508 40
    public function getTimeOut()
1509
    {
1510 40
        return $this->timeOut;
1511
    }
1512
1513
    /**
1514
     * @param int $timeOut
1515
     *
1516
     * @return $this
1517
     */
1518 2
    public function setTimeOut($timeOut)
1519
    {
1520 2
        $this->timeOut = $timeOut;
1521
1522 2
        return $this;
1523
    }
1524
1525
    /**
1526
     * @return int
1527
     */
1528 40
    public function getConnectTimeOut()
1529
    {
1530 40
        return $this->connectTimeOut;
1531
    }
1532
1533
    /**
1534
     * @param int $connectTimeOut
1535
     *
1536
     * @return $this
1537
     */
1538 2
    public function setConnectTimeOut($connectTimeOut)
1539
    {
1540 2
        $this->connectTimeOut = $connectTimeOut;
1541
1542 2
        return $this;
1543
    }
1544
}
1545