Files
go-telegram/docs/reference/dispatch.md
T
lukaszraczylo 1088b7f4d7 docs: auto-generate markdown reference + soften README
- Add gomarkdoc-driven reference docs in docs/reference/, regenerated
  automatically by 'make regen' alongside the api/ codegen
- New 'make docs' target installs gomarkdoc on first run; 'make
  docs-check' is a CI gate
- Fold doc-clean assertion into existing codegen-clean job (single
  diff check covers spec + api + reference)
- Rewrite README header: logo via <picture>, friendlier tagline,
  emoji-led 'Why you'll like it' bullets instead of Why-table
- Drop duplicate echo snippet, soften 'Codegen pipeline' section into
  'Keeping up with Telegram'
- Link reference from README, Pages nav, and a new Markdown reference
  card on index.html (target = GitHub source view, renders .md natively)
2026-05-09 14:14:37 +01:00

669 lines
22 KiB
Markdown

<!-- Code generated by gomarkdoc. DO NOT EDIT -->
# dispatch
```go
import "github.com/lukaszraczylo/go-telegram/dispatch"
```
Package dispatch provides a typed router for Telegram updates. It consumes any transport.Updater and dispatches updates to handlers registered by command, regex, or update\-payload kind.
## Index
- [Variables](<#variables>)
- [type Context](<#Context>)
- [func NewContext\(ctx context.Context, b \*client.Bot, u \*api.Update\) \*Context](<#NewContext>)
- [type Filter](<#Filter>)
- [func All\[T any\]\(filters ...Filter\[T\]\) Filter\[T\]](<#All>)
- [func Any\[T any\]\(filters ...Filter\[T\]\) Filter\[T\]](<#Any>)
- [func \(f Filter\[T\]\) And\(others ...Filter\[T\]\) Filter\[T\]](<#Filter[T].And>)
- [func \(f Filter\[T\]\) Not\(\) Filter\[T\]](<#Filter[T].Not>)
- [func \(f Filter\[T\]\) Or\(others ...Filter\[T\]\) Filter\[T\]](<#Filter[T].Or>)
- [type Handler](<#Handler>)
- [type Middleware](<#Middleware>)
- [func Chain\[T any\]\(mws ...Middleware\[T\]\) Middleware\[T\]](<#Chain>)
- [func Recovery\(\) Middleware\[\*api.Update\]](<#Recovery>)
- [type NamedHandlers](<#NamedHandlers>)
- [func NewNamedHandlers\[T any\]\(\) \*NamedHandlers\[T\]](<#NewNamedHandlers>)
- [func \(n \*NamedHandlers\[T\]\) Handler\(\) Handler\[T\]](<#NamedHandlers[T].Handler>)
- [func \(n \*NamedHandlers\[T\]\) Has\(name string\) bool](<#NamedHandlers[T].Has>)
- [func \(n \*NamedHandlers\[T\]\) Names\(\) \[\]string](<#NamedHandlers[T].Names>)
- [func \(n \*NamedHandlers\[T\]\) Remove\(name string\) bool](<#NamedHandlers[T].Remove>)
- [func \(n \*NamedHandlers\[T\]\) Set\(name string, h Handler\[T\]\)](<#NamedHandlers[T].Set>)
- [type Router](<#Router>)
- [func New\(b \*client.Bot, opts ...RouterOption\) \*Router](<#New>)
- [func \(r \*Router\) Group\(group int\) \*RouterScope](<#Router.Group>)
- [func \(r \*Router\) OnBusinessConnection\(h Handler\[\*api.BusinessConnection\]\)](<#Router.OnBusinessConnection>)
- [func \(r \*Router\) OnCallback\(pattern string, h Handler\[\*api.CallbackQuery\]\)](<#Router.OnCallback>)
- [func \(r \*Router\) OnCallbackFilter\(f Filter\[\*api.CallbackQuery\], h Handler\[\*api.CallbackQuery\]\)](<#Router.OnCallbackFilter>)
- [func \(r \*Router\) OnChannelPost\(h Handler\[\*api.Message\]\)](<#Router.OnChannelPost>)
- [func \(r \*Router\) OnChatBoost\(h Handler\[\*api.ChatBoostUpdated\]\)](<#Router.OnChatBoost>)
- [func \(r \*Router\) OnChatJoinRequest\(h Handler\[\*api.ChatJoinRequest\]\)](<#Router.OnChatJoinRequest>)
- [func \(r \*Router\) OnChatJoinRequestFilter\(f Filter\[\*api.ChatJoinRequest\], h Handler\[\*api.ChatJoinRequest\]\)](<#Router.OnChatJoinRequestFilter>)
- [func \(r \*Router\) OnChatMember\(h Handler\[\*api.ChatMemberUpdated\]\)](<#Router.OnChatMember>)
- [func \(r \*Router\) OnChatMemberFilter\(f Filter\[\*api.ChatMemberUpdated\], h Handler\[\*api.ChatMemberUpdated\]\)](<#Router.OnChatMemberFilter>)
- [func \(r \*Router\) OnChosenInlineResult\(h Handler\[\*api.ChosenInlineResult\]\)](<#Router.OnChosenInlineResult>)
- [func \(r \*Router\) OnCommand\(cmd string, h Handler\[\*api.Message\]\)](<#Router.OnCommand>)
- [func \(r \*Router\) OnEditedChannelPost\(h Handler\[\*api.Message\]\)](<#Router.OnEditedChannelPost>)
- [func \(r \*Router\) OnEditedMessage\(h Handler\[\*api.Message\]\)](<#Router.OnEditedMessage>)
- [func \(r \*Router\) OnInlineQuery\(h Handler\[\*api.InlineQuery\]\)](<#Router.OnInlineQuery>)
- [func \(r \*Router\) OnInlineQueryFilter\(f Filter\[\*api.InlineQuery\], h Handler\[\*api.InlineQuery\]\)](<#Router.OnInlineQueryFilter>)
- [func \(r \*Router\) OnMessageFilter\(f Filter\[\*api.Message\], h Handler\[\*api.Message\]\)](<#Router.OnMessageFilter>)
- [func \(r \*Router\) OnMessageReaction\(h Handler\[\*api.MessageReactionUpdated\]\)](<#Router.OnMessageReaction>)
- [func \(r \*Router\) OnMessageReactionCount\(h Handler\[\*api.MessageReactionCountUpdated\]\)](<#Router.OnMessageReactionCount>)
- [func \(r \*Router\) OnMyChatMember\(h Handler\[\*api.ChatMemberUpdated\]\)](<#Router.OnMyChatMember>)
- [func \(r \*Router\) OnMyChatMemberFilter\(f Filter\[\*api.ChatMemberUpdated\], h Handler\[\*api.ChatMemberUpdated\]\)](<#Router.OnMyChatMemberFilter>)
- [func \(r \*Router\) OnPoll\(h Handler\[\*api.Poll\]\)](<#Router.OnPoll>)
- [func \(r \*Router\) OnPollAnswer\(h Handler\[\*api.PollAnswer\]\)](<#Router.OnPollAnswer>)
- [func \(r \*Router\) OnPreCheckoutQuery\(h Handler\[\*api.PreCheckoutQuery\]\)](<#Router.OnPreCheckoutQuery>)
- [func \(r \*Router\) OnPreCheckoutQueryFilter\(f Filter\[\*api.PreCheckoutQuery\], h Handler\[\*api.PreCheckoutQuery\]\)](<#Router.OnPreCheckoutQueryFilter>)
- [func \(r \*Router\) OnPurchasedPaidMedia\(h Handler\[\*api.PaidMediaPurchased\]\)](<#Router.OnPurchasedPaidMedia>)
- [func \(r \*Router\) OnRemovedChatBoost\(h Handler\[\*api.ChatBoostRemoved\]\)](<#Router.OnRemovedChatBoost>)
- [func \(r \*Router\) OnShippingQuery\(h Handler\[\*api.ShippingQuery\]\)](<#Router.OnShippingQuery>)
- [func \(r \*Router\) OnText\(pattern string, h Handler\[\*api.Message\]\)](<#Router.OnText>)
- [func \(r \*Router\) Run\(ctx context.Context, u transport.Updater\) error](<#Router.Run>)
- [func \(r \*Router\) Use\(mw Middleware\[\*api.Update\]\)](<#Router.Use>)
- [type RouterOption](<#RouterOption>)
- [func WithMaxConcurrency\(n int\) RouterOption](<#WithMaxConcurrency>)
- [type RouterScope](<#RouterScope>)
- [func \(s \*RouterScope\) OnCommand\(cmd string, h Handler\[\*api.Message\]\)](<#RouterScope.OnCommand>)
- [func \(s \*RouterScope\) OnMessageFilter\(f Filter\[\*api.Message\], h Handler\[\*api.Message\]\)](<#RouterScope.OnMessageFilter>)
- [func \(s \*RouterScope\) OnText\(pattern string, h Handler\[\*api.Message\]\)](<#RouterScope.OnText>)
## Variables
<a name="ErrContinueGroups"></a>ErrContinueGroups signals that this group's handler should be treated as not\-matching when returned by a handler: dispatch moves on to the next handler in the same group, then to subsequent groups.
Without ErrContinueGroups, a non\-error return from a matched handler stops dispatch \(default first\-match\-wins semantics\).
```go
var ErrContinueGroups = errors.New("dispatch: continue groups")
```
<a name="ErrEndGroups"></a>ErrEndGroups stops dispatch from running any further handlers in any group for this update when returned by a handler. Use it to indicate the update has been definitively handled.
errors.Is\(err, ErrEndGroups\) is the canonical check, though dispatch itself recognises it by exact identity.
```go
var ErrEndGroups = errors.New("dispatch: end groups")
```
<a name="Context"></a>
## type Context
Context bundles the per\-update state every handler receives.
Ctx is the request context propagated from Router.Run; cancelling the run cancels every handler.
Bot is the API client. Handlers reply by calling api.SendMessage\(c.Ctx, c.Bot, ...\) etc.
Update is the raw update; payload\-typed handlers also receive a narrowed pointer to one of its sub\-fields.
Values is a per\-update bag matchers populate. Conventional keys:
```
"command": string, the matched bot command (e.g. "/start")
"command_args": string, everything after the command
"regex_match": []string, regex sub-matches when OnText matches
```
```go
type Context struct {
Ctx context.Context
Bot *client.Bot
Update *api.Update
Values map[string]any
}
```
<a name="NewContext"></a>
### func NewContext
```go
func NewContext(ctx context.Context, b *client.Bot, u *api.Update) *Context
```
NewContext constructs a Context. Used by Router internally; exposed for custom test harnesses.
<a name="Filter"></a>
## type Filter
Filter is a predicate over a typed payload \(e.g. \*api.Message\). Filters compose via And/Or/Not for multi\-condition matching.
Example:
```
f := message.HasPhoto().And(message.InChat(-100123456789))
```
```go
type Filter[T any] func(payload T) bool
```
<a name="All"></a>
### func All
```go
func All[T any](filters ...Filter[T]) Filter[T]
```
All combines filters with AND. Returns a Filter that matches when all match. Returns a filter that always matches when filters is empty.
<a name="Any"></a>
### func Any
```go
func Any[T any](filters ...Filter[T]) Filter[T]
```
Any combines filters with OR. Returns a Filter that matches when at least one matches. Returns a filter that never matches when filters is empty.
<a name="Filter[T].And"></a>
### func \(Filter\[T\]\) And
```go
func (f Filter[T]) And(others ...Filter[T]) Filter[T]
```
And returns a Filter that matches iff f and every one of others matches.
<a name="Filter[T].Not"></a>
### func \(Filter\[T\]\) Not
```go
func (f Filter[T]) Not() Filter[T]
```
Not returns a Filter that inverts f.
<a name="Filter[T].Or"></a>
### func \(Filter\[T\]\) Or
```go
func (f Filter[T]) Or(others ...Filter[T]) Filter[T]
```
Or returns a Filter that matches iff f matches OR any of others matches.
<a name="Handler"></a>
## type Handler
Handler is a generic handler over update payload type T. T is typically \*api.Message, \*api.CallbackQuery, \*api.InlineQuery, or \*api.Update for global middleware.
```go
type Handler[T any] func(ctx *Context, payload T) error
```
<a name="Middleware"></a>
## type Middleware
Middleware wraps a Handler\[T\] with cross\-cutting behaviour \(logging, recovery, auth\). Middleware composition is left\-to\-right: Use\(a,b,c\) runs as a\(b\(c\(handler\)\)\).
```go
type Middleware[T any] func(Handler[T]) Handler[T]
```
<a name="Chain"></a>
### func Chain
```go
func Chain[T any](mws ...Middleware[T]) Middleware[T]
```
Chain composes a slice of middleware into a single Middleware\[T\].
<a name="Recovery"></a>
### func Recovery
```go
func Recovery() Middleware[*api.Update]
```
Recovery returns middleware that recovers from panics in downstream handlers, converting them into a returned error and logging via the bot's configured logger. Registered automatically by NewRouter.
<a name="NamedHandlers"></a>
## type NamedHandlers
NamedHandlers manages handlers by string name, allowing runtime registration, replacement, and removal. This complements the Router's registration methods: each registration via Named\*\(\) also gets a name for later lookup.
Use case: a plugin system that loads/unloads command handlers without restarting the bot.
```go
type NamedHandlers[T any] struct {
// contains filtered or unexported fields
}
```
<a name="NewNamedHandlers"></a>
### func NewNamedHandlers
```go
func NewNamedHandlers[T any]() *NamedHandlers[T]
```
NewNamedHandlers returns a new, empty NamedHandlers\[T\].
<a name="NamedHandlers[T].Handler"></a>
### func \(\*NamedHandlers\[T\]\) Handler
```go
func (n *NamedHandlers[T]) Handler() Handler[T]
```
Handler returns a single Handler\[T\] that runs each registered handler in registration order, first non\-nil error stops the chain. Use this to wire NamedHandlers into a Router.OnXxx call:
```
names := dispatch.NewNamedHandlers[*api.Message]()
names.Set("logger", loggingHandler)
names.Set("audit", auditHandler)
router.OnCommand("/admin", names.Handler())
```
Subsequent Set/Remove calls take effect on the next dispatch.
<a name="NamedHandlers[T].Has"></a>
### func \(\*NamedHandlers\[T\]\) Has
```go
func (n *NamedHandlers[T]) Has(name string) bool
```
Has reports whether name is registered.
<a name="NamedHandlers[T].Names"></a>
### func \(\*NamedHandlers\[T\]\) Names
```go
func (n *NamedHandlers[T]) Names() []string
```
Names returns the registered names in registration order.
<a name="NamedHandlers[T].Remove"></a>
### func \(\*NamedHandlers\[T\]\) Remove
```go
func (n *NamedHandlers[T]) Remove(name string) bool
```
Remove unregisters the handler under name. Returns true if it existed.
<a name="NamedHandlers[T].Set"></a>
### func \(\*NamedHandlers\[T\]\) Set
```go
func (n *NamedHandlers[T]) Set(name string, h Handler[T])
```
Set registers or replaces the handler under name. If name is new, it is appended to the end of the registration order.
<a name="Router"></a>
## type Router
Router dispatches updates from any Updater to typed handlers.
Matchers run in registration order; first match wins. A panic\-recovery middleware is attached automatically and runs around every dispatch.
```go
type Router struct {
// contains filtered or unexported fields
}
```
<a name="New"></a>
### func New
```go
func New(b *client.Bot, opts ...RouterOption) *Router
```
New constructs a Router. Recovery middleware is added by default; users can disable it by passing WithoutRecovery \(not implemented here, but the hook is in place via Use\).
<a name="Router.Group"></a>
### func \(\*Router\) Group
```go
func (r *Router) Group(group int) *RouterScope
```
Group returns a RouterScope that registers handlers in the given group. Group 0 \(the default\) runs first, then group 1, etc. Within a group, handlers run in registration order; the first non\-skipped match terminates dispatch unless the handler returns ErrContinueGroups.
<a name="Router.OnBusinessConnection"></a>
### func \(\*Router\) OnBusinessConnection
```go
func (r *Router) OnBusinessConnection(h Handler[*api.BusinessConnection])
```
OnBusinessConnection registers a handler for business connection updates.
<a name="Router.OnCallback"></a>
### func \(\*Router\) OnCallback
```go
func (r *Router) OnCallback(pattern string, h Handler[*api.CallbackQuery])
```
OnCallback registers a handler for callback queries whose Data matches the regex.
Panics at registration time if pattern is not a valid regular expression.
<a name="Router.OnCallbackFilter"></a>
### func \(\*Router\) OnCallbackFilter
```go
func (r *Router) OnCallbackFilter(f Filter[*api.CallbackQuery], h Handler[*api.CallbackQuery])
```
OnCallbackFilter registers a typed callback\-query handler gated by filter f. Filter routes are checked after pattern\-based OnCallback routes; first match wins.
<a name="Router.OnChannelPost"></a>
### func \(\*Router\) OnChannelPost
```go
func (r *Router) OnChannelPost(h Handler[*api.Message])
```
OnChannelPost registers a handler for channel post updates.
<a name="Router.OnChatBoost"></a>
### func \(\*Router\) OnChatBoost
```go
func (r *Router) OnChatBoost(h Handler[*api.ChatBoostUpdated])
```
OnChatBoost registers a handler for chat boost updates.
<a name="Router.OnChatJoinRequest"></a>
### func \(\*Router\) OnChatJoinRequest
```go
func (r *Router) OnChatJoinRequest(h Handler[*api.ChatJoinRequest])
```
OnChatJoinRequest registers a handler for chat join requests.
<a name="Router.OnChatJoinRequestFilter"></a>
### func \(\*Router\) OnChatJoinRequestFilter
```go
func (r *Router) OnChatJoinRequestFilter(f Filter[*api.ChatJoinRequest], h Handler[*api.ChatJoinRequest])
```
OnChatJoinRequestFilter registers a filtered handler for chat join requests.
<a name="Router.OnChatMember"></a>
### func \(\*Router\) OnChatMember
```go
func (r *Router) OnChatMember(h Handler[*api.ChatMemberUpdated])
```
OnChatMember registers a handler for chat member status changes.
<a name="Router.OnChatMemberFilter"></a>
### func \(\*Router\) OnChatMemberFilter
```go
func (r *Router) OnChatMemberFilter(f Filter[*api.ChatMemberUpdated], h Handler[*api.ChatMemberUpdated])
```
OnChatMemberFilter registers a filtered handler for chat member status changes.
<a name="Router.OnChosenInlineResult"></a>
### func \(\*Router\) OnChosenInlineResult
```go
func (r *Router) OnChosenInlineResult(h Handler[*api.ChosenInlineResult])
```
OnChosenInlineResult registers a handler for chosen inline results.
<a name="Router.OnCommand"></a>
### func \(\*Router\) OnCommand
```go
func (r *Router) OnCommand(cmd string, h Handler[*api.Message])
```
OnCommand registers a handler for a slash command. The command string includes the leading slash \(e.g. "/start"\). Matching strips an optional "@BotName" suffix.
<a name="Router.OnEditedChannelPost"></a>
### func \(\*Router\) OnEditedChannelPost
```go
func (r *Router) OnEditedChannelPost(h Handler[*api.Message])
```
OnEditedChannelPost registers a handler for edited channel post updates.
<a name="Router.OnEditedMessage"></a>
### func \(\*Router\) OnEditedMessage
```go
func (r *Router) OnEditedMessage(h Handler[*api.Message])
```
OnEditedMessage registers a handler for edited message updates.
<a name="Router.OnInlineQuery"></a>
### func \(\*Router\) OnInlineQuery
```go
func (r *Router) OnInlineQuery(h Handler[*api.InlineQuery])
```
OnInlineQuery registers a handler for inline queries \(one matcher only; inline queries are not partitioned by content here\).
<a name="Router.OnInlineQueryFilter"></a>
### func \(\*Router\) OnInlineQueryFilter
```go
func (r *Router) OnInlineQueryFilter(f Filter[*api.InlineQuery], h Handler[*api.InlineQuery])
```
OnInlineQueryFilter registers an inline\-query handler gated by filter f. Filter routes are checked after bare OnInlineQuery handlers; first match wins.
<a name="Router.OnMessageFilter"></a>
### func \(\*Router\) OnMessageFilter
```go
func (r *Router) OnMessageFilter(f Filter[*api.Message], h Handler[*api.Message])
```
OnMessageFilter registers a typed message handler gated by filter f. Filter routes are checked after command and text routes; first match wins.
<a name="Router.OnMessageReaction"></a>
### func \(\*Router\) OnMessageReaction
```go
func (r *Router) OnMessageReaction(h Handler[*api.MessageReactionUpdated])
```
OnMessageReaction registers a handler for message reaction updates.
<a name="Router.OnMessageReactionCount"></a>
### func \(\*Router\) OnMessageReactionCount
```go
func (r *Router) OnMessageReactionCount(h Handler[*api.MessageReactionCountUpdated])
```
OnMessageReactionCount registers a handler for anonymous message reaction count updates.
<a name="Router.OnMyChatMember"></a>
### func \(\*Router\) OnMyChatMember
```go
func (r *Router) OnMyChatMember(h Handler[*api.ChatMemberUpdated])
```
OnMyChatMember registers a handler for bot's own chat member status changes.
<a name="Router.OnMyChatMemberFilter"></a>
### func \(\*Router\) OnMyChatMemberFilter
```go
func (r *Router) OnMyChatMemberFilter(f Filter[*api.ChatMemberUpdated], h Handler[*api.ChatMemberUpdated])
```
OnMyChatMemberFilter registers a filtered handler for bot's own chat member status changes.
<a name="Router.OnPoll"></a>
### func \(\*Router\) OnPoll
```go
func (r *Router) OnPoll(h Handler[*api.Poll])
```
OnPoll registers a handler for poll state updates.
<a name="Router.OnPollAnswer"></a>
### func \(\*Router\) OnPollAnswer
```go
func (r *Router) OnPollAnswer(h Handler[*api.PollAnswer])
```
OnPollAnswer registers a handler for poll answer updates.
<a name="Router.OnPreCheckoutQuery"></a>
### func \(\*Router\) OnPreCheckoutQuery
```go
func (r *Router) OnPreCheckoutQuery(h Handler[*api.PreCheckoutQuery])
```
OnPreCheckoutQuery registers a handler for pre\-checkout queries.
<a name="Router.OnPreCheckoutQueryFilter"></a>
### func \(\*Router\) OnPreCheckoutQueryFilter
```go
func (r *Router) OnPreCheckoutQueryFilter(f Filter[*api.PreCheckoutQuery], h Handler[*api.PreCheckoutQuery])
```
OnPreCheckoutQueryFilter registers a filtered handler for pre\-checkout queries.
<a name="Router.OnPurchasedPaidMedia"></a>
### func \(\*Router\) OnPurchasedPaidMedia
```go
func (r *Router) OnPurchasedPaidMedia(h Handler[*api.PaidMediaPurchased])
```
OnPurchasedPaidMedia registers a handler for purchased paid media updates.
<a name="Router.OnRemovedChatBoost"></a>
### func \(\*Router\) OnRemovedChatBoost
```go
func (r *Router) OnRemovedChatBoost(h Handler[*api.ChatBoostRemoved])
```
OnRemovedChatBoost registers a handler for removed chat boost updates.
<a name="Router.OnShippingQuery"></a>
### func \(\*Router\) OnShippingQuery
```go
func (r *Router) OnShippingQuery(h Handler[*api.ShippingQuery])
```
OnShippingQuery registers a handler for shipping queries.
<a name="Router.OnText"></a>
### func \(\*Router\) OnText
```go
func (r *Router) OnText(pattern string, h Handler[*api.Message])
```
OnText registers a handler for messages whose Text matches the regex.
Panics at registration time if pattern is not a valid regular expression.
<a name="Router.Run"></a>
### func \(\*Router\) Run
```go
func (r *Router) Run(ctx context.Context, u transport.Updater) error
```
Run consumes the Updater and dispatches each update. It blocks until the Updater's channel is closed or ctx is cancelled.
By default updates are processed concurrently \(up to WithMaxConcurrency\(50\) goroutines\). Handlers for different updates may therefore run simultaneously; shared state must be protected. Pass WithMaxConcurrency\(0\) to New to restore serial \(legacy\) behaviour.
Run waits for all in\-flight handlers to finish before returning.
<a name="Router.Use"></a>
### func \(\*Router\) Use
```go
func (r *Router) Use(mw Middleware[*api.Update])
```
Use registers a global middleware applied to every Update dispatch.
<a name="RouterOption"></a>
## type RouterOption
RouterOption configures a Router at construction time.
```go
type RouterOption func(*Router)
```
<a name="WithMaxConcurrency"></a>
### func WithMaxConcurrency
```go
func WithMaxConcurrency(n int) RouterOption
```
WithMaxConcurrency sets the maximum number of updates processed in parallel. Default is 50. Pass 0 to dispatch serially \(one update at a time, in the calling goroutine — the legacy behaviour before v1.1.0\).
Note: concurrent dispatch means handlers for different updates may run simultaneously. Handlers that mutate shared state must be safe for concurrent access.
<a name="RouterScope"></a>
## type RouterScope
RouterScope registers handlers into a specific priority group on its parent Router. Group 0 runs first, then group 1, etc. Within a group, handlers run in registration order; the first non\-skipped match terminates dispatch unless the handler returns ErrContinueGroups.
```go
type RouterScope struct {
// contains filtered or unexported fields
}
```
<a name="RouterScope.OnCommand"></a>
### func \(\*RouterScope\) OnCommand
```go
func (s *RouterScope) OnCommand(cmd string, h Handler[*api.Message])
```
OnCommand registers a command handler in this group.
<a name="RouterScope.OnMessageFilter"></a>
### func \(\*RouterScope\) OnMessageFilter
```go
func (s *RouterScope) OnMessageFilter(f Filter[*api.Message], h Handler[*api.Message])
```
OnMessageFilter registers a filter\-based message handler in this group.
<a name="RouterScope.OnText"></a>
### func \(\*RouterScope\) OnText
```go
func (s *RouterScope) OnText(pattern string, h Handler[*api.Message])
```
OnText registers a regex text handler in this group. Panics at registration time if pattern is not a valid regular expression.
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)