Skip to Content
👋 欢迎来到 HowToUseMoltbot 快速入门
频道Telegram

Telegram(Bot API)

Telegram 机器人设置:从 @BotFather 获取 token 并填入。状态:通过 grammY 支持私聊与群组,可用于生产。默认 long-polling;可选 webhook。

快速设置(入门)

  1. @BotFather 创建机器人并复制 token。
  2. 设置 token:
    • 环境变量:TELEGRAM_BOT_TOKEN=...
    • 或配置:channels.telegram.botToken: "..."
    • 若两者都设,以配置为准(环境变量仅作默认账号回退)。
  3. 启动网关。
  4. 私聊默认配对;首次联系时批准配对码。

最小配置:

{ channels: { telegram: { enabled: true, botToken: "123:abc", dmPolicy: "pairing" } } }

说明

  • 由网关持有的 Telegram Bot API 频道。
  • 确定性路由:回复始终发回 Telegram;模型不会选择频道。
  • 私聊共享 agent 主会话;群组独立(agent:<agentId>:telegram:group:<chatId>)。

设置(快速路径)

1) 创建机器人 token(BotFather)

  1. 打开 Telegram,与 @BotFather 对话。
  2. 发送 /newbot,按提示填写名称和以 bot 结尾的用户名。
  3. 复制 token 并妥善保存。

可选 BotFather 设置:

  • /setjoingroups — 允许/禁止将机器人加入群组。
  • /setprivacy — 控制机器人是否接收所有群组消息。

2) 配置 token(环境变量或配置)

示例:

{ channels: { telegram: { enabled: true, botToken: "123:abc", dmPolicy: "pairing", groups: { "*": { requireMention: true } } } } }

环境变量:TELEGRAM_BOT_TOKEN=...(仅对默认账号生效)。若环境变量与配置都设,以配置为准。多账号:使用 channels.telegram.accounts,每账号单独 token 并可设 name。共享模式见 配置

  1. 启动网关。解析到 token(先看配置,再回退环境变量)后 Telegram 会启动。
  2. 私聊默认配对。首次联系机器人时批准配对码。
  3. 群组:将机器人加入群组,决定隐私/管理员行为(见下),再通过 channels.telegram.groups 控制 @ 提及门控与白名单。

Token、隐私与权限(Telegram 侧)

创建 token(BotFather)

  • /newbot 会创建机器人并返回 token(请保密)。
  • 若 token 泄露,通过 @BotFather 撤销/重新生成并更新配置。

群组消息可见性(隐私模式)

Telegram 机器人默认开启隐私模式,会限制收到的群组消息。若机器人必须看到所有群组消息,有两种做法:

  • /setprivacy 关闭隐私模式,
  • 将机器人设为群组管理员(管理员机器人会收到所有消息)。

说明:切换隐私模式后,Telegram 要求从每个群组中移除并重新添加机器人,更改才会生效。

群组权限(管理员)

管理员在群组内设置(Telegram 界面)。管理员机器人始终会收到所有群组消息,若需完整可见性请使用管理员。

行为说明

  • 入站消息被规范为统一频道信封,带回复上下文与媒体占位符。
  • 群组回复默认需要 @ 提及(原生 @ 或 agents.list[].groupChat.mentionPatterns / messages.groupChat.mentionPatterns)。
  • 多 agent 覆盖:在 agents.list[].groupChat.mentionPatterns 上设每 agent 规则。
  • 回复始终路由回同一 Telegram 会话。
  • Long-polling 使用 grammY runner 按会话排序;总并发受 agents.defaults.maxConcurrent 限制。
  • Telegram Bot API 不支持已读回执;无 sendReadReceipts 选项。

格式(Telegram HTML)

  • 出站 Telegram 文本使用 parse_mode: "HTML"(Telegram 支持的标签子集)。
  • 类 Markdown 输入会渲染为** Telegram 安全 HTML**(粗体/斜体/删除线/代码/链接);块级元素会压成带换行/列表的文本。
  • 模型输出的原始 HTML 会被转义,避免 Telegram 解析错误。
  • 若 Telegram 拒绝 HTML payload,Moltbot 会以纯文本重发同一条消息。

