Files
Hermes-Skills/devops/clash-docker-workflow/references/telegram-adapter-diagnostics.md
T
Hermes Skills Manager 6770bc9b9d Initial commit: Hermes Agent skills collection
- Trading skills (OKX, dividend, lottery, quantitative)
- Creative skills (ASCII art, diagrams, video)
- Development skills (GitHub, debugging, TDD)
- Research skills (arXiv, blog monitoring)
- Productivity skills (email, documents, notes)
- MCP integration skills
- Custom user skills
2026-07-05 02:31:15 -04:00

5.5 KiB

Telegram Adapter Diagnostics

Quick Health Check

# 1. Is the adapter connected?
journalctl --user -u hermes-gateway --since '10 min ago' --no-pager | grep -i "telegram" | tail -5

# 2. Is the proxy working?
curl -s -o /dev/null -w "%{http_code}" --proxy http://127.0.0.1:7890 https://api.telegram.org

# 3. Is the bot alive?
# (replace TOKEN with actual bot token from ~/.hermes/.env)
curl -s "https://api.telegram.org/bot<TOKEN>/getMe" --proxy http://127.0.0.1:7890

# 4. Is the bot in the target group?
curl -s "https://api.telegram.org/bot<TOKEN>/getChatMember?chat_id=<GROUP_ID>&user_id=<BOT_ID>" --proxy http://127.0.0.1:7890

Diagnosing "Bot Not Processing Group Messages"

Step 1: Check if adapter is alive

journalctl --user -u hermes-gateway --no-pager --since '1 hour ago' | grep "\[Telegram\]" | tail -10
  • If only crash/reconnect-failed logs → adapter is dead, restart gateway
  • If "Reconnecting telegram" entries → watcher is alive, proxy may be down
  • If no Telegram logs at all → either adapter connected silently or watcher died

Step 2: Check if proxy is the issue

curl -s -o /dev/null -w "%{http_code}" --proxy http://127.0.0.1:7890 https://api.telegram.org
# 302 = proxy working, timeout/ConnectError = proxy down

Step 3: Check bot group membership

# Get bot info
python3 -c "
import json, urllib.request
with open('/home/openclaw/.hermes/.env') as f:
    token = [l.split('=',1)[1].strip() for l in f if l.startswith('TELEGRAM_BOT_TOKEN')][0]
proxy = urllib.request.ProxyHandler({'https': 'http://127.0.0.1:7890'})
opener = urllib.request.build_opener(proxy)
resp = opener.open(f'https://api.telegram.org/bot{token}/getChatMember?chat_id=<GROUP_ID>&user_id=<BOT_ID>')
print(json.loads(resp.read()))
"

Step 4: Check config

In ~/.hermes/config.yaml, under telegram::

  • free_response_chats or free_response_channels must include the group ID
  • channel_prompts can be set per group for custom behavior
  • allowed_chats when set acts as a whitelist (empty = no restriction)
  • require_mention: true means bot only responds when @mentioned (unless in free_response_chats)

Editing channel_prompts: Values are unicode-escaped with YAML line continuations (\ at line end). Don't use patch() — it breaks on multi-line unicode. Use Python regex instead:

import re
with open('/home/openclaw/.hermes/config.yaml') as f:
    content = f.read()
# Match across line breaks with [\s\\]* for YAML continuations
pattern = re.compile(r'\\uXXXX[\s\\]*\\uYYYY')
content = pattern.sub(r'\\uNEW1\\uNEW2', content)
with open('/home/openclaw/.hermes/config.yaml', 'w') as f:
    f.write(content)
# Always verify YAML validity after
import yaml; yaml.safe_load(open('/home/openclaw/.hermes/config.yaml'))

The same prompt string is duplicated across slack, discord, mattermost, and telegram sections — replace in all 4.

Step 5: Check forwarder

# Is the forwarder running?
docker ps | grep forwarder

# Check forwarder config
sqlite3 ~/TelegramForwarder/db/forward.db "SELECT * FROM chats;"
sqlite3 ~/TelegramForwarder/db/forward.db "SELECT * FROM forward_rules;"
sqlite3 ~/TelegramForwarder/db/forward.db "SELECT * FROM keywords;"

# Check recent forwarding activity
docker logs telegram-forwarder --tail 20 | grep "已发送"

Gateway Restart Constraints

  • Cannot restart from inside the gateway: hermes gateway restart is blocked when run from a gateway session (SIGTERM propagation prevention)
  • kill <PID> also blocked: Security scanner intercepts kill commands targeting the gateway PID. Terminal returns Blocked: cannot restart or stop the gateway from inside the gateway process.
  • Workaround 1: User runs hermes gateway restart from a separate SSH shell (recommended)
  • Workaround 2: systemctl --user restart hermes-gateway from a separate shell
  • Workaround 3: Write a small helper script to /tmp/ and ask user to run it manually

Reconnect Watcher Architecture

When a platform adapter hits a fatal error:

  1. _set_fatal_error() → sets adapter._running = False
  2. _handle_adapter_fatal_error() → disconnects adapter, removes from self.adapters
  3. If fatal_error_retryable=True → adds to self._failed_platforms with backoff
  4. _platform_reconnect_watcher() → background asyncio task, retries with exponential backoff (30s→300s cap)

Known bug: The watcher task can silently die. No upstream fix yet. Workaround: external gateway restart.

Root cause (observed 2026-06-23): When multiple platforms crash simultaneously (Telegram + WeChat + QQBot), the watcher may die. Evidence: journalctl shows the fatal error at 09:27 but ZERO "Reconnecting telegram" or "Reconnect telegram error" entries afterward — the watcher's while self._running loop exited without logging. On a previous crash (2026-06-22) with only Telegram affected, the watcher worked correctly and kept retrying with backoff.

Edge case — already-queued platform: _handle_adapter_fatal_error() checks adapter.platform not in self._failed_platforms before queueing. If Telegram was already in the queue from a prior failure, the new fatal error doesn't re-queue or reset the backoff. The existing entry's next_retry timer may be at the 300s cap, causing long silent gaps between reconnection attempts even when the watcher IS alive.

Definitive diagnosis: If after a crash you see zero reconnection attempt logs for >10 minutes, the watcher is dead. Restart the gateway from an external shell.