Appearance
OpenClaw 通过 grammY 接入 Telegram Bot,支持私信和群组,默认长轮询。配置 botToken 后启动 Gateway,配对码有效期 1 小时。私信访问控制(dmPolicy)支持 pairing(默认)、allowlist、open 和 disabled;群组通过 groupPolicy 和 groups 白名单控制,requireMention 控制是否需要 @ 触发。关键命令:openclaw gateway、openclaw pairing list/approve、openclaw channels status --probe。支持 Forum 话题路由、流式预览、内联按钮、Exec 审批等高级功能。
OpenClaw Telegram Bot 接入配置指南
快速配置
1. 在 BotFather 创建机器人 token
打开 Telegram,与 @BotFather 对话(确认 handle 完全一致 @BotFather)。运行 /newbot,按提示操作并保存生成的 token。
2. 配置 token 和私信策略
在配置文件中设置:
json5
{
channels: {
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing",
groups: { "*": { requireMention: true } },
},
},
}环境变量回退:TELEGRAM_BOT_TOKEN=...(仅默认账号)。Telegram 不使用 openclaw channels login telegram,直接在配置或环境变量中设置 token,然后启动 Gateway。
3. 启动 Gateway 并批准首个私信
bash
openclaw gateway
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>配对码有效期 1 小时。
4. 将机器人添加到群组
将机器人添加到群组,然后配置 channels.telegram.groups 和 groupPolicy 以匹配你的访问模型。
注意: token 解析顺序具有账号感知能力,配置值优先于环境变量回退,
TELEGRAM_BOT_TOKEN仅适用于默认账号。启动成功后 OpenClaw 会将 bot 身份缓存到状态目录最多 24 小时,变更或删除 token 会清除缓存。
Telegram 端设置
隐私模式与群组可见性
Telegram 机器人默认启用隐私模式,限制接收的群组消息。若机器人需要看到全部群组消息:
- 通过
/setprivacy禁用隐私模式,或 - 将机器人设为群组管理员。
切换隐私模式后,需将机器人移除并重新加入每个群组以使变更生效。
BotFather 常用开关
/setjoingroups:允许/禁止加入群组/setprivacy:群组可见性行为
访问控制与激活
私信策略(DM policy)
channels.telegram.dmPolicy 控制私信访问:
pairing(默认)allowlist(allowFrom中至少需一个发送者 ID)open(allowFrom需包含"*")disabled
channels.telegram.allowFrom 接受数字 Telegram 用户 ID,telegram: / tg: 前缀会被标准化。dmPolicy: "allowlist" 且 allowFrom 为空时会拦截所有私信,配置验证会报错。
实践建议: 单 Owner 机器人优先使用 dmPolicy: "allowlist" 加显式数字 allowFrom ID,使访问策略持久保存在配置中,而非依赖之前的配对批准。
常见混淆: DM 配对批准不代表该发送者在所有地方都获得授权。配对只授予私信访问权限,群组发送者授权仍需通过配置白名单明确设置。若希望配对一次后私信和群组都能使用,将你的数字 Telegram 用户 ID 填入 channels.telegram.allowFrom;若需要 Owner 命令,确保 commands.ownerAllowFrom 包含 telegram:<你的用户ID>。
查找 Telegram 用户 ID(安全方式):
- 给你的机器人发消息。
- 运行
openclaw logs --follow。 - 读取
from.id。
官方 Bot API 方式:
bash
curl "https://api.telegram.org/bot<bot_token>/getUpdates"第三方方式:@userinfobot 或 @getidsbot(隐私风险较低)。
群组策略(Group policy)与白名单
两个控制层同时生效:
允许哪些群组(
channels.telegram.groups)- 未配置
groups:groupPolicy: "open"时任意群组可通过群组 ID 检查;groupPolicy: "allowlist"(默认)时群组被拦截直到添加groups条目或"*"。 - 已配置
groups:作为白名单(显式 ID 或"*")。
- 未配置
允许哪些发送者进入群组(
channels.telegram.groupPolicy)openallowlist(默认)disabled
groupAllowFrom 用于群组发送者过滤;未设置时回退到配置中的 allowFrom(而非配对存储)。条目应为数字 Telegram 用户 ID。注意: 负数的群组/超级群组 ID 属于 channels.telegram.groups,不要放在 groupAllowFrom 里。
安全边界(2026.2.25+): 群组发送者授权不继承 DM 配对存储的批准。配对仅限私信。对于单 Owner 机器人的实用模式:将你的用户 ID 填入 channels.telegram.allowFrom,留空 groupAllowFrom,并在 channels.telegram.groups 下允许目标群组。
允许某个特定群组内任意成员的示例:
json5
{
channels: {
telegram: {
groups: {
"-1001234567890": {
groupPolicy: "open",
requireMention: false,
},
},
},
},
}只允许特定用户在某个群组内触发的示例:
json5
{
channels: {
telegram: {
groups: {
"-1001234567890": {
requireMention: true,
allowFrom: ["8734062810", "745123456"],
},
},
},
},
}提及行为
群组回复默认需要提及。提及来源:
- 原生
@botusername提及,或 - 提及模式(
agents.list[].groupChat.mentionPatterns或messages.groupChat.mentionPatterns)。
会话级命令切换(仅临时生效):
/activation always/activation mention
持久化配置示例:
json5
{
channels: {
telegram: {
groups: {
"*": { requireMention: false },
},
},
},
}运行时行为
- Telegram 由 Gateway 进程独占。
- 路由确定性:Telegram 入站消息始终回复到 Telegram(模型不选择渠道)。
- 入站消息规范化为共享渠道信封,包含回复元数据、媒体占位符和持久化的回复链上下文。
- 群组会话按群组 ID 隔离。Forum 话题在会话键后追加
:topic:<threadId>保持隔离。 - 私信可携带
message_thread_id;OpenClaw 在回复中保留线程 ID,但默认将私信保持在扁平会话中。如需 DM 话题会话隔离,配置channels.telegram.dm.threadReplies: "inbound"或requireTopic: true等。 - 长轮询使用 grammY runner,按聊天/线程顺序处理。整体 runner sink 并发度使用
agents.defaults.maxConcurrent。 - 多账号启动时限制并发 Telegram
getMe探测。 - 每个 Gateway 进程内只有一个活跃轮询器可使用同一 bot token;若出现
getUpdates409 冲突,检查是否有其他进程或脚本正在使用同一 token。 - 长轮询看门狗在 120 秒无完成
getUpdates活动后重启,可调节channels.telegram.pollingStallThresholdMs(允许 30000~600000ms)。 - Telegram Bot API 不支持已读回执(
sendReadReceipts不适用)。
功能参考
流式预览(消息编辑)
OpenClaw 支持实时流式局部回复:
channels.telegram.streaming:off | partial | block | progress(默认partial)progress模式为工具进度保留一条可编辑状态草稿,完成后清除并发送最终答案。streaming.preview.toolProgress控制是否显示工具进度预览(默认 true)。streaming.preview.commandText控制工具进度中命令/执行的显示细节:raw(默认)或status(仅工具标签)。- Telegram 独有的推理流:
/reasoning stream将推理内容发送到实时预览,最终答案不包含推理文本。
各模式行为差异:
off:完全禁用预览编辑,工具/进度提示被抑制(审批提示、媒体负载、错误仍正常投递)。partial:保持同一预览消息并执行最终就地编辑。progress:工具进度使用单独可编辑草稿,最终答案正常投递。block:显式启用块流时跳过预览流以避免双流。
格式化与 HTML 回退
出站文本使用 Telegram parse_mode: "HTML"。Markdown 风格文本渲染为 Telegram 安全 HTML,不支持的 HTML 标签会被转义。若 Telegram 拒绝解析后的 HTML,OpenClaw 以纯文本重试。链接预览默认启用,可通过 channels.telegram.linkPreview: false 禁用。
原生命令与自定义命令
Telegram 命令菜单注册在启动时通过 setMyCommands 处理。
commands.native: "auto"为 Telegram 启用原生命令。channels.telegram.customCommands添加自定义命令菜单条目(不自动实现行为)。
常见失败:
setMyCommands failed+BOT_COMMANDS_TOO_MUCH:菜单条目过多,减少插件/技能/自定义命令或禁用channels.telegram.commands.native。setMyCommands failed+ 网络错误:检查api.telegram.org是否可达。deleteMyCommands/setMyCommands启动时失败但直接 curl 正常:检查channels.telegram.apiRoot是否设置错误(不应包含/bot<TOKEN>路径)。
设备配对命令(device-pair 插件)
当 device-pair 插件安装后:
/pair生成设置码- 在 iOS 应用中粘贴
/pair pending列出待处理请求/pair approve <requestId>批准
设置码携带短期引导 token,首次连接创建待处理节点请求,批准后返回持久节点 token(scopes: []),不返回移交互操作员 token。更多细节:配对
内联按钮
配置作用范围:
json5
{
channels: {
telegram: {
capabilities: {
inlineButtons: "allowlist",
},
},
},
}范围选项:off | dm | group | all | allowlist(默认)。回调点击以文本形式传给 Agent:callback_data: <value>。
消息动作示例:
json5
{
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" }],
],
}Telegram web_app 按钮仅在用户与 bot 的私聊中生效。
消息动作(Telegram 工具)
Telegra m 工具动作包括:sendMessage、react、deleteMessage、editMessage、createForumTopic。开关配置:
channels.telegram.actions.sendMessagechannels.telegram.actions.deleteMessagechannels.telegram.actions.reactionschannels.telegram.actions.sticker(默认禁用)
edit 和 topic-create 默认启用,无单独开关。
Forum 话题与会话隔离
Forum 超级群组中话题会话键追加 :topic:<threadId>。话题配置路径:channels.telegram.groups.<chatId>.topics.<threadId>。每个话题可路由到不同 agent(设置 agentId 实现独立工作区、记忆和会话)。线程绑定的 ACP 绑定: /acp spawn <agent> --thread here|auto 将当前话题绑定到新 ACP 会话,需要 channels.telegram.threadBindings.spawnSessions 保持启用(默认 true)。
音频、视频与 Sticker
- 音频消息: 默认以文件发送,在 agent 回复中添加
[[audio_as_voice]]标签强制以语音发送。入站语音消息转录文本在 agent 上下文中标记为“机器生成,不可靠”,提及检测仍基于原始转录。 - 视频消息:
asVideoNote: true发送圆形视频(无字幕,文本单独发送)。 - Sticker: 静态 WEBP 下载并处理(占位符
<media:sticker>),动态 TGS 和视频 WEBM 跳过。启用 sticker 动作需channels.telegram.actions.sticker: true。缓存文件:~/.openclaw/telegram/sticker-cache.json。
反应通知
channels.telegram.reactionNotifications:off | own | all(默认own)channels.telegram.reactionLevel:off | ack | minimal | extensive(默认minimal)
注意:own 仅处理用户对 bot 消息的反应(基于发送消息缓存尽力而为)。反应事件仍受访问控制过滤。Forum 群组的反应路由到通用话题会话(:topic:1),而非精确来源话题。
Ack 反应
处理入站消息时发送确认 emoji。解析顺序:
channels.telegram.accounts.<accountId>.ackReactionchannels.telegram.ackReactionmessages.ackReaction- agent identity emoji 回退(
agents.list[].identity.emoji,否则"👀")
Telegram 要求 Unicode emoji,使用 "" 禁用。
配置写入
configWrites 默认启用,Telegram 触发的写入包括:群组迁移事件(migrate_to_chat_id)更新 groups、/config set 和 /config unset 命令。禁用:channels.telegram.configWrites: false。
长轮询 vs Webhook
默认长轮询。Webhook 模式需设置 channels.telegram.webhookUrl 和 channels.telegram.webhookSecret;可选 webhookPath(默认 /telegram-webhook)、webhookHost(默认 127.0.0.1)、webhookPort(默认 8787)。长轮询中持久化重启水印仅在更新成功分发后写入;失败保留可重试。Webhook 模式验证请求后再异步处理更新。
限制、重试与 CLI 发送目标
- 文本分块:
channels.telegram.textChunkLimit默认 4000;chunkMode="newline"按段落分块。 - 媒体大小限制:
channels.telegram.mediaMaxMb默认 100 MB。 - 媒体组刷新:
mediaGroupFlushMs默认 500ms。 - API 超时:
timeoutSeconds未设置时使用 grammY 默认;bot 客户端会将配置值夹紧在出站请求保护之下(防止长轮询过早超时)。 - 轮询停滞阈值:
pollingStallThresholdMs默认 120000ms,仅在有假阳性重启时调节。 - 历史限制: 群组
historyLimit默认 50(0禁用);私信dmHistoryLimit单独控制。 - 重试:
channels.telegram.retry对可恢复的出站 API 错误生效;入站最终回复投递也使用有限重试,但不重试可能导致重复消息的歧义网络错误。
CLI 发送示例:
bash
openclaw message send --channel telegram --target 123456789 --message "hi"
openclaw message send --channel telegram --target @name --message "hi"
openclaw message send --channel telegram --target -1001234567890:topic:42 --message "hi topic"轮询 CLI:
bash
openclaw message poll --channel telegram --target 123456789 \
--poll-question "Ship it?" --poll-option "Yes" --poll-option "No"Telegram 特有选项:--poll-duration-seconds(5-600)、--poll-anonymous、--poll-public、--thread-id、--pin、--force-document。
动作开关:channels.telegram.actions.sendMessage=false 禁用所有出站消息(包括轮询);channels.telegram.actions.poll=false 仅禁用轮询创建。
Exec 审批
Telegram 支持在审批人私信中进行 exec 审批,也可选择在原始聊天或话题中发布审批提示。
channels.telegram.execApprovals.target:dm | channel | both(默认dm)channels.telegram.execApprovals.approvers:审批人数字 Telegram 用户 ID 列表;若未设置,回退到commands.ownerAllowFrom中的数字 Owner ID。- 审批 ID 前缀
plugin:通过插件审批解析,其他优先尝试 exec 审批。 - 内联审批按钮需要
channels.telegram.capabilities.inlineButtons允许目标表面(dm、group或all)。 - 默认 30 分钟过期。
错误回复控制
| 配置键 | 可选值 | 默认值 | 说明 |
|---|---|---|---|
channels.telegram.errorPolicy | reply, silent | reply | reply 发送友好错误信息到聊天;silent 完全抑制错误回复 |
channels.telegram.errorCooldownMs | 毫秒数 | 60000 | 同一聊天的错误回复间隔,防止刷屏 |
支持每账号、每群组、每话题覆盖:
json5
{
channels: {
telegram: {
errorPolicy: "reply",
errorCooldownMs: 120000,
groups: {
"-1001234567890": {
errorPolicy: "silent",
},
},
},
},
}故障排查
机器人不响应未提及的群组消息
- 如果
requireMention=false,Telegram 隐私模式必须允许完整可见性:BotFather →/setprivacy→ Disable,然后移出并重新加入机器人。 openclaw channels status --probe可检查显式数字群组 ID;通配符"*"无法探针检查。- 快速会话测试:
/activation always。
机器人完全看不到群组消息
- 如果
channels.telegram.groups存在,群组必须在列表中(或包含"*")。 - 确认机器人已加入群组。
- 查看日志:
openclaw logs --follow。
命令部分或完全不生效
- 授权你的发送者身份(配对和/或数字
allowFrom)。 - 即使群组策略为
open,命令授权仍然生效。 setMyCommands报错BOT_COMMANDS_TOO_MUCH:减少命令数量或禁用原生命令。deleteMyCommands/setMyCommands持续网络错误:检查api.telegram.org可达性。
启动时报 unauthorized token
getMe returned 401:token 认证失败,更新botToken或环境变量。deleteWebhook 401同样表示 token 无效。
轮询或网络不稳定
- 检查 IPv6 出站是否正常:
dig +short api.telegram.org AAAA,若 IPv6 不可靠可在配置中设置network.autoSelectFamily: false或通过环境变量OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first强制 IPv4。 - 通过代理路由:
channels.telegram.proxy: socks5://user:pass@host:1080。 - 日志中出现
Polling stall detected时,默认 120 秒无 liveness 重启,可调高pollingStallThresholdMs。 openclaw channels status --probe和openclaw doctor可诊断运行状态。- RFC 2544 基准地址(198.18.0.0/15)默认允许;若使用 fake-IP 代理重写了
api.telegram.org到其他私有地址,可启用channels.telegram.network.dangerouslyAllowPrivateNetwork: true(会削弱 SSRF 保护)。
配置参考
关键配置字段
- 启动/认证:
enabled,botToken,tokenFile,accounts.* - 访问控制:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups,groups.*.topics.*,bindings[] - Exec 审批:
execApprovals,accounts.*.execApprovals - 命令/菜单:
commands.native,commands.nativeSkills,customCommands - 线程/回复:
replyToMode,dm.threadReplies,direct.*.threadReplies - 流式:
streaming(preview),streaming.preview.toolProgress,blockStreaming - 格式化/投递:
textChunkLimit,chunkMode,linkPreview,responsePrefix - 媒体/网络:
mediaMaxMb,mediaGroupFlushMs,timeoutSeconds,pollingStallThresholdMs,retry,network.autoSelectFamily,network.dangerouslyAllowPrivateNetwork,proxy - 自定义 API 根:
apiRoot(仅 Bot API 根,不含/bot<TOKEN>) - Webhook:
webhookUrl,webhookSecret,webhookPath,webhookHost - 动作/能力:
capabilities.inlineButtons,actions.sendMessage|editMessage|deleteMessage|reactions|sticker - 反应:
reactionNotifications,reactionLevel - 错误:
errorPolicy,errorCooldownMs - 写入/历史:
configWrites,historyLimit,dmHistoryLimit,dms.*.historyLimit
多账号优先级: 配置多个账号时,设置 channels.telegram.defaultAccount 或包含 channels.telegram.accounts.default 使默认路由明确;否则回退到第一个标准化账号 ID,openclaw doctor 会警告。命名账号继承 channels.telegram.allowFrom / groupAllowFrom,但不继承 accounts.default.* 值。
常见问题
机器人加到群后收不到非 @ 消息
Telegram 默认隐私模式会阻止未提及的消息。在 BotFather 中使用 /setprivacy 选择 Disable,然后将机器人移出并重新加入群组。若配置中设置了 requireMention: false,必须确保隐私模式已禁用。
dmPolicy 和 allowFrom 怎么配置才能只允许自己使用
推荐设置 dmPolicy: "allowlist",并在 channels.telegram.allowFrom 中填入你的数字 Telegram 用户 ID(可在 openclaw logs --follow 中查看 from.id)。对于群组,将你的用户 ID 同样填入 allowFrom 或 groupAllowFrom,并配置 groups 白名单。
启动报错 getMe returned 401 怎么办
这是 bot token 无效导致 Telegram 认证失败。在 BotFather 中重新复制或生成 token,然后更新配置文件中的 botToken、tokenFile 或环境变量 TELEGRAM_BOT_TOKEN。若配置了多账号,需检查对应账号的 token。