Yurst

Lifecycle

Startup, graceful shutdown, and bot information

Lifecycle

bot.start()

await bot.start();

Performs a sequence of steps to start the bot:

Signal registration

Subscribes to system signals:

  • SIGINT — Ctrl+C in the terminal
  • SIGTERM — process termination command
  • unhandledRejection — unhandled promises

Authentication

Performs GET /bot/me:

  • Checks the validity of the token
  • Retrieves bot data
  • Stores the result in bot.me

If the status is 401 — the process terminates with an error.

Command registration

Performs PUT /bot/commands with the command list:

  • Sends only commands with register !== false
  • Format: { Command, Description, Scope }
  • An empty list clears the registered commands

Delivery check

Performs GET /bot/delivery:

  • Checks the update delivery mode
  • Logs the result

Transport start

According to MODE:

  • ws — WebSocket with fallback to polling
  • poll — polling right away

Register before starting

Add commands, callbacks, and listeners before await bot.start(). The command list is sent to Yurba during startup.

In normal operation, bot.start() does not finish — the bot receives updates indefinitely.

bot.me — bot information

After a successful start, the bot.me getter is available:

bot.me.data           // Повний об'єкт User або null
bot.me.name           // Ім'я бота або null
bot.me.link           // Username без @ або null
bot.me.id             // Числовий ID або null
bot.me.invite()       // https://yurba.one/messenger?bot=username
bot.me.invite('ref')  // https://yurba.one/messenger?bot=username&start=ref

Usage example

bot.command('info', 'Інформація про бота', (ctx) => {
  const info = [
    `Ім'я: ${bot.me.name}`,
    `Username: @${bot.me.link}`,
    `ID: ${bot.me.id}`,
  ].join('\n');

  return ctx.reply(info);
});

bot.command('invite', 'Запросити друзів', (ctx) => {
  const ref = ctx.user?.ID ?? '';
  return ctx.reply(`Поширь це посилання:\n${bot.me.invite(`ref_${ref}`)}`);
});

Access them in handlers

Until the /bot/me request completes, the bot.me fields are null. Use bot.me in handlers, not at the top level of the module.

Payload encoding

bot.me.invite(payload) does not encode the value automatically. If the payload may contain special characters:

bot.me.invite(encodeURIComponent(payload));

Graceful Shutdown

When a termination signal is received (SIGINT / SIGTERM):

Stop receiving

Stops accepting new updates from the transport.

Close WebSocket

Closes the active WebSocket connection.

Wait for handlers

Waits for handlers that are already running to finish:

  • No longer than 5 seconds
  • Tracks all active promises via the inflight Set

Terminate the process

After waiting or the timeout — process.exit(0).

// Логи при завершенні:
// [info] bot SIGINT: shutting down, inflight=2
// [info] bot stopped after 2h 34m 12s

Make handlers interruptible or short. Long operations (>5s) will be interrupted during shutdown.

Runtime statistics

Yurst maintains counters:

import { stats, fmtUptime } from 'yurst.js';

console.log(stats);
// {
//   updates: 1523,
//   errors: 2,
//   apiCalls: 1540,
//   apiErrors: 0,
//   dupes: 3
// }

console.log(fmtUptime());
// "2h 34m 12s"
FieldDescription
updatesUpdates received
errorsErrors in handlers
apiCallsHTTP requests to the API
apiErrorsFailed HTTP requests
dupesDuplicate updates

Full cycle example

import { bot, stats, fmtUptime } from 'yurst.js';

// Реєстрація (до старту!)
bot.command('start', 'Почати', (ctx) => {
  const ref = ctx.payload || 'direct';
  return ctx.reply(`Вітаємо! Реферал: ${ref}`);
});

bot.command('stats', 'Статистика', (ctx) => {
  const info = [
    `Оновлень: ${stats.updates}`,
    `Помилок: ${stats.errors}`,
    `Аптайм: ${fmtUptime()}`,
  ].join('\n');
  return ctx.reply(info);
});

// Старт
console.log('Starting bot...');
await bot.start();

One start per process

bot.start() is designed for one call per process lifetime:

  • There is no protection against a repeated call
  • Re-registering signals will lead to duplicate handlers
  • To restart, use a process manager (PM2, Docker, and so on)

Do not call bot.start() several times. Restart the process to update the code.

Next

Transport

WebSocket, long polling, and details of receiving updates

On this page