Для безопасного хранения токенов и других чувствительных данных, вы можете использовать два подхода:
.env (рекомендуется)bot.setAppConfig({ env: './.env' });
Пример файла .env:
# Токены платформ
TELEGRAM_TOKEN=123456:ABC-DEF...
VK_TOKEN=vk1.a.abc123...
VK_CONFIRMATION_TOKEN=abcdef # обязательно для VK (для подтверждения вебхука)
VK_SECRET_KEY=abc123... # опционально: секретный ключ VK для проверки подлинности запросов
VIBER_TOKEN=1234567890-ABCDEF...
ALISA_TOKEN=y0_AgAAAAA... # OAuth-токен навыка (для аплоада медиа), без префикса "OAuth "
MARUSIA_TOKEN=abc.123...
MAX_TOKEN=abc123...
SMARTAPP_TOKEN=... # токен Сбер SmartApp (генерируется CLI; для работы адаптера не обязателен)
# Секреты вебхука (см. раздел «Проверка подписи вебхука» ниже).
# ВАЖНО: фреймворк не читает их из env автоматически — передайте в setAppConfig
# вручную: tokens.telegram.webhookSecret / tokens.max_app.webhookSecret.
TELEGRAM_WEBHOOK_SECRET=...
MAX_WEBHOOK_SECRET=...
# Yandex SpeechKit — для TTS на чат-ботах (Telegram/VK/Max).
# Значение автоматически записывается в speech_kit_token всех трёх платформ.
# Рекомендуется API-ключ сервисного аккаунта (уходит как `Api-Key`); IAM-токен `t1.…`
# тоже принимается (уходит как `Bearer`), но живёт не больше 12 часов.
SPEECH_KIT_TOKEN=AQVN...
# Подключение к MongoDB (если используете MongoAdapter)
DB_HOST=mongodb://localhost:27017
DB_USER=root
DB_PASSWORD=secret
DB_NAME=umbot
Важно! Никогда не добавляйте .env файлы в репозиторий Git. Используйте разные токены для разработки и продакшена. Значение
ALISA_TOKENуказывайте без префиксаOAuth— фреймворк добавит его сам. Устаревшее имяYANDEX_TOKENподдерживается для обратной совместимости, но приоритет уALISA_TOKEN.
Что будет, если файл не найден? Фреймворк попробует получить токены из process.env. Если и там их нет — в лог-файле будет выведено сообщение об ошибке. Адаптер при этом остаётся зарегистрированным, но операции, требующие токена (отправка сообщений, загрузка медиа), работать не будут.
Переменные окружения без
env. Еслиenvне настроен вовсе, фреймворк всё равно тихо попробует прочитать известные переменные (TELEGRAM_TOKEN,VK_TOKEN, ...) изprocess.envи дозаполнить ими токены — это позволяет передавать токены черезdocker run -eили окружение serverless-функции безenv: 'local'. Уже заданные токены при этом не перезаписываются.
bot.setAppConfig({
db: {
host: 'mongodb://localhost:27017',
user: 'bot_user',
pass: 'secure_password',
database: 'bot_database',
},
tokens: {
telegram: {
token: 'your-telegram-token',
},
vk: {
token: 'your-vk-token',
},
},
});
Механика такая: токен конструктора адаптера (new TelegramAdapter('token')) записывается в конфиг при вызове
bot.use() (в init() адаптера). Дальше решает env:
env (файл или 'local') — setAppConfig({ env }) и каждый последующий
setPlatformParams вызывают перезапись токенов из env: значения из .env/process.env перезапишут
и токен конструктора, и inline-tokens (не важно, вызван ли setAppConfig до или после bot.use()).env не настроен вовсе: тогда setPlatformParams
лишь дозаполняет отсутствующие токены из process.env, не перезаписывая заданные.tokens в setAppConfig — сливается с существующими токенами платформы.process.env без настроенного env — только дозаполняет отсутствующие токены, ничего не перезаписывая.Практический совет: не смешивайте способы для одной платформы. Либо передавайте токен в конструкторе адаптера и не настраивайте
env, либо используйте.env/process.envи создавайте адаптеры без токена.
| Сценарий | Рекомендация |
|---|---|
| Разработка, прототип | env: '.env' — просто и безопасно |
| Production на сервере | env: 'local' + переменные окружения на сервере |
| Тесты | Прямая передача в config.tokens или в конструкторе адаптера |
| Несколько сред (dev/prod) | .env файлы с разными токенами, передавайте через env |
IAppConfigМетод setAppConfig принимает объект Partial<IAppConfig>:
| Поле | Тип | Описание |
|---|---|---|
error_log |
string |
Путь к папке для логов ошибок (error.log, warn.log) |
json |
string |
Путь к папке для JSON-данных (используется FileAdapter) |
db |
IAppDB |
Параметры подключения к БД |
isLocalStorage |
boolean |
Использовать локальное хранилище платформы вместо БД |
memorySession |
IMemorySessionConfig | false |
Сессия userData в памяти процесса для Telegram/VK/MAX/Viber без БД при isLocalStorage: true. По умолчанию { maxSize: 10000, ttl: 86400000 }; false — выключить |
env |
string |
Путь к .env файлу ИЛИ строка 'local' для process.env |
tokens |
ITokenPlatform |
Токены платформ (для адаптеров, если не переданы через конструктор) |
bot.setAppConfig({
json: './data', // папка для JSON-файлов (FileAdapter)
error_log: './errors', // папка для логов
isLocalStorage: true, // локальное хранилище (для голосовых платформ)
env: '.env', // путь к файлу с токенами
db: {
// подключение к MongoDB (если не isLocalStorage)
host: 'mongodb://localhost:27017',
database: 'umbot',
},
});
На Telegram/VK/MAX/Viber локального хранилища нет: при
isLocalStorage: trueбез DB-адаптераuserDataхранится в памяти процесса (memorySession). Данные теряются при перезапуске и не разделяются между процессами, репликами и вызовами serverless-функции — для продакшена с шагами диалога подключите БД.
IAppParamМетод setPlatformParams принимает объект IAppParam:
| Поле | Тип | Описание |
|---|---|---|
intents |
IAppIntent[] | null |
Обязательное. Список интентов для распознавания команд |
welcome_text |
string | string[] |
Текст приветствия (при messageId === 0) |
help_text |
string | string[] |
Текст помощи (при команде "помощь") |
empty_text |
string | string[] |
Текст при отсутствии подходящих команд |
isAuthUser |
boolean |
Требуется ли авторизация пользователя |
utm_text |
string | null |
UTM-метки для ссылок (при null к кнопкам-ссылкам без UTM автоматически добавляется utm_source=umbot&utm_medium=cpc&utm_campaign=phone; строка заменяет эти метки целиком) |
bot.setPlatformParams({
welcome_text: 'Привет! Я умею считать.',
help_text: 'Это игра в математику.',
empty_text: 'Не поняла. Скажите "помощь".',
intents: [
{ name: 'game', slots: ['игра', 'начать игру'] },
{ name: 'bye', slots: ['пока', 'до свидания'] },
{ name: 'phone', slots: ['\\+?\\d{11}'], is_pattern: true }, // слот как regex
],
});
Важно: поле
intentsобязательно даже если оно пустое:intents: []. Без него TypeScript выдаст ошибку типа.
setAppMode| Режим | Логи | ReDoS-проверка | Когда использовать |
|---|---|---|---|
dev |
Подробные | Warn, но не блокирует | Разработка, BotTest |
prod |
Минимальные | Warn, но не блокирует (режим небезопасен, оставлен для обратной совместимости) | Pre-prod |
strict_prod |
Минимальные | Блокировка опасных | Production |
Что делает strict_prod:
dev и prod опасные RegExp используются как есть: с предупреждением, если установлен re2, и с ошибкой в логах, если нет (без re2 штатный движок Node уязвим к катастрофическому бэктрекингу).Маскировка секретов в логах (токены, пароли заменяются на
***) работает во всех режимах и отключается только кастомным логгером сmaskSecrets: false.
Вебхук — единственная точка входа вашего приложения. Пока проверка подписи не включена, любой, кто узнает URL
вебхука, может отправлять запросы от имени любого пользователя: обходить авторизацию по userId, читать и
перезаписывать чужие userData, управлять чужими диалоговыми шагами и расходовать квоты API. URL вебхука — не секрет
(он виден платформе, логам, реестрам доменов), поэтому подпись — не опция, а обязательный шаг настройки.
Проверка подписи включается автоматически, как только задан секрет — отдельно «включать» ничего не нужно. Фреймворк предупредит в логе при старте, если для подключённой платформы секрет не задан.
| Платформа | Что задать | Где секрет живёт на стороне платформы |
|---|---|---|
| Telegram | tokens.telegram.webhookSecret |
поле secret_token при вызове setWebhook |
| VK | tokens.vk.secret_key (или vk_secret_key) |
настройка «Секретный ключ» в настройках группы (VK Callback API) |
| MAX | tokens.max_app.webhookSecret (или secret) |
секрет, выданный при создании бота/подписки |
| Viber | tokens.viber.token |
токен бота — он же ключ HMAC (x-viber-content-signature) |
| Алиса, Маруся, SmartApp | — | платформа не подписывает запросы в принципе (см. ниже) |
Сгенерировать секрет можно любой командой:
node -e "console.log(require('crypto').randomBytes(24).toString('base64url'))"
# или: openssl rand -base64 24
# 1. Секрет — одна и та же строка в обоих местах
curl "https://api.telegram.org/bot<ТОКЕН>/setWebhook" \
-d "url=https://ваш-домен/webhook" \
-d "secret_token=<СЕКРЕТ>"
// 2. Тот же секрет в конфигурации приложения
bot.use(new TelegramAdapter('YOUR_BOT_TOKEN'));
bot.setAppConfig({
tokens: {
telegram: { token: 'YOUR_BOT_TOKEN', webhookSecret: process.env.TELEGRAM_WEBHOOK_SECRET },
},
});
Без webhookSecret адаптер принимает любой запрос с полем update_id — это допустимо только для локальной
отладки. С заданным секретом запросы без заголовка x-telegram-bot-api-secret-token (или с неверным значением)
отклоняются с 401 до выполнения какой-либо логики.
Включите «Секретный ключ» в настройках группы (Управление → Работа с API → Callback API) и передайте то же значение:
bot.use(new VkAdapter('YOUR_VK_TOKEN', { vk_secret_key: 'YOUR_SECRET' }));
// или через конфиг: tokens.vk.secret_key
VK присылает secret в теле каждого callback-запроса; адаптер сверяет его константным по времени сравнением
(timingSafeEqual). Если секрет в группе не включён — проверку включить нельзя (нечем сверять), см. ниже про
ipFilter.
MAX передаёт секрет заголовком x-max-bot-api-secret:
bot.use(new MaxAdapter('YOUR_MAX_TOKEN', { secret: 'YOUR_SECRET' }));
// или через конфиг: tokens.max_app.webhookSecret
Алиса, Маруся и SmartApp не предоставляют механизм подписи вебхука — всё содержимое payload, включая
user_id, контролирует отправитель запроса. Это ограничение платформ, а не фреймворка:
userId голосовой платформы аутентифицированной идентичностью;userData голосовых платформ данные, потеря или подмена которых критична.Дополнительный слой для любых платформ — ipFilter (см. middleware.md): ограничение входящих
запросов по диапазонам IP платформ (например, только для Telegram: 149.154.160.0/20, 91.108.4.0/22).
Фреймворк поддерживает работу с re2. За счет использования данной библиотеки, можно добиться существенного ускорения
обработки регулярных выражений, а также сокращения потребления памяти. Потребление памяти уменьшается
примерно в 3-7 раз, а время выполнения уменьшается в среднем в 2-15 раз.
npm install re2
Фреймворк автоматически определит, установлен ли re2, и будет использовать его.
Не рекомендуется использовать в релизной версии приложения файловую базу данных, так как данный подход может привести к падению приложения при большом количестве записей. Связано это с тем, что в файловой базе данные хранятся в оперативной памяти.
Для корректного сохранения данных в БД:
MongoAdapter), или создайте свой (bot.use(new MyAdapter()))bot.setAppConfig({db:{...}}), либо в конструкторе при подключении адаптера..env существует по указанному пути= — парсер обрезает их (TELEGRAM_TOKEN = abc работает так же, как TELEGRAM_TOKEN=abc; кавычки вокруг значения допускаются — парсер их снимет)dev для подробных логов: bot.setAppMode('dev')db.host: должен содержать протокол (mongodb://localhost:27017, а не localhost:27017)error_log покажет ошибку подключенияintents передан в setPlatformParams (даже если пустой: intents: [])userCommand)dev для просмотра процесса поиска командПодробнее о конфигурации (IAppConfig, IAppParam), приоритете токенов и содержимом .env — в разделе Конфигурация: IAppConfig и IAppParam.