61 lines
1.7 KiB
Markdown
61 lines
1.7 KiB
Markdown
|
# Rate limit
|
||
|
|
||
|
You may want to limit access to certain commands or handlers
|
||
|
in your bot, for example to avoid flood limits.
|
||
|
|
||
|
For that, you can use rate-limiting feature of the Dispatcher.
|
||
|
Rate limiting is built into update state object, and all you have to do
|
||
|
is to call `.rateLimit` function:
|
||
|
|
||
|
```ts
|
||
|
dp.onNewMessage(
|
||
|
filters.command('some_expensive_command'),
|
||
|
async (msg, state) => {
|
||
|
try {
|
||
|
// 1 request every 15 seconds
|
||
|
await state.rateLimit('some_expensive_command', 1, 15)
|
||
|
} catch (e) {
|
||
|
if (e instanceof RateLimitError) {
|
||
|
await msg.replyText('Try again later')
|
||
|
}
|
||
|
throw e
|
||
|
}
|
||
|
|
||
|
const result = doSomeExpensiveComputations()
|
||
|
await msg.replyText(result)
|
||
|
}
|
||
|
)
|
||
|
```
|
||
|
|
||
|
In the above example, we use `some_expensive_command` as a key for the
|
||
|
rate limit. This allows you to have multiple independent rate limits.
|
||
|
|
||
|
When the rate limit is exceeded, `rateLimit` throws `RateLimitError`, which
|
||
|
also contains `.reset` field with the Unix time when the rate limit will be
|
||
|
reset.
|
||
|
|
||
|
## Throttle
|
||
|
|
||
|
In some cases you might want to throttle a used instead of rate-limiting them,
|
||
|
and that is exactly what `.throttle` does. When a rate limit is reached,
|
||
|
it waits until the rate limit is replenished and then returns:
|
||
|
|
||
|
```ts
|
||
|
dp.onNewMessage(
|
||
|
filters.start,
|
||
|
async (msg, state) => {
|
||
|
// no more than 2 rps per user
|
||
|
await state.throttle('start', 2, 1)
|
||
|
|
||
|
await msg.replyText('Hi!')
|
||
|
}
|
||
|
)
|
||
|
```
|
||
|
|
||
|
`throttle` returns tuple containing number of requests left until
|
||
|
the user hits the limit, and when the limit will be reset:
|
||
|
|
||
|
```ts
|
||
|
const [left, reset] = await state.throttle('some_expensive_command', 1, 15)
|
||
|
await msg.replyText(`${left} requests left. Reset at ${new Date(reset).toString()}`)
|
||
|
```
|