Passed
Push — develop ( 0b6bc5...79a5e4 )
by Michele
02:17
created

TelegramTrait::sendInvoice()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 2
b 0
f 0
nc 1
nop 8
dl 0
loc 6
rs 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Zanzara\Telegram;
6
7
use Clue\React\Buzz\Browser;
8
use Clue\React\Buzz\Message\ResponseException;
9
use Psr\Container\ContainerInterface;
10
use Psr\Http\Message\ResponseInterface;
11
use React\Filesystem\Filesystem;
12
use React\Promise\PromiseInterface;
13
use RingCentral\Psr7\MultipartStream;
14
use Zanzara\Config;
15
use Zanzara\MessageQueue;
16
use Zanzara\Telegram\Type\Chat;
17
use Zanzara\Telegram\Type\ChatMember;
18
use Zanzara\Telegram\Type\File\File;
19
use Zanzara\Telegram\Type\File\StickerSet;
20
use Zanzara\Telegram\Type\File\UserProfilePhotos;
21
use Zanzara\Telegram\Type\Game\GameHighScore;
22
use Zanzara\Telegram\Type\Input\InputFile;
23
use Zanzara\Telegram\Type\Message;
24
use Zanzara\Telegram\Type\Poll\Poll;
25
use Zanzara\Telegram\Type\Response\TelegramException;
26
use Zanzara\Telegram\Type\Update;
27
use Zanzara\Telegram\Type\Webhook\WebhookInfo;
28
use Zanzara\ZanzaraLogger;
29
use Zanzara\ZanzaraMapper;
30
use function React\Promise\all;
31
32
/**
33
 * Class that interacts with Telegram Api.
34
 * Made trait in order to be used both by Telegram and Context classes.
35
 *
36
 * @see Telegram
37
 * @see Context
38
 */
