umbot
    Preparing search index...

    Migrating from umbot 2.x to 3.0

    This page is machine-translated from the Russian original. If something reads oddly, the Russian version is the source of truth — open an issue.

    Version 3.0.0 is a major update focused on modularity, flexibility and modern standards. We moved to a plugin architecture, updated the runtime requirements and made extending the functionality simpler.

    Version 2.x.x is in maintenance mode: only critical bug fixes are accepted.

    1. Plugin architecture — platform handling now lives in separate plugins. This lets you connect only the integrations you need and extend the functionality with third-party modules (for example, request validation or command rate limiting)
    2. Custom RegExp — since version 2.2.0 the framework supports re2 out of the box. You can also plug in your own regular expression implementation.
    3. Proactive messages — a send method was added for sending messages to users without an incoming request.
    4. Custom NLU provider — more flexibility through appContext.plugins.nlu.
    5. External i18n support — lets you build localized applications through appContext.plugins.i18n.
    6. Dependency updates — the minimum Node.js version is now 20.19. Version 18 has reached end of life.
    7. Faster regex search — the current implementation groups and caches RegExps. For further optimization with a large number of regex commands, use re2 and setCustomCommandResolver.
    8. Steps with addStep — a step bound to the name of the previous intent (controller.oldIntentName) or to an intent from the NLU is handled without iterating over the command list: the lookup goes straight to the step registry.
    9. Asynchronous handlers — command handlers can now be asynchronous (async/await).
    10. Overriding the webhook response — webhookHandle got a 3rd callback argument for overriding the response. run also accepts auth (the 3rd argument) and clientIp (the 4th argument).

    Before 3.0, all platform handling was built into the framework itself. In 3.0 we moved to an adapter-based architecture, so for your application to keep working you need to switch to the new mechanism. You can do it in the following ways:

    1. Pass a function that registers all platforms
        import { fullPlatforms } from 'umbot/plugins';
    import { Bot } from 'umbot';

    const bot = new Bot();
    bot.use(fullPlatforms); // Connect all platforms
    ```

    2. Pass a platform adapter

    ```ts
    import { AlisaAdapter, MarusiaAdapter } from 'umbot/plugins';
    import { Bot } from 'umbot';

    const bot = new Bot();
    bot.use(new AlisaAdapter()); // Connect the Alice platform
    bot.use(new MarusiaAdapter()); // Connect the Marusia platform
    ```

    Adapters can be combined — for example, you can connect Alice and a Telegram bot at the same time.

    The list of all adapters available out of the box:

    ```ts
    import { adapters } from 'umbot/plugins';

    You can also connect only voice platforms or only chatbot platforms — there are dedicated functions for that:

    • voicePlatforms - registers voice platforms only
    • botPlatforms - registers chatbots only

    For a single, clear format, all sounds and sound effects were moved to SoundConstants. This approach lets you create sound effects without tying them to a platform. How it used to work

    import { AlisaSound } from 'umbot';

    botController.tts = `${AlisaSound.S_AUDIO_GAME_WIN} `.repeat(i).trim();

    How it works now

    import { SoundConstants } from 'umbot';

    botController.tts = `${SoundConstants.S_AUDIO_GAME_WIN} `.repeat(i).trim();

    The framework then passes it to the adapter, and the adapter itself converts the text to the right form. The behavior depends on the platform: voice platforms (Alice, Marusia) replace or remove unsupported effects from tts, while chat platforms (Telegram, VK, etc.) build audio with a separate mechanism — via SpeechKit and sending audio files.

    In 3.x the run() signature changed: run(appType, content, auth, clientIp) — the first argument is the platform type, not the controller class. The controller class is set once with initBotController (or the Bot constructor).

    Before

    import { Bot, Alisa, T_ALISA } from 'umbot';

    const bot = new Bot(T_ALISA);
    const botClass = new Alisa(bot._appContext);
    bot.run(botClass, T_ALISA);

    now

    import { Bot } from 'umbot';
    import { AlisaAdapter, T_ALISA } from 'umbot/plugins';

    const bot = new Bot(T_ALISA);
    bot.use(new AlisaAdapter());
    // content is required: without it (or without a prior setContent) run() throws an error.
    // The payload must be a valid Alice request: without version/session the adapter will not recognize the platform
    bot.run(
    T_ALISA,
    JSON.stringify({
    version: '1.0',
    session: { message_id: 0, session_id: 'local', skill_id: 'local_test', user_id: 'user-1' },
    request: { command: 'hello', original_utterance: 'hello', type: 'SimpleUtterance' },
    }),
    );

    Starting with 3.0, the framework has no default database connection out of the box, so you need to connect the adapter you need yourself. You can do it like this:

    import { Bot } from 'umbot';
    import { FileAdapter, MongoAdapter } from 'umbot/plugins';

    const bot = new Bot();
    bot.use(new FileAdapter()); // Connect the file database
    bot.use(
    new MongoAdapter({
    host: process.env.DB_HOST ?? 'mongodb://localhost:27017',
    user: process.env.DB_USER,
    pass: process.env.DB_PASSWORD,
    database: process.env.DB_NAME ?? 'umbot',
    }),
    ); // Connect MongoDb

    You can now also provide your own database adapter.

    ⚠️ Important: only one database adapter can be used at a time. If several are registered, the last one is used.

    bot.run() no longer takes a platform class as its first argument — all platforms are now registered with bot.use(). Before

    import { Bot, Alisa, T_ALISA } from 'umbot';

    const bot = new Bot();
    bot.run(Alisa, T_ALISA, content);

    Now

    import { Bot } from 'umbot';
    import { T_ALISA, AlisaAdapter } from 'umbot/plugins';

    const bot = new Bot();
    bot.use(new AlisaAdapter());
    bot.run(T_ALISA, content);

    Before 3.0, defining your own platform was inconvenient for the following reasons:

    1. It was not quite clear how to define it and how the platform logic should work.
    2. Only 1 custom platform could be defined

    The move to adapters solved these problems. The documentation on defining your own platform was improved and became clearer. You can also create many platforms of your own and connect them.

    The old way of defining a platform looked like this:

    1. Extend TemplateTypeModel, defining the required methods.
    2. Pass the class to the application itself The connection code looked like this:
    import { BotTest, IBotTestParams } from 'umbot/test';
    import skillStorageConfig from '../../config/skillStorageConfig';
    import skillDefaultParam from '../../config/skillDefaultParam';
    import { UserAppController } from './controller/UserAppController';
    import { UserApp } from './UserTemplate/Controller/UserApp';
    import userDataConfig from './UserTemplate/userDataConfig';

    const bot = new BotTest();
    bot.setAppConfig(skillStorageConfig());
    bot.setPlatformParams(skillDefaultParam());
    bot.initBotController(UserAppController);

    //bot.run(userApp);
    /**
    * Show the skill response and the storage in the console.
    */
    const params: IBotTestParams = {
    isShowResult: true,
    isShowStorage: false,
    isShowTime: true,
    userBotClass: UserApp,
    userBotConfig: userDataConfig,
    };
    bot.test(params);

    In the new version you also extend a base class, but instead of TemplateTypeModel it is BasePlatformAdapter, which lives in umbot/plugins. Then, following the documentation, define the required methods and connect the adapter to the application with bot.use. A demo is available in examples/skills/UserApp of this repository. The resulting code looks like this:

    import { BotTest, IBotTestParams } from 'umbot/test';
    import skillStorageConfig from '../../config/skillStorageConfig';
    import skillDefaultParam from '../../config/skillDefaultParam';
    import { UserAppController } from './controller/UserAppController';
    import { UserAdapter } from './UserTemplate/Adapter/UserAdapter';

    const bot = new BotTest();
    bot.use(new UserAdapter()); // Connect the custom platform adapter
    bot.setAppConfig(skillStorageConfig());
    bot.setPlatformParams(skillDefaultParam());
    bot.initBotController(UserAppController);

    //bot.run();
    /**
    * Show the skill response and the storage in the console.
    */
    const params: IBotTestParams = {
    isShowResult: true,
    isShowStorage: false,
    isShowTime: true,
    };
    bot.test(params);

    Before 3.0

    1. Extend DbControllerModel, defining all the required methods.
    2. Connect it with bot.use(new DbConnect())

    In the new version you extend BaseDbAdapter, which lives in umbot/plugins. Then, following the documentation, define the required methods and connect the adapter to the application with bot.use. A demo is available in examples/skills/userDbConnect of this repository.