Files
skills/plugins/document-navigator/docs/communication/messaging/telegram-client
admin 9bf56a806b Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into
plugins/document-navigator/docs/ so the plugin is self-contained and
portable. docs/superpowers/ (specs and plans) stays at the repo root.

Moved via cp+rm rather than git mv because directory rename() fails with
EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the
identical-content files at commit time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 01:10:00 +01:00
..

@suaveplan/telegram-client - Telegram Bot API client — send/edit/delete messages, media, inline + custom keyboards, typed errors, injectable fetch + clock, OTel instrumented

Telegram Bot API client: send/edit/delete messages, six media variants, inline + custom keyboards, typed errors, injectable fetch + clock, and OpenTelemetry counters/histograms on every code path. Runtime-agnostic (works in Bun, Node, Deno, browsers).

Documentation tree

  • telegram-bot-client — TelegramBotClient is the public, runtime-agnostic Telegram Bot API client. It wraps the handful of Bot API endpoints…
    • telegram-bot-client — TelegramBotClient is the public, runtime-agnostic Telegram Bot API client. It wraps the handful of Bot API endpoints…
  • errors — Defines the namespaced, frozen error-code registry and the typed TelegramClientError class used by every runtime fail…
    • telegram-client-error — Defines the namespaced, frozen error-code registry and the typed TelegramClientError class used by every runtime fail…
  • types — Defines the Zod schema that validates TelegramBotConfig at the public construction boundary of TelegramBotClient. T…
    • telegram-bot-config — Defines the Zod schema that validates TelegramBotConfig at the public construction boundary of TelegramBotClient. T…
  • build-bodies — Pure, side-effect-free helpers that translate the camelCase public message / reply-markup shape used by callers into th…
  • classify-error — Pure helpers that turn an outgoing-protocol failure (HTTP status + Telegram description + parsed body) into a stable…

Installation

bun add @suaveplan/telegram-client

Quick Start

import { createTelegramBotClient } from "@suaveplan/telegram-client";

const bot = createTelegramBotClient({ token: process.env.TELEGRAM_TOKEN! });

const sent = await bot.sendMessage({
  chatId: 12345,
  text: "Hello",
  parseMode: "HTML",
});

console.log(sent.messageId);

Modules

Module Path Description
Client src/core/telegram-bot-client/telegram-bot-client.md TelegramBotClient class, factory, OTel metrics
Body Builders src/utils/build-bodies.md Pure camelCase → snake_case translators
Error Classifier src/utils/classify-error.md Pure status + retry-after classifier
Errors src/errors/telegram-client-error.md Code registry + typed error class
Config Schema src/types/telegram-bot-config.md Zod validation at the boundary
Types src/types/telegram-client.types.md Public type surface

Subpath Exports

import { createTelegramBotClient } from "@suaveplan/telegram-client";
import {
  TELEGRAM_CLIENT_CODES,
  TelegramClientError,
} from "@suaveplan/telegram-client/errors";
import type { TelegramMessage } from "@suaveplan/telegram-client/types";

Error Codes

Code When
TELEGRAM_CLIENT.CONFIG_MISSING Config rejected by Zod schema (missing token, invalid URL, etc.)
TELEGRAM_CLIENT.TIMEOUT Request aborted before completion
TELEGRAM_CLIENT.AUTH_ERROR Telegram returned HTTP 401
TELEGRAM_CLIENT.RATE_LIMITED Telegram returned HTTP 429 (context.retryAfterMs set if parseable)
TELEGRAM_CLIENT.CHAT_NOT_FOUND HTTP 404, or HTTP 400 with chat not found / channel not found
TELEGRAM_CLIENT.BOT_BLOCKED HTTP 403 with bot was blocked / user is deactivated
TELEGRAM_CLIENT.FORBIDDEN Other HTTP 403, or HTTP 400 with not enough rights / forbidden
TELEGRAM_CLIENT.API_ERROR Catch-all for unclassified Telegram failures

OTel Instruments

  • Counter telegram_client.request.total — keyed by { method, outcome }
  • Histogram telegram_client.request.duration_ms — keyed by { method, outcome }
  • outcome ∈ { "success", "error", "timeout" }

Call resetTelegramClientMetrics() from tests after replacing the global MeterProvider so each test sees a fresh meter.

Verification

  • Tests use injected fetch / clock — no mocks, no network.
  • 100% istanbul coverage on touched modules.