39
trait TelegramTrait
40
{
41
42
    /**
43
     * @var ContainerInterface
44
     */
45
    protected $container;
46
47
    /**
48
     * @var Browser
49
     */
50
    protected $browser;
51
52
    /**
53
     * @var Update|null
54
     */
55
    protected $update;
56
57
    /**
58
     * Use this method to receive incoming updates using long polling (wiki). An Array of @see Update objects is returned.
59
     *
60
     * More on https://core.telegram.org/bots/api#getupdates
61
     *
62
     * @param array $opt
63
     * @return PromiseInterface
64
     */
65
    public function getUpdates(array $opt = []): PromiseInterface
66
    {
67
        $method = "getUpdates";
68
        $query = http_build_query($opt);
69
70
        $browser = $this->browser->withOptions(array(
71
            "timeout" => $opt['timeout'] + 10 //timout browser necessary bigger than telegram timeout. They can't be equal
72
        ));
73
74
        return $this->wrapPromise($browser->get("$method?$query"), $method, $opt, Update::class);
75
    }
76
77
    /**
78
     * Use this method to send text messages. On success, the sent @see Message is returned.
79
     *
80
     * By default the message is sent to the chat_id of the context's update. Use $opt param to specify a different
81
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
82
     *
83
     * More on https://core.telegram.org/bots/api#sendmessage
84
     *
85
     * @param string $text
86
     * @param array|null $opt = [
87
     *     'chat_id' => 123456789,
88
     *     'parse_mode' => 'HTML',
89
     *     'disable_web_page_preview' => true,
90
     *     'disable_notification' => true,
91
     *     'reply_to_message_id' => 123456789,
92
     *     'reply_markup' => ['force_reply' => true],
93
     *     'reply_markup' => ['inline_keyboard' => [[
94
     *          ['callback_data' => 'data', 'text' => 'text']
95
     *      ]]],
96
     *      'reply_markup' => ['resize_keyboard' => true, 'one_time_keyboard' => true, 'selective' => true, 'keyboard' => [[
97
     *          ['text' => 'text', 'request_contact' => true, 'request_location' => true, 'request_poll' => ['type' => 'quiz']]
98
     *      ]]]
99
     * ]
100
     * @return PromiseInterface
101
     */
102
    public function sendMessage(string $text, ?array $opt = [])
103
    {
104
        $opt = $this->resolveChatId($opt);
105
        $required = compact("text");
106
        $params = array_merge($required, $opt);
107
        return $this->doSendMessage($params);
108
    }
109
110
    /**
111
     * Do not use it. Use @see TelegramTrait::sendMessage() instead.
112
     *
113
     * @internal
114
     * @param array $params
115
     * @return PromiseInterface
116
     */
117
    public function doSendMessage(array $params): PromiseInterface
118
    {
119
        return $this->callApi("sendMessage", $params, Message::class);
120
    }
121
122
    /**
123
     * Use this method to send a message to many chats. This method takes care of sending the message
124
     * with a delay in order avoid 429 Telegram errors (https://core.telegram.org/bots/faq#broadcasting-to-users).
125
     *
126
     * Eg. $ctx->sendBulkMessage([1111111111, 2222222222, 333333333], 'A wonderful notification', [parse_mode => 'HTML']);
127
     *
128
     * More on https://core.telegram.org/bots/api#sendmessage
129
     *
130
     * @param array $chatIds
131
     * @param string $text
132
     * @param array $opt
133
     */
134
    public function sendBulkMessage(array $chatIds, string $text, array $opt = []): void
135
    {
136
        $this->container->get(MessageQueue::class)
137
            ->push($chatIds, $text, $opt);
138
    }
139
140
    /**
141
     * Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update
142
     * for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update. In case
143
     * of an unsuccessful request, we will give up after a reasonable amount of attempts. Returns True on success.
144
     *
145
     * More on https://core.telegram.org/bots/api#setwebhook
146
     *
147
     * @param string $url
148
     * @param array|null $opt
149
     * @return PromiseInterface
150
     */
151
    public function setWebhook(string $url, ?array $opt = []): PromiseInterface
152
    {
153
        $required = compact("url");
154
        $params = array_merge($required, $opt);
155
        return $this->callApi("setWebhook", $params);
156
    }
157
158
    /**
159
     * Use this method to get current webhook status. Requires no parameters. On success, returns a @see WebhookInfo object.
160
     * If the bot is using getUpdates, will return an object with the url field empty.
161
     *
162
     * More on https://core.telegram.org/bots/api#getwebhookinfo
163
     *
164
     * @return PromiseInterface
165
     */
166
    public function getWebhookInfo(): PromiseInterface
167
    {
168
        return $this->callApi("getWebhookInfo", [], WebhookInfo::class);
169
    }
170
171
    /**
172
     * Use this method to remove webhook integration if you decide to switch back to getUpdates. Returns True on
173
     * success. Requires no parameters.
174
     *
175
     * More on https://core.telegram.org/bots/api#deletewebhook
176
     *
177
     * @return PromiseInterface
178
     */
179
    public function deleteWebhook(): PromiseInterface
180
    {
181
        return $this->callApi("deleteWebhook");
182
    }
183
184
    /**
185
     * Use this method to forward messages of any kind. On success, the sent @see Message is returned.
186
     *
187
     * More on https://core.telegram.org/bots/api#forwardmessage
188
     *
189
     * @param int $chat_id
190
     * @param int $from_chat_id
191
     * @param int $message_id
192
     * @param array|null $opt
193
     * @return PromiseInterface
194
     */
195
    public function forwardMessage(int $chat_id, int $from_chat_id, int $message_id, ?array $opt = []): PromiseInterface
196
    {
197
        $required = compact("chat_id", "from_chat_id", "message_id");
198
        $params = array_merge($required, $opt);
199
        return $this->callApi("forwardMessage", $params, Message::class);
200
    }
201
202
    /**
203
     * Use this method to send photos. On success, the sent @see Message is returned.
204
     *
205
     * The photo param can be either a string or a @see InputFile. Note that if you use the latter the file reading
206
     * operation is synchronous, so the main thread is blocked.
207
     * To make it asynchronous see https://github.com/badfarm/zanzara/wiki#working-with-files.
208
     *
209
     * By default the photo is sent to the chat_id of the context's update. Use $opt param to specify a different
210
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
211
     *
212
     * More on https://core.telegram.org/bots/api#sendphoto
213
     *
214
     * @param $photo
215
     * @param array|null $opt
216
     * @return PromiseInterface
217
     */
218
    public function sendPhoto($photo, ?array $opt = []): PromiseInterface
219
    {
220
        $opt = $this->resolveChatId($opt);
221
        $required = compact("photo");
222
        $params = array_merge($required, $opt);
223
        return $this->callApi("sendPhoto", $params, Message::class);
224
    }
225
226
    /**
227
     * Use this method to send audio files, if you want Telegram clients to display them in the music player. Your audio
228
     * must be in the .MP3 or .M4A format. On success, the sent @see Message is returned. Bots can currently send audio files
229
     * of up to 50 MB in size, this limit may be changed in the future.
230
     *
231
     * The audio and thumb params can be either a string or a @see InputFile. Note that if you use the latter the file reading
232
     * operation is synchronous, so the main thread is blocked.
233
     * To make it asynchronous see https://github.com/badfarm/zanzara/wiki#working-with-files.
234
     *
235
     * By default the audio is sent to the chat_id of the context's update. Use $opt param to specify a different
236
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
237
     *
238
     * More on https://core.telegram.org/bots/api#sendaudio
239
     *
240
     * @param $audio
241
     * @param array|null $opt
242
     * @return PromiseInterface
243
     */
244
    public function sendAudio($audio, ?array $opt = []): PromiseInterface
245
    {
246
        $opt = $this->resolveChatId($opt);
247
        $required = compact("audio");
248
        $params = array_merge($required, $opt);
249
        return $this->callApi("sendAudio", $params, Message::class);
250
    }
251
252
    /**
253
     * Use this method to send general files. On success, the sent @see Message is returned. Bots can currently send files of any
254
     * type of up to 50 MB in size, this limit may be changed in the future.
255
     *
256
     * The document and thumb params can be either a string or a @see InputFile. Note that if you use the latter the file reading
257
     * operation is synchronous, so the main thread is blocked.
258
     * To make it asynchronous see https://github.com/badfarm/zanzara/wiki#working-with-files.
259
     *
260
     * By default the document is sent to the chat_id of the context's update. Use $opt param to specify a different
261
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
262
     *
263
     * More on https://core.telegram.org/bots/api#senddocument
264
     *
265
     * @param $document
266
     * @param array|null $opt
267
     * @return PromiseInterface
268
     */
269
    public function sendDocument($document, ?array $opt = []): PromiseInterface
270
    {
271
        $opt = $this->resolveChatId($opt);
272
        $required = compact("document");
273
        $params = array_merge($required, $opt);
274
        return $this->callApi("sendDocument", $params, Message::class);
275
    }
276
277
    /**
278
     * Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document). On
279
     * success, the sent @see Message is returned. Bots can currently send video files of up to 50 MB in size, this limit may
280
     * be changed in the future.
281
     *
282
     * The video and thumb params can be either a string or a @see InputFile. Note that if you use the latter the file reading
283
     * operation is synchronous, so the main thread is blocked.
284
     * To make it asynchronous see https://github.com/badfarm/zanzara/wiki#working-with-files.
285
     *
286
     * By default the video is sent to the chat_id of the context's update. Use $opt param to specify a different
287
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
288
     *
289
     * More on https://core.telegram.org/bots/api#sendvideo
290
     *
291
     * @param $video
292
     * @param array|null $opt
293
     * @return PromiseInterface
294
     */
295
    public function sendVideo($video, ?array $opt = []): PromiseInterface
296
    {
297
        $opt = $this->resolveChatId($opt);
298
        $required = compact("video");
299
        $params = array_merge($required, $opt);
300
        return $this->callApi("sendVideo", $params, Message::class);
301
    }
302
303
    /**
304
     * Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound). On success, the sent @see Message
305
     * is returned. Bots can currently send animation files of up to 50 MB in size, this limit may be changed in the
306
     * future.
307
     *
308
     * The animation and thumb params can be either a string or a @see InputFile. Note that if you use the latter the file reading
309
     * operation is synchronous, so the main thread is blocked.
310
     * To make it asynchronous see https://github.com/badfarm/zanzara/wiki#working-with-files.
311
     *
312
     * By default the animation is sent to the chat_id of the context's update. Use $opt param to specify a different
313
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
314
     *
315
     * More on https://core.telegram.org/bots/api#sendanimation
316
     *
317
     * @param $animation
318
     * @param array|null $opt
319
     * @return PromiseInterface
320
     */
321
    public function sendAnimation($animation, ?array $opt = []): PromiseInterface
322
    {
323
        $opt = $this->resolveChatId($opt);
324
        $required = compact("animation");
325
        $params = array_merge($required, $opt);
326
        return $this->callApi("sendAnimation", $params, Message::class);
327
    }
328
329
    /**
330
     * Use this method to send audio files, if you want Telegram clients to display the file as a playable voice message.
331
     * For this to work, your audio must be in an .OGG file encoded with OPUS (other formats may be sent as Audio or
332
     * Document). On success, the sent @see Message is returned. Bots can currently send voice messages of up to 50 MB in
333
     * size, this limit may be changed in the future.
334
     *
335
     * The voice param can be either a string or a @see InputFile. Note that if you use the latter the file reading
336
     * operation is synchronous, so the main thread is blocked.
337
     * To make it asynchronous see https://github.com/badfarm/zanzara/wiki#working-with-files.
338
     *
339
     * By default the voice is sent to the chat_id of the context's update. Use $opt param to specify a different
340
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
341
     *
342
     * More on https://core.telegram.org/bots/api#sendvoice
343
     *
344
     * @param $voice
345
     * @param array|null $opt
346
     * @return PromiseInterface
347
     */
348
    public function sendVoice($voice, ?array $opt = []): PromiseInterface
349
    {
350
        $opt = $this->resolveChatId($opt);
351
        $required = compact("voice");
352
        $params = array_merge($required, $opt);
353
        return $this->callApi("sendVoice", $params, Message::class);
354
    }
355
356
    /**
357
     * As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long. Use this method to send video
358
     * messages. On success, the sent @see Message is returned.
359
     *
360
     * The video_note and thumb params can be either a string or a @see InputFile. Note that if you use the latter the file reading
361
     * operation is synchronous, so the main thread is blocked.
362
     * To make it asynchronous see https://github.com/badfarm/zanzara/wiki#working-with-files.
363
     *
364
     * By default the video note is sent to the chat_id of the context's update. Use $opt param to specify a different
365
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
366
     *
367
     * More on https://core.telegram.org/bots/api#sendvideonote
368
     *
369
     * @param $video_note
370
     * @param array|null $opt
371
     * @return PromiseInterface
372
     */
373
    public function sendVideoNote($video_note, ?array $opt = []): PromiseInterface
374
    {
375
        $opt = $this->resolveChatId($opt);
376
        $required = compact("video_note");
377
        $params = array_merge($required, $opt);
378
        return $this->callApi("sendVideoNote", $params, Message::class);
379
    }
380
381
    /**
382
     * Use this method to send a group of photos or videos as an album. On success, an array of the sent @see Message 's is returned.
383
     *
384
     * By default the media group is sent to the chat_id of the context's update. Use $opt param to specify a different
385
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
386
     *
387
     * More on https://core.telegram.org/bots/api#sendmediagroup
388
     *
389
     * @param $media
390
     * @param array|null $opt
391
     * @return PromiseInterface
392
     */
393
    public function sendMediaGroup($media, ?array $opt = []): PromiseInterface
394
    {
395
        $opt = $this->resolveChatId($opt);
396
        $required = compact("media");
397
        $params = array_merge($required, $opt);
398
        return $this->callApi("sendMediaGroup", $params, Message::class);
399
    }
400
401
    /**
402
     * Use this method to send point on the map. On success, the sent @see Message is returned.
403
     *
404
     * By default the location is sent to the chat_id of the context's update. Use $opt param to specify a different
405
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
406
     *
407
     * More on https://core.telegram.org/bots/api#sendlocation
408
     *
409
     * @param $latitude
410
     * @param $longitude
411
     * @param array|null $opt
412
     * @return PromiseInterface
413
     */
414
    public function sendLocation($latitude, $longitude, ?array $opt = []): PromiseInterface
415
    {
416
        $opt = $this->resolveChatId($opt);
417
        $required = compact("latitude", "longitude");
418
        $params = array_merge($required, $opt);
419
        return $this->callApi("sendLocation", $params, Message::class);
420
    }
421
422
    /**
423
     * Use this method to edit live location messages. A location can be edited until its live_period expires or editing is
424
     * explicitly disabled by a call to stopMessageLiveLocation. On success, if the edited message was sent by the bot,
425
     * the edited @see Message is returned, otherwise True is returned.
426
     *
427
     * By default the chat_id is taken from the context's update. Use $opt param to specify a different
428
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
429
     *
430
     * By default the message_id is taken from the context's update. Use $opt param to specify a different
431
     * message_id. Eg. $opt = ['message_id' => 123456789];
432
     *
433
     * By default the inline_message_id is taken from the context's update. Use $opt param to specify a different
434
     * inline_message_id. Eg. $opt = ['inline_message_id' => 123456789];
435
     *
436
     * More on https://core.telegram.org/bots/api#editmessagelivelocation
437
     *
438
     * @param $latitude
439
     * @param $longitude
440
     * @param array|null $opt
441
     * @return PromiseInterface
442
     */
443
    public function editMessageLiveLocation($latitude, $longitude, ?array $opt = []): PromiseInterface
444
    {
445
        $opt = $this->resolveMessageId($opt);
446
        $required = compact("latitude", "longitude");
447
        $params = array_merge($required, $opt);
448
        return $this->callApi("editMessageLiveLocation", $params, Message::class);
449
    }
450
451
    /**
452
     * Use this method to stop updating a live location message before live_period expires. On success, if the message was
453
     * sent by the bot, the sent @see Message is returned, otherwise True is returned.
454
     *
455
     * By default the chat_id is taken from the context's update. Use $opt param to specify a different
456
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
457
     *
458
     * By default the message_id is taken from the context's update. Use $opt param to specify a different
459
     * message_id. Eg. $opt = ['message_id' => 123456789];
460
     *
461
     * By default the inline_message_id is taken from the context's update. Use $opt param to specify a different
462
     * inline_message_id. Eg. $opt = ['inline_message_id' => 123456789];
463
     *
464
     * More on https://core.telegram.org/bots/api#stopmessagelivelocation
465
     *
466
     * @param array|null $opt
467
     * @return PromiseInterface
468
     */
469
    public function stopMessageLiveLocation(?array $opt = []): PromiseInterface
470
    {
471
        $opt = $this->resolveMessageId($opt);
472
        return $this->callApi("stopMessageLiveLocation", $opt, Message::class);
0 ignored issues
show
Bug introduced by
It seems like $opt can also be of type null; however, parameter $params of Zanzara\Telegram\TelegramTrait::callApi() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

472
        return $this->callApi("stopMessageLiveLocation", /** @scrutinizer ignore-type */ $opt, Message::class);
Loading history...
473
    }
474
475
    /**
476
     * Use this method to send information about a venue. On success, the sent @see Message is returned.
477
     *
478
     * By default the venue is sent to the chat_id of the context's update. Use $opt param to specify a different
479
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
480
     *
481
     * More on https://core.telegram.org/bots/api#sendvenue
482
     *
483
     * @param $latitude
484
     * @param $longitude
485
     * @param string $title
486
     * @param string $address
487
     * @param array|null $opt
488
     * @return PromiseInterface
489
     */
490
    public function sendVenue($latitude, $longitude, string $title, string $address, ?array $opt = []): PromiseInterface
491
    {
492
        $opt = $this->resolveChatId($opt);
493
        $required = compact("latitude", "longitude", "title", "address");
494
        $params = array_merge($required, $opt);
495
        return $this->callApi("sendVenue", $params, Message::class);
496
    }
497
498
    /**
499
     * Use this method to send phone contacts. On success, the sent @see Message is returned.
500
     *
501
     * By default the contact is sent to the chat_id of the context's update. Use $opt param to specify a different
502
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
503
     *
504
     * More on https://core.telegram.org/bots/api#sendcontact
505
     *
506
     * @param string $phone_number
507
     * @param string $first_name
508
     * @param array|null $opt
509
     * @return PromiseInterface
510
     */
511
    public function sendContact(string $phone_number, string $first_name, ?array $opt = []): PromiseInterface
512
    {
513
        $opt = $this->resolveChatId($opt);
514
        $required = compact("phone_number", "first_name");
515
        $params = array_merge($required, $opt);
516
        return $this->callApi("sendContact", $params, Message::class);
517
    }
518
519
    /**
520
     * Use this method to send a native poll. On success, the sent @see Message is returned.
521
     *
522
     * By default the poll is sent to the chat_id of the context's update. Use $opt param to specify a different
523
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
524
     *
525
     * More on https://core.telegram.org/bots/api#sendpoll
526
     *
527
     * @param string $question
528
     * @param $options
529
     * @param array|null $opt
530
     * @return PromiseInterface
531
     */
532
    public function sendPoll(string $question, $options, ?array $opt = []): PromiseInterface
533
    {
534
        $opt = $this->resolveChatId($opt);
535
        $required = compact("question", "options");
536
        $params = array_merge($required, $opt);
537
        return $this->callApi("sendPoll", $params, Message::class);
538
    }
539
540
    /**
541
     * Use this method to send a dice, which will have a random value from 1 to 6. On success, the sent @see Message is returned.
542
     * (Yes, we're aware of the "proper" singular of die. But it's awkward, and we decided to help it change. One dice at
543
     * a time!)
544
     *
545
     * By default the dice is sent to the chat_id of the context's update. Use $opt param to specify a different
546
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
547
     *
548
     * More on https://core.telegram.org/bots/api#senddice
549
     *
550
     * @param array|null $opt
551
     * @return PromiseInterface
552
     */
553
    public function sendDice(?array $opt = []): PromiseInterface
554
    {
555
        $opt = $this->resolveChatId($opt);
556
        return $this->callApi("sendDice", $opt, Message::class);
0 ignored issues
show
Bug introduced by
It seems like $opt can also be of type null; however, parameter $params of Zanzara\Telegram\TelegramTrait::callApi() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

556
        return $this->callApi("sendDice", /** @scrutinizer ignore-type */ $opt, Message::class);
Loading history...
557
    }
558
559
    /**
560
     * Use this method when you need to tell the user that something is happening on the bot's side. The status is set for 5
561
     * seconds or less (when a message arrives from your bot, Telegram clients clear its typing status). Returns True on
562
     * success.
563
     *
564
     * By default the chat action is sent to the chat_id of the context's update. Use $opt param to specify a different
565
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
566
     *
567
     * More on https://core.telegram.org/bots/api#sendchataction
568
     *
569
     * @param string $action
570
     * @param array|null $opt
571
     * @return PromiseInterface
572
     */
573
    public function sendChatAction(string $action, ?array $opt = []): PromiseInterface
574
    {
575
        $opt = $this->resolveChatId($opt);
576
        $required = compact("action");
577
        $params = array_merge($required, $opt);
578
        return $this->callApi("sendChatAction", $params);
579
    }
580
581
    /**
582
     * Use this method to get a list of profile pictures for a user. Returns a @see UserProfilePhotos object.
583
     *
584
     * More on https://core.telegram.org/bots/api#getuserprofilephotos
585
     *
586
     * @param int $user_id
587
     * @param array|null $opt
588
     * @return PromiseInterface
589
     */
590
    public function getUserProfilePhotos(int $user_id, ?array $opt = []): PromiseInterface
591
    {
592
        $required = compact("user_id");
593
        $params = array_merge($required, $opt);
594
        return $this->callApi("getUserProfilePhotos", $params, UserProfilePhotos::class);
595
    }
596
597
    /**
598
     * Use this method to get basic info about a file and prepare it for downloading. For the moment, bots can download
599
     * files of up to 20MB in size. On success, a @see File object is returned. The file can then be downloaded via the link
600
     * https://api.telegram.org/file/bot&lt;token&gt;/&lt;file_path&gt;, where &lt;file_path&gt; is taken from the
601
     * response. It is guaranteed that the link will be valid for at least 1 hour. When the link expires, a new one can
602
     * be requested by calling getFile again.
603
     *
604
     * More on https://core.telegram.org/bots/api#getfile
605
     *
606
     * @param string $file_id
607
     * @param array|null $opt
608
     * @return PromiseInterface
609
     */
610
    public function getFile(string $file_id, ?array $opt = []): PromiseInterface
611
    {
612
        $required = compact("file_id");
613
        $params = array_merge($required, $opt);
614
        return $this->callApi("getFile", $params, File::class);
615
    }
616
617
    /**
618
     * Use this method to kick a user from a group, a supergroup or a channel. In the case of supergroups and channels, the
619
     * user will not be able to return to the group on their own using invite links, etc., unless unbanned first. The bot
620
     * must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns True on
621
     * success.
622
     *
623
     * More on https://core.telegram.org/bots/api#kickchatmember
624
     *
625
     * @param int $chat_id
626
     * @param int $user_id
627
     * @param array|null $opt
628
     * @return PromiseInterface
629
     */
630
    public function kickChatMember(int $chat_id, int $user_id, ?array $opt = []): PromiseInterface
631
    {
632
        $required = compact("chat_id", "user_id");
633
        $params = array_merge($required, $opt);
634
        return $this->callApi("kickChatMember", $params);
635
    }
636
637
    /**
638
     * Use this method to unban a previously kicked user in a supergroup or channel. The user will not return to the group
639
     * or channel automatically, but will be able to join via link, etc. The bot must be an administrator for this to
640
     * work. Returns True on success.
641
     *
642
     * More on https://core.telegram.org/bots/api#unbanchatmember
643
     *
644
     * @param int $chat_id
645
     * @param int $user_id
646
     * @param array|null $opt
647
     * @return PromiseInterface
648
     */
649
    public function unbanChatMember(int $chat_id, int $user_id, ?array $opt = []): PromiseInterface
650
    {
651
        $required = compact("chat_id", "user_id");
652
        $params = array_merge($required, $opt);
653
        return $this->callApi("unbanChatMember", $params);
654
    }
655
656
    /**
657
     * Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for this to
658
     * work and must have the appropriate admin rights. Pass True for all permissions to lift restrictions from a user.
659
     * Returns True on success.
660
     *
661
     * More on https://core.telegram.org/bots/api#restrictchatmember
662
     *
663
     * @param int $chat_id
664
     * @param int $user_id
665
     * @param $permissions
666
     * @param array|null $opt
667
     * @return PromiseInterface
668
     */
669
    public function restrictChatMember(int $chat_id, int $user_id, $permissions, ?array $opt = []): PromiseInterface
670
    {
671
        $required = compact("chat_id", "user_id", "permissions");
672
        $params = array_merge($required, $opt);
673
        return $this->callApi("restrictChatMember", $params);
674
    }
675
676
    /**
677
     * Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in the
678
     * chat for this to work and must have the appropriate admin rights. Pass False for all boolean parameters to demote
679
     * a user. Returns True on success.
680
     *
681
     * More on https://core.telegram.org/bots/api#promotechatmember
682
     *
683
     * @param int $chat_id
684
     * @param int $user_id
685
     * @param array|null $opt
686
     * @return PromiseInterface
687
     */
688
    public function promoteChatMember(int $chat_id, int $user_id, ?array $opt = []): PromiseInterface
689
    {
690
        $required = compact("chat_id", "user_id");
691
        $params = array_merge($required, $opt);
692
        return $this->callApi("promoteChatMember", $params);
693
    }
694
695
    /**
696
     * Use this method to set a custom title for an administrator in a supergroup promoted by the bot. Returns True on success.
697
     *
698
     * More on https://core.telegram.org/bots/api#setchatadministratorcustomtitle
699
     *
700
     * @param int $chat_id
701
     * @param int $user_id
702
     * @param string $custom_title
703
     * @param array|null $opt
704
     * @return PromiseInterface
705
     */
706
    public function setChatAdministratorCustomTitle(int $chat_id, int $user_id, string $custom_title, ?array $opt = []): PromiseInterface
707
    {
708
        $required = compact("chat_id", "user_id", "custom_title");
709
        $params = array_merge($required, $opt);
710
        return $this->callApi("setChatAdministratorCustomTitle", $params);
711
    }
712
713
    /**
714
     * Use this method to set default chat permissions for all members. The bot must be an administrator in the group or a
715
     * supergroup for this to work and must have the can_restrict_members admin rights. Returns True on success.
716
     *
717
     * More on https://core.telegram.org/bots/api#setchatpermissions
718
     *
719
     * @param int $chat_id
720
     * @param $permissions
721
     * @param array|null $opt
722
     * @return PromiseInterface
723
     */
724
    public function setChatPermissions(int $chat_id, $permissions, ?array $opt = []): PromiseInterface
725
    {
726
        $required = compact("chat_id", "permissions");
727
        $params = array_merge($required, $opt);
728
        return $this->callApi("setChatPermissions", $params);
729
    }
730
731
    /**
732
     * Use this method to generate a new invite link for a chat; any previously generated link is revoked. The bot must be
733
     * an administrator in the chat for this to work and must have the appropriate admin rights. Returns the new invite
734
     * link as String on success.
735
     *
736
     * More on https://core.telegram.org/bots/api#exportchatinvitelink
737
     *
738
     * @param int $chat_id
739
     * @param array|null $opt
740
     * @return PromiseInterface
741
     */
742
    public function exportChatInviteLink(int $chat_id, ?array $opt = []): PromiseInterface
743
    {
744
        $required = compact("chat_id");
745
        $params = array_merge($required, $opt);
746
        return $this->callApi("exportChatInviteLink", $params);
747
    }
748
749
    /**
750
     * Use this method to set a new profile photo for the chat. Photos can't be changed for private chats. The bot must be
751
     * an administrator in the chat for this to work and must have the appropriate admin rights. Returns True on success.
752
     *
753
     * More on https://core.telegram.org/bots/api#setchatphoto
754
     *
755
     * @param int $chat_id
756
     * @param $photo
757
     * @param array|null $opt
758
     * @return PromiseInterface
759
     */
760
    public function setChatPhoto(int $chat_id, $photo, ?array $opt = []): PromiseInterface
761
    {
762
        $required = compact("chat_id", "photo");
763
        $params = array_merge($required, $opt);
764
        return $this->callApi("setChatPhoto", $params); //bool
765
    }
766
767
    /**
768
     * Use this method to delete a chat photo. Photos can't be changed for private chats. The bot must be an administrator
769
     * in the chat for this to work and must have the appropriate admin rights. Returns True on success.
770
     *
771
     * More on https://core.telegram.org/bots/api#deletechatphoto
772
     *
773
     * @param int $chat_id
774
     * @param array|null $opt
775
     * @return PromiseInterface
776
     */
777
    public function deleteChatPhoto(int $chat_id, ?array $opt = []): PromiseInterface
778
    {
779
        $required = compact("chat_id");
780
        $params = array_merge($required, $opt);
781
        return $this->callApi("deleteChatPhoto", $params);
782
    }
783
784
    /**
785
     * Use this method to change the title of a chat. Titles can't be changed for private chats. The bot must be an
786
     * administrator in the chat for this to work and must have the appropriate admin rights. Returns True on success.
787
     *
788
     * More on https://core.telegram.org/bots/api#setchattitle
789
     *
790
     * @param int $chat_id
791
     * @param string $title
792
     * @param array|null $opt
793
     * @return PromiseInterface
794
     */
795
    public function setChatTitle(int $chat_id, string $title, ?array $opt = []): PromiseInterface
796
    {
797
        $required = compact("chat_id", "title");
798
        $params = array_merge($required, $opt);
799
        return $this->callApi("setChatTitle", $params);
800
    }
801
802
    /**
803
     * Use this method to change the description of a group, a supergroup or a channel. The bot must be an administrator in
804
     * the chat for this to work and must have the appropriate admin rights. Returns True on success.
805
     *
806
     * More on https://core.telegram.org/bots/api#setchatdescription
807
     *
808
     * @param int $chat_id
809
     * @param array|null $opt
810
     * @return PromiseInterface
811
     */
812
    public function setChatDescription(int $chat_id, ?array $opt = []): PromiseInterface
813
    {
814
        $required = compact("chat_id");
815
        $params = array_merge($required, $opt);
816
        return $this->callApi("setChatDescription", $params);
817
    }
818
819
    /**
820
     * Use this method to pin a message in a group, a supergroup, or a channel. The bot must be an administrator in the chat
821
     * for this to work and must have the 'can_pin_messages' admin right in the supergroup or 'can_edit_messages' admin
822
     * right in the channel. Returns True on success.
823
     *
824
     * More on https://core.telegram.org/bots/api#pinchatmessage
825
     *
826
     * @param int $chat_id
827
     * @param int $message_id
828
     * @param array|null $opt
829
     * @return PromiseInterface
830
     */
831
    public function pinChatMessage(int $chat_id, int $message_id, ?array $opt = []): PromiseInterface
832
    {
833
        $required = compact("chat_id", "message_id");
834
        $params = array_merge($required, $opt);
835
        return $this->callApi("pinChatMessage", $params);
836
    }
837
838
    /**
839
     * Use this method to unpin a message in a group, a supergroup, or a channel. The bot must be an administrator in the
840
     * chat for this to work and must have the 'can_pin_messages' admin right in the supergroup or 'can_edit_messages'
841
     * admin right in the channel. Returns True on success.
842
     *
843
     * More on https://core.telegram.org/bots/api#unpinchatmessage
844
     *
845
     * @param int $chat_id
846
     * @param array|null $opt
847
     * @return PromiseInterface
848
     */
849
    public function unpinChatMessage(int $chat_id, ?array $opt = []): PromiseInterface
850
    {
851
        $required = compact("chat_id");
852
        $params = array_merge($required, $opt);
853
        return $this->callApi("unpinChatMessage", $params);
854
    }
855
856
    /**
857
     * Use this method for your bot to leave a group, supergroup or channel. Returns True on success.
858
     *
859
     * More on https://core.telegram.org/bots/api#leavechat
860
     *
861
     * @param int $chat_id
862
     * @param array|null $opt
863
     * @return PromiseInterface
864
     */
865
    public function leaveChat(int $chat_id, ?array $opt = []): PromiseInterface
866
    {
867
        $required = compact("chat_id");
868
        $params = array_merge($required, $opt);
869
        return $this->callApi("leaveChat", $params);
870
    }
871
872
    /**
873
     * Use this method to get up to date information about the chat (current name of the user for one-on-one conversations,
874
     * current username of a user, group or channel, etc.). Returns a @see Chat object on success.
875
     *
876
     * More on https://core.telegram.org/bots/api#getchat
877
     *
878
     * @param int $chat_id
879
     * @param array|null $opt
880
     * @return PromiseInterface
881
     */
882
    public function getChat(int $chat_id, ?array $opt = []): PromiseInterface
883
    {
884
        $required = compact("chat_id");
885
        $params = array_merge($required, $opt);
886
        return $this->callApi("getChat", $params, Chat::class);
887
    }
888
889
    /**
890
     * Use this method to get a list of administrators in a chat. On success, returns an Array of @see ChatMember objects that
891
     * contains information about all chat administrators except other bots. If the chat is a group or a supergroup and
892
     * no administrators were appointed, only the creator will be returned.
893
     *
894
     * More on https://core.telegram.org/bots/api#getchatadministrators
895
     *
896
     * @param int $chat_id
897
     * @param array|null $opt
898
     * @return PromiseInterface
899
     */
900
    public function getChatAdministrators(int $chat_id, ?array $opt = []): PromiseInterface
901
    {
902
        $required = compact("chat_id");
903
        $params = array_merge($required, $opt);
904
        return $this->callApi("getChatAdministrators", $params, ChatMember::class);
905
    }
906
907
    /**
908
     * Use this method to get the number of members in a chat. Returns Int on success.
909
     *
910
     * More on https://core.telegram.org/bots/api#getchatmemberscount
911
     *
912
     * @param int $chat_id
913
     * @param array|null $opt
914
     * @return PromiseInterface
915
     */
916
    public function getChatMembersCount(int $chat_id, ?array $opt = []): PromiseInterface
917
    {
918
        $required = compact("chat_id");
919
        $params = array_merge($required, $opt);
920
        return $this->callApi("getChatMembersCount", $params); //integer
921
    }
922
923
    /**
924
     * Use this method to get information about a member of a chat. Returns a @see ChatMember object on success.
925
     *
926
     * More on https://core.telegram.org/bots/api#getchatmember
927
     *
928
     * @param int $chat_id
929
     * @param int $user_id
930
     * @param array|null $opt
931
     * @return PromiseInterface
932
     */
933
    public function getChatMember(int $chat_id, int $user_id, ?array $opt = []): PromiseInterface
934
    {
935
        $required = compact("chat_id", "user_id");
936
        $params = array_merge($required, $opt);
937
        return $this->callApi("getChatMember", $params, ChatMember::class);
938
    }
939
940
    /**
941
     * Use this method to set a new group sticker set for a supergroup. The bot must be an administrator in the chat for
942
     * this to work and must have the appropriate admin rights. Use the field can_set_sticker_set optionally returned in
943
     * getChat requests to check if the bot can use this method. Returns True on success.
944
     *
945
     * More on https://core.telegram.org/bots/api#setchatstickerset
946
     *
947
     * @param int $chat_id
948
     * @param string $sticker_set_name
949
     * @param array|null $opt
950
     * @return PromiseInterface
951
     */
952
    public function setChatStickerSet(int $chat_id, string $sticker_set_name, ?array $opt = []): PromiseInterface
953
    {
954
        $required = compact("chat_id", "sticker_set_name");
955
        $params = array_merge($required, $opt);
956
        return $this->callApi("setChatStickerSet", $params);
957
    }
958
959
    /**
960
     * Use this method to delete a group sticker set from a supergroup. The bot must be an administrator in the chat for
961
     * this to work and must have the appropriate admin rights. Use the field can_set_sticker_set optionally returned in
962
     * getChat requests to check if the bot can use this method. Returns True on success.
963
     *
964
     * More on https://core.telegram.org/bots/api#deletechatstickerset
965
     *
966
     * @param int $chat_id
967
     * @param array|null $opt
968
     * @return PromiseInterface
969
     */
970
    public function deleteChatStickerSet(int $chat_id, ?array $opt = []): PromiseInterface
971
    {
972
        $required = compact("chat_id");
973
        $params = array_merge($required, $opt);
974
        return $this->callApi("deleteChatStickerSet", $params);
975
    }
976
977
    /**
978
     * Use this method to send answers to callback queries sent from inline keyboards. The answer will be displayed to the
979
     * user as a notification at the top of the chat screen or as an alert. On success, True is returned.
980
     *
981
     * By default it replies to the callback_query_id of the context's update. Use $opt param to specify a different
982
     * callback_query_id. Eg. $opt = ['callback_query_id' => 'abcdefgh'];
983
     *
984
     * More on https://core.telegram.org/bots/api#answercallbackquery
985
     *
986
     * @param array|null $opt
987
     * @return PromiseInterface
988
     */
989
    public function answerCallbackQuery(?array $opt = []): PromiseInterface
990
    {
991
        if (!isset($opt['callback_query_id']) && $this->update) {
992
            $opt['callback_query_id'] = $this->update->getCallbackQuery()->getId();
993
        }
994
        return $this->callApi("answerCallbackQuery", $opt);
995
    }
996
997
    /**
998
     * Use this method to change the list of the bot's commands. Returns True on success.
999
     *
1000
     * More on https://core.telegram.org/bots/api#setmycommands
1001
     *
1002
     * @param $commands
1003
     * @param array|null $opt
1004
     * @return PromiseInterface
1005
     */
1006
    public function setMyCommands($commands, ?array $opt = []): PromiseInterface
1007
    {
1008
        $required = compact("commands");
1009
        $params = array_merge($required, $opt);
1010
        return $this->callApi("setMyCommands", $params);
1011
    }
1012
1013
    /**
1014
     * Use this method to edit text and game messages. On success, if edited message is sent by the bot, the edited @see Message
1015
     * is returned, otherwise True is returned.
1016
     *
1017
     * By default the chat_id is taken from the context's update. Use $opt param to specify a different
1018
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
1019
     *
1020
     * By default the message_id is taken from the context's update. Use $opt param to specify a different
1021
     * message_id. Eg. $opt = ['message_id' => 123456789];
1022
     *
1023
     * By default the inline_message_id is taken from the context's update. Use $opt param to specify a different
1024
     * inline_message_id. Eg. $opt = ['inline_message_id' => 123456789];
1025
     *
1026
     * More on https://core.telegram.org/bots/api#editmessagetext
1027
     *
1028
     * @param string $text
1029
     * @param array|null $opt = [
1030
     *     'reply_markup' => ['inline_keyboard' => [[
1031
     *          ['callback_data' => 'data', 'text' => 'text']
1032
     *      ]]]
1033
     * ]
1034
     * @return PromiseInterface
1035
     */
1036
    public function editMessageText(string $text, ?array $opt = []): PromiseInterface
1037
    {
1038
        $opt = $this->resolveMessageId($opt);
1039
        $required = compact("text");
1040
        $params = array_merge($required, $opt);
1041
        return $this->callApi("editMessageText", $params, Message::class);
1042
    }
1043
1044
    /**
1045
     * Use this method to edit captions of messages. On success, if edited message is sent by the bot, the edited @see Message is
1046
     * returned, otherwise True is returned.
1047
     *
1048
     * By default the chat_id is taken from the context's update. Use $opt param to specify a different
1049
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
1050
     *
1051
     * By default the message_id is taken from the context's update. Use $opt param to specify a different
1052
     * message_id. Eg. $opt = ['message_id' => 123456789];
1053
     *
1054
     * By default the inline_message_id is taken from the context's update. Use $opt param to specify a different
1055
     * inline_message_id. Eg. $opt = ['inline_message_id' => 123456789];
1056
     *
1057
     * More on https://core.telegram.org/bots/api#editmessagecaption
1058
     *
1059
     * @param array|null $opt
1060
     * @return PromiseInterface
1061
     */
1062
    public function editMessageCaption(?array $opt = []): PromiseInterface
1063
    {
1064
        $opt = $this->resolveMessageId($opt);
1065
        return $this->callApi("editMessageCaption", $opt, Message::class);
0 ignored issues
show
Bug introduced by
It seems like $opt can also be of type null; however, parameter $params of Zanzara\Telegram\TelegramTrait::callApi() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1065
        return $this->callApi("editMessageCaption", /** @scrutinizer ignore-type */ $opt, Message::class);
Loading history...
1066
    }
1067
1068
    /**
1069
     * Use this method to edit animation, audio, document, photo, or video messages. If a message is a part of a message
1070
     * album, then it can be edited only to a photo or a video. Otherwise, message type can be changed arbitrarily. When
1071
     * inline message is edited, new file can't be uploaded. Use previously uploaded file via its file_id or specify a
1072
     * URL. On success, if the edited message was sent by the bot, the edited @see Message is returned, otherwise True is
1073
     * returned.
1074
     *
1075
     * By default the chat_id is taken from the context's update. Use $opt param to specify a different
1076
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
1077
     *
1078
     * By default the message_id is taken from the context's update. Use $opt param to specify a different
1079
     * message_id. Eg. $opt = ['message_id' => 123456789];
1080
     *
1081
     * By default the inline_message_id is taken from the context's update. Use $opt param to specify a different
1082
     * inline_message_id. Eg. $opt = ['inline_message_id' => 123456789];
1083
     *
1084
     * More on https://core.telegram.org/bots/api#editmessagemedia
1085
     *
1086
     * @param $media
1087
     * @param array|null $opt
1088
     * @return PromiseInterface
1089
     */
1090
    public function editMessageMedia($media, ?array $opt = []): PromiseInterface
1091
    {
1092
        $opt = $this->resolveMessageId($opt);
1093
        $required = compact("media");
1094
        $params = array_merge($required, $opt);
1095
        return $this->callApi("editMessageMedia", $params, Message::class);
1096
    }
1097
1098
    /**
1099
     * Use this method to edit only the reply markup of messages. On success, if edited message is sent by the bot, the
1100
     * edited @see Message is returned, otherwise True is returned.
1101
     *
1102
     * By default the chat_id is taken from the context's update. Use $opt param to specify a different
1103
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
1104
     *
1105
     * By default the message_id is taken from the context's update. Use $opt param to specify a different
1106
     * message_id. Eg. $opt = ['message_id' => 123456789];
1107
     *
1108
     * By default the inline_message_id is taken from the context's update. Use $opt param to specify a different
1109
     * inline_message_id. Eg. $opt = ['inline_message_id' => 123456789];
1110
     *
1111
     * More on https://core.telegram.org/bots/api#editmessagereplymarkup
1112
     *
1113
     * @param array|null $opt
1114
     * @return PromiseInterface
1115
     */
1116
    public function editMessageReplyMarkup(?array $opt = []): PromiseInterface
1117
    {
1118
        $opt = $this->resolveMessageId($opt);
1119
        return $this->callApi("editMessageReplyMarkup", $opt, Message::class);
0 ignored issues
show
Bug introduced by
It seems like $opt can also be of type null; however, parameter $params of Zanzara\Telegram\TelegramTrait::callApi() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1119
        return $this->callApi("editMessageReplyMarkup", /** @scrutinizer ignore-type */ $opt, Message::class);
Loading history...
1120
    }
1121
1122
    /**
1123
     * Use this method to stop a poll which was sent by the bot. On success, the stopped @see Poll with the final results is
1124
     * returned.
1125
     *
1126
     * More on https://core.telegram.org/bots/api#stoppoll
1127
     *
1128
     * @param int $chat_id
1129
     * @param int $message_id
1130
     * @param array|null $opt
1131
     * @return PromiseInterface
1132
     */
1133
    public function stopPoll(int $chat_id, int $message_id, ?array $opt = []): PromiseInterface
1134
    {
1135
        $required = compact("chat_id", "message_id");
1136
        $params = array_merge($required, $opt);
1137
        return $this->callApi("stopPoll", $params, Poll::class);
1138
    }
1139
1140
    /**
1141
     * Use this method to delete a message, including service messages, with the following limitations:- A message can only
1142
     * be deleted if it was sent less than 48 hours ago.- A dice message in a private chat can only be deleted if it was
1143
     * sent more than 24 hours ago.- Bots can delete outgoing messages in private chats, groups, and supergroups.- Bots
1144
     * can delete incoming messages in private chats.- Bots granted can_post_messages permissions can delete outgoing
1145
     * messages in channels.- If the bot is an administrator of a group, it can delete any message there.- If the bot has
1146
     * can_delete_messages permission in a supergroup or a channel, it can delete any message there.Returns True on
1147
     * success.
1148
     *
1149
     * More on https://core.telegram.org/bots/api#deletemessage
1150
     *
1151
     * @param int $chat_id
1152
     * @param int $message_id
1153
     * @param array|null $opt
1154
     * @return PromiseInterface
1155
     */
1156
    public function deleteMessage(int $chat_id, int $message_id, ?array $opt = []): PromiseInterface
1157
    {
1158
        $required = compact("chat_id", "message_id");
1159
        $params = array_merge($required, $opt);
1160
        return $this->callApi("deleteMessage", $params);
1161
    }
1162
1163
    /**
1164
     * Use this method to send static .WEBP or animated .TGS stickers. On success, the sent @see Message is returned.
1165
     *
1166
     * The sticker param can be either a string or a @see InputFile. Note that if you use the latter the file reading
1167
     * operation is synchronous, so the main thread is blocked.
1168
     * To make it asynchronous see https://github.com/badfarm/zanzara/wiki#working-with-files.
1169
     *
1170
     * By default the sticker is sent to the chat_id of the context's update. Use $opt param to specify a different
1171
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
1172
     *
1173
     * More on https://core.telegram.org/bots/api#sendsticker
1174
     *
1175
     * @param $sticker
1176
     * @param array|null $opt
1177
     * @return PromiseInterface
1178
     */
1179
    public function sendSticker($sticker, ?array $opt = []): PromiseInterface
1180
    {
1181
        $opt = $this->resolveChatId($opt);
1182
        $required = compact("sticker");
1183
        $params = array_merge($required, $opt);
1184
        return $this->callApi("sendSticker", $params, Message::class);
1185
    }
1186
1187
    /**
1188
     * Use this method to get a sticker set. On success, a @see StickerSet object is returned.
1189
     *
1190
     * More on https://core.telegram.org/bots/api#getstickerset
1191
     *
1192
     * @param string $name
1193
     * @param array|null $opt
1194
     * @return PromiseInterface
1195
     */
1196
    public function getStickerSet(string $name, ?array $opt = []): PromiseInterface
1197
    {
1198
        $required = compact("name");
1199
        $params = array_merge($required, $opt);
1200
        return $this->callApi("getStickerSet", $params, StickerSet::class);
1201
    }
1202
1203
    /**
1204
     * Use this method to upload a .PNG file with a sticker for later use in createNewStickerSet and addStickerToSet methods
1205
     * (can be used multiple times). Returns the uploaded @see File on success.
1206
     *
1207
     * More on https://core.telegram.org/bots/api#uploadstickerfile
1208
     *
1209
     * @param int $user_id
1210
     * @param $png_sticker
1211
     * @param array|null $opt
1212
     * @return PromiseInterface
1213
     */
1214
    public function uploadStickerFile(int $user_id, $png_sticker, ?array $opt = []): PromiseInterface
1215
    {
1216
        $required = compact("user_id", "png_sticker");
1217
        $params = array_merge($required, $opt);
1218
        return $this->callApi("uploadStickerFile", $params, File::class);
1219
    }
1220
1221
    /**
1222
     * Use this method to create a new sticker set owned by a user. The bot will be able to edit the sticker set thus
1223
     * created. You must use exactly one of the fields png_sticker or tgs_sticker. Returns True on success.
1224
     *
1225
     * The png_sticker param can be either a string or a @see InputFile. Note that if you use the latter the file reading
1226
     * operation is synchronous, so the main thread is blocked.
1227
     * To make it asynchronous see https://github.com/badfarm/zanzara/wiki#working-with-files.
1228
     *
1229
     * More on https://core.telegram.org/bots/api#createnewstickerset
1230
     *
1231
     * @param int $user_id
1232
     * @param string $name
1233
     * @param string $title
1234
     * @param string $emojis
1235
     * @param array|null $opt
1236
     * @return PromiseInterface
1237
     */
1238
    public function createNewStickerSet(int $user_id, string $name, string $title, string $emojis, ?array $opt = []): PromiseInterface
1239
    {
1240
        $required = compact("user_id", "name", "title", "emojis");
1241
        $params = array_merge($required, $opt);
1242
        return $this->callApi("createNewStickerSet", $params);
1243
    }
1244
1245
    /**
1246
     * Use this method to add a new sticker to a set created by the bot. You must use exactly one of the fields png_sticker
1247
     * or tgs_sticker. Animated stickers can be added to animated sticker sets and only to them. Animated sticker sets
1248
     * can have up to 50 stickers. Static sticker sets can have up to 120 stickers. Returns True on success.
1249
     *
1250
     * The png_sticker param can be either a string or a @see InputFile. Note that if you use the latter the file reading
1251
     * operation is synchronous, so the main thread is blocked.
1252
     * To make it asynchronous see https://github.com/badfarm/zanzara/wiki#working-with-files.
1253
     *
1254
     * More on https://core.telegram.org/bots/api#addstickertoset
1255
     *
1256
     * @param int $user_id
1257
     * @param string $name
1258
     * @param $png_sticker
1259
     * @param string $emojis
1260
     * @param array|null $opt
1261
     * @return PromiseInterface
1262
     */
1263
    public function addStickerToSet(int $user_id, string $name, $png_sticker, string $emojis, ?array $opt = []): PromiseInterface
1264
    {
1265
        $required = compact("user_id", "name", "png_sticker", "emojis");
1266
        $params = array_merge($required, $opt);
1267
        return $this->callApi("addStickerToSet", $params);
1268
    }
1269
1270
    /**
1271
     * Use this method to move a sticker in a set created by the bot to a specific position. Returns True on success.
1272
     *
1273
     * More on https://core.telegram.org/bots/api#setstickerpositioninset
1274
     *
1275
     * @param string $sticker
1276
     * @param int $position
1277
     * @param array|null $opt
1278
     * @return PromiseInterface
1279
     */
1280
    public function setStickerPositionInSet(string $sticker, int $position, ?array $opt = []): PromiseInterface
1281
    {
1282
        $required = compact("sticker", "position");
1283
        $params = array_merge($required, $opt);
1284
        return $this->callApi("setStickerPositionInSet", $params);
1285
    }
1286
1287
    /**
1288
     * Use this method to delete a sticker from a set created by the bot. Returns True on success.
1289
     *
1290
     * More on https://core.telegram.org/bots/api#deletestickerfromset
1291
     *
1292
     * @param string $sticker
1293
     * @param array|null $opt
1294
     * @return PromiseInterface
1295
     */
1296
    public function deleteStickerFromSet(string $sticker, ?array $opt = []): PromiseInterface
1297
    {
1298
        $required = compact("sticker");
1299
        $params = array_merge($required, $opt);
1300
        return $this->callApi("deleteStickerFromSet", $params);
1301
    }
1302
1303
    /**
1304
     * Use this method to set the thumbnail of a sticker set. Animated thumbnails can be set for animated sticker sets only.
1305
     * Returns True on success.
1306
     *
1307
     * The thumb param in $opt can be either a string or a @see InputFile. Note that if you use the latter the file reading
1308
     * operation is synchronous, so the main thread is blocked.
1309
     * To make it asynchronous see https://github.com/badfarm/zanzara/wiki#working-with-files.
1310
     *
1311
     * More on https://core.telegram.org/bots/api#setstickersetthumb
1312
     *
1313
     * @param string $name
1314
     * @param int $user_id
1315
     * @param array|null $opt
1316
     * @return PromiseInterface
1317
     */
1318
    public function setStickerSetThumb(string $name, int $user_id, ?array $opt = []): PromiseInterface
1319
    {
1320
        $required = compact("name", "user_id");
1321
        $params = array_merge($required, $opt);
1322
        return $this->callApi("setStickerSetThumb", $params);
1323
    }
1324
1325
    /**
1326
     * Use this method to send answers to an inline query. On success, True is returned.No more than 50 results per query
1327
     * are allowed.
1328
     *
1329
     * By default it replies to the inline_query_id of the context's update. Use $opt param to specify a different
1330
     * inline_query_id. Eg. $opt = ['inline_query_id' => 'abcdefgh'];
1331
     *
1332
     * More on https://core.telegram.org/bots/api#answerinlinequery
1333
     *
1334
     * @param $results
1335
     * @param array|null $opt
1336
     * @return PromiseInterface
1337
     */
1338
    public function answerInlineQuery($results, ?array $opt = []): PromiseInterface
1339
    {
1340
        if (!isset($opt['inline_query_id']) && $this->update) {
1341
            $opt['inline_query_id'] = $this->update->getInlineQuery()->getId();
1342
        }
1343
        $required = compact("results");
1344
        $params = array_merge($required, $opt);
1345
        return $this->callApi("answerInlineQuery", $params);
1346
    }
1347
1348
    /**
1349
     * Use this method to send invoices. On success, the sent @see Message is returned.
1350
     *
1351
     * By default the invoice is sent to the chat_id of the context's update. Use $opt param to specify a different
1352
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
1353
     *
1354
     * More on https://core.telegram.org/bots/api#sendinvoice
1355
     *
1356
     * @param string $title
1357
     * @param string $description
1358
     * @param string $payload
1359
     * @param string $provider_token
1360
     * @param string $start_parameter
1361
     * @param string $currency
1362
     * @param $prices
1363
     * @param array|null $opt
1364
     * @return PromiseInterface
1365
     */
1366
    public function sendInvoice(string $title, string $description, string $payload, string $provider_token, string $start_parameter, string $currency, $prices, ?array $opt = []): PromiseInterface
1367
    {
1368
        $opt = $this->resolveChatId($opt);
1369
        $required = compact("title", "description", "payload", "provider_token", "start_parameter", "currency", "prices");
1370
        $params = array_merge($required, $opt);
1371
        return $this->callApi("sendInvoice", $params, Message::class);
1372
    }
1373
1374
    /**
1375
     * @param array $params
1376
     * @return PromiseInterface
1377
     */
1378
    public function doSendInvoice(array $params): PromiseInterface
1379
    {
1380
        if (!isset($opt['chat_id']) && $this->update) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $opt seems to never exist and therefore isset should always be false.
Loading history...
1381
            $params['chat_id'] = $this->update->getEffectiveChat()->getId();
1382
        }
1383
        return $this->callApi("sendInvoice", $params, Message::class);
1384
    }
