Skip to content

Architecture ​

Verse Bot is built around a platform-neutral UniversalContext and separate adapters for Telegram and VK. A command can be implemented once and used on both platforms.

UniversalContext ​

UniversalContext hides the differences between the Telegram and VK APIs. Commands can use it to:

  • reply to a user with reply or replySafe;
  • inspect the message through text, userId and chatType;
  • check permissions through isAdmin;
  • access the optional database client through db;
  • send keyboards and photos through either built-in adapter, and files when the adapter supports them;
  • handle inline callbacks through callback.data, answer and editMessage;
  • inspect original update payloads and asynchronous admin checks.

replySafe removes reply-keyboards from group chats. Both built-in adapters honor one-time keyboards and keyboard removal through the shared reply options. File sending is optional because some platform APIs require additional upload scopes.

Adapters ​

  • @verse-bot/telegram creates a bot with grammY, converts updates into UniversalContext and registers commands.
  • @verse-bot/vk uses vk-io for VK API access and Long Poll events, then converts them into UniversalContext.

Both adapters dispatch simple button commands through the shared command map. Their optional onCallback handlers receive normalized string data; ctx.payload preserves the original platform payload when an application needs it.

Universal bot factories ​

createUniversalTelegramBot and createUniversalVKBot hide the shared setup: authentication middleware, logging and command dispatch. Pass the command handlers and keyboard definitions that your application needs.

ts
const telegramBot = createUniversalTelegramBot({
  token: '...',
  commands: { start: startCommand },
  buttons: [{ command: 'start', label: 'Start' }],
});

await telegramBot.start();

Message lifecycle ​

  1. Telegram or VK sends an update.
  2. The adapter creates a UniversalContext.
  3. If database is configured, the middleware creates or finds the user when appropriate.
  4. The command is logged when persistence is enabled.
  5. The matching command handler runs.
  6. The handler replies through the context.

The command itself stays independent of the platform. Platform-specific differences remain in the adapters and in optional rendering code owned by the application.