Handler Group Precedence
Which message watchers fire first and how propagation works in Alita Robot.
Handler Group Precedence
gotgbot dispatches incoming updates to handlers in ascending group number order. Lower group numbers fire first. Within the same group, handlers fire in registration order. A handler returning ext.EndGroups stops all further group processing for that update. ext.ContinueGroups allows downstream groups to continue firing.
This page documents every handler group the bot registers outside the default group 0, with its exact group number, verified from source code.
Precedence Table
| Group | Module | Handler | Filter | Return on Match | Notes |
|---|---|---|---|---|---|
| -10 | Captcha | handlePendingCaptchaMessage |
nil (all messages) | EndGroups |
Intercepts messages from users with pending captcha; stores and deletes message |
| -6 | Federations | enforceFedBan |
message.All |
ContinueGroups (always) |
Bans senders and new members who are banned in the chat’s federation; later groups still run |
| -6 | Federations | enforceFedBanOnJoin |
ChatMember (user joined) | ContinueGroups (always) |
Bans a joiner who is banned in the chat’s federation when the join arrives as a ChatMemberUpdated, also without a service message; a join takes the join claim before the ban, so of the two updates of one join only one bans and posts the notice, and a failed ban gives the claim back for the captcha |
| -5 | AntiRaid | onJoin |
Message with new_chat_members |
ContinueGroups (always) |
While raid mode is on (or once the auto-antiraid join threshold is reached, which turns it on), temp-bans each new joiner for the raid action time; skips the bot, admins, approved users and newcomers the chat’s federation has banned (fed-ban, group -6, has already banned them for good; they still count towards the threshold); does nothing if the bot cannot restrict |
| -4 | SpamDB | checkSpamDB |
Message with new_chat_members |
ContinueGroups (always) |
When the operator has ENABLE_SPAMDB on and the chat has /spamdb enabled in a group or supergroup, looks up each new joiner in CAS and applies the chat’s action (ban, mute or log only) to a listed one, reporting to the log channel only and taking the join so greetings and captcha stay quiet for a ban or mute; skips bots, admins and approved users; a failed lookup lets the joiner in |
| -2 | BotUpdates | adminCacheAutoUpdate |
MyChatMember (bot’s own admin status change) | ContinueGroups |
Invalidates and reloads the admin cache when the bot is promoted or demoted |
| -1 | BotUpdates | botJoinedGroup |
MyChatMember (bot joined; channel joins are filtered out and never reach it) | EndGroups for private chats and basic groups (it leaves basic groups), ContinueGroups for supergroups |
Early interceptor for bot group joins; leaves basic groups and stays in channels |
| -1 | Users | logUsers |
message.All |
ContinueGroups |
Logs user activity; never blocks propagation |
| 0 | All modules | Commands, callbacks | Various | varies | Default group; standard command handlers |
| 1 | Connections | connectedChatGuard |
update whose EffectiveChat a group-0 PM command swapped to the connected group |
EndGroups |
Keeps later groups from running on the swapped context; group 1 is reserved for this guard |
| 2 | Probation | checkProbation |
message.All |
ContinueGroups (always) |
Opt-in new-member probation: for a member who joined after /probation on, deletes links, forwards or media (as the chat chose) until enough different messages (counted in Redis) or the time has passed; skips admins and approved users; ends the probation on time or count |
| 3 | AISpam | checkAISpam |
message.All |
ContinueGroups (always) |
Opt-in AI spam filter; enqueues a check and never blocks propagation |
| 4 | Antiflood | checkFlood |
message.All |
ContinueGroups (always) |
Flood control; on flood deletes the message(s), punishes the sender and posts a notice without stopping later groups; skips anon admins, linked channels, approved users and media groups |
| 5 | Locks | permHandler |
message.All |
ContinueGroups (always) |
Content-type locks (sticker, gif, url, forward, rtl, anonchannel, …); deletes the offending message but does not block later groups |
| 6 | Locks | restHandler |
message.All |
ContinueGroups (always) |
Restriction locks (messages, comments, media, other, previews, all); deletes the offending message but does not block later groups |
| 7 | Blacklists | blacklistWatcher |
text or caption present | EndGroups after a warn (the default action); ContinueGroups otherwise (an error moves on to the next group) |
Checks words against blacklist; after a warn, later groups (reports, filters, pins, log channel) do not run |
| 8 | Reports | reportWatcher |
text mentioning @admin/@admins (case-insensitive, whole word) |
ContinueGroups (always) |
Treats a message that mentions @admin/@admins as a /report to the chat’s admins (silent when reports are off or /report is disabled); reactions, filters, pins and the log channel still see the message |
| 8 | Reactions | checkReactions |
message.All (acts only on text messages) |
ContinueGroups (always) |
Sets the chat’s configured emoji reaction on messages whose text contains a keyword (case-insensitive substring; first matching keyword in sorted order wins); never mutes, bans, or blocks propagation |
| 9 | Filters | filtersWatcher |
text or caption present | ContinueGroups; EndGroups when a non-admin sends <keyword> noformat |
Matches filter patterns; sends configured response but does not block |
| 10 | Pins | checkPinned |
linked-channel automatic forwards (GetSender().IsLinkedChannel()) |
ContinueGroups |
Deletes the post if /cleanlinked is on, otherwise unpins it if /antichannelpin is on. Group 10 also holds the /pin, /unpin, /unpinall, /permapin and /pinned commands (WrapCommand, Group: 10) |
| 11 | LogChannels | captureSetLogForward |
message.All |
ContinueGroups (always) |
Captures the channel post forwarded to finish /setlog |
Propagation Behavior
:::caution[Critical propagation rules] Understanding these rules is essential for debugging why a message did or did not trigger a particular watcher.
- Captcha is first (group -10). Any message from a user with a pending captcha is stored for moderator review and deleted. The message never reaches antiraid, antiflood, blacklists, or filters.
- AntiRaid bans raid joiners (group -5). During raid mode, users who join (seen through the join service message) are temp-banned for the raid action time, except those fed-banned in the chat’s federation, whom fed-ban (group -6) has already banned permanently. The handler always returns
ContinueGroups, so later groups still see the join message. - Filters use ContinueGroups; Blacklists depend on the action. Filters send their reply and never block later watchers. A blacklist
mute/ban/kick/tban/tmute/delete/noneaction returnsContinueGroups, so the message is still checked by filters. Thewarnaction (the default) returnsEndGroups, so reports, filters, pins and the log channel skip that message. One exception: when a non-admin sends<keyword> noformat, Filters replies with the admin-only error and returnsEndGroups, so pins and the log channel skip that update. - Locks use ContinueGroups (groups 5-6). A locked message is deleted, but blacklists, reports/reactions, filters and pins still see the update. :::
Interaction Examples
Scenario 1: User with pending captcha sends a message
- Captcha (group -10) intercepts the message, stores it in the pending queue, and deletes it from the chat.
- Returns
EndGroups. Nothing else fires. - After successful verification, the stored messages are deleted and the bot sends a type/count summary; their contents are not replayed.
Scenario 2: User sends a flood of messages
- Captcha (group -10) passes through (no pending captcha).
- AntiRaid (group -5) does not match (it only handles join service messages).
- Users (group -1) logs activity, continues.
- Commands (group 0) fire normally for earlier messages.
- Antiflood (group 4) triggers once the flood threshold is reached: it deletes the flooding message(s), applies the configured action (mute/kick/ban, or tmute/tban from older data), posts a notice, and returns
ContinueGroups. - Locks, blacklists, reports/reactions, filters, pins and the log channel still receive the update, although the message is already deleted from the chat.
Scenario 3: Message matches both a blacklist word and a filter
- Captcha (group -10) passes through.
- AntiRaid (group -5) does not match (it only handles join service messages).
- Users (group -1) logs activity, continues.
- Commands (group 0) — not a command, passes.
- Antiflood (group 4) — not flooding, continues.
- Locks (groups 5-6) check the chat’s content-type and restriction locks. Message passes (no lock violation).
- Blacklists (group 7) matches the word, takes the configured action (e.g., mute user), returns
ContinueGroups. - Group 8: Reports does nothing (the message does not mention @admin/@admins); Reactions adds an emoji reaction if a configured keyword matches, and returns
ContinueGroups. - Filters (group 9) matches the filter pattern, sends the configured response, returns
ContinueGroups. - Pins (group 10) does not match (the message is not a linked-channel post).
Both the blacklist action and the filter response are triggered for the same message.
If the blacklist action is warn (the default), the watcher returns EndGroups at step 7: steps 8-10 do not run and the filter does not reply.
Related Pages
- Request Flow — Full update processing pipeline
- Module Pattern — How modules register handlers