1385
1386
    /**
1387
     * If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, the Bot API will
1388
     * send an Update with a shipping_query field to the bot. Use this method to reply to shipping queries. On success,
1389
     * True is returned.
1390
     *
1391
     * By default it replies to the shipping_query_id of the context's update. Use $opt param to specify a different
1392
     * shipping_query_id. Eg. $opt = ['shipping_query_id' => 'abcdefgh'];
1393
     *
1394
     * More on https://core.telegram.org/bots/api#answershippingquery
1395
     *
1396
     * @param $ok
1397
     * @param array|null $opt
1398
     * @return PromiseInterface
1399
     */
1400
    public function answerShippingQuery($ok, ?array $opt = []): PromiseInterface
1401
    {
1402
        if (!isset($opt['shipping_query_id']) && $this->update) {
1403
            $opt['shipping_query_id'] = $this->update->getShippingQuery()->getId();
1404
        }
1405
        $required = compact("ok");
1406
        $params = array_merge($required, $opt);
1407
        return $this->callApi("answerShippingQuery", $params);
1408
    }
1409
1410
    /**
1411
     * Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation in the form
1412
     * of an Update with the field pre_checkout_query. Use this method to respond to such pre-checkout queries. On
1413
     * success, True is returned. Note: The Bot API must receive an answer within 10 seconds after the pre-checkout query
1414
     * was sent.
1415
     *
1416
     * By default it replies to the pre_checkout_query_id of the context's update. Use $opt param to specify a different
1417
     * pre_checkout_query_id. Eg. $opt = ['pre_checkout_query_id' => 'abcdefgh'];
1418
     *
1419
     * More on https://core.telegram.org/bots/api#answerprecheckoutquery
1420
     *
1421
     * @param $ok
1422
     * @param array|null $opt
1423
     * @return PromiseInterface
1424
     */
