Skip to content

Telegram Implementation

Telegram is one of the most complete channel implementations in OpenClaw. It is built on the grammy SDK and supports Markdown messages, media, buttons, and chunked sending.

Source Location

src/telegram/
├── send.ts              # Core message sending
├── bot.ts               # Bot initialization and connection
├── messages.ts          # Message processing and parsing
├── media.ts             # Media handling
├── commands.ts          # Bot command registration
├── reactions.ts         # Message reactions
├── threads.ts           # Threads/topics
├── keyboards.ts         # Inline keyboards
├── polling.ts           # Long polling
├── webhook.ts           # Webhook mode
├── formatting.ts        # Text formatting
├── rate-limit.ts        # Rate limiting
├── retry.ts             # Retry logic
└── *.test.ts            # Test files

Sending Messages

Source: src/telegram/send.ts

The core of Telegram sending revolves around TelegramSendOpts and the retry mechanism:

typescript
// src/telegram/send.ts (simplified)
interface TelegramSendOpts {
  token: string;              // Bot token
  accountId: string;          // Chat ID
  mediaUrl?: string;          // Optional media attachment
  maxBytes?: number;          // Max media size
  textMode: "markdown" | "html";  // Message format
  threadId?: number;          // Reply to thread/topic
  buttons?: InlineButton[];   // Inline keyboard buttons
}

interface TelegramSendResult {
  messageId: number;
  chatId: number;
}

Retry Mechanism

typescript
// src/telegram/retry.ts (simplified)
function createTelegramRetryRunner() {
  // Retry with exponential backoff
  // Handle rate-limit (429) responses
  // Respect Retry-After headers
}

Telegram's API has strict rate limits. createTelegramRetryRunner() wraps exponential backoff and 429 response handling.

Caption Splitting

When sending messages with media, Telegram imposes a caption length limit (1024 characters). If the text exceeds that limit, it is split as follows:

Text Chunking

Telegram's single message limit is 4096 characters (OpenClaw uses 4000 as a safe threshold). Long messages are split using a Markdown-aware chunking strategy:

typescript
// Text chunking for Telegram
// textChunkLimit: 4000
// chunkerMode: "markdown"
// Preserves code blocks, links, formatting across chunks

The chunker preserves Markdown syntax integrity:

  • Does not break in the middle of code blocks
  • Does not break in the middle of links
  • Maintains list and heading structure

grammy Bot

Source: src/telegram/bot.ts

Bot initialization and message listening:

typescript
// src/telegram/bot.ts (simplified)
// Uses grammy Bot API library
// Supports both long polling and webhook modes
// Registers command handlers
// Sets up message listeners

Two operation modes are supported:

ModeDescriptionUse Case
Long PollingActively pulls updatesDevelopment/local
WebhookReceives push notificationsProduction

Message Formatting

Source: src/telegram/formatting.ts

Telegram supports MarkdownV2 and HTML formats:

typescript
// Telegram format conversion
// Markdown → MarkdownV2 (with proper escaping)
// Markdown → HTML (alternative)
// Special character escaping rules

MarkdownV2 has strict escaping rules. All special characters (_, *, [, ], (, ), ~, `, >, #, +, -, =, |, {, }, ., !) outside of formatting markers must be escaped with a backslash.

Summary

  • Built on the grammy SDK, supporting Long Polling and Webhook modes
  • Text chunk limit of 4000 characters with Markdown-aware splitting
  • Retry mechanism handles 429 rate limits and network errors
  • Caption splitting strategy handles long text attached to media
  • MarkdownV2 formatting requires strict character escaping

Next: Discord Implementation

OpenClaw Source Code Tutorial