Transport Fetch API reference
Exports of @gramforge/transport-fetch. Back to the module
Functions
albumSizeError
functionRuntime backstop for the compile-time {@link MediaGroupItems} tuple: a value that reaches `sendMediaGroup` via a cast or an `unknown`-typed JSON decode is length-checked here. Returns a `badRequest` `DeliveryResult` when out of the 2-10 range, or `null` when the size is valid.
albumSizeError(items: readonly MediaGroupItem[]): DeliveryResult<never> | null
createBotClient
functionBuild a {@link BotClient} bound to a token + `fetch`.
createBotClient(config: BotClientConfig): BotClient
mapDelivery
functionMap the success value of a {@link DeliveryResult} while preserving every error variant unchanged. Used to adapt one method's result type to another (e.g. an `EditMessageResult` down to a `TelegramMessage`) without a cast and without dropping the typed-error branches.
<A, B>(result: DeliveryResult<A>, transform: (value: A) => B): DeliveryResult<B>
toWireEntities
functionProject a whole rendered entity list to wire objects.
toWireEntities(entities: readonly MessageEntity[]): readonly WireEntity[]
toWireEntity
functionProject one rendered {@link MessageEntity} to its Bot API wire object.
toWireEntity(entity: MessageEntity): WireEntity
toInlineMessageId
functionBrand a raw string as an {@link InlineMessageId}.
toInlineMessageId(value: string): InlineMessageId
toRetryAfter
functionBrand a raw seconds number as a {@link RetryAfter}. Called only on a value already zod-parsed from the wire `parameters.retry_after` field.
toRetryAfter(seconds: number): RetryAfter
createLiveMessage
functionConstruct a {@link LiveMessage} over an injected {@link LiveMessagePort}. Uses the ambient `setTimeout`/`clearTimeout`/`Date.now` (mockable by fake timers in tests); it never sleeps on a 429.
createLiveMessage(port: LiveMessagePort, options: LiveMessageOptions): LiveMessage
isMessageNotModified
functionThe single, tested predicate for Telegram's "message is not modified" reply. There is no dedicated error code, so this matches the `description` wording (isolated here so a future Bot API rewording is a one-line fix).
isMessageNotModified(result: DeliveryResult<unknown>): boolean
parseWireResponse
functionTHE wire boundary: read a `Response`'s JSON, `safeParse` the Bot API envelope, then `safeParse` the success `result` against `dataSchema`. A `res.json()` rejection becomes `networkError`; an unrecognized 200 body becomes `serverError`; an `ok: false` body maps to its typed error variant. Never throws, never returns unparsed data.
<T>(res: Response, dataSchema: WireSchema<T>): Promise<DeliveryResult<T>>
Types
FetchLike
typeThe `fetch` implementation a client calls — global `fetch` by default.
type FetchLike = { (input: RequestInfo | URL, init?: RequestInit): Promise<Response>; (input: string | URL | Request, init?: RequestInit): Promise<Response>; }MediaGroupItems
typeA 2-to-10-item album, enforced at COMPILE TIME by an explicit tuple-length union: 0/1 items and 11+ items fail to type-check (spec `bot-api-transport`, "Album size out of range is a compile-time error"). A runtime guard in `sendMediaGroup` backstops values that arrive via a cast.
type MediaGroupItems = | readonly [MediaGroupItem, MediaGroupItem]
| readonly [MediaGroupItem, MediaGroupItem, MediaGroupItem]
| readonly [MediaGroupItem, MediaGroupItem, MediaGroupItem, MediaGroupItem]
| readonly [MediaGroupItem, MediaGroupItem, MediaGroupItem, MediaGroupItem, MediaGroupItem]
| readonly [
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
]
| readonly [
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
]
| readonly [
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
]
| readonly [
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
]
| readonly [
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
MediaGroupItem,
]MediaSource
typeHow a media item's file is referenced (no raw multipart upload here).
type MediaSource = | { readonly kind: "fileId"; readonly fileId: string }
| { readonly kind: "url"; readonly url: string }WebAppInlineResult
typeThe inline result passed to `answerWebAppQuery`.
type WebAppInlineResult = WebAppInlineResultArticle
DeliveryResult
typeOutcome of a single Bot API call. `ok` carries the method's parsed result; every other variant is a typed, non-throwing failure.
type DeliveryResult = DeliveryResult<T>
WireEntity
typeA Bot API `MessageEntity` object as it appears on the wire.
type WireEntity = {
readonly type: string;
readonly offset: number;
readonly length: number;
readonly url?: string;
readonly language?: string;
readonly user?: { readonly id: number };
}InlineMessageId
typeThe opaque id of an inline message (from an inline query / web-app result).
type InlineMessageId = Brand<string, "InlineMessageId">
RetryAfter
typeSeconds a caller must wait before retrying, from a 429 `retry_after`.
type RetryAfter = Brand<number, "RetryAfter">
EditTarget
typeWhich message an `editMessageText` targets.
type EditTarget = | { readonly kind: "chatMessage"; readonly chatId: ChatId; readonly messageId: MessageId }
| { readonly kind: "inlineMessage"; readonly inlineMessageId: InlineMessageId }KnownOrUnknown
typePresence of a value, modeled as a DU rather than `T | undefined`.
type KnownOrUnknown = KnownOrUnknown<T>
EditMessageResult
typeResult of an `editMessageText` call. A chat-message edit returns the updated `Message`; an inline-message edit returns the wire literal `true` (there is no message object) — modeled as an explicit DU, never `Message | undefined`.
type EditMessageResult = | { readonly kind: "edited"; readonly message: TelegramMessage }
| { readonly kind: "inlineEdited" }Interfaces
AnswerCallbackQueryArgs
interfaceArguments for `answerCallbackQuery`.
interface AnswerCallbackQueryArgs
callbackQueryId
propertycallbackQueryId: string
text
propertytext: string
showAlert
propertyshowAlert: boolean
AnswerWebAppQueryArgs
interfaceArguments for `answerWebAppQuery`.
interface AnswerWebAppQueryArgs
webAppQueryId
propertywebAppQueryId: string
result
propertyresult: WebAppInlineResultArticle
BotClient
interfaceThe raw Bot API client surface.
interface BotClient
sendMessage
methodsendMessage(args: SendMessageArgs): Promise<DeliveryResult<TelegramMessage>>
sendPhoto
methodsendPhoto(args: SendPhotoArgs): Promise<DeliveryResult<TelegramMessage>>
editMessageText
methodeditMessageText(args: EditMessageTextArgs): Promise<DeliveryResult<EditMessageResult>>
sendMediaGroup
methodsendMediaGroup(args: SendMediaGroupArgs): Promise<DeliveryResult<readonly TelegramMessage[]>>
answerCallbackQuery
methodanswerCallbackQuery(args: AnswerCallbackQueryArgs): Promise<DeliveryResult<true>>
answerWebAppQuery
methodanswerWebAppQuery(args: AnswerWebAppQueryArgs): Promise<DeliveryResult<SentWebAppMessage>>
liveMessage
methodA create-once/edit-many live-progress message in `chatId`.
liveMessage(args: LiveMessageArgs): LiveMessage
BotClientConfig
interfaceConfiguration for {@link createBotClient}.
interface BotClientConfig
token
propertyThe bot token (the `bot<token>` path segment is added internally).
token: string
fetch
propertyOverride the `fetch` used (tests inject a fake); defaults to `globalThis.fetch`.
fetch: { (input: RequestInfo | URL, init?: RequestInit): Promise<Response>; (input: string | URL | Request, init?: RequestInit): Promise<Response>; }baseUrl
propertyOverride the API origin; defaults to `https://api.telegram.org`.
baseUrl: string
EditMessageTextArgs
interfaceArguments for `editMessageText` (chat-message or inline-message target).
interface EditMessageTextArgs
target
propertytarget: EditTarget
message
propertymessage: MessageText
replyMarkup
propertyreplyMarkup: InlineKeyboardMarkup
LiveMessageArgs
interfaceArguments for {@link BotClient.liveMessage}.
interface LiveMessageArgs
chatId
propertychatId: ChatId
minEditIntervalMs
propertyminEditIntervalMs: number
MediaGroupItem
interfaceA single album item. Its caption presence is a DU, never `undefined`.
interface MediaGroupItem
type
propertytype: "photo" | "video" | "document" | "audio"
source
propertysource: MediaSource
caption
propertycaption: { readonly kind: "known"; readonly value: CaptionText; } | { readonly kind: "unknown"; }SendMediaGroupArgs
interfaceArguments for `sendMediaGroup`.
interface SendMediaGroupArgs
chatId
propertychatId: ChatId
items
propertyitems: MediaGroupItems
SendMessageArgs
interfaceArguments for `sendMessage`.
interface SendMessageArgs
chatId
propertychatId: ChatId
message
propertymessage: MessageText
replyMarkup
propertyreplyMarkup: InlineKeyboardMarkup
SendPhotoArgs
interfaceArguments for `sendPhoto` — a single photo (by `file_id` or public URL) with an optional {@link CaptionText}. Telegram fetches a `url` photo itself, so it must be a publicly reachable absolute URL (not a relative path).
interface SendPhotoArgs
chatId
propertychatId: ChatId
photo
propertyphoto: MediaSource
caption
propertycaption: CaptionText
replyMarkup
propertyreplyMarkup: InlineKeyboardMarkup
WebAppInlineResultArticle
interfaceThe `answerWebAppQuery` inline-result subset this change ships (design Open Question, resolved): only an `article` result whose body is a rendered `MessageText` — the shape the mini-app "send to a chat" composer flow needs. Photo/video/other `InlineQueryResult` variants are added when `miniapp` lands as new DU members (non-breaking).
interface WebAppInlineResultArticle
kind
propertykind: "article"
id
propertyid: string
title
propertytitle: string
message
propertymessage: MessageText
LiveMessage
interfaceA live-progress message handle.
interface LiveMessage
update
methodRecord the latest text and schedule a debounced flush (synchronous).
update(text: string): void
flush
methodForce an immediate write of the pending text now, bypassing the debounce.
flush(): Promise<DeliveryResult<TelegramMessage>>
finish
methodWrite `finalText` once immediately and close the instance.
finish(finalText: string): Promise<DeliveryResult<TelegramMessage>>
LiveMessageOptions
interfaceOptions for {@link createLiveMessage}.
interface LiveMessageOptions
minEditIntervalMs
propertyMinimum spacing between issued edits, in milliseconds.
minEditIntervalMs: number
LiveMessagePort
interfaceThe transport seam `LiveMessage` drives: a `send` that establishes the target message and an `edit` that updates it, both returning a {@link DeliveryResult}. `transport-fetch` and `transport-grammy` each supply their own implementation.
interface LiveMessagePort
send
methodsend(text: string): Promise<DeliveryResult<TelegramMessage>>
edit
methodedit(target: EditTarget, text: string): Promise<DeliveryResult<TelegramMessage>>
SentWebAppMessage
interfaceThe confirmation returned by `answerWebAppQuery`: a `SentWebAppMessage` whose `inline_message_id` is present only when the message can later be edited.
interface SentWebAppMessage
inlineMessageId
propertyinlineMessageId: { readonly kind: "known"; readonly value: string; } | { readonly kind: "unknown"; }TelegramMessage
interfaceA Telegram `Message`, projected to the branded ids the transport exposes.
interface TelegramMessage
messageId
propertymessageId: MessageId
chatId
propertychatId: ChatId
date
propertydate: number
Constants
EditMessageResultSchema
const{@link EditMessageResult} response schema.
const EditMessageResultSchema: WireSchema<EditMessageResult>
SentWebAppMessageSchema
const{@link SentWebAppMessage} response schema.
const SentWebAppMessageSchema: WireSchema<SentWebAppMessage>
TelegramMessageArraySchema
constAn array of {@link TelegramMessage}s, as `sendMediaGroup` returns.
const TelegramMessageArraySchema: WireSchema<readonly TelegramMessage[]>
TelegramMessageSchema
const{@link TelegramMessage} response schema.
const TelegramMessageSchema: WireSchema<TelegramMessage>
TrueResultSchema
constThe `answerCallbackQuery` result — the Bot API returns the literal `true`.
const TrueResultSchema: WireSchema<true>