1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace TelegramBot\Api; |
4
|
|
|
|
5
|
|
|
use TelegramBot\Api\Types\ArrayOfUpdates; |
6
|
|
|
use TelegramBot\Api\Types\File; |
7
|
|
|
use TelegramBot\Api\Types\Message; |
8
|
|
|
use TelegramBot\Api\Types\Update; |
9
|
|
|
use TelegramBot\Api\Types\User; |
10
|
|
|
use TelegramBot\Api\Types\UserProfilePhotos; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Class BotApi |
14
|
|
|
* |
15
|
|
|
* @package TelegramBot\Api |
16
|
|
|
*/ |
17
|
|
|
class BotApi |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* HTTP codes |
21
|
|
|
* |
22
|
|
|
* @var array |
23
|
|
|
*/ |
24
|
|
|
public static $codes = [ |
25
|
|
|
// Informational 1xx |
26
|
|
|
100 => 'Continue', |
27
|
|
|
101 => 'Switching Protocols', |
28
|
|
|
102 => 'Processing', // RFC2518 |
29
|
|
|
// Success 2xx |
30
|
|
|
200 => 'OK', |
31
|
|
|
201 => 'Created', |
32
|
|
|
202 => 'Accepted', |
33
|
|
|
203 => 'Non-Authoritative Information', |
34
|
|
|
204 => 'No Content', |
35
|
|
|
205 => 'Reset Content', |
36
|
|
|
206 => 'Partial Content', |
37
|
|
|
207 => 'Multi-Status', // RFC4918 |
38
|
|
|
208 => 'Already Reported', // RFC5842 |
39
|
|
|
226 => 'IM Used', // RFC3229 |
40
|
|
|
// Redirection 3xx |
41
|
|
|
300 => 'Multiple Choices', |
42
|
|
|
301 => 'Moved Permanently', |
43
|
|
|
302 => 'Found', // 1.1 |
44
|
|
|
303 => 'See Other', |
45
|
|
|
304 => 'Not Modified', |
46
|
|
|
305 => 'Use Proxy', |
47
|
|
|
// 306 is deprecated but reserved |
48
|
|
|
307 => 'Temporary Redirect', |
49
|
|
|
308 => 'Permanent Redirect', // RFC7238 |
50
|
|
|
// Client Error 4xx |
51
|
|
|
400 => 'Bad Request', |
52
|
|
|
401 => 'Unauthorized', |
53
|
|
|
402 => 'Payment Required', |
54
|
|
|
403 => 'Forbidden', |
55
|
|
|
404 => 'Not Found', |
56
|
|
|
405 => 'Method Not Allowed', |
57
|
|
|
406 => 'Not Acceptable', |
58
|
|
|
407 => 'Proxy Authentication Required', |
59
|
|
|
408 => 'Request Timeout', |
60
|
|
|
409 => 'Conflict', |
61
|
|
|
410 => 'Gone', |
62
|
|
|
411 => 'Length Required', |
63
|
|
|
412 => 'Precondition Failed', |
64
|
|
|
413 => 'Payload Too Large', |
65
|
|
|
414 => 'URI Too Long', |
66
|
|
|
415 => 'Unsupported Media Type', |
67
|
|
|
416 => 'Range Not Satisfiable', |
68
|
|
|
417 => 'Expectation Failed', |
69
|
|
|
422 => 'Unprocessable Entity', // RFC4918 |
70
|
|
|
423 => 'Locked', // RFC4918 |
71
|
|
|
424 => 'Failed Dependency', // RFC4918 |
72
|
|
|
425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817 |
73
|
|
|
426 => 'Upgrade Required', // RFC2817 |
74
|
|
|
428 => 'Precondition Required', // RFC6585 |
75
|
|
|
429 => 'Too Many Requests', // RFC6585 |
76
|
|
|
431 => 'Request Header Fields Too Large', // RFC6585 |
77
|
|
|
// Server Error 5xx |
78
|
|
|
500 => 'Internal Server Error', |
79
|
|
|
501 => 'Not Implemented', |
80
|
|
|
502 => 'Bad Gateway', |
81
|
|
|
503 => 'Service Unavailable', |
82
|
|
|
504 => 'Gateway Timeout', |
83
|
|
|
505 => 'HTTP Version Not Supported', |
84
|
|
|
506 => 'Variant Also Negotiates (Experimental)', // RFC2295 |
85
|
|
|
507 => 'Insufficient Storage', // RFC4918 |
86
|
|
|
508 => 'Loop Detected', // RFC5842 |
87
|
|
|
510 => 'Not Extended', // RFC2774 |
88
|
|
|
511 => 'Network Authentication Required', // RFC6585 |
89
|
|
|
]; |
90
|
|
|
|
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Default http status code |
94
|
|
|
*/ |
95
|
|
|
const DEFAULT_STATUS_CODE = 200; |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* Not Modified http status code |
99
|
|
|
*/ |
100
|
|
|
const NOT_MODIFIED_STATUS_CODE = 304; |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Limits for tracked ids |
104
|
|
|
*/ |
105
|
|
|
const MAX_TRACKED_EVENTS = 200; |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Url prefixes |
109
|
|
|
*/ |
110
|
|
|
const URL_PREFIX = 'https://api.telegram.org/bot'; |
111
|
|
|
const FILE_URL_PREFIX = 'https://api.telegram.org/file/bot'; |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* CURL object |
115
|
|
|
* |
116
|
|
|
* @var |
117
|
|
|
*/ |
118
|
|
|
protected $curl; |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Bot token |
122
|
|
|
* |
123
|
|
|
* @var string |
124
|
|
|
*/ |
125
|
|
|
protected $token; |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* Botan tracker |
129
|
|
|
* |
130
|
|
|
* @var \TelegramBot\Api\Botan |
131
|
|
|
*/ |
132
|
|
|
protected $tracker; |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* list of event ids |
136
|
|
|
* |
137
|
|
|
* @var array |
138
|
|
|
*/ |
139
|
|
|
protected $trackedEvents = []; |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Check whether return associative array |
143
|
|
|
* |
144
|
|
|
* @var bool |
145
|
|
|
*/ |
146
|
|
|
protected $returnArray = true; |
147
|
|
|
|
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Constructor |
151
|
|
|
* |
152
|
|
|
* @param string $token Telegram Bot API token |
153
|
|
|
* @param string|null $trackerToken Yandex AppMetrica application api_key |
154
|
|
|
*/ |
155
|
9 |
|
public function __construct($token, $trackerToken = null) |
156
|
|
|
{ |
157
|
9 |
|
$this->curl = curl_init(); |
158
|
9 |
|
$this->token = $token; |
159
|
|
|
|
160
|
9 |
|
if ($trackerToken) { |
161
|
|
|
$this->tracker = new Botan($trackerToken); |
162
|
|
|
} |
163
|
9 |
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* Set return array |
167
|
|
|
* |
168
|
|
|
* @param bool $mode |
169
|
|
|
* |
170
|
|
|
* @return $this |
171
|
|
|
*/ |
172
|
|
|
public function setModeObject($mode = true) |
173
|
|
|
{ |
174
|
|
|
$this->returnArray = !$mode; |
175
|
|
|
|
176
|
|
|
return $this; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* Call method |
182
|
|
|
* |
183
|
|
|
* @param string $method |
184
|
|
|
* @param array|null $data |
185
|
|
|
* |
186
|
|
|
* @return mixed |
187
|
|
|
* @throws \TelegramBot\Api\Exception |
188
|
|
|
* @throws \TelegramBot\Api\HttpException |
189
|
|
|
* @throws \TelegramBot\Api\InvalidJsonException |
190
|
|
|
*/ |
191
|
|
|
public function call($method, array $data = null) |
192
|
|
|
{ |
193
|
|
|
$options = [ |
194
|
|
|
CURLOPT_URL => $this->getUrl() . '/' . $method, |
195
|
|
|
CURLOPT_RETURNTRANSFER => true, |
196
|
|
|
CURLOPT_POST => null, |
197
|
|
|
CURLOPT_POSTFIELDS => null |
198
|
|
|
]; |
199
|
|
|
|
200
|
|
|
if ($data) { |
201
|
|
|
$options[CURLOPT_POST] = true; |
202
|
|
|
$options[CURLOPT_POSTFIELDS] = http_build_query($data); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
$response = self::jsonValidate($this->executeCurl($options), $this->returnArray); |
206
|
|
|
|
207
|
|
|
if ($this->returnArray) { |
208
|
|
|
if (!isset($response['ok'])) { |
209
|
|
|
throw new Exception($response['description'], $response['error_code']); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
return $response['result']; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
if (!$response->ok) { |
216
|
|
|
throw new Exception($response->description, $response->error_code); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
return $response->result; |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* curl_exec wrapper for response validation |
224
|
|
|
* |
225
|
|
|
* @param array $options |
226
|
|
|
* |
227
|
|
|
* @return string |
228
|
|
|
* |
229
|
|
|
* @throws \TelegramBot\Api\HttpException |
230
|
|
|
*/ |
231
|
|
|
protected function executeCurl(array $options) |
232
|
|
|
{ |
233
|
|
|
curl_setopt_array($this->curl, $options); |
234
|
|
|
|
235
|
|
|
$result = curl_exec($this->curl); |
236
|
|
|
self::curlValidate($this->curl); |
237
|
|
|
|
238
|
|
|
return $result; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* Response validation |
243
|
|
|
* |
244
|
|
|
* @param resource $curl |
245
|
|
|
* |
246
|
|
|
* @throws \TelegramBot\Api\HttpException |
247
|
|
|
*/ |
248
|
|
|
public static function curlValidate($curl) |
249
|
|
|
{ |
250
|
|
|
if (($httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE)) |
251
|
|
|
&& !in_array($httpCode, [self::DEFAULT_STATUS_CODE, self::NOT_MODIFIED_STATUS_CODE]) |
252
|
|
|
) { |
253
|
|
|
throw new HttpException(self::$codes[$httpCode], $httpCode); |
254
|
|
|
} |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* JSON validation |
259
|
|
|
* |
260
|
|
|
* @param string $jsonString |
261
|
|
|
* @param boolean $asArray |
262
|
|
|
* |
263
|
|
|
* @return object|array |
264
|
|
|
* @throws \TelegramBot\Api\InvalidJsonException |
265
|
|
|
*/ |
266
|
|
|
public static function jsonValidate($jsonString, $asArray) |
267
|
|
|
{ |
268
|
|
|
$json = json_decode($jsonString, $asArray); |
269
|
|
|
|
270
|
|
|
if (json_last_error() != JSON_ERROR_NONE) { |
271
|
|
|
throw new InvalidJsonException(json_last_error_msg(), json_last_error()); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
return $json; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Use this method to send text messages. On success, the sent \TelegramBot\Api\Types\Message is returned. |
279
|
|
|
* |
280
|
|
|
* @param int|string $chatId |
281
|
|
|
* @param string $text |
282
|
|
|
* @param string|null $parseMode |
283
|
|
|
* @param bool $disablePreview |
284
|
|
|
* @param int|null $replyToMessageId |
285
|
|
|
* @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup |
286
|
|
|
* |
287
|
|
|
* @return \TelegramBot\Api\Types\Message |
288
|
|
|
* @throws \TelegramBot\Api\InvalidArgumentException |
289
|
|
|
* @throws \TelegramBot\Api\Exception |
290
|
|
|
*/ |
291
|
|
View Code Duplication |
public function sendMessage( |
|
|
|
|
292
|
|
|
$chatId, |
293
|
|
|
$text, |
294
|
|
|
$parseMode = null, |
295
|
|
|
$disablePreview = false, |
296
|
|
|
$replyToMessageId = null, |
297
|
|
|
$replyMarkup = null |
298
|
|
|
) { |
299
|
|
|
return Message::fromResponse($this->call('sendMessage', [ |
300
|
|
|
'chat_id' => $chatId, |
301
|
|
|
'text' => $text, |
302
|
|
|
'parse_mode' => $parseMode, |
303
|
|
|
'disable_web_page_preview' => $disablePreview, |
304
|
|
|
'reply_to_message_id' => (int) $replyToMessageId, |
305
|
|
|
'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson() |
306
|
|
|
])); |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
/** |
310
|
|
|
* Use this method when you need to tell the user that something is happening on the bot's side. |
311
|
|
|
* The status is set for 5 seconds or less (when a message arrives from your bot, |
312
|
|
|
* Telegram clients clear its typing status). |
313
|
|
|
* |
314
|
|
|
* We only recommend using this method when a response from the bot will take a noticeable amount of time to arrive. |
315
|
|
|
* |
316
|
|
|
* Type of action to broadcast. Choose one, depending on what the user is about to receive: |
317
|
|
|
* `typing` for text messages, `upload_photo` for photos, `record_video` or `upload_video` for videos, |
318
|
|
|
* `record_audio` or upload_audio for audio files, `upload_document` for general files, |
319
|
|
|
* `find_location` for location data. |
320
|
|
|
* |
321
|
|
|
* @param int $chatId |
322
|
|
|
* @param string $action |
323
|
|
|
* |
324
|
|
|
* @return bool |
325
|
|
|
* @throws \TelegramBot\Api\Exception |
326
|
|
|
*/ |
327
|
|
|
public function sendChatAction($chatId, $action) |
328
|
|
|
{ |
329
|
|
|
return $this->call('sendChatAction', [ |
330
|
|
|
'chat_id' => $chatId, |
331
|
|
|
'action' => $action |
332
|
|
|
]); |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
/** |
336
|
|
|
* Use this method to get a list of profile pictures for a user. |
337
|
|
|
* |
338
|
|
|
* @param int $userId |
339
|
|
|
* @param int $offset |
340
|
|
|
* @param int $limit |
341
|
|
|
* |
342
|
|
|
* @return \TelegramBot\Api\Types\UserProfilePhotos |
343
|
|
|
* @throws \TelegramBot\Api\Exception |
344
|
|
|
*/ |
345
|
|
|
public function getUserProfilePhotos($userId, $offset = 0, $limit = 100) |
346
|
|
|
{ |
347
|
|
|
return UserProfilePhotos::fromResponse($this->call('getUserProfilePhotos', [ |
348
|
|
|
'user_id' => (int) $userId, |
349
|
|
|
'offset' => (int) $offset, |
350
|
|
|
'limit' => (int) $limit, |
351
|
|
|
])); |
352
|
|
|
} |
353
|
|
|
|
354
|
|
|
/** |
355
|
|
|
* Use this method to specify a url and receive incoming updates via an outgoing webhook. |
356
|
|
|
* Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, |
357
|
|
|
* containing a JSON-serialized Update. |
358
|
|
|
* In case of an unsuccessful request, we will give up after a reasonable amount of attempts. |
359
|
|
|
* |
360
|
|
|
* @param string $url HTTPS url to send updates to. Use an empty string to remove webhook integration |
361
|
|
|
* @param \CURLFile|string $certificate Upload your public key certificate |
362
|
|
|
* so that the root certificate in use can be checked |
363
|
|
|
* |
364
|
|
|
* @return string |
365
|
|
|
* |
366
|
|
|
* @throws \TelegramBot\Api\Exception |
367
|
|
|
*/ |
368
|
|
|
public function setWebhook($url = '', $certificate = null) |
369
|
|
|
{ |
370
|
|
|
return $this->call('setWebhook', ['url' => $url, 'certificate' => $certificate]); |
371
|
|
|
} |
372
|
|
|
|
373
|
|
|
/** |
374
|
|
|
* A simple method for testing your bot's auth token.Requires no parameters. |
375
|
|
|
* Returns basic information about the bot in form of a User object. |
376
|
|
|
* |
377
|
|
|
* @return \TelegramBot\Api\Types\User |
378
|
|
|
* @throws \TelegramBot\Api\Exception |
379
|
|
|
* @throws \TelegramBot\Api\InvalidArgumentException |
380
|
|
|
*/ |
381
|
|
|
public function getMe() |
382
|
|
|
{ |
383
|
|
|
return User::fromResponse($this->call('getMe')); |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
/** |
387
|
|
|
* Use this method to receive incoming updates using long polling. |
388
|
|
|
* An Array of Update objects is returned. |
389
|
|
|
* |
390
|
|
|
* Notes |
391
|
|
|
* 1. This method will not work if an outgoing webhook is set up. |
392
|
|
|
* 2. In order to avoid getting duplicate updates, recalculate offset after each server response. |
393
|
|
|
* |
394
|
|
|
* @param int $offset |
395
|
|
|
* @param int $limit |
396
|
|
|
* @param int $timeout |
397
|
|
|
* |
398
|
|
|
* @return Update[] |
399
|
|
|
* @throws \TelegramBot\Api\Exception |
400
|
|
|
* @throws \TelegramBot\Api\InvalidArgumentException |
401
|
|
|
*/ |
402
|
2 |
|
public function getUpdates($offset = 0, $limit = 100, $timeout = 0) |
403
|
|
|
{ |
404
|
2 |
|
$updates = ArrayOfUpdates::fromResponse($this->call('getUpdates', [ |
405
|
2 |
|
'offset' => $offset, |
406
|
2 |
|
'limit' => $limit, |
407
|
|
|
'timeout' => $timeout |
408
|
2 |
|
])); |
409
|
|
|
|
410
|
2 |
|
if ($this->tracker instanceof Botan) { |
411
|
|
|
foreach ($updates as $update) { |
412
|
|
|
$this->trackUpdate($update); |
413
|
|
|
} |
414
|
|
|
} |
415
|
|
|
|
416
|
2 |
|
return $updates; |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
/** |
420
|
|
|
* Use this method to send point on the map. On success, the sent Message is returned. |
421
|
|
|
* |
422
|
|
|
* @param int $chatId |
423
|
|
|
* @param float $latitude |
424
|
|
|
* @param float $longitude |
425
|
|
|
* @param int|null $replyToMessageId |
426
|
|
|
* @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup |
427
|
|
|
* |
428
|
|
|
* @return \TelegramBot\Api\Types\Message |
429
|
|
|
* @throws \TelegramBot\Api\Exception |
430
|
|
|
*/ |
431
|
|
|
public function sendLocation($chatId, $latitude, $longitude, $replyToMessageId = null, $replyMarkup = null) |
432
|
|
|
{ |
433
|
|
|
return Message::fromResponse($this->call('sendLocation', [ |
434
|
|
|
'chat_id' => $chatId, |
435
|
|
|
'latitude' => $latitude, |
436
|
|
|
'longitude' => $longitude, |
437
|
|
|
'reply_to_message_id' => $replyToMessageId, |
438
|
|
|
'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson() |
439
|
|
|
])); |
440
|
|
|
} |
441
|
|
|
|
442
|
|
|
/** |
443
|
|
|
* Use this method to send .webp stickers. On success, the sent Message is returned. |
444
|
|
|
* |
445
|
|
|
* @param int $chatId |
446
|
|
|
* @param \CURLFile|string $sticker |
447
|
|
|
* @param int|null $replyToMessageId |
448
|
|
|
* @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup |
449
|
|
|
* |
450
|
|
|
* @return \TelegramBot\Api\Types\Message |
451
|
|
|
* @throws \TelegramBot\Api\InvalidArgumentException |
452
|
|
|
* @throws \TelegramBot\Api\Exception |
453
|
|
|
*/ |
454
|
|
|
public function sendSticker($chatId, $sticker, $replyToMessageId = null, $replyMarkup = null) |
455
|
|
|
{ |
456
|
|
|
return Message::fromResponse($this->call('sendSticker', [ |
457
|
|
|
'chat_id' => $chatId, |
458
|
|
|
'sticker' => $sticker, |
459
|
|
|
'reply_to_message_id' => $replyToMessageId, |
460
|
|
|
'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson() |
461
|
|
|
])); |
462
|
|
|
} |
463
|
|
|
|
464
|
|
|
/** |
465
|
|
|
* Use this method to send video files, |
466
|
|
|
* Telegram clients support mp4 videos (other formats may be sent as Document). |
467
|
|
|
* On success, the sent Message is returned. |
468
|
|
|
* |
469
|
|
|
* @param int $chatId |
470
|
|
|
* @param \CURLFile|string $video |
471
|
|
|
* @param int|null $duration |
472
|
|
|
* @param string|null $caption |
473
|
|
|
* @param int|null $replyToMessageId |
474
|
|
|
* @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup |
475
|
|
|
* |
476
|
|
|
* @return \TelegramBot\Api\Types\Message |
477
|
|
|
* @throws \TelegramBot\Api\InvalidArgumentException |
478
|
|
|
* @throws \TelegramBot\Api\Exception |
479
|
|
|
*/ |
480
|
|
View Code Duplication |
public function sendVideo( |
|
|
|
|
481
|
|
|
$chatId, |
482
|
|
|
$video, |
483
|
|
|
$duration = null, |
484
|
|
|
$caption = null, |
485
|
|
|
$replyToMessageId = null, |
486
|
|
|
$replyMarkup = null |
487
|
|
|
) { |
488
|
|
|
return Message::fromResponse($this->call('sendVideo', [ |
489
|
|
|
'chat_id' => $chatId, |
490
|
|
|
'video' => $video, |
491
|
|
|
'duration' => $duration, |
492
|
|
|
'caption' => $caption, |
493
|
|
|
'reply_to_message_id' => $replyToMessageId, |
494
|
|
|
'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson() |
495
|
|
|
])); |
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
/** |
499
|
|
|
* Use this method to send audio files, |
500
|
|
|
* if you want Telegram clients to display the file as a playable voice message. |
501
|
|
|
* For this to work, your audio must be in an .ogg file encoded with OPUS |
502
|
|
|
* (other formats may be sent as Audio or Document). |
503
|
|
|
* On success, the sent Message is returned. |
504
|
|
|
* Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future. |
505
|
|
|
* |
506
|
|
|
* @param int $chatId |
507
|
|
|
* @param \CURLFile|string $voice |
508
|
|
|
* @param int|null $duration |
509
|
|
|
* @param int|null $replyToMessageId |
510
|
|
|
* @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup |
511
|
|
|
* |
512
|
|
|
* @return \TelegramBot\Api\Types\Message |
513
|
|
|
* @throws \TelegramBot\Api\InvalidArgumentException |
514
|
|
|
* @throws \TelegramBot\Api\Exception |
515
|
|
|
*/ |
516
|
|
View Code Duplication |
public function sendVoice($chatId, $voice, $duration = null, $replyToMessageId = null, $replyMarkup = null) |
517
|
|
|
{ |
518
|
|
|
return Message::fromResponse($this->call('sendVoice', [ |
519
|
|
|
'chat_id' => $chatId, |
520
|
|
|
'voice' => $voice, |
521
|
|
|
'duration' => $duration, |
522
|
|
|
'reply_to_message_id' => $replyToMessageId, |
523
|
|
|
'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson() |
524
|
|
|
])); |
525
|
|
|
} |
526
|
|
|
|
527
|
|
|
/** |
528
|
|
|
* Use this method to forward messages of any kind. On success, the sent Message is returned. |
529
|
|
|
* |
530
|
|
|
* @param int $chatId |
531
|
|
|
* @param int $fromChatId |
532
|
|
|
* @param int $messageId |
533
|
|
|
* |
534
|
|
|
* @return \TelegramBot\Api\Types\Message |
535
|
|
|
* @throws \TelegramBot\Api\InvalidArgumentException |
536
|
|
|
* @throws \TelegramBot\Api\Exception |
537
|
|
|
*/ |
538
|
|
|
public function forwardMessage($chatId, $fromChatId, $messageId) |
539
|
|
|
{ |
540
|
|
|
return Message::fromResponse($this->call('forwardMessage', [ |
541
|
|
|
'chat_id' => $chatId, |
542
|
|
|
'from_chat_id' => $fromChatId, |
543
|
|
|
'message_id' => (int) $messageId, |
544
|
|
|
])); |
545
|
|
|
} |
546
|
|
|
|
547
|
|
|
/** |
548
|
|
|
* Use this method to send audio files, |
549
|
|
|
* if you want Telegram clients to display them in the music player. |
550
|
|
|
* Your audio must be in the .mp3 format. |
551
|
|
|
* On success, the sent Message is returned. |
552
|
|
|
* Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future. |
553
|
|
|
* |
554
|
|
|
* For backward compatibility, when the fields title and performer are both empty |
555
|
|
|
* and the mime-type of the file to be sent is not audio/mpeg, the file will be sent as a playable voice message. |
556
|
|
|
* For this to work, the audio must be in an .ogg file encoded with OPUS. |
557
|
|
|
* This behavior will be phased out in the future. For sending voice messages, use the sendVoice method instead. |
558
|
|
|
* |
559
|
|
|
* @param int $chatId |
560
|
|
|
* @param \CURLFile|string $audio |
561
|
|
|
* @param int|null $duration |
562
|
|
|
* @param string|null $performer |
563
|
|
|
* @param string|null $title |
564
|
|
|
* @param int|null $replyToMessageId |
565
|
|
|
* @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup |
566
|
|
|
* |
567
|
|
|
* @return \TelegramBot\Api\Types\Message |
568
|
|
|
* @throws \TelegramBot\Api\InvalidArgumentException |
569
|
|
|
* @throws \TelegramBot\Api\Exception |
570
|
|
|
*/ |
571
|
|
View Code Duplication |
public function sendAudio( |
|
|
|
|
572
|
|
|
$chatId, |
573
|
|
|
$audio, |
574
|
|
|
$duration = null, |
575
|
|
|
$performer = null, |
576
|
|
|
$title = null, |
577
|
|
|
$replyToMessageId = null, |
578
|
|
|
$replyMarkup = null |
579
|
|
|
) { |
580
|
|
|
return Message::fromResponse($this->call('sendAudio', [ |
581
|
|
|
'chat_id' => $chatId, |
582
|
|
|
'audio' => $audio, |
583
|
|
|
'duration' => $duration, |
584
|
|
|
'performer' => $performer, |
585
|
|
|
'title' => $title, |
586
|
|
|
'reply_to_message_id' => $replyToMessageId, |
587
|
|
|
'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson() |
588
|
|
|
])); |
589
|
|
|
} |
590
|
|
|
|
591
|
|
|
/** |
592
|
|
|
* Use this method to send photos. On success, the sent Message is returned. |
593
|
|
|
* |
594
|
|
|
* @param int $chatId |
595
|
|
|
* @param \CURLFile|string $photo |
596
|
|
|
* @param string|null $caption |
597
|
|
|
* @param int|null $replyToMessageId |
598
|
|
|
* @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup |
599
|
|
|
* |
600
|
|
|
* @return \TelegramBot\Api\Types\Message |
601
|
|
|
* @throws \TelegramBot\Api\InvalidArgumentException |
602
|
|
|
* @throws \TelegramBot\Api\Exception |
603
|
|
|
*/ |
604
|
|
View Code Duplication |
public function sendPhoto($chatId, $photo, $caption = null, $replyToMessageId = null, $replyMarkup = null) |
605
|
|
|
{ |
606
|
|
|
return Message::fromResponse($this->call('sendPhoto', [ |
607
|
|
|
'chat_id' => $chatId, |
608
|
|
|
'photo' => $photo, |
609
|
|
|
'caption' => $caption, |
610
|
|
|
'reply_to_message_id' => $replyToMessageId, |
611
|
|
|
'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson() |
612
|
|
|
])); |
613
|
|
|
} |
614
|
|
|
|
615
|
|
|
/** |
616
|
|
|
* Use this method to send general files. On success, the sent Message is returned. |
617
|
|
|
* Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future. |
618
|
|
|
* |
619
|
|
|
* @param int $chatId |
620
|
|
|
* @param \CURLFile|string $document |
621
|
|
|
* @param int|null $replyToMessageId |
622
|
|
|
* @param Types\ReplyKeyboardMarkup|Types\ReplyKeyboardHide|Types\ForceReply|null $replyMarkup |
623
|
|
|
* |
624
|
|
|
* @return \TelegramBot\Api\Types\Message |
625
|
|
|
* @throws \TelegramBot\Api\InvalidArgumentException |
626
|
|
|
* @throws \TelegramBot\Api\Exception |
627
|
|
|
*/ |
628
|
|
|
public function sendDocument($chatId, $document, $replyToMessageId = null, $replyMarkup = null) |
629
|
|
|
{ |
630
|
|
|
return Message::fromResponse($this->call('sendDocument', [ |
631
|
|
|
'chat_id' => $chatId, |
632
|
|
|
'document' => $document, |
633
|
|
|
'reply_to_message_id' => $replyToMessageId, |
634
|
|
|
'reply_markup' => is_null($replyMarkup) ? $replyMarkup : $replyMarkup->toJson() |
635
|
|
|
])); |
636
|
|
|
} |
637
|
|
|
|
638
|
|
|
/** |
639
|
|
|
* Use this method to get basic info about a file and prepare it for downloading. |
640
|
|
|
* For the moment, bots can download files of up to 20MB in size. |
641
|
|
|
* On success, a File object is returned. |
642
|
|
|
* The file can then be downloaded via the link https://api.telegram.org/file/bot<token>/<file_path>, |
643
|
|
|
* where <file_path> is taken from the response. |
644
|
|
|
* It is guaranteed that the link will be valid for at least 1 hour. |
645
|
|
|
* When the link expires, a new one can be requested by calling getFile again. |
646
|
|
|
* |
647
|
|
|
* @param $fileId |
648
|
|
|
* |
649
|
|
|
* @return \TelegramBot\Api\Types\File |
650
|
|
|
* @throws \TelegramBot\Api\InvalidArgumentException |
651
|
|
|
* @throws \TelegramBot\Api\Exception |
652
|
|
|
*/ |
653
|
|
|
public function getFile($fileId) |
654
|
|
|
{ |
655
|
|
|
return File::fromResponse($this->call('getFile', ['file_id' => $fileId])); |
656
|
|
|
} |
657
|
|
|
|
658
|
|
|
/** |
659
|
|
|
* Get file contents via cURL |
660
|
|
|
* |
661
|
|
|
* @param $fileId |
662
|
|
|
* |
663
|
|
|
* @return string |
664
|
|
|
* |
665
|
|
|
* @throws \TelegramBot\Api\HttpException |
666
|
|
|
*/ |
667
|
|
|
public function downloadFile($fileId) |
668
|
|
|
{ |
669
|
|
|
$file = $this->getFile($fileId); |
670
|
|
|
$options = [ |
671
|
|
|
CURLOPT_HEADER => 0, |
672
|
|
|
CURLOPT_HTTPGET => 1, |
673
|
|
|
CURLOPT_RETURNTRANSFER => 1, |
674
|
|
|
CURLOPT_URL => $this->getFileUrl() . '/' . $file->getFilePath() |
675
|
|
|
]; |
676
|
|
|
|
677
|
|
|
return $this->executeCurl($options); |
678
|
|
|
} |
679
|
|
|
|
680
|
|
|
/** |
681
|
|
|
* Use this method to send answers to an inline query. On success, True is returned. |
682
|
|
|
* No more than 50 results per query are allowed. |
683
|
|
|
* |
684
|
|
|
* @param string $inlineQueryId |
685
|
|
|
* @param \TelegramBot\Api\Types\Inline\AbstractInlineQueryResult[] $results |
686
|
|
|
* @param int $cacheTime |
687
|
|
|
* @param bool $isPersonal |
688
|
|
|
* @param string $nextOffset |
689
|
|
|
* |
690
|
|
|
* @return mixed |
691
|
|
|
* @throws Exception |
692
|
|
|
*/ |
693
|
|
|
public function answerInlineQuery($inlineQueryId, $results, $cacheTime = 300, $isPersonal = false, $nextOffset = '') |
694
|
|
|
{ |
695
|
|
|
$results = array_map(function ($item) { |
696
|
|
|
/* @var \TelegramBot\Api\Types\Inline\AbstractInlineQueryResult $item */ |
697
|
|
|
|
698
|
|
|
return json_decode($item->toJson(), true); |
699
|
|
|
}, $results); |
700
|
|
|
|
701
|
|
|
return $this->call('answerInlineQuery', [ |
702
|
|
|
'inline_query_id' => $inlineQueryId, |
703
|
|
|
'results' => json_encode($results), |
704
|
|
|
'cache_time' => $cacheTime, |
705
|
|
|
'is_personal' => $isPersonal, |
706
|
|
|
'next_offset' => $nextOffset, |
707
|
|
|
]); |
708
|
|
|
} |
709
|
|
|
|
710
|
|
|
/** |
711
|
|
|
* Close curl |
712
|
|
|
*/ |
713
|
9 |
|
public function __destruct() |
714
|
|
|
{ |
715
|
9 |
|
$this->curl && curl_close($this->curl); |
716
|
9 |
|
} |
717
|
|
|
|
718
|
|
|
/** |
719
|
|
|
* @return string |
720
|
|
|
*/ |
721
|
|
|
public function getUrl() |
722
|
|
|
{ |
723
|
|
|
return self::URL_PREFIX . $this->token; |
724
|
|
|
} |
725
|
|
|
|
726
|
|
|
/** |
727
|
|
|
* @return string |
728
|
|
|
*/ |
729
|
|
|
public function getFileUrl() |
730
|
|
|
{ |
731
|
|
|
return self::FILE_URL_PREFIX . $this->token; |
732
|
|
|
} |
733
|
|
|
|
734
|
|
|
/** |
735
|
|
|
* @param \TelegramBot\Api\Types\Update $update |
736
|
|
|
* @param string $eventName |
737
|
|
|
* |
738
|
|
|
* @throws \TelegramBot\Api\Exception |
739
|
|
|
*/ |
740
|
|
|
public function trackUpdate(Update $update, $eventName = 'Message') |
741
|
|
|
{ |
742
|
|
|
if (!in_array($update->getUpdateId(), $this->trackedEvents)) { |
743
|
|
|
$this->trackedEvents[] = $update->getUpdateId(); |
744
|
|
|
|
745
|
|
|
$this->track($update->getMessage(), $eventName); |
746
|
|
|
|
747
|
|
|
if (count($this->trackedEvents) > self::MAX_TRACKED_EVENTS) { |
748
|
|
|
$this->trackedEvents = array_slice($this->trackedEvents, round(self::MAX_TRACKED_EVENTS / 4)); |
749
|
|
|
} |
750
|
|
|
} |
751
|
|
|
} |
752
|
|
|
|
753
|
|
|
/** |
754
|
|
|
* Wrapper for tracker |
755
|
|
|
* |
756
|
|
|
* @param \TelegramBot\Api\Types\Message $message |
757
|
|
|
* @param string $eventName |
758
|
|
|
* |
759
|
|
|
* @throws \TelegramBot\Api\Exception |
760
|
|
|
*/ |
761
|
|
|
public function track(Message $message, $eventName = 'Message') |
762
|
|
|
{ |
763
|
|
|
if ($this->tracker instanceof Botan) { |
764
|
|
|
$this->tracker->track($message, $eventName); |
765
|
|
|
} |
766
|
|
|
} |
767
|
|
|
} |
768
|
|
|
|
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.