Создает тестовое приложение. Контроллер опционален — если не передан, используется BaseBotController.
Optionaltype: stringТип платформы (по умолчанию автоопределение)
OptionalbotController: TBotControllerClassКласс контроллера с логикой приложения
Созданный экземпляр BotTest
Protected_botControllerProtected_contentПолученный запрос от пользователя. Может быть JSON-строкой, текстом или null
Protected_clearStateОчищает состояние пользователя
Protected_setBotControllerProtectedУстановка контроллера. Используется только для тестирования
Регистрирует обработчик нажатия кнопки по её payload — аналог bot.action()
в популярных фреймворках.
Работает поверх обычных команд: addAction('buy', ...) эквивалентен
addCommand('buy', ['buy'], ...), но сигналит читателю кода, что триггер —
нажатие кнопки, а не текст. Payload кнопки задаётся третьим аргументом
buttons.addBtn('Купить', '', 'buy') или объектом { command: 'buy' }.
Имя действия (должно совпадать с payload кнопки)
Обработчик. Получает текст нажатой кнопки и BotController.
Поддерживает async и возврат строки-ответа, как addCommand.
Текущий экземпляр Bot для цепочки вызовов
Адаптеры Telegram, VK и MAX нормализуют payload callback-кнопок: если
payload — строка 'buy' или JSON {"command":"buy"}, в userCommand
попадает buy, и команда срабатывает как обычная. Для платформ без
callback-кнопок (Алиса, Маруся) обработчик не вызовется — кнопки там
отправляют текст, который матчится штатным слотом.
Регистрирует команду — обработчик, срабатывающий при совпадении входящего текста с одним из шаблонов.
Поиск команд оптимизирован:
Первая совпавшая команда выполняется.
Уникальное имя команды (например, 'greeting'). Используется для логирования и отладки.
Массив шаблонов для сопоставления:
text.includes(...))..test(text)).isPattern = true строковые слоты компилируются в одно объединённое
регулярное выражение с флагом ium.slots — готовые RegExp, isPattern для строк
не применяется (строк нет): каждый элемент обрабатывается по своему типу.Обработчик команды. Принимает:
text — нормализованный текст пользователя (userCommand: нижний регистр, обрезка;
исходный текст доступен в controller.originalUserCommand);controller — экземпляр BotController для формирования ответа (кнопки, текст, шаги, данные и т.д.);Поддерживает async.
Если true и в slots нет RegExp, все строки преобразуются в регулярные выражения.
⚠️ Используйте с осторожностью: возможен ReDoS. Все RegExp проверяются на уязвимости.
Простая текстовая команда:
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) => {
// Доступ к пользовательским данным
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.example.com/weather?city=Москва');
controller.text = `Погода: ${await weather.text()}`;
});
// Fallback: срабатывает, если ни одна команда не подошла:
bot.addCommand('*', [], (text, controller) => {
controller.text = `Извините, я не понял "${text}". Скажите "помощь" для списка команд.`;
});
Поиск команд оптимизирован:
При регистрации более 300 команд с регулярными выражениями фреймворк автоматически объединяет их в группы для повышения производительности.
При isPattern=true используются регулярные выражения JavaScript В callback доступен весь функционал BotController Можно использовать async функции в callback
Регистрирует обработчик события платформы (фото, голосовое, нажатие кнопки и др.).
Это декларативный роутинг по типу апдейта — аналог bot.on(':photo') в
Telegram-фреймворках, но для всех подключённых платформ сразу. Адаптер
определяет тип события и записывает его в controller.eventType; обработчики
вызываются до поиска шагов и команд.
Универсальный тип события
Обработчик. Получает BotController. Может:
ctx.text/ctx.buttons — обработка завершится (событие перехвачено);false — «событие не моё», конвейер продолжится штатно;async — фреймворк дожидается результата.Текущий экземпляр Bot для цепочки вызовов
Какие события бывают (см. TEventType): 'message', 'photo', 'voice',
'video', 'document', 'location', 'contact', 'sticker', 'callback',
'inline', 'message_edited', 'channel_post', 'start', 'subscribed',
'unsubscribed', 'auth', 'rating'.
Платформа сама определяет, какие события возможны: у Алисы нет фото, у VK нет inline-режима. Обработчик просто не вызовется там, где событие физически невозможно — это корректное поведение для мультиплатформенного бота.
Событие 'message' — обычный текстовый ввод. Обработчик на него перехватывает
все текстовые запросы; возвращайте false, чтобы передать запрос обычному
конвейеру (шаги → команды → интенты → fallback).
// Фото от пользователя — без ручного разбора requestObject
bot.addEvent('photo', (ctx) => {
ctx.text = 'Отличное фото!';
});
// Нажатие inline-кнопки (payload в ctx.payload)
bot.addEvent('callback', (ctx) => {
ctx.text = `Вы нажали: ${String(ctx.payload)}`;
});
// Групповой «фильтр»: перехватываем сообщение, но отдаём его командам
bot.addEvent('message', (ctx) => {
if (ctx.userEvents?.auth?.status) return false; // идём в обычный конвейер
ctx.text = 'Перехвачено!';
});
Регистрирует многошаговую форму (опросник) с автоматической последовательностью шагов.
Под капотом создаётся цепочка addStep — по одному на каждое поле. Состояние формы
(частичные ответы) сохраняется в ctx.userData.__formdata_<formName>.
Чтобы запустить форму из команды, вызовите ctx.thisIntentName = '__form_<formName>_0' —
тогда следующий ответ пользователя пойдёт в обработчик первого поля.
— Уникальное имя формы. Используется как префикс для шагов
и для ключа __formdata_<formName> в userData. Рекомендуется формат
идентификатора [a-zA-Z_$][\w$]* (с точками для dotted-имён) — генератор
шагов использует это имя в названиях __form_* (валидации в коде нет).
— Настройки формы: поля, onComplete, cancelText и т.п.
Текущий экземпляр Bot (для цепочки).
Метод использует зарезервированные префиксы:
__form_<formName>_<idx>userData.__formdata_<formName>Не создавайте свои команды, шаги или поля userData с такими префиксами —
они будут перезаписаны или удалены при removeForm.
bot.addForm('registration', {
fields: [
{ name: 'name', prompt: 'Как вас зовут?', validate: (v) => v.length > 0 },
{ name: 'email', prompt: 'Ваш email?', validate: (v) => /\S+@\S+/.test(v) || 'Некорректный email' },
{ name: 'age', prompt: 'Сколько вам лет?', validate: (v) => +v > 0 || 'Возраст должен быть числом' },
],
onComplete: (ctx, answers) => {
ctx.text = `Спасибо, ${answers.name}!`;
},
});
// Запуск из команды
bot.addCommand('start_signup', ['зарегистрироваться'], (_, ctx) => {
ctx.thisIntentName = '__form_registration_0';
ctx.text = 'Как вас зовут?'; // первый prompt
});
Регистрирует обработчик для именованного шага диалога.
Шаг — это часть многошагового сценария (например: "регистрация", "оформление заказа").
После вызова ctx.thisIntentName = 'myStep' в команде или другом шаге,
следующее сообщение пользователя будет обработано этим обработчиком.
💡 Обработчик получает полный
BotController, как и в командах: доступныthis.text,this.userData,this.buttonsи т.д.
— Уникальное имя шага (например, 'enter_email').
— Функция, вызываемая при получении сообщения в этом шаге.
Может вернуть false, чтобы пропустить шаг и передать управление командам.
Текущий экземпляр 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; // сбрасываем шаг
});
Удаляет все зарегистрированные команды
⚠️ Это глобальная операция: все сценарии станут недоступны. Используйте с осторожностью (например, при перезагрузке логики приложения).
Текущий экземпляр Bot для цепочки вызовов
Удаляет все зарегистрированные платформы, плагины и middleware службы.
Для каждого объектного плагина вызывается метод destroy().
⚠️ Это глобальная операция: все адаптеры и middleware станут недоступны. Команды и шаги при этом не удаляются — для их очистки используйте
clearCommands()/clearSteps().
Текущий экземпляр Bot.
Корректно завершает работу встроенного HTTP-сервера (если он был запущен через start). Ожидает завершения всех текущих запросов, освобождает сетевые ресурсы и отменяет все активные асинхронные операции, связанные с жизненным циклом приложения.
Метод безопасен для повторного вызова.
Завершается, когда сервер остановлен и все ресурсы освобождены.
Возвращает контекст приложения — центральный объект для расширенной настройки фреймворка.
Когда использовать:
bot.getAppContext().httpClient = customFetchbot.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().
Контекст приложения
ProtectedgetSkillContentProtectedФормирует конфигурацию для тестирования конкретной платформы. Создает структуру данных, соответствующую формату выбранной платформы
Пользовательский запрос
Номер сообщения в диалоге
Данные из хранилища
Конфигурация для выбранной платформы
Переустанавливает класс контроллера и обновляет переиспользуемый тестовый экземпляр.
Новый класс контроллера
Текущий экземпляр для цепочки вызовов
Удаляет все обработчики указанного события.
Тип события
Текущий экземпляр Bot для цепочки вызовов
Удаляет зарегистрированную многошаговую форму по имени.
После удаления форма больше не будет обрабатываться, даже если она активна у пользователя.
(Рекомендуется завершать активные сценарии через ctx.thisIntentName = null перед удалением.)
— Имя формы для удаления.
Текущий экземпляр Bot.
Сравнение идёт по префиксу __form_<formName>_. Осторожно: если у вас
есть формы user и user_2, вызов removeForm('user') также удалит
шаги формы user_2 (её имя начинается с __form_user_).
Чтобы избежать этого, выбирайте formName с уникальным суффиксом,
не являющимся префиксом другой формы (например, signup vs signupV2).
Удаляет зарегистрированный шаг по имени.
После удаления шаг больше не будет обрабатываться, даже если активен у пользователя.
(Рекомендуется завершать активные сценарии через ctx.thisIntentName = null перед удалением.)
— Имя шага для удаления.
Текущий экземпляр Bot.
Запускает обработку запроса Не рекомендуется вызывать самостоятельно, ответственность за вызов метода лежит на классе.
OptionalappType: string | nullТип платформы. Если не передан, принудительно используется alisa (автоопределение в BotTest не выполняется)
Optionalcontent: string | nullСодержимое запроса
Результат обработки запроса
Отправка текста пользователю Этот метод используется для активных рассылок — когда голосовой навык или чат-бот инициирует диалог первым (например, уведомление). Метод делегирует отправку соответствующему адаптеру платформы.
Если платформа не поддерживает возможность начать диалог самостоятельно, то вернется false
Ид пользователя, которому нужно отправить сообщение
Контроллер приложения или текст. Если необходимо отправить просто текст, можно передать строку, в случае, если необходимо передать картинку звук и тд, то необходимо корректно заполнить контроллер.
Платформа, на которую необходимо отправить запрос
Результат отправки (формат зависит от адаптера платформы) или false, если платформа не зарегистрирована/не поддерживает проактивную отправку
Задаёт инфраструктурную конфигурацию приложения: подключение к БД, загрузку .env, и другие
настройки, связанные с окружением выполнения (а не с бизнес-логикой приложения).
🔒 Безопасность: никогда не храните секреты (пароли, токены, API-ключи) прямо в коде. Всегда используйте
.env-файлы или переменные окружения.
Конфигурация приложения
Текущий экземпляр Bot для цепочки вызовов
Устанавливает режим работы приложения
Режим работы:
⚠️ ВАЖНО: В продакшене всегда используйте 'strict_prod' для защиты от атак через регулярные выражения. Режим 'prod' оставлен для обратной совместимости, но небезопасен.
Текущий экземпляр Bot для цепочки вызовов
Задает режим работы с регулярными выражениями. При значении auto, регулярные выражения будут группироваться в группу, благодаря чему уменьшается время обработки. Логика начинает отрабатывать после того, как добавили более 300 команд с регулярными выражениями. При значении no-group, группировка регулярных выражений производиться не будет, из-за чего каждое регулярное выражение будет обрабатываться отдельно. Указывать данное значение стоит в том случае, если вы получаете сильную деградацию при обработке групп. При значении group, все регулярные выражения будут добавляться в группу. Перед использованием данного значения, перепроверьте производительность, так как при группировке определенных регулярных выражений, производительность может быть ниже.
Определяет режим работы с регулярными выражениями.
Текущий экземпляр Bot для цепочки вызовов
Устанавливает контент запроса. Задаёт входящие данные запроса, которые обработает run. Не рекомендуется использовать напрямую, использовать только в крайнем случае, либо для тестов
Контент запроса
Позволяет заменить встроенный механизм сопоставления команд на кастомный алгоритм поиска.
По умолчанию umbot использует оптимизированный поиск:
includes),Это обеспечивает предсказуемость, простоту отладки и соответствие поведению большинства платформ: первая совпавшая команда (в порядке регистрации) — выигрывает.
Однако при:
Функция вида (userCommand: string, commands: Map<string, ICommandParam>) => string | null | Promise<string | null>.
Должна вернуть имя команды или null, если совпадений нет.
Текущий экземпляр Bot для цепочки вызовов
// Пример: кэширование частых запросов
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'а:
fuse.js, natural или trie-структуры.Позволяет установить свою реализацию для логирования
Экземпляр логгера или null для отключения
Текущий экземпляр Bot для цепочки вызовов
Задаёт параметры, управляющие логикой приложения на всех платформах.
Сюда входят:
help, welcome и др.),welcome_text, help_text, empty_text),Параметры платформы
Текущий экземпляр Bot для цепочки вызовов
Устанавливает кастомный обработчик для определения типа платформы.
По умолчанию фреймворк определяет платформу автоматически, перебирая зарегистрированные адаптеры
и вызывая их метод isPlatformOnQuery. Этот метод позволяет переопределить логику определения,
что полезно в следующих случаях:
Важно: резолвер выполняется до вызова isPlatformOnQuery любого адаптера.
Если резолвер возвращает строку (имя платформы), фреймворк использует это значение
и не выполняет стандартное автоопределение. Если возвращает null, то запускается
стандартный перебор адаптеров.
В резолвер передаётся опциональная функция detect, которая вызывает встроенное
автоопределение. Это позволяет, например, получить результат стандартного определения
и затем скорректировать его.
Функция, принимающая запрос, заголовки и опционально detect.
Должна вернуть имя платформы (строка) или null.
Тот же экземпляр приложения для цепочечных вызовов.
// Простейший резолвер, который для всех запросов использует платформу 'alisa'
bot.setPlatformResolver(() => 'alisa');
// Резолвер, который вызывает стандартное определение и при необходимости
// заменяет результат для конкретного заголовка.
bot.setPlatformResolver((query, headers, detect) => {
const platform = detect?.(query, headers);
if (platform === 'telegram' && headers?.['x-force-vk']) {
return 'vk';
}
return platform;
});
// Полное переопределение: обработка запросов от собственного сервиса.
bot.setPlatformResolver((query) => {
if (typeof query === 'object' && query?.source === 'my_service') {
return 'my_platform';
}
return null;
});
query или headers, если нужно повлиять
на дальнейшую обработку (например, добавить недостающие поля).Упрощённый способ вызвать bot.run(...) с автоматической подготовкой query.
Если запрашиваемая платформа зарегистрирована в platforms — используется её
getQueryExample для генерации валидного payload. Иначе метод выбрасывает
исключение (throw new Error).
Текст пользователя (например, "привет")
Параметры симуляции: platform, userId, count, state
Ответ платформы (результат run())
На время симуляции включается skipAutoReply, поэтому чат-платформы
(Telegram, VK, Viber, Max) НЕ отправляют сообщение в реальное API —
их getContent() возвращает 'ok'. Текст ответа в этом случае остаётся
в text контроллера. Для голосовых платформ результатом будет готовый
JSON-ответ платформы (например, res.response.text).
const tester = new BotTest();
tester.use(new AlisaAdapter());
tester.addCommand('start', ['привет'], (_, ctx) => { ctx.text = 'Привет!'; });
// Голосовая платформа: ответ приходит в формате платформы
const res = await tester.simulate('привет', { platform: 'alisa' }) as {
response: { text: string };
};
console.log(res.response.text); // 'Привет!'
// Чат-платформа: отправка в API пропускается, результат — 'ok',
// а текст ответа доступен через контроллер
tester.use(new TelegramAdapter('token'));
await tester.simulate('привет', { platform: 'telegram' }); // 'ok'
Запускает встроенный HTTP-сервер на указанном хосте и порте для приёма webhook-запросов
от поддерживаемых платформ. Сервер использует нативный http.createServer.
Метод возвращает экземпляр http.Server, что позволяет, например, корректно
остановить сервер или добавить обработчики событий ('listening', 'error' и т.д.).
Если требуется интеграция с фреймворком (например, Express, Fastify и др.), рекомендуется использовать webhookHandle как middleware-обработчик.
Имя хоста
Порт
OptionalresponseCb: TBotResponseCbCallback, для пользовательской обработки ответа пользователю. Стоит использовать в том случае, если есть необходимость переопределить стандартный ответ фреймворка.
Экземпляр http.Server для управления сервером
// Запуск встроенного сервера
const bot = new Bot();
bot.start('0.0.0.0', 8080);
// Интеграция с Express (вместо встроенного сервера)
// webhookHandle сам читает тело запроса — не подключайте express.json().
import express from 'express';
import { Bot } from 'umbot';
const bot = new Bot();
const app = express();
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(...);// Какое-то содержимое страницы
});
Запускает интерактивное тестирование приложения.
Позволяет вводить команды и получать ответы в консоли.
Также, если не задан setAppMode равный strict_prod, то режим автоматически выставится в dev
Optionalparams: IBotTestParams = {}Параметры тестирования
Регистрирует middleware, вызываемый до выполнения BotController.action().
Middleware получает доступ к полному BotController (включая text, isEnd, userData, buttons и т.д.)
и может:
next())Middleware-функция
Текущий экземпляр Bot для цепочки вызовов
Регистрирует middleware, вызываемый только для указанной платформы.
Идентификатор платформы (alisa, telegram, vk, и т.д.)
Middleware-функция
Текущий экземпляр Bot
Регистрирует плагин — объект, расширяющий функциональность приложения.
Плагин может быть функцией или объектом (классом).
Для функции обязательно должен быть выставлен флаг isPlugin = true
(иначе она будет принята за middleware) — проще использовать хелпер createPlugin().
Для объекта (класса) должен быть реализован метод init(appContext: AppContext, bot: Bot).
— Объект плагина, совместимый с TPlugin.
Текущий экземпляр Bot.
Обрабатывает входящее событие от серверлесс-платформы (например, Yandex Cloud Functions)
с предварительной проверкой подлинности запроса через isCorrectQuery соответствующей платформы.
Зачем это нужно: В отличие от run, метод принимает заголовки запроса и выполняет ту же проверку webhook-токена/подписи, что и webhookHandle. Это защищает cloud-функцию от поддельных запросов: если у платформы задан секрет вебхука, запрос без корректной подписи будет отклонён со статусом 401 до выполнения какой-либо логики.
Когда использовать:
IncomingMessage/ServerResponse для webhookHandle.Тело запроса. Рекомендуется передавать сырую строку (как она пришла от платформы), чтобы проверка подписи (HMAC) считалась от исходного тела.
Optionalheaders: Record<string, unknown> = {}Заголовки запроса (для проверки подписи и авторизации).
OptionalclientIp: stringIP-адрес клиента (опционально, для middleware и логирования).
Объект с HTTP-статусом и телом ответа для возврата из cloud-функции.
// Обработчик Yandex Cloud Function
export const handler = async (event: Record<string, unknown>) => {
const result = await bot.webhookEvent(event.body, event.headers);
return {
statusCode: result.statusCode,
headers: { 'Content-Type': 'application/json' },
body: typeof result.body === 'string' ? result.body : JSON.stringify(result.body),
};
};
Обрабатывает входящий webhook-запрос от поддерживаемой платформы (Telegram, VK, Алиса и др.).
Метод автоматически распознаёт платформу по заголовкам или телу запроса и делегирует обработку
соответствующему адаптеру. Ответ отправляется автоматически через переданный объект res.
Объект входящего запроса (IncomingMessage или совместимый)
Объект ответа (ServerResponse или совместимый)
OptionalresponseCb: TBotResponseCbCallback, для пользовательской обработки ответа пользователю. Стоит использовать в том случае, если есть необходимость переопределить стандартный ответ фреймворка. Если передан, ВЫ ДОЛЖНЫ вызвать res.end() самостоятельно. Без колбэка фреймворк автоматически завершит ответ через res.end().
// Использование с Express
// Важно: НЕ подключайте express.json() перед обработчиком —
// webhookHandle сам читает тело запроса, а парсер съест стрим.
import express from 'express';
const app = express();
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);
Класс для тестирования созданного навыка/бота через консольный интерфейс. Позволяет протестировать логику вашего приложения без предварительной публикации. Также предоставляет интерактивный режим для отладки и тестирования функциональности. Для того чтобы протестировать необходимую платформу, необходимо указать
appType, в случае если значение не указано или установлено в auto, то для тестирования будет использоваться первая платформа.⚠️ Особенность
run()без явногоappType: он принудительно используетalisa(а не первую зарегистрированную платформу) — поэтому при тестировании только чат-платформ передавайтеappTypeявно:bot.run('telegram', ...). Интерактивныйtest()использует первую зарегистрированную платформу, как описано выше.Example