import type { ActionControllerParams, Filter, GetBusinessAccountGiftsParams, GetChatGiftsParams, GetUserGiftsParams, MessageUpdate, SendChatActionParams, TelegramDispatchers, TelegramShortcuts, TelegramUser } from '@puregram/api'; import { CallbackQueryUpdate } from '@puregram/api'; import { ChatActionController } from './api/chat-action.js'; import type { DownloadTarget } from './api/download.js'; import type { TelegramApi } from './api/proxy.js'; import { type ManualShortcuts } from './api/shortcuts.js'; import { CustomUpdateRegistry } from './dispatch/custom-updates.js'; import type { DispatchErrorHandler, ErrorHandler, HookOptions, Middleware, RequestContext, RequestHookName } from './dispatch/hooks.js'; import { HookRegistry } from './dispatch/hooks.js'; import type { AnyUpdate, OnOptions, UpdateHandler } from './dispatch/on.js'; import { Dispatcher } from './dispatch/on.js'; import type { ApiResponseError } from './errors.js'; import type { HttpClient } from './http/client.js'; import type { TelegramOptions, ResolvedTelegramOptions } from './options.js'; import type { Plugin } from './plugins/plugin.js'; import { PluginRegistry } from './plugins/registry.js'; import { PollingTransport, type StartPollingOptions } from './transport/polling.js'; import type { WebhookOptions } from './transport/webhook/index.js'; import { type DeleteWebhookOptions, type SetWebhookOptions } from './transport/webhook/helpers.js'; import type { StartWebhookOptions } from './transport/webhook/listener.js'; export interface Telegram extends TelegramShortcuts, TelegramDispatchers, ManualShortcuts { } export declare class Telegram { readonly options: ResolvedTelegramOptions; readonly api: TelegramApi; /** populated by startPolling on first getMe call */ bot: TelegramUser; protected readonly hooks: HookRegistry; protected readonly dispatcher: Dispatcher; protected readonly customUpdates: CustomUpdateRegistry; protected readonly plugins: PluginRegistry; protected readonly pendingPlugins: Plugin[]; protected readonly rawUpdateHandlers: ((raw: Record) => void | Promise)[]; protected readonly httpClient: HttpClient; protected readonly inFlight: Set>; protected readonly cleanups: (() => Promise)[]; protected readonly seenUpdates: Set; protected polling: PollingTransport | undefined; protected started: boolean; protected startPromise: Promise | undefined; private readonly apiCaller; constructor(input: TelegramOptions); static fromToken(token: string, options?: Partial): Telegram; static isErrorResponse(value: unknown): value is ApiResponseError; extend(plugin: Plugin): Telegram; }> & Ext & { [K in N]: Awaited; }; has(pluginName: string): boolean; start(): Promise; shutdown(): Promise; /** register a cleanup callback to run on `shutdown()`. userland can hook teardown onto the bot's lifecycle */ registerCleanup(fn: () => Promise): void; /** * register a handler for a specific update kind by name. the typed `on*` dispatchers * (`onMessage`, `onCallbackQuery`, …) cover the bot-api's curated kind list with full * type narrowing; this method also routes to custom kinds registered via `defineUpdate` */ on(kind: string, handler: UpdateHandler, options?: OnOptions): this; /** * register a cross-kind handler — fires for every supported update. the bare form * receives `AnyUpdate`; the filter form narrows via `Modify`. use * this for multi-kind handlers or custom predicates that don't fit per-kind dispatchers * * @example * ```ts * tg.onUpdate((update) => console.log('[any]', update.kind)) * * tg.onUpdate( * (u): u is MessageUpdate => u.is('message') && u.hasText(), * (m) => m.send(`echo: ${m.text}`) * ) * ``` */ onUpdate(handler: UpdateHandler, options?: OnOptions): this; onUpdate(filter: Filter, handler: UpdateHandler, options?: OnOptions): this; onUpdate(predicate: (update: AnyUpdate) => update is T, handler: UpdateHandler, options?: OnOptions): this; onUpdate(predicate: (update: AnyUpdate) => boolean | Promise, handler: UpdateHandler, options?: OnOptions): this; /** * register a raw-update handler — fires before kind discrimination, so it sees * even unknown kinds that landed in bot-api ahead of our schema regen. handler * arg is the raw payload from polling/webhook. handy for forward-compat logging * or ingestion pipelines that want every update before wrapper allocation */ onRawUpdate(handler: (raw: Record) => void | Promise): this; /** * register a command handler. string form matches `/hello`, `/hello arg`, * `/hello@bot`, or `/hello`-prefixed line break (Telegram conventions); regex form * runs against `message.text` directly. non-matching messages call `next()`. * matching messages get `match: RegExpMatchArray` attached for named captures * * @example * ```ts * tg.command(/^\/say(?:\s+(?.+))?$/i, async (m) => { * await m.send(m.match?.groups?.text ?? 'silence') * }) * ``` */ command(nameOrPattern: string | RegExp, handler: UpdateHandler): this; /** * register a handler against callback queries with matching data. string form is * equality on `update.raw.data`; regex form attaches `match: RegExpMatchArray` on success. * shorthand for `tg.onCallbackQuery(callbackData(value), handler)` * * @example * ```ts * tg.callbackQuery(/^buy:(?.+)$/, async (q) => { * await q.answer({ text: `bought ${q.match?.groups?.sku}` }) * }) * ``` */ callbackQuery(value: string | RegExp, handler: UpdateHandler): this; off(kind: string, handler: UpdateHandler): this; /** * register a handler for errors thrown by dispatched update handlers — alias * for `useHook('onDispatchError', fn)`. when `swallowDispatchErrors` is true * in options, registered catch handlers are the only escape hatch (otherwise * unhandled errors rethrow on a microtask and trip `uncaughtException`) * * @example * ```ts * tg.catch((err, ctx) => { * console.error('handler threw on update', ctx.raw.update_id, err) * }) * ``` */ catch(handler: DispatchErrorHandler): this; useHook(name: RequestHookName, fn: Middleware, options?: HookOptions): this; useHook(name: 'onApiCall', fn: Middleware, options?: HookOptions): this; useHook(name: 'onUpdate', fn: Middleware, options?: HookOptions): this; useHook(name: 'onInit' | 'onShutdown', fn: Middleware<{ tg: unknown; }>): this; useHook(name: 'onError', fn: ErrorHandler): this; useHook(name: 'onDispatchError', fn: DispatchErrorHandler): this; /** * register a dispatch middleware — shorthand for `useHook('onUpdate', fn, options)`. * default priority `'normal'` runs before `tg.on(...)` handlers and after `'high'` middleware * (waitFor/session). the 2-arg form gates on a `Filter` (equivalent to `when(filter, mw)`) * and benefits from the same `kinds` fast-path as `tg.on(filter, …)` * * @example * ```ts * tg.use(async (update, next) => { * const start = Date.now() * await next() * console.log(`update took ${Date.now() - start}ms`) * }) * * tg.use(f.chat.private, async (u, next) => { * console.log('[private]', u.kind) * await next() * }, { priority: 'high' }) * ``` */ use(fn: Middleware, options?: HookOptions): this; use(filter: Filter, mw: Middleware, options?: HookOptions): this; defineUpdate(kind: N): this; emit(kind: string, payload: Record): void; startPolling(options?: StartPollingOptions): Promise; stopPolling(): void; /** * framework-agnostic webhook handler consumed by `puregram/webhook/` * adapters. for raw `node:http` use `getWebhookCallback` */ webhookHandler(options?: WebhookOptions): import("./index.js").WebhookHandler; /** * node `http`/`https` callback. for express/koa/fastify/hono/h3/elysia, * import the matching adapter from `puregram/webhook/` */ getWebhookCallback(options?: WebhookOptions): import("./index.js").NodeWebhookCallback; /** * one-shot — starts the bot, calls `setWebhook`, and (when `port` is given) * spins up a built-in node `http` listener. `secretToken` is used both to * register the webhook and to validate incoming requests */ startWebhook(options: StartWebhookOptions): Promise<{ server: undefined; callback: import("./index.js").NodeWebhookCallback; stop: () => Promise; } | { server: import("http").Server; callback: import("./index.js").NodeWebhookCallback; stop: () => Promise; }>; setWebhook(options: SetWebhookOptions): Promise; resolveAllowedUpdates(value: string[] | 'auto'): string[]; iterUserProfilePhotos(userId: number, params?: { offset?: number; limit?: number; }): import("./api/paginate.js").PageIterator; iterUserProfileAudios(userId: number, params?: { offset?: number; limit?: number; }): import("./api/paginate.js").PageIterator; iterStarTransactions(params?: { offset?: number; limit?: number; }): import("./api/paginate.js").PageIterator; iterUserGifts(userId: number, params?: Omit): import("./api/paginate.js").PageIterator; iterChatGifts(chatId: number | string, params?: Omit): import("./api/paginate.js").PageIterator; iterBusinessAccountGifts(businessConnectionId: string, params?: Omit): import("./api/paginate.js").PageIterator; /** * a scoped api proxy that injects `business_connection_id` into every call — act on behalf of a * connected business account. a call-site `business_connection_id` overrides the bound one. * * @example * ```ts * const biz = tg.business(connectionId) * await biz.sendMessage({ chat_id, text: 'on behalf of the account' }) * ``` */ business(businessConnectionId: string): TelegramApi; /** * a scoped api proxy that injects `receiver_user_id` (and optionally `callback_query_id`) * into every call — send group messages visible only to one user. call-site params * override the bound ones. not chainable with `tg.business(…)` (both return flat api * proxies) — pass `business_connection_id` as a call-site param instead. * * @example * ```ts * const eph = tg.ephemeral(userId) * await eph.sendMessage({ chat_id, text: 'only you can see this' }) * ``` */ ephemeral(receiverUserId: number, callbackQueryId?: string): TelegramApi; deleteWebhook(options?: DeleteWebhookOptions): Promise; getWebhookInfo(): Promise; /** * download a telegram file into a `Buffer`. accepts a raw `file_id`, any * `MediaSource.fileId(...)`, any wrapper or raw payload, plus `Photo` / * `TelegramPhotoSize[]` (largest auto-picked). other upload variants throw `TypeError` * * @example * ```ts * const bytes = await tg.download(update.document) * ``` */ download(target: DownloadTarget): Promise>; /** download a Telegram file as a node `Readable` */ downloadStream(target: DownloadTarget): Promise; /** download a Telegram file as an async-iterable byte stream */ downloadIterable(target: DownloadTarget): Promise>>; /** download a Telegram file straight to disk */ downloadToFile(path: string, target: DownloadTarget): Promise; /** resolve the public download URL. calls `getFile` if needed — pass a resolved `File` to skip the round-trip */ getFileURL(target: DownloadTarget): Promise; /** * create a controller that re-sends `sendChatAction(action)` every `interval` * ms (default `5000`) until `stop()` is called — telegram clears the action * after ~5 seconds, so a long task needs it refreshed * * @example * ```ts * const controller = tg.createActionController(chatId, 'typing') * controller.start() * // ... long task ... * controller.stop() * ``` */ createActionController(chatId: number | string, action: SendChatActionParams['action'], options?: ActionControllerParams): ChatActionController; /** * run `fn` while continuously sending `sendChatAction(action)`. the action * auto-stops when `fn` settles — even if it throws — and `fn`'s result is * returned * * @example * ```ts * const photo = await tg.withChatAction(chatId, 'upload_photo', () => buildPhoto()) * ``` */ withChatAction(chatId: number | string, action: SendChatActionParams['action'], fn: () => Promise | T, options?: ActionControllerParams): Promise; dropPendingUpdates(value?: boolean | string[]): Promise; protected dispatch(update: AnyUpdate): Promise; protected handleIncoming(raw: Record): Promise; protected isDuplicateUpdate(raw: Record): boolean; protected dispatchAutoAnswered(update: CallbackQueryUpdate): Promise; private downloadDeps; private bootstrap; private trackInFlight; private drainInFlight; private runRawUpdateHandlers; private reportDispatchError; } declare module '@puregram/api' { interface MessageUpdate { match?: RegExpMatchArray; } interface EditedMessageUpdate { match?: RegExpMatchArray; } interface ChannelPostUpdate { match?: RegExpMatchArray; } interface EditedChannelPostUpdate { match?: RegExpMatchArray; } interface BusinessMessageUpdate { match?: RegExpMatchArray; } interface EditedBusinessMessageUpdate { match?: RegExpMatchArray; } interface CallbackQueryUpdate { match?: RegExpMatchArray; } interface InlineQueryUpdate { match?: RegExpMatchArray; } interface ChosenInlineResultUpdate { match?: RegExpMatchArray; } } //# sourceMappingURL=telegram.d.ts.map