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>
1.7 KiB
Executable file
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:
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:
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:
const [left, reset] = await state.throttle('some_expensive_command', 1, 15)
await msg.replyText(`${left} requests left. Reset at ${new Date(reset).toString()}`)