Section: Messaging Platforms · URL: https://hermesbible.com/docs/user-guide/messaging/telegram
Telegram 設定
Hermes Agent 與 Telegram 整合為一個功能完整的對話機器人。連線完成後,你可以從任何裝置與 Agent 對話、傳送語音訊息並自動轉錄文字、接收排程任務的結果,還能在群組聊天中使用 Agent。此整合基於 python-telegram-bot,支援文字、語音、圖片和檔案附件。
步驟 1:透過 BotFather 建立機器人
每個 Telegram 機器人都需要一組由 @BotFather(Telegram 官方的機器人管理工具)發行的 API token。
- 開啟 Telegram 並搜尋 @BotFather,或造訪 t.me/BotFather
- 傳送
/newbot - 選擇一個顯示名稱(例如 "Hermes Agent")——可以是任何名字
- 選擇一個使用者名稱——必須是唯一的,且以
bot結尾(例如my_hermes_bot) - BotFather 會回覆你的 API token。格式如下:
123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
WARNING
請妥善保管你的 bot token。任何取得此 token 的人都能控制你的機器人。如果 token 洩露,請立即透過 BotFather 的
/revoke指令撤銷它。
步驟 2:自訂你的機器人(選用)
以下 BotFather 指令可以改善使用者體驗。向 @BotFather 傳送以下指令:
| 指令 | 用途 |
|---|---|
/setdescription | 使用者開始聊天前顯示的「這個機器人能做什麼?」說明文字 |
/setabouttext | 機器人個人頁面上的簡短描述 |
/setuserpic | 上傳機器人的頭像 |
/setcommands | 定義指令選單(聊天中的 / 按鈕) |
/setprivacy | 控制機器人是否能看到所有群組訊息(詳見步驟 3) |
TIP
建議使用
/setcommands設定以下基本指令:help - Show help information new - Start a new conversation sethome - Set this chat as the home channel
步驟 3:隱私模式(群組使用時至關重要)
Telegram 機器人預設啟用隱私模式。這是使用機器人在群組中時最常見的困惑來源。
啟用隱私模式時,你的機器人只能看到:
- 以
/指令開頭的訊息 - 直接回覆機器人自身訊息的訊息
- 系統訊息(成員加入/離開、置頂訊息等)
- 機器人是管理員的頻道訊息
停用隱私模式時,機器人會收到群組中的每一則訊息。
如何停用隱私模式
- 傳訊息給 @BotFather
- 傳送
/mybots - 選擇你的機器人
- 前往 Bot Settings → Group Privacy → Turn off
WARNING
更改隱私設定後,你必須將機器人從群組中移除並重新加入。 Telegram 會在機器人加入群組時快取隱私狀態,直到機器人被移除並重新加入才會更新。
TIP
替代方案:將機器人提升為群組管理員。管理員機器人不論隱私設定如何,都會收到所有訊息,這樣就不需要切換全域隱私模式。
觀察群組訊息但不自動回覆
若要實現 OpenClaw/Yuanbao 風格的群組行為,可以設定 Telegram 讓機器人看到一般群組訊息,但只在被明確觸發時才回覆:
telegram:
allowed_chats:
- "-1001234567890"
group_allowed_chats:
- "-1001234567890"
require_mention: true
observe_unmentioned_group_messages: true
啟用此模式後,來自明確允許清單中聊天/主題的未提及群組訊息,會作為觀察上下文附加到共用聊天/主題的對話記錄中,但不會觸發 Agent。allowed_chats 控制機器人回覆的範圍;group_allowed_chats 授權用於觀察上下文的共用群組會話,因此此模式請使用相同的聊天 ID。在該允許清單聊天/主題中,稍後的 @botname 提及、回覆機器人、或配置的提及模式,都可以使用該觀察上下文。觸發訊息也會標註 [nickname|user_id],並附帶逐輪的安全提示,讓模型將先前觀察到的內容視為上下文而非對機器人的指令。
對應的環境變數:
TELEGRAM_ALLOWED_CHATS=-1001234567890
TELEGRAM_GROUP_ALLOWED_CHATS=-1001234567890
TELEGRAM_OBSERVE_UNMENTIONED_GROUP_MESSAGES=true
此功能需要 Telegram 將一般群組訊息傳遞給 gateway,因此請按照上述說明停用 BotFather 隱私模式或將機器人提升為群組管理員。
步驟 4:取得你的使用者 ID
Hermes Agent 使用數字型 Telegram 用戶 ID 來控制存取權限。你的使用者 ID 不是你的使用者名稱——它是一個類似 123456789 的數字。
方法 1(推薦): 傳訊息給 @userinfobot——它會立即回覆你的使用者 ID。
方法 2: 傳訊息給 @get_id_bot——另一個可靠的選項。
請記下這個數字;下一步會用到。
步驟 5:設定 Hermes
選項 A:互動式設定(推薦)
hermes gateway setup
系統提示時選擇 Telegram。設定精靈會詢問你的 bot token 和允許的使用者 ID,然後自動寫入設定檔。
選項 B:手動設定
在 ~/.hermes/.env 中加入以下內容:
TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
TELEGRAM_ALLOWED_USERS=123456789 # 多個使用者請以逗號分隔
啟動 Gateway
hermes gateway
機器人應在幾秒內上線。在 Telegram 上傳訊息給它以驗證。
從 Docker 後端終端發送生成的檔案
如果你的終端後端是 docker,請注意 Telegram 附件是由 gateway 進程發送的,而非從容器內部發送。這意味著最終的 MEDIA:/... 路徑必須在執行 gateway 的主機上可讀。
常見問題:
- Agent 在 Docker 內寫入檔案到
/workspace/report.txt - 模型產出
MEDIA:/workspace/report.txt - Telegram 傳送失敗,因為
/workspace/report.txt只存在於容器內,而非主機上
建議的模式:
terminal:
backend: docker
docker_volumes:
- "/home/user/.hermes/cache/documents:/output"
然後:
- 在 Docker 內將檔案寫入
/output/... - 在
MEDIA:中使用主機可見的路徑,例如:MEDIA:/home/user/.hermes/cache/documents/report.txt
如果你已有 docker_volumes: 區段,請將新的掛載加到同一個列表中。YAML 重複的 key 會靜默覆蓋先前的值。
支援的 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 網址,支援閒置時休眠的部署。
| 輪詢(預設) | Webhook | |
|---|---|---|
| 方向 | Gateway → Telegram(出站) | Telegram → Gateway(入站) |
| 適用場景 | 本地、常時運行的伺服器 | 有自動喚醒功能的雲端平台 |
| 設定 | 無需額外設定 | 設定 TELEGRAM_WEBHOOK_URL |
| 閒置成本 | 機器必須持續運行 | 機器可在訊息間休眠 |
設定
在 ~/.hermes/.env 中加入以下內容:
TELEGRAM_WEBHOOK_URL=https://my-app.fly.dev/telegram
TELEGRAM_WEBHOOK_SECRET="$(openssl rand -hex 32)" # 必填
# TELEGRAM_WEBHOOK_PORT=8443 # 選用,預設 8443
| 變數 | 必填 | 說明 |
|---|---|---|
TELEGRAM_WEBHOOK_URL | 是 | Telegram 發送更新的公開 HTTPS 網址。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)
- 將環境變數加入你的 Fly.io 應用密鑰:
fly secrets set TELEGRAM_WEBHOOK_URL=https://my-app.fly.dev/telegram
fly secrets set TELEGRAM_WEBHOOK_SECRET=$(openssl rand -hex 32)
- 在你的
fly.toml中暴露 webhook 連接埠:
[[services]]
internal_port = 8443
protocol = "tcp"
[[services.ports]]
handlers = ["tls", "http"]
port = 443
- 部署:
fly deploy
Gateway 日誌應顯示:[telegram] Connected to Telegram (webhook mode)。
代理支援
如果你的網路需要透過代理連接網際網路(企業環境中很常見),Telegram 適配器會自動讀取標準代理環境變數,並將所有連接透過代理路由。
支援的變數
適配器依序檢查以下環境變數,使用第一個有設定的:
HTTPS_PROXYHTTP_PROXYALL_PROXYhttps_proxy/http_proxy/all_proxy(小寫變體)
設定
在啟動 gateway 前設定代理:
export HTTPS_PROXY=http://proxy.example.com:8080
hermes gateway
或加入 ~/.hermes/.env:
HTTPS_PROXY=http://proxy.example.com:8080
此代理適用於主傳輸層和所有備用 IP 傳輸層。無需額外的 Hermes 設定——只要環境變數已設定,就會自動使用。
NOTE
以上涵蓋了 Hermes 用於 Telegram 連接的自訂備用傳輸層。其他地方使用的標準
httpx用戶端本身已原生支援代理環境變數。
首頁頻道
在任何 Telegram 聊天(私訊或群組)中使用 /sethome 指令,將其指定為首頁頻道。排程任務(cron 工作)的結果會傳遞到此頻道。
你也可以在 ~/.hermes/.env 中手動設定:
TELEGRAM_HOME_CHANNEL=-1001234567890
TELEGRAM_HOME_CHANNEL_NAME="My Notes"
TIP
群組聊天 ID 是負數(例如
-1001234567890)。你的個人私訊聊天 ID 與你的使用者 ID 相同。
Topic 模式下的 Cron 傳遞
如果你在機器人的私訊中啟用了 topic 模式,傳送到根聊天的 cron 訊息會落入僅限系統的大廳——在此回覆不會開啟會話,你會看到「主聊天保留給系統指令」的提示。請建立一個專用的論壇主題(例如 Cron)並設定:
TELEGRAM_CRON_THREAD_ID=<topic_thread_id>
TELEGRAM_CRON_THREAD_ID 僅覆蓋 cron 傳遞的 TELEGRAM_HOME_CHANNEL_THREAD_ID。在該主題中的回覆會繼續該主題的現有會話。
語音訊息
接收語音(語音轉文字)
你在 Telegram 上傳送的語音訊息會由 Hermes 配置的 STT 供應商自動轉錄,並以文字形式注入對話中。
local使用執行 Hermes 的機器上的faster-whisper——無需 API 金鑰groq使用 Groq Whisper,需要GROQ_API_KEYopenai使用 OpenAI Whisper,需要VOICE_TOOLS_OPENAI_KEY
跳過 STT:將原始音訊檔案傳給 Agent
如果你希望Agent 本身處理音訊——例如進行說話者分離、使用自訂轉錄工具,或僅僅是歸檔錄音——請在 ~/.hermes/config.yaml 中設定 stt.enabled: false:
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:
# Ubuntu/Debian
sudo apt install ffmpeg
# macOS
brew install ffmpeg
沒有 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 設定時,會自動解除自身的內部上限。
這解鎖了以下工作流程:
- 傳送長語音訊息(45 分鐘的會議、播客)給機器人
- 上傳大影片進行視覺工具處理
- 歸檔原始音訊用於離線管線,如說話者分離、校準或訓練資料
步驟 1:取得 Telegram API 憑證
本地伺服器直接與 Telegram 的 MTProto 層通訊(而非公開 Bot API),因此需要 MTProto 憑證:
- 造訪 my.telegram.org/apps 並使用你的 Telegram 帳號登入。
- 建立一個新應用程式(名稱和簡短描述隨意)。
- 複製
api_id和api_hash——兩者都是必需的。
步驟 2:執行 telegram-bot-api 伺服器
社群維護的 aiogram/telegram-bot-api Docker 映像是最簡單的方式。一個最小的 docker-compose.yaml(使用 --local 模式啟用更高的限制):
services:
tg-bot-api:
image: aiogram/telegram-bot-api:latest
container_name: tg-bot-api
restart: unless-stopped
ports:
- "127.0.0.1:8081:8081" # 僅綁定到迴圈介面;詳見安全說明
environment:
TELEGRAM_API_ID: "12345" # 來自步驟 1 的 api_id
TELEGRAM_API_HASH: "abcdef..." # 來自步驟 1 的 api_hash
TELEGRAM_LOCAL: "1" # 啟用 --local 模式(將 20MB 提升至 2GB)
volumes:
- ./tg-bot-api-data:/var/lib/telegram-bot-api
啟動:
docker compose up -d tg-bot-api
docker logs --tail 20 tg-bot-api
WARNING — 安全性
本地 Bot API 伺服器將你的 bot token 放在 URL 路徑中(例如
/bot<TOKEN>/getMe),無額外驗證。任何能連到該連接埠的人都能完全控制你的機器人——讀取它能看到的所有訊息、以它的名義傳送訊息等。請將容器綁定到127.0.0.1和/或在私有網路上用反向代理作為前端。永遠不要將 8081 連接埠暴露到公開網際網路。
步驟 3:將機器人從公開 API 登出(一次性)
一個機器人同時只能在一個 Bot API 伺服器上活躍。如果你的機器人已經在 api.telegram.org 上運行(幾乎可以肯定如此),你必須先在該處明確登出,本地伺服器才會接受它:
curl "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/logOut"
# 預期回應:{"ok":true,"result":true}
這是一次性的遷移步驟——不需要在每次重啟時都執行。Telegram 會將 logOut 後收到的任何訊息改為透過新的伺服器傳遞。
驗證本地伺服器能代表機器人與 Telegram 通訊:
curl "http://127.0.0.1:8081/bot<YOUR_BOT_TOKEN>/getMe"
# 預期回應:{"ok":true,"result":{"id":...,"is_bot":true,...}}
步驟 4:將 Hermes 指向本地伺服器
在 ~/.hermes/config.yaml 的 platforms.telegram.extra 下加入網址:
platforms:
telegram:
extra:
base_url: "http://127.0.0.1:8081/bot"
base_file_url: "http://127.0.0.1:8081/file/bot"
local_mode: true # 見下方步驟 5——僅在機器人的資料
# 目錄可被 Hermes 進程讀取時才設定
CAUTION — 請使用
platforms.telegram.extra,而非telegram.extra目前只有
platforms.<name>.extra形式會深度合併到平台設定中。直接放在頂層telegram.extra區塊下的 key 會被靜默丟棄。
設定 base_url 後,Hermes 會:
- 針對本地伺服器建立 python-telegram-bot 用戶端
- 自動將內部文件/音訊大小上限從 20 MB 提升到 2 GB
- 在「檔案過大」錯誤訊息中報告當前的上限(
Maximum: 2048 MB.),讓你清楚知道目前使用的模式
重啟 gateway 並查看確認日誌行:
hermes gateway restart
grep -E "Using custom Telegram base_url|Using Telegram local_mode" ~/.hermes/logs/gateway.log | tail
步驟 5:local_mode —— 磁碟上的檔案存取
本地伺服器有兩種方式傳遞檔案:
- 未使用
--local(預設):檔案透過 HTTP 在/file/bot<TOKEN>/<path>提供,與公開 Bot API 相同。20MB 上限仍然有效。僅作為網路修復使用(例如當api.telegram.org無法存取但你可以自架時);這不是你想要的大小提升方式。 - 使用
--local(透過上述TELEGRAM_LOCAL=1設定):檔案寫入伺服器的檔案系統,getFile回傳絕對路徑而非 HTTP 網址。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、獨立的 VM),而 Hermes 在另一台上。伺服器的資料目錄必須以伺服器報告的相同絕對路徑與 Hermes 機器共享(通常是
/var/lib/telegram-bot-api)。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 而不會出現權限錯誤。
步驟 6:測試
傳送一個超過 20MB 的語音訊息或音訊檔案給機器人。追蹤 gateway 日誌:
tail -f ~/.hermes/logs/gateway.log | grep -iE "telegram|cache"
你應該會看到一行 [Telegram] Cached user voice at /home/<user>/.hermes/cache/audio/...,且沒有「檔案過大」的拒絕訊息。結合上述的 stt.enabled: false,原始音訊檔案的路徑會出現在 Agent 的輸入訊息中,供後續處理。
群組聊天使用
Hermes Agent 可以在 Telegram 群組聊天中使用,但有幾個注意事項:
- 隱私模式決定機器人能看到哪些訊息(詳見步驟 3)
TELEGRAM_ALLOWED_USERS仍然適用——只有授權使用者才能觸發機器人,即使在群組中也是如此- 你可以透過
telegram.require_mention: true防止機器人回覆一般群組閒聊 - 當
telegram.require_mention: true時,群組訊息在以下情況會被接受:- 回覆機器人的訊息
@botusername提及/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 裡重複使用同一個 bot token;Telegram 會拒絕針對同一個 token 的並行輪詢。
建議的群組設定:
telegram:
require_mention: true
exclusive_bot_mentions: true
mention_patterns: []
在此設定下,像 @research_bot @ops_bot summarize this 這樣的群組訊息只會由 research_bot 和 ops_bot 處理。群組中的其他 Hermes 機器人會保持安靜,即使訊息是對它們先前訊息的回覆,或原本會匹配共用的喚醒詞。
僅在需要保留回覆和喚醒詞觸發的舊版群組行為時,才設定 exclusive_bot_mentions: false。
要運行多個配置,請為每個配置執行一次 gateway 指令。例如:
# 預設配置
hermes gateway start
hermes gateway status
hermes gateway stop
# 命名配置
hermes -p research gateway start
hermes -p research gateway status
hermes -p research gateway stop
對於小型固定機器群,使用 shell 迴圈或腳本,對預設配置呼叫 hermes gateway <action>,對每個命名配置呼叫 hermes -p <profile> gateway <action>。這比假設單一進程級指令能控制每個服務管理器上的所有命名配置更可靠。
疑難排解:私訊可用但群組不行
如果機器人在私訊中能回覆但在群組中保持安靜,請依序檢查以下關卡:
- Telegram 傳遞: 停用 BotFather 隱私模式、將機器人提升為管理員,或直接提及機器人。Hermes 無法回覆 Telegram 未傳遞給機器人的群組訊息。
- 更改隱私後重新加入: 更改 BotFather 隱私設定後,將機器人從群組中移除並重新加入。Telegram 可能會保留現有成員資格的舊傳遞行為。
- Hermes 授權: 確認傳送者列在
TELEGRAM_ALLOWED_USERS或TELEGRAM_GROUP_ALLOWED_USERS中,或使用TELEGRAM_GROUP_ALLOWED_CHATS允許該群組聊天。 - 提及過濾器: 如果設定了
telegram.require_mention: true,一般群組閒聊會被忽略,除非訊息是斜線指令、回覆機器人、@botusername提及或匹配配置的mention_patterns。 - 多機器人路由: 如果群組包含多個機器人,請確保每個 Hermes 配置使用唯一的 bot token,並保持
exclusive_bot_mentions啟用,除非你確實想要保留舊版的共用觸發行為。
群組和超級群組的負數聊天 ID 是正常的。如果你使用聊天範圍的授權,請將這些 ID 放在 TELEGRAM_GROUP_ALLOWED_CHATS 中,而非傳送者使用者允許清單中。
群組觸發設定範例
在 ~/.hermes/config.yaml 中加入:
telegram:
require_mention: true
exclusive_bot_mentions: true
mention_patterns:
- "^\\s*chompy\\b"
ignored_threads:
- 31
- "42"
此範例允許所有一般的直接觸發方式,以及以 chompy 開頭的訊息,即使它們沒有使用 @mention。
Telegram 主題 31 和 42 中的訊息會在提及和自由回覆檢查之前被忽略。
mention_patterns 注意事項
- 模式使用 Python 正則表達式
- 匹配不區分大小寫
- 模式會同時檢查文字訊息和媒體說明
- 無效的正則表達式會被忽略並在 gateway 日誌中發出警告,不會導致機器人崩潰
- 如果你希望模式只匹配訊息開頭,請使用
^錨定
私人聊天主題(Bot API 9.4)
Telegram Bot API 9.4(2026 年 2 月)引入了私人聊天主題——機器人可以直接在 1 對 1 私訊聊天中建立論壇風格的主題執行緒,無需超級群組。這讓你可以在現有的 Hermes 私訊中運行多個隔離的工作空間。
使用場景
如果你同時進行多個長期專案,主題可以保持各自的上下文分離:
- 主題「Website」 — 處理你的生產環境 Web 服務
- 主題「Research」 — 文獻回顧和論文探索
- 主題「General」 — 雜項任務和快速問題
每個主題都有自己的對話會話、歷史記錄和上下文——完全與其他主題隔離。
設定
CAUTION — 前置條件
在將主題加入你的設定之前,使用者必須在與機器人的私訊中啟用 Topics 模式:
- 在 Telegram 中開啟你與 Hermes 機器人的私訊
- 點擊頂部的機器人名稱以開啟聊天資訊
- 啟用 Topics(將聊天轉換為論壇的開關)
否則,Hermes 會在啟動時記錄
The chat is not a forum並跳過主題建立。這是 Telegram 客戶端的設定——機器人無法以程式方式啟用它。
在 ~/.hermes/config.yaml 的 platforms.telegram.extra.dm_topics 下加入主題:
platforms:
telegram:
extra:
dm_topics:
- chat_id: 123456789 # 你的 Telegram 使用者 ID
topics:
- name: General
icon_color: 7322096
- name: Website
icon_color: 9367192
- name: Research
icon_color: 16766590
skill: arxiv # 在此主題中自動載入的技能
欄位說明:
| 欄位 | 必填 | 說明 |
|---|---|---|
name | 是 | 主題顯示名稱 |
icon_color | 否 | Telegram 圖示顏色代碼(整數) |
icon_custom_emoji_id | 否 | 主題圖示的自訂表情 ID |
skill | 否 | 在此主題的新會話中自動載入的技能 |
thread_id | 否 | 主題建立後自動填入——不要手動設定 |
運作方式
- Gateway 啟動時,Hermes 會為每個尚無
thread_id的主題呼叫createForumTopic thread_id會自動回寫到config.yaml——後續重啟會跳過 API 呼叫- 每個主題對應一個隔離的會話鍵:
agent:main:telegram:dm:{chat_id}:{thread_id} - 每個主題的訊息有各自的對話歷史、記憶刷新和上下文視窗
根私訊處理
預設情況下,發送到根私訊(不在任何主題中的訊息)會正常處理。設定 ignore_root_dm: true 可將根私訊變為大廳——對已設定 DM 主題的使用者,普通訊息會被靜默忽略,而系統指令(/start、/help、/status 等)仍然有效。
platforms:
telegram:
extra:
ignore_root_dm: true
dm_topics:
- chat_id: 123456789
topics:
- name: General
檢查是逐聊天的:只有在 dm_topics 中至少有一個條目的使用者才會受到根私訊影響。沒有設定主題的使用者不受影響。
技能綁定
帶有 skill 欄位的主題會在新會話於該主題啟動時自動載入該技能。這與在對話開始時輸入 /skill-name 完全相同——技能內容會注入第一則訊息中,後續訊息會在對話歷史中看到它。
例如,帶有 skill: arxiv 的主題會在其會話重置時(由於閒置逾時、每日重置或手動 /reset)預先載入 arxiv 技能。
TIP
在設定之外建立的主題(例如透過手動呼叫 Telegram API)會在收到
forum_topic_created系統訊息時自動發現。你也可以在 gateway 執行時將主題加入設定——它們會在下次快取未命中時被擷取。
多會話私訊模式(/topic)
ChatGPT 風格的多會話私訊——一個機器人,多個並行對話。與上述由營運者管理的 extra.dm_topics 不同,此模式由使用者驅動:無需設定,無需預先宣告的主題名稱。終端使用者使用 /topic 啟用它,然後點擊 Telegram 的 + 按鈕建立任意數量的主題,每個主題都是一個完全獨立的 Hermes 會話。
/topic 子指令
| 格式 | 情境 | 效果 |
|---|---|---|
/topic | 根私訊,尚未啟用 | 檢查 BotFather 功能,啟用多會話模式,建立已置頂的 System 主題 |
/topic | 根私訊,已啟用 | 顯示狀態:可恢復的未連結會話 |
/topic | 在主題內 | 顯示目前主題的會話綁定 |
/topic help | 任何位置 | 內建使用說明 |
/topic off | 根私訊 | 停用多會話模式並清除此聊天的所有主題綁定 |
/topic <session-id> | 在主題內 | 將先前的 Telegram 會話恢復到目前主題 |
只有授權使用者(透過 TELEGRAM_ALLOWED_USERS / 平台授權設定的允許清單)可以執行 /topic。未授權的傳送者會收到拒絕訊息而非啟用。
DM 主題 vs 多會話私訊模式
extra.dm_topics(設定驅動) | /topic(使用者驅動) | |
|---|---|---|
| 誰來啟用 | 營運者,在 config.yaml 中 | 終端使用者,透過傳送 /topic |
| 主題清單 | 在設定中宣告的固定集合 | 使用者自由建立/刪除主題 |
| 主題名稱 | 由營運者選擇 | 由使用者選擇;自動重新命名以匹配 Hermes 會話標題 |
| 根私訊行為 | 一般聊天(若 ignore_root_dm: true 則為大廳) | 變為系統大廳(非指令訊息被拒絕) |
| 主要使用場景 | 搭配可選技能綁定的永久工作空間 | 隨時建立的並行會話 |
| 持久化 | 設定中的 extra.dm_topics | telegram_dm_topic_mode + telegram_dm_topic_bindings SQLite 表格 |
兩項功能可以在同一個機器人上共存——你從使用者的私訊中執行 /topic,而 extra.dm_topics 繼續管理其他聊天中由營運者宣告的主題。
前置條件
在 @BotFather 中,開啟你的機器人 → Bot Settings → Threads Settings:
- 開啟 Threaded Mode(啟用
has_topics_enabled) - 不要停用使用者建立主題的功能(保持
allows_users_to_create_topics為開啟)
當使用者首次執行 /topic 時,Hermes 會呼叫 getMe 來驗證這兩個標誌。如果任一關閉,Hermes 會傳送 BotFather Threads Settings 頁面的截圖並說明需要切換哪些設定——在滿足前置條件之前不會進行任何啟用。
啟用流程
在根私訊中傳送:
topic
Hermes 會:
- 檢查
getMe().has_topics_enabled和allows_users_to_create_topics - 如果兩者都是 true,為此私訊啟用多會話主題模式
- 建立並置頂一個 System 主題用於狀態/指令(盡力為之)
- 回覆一份先前未連結的 Telegram 會話清單,供使用者恢復
啟用後,根私訊變成大廳:普通提示會被拒絕,並附帶指向 All Messages 的指引。系統指令(/status、/sessions、/usage、/help 等)在根私訊中仍然有效。
建立新主題(終端使用者流程)
- 在 Telegram 中開啟機器人私訊
- 點擊機器人介面頂部的 All Messages,然後傳送任何訊息
- Telegram 為該訊息建立一個新主題
- Hermes 在該主題內回覆——該主題現在是一個獨立會話
每個主題都有各自的對話歷史、模型狀態、工具執行和會話 ID。隔離鍵是 agent:main:telegram:dm:{chat_id}:{thread_id}——與設定驅動的 DM 主題隔離方式相同。
自動重新命名的主題
當 Hermes 為主題產生會話標題時(透過自動標題管線,在第一次交流後),Telegram 主題本身會被重新命名以匹配——例如「New Topic」變成「Database migration plan」。重新命名是盡力為之的:失敗會被記錄但不會中斷會話。
要停用此功能並保持你手動選擇的主題名稱不變,請設定:
gateway:
platforms:
telegram:
extra:
disable_topic_auto_rename: true
啟用此標誌後,Hermes 仍會產生內部會話標題(由 hermes sessions、TUI 等使用),但永遠不會編輯 Telegram 主題名稱。當你在 BotFather Threaded Mode 下手工組織主題且不希望每次第一則回覆都覆蓋標題時很有用。
在主題中使用 /new
重設目前主題的會話(新的會話 ID、全新的歷史),但不影響其他主題。Hermes 會回覆提醒,指出對於並行工作,建立另一個主題(透過 All Messages)通常是更好的選擇。
恢復先前的會話
在主題中傳送:
topic <session-id>
這會將目前主題綁定到現有的 Hermes 會話,而非開始新的。適用於繼續在啟用主題模式之前開始的對話。限制:
- 目標會話必須屬於同一個 Telegram 使用者
- 目標會話不得已綁定到另一個主題
Hermes 會用會話標題確認,並回放最後一則助理訊息作為上下文。
要發現會話 ID,在根私訊中傳送 /topic(無參數)——Hermes 會列出使用者未連結的 Telegram 會話。
在主題中使用 /topic(無參數)
顯示目前主題的綁定:會話標題、會話 ID,以及 /new 或建立另一個主題的提示。
底層運作
- 啟用狀態持久化到
state.db中的telegram_dm_topic_mode(chat_id, user_id, enabled, ...) - 每個主題綁定持久化到
telegram_dm_topic_bindings(chat_id, thread_id, session_id, ...),對session_id設有ON DELETE CASCADE——刪除會話會自動清除其主題綁定 - 主題模式的 SQLite 遷移是選擇性的:它在首次
/topic呼叫時運行,永遠不在 gateway 啟動時運行。在使用者在此配置中執行/topic之前,state.db保持不變 - 每條收到的 DM 訊息會查找其
(chat_id, thread_id)綁定。如果存在,查找會透過SessionStore.switch_session()將訊息路由到綁定的會話,確保會話鍵到會話 ID 的映射在磁碟上保持一致 - 在主題中使用
/new會改寫綁定列以指向新的會話 ID,確保下一則訊息留在新會話中 - 在
extra.dm_topics中宣告的主題永遠不會自動重新命名——即使啟用了多會話模式,營運者選擇的名稱也會被保留 - 設定
extra.disable_topic_auto_rename: true可關閉此聊天中所有主題的自動重新命名(包括透過 Threaded Mode 建立的隨機主題) - 在啟用論壇的私訊中,General(置頂頂部)主題被視為根大廳,無論 Telegram 是以
message_thread_id=1還是無 thread_id 傳送其訊息 - 根大廳提醒受到速率限制:每個聊天每 30 秒最多一條訊息——忘記已啟用主題模式的使用者在根私訊中輸入十個提示不會收到十個回覆
- BotFather 設定截圖受到速率限制:每個聊天每 5 分鐘最多發送一次——在 Threads Settings 仍被停用時重複嘗試
/topic不會重新上傳相同的圖片 - 在主題中啟動的
/background <prompt>會將結果送回同一個主題;背景會話不會觸發所屬主題的自動重新命名 /topic本身受到機器人使用者授權檢查的控制——未授權的 DM 會收到拒絕訊息而非啟用
停用多會話模式
在根私訊中傳送 /topic off。Hermes 會關閉該列,清除聊天的 (thread_id → session_id) 綁定,根私訊恢復為一般的 Hermes 聊天。Telegram 中的現有主題不會被刪除——它們只是不再作為獨立會話被控制。稍後重新執行 /topic 即可再次啟用。
如果你需要手動清理(例如跨多個聊天的批量重設),可以直接刪除列:
sqlite3 ~/.hermes/state.db \
"UPDATE telegram_dm_topic_mode SET enabled = 0 WHERE chat_id = '<your_chat_id>'; \
DELETE FROM telegram_dm_topic_bindings WHERE chat_id = '<your_chat_id>';"
降級 Hermes
如果你降級到早於 /topic 的 Hermes 版本,此功能會停止運作——telegram_dm_topic_mode 和 telegram_dm_topic_bindings 表格仍留在 state.db 中,但會被舊版程式碼忽略。DM 恢復為原生的逐執行緒隔離(每個 message_thread_id 仍透過 build_session_key 獲得自己的會話),因此你現有的 Telegram 主題會繼續作為並行會話運作。根私訊不再是大廳——那裡的訊息會像以前一樣送入 Agent。重新升級後會恢復到之前的多會話模式狀態。
群組論壇主題技能綁定
啟用了Topics 模式的超級群組(也稱為「論壇主題」)已經有逐主題的會話隔離——每個 thread_id 對應自己的對話。但你可能希望在特定群組主題收到訊息時自動載入技能,就像 DM 主題技能綁定一樣。
使用場景
一個具有論壇主題的工作團隊超級群組:
- Engineering 主題 → 自動載入
software-development技能 - Research 主題 → 自動載入
arxiv技能 - General 主題 → 無技能,通用助理
設定
在 ~/.hermes/config.yaml 的 platforms.telegram.extra.group_topics 下加入主題綁定:
platforms:
telegram:
extra:
group_topics:
- chat_id: -1001234567890 # 超級群組 ID
topics:
- name: Engineering
thread_id: 5
skill: software-development
- name: Research
thread_id: 12
skill: arxiv
- name: General
thread_id: 1
# 無技能——通用用途
欄位說明:
| 欄位 | 必填 | 說明 |
|---|---|---|
chat_id | 是 | 超級群組的數字 ID(以 -100 開頭的負數) |
name | 否 | 主題的人類可讀標籤(僅供參考) |
thread_id | 是 | Telegram 論壇主題 ID——可在 t.me/c/<group_id>/<thread_id> 連結中找到 |
skill | 否 | 在此主題的新會話中自動載入的技能 |
運作方式
- 當訊息到達已映射的群組主題時,Hermes 會在
group_topics設定中查找chat_id和thread_id - 如果匹配的條目有
skill欄位,該技能會自動載入——與 DM 主題技能綁定相同 - 沒有
skill鍵的主題只獲得會話隔離(現有行為,不變) - 未映射的
thread_id或chat_id值會靜默忽略——無錯誤,無技能
與 DM 主題的差異
| DM 主題 | 群組主題 | |
|---|---|---|
| 設定鍵 | extra.dm_topics | extra.group_topics |
| 主題建立 | 如果缺少 thread_id,Hermes 透過 API 建立主題 | 管理員在 Telegram UI 中建立主題 |
thread_id | 建立後自動填入 | 必須手動設定 |
icon_color / icon_custom_emoji_id | 支援 | 不適用(管理員控制外觀) |
| 技能綁定 | ✓ | ✓ |
| 會話隔離 | ✓ | ✓(論壇主題已內建) |
TIP
要找到主題的
thread_id,在 Telegram Web 或桌面版中開啟主題並查看 URL:https://t.me/c/1234567890/5——最後一個數字(5)就是thread_id。超級群組的chat_id是群組 ID 加上-100前綴(例如群組1234567890變為-1001234567890)。
近期 Bot API 功能
- Bot API 9.4(2026 年 2 月): 私人聊天主題——機器人可以透過
createForumTopic在 1 對 1 私訊聊天中建立論壇主題。Hermes 將此用於兩項不同的功能:由營運者管理的私人聊天主題(設定驅動,固定主題列表)和由使用者驅動的多會話私訊模式(透過/topic啟用,使用者可建立無限主題)。 - 隱私政策: Telegram 現在要求機器人必須有隱私政策。請透過 BotFather 的
/setprivacy_policy設定,否則 Telegram 可能會自動產生佔位符。如果你的機器人是公開的,這點尤其重要。 - Bot API 9.5(2026 年 3 月):透過
sendMessageDraft的原生串流。 Hermes 將 Telegram 的原生串流草稿 API 作為私訊的選擇性傳輸方式。預設仍使用舊版的editMessageText路徑,因為草稿預覽在某些 Telegram 客戶端上可能會明顯崩潰並重新渲染。
串流傳輸(gateway.streaming.transport)
啟用串流後(gateway.streaming.enabled: true),Hermes 會從四種傳輸方式中選擇一種:
| 值 | 行為 |
|---|---|
auto(預設) | 在支援的聊天(目前為 Telegram 私訊)中使用原生草稿串流;其他情況使用舊版基於編輯的路徑。如果草稿幀失敗,會優雅退降。 |
draft | 強制使用原生草稿。如果聊天不支援草稿(例如群組/主題),會記錄降級並退回到編輯模式。 |
edit | 對所有聊天類型使用舊版漸進式 editMessageText 輪詢。 |
off | 完全停用串流(僅最終回覆,無漸進式更新)。 |
在 ~/.hermes/config.yaml 中:
gateway:
streaming:
enabled: true
transport: auto # auto | draft | edit | off
使用 edit(預設)時在私訊中的效果 — gateway 傳送一般的預覽訊息,並透過 editMessageText 漸進式更新,避免 Telegram 草稿預覽的崩潰/回滾效果。
使用 auto 或 draft 時在私訊中的效果 — Telegram 顯示一個動畫草稿預覽,逐 token 更新。回覆完成後,會作為一般訊息傳遞,草稿預覽會在客戶端自然清除。草稿沒有訊息 ID,因此最終回答才是保留在聊天記錄中的內容。
群組、超級群組、論壇主題呢? Telegram 將 sendMessageDraft 限制在私訊中。Gateway 會對其他所有情況透明退回到基於編輯的路徑——與之前的使用體驗相同。
如果草稿幀失敗怎麼辦? 任何失敗(暫時性網路錯誤、伺服器端拒絕、較舊版本的 python-telegram-bot)都會將該回應切換回基於編輯的路徑完成剩餘串流。下一次回應會重新嘗試。
渲染:富訊息、表格與連結預覽
富訊息(Bot API 10.1)。 包含舊版 MarkdownV2 路徑會降級的結構的最終回覆——表格、任務列表、可折疊的 <details> 和區塊數學——會使用 Telegram 的原生 sendRichMessage 並搭配 Agent 的原始 markdown 傳送,因此它們會原生渲染,不會有客戶端的扁平化處理。在串流期間,最終回答透過 editMessageText 的 rich_message 參數就地編輯現有預覽來傳遞——沒有第二則訊息、沒有刪除,因此不會在回合結束時出現重複傳送的閃爍。在私訊中,即時串流預覽也使用 sendRichMessageDraft,因此動畫草稿與最終的富訊息匹配。一般回覆(純散文、粗體/斜體、簡單列表)仍使用 MarkdownV2 路徑,以確保跨客戶端的字重和間距一致。
當內容超過 32,768 字元的富文字限制時,富路徑會自動跳過,而 Telegram 的任何拒絕(舊版 python-telegram-bot 不支援的端點、解析器錯誤、過大的區塊/欄位)都會透明退回到 MarkdownV2 路徑——你的訊息永遠不會丟失。暫時性/網路錯誤不會靜默重傳(不會有重複的最終訊息)。
MarkdownV2 退路。 當富路徑對某則訊息不可用時,Hermes 會將 markdown 轉換為 MarkdownV2。由於 MarkdownV2 沒有原生的表格語法,pipe 表格會被標準化:
- 小型表格會被扁平化為逐列項目符號——每一行變成列標題下的可讀項目符號列表。適用於 2–4 欄且儲存格較短的表格。
- 較大或較寬的表格會退回到圍欄程式碼區塊,欄位對齊,確保不會崩潰。
富訊息預設啟用。某些 Telegram 客戶端接受 Bot API 載荷但渲染效果不佳;要退出並強制所有回覆使用舊版 MarkdownV2 路徑:
gateway:
platforms:
telegram:
extra:
rich_messages: false
此設定是為了客戶端渲染相容性;Hermes 在 Telegram 拒絕富 API 呼叫時已會自動退降。如果你只想保留舊版的「一律程式碼區塊」表格行為同時保持富訊息啟用,請在 config.yaml 中設定 telegram.pretty_tables: false(預設:true)。
連結預覽。 Telegram 會為機器人訊息中的 URL 自動產生連結預覽。如果你想要隱藏它們(長 /tools 輸出、提到十個連結的 Agent 回覆等):
gateway:
platforms:
telegram:
extra:
disable_link_previews: true
啟用後,Hermes 會在每則出站訊息附加 Telegram 的 LinkPreviewOptions(is_disabled=True),並在舊版 python-telegram-bot 版本上退回到 disable_web_page_preview 參數。
群組允許清單
Telegram 群組和論壇聊天有兩個你可以設定的正交關卡:
- 傳送者使用者 ID(
group_allow_from/TELEGRAM_GROUP_ALLOWED_USERS)— 僅適用於群組/論壇訊息的傳送者範圍允許清單。當你希望特定使用者能在群組中觸發機器人,但不想將他們加入TELEGRAM_ALLOWED_USERS(那也會給他們私訊存取權)時使用。 - 聊天 ID(
group_allowed_chats/TELEGRAM_GROUP_ALLOWED_CHATS)— 聊天範圍的允許清單。這些群組/論壇的任何成員都可以與機器人互動。適用於群組成員資格本身就是存取訊號的團隊/客服機器人。
gateway:
platforms:
telegram:
extra:
# 全域存取(私訊 + 群組)。列在這裡的使用者隨時可以觸發機器人。
allow_from:
- "123456789"
# 僅允許在群組/論壇中的傳送者 ID。不會授予私訊存取權。
group_allow_from:
- "987654321"
# 整個群組/論壇——任何成員都已授權。
group_allowed_chats:
- "-1001234567890"
對應的環境變數:
TELEGRAM_ALLOWED_USERS="123456789"
TELEGRAM_GROUP_ALLOWED_USERS="987654321"
TELEGRAM_GROUP_ALLOWED_CHATS="-1001234567890"
行為:
TELEGRAM_ALLOWED_USERS涵蓋所有聊天類型(私訊、群組、論壇)。TELEGRAM_GROUP_ALLOWED_USERS僅授權列在其中的傳送者在群組/論壇中使用。除非也在TELEGRAM_ALLOWED_USERS中,否則他們仍然無法私訊機器人。TELEGRAM_GROUP_ALLOWED_CHATS中的聊天授權該聊天的每位成員,不論傳送者是誰。- 在以上任何變數中使用
*可允許任何傳送者/聊天。 - 這層疊加在現有的提及/模式觸發器以及
group_topics+ignored_threads之上。
從 PR #17686 之前的版本遷移
在此分離之前,TELEGRAM_GROUP_ALLOWED_USERS 是唯一的控制項,使用者在其中放入聊天 ID。為了向後相容,TELEGRAM_GROUP_ALLOWED_USERS 中以 - 開頭的聊天 ID 格式值仍會被視為聊天 ID,且會記錄一次棄用警告。遷移方式:
# 舊版(仍可運作,但已棄用)
TELEGRAM_GROUP_ALLOWED_USERS="-1001234567890"
# 新版
TELEGRAM_GROUP_ALLOWED_CHATS="-1001234567890"
訪客 @提及繞過(guest_mode)
在典型設定中,group_allowed_chats 是一個硬性關卡:來自不在清單中的群組的訊息會被靜默丟棄,即使成員明確 @提及了機器人。這對客服/團隊機器人來說是正確的預設行為。
對於更休閒的設定——朋友群組聊天中,你希望機器人大部分保持安靜但偶爾在被明確 @提及時可用——請啟用 guest_mode:
gateway:
platforms:
telegram:
extra:
group_allowed_chats:
- "-1001234567890" # 你的主要允許群組
guest_mode: true # 未允許的群組:僅在 @提及時允許
環境變數等效:
TELEGRAM_GUEST_MODE=true
預設:false。
啟用 guest_mode: true 後,來自未允許群組的訊息只有在明確 @提及機器人時才會被處理。每個回合都需要提及——訪客互動沒有會話黏性,因此機器人永遠不會在未被 @提及的朋友群組討論串中自動參與。
私訊和已允許群組的行為與之前完全相同。
斜線指令存取控制
預設情況下,每位允許的使用者都可以執行所有斜線指令。要將你的允許清單分為管理員(完整的斜線指令存取權)和一般使用者(只能使用你明確啟用的指令),請在平台的 extra 區塊中加入 allow_admin_from 和 user_allowed_commands:
gateway:
platforms:
telegram:
extra:
# 現有的允許清單(不變)
allow_from:
- "123456789" # 管理員
- "555555555" # 一般使用者
- "777777777" # 一般使用者
# 新增——管理員可使用所有斜線指令(內建 + 外掛)
allow_admin_from:
- "123456789"
# 新增——非管理員的允許使用者只能執行以下斜線指令。
# /help 和 /whoami 始終允許,讓使用者可以查看自己的存取權限。
user_allowed_commands:
- status
- model
- history
# 選用:為群組分開設定管理員/指令清單
group_allow_admin_from:
- "123456789"
group_user_allowed_commands:
- status
行為:
- 列在某個範圍(私訊或群組)的
allow_admin_from中的使用者,可以透過即時註冊表執行所有已註冊的斜線指令——包括內建指令和外掛註冊的指令。 - 列在
allow_from但未列在allow_admin_from中的使用者,只能執行user_allowed_commands中列示的指令,加上始終允許的基礎指令:/help和/whoami。 - 一般聊天(非斜線訊息)不受影響。非管理員使用者仍可正常與 Agent 對話,只是無法觸發任意指令。
- 向後相容: 如果某個範圍未設定
allow_admin_from,該範圍的斜線指令控制會停用。現有安裝無需變更即可繼續運作。 - 私訊的管理員狀態不意味著群組的管理員狀態。每個範圍有自己的管理員清單。
- 如果只設定了
group_allow_admin_from,私訊範圍保持在不受限(向後相容)模式。
使用 /whoami 查看目前的範圍、你的層級(管理員/使用者/不受限),以及你可以執行哪些斜線指令。
互動式模型選擇器
當你在 Telegram 聊天中不帶參數傳送 /model 時,Hermes 會顯示一個互動式內嵌鍵盤用於切換模型:
- 供應商選擇 — 按鈕顯示每個可用供應商及其模型數量(例如 "OpenAI (15)"、"✓ Anthropic (12)" 表示目前的供應商)。
- 模型選擇 — 分頁模型列表,帶有 Prev/Next 導航、Back 按鈕返回供應商列表,以及 Cancel。
目前的模型和供應商顯示在頂部。所有導航都透過就地編輯同一則訊息完成(不會造成聊天雜亂)。
TIP
如果你知道確切的模型名稱,直接輸入
/model <name>跳過選擇器。你也可以輸入/model <name> --global將變更跨會話持久化。
DNS-over-HTTPS 備用 IP
在某些受限的網路環境中,api.telegram.org 可能會解析到一個無法連線的 IP。Telegram 適配器包含一個備用 IP 機制,可以在保持正確的 TLS 主機名和 SNI 的同時,透明地對替代 IP 重試連線。
運作方式
- 如果設定了
TELEGRAM_FALLBACK_IPS,則直接使用這些 IP。 - 否則,適配器會自動透過 DNS-over-HTTPS(DoH)查詢 Google DNS 和 Cloudflare DNS,為
api.telegram.org發現替代 IP。 - DoH 回傳的、與系統 DNS 結果不同的 IP 會作為備用。
- 如果 DoH 也被封鎖,會使用硬編碼的種子 IP(
149.154.167.220)作為最後手段。 - 一旦某個備用 IP 成功,它就會變成「黏性」的——後續請求會直接使用它,而不先重試主路徑。
設定
# 明確的備用 IP(逗號分隔)
TELEGRAM_FALLBACK_IPS=149.154.167.220,149.154.167.221
或在 ~/.hermes/config.yaml 中:
platforms:
telegram:
extra:
fallback_ips:
- "149.154.167.220"
TIP
你通常不需要手動設定此項。透過 DoH 的自動發現能處理大多數受限網路的情境。只有在你的網路也封鎖了 DoH 時才需要
TELEGRAM_FALLBACK_IPS環境變數。
訊息回應表情
機器人可以對訊息添加表情反應作為視覺化的處理回饋:
- 👀 當機器人開始處理你的訊息時
- ✅ 當回覆成功傳遞時
- ❌ 當處理過程中發生錯誤時
反應預設停用。在 config.yaml 中啟用:
telegram:
reactions: true
或透過環境變數:
TELEGRAM_REACTIONS=true
NOTE
與 Discord 不同(反應是累加的),Telegram 的 Bot API 在單次呼叫中替換所有機器人反應。從 👀 到 ✅/❌ 的過渡是原子性的——你不會同時看到兩者。
TIP
如果機器人在群組中沒有添加反應的權限,反應呼叫會靜默失敗,訊息處理會正常繼續。
逐頻道提示
為特定的 Telegram 群組或論壇主題指派臨時性的系統提示。提示會在每次回合時注入運行時——永遠不會持久化到對話記錄歷史——因此變更會立即生效。
telegram:
channel_prompts:
"-1001234567890": |
You are a research assistant. Focus on academic sources,
citations, and concise synthesis.
"42": |
This topic is for creative writing feedback. Be warm and
constructive.
鍵值是聊天 ID(群組/超級群組)或論壇主題 ID。對於論壇群組,主題級別的提示會覆蓋群組級別的提示:
- 在群組
-1001234567890中的主題42發送訊息 → 使用主題42的提示 - 在主題
99(無明確條目)中發送訊息 → 退回到群組-1001234567890的提示 - 在沒有條目的群組中發送訊息 → 不套用頻道提示
數字型的 YAML 鍵會自動標準化為字串。
疑難排解
| 問題 | 解決方案 |
|---|---|
| 機器人完全沒有回應 | 確認 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 轉換需要)。 |
| Bot token 被撤銷/無效 | 透過 BotFather 的 /revoke 產生新 token,然後使用 /newbot 或 /token。更新你的 .env 檔案。 |
| Webhook 未收到更新 | 確認 TELEGRAM_WEBHOOK_URL 公開可達(用 curl 測試)。確保你的平台/反向代理將來自 URL 連接埠的入站 HTTPS 流量路由到 TELEGRAM_WEBHOOK_PORT 設定的本地監聽連接埠(兩者不必是相同的數字)。確保 SSL/TLS 已啟用——Telegram 只會發送到 HTTPS 網址。檢查防火牆規則。 |
指令執行審批
當 Agent 嘗試執行 potentially 危險的指令時,它會在聊天中請求你的審批:
⚠️ This command is potentially dangerous (recursive delete). Reply "yes" to approve.
回覆「yes」/「y」批准或「no」/「n」拒絕。
互動式提示(clarify)
當 Agent 呼叫 clarify 工具——詢問你偏好哪種方法、取得任務後的回饋,或在非平凡決策前進行確認——Telegram 會用內嵌鍵盤按鈕渲染問題:
❓ Which framework should I use for the dashboard?
[1. Next.js] [2. Remix] [3. Astro] [✏️ Other (type answer)]
點擊按鈕回答,或點擊 Other 輸入自由格式的回答(你發送的下一則訊息會成為答案)。開放式的 clarify 呼叫(無預設選項)會跳過按鈕,直接擷取你的下一則訊息。
透過 ~/.hermes/config.yaml 中的 agent.clarify_timeout 設定回應逾時時間(預設 600 秒)。如果你未在逾時時間內回應,Agent 會以哨兵訊息解除阻塞並進行適應,而非掛起。
推送通知音量
Telegram 在機器人發送的每則訊息上都會觸發推送通知。對於產生工具進度氣泡、串流更新和狀態回調的長 Agent 回合,這很快就會變得嘈雜。Telegram 適配器有兩種通知模式:
| 模式 | 行為 |
|---|---|
important(預設) | 只有最終回覆、審批提示和斜線指令確認會響鈴。工具進度、串流片段和狀態訊息以 disable_notification=true 傳送。 |
all | 每則出站訊息都觸發推送通知。舊版行為;如果你確實想知道每次工具呼叫的狀態,請選擇此模式。 |
在 ~/.hermes/config.yaml 中設定:
display:
platforms:
telegram:
notifications: important # 或 "all"
環境變數覆寫(方便快速 A/B 測試):
HERMES_TELEGRAM_NOTIFICATIONS=all
未知值會記錄警告並退回到 important。
狀態訊息就地編輯
Telegram 適配器透過 send_or_update_status() 路由重複的 Agent 狀態回調(例如 "Compressing context…"、"Calling tool…"),它維護一個 {(chat_id, status_key) → message_id} 快取,並在後續觸發時編輯現有氣泡而非每次追加新的。不同的 status_key 值有自己的訊息;不同的聊天不會衝突。如果編輯失敗(例如使用者刪除了訊息,或它已超過 Telegram 允許的編輯時效),快取條目會被移除,下次觸發會發布新訊息並重新快取其 ID。無需設定——這是 Telegram 的預設行為。未實作 send_or_update_status 的其他適配器會退回為一般的 send()。
在 Agent 回合期間釘選使用者傳入訊息
當使用者傳送觸發 Agent 回合的訊息時,Telegram 適配器會在回合期間釘選該傳入訊息,並在回應完成時取消釘選——這是一個輕量的視覺指示器,表示機器人正在處理該訊息而非忽略它。釘選使用 disable_notification=true 以避免額外的提示音。無需設定。
安全性
WARNING
請務必設定
TELEGRAM_ALLOWED_USERS來限制誰可以與你的機器人互動。沒有它的話,gateway 會基於安全考量預設拒絕所有使用者。
永遠不要公開分享你的 bot token。如果洩露,請立即透過 BotFather 的 /revoke 指令撤銷它。
更多詳細資訊,請參閱安全性文件。你也可以使用 DM 配對作為更動態的使用者授權方式。