Aleph
Interfaces

Telegram

Telegram Bot interface for Aleph -- setup, configuration, and media handling

The Telegram interface connects Aleph to the Telegram Bot API using the teloxide framework. It supports direct messages, group chats, file attachments, inline keyboards, and Markdown formatting.

Capabilities

FeatureStatus
Text messagesSupported
Markdown (MarkdownV2)Supported
PhotosSupported (send and receive)
DocumentsSupported (send and receive)
AudioSupported (send and receive)
VideoSupported (send and receive)
Voice messagesSupported (receive)
Inline keyboardsSupported
Reply threadingSupported
Message editingSupported (with chat context)
Message deletionSupported (with chat context)
Typing indicatorSupported
Max message length4,096 characters
Max attachment size50 MB
ReactionsLimited (Telegram Premium only)

Prerequisites

Create a Bot with BotFather

  1. Open Telegram and search for @BotFather
  2. Send /newbot and follow the prompts to name your bot
  3. BotFather will reply with your bot token (format: 123456789:ABCdefGHIjklMNOpqrsTUVwxyz)
  4. Save this token securely -- it is your bot's authentication credential

Configure Bot Settings (Optional)

While still in BotFather, you can customize your bot:

  • /setdescription -- Set the bot's description shown in the profile
  • /setabouttext -- Set the "About" text
  • /setuserpic -- Upload a profile picture
  • /setcommands -- Define the command menu (e.g., /start, /help)
  • /setprivacy -- Disable "Privacy Mode" if you want the bot to see all group messages (not just commands and mentions)

Enable the Telegram Feature

Build Aleph with the telegram feature flag:

cargo build --release --features telegram
# or for all interfaces:
cargo build --release --features all-interfaces

Configuration

Minimal Configuration

[[channels]]
id = "telegram"
channel_type = "telegram"
enabled = true

[channels.config]
bot_token = "123456789:ABCdefGHIjklMNOpqrsTUVwxyz"

Full Configuration Reference

[[channels]]
id = "telegram"
channel_type = "telegram"
enabled = true

[channels.config]
# Bot token from @BotFather (required)
# Supports ${ENV_VAR} expansion
bot_token = "${TELEGRAM_BOT_TOKEN}"

# Bot username without @ (auto-detected on connect)
bot_username = "my_aleph_bot"

# User allowlist -- empty means allow all users
# Use Telegram user IDs (not usernames)
allowed_users = [123456789, 987654321]

# Group/chat allowlist -- empty means allow all groups
allowed_groups = [-1001234567890]

# Allow direct messages (default: true)
dm_allowed = true

# Allow group messages (default: true)
groups_allowed = true

# Polling interval in seconds for long-polling mode (default: 1)
polling_interval_secs = 1

# Send typing indicator while processing (default: true)
send_typing = true

# Maximum retries for failed messages (default: 3)
max_retries = 3

# Webhook configuration (optional -- defaults to long-polling)
# [channels.config.webhook]
# url = "https://your-domain.com/telegram/webhook"
# port = 8443
# path = "/telegram/webhook"
# certificate = "/path/to/cert.pem"    # For self-signed certificates
# secret_token = "your-webhook-secret"  # Verification token

Never commit bot tokens to version control. Use environment variables (${TELEGRAM_BOT_TOKEN}) or a secrets manager.

Environment Variable Mode

The simplest setup uses a single environment variable:

export TELEGRAM_BOT_TOKEN="123456789:ABCdefGHIjklMNOpqrsTUVwxyz"

Aleph will pick it up automatically via TelegramConfig::from_env().

Long-Polling vs Webhook

Aleph supports two modes for receiving updates from Telegram:

Long-Polling (Default)

The bot periodically asks Telegram's servers for new updates. This is the default and works out of the box with no additional infrastructure.

Pros:

  • No public URL or SSL certificate required
  • Works behind NATs and firewalls
  • Simple setup

Cons:

  • Slightly higher latency (configurable via polling_interval_secs)
  • Keeps a persistent connection to Telegram servers

Webhook Mode

Telegram pushes updates to your server via HTTPS POST requests. Enable by adding a webhook section:

[channels.config.webhook]
url = "https://aleph.example.com/telegram/webhook"
port = 8443
secret_token = "a-random-secret-string"

Pros:

  • Lower latency (instant delivery)
  • More efficient for high-traffic bots

Cons:

  • Requires a public HTTPS endpoint
  • Needs a valid SSL certificate (or self-signed with certificate field)

