Создает новый экземпляр контроллера. UI-компоненты (кнопки, карточки, звуки, NLU) инициализируются лениво — при первом обращении через соответствующие геттеры.
OptionalappContext: AppContext<IDatabaseInfo, unknown>Контекст приложения. Если не передан, будет создан новый AppContext
Контекст приложения.
Стиль обращения к пользователю. Определяет формальность общения, используется для платформ, которые поддерживают данное поведение.
Платформа, от которой был получен запрос.
Эмоция для голосового ответа. Используется для платформ, которые поддерживают данное поведение.
Универсальный тип события, вызвавшего запрос ('message', 'photo', 'callback', …).
Заполняется адаптером платформы. Позволяет различать не-текстовые апдейты
(фото, голосовые, нажатия кнопок) без ручного разбора requestObject.
Если платформа не проставила событие, значение — 'message'.
Флаг необходимости авторизации. Определяет, требуется ли авторизация пользователя или нет.
Флаг, определяющий необходимость завершения диалога. Актуально когда необходимо принудительно завершить диалог с пользователем. Поддержка работы флага зависит от платформы.
Определяет, запущено ли приложение с колонки или с устройства с экраном.
Флаг отправки запроса на оценку. Определяет, нужно ли запросить оценку у пользователя. Используется для платформ, которые поддерживают данное поведение.
ID сообщения.
На голосовых платформах (Алиса, Маруся) messageId === 0 означает начало
нового диалога — по этому признаку срабатывает welcome-интент. На чат-платформах
(Telegram, VK, Max, Viber) это ID конкретного сообщения, и поле может быть null.
Название предыдущего интента/команды, полученное из userData.oldIntentName
(а при включённом локальном хранилище и пустом userData — из
state.oldIntentName).
Используется для отслеживания контекста диалога.
КАК ЭТО РАБОТАЕТ:
this.thisIntentName сохраняется:
при включённом isLocalStorage и пустом userData — в state.oldIntentName,
иначе — в userData.oldIntentNamethis.oldIntentNameТИПИЧНОЕ ИСПОЛЬЗОВАНИЕ:
bot.addStep()// Пример: Многошаговая регистрация
class RegistrationBot extends BotController {
public action(intentName: string | null): void {
// Определяем на каком шаге находимся
const previousStep = this.oldIntentName;
if (previousStep === 'enter_name') {
// Пользователь только что ввел имя, спрашиваем email
this.userData.name = this.userCommand;
this.text = 'Отлично! Теперь введите ваш email:';
this.thisIntentName = 'enter_email'; // Сохранится для следующего шага
} else if (previousStep === 'enter_email') {
// Пользователь ввел email, завершаем регистрацию
this.userData.email = this.userCommand;
this.text = 'Регистрация завершена!';
}
}
}
// Пример: Кнопка "Назад"
if (intentName === 'back') {
// Возвращаемся к предыдущему шагу
switch(this.oldIntentName) {
case 'product_list':
this.text = 'Выберите категорию:';
break;
case 'category_list':
this.text = 'Добро пожаловать!';
break;
}
}
Оригинальный запрос пользователя. Текст запроса без изменений, включая регистр и знаки препинания.
Дополнительные параметры запроса. Может содержать любые дополнительные данные, полученные от платформы.
Дополнительные опции платформы. ⚠️ Внутреннее свойство. Заполняется адаптером платформы. Не предназначено для прямого использования в пользовательском коде.
Полученный запрос от платформы. Содержит оригинальный объект запроса.
Флаг, указывающий, что ответ уже отправлен через API и не требуется автоматическая отправка. Как правило, данный флаг стоит использовать для платформ, которые не ждут ответ в виде возвращаемого содержимого, а ожидают что к самой платформе будет отправлен запрос. Например, чат-бот для Telegram, для отображения результата пользователю, отправляется запрос к платформе с нужным содержимым.
Пользовательское локальное хранилище.
Используется для временного хранения данных, специфичных для текущего диалога.
Работает только при включённой опции isLocalStorage: true в конфигурации.
bot.setAppConfig({
isLocalStorage: true,
});
Правила синхронизации с базой данных (если подключена):
userData, и state: userData сохраняется в БД,
а state — в локальное хранилище платформы.userData (а state пуст или совпадает с ним):
при использовании локального хранилища данные уходят только в него
(в БД не сохраняются), без локального хранилища — только в БД.state (userData пуст): перед формированием
ответа userData подменяется на state, поэтому state уходит
в локальное хранилище платформы, а без него — в БД.При загрузке данных:
userData, и в state (у Алисы и Маруси это
один и тот же объект); данные из БД при этом не читаются.userData;
state остаётся тем, что прислала платформа (у чат-платформ — null).userData — для постоянного хранения данных пользователя.
Текст, который будет отображен пользователю. Основной способ коммуникации с пользователем, так как именно этот текст пользователь увидит в интерфейсе.
Название текущего интента. Определяет следующий шаг диалога.
Текст, который пользователь может услышать. Для голосовых платформ, озвучка будет произведена силами самой платформы, для не голосовых платформ, поведение зависит непосредственно от реализации адаптера. Так для некоторых стандартных адаптеров, в случае заполнения поля и указания токена yandex SpeechKit, будет отправлен запрос на преобразование текста в аудиофайл, после чего аудиофайл будет отправлен пользователю.
Запрос пользователя в нижнем регистре.
Пользовательские данные, которые были сохранены.
⚠️ Мутируйте отдельные поля (this.userData.name = ...), а не
переприсваивайте объект целиком (this.userData = {...}) — фреймворк
хранит ссылку на исходный объект, и переприсваивание разрывает её.
Пользовательские события. Содержит информацию об авторизации или оценке.
Уникальный идентификатор пользователя.
Дополнительная информация о пользователе.
Пользовательский токен авторизации. Заполняется адаптером Алисы (access_token из account linking после авторизации пользователя). Читайте его для запросов к внешним API, требующим авторизации пользователя.
API активной платформы: отправка медиа и ответов на callback-кнопки без ручного конструирования платформенных Request-классов.
Доступно на чат-платформах (Telegram, VK, MAX, Viber с оговорками);
на голосовых (Алиса, Маруся, SmartApp) — null: их ответ формируется
телом webhook, используйте card/sound.
Компонент для отображения различных кнопок пользователю. Позволяет создавать интерактивные элементы управления в приложении.
Компонент для отображения карточек пользователю. Позволяет создавать визуальные элементы с изображениями и текстом. Также при указании нескольких изображений, они автоматически преобразуются в карточку.
// КАТАЛОГ ТОВАРОВ (интернет-магазин):
this.text = 'Популярные товары:';
this.card
.addImage(
'http://localhost/iphone.jpg',
'iPhone 15 Pro',
'99 990 ₽\nЭкран 6.1", процессор A17 Pro'
)
.addButton('Купить')
.addImage(
'http://localhost/macbook.jpg',
'MacBook Air M2',
'124 990 ₽\n13.6", 8ГБ RAM, 256ГБ SSD'
)
.addButton('Купить');
// ГАЛЕРЕЯ ФОТОГРАФИЙ:
this.text = 'Наши работы:';
this.card
.addImage('photo1.jpg', 'Свадьба', 'Иван и Мария')
.addImage('photo2.jpg', 'Выпускной', 'Школа №123')
.addImage('photo3.jpg', 'Корпоратив', 'Компания "Рога и копыта"');
// КАРТОЧКИ НОВОСТЕЙ:
this.card
.addImage(
'news1.jpg',
'Новое обновление',
'Добавлена оплата картой и доставка',
{
title: 'Перейти',
url: 'http://localhost/news/1'
}
)
Результат совпадения команды с регулярным выражением.
Заполняется лениво при первом обращении: фреймворк запоминает регулярку
сработавшей команды (RegExp-слот, isPattern-паттерн или группу регулярок)
и прогоняет её по тексту только если обработчик реально читает match.
Содержит RegExpExecArray совпавшей регулярки — группы доступны как
this.match[1], this.match.groups. Для строковых команд и событий — null.
Обработанный NLU (Natural Language Understanding). Содержит результаты обработки естественного языка, как правило, данные заполняются самой платформой.
Компонент для работы со звуками. Позволяет добавлять звуковые эффекты и музыку. Используется вместе с tts.
Protected_actionMetricЗапуск обработки пользовательских команд с учетом метрик.
Имя команды
Является ли обработка командой (а не шагом)
Является ли обработка шагом диалога
Protected_getCommandИзвлекает нужную команду из запроса.
результат выполнения обработчика найденной команды или null, если подходящая команда не найдена
Protected_getIntentНаходит нужный интент по тексту запроса.
Текст запроса
Название интента или null
Protected_intentsОбработка запроса по умолчанию.
Вызывается фреймворком последним, после поиска команд и шагов.
Если команда или шаг уже обработали запрос (isCommand/isStep = true), метод просто применяет i18n и выходит.
Если ничего не подошло — устанавливает текст из platformParams.empty_text (только если text пуст,
if (!this.text)), затем применяет i18n.
Имя сработавшего интента/команды/шага. null если ничего не найдено.
OptionalisCommand: booleantrue если запрос обработан командой из addCommand
OptionalisStep: booleantrue если запрос обработан шагом из addStep
Полностью сбрасывает состояние контроллера, включая текст ответа, пользовательские данные, состояние диалога и внутренние флаги.
Флаг возвращающий информацию о том, были ли инициализированы кнопки или нет
true если кнопки были инициализированы
Флаг возвращающий информацию о том, были ли инициализированы карточки или нет
true если карточки были инициализированы
Метод: возвращает true, только если объект Nlu уже создан (было обращение
к геттеру nlu). Вызов setThisUser сам по себе объекта
не создаёт: при неинициализированном Nlu данные буферизуются в
#thisUserBuffer и применятся при первом же обращении к геттеру.
true если объект NLU был инициализирован
Флаг возвращающий информацию о том, были ли инициализированы звуки или нет
true если звуки были инициализированы
Основной метод обработки запроса, вызываемый автоматически фреймворком.
Может быть асинхронным
Как это работает:
run() определяет тип запроса (команда/интент/шаг)action() с результатомtext, buttons, card)Не вызывайте run() вручную и не переопределяйте его —
для своей логики переопределяйте только action().
Порядок обработки внутри run():
run()
├── Шаг 0: Вызывает событийные обработчики (bot.addEvent) по controller.eventType
│ → Обработчик не вернул false → обработка завершена (action(eventType))
├── Шаг 1: Проверяет есть ли активный шаг
│ → Если есть → вызывает action(stepName, false, true)
├── Шаг 2: Ищет команду
│ → Если нашел → вызывает action(commandName, true, false)
├── Шаг 3: Ищет интент (включая welcome/help)
│ → Если нашел → вызывает action(intentName, false, false)
│ → welcome-интент: messageId === 0 (начало диалога) и fallback-команда
│ не зарегистрирована
└── Шаг 4: Если интент не найден → fallback-команда ("*"), если зарегистрирована.
Fallback проверяется раньше welcome и имеет над ним приоритет —
welcome при messageId === 0 срабатывает, только если fallback не зарегистрирован
// ВАШ КОД (контроллер):
class MyController extends BotController {
public action(intentName: string | null): void {
// Ваша логика здесь
this.text = "Ответ пользователю";
}
}
// КОД ФРЕЙМВОРКА (не ваш):
// Когда приходит запрос от пользователя:
const controller = new MyController();
{...}; // Наполняет контроллер данными. Как правило, этим занимается адаптер платформы
await controller.run(); // Автоматически вызывает ваш action()
const response = ...; // Адаптер формирует ответ в зависимости от состояния контроллера
Устанавливает контекст приложения (обновляет контекст в уже созданных
компонентах buttons и card).
Контекст приложения
Текущий экземпляр для цепочки вызовов
Записывает данные отправителя сообщения (username/имя/фамилия) в NLU.
Используется адаптерами чат-платформ (через хелпер setThisUserToNlu
из pUtils). Значение сначала держится в приватном буфере: если логика
приложения ни разу не обратится к nlu, объект Nlu и его кэш
не создаются вовсе. При первом обращении буфер переносится в Nlu
(nlu.getUserName() возвращает переданные данные).
Данные отправителя; пустые поля интерпретируются как отсутствие данных
Текущий экземпляр для цепочки вызовов
Контроллер для обработки запросов приложения по умолчанию. Используется в качестве контроллера по умолчанию, и позволяет не создавать свой контроллер, если вся обработка команд или шагов осуществляется через bot.addCommand или bot.addStep.
Стандартные команды (приветствие и помощь) обрабатываются конвейером BotController (тексты welcome_text/help_text и интенты welcome/help), а не этим action(). Обработка в action происходит только в том случае, если не была обработана ни одна команда или шаг.