public api reference

the generated bot api reference covers telegram methods and objects. this page maps the public yaebal library surface: the engine, context, api client, plugin contracts and storage interfaces.

checked against source. the stable source of truth is the exported types from each package. this page is the human entry point; pnpm docs:check typechecks every snippet on this page against the workspace packages, so the examples cannot drift silently.

core package

symbolkinduse it for
Botclasstoken-bound composer with polling, lifecycle hooks, api client and webhook entrypoint
Composerclassstandalone middleware chain for feature modules and plugin composition
Contextclassbase per-update wrapper with update accessors and reply/send helpers
Apiinterfacetelegram api client with typed known methods, call() and hooks
Plugintypecomposer extension that adds typed context fields
BotPlugintypebot extension that needs bot-only lifecycle or api access
Middlewaretypekoa-style (ctx, next) handler
Filterinterfacetype-guard predicate consumed by composer.filter()
FilterQuerytypegrammy-style query strings such as message:text
MediaSourcetypefile id, url, buffer or path input for media sends
mediahelperbuilds a MediaSource: media.path(), media.url(), media.buffer(), media.fileId()
formathelperentity-based formatting: tagged template plus bold, italic, link, …
webhookCallbackfunctionfetch-style (Request) => Promise<Response> webhook handler
TelegramErrorclassthrown on failed api calls; carries method, code, description, parameters

bot

Bot<C> extends Composer<C>. every context-enriching method keeps returning a bot so lifecycle methods stay reachable after derive(), decorate(), install() and extend().

bot.ts
import { Bot } from "@yaebal/core";

const bot = new Bot(process.env.BOT_TOKEN!, {
  allowedUpdates: ["message", "callback_query"],
});

bot.onStart((me) => console.log("started @" + me.username));
bot.onError((error, ctx) => console.error(ctx.update.update_id, error));

// long polling — resolves only when bot.stop() is called
await bot.start();

long polling and webhooks are alternatives: call start() for polling, or skip it and export the webhookCallback() handler instead — see webhooks for per-runtime setups.

webhook.ts
import { Bot, webhookCallback } from "@yaebal/core";

const bot = new Bot(process.env.BOT_TOKEN!);

// fetch-style handler — the webhook alternative to bot.start()
export default {
  fetch: webhookCallback(bot, { secretToken: process.env.WEBHOOK_SECRET }),
};
apidescription
new Bot(token, options?)creates the api client and composer-backed bot
start() / stop()long polling lifecycle
handleUpdate(update)run one update through the realized chain; used by webhooks and tests
onStart() / onStop() / onError()lifecycle and handler-failure hooks
apithe low-level telegram api client

composer

Composer is the reusable middleware engine. feature files should usually export a composer, not a token-bound bot.

composer.ts
import { Composer, type Context, type Plugin } from "@yaebal/core";

const shared = new Composer()
  .decorate({ app: "shop" as const })
  .derive(async (ctx) => ({ requestId: crypto.randomUUID() }));

const feature = new Composer()
  .extend(shared)
  .command("start", (ctx) => ctx.reply(ctx.app));

type NeedsApp = Context & { app: string };
const plugin: Plugin<NeedsApp, { ready: true }> = (composer) =>
  composer.decorate({ ready: true as const });
methodtype behavior
use(...middleware)keeps the same context type
on(query, ...handlers)narrows handlers with Filtered<C, Q>
command(), hears(), callbackQuery()attach match/command fields for the handler
guard(predicate)runtime gate, no type widening
filter(filter, ...handlers)uses the filter's type guard to narrow context
derive()async per-update enrichment; returns Composer<C & D>
decorate()static zero-per-update enrichment; returns Composer<C & D>
install(plugin)applies a typed plugin and checks its required input context
extend(composer)merges another composer and carries both context types forward

context

Context exposes the raw update plus safe accessors: message, callbackQuery, from, chat, text, routing helpers and base shortcuts such as send(), reply(), sendPhoto(), sendDocument(), answerCallbackQuery(). use generated contexts via createBot() when you want every schema-derived shortcut.

api client

Api is deliberately small: known high-traffic methods are direct, every other telegram method goes through call<T>(), and hooks let plugins implement retry, logging, metrics and transforms.

api.ts
import { Bot } from "@yaebal/core";

const bot = new Bot(process.env.BOT_TOKEN!);

bot.api.before((method, params) => {
  console.log("telegram ->", method);
  return params;
});

bot.api.after((method, params, result) => result);

bot.api.onError((method, error, attempt) => {
  if (attempt < 3) return { retry: true, delayMs: 500 };
});

await bot.api.call("sendMessage", { chat_id: 123, text: "hello" });

plugin contracts

typewhen to use
Plugin<In, Out>composer-only extension that requires In and adds Out
BotPlugin<In, Out>extension that needs bot.api, lifecycle hooks or bot-only behavior
Filter<C, Add>type-narrowing predicate for composer.filter()

storage interfaces

stateful plugins expose tiny storage contracts instead of global adapters. sessions use StorageAdapter<T>; broadcasts use BroadcastStorage for durable jobs and deliveries.

storage.ts
import { Bot } from "@yaebal/core";
import { session, type StorageAdapter } from "@yaebal/session";

class RedisStorage<T> implements StorageAdapter<T> {
  get(key: string): Promise<T | undefined> { /* load */ throw new Error("todo"); }
  set(key: string, value: T): Promise<void> { /* save */ throw new Error("todo"); }
  delete(key: string): Promise<void> { /* delete */ throw new Error("todo"); }
}

const bot = new Bot(process.env.BOT_TOKEN!);

bot.install(session({
  initial: () => ({ count: 0 }),
  storage: new RedisStorage<{ count: number }>(),
}));

package references

packageprimary exports
yaebalcreateBot, generated contexts, common plugins and core re-exports
@yaebal/coreBot, Composer, Context, Api, media, format, webhookCallback
@yaebal/typesgenerated telegram bot api types and method params
@yaebal/contextsgenerated per-update context classes and shortcut methods
@yaebal/sessionsession, StorageAdapter, MemoryStorage
@yaebal/broadcastBroadcast, createBroadcast, BroadcastStorage, MemoryBroadcastStorage
next: use bot api reference for telegram methods and packages map for every first-party package.