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 terminalSIGTERM— process termination commandunhandledRejection— 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
Transport start
According to MODE:
ws— WebSocket with fallback to pollingpoll— 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=refUsage 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
inflightSet
Terminate the process
After waiting or the timeout — process.exit(0).
// Логи при завершенні:
// [info] bot SIGINT: shutting down, inflight=2
// [info] bot stopped after 2h 34m 12sMake 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"| Field | Description |
|---|---|
updates | Updates received |
errors | Errors in handlers |
apiCalls | HTTP requests to the API |
apiErrors | Failed HTTP requests |
dupes | Duplicate 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