Skip to content

Commit cb9868e

Browse files
authored
Merge pull request #1202 from noplanman/1201-allowed_updates-for-getupdates
Allow defining update types when handling updates via `getUpdates` method
2 parents ce8452e + 656f9e7 commit cb9868e

File tree

4 files changed

+119
-52
lines changed

4 files changed

+119
-52
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ Exclamation symbols (:exclamation:) note something of importance e.g. breaking c
1010
- Bot API 5.1 (ChatMember Update types, Improved Invite Links, Voice Chat). (@massadm, @noplanman)
1111
### Changed
1212
### Deprecated
13+
- `Telegram::handleGetUpdates` method should be passed a `$data` array for parameters.
1314
### Removed
1415
### Fixed
1516
- `message.edit_date` is now of type `timestamp`.
17+
- Allow all update types by default when using `getUpdates` method.
1618
### Security
1719

1820
## [0.71.0] - 2021-03-05

README.md

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
A Telegram Bot based on the official [Telegram Bot API]
99

10-
[![API Version](https://img.shields.io/badge/Bot%20API-5.1%20%28March%202021%29-32a2da.svg)](https://core.telegram.org/bots/api#november-4-2020)
10+
[![API Version](https://img.shields.io/badge/Bot%20API-5.1%20%28March%202021%29-32a2da.svg)](https://core.telegram.org/bots/api#march-9-2021)
1111
[![Join the bot support group on Telegram](https://img.shields.io/badge/telegram-@PHP__Telegram__Bot__Support-64659d.svg)](https://telegram.me/PHP_Telegram_Bot_Support)
1212
[![Donate](https://img.shields.io/badge/%F0%9F%92%99-Donate%20%2F%20Support%20Us-blue.svg)](#donate)
1313

@@ -33,6 +33,7 @@ A Telegram Bot based on the official [Telegram Bot API]
3333
- [Unset Webhook](#unset-webhook)
3434
- [getUpdates installation](#getupdates-installation)
3535
- [getUpdates without database](#getupdates-without-database)
36+
- [Filter Update](#filter-update)
3637
- [Support](#support)
3738
- [Types](#types)
3839
- [Inline Query](#inline-query)
@@ -43,7 +44,6 @@ A Telegram Bot based on the official [Telegram Bot API]
4344
- [getUserProfilePhoto](#getuserprofilephoto)
4445
- [getFile and downloadFile](#getfile-and-downloadfile)
4546
- [Send message to all active chats](#send-message-to-all-active-chats)
46-
- [Filter Update](#filter-update)
4747
- [Utils](#utils)
4848
- [MySQL storage (Recommended)](#mysql-storage-recommended)
4949
- [External Database connection](#external-database-connection)
@@ -339,6 +339,52 @@ If you choose to / or are obliged to use the `getUpdates` method without a datab
339339
$telegram->useGetUpdatesWithoutDatabase();
340340
```
341341

342+
## Filter Update
343+
344+
:exclamation: Note that by default, Telegram will send any new update types that may be added in the future. This may cause commands that don't take this into account to break!
345+
346+
It is suggested that you specifically define which update types your bot can receive and handle correctly.
347+
348+
You can define which update types are sent to your bot by defining them when setting the [webhook](#webhook-installation) or passing an array of allowed types when using [getUpdates](#getupdates-installation).
349+
350+
```php
351+
use Longman\TelegramBot\Entities\Update;
352+
353+
// For all update types currently implemented in this library:
354+
// $allowed_updates = Update::getUpdateTypes();
355+
356+
// Define the list of allowed Update types manually:
357+
$allowed_updates = [
358+
Update::TYPE_MESSAGE,
359+
Update::TYPE_CHANNEL_POST,
360+
// etc.
361+
];
362+
363+
// When setting the webhook.
364+
$telegram->setWebhook($hook_url, ['allowed_updates' => $allowed_updates]);
365+
366+
// When handling the getUpdates method.
367+
$telegram->handleGetUpdates(['allowed_updates' => $allowed_updates]);
368+
```
369+
370+
Alternatively, Update processing can be allowed or denied by defining a custom update filter.
371+
372+
Let's say we only want to allow messages from a user with ID `428`, we can do the following before handling the request:
373+
374+
```php
375+
$telegram->setUpdateFilter(function (Update $update, Telegram $telegram, &$reason = 'Update denied by update_filter') {
376+
$user_id = $update->getMessage()->getFrom()->getId();
377+
if ($user_id === 428) {
378+
return true;
379+
}
380+
381+
$reason = "Invalid user with ID {$user_id}";
382+
return false;
383+
});
384+
```
385+
386+
The reason for denying an update can be defined with the `$reason` parameter. This text gets written to the debug log.
387+
342388
## Support
343389

344390
### Types
@@ -433,26 +479,6 @@ $results = Request::sendToActiveChats(
433479

434480
You can also broadcast a message to users, from the private chat with your bot. Take a look at the [admin commands](#admin-commands) below.
435481

436-
#### Filter Update
437-
438-
Update processing can be allowed or denied by defining a custom update filter.
439-
440-
Let's say we only want to allow messages from a user with ID 428, we can do the following before handling the request:
441-
442-
```php
443-
$telegram->setUpdateFilter(function (Update $update, Telegram $telegram, &$reason = 'Update denied by update_filter') {
444-
$user_id = $update->getMessage()->getFrom()->getId();
445-
if ($user_id === 428) {
446-
return true;
447-
}
448-
449-
$reason = "Invalid user with ID {$user_id}";
450-
return false;
451-
});
452-
```
453-
454-
The reason for denying an update can be defined with the `$reason` parameter. This text gets written to the debug log.
455-
456482
## Utils
457483

458484
### MySQL storage (Recommended)

src/Entities/Update.php

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,37 +36,60 @@
3636
*/
3737
class Update extends Entity
3838
{
39+
public const TYPE_MESSAGE = 'message';
40+
public const TYPE_EDITED_MESSAGE = 'edited_message';
41+
public const TYPE_CHANNEL_POST = 'channel_post';
42+
public const TYPE_EDITED_CHANNEL_POST = 'edited_channel_post';
43+
public const TYPE_INLINE_QUERY = 'inline_query';
44+
public const TYPE_CHOSEN_INLINE_RESULT = 'chosen_inline_result';
45+
public const TYPE_CALLBACK_QUERY = 'callback_query';
46+
public const TYPE_SHIPPING_QUERY = 'shipping_query';
47+
public const TYPE_PRE_CHECKOUT_QUERY = 'pre_checkout_query';
48+
public const TYPE_POLL = 'poll';
49+
public const TYPE_POLL_ANSWER = 'poll_answer';
50+
public const TYPE_MY_CHAT_MEMBER = 'my_chat_member';
51+
public const TYPE_CHAT_MEMBER = 'chat_member';
52+
3953
/**
4054
* {@inheritdoc}
4155
*/
4256
protected function subEntities(): array
4357
{
4458
return [
45-
'message' => Message::class,
46-
'edited_message' => EditedMessage::class,
47-
'channel_post' => ChannelPost::class,
48-
'edited_channel_post' => EditedChannelPost::class,
49-
'inline_query' => InlineQuery::class,
50-
'chosen_inline_result' => ChosenInlineResult::class,
51-
'callback_query' => CallbackQuery::class,
52-
'shipping_query' => ShippingQuery::class,
53-
'pre_checkout_query' => PreCheckoutQuery::class,
54-
'poll' => Poll::class,
55-
'poll_answer' => PollAnswer::class,
56-
'my_chat_member' => ChatMemberUpdated::class,
57-
'chat_member' => ChatMemberUpdated::class,
59+
self::TYPE_MESSAGE => Message::class,
60+
self::TYPE_EDITED_MESSAGE => EditedMessage::class,
61+
self::TYPE_CHANNEL_POST => ChannelPost::class,
62+
self::TYPE_EDITED_CHANNEL_POST => EditedChannelPost::class,
63+
self::TYPE_INLINE_QUERY => InlineQuery::class,
64+
self::TYPE_CHOSEN_INLINE_RESULT => ChosenInlineResult::class,
65+
self::TYPE_CALLBACK_QUERY => CallbackQuery::class,
66+
self::TYPE_SHIPPING_QUERY => ShippingQuery::class,
67+
self::TYPE_PRE_CHECKOUT_QUERY => PreCheckoutQuery::class,
68+
self::TYPE_POLL => Poll::class,
69+
self::TYPE_POLL_ANSWER => PollAnswer::class,
70+
self::TYPE_MY_CHAT_MEMBER => ChatMemberUpdated::class,
71+
self::TYPE_CHAT_MEMBER => ChatMemberUpdated::class,
5872
];
5973
}
6074

75+
/**
76+
* Get the list of all available update types
77+
*
78+
* @return string[]
79+
*/
80+
public static function getUpdateTypes(): array
81+
{
82+
return array_keys((new self([]))->subEntities());
83+
}
84+
6185
/**
6286
* Get the update type based on the set properties
6387
*
6488
* @return string|null
6589
*/
6690
public function getUpdateType(): ?string
6791
{
68-
$types = array_keys($this->subEntities());
69-
foreach ($types as $type) {
92+
foreach (self::getUpdateTypes() as $type) {
7093
if ($this->getProperty($type)) {
7194
return $type;
7295
}

src/Telegram.php

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -391,13 +391,15 @@ public function getLastCommandResponse(): ServerResponse
391391
/**
392392
* Handle getUpdates method
393393
*
394-
* @param int|null $limit
395-
* @param int|null $timeout
394+
* @todo Remove backwards compatibility for old signature and force $data to be an array.
395+
*
396+
* @param array|int|null $data
397+
* @param int|null $timeout
396398
*
397399
* @return ServerResponse
398400
* @throws TelegramException
399401
*/
400-
public function handleGetUpdates(?int $limit = null, ?int $timeout = null): ServerResponse
402+
public function handleGetUpdates($data = null, ?int $timeout = null): ServerResponse
401403
{
402404
if (empty($this->bot_username)) {
403405
throw new TelegramException('Bot Username is not defined!');
@@ -414,8 +416,27 @@ public function handleGetUpdates(?int $limit = null, ?int $timeout = null): Serv
414416
}
415417

416418
$offset = 0;
419+
$limit = null;
420+
421+
// By default, get update types sent by Telegram.
422+
$allowed_updates = [];
423+
424+
// @todo Backwards compatibility for old signature, remove in next version.
425+
if (!is_array($data)) {
426+
$limit = $data;
417427

418-
//Take custom input into account.
428+
@trigger_error(
429+
sprintf('Use of $limit and $timeout parameters in %s is deprecated. Use $data array instead.', __METHOD__),
430+
E_USER_DEPRECATED
431+
);
432+
} else {
433+
$offset = $data['offset'] ?? $offset;
434+
$limit = $data['limit'] ?? $limit;
435+
$timeout = $data['timeout'] ?? $timeout;
436+
$allowed_updates = $data['allowed_updates'] ?? $allowed_updates;
437+
}
438+
439+
// Take custom input into account.
419440
if ($custom_input = $this->getCustomInput()) {
420441
try {
421442
$input = json_decode($this->input, true, 512, JSON_THROW_ON_ERROR);
@@ -437,11 +458,7 @@ public function handleGetUpdates(?int $limit = null, ?int $timeout = null): Serv
437458
$offset = $this->last_update_id + 1; // As explained in the telegram bot API documentation.
438459
}
439460

440-
$response = Request::getUpdates([
441-
'offset' => $offset,
442-
'limit' => $limit,
443-
'timeout' => $timeout,
444-
]);
461+
$response = Request::getUpdates(compact('offset', 'limit', 'timeout', 'allowed_updates'));
445462
}
446463

447464
if ($response->isOk()) {
@@ -455,12 +472,11 @@ public function handleGetUpdates(?int $limit = null, ?int $timeout = null): Serv
455472
}
456473

457474
if (!DB::isDbConnected() && !$custom_input && $this->last_update_id !== null && $offset === 0) {
458-
//Mark update(s) as read after handling
459-
Request::getUpdates([
460-
'offset' => $this->last_update_id + 1,
461-
'limit' => 1,
462-
'timeout' => $timeout,
463-
]);
475+
// Mark update(s) as read after handling
476+
$offset = $this->last_update_id + 1;
477+
$limit = 1;
478+
479+
Request::getUpdates(compact('offset', 'limit', 'timeout', 'allowed_updates'));
464480
}
465481
}
466482

0 commit comments

Comments
 (0)