umbot
Version:
Мультиплатформенный фреймворк для создания голосовых навыков и чат-ботов с единой бизнес-логикой. Встроенная поддержка ВКонтакте, Telegram, Viber, MAX, Яндекс Алисы, Маруси и Сбера SmartApp. Архитектура на адаптерах позволяет подключать любые другие платф
54 lines (53 loc) • 4.21 kB
TypeScript
import { BotController } from '../controller';
import { MiddlewareNext } from '../core';
/**
* Создаёт middleware для ограничения частоты входящих запросов (rate limiting) на уровне платформы.
*
* 🎯 **Для чего используется:**
* Некоторые платформы (например, Max, Telegram, VK, Viber) имеют ограничение на количество
* отправляемых запросов в секунду (обычно 30). Данный middleware защищает от превышения
* этого лимита, автоматически задерживая запросы, если они поступают слишком часто.
*
* ⚙️ **Как это работает:**
* - Лимит берётся из свойства `limit` адаптера платформы (`platformAdapter.limit`).
* Если свойство не задано или равно 0, ограничение не применяется.
* - Для каждой комбинации `{platform}:{userId}` ведётся отдельная очередь и счётчик запросов.
* - Счётчик сбрасывается каждую секунду, что позволяет точно соблюдать лимит в скользящем окне.
* - Если лимит исчерпан, запрос помещается в очередь и будет выполнен, когда появится свободное «окно».
* - Очередь имеет максимальный размер (`maxQueueSize`); при переполнении выбрасывается ошибка.
* - Запросы в очереди выполняются с равномерной задержкой (⌈1000/limit⌉ мс), чтобы не превышать лимит.
* - Неактивные записи (без запросов дольше `inactivityTimeout`) автоматически удаляются из памяти.
*
* 🧠 **Важные особенности:**
* - Middleware применяется **только к входящим запросам** (webhook). Для исходящих уведомлений
* ограничение нужно реализовывать непосредственно в адаптерах платформ.
* - Функцию необходимо **вызвать** при подключении: `bot.use(rateLimiter())`.
* - Все внутренние таймеры используют `unref()`, поэтому не блокируют завершение процесса.
*
* @param maxQueueSize - Максимальное количество ожидающих запросов в очереди для одного ключа (по умолчанию 100).
* При превышении очередь перестаёт принимать новые запросы и выбрасывается исключение.
* @param inactivityTimeout - Время в миллисекундах, после которого запись (очередь + счётчик) удаляется,
* если не было активности. По умолчанию 60000 (1 минута).
* @returns Middleware-функция для использования в `bot.use()`.
*
* @example
* ```ts
* import { rateLimiter } from 'umbot/middleware';
*
* // Подключаем middleware с параметрами по умолчанию
* bot.use(rateLimiter());
*
* // Или с кастомными настройками
* bot.use(rateLimiter(200, 120000));
* ```
*
* @remarks
* Чтобы лимит заработал для вашей платформы, добавьте в соответствующий адаптер публичное поле `limit`:
* ```ts
* export class TelegramAdapter extends BasePlatform {
* public limit = 30;
* // ...
* }
* ```
*/
export declare function rateLimiter(maxQueueSize?: number, inactivityTimeout?: number): (ctx: BotController, next: MiddlewareNext) => Promise<void>;