cheat sheet
the most common yaebal patterns on one page.
setup
pnpm add yaebal
import { createBot } from "yaebal";
const bot = createBot(process.env.BOT_TOKEN!);
await bot.start();handlers
bot.command("start", (ctx) => ctx.reply("hi"));
bot.hears(/buy (.+)/, (ctx) => ctx.reply("matched"));
bot.callbackQuery(/^page:(\d+)$/, (ctx) => ctx.answerCallbackQuery());
bot.on("message:text", (ctx) => ctx.text);| method | use |
|---|---|
command | /start, /help, command args |
hears | text/caption string or regexp matches |
callbackQuery | inline button callbacks |
on("message:text") | filter query with typed narrowing |
context enrichment
const bot = createBot(token)
.derive(async (ctx) => ({ user: await loadUser(ctx.from?.id) }))
.decorate({ version: "1.0.0" })
.on("message:text", (ctx) => {
ctx.user;
ctx.version;
ctx.text;
});keyboards and callback data
import { InlineKeyboard, callbackData } from "yaebal";
const vote = callbackData("vote", { id: Number });
await ctx.reply("pick", {
reply_markup: new InlineKeyboard()
.text("yes", vote.pack({ id: 1 }))
.text("no", vote.pack({ id: 2 })),
});formatting
import { html, format, bold, link } from "yaebal";
await ctx.send(html`<b>hello</b> ${user.name}`);
await ctx.send(format`${bold("safe entities")} ${link("docs", "https://yaebal.pages.dev")}`);media
import { media } from "yaebal";
await ctx.sendPhoto(media.url("https://example.com/cat.jpg"));
await ctx.sendDocument(media.path("./report.pdf"));
await ctx.sendPhoto("AgACAgIAAx...");sessions and i18n
import { session, i18n } from "yaebal";
const bot = createBot(token)
.install(session({ initial: () => ({ count: 0 }) }))
.install(i18n({ defaultLocale: "en", locales: { en: { hi: "hello" } } }))
.command("count", (ctx) => ctx.reply(String(++ctx.session.count)));webhooks
import { createBot, webhook } from "yaebal";
const bot = createBot(env.BOT_TOKEN);
export default { fetch: webhook(bot, { secretToken: env.SECRET }) };testing
import { createTestEnv } from "@yaebal/test";
const env = createTestEnv(bot);
const user = env.createUser({ firstName: "Linia" });
await user.sendCommand("start");
env.lastApiCall("sendMessage")?.params?.text;production defaults
@yaebal/againfor structuredretry_afterand 5xx retry.@yaebal/throttlefor outgoing Telegram buckets and priority queues.@yaebal/runnerfor concurrent polling with per-chat ordering.@yaebal/testfor in-process bot tests.