Completed
Push — master ( e02d88...60454e )
by Irfaq
02:29
created

Api::emojify()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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