> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hitheo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Telegram 机器人设置

> 使用 @hitheo/telegram 适配器将 Theo 接入 Telegram。

`@hitheo/telegram` 包可将 Theo 作为机器人接入 Telegram。用户向你的机器人发送消息，Theo 通过完整的编排流程处理响应，适配器再通过 Bot API 回复。

<Note>
  Theo 从不托管你的机器人。你需要通过 [@BotFather](https://t.me/BotFather) 创建机器人并持有令牌，并将本适配器部署在**你自己的**基础设施上；Theo 只处理适配器转发过来的补全流量。这样一来，每一条消息、Webhook URL 和凭证都始终掌握在你手中。
</Note>

## 前提条件

1. 从 [@BotFather](https://t.me/BotFather) 获取的 Telegram 机器人令牌
2. 一个 Theo API 密钥（`theo_sk_...`）

## 安装

<CodeGroup>
  ```bash npm theme={null}
  npm install @hitheo/telegram
  ```

  ```bash yarn theme={null}
  yarn add @hitheo/telegram
  ```

  ```bash pnpm theme={null}
  pnpm add @hitheo/telegram
  ```
</CodeGroup>

## 快速设置

`createTelegramHandler` 返回一个异步函数，用于处理单条 Telegram Webhook 更新。你可以将它接入任意 HTTP 框架——Express、Next.js 路由处理器、Cloudflare Workers、AWS Lambda 等。

```typescript theme={null}
import express from "express";
import { createTelegramHandler } from "@hitheo/telegram";

const app = express();
app.use(express.json());

const handle = createTelegramHandler({
  theoApiKey: process.env.THEO_API_KEY!,
  telegramToken: process.env.TELEGRAM_BOT_TOKEN!,
  secretToken: process.env.TELEGRAM_WEBHOOK_SECRET, // 可选，但建议设置
  mode: "auto",
  skills: ["customer-support"],
  persona: "You are a helpful assistant for Acme Corp.",
});

app.post("/webhook", async (req, res) => {
  try {
    await handle(req.body, {
      secretToken: req.header("X-Telegram-Bot-Api-Secret-Token"),
    });
    res.sendStatus(200);
  } catch (err) {
    // TelegramSignatureError indicates an unauthorized POST.
    res.sendStatus(401);
  }
});

app.listen(3000, () => console.log("Telegram bot listening on :3000"));
```

## 工作原理

1. 用户向你的 Telegram 机器人发送一条消息
2. Telegram 将该更新以 POST 方式推送到你的 Webhook URL
3. 适配器校验 `X-Telegram-Bot-Api-Secret-Token` 请求头（当配置了 `secretToken` 时）
4. 适配器将文本（以及任何图片/文档附件）转发至 `POST /api/v1/completions`，并复用与该会话关联的 `conversation_id`
5. Theo 通过完整流程（分类、技能、代理循环）处理该请求
6. 响应被发回该 Telegram 聊天，如有需要会拆分为多条消息发送

## 处理器配置

| 选项 | 类型 | 是否必填 | 说明 |
| - | - | - | - |
| `theoApiKey` | `string` | ✅ | 你的 `theo_sk_...` API 密钥 |
| `telegramToken` | `string` | ✅ | 来自 BotFather 的机器人令牌 |
| `secretToken` | `string` | | 传给 `setWebhook` 的共享密钥。设置后，若更新缺少该请求头或其值不匹配，将抛出 `TelegramSignatureError`。 |
| `theoBaseUrl` | `string` | | API 基础 URL（默认：`https://www.hitheo.ai`） |
| `mode` | `ChatMode` | | 默认模式 —— `auto`、`fast`、`think`、`code` 等 |
| `persona` | `PersonaInput` | | 自定义角色，或 `"theo"` / `"none"` |
| `skills` | `string[]` | | 每条消息都会激活的技能 slug 列表 |
| `conversationStore` | `ConversationStore` | | 将聊天 ID 映射到 Theo 会话 ID。默认使用进程内的 `Map`；跨实例部署时请替换为 Redis/数据库实现。 |
| `enableVoice` | `boolean` | | 使用 Theo 语音转文本转录语音/音频，并将转录文本附加到提示词中。默认关闭（语音转文本会产生额外费用）。 |
| `maxChunkChars` | `number` | | 每条出站消息的最大字符数。默认 4000。 |

## 内置命令

适配器会自行处理以下三个命令（不会调用 Theo）：

| 命令 | 行为 |
| - | - |
| `/start` | 发送一条介绍消息 |
| `/help` | 列出可用命令 |
| `/reset` | 清除该聊天已存储的 `conversation_id`，下一条消息将开启全新上下文 |

其他任何 `/foo` 命令都会返回一条简短的“未知命令”回复。

## 附件

消息中附带的照片（以及图片类文档）会在适配器内部下载，并以 **base64 图片数据**的形式转发给 Theo——适配器绝不会把 Telegram 的文件 URL 传给 Theo。这样可以确保机器人令牌始终留在你的部署环境内。

<Warning>
  请始终使用最新版本的 `@hitheo/telegram`。如果你还在使用 `≤0.1.3` 版本，请升级到 `^0.1.4`，并在升级过程中通过 `@BotFather` 轮换机器人令牌。
</Warning>

语音和音频消息默认会被忽略，除非你设置了 `enableVoice: true`。启用后，适配器会下载语音片段，通过 Theo 语音转文本进行处理，并将转录文本以文字形式附加到提示词中。语音**不会**作为附件发送——Theo 的补全端点只接受图片附件。

## 设置 Webhook

向 Telegram 注册你的 Webhook URL，并附上 `secret_token`：

```bash theme={null}
curl -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/setWebhook" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-domain.com/webhook",
    "secret_token": "'"$TELEGRAM_WEBHOOK_SECRET"'"
  }'
```

## 跨实例保持会话持久化

默认的 `ConversationStore` 是一个进程内的 `Map`——这对单个长期运行的服务器没问题，但不适用于无服务器场景（每次调用都是全新进程）。请提供你自己的存储实现：

```typescript theme={null}
import Redis from "ioredis";

const redis = new Redis(process.env.REDIS_URL!);

const handle = createTelegramHandler({
  theoApiKey: process.env.THEO_API_KEY!,
  telegramToken: process.env.TELEGRAM_BOT_TOKEN!,
  conversationStore: {
    get: (chatId) => redis.get(`tg:conv:${chatId}`),
    set: async (chatId, id) => {
      await redis.set(`tg:conv:${chatId}`, id, "EX", 60 * 60 * 24 * 30);
    },
    clear: async (chatId) => {
      await redis.del(`tg:conv:${chatId}`);
    },
  },
});
```

## 部署

可以部署为任意 Node.js HTTP 服务器。生产环境建议：

* **Railway / Render / Fly.io** —— 对基于 Webhook 的机器人来说最简单
* **Vercel / Cloudflare Workers** —— 无服务器（每条消息对应一次调用）；请配合远程 `conversationStore` 使用
* **Docker + PM2** —— 自托管

<Tip>
  开发阶段请使用 `theo_sk_test_` 密钥，以避免产生计费。
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.