Telegram
Telegram (Bot API)
Section titled “Telegram (Bot API)”状态:生产就绪,支持机器人私信(DM)+ 群组(通过 grammY)。默认使用长轮询(Long-polling);可选 Webhook。
快速设置(初学者)
Section titled “快速设置(初学者)”- 使用 @BotFather 创建一个机器人并复制令牌(token)。
- 设置令牌:
- 环境变量:
TELEGRAM_BOT_TOKEN=... - 或配置:
channels.telegram.botToken: "..."。 - 如果两者都设置了,配置优先(环境变量回退仅适用于默认账户)。
- 环境变量:
- 启动网关。
- 私信访问默认为配对模式;在首次联系时批准配对代码。
最小配置:
{ channels: { telegram: { enabled: true, botToken: "123:abc", dmPolicy: "pairing" } }}- 一个由网关拥有的 Telegram Bot API 频道。
- 确定性路由:回复会返回到 Telegram;模型从不选择频道。
- 私信共享智能体的主会话;群组保持隔离 (
agent:<agentId>:telegram:group:<chatId>)。
设置(快速路径)
Section titled “设置(快速路径)”1) 创建机器人令牌 (BotFather)
Section titled “1) 创建机器人令牌 (BotFather)”- 打开 Telegram 并与 @BotFather 聊天。
- 运行
/newbot,然后按照提示操作(名称 + 以bot结尾的用户名)。 - 复制令牌并妥善保存。
可选的 BotFather 设置:
/setjoingroups— 允许/拒绝将机器人添加到群组。/setprivacy— 控制机器人是否可以看到所有群组消息。
2) 配置令牌(环境变量或配置)
Section titled “2) 配置令牌(环境变量或配置)”示例:
{ channels: { telegram: { enabled: true, botToken: "123:abc", dmPolicy: "pairing", groups: { "*": { requireMention: true } } } }}环境变量选项:TELEGRAM_BOT_TOKEN=...(适用于默认账户)。 如果同时设置了环境变量和配置,配置优先。
多账户支持:使用 channels.telegram.accounts,配置每个账户的令牌和可选的 name。参见 gateway/configuration 了解共享模式。
- 启动网关。当令牌解析后(配置优先,环境变量回退),Telegram 启动。
- 私信访问默认为配对。当首次联系机器人时批准代码。
- 对于群组:添加机器人,决定隐私/管理员行为(见下文),然后设置
channels.telegram.groups来控制提及门槛 + 白名单。
令牌 + 隐私 + 权限(Telegram 端)
Section titled “令牌 + 隐私 + 权限(Telegram 端)”令牌创建 (BotFather)
Section titled “令牌创建 (BotFather)”/newbot创建机器人并返回令牌(保密)。- 如果令牌泄露,通过 @BotFather 撤销/重新生成它并更新你的配置。
群组消息可见性(隐私模式)
Section titled “群组消息可见性(隐私模式)”Telegram 机器人默认为 隐私模式 (Privacy Mode),这限制了它们接收哪些群组消息。 如果你的机器人必须查看 所有 群组消息,你有两个选择:
- 使用
/setprivacy禁用隐私模式 或 - 将机器人添加为群组 管理员(管理员机器人接收所有消息)。
注意: 当你切换隐私模式时,Telegram 要求将机器人从每个群组移除并重新添加,更改才会生效。
群组权限(管理员权限)
Section titled “群组权限(管理员权限)”管理员状态在群组内设置(Telegram UI)。管理员机器人总是接收所有群组消息,所以如果你需要完全可见性,请使用管理员。
工作原理(行为)
Section titled “工作原理(行为)”- 入站消息被标准化为带有回复上下文和媒体占位符的共享频道信封。
- 群组回复默认需要提及(原生 @mention 或
agents.list[].groupChat.mentionPatterns/messages.groupChat.mentionPatterns)。 - 多智能体覆盖:在
agents.list[].groupChat.mentionPatterns上设置每个智能体的模式。 - 回复总是路由回同一个 Telegram 聊天。
- 长轮询使用带有每个聊天排序的 grammY runner;总并发数由
agents.defaults.maxConcurrent限制。 - Telegram Bot API 不支持已读回执;没有
sendReadReceipts选项。
格式化(Telegram HTML)
Section titled “格式化(Telegram HTML)”- 出站 Telegram 文本使用
parse_mode: "HTML"(Telegram 支持的标签子集)。 - Markdown 风格的输入被渲染为 Telegram 安全的 HTML(粗体/斜体/删除线/代码/链接);块元素被扁平化为带有换行符/项目符号的文本。
- 来自模型的原始 HTML 被转义以避免 Telegram 解析错误。
- 如果 Telegram 拒绝 HTML 有效负载,OpenClaw 会作为纯文本重试相同的消息。
命令(原生 + 自定义)
Section titled “命令(原生 + 自定义)”OpenClaw 在启动时向 Telegram 的机器人菜单注册原生命令(如 /status, /reset, /model)。 你可以通过配置向菜单添加自定义命令:
{ channels: { telegram: { customCommands: [ { command: "backup", description: "Git backup" }, { command: "generate", description: "Create an image" } ] } }}- 日志中的
setMyCommands failed通常意味着到api.telegram.org的出站 HTTPS/DNS 被阻止。 - 如果你看到
sendMessage或sendChatAction失败,请检查 IPv6 路由和 DNS。
更多帮助:频道故障排除。
注意:
- 自定义命令 仅是菜单条目;OpenClaw 不会实现它们,除非你在其他地方处理它们。
- 命令名称被标准化(去除前导
/,小写)并且必须匹配a-z,0-9,_(1–32 个字符)。 - 自定义命令 不能覆盖原生命令。冲突会被忽略并记录。
- 如果禁用了
commands.native,则仅注册自定义命令(如果无则清除)。
- 出站文本分块限制为
channels.telegram.textChunkLimit(默认 4000)。 - 可选换行符分块:设置
channels.telegram.chunkMode="newline"以在长度分块之前按空行(段落边界)拆分。 - 媒体下载/上传限制为
channels.telegram.mediaMaxMb(默认 5)。 - Telegram Bot API 请求在
channels.telegram.timeoutSeconds后超时(默认通过 grammY 为 500)。设置较低的值以避免长时间挂起。 - 群组历史上下文使用
channels.telegram.historyLimit(或channels.telegram.accounts.*.historyLimit),回退到messages.groupChat.historyLimit。设置为0以禁用(默认 50)。 - 私信历史可以通过
channels.telegram.dmHistoryLimit(用户轮次)进行限制。每个用户的覆盖:channels.telegram.dms["<user_id>"].historyLimit。
群组激活模式
Section titled “群组激活模式”默认情况下,机器人仅响应群组中的提及(@botname 或 agents.list[].groupChat.mentionPatterns 中的模式)。要更改此行为:
通过配置(推荐)
Section titled “通过配置(推荐)”{ channels: { telegram: { groups: { "-1001234567890": { requireMention: false } // 在此群组中总是响应 } } }}重要: 设置 channels.telegram.groups 会创建一个 白名单 - 只有列出的群组(或 "*")会被接受。 论坛主题继承其父群组配置(allowFrom, requireMention, skills, prompts),除非你在 channels.telegram.groups.<groupId>.topics.<topicId> 下添加每个主题的覆盖。
允许所有群组总是响应:
{ channels: { telegram: { groups: { "*": { requireMention: false } // 所有群组,总是响应 } } }}保持所有群组仅提及(默认行为):
{ channels: { telegram: { groups: { "*": { requireMention: true } // 或者完全省略 groups } } }}通过命令(会话级别)
Section titled “通过命令(会话级别)”在群组中发送:
/activation always- 响应所有消息/activation mention- 需要提及(默认)
注意: 命令仅更新会话状态。要在重启后保持持久行为,请使用配置。
获取群组聊天 ID
Section titled “获取群组聊天 ID”将群组中的任何消息转发给 Telegram 上的 @userinfobot 或 @getidsbot 以查看聊天 ID(类似 -1001234567890 的负数)。
提示: 对于你自己的用户 ID,私信机器人,它将回复你的用户 ID(配对消息),或者一旦启用命令,使用 /whoami。
隐私说明: @userinfobot 是第三方机器人。如果你更喜欢,将机器人添加到群组,发送消息,并使用 openclaw logs --follow 读取 chat.id,或使用 Bot API getUpdates。
默认情况下,Telegram 允许写入由频道事件或 /config set|unset 触发的配置更新。
这发生在:
- 群组升级为超级群组且 Telegram 发出
migrate_to_chat_id(聊天 ID 更改)时。OpenClaw 可以自动迁移channels.telegram.groups。 - 你在 Telegram 聊天中运行
/config set或/config unset(需要commands.config: true)。
禁用方法:
{ channels: { telegram: { configWrites: false } }}主题(论坛超级群组)
Section titled “主题(论坛超级群组)”Telegram 论坛主题在每条消息中包含一个 message_thread_id。OpenClaw:
- 将
:topic:<threadId>附加到 Telegram 群组会话键,以便每个主题都是隔离的。 - 发送带有
message_thread_id的输入指示和回复,以便响应保留在主题中。 - 常规主题(线程 ID
1)很特殊:消息发送省略message_thread_id(Telegram 拒绝它),但输入指示仍包含它。 - 在模板上下文中公开
MessageThreadId+IsForum以用于路由/模板化。 - 主题特定配置可在
channels.telegram.groups.<chatId>.topics.<threadId>下获得(skills, allowlists, auto-reply, system prompts, disable)。 - 主题配置继承群组设置(requireMention, allowlists, skills, prompts, enabled),除非每个主题被覆盖。
私聊在某些边缘情况下可能包含 message_thread_id。OpenClaw 保持 DM 会话键不变,但在存在时仍使用线程 ID 进行回复/草稿流式传输。
内联按钮 (Inline Buttons)
Section titled “内联按钮 (Inline Buttons)”Telegram 支持带有回调按钮的内联键盘。
{ "channels": { "telegram": { "capabilities": { "inlineButtons": "allowlist" } } }}对于每个账户的配置:
{ "channels": { "telegram": { "accounts": { "main": { "capabilities": { "inlineButtons": "allowlist" } } } } }}范围:
off— 禁用内联按钮dm— 仅私信(群组目标被阻止)group— 仅群组(私信目标被阻止)all— 私信 + 群组allowlist— 私信 + 群组,但仅限allowFrom/groupAllowFrom允许的发送者(与控制命令规则相同)
默认值:allowlist。 旧版:capabilities: ["inlineButtons"] = inlineButtons: "all"。
使用带有 buttons 参数的 message 工具:
{ "action": "send", "channel": "telegram", "to": "123456789", "message": "Choose an option:", "buttons": [ [ {"text": "Yes", "callback_data": "yes"}, {"text": "No", "callback_data": "no"} ], [ {"text": "Cancel", "callback_data": "cancel"} ] ]}当用户点击按钮时,回调数据作为具有以下格式的消息发送回智能体: callback_data: value
Telegram 功能可以在两个级别配置(如上所示的对象形式;仍支持旧版字符串数组):
channels.telegram.capabilities:除非被覆盖,否则应用于所有 Telegram 账户的全局默认功能配置。channels.telegram.accounts.<account>.capabilities:每个账户的功能,覆盖该特定账户的全局默认值。
当所有 Telegram 机器人/账户应表现相同时,使用全局设置。当不同的机器人需要不同的行为时(例如,一个账户仅处理私信,而另一个允许在群组中),使用每个账户的配置。
访问控制(私信 + 群组)
Section titled “访问控制(私信 + 群组)”- 默认:
channels.telegram.dmPolicy = "pairing"。未知发送者会收到一个配对代码;消息会被忽略,直到获得批准(代码在 1 小时后过期)。 - 批准方式:
openclaw pairing list telegramopenclaw pairing approve telegram <CODE>
- 配对是用于 Telegram 私信的默认令牌交换。详情:配对
channels.telegram.allowFrom接受数字用户 ID(推荐)或@username条目。它 不是 机器人用户名;使用人类发送者的 ID。向导接受@username并在可能时将其解析为数字 ID。
查找你的 Telegram 用户 ID
Section titled “查找你的 Telegram 用户 ID”更安全(无第三方机器人):
- 启动网关并私信你的机器人。
- 运行
openclaw logs --follow并查找from.id。
替代方案(官方 Bot API):
- 私信你的机器人。
- 使用你的机器人令牌获取更新并读取
message.from.id:Terminal window curl "https://api.telegram.org/bot<bot_token>/getUpdates"
第三方(隐私性较低):
- 私信
@userinfobot或@getidsbot并使用返回的用户 id。
两个独立的控制:
1. 哪些群组被允许(通过 channels.telegram.groups 的群组白名单):
- 无
groups配置 = 允许所有群组 - 有
groups配置 = 仅允许列出的群组或"*" - 示例:
"groups": { "-1001234567890": {}, "*": {} }允许所有群组
2. 哪些发送者被允许(通过 channels.telegram.groupPolicy 的发送者过滤):
"open"= 允许群组中的所有发送者发消息"allowlist"= 仅channels.telegram.groupAllowFrom中的发送者可以发消息"disabled"= 完全不接受群组消息 默认为groupPolicy: "allowlist"(除非你添加groupAllowFrom,否则被阻止)。
大多数用户想要:groupPolicy: "allowlist" + groupAllowFrom + 在 channels.telegram.groups 中列出的特定群组
长轮询 vs Webhook
Section titled “长轮询 vs Webhook”- 默认:长轮询(不需要公共 URL)。
- Webhook 模式:设置
channels.telegram.webhookUrl(可选channels.telegram.webhookSecret+channels.telegram.webhookPath)。- 本地监听器默认绑定到
0.0.0.0:8787并服务POST /telegram-webhook。 - 如果你的公共 URL 不同,请使用反向代理并将
channels.telegram.webhookUrl指向公共端点。
- 本地监听器默认绑定到
回复线程 (Threading)
Section titled “回复线程 (Threading)”Telegram 支持通过标签进行可选的线程回复:
[[reply_to_current]]— 回复触发消息。[[reply_to:<id>]]— 回复特定的消息 id。
由 channels.telegram.replyToMode 控制:
first(默认),all,off。
音频消息(语音 vs 文件)
Section titled “音频消息(语音 vs 文件)”Telegram 区分 语音笔记(圆形气泡)和 音频文件(元数据卡片)。 OpenClaw 默认为音频文件以保持向后兼容性。
要在智能体回复中强制使用语音笔记气泡,请在回复的任何位置包含此标签:
[[audio_as_voice]]— 将音频作为语音笔记而不是文件发送。
该标签会从交付的文本中剥离。其他频道忽略此标签。
对于 message 工具发送,设置 asVoice: true 并带有语音兼容的音频 media URL(当存在媒体时 message 是可选的):
{ "action": "send", "channel": "telegram", "to": "123456789", "media": "https://example.com/voice.ogg", "asVoice": true}贴纸 (Stickers)
Section titled “贴纸 (Stickers)”OpenClaw 支持接收和发送带有智能缓存的 Telegram 贴纸。
当用户发送贴纸时,OpenClaw 根据贴纸类型进行处理:
- 静态贴纸 (WEBP): 下载并通过视觉处理。贴纸在消息内容中显示为
<media:sticker>占位符。 - 动画贴纸 (TGS): 跳过(不支持处理 Lottie 格式)。
- 视频贴纸 (WEBM): 跳过(不支持处理视频格式)。
接收贴纸时可用的模板上下文部分:
Sticker— 对象包含:emoji— 与贴纸关联的表情符号setName— 贴纸集的名称fileId— Telegram 文件 ID(发送回相同的贴纸)fileUniqueId— 用于缓存查找的稳定 IDcachedDescription— 可用时的缓存视觉描述
贴纸通过 AI 的视觉功能进行处理以生成描述。由于相同的贴纸经常被重复发送,OpenClaw 会缓存这些描述以避免冗余的 API 调用。
工作原理:
- 首次遇到: 贴纸图像被发送给 AI 进行视觉分析。AI 生成描述(例如,“一只热情挥手的卡通猫”)。
- 缓存存储: 描述与贴纸的文件 ID、表情符号和集合名称一起保存。
- 后续遇到: 当再次看到相同的贴纸时,直接使用缓存的描述。图像不会发送给 AI。
缓存位置: ~/.openclaw/telegram/sticker-cache.json
缓存条目格式:
{ "fileId": "CAACAgIAAxkBAAI...", "fileUniqueId": "AgADBAADb6cxG2Y", "emoji": "👋", "setName": "CoolCats", "description": "A cartoon cat waving enthusiastically", "cachedAt": "2026-01-15T10:30:00.000Z"}好处:
- 通过避免对同一贴纸的重复视觉调用来降低 API 成本
- 缓存贴纸的响应时间更快(无视觉处理延迟)
- 启用基于缓存描述的贴纸搜索功能
缓存随着接收贴纸自动填充。不需要手动缓存管理。
智能体可以使用 sticker 和 sticker-search 动作发送和搜索贴纸。这些默认是禁用的,必须在配置中启用:
{ channels: { telegram: { actions: { sticker: true } } }}发送贴纸:
{ "action": "sticker", "channel": "telegram", "to": "123456789", "fileId": "CAACAgIAAxkBAAI..."}参数:
fileId(必需)— 贴纸的 Telegram 文件 ID。接收贴纸时从Sticker.fileId获取,或从sticker-search结果中获取。replyTo(可选)— 要回复的消息 ID。threadId(可选)— 论坛主题的消息线程 ID。
搜索贴纸:
智能体可以按描述、表情符号或集合名称搜索缓存的贴纸:
{ "action": "sticker-search", "channel": "telegram", "query": "cat waving", "limit": 5}返回缓存中的匹配贴纸:
{ "ok": true, "count": 2, "stickers": [ { "fileId": "CAACAgIAAxkBAAI...", "emoji": "👋", "description": "A cartoon cat waving enthusiastically", "setName": "CoolCats" } ]}搜索使用跨描述文本、表情符号字符和集合名称的模糊匹配。
带线程的示例:
{ "action": "sticker", "channel": "telegram", "to": "-1001234567890", "fileId": "CAACAgIAAxkBAAI...", "replyTo": 42, "threadId": 123}流式传输(草稿)
Section titled “流式传输(草稿)”Telegram 可以在智能体生成回复时流式传输 草稿气泡。 OpenClaw 使用 Bot API sendMessageDraft(不是真实消息),然后作为普通消息发送最终回复。
要求 (Telegram Bot API 9.3+):
- 启用了主题的私聊(机器人的论坛主题模式)。
- 传入消息必须包含
message_thread_id(私有主题线程)。 - 对于群组/超级群组/频道,流式传输被忽略。
配置:
channels.telegram.streamMode: "off" | "partial" | "block"(默认:partial)partial:使用最新的流式文本更新草稿气泡。block:以较大的块(分块)更新草稿气泡。off:禁用草稿流式传输。
- 可选(仅适用于
streamMode: "block"):channels.telegram.draftChunk: { minChars?, maxChars?, breakPreference? }- 默认值:
minChars: 200,maxChars: 800,breakPreference: "paragraph"(限制为channels.telegram.textChunkLimit)。
- 默认值:
注意:草稿流式传输与 块流式传输(频道消息)是分开的。 块流式传输默认关闭,如果你想要早期 Telegram 消息而不是草稿更新,需要 channels.telegram.blockStreaming: true。
推理流(仅限 Telegram):
/reasoning stream在生成回复时将推理流式传输到草稿气泡中,然后发送不带推理的最终答案。- 如果
channels.telegram.streamMode为off,推理流被禁用。 更多上下文:流式传输 + 分块。
出站 Telegram API 调用会在瞬态网络/429 错误时进行带有指数退避和抖动的重试。通过 channels.telegram.retry 配置。参见 重试策略。
智能体工具(消息 + 反应)
Section titled “智能体工具(消息 + 反应)”- 工具:带有
sendMessage动作的telegram(to,content, 可选mediaUrl,replyToMessageId,messageThreadId)。 - 工具:带有
react动作的telegram(chatId,messageId,emoji)。