1425
    public function answerPreCheckoutQuery($ok, ?array $opt = []): PromiseInterface
1426
    {
1427
        if (!isset($opt['pre_checkout_query_id']) && $this->update) {
1428
            $opt['pre_checkout_query_id'] = $this->update->getPreCheckoutQuery()->getId();
1429
        }
1430
        $required = compact("ok");
1431
        $params = array_merge($required, $opt);
1432
        return $this->callApi("answerPreCheckoutQuery", $params);
1433
    }
1434
1435
    /**
1436
     * Informs a user that some of the Telegram Passport elements they provided contains errors. The user will not be able
1437
     * to re-submit their Passport to you until the errors are fixed (the contents of the field for which you returned
1438
     * the error must change). Returns True on success.
1439
     *
1440
     * More on https://core.telegram.org/bots/api#setpassportdataerrors
1441
     *
1442
     * @param int $user_id
1443
     * @param $errors
1444
     * @param array|null $opt
1445
     * @return PromiseInterface
1446
     */
1447
    public function setPassportDataErrors(int $user_id, $errors, ?array $opt = []): PromiseInterface
1448
    {
1449
        $required = compact("user_id", "errors");
1450
        $params = array_merge($required, $opt);
1451
        return $this->callApi("setPassportDataErrors", $params);
1452
    }
