/** One public slash command as Telegram publishes it. */ export interface BotCommandEntry { command: string; description: string; } /** Per-language values; the FIRST key doubles as the unlocalized default. */ export type Localized = Record; /** The structural bot surface the sync needs (satisfied by a gramio Bot). Param shapes are * EXACT (never bare `object`): a looser param type would make real client methods — which * require specific fields — unassignable (function-parameter contravariance). */ type Lang = { language_code?: string; }; export type ProfileBot = { info?: { username?: string; supports_inline_queries?: boolean; supports_guest_queries?: boolean; can_connect_to_business?: boolean; can_read_all_group_messages?: boolean; }; api: { /** Optional in the type: needs gramio with Bot API 10.1+ types (declaring `photo` on an * older client logs an error instead of silently doing nothing). */ setMyProfilePhoto?: (p: { photo: { type: "static"; photo: Blob; }; }) => Promise; getMyName: (p: Lang) => Promise<{ name?: string; }>; setMyName: (p: { name: string; } & Lang) => Promise; getMyDescription: (p: Lang) => Promise<{ description?: string; }>; setMyDescription: (p: { description: string; } & Lang) => Promise; getMyShortDescription: (p: Lang) => Promise<{ short_description?: string; }>; setMyShortDescription: (p: { short_description: string; } & Lang) => Promise; getMyCommands: (p: Lang) => Promise>; setMyCommands: (p: { commands: BotCommandEntry[]; } & Lang) => Promise; sendMessage: (p: { chat_id: number; text: string; }) => Promise; /** Optional: lets capability checks read LIVE state instead of the boot snapshot. */ getMe?: () => Promise; }; }; export interface BotProfileOptions { /** Display name (`setMyName`, 64 chars). */ name?: Localized; /** "What can this bot do?" (`setMyDescription`, 512 chars). */ description?: Localized; /** About / short description (`setMyShortDescription`, 120 chars). */ about?: Localized; /** Public command list per language (admin commands stay out — they're behavior, not menu). */ commands?: Localized>; /** * Profile photo as CODE (`setMyProfilePhoto`, Bot API 10.1+): commit the art, declare it * here, and a fresh token (or a garbage BotFather upload) heals on the next boot. Telegram * re-encodes uploads, so bytes can't be diffed against the current photo — `version` IS the * identity: it's persisted via `applied` after a successful set, and the sync re-uploads * only when the declared version differs from the stored one. Bump it when the art changes. */ photo?: { /** JPEG bytes, square, ≥512px (Workers: bundle the asset via a wrangler `Data` rule). */ data: ArrayBuffer | Uint8Array; /** The art's identity ("ghost-v1") — bump to force a re-upload. */ version: string; /** Where the applied-version marker persists (the bot's own config record). */ applied: { get: () => Promise; set: (version: string) => Promise; }; }; /** * BotFather-only capabilities this bot's features assume. Checked against `getMe` on every * sync; a mismatch WARNS the admins (it can't be fixed over the API, only surfaced). */ expects?: { inline?: boolean; guestQueries?: boolean; secretary?: boolean; /** Group Privacy, inverted to what it grants: `true` = the bot must SEE ordinary group * messages (privacy disabled), `false` = privacy must stay on. */ readsGroups?: boolean; }; /** Admins to DM on an expectation mismatch: a plain array or a live resolver. */ adminIds?: readonly number[] | (() => Promise | readonly number[]); } /** * Reconcile the declared profile with Telegram, field by field, language by language — * writes only genuine diffs. Never throws. Call fire-and-forget after `bot.init()`. */ export declare function syncBotProfile(bot: ProfileBot, opts: BotProfileOptions): Promise; /** The bot's BotFather-governed capabilities, read LIVE when possible: `bot.info` is the * boot-time getMe snapshot, and a BotFather flip must be visible to the very next check, * not to the next isolate (the stale heads-up bug class). Normalizes gramio's camelCase * and the raw API's snake_case; falls back to the snapshot if the call fails. */ export declare function botCapabilities(bot: ProfileBot): Promise<{ inline?: boolean; guestQueries?: boolean; secretary?: boolean; readsGroups?: boolean; }>; export {}; //# sourceMappingURL=profile.d.ts.map