# 飞书 bot 在群里静默、私聊却正常 —— 诊断配方

实证：2026-06-22 群「小Maggie工作群」(`oc_a927f86118216c36cb9394b0e95f2a11`)。WeiWei/颜伽艺在群里 @小Maggie 无反应，私聊正常。

## 症状
- 用户在飞书**群**里 @小Maggie，bot 不回。
- 但**私聊**（DM）发消息 bot 正常回复。
- gateway 进程活着，飞书连接日志显示 `[Feishu] Connected in websocket mode`。

## 根因类别（按概率排序）
1. **身份不匹配（display-name 撞名）** — 群里被 @ 的「小Maggie」其实是**另一个 bot 身份**（不同 open_id），不是当前 gateway 跑的那个 app。常见触发：做过「新 Agent 迁移 / provisioning」，新身份被拉进群并占用了群里「小Maggie」的 @ 目标。群 @ 解析到新身份的 open_id，旧 gateway（旧 app_id）的事件流里根本收不到这条，所以"不回"。**DM 仍正常，因为 DM 按会话路由、不按 @ 身份。** ← 本会话确诊就是这一类。
2. 订阅/连接在空窗后失效（同类：企微 errcode 846609 静默两小时）。
3. 发送侧失败：历史上见过 `[99992402] field validation failed`（连 plain-text 兜底也失败）——这是**发**不出去，不是**收**不到，必须区分。

## 诊断步骤（命令均已实测可用）
所有 lark-cli 命令加 `LARK_CLI_NO_PROXY=1` 前缀，避免凭据走 HTTPS_PROXY。

**1. 确认 bot 在哪些群、拿群 chat_id：**
```bash
LARK_CLI_NO_PROXY=1 lark-cli im +chat-list --as bot
```

**2. 查 gateway 实际收到了这个群的哪些 inbound：**
```bash
grep "oc_<群id>" ~/.hermes/logs/gateway.log | grep -iE "Inbound|inbound message"
```
若最后一条 inbound 停在很久以前、之后空白 → gateway 根本没收到新群消息（排除"收到但没回"）。

**3. 拉群的真实消息历史，和第 2 步对照：**
> bot 身份读群历史会因缺 scope 失败：`+chat-messages-list --as bot` → 230027 / 99991672，缺 `im:chat:readonly` `im:chat.members:read`。**改用 `--as user`**。
```bash
LARK_CLI_NO_PROXY=1 lark-cli im +chat-messages-list \
  --chat-id oc_<群id> --as user --order desc --page-size 30 --no-reactions --format json
```
返回 JSON 字段：`data.messages[]`，每条含 `content`(直接是文本)、`create_time`、`sender.{id,sender_type,name}`、`mentions[].{id,name}`。**注意不是 `items`/`body`** —— 用错字段会得到 `count=0` 的假空，误判成"群里没人发"。

**4. 关键判定 —— 看 @ 到的是谁的 open_id：**
群消息的 `mentions[].id` 就是被 @ 对象的 open_id。和当前 gateway 的 bot 身份对比：
```bash
# 当前 gateway 用的飞书 app_id
python3 -c "import yaml;c=yaml.safe_load(open('/home/maggie/.hermes/config.yaml'));print(c['gateway']['platforms']['feishu'].get('extra',{}).get('app_id'))"
```
- 对照法：第 2 步里 gateway 正常工作时段，bot 在群里发言的 sender 是 `app cli_<app_id>`。拿这个和第 4 步 mentions 里「小Maggie」的 open_id 比。
- 若群历史里「小Maggie」被 @ 的 open_id ≠ 当前 gateway bot 的身份 → **确诊身份不匹配**：群里有两个同名「小Maggie」，大家 @ 错了。

**5. 旁证：DM 是否正常。** 私聊 inbound 在 gateway.log 里照常出现 → 证明连接/订阅活着，问题收敛到"群 @ 身份"这一层。

## 结论怎么报
- 这是技术/配置问题，按铁律修复决策交给技术负责人（WeiWei/Scott），不自作主张改。
- 给三个方向：①新 Agent 接管群（@ 目标对到新身份 / 把新身份订阅配通）；②仍由旧 bot 管群（移除或换回群里的新「小Maggie」）；③过渡期走私聊。

## Pitfalls
- **别一看 bot 没回就说"掉线了"** —— 先分清"没收到（群 @ 身份不对 / 订阅失效）" vs "收到但没发出去（send 失败 99992402）"。
- **lark-cli 读群历史/群成员要用 `--as user`**，bot 身份缺 scope。要让 bot 自己能读，得在开放平台给 `cli_xxx` 补 `im:chat:readonly` `im:chat.group_info:readonly` `im:chat.members:read`。
- **JSON 字段名**：`+chat-messages-list` 返回 `data.messages[].content`，不是 `items[].body`。用错字段会得到误导性的 `count=0`。
- **重启时 DNS 抽风是环境问题，不是代码问题** —— 重启日志里若有 `Temporary failure in name resolution`（open.feishu.cn / openws.work.weixin.qq.com），那是当时网络/DNS 短暂故障；飞书多半自己重连上了，企微可能没重连成功，单独核实企微在线状态即可，别当成代码 bug 去改。