User and Group Allowlists

Finding User IDs

Telegram user IDs are numeric. To find a user's ID:

  1. Have the user send a message to @userinfobot
  2. Or use the getUpdates API to see raw message data

Allowlist Behavior

# Empty list = allow everyone
allowed_users = []

# Specific users only
allowed_users = [123456789, 987654321]

When allowed_users is non-empty, messages from unlisted users are silently dropped. The same logic applies to allowed_groups for group chats.

Group Chat Behavior

When Aleph receives a message in a group:

  1. Check if the group ID is in allowed_groups (or if the list is empty)
  2. Check if the sender is in allowed_users (or if the list is empty)
  3. If both pass, route the message to the agent

By default, Telegram bots in "Privacy Mode" only see messages that mention the bot or start with /. Disable privacy mode via BotFather (/setprivacy) if you want Aleph to see all messages in a group.

Media Handling

Receiving Media

Aleph extracts attachments from all supported Telegram media types:

Media TypeMIME TypeNotes
Photoimage/jpegLargest available resolution is selected
DocumentFrom metadataGeneric files up to 50 MB
AudioFrom metadata or audio/mpegMusic files with metadata
VideoFrom metadata or video/mp4Video files with thumbnail
VoiceFrom metadata or audio/oggOpus-encoded voice messages

Captions on media messages are extracted as the message text. If a message has both a caption and media, the caption becomes the text field.

Sending Media

Outbound attachments are dispatched based on MIME type:

  • image/* -- Sent as a photo (sendPhoto)
  • audio/* -- Sent as audio (sendAudio)
  • video/* -- Sent as video (sendVideo)
  • Everything else -- Sent as a document (sendDocument)

Attachments can be provided as:

  • In-memory bytes (data field)
  • Local file path (path field)
  • Remote URL (url field)

Inline Keyboards

The Telegram interface supports inline keyboard buttons for interactive prompts. This is primarily used by the tool approval system to let users approve or deny tool executions directly from the chat:

Aleph wants to execute: shell_exec("ls -la")

[Allow Once] [Allow Always] [Deny]

When a user clicks a button, a callback query is routed back through the Gateway and processed by the approval bridge. The loading indicator on the button is automatically dismissed via answerCallbackQuery.

Keyboards can also be used for custom multi-choice responses built by the agent itself.

Session Routing

Each Telegram conversation gets a unique session key:

ContextSession Key
DM with user 12345agent:main:dm:12345 or agent:main:telegram:dm:12345
Group chat -100123agent:main:telegram:group:-100123

The exact format depends on your dm_scope setting (see Interfaces Overview).

Message Formatting

Aleph sends messages using Telegram's MarkdownV2 parse mode. The following formatting is supported:

SyntaxResult
*bold*bold
_italic_italic
`code`code
```language\ncode```Code block with syntax highlighting
[text](url)Hyperlink

MarkdownV2 requires escaping special characters (_, *, [, ], (, ), ~, `, >, #, +, -, =, |, {, }, ., !). Aleph handles this escaping automatically when formatting outbound messages.

Error Handling

The Telegram interface handles common failure scenarios:

ErrorBehavior
Invalid bot tokenDetected at startup via getMe API call; channel enters Error state
Rate limitingTelegram rate limits are respected; retries up to max_retries times
Network failureLong-polling reconnects automatically; webhook mode relies on Telegram's retry
User not in allowlistMessage is silently dropped with a debug-level log
Empty messageSkipped (no text and no attachments)
Service messagesIgnored (join/leave notifications, pinned messages, etc.)

Validation

The bot token is validated at two stages:

  1. Format check (config load) -- Token must be non-empty and contain a colon (format: <bot_id>:<hash>)
  2. API check (channel start) -- getMe is called to verify the token and retrieve the bot's username and ID

If either check fails, the channel reports a ConfigError or AuthFailed error and does not start polling.

Troubleshooting

ProblemSolution
Bot does not respondCheck that the telegram feature flag is enabled in your build
Bot ignores group messagesDisable Privacy Mode via BotFather (/setprivacy) or ensure the bot is mentioned
"User not in allowlist" in logsAdd the user's numeric Telegram ID to allowed_users
"Failed to verify bot token"Verify your token with curl https://api.telegram.org/bot<TOKEN>/getMe
Messages are delayedDecrease polling_interval_secs or switch to webhook mode
Formatting looks brokenAleph uses MarkdownV2; check that special characters are not double-escaped

On this page