alina sireneva
690948b8b1
All checks were successful
Build and deploy typedoc / build (push) Successful in 5m15s
Co-authored-by: Kamilla 'ova <me@kamillaova.dev> Co-authored-by: Alina Chebakova <chebakov05@gmail.com> Co-authored-by: Kravets <57632712+kravetsone@users.noreply.github.com> Co-authored-by: starkow <hello@starkow.dev> Co-authored-by: sireneva <150665887+sireneva@users.noreply.github.com>
191 lines
4.2 KiB
Markdown
Executable file
191 lines
4.2 KiB
Markdown
Executable file
# Groups and propagation
|
|
|
|
When you register multiple handlers with conflicting filters,
|
|
only the one registered the first will be executed, to avoid
|
|
handling the same update twice.
|
|
|
|
This is sometimes undesirable, and to handle these you can use
|
|
either [handler groups](#groups), or [propagation symbols](#propagation)
|
|
|
|
::: tip
|
|
You can also use a [child Dispatcher](children.html). In this page, however,
|
|
it is assumed that all handlers are registered to one dispatcher.
|
|
:::
|
|
|
|
## Groups
|
|
|
|
Your first option to handle the same update multiple times is by
|
|
using a separate handler group.
|
|
|
|
Handler groups are identified with a single number (group `0` is the
|
|
default group) and are processed within the same dispatcher one-by-one
|
|
in order (`..., -2, -1, 0, 1, 2, ...`).
|
|
|
|
For example, consider the following code
|
|
|
|
```ts
|
|
dp.onNewMessage(
|
|
filters.or(filters.text, filters.sticker),
|
|
async (msg) => {
|
|
console.log('Text or sticker')
|
|
}
|
|
)
|
|
|
|
dp.onNewMessage(
|
|
filters.text,
|
|
async (msg) => {
|
|
console.log('Text only')
|
|
}
|
|
)
|
|
```
|
|
|
|
In this code, the second handler will never be executed, because
|
|
the first one handles `text` messages as well.
|
|
|
|
To make the Dispatcher execute the second handler, you can
|
|
register it to a different group:
|
|
|
|
```ts
|
|
dp.onNewMessage(
|
|
filters.text,
|
|
async (msg) => {
|
|
console.log('Text only')
|
|
},
|
|
1
|
|
)
|
|
```
|
|
|
|
In this case, this handler will be executed *after* the first one.
|
|
Alternatively, you can pass a negative number to make the second
|
|
handler execute *before* the first one:
|
|
|
|
```ts
|
|
dp.onNewMessage(
|
|
filters.text,
|
|
async (msg) => {
|
|
console.log('Text only')
|
|
},
|
|
-1
|
|
)
|
|
```
|
|
|
|
Group can also be set using `addUpdateHandler`:
|
|
|
|
```ts
|
|
dp.addUpdateHandler({ ... }, 1)
|
|
```
|
|
|
|
## Propagation
|
|
|
|
To customize the behaviour even further, you can use propagation symbols
|
|
that `@mtcute/dispatcher` exports in `PropagationAction` enum.
|
|
|
|
### Stop propagation
|
|
|
|
To prevent the update from being handled by any other handlers
|
|
within the same dispatcher, you can use `PropagationAction.Stop`:
|
|
|
|
```ts
|
|
dp.onNewMessage(
|
|
filters.or(filters.text, filters.sticker),
|
|
async (msg) => {
|
|
console.log('Text or sticker')
|
|
|
|
return PropagationAction.Stop
|
|
}
|
|
)
|
|
|
|
dp.onNewMessage(
|
|
filters.text,
|
|
async (msg) => {
|
|
console.log('Text only')
|
|
},
|
|
1
|
|
)
|
|
```
|
|
|
|
In the above code, second handler *will not* be executed even though it is
|
|
in a separate group.
|
|
|
|
This will not, however, prevent the handlers from a
|
|
[child Dispatcher](children.html) to be executed.
|
|
|
|
### Stop children propagation
|
|
|
|
A bit ahead of ourselves, since we haven't covered child
|
|
Dispatchers yet, but the idea is pretty simple.
|
|
|
|
`PropagationAction.StopChidlren` is very similar to the previous one, but also
|
|
prevents the handlers from child dispatchers to be executed:
|
|
|
|
```ts
|
|
dp.onNewMessage(
|
|
filters.or(filters.text, filters.sticker),
|
|
async (msg) => {
|
|
console.log('Text or sticker')
|
|
|
|
return PropagationAction.StopChidlren
|
|
}
|
|
)
|
|
|
|
const dp1 = new Dispatcher()
|
|
dp.addChild(dp1)
|
|
|
|
dp1.onNewMessage(
|
|
filters.text,
|
|
async (msg) => {
|
|
console.log('Text only')
|
|
}
|
|
)
|
|
```
|
|
|
|
In the above code, second executor will not be called, even though
|
|
it is in a child dispatcher.
|
|
|
|
### Continue propagation
|
|
|
|
As an alternative to [groups](#groups), you can use `PropagationAction.Continue`
|
|
symbol. It makes the dispatcher continue propagating this update within
|
|
the same group even though some handler from that group was already executed:
|
|
|
|
```ts
|
|
dp.onNewMessage(
|
|
filters.or(filters.text, filters.sticker),
|
|
async (msg) => {
|
|
console.log('Text or sticker')
|
|
|
|
return PropagationAction.Continue
|
|
}
|
|
)
|
|
|
|
dp.onNewMessage(
|
|
filters.text,
|
|
async (msg) => {
|
|
console.log('Text only')
|
|
}
|
|
)
|
|
```
|
|
|
|
In the above code, the second dispatcher will be called for text messages
|
|
even though the first one also matches them.
|
|
|
|
Note that `Continue` only works within the same handler group.
|
|
|
|
## Raw updates
|
|
|
|
As mentioned earlier, raw updates are handled independently of parsed
|
|
updates, and they have their own groups and propagation chain.
|
|
|
|
This means that in the following example both handlers will be called,
|
|
despite returning `Stop` action:
|
|
|
|
```ts
|
|
dp.onNewMessage(() => {
|
|
return PropagationAction.Stop
|
|
})
|
|
|
|
dp.onRawUpdate(
|
|
(cl, upd) => upd._ === 'updateNewMessage',
|
|
() => { ... }
|
|
)
|
|
```
|