Навык Алисы на TypeScript: создание с нуля на Node.js и umbot
Пошаговая разработка навыка для Яндекс.Алисы на TypeScript и Node.js: команды, шаги диалога, формы, кнопки, TTS, отладка в консоли и частые ошибки новичка.
Навык Алисы на TypeScript: создание с нуля на Node.js и umbot
26 Сентября, 2026 Автор: Максим МНавык Алисы на TypeScript: создание с нуля на Node.js и umbot
Пошагово: от установки до работающего навыка с кнопками, голосом, формами и тестами в консоли.
Большинство руководств по созданию навыка для Алисы начинается с «чистого Node.js»: вручную
собрать JSON ответа, вручную следить за лимитом в 1024 символа, руками писать tts и
надеяться не опечататься в end_session. Работает — но при каждом изменении ответа
вы пересобираете структуру заново, а первый же баг в формате ловится только на опубликованном
навыке. Мы пойдём другим путём: навык на TypeScript, где типы описывают формат ответа, а рутину
берёт фреймворк umbot. Разберём создание навыка для Яндекс.Алисы с нуля — от установки Node.js
до диалога с кнопками, шагами и TTS в консоли вашего компьютера.
Как устроен навык Алисы: 30 секунд теории
Навык — это обычный HTTPS-сервер. Когда пользователь говорит с навыком, Яндекс.Диалоги
отправляют на ваш адрес (вебхук) POST-запрос с JSON: что сказал пользователь
(request.command), данные сессии и сохранённое состояние. Ваш сервер за несколько
секунд должен вернуть JSON с текстом ответа, голосом (tts), кнопками и признаком
завершения сессии. Всё. Фреймворк нужен, чтобы вы писали не этот JSON, а логику диалога.
Шаг 1. Создание проекта
Установите Node.js 20+ и выполните:
npx umbot create my-skill
cd my-skill
npm install
npm run build
npm start
CLI разворачивает готовый проект: точку входа src/index.ts, конфигурацию,
класс-контроллер и tsconfig.json. В .gitignore уже внесён
.env — токены не уедут в репозиторий. Сам файл .env с шаблонами
переменных создайте одной командой:
npx umbot add env
Для быстрого прототипа есть флаг --minimal: он создаёт рабочий проект без
класса-контроллера — вся логика пишется в одном файле через addCommand. Именно
такой стиль используется в примерах ниже.
Шаг 2. Логика навыка: команды и фразы-синонимы
Основной способ описания логики — регистрация команд списком фраз-синонимов. Типовой навык из getting-started:
import { Bot, WELCOME_INTENT_NAME, FALLBACK_COMMAND } from 'umbot';
import { voicePlatforms } from 'umbot/plugins';
const bot = new Bot()
.use(voicePlatforms) // Алиса, Маруся, SmartApp
.setAppConfig({ isLocalStorage: true });
// Приветствие — на фразы из списка
bot.addCommand(WELCOME_INTENT_NAME, ['привет'], (_, bc) => {
bc.text = 'Привет! Я новый навык.';
bc.buttons.addBtn('Помощь');
});
// Команда со списком фраз-синонимов
bot.addCommand('help', ['помощь', 'что ты умеешь'], (_, bc) => {
bc.text = 'Я умею отвечать на команды и показывать кнопки.';
});
// Fallback — ловит всё, что не совпало с командами
bot.addCommand(FALLBACK_COMMAND, [], (userCommand, bc) => {
if (bc.messageId === 0) {
// первый запрос сессии: «Алиса, запусти навык ...»
bc.text = 'Привет! Я новый навык. Скажите «помощь», чтобы узнать, что я умею.';
bc.buttons.addBtn('Помощь');
return;
}
bc.text = `Не знаю команду «${userCommand}». Скажите «помощь».`;
});
bot.start('localhost', 3000);
Что здесь важно: WELCOME_INTENT_NAME — имя интента приветствия,
FALLBACK_COMMAND ловит нераспознанное. Тонкость, о которую спотыкаются почти все:
при запуске навыка («Алиса, запусти навык…») команда пустая, и если fallback зарегистрирован,
первым сработает именно он, а не приветствие. Поэтому начало сессии обрабатывается в fallback по
bc.messageId === 0 — иначе на запуск навык ответит «не знаю команду», и такой навык
не пройдёт модерацию. Ввод пользователя приводится к нижнему регистру, поэтому фразы пишутся в
нижнем. Слоты можно задавать и регулярными выражениями — фреймворк проверяет их на
ReDoS-уязвимости до выполнения.
Свои интенты со слотами регистрируются через setPlatformParams:
bot.setPlatformParams({
intents: [
{ name: 'help', slots: ['помощь', 'что ты умеешь'] },
],
});
Важно: переданный массив интентов заменяет встроенные
welcome/help — либо добавьте их в свой список, либо задайте свои слоты
для приветствия и помощи. Нативные NLU-интенты, настроенные в консоли Яндекс.Диалогов, при этом
тоже доступны: распознанное придёт в nlu.intents запроса.
Шаг 3. Шаги диалога и состояние пользователя
Когда сценарий перестаёт быть «вопрос — ответ» и появляется ветвление, нужны шаги: команда переводит пользователя в шаг, шаг обрабатывает его следующий ответ. Пример по мотивам GUIDE по фреймворку:
bot.addCommand('game_start', ['играть', 'начать игру'], (_, bc) => {
bc.userData.score = 0; // состояние пользователя
bc.text = 'Игра началась! Сколько будет 2+2?';
bc.buttons.addBtn('3').addBtn('4').addBtn('5');
bc.thisIntentName = 'game_answer'; // следующий ответ обработает шаг
});
bot.addStep('game_answer', (bc) => {
if (bc.userCommand === '4') {
bc.userData.score = Number(bc.userData.score ?? 0) + 1;
bc.text = 'Правильно!';
} else {
bc.text = 'Неправильно.';
}
bc.thisIntentName = null; // выходим из шага
});
userData — встроенное состояние: у голосовых платформ оно хранится в хранилище
платформы (приходит в каждом запросе), поэтому для навыка Алисы отдельная БД на старте не нужна.
Шаг 4. Формы: сбор данных в несколько вопросов
Частая задача навыка — задать пользователю несколько вопросов подряд: имя, телефон, дату записи.
На шагах это десяток обработчиков; для таких случаев есть addForm — поля, валидация
и итоговый обработчик в одном месте:
bot.addForm('registration', {
fields: [
{ name: 'name', prompt: 'Как вас зовут?', validate: (v) => v.length > 0 },
{ name: 'age', prompt: 'Сколько вам лет?', validate: (v) => +v > 0 || 'Возраст должен быть числом' },
],
onComplete: (bc, answers) => {
bc.text = `Спасибо, ${answers.name}!`;
},
});
// Запуск формы из команды
bot.addCommand('start_signup', ['зарегистрироваться'], (_, bc) => {
bc.thisIntentName = '__form_registration_0';
bc.text = 'Как вас зовут?'; // первый вопрос формы
});
Если ответ не прошёл валидацию, навык повторит вопрос с текстом ошибки. Промежуточные ответы
хранятся в userData, так что форма переживает паузы между репликами.
Шаг 5. Кнопки, карточки, голос
-
Кнопки:
bc.buttons.addBtn('Да').addBtn('Нет')— единый API, адаптер Алисы сам разложит их по формату платформы и обрежет по лимитам. -
Карточки:
bc.card.addOneImage('image.jpg', 'Заголовок', 'Описание')— одиночная карточка BigImage;addImage()— список до 5 элементов, галерея — до 10. -
Голос:
bc.ttsзадаётся отдельно от текста — то, что услышит пользователь, может отличаться от того, что он увидит на экране. Стандартные звуки и эффекты Алисы и паузы в речи — черезSoundConstants. - Медиа: изображение по URL или пути загрузится на платформу при первом использовании, его идентификатор закэшируется — повторные показы мгновенны. Для загрузки картинок в Алису понадобится OAuth-токен навыка.
Шаг 6. Запуск и отладка в консоли
После npm run build и npm start навык слушает вебхук на порту 3000. Но
до деплоя его можно проверить прямо в терминале. Для этого при создании проекта укажите режим
dev в JSON-конфигурации CLI — тогда точка входа соберётся не вокруг HTTP-сервера, а
вокруг класса BotTest:
// my-skill.json — конфигурация для CLI
{
"name": "my-skill",
"mode": "dev",
"isEnv": true
}
npx umbot create my-skill.json
Сгенерированная точка входа выглядит так (сокращённо):
import { BotTest } from 'umbot/test';
import { fullPlatforms } from 'umbot/plugins';
const bot = new BotTest();
bot.use(fullPlatforms);
// ...конфигурация и контроллер из шаблона...
bot.test(); // вводите фразы — получаете ответы навыка
Метод test() принимает опции: isShowResult покажет полный JSON ответа
платформы, isShowStorage — что навык запомнил о пользователе,
isShowTime — время обработки. Для выхода введите exit. Так вы
проверяете и лимит в 1024 символа, и структуру кнопок до того, как их увидит модерация.
Подробнее — в статье про
тестирование навыка без публикации.
Шаг 7. Подключение к Яндекс.Диалогам
- Создайте навык в консоли Яндекс.Диалогов (тип «Навык в Алисе»).
- Для проверки с локального компьютера поднимите туннель (ngrok, cloudflared) до порта 3000 и укажите выданный HTTPS-адрес в поле Webhook URL.
- Откройте вкладку «Тестирование» в консоли и поговорите с навыком — запросы пойдут на ваш компьютер.
- Для постоянной работы разверните приложение на сервере или в облаке — пошагово в документации по развёртыванию или в статье про навык на serverless.
Частые ошибки новичков
-
Фразы-слоты в верхнем регистре. Ввод приводится к нижнему регистру — слот
'Привет'никогда не сработает, пишите'привет'. -
Навык молчит или «не понимает» при запуске. Приветствие со списком фраз не
срабатывает на пустую команду запуска, если зарегистрирован fallback — обработайте
messageId === 0в fallback, как в примере выше. -
Нет fallback-команды. Пользователь скажет что-то вне сценария — и навык
ответит невнятным дефолтом.
FALLBACK_COMMANDобязателен. -
Переопределили интенты и потеряли приветствие. Свой список
intentsвsetPlatformParamsзаменяет встроенные — не забудьте вернутьwelcome/help. - Текст длиннее 1024 символов. Фреймворк обрежет его до лимита, и пользователь не услышит конец ответа. Длинный текст разбивайте на шаги.
-
Медиа грузится в момент ответа. Первая загрузка изображения может занять
заметную часть времени на ответ — предзагружайте медиа через
Preloadдо старта. -
Забыли выйти из шага. Если не сбросить
thisIntentName, все следующие фразы пользователя попадут в тот же шаг.
Куда дальше
- GUIDE по фреймворку — шаги диалога, состояние, middleware, деплой.
- FAQ по фреймворку — типичные ошибки и их решения.
- Бот для Алисы и Телеграма одновременно — как расширить этот же навык на мессенджеры.
- Разработка навыков под ключ — если навык нужен, а писать его самому некогда.
Рекомендую к прочтению следующие статьи:
Telegraf или grammY — что выбрать для Telegram-бота в 2026?
Честное сравнение Telegraf и grammY с примерами кода и таблицей: типы, плагины, вебхуки — и когда вместо библиотеки нужен мультиплатформенный фреймворк.
Читать статью
Сколько стоит разработка навыка для Алисы в 2026 году
Сколько стоит навык для Алисы: цены от 5 000 ₽, что влияет на стоимость, три уровня сложности, доли бюджета по этапам и как сэкономить без потери качества.
Читать статью
Конструктор навыков Алисы или разработка на фреймворке: что выбрать
Когда хватит конструктора навыков для Алисы без программирования, а когда нужны фреймворк и разработчик: потолок конструкторов, логика и владение продуктом.
Читать статью
Навык для Алисы без своего сервера: serverless на Yandex Cloud
Как запустить навык Алисы в Yandex Cloud Functions без своего сервера: генерация serverless-проекта через CLI umbot, деплой, публичный вызов и лимиты.
Читать статью
Бот для мессенджера MAX: создание на typescript и Node.js
Создание бота для мессенджера MAX на Node.js: регистрация, подключение вебхука, отличия API от Telegram и VK, лимиты отправки и пример бота на фреймворке umbot.
Читать статью
Комментарии
Оставить комментарий
Как со мной связаться?
Свяжитесь со мной по любому поводу!
Я с радостью отвечу на все вопросы!
Телефон:
+7(909) 281 35-20Почта:
maximco36895@yandex.ruДополнительная почта:
info@maxim-m.ruЯ в социальных сетях: