- 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
109 lines
5.5 KiB
Markdown
109 lines
5.5 KiB
Markdown
# Telegram Adapter Diagnostics
|
|
|
|
## Quick Health Check
|
|
|
|
```bash
|
|
# 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
|
|
```bash
|
|
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
|
|
```bash
|
|
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
|
|
```bash
|
|
# 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:
|
|
```python
|
|
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
|
|
```bash
|
|
# 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.
|