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\DialogPaymentSent » - A payment was sent.
- danog\MadelineProto\EventHandler\Message\Service\DialogPaymentSentMe » - A user just sent a payment to me (a bot).
- 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\FilterBotCommand(string $command) » - Allow only messages containing the specified command, optionally postfixed with the bot’s username.
- 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-2025 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);
}
#[\Override]
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;
}
#[\Override]
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-2025 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)
{
}
#[\Override]
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);
}
#[\Override]
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 (emitted specifically for messages like voice messages or video, only once the media is watched and marked as read using messages.readMessageContents).
- onUpdateChannelTooLong » - There are new updates in the specified channel, the client must fetch them.
- onUpdateChannel » - Channel/supergroup (channel and/or channelFull) information was updated.
- 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 and help.getAppConfig.
- 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 (emitted specifically for messages like voice messages or video, only once the media is watched and marked as read using channels.readMessageContents)
- 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 (or sent) 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 » - Chat (chat and/or chatFull) information was updated.
- 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 » - You bought a paid media »: this update contains the revealed media.
- onUpdateUser » - User (user and/or userFull) information was updated.
- 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/supergroup 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 » - The list of reaction tag » names assigned by the user has changed and should be refetched using messages.getSavedReactionTags ».
- onUpdateSmsJob » - A new SMS job was received
- onUpdateQuickReplies » - Info about or the order of quick reply shortcuts » was changed.
- onUpdateNewQuickReply » - A new quick reply shortcut » was created.
- onUpdateDeleteQuickReply » - A quick reply shortcut » was deleted. This will not emit updateDeleteQuickReplyMessages updates, even if all the messages in the shortcut are also deleted by this update.
- onUpdateQuickReplyMessage » - A new message was added to a quick reply shortcut ».
- onUpdateDeleteQuickReplyMessages » - One or more messages in a quick reply shortcut » were deleted.
- onUpdateBotBusinessConnect » - Connecting or disconnecting a business bot or changing the connection settings will emit an updateBotBusinessConnect update to the bot, with the new settings and a
connection_idthat will be used by the bot to handle updates from and send messages as the user. - onUpdateBotNewBusinessMessage » - A message was received via a connected business chat ».
- onUpdateBotEditBusinessMessage » - A message was edited in a connected business chat ».
- onUpdateBotDeleteBusinessMessage » - A message was deleted in a connected business chat ».
- onUpdateNewStoryReaction » - Represents a new reaction to a story.
- onUpdateStarsBalance » - The current account’s Telegram Stars balance » has changed.
- onUpdateBusinessBotCallbackQuery » - A callback button sent via a business connection was pressed, and the button data was sent to the bot that created the button.
- onUpdateStarsRevenueStatus » - The Telegram Star balance of a channel/bot we own has changed ».
- onUpdateBotPurchasedPaidMedia » - Bots only: a user has purchased a paid media.
- onUpdatePaidReactionPrivacy » - Contains the current default paid reaction privacy, see here » for more info.
- onUpdateSentPhoneCode » - A paid login SMS code was successfully sent.
- onUpdateGroupCallChainBlocks » - Contains updates to the blockchain of a conference call, see here » for more info.
- onUpdateReadMonoForumInbox » - Incoming messages in a monoforum topic were read
- onUpdateReadMonoForumOutbox » - Outgoing messages in a monoforum were read.
- onUpdateMonoForumNoPaidException » - An admin has (un)exempted this monoforum topic » from payment to send messages using account.toggleNoPaidMessagesException.
- onUpdateGroupCallMessage » -
- onUpdateGroupCallEncryptedMessage » -
- onUpdatePinnedForumTopic » -
- onUpdatePinnedForumTopics » -