Telegram 设置#
Hermes Agent 与 Telegram 集成,作为功能完整的对话机器人。连接后,你可以从任何设备与 Agent 聊天、发送自动转录的语音备忘录、接收定时任务结果,并在群聊中使用 Agent。该集成基于 python-telegram-bot 构建,支持文本、语音、图片和文件附件。第一步:通过 BotFather 创建机器人#
每个 Telegram 机器人都需要由 @BotFather(Telegram 官方机器人管理工具)颁发的 API token(令牌)。3.
选择一个显示名称(例如 "Hermes Agent")——可以是任意名称
4.
选择一个用户名——必须唯一且以 bot 结尾(例如 my_hermes_bot)
5.
BotFather 会回复你的 API token,格式如下:
123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
请妥善保管你的机器人 token。任何持有该 token 的人都可以控制你的机器人。如果泄露,请立即通过 BotFather 的 /revoke 命令撤销。
第二步:自定义机器人(可选)#
以下 BotFather 命令可改善用户体验。向 @BotFather 发送:| 命令 | 用途 |
|---|
/setdescription | 用户开始聊天前显示的"这个机器人能做什么?"文本 |
/setabouttext | 机器人个人资料页面上的简短文字 |
/setuserpic | 为机器人上传头像 |
/setcommands | 定义命令菜单(聊天中的 / 按钮) |
/setprivacy | 控制机器人是否能看到所有群消息(见第三步) |
对于 /setcommands,一个实用的初始命令集:help - Show help information
new - Start a new conversation
sethome - Set this chat as the home channel
第三步:隐私模式(群组关键设置)#
Telegram 机器人有一个隐私模式,默认启用。这是在群组中使用机器人时最常见的困惑来源。如何关闭隐私模式#
4.
进入 Bot Settings → Group Privacy → Turn off
更改隐私设置后,必须将机器人从所有群组中移除并重新添加。 Telegram 在机器人加入群组时会缓存隐私状态,在机器人被移除并重新添加之前不会更新。
禁用隐私模式的替代方案:将机器人提升为群组管理员。管理员机器人无论隐私设置如何都能接收所有消息,这样就无需切换全局隐私模式。
观察群组消息但不自动回复#
对于 OpenClaw/Yuanbao 风格的群组行为,可配置 Telegram 使机器人能看到普通群组消息,但只在被直接触发时响应:启用此模式后,来自明确白名单聊天/话题的未提及群组消息会作为观察上下文追加到共享聊天/话题会话记录中,但不会触发 Agent。allowed_chats 控制机器人在哪里响应;group_allowed_chats 授权用于观察上下文的共享群组会话,因此在此模式下使用相同的聊天 ID。同一白名单聊天/话题中后续的 @botname 提及、对机器人的回复或配置的提及模式可以使用该观察上下文。触发消息还会标记 [nickname|user_id],并获得每轮安全 prompt(提示词),使模型将之前观察到的内容视为上下文而非发给机器人的指令。这需要 Telegram 将普通群组消息传递给 gateway,因此请按上述说明禁用 BotFather 隐私模式或将机器人提升为群组管理员。第四步:获取你的用户 ID#
Hermes Agent 使用 Telegram 数字用户 ID 来控制访问权限。你的用户 ID 不是你的用户名——它是一个类似 123456789 的数字。第五步:配置 Hermes#
方式 A:交互式设置(推荐)#
在提示时选择 Telegram。向导会询问你的机器人 token 和允许的用户 ID,然后为你写入配置。方式 B:手动配置#
启动 Gateway#
机器人应在几秒内上线。在 Telegram 上向它发送消息以验证。从 Docker 后端终端发送生成的文件#
如果你的终端后端是 docker,请注意 Telegram 附件由 gateway 进程发送,而非从容器内部发送。这意味着最终的 MEDIA:/... 路径必须在运行 gateway 的宿主机上可读。Agent 在 Docker 内将文件写入 /workspace/report.txt
模型发出 MEDIA:/workspace/report.txt
Telegram 投递失败,因为 /workspace/report.txt 只存在于容器内,而非宿主机上
在 Docker 内将文件写入 /output/...
在 MEDIA: 中使用宿主机可见的路径,例如:
MEDIA:/home/user/.hermes/cache/documents/report.txt
如果你已有 docker_volumes: 部分,将新挂载添加到同一列表中。YAML 重复键会静默覆盖之前的值。支持的 MEDIA: 文件扩展名#
gateway 从 Agent 回复中提取 MEDIA:/path/to/file 标签,并将引用的文件作为平台原生附件发送。所有 gateway 平台支持的扩展名:| 类别 | 扩展名 |
|---|
| 图片 | png, jpg, jpeg, gif, webp, bmp, tiff, svg |
| 音频 | mp3, wav, ogg, m4a, opus, flac, aac |
| 视频 | mp4, mov, webm, mkv, avi |
| 文档 | pdf, txt, md, csv, json, xml, html, yaml, yml, log |
| Office | docx, xlsx, pptx, odt, ods, odp |
| 压缩包 | zip, rar, 7z, tar, gz, bz2 |
| 书籍/安装包 | epub, apk, ipa |
此列表中的任何内容都会在支持原生附件的平台(Telegram、Discord、Signal、Slack、WhatsApp、飞书、Matrix 等)上作为原生附件投递;在不支持原生附件的平台上,会回退为链接或纯文本指示。加粗类别是最近几个版本新增的——如果你之前依赖模型输出 here is the file: /path/to/report.docx,请改用 MEDIA:/path/to/report.docx 以实现原生投递。Webhook 模式#
默认情况下,Hermes 使用长轮询连接 Telegram——gateway 向 Telegram 服务器发出出站请求以获取新更新。这对本地和常驻部署效果良好。对于云部署(Fly.io、Railway、Render 等),webhook 模式更具成本效益。这些平台可以在入站 HTTP 流量时自动唤醒休眠的机器,但无法通过出站连接唤醒。由于轮询是出站的,轮询机器 人永远无法休眠。Webhook 模式反转了方向——Telegram 将更新推送到你的机器人 HTTPS URL,从而实现空闲时休眠的部署。 | 轮询(默认) | Webhook |
|---|
| 方向 | Gateway → Telegram(出站) | Telegram → Gateway(入站) |
| 适用场景 | 本地、常驻服务器 | 支持自动唤醒的云平台 |
| 设置 | 无需额外配置 | 设置 TELEGRAM_WEBHOOK_URL |
| 空闲成本 | 机器必须保持运行 | 机器可在消息间隙休眠 |
| 变量 | 是否必填 | 说明 |
|---|
TELEGRAM_WEBHOOK_URL | 是 | Telegram 发送更新的公开 HTTPS URL。URL 路径会自动提取(例如上例中的 /telegram)。 |
TELEGRAM_WEBHOOK_SECRET | 是(设置 TELEGRAM_WEBHOOK_URL 时) | Telegram 在每个 webhook 请求中回显的密钥 token,用于验证。gateway 在没有该密钥时拒绝启动——参见 GHSA-3vpc-7q5r-276h。使用 openssl rand -hex 32 生成。 |
TELEGRAM_WEBHOOK_PORT | 否 | webhook 服务器监听的本地端口(默认:8443)。 |
设置 TELEGRAM_WEBHOOK_URL 后,gateway 会启动 HTTP webhook 服务器而非轮询。未设置时使用轮询模式——与之前版本行为无变化。云部署示例(Fly.io)#
2.
在 fly.toml 中暴露 webhook 端口:
[[services]]
internal_port = 8443
protocol = "tcp"
[[services.ports]]
handlers = ["tls", "http"]
port = 443
gateway 日志应显示:[telegram] Connected to Telegram (webhook mode)。代理支持#
如果 Telegram 的 API 被封锁,或你需要通过代理路由流量,可设置 Telegram 专用代理 URL。此设置优先于通用的 HTTPS_PROXY / HTTP_PROXY 环境变量。支持的协议:http://、https://、socks5://。代理同时适用于主 Telegram 连接和备用 IP 传输。如果未设置 Telegram 专用代理,gateway 会回退到 HTTPS_PROXY / HTTP_PROXY / ALL_PROXY(或 macOS 系统代理自动检测)。主频道#
在任意 Telegram 聊天(私聊或群组)中使用 /sethome 命令,将其指定为主频道。定时任务(cron 任务)的结果会投递到此频道。也可以在 ~/.hermes/.env 中手动设置:群聊 ID 是负数(例如 -1001234567890)。你的个人私聊 ID 与你的用户 ID 相同。
话题模式下的 Cron 投递#
如果你在机器人私聊中启用了话题模式,投递到根聊天的 cron 消息会落入仅限系统的大厅——在那里回复不会开启会话,你会看到"主聊天保留给系统命令"的提示。创建一个专用论坛话题(例 如 Cron)并设置:TELEGRAM_CRON_THREAD_ID 仅针对 cron 投递覆盖 TELEGRAM_HOME_CHANNEL_THREAD_ID。在该话题中的回复会继续该话题的现有会话。语音消息#
接收语音(语音转文字)#
你在 Telegram 上发送的语音消息会由 Hermes 配置的 STT(语音转文字)提供商自动转录,并作为文本注入对话。local 在运行 Hermes 的机器上使用 faster-whisper— —无需 API 密钥
groq 使用 Groq Whisper,需要 GROQ_API_KEY
openai 使用 OpenAI Whisper,需要 VOICE_TOOLS_OPENAI_KEY
跳过 STT:将原始音频文件传递给 Agent#
如果你希望由 Agent 本身处理音频——用于说话人分离、自定义转录工具或仅存档录音——请在 ~/.hermes/config.yaml 中设置 stt.enabled: false:禁用 STT 后,gateway 仍会将语音/音频附件下载到 Hermes 的音频缓存中,但不进行转录。Agent 收到的消息带有如下标记:[The user sent a voice message: /home/<user>/.hermes/cache/audio/<hash>.ogg]
你的工具或技能可以直接读取该路径(例如,将其传递给本地说话人分离管道、更丰富的转录模型,或上传到长期存储)。文件扩展名反映 Telegram 投递的原始格式(语音备忘录为 .ogg,音频附件为 .mp3/.m4a 等)。这与下方的本地 Bot API 服务器部分配合使用效果极佳,该功能将 Telegram 的 20MB getFile 上限提升至 2GB——当你需要处理超过几分钟的录音时非常有用。发送语音(文字转语音)#
当 Agent 通过 TTS 生成音频时,它会作为 Telegram 原生语音气泡投递——即圆形、可内联播放的那种。OpenAI 和 ElevenLabs 原生生成 Opus——无需额外设置
Edge TTS(默认免费提供商)输出 MP3,需要 ffmpeg 转换为 Opus:
没有 ffmpeg,Edge TTS 音频会作为普通音频文件发送(仍可播放,但使用矩形播放器而非语音气泡)。在 config.yaml 的 tts.provider 键下配置 TTS 提供商。通过本地 Bot API 服务器处理大文件(>20MB)#
Telegram 的公共 Bot API 将 getFile 下载限制为 20 MB,因此任何超过该大小的语音备忘录、音频文件、视频或文档都会被 Hermes 静默拒绝并回复"文件过大"。官方解决方案是运行本地 telegram-bot-api 守护进程——与 Telegram 使用的相同服务器软件,但运行在你的网络上。本地服务器将文件上限提升至 2 GB,Hermes 在检测到自定义 base_url 配置时会自动解除自身内部限制。存档原始音频用于离线管道,如说话人分离、对齐或训练数据
第一步:获取 Telegram API 凭据#
本地服务器直接与 Telegram 的 MTProto 层通信(而非公共 Bot API),因此需要 MTProto 凭据:3.
复制 api_id 和 api_hash——两者都是必需的。
第二步:运行 telegram-bot-api 服务器#
本地 Bot API 服务器在 URL 路径中接受你的机器人 token(例如 /bot<TOKEN>/getMe),无额外认证。任何能访问该端口的人都可以完全控制你的机器人——读取它能看到的每条消息、以它的身份发送消息等。将容器绑 定到 127.0.0.1,并/或在私有网络上用反向代理保护。切勿将 8081 端口暴露到公网。
第三步:将机器人从公共 API 登出(一次性操作)#
一个机器人在同一时间只能在一个 Bot API 服务器上活跃。如果你的机器人之前已在 api.telegram.org 上运行(几乎可以肯定),你必须先在那里明确登出,本地服务器才会接受它:这是一次性迁移步骤——不需要在每次重启时重复。logOut 后收到的消息会通过新服务器投递。验证本地服务器能代表机器人与 Telegram 通信:第四步:将 Hermes 指向本地服务器#
在 ~/.hermes/config.yaml 的 platforms.telegram.extra 下添加 URL::::caution 使用 platforms.telegram.extra,而非 telegram.extra
目前只有 platforms.<name>.extra 形式会深度合并到平台配置中。直接放在顶层 telegram.extra 块下的键会被静默丢弃。
:::基于本地服务器构建 python-telegram-bot 客户端
自动将内部文档/音频大小上限从 20 MB 提升至 2 GB
在"文件过大"错误消息中报告当前限制(Maximum: 2048 MB.),以便清楚了解所处模式
第五步:local_mode——磁盘上的文件访问#
1.
不使用 --local(默认):文件通过 HTTP 在 /file/bot<TOKEN>/<path> 提供,与公共 Bot API 相同。20MB 上限仍然有效。仅作为网络修复使用(例如 api.telegram.org 不可达但你可以自托管);这不是你想要的大小提升方式。
2.
使用 --local(通过上方的 TELEGRAM_LOCAL=1 设置):文件写入服务器文件系统,getFile 响应返回绝对路径而非 HTTP URL。20MB 上限被解除。Hermes 必须从磁盘读取字节,而非通过 HTTP。
要使磁盘读取路径正常工作,请在上方配置中设置 local_mode: true,并确保 Hermes 进程能读取服务器返回 的路径。两种场景:同一台机器——telegram-bot-api 和 Hermes 运行在同一宿主机上。将数据卷绑定挂载到 Hermes 可读的目录(例如 /var/lib/telegram-bot-api),并确保文件所有权匹配。容器会降权到其内部的 telegram-bot-api 用户(uid 因镜像而异);最简单的解决方法是在 compose 服务中添加 user: "<UID>:<GID>",使文件归 Hermes 已运行的 uid 所有。
不同机器——机器人服务器运行在一台主机上(例如 NAS、独立虚拟机),Hermes 运行在另一台上。服务器的数据目录必须以服务器报告的相同绝对路径(通常为 /var/lib/telegram-bot-api)共享给 Hermes 机器。NFS 效果良好;如果你不想在文件系统级别处理 uid 不匹配问题,带 uid= 挂载重映射的 CIFS/SMB 更友好。
如果设置了 local_mode: true 但 Hermes 无法 stat 返回的文件路径(权限问题或挂载错误),python-telegram-bot 会静默回退到对本地服务器的 HTTP getFile——在 --local 模式下会响应 404 Not Found。症状在 gateway.log 中表现为:[Telegram] Failed to cache voice: Not Found
telegram.error.InvalidToken: Not Found
如果你看到这个,说明大小提升正在工作,但文件共享没有。以 gateway 运行用户的身份从 Hermes 宿主机执行 ls -la /var/lib/telegram-bot-api/<TOKEN>/voice/,并确认单个文件可以 cat 而不出现权限错误。第六步:测试#
向机器人发送一个超过 20 MB 的语音备忘录或音频文件。查看 gateway 日志:你应该看到 [Telegram] Cached user voice at /home/<user>/.hermes/cache/audio/... 行,且没有"文件过大"拒绝。结合上方的 stt.enabled: false,原始音频文件的路径会出现在 Agent 的入站消息中,供下游处理使用。群聊使用#
Hermes Agent 在 Telegram 群聊中工作时有几点注意事项:TELEGRAM_ALLOWED_USERS 仍然适用——即使在群组中,也只有授权用户才能触发机器人
你可以通过 telegram.require_mention: true 阻止机器人响应普通群组消息
设置 telegram.require_mention: true 时,以下情况的群组消息会被接受:/command@botusername(包含机器人名称的 Telegram 机器人菜单命令形式)
与 telegram.mention_patterns 中配置的正则唤醒词匹配的内容
在有多个 Hermes 机器人的群组中,telegram.exclusive_bot_mentions 使路由具有确定性。当消息明确提及一个或多个 Telegram 机器人用户名时,只有被提及的机器人配置文件处理该消息;其他 Hermes 机器人在回复和唤醒词回退运行之前忽略它。此功能默认启用。
使用 telegram.ignored_threads 使 Hermes 在特定 Telegram 论坛话题中保持沉默,即使群组本来允许自由响应或提及触发的回复
如果 telegram.require_mention 未设置或为 false,Hermes 保持之前的开放群组行为,响应它能看到的普通群组消息
同一群组中的多个 Hermes 机器人#
如果你在同一个 Telegram 群组中运行多个 Hermes 配置文件,请为每个配置文件创建一个 Telegram 机器人 token,并为每个配置文件启动一个 gateway。不要在多个运行中的 gateway 中重用同一个机器人 token;Telegram 会拒绝对同一 token 的并发轮询。使用此设置, 群组消息如 @research_bot @ops_bot summarize this 只由 research_bot 和 ops_bot 处理。群组中的其他 Hermes 机器人保持沉默,即使该消息是对其早期消息的回复或与共享唤醒词匹配。仅在旧版群组中(明确提及不应覆盖回复和唤醒词触发)才将 exclusive_bot_mentions: false。要运行多个配置文件,每个配置文件运行一次 gateway 命令。例如:对于小型固定机器人集群,使用 shell 循环或脚本,对默认配置文件调用 hermes gateway <action>,对每个命名配置文件调用 hermes -p <profile> gateway <action>。这比假设单个进程级命令在每个服务管理器上控制所有命名配置文件更可靠。故障排除:私聊正常但群组无响应#
如果机器人在私聊中响应但在群 组中保持沉默,请按顺序检查以下关卡:1.
Telegram 投递: 关闭 BotFather 隐私模式、将机器人提升为管理员,或直接提及机器人。Hermes 无法响应 Telegram 从未投递给机器人的群组消息。
2.
更改隐私后重新加入: 更改 BotFather 隐私设置后,将机器人从群组中移除并重新添加。Telegram 可能对现有成员保留旧的投递行为。
3.
Hermes 授权: 确保发送者在 TELEGRAM_ALLOWED_USERS 或 TELEGRAM_GROUP_ALLOWED_USERS 中,或通过 TELEGRAM_GROUP_ALLOWED_CHATS 允许该群聊。
4.
提及过滤器: 如果设置了 telegram.require_mention: true,普通群组消息会被忽略,除非消息是斜杠命令、对机器人的回复、@botusername 提及或配置的 mention_patterns 匹配。
5.
多机器人路由: 如果群组包含多个机器人,确保每个 Hermes 配置文件使用唯一的机器人 token,并保持 exclusive_bot_mentions 启用,除非你有意使用旧版共享触发行为。
Telegram 群组和超级群组的负数聊天 ID 是正常的。如果你使用聊天范围的授权,请将这些 ID 放在 TELEGRAM_GROUP_ALLOWED_CHATS 中,而非发送者用户白名单中。群组触发配置示例#
将以下内容添加到 ~/.hermes/config.yaml:此示例允许所有常规直接触发,以及以 chompy 开头的消息,即使它们不使用 @mention。
Telegram 话题 31 和 42 中的消息在提及和自由响应检查运行之前始终被忽略。mention_patterns 说明#
无效的正则表达式模式会在 gateway 日志中记录警告并被忽略,而不会导致机器人崩溃
私聊话题(Bot API 9.4)#
Telegram Bot API 9.4(2026 年 2 月)引入了私聊话题——机器人可以直接在一对一私聊中创建论坛风格的话题线程,无需超级群组。这让你可以在与 Hermes 的现有私聊中运行多个隔离的工作区。使用场景#
如果你同时处理多个长期项目,话题可以保持各自上下文独立:话题"Website" — 处理你的生产 Web 服务
每个话题都有自己的对话会话、历史记录和上下文——完全相互隔离。配置