1453
1454
    /**
1455
     * Use this method to send a game. On success, the sent @see Message is returned.
1456
     *
1457
     * By default the game is sent to the chat_id of the context's update. Use $opt param to specify a different
1458
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
1459
     *
1460
     * More on https://core.telegram.org/bots/api#sendgame
1461
     *
1462
     * @param string $game_short_name
1463
     * @param array|null $opt
1464
     * @return PromiseInterface
1465
     */
1466
    public function sendGame(string $game_short_name, ?array $opt = []): PromiseInterface
1467
    {
1468
        $opt = $this->resolveChatId($opt);
1469
        $required = compact("game_short_name");
1470
        $params = array_merge($required, $opt);
1471
        return $this->callApi("sendGame", $params, Message::class);
1472
    }
1473
1474
    /**
1475
     * Use this method to set the score of the specified user in a game. On success, if the message was sent by the bot,
1476
     * returns the edited @see Message, otherwise returns True. Returns an error, if the new score is not greater than the
1477
     * user's current score in the chat and force is False.
1478
     *
1479
     * By default the chat_id is taken from the context's update. Use $opt param to specify a different
1480
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
1481
     *
1482
     * By default the message_id is taken from the context's update. Use $opt param to specify a different
1483
     * message_id. Eg. $opt = ['message_id' => 123456789];
1484
     *
1485
     * By default the inline_message_id is taken from the context's update. Use $opt param to specify a different
1486
     * inline_message_id. Eg. $opt = ['inline_message_id' => 123456789];
1487
     *
1488
     * More on https://core.telegram.org/bots/api#setgamescore
1489
     *
1490
     * @param int $user_id
1491
     * @param int $score
1492
     * @param array|null $opt
1493
     * @return PromiseInterface
1494
     */
