umbot
    Preparing search index...

    Класс для тестирования бота. Предоставляет интерактивный режим для отладки и тестирования функциональности. Для того чтобы протестировать необходимую платформу, необходимо указать appType, в случае если значение не указано или установлено в auto, то для тестирования будет использоваться первая платформа.

    const botTest = new BotTest();
    botTest.setPlatformParams({
    intents: [{
    name: 'greeting',
    slots: ['привет', 'здравствуйте']
    }]
    });
    botTest.initBotController(MyController);

    // Запуск тестирования
    await botTest.test({
    isShowResult: true,
    isShowStorage: true
    });

    Hierarchy (View Summary)

    Index

    Constructors

    Properties

    _botController: BotController
    _content: TBotContent = null

    Полученный запрос от пользователя. Может быть JSON-строкой, текстом или null

    Accessors

    • get appType(): string

      Возвращает установленный тип приложения.

      Returns string

    • set appType(appType: string): void

      Явно устанавливает тип платформы для всего приложения. Стоит использовать в крайнем случае

      Parameters

      • appType: string

      Returns void

    Methods

    • Регистрирует команду — обработчик, срабатывающий при совпадении входящего текста с одним из шаблонов.

      Поиск команд оптимизирован:

      1. Сначала проверяется точное совпадение
      2. Если точного совпадения нет — выполняется последовательный перебор в порядке регистрации

      Первая совпавшая команда выполняется.

      Type Parameters

      Parameters

      • commandName: string

        Уникальное имя команды (например, 'greeting'). Используется для логирования и отладки.

      • slots: TSlots

        Массив шаблонов для сопоставления:

        • Если элемент — строка → ищется как подстрока (text.includes(...)).
        • Если элемент — RegExp → проверяется как регулярное выражение (.test(text)).
        • Параметр isPattern учитывается только если в slots нет RegExp.
        • При наличии хотя бы одного RegExp, isPattern = false игнорируется, и каждый элемент обрабатывается согласно своему типу.
      • cb: (
            userCommand: string,
            botController: TBotController,
        ) => string | void | Promise<string | void>

        Обработчик команды. Принимает:

        • text — исходный текст от пользователя;
        • controller — экземпляр BotController для формирования ответа (кнопки, текст, шаги, данные и т.д.);

        Поддерживает async.

      • isPattern: boolean = false

        Если true и в slots нет RegExp, все строки преобразуются в регулярные выражения. ⚠️ Используйте с осторожностью: возможен ReDoS. Все RegExp проверяются на уязвимости.

      Returns this

      Простая текстовая команда:

      bot.addCommand(
      'greeting',
      ['привет', 'здравствуй'],
      (cmd, ctrl) => {
      ctrl.text = 'Здравствуйте!';
      }
      );

      Команда с регулярными выражениями:

      // Обработка чисел от 0 до 999
      bot.addCommand(
      'number',
      ['\\b(\\d{0,3})\\b'],
      (cmd, ctrl) => {
      ctrl.text = `Вы ввели число: ${cmd}`;
      },
      true // включаем поддержку регулярных выражений
      );

      Команда с доступом к состоянию:

      bot.addCommand(
      'stats',
      ['статистика'],
      async (cmd, ctrl) => {
      if (ctrl) {
      // Доступ к пользовательским данным
      const visits = ctrl.userData?.visits || 0;
      ctrl.text = `Вы использовали бота ${visits} раз`;

      // Доступ к кнопкам и другим UI элементам
      ctrl.buttons
      .addBtn('Сбросить статистику')
      .addBtn('Закрыть');
      }
      }
      );

      // Асинхронная команда (работа с API):

      bot.addCommand('weather', ['погода'], async (text, controller) => {
      const weather = await fetch('https://api.weather.com');
      controller.text = `Погода: ${await weather.text()}`;
      });

      // Fallback: срабатывает, если ни одна команда не подошла:

      bot.addCommand('*', [], (text, controller) => {
      controller.text = `Извините, я не понял "${text}". Скажите "помощь" для списка команд.`;
      });

      Поиск команд оптимизирован:

      1. Сначала проверяется точное совпадение
      2. Если точного совпадения нет — выполняется последовательный перебор

      При регистрации более 300 команд с регулярными выражениями фреймворк автоматически объединяет их в группы для повышения производительности.

      При isPattern=true используются регулярные выражения JavaScript В callback доступен весь функционал BotController Можно использовать async функции в callback

    • Регистрирует обработчик для именованного шага диалога.

      Шаг — это часть многошагового сценария (например: "регистрация", "оформление заказа"). После вызова ctx.thisIntentName = 'myStep' в команде или другом шаге, следующее сообщение пользователя будет обработано этим обработчиком.

      💡 Обработчик получает полный BotController, как и в командах: доступны this.text, this.userData, this.buttons и т.д.

      Type Parameters

      Parameters

      • stepName: string

        — Уникальное имя шага (например, 'enter_email').

      • handler: (botController: TBotController) => void | Promise<void>

        — Функция, вызываемая при получении сообщения в этом шаге.

      Returns this

      Текущий экземпляр Bot (для цепочки вызовов).

      bot.addCommand('start', ['начать'], (_, ctx) => {
      ctx.text = 'Готовы начать приключение?';
      ctx.buttons.addBtn('Да').addBtn('Нет');
      ctx.thisIntentName = 'confirm';
      });
      bot.addStep('confirm', (ctx) => {
      if (ctx.userCommand === 'да') {
      ctx.text = 'Отлично! Добро пожаловать.';
      } else {
      ctx.text = 'Извините, вход запрещён.';
      ctx.thisIntentName = 'goodbye'; // переходим к другому шагу
      }
      });
      // Пример многошаговой формы
      bot.addCommand('order', ['заказать'], (_, ctx) => {
      ctx.text = 'Введите ваше имя:';
      ctx.thisIntentName = 'step_name';
      });

      bot.addStep('step_name', (ctx) => {
      ctx.userData.name = ctx.userCommand;
      ctx.text = `Приятно познакомиться, ${ctx.userData.name}! Теперь введите email:`;
      ctx.thisIntentName = 'step_email';
      });

      bot.addStep('step_email', (ctx) => {
      ctx.userData.email = ctx.userCommand;
      ctx.text = `Заказ оформлен! Имя: ${ctx.userData.name}, Email: ${ctx.userData.email}`;
      ctx.thisIntentName = null; // сбрасываем шаг
      });
    • Удаляет все зарегистрированные команды

      ⚠️ Это глобальная операция: все сценарии станут недоступны. Используйте с осторожностью (например, при перезагрузке логики бота).

      Returns this

    • Удаляет все зарегистрированные шаги.

      ⚠️ Это глобальная операция: все сценарии станут недоступны. Используйте с осторожностью (например, при перезагрузке логики бота).

      Returns this

      Текущий экземпляр Bot.

    • Удаляет все зарегистрированные платформы, плагины и middleware службы.

      ⚠️ Это глобальная операция: все сценарии станут недоступны. Используйте с осторожностью (например, при перезагрузке логики бота).

      Returns this

      Текущий экземпляр Bot.

    • Корректно завершает работу встроенного HTTP-сервера (если он был запущен через start). Ожидает завершения всех текущих запросов, освобождает сетевые ресурсы и отменяет все активные асинхронные операции, связанные с жизненным циклом бота.

      Метод безопасен для повторного вызова.

      Returns Promise<void>

      Завершается, когда сервер остановлен и все ресурсы освобождены.

      const bot = new Bot();
      bot.start('localhost', 3000);

      // ... позже, при завершении приложения
      await bot.close();
    • Возвращает контекст приложения — центральный объект для расширенной настройки фреймворка.

      Когда использовать:

      • Замена HTTP-клиента: bot.getAppContext().httpClient = customFetch
      • Доступ к зарегистрированным адаптерам: bot.getAppContext().platforms
      • Настройка метрик и логирования

      Пример:

      // Добавление таймаутов к запросам
      const customFetch: THttpClient = async (url, init) => {
      const controller = new AbortController();
      const timeout = setTimeout(() => controller.abort(), 5000);
      return fetch(url, { ...init, signal: controller.signal });
      };

      bot.getAppContext().httpClient = customFetch;

      ⚠️ Важно: Не модифицируйте внутренние поля контекста напрямую (например, commands, steps). Используйте публичные методы addCommand(), addStep

      Returns AppContext

    • Protected

      Формирует конфигурацию для тестирования конкретной платформы. Создает структуру данных, соответствующую формату выбранной платформы

      Parameters

      • query: string

        Пользовательский запрос

      • count: number

        Номер сообщения в диалоге

      • state: string | Record<string, unknown>

        Данные из хранилища

      Returns unknown

      Конфигурация для выбранной платформы

    • Устанавливает контроллер, метод action() которого вызывается после обработки каждого запроса — независимо от того, была ли распознана команда, активен ли шаг сценария, или обработан базовый интент.

      Метод action() получает флаги isCommand и isStep, чтобы вы могли:

      • добавить общую логику (аналитика, логирование, трассировка);
      • модифицировать ответ глобально (например, добавить рекламу, кнопку "Оценить");
      • применить кросс-функциональные правила (rate limiting, мутации текста и т.д.);

      💡 Рекомендация: основную бизнес-логику размещайте в командах (addCommand) и шагах (addStep), а в action() — только сквозную логику, которую не хочется дублировать.

      Контроллер по умолчанию уже обрабатывает интенты welcome, help и fallback, но вы можете заменить его, если нужно кастомное поведение.

      Parameters

      • fn: TBotControllerClass

        Экземпляр контроллера, наследующий BotController<TUserData>

      Returns this

      class MyController extends BotController {
      public action(intentName: string): void {
      switch (intentName) {
      case 'greeting':
      this.text = 'Привет!';
      break;
      case 'help':
      this.text = 'Чем могу помочь?';
      break;
      }
      }
      }

      bot.initBotController(MyController);
      // Добавление рекламы ко всем ответам
      class MyController extends BotController {
      public action(
      intentName: string | null,
      isCommand: boolean = false,
      isStep: boolean = false
      ): void {
      // Добавим кнопку "Подписаться" везде, кроме шагов
      if (!isStep) {
      this.buttons.addBtn('Подписаться на рассылку', 'https://example.com');
      }

      // Логирование
      console.log(`Обработано: ${isCommand ? 'команда' : isStep ? 'шаг' : 'интент'}${intentName}`);
      }
      }

      bot.initBotController(MyController);
    • Удаляет зарегистрированную команду по имени

      Parameters

      • commandName: string

        Имя команды

      Returns this

    • Удаляет зарегистрированный шаг по имени.

      После удаления шаг больше не будет обрабатываться, даже если активен у пользователя. (Рекомендуется завершать активные сценарии через ctx.clearStep() перед удалением.)

      Parameters

      • stepName: string

        — Имя шага для удаления.

      Returns this

      Текущий экземпляр Bot.

    • Запуск обработку запроса Не рекомендуется вызывать самостоятельно, ответственность за вызов метода лежит за классом.

      Parameters

      • OptionalappType: string | null
      • Optionalcontent: string | null

      Returns Promise<TRunResult>

    • Отправка текста пользователю Этот метод используется для активных рассылок — когда бот инициирует диалог первым (например, уведомление). В методе реализована механика преобразования текстового значения controllerOrText в контроллер, а также базовый механизм для отправки ответа.

      Если платформа не поддерживает возможность начать диалог самостоятельно, то вернется false

      Parameters

      • userId: string | number

        Ид пользователя, которому нужно отправить сообщение

      • controllerOrText: string | BotController<IUserData, IPlatformData>

        Контроллер приложения или текст. Если необходимо отправить просто текст, можно передать строку, в случае, если необходимо передать картинку звук и тд, то необходимо корректно заполнить контроллер.

      • platform: string

        Платформа, на которую необходимо отправить запрос

      Returns Promise<unknown>

    • Задаёт инфраструктурную конфигурацию приложения: подключение к БД, загрузку .env, и другие настройки, связанные с окружением выполнения (а не с бизнес-логикой бота).

      🔒 Безопасность: никогда не храните секреты (пароли, токены, API-ключи) прямо в коде. Всегда используйте .env-файлы или переменные окружения.

      Parameters

      • config: Partial<IAppConfig>

        Конфигурация приложения

      Returns this

      // Конфигурация с базой данных
      bot.setAppConfig({
      db: {
      host: 'localhost',
      database: 'bot_db',
      user: 'user',
      pass: 'password'
      }
      });


      @remarks
      Важно! Чувствительные данные рекомендуется сохранять в .env файл, передав путь к нему:
      ```ts
      bot.setAppConfig({
      env: './.env', // путь до файла
      });
    • Устанавливает режим работы приложения

      Parameters

      • appMode: TAppMode

        Режим работы:

        • 'dev': подробные логи, отладочная информация, отключена проверка ReDoS
        • 'prod': минимальные логи, производительность, НО небезопасные регулярки всё равно регистрируются
        • 'strict_prod': строгая проверка безопасности — любая регулярка с потенциальным ReDoS отклоняется с ошибкой

        ⚠️ ВАЖНО: В продакшене всегда используйте 'strict_prod' для защиты от атак через регулярные выражения. Режим 'prod' оставлен для обратной совместимости, но небезопасен.

      Returns this

      // Для продакшена (обязательно!)
      bot.setAppMode('strict_prod');

      // Для разработки
      bot.setAppMode('dev');
    • Задает режим работы с регулярным выражениями. При значении auto, регулярные выражения будут группироваться в группу, благодаря чему уменьшается время обработки. Логика начинает отрабатывать после того, как добавили более 300 команд. При значении no-group, группировка регулярных выражений производиться не будет, из-за чего каждое регулярное выражение будет обрабатываться отдельно. Указывать данное значение стоит в том случае, если вы получаете сильную деградацию при обработке групп. При значении group, все регулярные выражения будут добавляться в группу. Перед использованием данного значения, перепроверьте производительность, так как при группировке определенных регулярных выражений, производительность может быть ниже.

      Parameters

      • mode: TCommandGroupMode

        Определяет режим работы с регулярными выражениями.

      Returns void

    • Устанавливает контент запроса. Используется для передачи данных от пользователя в бот. Не рекомендуется использовать напрямую, использовать только в крайнем случае, либо для тестов

      Parameters

      Returns void

      // Установка текстового сообщения
      bot.setContent('Привет!');

      // Установка JSON-данных
      bot.setContent({
      request: {
      command: 'привет',
      original_utterance: 'Привет, бот!'
      }
      });
    • Позволяет заменить встроенный механизм сопоставления команд на кастомный алгоритм поиска.

      По умолчанию umbot использует оптимизированный поиск:

      1. Сначала проверяется точное совпадение
      2. Если точного совпадения нет — выполняется последовательный перебор с поддержкой:
        • подстрок (includes),
        • простых регулярных выражений.

      Это обеспечивает предсказуемость, простоту отладки и соответствие поведению большинства платформ: первая совпавшая команда (в порядке регистрации) — выигрывает.

      Однако при:

      • количестве команд >1000,
      • высокой нагрузке (>1000 RPS),
      • необходимости в fuzzy-поиске или сложной маршрутизации, вы можете подключить оптимизированный resolver.

      Parameters

      • resolver: TCommandResolver

        Функция вида (userText: string, commands: Map<string, ICommand>) => string | null. Должна вернуть имя команды или null, если совпадений нет.

      Returns this

      // Пример: кэширование частых запросов
      const cache = new Map<string, string | null>();
      bot.setCustomCommandResolver((text, commands) => {
      if (cache.has(text)) return cache.get(text)!;

      for (const [name, cmd] of commands) {
      if (cmd.slots && cmd.slots.some(slot => typeof slot === 'string' && text.includes(slot))) {
      cache.set(text, name);
      return name;
      }
      }
      cache.set(text, null);
      return null;
      });

      Рекомендации при реализации resolver'а:

      • Сохраняйте порядок регистрации команд, если логика зависит от приоритета.
      • Используйте кэширование для часто встречающихся фраз (но учитывайте потребление памяти).
      • Для fuzzy-поиска — рассмотрите fuse.js, natural или trie-структуры.
      • При работе с регулярными выражениями обязательно проверяйте их на ReDoS.
      • Избегайте тяжёлых синхронных операций — они блокируют event loop.
    • Позволяет установить свою реализацию для логирования

      Parameters

      Returns void

    • Задаёт параметры, управляющие логикой бота на всех платформах.

      Сюда входят:

      • список интентов по умолчанию (help, welcome и др.),
      • тексты ответов по умолчанию (welcome_text, help_text, empty_text),
      • другие настройки, не зависящие от конкретной платформы

      Parameters

      • params: IAppParam

        Параметры платформы

      Returns this

      // Базовая настройка
      bot.setPlatformParams({
      intents: [{
      name: 'help',
      slots: ['помощь', 'справка']
      }],
      welcome_text: 'Привет! Я ваш бот.',
      help_text: 'Скажите "помощь", чтобы увидеть команды.',
      empty_text: 'Извините, я не понял.'
      });
    • Запускает встроенный HTTP-сервер на указанном хосте и порту для приёма webhook-запросов от поддерживаемых платформ. Сервер использует нативный http.createServer.

      Метод возвращает экземпляр http.Server, что позволяет, например, корректно остановить сервер или добавить обработчики событий ('listening', 'error' и т.д.).

      Если требуется интеграция с фреймворком (например, Express, Fastify и др.), рекомендуется использовать webhookHandle как middleware-обработчик.

      Parameters

      • hostname: string = 'localhost'

        Имя хоста

      • port: number = 3000

        Порт

      • OptionalresponseCb: TBotResponseCb

        Callback, для пользовательской обработки ответа пользователю. Стоит использовать в том случае, если есть необходимость переопределить стандартный ответ фреймворка.

      Returns Server

      webhookHandle

      // Запуск встроенного сервера
      const bot = new Bot();
      bot.start('0.0.0.0', 8080);

      // Интеграция с Express (вместо встроенного сервера)
      import express from 'express';
      import { Bot } from 'umbot';

      const bot = new Bot();
      const app = express();
      app.use(express.json());
      app.post('/webhook', (req, res) => bot.webhookHandle(req, res));

      app.listen(3000, () => {
      console.log('Bot listening on port 3000');
      });
      // Пример с переопределением ответа
      const bot = new Bot();
      // В случае если вернулся статус отличный от 200, вернет содержимое какой-то страницы.
      bot.start('0.0.0.0', 8080, (reg: IncomingMessage, _res: ServerResponse, state: IBotResponseState) => {
      if (state.statusCode === 200) {
      return state.defaultSend(_res, state);
      }
      res.statusCode = 200;
      res.end(...);// Какое-то содержимое страницы
      });
    • Запускает интерактивное тестирование бота Позволяет вводить команды и получать ответы в консоли

      Parameters

      • Optionalparams: IBotTestParams = {}

        Параметры тестирования

      Returns Promise<void>

      // Базовое тестирование
      await botTest.test();

      // Расширенное тестирование с отображением всех данных
      await botTest.test({
      isShowResult: true,
      isShowStorage: true,
      isShowTime: true
      });
    • Регистрирует middleware, вызываемый до выполнения BotController.action().

      Middleware получает доступ к полному BotController (включая text, isEnd, userData, buttons и т.д.) и может:

      • Модифицировать контекст
      • Прервать выполнение (если не вызвать next())
      • Выполнить логирование, tracing, rate limiting и др.

      Parameters

      Returns this

      Текущий экземпляр Bot для цепочки вызовов

      // Глобальный middleware (для всех платформ)
      bot.use(async (ctx, next) => {
      console.log('Запрос от:', ctx.appType);
      await next();
      });
    • Регистрирует middleware, вызываемый только для указанной платформы.

      Parameters

      • platform: string

        Идентификатор платформы (alisa, telegram, vk, и т.д.)

      • fn: MiddlewareFn

        Middleware-функция

      Returns this

      Текущий экземпляр Bot

      // Только для Алисы
      bot.use(T_ALISA, async (ctx, next) => {
      if (!ctx.appContext.requestObject?.session?.user_id) {
      ctx.text = 'Некорректный запрос';
      ctx.isEnd = true;
      // next() не вызывается → action() не запускается
      return;
      }
      await next();
      });
    • Регистрирует плагин — объект, расширяющий функциональность приложения.

      Плагин может быть как функцией, так и классом. Если он реализован как метод, то должен быть указан флаг isPlugin. В случае когда используется класс, то должен быть реализован метод init(appContext: AppContext)

      Parameters

      • plugin: TPlugin

        — Объект плагина, совместимый с TPlugin.

      Returns this

      Текущий экземпляр Bot.

      import {AlisaAdapter} from 'umbot/plugins'
      bot.use(new AlisaAdapter());
    • Обрабатывает входящий webhook-запрос от поддерживаемой платформы (Telegram, VK, Алиса и др.). Метод автоматически распознаёт платформу по заголовкам или телу запроса и делегирует обработку соответствующему адаптеру. Ответ отправляется автоматически через переданный объект res.

      Parameters

      • req: IncomingMessage

        Объект входящего запроса (IncomingMessage или совместимый)

      • res: ServerResponse

        Объект ответа (ServerResponse или совместимый)

      • OptionalresponseCb: TBotResponseCb

        Callback, для пользовательской обработки ответа пользователю. Стоит использовать в том случае, если есть необходимость переопределить стандартный ответ фреймворка. Если передан, ВЫ ДОЛЖНЫ вызвать res.end() самостоятельно. Без колбэка фреймворк автоматически завершит ответ через res.end().

      Returns Promise<void>

      // Использование с Express
      import express from 'express';
      const app = express();
      app.use(express.json());

      const bot = new Bot();

      app.post('/webhook', (req, res) => bot.webhookHandle(req, res));
      // Использование с встроенным HTTP-сервером Node.js
      import { createServer } from 'http';

      const bot = new Bot();
      const server = createServer((req, res) => {
      if (req.method === 'POST' && req.url === '/webhook') {
      bot.webhookHandle(req, res);
      } else {
      res.statusCode = 404;
      res.end();
      }
      });
      server.listen(3000);
      // Пример с переопределением ответа
      import { createServer } from 'http';

      const bot = new Bot();
      const server = createServer((req, res) => {
      if (req.method === 'POST' && req.url === '/webhook') {
      // В случае если вернулся статус отличный от 200, вернет содержимое какой-то страницы.
      bot.webhookHandle(req, res, (_reg: IncomingMessage, _res: ServerResponse, state: IBotResponseState) => {
      if (state.statusCode === 200) {
      return state.defaultSend(_res, state);
      }
      res.statusCode = 200;
      res.end(...);// Какое-то содержимое страницы
      });
      } else {
      res.statusCode = 404;
      res.end();
      }
      });
      server.listen(3000);