命令(原生 + 自定义)

Moltbot 在启动时向 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 被阻断。
  • 若出现 sendMessagesendChatAction 失败,检查 IPv6 路由与 DNS。

更多帮助见 频道故障排查。说明:

  • 自定义命令仅作为菜单项;除非你在别处处理,否则 Moltbot 不会实现它们。
  • 命令名会规范化(去掉前导 /、转小写),且必须匹配 a-z0-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

群组激活模式

默认机器人仅在群组中被人 @ 时回复(@机器人名agents.list[].groupChat.mentionPatterns 中的规则)。要改变此行为:

通过配置(推荐)

{ 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 } } } }

通过命令(会话级)

在群组中发送:

  • /activation always — 回复所有消息
  • /activation mention — 需要 @ 提及(默认)

说明:命令只更新会话状态。若要重启后仍生效,请用配置。

获取群组 chat ID

将群组中任意一条消息转发给 Telegram 上的 @userinfobot@getidsbot 即可看到 chat ID(负数如 -1001234567890)。提示:要查自己的用户 ID,可私聊机器人,配对消息中会回复你的用户 ID,或启用命令后使用 /whoami隐私说明@userinfobot 为第三方机器人。若介意,可将机器人加入群组、发一条消息,用 moltbot logs --follow 查看 chat.id,或使用 Bot API 的 getUpdates

配置写入

默认允许 Telegram 写入由频道事件或 /config set|unset 触发的配置更新。会在以下情况发生:

  • 群组升级为超级群组且 Telegram 发出 migrate_to_chat_id(chat ID 变更)。Moltbot 可自动迁移 channels.telegram.groups
  • 你在 Telegram 会话中执行 /config set/config unset(需 commands.config: true)。

禁用方式:

{ channels: { telegram: { configWrites: false } } }

主题(论坛超级群组)

Telegram 论坛主题中每条消息带有 message_thread_id。Moltbot:

  • 在 Telegram 群组会话键后追加 :topic:<threadId>,使每个主题独立。
  • 发送输入中与回复时带上 message_thread_id,使回复留在主题内。
  • 通用主题(thread id 1)较特殊:发送消息时不带 message_thread_id(Telegram 会拒绝),但输入中仍会带。
  • 在模板上下文中暴露 MessageThreadIdIsForum,用于路由/模板。
  • 每主题配置在 channels.telegram.groups.<chatId>.topics.<threadId> 下(skills、白名单、自动回复、系统提示、禁用)。
  • 主题配置继承群组设置(requireMention、白名单、skills、prompts、enabled),除非按主题覆盖。

私聊在少数情况下也可能带 message_thread_id。Moltbot 保持私聊会话键不变,但若存在则仍用 thread id 做回复/草稿流式。

内联按钮

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"

发送按钮

使用 message 工具的 buttons 参数:

