# dws-chat 命令参考

> 主流程见 `../SKILL.md`：用户给群名时禁止索要 groupId（先 `chat search`）；未登录跑 `get_device_auth_link.py`（禁止让用户自跑 `dws auth login`）。
>
> ⚠️ flag 权威来源：`dws <cmd> --help` / `dws schema <path>` 输出，本文仅作参考。

---

## 搜索群 (chat search)

```bash
dws chat search --query "<群名关键词>" [-f json|table|raw]
```

返回字段：
- `title`：群名称
- `openConversationId`：群 ID（发消息时直接使用）
- `memberCount`：成员数
- `gmtCreateAt`：群创建时间

---

## 查询群消息 (chat message list)

> ⚠️ **`dws mcp chat list_conversation_message_v2` 已从 CLI 移除**（v1.0.30 起 `dws mcp chat list_conversation_message_v2 --help` 不再存在该子命令）。群聊历史统一用 **`dws chat message list --group`**。

```bash
dws chat message list \
  --group "<openConversationId>" \
  --time "<yyyy-MM-dd HH:mm:ss>" \
  --limit <n> \
  --forward \
  -f json
```

参数（以 `dws chat message list --help` 为准）：
- `--group`：群会话 **openConversationId**（必填，仅群聊；先 `dws chat search` 获取）
- `--time`：起始时间，格式 `yyyy-MM-dd HH:mm:ss`
- `--limit`：返回条数（默认 50）
- `--forward`：拉取方向，默认 **true**（从旧到新）

### `--time` / `--forward` 取舍（实测要点）

| 诉求 | 推荐组合 |
|------|----------|
| 拉「今天 / 指定日期之后」 | **必须** `--time "<YYYY-MM-DD> 00:00:00" --forward --limit 100` |
| 拉「最近 N 条」无时间限制 | `--forward=false --limit <N>` |
| 指定时间窗口 | `--time "<start>" --forward` + 分页 |

⚠️ **不带 `--time` + `--forward=true`** 对部分群（尤其挂 CSpace 协作空间的群，`chat search` 返回 `extension.newCSpaceIdIM` 非空）**会返回空数组**。拉某天消息务必显式 `--time`。

⚠️ 返回 0 条时的诊断顺序：
1. 改 `--forward=false --limit 50`（从新到旧拿最近）
2. 去掉 `--time` 后再用 `--forward=false`
3. `chat conversation-info --group <id>` 确认群和成员关系
4. 仍 0 条才告知用户「无可见消息」；**不要**归因为「机器人不在群」（dws 用用户身份读取）

### 分页 / 补拉

- `hasMore=true` 时，用当前页最后一条的 `createTime` 作为下次 `--time` 继续拉
- ⚠️ `--time` 格式为 `yyyy-MM-dd HH:mm:ss`，**不是**数字时间戳 cursor

---

## 发送群消息（用户身份）(chat message send)

```bash
dws chat message send --group "<openConversationId>" --title "<标题>" --text "<内容>" [-f json]
```

参数：
- `--group`：群 ID（必填）
- `--title`：消息卡片标题（**必填**）
- `--text`：消息正文，支持 Markdown（必填）

返回 `success: true` 表示发送成功，`open_taskId` 可用于追踪。

---

## 发送单聊消息（用户身份）(chat message send)

```bash
dws chat message send --user "<userId>" --title "<标题>" --text "<内容>" [-f json]
```

- `--user`：接收人 userId（必填，通过 `contact user search` 获取）
- `--title`：**必填**
- `--text`：消息正文（必填）

---

## 发送机器人消息（群）(chat message send-by-bot)

```bash
dws chat message send-by-bot --robot-code "<robot-code>" --group "<openConversationId>" --title "<标题>" --text "<内容>" [-f json]
```

参数：
- `--robot-code`：机器人 Code（通过 `bot search` 获取）
- `--group`：群 ID
- `--title`：消息标题（**必填**）
- `--text`：消息正文（必填）

---

## 搜索用户 (contact user search)

```bash
dws contact user search --query "<姓名/工号/手机号关键词>" [-f json]
```

返回字段：
- `name`：姓名
- `userId`：用户 ID（发消息用）
- `openDingTalkId`：Open DingTalk ID（单聊用）
- `title`：职位

---

## 搜索机器人 (chat bot search)

搜索**当前用户有权限使用/创建的机器人**（用于 `add-bot`、`send-by-bot`）。

```bash
dws chat bot search [--name "<机器人名关键词>"] [--page 1] [--size 20] [-f json]
```

返回 `robotList[]`（字段名以 JSON 为准），常见：
- `robotCode`：机器人代码（`add-bot` / `send-by-bot` 必填）
- `robotName`：机器人名称

---

## 将机器人加入现有群 (chat group members add-bot)

把已选机器人加入用户所在的**已有群聊**（非建群）。

```bash
dws chat group members add-bot \
  --robot-code "<robotCode>" \
  --id "<openConversationId>" \
  [--yes] \
  [-f json]
```

| 参数 | 说明 |
|------|------|
| `--robot-code` | `chat bot search` 返回的 `robotCode` |
| `--id` | 群的 **openConversationId**（先 `chat search --query "群名"`） |
| `--yes` | 用户确认后加（修改群成员，属危险操作） |

**推荐顺序**：`bot search` → `chat search` → 向用户确认 → `add-bot --yes`

若报错 `PAT_MEDIUM_RISK_NO_PERMISSION`，需补 OAuth scope（如 `chat.group.members:add-bot`），按 CLI 错误提示完成授权。

---

## 查询会话信息 (chat conversation-info)

获取单聊会话 ID（用于查询与某人的单聊消息）：

```bash
dws chat conversation-info --open-dingtalk-id "<openDingTalkId>" [-f json]
```

返回：`openConversationId`（单聊 ID）

拿到单聊 ID 后，用 `--group` 参数查询消息：
```bash
dws chat message list --group "<单聊openConversationId>" --limit 20 -f json
```

---

## 获取群成员列表 (chat group members list)

```bash
dws chat group members list --id "<openConversationId>" [-f json]
```

---

## 添加群成员 (chat group members add)

```bash
dws chat group members add --id "<openConversationId>" --users "<userId1,userId2>" [-f json]
```

---

## 常见问题

**Q: 提示 `--title is required`？**  
群消息和单聊消息的 `--title` 均必填，不可省略。

**Q: 发送失败，提示权限不足？**  
部分操作需要额外的 OAuth 授权 scope，错误返回中会附带授权链接，按提示在浏览器完成授权即可。

**Q: 想用机器人发消息？**  
用 `send-by-bot` 子命令，需指定 `--robot-code`，先通过 `dws chat bot search` 查到机器人代码。

**Q: 查询单聊消息？**  
先用 `dws chat conversation-info --open-dingtalk-id <openDingTalkId>` 获取单聊会话 ID，再用 `dws chat message list --group <单聊ID>` 查询。

---

## Recovery 闭环（如遇错误）

当命令失败且 stderr 包含 `RECOVERY_EVENT_ID=<event_id>` 时：

```bash
# 1. 执行 recovery 获取分析包
dws recovery execute --event-id <event_id> -f json

# 2. 读取 RecoveryBundle，判断 decision_owner
#    - 若为 agent：基于完整 bundle 做整体判断
#    - 若为 handoff：不盲猜，继续用 probe_results 中的真实参数

# 3. 恢复尝试结束后执行 finalize
dws recovery finalize --event-id <event_id> --outcome recovered|failed|handoff --execution-file execution.json -f json
```

`execution.json` 最小必须包含：`actions`、`attempts`、`result`、`error_summary`