1495
    public function setGameScore(int $user_id, int $score, ?array $opt = []): PromiseInterface
1496
    {
1497
        $opt = $this->resolveMessageId($opt);
1498
        $required = compact("user_id", "score");
1499
        $params = array_merge($required, $opt);
1500
        return $this->callApi("setGameScore", $params, Message::class);
1501
    }
1502
1503
    /**
1504
     * Use this method to get data for high score tables. Will return the score of the specified user and several of his
1505
     * neighbors in a game. On success, returns an Array of @see GameHighScore objects.
1506
     *
1507
     * By default the chat_id is taken from the context's update. Use $opt param to specify a different
1508
     * chat_id. Eg. $opt = ['chat_id' => 123456789];
1509
     *
1510
     * By default the message_id is taken from the context's update. Use $opt param to specify a different
1511
     * message_id. Eg. $opt = ['message_id' => 123456789];
1512
     *
1513
     * By default the inline_message_id is taken from the context's update. Use $opt param to specify a different
1514
     * inline_message_id. Eg. $opt = ['inline_message_id' => 123456789];
1515
     *
1516
     * More on https://core.telegram.org/bots/api#getgamehighscores
1517
     *
1518
     * @param int $user_id
1519
     * @param array|null $opt
1520
     * @return PromiseInterface
1521
     */