{ "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 数据会以消息形式发回 agent,格式为:callback_data: value

配置选项

Telegram 能力可在两个层级配置(上为对象形式;旧版字符串数组仍支持):

  • channels.telegram.capabilities:全局默认能力配置,应用于所有 Telegram 账号,除非被覆盖。
  • channels.telegram.accounts.<account>.capabilities:每账号能力,覆盖该账号的全局默认。

所有 Telegram 机器人/账号行为一致时用全局;不同机器人需要不同行为时(例如一个只处理私聊、另一个允许群组)用每账号配置。

访问控制(私聊 + 群组)

私聊访问

  • 默认:channels.telegram.dmPolicy = "pairing"。未知发件人收到配对码;批准前消息被忽略(配对码 1 小时后过期)。
  • 批准方式:moltbot pairing list telegrammoltbot pairing approve telegram <CODE>
  • 配对是 Telegram 私聊的默认 token 交换方式。详见 配对
  • channels.telegram.allowFrom 接受数字用户 ID(推荐)或 @username不是机器人用户名;请用人类发件人的 ID。向导接受 @username 并在可能时解析为数字 ID。

查找你的 Telegram 用户 ID

更安全(无需第三方机器人):

  1. 启动网关并私聊你的机器人。
  2. 运行 moltbot logs --follow,查找 from.id

替代(官方 Bot API):

  1. 私聊你的机器人。
  2. 用机器人 token 拉取 updates 并读取 message.from.id
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 中列出具体群组。

Long-polling 与 webhook

  • 默认:long-polling(无需公网 URL)。
  • Webhook 模式:设置 channels.telegram.webhookUrl(可选 channels.telegram.webhookSecret + channels.telegram.webhookPath)。
    • 本地监听默认绑定 0.0.0.0:8787,提供 POST /telegram-webhook
    • 若公网 URL 不同,使用反向代理并将 channels.telegram.webhookUrl 指向公网端点。

回复主题

Telegram 支持通过标签进行可选主题回复:

  • [[reply_to_current]] — 回复触发该轮的消息。
  • [[reply_to:<id>]] — 回复上下文/历史中的指定消息 id。

channels.telegram.replyToMode 控制:first(默认)、alloff

语音消息(语音与文件)

Telegram 区分语音消息(圆泡)与音频文件(元数据卡片)。Moltbot 默认按音频文件处理以保持兼容。若希望 agent 回复以语音消息泡显示,在回复中任意位置加入标签:[[audio_as_voice]] — 以语音消息而非文件发送音频。该标签会从发出的文本中移除,其他频道会忽略。message 工具发送时,对兼容语音的 media URL 设置 asVoice: true(有 media 时 message 可选):

{ "action": "send", "channel": "telegram", "to": "123456789", "media": "https://example.com/voice.ogg", "asVoice": true }

贴纸

Moltbot 支持接收与发送 Telegram 贴纸,并带智能缓存。

接收贴纸

用户发送贴纸时,Moltbot 按贴纸类型处理:

  • 静态贴纸(WEBP):下载并通过视觉模型处理。贴纸在消息内容中以 <media:sticker> 占位符出现。
  • 动图贴纸(TGS):跳过(Lottie 格式不支持处理)。
  • 视频贴纸(WEBM):跳过(不支持该视频格式处理)。

接收贴纸时可用的模板上下文字段:Sticker — 对象,含 emojisetNamefileIdfileUniqueIdcachedDescription(有缓存时)。

贴纸缓存

贴纸经 AI 视觉能力生成描述。同一贴纸常被重复发送,Moltbot 会缓存这些描述以减少重复 API 调用。流程:首次遇到时发送贴纸图片给 AI 做视觉分析并生成描述;描述与 file ID、emoji、set name 一起存入缓存;再次遇到同一贴纸时直接使用缓存描述,不再发图给 AI。缓存位置~/.clawdbot/telegram/sticker-cache.json

发送贴纸

Agent 可通过 stickersticker-search 动作发送与搜索贴纸。默认关闭,需在配置中启用:channels.telegram.actions.sticker: true。发送贴纸时 fileId 必填(来自接收时的 Sticker.fileIdsticker-search 结果);可选 replyTothreadId。搜索贴纸:agent 可按描述、emoji 或 set name 搜索缓存贴纸,使用 sticker-search 动作。

流式(草稿)

Telegram 可在 agent 生成回复时流式显示草稿泡。Moltbot 使用 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: 200maxChars: 800breakPreference: "paragraph"(受 channels.telegram.textChunkLimit 限制)

说明:草稿流式与块流式(频道消息)是分开的。块流式默认关闭,若希望提前发 Telegram 消息而非草稿更新,需设 channels.telegram.blockStreaming: true

推理流式(仅 Telegram)/reasoning stream 会在生成回复时将推理内容流式写入草稿泡,最终只发送不含推理的答案。若 channels.telegram.streamModeoff,推理流式会被关闭。更多说明见 流式与分块

重试策略

出站 Telegram API 在瞬时网络/429 错误时会指数退避与抖动重试。通过 channels.telegram.retry 配置。见 重试策略

Agent 工具(消息 + 表态)

  • 工具:telegram,动作 sendMessagetocontent,可选 mediaUrlreplyToMessageIdmessageThreadId)。
  • 工具:telegram,动作 reactchatIdmessageIdemoji)。
  • 工具:telegram,动作 deleteMessagechatIdmessageId)。
  • 表态移除语义见 表态
  • 工具门控:channels.telegram.actions.reactionschannels.telegram.actions.sendMessagechannels.telegram.actions.deleteMessage(默认启用),以及 channels.telegram.actions.sticker(默认禁用)。

