Files
2026-05-27 23:29:53 +01:00

5.2 KiB

OpenSpec Change: enterprise-telegram-client

  • Change ID: enterprise-telegram-client
  • Package: @suaveplan/telegram-client
  • Category: universal
  • Target path: universal/social/telegram-client
  • Status: IN PROGRESS
  • Date: 2026-04-24
  • Reference spec: /mnt/s/web/suaveplan/enterprise/telegram-client.md

Summary

Deliver @suaveplan/telegram-client on the genesis branch from scratch at enterprise quality. The package provides a generic Telegram Bot API client: sendMessage, sendPhoto, sendDocument, sendAudio, sendVideo, editMessageText, deleteMessage, answerCallbackQuery, answerInlineQuery, setWebhook/deleteWebhook, getUpdates long-poll loop, inline keyboard builder, reply keyboard builder, and a TelegramBot facade. Injectable fetch; no node-telegram-bot-api dependency. Genesis adds structured errors, Zod schemas, OTel instrumentation, retry with circuit breaker, and AbortSignal cancellation.


Current-state audit (genesis)

The package does not exist on genesis yet — this is a fresh build.


Available workspace deps on genesis

Package Role
@suaveplan/error (workspace:^) TelegramError; TELEGRAM.* error codes
@suaveplan/types (workspace:^) LoggerLike, Clock
@suaveplan/retry (workspace:^) Retry + circuit breaker for API calls
zod (catalog:forms) Schema validation
@opentelemetry/api (catalog:observability) Spans + counters

Dev deps: vitest, @vitest/coverage-istanbul, fast-check (all catalog:testing).


Public API surface

TelegramBot

class TelegramBot {
  constructor(options: TelegramBotOptions)

  // Messaging
  sendMessage(chatId: ChatId, text: string, options?: SendMessageOptions): Promise<TelegramMessage>
  sendPhoto(chatId: ChatId, photo: string | Uint8Array, options?: SendMediaOptions): Promise<TelegramMessage>
  sendDocument(chatId: ChatId, document: string | Uint8Array, options?: SendMediaOptions): Promise<TelegramMessage>
  editMessageText(chatId: ChatId, messageId: number, text: string, options?: EditOptions): Promise<TelegramMessage>
  deleteMessage(chatId: ChatId, messageId: number): Promise<void>
  forwardMessage(toChatId: ChatId, fromChatId: ChatId, messageId: number): Promise<TelegramMessage>

  // Callbacks and inline
  answerCallbackQuery(callbackQueryId: string, options?: AnswerCallbackOptions): Promise<void>
  answerInlineQuery(inlineQueryId: string, results: InlineQueryResult[]): Promise<void>

  // Webhooks and polling
  setWebhook(url: string, options?: WebhookOptions): Promise<void>
  deleteWebhook(): Promise<void>
  getUpdates(options?: GetUpdatesOptions): AsyncGenerator<TelegramUpdate>

  // Bot info
  getMe(): Promise<TelegramUser>
}

type ChatId = number | string

interface TelegramBotOptions {
  token: string
  retryOptions?: RetryOptions
  fetch?: typeof globalThis.fetch
  clock?: Clock
  logger?: LoggerLike
}

Keyboard builders

function inlineKeyboard(rows: InlineKeyboardButton[][]): InlineKeyboardMarkup
function replyKeyboard(rows: KeyboardButton[][], options?: ReplyKeyboardOptions): ReplyKeyboardMarkup
function removeKeyboard(): ReplyKeyboardRemove

Error codes

type TelegramErrorCode =
  | 'TELEGRAM_AUTH_FAILED'
  | 'TELEGRAM_API_ERROR'
  | 'TELEGRAM_RATE_LIMITED'
  | 'TELEGRAM_CHAT_NOT_FOUND'
  | 'TELEGRAM_MESSAGE_NOT_FOUND'
  | 'TELEGRAM_WEBHOOK_FAILED'
  | 'TELEGRAM_ABORTED'

Genesis additions

  1. TelegramError extends SuaveplanError with seven stable codes.
  2. Zod schemas for TelegramMessage, TelegramUpdate, TelegramUser, SendMessageOptions, InlineKeyboardMarkup, ReplyKeyboardMarkup, InlineQueryResult.
  3. Long-poll loop — getUpdates returns an AsyncGenerator<TelegramUpdate> that manages offset tracking and exits cleanly on AbortSignal.
  4. Rate-limit handling — Telegram returns 429 with retry_after; the client waits the prescribed delay before retrying.
  5. OTel instrumentation — span telegram.api_call with attribute telegram.method; counter telegram.api_total; histogram telegram.api_duration_ms.
  6. Property-based tests — keyboard builder produces valid nested JSON for arbitrary row/button configurations.

File layout

universal/social/telegram-client/
  package.json
  tsconfig.json
  vitest.config.ts
  src/
    index.ts
    error-codes.ts
    constants/
      index.ts
    types/
      common.ts
      common.md
    core/
      telegram-bot/
        telegram-bot.ts
        telegram-bot.md
        telegram-bot.types.ts
        telegram-bot.test.ts
        index.ts
      api-caller/
        api-caller.ts
        api-caller.md
        api-caller.test.ts
        index.ts
      update-poller/
        update-poller.ts
        update-poller.md
        update-poller.test.ts
        index.ts
    keyboards/
      keyboard-builder/
        keyboard-builder.ts
        keyboard-builder.md
        keyboard-builder.test.ts
        index.ts
    __benchmarks__/
      telegram-client.bench.ts
  tests/
    integration.test.ts
    property.test.ts

Impact

Downstream consumers: @suaveplan/message-bridge, @suaveplan/notification-channel.

Workspace dep prerequisites: @suaveplan/error, @suaveplan/types, @suaveplan/retry.