---
title: Telegram
description: Reach your agent from Telegram bot webhooks, with inline-keyboard human-in-the-loop prompts and attachments.
type: integration
---

# Telegram



The Telegram channel puts your agent behind a Telegram bot. It takes Bot API webhooks, checks the `X-Telegram-Bot-Api-Secret-Token` header before trusting anything, and routes the messages it cares about (private chats plus group messages that address the bot) to a reply over `sendMessage`. See [Channels](./overview) for the contract this builds on.

## Add the channel

```ts title="agent/channels/telegram.ts"
import { telegramChannel } from "eve/channels/telegram";

export default telegramChannel({
  botUsername: "my_bot",
});
```

```bash
TELEGRAM_BOT_TOKEN=123456:...        # replies, typing, callbacks, proactive sends
TELEGRAM_WEBHOOK_SECRET_TOKEN=...    # must match the secret_token you register
```

You can pass the same values via `credentials: { botToken, webhookSecretToken }`. The channel mounts `POST /eve/v1/telegram`. Register the deployed URL yourself; Eve does not call `setWebhook`:

```bash
curl -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/setWebhook" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://your-app.example.com/eve/v1/telegram",
       "secret_token":"'"$TELEGRAM_WEBHOOK_SECRET_TOKEN"'",
       "allowed_updates":["message","callback_query"]}'
```

## How the channel handles messages

### Dispatch

In a private chat, text, captions, photos, and documents all go through. Groups are stricter. Only three things wake the bot: a command (`/ask`, `/ask@my_bot`), an `@my_bot` mention (when `botUsername` is set), or a reply to one of the bot's own messages. Everything else is ignored.

Forum topics carry `message_thread_id` in the continuation token, so each topic stays on its own thread.

To customize auth or filtering, override `onMessage`. Group privacy mode itself lives in BotFather, not here.

### Delivery

The default `message.completed` handler sends plain text via `sendMessage`. It passes no `parse_mode`, so any Markdown shows up literally. Replies longer than Telegram's 4096-char limit are split across messages. Custom handlers use `channel.telegram`.

### Human-in-the-loop (HITL)

Human-in-the-loop (HITL) turns option requests into inline-keyboard buttons and freeform requests into `ForceReply`. Telegram caps `callback_data` at 64 bytes, so Eve keeps compact callback ids in channel state instead. It acknowledges its own callbacks with `answerCallbackQuery`; anything it doesn't recognize goes to `onCallbackQuery`.

### Proactive sessions

Start a session without an inbound message through `receive(telegram, { message, target, auth })` from a schedule `run` handler, or `args.receive(telegram, ...)` from another channel. `target.chatId` is required. Add `messageThreadId` to land in a specific forum topic.

### Attachments

Inbound photos and documents are supported. Eve fetches them on demand via `getFile`, only when an upload policy allows the type:

```ts
export default telegramChannel({
  botUsername: "my_bot",
  uploadPolicy: { allowedMediaTypes: ["image/*", "application/pdf"], maxBytes: 10 * 1024 * 1024 },
});
```

## What to read next

* [Channels overview](./overview): the channel contract and every built-in channel
* [Auth & route protection](../guides/auth-and-route-protection): authenticating inbound traffic


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)