表态通知

Telegram 表态以独立的 message_reaction 事件到达,而非消息 payload 中的属性。用户添加表态时,Moltbot:1) 从 Telegram API 收到 message_reaction 更新;2) 转为格式为 "Telegram reaction added: {emoji} by {user} on msg {id}"系统事件;3) 使用与普通消息相同的会话键将系统事件入队;4) 当下一条消息到达该会话时,系统事件被取出并追加到 agent 上下文前。Agent 在会话历史中看到的是系统通知形式的表态,而非消息元数据。配置:channels.telegram.reactionNotifications 控制哪些表态触发通知(offown(默认)、all);channels.telegram.reactionLevel 控制 agent 表态能力(offack(默认)、minimalextensive)。

投递目标(CLI/定时任务)

  • 使用 chat id(123456789)或用户名(@name)作为目标。
  • 示例:moltbot message send --channel telegram --target 123456789 --message "hi"

故障排查

机器人在群组中不回复非 @ 消息:若设置了 channels.telegram.groups.*.requireMention=false,Telegram Bot API 的隐私模式必须关闭(BotFather:/setprivacyDisable,然后从群组移除并重新添加机器人)。moltbot channels status 在配置期望未 @ 的群组消息时会显示警告。快速测试:/activation always(仅会话级;持久化需用配置)。

机器人完全收不到群组消息:若设置了 channels.telegram.groups,群组必须在列表中或使用 "*";在 @BotFather 中检查「Group Privacy」应为 OFF;确认机器人确实是成员;查看网关日志 moltbot logs --follow(查找 “skipping group message”)。

机器人回复 @ 但不响应 /activation always/activation 只更新会话状态,不会写入配置;要持久生效,请在 channels.telegram.groups 中为该群组添加 requireMention: false

/status 等命令不工作:确认你的 Telegram 用户 ID 已授权(通过配对或 channels.telegram.allowFrom);即使 groupPolicy: "open" 的群组中,命令也需要授权。

Node 22+ 下 long-polling 立即中止:Node 22+ 对 AbortSignal 更严格;可升级到规范化 abort 信号的 Moltbot 版本,或在能升级前用 Node 20 运行网关。

机器人启动后静默不再响应(或日志 HttpError: Network request ... failed:部分主机会优先将 api.telegram.org 解析为 IPv6。若服务器没有可用 IPv6 出口,grammY 可能卡在仅 IPv6 请求。解决:启用 IPv6 出口强制对 api.telegram.org 使用 IPv4(例如在 /etc/hosts 中添加 IPv4 A 记录,或在系统 DNS 中优先 IPv4),然后重启网关。快速检查:dig +short api.telegram.org Adig +short api.telegram.org AAAA 确认 DNS 返回结果。

配置参考(Telegram)

完整配置见 配置。本频道选项包括:channels.telegram.enabledbotTokentokenFiledmPolicyallowFromgroupPolicygroupAllowFromgroups(含 requireMentionskillsallowFromsystemPromptenabledtopics.<threadId>.*)、capabilities.inlineButtonsreplyToModetextChunkLimitchunkModelinkPreviewstreamModemediaMaxMbretrynetwork.autoSelectFamilyproxywebhookUrlwebhookSecretwebhookPathactions.reactionsactions.sendMessageactions.deleteMessageactions.stickerreactionNotificationsreactionLevel。相关全局选项:agents.list[].groupChat.mentionPatternsmessages.groupChat.mentionPatternscommands.nativecommands.textcommands.useAccessGroups(可被 channels.telegram.commands.native 覆盖)、messages.responsePrefixmessages.ackReactionmessages.ackReactionScopemessages.removeAckAfterReply

最后更新于: