跳到主要内容

Telegram 配置

Hermes Agent 与 Telegram 集成,作为功能完整的对话机器人。连接成功后,您可从任意设备与您的代理聊天,发送语音备忘录(自动转录)、接收定时任务结果,并在群组聊天中使用该代理。该集成基于 python-telegram-bot,支持文本、语音、图片和文件附件。

第一步:通过 BotFather 创建机器人

每个 Telegram 机器人都需要由 @BotFather(Telegram 官方机器人管理工具)颁发的 API 密钥。

  1. 打开 Telegram 并搜索 @BotFather,或访问 t.me/BotFather
  2. 发送 /newbot
  3. 选择一个 显示名称(例如:“Hermes Agent”)—— 可以是任意内容
  4. 选择一个 用户名 —— 必须唯一且以 bot 结尾(例如:my_hermes_bot
  5. BotFather 会回复您的 API 密钥。格式如下:
123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
注意

请保密您的机器人密钥。任何持有此密钥的人都可以控制您的机器人。如果密钥泄露,请立即通过 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 机器人默认启用 隐私模式。这是在群组中使用机器人时最常见的困惑来源。

当隐私模式开启时,您的机器人只能看到:

  • / 开头的命令消息
  • 直接回复机器人自身消息的消息
  • 服务消息(成员加入/离开、置顶消息等)
  • 机器人是管理员的频道中的消息

当隐私模式关闭时,机器人将接收群组中的每一条消息。

如何关闭隐私模式

  1. @BotFather 发送消息
  2. 发送 /mybots
  3. 选择您的机器人
  4. 进入 Bot 设置 → 群组隐私 → 关闭
注意

在更改隐私设置后,您必须从群组中移除并重新添加机器人。Telegram 在机器人加入群组时会缓存其隐私状态,除非机器人被移除并重新添加,否则不会更新。

提示

替代关闭隐私模式的方法:将机器人提升为 群组管理员。管理员机器人无论隐私设置如何,都会收到所有消息,从而避免需要切换全局隐私模式。

第四步:查找您的用户 ID

Hermes Agent 使用数字型 Telegram 用户 ID 来控制访问权限。您的用户 ID 不是您的用户名——而是一个数字,如 123456789

方法一(推荐):@userinfobot 发送消息——它会立即回复您的用户 ID。

方法二:@get_id_bot 发送消息——另一个可靠的选项。

请保存该数字,您将在下一步需要它。

第五步:配置 Hermes

hermes gateway setup

在提示时选择 Telegram。向导将要求您输入机器人密钥和允许的用户 ID,然后为您生成配置文件。

选项 B:手动配置

将以下内容添加到 ~/.hermes/.env 文件中:

TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
TELEGRAM_ALLOWED_USERS=123456789 # Comma-separated for multiple users

启动网关

hermes gateway

机器人应在几秒内上线。请在 Telegram 中向其发送一条消息以验证。

Webhook 模式

默认情况下,Hermes 使用 长轮询(long polling) 方式连接 Telegram —— 网关主动向 Telegram 服务器发起请求以获取新消息。这种方式适用于本地部署或始终在线的服务器。

对于 云部署(Fly.io、Railway、Render 等),Webhook 模式 更具成本效益。这些平台可以在收到 HTTP 入站流量时自动唤醒休眠的机器,但无法通过出站连接唤醒。由于轮询是出站的,使用轮询的机器人永远无法休眠。Webhook 模式则反转了方向——Telegram 将更新推送到您机器人的 HTTPS 地址,从而实现“空闲时休眠”的部署。

轮询(默认)Webhook
方向网关 → Telegram(出站)Telegram → 网关(入站)
适用场景本地、始终在线的服务器具备自动唤醒功能的云平台
配置无需额外配置设置 TELEGRAM_WEBHOOK_URL
空闲成本机器必须持续运行机器可在消息之间休眠

配置

将以下内容添加到 ~/.hermes/.env 文件中:

TELEGRAM_WEBHOOK_URL=https://my-app.fly.dev/telegram
# TELEGRAM_WEBHOOK_PORT=8443 # optional, default 8443
# TELEGRAM_WEBHOOK_SECRET=mysecret # optional, recommended
变量必填描述
TELEGRAM_WEBHOOK_URLTelegram 将更新发送到的公共 HTTPS URL。URL 路径会自动提取(例如,上例中的 /telegram)。
TELEGRAM_WEBHOOK_PORTWebhook 服务器监听的本地端口(默认:8443)。
TELEGRAM_WEBHOOK_SECRET用于验证更新确实来自 Telegram 的密钥令牌。强烈建议在生产部署中使用

当设置了 TELEGRAM_WEBHOOK_URL 时,网关将启动一个 HTTP Webhook 服务器,而不是轮询模式。若未设置,则使用轮询模式——行为与之前版本保持一致。

云部署示例(Fly.io)

  1. 将环境变量添加到你的 Fly.io 应用密钥中:
fly secrets set TELEGRAM_WEBHOOK_URL=https://my-app.fly.dev/telegram
fly secrets set TELEGRAM_WEBHOOK_SECRET=$(openssl rand -hex 32)
  1. fly.toml 中暴露 Webhook 端口:
[[services]]
internal_port = 8443
protocol = "tcp"

[[services.ports]]
handlers = ["tls", "http"]
port = 443
  1. 部署:
fly deploy

网关日志应显示:[telegram] Connected to Telegram (webhook mode)

主频道

在任意 Telegram 聊天(私聊或群组)中使用 /sethome 命令,将该聊天设为 主频道。计划任务(cron 作业)的结果将发送至此频道。

你也可以在 ~/.hermes/.env 中手动设置:

TELEGRAM_HOME_CHANNEL=-1001234567890
TELEGRAM_HOME_CHANNEL_NAME="My Notes"
提示

群组聊天 ID 为负数(例如:-1001234567890)。你的个人私聊聊天 ID 与你的用户 ID 相同。

语音消息

入站语音(语音转文字)

你在 Telegram 中发送的语音消息将由 Hermes 配置的 STT 提供商自动转录,并作为文本注入到对话中。

  • local 使用运行 Hermes 的机器上的 faster-whisper —— 无需 API 密钥
  • groq 使用 Groq Whisper,需要 GROQ_API_KEY
  • openai 使用 OpenAI Whisper,需要 VOICE_TOOLS_OPENAI_KEY

出站语音(文字转语音)

当代理生成音频时,将以原生 Telegram 语音气泡 形式发送——即圆形的、可内联播放的语音。

  • OpenAI 和 ElevenLabs 原生输出 Opus —— 无需额外配置
  • Edge TTS(默认免费提供者)输出 MP3,需要 ffmpeg 转换为 Opus:
# Ubuntu/Debian
sudo apt install ffmpeg

# macOS
brew install ffmpeg

若无 ffmpeg,Edge TTS 音频将以普通音频文件形式发送(仍可播放,但使用矩形播放器而非语音气泡)。

config.yaml 中通过 tts.provider 键配置 TTS 提供商。

群组聊天使用

Hermes Agent 可在 Telegram 群组聊天中使用,但需注意以下几点:

  • 隐私模式 决定了机器人能看到哪些消息(参见 步骤 3
  • TELEGRAM_ALLOWED_USERS 仍然适用——即使在群组中,也只有授权用户才能触发机器人
  • 你可以通过设置 telegram.require_mention: true 防止机器人对普通群组闲聊做出响应
  • telegram.require_mention: true 时,群组消息仅在以下情况被接受:
    • 以斜杠命令开头
    • 回复机器人的一条消息
    • 包含 @botusername 的提及
    • 与你在 telegram.mention_patterns 中配置的正则唤醒词匹配
  • telegram.require_mention 未设置或为 false,Hermes 保持之前的开放群组行为,对它能看到的普通群组消息做出响应

群组触发配置示例

将以下内容添加到 ~/.hermes/config.yaml

telegram:
require_mention: true
mention_patterns:
- "^\\s*chompy\\b"

此示例允许所有常规直接触发方式,以及以 chompy 开头的消息,即使未使用 @mention 也能触发。

关于 mention_patterns 的说明

  • 模式使用 Python 正则表达式
  • 匹配不区分大小写
  • 模式会同时检查文本消息和媒体标题
  • 无效的正则表达式模式会被忽略,并在网关日志中发出警告,而不会导致机器人崩溃
  • 若希望模式仅匹配消息开头,需使用 ^ 进行锚定

私聊话题(Bot API 9.4)

Telegram Bot API 9.4(2026 年 2 月发布)引入了 私聊话题——机器人可在一对一私聊中直接创建论坛风格的话题线程,无需超级群组。这使得你可以在与 Hermes 的现有私聊中运行多个隔离的工作空间。

使用场景

如果你同时处理多个长期项目,话题可保持各自上下文独立:

  • 话题 "Website" —— 处理你的生产 Web 服务
  • 话题 "Research" —— 文献综述与论文探索
  • 话题 "General" —— 杂项任务和快速提问

每个话题都有独立的会话、历史记录和上下文——彼此完全隔离。

配置

~/.hermes/config.yaml 中的 platforms.telegram.extra.dm_topics 下添加话题:

platforms:
telegram:
extra:
dm_topics:
- chat_id: 123456789 # Your Telegram user ID
topics:
- name: General
icon_color: 7322096
- name: Website
icon_color: 9367192
- name: Research
icon_color: 16766590
skill: arxiv # Auto-load a skill in this topic

字段:

字段必填描述
name话题显示名称
icon_colorTelegram 图标颜色代码(整数)
icon_custom_emoji_id话题图标的自定义表情 ID
skill在此话题的新会话中自动加载的技能
thread_id话题创建后自动填充——请勿手动设置
  1. 在网关启动时,Hermes 会为每个尚未拥有 thread_id 的话题调用 createForumTopic
  2. thread_id 会自动保存回 config.yaml —— 后续重启将跳过 API 调用
  3. 每个话题映射到一个独立的会话密钥:agent:main:telegram:dm:{chat_id}:{thread_id}
  4. 每个话题中的消息拥有独立的对话历史、内存清空机制和上下文窗口

技能绑定

带有 skill 字段的话题在新会话启动时会自动加载该技能。其行为与在对话开头输入 /skill-name 完全相同 —— 技能内容会被注入到第一条消息中,后续消息可在对话历史中看到该内容。

例如,一个 skill: arxiv 的话题,每当其会话重置时(由于空闲超时、每日重置或手动执行 /reset),都会自动加载 arxiv 技能。

提示

通过手动调用 Telegram API 创建的话题(非配置文件中定义)会在收到 forum_topic_created 服务消息时被自动发现。你也可以在网关运行时向配置文件中添加话题 —— 它们将在下一次缓存未命中时被加载。

群组论坛话题技能绑定

启用了 话题模式(也称“论坛话题”)的超级群组已支持按话题进行会话隔离 —— 每个 thread_id 映射到独立的对话。但你可能希望在特定群组话题中收到消息时 自动加载某个技能,就像私聊话题的技能绑定一样。

使用场景

一个团队超级群组,其论坛话题用于不同工作流:

  • 工程 话题 → 自动加载 software-development 技能
  • 研究 话题 → 自动加载 arxiv 技能
  • 通用 话题 → 不加载技能,作为通用助手使用

配置

~/.hermes/config.yaml 中的 platforms.telegram.extra.group_topics 下添加话题绑定:

platforms:
telegram:
extra:
group_topics:
- chat_id: -1001234567890 # Supergroup ID
topics:
- name: Engineering
thread_id: 5
skill: software-development
- name: Research
thread_id: 12
skill: arxiv
- name: General
thread_id: 1
# No skill — general purpose

字段说明:

字段必填描述
chat_id超级群组的数字 ID(以 -100 开头的负数)
name话题的人类可读标签(仅用于信息参考)
thread_idTelegram 论坛话题 ID —— 可在 t.me/c/<group_id>/<thread_id> 链接中查看
skill在此话题的新会话中自动加载的技能

工作原理

  1. 当消息到达已映射的群组话题时,Hermes 会根据 chat_idthread_idgroup_topics 配置中查找匹配项
  2. 如果匹配项包含 skill 字段,则该技能将被自动加载到会话中 —— 与私聊话题的技能绑定行为完全一致
  3. 未设置 skill 键的话题仅获得会话隔离功能(原有行为,保持不变)
  4. 未映射的 thread_idchat_id 值将静默处理 —— 不报错,也不加载技能

与私聊话题的区别

私聊话题 (DM Topics)群组话题 (Group Topics)
配置键extra.dm_topicsextra.group_topics
话题创建Hermes 通过 API 自动创建(若 thread_id 缺失)管理员在 Telegram 界面中手动创建
thread_id创建后自动填充必须手动设置
icon_color / icon_custom_emoji_id支持不适用(由管理员控制外观)
技能绑定
会话隔离✓(论坛话题已内置此功能)
提示

要查找话题的 thread_id,请在 Telegram Web 或桌面客户端中打开该话题,查看 URL:https://t.me/c/1234567890/5 —— 最后一个数字(5)即为 thread_id。超级群组的 chat_id 是群组 ID 前缀加上 -100(例如,群组 1234567890 对应的 chat_id-1001234567890)。

新版 Bot API 功能

  • Bot API 9.4(2026 年 2 月): 私聊话题 —— 机器人可通过 createForumTopic 在一对一私聊中创建论坛话题。详见上方 私聊话题(Bot API 9.4)
  • 隐私政策: Telegram 现在要求机器人必须设置隐私政策。可通过 BotFather 使用 /setprivacy_policy 设置,否则 Telegram 可能自动生成占位符。若你的机器人面向公众,这一点尤为重要。
  • 消息流式传输: Bot API 9.x 增加了对长响应流式传输的支持,可显著改善机器人长回复的感知延迟。

交互式模型选择器

当你在 Telegram 聊天中发送 /model 且不带参数时,Hermes 会显示一个交互式内联键盘,用于切换模型:

  1. 提供方选择 —— 按钮显示每个可用提供方及其模型数量(例如:“OpenAI (15)”、“✓ Anthropic (12)” 表示当前提供方)
  2. 模型选择 —— 分页模型列表,包含 上一页/下一页 导航按钮,返回 按钮返回提供方列表,以及 取消 按钮

当前模型和提供方信息显示在顶部。所有导航操作均通过原地编辑同一消息完成(不会造成聊天混乱)。

提示

如果你知道确切的模型名称,可直接输入 /model <name> 跳过选择器。你也可以输入 /model <name> --global 以在所有会话中持久化该设置。

Webhook 模式

默认情况下,Telegram 适配器通过 长轮询 方式连接 —— 网关主动向 Telegram 服务器发起出站连接。这种方式适用于所有环境,但会保持一个持久连接。

Webhook 模式 是一种替代方案,Telegram 会通过 HTTPS 将更新推送至你的服务器。该模式非常适合 无服务器和云部署(如 Fly.io、Railway 等),在这些环境中,入站 HTTP 请求可以唤醒处于挂起状态的机器。

配置

设置 TELEGRAM_WEBHOOK_URL 环境变量以启用 webhook 模式:

# Required — your public HTTPS endpoint
TELEGRAM_WEBHOOK_URL=https://app.fly.dev/telegram

# Optional — local listen port (default: 8443)
TELEGRAM_WEBHOOK_PORT=8443

# Optional — secret token for update verification (auto-generated if not set)
TELEGRAM_WEBHOOK_SECRET=my-secret-token

或在 ~/.hermes/config.yaml 中配置:

telegram:
webhook_mode: true

当设置了 TELEGRAM_WEBHOOK_URL 后,网关将启动一个监听在 0.0.0.0:<port> 的 HTTP 服务器,并向 Telegram 注册 webhook URL。URL 路径从 webhook URL 中提取(默认为 /telegram)。

注意

Telegram 要求 webhook 端点必须使用 有效的 TLS 证书。自签名证书将被拒绝。请使用反向代理(如 nginx、Caddy)或提供 TLS 终止功能的平台(如 Fly.io、Railway、Cloudflare Tunnel)。

DNS-over-HTTPS 备用 IP

在某些受限网络中,api.telegram.org 可能解析为不可达的 IP 地址。Telegram 适配器包含一个 备用 IP 机制,可在不改变正确 TLS 主机名和 SNI 的前提下,透明地重试连接到其他 IP 地址。

工作原理

  1. 如果设置了 TELEGRAM_FALLBACK_IPS,则直接使用这些 IP。
  2. 否则,适配器会自动通过 DNS-over-HTTPS(DoH)查询 Google DNSCloudflare DNS,以发现 api.telegram.org 的备用 IP。
  3. 由 DoH 返回且与系统 DNS 结果不同的 IP 将作为备用 IP 使用。
  4. 如果 DoH 也被屏蔽,则使用一个硬编码的种子 IP(149.154.167.220)作为最后手段。
  5. 一旦某个备用 IP 成功连接,它将变为“粘性”IP —— 后续请求将直接使用该 IP,不再先尝试主路径。

配置

# Explicit fallback IPs (comma-separated)
TELEGRAM_FALLBACK_IPS=149.154.167.220,149.154.167.221

或在 ~/.hermes/config.yaml 中配置:

platforms:
telegram:
extra:
fallback_ips:
- "149.154.167.220"
提示

通常无需手动配置。通过 DoH 自动发现机制可处理大多数受限网络场景。仅当你的网络也屏蔽了 DoH 时,才需要设置 TELEGRAM_FALLBACK_IPS 环境变量。

代理支持

如果你的网络需要通过 HTTP 代理访问互联网(常见于企业环境),Telegram 适配器会自动读取标准的代理环境变量,并将所有连接通过代理路由。

支持的变量

适配器按顺序检查以下环境变量,使用第一个已设置的:

  1. HTTPS_PROXY
  2. HTTP_PROXY
  3. ALL_PROXY
  4. https_proxy / http_proxy / all_proxy(小写变体)

配置

在启动网关前设置代理环境变量:

export HTTPS_PROXY=http://proxy.example.com:8080
hermes gateway

或添加到 ~/.hermes/.env 文件中:

HTTPS_PROXY=http://proxy.example.com:8080

代理适用于主传输通道以及所有备用 IP 传输通道。无需额外的 Hermes 配置 —— 只要环境变量已设置,便会自动生效。

备注

这涵盖了 Hermes 为 Telegram 连接使用的自定义备用传输层。其他地方使用的标准 httpx 客户端已原生支持代理环境变量。

消息反应

机器人可以为消息添加表情符号反应,作为视觉处理反馈:

  • 👀:当机器人开始处理你的消息时
  • ✅:当响应成功送达时
  • ❌:处理过程中发生错误时

反应功能 默认关闭。你可以在 config.yaml 中启用:

telegram:
reactions: true

或通过环境变量启用:

TELEGRAM_REACTIONS=true
备注

与 Discord(反应为累加式)不同,Telegram 的 Bot API 在单次调用中会替换所有机器人反应。从 👀 到 ✅/❌ 的转换是原子性的 —— 你不会同时看到两者。

提示

如果机器人在群组中没有添加反应的权限,反应调用将静默失败,消息处理将继续正常进行。

故障排除

问题解决方案
机器人完全无响应验证 TELEGRAM_BOT_TOKEN 是否正确。检查 hermes gateway 日志中的错误信息。
机器人回复“未授权”你的用户 ID 不在 TELEGRAM_ALLOWED_USERS 列表中。请使用 @userinfobot 确认。
机器人忽略群组消息可能启用了隐私模式。请禁用它(步骤 3),或让机器人成为群组管理员。记得在更改隐私设置后移除并重新添加机器人。
语音消息未转录验证 STT 是否可用:安装 faster-whisper 实现本地转录,或在 ~/.hermes/.env 中设置 GROQ_API_KEY / VOICE_TOOLS_OPENAI_KEY
语音回复为文件而非气泡安装 ffmpeg(用于 Edge TTS Opus 转换)。
机器人令牌被撤销/无效通过 BotFather 的 /revoke 然后 /newbot/token 生成新令牌。更新你的 .env 文件。
Webhook 未接收更新验证 TELEGRAM_WEBHOOK_URL 是否可公开访问(使用 curl 测试)。确保你的平台/反向代理将来自 URL 端口的入站 HTTPS 流量路由到由 TELEGRAM_WEBHOOK_PORT 配置的本地监听端口(两者不必相同)。确保 SSL/TLS 已启用 —— Telegram 仅向 HTTPS URL 发送数据。检查防火墙规则。

执行审批

当代理尝试运行可能具有危险性的命令时,它会在聊天中向您请求批准:

⚠️ 此命令可能具有危险性(递归删除)。回复 "yes" 以批准。

回复 "yes"/"y" 以批准,或 "no"/"n" 以拒绝。

安全性

注意

请始终设置 TELEGRAM_ALLOWED_USERS 以限制谁可以与您的机器人交互。如果没有设置,网关将默认拒绝所有用户,作为一项安全措施。

切勿公开分享您的机器人令牌。如果令牌泄露,请立即通过 BotFather 的 /revoke 命令撤销。

如需了解更多信息,请参阅 安全性文档。您还可以使用 私信配对 来采用更动态的用户授权方式。