Skip to content

OpenClaw 通过 grammY 接入 Telegram Bot,支持私信和群组,默认长轮询。配置 botToken 后启动 Gateway,配对码有效期 1 小时。私信访问控制(dmPolicy)支持 pairing(默认)、allowlist、open 和 disabled;群组通过 groupPolicygroups 白名单控制,requireMention 控制是否需要 @ 触发。关键命令:openclaw gatewayopenclaw pairing list/approveopenclaw 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.groupsgroupPolicy 以匹配你的访问模型。

注意: token 解析顺序具有账号感知能力,配置值优先于环境变量回退,TELEGRAM_BOT_TOKEN 仅适用于默认账号。启动成功后 OpenClaw 会将 bot 身份缓存到状态目录最多 24 小时,变更或删除 token 会清除缓存。

Telegram 端设置

隐私模式与群组可见性

Telegram 机器人默认启用隐私模式,限制接收的群组消息。若机器人需要看到全部群组消息:

  • 通过 /setprivacy 禁用隐私模式,或
  • 将机器人设为群组管理员。

切换隐私模式后,需将机器人移除并重新加入每个群组以使变更生效。

BotFather 常用开关

  • /setjoingroups:允许/禁止加入群组
  • /setprivacy:群组可见性行为

访问控制与激活

私信策略(DM policy)

channels.telegram.dmPolicy 控制私信访问:

  • pairing(默认)
  • allowlistallowFrom 中至少需一个发送者 ID)
  • openallowFrom 需包含 "*"
  • 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(安全方式):

  1. 给你的机器人发消息。
  2. 运行 openclaw logs --follow
  3. 读取 from.id

官方 Bot API 方式:

bash
curl "https://api.telegram.org/bot<bot_token>/getUpdates"

第三方方式:@userinfobot@getidsbot(隐私风险较低)。

群组策略(Group policy)与白名单

两个控制层同时生效:

  1. 允许哪些群组channels.telegram.groups

    • 未配置 groupsgroupPolicy: "open" 时任意群组可通过群组 ID 检查;groupPolicy: "allowlist"(默认)时群组被拦截直到添加 groups 条目或 "*"
    • 已配置 groups:作为白名单(显式 ID 或 "*")。
  2. 允许哪些发送者进入群组channels.telegram.groupPolicy

    • open
    • allowlist(默认)
    • 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.mentionPatternsmessages.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;若出现 getUpdates 409 冲突,检查是否有其他进程或脚本正在使用同一 token。
  • 长轮询看门狗在 120 秒无完成 getUpdates 活动后重启,可调节 channels.telegram.pollingStallThresholdMs(允许 30000~600000ms)。
  • Telegram Bot API 不支持已读回执(sendReadReceipts 不适用)。

功能参考

流式预览(消息编辑)

OpenClaw 支持实时流式局部回复:

  • channels.telegram.streamingoff | 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 插件安装后:

  1. /pair 生成设置码
  2. 在 iOS 应用中粘贴
  3. /pair pending 列出待处理请求
  4. /pair approve <requestId> 批准

设置码携带短期引导 token,首次连接创建待处理节点请求,批准后返回持久节点 token(scopes: []),不返回移交互操作员 token。更多细节:配对

内联按钮

配置作用范围:

json5
{
  channels: {
    telegram: {
      capabilities: {
        inlineButtons: "allowlist",
      },
    },
  },
}

范围选项:off | dm | group | all | allowlist(默认)。回调点击以文本形式传给 Agent:callback_data: &lt;value&gt;

消息动作示例:

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 工具动作包括:sendMessagereactdeleteMessageeditMessagecreateForumTopic。开关配置:

  • channels.telegram.actions.sendMessage
  • channels.telegram.actions.deleteMessage
  • channels.telegram.actions.reactions
  • channels.telegram.actions.sticker(默认禁用)

edittopic-create 默认启用,无单独开关。

Forum 话题与会话隔离

Forum 超级群组中话题会话键追加 :topic:<threadId>。话题配置路径:channels.telegram.groups.<chatId>.topics.<threadId>。每个话题可路由到不同 agent(设置 agentId 实现独立工作区、记忆和会话)。线程绑定的 ACP 绑定: /acp spawn &lt;agent&gt; --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.reactionNotificationsoff | own | all(默认 own
  • channels.telegram.reactionLeveloff | ack | minimal | extensive(默认 minimal

注意:own 仅处理用户对 bot 消息的反应(基于发送消息缓存尽力而为)。反应事件仍受访问控制过滤。Forum 群组的反应路由到通用话题会话(:topic:1),而非精确来源话题。

Ack 反应

处理入站消息时发送确认 emoji。解析顺序:

  • channels.telegram.accounts.<accountId>.ackReaction
  • channels.telegram.ackReaction
  • messages.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.webhookUrlchannels.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.targetdm | channel | both(默认 dm
  • channels.telegram.execApprovals.approvers:审批人数字 Telegram 用户 ID 列表;若未设置,回退到 commands.ownerAllowFrom 中的数字 Owner ID。
  • 审批 ID 前缀 plugin: 通过插件审批解析,其他优先尝试 exec 审批。
  • 内联审批按钮需要 channels.telegram.capabilities.inlineButtons 允许目标表面(dmgroupall)。
  • 默认 30 分钟过期。

错误回复控制

配置键可选值默认值说明
channels.telegram.errorPolicyreply, silentreplyreply 发送友好错误信息到聊天;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 --probeopenclaw 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 同样填入 allowFromgroupAllowFrom,并配置 groups 白名单。

启动报错 getMe returned 401 怎么办

这是 bot token 无效导致 Telegram 认证失败。在 BotFather 中重新复制或生成 token,然后更新配置文件中的 botTokentokenFile 或环境变量 TELEGRAM_BOT_TOKEN。若配置了多账号,需检查对应账号的 token。

相关链接