1522
    public function getGameHighScores(int $user_id, ?array $opt = []): PromiseInterface
1523
    {
1524
        $opt = $this->resolveMessageId($opt);
1525
        $required = compact("user_id");
1526
        $params = array_merge($required, $opt);
1527
        return $this->callApi("getGameHighScores", $params, GameHighScore::class);
1528
    }
1529
1530
    /**
1531
     * @param string $method
1532
     * @param array $params
1533
     * @param string $class
1534
     * @param string[] $headers
1535
     * @return PromiseInterface
1536
     */
1537
    public function callApi(string $method, array $params = [], string $class = 'Scalar', $headers = ["Content-type" => "application/json"])
1538
    {
1539
        if ($this->container->get(Config::class)->getParseMode() && !isset($params['parse_mode'])) {
1540
            $params['parse_mode'] = $this->container->get(Config::class)->getParseMode();
1541
        }
1542
        foreach ($params as $param) {
1543
            if ($param instanceof InputFile) {
1544
1545
                $async = $this->container->get(Config::class)->isReactFileSystem();
1546
1547
                if ($async) {
1548
                    return $this->prepareMultipartDataAsync($params)->then(function ($result) use ($method) {
1549
                        $headers = array("Content-Length" => $result->getSize(), "Content-Type" => "multipart/form-data; boundary={$result->getBoundary()}");
1550
                        return $this->browser->post($method, $headers, $result);
1551
                    });
1552
                } else {
1553
                    $multipart = $this->prepareMultipartData($params);
1554
                    $headers = array("Content-Length" => $multipart->getSize(), "Content-Type" => "multipart/form-data; boundary={$multipart->getBoundary()}");
1555
                    return $this->browser->post($method, $headers, $multipart);
1556
                }
1557
            }
1558
        }
1559
        return $this->wrapPromise($this->browser->post($method, $headers, json_encode($params)), $method, $params, $class);
1560
    }
