import { type Api, type FileReader } from "./api.js"; import { Composer } from "./composer.js"; import { Context } from "./context.js"; import type { Update, UpdateName, User } from "./telegram-types.js"; import type { HandleUpdateOptions } from "./webhook.js"; export type BotPlugin> = (bot: Bot) => Bot; export interface BotOptions { apiRoot?: string; /** * resolve `media.path()` into bytes. injected per runtime so core stays free of any * `node:` import. the `yaebal` package wires an auto-detecting default; on bare core * (or edge) leave it unset and `media.path()` throws — send `media.buffer()`/`url()`. */ readFile?: FileReader; /** update types to request; `undefined` = telegram default. */ allowedUpdates?: UpdateName[]; /** * build the context for each update. defaults to the base {@link Context}. * higher-level packages (e.g. the `yaebal` meta-package) inject a factory here * to produce richer per-update contexts with auto-generated shortcut methods. * `me` is the bot's own account when known (long polling fills it after `getMe`). */ contextFactory?: (api: Api, update: Update, updateType: UpdateName, me?: User) => Context; /** * the bot's own account, if already known — skips the `getMe` that `init()` / * `start()` would otherwise fire. worth passing on serverless webhooks to * shave a round trip off the cold start. */ botInfo?: User; } type StartHandler = (info: User) => unknown | Promise; type StopHandler = () => unknown | Promise; type ErrorHandler = (error: unknown, ctx: Context) => unknown | Promise; /** what the polling loop knows about a failure when it hands it to {@link Bot.onPollingError}. */ export interface PollingErrorInfo { /** how many consecutive `getUpdates` calls have failed, this one included. resets on success. */ attempt: number; /** how long the loop waits before the next attempt. */ retryInMs: number; /** true when the poll was aborted (the hang timer fired) rather than failing on the wire. */ aborted: boolean; } type PollingErrorHandler = (error: unknown, info: PollingErrorInfo) => unknown | Promise; /** * the bot. extends {@link Composer}, so the whole chainable, type-accumulating * surface is available — and `derive` / `decorate` / `extend` keep returning a * `Bot` (not a bare `Composer`) so lifecycle methods stay reachable down the chain. */ export declare class Bot extends Composer { #private; readonly api: Api; constructor(token: string, options?: BotOptions); /** bot account info, available after `init()` / `start()` (or via the `botInfo` option). */ get info(): User | undefined; /** * resolve the bot's own account via `getMe` — cached, concurrent calls * coalesce, and the `botInfo` option skips the request entirely. `start()` * runs this; webhook handlers run it lazily on the first update so * `ctx.me` and `/cmd@botname` addressing work without long polling. */ init(): Promise; derive(fn: (ctx: C) => D | Promise): Bot; derive(updates: UpdateName | UpdateName[], fn: (ctx: C) => D | Promise): Bot>; decorate(value: D): Bot; guard(predicate: (ctx: C) => ctx is C2): Bot; guard(predicate: (ctx: C) => boolean | Promise): this; extend(other: Composer): Bot; install(plugin: (composer: Composer) => Composer): Bot; install(plugin: (bot: Bot) => Bot): Bot; /** register a callback fired once the bot has started. */ onStart(handler: StartHandler): this; /** register a callback fired when `stop()` is requested or polling exits. */ onStop(handler: StopHandler): this; /** replace the default error handler. */ onError(handler: ErrorHandler): this; /** * replace the default polling-error handler (a `console.error`). called when a `getUpdates` * long poll fails; polling retries either way, backing off 3s → 30s while failures repeat and * resetting on the first success. the second argument carries the consecutive-failure count and * the wait before the next attempt, so an alerting handler can throttle itself. * * the routine hang-timeout abort (a connection a proxy dropped without closing) is retried * silently the first {@link POLL_QUIET_ABORTS} times — only a run of them reaches the handler. */ onPollingError(handler: PollingErrorHandler): this; /** * run the middleware chain for a single update. this is the webhook entry * point — call it from your HTTP handler. errors go to the error handler. * * the chain is realized (and frozen) on the first call, so register all * middleware/plugins before the first `handleUpdate` / `start`. */ handleUpdate(update: Update, options?: HandleUpdateOptions): Promise; /** * start long polling. resolves only when `stop()` is called — it is the loop itself, not a * fire-and-forget kick, so hold the promise (`const polling = bot.start()`) if anything else * has to run after it. * * updates in a batch are handled strictly one after another. that keeps ordering trivial, but * one slow handler delays every update behind it — long enough and telegram rejects the * follow-up with "query is too old and response timeout expired" (callback queries) or drops * an inline answer. install `@yaebal/runner` for bounded concurrency (per-chat order kept) * when handlers do real work. */ start(): Promise; /** stop the polling loop (aborting the in-flight long poll) and run registered stop handlers once. */ stop(): Promise; } export {}; //# sourceMappingURL=bot.d.ts.map