umbot — это мультиплатформенный фреймворк на TypeScript для создания чат-ботов и голосовых ассистентов. Позволяет
писать
код один раз и запускать на 7+ платформах: Алиса, Маруся, Сбер, Telegram, VK, Viber, MAX.
npm install umbot
npx umbot create my-bot
cd my-bot
npm install
npm run start
Сохраните токены в .env файл:
TELEGRAM_TOKEN=your-token
VK_TOKEN=your-token
VK_CONFIRMATION_TOKEN=your-token
YANDEX_TOKEN=your-token
# ... и другие токены
Затем укажите путь в конфигурации:
bot.setAppConfig({
env: './.env',
});
Проблема: В версии 3.0 произошел переход на плагинную архитектуру. Работа с платформами теперь осуществляется через адаптеры. Было (2.2.x):
import { Bot } from 'umbot';
const bot = new Bot();
bot.setPlatformParams(params);
bot.start('localhost', 3000);
Стало (3.0):
import { Bot } from 'umbot';
import { fullPlatforms, FileAdapter } from 'umbot/plugins';
const bot = new Bot()
.use(fullPlatforms) // Подключаем платформы как плагин
.use(new FileAdapter()) // Подключаем адаптер БД
.setPlatformParams(params)
.start('localhost', 3000);
Подробнее об изменениях можно прочитать тут
Важно: Версия 2.1.x содержит критическую архитектурную проблему. Обязательно обновитесь! Обновите пакет:
npm install umbot@2.2
Проверьте код на использование устаревших методов (они были удалены в 2.2.x)
npm list umbot
umbot в состоянии обработать любое количество команд, но важно понимать что большое количество команд, как правило,
говорит о не оптимальной архитектуре приложения.
Также при большом количестве команд, время ответа приложения будет увеличиваться.
Рекомендуется не использовать более 1000 команд в своем приложении.
| Количество команд | Время обработки (с re2) | Рекомендация |
|---|---|---|
| 50 | 0.06 мс | ✅ Отлично |
| 500 | 0.26 мс | ✅ Отлично |
| 1000 | < 30 мс | ✅ Хорошо |
| 10000 | < 1 сек | ⚠️ Проверьте сервер |
| 20000 | 22.44 мс | ⚠️ Используйте re2 |
re2 — это библиотека для работы с регулярными выражениями, которая:
Установка:
npm install --save re2
После установки umbot автоматически начнет использовать re2.
Node.js на Windows работает менее эффективно, чем на Unix-системах (Linux/macOS). Это может приводить к высокому потреблению памяти (до 4ГБ против 400МБ на Linux). Рекомендация: Для продакшена используйте Linux-сервер.
Не рекомендуется. Файловая БД (FileAdapter) хранит данные в оперативной памяти. При большом количестве записей (>10000) возможен Out of Memory и падение приложения.
Рекомендация: Используйте MongoAdapter или создайте свой адаптер:
import { MongoAdapter } from 'umbot/adapters';
bot.use(
new MongoAdapter({
host: 'mongodb://localhost:27017/my-bot',
database: 'bot_db',
user: 'user',
pass: '***',
}),
);
BaseDbAdapterisConnected, _select, _insert, _update, _removeuse:bot.use(new MyCustomAdapter(config));
Да, можно одновременно хранить данные как в локальном хранилище платформы, так и в вашей базе данных. Сделать это можно следующим образом:
import { Bot } from 'umbot';
import { FileAdapter } from 'umbot/plugins';
const bot = new Bot();
bot.use(new FileAdapter());
bot.addCommand('test', ['сохранить'], (_, cBot) => {
cBot.userData = {}; // Сохраняем даныне в базу данных.
cBot.state = {}; // Сохраняем данные в локальное хранилище платформы.
// Ваша логика
});
Далее, при повторном запросе, данные из базы данных будет лежать в userData, а данные из платформы в state.
При этом, важно учитывать тот факт, что логика с локальным хранилищем будет работать только в том случае, если сама
платформа поддерживает такое поведение.
Подобное сделать можно. Для этого напишите следующий код:
import { Bot } from 'umbot';
const bot = new Bot();
bot.setAppConfig({
isLocalStorage: true, // говорим что данные сохраняются в локальное хранилище платформы
});
bot.addCommand('test', ['сохранить'], (_, cBot) => {
cBot.userData = {}; // Сохраняем даныне в хранилище платформы.
// Ваша логика
});
Обратите внимание, что используется userData, данная механика реализована для удобства работы в сценариях, когда не
подразумевается использование базы данных.
Также важно учитывать что задан isLocalStorage, без его указания, механика работать не будет.
Информация только для базовых адаптеров платформ. При использовании сторонних адаптеров, поведение может отличаться.
В случае, если происходит попытка записать данные в userData и в state, то поведение может быть скудеющим:
userData, будут сохранены в базу, а в локальное
хранилище запишется state.state.BasePlatformAdapterisPlatformOnQuery, setQueryData, getContentbot.use(new MyPlatformAdapter(token));
По умолчанию рекомендуется использовать fullPlatforms, который подключает все платформы. Для подключения конкретных
платформ выполните следующие действия:
import { TelegramPlatform, VkPlatform } from 'umbot/plugins';
// Подключаем телеграм и вк
bot.use(new TelegramPlatform(telegramToken)).use(new VkPlatform(vkToken));
Также не стоит забывать о том, что можно подключить только голосовые платформы(voicePlatforms), либо только платформы
для чат-ботов(botPlatforms)
Проверьте:
Используйте класс BotTest:
import { BotTest } from 'umbot/test';
import { fullPlatforms } from 'umbot/plugins';
const bot = new BotTest();
bot.use(fullPlatforms);
bot.test(); // Запускает интерактивный режим в консоли
Логи сохраняются в директорию, указанную в error_log:
bot.setAppConfig({
error_log: './logs',
});
В режиме разработки (dev) ошибки также выводятся в консоль.
bot.setAppMode('dev');
Это означает, что входящий текст не совпал ни с одним слотом или командой. Проверьте:
Проблема: Файловая БД переполняется, из-за чего приложение в какой-то момент может упасть с ошибкой. Решение:
Платформы (Алиса, Сбер и др.) дают максимум 3 секунды на ответ. Оптимизация:
Проблема: В ваших регулярных выражениях обнаружена потенциальная уязвимость. Решение:
bot.setAppMode('strict_prod')umbot автоматически проверяет регулярные выражения на уязвимости.
В строгом режиме все потенциально опасные регулярки будут отклоняться.
bot.getAppContext().httpClient = async (url, options) => {
// Ваша реализация
return fetch(url, options);
};
// Вариант 1: объект
class MyI18nPlugin implements IPlugin {
init(appContext: AppContext<IDatabaseInfo>) {
appContext.plugins['i18n'] = {
getData(key: string, ...params: any[]): string {
return `Translated: ${key}`;
},
};
}
}
// Вариант 2: функция
const myNluPlugin: IPluginFn = (appContext: AppContext) => {
appContext.plugins['i18n'] = (input: string, ctx?: any) => ({
intent: 'default',
entities: {},
});
};
myNluPlugin.isPlugin = true; // маркер обязательного наличия
bot.use(i18n);