Filters
MadelineProto offers a very simple and intuitive message filtering system, based on PHP’s type system and attributes.
There are two filter types:
Simple filters
Simple filters are implemented using simple PHP types, for example:
use danog\MadelineProto\SimpleEventHandler;
use danog\MadelineProto\EventHandler\Attributes\Handler;
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\EventHandler\Message\PrivateMessage;
use danog\MadelineProto\EventHandler\Message\GroupMessage;
use danog\MadelineProto\EventHandler\Message\ChannelMessage;
use danog\MadelineProto\EventHandler\SimpleFilter\Incoming;
use danog\MadelineProto\EventHandler\SimpleFilter\Outgoing;
use danog\MadelineProto\EventHandler\SimpleFilter\HasMedia;
class MyEventHandler extends SimpleEventHandler
{
#[Handler]
public function h1(Incoming & Message $message): void
{
// Handle all incoming messages (private+groups+channels).
}
#[Handler]
public function h2(Outgoing & PrivateMessage $message): void
{
// Handle all outgoing messages (private).
}
#[Handler]
public function h3((Incoming & GroupMessage & HasMedia) | (Incoming & ChannelMessage & HasMedia) $message): void
{
// Handle all incoming messages with media attached (groups+channels).
}
}
MadelineProto will send updates about new messages to all methods marked with the Handler
attribute, appropriately filtering them first according to the typehint.
A filter typehint is composed of:
- A single concrete type:
A
- Concrete types are objects with useful bound methods and properties containing the fields of the message.
- A single concrete type intersected with one or more filter interfaces:
A&B&C
(used to AND filters)- Filter interfaces are PHP interfaces that are automatically parsed using reflection.
Unlike concrete types, they cannot be used for type assertions outside of a method marked by#[Handler]
or#[Filter...]
attributes.
- Filter interfaces are PHP interfaces that are automatically parsed using reflection.
- A union of concrete types:
A|B|C
(used to OR filters) - A union of concrete types or intersections:
(A&B)|C|(D&F)
(used to OR filters in DNF form)
Single concrete type examples:
Message
- Handle all incoming and outgoing messages (private or groups or channels).ChannelMessage
- Handle all incoming and outgoing messages (channels).GroupMessage
- Handle all incoming and outgoing messages (groups).PrivateMessage
- Handle all incoming and outgoing messages (private).ServiceMessage
- Handle all incoming and outgoing service messages (private or groups or channels).AbstractMessage
- Handle all incoming and outgoing service+normal messages (private or groups or channels).
Intersection examples:
Incoming & Message
- Handle all incoming messages (private or groups or channels).Incoming & GroupMessage & HasMedia
- Handle all incoming media messages (groups).
Union/DNF examples:
GroupMessage|ChannelMessage
- Handle all incoming and outgoing messages (groups or channels).(Incoming&GroupMessage)|(Incoming&ChannelMessage)
- Handle all incoming messages (groups or channels).ServiceMessage|(ChannelMessage&HasMedia)
- Handle all service messages or incoming and outgoing media channel messages.
Simple filters can optionally be combined with attribute filters, in which case they will be AND-ed together.
Here’s the full list of all concrete types:
- danog\MadelineProto\Broadcast\Progress » - Broadcast progress.
- danog\MadelineProto\EventHandler\AbstractMessage » - Represents an incoming or outgoing message.
- danog\MadelineProto\EventHandler\AbstractPrivateMessage » - Represents a private or secret chat message.
- danog\MadelineProto\EventHandler\AbstractStory » - Represents a Telegram Story.
- danog\MadelineProto\EventHandler\BotCommands » - The command set of a certain bot in a certain chat has changed.
- danog\MadelineProto\EventHandler\CallbackQuery » - Represents a query sent by the user by clicking on a button.
- danog\MadelineProto\EventHandler\Channel\ChannelParticipant » - A participant has left, joined, was banned or admin’d in a channel or supergroup.
- danog\MadelineProto\EventHandler\Channel\MessageForwards » - Indicates that the forward counter of a message in a channel has changed.
- danog\MadelineProto\EventHandler\Channel\MessageViewsChanged » - Indicates that the view counter of a message in a channel has changed.
- danog\MadelineProto\EventHandler\Channel\UpdateChannel » - A new channel is available, or info about an existing channel was changed.
- danog\MadelineProto\EventHandler\ChatInviteRequester » - Indicates someone has requested to join a chat or channel.
- danog\MadelineProto\EventHandler\ChatInviteRequester\BotChatInviteRequest » - Indicates someone has requested to join a chat or channel (bots only).
- danog\MadelineProto\EventHandler\ChatInviteRequester\PendingJoinRequests » - Someone has requested to join a chat or channel.
- danog\MadelineProto\EventHandler\Delete » - Indicates that some messages were deleted.
- danog\MadelineProto\EventHandler\Delete\DeleteChannelMessages » - Some messages in a supergroup/channel were deleted.
- danog\MadelineProto\EventHandler\Delete\DeleteMessages » - Some messages were deleted in a private chat or simple group.
- danog\MadelineProto\EventHandler\Delete\DeleteScheduledMessages » - Some scheduled messages were deleted from the schedule queue of a chat.
- danog\MadelineProto\EventHandler\InlineQuery » - An incoming inline query.
- danog\MadelineProto\EventHandler\Message » - Represents an incoming or outgoing message.
- danog\MadelineProto\EventHandler\Message\ChannelMessage » - Represents an incoming or outgoing channel message.
- danog\MadelineProto\EventHandler\Message\CommentReply » - Represents a reply to one of our messages in a channel comment group that we’re not a member of (i.e. received via
@replies
). - danog\MadelineProto\EventHandler\Message\GroupMessage » - Represents an incoming or outgoing group message.
- danog\MadelineProto\EventHandler\Message\PrivateMessage » - Represents an incoming or outgoing private message.
- danog\MadelineProto\EventHandler\Message\SecretMessage » - Represents New encrypted message.
- danog\MadelineProto\EventHandler\Message\ServiceMessage » - Represents info about a service message.
- danog\MadelineProto\EventHandler\Message\ServiceMessage » - Represents info about a service message.
- danog\MadelineProto\EventHandler\Message\Service\DialogBotAllowed » - We have given the bot permission to send us direct messages.
- danog\MadelineProto\EventHandler\Message\Service\DialogChannelCreated » - The channel was created.
- danog\MadelineProto\EventHandler\Message\Service\DialogChannelMigrateFrom » - Indicates the channel was migrated from the specified chat.
- danog\MadelineProto\EventHandler\Message\Service\DialogChatJoinedByLink » - A user joined the chat via an invite link.
- danog\MadelineProto\EventHandler\Message\Service\DialogChatMigrateTo » - Indicates the chat was migrated to the specified supergroup.
- danog\MadelineProto\EventHandler\Message\Service\DialogContactSignUp » - A contact just signed up to telegram.
- danog\MadelineProto\EventHandler\Message\Service\DialogCreated » - A chat or channel was created.
- danog\MadelineProto\EventHandler\Message\Service\DialogDeleteMessages » - Deleted messages.
- danog\MadelineProto\EventHandler\Message\Service\DialogGameScore » - Someone scored in a game.
- danog\MadelineProto\EventHandler\Message\Service\DialogGeoProximityReached » - A user of the chat is now in proximity of another user.
- danog\MadelineProto\EventHandler\Message\Service\DialogGiftPremium » - Info about a gifted Telegram Premium subscription.
- danog\MadelineProto\EventHandler\Message\Service\DialogGiftStars » - Info about a gifted Telegram Stars.
- danog\MadelineProto\EventHandler\Message\Service\DialogGroupCall » - Represents a service message about a group call.
- danog\MadelineProto\EventHandler\Message\Service\DialogGroupCall\GroupCall » - The group call has started or ended.
- danog\MadelineProto\EventHandler\Message\Service\DialogGroupCall\GroupCallInvited » - A set of users was invited to the group call.
- danog\MadelineProto\EventHandler\Message\Service\DialogGroupCall\GroupCallScheduled » - A group call was scheduled.
- danog\MadelineProto\EventHandler\Message\Service\DialogHistoryCleared » - Chat history was cleared.
- danog\MadelineProto\EventHandler\Message\Service\DialogMemberJoinedByRequest » - A user was accepted into the group by an admin.
- danog\MadelineProto\EventHandler\Message\Service\DialogMemberLeft » - A member left the chat or channel.
- danog\MadelineProto\EventHandler\Message\Service\DialogMembersJoined » - Some members joined the chat or channel.
- danog\MadelineProto\EventHandler\Message\Service\DialogMessagePinned » - A message was pinned in a chat.
- danog\MadelineProto\EventHandler\Message\Service\DialogPeerRequested » - Contains info about a peer that the user shared with the bot after clicking on a keyboardButtonRequestPeer button.
- danog\MadelineProto\EventHandler\Message\Service\DialogPhoneCall » - A phone call.
- danog\MadelineProto\EventHandler\Message\Service\DialogPhotoChanged » - The photo of the dialog was changed or deleted.
- danog\MadelineProto\EventHandler\Message\Service\DialogReadMessages » - Messages marked as read.
- danog\MadelineProto\EventHandler\Message\Service\DialogScreenshotTaken » - A screenshot of the chat was taken.
- danog\MadelineProto\EventHandler\Message\Service\DialogSetChatTheme » - The chat theme was changed.
- danog\MadelineProto\EventHandler\Message\Service\DialogSetChatWallPaper » - The wallpaper of the current chat was changed.
- danog\MadelineProto\EventHandler\Message\Service\DialogSetTTL » - The Time-To-Live of messages in this chat was changed.
- danog\MadelineProto\EventHandler\Message\Service\DialogStarGift » - Info about a Star gifted.
- danog\MadelineProto\EventHandler\Message\Service\DialogSuggestProfilePhoto » - A new profile picture was suggested using photos.uploadContactProfilePhoto.
- danog\MadelineProto\EventHandler\Message\Service\DialogTitleChanged » - The title of a channel or group has changed.
- danog\MadelineProto\EventHandler\Message\Service\DialogTopicCreated » - A forum topic was created.
- danog\MadelineProto\EventHandler\Message\Service\DialogTopicEdited » - Forum topic information was edited.
- danog\MadelineProto\EventHandler\Message\Service\DialogWebView » - Data from an opened reply keyboard bot web app was relayed to the bot that owns it (user & bot side service message).
- danog\MadelineProto\EventHandler\Payments\Payment » - This object contains information about an incoming pre-checkout query.
- danog\MadelineProto\EventHandler\Pinned » - Indicates that some messages were pinned/unpinned.
- danog\MadelineProto\EventHandler\Pinned\PinnedChannelMessages » - Represents messages that were pinned/unpinned in a channel.
- danog\MadelineProto\EventHandler\Pinned\PinnedGroupMessages » - Represents messages that were pinned/unpinned in a chat/supergroup.
- danog\MadelineProto\EventHandler\Pinned\PinnedPrivateMessages » - Some messages were pinned in a private chat.
- danog\MadelineProto\EventHandler\Privacy » - Indicates some privacy rules for a user or set of users.
- danog\MadelineProto\EventHandler\Query\ButtonQuery » - Represents a query sent by the user by clicking on a button.
- danog\MadelineProto\EventHandler\Query\ChatButtonQuery » - Represents a query sent by the user by clicking on a button in a chat.
- danog\MadelineProto\EventHandler\Query\ChatGameQuery » - Represents a query sent by the user by clicking on a “Play game” button in a chat.
- danog\MadelineProto\EventHandler\Query\GameQuery » - Represents a query sent by the user by clicking on a “Play game” button.
- danog\MadelineProto\EventHandler\Query\InlineButtonQuery » - Represents a query sent by the user by clicking on a button in an inline message.
- danog\MadelineProto\EventHandler\Query\InlineGameQuery » - Represents a query sent by the user by clicking on a “Play game” button in an inline message.
- danog\MadelineProto\EventHandler\Story\Story » - Represents a Telegram story.
- danog\MadelineProto\EventHandler\Story\StoryDeleted » - Represents a deleted story.
- danog\MadelineProto\EventHandler\Story\StoryReaction » - Represents a reaction to a story.
- danog\MadelineProto\EventHandler\Typing » - A user is typing.
- danog\MadelineProto\EventHandler\Typing\ChatUserTyping » - The user is preparing a message in a group; typing, recording, uploading, etc. This update is valid for 6 seconds. If no further updates of this kind are received after 6 seconds, it should be considered that the user stopped doing whatever they were doing.
- danog\MadelineProto\EventHandler\Typing\SecretUserTyping » - The user is preparing a message in a secret chat; typing, recording, uploading, etc. This update is valid for 6 seconds. If no further updates of this kind are received after 6 seconds, it should be considered that the user stopped doing whatever they were doing.
- danog\MadelineProto\EventHandler\Typing\SupergroupUserTyping » - A user is typing in a supergroup.
- danog\MadelineProto\EventHandler\Typing\UserTyping » - The user is preparing a message; typing, recording, uploading, etc. This update is valid for 6 seconds. If no further updates of this kind are received after 6 seconds, it should be considered that the user stopped doing whatever they were doing.
- danog\MadelineProto\EventHandler\User\Blocked » - A peer was blocked.
- danog\MadelineProto\EventHandler\User\BotStopped » - A bot was stopped or re-started.
- danog\MadelineProto\EventHandler\User\Phone » - A user’s phone number was changed.
- danog\MadelineProto\EventHandler\User\Status » - Contains a status update.
- danog\MadelineProto\EventHandler\User\Status\Emoji » - The emoji status of a certain user has changed or was removed.
- danog\MadelineProto\EventHandler\User\Status\EmptyStatus » - User status has not been set yet.
- danog\MadelineProto\EventHandler\User\Status\LastMonth » - Online status: last seen last month.
- danog\MadelineProto\EventHandler\User\Status\LastWeek » - Online status: last seen last week.
- danog\MadelineProto\EventHandler\User\Status\Offline » - The user’s offline status.
- danog\MadelineProto\EventHandler\User\Status\Online » - Online status of the user.
- danog\MadelineProto\EventHandler\User\Status\Recently » - Online status: last seen recently.
- danog\MadelineProto\EventHandler\User\Username » - Changes were made to the user’s first name, last name or username.
- danog\MadelineProto\VoIP » - This update represents a VoIP Telegram call.
Here’s the full list of simple filter interfaces (see attribute filters for more advanced filters like commands, regexes, and much more!):
- danog\MadelineProto\EventHandler\SimpleFilter\Ended » - Represents an ended call
- danog\MadelineProto\EventHandler\SimpleFilter\FromAdmin » - Allows messages from the bot admin
- danog\MadelineProto\EventHandler\SimpleFilter\FromAdminOrOutgoing » - Allows messages from the bot admin or outgoing messages
- danog\MadelineProto\EventHandler\SimpleFilter\HasAudio » - Allows only audio messages
- danog\MadelineProto\EventHandler\SimpleFilter\HasDocument » - Allows only documents
- danog\MadelineProto\EventHandler\SimpleFilter\HasDocumentPhoto » - Allows only document photos
- danog\MadelineProto\EventHandler\SimpleFilter\HasGif » - Allows only GIFs
- danog\MadelineProto\EventHandler\SimpleFilter\HasMedia » - Allows only media messages
- danog\MadelineProto\EventHandler\SimpleFilter\HasMultiplePoll » - Allows only messages that contain a multiple poll
- danog\MadelineProto\EventHandler\SimpleFilter\HasNoMedia » - Allows only messages with no media
- danog\MadelineProto\EventHandler\SimpleFilter\HasPhoto » - Allows only photos
- danog\MadelineProto\EventHandler\SimpleFilter\HasPoll » - Allows only messages that contain a poll
- danog\MadelineProto\EventHandler\SimpleFilter\HasQuizPoll » - Allows only messages that contain a quiz poll
- danog\MadelineProto\EventHandler\SimpleFilter\HasRoundVideo » - Allows only round videos
- danog\MadelineProto\EventHandler\SimpleFilter\HasSinglePoll » - Allows only messages that contain a single poll
- danog\MadelineProto\EventHandler\SimpleFilter\HasSticker » - Allows only stickers
- danog\MadelineProto\EventHandler\SimpleFilter\HasTopic » - Allow only messages coming from groups that has topics (Supergroups only).
- danog\MadelineProto\EventHandler\SimpleFilter\HasVideo » - Allows only videos
- danog\MadelineProto\EventHandler\SimpleFilter\HasVoice » - Allows only voice messages
- danog\MadelineProto\EventHandler\SimpleFilter\Incoming » - Represents an incoming message
- danog\MadelineProto\EventHandler\SimpleFilter\IsEdited » - Allows messages that were edited.
- danog\MadelineProto\EventHandler\SimpleFilter\IsForwarded » - Allows only forwarded messages
- danog\MadelineProto\EventHandler\SimpleFilter\IsNotEdited » - Allows messages that weren’t edited.
- danog\MadelineProto\EventHandler\SimpleFilter\IsReply » - Allows only messages that reply to other messages
- danog\MadelineProto\EventHandler\SimpleFilter\IsReplyToSelf » - Allows only messages that reply to one of our messages
- danog\MadelineProto\EventHandler\SimpleFilter\Outgoing » - Represents an outgoing message
- danog\MadelineProto\EventHandler\SimpleFilter\Running » - Allow only currently running calls
Attribute filters
Attribute filters are implemented using PHP attributes, for example:
use danog\MadelineProto\SimpleEventHandler;
use danog\MadelineProto\EventHandler\Attributes\Handler;
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\EventHandler\Message\PrivateMessage;
use danog\MadelineProto\EventHandler\Message\GroupMessage;
use danog\MadelineProto\EventHandler\Message\ChannelMessage;
use danog\MadelineProto\EventHandler\Filter\FilterIncoming;
class MyEventHandler extends SimpleEventHandler
{
#[FilterIncoming]
public function h1(Message $message): void
{
// Handle all incoming messages (private+groups+channels).
}
#[FiltersAnd(new FilterOutgoing, new FilterPrivate)]
public function h2(Message $message): void
{
// Handle all outgoing messages (private).
}
#[FiltersAnd(new FilterIncoming, new FiltersOr(new FilterGroup, new FilterChannel), new FilterMedia)]
public function h3(Message $message): void
{
// Handle all incoming messages with media attached (groups+channels).
}
#[FiltersOr(new FilterGroup, new FilterChannel)]
public function h4(Incoming&Message&HasMedia $message): void
{
// Same as h3, but combining simple filters with attribute filters.
}
}
Attribute filters are usual combined with simple filters.
Attribute filters are ANDed with simple filters defined on the same method, for example this:
#[FiltersOr(new FilterGroup, new FilterChannel)]
public function h4(Incoming&Message&HasMedia $message)
Is exactly the same as this:
#[FiltersAnd(new FilterIncoming, new FilterMessage, new FilterMedia, new FiltersOr(new FilterGroup, new FilterChannel))]
public function h3($message): void
Which can also be written using only simple filters:
#[Handler]
public function h3((Incoming & GroupMessage & HasMedia) | (Incoming & ChannelMessage & HasMedia) $message): void
Here’s the full list of filter attributes (see the MTProto filters » for even more low-level filters):
- danog\MadelineProto\EventHandler\Filter\FilterAllowAll » - Allow all updates.
- danog\MadelineProto\EventHandler\Filter\FilterButtonQueryData(string $content) » - Filters based on the content of a button query.
- danog\MadelineProto\EventHandler\Filter\FilterChannel » - Allow only updates coming from channels.
- danog\MadelineProto\EventHandler\Filter\FilterCommand(string $command, list
$types = [ 0 => \danog\MadelineProto\EventHandler\CommandType::BANG, 1 => \danog\MadelineProto\EventHandler\CommandType::DOT, 2 => \danog\MadelineProto\EventHandler\CommandType::SLASH,]) » - Allow only messages containing the specified command. - danog\MadelineProto\EventHandler\Filter\FilterCommandCaseInsensitive(string $command, list
$types = [ 0 => \danog\MadelineProto\EventHandler\CommandType::BANG, 1 => \danog\MadelineProto\EventHandler\CommandType::DOT, 2 => \danog\MadelineProto\EventHandler\CommandType::SLASH,]) » - Allow only messages containing the specified case-insensitive command. - danog\MadelineProto\EventHandler\Filter\FilterCommentReply » - Allow messages that coming from @replies.
- danog\MadelineProto\EventHandler\Filter\FilterEdited » - Allows messages that were edited.
- danog\MadelineProto\EventHandler\Filter\FilterEnded » - Allow only ended calls.
- danog\MadelineProto\EventHandler\Filter\FilterForwarded » - Allow only forwarded messages.
- danog\MadelineProto\EventHandler\Filter\FilterForwardedFrom(string|int $peer) » - Allow only forwarded messages from a certain sender.
- danog\MadelineProto\EventHandler\Filter\FilterFromAdmin » - Allow only messages coming from the admin (defined as the peers returned by getReportPeers).
- danog\MadelineProto\EventHandler\Filter\FilterFromBot » - Allow only messages coming from bots.
- danog\MadelineProto\EventHandler\Filter\FilterFromSender(string|int $peer) » - Allow incoming or outgoing group messages made by a certain sender.
- danog\MadelineProto\EventHandler\Filter\FilterFromSenders(string|int …$idOrUsername) » - Allow incoming or outgoing group messages made by a certain list of senders.
- danog\MadelineProto\EventHandler\Filter\FilterGroup » - Allow only updates coming from groups.
- danog\MadelineProto\EventHandler\Filter\FilterIncoming » - Allow only incoming messages.
- danog\MadelineProto\EventHandler\Filter\FilterMedia » - Allow any media messages.
- danog\MadelineProto\EventHandler\Filter\FilterMessage » - Allow any non-service message.
- danog\MadelineProto\EventHandler\Filter\FilterNoMedia » - Allow any messages except media messages.
- danog\MadelineProto\EventHandler\Filter\FilterNotEdited » - Allows messages that weren’t edited.
- danog\MadelineProto\EventHandler\Filter\FilterOutgoing » - Allow only outgoing messages.
- danog\MadelineProto\EventHandler\Filter\FilterPeer(string|int $peer) » - Allow messages coming from or sent to a certain peer.
- danog\MadelineProto\EventHandler\Filter\FilterPoll » - Allow only messages that contain a poll.
- danog\MadelineProto\EventHandler\Filter\FilterPrivate » - Allow only updates coming from private chats.
- danog\MadelineProto\EventHandler\Filter\FilterRegex(non-empty-string $regex, int-mask<0, 256, 512> $flags = 0, int $offset = 0) » - Allow only messages or button queries matching the specified regex.
- danog\MadelineProto\EventHandler\Filter\FilterRegexMatchAll(non-empty-string $regex, int $flags = 0, int $offset = 0) » - Allow only messages or button queries matching the specified regex.
- danog\MadelineProto\EventHandler\Filter\FilterReply » - Allow messages that reply to other messages.
- danog\MadelineProto\EventHandler\Filter\FilterReplyToSelf » - Allow messages that reply to one of our messages.
- danog\MadelineProto\EventHandler\Filter\FilterRunning » - Allow only running calls.
- danog\MadelineProto\EventHandler\Filter\FilterSecret » - Allow only updates coming from secret chats.
- danog\MadelineProto\EventHandler\Filter\FilterSender(string|int $peer) » - Allow incoming or outgoing group messages made by a certain sender.
- danog\MadelineProto\EventHandler\Filter\FilterSenders(string|int …$idOrUsername) » - Allow incoming or outgoing group messages made by a certain list of senders.
- danog\MadelineProto\EventHandler\Filter\FilterService » - Allow only service messages of any type.
- danog\MadelineProto\EventHandler\Filter\FilterText(string $content) » - Allow only messages with a specific content.
- danog\MadelineProto\EventHandler\Filter\FilterTextCaseInsensitive(string $content) » - Allow only messages with a specific case-insensitive content.
- danog\MadelineProto\EventHandler\Filter\FilterTextContains(string $content) » - Allow only messages that contain a specific content.
- danog\MadelineProto\EventHandler\Filter\FilterTextContainsCaseInsensitive(string $content) » - Allow only messages that contain a specific case-insensitive content.
- danog\MadelineProto\EventHandler\Filter\FilterTextEnds(string $content) » - Allow only messages that ends with a specific content.
- danog\MadelineProto\EventHandler\Filter\FilterTextEndsCaseInsensitive(string $content) » - Allow only messages that ends with a specific case-insensitive content.
- danog\MadelineProto\EventHandler\Filter\FilterTextStarts(string $content) » - Allow only messages that start with a specific content.
- danog\MadelineProto\EventHandler\Filter\FilterTextStartsCaseInsensitive(string $content) » - Allow only messages that start with a specific case-insensitive content.
- danog\MadelineProto\EventHandler\Filter\FilterTopic » - Allow only messages coming from groups that has topics (Supergroups only).
- danog\MadelineProto\EventHandler\Filter\FilterTopicId(int $topicId) » - Allow only messages with a specific topic id (Supergroups only).
- danog\MadelineProto\EventHandler\Filter\Combinator\FilterNot(Filter $filter) » - NOTs a filter.
- danog\MadelineProto\EventHandler\Filter\Combinator\FiltersAnd(Filter …$filters) » - ANDs multiple filters.
- danog\MadelineProto\EventHandler\Filter\Combinator\FiltersOr(Filter …$filters) » - ORs multiple filters.
- danog\MadelineProto\EventHandler\Filter\Media\FilterAudio » - Allow only audio files.
- danog\MadelineProto\EventHandler\Filter\Media\FilterDocument » - Allow only documents.
- danog\MadelineProto\EventHandler\Filter\Media\FilterDocumentPhoto » - Allow only documents containing an image.
- danog\MadelineProto\EventHandler\Filter\Media\FilterGif » - Allow only GIFs.
- danog\MadelineProto\EventHandler\Filter\Media\FilterPhoto » - Allow only photos.
- danog\MadelineProto\EventHandler\Filter\Media\FilterRoundVideo » - Allow only round videos.
- danog\MadelineProto\EventHandler\Filter\Media\FilterSticker » - Allow only stickers.
- danog\MadelineProto\EventHandler\Filter\Media\FilterVideo » - Allow only videos.
- danog\MadelineProto\EventHandler\Filter\Media\FilterVoice » - Allow only voice messages.
- danog\MadelineProto\EventHandler\Filter\Poll\FilterMultiplePoll » - Allow only messages that contain a multiple poll.
- danog\MadelineProto\EventHandler\Filter\Poll\FilterQuizPoll » - Allow only messages that contain a quiz poll.
- danog\MadelineProto\EventHandler\Filter\Poll\FilterSinglePoll » - Allow only messages that contain a single poll.
Creating custom attribute filters
To create a custom attribute filter, simply create a method attribute that extends the Filter class.
You must implement an apply(Update $update): bool
method, that returns true or false according to the filter’s logic.
<?php declare(strict_types=1);
use Attribute;
use danog\MadelineProto\EventHandler\Update;
/**
* Use with #[FilterBoolean(true/false)]
*/
#[Attribute(Attribute::TARGET_METHOD)]
final class FilterBoolean extends Filter
{
public function __construct(private readonly bool $applyIf) {}
public function apply(Update $update): bool
{
return $this->applyIf;
}
}
You can also optionally implement the public function initialize(EventHandler $API): Filter
function.
This function is useful to perform expensive one-time initialization tasks, to avoid performing them during filtering, for example:
<?php declare(strict_types=1);
/**
* This file is part of MadelineProto.
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
* You should have received a copy of the GNU General Public License along with MadelineProto.
* If not, see <http://www.gnu.org/licenses/>.
*
* @author Daniil Gentili <daniil@daniil.it>
* @copyright 2016-2023 Daniil Gentili <daniil@daniil.it>
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
* @link https://docs.madelineproto.xyz MadelineProto documentation
*/
namespace danog\MadelineProto\EventHandler\Filter;
use danog\MadelineProto\EventHandler;
use danog\MadelineProto\EventHandler\AbstractMessage;
use danog\MadelineProto\EventHandler\AbstractStory;
use danog\MadelineProto\EventHandler\BotCommands;
use danog\MadelineProto\EventHandler\ChatInviteRequester\BotChatInviteRequest;
use danog\MadelineProto\EventHandler\InlineQuery;
use danog\MadelineProto\EventHandler\Query\ButtonQuery;
use danog\MadelineProto\EventHandler\Story\StoryReaction;
use danog\MadelineProto\EventHandler\Typing;
use danog\MadelineProto\EventHandler\Update;
use danog\MadelineProto\EventHandler\User\Blocked;
use danog\MadelineProto\EventHandler\User\BotStopped;
use danog\MadelineProto\EventHandler\User\Phone;
use danog\MadelineProto\EventHandler\User\Status;
use danog\MadelineProto\EventHandler\User\Username;
/**
* Allow incoming or outgoing group messages made by a certain list of senders.
*
* @internal
*/
abstract class AbstractFilterFromSenders extends Filter
{
/** @var array<string|int> */
private readonly array $peers;
/** @var list<int> */
private readonly array $peersResolved;
public function __construct(string|int ...$idOrUsername)
{
$this->peers = array_unique($idOrUsername);
}
public function initialize(EventHandler $API): Filter
{
if (\count($this->peers) === 1) {
return (new FilterFromSender(array_values($this->peers)[0]))->initialize($API);
}
$res = [];
foreach ($this->peers as $peer) {
$res []= $API->getId($peer);
}
/** @psalm-suppress InaccessibleProperty */
$this->peersResolved = $res;
return $this;
}
public function apply(Update $update): bool
{
return $update instanceof AbstractMessage && \in_array($update->senderId, $this->peersResolved, true) ||
($update instanceof AbstractStory && \in_array($update->senderId, $this->peersResolved, true)) ||
($update instanceof StoryReaction && \in_array($update->senderId, $this->peersResolved, true)) ||
($update instanceof ButtonQuery && \in_array($update->userId, $this->peersResolved, true)) ||
($update instanceof InlineQuery && \in_array($update->userId, $this->peersResolved, true)) ||
($update instanceof Typing && \in_array($update->userId, $this->peersResolved, true)) ||
($update instanceof Blocked && \in_array($update->userId, $this->peersResolved, true)) ||
($update instanceof BotStopped && \in_array($update->userId, $this->peersResolved, true)) ||
($update instanceof Phone && \in_array($update->userId, $this->peersResolved, true)) ||
($update instanceof Status && \in_array($update->userId, $this->peersResolved, true)) ||
($update instanceof Username && \in_array($update->userId, $this->peersResolved, true)) ||
($update instanceof BotCommands && \in_array($update->botId, $this->peersResolved, true)) ||
($update instanceof BotChatInviteRequest && \in_array($update->userId, $this->peersResolved, true));
}
}
Usually you should return $this
from initialize()
, but if you want to replace the current filter with another filter, you can return the new filter, instead:
<?php declare(strict_types=1);
use Attribute;
use danog\MadelineProto\EventHandler;
use danog\MadelineProto\EventHandler\Filter\Filter;
use danog\MadelineProto\EventHandler\Filter\FilterPrivate;
use danog\MadelineProto\EventHandler\Filter\FilterFromAdmin;
use danog\MadelineProto\EventHandler\Update;
/**
* A shorthand filter for FilterPrivate && FilterFromAdmin
*/
#[Attribute(Attribute::TARGET_METHOD)]
final class FilterPrivateAdmin extends Filter
{
public function initialize(EventHandler $API): Filter
{
return (new FiltersAnd(new FilterPrivate, new FilterFromAdmin))->initialize($API);
}
public function apply(Update $update): bool
{
throw new AssertionError("Unreachable!");
}
}
Another example:
<?php declare(strict_types=1);
/**
* This file is part of MadelineProto.
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
* You should have received a copy of the GNU General Public License along with MadelineProto.
* If not, see <http://www.gnu.org/licenses/>.
*
* @author Daniil Gentili <daniil@daniil.it>
* @copyright 2016-2023 Daniil Gentili <daniil@daniil.it>
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
* @link https://docs.madelineproto.xyz MadelineProto documentation
*/
namespace danog\MadelineProto\EventHandler\Filter\Combinator;
use Attribute;
use danog\MadelineProto\EventHandler;
use danog\MadelineProto\EventHandler\Filter\Filter;
use danog\MadelineProto\EventHandler\Update;
/**
* NOTs a filter.
*/
#[Attribute(Attribute::TARGET_METHOD)]
final class FilterNot extends Filter
{
public function __construct(private readonly Filter $filter)
{
}
public function initialize(EventHandler $API): Filter
{
$filter = $this->filter->initialize($API);
if ($filter instanceof self) {
// The nested filter is a FilterNot, optimize !!A => A
return $filter->filter;
}
if ($filter === $this->filter) {
// The nested filter didn't replace itself
return $this;
}
// The nested filter replaced itself, re-wrap it
return new self($filter);
}
public function apply(Update $update): bool
{
return !$this->filter->apply($update);
}
}
MTProto filters
MTProto filters are used to obtain raw MTProto updates in the form of arrays.
Unlike simple updates, raw MTProto updates do not have bound methods, but MadelineProto offers a bunch of helper methods that can be used, instead.
Please note that MTProto filters are not covered by any backwards compatibility promise: they may change at any time, including in minor versions, because they’re related directly to the Telegram API schema.
Use simple filters for a stable object-oriented update API.
MTProto filters are defined by creating a function with the appropriate name, for example to handle updateNewMessage updates:
use danog\MadelineProto\SimpleEventHandler;
class MyEventHandler extends SimpleEventHandler
{
/**
* Handle updates from users.
*
* 100+ other types of onUpdate... method types are available, see https://docs.madelineproto.xyz/API_docs/types/Update.html for the full list.
* You can also use onAny to catch all update types (only for debugging)
* A special onUpdateCustomEvent method can also be defined, to send messages to the event handler from an API instance, using the sendCustomEvent method.
*
* @param array $update Update
*/
public function onUpdateNewMessage(array $update): void
{
if ($update['message']['_'] === 'messageEmpty') {
return;
}
$this->logger($update);
// Chat ID
$id = $this->getId($update);
// Sender ID, not always present
$from_id = isset($update['message']['from_id'])
? $this->getId($update['message']['from_id'])
: null;
// In this example code, send the "This userbot is powered by MadelineProto!" message only once per chat.
// Ignore all further messages coming from this chat.
if (!isset($this->notifiedChats[$id])) {
$this->notifiedChats[$id] = true;
$this->messages->sendMessage(
peer: $update,
message: "This userbot is powered by [MadelineProto](https://t.me/MadelineProto)!",
reply_to_msg_id: $update['message']['id'] ?? null,
parse_mode: 'Markdown'
);
}
}
}
Here’s a full list of all MTProto filters (click on each filter name to view the structure of the array that will be passed to it):
- onUpdateCustomEvent: Receives messages sent to the event handler from an API instance using the
sendCustomEvent
» method. - onAny: Catch-all filter, if defined catches all updates that aren’t catched by any other filter.
- onUpdateBroadcastProgress »: Used to receive updates to an in-progress message broadcast »* onUpdateNewMessage » - New message in a private chat or in a basic group.
- onUpdateMessageID » - Sent message with random_id client identifier was assigned an identifier.
- onUpdateDeleteMessages » - Messages were deleted.
- onUpdateUserTyping » - The user is preparing a message; typing, recording, uploading, etc. This update is valid for 6 seconds. If no further updates of this kind are received after 6 seconds, it should be considered that the user stopped doing whatever they were doing
- onUpdateChatUserTyping » - The user is preparing a message in a group; typing, recording, uploading, etc. This update is valid for 6 seconds. If no further updates of this kind are received after 6 seconds, it should be considered that the user stopped doing whatever they were doing
- onUpdateChatParticipants » - Composition of chat participants changed.
- onUpdateUserStatus » - Contact status update.
- onUpdateUserName » - Changes the user’s first name, last name and username.
- onUpdateNewAuthorization » - A new session logged into the current user’s account through an unknown device.
- onUpdateNewEncryptedMessage » - New encrypted message.
- onUpdateEncryptedChatTyping » - Interlocutor is typing a message in an encrypted chat. Update period is 6 second. If upon this time there is no repeated update, it shall be considered that the interlocutor stopped typing.
- onUpdateEncryption » - Change of state in an encrypted chat.
- onUpdateEncryptedMessagesRead » - Communication history in an encrypted chat was marked as read.
- onUpdateChatParticipantAdd » - New group member.
- onUpdateChatParticipantDelete » - A member has left the group.
- onUpdateDcOptions » - Changes in the data center configuration options.
- onUpdateNotifySettings » - Changes in notification settings.
- onUpdateServiceNotification » - A service message for the user.
- onUpdatePrivacy » - Privacy rules were changed
- onUpdateUserPhone » - A user’s phone number was changed
- onUpdateReadHistoryInbox » - Incoming messages were read
- onUpdateReadHistoryOutbox » - Outgoing messages were read
- onUpdateWebPage » - An instant view webpage preview was generated
- onUpdateReadMessagesContents » - Contents of messages in the common message box were read
- onUpdateChannelTooLong » - There are new updates in the specified channel, the client must fetch them.
- onUpdateChannel » - A new channel or supergroup is available, or info about an existing channel has changed and must be refeteched.
- onUpdateNewChannelMessage » - A new message was sent in a channel/supergroup
- onUpdateReadChannelInbox » - Incoming messages in a channel/supergroup were read
- onUpdateDeleteChannelMessages » - Some messages in a supergroup/channel were deleted
- onUpdateChannelMessageViews » - The view counter of a message in a channel has changed
- onUpdateChatParticipantAdmin » - Admin permissions of a user in a basic group were changed
- onUpdateNewStickerSet » - A new stickerset was installed
- onUpdateStickerSetsOrder » - The order of stickersets was changed
- onUpdateStickerSets » - Installed stickersets have changed, the client should refetch them as described in the docs.
- onUpdateSavedGifs » - The saved gif list has changed, the client should refetch it using messages.getSavedGifs
- onUpdateBotInlineQuery » - An incoming inline query
- onUpdateBotInlineSend » - The result of an inline query that was chosen by a user and sent to their chat partner. Please see our documentation on the feedback collecting for details on how to enable these updates for your bot.
- onUpdateEditChannelMessage » - A message was edited in a channel/supergroup
- onUpdateBotCallbackQuery » - A callback button was pressed, and the button data was sent to the bot that created the button
- onUpdateEditMessage » - A message was edited
- onUpdateInlineBotCallbackQuery » - This notification is received by bots when a button is pressed
- onUpdateReadChannelOutbox » - Outgoing messages in a channel/supergroup were read
- onUpdateDraftMessage » - Notifies a change of a message draft.
- onUpdateReadFeaturedStickers » - Some featured stickers were marked as read
- onUpdateRecentStickers » - The recent sticker list was updated
- onUpdateConfig » - The server-side configuration has changed; the client should re-fetch the config using help.getConfig
- onUpdatePtsChanged » - Common message box sequence PTS has changed, state has to be refetched using updates.getState
- onUpdateChannelWebPage » - A webpage preview of a link in a channel/supergroup message was generated
- onUpdateDialogPinned » - A dialog was pinned/unpinned
- onUpdatePinnedDialogs » - Pinned dialogs were updated
- onUpdateBotWebhookJSON » - A new incoming event; for bots only
- onUpdateBotWebhookJSONQuery » - A new incoming query; for bots only
- onUpdateBotShippingQuery » - This object contains information about an incoming shipping query.
- onUpdateBotPrecheckoutQuery » - This object contains information about an incoming pre-checkout query.
- onUpdatePhoneCall » - An incoming phone call
- onUpdateLangPackTooLong » - A language pack has changed, the client should manually fetch the changed strings using langpack.getDifference
- onUpdateLangPack » - Language pack updated
- onUpdateFavedStickers » - The list of favorited stickers was changed, the client should call messages.getFavedStickers to refetch the new list
- onUpdateChannelReadMessagesContents » - The specified channel/supergroup messages were read
- onUpdateContactsReset » - All contacts were deleted
- onUpdateChannelAvailableMessages » - The history of a channel/supergroup was hidden.
- onUpdateDialogUnreadMark » - The manual unread mark of a chat was changed
- onUpdateMessagePoll » - The results of a poll have changed
- onUpdateChatDefaultBannedRights » - Default banned rights in a normal chat were updated
- onUpdateFolderPeers » - The peer list of a peer folder was updated
- onUpdatePeerSettings » - Settings of a certain peer have changed
- onUpdatePeerLocated » - List of peers near you was updated
- onUpdateNewScheduledMessage » - A message was added to the schedule queue of a chat
- onUpdateDeleteScheduledMessages » - Some scheduled messages were deleted from the schedule queue of a chat
- onUpdateTheme » - A cloud theme was updated
- onUpdateGeoLiveViewed » - Live geoposition message was viewed
- onUpdateLoginToken » - A login token (for login via QR code) was accepted.
- onUpdateMessagePollVote » - A specific peer has voted in a poll
- onUpdateDialogFilter » - A new folder was added
- onUpdateDialogFilterOrder » - New folder order
- onUpdateDialogFilters » - Clients should update folder info
- onUpdatePhoneCallSignalingData » - Incoming phone call signaling payload
- onUpdateChannelMessageForwards » - The forward counter of a message in a channel has changed
- onUpdateReadChannelDiscussionInbox » - Incoming comments in a discussion thread were marked as read
- onUpdateReadChannelDiscussionOutbox » - Outgoing comments in a discussion thread were marked as read
- onUpdatePeerBlocked » - We blocked a peer, see here » for more info on blocklists.
- onUpdateChannelUserTyping » - A user is typing in a supergroup, channel or message thread
- onUpdatePinnedMessages » - Some messages were pinned in a chat
- onUpdatePinnedChannelMessages » - Messages were pinned/unpinned in a channel/supergroup
- onUpdateChat » - A new chat is available
- onUpdateGroupCallParticipants » - The participant list of a certain group call has changed
- onUpdateGroupCall » - A new groupcall was started
- onUpdatePeerHistoryTTL » - The Time-To-Live for messages sent by the current user in a specific chat has changed
- onUpdateChatParticipant » - A user has joined or left a specific chat
- onUpdateChannelParticipant » - A participant has left, joined, was banned or admined in a channel or supergroup.
- onUpdateBotStopped » - A bot was stopped or re-started.
- onUpdateGroupCallConnection » - New WebRTC parameters
- onUpdateBotCommands » - The command set of a certain bot in a certain chat has changed.
- onUpdatePendingJoinRequests » - Someone has requested to join a chat or channel
- onUpdateBotChatInviteRequester » - Someone has requested to join a chat or channel (bots only, users will receive an updatePendingJoinRequests, instead)
- onUpdateMessageReactions » - New message reactions » are available
- onUpdateAttachMenuBots » - The list of installed attachment menu entries » has changed, use messages.getAttachMenuBots to fetch the updated list.
- onUpdateWebViewResultSent » - Indicates to a bot that a webview was closed and an inline message was sent on behalf of the user using messages.sendWebViewResultMessage
- onUpdateBotMenuButton » - The menu button behavior for the specified bot has changed
- onUpdateSavedRingtones » - The list of saved notification sounds has changed, use account.getSavedRingtones to fetch the new list.
- onUpdateTranscribedAudio » - A pending voice message transcription » initiated with messages.transcribeAudio was updated.
- onUpdateReadFeaturedEmojiStickers » - Some featured custom emoji stickers were marked as read
- onUpdateUserEmojiStatus » - The emoji status of a certain user has changed
- onUpdateRecentEmojiStatuses » - The list of recent emoji statuses has changed
- onUpdateRecentReactions » - The list of recent message reactions has changed
- onUpdateMoveStickerSetToTop » - A stickerset was just moved to top, see here for more info »
- onUpdateMessageExtendedMedia » - Extended media update
- onUpdateChannelPinnedTopic » - A forum topic » was pinned or unpinned.
- onUpdateChannelPinnedTopics » - The pinned topics of a forum have changed.
- onUpdateUser » - User information was updated, it must be refetched using users.getFullUser.
- onUpdateAutoSaveSettings » - Media autosave settings have changed and must be refetched using account.getAutoSaveSettings.
- onUpdateStory » - A new story was posted.
- onUpdateReadStories » - Stories of a specific peer were marked as read.
- onUpdateStoryID » - A story was successfully uploaded.
- onUpdateStoriesStealthMode » - Indicates that stories stealth mode was activated.
- onUpdateSentStoryReaction » - Indicates we reacted to a story ».
- onUpdateBotChatBoost » - A channel boost has changed (bots only)
- onUpdateChannelViewForumAsMessages » - Users may also choose to display messages from all topics as if they were sent to a normal group, using a “View as messages” setting in the local client.
- onUpdatePeerWallpaper » - The wallpaper » of a given peer has changed.
- onUpdateBotMessageReaction » - Bots only: a user has changed their reactions on a message with public reactions.
- onUpdateBotMessageReactions » - Bots only: the number of reactions on a message with anonymous reactions has changed.
- onUpdateSavedDialogPinned » - A saved message dialog was pinned/unpinned
- onUpdatePinnedSavedDialogs » - Pinned saved dialogs » were updated
- onUpdateSavedReactionTags » -
- onUpdateSmsJob » -
- onUpdateQuickReplies » -
- onUpdateNewQuickReply » -
- onUpdateDeleteQuickReply » -
- onUpdateQuickReplyMessage » -
- onUpdateDeleteQuickReplyMessages » -
- onUpdateBotBusinessConnect » -
- onUpdateBotNewBusinessMessage » -
- onUpdateBotEditBusinessMessage » -
- onUpdateBotDeleteBusinessMessage » -
- onUpdateNewStoryReaction » -
- onUpdateBroadcastRevenueTransactions » -
- onUpdateStarsBalance » -
- onUpdateBusinessBotCallbackQuery » -
- onUpdateStarsRevenueStatus » -
- onUpdateBotPurchasedPaidMedia » -
- onUpdatePaidReactionPrivacy » -
- onUpdateBotSubscriptionExpire » -