@effect-ak/tg-bot-client
v1.12.0
Published
Type-safe HTTP client for Telegram Bot API
Maintainers
Readme
@effect-ak/tg-bot-client
Type-safe HTTP client for the Telegram Bot API. One execute method covers every API method, files are encoded to FormData automatically, errors are typed. Native fetch, zero runtime dependencies — runs on Node.js 18+, Bun, Deno, Cloudflare Workers, browsers.
Types come from @effect-ak/tg-bot-api; the bot framework @effect-ak/tg-bot is built on this client.
Installation
npm install @effect-ak/tg-bot-clientThe Bot API types are re-exported under a subpath, so this is the only package you need:
import { makeTgBotClient } from "@effect-ak/tg-bot-client"
import type { Message, Update } from "@effect-ak/tg-bot-client/api"Quick Start
import { makeTgBotClient } from "@effect-ak/tg-bot-client"
const client = makeTgBotClient({ bot_token: "YOUR_BOT_TOKEN" })
// Method names are snake_case, exactly as in the official docs
const message = await client.execute("send_message", {
chat_id: 123456789,
text: "Hello!"
})API Surface
makeTgBotClient({ bot_token, base_url?, timeout? }): TgBotClient
interface TgBotClient {
execute(method, params, options?): Promise<Result> // throws TgBotClientError
executeSafe(method, params, options?): Promise<ClientResult> // never throws
getFile({ fileId }): Promise<TgFile> // download by file_id
getFileSafe({ fileId }): Promise<ClientResult<TgFile>>
}
type ClientResult<T> = { ok: true; data: T } | { ok: false; error: ClientErrorReason }
type ClientErrorReason =
| { _tag: "NotOkResponse"; errorCode?: number; details?: string } // Telegram said ok:false
| { _tag: "RequestTimeout"; timeoutMs: number }
| { _tag: "NotJsonResponse" | "UnexpectedResponse" | "ClientInternalError" | "UnableToGetFile"; ... }- Method and parameter names match https://core.telegram.org/bots/api in
snake_case(send_message,edit_message_text,answer_callback_query). Both are autocompleted; return types are inferred. - Files: pass
{ file_content: Uint8Array, file_name: string }wherever the API acceptsInputFile— the client switches to multipart automatically. Or pass afile_id/ URL string. - Message effects:
message_effect_idaccepts an emoji key ofMESSAGE_EFFECTS("🔥" | "👍" | "👎" | "❤️" | "🎉" | "💩") and is mapped to the real id. - Errors:
executethrowsTgBotClientError(error.reasonis the tagged union above);executeSafereturns the union — pick one style and stick to it. - Options:
{ timeout }per call;base_urlfor a self-hosted Bot API server.
Examples
// Safe variant
const result = await client.executeSafe("get_chat", { chat_id: 1 })
if (!result.ok) console.error(result.error._tag)
// Upload a file
await client.execute("send_document", {
chat_id,
document: { file_content: new TextEncoder().encode("hi"), file_name: "hi.txt" },
caption: "Generated on the fly"
})
// Download a file
const file = await client.getFile({ fileId })
file.content // ArrayBufferDocumentation
- Guide: tg-bot-sdk.website/client/usage
- Bot API reference (one page per method): https://tg-bot-sdk.website/api/
- For LLMs / coding agents: https://tg-bot-sdk.website/llms.txt
License
MIT
