# QQ Bot / Hermes Gateway 推送故障诊断

当 QQ Bot 推送失败（cron job 或 send_message 报错）时，按以下顺序排查。

## 1. 从 Cron Job 错误入手

```bash
cronjob(action='list')  # 查看 last_delivery_error
```

典型错误模式：

| 错误 | 根因 |
|------|------|
| `Not connected` | QQ Bot 适配器未连接（离线/WebSocket断连） |
| `Temporary failure in name resolution` | DNS 解析失败（本地 DNS 问题） |
| `Name or service not known` | 同上，DNS 不通 |
| `WebSocket closed` | QQ API WebSocket 连接断开 |

## 2. 检查 Gateway 状态

```bash
cat ~/.hermes/gateway_state.json
# 关注 platforms.qqbot.state 字段
# state=connected → 连接正常
# state=disconnected/reconnecting → 出问题了
```

输出示例：
```json
{
  "gateway_state": "running",
  "platforms": {
    "qqbot": {
      "state": "connected",
      "updated_at": "2026-06-26T11:30:37.726746+00:00"
    }
  }
}
```

## 3. 检查 Gateway 日志

```bash
strings ~/.hermes/logs/gateway.log | grep -i "qqbot"
# 或筛选更全面
strings ~/.hermes/logs/gateway.log | grep -iE "qqbot|error|disconnect"
```

关键日志标记（按时间序）：

| 日志 | 含义 |
|------|------|
| `Not connected` | QQ Bot 刚启但尚未就绪 |
| `Still not connected after 15s` | 连接超时 |
| `Disconnected` | WebSocket 已断开 |
| `Access token refreshed` | Token 刷新成功（正常） |
| `WebSocket connected` | WebSocket 长连建立 ✅ |
| `Connected` + `Identify sent` | 适配器登录完成 ✅ |
| `Ready, session_id=...` | 完全就绪，可收发消息 ✅ |

## 4. 检查进程/容器

```bash
# QQ Bot 是 Hermes gateway 内部适配器，没有独立进程
# 检查 gateway 本身运行状态
systemctl --user status hermes-gateway | head -10
```

## 5. 常见根因与修复

### DNS 故障（最常见）
- 错误: `Temporary failure in name resolution`
- 影响: QQ Bot 和微信同时断连
- 修复: 重启 gateway 让适配器重新解析 DNS
  ```bash
  # 注意：agent 内可能被拦截，需外部 shell 执行
  systemctl --user restart hermes-gateway
  ```
- 验证: 重启后检查 `gateway_state.json` 中 qqbot.state=connected

### Gateway 重启
- 错误: `Not connected` 后紧跟 `Disconnected`
- 修复: 等待 gateway 自动恢复（~30s）
- 验证: qqbot 日志出现 `Ready, session_id=...` 即恢复

### WebSocket 异常断开
- 错误: `WebSocket closed` 无重连
- 修复: 重启 gateway
- 验证: 同上

## 6. 验证推送

修复后立即测试：

```python
cronjob(action='create',
        deliver='qqbot:B1EF50442496D57C1B4F3890501C34C2',
        prompt='直接原样输出：✅ QQ Bot 推送测试 - ' + __import__('datetime').datetime.now().strftime('%H:%M:%S'),
        schedule='2099-01-01T00:00:00')
cronjob(action='remove', job_id='<返回的job_id>')
```

## 7. 系统级网络健康

如果 DNS 反复故障：
```bash
# 检查 DNS 配置
cat /etc/resolv.conf
# 测试 QQ API DNS 解析
nslookup api.sgroup.qq.com
# 或换公共 DNS（8.8.8.8 / 114.114.114.114）
```