1561
1562
    /**
1563
     *
1564
     * Create MultipartStream, iterate over params to find InputFile
1565
     *
1566
     * @param $params
1567
     * @return PromiseInterface
1568
     */
1569
    private function prepareMultipartDataAsync($params)
1570
    {
1571
        $filesystem = $this->container->get(Filesystem::class);
1572
        $multipart_data = [];
1573
        $promises = [];
1574
        foreach ($params as $key => $value) {
1575
1576
            if ($value instanceof InputFile) {
1577
                array_push($promises, $filesystem->getContents($value->getPath())->then(function ($contents) use ($value, $multipart_data, $key) {
0 ignored issues
show
Unused Code introduced by
The import $multipart_data is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
1578
                    $data = ['name' => $key];
1579
                    $data['contents'] = $contents;
1580
                    $data['filename'] = basename($value->getPath());
1581
                    return $data;
1582
                }, function ($error) {
1583
                    $this->container->get(ZanzaraLogger::class)->error($error);
1584
                    return $error;
1585
                }));
1586
1587
            } else {
1588
                $data = ['name' => $key];
1589
                $data['contents'] = strval($value);
1590
                array_push($multipart_data, $data);
1591
            }
1592
        }
1593
1594
        return all($promises)->then(function ($files) use ($multipart_data) {
1595
            foreach ($files as $key => $value) {
1596
                array_push($multipart_data, $value);
1597
            }
1598
            return new MultipartStream($multipart_data);
1599
        }, function ($error) {
1600
            $this->container->get(ZanzaraLogger::class)->error($error);
1601
            return $error;
1602
        });
1603
    }
1604
1605
    private function prepareMultipartData($params)
1606
    {
1607
        $multipart_data = [];
1608
        foreach ($params as $key => $value) {
1609
            $data = ['name' => $key];
1610
            if ($value instanceof InputFile) {
1611
                if (file_exists($value->getPath())) {
1612
                    $fileData = file_get_contents($value->getPath());
1613
                    $data['contents'] = $fileData;
1614
                    $data['filename'] = basename($value->getPath());
1615
                } else {
1616
                    $this->container->get(ZanzaraLogger::class)->error("File not found: {$value->getPath()}");
1617
                }
1618
1619
            } else {
1620
                $data['contents'] = strval($value);
1621
            }
1622
            array_push($multipart_data, $data);
1623
        }
1624
        return new MultipartStream($multipart_data);
1625
    }
1626
1627
    /**
1628
     * ZanzaraPromise class was removed since it swallowed the promise chain.
1629
     * We actually have to call the original promise, get the response and propagate the casted response along
1630
     * the promise chain.
1631
     * For the rejected promise, we have to cast the original exception to a TelegramException and rethrow it
1632
     * in order to let the user receive the exception in his onRejected function.
1633
     *
1634
     * Unfortunately, we don't have control on user's callback input parameter anymore. In this way the user
1635
     * needs to manage the otherwise() promise callback to see the error.
1636
     *
1637
     * @param PromiseInterface $promise
1638
     * @param string $method
1639
     * @param array $params
1640
     * @param string $class
1641
     * @return PromiseInterface
1642
     */
1643
    private function wrapPromise(PromiseInterface $promise, string $method, array $params = [], string $class = "Scalar"): PromiseInterface
1644
    {
1645
        $mapper = $this->container->get(ZanzaraMapper::class);
1646
        $logger = $this->container->get(ZanzaraLogger::class);
1647
1648
        return $promise
1649
            ->then(function (ResponseInterface $response) use ($class, $mapper) {
1650
                $json = (string)$response->getBody();
1651
                $object = json_decode($json);
1652
1653
                if (is_scalar($object->result) && $class === "Scalar") {
1654
                    return $object->result;
1655
                }
1656
1657
                return $mapper->mapObject($object->result, $class);
1658
            }, function ($e) use ($method, $params, $logger, $mapper) {
1659
                if ($e instanceof ResponseException) {
1660
                    $json = (string)$e->getResponse()->getBody();
1661
                    $e = $mapper->mapJson($json, TelegramException::class);
1662
                }
1663
                $logger->errorTelegramApi($method, $params, $e);
1664
                throw $e;
1665
            });
1666
    }
1667
1668
    /**
1669
     * @param array|null $opt
1670
     * @return array|null
1671
     */
1672
    public function resolveMessageId(?array $opt): ?array
1673
    {
1674
        // if the user doesn't provide inline_message_id, chat_id or message_id the framework tries to resolve them
1675
        // based on the Update's type
1676
        if ($this->update) {
1677
            if (!isset($opt['inline_message_id']) && !isset($opt['chat_id']) && !isset($opt['message_id'])) {
1678
                if ($this->update->getUpdateType() == CallbackQuery::class) {
0 ignored issues
show
Bug introduced by
The type Zanzara\Telegram\CallbackQuery was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1679
                    $cbQuery = $this->update->getCallbackQuery();
1680
                    if ($cbQuery->getInlineMessageId()) {
1681
                        $opt['inline_message_id'] = $cbQuery->getInlineMessageId();
1682
                    } else if ($cbQuery->getMessage()) {
1683
                        $opt['message_id'] = $cbQuery->getMessage()->getMessageId();
1684
                    }
1685
                }
1686
                // set chat_id only if inline_message_id wasn't set
1687
                if (!isset($opt['inline_message_id']) && $this->update->getEffectiveChat()) {
1688
                    $opt['chat_id'] = $this->update->getEffectiveChat()->getId();
1689
                }
1690
            }
1691
        }
1692
        return $opt;
1693
    }
1694
1695
    /**
1696
     * @param array|null $opt
1697
     * @return array|null
1698
     */
1699
    public function resolveChatId(?array $opt): ?array
1700
    {
1701
        if (!isset($opt['chat_id']) && $this->update) {
1702
            $opt['chat_id'] = $this->update->getEffectiveChat()->getId();
1703
        }
1704
        return $opt;
1705
    }
1706
1707
}