auto backup 2026-07-02 11:00

This commit is contained in:
2026-07-02 11:00:05 +08:00
parent 022b6edbe4
commit c7ff34d012
199 changed files with 43050 additions and 0 deletions
+95
View File
@@ -0,0 +1,95 @@
# 错误码说明
全产品错误参考 + 调试流程。Agent 遇到错误时查阅此文档。
## 错误返回格式
```json
{"success": false, "code": "InvalidParameter", "message": "baseId is required"}
{"success": false, "code": "AUTH_TOKEN_EXPIRED", "message": "Token验证失败"}
{"success": false, "code": "PermissionDenied", "message": "无权限访问该资源"}
```
## 错误分类与 Agent 行为
### 可自行修复
- 参数缺失 / 格式错误 / ID 无效 → 检查参数后修正重试
### 需用户介入
- 权限不足 / 资源不存在 / 配额超限 → 报告完整错误信息给用户,不要自行尝试替代方案
## 通用错误
- 请求超时 — 网络慢或服务端响应慢 → `--timeout 60` 重试
- 网络连接失败 — 无法连接 MCP Server → 用最简命令验证: `dws contact user get-self --format json`
- stderr 出现 `RECOVERY_EVENT_ID=<event_id>` — runtime 失败已被 CLI 捕获 → 优先执行 `dws recovery execute --event-id <event_id> --format json`
## Recovery 闭环
- `dws recovery plan --last|--event-id <event_id> --format json`:读取失败快照并生成恢复计划
- `dws recovery execute --last|--event-id <event_id> --format json`:生成带 `doc_search``probe_results``agent_task` 的分析包
- `dws recovery finalize --event-id <event_id> --outcome recovered|failed|handoff --execution-file execution.json --format json`:回写恢复结果
执行 `finalize` 时:
- `execution-file` 至少应包含 `actions``attempts``result``error_summary`
- 兼容旧格式:`action` + 数值型 `attempts`
- 若 recovery bundle 已进入 unknown/agent 路线,不要把 `human_actions` 视为最终结论;必须结合完整 bundle 判断
更多字段解释见 [recovery-guide.md](./recovery-guide.md)。
---
## aitable 高频错误
> 参数体系: `baseId / tableId / fieldId / recordId`。CLI flag 用 kebab-case`--base-id`),JSON 内用 camelCase`baseId`)。
- 参数缺失 / 无效请求 — 还在用旧参数 `dentryUuid` / `--doc` / `--sheet` → 改用 `--base-id` / `--table-id` / `--field-id` / `--record-ids`
- 参数传了但服务端没收到 — flag 用了 camelCase(如 `--baseId`)→ flag 用 kebab-case: `--base-id <ID>`
- `record query --filters` 无结果 — 单选/多选过滤用了 option name 而非 id → 先 `field get` 读取 options,用 option id 过滤
- record create/update 失败 — `cells` key 用了字段名(应为 fieldId);特殊字段格式错误 → 先 `table get` 拿字段目录;url 传 `{"text":"..","link":".."}`
- 更新选项后历史数据异常 — 更新 options 没传完整列表 / 没保留原 id → 先 `field get` 取完整配置,保留已有 option 的 id
- `cannot delete the last table` — 该表是 Base 最后一张表 → 先新建表再删旧表,或用 `base delete`
- `formula` 类型 `not supported yet` — 部分字段类型暂不支持 API 创建 → 复杂字段拆开单独创建,先建基础结构
**排查链路**: `base list``base get`(→tableId) → `table get`(→fieldId) → `record query`(→recordId)。别跳步,别猜 ID。
**批量上限**: record 100 条 / field 15 个 / table·field 详情 10 个。
---
## approval 高频错误
- approve/reject 缺少 taskId — 未先获取审批任务 → 先 `approval tasks --instance-id <ID>` 获取 taskId
- list-initiated 缺少 processCode — 未查询审批表单 → 先 `approval list-forms` 获取 processCode
- 撤销审批失败 — 非本人发起的审批 → `revoke` 只能撤销自己发起的审批
---
## chat 高频错误
- 参数互斥报错 — `--group``--users` 同时传入 → 群聊用 `--group`,单聊用 `--users`,二者互斥
- 群不存在 — openConversationId 不正确 → `chat search --query "群名"` 获取正确 ID
- 机器人无法添加到群 — 当前用户非群管理员 → 报告给用户,需群管理员操作
- Webhook Token 无效 — token 不正确或已失效 → 确认 Webhook Token 来源正确
- 添加/移除群成员失败 — userId 不正确或无权限 → 先 `contact user search` 确认 userId,需当前用户为群管理员
---
## calendar 高频错误
- 时间格式错误 — 未使用 ISO-8601 格式 → 标准格式: `2026-03-10T14:00:00+08:00`
- 会议室搜索报错 / 返空 — 企业会议室超 100 条未分组查询 → 先 `room list-groups` → 按 `--group-id` 逐组搜索
- 参与者 / 会议室添加失败 — eventId 不正确 → 先 `event list``event create` 获取正确 eventId
---
## contact 高频错误
- `dept list-children` 报错 — `--id` 传了非整数值 → deptId 必须为整数,从 `dept search` 获取
---
## 通用排查三步法
1. **确认 ID** — 从最顶层资源逐级获取,不猜 ID、不跳步
2. **确认参数** — flag 用 kebab-caseJSON 用 camelCase;特殊字段查产品参考文档确认格式
3. **确认限制** — 检查批量上限和已知约束(各产品注意事项见对应产品参考文档)
+105
View File
@@ -0,0 +1,105 @@
# 易混淆操作与字段规则
## 易混淆操作 (高风险场景必读)
| 用户说的 | 正确命令 | 不是这个 |
|---------|----------|---------|
| "创建一个新表格 (Base)" | `base create` | 不是 `table create` |
| "在表格里加一个数据表" | `table create` | 不是 `base create` |
| "看看表格里有哪些表" | `base get` | 不是 `field get` |
| "看看表里有哪些列" | `field get` / `table get` | 不是 `base get` |
| "搜索表格" (找 Base) | `base search` | 不是 `record query` |
| "搜索记录" (查表内数据) | `record query` | 不是 `base search` |
| "删掉这个数据表" | `table delete` | 不是 `record delete` |
| "删掉这条数据" | `record delete` | 不是 `table delete` |
| "删掉这个列" | `field delete` | 不是 `record delete` |
| "改字段类型" | 先 `field delete``field create` | `field update` **不能改类型** |
| "移动字段/调整字段顺序" | **不支持**,需在钉钉界面手动拖拽 | 没有 `reorder`/`move` 命令 |
## field 子命令总览
> ⚠️ field 有且仅有以下 **4 个** 子命令,没有 `list`、`reorder`、`move`
| 子命令 | 用途 |
|-------|------|
| `field get` | 获取字段详情(含完整 config/options)。**不是 `field list`** |
| `field create` | **创建字段(支持通过 config.options 设置选项)** |
| `field update` | 更新字段名称或配置(**不能改类型**) |
| `field delete` | 删除字段(不可逆) |
## 字段创建时设置 config(重要)
创建 singleSelect/multipleSelect 字段时,**必须在 `--fields``config.options` 中设置选项**
```bash
# 创建带选项的单选字段
dws aitable field create --base-id <BASE_ID> --table-id <TABLE_ID> \
--fields '[{"fieldName":"优先级","type":"singleSelect","config":{"options":[{"name":"高"},{"name":"中"},{"name":"低"}]}}]' \
--format json
# 建表时也可以直接带选项字段
dws aitable table create --base-id <BASE_ID> --name "任务表" \
--fields '[{"fieldName":"任务","type":"text"},{"fieldName":"状态","type":"singleSelect","config":{"options":[{"name":"待办"},{"name":"进行中"},{"name":"已完成"}]}}]' \
--format json
```
> ⚠️ **不要混淆**
> - **字段创建**field create / table create 的 --fields):通过 `config.options` 设置选项,创建时就指定
> - **记录写入**record create / record update 的 --records):只能写入已存在的选项名称
## 主字段约束(table create 必读)
> ⚠️ `table create` 的 `--fields` 中,**第一个字段自动成为主字段**。
> 主字段只能是 **text** 类型,不能是 attachment、checkbox、formula 等。
**实际影响**:当用户要求创建的字段不适合做主字段时(如附件、复选框),必须:
1. 先放一个 text 字段作为第一个字段(主字段)
2. 再放用户要求的字段
3. **告知用户**为何多了一个字段
```bash
# 例: 用户要求只创建附件字段 → 附件不能做主字段,必须先加 text 主字段
dws aitable table create --base-id <BASE_ID> --name "产品图片" \
--fields '[{"fieldName":"名称","type":"text"},{"fieldName":"产品图片","type":"attachment"}]' \
--format json
```
## 只读字段 (不可写入)
以下类型的字段不可写入, 执行 `field get` / `table get` 后识别并跳过:
- 创建时间 / 修改时间 (系统自动)
- 创建人 / 修改人 (系统自动)
- 自动编号
- 公式字段
- 引用字段
## 记录写入格式(record create / record update
> 以下是 **记录写入** 时 cells 的格式,不是字段创建的格式。
| 类型 | 写入格式 | 读取返回格式 |
|------|----------|-------------|
| text | `"fldXXX":"文本值"` | `"fldXXX":"文本值"` |
| number | `"fldXXX":123` | `"fldXXX":123` |
| singleSelect | `"fldXXX":"选项名"` (必须是已存在的选项) | `"fldXXX":{"id":"x","name":"选项名"}` |
| multipleSelect | `"fldXXX":["选项1","选项2"]` (必须是已存在的选项) | `"fldXXX":[{"id":"x","name":"选项1"}]` |
| date | `"fldXXX":"2026-03-04"` 或 Unix ms | `"fldXXX":1709510400000` (ms) |
| user | `"fldXXX":[{"userId":"123"}]` | `"fldXXX":{"uid":"123"}` |
| attachment | `[{"fileToken":"<token>"}]` — 需先通过 `attachment upload` 获取,见下方 ⬇️ | `[{"url":"...","filename":"...","size":N}]` |
## ⚠️ 附件上传完整流程(必读!)
> **不要**使用钉盘 (drive) 上传来替代此流程!钉盘 fileId **无法**写入 attachment 字段。
附件字段写入使用 `upload_attachment.py` 脚本,**2 步**完成:
```bash
# 步骤 1: 一键上传文件(脚本内部自动完成 prepare + PUT to OSS
python3 scripts/upload_attachment.py <BASE_ID> /path/to/photo.png
# 输出: { "fileToken": "ft_xxx", "fileName": "photo.png", "size": 1024 }
# 步骤 2: 在 record create/update 中使用 fileToken
dws aitable record create --base-id <BASE_ID> --table-id <TABLE_ID> \
--records '[{"cells":{"fldAttachId":[{"fileToken":"ft_xxx"}]}}]' --format json
```
+104
View File
@@ -0,0 +1,104 @@
# 全局参考
## 认证
```bash
# 首次: OAuth 设备流登录 (钉钉扫码授权)
dws auth login
# 查看状态
dws auth status
# 退出
dws auth logout
# 重置本地凭证 (Token 解密失败时使用)
dws auth reset
```
登录后自动管理 token 刷新,日常使用无需重复登录。
| Token | 有效期 | 说明 |
|-------|--------|------|
| Access Token | 2 小时 | 调用 API 的凭证,过期自动刷新 |
| Refresh Token | 30 天 | 换新 Access Token,使用后轮转 |
30 天内使用一次即自动续期。
### 认证失败处理
- 命令返回 `AUTH_TOKEN_EXPIRED` / `USER_TOKEN_ILLEGAL` / "Token验证失败" → 执行 `dws auth login` 重新登录
### Headless 环境 (CI/CD)
```bash
# 通过环境变量配置认证(无需交互式登录)
export DWS_CLIENT_ID=<your-app-key>
export DWS_CLIENT_SECRET=<your-app-secret>
dws auth login
# 或使用 --device 设备流登录(远程服务器/Docker)
dws auth login --device
```
refresh_token 单设备独占,远程刷新后源设备凭证失效。
## Recovery
当 runtime/MCP 命令失败且 stderr 额外输出 `RECOVERY_EVENT_ID=<event_id>` 时,说明 CLI 已经持久化了失败快照,可进入 recovery 闭环:
```bash
dws recovery plan --event-id <event_id> --format json
dws recovery execute --event-id <event_id> --format json
dws recovery finalize --event-id <event_id> --outcome recovered|failed|handoff --execution-file execution.json --format json
```
- `plan` / `execute` 也支持 `--last`,但 `--last``--event-id` 互斥
- recovery 文件保存在 `DWS_CONFIG_DIR/recovery/`
- CLI 会自动清理 30 天前的 recovery 文件和事件记录
- recovery 自己发起的文档检索与只读 probe 不会再创建新的 recovery 事件
更多闭环要求见 [recovery-guide.md](./recovery-guide.md)。
## 全局标志
| 标志 | 短名 | 说明 | 默认 |
|------|:---:|------|------|
| `--format` | `-f` | 输出格式: json / table / raw | json |
| `--jq` | | jq 表达式过滤输出 (如: `.items[] \| .name`) | 无 |
| `--fields` | | 筛选输出字段 (逗号分隔, 如: name,id,status) | 无 |
| `--verbose` | `-v` | 详细日志 | false |
| `--debug` | | 调试日志 | false |
| `--yes` | `-y` | 跳过确认提示 | false |
| `--dry-run` | | 预览操作不执行 | false |
| `--timeout` | | HTTP 超时 (秒) | 30 |
| `--mock` | | Mock 数据 (开发用) | false |
| `--client-id` | | 覆盖 OAuth Client ID | 无 |
| `--client-secret` | | 覆盖 OAuth Client Secret | 无 |
## 输出格式
### --format json (机器可读, 默认)
```json
{"success": true, "body": {...}}
```
### --format table (人类可读)
```
已创建 AI 表格 "项目管理" (UUID: abc123)
下一步:
dws aitable base get --base-id abc123
```
## 环境变量
| 变量 | 说明 |
|------|------|
| `DWS_CONFIG_DIR` | 覆盖默认配置目录 |
| `DWS_SERVERS_URL` | 自定义服务发现端点 |
| `DWS_CLIENT_ID` | 覆盖 OAuth Client ID (DingTalk AppKey) |
| `DWS_CLIENT_SECRET` | 覆盖 OAuth Client Secret (DingTalk AppSecret) |
凭证优先级: `--token` > `DWS_CLIENT_ID`/`DWS_CLIENT_SECRET` > OAuth 加密存储 (.data)
+114
View File
@@ -0,0 +1,114 @@
# 意图路由指南
当用户请求难以判断归属哪个产品时,参考本指南。
## 易混淆场景快速对照表
| 用户说... | 真实意图 | 应该用 | 不要用 | 理由 |
|-----------|----------|--------|--------|------|
| "搜一下 OAuth2 接入文档" | 搜索开发文档 | `devdoc` | — | 搜索开放平台技术文档,不是钉钉内部内容 |
| "帮我建一个项目跟踪表" | 创建数据表格 | `aitable` | `todo` | 涉及结构化数据/行列操作,不是个人待办 |
| "帮我记一下明天要做的事" | 创建个人待办 | `todo` | `aitable` | 个人待办提醒,非数据表 |
| "帮我建一个明天下午的日程" | 日历日程 | `calendar` | — | 日历日程管理(可含参与者/会议室)|
| "帮我看看收到的日报" | 日志收件箱 | `report` | `todo` | 钉钉日志系统(日报/周报),不是待办 |
| "帮我创建一个待办提醒" | 个人待办 | `todo` | `report` | 个人任务提醒,不是日志汇报 |
| "帮我提交请假审批" | 发起审批 | `oa` | — | 审批流程,不是待办或日志 |
| "帮我建一个项目群" | 创建群聊 | `chat group create` | — | 群聊管理,不是日历日程 |
| "把张三拉进群" | 添加群成员 | `chat group members add` | — | 先查 userId,再添加 |
| "让机器人在群里发个通知" | 机器人群发 | `chat message send-by-bot` | `chat message send-by-webhook` | 企业内部机器人发消息,需 robotCode |
| "通过 Webhook 发告警到群里" | Webhook 告警 | `chat message send-by-webhook` | `chat message send-by-bot` | 自定义机器人 Webhook,需 token |
| "给张三发一条机器人单聊消息" | 机器人单聊 | `chat message send-by-bot --users` | — | 机器人批量单聊,先查 userId |
---
## 典型场景详解
### 1. aitable vs todo — 表格数据 vs 待办任务
**用 `aitable` 的场景**
- "创建一个表格记录团队成员信息" — 结构化数据,有行列
- "在表格里加一列'状态'字段" — 字段/列操作
- "查一下表格里所有优先级为高的记录" — 数据筛选和查询
- "用项目管理模板建一个表" — 模板创建
- 用户提到"多维表"、"Base"、"数据表"、"记录"
**用 `todo` 的场景**
- "帮我记一下这周要做的事" — 个人任务管理
- "创建一个待办提醒" — 任务提醒
**判断关键**:有没有行列/字段/记录概念?有→ `aitable`;个人任务清单 → `todo`
---
### 2. devdoc — 开发文档搜索
**用 `devdoc` 的场景**
- "API 调用报错 403 怎么解决" — 开发调试问题
- "搜一下 OAuth2 接入文档" — 开放平台技术文档
- "CLI 命令出错了怎么办" — CLI 使用错误
- 用户提到"开发"、"API"、"调用错误"
---
### 3. report vs todo — 日志 vs 待办
**用 `report` 的场景**
- "帮我看看收到的日报" — 日志收件箱
- "帮我写/提交今天的日报(钉钉日志模版)" — 先 `report template list` / `template detail`,再 `report create`
- "有什么日志模版" — 查看模版
- "看看这个日志的已读统计" — 阅读状态
- "我发过的日志有哪些" — 已发送列表 (`report sent`)
- 用户提到"日报"、"周报"、"日志"
**用 `todo` 的场景**
- "记一下这周要做的事" — 个人任务管理
**判断关键**:钉钉日志系统(日报/周报模版,含按模版创建汇报)→ `report`;任务清单→ `todo`
---
### 4. chat 内部 — 两种消息发送方式
**用 `chat message send-by-bot` 的场景**
- "让机器人在群里发一条通知" — **机器人身份**发群消息
- "给张三发一条机器人单聊消息" — 机器人批量单聊
**用 `chat message send-by-webhook` 的场景**
- "通过 Webhook 发告警到群里" — 自定义机器人 Webhook
- 用户有 Webhook Token
**判断关键**:企业内部机器人→ `send-by-bot`(需 robotCode);有 Webhook Token→ `send-by-webhook`
---
## 跨产品工作流路由
以下场景需要多个产品配合完成,注意上下文传递顺序。
### 创建日程并邀请同事(contact → calendar
用户说"约张三明天下午开会":
```bash
# 1. 搜索同事 userId
dws contact user search --query "张三" --format json
# 2. 创建日程
dws calendar event create --title "会议" \
--start "2026-03-15T14:00:00+08:00" --end "2026-03-15T15:00:00+08:00" --format json
# 3. 添加参与者
dws calendar participant add --event <EVENT_ID> --users <USER_ID> --format json
```
### 创建待办并指派(contact → todo
用户说"给张三建个待办":
```bash
# 1. 搜索同事 userId
dws contact user search --query "张三" --format json
# 2. 创建待办
dws todo task create --title "任务内容" --executors <USER_ID> --format json
```
+925
View File
@@ -0,0 +1,925 @@
# AI表格 (aitable) 命令参考
## 文档地址 (URI)
所有 AI 表格操作完成后,可通过以下 URI 直接访问对应文档:
| 资源 | URI 格式 |
|------|----------|
| Base 文档 | `https://alidocs.dingtalk.com/i/nodes/{baseId}` |
| 模板预览 | `https://docs.dingtalk.com/table/template/{templateId}` |
> 💡 **操作后请返回文档 URI**:每次执行 base list/search/create/get 操作后,从返回数据中提取 `baseId`,拼接为 `https://alidocs.dingtalk.com/i/nodes/{baseId}` 返回给用户,方便直接点击打开。
## 命令总览
### base (Base 管理)
#### 获取 AI 表格列表
```
Usage:
dws aitable base list [flags]
Example:
dws aitable base list
dws aitable base list --limit 5 --cursor NEXT_CURSOR
Flags:
--cursor string 分页游标,首次不传
--limit int 每页数量,默认 10,最大 10
```
返回 baseId 与 baseName。
> 📎 **操作后返回文档链接**:遍历返回的每个 base,拼接 `https://alidocs.dingtalk.com/i/nodes/{baseId}` 返回给用户。
> ⚠️ **重要**`base list` 仅返回**最近访问过**的 Base**不是全部 Base**。
> 如需查找表格,**请优先使用 `base search`**`base list` 仅作为浏览最近表格的辅助手段。
> 如果刚创建完,直接使用 `create` 返回的 `baseId` 即可。
#### 搜索 AI 表格
```
Usage:
dws aitable base search [flags]
Example:
dws aitable base search --query "项目管理"
Flags:
--cursor string 分页游标,首次不传
--query string Base 名称关键词,建议至少 2 个字符 (必填)
```
#### 获取 AI 表格信息
```
Usage:
dws aitable base get [flags]
Example:
dws aitable base get --base-id <BASE_ID>
Flags:
--base-id string Base 唯一标识 (必填)
```
> 💡 **用户提供 URL 时**:如果用户给出了链接如 `https://alidocs.dingtalk.com/i/nodes/ABC123`,请提取末尾的 `ABC123` 作为 `--base-id` 传入。详见下方「URL → baseId 提取」章节。
返回 baseName、tables、dashboards 的 summary 信息(不含字段与记录详情)。
后续如需 tableId,优先从这里读取。
> 📎 **文档地址**`https://alidocs.dingtalk.com/i/nodes/{baseId}`
#### 创建 AI 表格
```
Usage:
dws aitable base create [flags]
Example:
dws aitable base create --name "项目跟踪"
Flags:
--name string Base 名称,1-50 字符 (必填)
--template-id string 模板 ID (可选,可通过 template search 获取)
```
> 💡 **创建后直接使用返回的 `baseId`**,无需再调用 `base list` 或 `base search` 查找。
> 后续可直接 `base get --base-id <返回的baseId>` 获取 tableId,或 `table create --base-id <返回的baseId>` 创建数据表。
>
> 📎 **文档地址**`https://alidocs.dingtalk.com/i/nodes/{返回的baseId}`
#### 更新 AI 表格
```
Usage:
dws aitable base update [flags]
Example:
dws aitable base update --base-id <BASE_ID> --name "新名称"
Flags:
--base-id string 目标 Base ID (必填)
--desc string 备注文本
--name string 新名称,1-50 字符 (必填)
```
#### 删除 AI 表格
```
Usage:
dws aitable base delete [flags]
Example:
dws aitable base delete --base-id <BASE_ID> --yes
Flags:
--base-id string 待删除 Base ID (必填)
--reason string 删除原因
```
高风险操作,不可逆。
### table (数据表管理)
#### 获取数据表
```
Usage:
dws aitable table get [flags]
Example:
dws aitable table get --base-id <BASE_ID>
dws aitable table get --base-id <BASE_ID> --table-ids tbl1,tbl2
Flags:
--base-id string 所属 Base ID (必填)
--table-ids string Table ID 列表,逗号分隔,单次最多 10 个
```
返回 tableId、tableName、description、fields 目录、views 目录。不传 table-ids 返回全部表。
> 📎 **文档地址**`https://alidocs.dingtalk.com/i/nodes/{baseId}`
#### 创建数据表
```
Usage:
dws aitable table create [flags]
Example:
dws aitable table create --base-id <BASE_ID> --name "任务表" \
--fields '[{"fieldName":"任务名称","type":"text"},{"fieldName":"优先级","type":"singleSelect","config":{"options":[{"name":"高"},{"name":"中"},{"name":"低"}]}}]'
Flags:
--base-id string 目标 Base ID (必填)
--fields string 初始字段 JSON 数组,至少 1 个,单次最多 15 个 (必填)
--name string 表格名称,1-100 字符 (必填)
```
> 💡 **创建后直接使用返回的 `tableId`**,无需再调 `table get` 查找。
> 后续可直接 `field create --table-id <返回的tableId>` 补充字段,或 `record create` 写入数据。
>
> 📎 **文档地址**`https://alidocs.dingtalk.com/i/nodes/{baseId}`
#### 更新数据表
```
Usage:
dws aitable table update [flags]
Example:
dws aitable table update --base-id <BASE_ID> --table-id <TABLE_ID> --name "新表名"
Flags:
--base-id string 所属 Base ID (必填)
--name string 新表名 (必填)
--table-id string 目标 Table ID (必填)
```
#### 删除数据表
```
Usage:
dws aitable table delete [flags]
Example:
dws aitable table delete --base-id <BASE_ID> --table-id <TABLE_ID> --yes
Flags:
--base-id string 目标 Base ID (必填)
--reason string 删除原因
--table-id string 将被删除的 Table ID (必填)
```
不可逆。若为 Base 中最后一张表,删除会失败。
### field (字段管理)
#### 获取字段详情
```
Usage:
dws aitable field get [flags]
Example:
dws aitable field get --base-id <BASE_ID> --table-id <TABLE_ID>
dws aitable field get --base-id <BASE_ID> --table-id <TABLE_ID> --field-ids fld1,fld2
Flags:
--base-id string Base ID (必填)
--field-ids string 字段 ID 列表,逗号分隔,单次最多 10 个
--table-id string Table ID (必填)
```
返回字段的完整配置(含 options 等)。在 table get 拿到字段目录后,按需展开少量字段的完整配置。
#### 创建字段
```
Usage:
dws aitable field create [flags]
Example:
# 单字段模式
dws aitable field create --base-id <BASE_ID> --table-id <TABLE_ID> \
--name "状态" --type "singleSelect" --config '{"options":[{"name":"待办"},{"name":"进行中"},{"name":"已完成"}]}'
# 批量模式
dws aitable field create --base-id <BASE_ID> --table-id <TABLE_ID> \
--fields '[{"fieldName":"状态","type":"singleSelect","config":{"options":[{"name":"待办"}]}}]'
Flags:
--base-id string Base ID (必填)
--name string 单字段名称(与 --type 配合使用,替代 --fields
--type string 单字段类型(参考 table create 字段类型)
--config string 单字段配置 JSON(可选,如 options
--fields string 批量新增字段 JSON 数组,单次最多 15 个(与 --name/--type 二选一)
--table-id string Table ID (必填)
```
允许部分成功,返回结果逐项标明成功/失败状态。
`--name/--type/--config` 为单字段模式;`--fields` 为批量模式;两种模式二选一。
#### 更新字段
```
Usage:
dws aitable field update [flags]
Example:
dws aitable field update --base-id <BASE_ID> --table-id <TABLE_ID> --field-id <FIELD_ID> --name "新字段名"
dws aitable field update --base-id <BASE_ID> --table-id <TABLE_ID> --field-id <FIELD_ID> --config '{"options":[{"name":"A"},{"name":"B"}]}'
Flags:
--ai-config string AI 字段配置 JSON(AI 字段类型专用,可选)
--base-id string Base ID (必填)
--config string 字段配置 JSON (不修改时省略)
--field-id string Field ID (必填)
--name string 新字段名称 (不修改时省略)
--table-id string Table ID (必填)
```
不可变更字段类型。更新 singleSelect/multipleSelect 的 options 时需传入完整列表,已有选项应回传原 id。
#### 删除字段
```
Usage:
dws aitable field delete [flags]
Example:
dws aitable field delete --base-id <BASE_ID> --table-id <TABLE_ID> --field-id <FIELD_ID> --yes
Flags:
--base-id string Base ID (必填)
--field-id string 待删除字段 ID (必填)
--table-id string Table ID (必填)
```
不可逆。禁止删除主字段和最后一个字段。
### record (记录管理)
#### 查询记录
```
Usage:
dws aitable record query [flags]
Example:
dws aitable record query --base-id <BASE_ID> --table-id <TABLE_ID>
dws aitable record query --base-id <BASE_ID> --table-id <TABLE_ID> --record-ids rec1,rec2
dws aitable record query --base-id <BASE_ID> --table-id <TABLE_ID> --query "关键词" --limit 50
Flags:
--base-id string Base ID (必填)
--cursor string 分页游标,首次不传
--field-ids string 返回字段 ID 列表,逗号分隔,单次最多 100 个
--filters string 结构化过滤条件 JSON
--query string 全文关键词搜索
--limit int 单次最大记录数,默认 100,最大 100
--record-ids string 指定记录 ID 列表,逗号分隔,单次最多 100 个
--sort string 排序条件 JSON 数组
--table-id string Table ID (必填)
```
两种模式: 按 ID 取(传 record-ids,忽略 filters/sort)或条件查(filters+sort+cursor 分页)。
> ⚠️ **排序参数规范(关键)**:`--sort` 需要传 JSON 数组,排序方向字段必须是 `direction``asc` 或 `desc`),**不要使用 `order`**。
>
> 正确示例:`--sort '[{"fieldId":"wm8ns9bw2vmucb45xj3ix","direction":"desc"}]'`
filters 结构:`{"operator":"and|or","operands":[{"operator":"<op>","operands":["<fieldId>","<value>"]}]}`
> 💡 **singleSelect/multipleSelect 过滤**filters 中可传 option id 或 option name,但建议优先用 **option id**(通过 `field get` 获取),更可靠。
> 写入时(record create/update)可直接传 option name。
> 💡 **减少响应体积**:字段较多时,用 `--field-ids` 仅返回需要的字段,可显著减少返回数据量。
#### 新增记录
```
Usage:
dws aitable record create [flags]
Example:
dws aitable record create --base-id <BASE_ID> --table-id <TABLE_ID> \
--records '[{"cells":{"fldTextId":"文本内容","fldNumId":123}}]'
Flags:
--base-id string Base ID (必填)
--records string 记录列表 JSON 数组,单次最多 100 条 (必填)
--table-id string Table ID (必填)
```
> ⚠️ **常见错误(严格避免)**
> - **参数名是 `--records`**,不是 `--data`
> - **cells 的 key 必须是 fieldId**(如 `fldXXX`),**不是字段名称**(如 `"课程名称"`
> - 必须先 `table get` 获取 fieldId,再写入记录
```bash
# 正确流程:先获取 fieldId
dws aitable table get --base-id <BASE_ID> --table-id <TABLE_ID> --format json
# 从返回中提取 fieldId(如 fldABC123
# 再用 fieldId 写入记录
dws aitable record create --base-id <BASE_ID> --table-id <TABLE_ID> \
--records '[{"cells":{"fldABC123":"Python入门"}}]' --format json
```
#### 更新记录
```
Usage:
dws aitable record update [flags]
Example:
dws aitable record update --base-id <BASE_ID> --table-id <TABLE_ID> \
--records '[{"recordId":"recXXX","cells":{"fldStatusId":"已完成"}}]'
Flags:
--base-id string Base ID (必填)
--records string 待更新记录 JSON 数组,单次最多 100 条 (必填)
--table-id string Table ID (必填)
```
只需传入需修改的字段,未传入的保持原值。每条记录必须含 recordId 和 cells。
#### 删除记录
```
Usage:
dws aitable record delete [flags]
Example:
dws aitable record delete --base-id <BASE_ID> --table-id <TABLE_ID> --record-ids rec1,rec2 --yes
Flags:
--base-id string Base ID (必填)
--record-ids string 待删除记录 ID 列表,逗号分隔,最多 100 条 (必填)
--table-id string Table ID (必填)
```
不可逆。调用前建议先 record query 确认目标记录。
### attachment (附件管理)
> 🛑 **STOP — 不要使用钉盘 (drive) 上传!** 钉盘 fileId 无法写入 attachment 字段。必须使用以下流程。
#### 准备附件上传
```
Usage:
dws aitable attachment upload [flags]
Example:
dws aitable attachment upload --base-id <BASE_ID> --file-name report.xlsx --size 204800
dws aitable attachment upload --base-id <BASE_ID> --file-name photo.png --size 1024 --mime-type image/png
Flags:
--base-id string Base ID (必填)
--file-name string 文件名,必须含扩展名 (必填)
--size int 文件大小(字节),>0 (必填)
--mime-type string MIME type(不传时根据扩展名推断)
```
#### 附件上传完整流程(推荐:使用脚本,2 步完成)
```bash
# 步骤 1: 使用脚本一键上传(内部自动完成 prepare + PUT
python3 scripts/upload_attachment.py <BASE_ID> /path/to/report.pdf
# 输出: { "fileToken": "ft_xxx", "fileName": "report.pdf", "size": 204800 }
# 步骤 2: 在 record create/update 中使用 fileToken 写入
dws aitable record create --base-id <BASE_ID> --table-id <TABLE_ID> \
--records '[{"cells":{"fldAttachId":[{"fileToken":"ft_xxx"}]}}]' --format json
```
> ⚠️ `uploadUrl` 有时效性(`expiresAt`),脚本会自动在获取后立即上传。
### view (视图管理)
视图是同一张数据表的筛选/排序/分组/可见字段组合的备用呈现。record query 可以通过视图收敛查询范围。
#### 获取视图
```
Usage:
dws aitable view get [flags]
Example:
dws aitable view get --base-id <BASE_ID> --table-id <TABLE_ID>
dws aitable view get --base-id <BASE_ID> --table-id <TABLE_ID> --view-ids viw1,viw2
Flags:
--base-id string Base ID (必填)
--table-id string Table ID (必填)
--view-ids string View ID 列表,逗号分隔,单次最多 10 个
```
返回视图配置(过滤、排序、可见字段、分组)。不传 view-ids 返回该表全部视图。
#### 创建视图
```
Usage:
dws aitable view create [flags]
Example:
dws aitable view create --base-id <BASE_ID> --table-id <TABLE_ID> --name "进行中看板" --view-type kanban
Flags:
--base-id string Base ID (必填)
--config string 视图配置 JSON:过滤/排序/分组/可见字段(可选,创建后可再 update)
--name string 视图名称 (必填)
--table-id string Table ID (必填)
--view-type string 视图类型:grid/gallery/kanban/gantt/calendar/form 等 (必填)
```
> ⚠️ 视图类型参数是 `--view-type`,不是 `--type`。
#### 更新视图
```
Usage:
dws aitable view update [flags]
Example:
dws aitable view update --base-id <BASE_ID> --table-id <TABLE_ID> --view-id <VIEW_ID> --name "新视图名"
Flags:
--base-id string Base ID (必填)
--config string 视图配置 JSON:过滤/排序/分组/可见字段
--name string 新视图名
--table-id string Table ID (必填)
--view-id string 目标 View ID (必填)
```
调整过滤、排序、分组、可见字段时使用。不重建视图即可替换配置。
#### 删除视图
```
Usage:
dws aitable view delete [flags]
Example:
dws aitable view delete --base-id <BASE_ID> --table-id <TABLE_ID> --view-id <VIEW_ID> --yes
Flags:
--base-id string Base ID (必填)
--table-id string Table ID (必填)
--view-id string 待删除 View ID (必填)
```
不可逆。若是主视图或最后一个视图,删除会失败。
### import (数据导入)
把外部 Excel/CSV 批量写入某张数据表,按两步走:先 upload 拿 importId,再 data 触发导入。
#### 准备导入上传
```
Usage:
dws aitable import upload [flags]
Example:
dws aitable import upload --base-id <BASE_ID> --file-name sales.xlsx --file-size 204800
Flags:
--base-id string Base ID (必填)
--file-name string 文件名,必须含扩展名 (必填)
--file-size int 文件大小(字节),>0 (必填)
```
> ⚠️ 参数是 `--file-size`,不是 `--size`。返回 uploadUrlPUT 上传)与 importId。
#### 触发导入
```
Usage:
dws aitable import data [flags]
Example:
dws aitable import data --import-id <IMPORT_ID> --timeout 60
Flags:
--import-id string import upload 返回的 importId (必填)
--timeout int 等待导入完成的超时秒数,默认 30
```
把上一步上传到暂存区的文件正式导入为记录;超时未完成时返回处理状态,按 importId 再次查询即可。
### dashboard (仪表盘)
仪表盘 = 多个图表的布局容器;图表绑定数据表/视图。创建仪表盘之前通常先查 `dashboard config-example`,拿到 JSON 骨架,再把图表塞进 `--config` 的布局里。
#### 仪表盘配置示例
```
Usage:
dws aitable dashboard config-example [flags]
Example:
dws aitable dashboard config-example --format json
```
返回仪表盘 `--config` 的 JSON 示例,供 create/update 复制裁剪。
#### 获取仪表盘
```
Usage:
dws aitable dashboard get [flags]
Example:
dws aitable dashboard get --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID>
Flags:
--base-id string Base ID (必填)
--dashboard-id string Dashboard ID (必填)
```
返回布局和 `charts[].chartId`,可直接喂给 `chart get`
#### 创建仪表盘
```
Usage:
dws aitable dashboard create [flags]
Example:
dws aitable dashboard create --base-id <BASE_ID> --config '<JSON>'
Flags:
--base-id string Base ID (必填)
--config string 仪表盘配置 JSON(名称、布局、图表列表都在里面) (必填)
```
> ⚠️ 没有独立的 `--name`;名称和布局一起放在 `--config` JSON 中。
#### 更新仪表盘
```
Usage:
dws aitable dashboard update [flags]
Example:
dws aitable dashboard update --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --config '<JSON>'
Flags:
--base-id string Base ID (必填)
--config string 更新后的仪表盘配置 JSON (必填)
--dashboard-id string Dashboard ID (必填)
```
调整布局、增删图表一律改 `--config`
#### 删除仪表盘
```
Usage:
dws aitable dashboard delete [flags]
Example:
dws aitable dashboard delete --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --yes
Flags:
--base-id string Base ID (必填)
--dashboard-id string Dashboard ID (必填)
--reason string 删除原因
```
不可逆。
#### 查看仪表盘分享状态
```
Usage:
dws aitable dashboard share get [flags]
Example:
dws aitable dashboard share get --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID>
Flags:
--base-id string Base ID (必填)
--dashboard-id string Dashboard ID (必填)
```
> ⚠️ 可能返回 404(资源不存在或未开通外链),按可重试错误处理,不要误判为参数拼错。
#### 更新仪表盘分享
```
Usage:
dws aitable dashboard share update [flags]
Example:
dws aitable dashboard share update --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --enabled true
Flags:
--allow-back-to-doc 是否允许从分享页返回原文档(可选)
--base-id string Base ID (必填)
--dashboard-id string Dashboard ID (必填)
--enabled 是否开启外链分享 (必填)
--share-type string 分享类型(权限/可见范围等,可选)
```
开启后返回 shareUrl;关闭后原链接失效。
### chart (图表)
图表挂在某个仪表盘下,绑定数据表(可进一步绑定视图)。新建前通常先查 `chart widgets-example`
#### 图表组件示例
```
Usage:
dws aitable chart widgets-example [flags]
Example:
dws aitable chart widgets-example --format json
```
返回图表 widget 的 JSON 示例,供 `chart create/update --config` 参考。
#### 获取图表
```
Usage:
dws aitable chart get [flags]
Example:
dws aitable chart get --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --chart-id <CHART_ID>
Flags:
--base-id string Base ID (必填)
--chart-id string Chart ID (必填)
--dashboard-id string Dashboard ID (必填)
```
#### 创建图表
```
Usage:
dws aitable chart create [flags]
Example:
dws aitable chart create --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --config '<JSON>'
Flags:
--base-id string Base ID (必填)
--config string 图表配置 JSON:数据源、维度、度量、样式 (必填)
--dashboard-id string 挂载到的 Dashboard ID (必填)
--layout string 图表布局 JSON(位置、尺寸,可选)
```
> ⚠️ 名称和类型都在 `--config` JSON 里,没有独立 `--name` / `--type`。
#### 更新图表
```
Usage:
dws aitable chart update [flags]
Example:
dws aitable chart update --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --chart-id <CHART_ID> --config '<JSON>'
Flags:
--base-id string Base ID (必填)
--chart-id string Chart ID (必填)
--config string 图表配置 JSON (必填)
--dashboard-id string Dashboard ID (必填)
--layout string 图表布局 JSON(位置、尺寸,可选)
```
#### 删除图表
```
Usage:
dws aitable chart delete [flags]
Example:
dws aitable chart delete --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --chart-id <CHART_ID> --yes
Flags:
--base-id string Base ID (必填)
--chart-id string 待删除 Chart ID (必填)
--dashboard-id string Dashboard ID (必填)
--reason string 删除原因
```
不可逆。
#### 查看图表分享状态
```
Usage:
dws aitable chart share get [flags]
Example:
dws aitable chart share get --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --chart-id <CHART_ID>
Flags:
--base-id string Base ID (必填)
--chart-id string Chart ID (必填)
--dashboard-id string Dashboard ID (必填)
```
返回 `enabled``shareUrl`,用来判断是否已经对外分享。
#### 更新图表分享
```
Usage:
dws aitable chart share update [flags]
Example:
dws aitable chart share update --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --chart-id <CHART_ID> --enabled true
Flags:
--allow-back-to-doc 是否允许从分享页返回原文档(可选)
--base-id string Base ID (必填)
--chart-id string Chart ID (必填)
--dashboard-id string Dashboard ID (必填)
--enabled 是否开启外链分享 (必填)
--share-type string 分享类型(权限/可见范围等,可选)
```
### export (数据导出)
把数据表/视图/整张 Base 导出为 Excel/CSV,下发下载链接;常见是异步任务,首次调用可能只返回 `taskId`,需要按 `taskId` 继续轮询直到拿到 `downloadUrl`
#### 导出数据
```
Usage:
dws aitable export data [flags]
Example:
# 第一步:创建任务(按 scope 传必要参数)
dws aitable export data --base-id <BASE_ID> --scope table --table-id <TABLE_ID> --format excel --timeout-ms 1000
# 第二步:拿 taskId 继续轮询,直到返回 downloadUrl
dws aitable export data --base-id <BASE_ID> --task-id <TASK_ID> --timeout-ms 3000
Flags:
--base-id string Base ID (必填)
--scope string 导出范围:all / table / view
--table-id string Table IDscope=table/view 时必填)
--view-id string View IDscope=view 时必填)
--format string 导出格式:excel / csv,默认 excel
--task-id string 轮询已有任务的 taskId
--timeout-ms int 单次调用服务端等待时间(毫秒)
```
参数约束:
- `scope=all`:只需 `--base-id`
- `scope=table`:必须同时传 `--table-id`
- `scope=view`:必须同时传 `--table-id + --view-id`
### template (模板搜索)
#### 搜索模板
```
Usage:
dws aitable template search [flags]
Example:
dws aitable template search --query "项目管理"
Flags:
--cursor string 分页游标,首次不传
--limit int 每页返回数量,默认 10,最大 30
--query string 模板名称关键词 (必填)
```
返回 templateId 可用于 `base create --template-id`
> 📎 **模板预览地址**`https://docs.dingtalk.com/table/template/{templateId}`
## 复杂操作
### 仪表盘 / 图表(建议顺序)
```bash
# 1) 先看配置模板(JSONC
dws aitable dashboard config-example --format json
dws aitable chart widgets-example --format json
# 2) 先拿 dashboard,再拿 chart 详情
dws aitable dashboard get --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --format json
dws aitable chart get --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --chart-id <CHART_ID> --format json
# 3) 写入/更新都用 --config JSON(名称、布局、图表类型都在里面)
dws aitable dashboard create --base-id <BASE_ID> --config '<JSON>' --format json
dws aitable chart update --base-id <BASE_ID> --dashboard-id <DASHBOARD_ID> --chart-id <CHART_ID> --config '<JSON>' --format json
```
要点:
- `dashboard get` 返回的 `charts[].chartId` 可直接给 `chart get` 使用。
- `dashboard share get` 可能返回 `404`(资源不存在或未开通),需按可重试错误处理,不要误判为参数拼错。
- `chart share get` 可正常返回 `enabled/shareUrl`,用于分享状态判断。
- dashboard/chart 的 create/update 只有 `--config`,没有独立的 `--name` / `--type`,名称与布局都在 JSON 里。
### 导入外部数据(两步走)
```bash
# 1) 先上传文件拿 importId
dws aitable import upload --base-id <BASE_ID> --file-name sales.xlsx --file-size 204800 --format json
# 把本地文件 PUT 到返回的 uploadUrl(过期前必须上传完成)
# 2) 触发导入
dws aitable import data --import-id <IMPORT_ID> --timeout 60 --format json
```
要点:`--file-size` 单位字节,必须与实际文件一致;`--timeout` 单位秒,不是毫秒。
## 意图判断
用户说"表格/多维表/AI表格":
- 查看/查找/列表 → `base search`(优先)或 `base list`(仅浏览最近访问)
- 搜索 → `base search`
- 详情 → `base get`
- 创建 → `base create`
- 修改 → `base update`
- 删除 → `base delete` [危险]
用户说"数据表/子表/table":
- 查看 → `table get`
- 创建 → `table create`
- 重命名 → `table update`
- 删除 → `table delete` [危险]
用户说"字段/列/column":
- 查看 → `field get`
- 添加 → `field create`
- 修改 → `field update`
- 删除 → `field delete` [危险]
用户说"记录/行/数据/row":
- 查看/搜索 → `record query`(先 `table get` 获取 fieldId
- 添加/写入 → `record create`(先 `table get` 必须!
- 修改/更新 → `record update`(需 recordId,先 `record query`
- 删除 → `record delete` [危险](需 recordId
用户说"视图/筛选视图/看板/画廊":
- 查看 → `view get`
- 新建 → `view create``--view-type` 指定视图类型)
- 修改(过滤/排序/分组/可见字段) → `view update`
- 删除 → `view delete` [危险]
用户说"导入/上传 Excel/CSV":
- 外部文件导入 → `import upload` → PUT 文件 → `import data`(两步)
用户说"导出/下载表格数据":
-`export data`(按 scope=all/table/view 传参,异步轮询)
用户说"仪表盘/dashboard":
- 查看布局 → `dashboard get`
- 查看模板 → `dashboard config-example`
- 新建/修改布局 → `dashboard create` / `dashboard update`(配置都在 `--config` JSON
- 删除 → `dashboard delete` [危险]
- 对外分享 → `dashboard share get` / `dashboard share update`
用户说"图表/chart":
- 查看 → `chart get`(需要 dashboardId
- 查看组件模板 → `chart widgets-example`
- 新建/修改 → `chart create` / `chart update`(配置都在 `--config` JSON
- 删除 → `chart delete` [危险]
- 对外分享 → `chart share get` / `chart share update`
用户说"附件/文件字段" → `attachment upload`(不要用钉盘 drive
用户说"模板" → `template search`
关键区分: base=表格文件, table=数据表, field=列, record=行, view=视图, dashboard=仪表盘, chart=图表
## 核心工作流
```bash
# 1. 搜索/列出 Base — 提取 baseId
dws aitable base search --query "项目" --format json
# 2. 获取 Base 信息 — 提取 tableId
dws aitable base get --base-id <BASE_ID> --format json
# 3. 获取表结构 — 提取 fieldId
dws aitable table get --base-id <BASE_ID> --table-id <TABLE_ID> --format json
# 4. 查询记录
dws aitable record query --base-id <BASE_ID> --table-id <TABLE_ID> --format json
# 5. 新增记录 (cells 用 fieldId 作 key)
dws aitable record create --base-id <BASE_ID> --table-id <TABLE_ID> \
--records '[{"cells":{"fldXXX":"值"}}]' --format json
```
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `base list/search` | `baseId` | 所有后续命令的 --base-id,拼接文档 URI |
| `base create` | `baseId` | 后续命令 + 文档 URI |
| `base get` | `tables[].tableId``dashboards[].dashboardId` | --table-id / --dashboard-id |
| `table get` | `fields[].fieldId``views[].viewId` | record 操作的 cells keyfield get/update/deleteview 操作 |
| `view get` | `viewId` | record query 按视图收敛;view update/delete |
| `record query` | `recordId` | record update/delete |
| `dashboard get` | `charts[].chartId` | chart get/update/delete/share |
| `import upload` | `importId``uploadUrl` | PUT 文件后调 import data |
| `export data` (首次) | `taskId` | 下一轮 export data 轮询 |
| `attachment upload` | `fileToken` | record create/update 写入 attachment 字段 |
| `template search` | `templateId` | base create --template-id,拼接模板预览 URI |
## 注意事项
- 所有操作使用 IDbaseId/tableId/fieldId/recordId/viewId/dashboardId/chartId),不使用名称
- records 的 cells key 是 fieldId,不是字段名称
- dashboard/chart 的 create/update 只有 `--config`(JSON 内含名称/布局/类型),没有独立 `--name`
- view 创建的类型参数是 `--view-type`,不是 `--type`
- import upload 的文件大小参数是 `--file-size`,不是 `--size`
## `--filters` 筛选语法排错与使用规范(极易出错)
调用 `record query` 时,如果条件筛选**完全失效(查询返回了所有记录)**,通常是因为 `--filters` JSON 语法错误,API 默默丢弃了不合规的 filter。
**强制规则:**
1. **根节点必须是逻辑操作符**`"operator"` 必须是 `"and"``"or"`,不能是 `"eq"` 等比较操作符。
2. 比较操作必须放在根节点的 `"operands"` 数组内的对象中。
3. `singleSelect``multipleSelect` 字段,推荐使用 **选项的 exact String 名称 (name)** 作为比较值,而不是 ID。
4. **内层比较操作符语义**:支持 `eq`(等于)、`not_eq`(不等于)、`contain`(包含/模糊搜索)、`not_contain`(不包含)、`gt/gte`(大于/大于等于)、`lt/lte`(小于/小于等于)、`is_empty/is_not_empty`(为空/不为空,对应 operands 内只传单个 fieldId)。
**精简防呆模板与 4 种衍生情况**
```json
{
"operator": "and", // 情况 4 (OR 查询): 这里改为 "or"
"operands": [
{
"operator": "eq", // 情况 3 (文本包含): 这里改为 "contain"
"operands": ["fld_state", "进行中"] // 情况 1 (基础等于)
}
// 情况 2 (多条件 AND): 在此行增加类似 {"operator":"eq","operands":["fld_priority","高"]}
]
}
```
**错误示例 1:缺失根节点 and/or**(API 将忽略该 filter,返回全表)
```json
{"operator":"eq","operands":["fldXXX","本科"]}
```
**错误示例 2:传入选项 ID 而非名称**(可能导致匹配不到 0 记录)
```json
{"operator":"and","operands":[{"operator":"eq","operands":["fldXXX","CXzrOHK9JI"]}]}
```
## URL → baseId 提取
用户经常通过钉钉链接指定表格,链接格式为:
```
https://alidocs.dingtalk.com/i/nodes/{baseId}
https://alidocs.dingtalk.com/i/nodes/{baseId}?xxx=yyy
```
**处理规则**(必须严格遵守):
1. 当用户提供了包含 `alidocs.dingtalk.com/i/nodes/` 的 URL 时,提取 `/nodes/` 后的路径段作为 `baseId`
2. 去掉尾部的查询参数(`?` 及其后内容)和尾部斜杠
3. 将提取得到的 ID 传入 `--base-id` 参数
**示例**
```
用户输入:帮我查看 https://alidocs.dingtalk.com/i/nodes/ABC123XYZ 这个表格
→ 提取 baseId = ABC123XYZ
→ 执行: dws aitable base get --base-id ABC123XYZ --format json
```
> 💡 **注意**URL 中的 nodeId 在 AI 表格场景下等同于 baseId,可以直接作为 `--base-id` 使用。
### cells 写入/读取格式速查
| 字段类型 | 写入格式 | 读取返回格式 |
|---------|---------|------------|
| text | `"字符串"` | `"字符串"` |
| number | `123` | `"123"` |
| singleSelect | `"选项名"``{"id":"xxx"}` | `{"id":"xxx","name":"选项名"}` |
| multipleSelect | `["选项A","选项B"]` | `[{"id":"x","name":"选项A"},...]` |
| date | `"2026-03-13"` 或时间戳 | ISO 日期字符串 |
| checkbox | `true`/`false` | `true`/`false` |
| user | `[{"userId":"xxx"}]` | `[{"corpId":"xxx","userId":"xxx"}]` |
| attachment | `[{"fileToken":"ft_xxx"}]` ⚠️需先走 attachment upload 3步流程 | `[{"url":"...","filename":"...","size":N}]` |
| url | `{"text":"显示文本","link":"https://..."}` | 同写入 |
| richText | `{"markdown":"**加粗**"}` | `{"markdown":"..."}` |
| group | `[{"cid":"xxx"}]` (注意: key 是 cid,不是 openConversationId) | 同写入 |
- 详见 [field-rules.md](../field-rules.md) 和 [error-codes.md](../error-codes.md)
## 相关产品
- [doc](./doc.md) — 富文本文档编辑,不是结构化数据表格
@@ -0,0 +1,97 @@
# 考勤 (attendance) 命令参考
## 命令总览
### 查询个人考勤详情
```
Usage:
dws attendance record get [flags]
Example:
dws attendance record get --user <USER_ID> --date 2026-03-08
Flags:
--date string 查询日期, 格式 YYYY-MM-DD (必填)
--user string 钉钉用户 ID (必填)
```
### 批量查询员工班次信息
```
Usage:
dws attendance shift list [flags]
Example:
dws attendance shift list --users userId1,userId2 --start 2026-03-03 --end 2026-03-07
Flags:
--end string 结束日期, 格式 YYYY-MM-DD (必填)
--start string 开始日期, 格式 YYYY-MM-DD (必填)
--users string 用户 ID 列表, 逗号分隔, 最多 50 个 (必填)
```
返回每条记录含:用户 ID、工作日期、打卡类型(OnDuty/OffDuty)、计划打卡时间、是否休息日。间隔不超过 7 天,最多 50 人。
### 查询某个人的考勤统计摘要
```
Usage:
dws attendance summary [flags]
Example:
dws attendance summary --user USER_ID --date "2026-03-12 15:00:00" --stats-type month
dws attendance summary --user USER_ID --date "2026-03-12 15:00:00" --stats-type week
Flags:
--date string 工作日期, 格式 yyyy-MM-dd HH:mm:ss (必填)
--stats-type string 统计类型:week(周统计)或 month(月统计)(必填,钉钉服务端业务层强制要求;CLI 层会直接拒绝缺失/非法值)
--user string 钉钉用户 ID (必填)
```
> ⚠️ **重要**`--stats-type` 在钉钉 schema 中标记为 `required: []`(看似可选),但服务端业务层**强制要求**,不传服务端会回 `C0002 / 统计类型错误`。CLI 已在客户端层做了 fail-fast:缺失或非 `week`/`month` 的取值会直接被 CLI 拒绝,不会发出请求。
### 查询考勤组与考勤规则
```
Usage:
dws attendance rules [flags]
Example:
dws attendance rules --date 2026-03-14
dws attendance rules --date "2026-03-14 09:00:00"
Flags:
--date string 考勤日期, 格式 YYYY-MM-DD 或 yyyy-MM-dd HH:mm:ss (必填)
```
查询考勤组/考勤规则。例如:我属于哪个考勤组、打卡范围是什么、弹性工时怎么算。
## 意图判断
用户说"打卡记录/出勤/考勤" → `record get`
用户说"排班/班次/当班" → `shift list`
用户说"考勤汇总/统计" → `summary`
用户说"考勤组/考勤规则/打卡规则" → `rules`
## 核心工作流
```bash
# 查看某人考勤
dws attendance record get --user <USER_ID> --date 2026-03-08 --format json
# 批量查排班
dws attendance shift list --users userId1,userId2 \
--start 2026-03-03 --end 2026-03-07 --format json
# 查看考勤统计摘要
dws attendance summary --user <USER_ID> --date "2026-03-12 15:00:00" --format json
# 查看考勤组和规则
dws attendance rules --date 2026-03-14 --format json
```
## 上下文传递表
| 操作 | 提取 | 用于 |
|------|------|------|
| `contact user get-self` | `userId` | record get 的 --user, shift list 的 --users, summary 的 --user |
## 注意事项
- `record get``--date` 格式: YYYY-MM-DD(如 `2026-03-08`),CLI 自动转换为毫秒时间戳
- `shift list``--start/--end` 同样使用 YYYY-MM-DD 格式,间隔不超过 7 天
- `summary``--date` 格式: yyyy-MM-dd HH:mm:ss(如 `2026-03-12 15:00:00`
- `rules``--date` 支持 YYYY-MM-DD 或 yyyy-MM-dd HH:mm:ss 两种格式
- 用户 ID 需从 `contact user get-self``contact user search` 获取
## 自动化脚本
| 脚本 | 场景 | 用法 |
|------|------|------|
| [attendance_my_record.py](../../scripts/attendance_my_record.py) | 查看我今天/指定日期的考勤记录 | `python attendance_my_record.py today` |
| [attendance_team_shift.py](../../scripts/attendance_team_shift.py) | 查询团队成员本周排班 | `python attendance_team_shift.py --users userId1,userId2` |
+245
View File
@@ -0,0 +1,245 @@
# 日历 (calendar) 命令参考
## 命令总览
### 查询日程列表
```
Usage:
dws calendar event list [flags]
Example:
dws calendar event list --start "2026-03-10T14:00:00+08:00" --end "2026-03-10T18:00:00+08:00"
Flags:
--end string 结束时间 ISO-8601 (例如 2026-03-10T18:00:00+08:00)
--start string 开始时间 ISO-8601 (例如 2026-03-10T14:00:00+08:00)
```
### 获取日程详情
```
Usage:
dws calendar event get [flags]
Example:
dws calendar event get --id <EVENT_ID>
Flags:
--id string 日程 ID (必填)
```
### 创建日程
```
Usage:
dws calendar event create [flags]
Example:
dws calendar event create --title "Q1 复盘会" \
--start "2026-03-10T14:00:00+08:00" --end "2026-03-10T15:00:00+08:00"
dws calendar event create --title "Q1 复盘会" \
--start "2026-03-10T14:00:00+08:00" --end "2026-03-10T15:00:00+08:00" \
--attendees userId1,userId2 --timezone "Asia/Shanghai" --desc "Q1 复盘"
Flags:
--attendees string 参会人 userId 列表 (逗号分隔)
--desc string 日程描述
--end string 结束时间 ISO-8601 (必填)
--open-dingtalk-ids string 参会人 openDingTalkId 列表 (逗号分隔)
--start string 开始时间 ISO-8601 (必填)
--timezone string 时区 (如 Asia/Shanghai)
--title string 日程标题 (必填)
```
### 修改日程
```
Usage:
dws calendar event update [flags]
Example:
dws calendar event update --id <EVENT_ID> --title "新标题"
dws calendar event update --id <EVENT_ID> --desc "议程调整" --timezone "Asia/Shanghai"
Flags:
--desc string 新描述
--end string 新结束时间
--id string 日程 ID (必填)
--start string 新开始时间
--timezone string 时区 (如 Asia/Shanghai)
--title string 新标题
```
### 删除日程
```
Usage:
dws calendar event delete [flags]
Example:
dws calendar event delete --id <EVENT_ID> --yes
Flags:
--id string 日程 ID (必填)
```
### 推荐会议时间
```
Usage:
dws calendar event suggest [flags]
Example:
dws calendar event suggest --users <USER_ID_1>,<USER_ID_2> \
--start "2026-03-10T09:00:00+08:00" --end "2026-03-10T18:00:00+08:00" --duration 30
Flags:
--duration string 会议时长(分钟)
--end string 候选时段结束时间 ISO-8601 (必填)
--start string 候选时段开始时间 ISO-8601 (必填)
--timezone string 时区 (如 Asia/Shanghai)
--users string 参会人 userId 列表 (必填)
```
基于参会人闲忙数据给出排名后的候选时段,比 `busy search` 直接给出原始忙闲更适合"帮我约"场景。
### 查看参与者
```
Usage:
dws calendar participant list [flags]
Example:
dws calendar participant list --event <EVENT_ID>
Flags:
--event string 日程 ID (必填)
```
### 添加参与者
```
Usage:
dws calendar participant add [flags]
Example:
dws calendar participant add --event <EVENT_ID> --users <USER_ID_1>,<USER_ID_2>
Flags:
--event string 日程 ID (必填)
--users string 用户 ID 列表 (必填)
```
### 移除参与者
```
Usage:
dws calendar participant delete [flags]
Example:
dws calendar participant delete --event <EVENT_ID> --users <USER_ID> --yes
Flags:
--event string 日程 ID (必填)
--users string 用户 ID 列表 (必填)
```
### 搜索会议室
```
Usage:
dws calendar room search [flags]
Example:
dws calendar room search --start "2026-03-10T14:00:00+08:00" --end "2026-03-10T15:00:00+08:00" --available
dws calendar room search --start "2026-03-10T14:00:00+08:00" --end "2026-03-10T15:00:00+08:00" --group-id <GROUP_ID>
Flags:
--available 仅查空闲会议室
--end string 结束时间 ISO-8601 (必填)
--group-id string 会议室分组ID(可选,留空查根目录;超100条时需按分组查询)
--start string 开始时间 ISO-8601 (必填)
```
### 预定会议室
```
Usage:
dws calendar room add [flags]
Example:
dws calendar room add --event <EVENT_ID> --rooms <ROOM_ID>
Flags:
--event string 日程 ID (必填)
--rooms string 会议室 ID 列表 (必填)
```
### 移除会议室
```
Usage:
dws calendar room delete [flags]
Example:
dws calendar room delete --event <EVENT_ID> --rooms <ROOM_ID> --yes
Flags:
--event string 日程 ID (必填)
--rooms string 会议室 ID 列表 (必填)
```
### 会议室分组列表
```
Usage:
dws calendar room list-groups [flags]
Example:
dws calendar room list-groups
```
### 查询用户闲忙状态
```
Usage:
dws calendar busy search [flags]
Example:
dws calendar busy search --users <USER_ID_1>,<USER_ID_2> \
--start "2026-03-10T14:00:00+08:00" --end "2026-03-10T18:00:00+08:00"
Flags:
--end string 结束时间 ISO-8601 (必填)
--start string 开始时间 ISO-8601 (必填)
--users string 用户 ID 列表 (必填)
```
## 意图判断
用户说"日程/会议/约会/日历":
- 查看 → `event list`
- 详情 → `event get`
- 创建/约 → `event create`
- 修改/改时间 → `event update`
- 取消/删除 → `event delete`
- 帮我约/找个大家都有空的时间 → `event suggest`
用户说"参会人/与会者":
- 查看 → `participant list`
- 邀请/添加 → `participant add`
- 移除 → `participant delete`
用户说"会议室/订会议室":
- 哪个空闲 → `room search`
- 预定 → `room add`
- 取消预定 → `room delete`
- 分组 → `room list-groups`,取 groupId 后 `room search --group-id`
用户说"有空吗/忙不忙/闲忙":
- 要原始闲忙块 → `busy search`
- 要直接给时段候选 → `event suggest`
## 核心工作流
```bash
# 1. 创建日程 — 提取 eventId
dws calendar event create --title "Q1 复盘会" \
--start "2026-03-10T14:00:00+08:00" --end "2026-03-10T15:00:00+08:00" --format json
# 2. 添加参与者
dws calendar participant add --event <EVENT_ID> --users userId1,userId2 --format json
# 3. 预定会议室 (先搜空闲)
dws calendar room search --start "2026-03-10T14:00:00+08:00" --end "2026-03-10T15:00:00+08:00" --format json
# 若返回错误(会议室超100条),先查分组再按分组搜索:
# dws calendar room list-groups --format json
# dws calendar room search --start ... --end ... --group-id <GROUP_ID> --format json
dws calendar room add --event <EVENT_ID> --rooms <ROOM_ID> --format json
# 4. 查看日程列表
dws calendar event list --start "2026-03-10T14:00:00+08:00" --end "2026-03-10T15:00:00+08:00" --format json
```
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `event create` | `eventId` | participant/room 操作的 --event |
| `event list` | `events[].eventId` | event get/update/delete 的 --id |
| `room search` | `rooms[].roomId` | room add 的 --rooms |
| `room list-groups` | `groups[].groupId` | room search 的 --group-id |
## 注意事项
- 时间格式: `event create/update``event list``busy search` 用 ISO-8601
- 创建日程不会自动预定会议室,需额外 `room add`
- `room search` 不带 `--group-id` 时查根目录;企业会议室超过 100 条会报错,此时需先 `room list-groups` 获取分组,再按分组逐一查询
## 自动化脚本
| 脚本 | 场景 | 用法 |
|------|------|------|
| [calendar_today_agenda.py](../../scripts/calendar_today_agenda.py) | 查看今天/明天/本周日程安排 | `python calendar_today_agenda.py today` |
| [calendar_schedule_meeting.py](../../scripts/calendar_schedule_meeting.py) | 一键创建日程+添加参与者+预定会议室 | `python calendar_schedule_meeting.py --title "复盘会" --start "2026-03-15T14:00" --end "2026-03-15T15:00" --users userId1 --book-room` |
| [calendar_free_slot_finder.py](../../scripts/calendar_free_slot_finder.py) | 查询多人共同空闲时段 | `python calendar_free_slot_finder.py --users userId1,userId2 --date 2026-03-15` |
+771
View File
@@ -0,0 +1,771 @@
# 会话与群聊 (chat) 命令参考
> 命令别名: `dws im` 等价于 `dws chat`
## 命令总览
### group (群组管理)
| 子命令 | 用途 |
|-------|------|
| `group create` | 创建内部群 |
| `group members` | 查看群成员列表 |
| `group members add` | 添加群成员 |
| `group members remove` | 移除群成员(⚠️ 危险操作) |
| `group members add-bot` | 添加机器人到群 |
| `group rename` | 修改群名称 |
| `search` | 搜索群会话 |
| `search-common` | 搜索共同群 |
| `conversation-info` | 获取会话基础信息(单聊/群聊) |
### message (会话消息管理)
| 子命令 | 用途 |
|-------|------|
| `message send` | 以当前用户身份发群消息或单聊消息 |
| `message list` | 拉取群聊或单聊会话消息 |
| `message list-all` | 按时间范围拉取当前用户所有会话消息 |
| `message list-topic-replies` | 拉取群话题回复消息列表 |
| `message list-by-sender` | 搜索指定发送者的消息 |
| `message list-mentions` | 拉取 @我 的消息 |
| `message list-focused` | 拉取特别关注人的消息 |
| `message list-unread-conversations` | 获取未读会话列表 |
| `message search` | 按关键词搜索消息 |
| `message send-by-bot` | 机器人发消息(群聊或批量单聊) |
| `message recall-by-bot` | 机器人撤回消息 |
| `message send-by-webhook` | 自定义机器人 Webhook 发消息 |
| `list-top-conversations` | 拉取置顶会话列表 |
### bot (机器人管理)
| 子命令 | 用途 |
|-------|------|
| `bot search` | 搜索我的机器人 |
---
## group create — 创建内部群
当前登录用户自动成为群主。
```
Usage:
dws chat group create [flags]
Example:
dws chat group create --name "Q1 项目冲刺群" --users userId1,userId2,userId3
Flags:
--users string 成员 userId 列表,用户本身会自动加入,无需包含,逗号分隔,不超过20个 (必填)
--name string 群名称 (必填)
```
---
## group members list — 查看群成员列表
分页查询指定群聊的成员。
```
Usage:
dws chat group members list [flags]
Example:
dws chat group members list --id <openconversation_id>
Flags:
--cursor string 分页游标,首次从 0 开始
--id string 群 ID / openconversation_id (必填)
```
> ⚠️ 注意:v1.0.17 起 list 是显式子命令;旧用法 `dws chat group members --id ...` 已不再支持,请改用 `dws chat group members list --id ...`。
---
## group members add — 添加群成员
向指定群聊添加成员,需传入群 ID 与用户 ID 列表。
```
Usage:
dws chat group members add [flags]
Example:
dws chat group members add --id <openconversation_id> --users userId1,userId2
Flags:
--id string 群 ID / openconversation_id (必填)
--users string 要添加的用户 userId 列表,逗号分隔 (必填)
```
---
## group members remove — 移除群成员
> ⚠️ 危险操作:执行前必须向用户确认,同意后才加 `--yes`。
```
Usage:
dws chat group members remove [flags]
Example:
dws chat group members remove --id <openconversation_id> --users userId1,userId2
Flags:
--id string 群 ID / openconversation_id (必填)
--users string 要移除的用户 userId 列表,逗号分隔 (必填)
```
---
## group members add-bot — 添加机器人到群
将自定义机器人添加到当前用户有管理权限的群聊中,如果没有权限则会报错。
```
Usage:
dws chat group members add-bot [flags]
Example:
dws chat group members add-bot --robot-code <robot-code> --id <openconversation_id>
Flags:
--id string 群聊 openConversationId (必填)
--robot-code string 机器人 Code (必填)
```
---
## group rename — 修改群名称
```
Usage:
dws chat group rename [flags]
Example:
dws chat group rename --id <openconversation_id> --name "新群名"
Flags:
--id string 群 ID / openconversation_id (必填)
--name string 修改后的群名称 (必填)
```
---
## search — 搜索群会话
根据名称搜索会话列表。
```
Usage:
dws chat search [flags]
Example:
dws chat search --query "项目冲刺"
Flags:
--cursor string 分页游标 (首页留空)
--query string 搜索关键词 (必填)
```
---
## search-common — 搜索共同群
根据昵称列表搜索共同群聊。--nicks 指定要搜索的人员昵称(逗号分隔,必填)。--match-mode 控制匹配模式:AND 表示所有人都在群里,OR 表示任一人在群里(默认 AND)。
```
Usage:
dws chat search-common [flags]
Example:
dws chat search-common --nicks "风雷,山乔" --limit 20 --cursor 0
dws chat search-common --nicks "天鸡,乐函" --match-mode OR --limit 20 --cursor 0
dws chat search-common --nicks "风雷,山乔,天鸡" --limit 10 --cursor <nextCursor>
Flags:
--nicks string 要搜索的昵称列表,逗号分隔 (必填)
--match-mode string 匹配模式:AND=所有人都在群里,OR=任一人在群里(默认 AND)
--limit int 每页返回数量(默认 20)
--cursor string 分页游标(默认 "0",翻页传 nextCursor
注意:
- --nicks 传人员昵称(花名),逗号分隔,如 "风雷,山乔"
- --match-mode AND 表示群里必须包含所有指定的人;OR 表示包含任意一人即可
- 翻页:hasMore=true 时,用返回的 nextCursor 作为下次 --cursor
```
---
## message send — 以当前用户身份发消息
--group 指定群聊 ID 发群消息;--user 指定用户 userId 发单聊;--open-dingtalk-id 指定用户 openDingTalkId 发单聊。三者只能选其一,不能同时指定。消息内容为位置参数(恰好 1 个),支持 Markdown。`--title` 是消息标题,**群聊与单聊都必填**(API 强制要求;缺失时服务端返回误导性的 "发群服务窗会话消息失败",CLI 现在前置校验直接报错)。
--群聊时可选 --at-all @所有人,或 --at-users 指定成员(仅群聊时生效)。
--发送图片消息:指定 --media-id(通过 dt_media_upload 工具上传获得),自动设置 msgType=image,此时不需要传文本内容。
```
Usage:
dws chat message send [flags] [<text>]
Example:
dws chat message send --group <openconversation_id> --title "周报" --text "请提交本周日报"
dws chat message send --user <userId> --title "提醒" --text "请查收"
dws chat message send --open-dingtalk-id <openDingTalkId> --title "提醒" --text "请查收"
dws chat message send --group <openconversation_id> --title "通知" "hello"
dws chat message send --group <openconversation_id> --title "周报提醒" --text "请大家本周五前提交周报"
dws chat message send --group <openconversation_id> --title "通知" --at-all "<@all> 请大家注意"
dws chat message send --group <openconversation_id> --title "通知" --at-users userId1,userId2 "<@userId1> <@userId2> 请查收"
dws chat message send --group <openconversation_id> --title "图片" --media-id <mediaId>
dws chat message send --open-dingtalk-id <openDingTalkId> --title "图片" --media-id <mediaId>
Flags:
--text string 消息内容(推荐使用,也可用位置参数)
--group string 群聊 openconversation_id(群聊时必填)
--user string 接收人 userId(单聊时与 --open-dingtalk-id 二选一)
--open-dingtalk-id string 接收人 openDingTalkId(单聊时与 --user 二选一,适用于三方应用等无法获取 userId 的场景)
--title string 消息标题(必填)
--at-all @所有人(仅群聊时生效,可选,默认 false)
--at-users string @指定成员的 userId 列表,逗号分隔(仅群聊时生效,可选)
--at-mobiles string @指定成员的手机号列表,逗号分隔(仅群聊时生效,可选)
--media-id string 图片 mediaId(通过 dt_media_upload 工具上传获得,需从返回链接中去除 _宽_高.格式 后缀并加上 @ 前缀),指定后发送图片消息,不需要传文本内容
--msg-type string 消息类型(可选,如 text/markdown/image/file;通常由 --text/--media-id/--dentry-id 自动推断)
--dentry-id string 钉盘文件 dentryId(发送钉盘文件消息时使用,需配合 --space-id
--space-id string 钉盘空间 spaceId(与 --dentry-id 配合使用)
--file-name string 文件消息的文件名
--file-size string 文件消息的文件大小(字节)
--file-type string 文件消息的文件类型(如 pdf / docx / xlsx 等)
注意:
- --text 和位置参数二选一,--text 优先
- --title 必填(群聊与单聊都必填,API 强制要求)
- --group、--user、--open-dingtalk-id 三者互斥,只需指定其一:群聊用 --group,单聊用 --user 或 --open-dingtalk-id
- --group 的别名: --id, --chat, --conversation-id (均可替代 --group)
- --at-all / --at-users / --at-mobiles 仅在 --group 群聊时生效;当设置--at-all时,消息内容中一定要包含对应的占位符<@all>;当设置--at-users userId1,userId2时,消息内容中一定要包含对应格式的占位符<@userId1> <@userId2>
- --media-id 指定图片 mediaId 时自动发送图片消息(msgType=image),不需要传 --text;图片单聊仅支持 --open-dingtalk-id,不支持 --user
- 发送钉盘文件消息:传 --dentry-id + --space-id(必要时配合 --file-name / --file-size / --file-type),msg-type 自动推断为 file
```
---
## message list — 拉取会话消息内容
拉取指定群聊或单聊的会话消息内容。
--group 指定群聊,--user 指定单聊用户(通过 userId),--open-dingtalk-id 指定单聊用户(通过 openDingTalkId),三者互斥。默认拉取给定时间之后的消息,--forward=false 拉之前的。
```
Usage:
dws chat message list [flags]
Example:
# 拉取群聊中某个时间点之后的消息
dws chat message list --group <openconversation_id> --time "2025-03-01 00:00:00"
# 拉取单聊消息(通过 userId)
dws chat message list --user <userId> --time "2025-03-01 00:00:00" --limit 50
# 拉取单聊消息(通过 openDingTalkId
dws chat message list --open-dingtalk-id <openDingTalkId> --time "2025-03-01 00:00:00" --limit 50
# 拉取某个时间点之前的消息(向过去翻页)
dws chat message list --group <openconversation_id> --time "2025-03-01 00:00:00" --forward=false
Flags:
--forward true=拉给定时间之后的消息,false=拉给定时间之前的消息 (default true)
--group string 群聊 openconversation_id(群聊时必填)
--limit int 返回数量,不传则不限制
--time string 开始时间,格式: yyyy-MM-dd HH:mm:ss(不传则默认拉取最新消息)
--user string 单聊用户 userId(单聊时与 --open-dingtalk-id 二选一)
--open-dingtalk-id string 单聊用户 openDingTalkId(单聊时与 --user 二选一,适用于三方应用等无法获取 userId 的场景)
注意:
- --group、--user、--open-dingtalk-id 三者互斥,只需指定其一:群聊用 --group,单聊用 --user 或 --open-dingtalk-id
- --group 的别名: --id, --chat, --conversation-id (均可替代 --group)
- 如果返回的会话消息中包含 openConvThreadId 字段,说明是话题类消息,需要调用 dws chat message list-topic-replies 拉取话题的回复内容列表,openConvThreadId 作为 --topic-id 参数
```
### 分页翻页说明(重要)
`message list` 的翻页方式与 `message list-all` **完全不同**,请勿混淆:
| 命令 | 翻页参数 | 翻页值来源 | 值格式 |
|------|---------|-----------|--------|
| `message list` | `--time` | 上一页结果中**最后一条消息的 `createTime` 字段** | `yyyy-MM-dd HH:mm:ss`(如 `"2025-03-01 14:30:00"` |
| `message list-all` | `--cursor` | 上一页响应中的 `nextCursor` 字段 | 字符串(如 `"abc123token"` |
**翻页步骤(message list):**
1. **首次请求**:指定起始时间
```bash
dws chat message list --group <id> --time "2025-03-01 00:00:00" --limit 50 --format json
```
2. **检查响应**:查看 `hasMore` 字段
- `hasMore: false` → 没有更多消息,翻页结束
- `hasMore: true` → 还有更多消息,继续下一步
3. **获取翻页时间**:取返回结果中**最后一条消息**的 `createTime` 字段值(如 `"2025-03-01 14:30:00"`
4. **下一页请求**:将该 `createTime` 作为 `--time` 传入
```bash
dws chat message list --group <id> --time "2025-03-01 14:30:00" --limit 50 --format json
```
5. 重复步骤 2-4 直到 `hasMore: false`
> ⚠️ **常见错误**
> - **不要把 `nextCursor` 传给 `--time`**:响应中的 `nextCursor` 字段(纯数字时间戳如 `1776684611219`**不是给 `--time` 用的**。`--time` 只接受 `yyyy-MM-dd HH:mm:ss` 格式。将 `nextCursor` 传给 `--time` 会导致返回相同页面,陷入死循环。`nextCursor` 仅用于 `message list-all` 的 `--cursor` 参数。
> - **不要把 `nextCursor` 传给 `--forward`**`--forward` 只接受 `true`(拉给定时间之后的消息)或 `false`(拉给定时间之前的消息),不是时间戳或游标参数。
---
## message list-all — 拉取指定时间范围内当前用户的所有会话消息
分页拉取当前登录用户在指定时间范围内的所有会话消息。
--start 和 --end 限定时间范围,--limit 指定每页数量,--cursor 传分页游标(首页传 "0",后续从响应中的 nextCursor 获取)。
```
Usage:
dws chat message list-all [flags]
Example:
dws chat message list-all --start "2025-03-01 00:00:00" --end "2025-03-31 23:59:59" --limit 50
dws chat message list-all --start "2025-03-01 00:00:00" --end "2025-03-31 23:59:59" --limit 50 --cursor "abc123token"
Flags:
--start string 起始时间,格式: yyyy-MM-dd HH:mm:ss (必填)
--end string 结束时间,格式: yyyy-MM-dd HH:mm:ss (必填)
--limit int 每页返回数量(默认 50)
--cursor string 分页游标(首页传 "0",后续从响应中的 nextCursor 获取)
注意:
- 四个参数每次请求都会传递给服务端,cursor 首页传 "0"
- 与 chat message list 的区别:list 拉取指定单个会话(群聊或单聊)的消息,list-all 拉取当前用户所有会话的消息
- 翻页:hasMore=true 时,用响应中的 nextCursor 值作为下次 --cursor 参数继续翻页
- 时间格式统一为 yyyy-MM-dd HH:mm:ss
```
---
## message list-topic-replies — 拉取群话题回复消息列表
查询指定群聊中某条话题消息的全部回复。--group 指定群会话 ID--topic-id 指定话题 ID(由 dws chat message list 返回)。
```
Usage:
dws chat message list-topic-replies [flags]
Example:
dws chat message list-topic-replies --group <openconversation_id> --topic-id <topicId>
dws chat message list-topic-replies --group <openconversation_id> --topic-id <topicId> --time "2025-03-01 00:00:00" --limit 20
Flags:
--group string 群会话 openconversationId (必填)
--topic-id string 话题 ID,由 dws chat message list 返回 (必填)
--time string 开始时间,格式: yyyy-MM-dd HH:mm:ss(可选)
--limit int 返回数量(默认 50)
--forward true=从老往新,false=从新往老(默认 false
```
---
## message list-by-sender — 拉取指定发送者的消息
搜索特定人发送给我的消息,返回结果包含单聊和群聊标识。--sender-user-id 指定发送者 userId--sender-open-dingtalk-id 指定发送者 openDingTalkId,二者互斥。
```
Usage:
dws chat message list-by-sender [flags]
Example:
dws chat message list-by-sender --sender-user-id <userId> --start "2026-03-10T00:00:00+08:00" --end "2026-03-11T00:00:00+08:00" --limit 50 --cursor 0
dws chat message list-by-sender --sender-open-dingtalk-id <openDingTalkId> --start "2026-03-10T00:00:00+08:00" --end "2026-03-11T00:00:00+08:00" --limit 50 --cursor 0
Flags:
--sender-user-id string 发送者 userId(与 --sender-open-dingtalk-id 二选一)
--sender-open-dingtalk-id string 发送者 openDingTalkId(与 --sender-user-id 二选一)
--start string 开始时间,ISO-8601 格式 (必填)
--end string 结束时间,ISO-8601 格式 (必填)
--limit int 每页返回数量(默认 50)
--cursor string 分页游标(默认 "0",翻页传 nextCursor
注意:
- --sender-user-id 和 --sender-open-dingtalk-id 二者互斥,必须且只能指定其一
- 不需要指定单聊/群聊,MCP 返回结果自带会话类型标识
- 时间支持多种 ISO-8601 格式,如 "2026-03-10T00:00:00+08:00"、"2026-03-10 14:00:00" 等
- 翻页:hasMore=true 时,用返回的 nextCursor 作为下次 --cursor
```
---
## message list-mentions — 拉取 @我 的消息
搜索时间范围内 @我 的消息,可选指定群聊。
```
Usage:
dws chat message list-mentions [flags]
Example:
dws chat message list-mentions --start "2026-03-10T00:00:00+08:00" --end "2026-03-11T00:00:00+08:00" --limit 50 --cursor 0
dws chat message list-mentions --group <openconversation_id> --start "2026-03-10T00:00:00+08:00" --end "2026-03-11T00:00:00+08:00" --limit 50 --cursor 0
Flags:
--group string 群聊 openconversation_id(可选,不传则查全部)
--start string 开始时间,ISO-8601 格式 (必填)
--end string 结束时间,ISO-8601 格式 (必填)
--limit int 每页返回数量(默认 50)
--cursor string 分页游标(默认 "0",翻页传 nextCursor
注意:
- --group 可选,不传则查询所有会话中 @我 的消息;传入则只查指定群聊
- --group 的别名: --id, --chat, --conversation-id (均可替代 --group)
- 翻页:hasMore=true 时,用返回的 nextCursor 作为下次 --cursor
```
---
## message list-focused — 拉取特别关注人的消息
拉取当前用户特别关注人的消息。
```
Usage:
dws chat message list-focused [flags]
Example:
dws chat message list-focused --limit 50
dws chat message list-focused --limit 20 --cursor <nextCursor>
Flags:
--limit int 每页返回数量(默认 50)
--cursor int64 分页游标(首次不传或传 0,翻页传 nextCursor
注意:
- 首次调用不传 --cursor 或传 0,后续翻页传 nextCursor
```
---
## message list-unread-conversations — 获取未读会话列表
获取当前用户有未读消息的会话信息。可选通过 `--count` 限制返回条数。
```
Usage:
dws chat message list-unread-conversations [flags]
Example:
dws chat message list-unread-conversations
dws chat message list-unread-conversations --count 20
Flags:
--count int 返回未读会话条数(可选)
```
---
## message search — 按关键词搜索消息
在当前用户的会话中按关键词搜索消息。--keyword 必填,可选 --group 限定搜索某个会话。
```
Usage:
dws chat message search [flags]
Example:
dws chat message search --keyword "changefree" --start "2026-04-01T00:00:00+08:00" --end "2026-04-15T00:00:00+08:00" --limit 50 --cursor 0
dws chat message search --keyword "codereview" --group <openconversation_id> --start "2026-04-01T00:00:00+08:00" --end "2026-04-15T00:00:00+08:00" --limit 100 --cursor 0
Flags:
--keyword string 搜索关键词 (必填)
--group string 群聊 openconversation_id(可选,不传则搜索所有会话)
--start string 开始时间,ISO-8601 格式 (必填)
--end string 结束时间,ISO-8601 格式 (必填)
--limit int 每页返回数量(默认 100)
--cursor string 分页游标(默认 "0",翻页传 nextCursor
注意:
- --group 可选,不传则搜索所有会话中的消息;传入则只搜索指定会话
- --group 的别名: --id, --chat, --conversation-id (均可替代 --group)
- 翻页:hasMore=true 时,用返回的 nextCursor 作为下次 --cursor
```
---
## conversation-info — 获取会话基础信息
按会话 ID 获取单聊或群聊的基础元数据(名称、类型、成员数等)。在对会话执行操作前用来确认上下文。
```
Usage:
dws chat conversation-info [flags]
Example:
dws chat conversation-info --group <openConversationId>
dws chat conversation-info --open-dingtalk-id <openDingTalkId>
Flags:
--group string 群聊会话 ID openConversationId(与 --open-dingtalk-id 二选一)
--open-dingtalk-id string 用户 openDingTalkId(单聊时与 --group 二选一)
注意:
- --group(群聊 openConversationId)和 --open-dingtalk-id(单聊用户 openDingTalkId)二选一
```
---
## list-top-conversations — 拉取置顶会话列表
拉取当前用户的置顶会话列表。
```
Usage:
dws chat list-top-conversations [flags]
Example:
dws chat list-top-conversations --limit 1000
dws chat list-top-conversations --limit 1000 --cursor <nextCursor>
Flags:
--limit int 每页返回数量(默认 1000)
--cursor int 分页游标(首次不传或传 0,翻页传 nextCursor
注意:
- 用户询问"置顶会话"时,直接调用此命令返回置顶会话列表即可
- 用户询问"置顶消息"时,需两步:先调用此命令拉取置顶会话列表获取各会话的 openConversationId,再用 `chat message list --group <openConversationId>` 分别拉取每个会话内的消息
- 翻页:hasMore=true 时,用返回的 nextCursor 作为下次 --cursor
```
---
## bot search — 搜索我的机器人
```
Usage:
dws chat bot search [flags]
Example:
dws chat bot search --page 1
dws chat bot search --page 1 --size 10 --name "日报"
Flags:
--name string 按名称搜索
--page int 页码,从1开始 (默认 1)
--size int 每页条数 (默认 50),别名: --limit
```
---
## message send-by-bot — 机器人发消息
群聊:传 --group 指定群;单聊:传 --users 指定用户列表,二者只能选其一,不能同时指定。--text 支持 Markdown。
```
Usage:
dws chat message send-by-bot [flags]
Example:
dws chat message send-by-bot --robot-code <robot-code> --group <openconversation_id> --title "日报" --text "## 今日完成..."
dws chat message send-by-bot --robot-code <robot-code> --users userId1,userId2 --title "提醒" --text "请提交周报"
Flags:
--group string 群聊 openConversationId(群聊时必填)
--robot-code string 机器人 Code (必填)
--text string 消息内容 Markdown (必填)
--title string 消息标题 (必填)
--users string 用户 userId 列表,逗号分隔,最多20个(单聊时必填)
注意:
- --group 与 --users 互斥,必须且只能指定其一
- --group 的别名: --id, --chat, --conversation-id (均可替代 --group)
```
---
## message recall-by-bot — 机器人撤回消息
群聊:传 --group 与 --keys;单聊:仅传 --keys。--keys 为发送时返回的 processQueryKey 列表,逗号分隔。
```
Usage:
dws chat message recall-by-bot [flags]
Example:
dws chat message recall-by-bot --robot-code <robot-code> --group <openconversation_id> --keys <process-query-key>
dws chat message recall-by-bot --robot-code <robot-code> --keys key1,key2
Flags:
--group string 群聊 openConversationId(群聊撤回时必填)
--keys string 消息 processQueryKey 列表,逗号分隔 (必填)
--robot-code string 机器人 Code (必填)
```
---
## message send-by-webhook — 自定义机器人 Webhook 发消息
@ 人时需在 --text 中包含 @userId 或 @手机号,否则 @ 不生效。
```
Usage:
dws chat message send-by-webhook [flags]
Example:
dws chat message send-by-webhook --token <webhook-token> --title "告警" --text "CPU 超 90%" --at-all
dws chat message send-by-webhook --token <webhook-token> --title "test" --text "hi @118785" --at-users 118785
Flags:
--at-all @ 所有人
--at-mobiles string @ 指定手机号,逗号分隔
--at-users string @ 指定用户,逗号分隔(需在 text 中包含 @userId
--text string 消息内容 (必填)
--title string 消息标题 (必填)
--token string Webhook Token (必填)
```
---
## 意图判断
用户说"建群/创建群聊" → `chat group create`
用户说"搜索群/找群" → `chat search`
用户说"群成员/看群里有谁" → `chat group members list`
用户说"拉人进群/加群成员" → `chat group members add`
用户说"踢人/移除群成员" → `chat group members remove`
用户说"加机器人到群" → `chat group members add-bot`
用户说"改群名" → `chat group rename`
用户说"聊天记录/会话消息/拉取会话" → `chat message list`
用户说"某人发给我的消息/指定发送者/某人的消息" → `chat message list-by-sender`(用户未明确说"单聊"时优先使用,跨单聊/群聊)
用户说"拉取和某人的单聊记录/单聊消息" → `chat message list --user`(用户明确说"单聊"时使用)
用户说"@我的消息/at我的/提及我的" → `chat message list-mentions`
用户说"未读消息会话/未读会话列表/我的未读会话" → `chat message list-unread-conversations`
用户说"发群消息(以个人身份)" → `chat message send --group`
用户说"发单聊消息(以个人身份)" → `chat message send --user`(有 userId 时)或 `chat message send --open-dingtalk-id`(有 openDingTalkId 时)
用户说"机器人发消息/机器人群发" → `chat message send-by-bot`
用户说"机器人撤回消息" → `chat message recall-by-bot`
用户说"Webhook 发消息/告警消息" → `chat message send-by-webhook`
用户说"话题回复/群话题消息回复/拉取话题回复" → `chat message list-topic-replies`
用户说"所有消息/全部会话消息/拉取全部消息/时间范围内消息/我的消息/我今天的消息/查我的钉钉消息/最近的消息" → `chat message list-all`
用户说"特别关注人的消息/关注的人的消息/星标联系人的消息" → `chat message list-focused`
用户说"查看我的机器人" → `chat bot search`
用户说"搜索消息/查找关键词/搜一下消息里的XX" → `chat message search`
用户说"我和XX的共同群/我们都在哪些群/查共同群" → `chat search-common`
用户说"置顶会话/置顶消息/我的置顶/查看置顶" → `chat list-top-conversations`
用户说"获取会话信息/会话详情/会话元数据" → `chat conversation-info`
关键区分:
- `chat message list` — 拉取指定会话的消息(需指定 --group 或 --user),按时间点 + 方向翻页
- `chat message list --user` — list 的单聊模式,拉取与指定用户的单聊记录(用户明确说"单聊""私聊"时使用)
- `chat message list-by-sender` — 搜索指定发送者发给我的消息,跨所有会话(单聊+群聊均包含,用户只说"某人发的消息"时优先使用)
- `chat message list-mentions` — 拉取 @我 的消息(跨单聊/群聊,可选指定群)
- `chat message list-unread-conversations` — 拉取当前用户存在未读消息的会话列表(可选 `--count`
- `chat message list-all` — 拉取当前用户所有会话的消息,按时间范围 + cursor 分页。只要用户没有指定某个具体的会话(如某个群名、某个人名),即使提到"单聊消息""群聊消息"等笼统范围,也应路由到此命令
- `chat message list-topic-replies` — 拉取群话题的回复消息列表
- `chat message list-focused` — 拉取特别关注人的消息,cursor 分页
- `chat list-top-conversations` — 拉取置顶会话列表(用户询问"置顶会话"或"置顶消息"时路由到此),cursor 分页
- `chat message send` — 以**当前用户**身份发消息(群聊或单聊),text 为位置参数;支持 --media-id 发送图片消息
- `chat message search` — 按关键词搜索消息内容(跨所有会话,可选指定群)
- `chat search-common` — 搜索共同群,查询指定人共同所在的群聊(AND=所有人都在,OR=任一人在)
- `chat message send-by-bot` — 以**机器人**身份发消息(群聊或单聊),text 为 --text flag
- `chat message send-by-webhook` — 通过**自定义机器人 Webhook** 发群消息
- `chat message recall-by-bot` — 通过机器人撤回已发送的消息
- `chat conversation-info` — 按会话 ID 获取单聊/群聊的基础元数据(名称、类型、成员数等)
- `chat bot search` — 搜索当前用户名下的机器人,拿到 robotCode 用于 send-by-bot / recall-by-bot / group members add-bot
## 核心工作流
```bash
# 1. 搜索群 — 提取 openconversation_id
dws chat search --query "项目冲刺" --format json
# 2. 拉取群消息
dws chat message list --group <openconversation_id> --time "2025-03-01 00:00:00" --format json
# 2b. 拉取未读会话列表
dws chat message list-unread-conversations --count 20 --format json
# 3. 以个人身份发送群消息
dws chat message send --group <openconversation_id> --title "周报提醒" "请大家本周五前提交周报" --format json
# 4. 以个人身份单聊(通过 userId)
dws chat message send --user <userId> --title "问候" "你好" --format json
# 4b. 以个人身份单聊(通过 openDingTalkId,三方应用等无法获取 userId 时使用)
dws chat message send --open-dingtalk-id <openDingTalkId> --title "问候" "你好" --format json
# 5. 机器人发群消息(Markdown
dws chat message send-by-bot --robot-code <robot-code> \
--group <openconversation_id> --title "日报" --text "## 今日完成..." --format json
# 6. 机器人单聊发消息
dws chat message send-by-bot --robot-code <robot-code> \
--users userId1,userId2 --title "提醒" --text "请提交周报" --format json
# 7. Webhook 发告警
dws chat message send-by-webhook --token <webhook-token> \
--title "告警" --text "CPU 超 90%" --at-all --format json
```
## 复合工作流
### 机器人发消息后撤回(完整流程)
撤回只能用于 `send-by-bot` 发出的消息。个人身份 (`chat message send`) 发出的消息**无法通过 API 撤回**。
```bash
# Step 1: 查我的机器人 — 提取 robot-code
dws chat bot search --format json
# Step 2: 用机器人发消息 — 提取返回中的 processQueryKey
dws chat message send-by-bot --robot-code <robot-code> --group <openconversation_id> \
--title "通知" --text "内容" --format json
# Step 3: 用同一个 robot-code + processQueryKey 撤回
dws chat message recall-by-bot --robot-code <robot-code> --group <openconversation_id> \
--keys <processQueryKey> --format json
```
### 将已有机器人加入群并发消息(完整流程)
机器人需先在钉钉开放平台创建好,这里只做"找机器人 → 加入群 → 发消息"。
```bash
# Step 1: 搜索我的机器人 — 提取 robotCode
dws chat bot search --name "项目提醒" --format json
# Step 2: 搜索群 — 提取 openConversationId
dws chat search --query "项目群" --format json
# Step 3: 将机器人添加到群(需当前用户对该群有管理权限)
dws chat group members add-bot --id <openConversationId> --robot-code <robotCode> --format json
# Step 4: 机器人发消息
dws chat message send-by-bot --robot-code <robotCode> --group <openConversationId> \
--title "提醒" --text "请及时更新项目状态" --format json
```
### 机器人 @指定人发群消息
`--text` 中**必须**包含 `<@userId>` 占位符,否则 @ 不生效。
```bash
# Step 1: 搜人获取 userId
dws aisearch person --keyword "张三" --dimension name --format json
# Step 2: 取 userId 发送(注意 text 中的占位符)
dws chat message send-by-bot --robot-code <robot-code> --group <openconversation_id> \
--title "提醒" --text "<@userId1> <@userId2> 请查收本周报告" --format json
```
### 发送图片/文件消息(跨产品: drive → chat
```bash
# Step 1: 上传文件到钉盘 — 获取 uploadId 和凭证
dws drive upload-info --file-name "截图.png" --file-size <字节数> --format json
# Step 2: HTTP PUT 上传文件到 OSS
curl -X PUT -T "截图.png" "<upload-info 返回的上传 URL>"
# Step 3: 提交上传 — 获取 dentryUuid
dws drive commit --file-name "截图.png" --file-size <字节数> --upload-id <uploadId> --format json
# Step 4: 获取下载链接
dws drive download --file-id <dentryUuid> --format json
# Step 5: 用 Markdown 图片语法发送
dws chat message send --group <openconversation_id> \
--title "截图" --text "![截图](下载链接)" --format json
```
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `chat search` | `openConversationId` | message send/list、group members 等的 --group |
| `chat group create` | `openConversationId` | 同上 |
| `chat message list-all` | `nextCursor` | 下次 list-all 的 --cursor |
| `aisearch person` | `userId` | message send 的 --user、--at-users、send-by-bot 的 --users、list-by-sender 的 --sender-user-id |
| `aisearch person` → `contact user get` | `openDingTalkId` | list-by-sender 的 --sender-open-dingtalk-id、message send/list 的 --open-dingtalk-id |
| `chat bot search` | `robotCode` | send-by-bot / recall-by-bot 的 --robot-code、group members add-bot 的 --robot-code |
| `chat message send-by-bot` | `processQueryKey` | recall-by-bot 的 --keys |
| `chat conversation-info` | `openConversationId` / 成员信息 | 作为 message send/list 等后续操作的会话上下文确认 |
| `chat message search` | `nextCursor` | 下次 message search 的 --cursor |
| `chat search-common` | `openConversationId` | message send/list 等的 --group |
| `drive download` | 下载链接 | message send 的 Markdown 图片/链接语法 |
## 注意事项
- `--group` 为群聊会话 ID (openconversation_id),可从群搜索或群聊信息中获取
- `chat message send` 的 text 是位置参数(恰好 1 个),非 flag;群聊用 `--group`,单聊用 `--user`userId)或 `--open-dingtalk-id`openDingTalkId),三者互斥;`--at-all`、`--at-users` 仅在 `--group` 群聊时生效;发送图片消息用 `--media-id`
- `chat message list-all` 的四个参数(--start、--end、--limit、--cursor)每次请求都必须传递;翻页时用响应中的 nextCursor 值作为下次 --cursor
- `chat message list` 的 `--group`、`--user`、`--open-dingtalk-id` 三者互斥,必须且只能指定其一
- `chat message list-by-sender` 不需要指定单聊/群聊,返回结果自带会话类型标识
- `chat message list-mentions` 可选 `--group` 指定群聊,不传则查全部
- `chat message list-unread-conversations` 获取当前用户未读会话列表,可选 `--count` 指定返回条数
- `chat message search` 按关键词搜索消息内容,`--keyword` 必填,可选 `--group` 限定搜索某个会话
- `chat search-common` 搜索共同群,`--nicks` 传人员昵称(逗号分隔),`--match-mode` AND/OR 控制匹配逻辑
- `chat list-top-conversations` 拉取置顶会话列表,分页用 `--limit`(默认 1000/`--cursor`
- `send-by-bot` 群聊传 `--group`,单聊传 `--users`,二者互斥且必选其一
- `recall-by-bot` 群聊传 `--group` + `--keys`,单聊仅传 `--keys`(不传 `--group` 即为单聊撤回)
- `send-by-webhook` 支持 `--at-all`、`--at-mobiles`、`--at-users` 进行 @ 操作,但需在 `--text` 中包含 `@userId` 或 `@手机号` 才能生效
## 自动化脚本
| 脚本 | 场景 | 用法 |
|------|------|------|
| [chat_export_messages.py](../../scripts/chat_export_messages.py) | 导出群聊消息到 JSON 文件 | `python chat_export_messages.py --query "项目冲刺" --time "2026-03-10 00:00:00"` |
| [chat_history_with_user.py](../../scripts/chat_history_with_user.py) | 查询与某人的单聊聊天记录 | `python chat_history_with_user.py --name "张三" --time "2026-03-10 00:00:00"` |
## 相关产品
- [contact](./contact.md) — 搜索同事/好友,获取 userId 用于 --user、--at-users、send-by-bot --users、list-by-sender --sender-user-id;获取 openDingTalkId 用于 list-by-sender --sender-open-dingtalk-id、--open-dingtalk-id
- [drive](./drive.md) — 上传文件获取下载链接,用于 Markdown 图片/文件消息
+107
View File
@@ -0,0 +1,107 @@
# 通讯录 (contact) 命令参考
## 命令总览
### user (人员查询)
#### 获取当前用户信息
```
Usage:
dws contact user get-self [flags]
Example:
dws contact user get-self
```
#### 按关键词搜索用户
```
Usage:
dws contact user search [flags]
Example:
dws contact user search --query "张三"
Flags:
--query string 搜索关键词 (必填)
```
#### 按手机号搜索用户
```
Usage:
dws contact user search-mobile [flags]
Example:
dws contact user search-mobile --mobile 13800138000
Flags:
--mobile string 手机号 (必填)
```
#### 批量获取用户详情
```
Usage:
dws contact user get [flags]
Example:
dws contact user get --ids userId1,userId2
Flags:
--ids string 用户 ID 列表,逗号分隔 (必填)
```
### dept (部门查询)
#### 搜索部门
```
Usage:
dws contact dept search [flags]
Example:
dws contact dept search --query "技术部"
Flags:
--query string 搜索关键词 (必填)
```
#### 查看部门成员
```
Usage:
dws contact dept list-members [flags]
Example:
dws contact dept list-members --ids 12345,67890
Flags:
--ids string 部门 ID 列表,逗号分隔 (必填)
```
## 意图判断
用户说"我是谁/我的信息" → `user get-self`
用户说"找人/搜人" → `user search`(按名字)或 `user search-mobile`(按手机号)
用户说"查用户详情" → `user get`(需 userId
用户说"找部门/哪个部门" → `dept search`
用户说"部门有谁/部门成员" → `dept list-members`(需 deptId
## 核心工作流
```bash
# 1. 查看自己的信息 — 提取 userId
dws contact user get-self --format json
# 2. 按名字搜索同事 — 提取 userId
dws contact user search --query "张三" --format json
# 3. 查看部门结构 — 提取 deptId
dws contact dept search --query "技术部" --format json
# 4. 查看部门成员
dws contact dept list-members --ids <deptId> --format json
```
## 上下文传递表
| 操作 | 提取 | 用于 |
|------|------|------|
| `user get-self/search` | `userId` | 其他产品中的 --users/--executor 参数 |
| `dept search` | `deptId` | dept list-members 的 --ids |
## 注意事项
- `user get-self` 是获取 userId 的最快方式,其他产品的 --users/--executor 都需要 userId
- `user get --ids``dept list-members --ids` 都支持批量查询,逗号分隔
## 自动化脚本
| 脚本 | 场景 | 用法 |
|------|------|------|
| [contact_dept_members.py](../../scripts/contact_dept_members.py) | 按部门名称搜索并列出所有成员 | `python contact_dept_members.py --keyword "技术部"` |
+48
View File
@@ -0,0 +1,48 @@
# 开放平台文档 (devdoc) 命令参考
搜索钉钉**开放平台**开发文档,用于回答开发者关于 OpenAPI、字段、错误码、接入指南、配额等技术问题。
## 命令总览
### 搜索开发文档
```
Usage:
dws devdoc article search [flags]
Example:
dws devdoc article search --query "OAuth2 接入"
dws devdoc article search --query "消息卡片" --page 2 --size 5
dws devdoc article search --query "机器人" --size 10
Flags:
--query string 搜索关键词 (必填)
--page int 分页页码 (从 1 开始,默认 1)
--size int 分页大小 (默认 10)
```
## 意图判断
用户问开放平台 API / 字段 / 错误码 / SDK / 鉴权 / 回调 / 配额相关的技术细节:
-`devdoc article search`,把用户问的关键短语作为 `--query`
关键区分:
- devdoc(钉钉**开放平台**开发者文档,面向研发) vs doc(钉钉在线文档,面向普通用户内容)
- devdoc 只做搜索,不做读取;命中条目返回标题、摘要、文档链接,由 Agent 引用链接或进一步浏览
## 核心工作流
```bash
# 开发者问"OAuth2 怎么接"
dws devdoc article search --query "OAuth2 接入" --format json
# 命中结果多时翻页
dws devdoc article search --query "消息卡片" --page 2 --size 5 --format json
# 查错误码 / 字段含义
dws devdoc article search --query "errcode 40078" --format json
```
## 注意事项
- `--query` 必填;建议传用户原话里的关键名词(API 名、错误码、能力名),不要过度改写
- 返回按相关性排序,默认 `--size 10`;要拿更多结果时先翻页,再考虑换关键词
- 命中结果里的链接是钉钉开放平台公开文档,可直接给用户做参考
- 不要把 devdoc 用来查业务数据(那是 aitable / doc / report 的事);devdoc 只查**官方开发者文档**
+57
View File
@@ -0,0 +1,57 @@
# DING 消息 (ding) 命令参考
## 命令总览
### 发送 DING 消息
```
Usage:
dws ding message send [flags]
Example:
dws ding message send --robot-code <ROBOT_CODE> --users <USER_ID_1>,<USER_ID_2> --content "请查看"
Flags:
--content string 消息内容 (必填)
--robot-code string 机器人 ID (必填, 可从 应用管理→机器人 获取, 或设 DINGTALK_DING_ROBOT_CODE)
--users string 接收人 userId 列表 (必填)
--type string 提醒类型: app/sms/call (默认 app)
```
### 撤回 DING 消息
```
Usage:
dws ding message recall [flags]
Example:
dws ding message recall --robot-code <ROBOT_CODE> --id <OPEN_DING_ID>
Flags:
--id string DING 消息 ID (必填)
--robot-code string 机器人 ID (必填, 或设 DINGTALK_DING_ROBOT_CODE)
```
## 意图判断
用户说"DING 一下/紧急通知/电话提醒" → `message send`
用户说"撤回 DING" → `message recall`
关键区分:
- ding(紧急提醒, 支持电话/短信) vs bot(常规群/单聊消息)
- sms/call 类型有通信费用
## 核心工作流
```bash
# 应用内 DING (免费)
dws ding message send --robot-code <ROBOT_CODE> --type app --users userId1,userId2 --content "请查看" --format json
# 电话 DING (紧急, 有成本!)
dws ding message send --robot-code <ROBOT_CODE> --type call --users userId1 --content "紧急告警" --format json
# 撤回
dws ding message recall --robot-code <ROBOT_CODE> --id <OPEN_DING_ID> --format json
```
## 上下文传递表
| 操作 | 提取 | 用于 |
|------|------|------|
| `message send` | `openDingId` | message recall 的 --id |
## 注意事项
- `--robot-code` 从钉钉开放平台 **应用管理 → 机器人** 中获取,也可设环境变量 `DINGTALK_DING_ROBOT_CODE`
- sms/call 类型有通信费用,使用前需和用户确认
- 默认 `--type app`(应用内 DING,免费)
+577
View File
@@ -0,0 +1,577 @@
# 文档 (doc) 命令参考
## 命令总览
### 搜索文档
```
Usage:
dws doc search [flags]
Example:
dws doc search --query "会议纪要"
dws doc search
dws doc search --extensions pdf,docx
dws doc search --query "方案" --created-from 1700000000000 --created-to 1710000000000
dws doc search --creator-uids uid1,uid2
dws doc search --workspace-ids wsId1,wsId2
Flags:
--query string 搜索关键词 (不传则返回最近访问)
--extensions strings 按文件扩展名过滤,不含点号,逗号分隔 (如 pdf,docx,png)。支持的在线文档类型后缀名: adoc=文字, axls=表格, appt=演示文稿, awbd=白板, adraw=画板, amind=脑图, able=多维表格, aform=收集表
--created-from int 创建时间起始 (毫秒时间戳,含)
--created-to int 创建时间截止 (毫秒时间戳,含)
--visited-from int 访问时间起始 (毫秒时间戳,含)
--visited-to int 访问时间截止 (毫秒时间戳,含)
--creator-uids strings 按创建者用户 ID 过滤,逗号分隔
--editor-uids strings 按编辑者用户 ID 过滤,逗号分隔
--mentioned-uids strings 按 @提及的用户 ID 过滤,逗号分隔
--workspace-ids strings 按知识库 ID 过滤,支持知识库 URL,逗号分隔
--page-size int 每页数量 (默认 10,最大 30)
--page-token string 分页游标 (从上次结果的 nextPageToken 获取)
```
### 遍历文件列表
```
Usage:
dws doc list [flags]
Example:
dws doc list
dws doc list --folder <FOLDER_ID>
dws doc list --workspace <WS_ID> --page-size 20
Flags:
--folder string 文件夹 ID 或 URL
--workspace string 知识库 ID
--page-size int 每页数量 (默认 50,最大 50)
--page-token string 分页游标 (从上次结果的 nextPageToken 获取)
```
### 获取文档元信息
```
Usage:
dws doc info [flags]
Example:
dws doc info --node <DOC_ID>
dws doc info --node "https://alidocs.dingtalk.com/i/nodes/<DOC_UUID>"
Flags:
--node string 文档 ID 或 URL (必填)
```
### 读取文档内容
```
Usage:
dws doc read [flags]
Example:
dws doc read --node <DOC_ID>
dws doc read --node "https://alidocs.dingtalk.com/i/nodes/<DOC_UUID>"
Flags:
--node string 文档 ID 或 URL (必填)
```
### 创建文档
```
Usage:
dws doc create [flags]
Example:
dws doc create --name "项目周报"
dws doc create --name "Q1 总结" --markdown "# Q1 总结" --folder <FOLDER_ID>
dws doc create --name "知识库文档" --workspace <WS_ID>
Flags:
--name string 文档名称 (必填)
--folder string 目标文件夹 ID 或 URL
--workspace string 目标知识库 ID
--markdown string 文档初始 Markdown 内容
```
### 创建其他类型文件 (表格/脑图/白板/多维表/画板)
```
Usage:
dws doc file create [flags]
Example:
dws doc file create --name "项目周报" --type adoc
dws doc file create --name "数据统计" --type axls --folder <FOLDER_ID>
dws doc file create --name "思维导图" --type amind --workspace <WS_ID>
dws doc file create --name "子文件夹" --type folder
Flags:
--name string 文件名称 (必填)
--type string 文件类型 (必填): adoc=文档, axls=表格, appt=演示, adraw=白板, amind=脑图, able=多维表, folder=文件夹
--folder string 目标文件夹 ID 或 URL
--workspace string 目标知识库 ID 或 URL
```
### 更新文档内容
```
Usage:
dws doc update [flags]
Example:
dws doc update --node <DOC_ID> --markdown "# 追加内容" --mode append
dws doc update --node <DOC_ID> --markdown "# 完整替换" --mode overwrite
Flags:
--node string 文档 ID 或 URL (必填)
--markdown string Markdown 内容 (必填)
--mode string 更新模式: overwrite=覆盖, append=追加 (默认 append)
```
### 上传文件到钉钉文档或钉钉知识库
```
Usage:
dws doc upload [flags]
Example:
dws doc upload --file ./report.pdf
dws doc upload --file ./slides.pptx --name "Q1汇报.pptx" --folder <FOLDER_ID>
dws doc upload --file ./data.xlsx --workspace <WS_ID> --convert
Flags:
--file string 本地文件路径 (必填)
--name string 文件显示名称 (默认使用文件名)
--folder string 目标文件夹 ID 或 URL
--workspace string 目标知识库 ID
--convert 是否转换为钉钉在线文档
```
### 下载文件到本地
```
Usage:
dws doc download [flags]
Example:
dws doc download --node <NODE_ID>
dws doc download --node <NODE_ID> --output ./report.pdf
dws doc download --node "https://alidocs.dingtalk.com/i/nodes/<DOC_UUID>" --output ~/downloads/
Flags:
--node string 文件节点 ID 或 URL (必填)
--output string 本地保存路径 (文件路径或目录,必填)
```
### 创建文件夹
```
Usage:
dws doc folder create [flags]
Example:
dws doc folder create --name "项目资料"
dws doc folder create --name "子文件夹" --folder <PARENT_FOLDER_ID>
Flags:
--name string 文件夹名称 (必填)
--folder string 父文件夹 ID 或 URL
--workspace string 目标知识库 ID
```
### 复制文档/文件
```
Usage:
dws doc copy [flags]
Example:
dws doc copy --node <DOC_ID> --folder <TARGET_FOLDER_ID>
dws doc copy --node <DOC_ID> --workspace <TARGET_WS_ID>
dws doc copy --node "https://alidocs.dingtalk.com/i/nodes/<DOC_UUID>" --folder <FOLDER_ID>
Flags:
--node string 源文档/文件 ID 或 URL (必填)
--folder string 目标文件夹 ID 或 URL
--workspace string 目标知识库 ID 或 URL (不传 --folder 时复制到该知识库根目录)
```
### 移动文档/文件
```
Usage:
dws doc move [flags]
Example:
dws doc move --node <DOC_ID> --folder <TARGET_FOLDER_ID>
dws doc move --node <DOC_ID> --workspace <TARGET_WS_ID>
Flags:
--node string 源文档/文件 ID 或 URL (必填)
--folder string 目标文件夹 ID 或 URL
--workspace string 目标知识库 ID 或 URL (不传 --folder 时移动到该知识库根目录)
```
### 重命名文档/文件
```
Usage:
dws doc rename [flags]
Example:
dws doc rename --node <DOC_ID> --name "新名称"
dws doc rename --node "https://alidocs.dingtalk.com/i/nodes/<DOC_UUID>" --name "项目周报 v2"
Flags:
--node string 文档/文件 ID 或 URL (必填)
--name string 新名称 (必填)
```
### 查询块元素
```
Usage:
dws doc block list [flags]
Example:
dws doc block list --node <DOC_ID>
dws doc block list --node <DOC_ID> --start-index 0 --end-index 5
dws doc block list --node <DOC_ID> --block-type heading
Flags:
--node string 文档 ID 或 URL (必填)
--start-index int 起始位置 (从 0 开始)
--end-index int 终止位置 (含)
--block-type string 按块类型过滤
```
### 插入块元素
```
Usage:
dws doc block insert [flags]
Example:
dws doc block insert --node <DOC_ID> --text "这是一段文字"
dws doc block insert --node <DOC_ID> --heading "二级标题" --level 2
dws doc block insert --node <DOC_ID> --element '{"blockType":"paragraph","paragraph":{"text":"内容"}}'
dws doc block insert --node <DOC_ID> --text "在此处之前插入" --ref-block <BLOCK_ID> --where before
Flags:
--node string 文档 ID 或 URL (必填)
--text string 快捷: 段落文本内容
--heading string 快捷: 标题文本
--level int 标题级别 1-6 (配合 --heading,默认 1)
--element string 块元素 JSON (高级)
--index int 参照位置索引 (从 0 开始)
--where string 插入方向: before / after (默认 after)
--ref-block string 参照块 ID (优先级高于 --index)
```
### 更新块元素
```
Usage:
dws doc block update [flags]
Example:
dws doc block update --node <DOC_ID> --block-id <BLOCK_ID> --text "新内容"
dws doc block update --node <DOC_ID> --block-id <BLOCK_ID> --element '{"blockType":"heading","heading":{"text":"新标题","level":1}}'
Flags:
--node string 文档 ID 或 URL (必填)
--block-id string 目标块 ID (必填)
--text string 快捷: 段落文本内容
--heading string 快捷: 标题文本
--level int 标题级别 1-6 (配合 --heading,默认 1)
--element string 块元素 JSON (高级)
```
### 删除块元素
> **CAUTION:** 不可逆操作 — 执行前必须向用户确认。
```
Usage:
dws doc block delete [flags]
Example:
dws doc block delete --node <DOC_ID> --block-id <BLOCK_ID> --yes
Flags:
--node string 文档 ID 或 URL (必填)
--block-id string 目标块 ID (必填)
```
### 查询文档评论列表
```
Usage:
dws doc comment list [flags]
Example:
dws doc comment list --node <DOC_ID>
dws doc comment list --node <DOC_ID> --type inline --resolve-status unresolved
dws doc comment list --node <DOC_ID> --page-size 20 --next-token <TOKEN>
Flags:
--node string 目标文档的标识,支持传入 URL 或 ID (必填)
--page-size int 每页返回的评论数量,默认 50,最大 50
--next-token string 分页游标,从上一次请求的返回结果中获取 (首次请求不传)
--type string 按评论类型过滤: global (全文评论) / inline (划词评论)
--resolve-status string 按解决状态过滤: resolved (已解决) / unresolved (未解决)
```
### 创建文档评论
```
Usage:
dws doc comment create [flags]
Example:
dws doc comment create --node <DOC_ID> --content "这里需要修改"
dws doc comment create --node <DOC_ID> --content "请review" --mention uid1,uid2
Flags:
--node string 目标文档的标识,支持传入 URL 或 ID (必填)
--content string 评论的文字内容,纯文本 (必填)
--mention string 被 @ 的用户 uid 列表,逗号分隔
```
### 创建划词评论 (内联评论)
```
Usage:
dws doc comment create-inline [flags]
Example:
dws doc comment create-inline --node <DOC_ID> --block-id <BLOCK_ID> --start 0 --end 10 --content "这里需要修改"
dws doc comment create-inline --node <DOC_ID> --block-id <BLOCK_ID> --start 5 --end 20 --content "建议调整" --selected-text "被选中的原文"
dws doc comment create-inline --node <DOC_ID> --block-id <BLOCK_ID> --start 0 --end 10 --content "请review" --mention uid1,uid2
Flags:
--node string 目标文档的标识,支持传入 URL 或 ID (必填)
--block-id string 评论锚定所在的块 ID (必填,可通过 dws doc block list 获取)
--start int 选中文本在块内的起始字符偏移量,从 0 开始 (必填)
--end int 选中文本在块内的结束字符偏移量,必须大于 start (必填)
--content string 评论的文字内容,纯文本 (必填)
--selected-text string 选中文本内容,填写后评论列表会展示「引用原文:xxx」
--mention string 被 @ 的用户 uid 列表,逗号分隔
```
### 回复文档评论
```
Usage:
dws doc comment reply [flags]
Example:
dws doc comment reply --node <DOC_ID> --comment-key <COMMENT_KEY> --content "同意"
dws doc comment reply --node <DOC_ID> --comment-key <COMMENT_KEY> --content "比心" --emoji
dws doc comment reply --node <DOC_ID> --comment-key <COMMENT_KEY> --content "请确认" --mention uid1,uid2
Flags:
--node string 目标文档的标识,支持传入 URL 或 ID (必填)
--content string 回复的文字内容,表情回复时填写表情名称 (必填)
--comment-key string 被回复评论的 commentKey,格式: {13位毫秒时间戳}{32位UUID},可从 list/create 结果获取 (必填)
--emoji 设为 true 时作为表情贴图回复 (默认 false)
--mention string 被 @ 的用户 uid 列表,逗号分隔
```
## URL 识别与 DOC_ID 提取
当用户输入包含钉钉文档 URL 时,**必须先识别并提取 DOC_ID**,再判断意图。
### 支持的 URL 格式
| 格式 | 示例 | DOC_ID 提取方式 |
|------|------|----------------|
| `alidocs.dingtalk.com/i/nodes/{id}` | `https://alidocs.dingtalk.com/i/nodes/9E05BDRVQePjzLkZt2p2vE7kV63zgkYA` | 取 URL 路径最后一段:`9E05BDRVQePjzLkZt2p2vE7kV63zgkYA` |
| `alidocs.dingtalk.com/i/nodes/{id}?queryParams` | `https://alidocs.dingtalk.com/i/nodes/abc123?doc_type=wiki_doc` | 忽略 query 参数,取路径最后一段:`abc123` |
### 提取规则
1. 匹配 URL 中 `alidocs.dingtalk.com` 域名
2. 取 URL path 的最后一段作为 DOC_ID(去掉 query string 和 fragment
3. 提取出的 DOC_ID 可直接用于所有 `--node` 参数,也可将完整 URL 传给 `--node`CLI 会自动解析)
### 处理流程
```
用户输入含 alidocs.dingtalk.com URL
→ 提取 DOC_ID(URL 路径最后一段)
→ 结合用户意图选择命令(默认 read)
→ 将 DOC_ID 传给 --node 参数
```
## 意图判断
用户说"找文档/搜文档/最近文档":
- 搜索 → `search`
- 浏览 → `list`
用户说"看文档/读内容/文档内容":
- 读取 → `read` (需文档 ID 或 URL)
- 元信息 → `info`
用户说"写文档/创建文档":
- 新建纯文档 (adoc) → `create`
- 追加内容 → `update --mode append`
- 覆盖替换 → `update --mode overwrite`
用户说"新建表格/脑图/白板/多维表/演示文稿":
-`file create --type` 指定类型 (axls/amind/adraw/able/appt/adraw)
用户说"建文件夹/新建目录":
- 创建 → `folder create``file create --type folder`
用户说"复制文档/拷贝一份":
- 复制 → `copy` (需源 --node 和目标 --folder/--workspace)
用户说"移动文档/换个目录":
- 移动 → `move` (需源 --node 和目标 --folder/--workspace)
用户说"改文档名字/重命名":
- 改名 → `rename` (需 --node 和新 --name)
用户说"上传文件/传文件/上传到文档/上传到知识库":
- 上传 → `upload`(需本地文件路径)
- 上传并转换 → `upload --convert`
用户说"下载文件/导出文件/下载到本地":
- 下载 → `download`(需文件节点 ID 或 URL
用户说"编辑块/改段落/插入标题/删除块":
- 查看结构 → `block list`
- 插入 → `block insert`
- 修改 → `block update`
- 删除 → `block delete`
**用户直接粘贴文档 URL(无其他指令)**:
- 默认 → `read`(读取文档内容)
- 如 URL 明显是文件夹 → `list`(列出文件夹内容)
**用户粘贴 URL + 附加指令**:
- "帮我看看这个文档" → `read`
- "这个文档的信息" → `info`
- "往这个文档追加内容" → `update --mode append`
- "编辑这个文档的标题" → `block update`
关键区分: doc(文档编辑/阅读) vs aitable(数据表格操作) vs drive(钉盘文件管理)
## 核心工作流
```bash
# ── 工作流 1: 浏览并阅读文档 ──
# 1. 浏览我的文档根目录
dws doc list --format json
# 2. 浏览子文件夹
dws doc list --folder <FOLDER_ID> --format json
# 3. 获取文档元信息 (标题、类型、权限)
dws doc info --node <DOC_ID> --format json
# 4. 读取文档内容 (Markdown 格式)
dws doc read --node <DOC_ID> --format json
# ── 工作流 2: 创建文档并写入内容 ──
# 1. (可选) 创建文件夹 — 提取 nodeId
dws doc folder create --name "项目资料" --format json
# 2. 创建文档 — 提取 nodeId
dws doc create --name "项目周报" --folder <FOLDER_ID> --format json
# 3. 写入内容 (追加模式)
dws doc update --node <DOC_ID> --markdown "# 本周总结\n\n- 完成了 A\n- 推进了 B" --mode append --format json
# ── 工作流 3: 一步创建带内容的文档 ──
dws doc create --name "会议纪要" --markdown "# 会议纪要\n\n## 议题\n\n1. ..." --format json
# ── 工作流 4: 上传本地文件到钉钉文档/知识库 ──
# 1. 上传到"我的文档"根目录
dws doc upload --file ./report.pdf
# 2. 上传到指定文件夹
dws doc upload --file ./slides.pptx --name "Q1汇报.pptx" --folder <FOLDER_ID>
# 3. 上传到知识库并转换为在线文档
dws doc upload --file ./data.xlsx --workspace <WS_ID> --convert
# ── 工作流 5: 下载文件到本地 ──
# 1. 下载到当前目录 (自动推断文件名)
dws doc download --node <NODE_ID>
# 2. 下载到指定路径
dws doc download --node <NODE_ID> --output ./report.pdf
# 3. 下载到指定目录 (自动推断文件名)
dws doc download --node <NODE_ID> --output ~/downloads/
# ── 工作流 6: 块级精细编辑 ──
# 1. 查看文档块结构 — 获取 blockId
dws doc block list --node <DOC_ID> --format json
# 2. 在文档末尾插入段落
dws doc block insert --node <DOC_ID> --text "新增内容"
# 3. 在指定块之前插入标题
dws doc block insert --node <DOC_ID> --heading "新章节" --level 2 --ref-block <BLOCK_ID> --where before
# 4. 更新某个块的内容
dws doc block update --node <DOC_ID> --block-id <BLOCK_ID> --text "修改后的内容"
# 5. 删除块
dws doc block delete --node <DOC_ID> --block-id <BLOCK_ID> --yes
# ── 工作流 7: 文档评论管理 ──
# 1. 查看文档的所有评论
dws doc comment list --node <DOC_ID> --format json
# 2. 在文档上创建全文评论
dws doc comment create --node <DOC_ID> --content "这里需要补充数据来源" --format json
# 3. 创建评论并 @ 相关人
# 先搜索用户: dws contact user search --query "张三" --format json → 提取 userId
# 再将 userId 传入 --mention
dws doc comment create --node <DOC_ID> --content "请确认这部分内容" --mention <userId1>,<userId2> --format json
# 4. 对某段文字创建划词评论(需先 block list 拿 blockId 和字符偏移)
dws doc block list --node <DOC_ID> --format json
dws doc comment create-inline --node <DOC_ID> --block-id <BLOCK_ID> --start 0 --end 12 \
--content "这里的数据要复核" --selected-text "被选中的原文片段" --format json
# 5. 回复某条评论(commentKey 从 list 或 create 返回中获取)
dws doc comment reply --node <DOC_ID> --comment-key <COMMENT_KEY> --content "已修改" --format json
# 6. 用表情回复评论
dws doc comment reply --node <DOC_ID> --comment-key <COMMENT_KEY> --content "比心" --emoji --format json
# ── 工作流 8: 创建非文档类型文件 ──
# 创建表格 / 脑图 / 白板 / 多维表 / 演示文稿
dws doc file create --name "销售数据" --type axls --folder <FOLDER_ID> --format json
dws doc file create --name "需求脑图" --type amind --workspace <WS_ID> --format json
dws doc file create --name "Q1 立项会" --type appt --format json
# ── 工作流 9: 整理文档结构 (复制 / 移动 / 重命名) ──
# 1. 把模板复制到目标目录作为新工作件
dws doc copy --node <TEMPLATE_DOC_ID> --folder <TARGET_FOLDER_ID> --format json
# 2. 把文档从个人空间挪到团队知识库
dws doc move --node <DOC_ID> --workspace <WS_ID> --format json
# 3. 重命名
dws doc rename --node <DOC_ID> --name "项目周报 v2" --format json
```
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `list` | `nodes[].nodeId` | read / info / update / block 操作的 --node |
| `list` | folder 类型的 `nodeId` | list 的 --folder, create 的 --folder |
| `search` | 文档 `nodeId` / URL / `createTime` / `creatorUid` | read / info / update 的 --node;创建时间与创建者信息 |
| `create` | `nodeId` | update / block 操作的 --node |
| `folder create` | `nodeId` | create / list / upload 的 --folder |
| `block list` | `blockId` | block insert 的 --ref-block, block update/delete 的 --block-id |
| `upload` | `nodeId` / URL | 上传后文件的访问链接 |
| `download` | 本地文件路径 | 下载后的文件保存位置 |
| `comment list` | `commentList[].commentKey` | comment reply 的 --comment-key |
| `comment create` / `comment create-inline` | `commentKey` | comment reply 的 --comment-key |
| `block list` | `blockId` + 文本内容 | comment create-inline 的 --block-id 及 --start/--end 计算 |
| `contact user search` | `userId` | comment create / create-inline / reply 的 --mention |
| `file create` | `nodeId` | 后续 read / update / block 操作的 --node(仅 adoc 支持 read/updateaxls/amind 等类型用各自产品的命令) |
| `copy` / `move` | 新 `nodeId`copy)或原 nodeIdmove | 后续 read / info 等的 --node |
## nodeId 双格式说明
所有 `--node` 参数同时支持两种格式,系统自动识别:
- **文档 ID**: 字母数字字符串,如 `9E05BDRVQePjzLkZt2p2vE7kV63zgkYA`
- **文档 URL**: `https://alidocs.dingtalk.com/i/nodes/{dentryUuid}`,如 `https://alidocs.dingtalk.com/i/nodes/9E05BDRVQePjzLkZt2p2vE7kV63zgkYA`
两种方式等价,以下命令效果相同:
```bash
dws doc read --node 9E05BDRVQePjzLkZt2p2vE7kV63zgkYA
dws doc read --node "https://alidocs.dingtalk.com/i/nodes/9E05BDRVQePjzLkZt2p2vE7kV63zgkYA"
```
`--folder` 参数同样支持文件夹 URL 或 ID。
## 注意事项
- `update --mode overwrite` 会**清空原内容后重写**,⚠️ 谨慎使用;默认 `--mode append` (追加) 更安全
- `read` 返回 Markdown 格式的文档内容,仅限有"下载"权限的文档
- `create` 不传 `--folder``--workspace` 时,默认创建在"我的文档"根目录
- `block list/insert/update/delete` 是块级精细编辑,适合结构化修改;简单内容追加建议用 `update --mode append`
- `block insert` 优先使用 `--text``--heading` 快捷方式;复杂块类型 (table, callout 等) 使用 `--element` JSON
- `markdown` 参数中的换行必须使用**真实换行符**(即实际的换行字符,Unicode `U+000A`),而不是字面量字符串 `\n`(反斜杠加字母 n)。在通过程序或大模型构造此参数时,请确保字符串在发送前已正确反转义。如果传入的是两个字符的字面量 `\n`,所有内容将渲染在同一行,导致标题、段落和表格格式全部错乱。
- 块类型包括: paragraph, heading, blockquote, callout, columns, orderedList, unorderedList, table, sheet, attachment, slot
- 关键区分: doc(文档编辑/阅读) vs aitable(数据表格操作) vs drive(钉盘文件管理)
- `upload` 支持上传任意类型文件 (PDF、Office、图片等) 到钉钉文档空间或知识库;`--convert` 可将 Office 文件转换为钉钉在线文档
- `upload` 是三步自动完成的流程 (获取凭证 → OSS 上传 → 提交入库),无需手动分步操作
- `download` 是两步自动完成的流程 (获取下载链接 → HTTP GET 下载),支持自动推断文件名;`--output` 可指定文件路径或目录
- `create` 只能建"文档"(adoc);要建表格/脑图/白板/多维表/演示/文件夹,用 `file create --type`
- `copy` 需要对源节点有"阅读"权限、对目标目录有"编辑"权限;`move` 需要对源节点有"管理"权限
- `copy` / `move` 不传 `--folder` 时,`--workspace` 表示放到知识库根目录;两者都不传则回落到"我的文档"
- `comment create` 是全文评论;`comment create-inline` 是划词评论,必须先 `block list` 拿到 `blockId` 并确定 `--start` / `--end` 偏移(按块内纯文本字符算,从 0 开始)
## 自动化脚本
| 脚本 | 场景 | 用法 |
|------|------|------|
| [doc_create_and_write.py](../../scripts/doc_create_and_write.py) | 创建文档并写入 Markdown 内容 | `python doc_create_and_write.py --name "周报" --content "# 本周总结"` |
## 相关产品
- [aitable](./aitable.md) — 结构化数据表格(行列/字段/记录),不是富文本文档
- [drive](./drive.md) — 钉盘文件存储/上传/下载,不是文档内容编辑
- [report](./report.md) — 钉钉日志系统(日报/周报模版),不是在线文档
+177
View File
@@ -0,0 +1,177 @@
# 钉盘 (drive) 命令参考
钉盘 = DingTalk Drive,用于云端文件存储 / 上传 / 下载 / 目录管理。不是在线文档编辑;要编辑文档请用 [doc](./doc.md)。
## 命令总览
### 列出钉盘目录
```
Usage:
dws drive list [flags]
Example:
dws drive list
dws drive list --parent-id <FOLDER_ID>
dws drive list --parent-id <FOLDER_ID> --max 20 --order-by modifiedTime --order desc
Flags:
--parent-id string 父目录 ID (不传则列根目录)
--space-id string 钉盘空间 ID (一般无需指定)
--max int 每页数量 (默认 20)
--next-token string 分页游标 (从上次结果的 nextToken 获取)
--order-by string 排序字段: name / createdTime / modifiedTime
--order string 排序方向: asc / desc
--thumbnail 是否返回缩略图链接
```
### 获取文件元信息
```
Usage:
dws drive info [flags]
Example:
dws drive info --file-id <FILE_ID>
Flags:
--file-id string 文件或文件夹 ID (必填)
--space-id string 钉盘空间 ID (一般无需指定)
```
### 创建文件夹
```
Usage:
dws drive mkdir [flags]
Example:
dws drive mkdir --name "项目资料"
dws drive mkdir --name "子目录" --parent-id <PARENT_FOLDER_ID>
Flags:
--name string 文件夹名称 (必填)
--parent-id string 父目录 ID (不传则建在根目录)
--space-id string 钉盘空间 ID (一般无需指定)
```
### 获取下载临时链接
```
Usage:
dws drive download [flags]
Example:
dws drive download --file-id <FILE_ID>
Flags:
--file-id string 文件 ID (必填)
--space-id string 钉盘空间 ID (一般无需指定)
```
### 获取上传凭证 (上传第一步)
```
Usage:
dws drive upload-info [flags]
Example:
dws drive upload-info --file-name "report.pdf" --file-size 102400
dws drive upload-info --file-name "slides.pptx" --file-size 512000 --parent-id <FOLDER_ID>
Flags:
--file-name string 文件名含后缀 (必填)
--file-size int 文件大小,单位字节 (必填)
--mime-type string MIME 类型 (可选,服务端会自动推断)
--parent-id string 父目录 ID (不传则上传到根目录)
--space-id string 钉盘空间 ID (一般无需指定)
```
### 提交上传 (上传第三步)
```
Usage:
dws drive commit [flags]
Example:
dws drive commit --file-name "report.pdf" --file-size 102400 --upload-id <UPLOAD_ID>
Flags:
--file-name string 文件名含后缀 (必填,须与 upload-info 一致)
--file-size int 文件大小,单位字节 (必填,须与 upload-info 一致)
--upload-id string upload-info 返回的 uploadId (必填)
--parent-id string 父目录 ID (必填时须与 upload-info 一致)
--space-id string 钉盘空间 ID (一般无需指定)
--conflict-handler string 同名冲突策略: AUTO_RENAME / OVERWRITE / RETURN_DENTRY_IF_EXIST (默认 AUTO_RENAME)
```
## 意图判断
用户说"钉盘有什么文件/列钉盘/看钉盘目录" → `list`
用户说"钉盘文件详情/文件信息" → `info` (需 fileId)
用户说"新建钉盘目录/钉盘里建文件夹" → `mkdir`
用户说"下载钉盘文件/把这个文件拿下来" → `download` 拿临时 URL,再由 Agent 自行发起 HTTP GET
用户说"上传文件到钉盘/把本地文件传钉盘":
- 三步走: `upload-info` → HTTP PUT 到预签名 URL → `commit`
- **没有**一条聚合命令可以完成;必须完整走完三步
关键区分:
- drive(钉盘云存储,面向文件二进制) vs doc(在线文档/知识库,面向富文本内容)
- 把图片/文件发到群里一般走 drive 上传拿链接 → chat 发送 Markdown 链接 (见 [chat.md](./chat.md) 的 `drive → chat` 工作流)
## 核心工作流
```bash
# ── 工作流 1: 浏览钉盘 ──
# 1. 看根目录
dws drive list --format json
# 2. 进入子目录 (parentId 取自上一步的 dentryUuid)
dws drive list --parent-id <FOLDER_ID> --format json
# 3. 看单个文件的元信息
dws drive info --file-id <FILE_ID> --format json
# ── 工作流 2: 上传本地文件到钉盘 (三步不能省) ──
# Step 1: 拿上传凭证
dws drive upload-info --file-name "report.pdf" --file-size 102400 --parent-id <FOLDER_ID> --format json
# → 返回: resourceUrl (预签名 URL), headers, uploadId
# Step 2: Agent 自己发 HTTP PUT 把文件二进制推到 resourceUrl
# 请求头必须携带返回的 headers 全部键值对;期望 HTTP 200
curl -X PUT -T ./report.pdf -H "<header-from-step-1>: <value>" "<resourceUrl>"
# Step 3: 提交入库
dws drive commit --file-name "report.pdf" --file-size 102400 --upload-id <UPLOAD_ID> \
--parent-id <FOLDER_ID> --format json
# → 返回: dentryUuid (= 后续 download/info 用的 fileId)
# ── 工作流 3: 下载钉盘文件到本地 (两步) ──
# Step 1: 拿临时下载 URL
dws drive download --file-id <FILE_ID> --format json
# → 返回: resourceUrl (带签名的临时下载 URL), expirationSeconds
# Step 2: Agent 自己发 HTTP GET 下载二进制
curl -o ./report.pdf "<resourceUrl>"
# ── 工作流 4: 建目录后批量上传 ──
# 1. 建目录 → 拿 folderId
dws drive mkdir --name "2026 Q1 归档" --format json
# 2. 再走 "工作流 2" 把每个文件上传到该目录
```
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `list` | `dentryUuid` (folder 类) | 下次 list 的 --parent-id、upload-info / commit 的 --parent-id、mkdir 的 --parent-id |
| `list` | `dentryUuid` (file 类) | info / download 的 --file-id |
| `list` | `nextToken` | 下次 list 的 --next-token |
| `mkdir` | `dentryUuid` | 作为父目录传给 upload-info / commit 的 --parent-id |
| `upload-info` | `resourceUrl` + `headers` | Agent 自行执行 HTTP PUT 上传二进制 |
| `upload-info` | `uploadId` | commit 的 --upload-id |
| `commit` | `dentryUuid` | download / info / chat message 发送图片链接的 --file-id |
| `download` | `resourceUrl` | Agent 自行执行 HTTP GET 下载;也可作为 Markdown 图片/附件链接发送到 chat |
## 注意事项
- 上传是**三步**流程:`upload-info` → 客户端 HTTP PUT 到预签名 URL → `commit`。**没有**自动聚合命令,跳过任何一步都会失败
- Step 2 的 HTTP PUT 必须把 upload-info 返回的 `headers` 全部回传,`Content-Type` 通常要留空;只有 PUT 返回 200 才能调 `commit`
- 上传凭证 (`uploadId`) 有过期时间,拿到后尽快 commit;过期需重新调 `upload-info`
- `download` 只返回临时 URL(几分钟级别有效期),不会把文件落地;要真正下载到本地必须再发 HTTP GET
- `--parent-id` 在 upload-info / commit 中要保持一致,否则 commit 会报位置不匹配
- `--conflict-handler` 默认 `AUTO_RENAME` (自动重命名)`OVERWRITE` 覆盖同名文件前必须和用户确认
- `--space-id` 绝大多数场景不需要传;默认会用用户主钉盘空间
- 文件名规则:头尾不能有空格;不能含 `*``"``<``>``|`、制表符;不能以 `.` 结尾
## 相关产品
- [doc](./doc.md) — 钉钉在线文档 / 知识库(文字、表格、脑图等富文本节点),和 drive 的裸文件存储不同
- [chat](./chat.md) — 结合 drive 发送图片 / 附件消息到群聊(Markdown 链接语法)
+160
View File
@@ -0,0 +1,160 @@
# 邮箱 (mail) 命令参考
## 命令总览
### 查询可用邮箱地址
```
Usage:
dws mail mailbox list [flags]
Example:
dws mail mailbox list
```
**返回字段:**
| 字段 | 类型 | 说明 |
|------|------|------|
| `mailboxes` | `List[]` | 邮箱列表,每条包含邮箱地址、账号类型、所属企业 |
### 搜索邮件 (KQL 语法)
```
Usage:
dws mail message search [flags]
Example:
dws mail message search --email user@company.com --query "subject:\"周报\"" --size 20
dws mail message search --email user@company.com --query "from:alice AND date>2025-06-01T00:00:00Z" --size 10
Flags:
--cursor string 邮件的起始偏移标识, 其值取自响应中的nextCursor字段。""表示从头开始
--email string 搜索目标邮箱地址 (必填)
--query string KQL 查询表达式 (必填), 其中 date 格式需遵循 ISO8601 规范
--size string 每页返回数量(最大限制 100, 默认 20) (必填),别名: --limit, --page-size
```
KQL 查询字段: date, size, tag, folderId, isRead, hasAttachments, subject, attachname, body, from, to
常用文件夹 ID: 1=已发送, 2=收件箱, 3=垃圾邮件, 5=草稿, 6=已删除
### KQL 查询字段说明
| 字段 | 类型 | 说明 | 正确示例 | 错误示例 |
|------|------|------|----------|----------|
| `date` | ISO8601 日期时间 | 邮件日期,支持 `>` `<` `>=` `<=` 比较运算符 | `date>2025-06-01T00:00:00Z` | `date>2025-06-01`(缺少时间部分) |
| `size` | 整数(字节数) | 邮件大小,支持 `>` `<` `>=` `<=` 比较运算符 | `size>1024` | `size>"1024"`(值不需要引号) |
| `tag` | 字符串 | 邮件标签 | `tag:important` | `tag:""` |
| `folderId` | 整数 | 文件夹 ID(1=已发送, 2=收件箱, 3=垃圾邮件, 5=草稿, 6=已删除) | `folderId:2` | `folderId:"收件箱"`(必须用数字 ID |
| `isRead` | 布尔 `true`/`false` | 是否已读 | `isRead:false` | `isRead:0``isRead:"false"`(不支持数字或字符串形式) |
| `hasAttachments` | 布尔 `true`/`false` | 是否有附件 | `hasAttachments:true` | `hasAttachments:yes` |
| `subject` | 字符串 | 邮件主题,含空格须加双引号 | `subject:周报``subject:"项目 进展"` | `subject:项目 进展`(含空格未加引号) |
| `attachname` | 字符串 | 附件文件名,含空格须加双引号 | `attachname:report.pdf``attachname:"月度 报告.xlsx"` | `attachname:月度 报告.xlsx`(含空格未加引号) |
| `body` | 字符串 | 邮件正文内容,含空格须加双引号 | `body:会议纪要``body:"Q1 总结"` | `body:Q1 总结`(含空格未加引号) |
| `from` | 字符串(邮件地址或名称) | 发件人,支持:纯邮件地址、纯名称(含空格须加双引号)、`"名称<邮件地址>"` 格式 | `from:alice@company.com``from:"张 三"``from:"alice<a@b.com>"` | `from:张 三`(含空格未加引号) |
| `to` | 字符串(邮件地址或名称) | 收件人,支持:纯邮件地址、纯名称(含空格须加双引号)、`"名称<邮件地址>"` 格式 | `to:bob@company.com``to:"李 四"``to:"alice<a@b.com>"` | `to:李 四`(含空格未加引号) |
**组合查询说明:**
- 支持 `AND` / `OR` / `NOT` 逻辑运算符(大写)
- 括号用于分组:`(from:alice OR from:bob) AND folderId:2`
- 排除特定文件夹:`(NOT folderId:3) AND (NOT folderId:6)`
### message search 返回值说明
| 字段 | 类型 | 说明 |
|------|------|------|
| `messages` | `List[]` | 邮件列表,每条包含邮件 ID 及元信息(不含正文) |
| `total` | `int32` | 符合条件的总邮件数 |
| `nextCursor` | `string` | 下一页游标,传入 `--cursor` 翻页;值为 `$` 表示已到达列表尾部 |
**翻页示例:**
```bash
# 第一页
dws mail message search --email user@company.com --query "folderId:2" --size 20 --format json
# 取返回中的 nextCursor,传入下一次请求(nextCursor="$" 时停止)
dws mail message search --email user@company.com --query "folderId:2" --size 20 --cursor <nextCursor> --format json
```
### 查看邮件完整内容
```
Usage:
dws mail message get [flags]
Example:
dws mail message get --email user@company.com --id <messageId>
Flags:
--email string 邮件所属邮箱地址 (必填)
--id string 邮件 ID (必填)
```
**返回字段:**
| 字段 | 类型 | 说明 |
|------|------|------|
| `message` | `object` | 邮件完整信息,包含主题、发件人、收件人、正文、附件等 |
### 发送邮件
```
Usage:
dws mail message send [flags]
Example:
dws mail message send --from user@company.com --to colleague@company.com \
--subject "周报" --body "本周完成任务A和任务B"
Flags:
--body string 邮件正文,支持 Markdown 格式 (必填)
--cc string 抄送人列表
--from string 发件人邮箱 (必填),别名: --sender
--subject string 邮件标题 (必填)
--to string 收件人列表 (必填)
```
## 通用错误说明
以下错误适用于所有 mail 命令。
| 错误标识 | 含义 | 处理建议 |
|----------|------|----------|
| `domain.notFound` | 该用户的邮箱不是由钉钉邮箱托管,无法完成操作 | 确认邮箱是否已开通钉钉企业邮箱服务 |
## 意图判断
用户说"我的邮箱/邮箱地址" → `mailbox list`
用户说"找邮件/搜邮件/查邮件" → `message search`
用户说"看邮件/打开邮件/邮件内容" → 先 `message search` 获取 messageId,再 `message get`
用户说"发邮件/写邮件" → 先 `mailbox list` 获取发件地址,再 `message send`
用户说"给(某人名字)发邮件" → 先 `aisearch person` 获取 userId,再 `contact user get` 获取收件人邮箱,再 `message send`
## 严格禁止 (NEVER DO)
- 明确禁止猜测、假设、推断发件人和收件人邮箱
- 无法获取邮箱时,强引导ask_human,由用户确认,不要通过假设或其他方式继续执行
## 核心工作流
```bash
# 1. 查看可用邮箱 — 提取邮箱地址
dws mail mailbox list --format json
# 2. 搜索邮件 — 提取 messageId
dws mail message search --email user@company.com \
--query "subject:\"周报\" AND date>2025-06-01T00:00:00Z" --size 10 --format json
# 3. 查看邮件详情
dws mail message get --email user@company.com --id <messageId> --format json
# 4. 发送邮件
dws mail message send --from user@company.com --to colleague@company.com \
--subject "周报" --body "本周完成…" --format json
```
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `mailbox list` | 邮箱地址 | message search/get/send 的 --email/--from |
| `message search` | `messageId` | message get 的 --id |
| `aisearch person``contact user get` | 用户邮箱 (orgAuthEmail) | message send 的 --to/--cc (跨产品) |
## 注意事项
- `mailbox list` 返回用户所有邮箱(含个人和企业),每条记录包含邮箱地址、账号类型、所属企业。选择邮箱时优先匹配用户当前所在企业的企业邮箱;若有多个可选,向用户确认后再操作
- `message search` 返回邮件 ID 和元信息(不含正文),需 `message get` 获取完整内容
- KQL 查询支持 AND/OR/NOT 组合,字段值含空格时需用双引号
- `--cc` 抄送人支持多人,逗号分隔
- 收件人邮箱获取:用户只知道同事名字时,先通过 `dws aisearch person --keyword "名字" --dimension name` 获取 userId,再 `dws contact user get --ids <userId>` 从返回中提取 orgAuthEmail 字段
+369
View File
@@ -0,0 +1,369 @@
# AI听记 (minutes) 命令参考
AI 听记:列表 / 详情 / 摘要 / 待办 / 文字稿 / 思维导图 / 发言人 / 热词 / 文件上传。
## 命令总览
### 查询我创建的听记列表
```
Usage:
dws minutes list mine [flags]
Example:
dws minutes list mine
dws minutes list mine --max 10
dws minutes list mine --max 10 --next-token <nextToken>
dws minutes list mine --query "周会"
Flags:
--max float 查询的听记篇数 (默认 10)
--next-token string 分页 token (首页留空,后续填写前次返回的 nextToken)
--query string 关键字筛选 (可选)
--start string 开始时间 ISO-8601 (可选)
--end string 结束时间 ISO-8601 (可选)
```
查询我创建的听记列表,支持 `--max``--next-token` 分页,支持按关键字和时间范围筛选。
### 查询他人共享给我的听记列表
```
Usage:
dws minutes list shared [flags]
Example:
dws minutes list shared
dws minutes list shared --max 20
dws minutes list shared --max 5 --next-token <nextToken>
Flags:
--max float 查询的听记篇数 (默认 10)
--next-token string 分页 token (首页留空,后续填写前次返回的 nextToken)
--query string 关键字筛选 (可选)
--start string 开始时间 ISO-8601 (可选)
--end string 结束时间 ISO-8601 (可选)
```
查询他人共享给我的听记列表,支持 `--max``--next-token` 分页,支持按关键字和时间范围筛选。
### 查询我有权限访问的所有听记列表
```
Usage:
dws minutes list all [flags]
Example:
dws minutes list all
dws minutes list all --max 20
dws minutes list all --query "周会" --max 20
dws minutes list all --start "2026-03-01T00:00:00+08:00" --end "2026-03-20T23:59:59+08:00"
dws minutes list all --max 10 --next-token <nextToken>
Flags:
--end string 结束时间 ISO-8601 (可选)
--query string 关键字筛选 (可选)
--max float 查询的听记篇数 (默认 10)
--next-token string 分页 token (首页留空,后续填写前次返回的 nextToken)
--start string 开始时间 ISO-8601 (可选)
```
查询我有权限访问的所有听记列表(包括我创建的、他人共享给我的等所有有权限的听记)。支持按关键字和时间范围筛选。时间范围和关键字为可选参数,不传则返回所有有权限的听记。支持使用 `--max``--next-token` 进行分页查询。
### 获取听记基础信息
```
Usage:
dws minutes get info [flags]
Example:
dws minutes get info --id <taskUuid>
Flags:
--id string 听记 taskUuid (必填),取值逻辑参考 ## 注意事项
```
返回字段: 创建人、开始时间、截止时间、听记标题、听记访问链接URL
### 获取听记 AI 摘要
```
Usage:
dws minutes get summary [flags]
Example:
dws minutes get summary --id <taskUuid>
Flags:
--id string 听记 taskUuid (必填),取值逻辑参考 ## 注意事项
```
返回 Markdown 格式摘要,涵盖会议主题、核心结论、关键讨论点等
### 获取听记关键字列表
```
Usage:
dws minutes get keywords [flags]
Example:
dws minutes get keywords --id <taskUuid>
Flags:
--id string 听记 taskUuid (必填),取值逻辑参考 ## 注意事项
```
### 获取听记语音转写原文
```
Usage:
dws minutes get transcription [flags]
Example:
dws minutes get transcription --id <taskUuid>
dws minutes get transcription --id <taskUuid> --direction 1
Flags:
--direction string 排序方向: 0=正序, 1=倒序 (默认 0)
--id string 听记 taskUuid (必填),取值逻辑参考 ## 注意事项
--next-token string 下一页的token 首次查询可空 后续查询需填写前次请求返回的nextToken
```
每条记录包含: 发言人信息、转写文本、对应时间戳
### 获取听记中提取的待办事项
```
Usage:
dws minutes get todos [flags]
Example:
dws minutes get todos --id <taskUuid>
Flags:
--id string 听记 taskUuid (必填),取值逻辑参考 ## 注意事项
```
每条记录包含: 待办内容、待办唯一ID、参与人信息、待办时间
### 批量查询听记详情
```
Usage:
dws minutes get batch [flags]
Example:
dws minutes get batch --ids uuid1,uuid2,uuid3
Flags:
--ids string 听记 taskUuid 列表,逗号分隔 (必填)
```
返回字段: 听记标题、时长、参与人列表、创建时间、taskUuid、听记状态
### 修改听记标题
```
Usage:
dws minutes update title [flags]
Example:
dws minutes update title --id <taskUuid> --title "Q2 复盘会议"
Flags:
--id string 听记 taskUuid (必填),取值逻辑参考 ## 注意事项
--title string 新标题 (必填)
```
### 覆盖听记 AI 摘要
```
Usage:
dws minutes update summary [flags]
Example:
dws minutes update summary --id <taskUuid> --content "修订后的摘要 Markdown"
Flags:
--id string 听记 taskUuid (必填)
--content string 新的摘要正文 (必填),会整体覆盖原摘要
```
将 AI 生成的摘要替换成定制版本,适合人工修订或按业务口径重写后回写。
### 全文替换听记文本
```
Usage:
dws minutes replace-text [flags]
Example:
dws minutes replace-text --id <taskUuid> --search "小钉" --replace "DingTalk"
Flags:
--id string 听记 taskUuid (必填)
--search string 需要替换的原文 (必填)
--replace string 替换后的文本 (必填)
```
在转写段落与摘要中一次性替换所有命中文本,适合纠正系统性的识别错误(如专有名词)。
### 替换发言人标签
```
Usage:
dws minutes speaker replace [flags]
Example:
dws minutes speaker replace --id <taskUuid> --from "说话人1" --to "张三"
dws minutes speaker replace --id <taskUuid> --from "说话人1" --to "张三" --target-uid <userId>
Flags:
--id string 听记 taskUuid (必填)
--from string 原发言人昵称,如 "说话人1" (必填)
--to string 新发言人昵称 (必填)
--target-uid string 绑定到指定钉钉 userId (可选)
```
修正自动分离的发言人标签,可顺带把该说话人对应到真实用户。
### 添加个人热词
```
Usage:
dws minutes hot-word add [flags]
Example:
dws minutes hot-word add --words "钉钉,悟空,DWS"
Flags:
--words string 热词列表,逗号分隔 (必填)
```
把专有名词/业务术语写入个人热词库,后续听记的语音识别会优先匹配,用来兜底高频误识别。
### 生成思维导图
```
Usage:
dws minutes mind-graph create [flags]
Example:
dws minutes mind-graph create --id <taskUuid>
Flags:
--id string 听记 taskUuid (必填)
```
异步任务:提交后返回 jobId,需要用 `mind-graph status` 轮询结果。
### 查询思维导图状态
```
Usage:
dws minutes mind-graph status [flags]
Example:
dws minutes mind-graph status --id <taskUuid>
Flags:
--id string 听记 taskUuid (必填)
```
轮询 `mind-graph create` 的生成任务,就绪后返回思维导图内容。
### 创建文件上传会话
```
Usage:
dws minutes upload create [flags]
Example:
dws minutes upload create --file-name "会议录音.m4a" --file-size 10485760 --title "Q2 复盘"
Flags:
--file-name string 本地文件名 (必填)
--file-size string 文件大小,单位字节 (必填)
--title string 听记标题 (可选)
--template-id string 摘要模板 ID (可选)
--input-language string 语言,如 zh_CN / en_US (可选)
--enable-message-card string 是否推送消息卡片: true/false (可选)
```
三步上传的第 1 步:返回 sessionId 和预签名 URL,由调用方把本地音视频文件 HTTP PUT 到该 URL。
### 完成上传并生成听记
```
Usage:
dws minutes upload complete [flags]
Example:
dws minutes upload complete --session-id <sessionId>
Flags:
--session-id string upload create 返回的 sessionId (必填)
```
三步上传的第 3 步:通知服务端文件已上传完毕,触发转写与 AI 处理,返回新的 taskUuid。
### 取消上传
```
Usage:
dws minutes upload cancel [flags]
Example:
dws minutes upload cancel --session-id <sessionId>
Flags:
--session-id string upload create 返回的 sessionId (必填)
```
上传中途放弃或上游出错时释放会话,避免残留。
## 意图判断
用户说"我的听记/我创建的听记" → `list mine`(可附加 `--query``--start``--end` 筛选)
用户说"别人给我的听记/共享听记" → `list shared`(可附加 `--query``--start``--end` 筛选)
用户说"有权限的听记/我能访问的听记/所有听记" → `list all`(可附加 `--query``--start``--end` 筛选)
用户说"某时间段内的听记/按时间查听记/按关键词查听记" → 根据所属范围选择 `list mine`/`list shared`/`list all`,附加 `--start``--end``--query` 参数
用户说"听记详情/听记信息" → `get info`
用户说"批量看听记/一次查多篇" → `get batch``--ids` 传逗号分隔 taskUuid
用户说"摘要/总结/会议纪要" → `get summary`
用户说"关键字/关键词" → `get keywords`
用户说"原文/转写/录音文字" → `get transcription`
用户说"会议待办/听记待办" → `get todos`
用户说"改听记标题/重命名听记" → `update title`
用户说"改摘要/覆盖摘要/重写总结" → `update summary`
用户说"全文替换/批量改转写里的错字/专有名词搞错了" → `replace-text`
用户说"改发言人/把说话人1改成张三/认领发言人" → `speaker replace`
用户说"加热词/让后续识别更准/把某个专业术语教给系统" → `hot-word add`
用户说"生成思维导图/导图/脑图" → `mind-graph create`(异步),再 `mind-graph status` 轮询
用户说"上传录音生成听记/把本地音视频变听记" → `upload create` → 本地 PUT → `upload complete`;放弃则 `upload cancel`
用户传入听记 URL(如 `https://shanji.dingtalk.com/app/transcribes/xxx`),从 URL 提取 taskUuid,再执行对应的 get/update 操作
## 核心工作流
```bash
# 1. 查看我的听记列表 — 提取 taskUuid
dws minutes list mine --format json
dws minutes list mine --max 10 --next-token <nextToken> --format json
dws minutes list mine --query "周会" --format json
# 1b. 查看共享给我的听记
dws minutes list shared --max 20 --format json
dws minutes list shared --query "日报" --format json
# 1c. 查看我有权限访问的所有听记(支持关键字和时间范围筛选)
dws minutes list all --format json
dws minutes list all --query "周会" --start "2026-03-01T00:00:00+08:00" --end "2026-03-20T23:59:59+08:00" --format json
# 2. 获取 AI 摘要
dws minutes get summary --id <taskUuid> --format json
# 3. 查看完整转写原文
dws minutes get transcription --id <taskUuid> --format json
# 4. 提取待办事项
dws minutes get todos --id <taskUuid> --format json
# 5. 批量补齐多个 taskUuid 的详情
dws minutes get batch --ids <taskUuid1>,<taskUuid2>,<taskUuid3> --format json
# 6. 修改标题 / 覆盖摘要
dws minutes update title --id <taskUuid> --title "新标题" --format json
dws minutes update summary --id <taskUuid> --content "修订后的摘要 Markdown" --format json
# 7. 修正转写错字 / 发言人标签 / 加热词
dws minutes replace-text --id <taskUuid> --search "小钉" --replace "DingTalk" --format json
dws minutes speaker replace --id <taskUuid> --from "说话人1" --to "张三" --format json
dws minutes hot-word add --words "钉钉,悟空,DWS" --format json
# 8. 异步生成思维导图(create 拿 jobIdstatus 轮询)
dws minutes mind-graph create --id <taskUuid> --format json
dws minutes mind-graph status --id <taskUuid> --format json
# 9. 从本地音视频上传生成听记(三步走)
dws minutes upload create --file-name "会议录音.m4a" --file-size 10485760 --title "Q2 复盘" --format json
# → 拿到 sessionId 和预签名 URL,调用方自行 HTTP PUT 把文件推上去
dws minutes upload complete --session-id <sessionId> --format json
# 放弃上传
dws minutes upload cancel --session-id <sessionId> --format json
```
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `list mine` | `taskUuid``nextToken` | get/update 的 --id;翻页时 --next-token |
| `list shared` | `taskUuid``nextToken` | get/update 的 --id;翻页时 --next-token |
| `list all` | `taskUuid``nextToken` | get/update 的 --id;翻页时 --next-token |
| `get batch` | 各听记 `taskUuid` | 进一步查询详情 |
| `upload create` | `sessionId`、预签名 URL | 本地 PUT 上传 + `upload complete` / `upload cancel` 的 --session-id |
| `upload complete` | 新听记 `taskUuid` | 后续 get/update/mind-graph 的 --id |
| `mind-graph create` | 异步 jobId(随 taskUuid 关联) | `mind-graph status` 的 --id 查进度与结果 |
## 注意事项
- `taskUuid` 是听记的唯一标识,所有 get/update/mind-graph/speaker/replace-text 操作均以此为入参
- 如果用户传入听记 URL(格式: `https://shanji.dingtalk.com/app/transcribes/<taskUuid>`),直接从路径末段提取 taskUuid 作为 `--id` 参数,无需再调用 list 查询
- `list mine``list shared``list all` 统一走 `list_by_keyword_and_time_range` 链路,通过 `belongingConditionId` 区分(`created` / `shared` / `noLimit`);三者均支持 `--max``--next-token` 分页及 `--query``--start``--end` 筛选
- `list mine``list shared` 默认每页 20 条,`list all` 默认每页 10 条
- `get info` 是单条查询;`get batch` 是批量补齐 ID 列表(`--ids` 逗号分隔),用在"有一串 taskUuid,想一次拿标题/时长/参与人"的场景
- `get summary` 返回 AI 生成的结构化 Markdown 摘要;`update summary` 会整体覆盖原摘要,不做增量合并
- `get transcription``--direction` 控制时间排序: 0=正序(默认), 1=倒序
- `replace-text` 是系统性纠错:命中即替换,整篇转写与摘要一起改,慎用模糊文本
- `speaker replace` 只改"标签",不重跑说话人分离;`--target-uid` 可顺带把该说话人绑定到真实 userId
- `hot-word add` 作用于**个人**热词库,只对本人后续的听记识别生效
- `mind-graph create` 是异步:调用后立即返回,需要用 `mind-graph status --id <taskUuid>` 轮询到 ready 才能拿到图
- 上传流程严格三步:`upload create`(拿 sessionId + 预签名 URL)→ 客户端自己 HTTP PUT 文件 → `upload complete`(触发转写);中途放弃必须用 `upload cancel` 释放会话,不要只丢 sessionId
## 自动化脚本
| 脚本 | 场景 | 用法 |
|------|------|------|
| [minutes_recent_summary.py](../../scripts/minutes_recent_summary.py) | 获取最近听记的 AI 摘要并合并 | `python minutes_recent_summary.py --max 5` |
| [minutes_extract_todos.py](../../scripts/minutes_extract_todos.py) | 从听记中提取待办事项汇总 | `python minutes_extract_todos.py --max 5` |
+199
View File
@@ -0,0 +1,199 @@
# OA 审批 (oa) 命令参考
钉钉 OA 审批:待办审批列表 / 查看详情 / 同意 / 拒绝 / 撤销 / 流程记录 / 表单模板。
## 命令总览
### 查询待我处理的审批实例
```
Usage:
dws oa approval list-pending [flags]
Example:
dws oa approval list-pending
dws oa approval list-pending --page 1 --size 20
dws oa approval list-pending --start "2026-03-01T00:00:00+08:00" --end "2026-03-31T23:59:59+08:00"
Flags:
--page string 页码 (默认 1)
--size string 每页数量 (默认 10)
--start string 提交开始时间 ISO-8601 (可选)
--end string 提交结束时间 ISO-8601 (可选)
```
"待办收件箱"视图:列出当前用户仍需动作的审批 `processInstanceId`。注意返回的是**实例 ID**,真正驱动 approve/reject 还需要用 `tasks` 再换成 `taskId`
### 查询我发起的审批实例
```
Usage:
dws oa approval list-initiated [flags]
Example:
dws oa approval list-initiated
dws oa approval list-initiated --process-code <processCode> --max-results 20
dws oa approval list-initiated --start "2026-03-01T00:00:00+08:00" --end "2026-03-31T23:59:59+08:00" --next-token <nextToken>
Flags:
--process-code string 按指定表单/流程模板过滤 (可选)
--start string 发起开始时间 ISO-8601 (可选)
--end string 发起结束时间 ISO-8601 (可选)
--max-results string 每页条数 (可选)
--next-token string 分页 token (首页留空)
```
查询当前用户作为申请人发起的审批,用来查"我报销到哪一步了"、"我之前提的请假单"。
### 查询可发起的审批表单模板
```
Usage:
dws oa approval list-forms [flags]
Example:
dws oa approval list-forms
dws oa approval list-forms --cursor 0 --size 20
Flags:
--cursor string 分页游标,首次传 0 (默认 0)
--size string 每页大小 (可选)
```
列出当前用户被授权发起的审批表单(如"请假"、"报销"),返回 `processCode`,后续用于提交新的申请或按模板筛选历史实例。
### 获取审批实例详情
```
Usage:
dws oa approval detail [flags]
Example:
dws oa approval detail --instance-id <processInstanceId>
Flags:
--instance-id string 审批实例 processInstanceId (必填)
```
拉取单个实例的完整内容:表单字段、附件、当前状态、参与人。适合让 AI 读懂审批单再决定动作或生成摘要。
### 查询审批实例的操作记录
```
Usage:
dws oa approval records [flags]
Example:
dws oa approval records --instance-id <processInstanceId>
Flags:
--instance-id string 审批实例 processInstanceId (必填)
```
列出实例的流转历史(谁在什么时候同意/加签/转交/评论),用于复盘或解释"这单卡在哪"。
### 查询实例下待处理的任务
```
Usage:
dws oa approval tasks [flags]
Example:
dws oa approval tasks --instance-id <processInstanceId>
Flags:
--instance-id string 审批实例 processInstanceId (必填)
```
针对具体实例拿到当前用户名下的 `taskId`。approve / reject 要的是 `taskId`,不是 `processInstanceId`,这一步不能省。
### 同意审批
```
Usage:
dws oa approval approve [flags]
Example:
dws oa approval approve --instance-id <processInstanceId> --task-id <taskId>
dws oa approval approve --instance-id <processInstanceId> --task-id <taskId> --remark "同意,按流程推进"
Flags:
--instance-id string 审批实例 processInstanceId (必填)
--task-id string 待办任务 taskId (必填),来自 approval tasks
--remark string 审批意见 (可选)
```
以当前用户身份同意某个审批任务。`--task-id` 必须是当前用户的待办 taskId,否则 MCP 会拒绝。
### 拒绝审批
```
Usage:
dws oa approval reject [flags]
Example:
dws oa approval reject --instance-id <processInstanceId> --task-id <taskId> --remark "预算不足,下月再议"
Flags:
--instance-id string 审批实例 processInstanceId (必填)
--task-id string 待办任务 taskId (必填),来自 approval tasks
--remark string 拒绝理由 (可选,但强烈建议填)
```
以当前用户身份驳回审批任务;拒绝后一般由 MCP 端决定流程是打回申请人还是整体终止。
### 撤回已发起的审批
```
Usage:
dws oa approval revoke [flags]
Example:
dws oa approval revoke --instance-id <processInstanceId>
dws oa approval revoke --instance-id <processInstanceId> --remark "金额填错,重新提交" --yes
Flags:
--instance-id string 审批实例 processInstanceId (必填)
--remark string 撤回原因 (可选)
```
只能撤销**自己发起且尚未终态**的实例。命令标了 `isSensitive`,AI 调用前建议与用户再确认一次,可配合全局 `--yes` 跳过确认。
## 意图判断
用户说"我要审的单/待我处理的审批/审批收件箱" → `list-pending``processInstanceId`
用户说"这单我同意/批了它/通过" → `approval tasks``taskId``approval approve`
用户说"这单不行/驳回/拒绝" → `approval tasks``taskId``approval reject --remark "<理由>"`
用户说"这单详情/看看内容/这单在说什么" → `approval detail`
用户说"这单卡在谁那/谁还没审/流程走到哪" → `approval records`
用户说"我发起的审批/我的申请" → `list-initiated`(可用 `--process-code` 按模板筛)
用户说"能发起哪些审批/有哪些表单" → `list-forms`
用户说"撤回我的申请/我不提了" → `approval revoke`(仅限自己发起且未终态)
关键区分: oa(钉钉 OA 审批流程) vs todo(个人待办) vs report(日志汇报)
## 核心工作流
```bash
# 1. 看我有哪些待审的单 — 提取 processInstanceId
dws oa approval list-pending --page 1 --size 20 --format json
# 2. 看单子内容(表单字段 / 附件 / 当前状态)
dws oa approval detail --instance-id <processInstanceId> --format json
# 3. 想动作(同意/拒绝)前,先拿 taskId
dws oa approval tasks --instance-id <processInstanceId> --format json
# 4. 同意 / 拒绝(taskId 来自步骤 3)
dws oa approval approve --instance-id <processInstanceId> --task-id <taskId> --remark "同意" --format json
dws oa approval reject --instance-id <processInstanceId> --task-id <taskId> --remark "预算不足" --format json
# 5. 查看流程记录 — 谁何时做了什么
dws oa approval records --instance-id <processInstanceId> --format json
# 6. 查我发起的审批 / 按模板过滤
dws oa approval list-initiated --format json
dws oa approval list-initiated --process-code <processCode> --format json
# 7. 能发起哪些表单
dws oa approval list-forms --cursor 0 --size 20 --format json
# 8. 撤回我发起的单
dws oa approval revoke --instance-id <processInstanceId> --remark "填错了" --yes --format json
```
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `list-pending` | `processInstanceId``nextToken` | detail / tasks / records 的 --instance-id |
| `list-initiated` | `processInstanceId``nextToken` | detail / records / revoke 的 --instance-id |
| `list-forms` | `processCode` | `list-initiated --process-code` 按模板过滤,或后续发起新审批 |
| `approval tasks` | `taskId` | approve / reject 的 --task-id |
| `approval detail` | 表单字段、参与人、当前状态 | 供 AI 决策是否批准、生成摘要 |
## 注意事项
- `processInstanceId`(实例 ID)与 `taskId`(待办任务 ID)**不是一回事**,不能混用:
- `list-pending` / `list-initiated` / `detail` / `records` / `revoke``processInstanceId`
- `approve` / `reject``taskId`,必须先 `approval tasks --instance-id <processInstanceId>` 换一次
- `list-pending` 是"需要我动作"视图;同一个实例如果流转到下一节点就会从这里消失
- `list-initiated` 是"我发起的"视图;和 `list-pending` 是两套语义,不要互相替代
- `--start` / `--end` 使用 ISO-8601 格式,内部会自动转毫秒时间戳
- `revoke` 只能撤销**当前用户发起且未完结**的实例;已流转结束、已作废、或不是自己发起的都会失败
- `approve` / `reject``--remark` 可选但强烈建议填,尤其是 `reject`——审批流下游会把理由展示给申请人
- 所有敏感动作(`approve` / `reject` / `revoke`)在 AI 调用时应与用户二次确认,可用全局 `--yes` 跳过确认
- `list-forms` 返回的 `processCode` 是未来发起新审批、或筛选历史实例的钩子;目前本命令集只覆盖审批的"处理侧",发起新审批需走业务方自己的流程
+164
View File
@@ -0,0 +1,164 @@
# 日志 (report) 命令参考
## 命令总览
### 获取日志模版列表
```
Usage:
dws report template list [flags]
Example:
dws report template list
```
### 获取日志模版详情
```
Usage:
dws report template detail [flags]
Example:
dws report template detail --name <templateName>
Flags:
--name string 模版名称 (必填)
```
### 创建日志
```
Usage:
dws report create [flags]
Example:
dws report create --template-id <templateId> \
--contents '[{"key":"今日完成","sort":"0","content":"完成了需求评审","contentType":"markdown","type":"1"}]' \
--format json
dws report create --template-id <templateId> \
--contents '[{"key":"今日完成","sort":"0","content":"内容","contentType":"markdown","type":"1"}]' \
--dd-from "script" --to-chat --to-user-ids "userId1,userId2" --format json
Flags:
--template-id string 日志模版 ID (必填),从 template list 返回中取
--contents string 日志内容 JSON 数组 (必填),每项须含 key/sort/content/contentType/type
--dd-from string 创建来源标识 (默认 dws)
--to-chat string 是否发送到日志接收人单聊 (传 "true" 发送)
--to-user-ids string 接收人 userId,逗号分隔 (可选)
```
**`contents` 数组元素**(与 MCP `create_report` 一致):
| 字段 | 说明 |
|------|------|
| `key` | 控件标题,与 template detail 一致 |
| `sort` | 控件排序,与 template detail 一致 |
| `content` | 填写值;文本类可写 Markdown |
| `contentType` | `type` 为文本 (`1`) 时用 `markdown`,其余类型用 `origin` |
| `type` | `1` 文本、`2` 数字、`3` 单选、`5` 日期、`7` 多选 |
shell 中传 `--contents` 时外层建议用**单引号**包住整段 JSON。
### 获取日志详情
```
Usage:
dws report detail [flags]
Example:
dws report detail --report-id <reportId>
Flags:
--report-id string 日志 ID (必填)
```
### 日志收件箱列表
```
Usage:
dws report list [flags]
Example:
dws report list --start "2026-03-10T00:00:00+08:00" --end "2026-03-10T23:59:59+08:00" --cursor 0 --size 20
Flags:
--cursor string 分页游标 (必填)
--end string 结束时间 ISO-8601 (如 2026-03-10T23:59:59+08:00) (必填)
--size string 每页大小 (必填)
--start string 开始时间 ISO-8601 (如 2026-03-10T00:00:00+08:00) (必填)
```
### 获取日志统计数据
```
Usage:
dws report stats [flags]
Example:
dws report stats --report-id <reportId>
Flags:
--report-id string 日志 ID (必填)
```
返回该日志的互动聚合数据:浏览数 (views)、点赞数 (likes)、评论数 (comments) 等,用于衡量一篇日志的阅读与反馈情况。
### 查询当前人创建的日志列表
```
Usage:
dws report sent [flags]
Example:
dws report sent --cursor 0 --size 20
dws report sent --cursor 0 --size 20 --start "2026-03-10T00:00:00+08:00" --end "2026-03-10T23:59:59+08:00"
dws report sent --cursor 0 --size 20 --template-name "日报"
Flags:
--cursor string 分页游标,首次传 0 (默认 0)
--size string 每页条数,最大 20 (默认 20)
--start string 创建开始时间 ISO-8601 (默认最近 30 天)
--end string 创建结束时间 ISO-8601 (默认最近 30 天)
--modified-start string 修改开始时间 ISO-8601 (可选)
--modified-end string 修改结束时间 ISO-8601 (可选)
--template-name string 日志模版名称 (可选,不传查全部)
```
## 意图判断
用户说"查日志/看日报" → `list` 获取列表,再 `detail`
用户说"写日报/提交周报/发日志/填日志" → 先 `template list` / `template detail``templateId` 与各控件 `key`/`sort`/类型,拼 `--contents` JSON,再 `create`
用户说"日志数据/互动情况/多少人看了/点赞评论" → `stats`
用户说"有什么日志模版" → `template list``template detail`
用户说"我发过的日志/我创建的日志" → `sent`
关键区分: report(钉钉日志模版汇报,含创建) vs doc(文档编辑) vs todo(待办任务)
## 核心工作流
```bash
# 1. 获取当前用户可用的日志模版
dws report template list --format json
# 2. 按名称查看模版详情(含字段定义)
dws report template detail --name "日报" --format json
# 2b. 创建日志(从步骤 1/2 取 templateId 与 contents 字段)
dws report create --template-id <templateId> \
--contents '[{"key":"今日完成","sort":"0","content":"完成了需求评审","contentType":"markdown","type":"1"}]' \
--format json
# 3. 查看收件箱日志列表 — 提取 reportId
dws report list --start "2026-03-10T00:00:00+08:00" --end "2026-03-10T23:59:59+08:00" \
--cursor 0 --size 20 --format json
# 4. 查看日志详情
dws report detail --report-id <reportId> --format json
# 5. 查看日志统计(浏览/点赞/评论聚合)
dws report stats --report-id <reportId> --format json
# 6. 查看当前人创建的日志列表
dws report sent --cursor 0 --size 20 --format json
```
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `template list` | template 名称 | template detail 的 --name |
| `template list` | `templateId`(或等价字段) | `create` 的 --template-id |
| `template detail` | 各控件 `key``sort`、类型 | 拼 `create` 的 --contents JSON(含 contentType/type |
| `list` | `reportId` | detail / stats 的 --report-id |
## 注意事项
- `--start` / `--end` 使用 ISO-8601 格式(如 `2026-03-10T00:00:00+08:00`
- `template list` 不需要参数,直接返回当前用户可用的所有日志模版
- `create` 前必须先查模版,勿猜测 `templateId``contents` 中的 `key`/`sort`;多控件时数组须覆盖模版必填项
## 自动化脚本
| 脚本 | 场景 | 用法 |
|------|------|------|
| [report_inbox_today.py](../../scripts/report_inbox_today.py) | 查看今天收到的日志列表及详情 | `python report_inbox_today.py` |
+304
View File
@@ -0,0 +1,304 @@
# 在线电子表格 (sheet) 命令参考
## 适用范围(重要)
`sheet` 产品**仅支持钉钉在线电子表格**`contentType=ALIDOC``extension=axls`),**不支持**上传的 `xlsx` / `xls` / `xlsm` / `csv` 等本地表格文件。
| 文件类型 | 处理方式 |
|---------|---------|
| 在线电子表格(`axls` | 走 `sheet` 全部命令(读/写/筛选/合并/导出等服务端原子操作) |
| `xlsx` / `xls` / `xlsm` / `csv` 等本地表格文件 | 必须用 `dws doc download --node <ID> --output <路径>` 先下载到本地再用本地工具解析,**禁止**调用任何 `sheet` 子命令 |
| 想把在线表格导出为 xlsx | 用 `dws sheet submit_export_job` 提交导出任务 → 拿到 `jobId``dws sheet query_export_job` 轮询直到 `finished` → 用返回的 `downloadUrl` 下载 |
> 用户直接粘贴 `alidocs` URL 时,先用 `dws doc info --node <URL> --format json` 确认 `contentType=ALIDOC``extension=axls` 后再走 `sheet`;否则转 `dws doc download`
## 命名风格说明(v1.0.25 envelope 现状)
`sheet` 产品的命令 cli_name **当前同时存在两种风格**——这是 envelope schema 还在演进中、`CLIAliases` (#246) 重命名尚未完成的过渡态:
- **kebab-case** (~17 个)`add-dimension``merge-cells``filter-view update-criteria` 等,与 dws 其它产品风格一致
- **snake_case** (~12 个)`copy_sheet``submit_export_job``set_filter_criteria` 等,envelope 原始名直透出来
**调用时以 `dws sheet --help` 输出为准**——本文档与 envelope schema 同步,未来命名收敛后会同步更新。所有命令的最终参数名以 `dws sheet <cmd> --help``dws schema sheet.<canonical_path>` 为准。
## 命令总览(按功能分组)
### 工作表 (Worksheet) 级
| 命令 | canonical | 用途 |
|------|-----------|------|
| `dws sheet create` | `sheet.create_workspace_sheet` | 在知识库中创建一个新的钉钉表格文档 |
| `dws sheet new` | `sheet.create_sheet` | 在已有钉钉表格文档中新建一张工作表 |
| `dws sheet list` | `sheet.get_all_sheets` | 列出指定文档的所有工作表 |
| `dws sheet info` | `sheet.get_sheet` | 获取指定工作表详情 |
| `dws sheet copy_sheet` | `sheet.copy_sheet` | 复制工作表(同文档内) |
| `dws sheet update_sheet` | `sheet.update_sheet` | 更新工作表元信息(如改名) |
### 区域 (Range) 读写
| 命令 | canonical | 用途 |
|------|-----------|------|
| `dws sheet range read` | `sheet.get_range` | 读取指定区域的单元格内容 |
| `dws sheet range update` | `sheet.update_range` | 写入/更新指定区域的单元格 |
| `dws sheet append` | `sheet.append_rows` | 在工作表末尾追加若干行 |
### 行列 (Dimension)
| 命令 | canonical | 用途 |
|------|-----------|------|
| `dws sheet add-dimension` | `sheet.add_dimension` | 在末尾追加空行或空列 |
| `dws sheet insert-dimension` | `sheet.insert_dimension` | 在指定位置插入空行/空列 |
| `dws sheet delete-dimension` | `sheet.delete_dimension` | 删除指定位置起的若干行/列 |
| `dws sheet move-dimension` | `sheet.move_dimension` | 移动行/列到指定位置 |
| `dws sheet update-dimension` | `sheet.update_dimension` | 更新行/列属性(显隐、行高/列宽) |
### 单元格合并
| 命令 | canonical | 用途 |
|------|-----------|------|
| `dws sheet merge-cells` | `sheet.merge_cells` | 合并指定范围的单元格(`mergeAll`/`mergeRows`/`mergeColumns` |
| `dws sheet unmerge-cells` | `sheet.unmerge_range` | 取消指定范围的合并 |
### 查找/替换
| 命令 | canonical | 用途 |
|------|-----------|------|
| `dws sheet find` | `sheet.find_cells` | 在工作表中搜索单元格内容(支持正则/整格匹配/隐藏) |
| `dws sheet replace` | `sheet.replace_all` | 全局查找替换 |
### 筛选视图 (Filter View) — 命名视图、按列条件、不影响表本身
| 命令 | canonical | 用途 |
|------|-----------|------|
| `dws sheet filter-view create` | `sheet.create_filter_view` | 创建筛选视图 |
| `dws sheet filter-view list` | `sheet.get_filter_views` | 列出工作表的所有筛选视图 |
| `dws sheet filter-view update` | `sheet.update_filter_view` | 更新筛选视图(名称/范围/条件) |
| `dws sheet filter-view delete` | `sheet.delete_filter_view` | 删除整个筛选视图 |
| `dws sheet filter-view update-criteria` | `sheet.set_filter_view_criteria` | 设置/更新视图内某列的筛选条件 |
| `dws sheet filter-view delete-criteria` | `sheet.clear_filter_view_criteria` | 清除视图内某列的筛选条件 |
### 表级筛选 (Filter) — 直接作用于工作表本身的临时筛选
| 命令 | canonical | 用途 |
|------|-----------|------|
| `dws sheet create_filter` | `sheet.create_filter` | 在工作表上创建筛选器 |
| `dws sheet get_filter` | `sheet.get_filter` | 获取当前筛选器配置 |
| `dws sheet update_filter` | `sheet.update_filter` | 更新筛选器条件 |
| `dws sheet delete_filter` | `sheet.delete_filter` | 删除筛选器 |
| `dws sheet set_filter_criteria` | `sheet.set_filter_criteria` | 设置某列的筛选条件 |
| `dws sheet clear_filter_criteria` | `sheet.clear_filter_criteria` | 清除某列的筛选条件 |
| `dws sheet sort_filter` | `sheet.sort_filter` | 对筛选范围按指定列排序 |
### 图片
| 命令 | canonical | 用途 |
|------|-----------|------|
| `dws sheet write-image` | `sheet.write_image` | 将已上传的图片资源写入指定单元格 |
### 导出(两步原子,**v1.0.25 没有合并的 `export` 命令**
| 命令 | canonical | 用途 |
|------|-----------|------|
| `dws sheet submit_export_job` | `sheet.submit_export_job` | 提交导出任务,返回 `jobId` |
| `dws sheet query_export_job` | `sheet.query_export_job` | 轮询导出任务状态,完成后返回 `downloadUrl` |
> v1.0.25 envelope 暴露的是这两个**原子动作**。要完整完成"导出 → 下载"流程需要 client 侧轮询 + 调 `downloadUrl``CLIToolOverride.Pipeline` (#247) 提供了底层编排能力,但**当前 envelope 还没把这两个动作 Pipeline 化成一条 `dws sheet export` 总命令**。
## 通用必填参数
绝大多数 `sheet` 命令都需要:
- `--node <NODE_ID>` —— 钉钉表格文档的 nodeId 或 `https://alidocs.dingtalk.com/i/nodes/<DOC_UUID>` URLalias 来自 `nodeId`
- `--sheet-id <SHEET_ID>` —— 工作表 ID(alias 来自 `sheetId`),从 `dws sheet list`
例外:
- `create` 只需要 `--name`(在知识库创建文档时不需要 nodeId)
- `list` / `info` / `range read` 只需要 `--node`
- `submit_export_job` 只需要 `--node` + `--export-format`(无 sheet-id
- `query_export_job` 只需要 `--job-id`
## 常用命令示例
### 创建文档 + 新建工作表
```bash
# 在知识库下创建一个钉钉表格文档
dws sheet create --name "销售数据" --workspace <WS_ID> --format json
# 返回的 nodeId 用于后续操作
# 在已有文档中新建一张工作表
dws sheet new --node <NODE_ID> --name "Q1 数据" --format json
```
### 读写区域
```bash
# 读 A1:D10
dws sheet range read --node <NODE_ID> --sheet-id <SHEET_ID> --range "A1:D10" --format json
# 写入 5x4 区域(values 是二维 JSON 数组)
dws sheet range update --node <NODE_ID> --sheet-id <SHEET_ID> --range "A1:D5" \
--values '[["姓名","岗位","入职","薪资"],["张三","研发","2024-01","30000"]]' \
--format json
# 追加行
dws sheet append --node <NODE_ID> --sheet-id <SHEET_ID> \
--values '[["李四","产品","2025-03","28000"]]' \
--format json
```
### 行列操作
```bash
# 在第 5 行处插入 2 个空行
dws sheet insert-dimension --node <NODE_ID> --sheet-id <SHEET_ID> \
--dimension rows --position 4 --length 2 --format json
# 末尾追加 3 列
dws sheet add-dimension --node <NODE_ID> --sheet-id <SHEET_ID> \
--dimension columns --length 3 --format json
# 删除第 10-12 行
dws sheet delete-dimension --node <NODE_ID> --sheet-id <SHEET_ID> \
--dimension rows --position 9 --length 3 --format json
# 隐藏 B 列(startIndex=1, length=1
dws sheet update-dimension --node <NODE_ID> --sheet-id <SHEET_ID> \
--dimension columns --start-index 1 --length 1 --hidden true --format json
```
### 合并/取消合并
```bash
# 合并 A1:C1
dws sheet merge-cells --node <NODE_ID> --sheet-id <SHEET_ID> \
--range "A1:C1" --merge-type mergeAll --format json
# 取消合并
dws sheet unmerge-cells --node <NODE_ID> --sheet-id <SHEET_ID> \
--range "A1:C1" --format json
```
### 查找/替换
```bash
# 查找
dws sheet find --node <NODE_ID> --sheet-id <SHEET_ID> \
--find "TODO" --use-regexp false --match-case false --format json
# 全局替换
dws sheet replace --node <NODE_ID> --sheet-id <SHEET_ID> \
--find "TODO" --replacement "DONE" --format json
```
### 筛选视图(推荐:可命名、不破坏原表)
```bash
# 创建筛选视图(范围必须包含表头行)
dws sheet filter-view create --node <NODE_ID> --sheet-id <SHEET_ID> \
--name "未完成项" --range "A1:E100" --format json
# 返回的 filterViewId 用于后续 update/delete/criteria 操作
# 列出所有筛选视图
dws sheet filter-view list --node <NODE_ID> --sheet-id <SHEET_ID> --format json
# 给视图的某一列设置筛选条件(column 是相对视图范围首列的 0-based 偏移)
dws sheet filter-view update-criteria --node <NODE_ID> --sheet-id <SHEET_ID> \
--filter-view-id <FV_ID> --column 2 \
--filter-criteria '{"conditions":[{"type":"TEXT_CONTAINS","values":["pending"]}]}' \
--format json
# 清除某列的筛选条件(不删除视图本身)
dws sheet filter-view delete-criteria --node <NODE_ID> --sheet-id <SHEET_ID> \
--filter-view-id <FV_ID> --column 2 --format json
# 删除整个筛选视图
dws sheet filter-view delete --node <NODE_ID> --sheet-id <SHEET_ID> \
--filter-view-id <FV_ID> --format json
```
### 表级筛选(snake_case 系列,直接作用于工作表本身)
```bash
# 创建筛选器(一张表只有一个,再次 create 会替换)
dws sheet create_filter --node <NODE_ID> --sheet-id <SHEET_ID> \
--range "A1:E100" --format json
# 给某列加筛选条件
dws sheet set_filter_criteria --node <NODE_ID> --sheet-id <SHEET_ID> \
--column 0 --filter-criteria '{...}' --format json
# 按指定列排序
dws sheet sort_filter --node <NODE_ID> --sheet-id <SHEET_ID> --field 0 --format json
# 删除筛选器
dws sheet delete_filter --node <NODE_ID> --sheet-id <SHEET_ID> --format json
```
### 复制工作表
```bash
dws sheet copy_sheet --node <NODE_ID> --sheet-id <SHEET_ID> --format json
# 返回新工作表 ID
```
### 写入图片
```bash
# 已有图片资源 ID 和 URL(通过 drive 或 doc 上传得到)后写入单元格
dws sheet write-image --node <NODE_ID> --sheet-id <SHEET_ID> \
--range "B2:B2" --resource-id <RES_ID> --resource-url <RES_URL> \
--width 200 --height 100 --format json
```
### 导出 xlsx(两步流程)
```bash
# Step 1: 提交导出任务
JOB=$(dws sheet submit_export_job --node <NODE_ID> --export-format xlsx --format json --jq '.result.jobId')
# Step 2: 轮询任务状态(建议 sleep + 重试)
dws sheet query_export_job --job-id "$JOB" --format json
# 直到返回 status=finished + downloadUrl
# Step 3: 下载(用 curl / dws doc download / 其它工具拉 downloadUrl
```
## 易混淆点
| 区分 | 说明 |
|---|---|
| `dws sheet create` vs `dws sheet new` | `create` 在知识库**新建一个文档**(返回新 nodeId);`new` 在**已有文档中新建一张工作表**(需 nodeId) |
| `dws sheet filter-view *` vs `dws sheet create_filter`/`set_filter_criteria` 等 | filter-view 是**命名视图**,多个并存、不影响表本身;filter 是**表级唯一**筛选器,直接作用于工作表显示 |
| `filter-view update-criteria` vs `filter-view delete-criteria` | update 是设置/覆盖列条件;delete 是清除列条件(视图本身保留);要删整个视图用 `filter-view delete` |
| `dws sheet submit_export_job` + `query_export_job` vs `dws sheet export` | 后者**不存在**于 v1.0.25 envelope。需 client 端自己轮询,或基于 Pipeline (#247) 在 envelope 侧 PR 一条总命令 |
| `dws sheet write-image` vs `range update` | write-image 写入图片(需 resourceId + resourceUrl);range update 写入文本/数字/公式 |
| `range update` vs `append` | range update 指定区域覆盖;append 在末尾追加行 |
| online axls vs 本地 xlsx | sheet 全部命令只认 axls;本地 xlsx 必须先 `doc download` 再用本地工具解析 |
## 危险操作(必须先向用户确认)
| 命令 | 风险 |
|---|---|
| `delete-dimension` | 删除行/列(含数据),不可恢复 |
| `filter-view delete` | 删除整个筛选视图 |
| `delete_filter` | 删除表级筛选器 |
| `replace` | 全局替换可能影响大量单元格 |
| `unmerge-cells` | 取消合并可能丢失部分单元格内容(钉钉行为依赖合并模式) |
| `update_sheet` | 更新工作表元信息(如改名) |
执行前先 `--dry-run` 预览,并向用户展示操作摘要 + 拿到明确同意,再加 `--yes` 提交。
## 何时**不要**用 sheet
- 用户给的是 `xlsx` / `xls` / `xlsm` / `csv` 本地文件 → 用 `dws doc download` 下载后本地解析
- 用户给的是 AI 表格(不是在线电子表格)→ 用 `dws aitable record query`
- 用户给的是富文本/普通文档 → 用 `dws doc read`
## 权威参考
- 列出所有 sheet 工具:`dws schema | jq '.products[] | select(.id=="sheet") | .tools[] | "\(.group) \(.cli_name)"' -r`
- 看某个命令的完整 JSON Schema`dws schema sheet.<canonical_path>`(如 `dws schema sheet.update_range`
- 看某个命令的 flag 别名映射:`dws schema sheet.<canonical_path> --jq '.tool.flag_overlay'`
- 看必填字段:`dws schema sheet.<canonical_path> --jq '.tool.required'`
- 命令的人读视图:`dws sheet <cmd> --help`
+117
View File
@@ -0,0 +1,117 @@
# 单命令产品合集
以下产品命令较少,合并参考。
---
## devdoc — 开放平台文档
### 搜索开放平台文档
```
Usage:
dws devdoc article search [flags]
Example:
dws devdoc article search --keyword "OAuth2 接入" --page 1 --size 10
Flags:
--keyword string 搜索关键词 (必填)
--page string 页码 (默认 1)
--size string 每页数量 (默认 10)
```
---
## oa — 审批
### 查询可见审批流程
```
Usage:
dws oa approval list-forms [flags]
Example:
dws oa approval list-forms --format json
```
### 查询审批实例详情
```
Usage:
dws oa approval detail --instance-id <ID> [flags]
Example:
dws oa approval detail --instance-id <ID> --format json
```
### 查询审批记录
```
Usage:
dws oa approval records --instance-id <ID> [flags]
Example:
dws oa approval records --instance-id <ID> --format json
```
### 查询待我审批的任务
```
Usage:
dws oa approval tasks [flags]
Example:
dws oa approval tasks --format json
```
### 查询待我处理的审批
```
Usage:
dws oa approval list-pending [flags]
Example:
dws oa approval list-pending --format json
```
### 查询我发起的审批
```
Usage:
dws oa approval list-initiated [flags]
Example:
dws oa approval list-initiated --format json
```
### 同意审批
```
Usage:
dws oa approval approve --instance-id <ID> --task-id <TASK_ID> [flags]
Example:
dws oa approval approve --instance-id <ID> --task-id <TASK_ID> --format json
```
### 拒绝审批
```
Usage:
dws oa approval reject --instance-id <ID> --task-id <TASK_ID> [flags]
Example:
dws oa approval reject --instance-id <ID> --task-id <TASK_ID> --remark "不符合要求" --format json
```
### 撤销审批
```
Usage:
dws oa approval revoke --instance-id <ID> [flags]
Example:
dws oa approval revoke --instance-id <ID> --format json
```
---
## 意图判断
- 用户说"开发文档/API 文档/接口文档" → `devdoc article search`
- 用户说"审批/请假/报销/出差" → `oa approval`
- 用户说"同意审批/批准" → `oa approval approve`
- 用户说"拒绝审批/驳回" → `oa approval reject`
- 用户说"撤销审批/撤回" → `oa approval revoke`
- 用户说"待我审批/我要审批的" → `oa approval list-pending``oa approval tasks`
- 用户说"我发起的审批" → `oa approval list-initiated`
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `devdoc article search` | 文档链接 | 直接展示给用户 |
| `oa approval list-forms` | processCode | detail / records 等 |
| `oa approval tasks` | taskId, instanceId | approve / reject |
| `oa approval list-pending` | instanceId | detail / approve / reject |
| `oa approval list-initiated` | instanceId | detail / revoke |
+143
View File
@@ -0,0 +1,143 @@
# 待办 (todo) 命令参考
## 命令总览
### 创建待办
```
Usage:
dws todo task create [flags]
Example:
dws todo task create --title "修复线上Bug" --executors <USER_ID_1>,<USER_ID_2> --priority 40
dws todo task create --title "提交报告" --executors <USER_ID> --due "2026-03-20T10:00:00+08:00"
dws todo task create --title "每日站会" --executors <USER_ID> \
--due "2026-03-20T10:00:00+08:00" \
--recurrence $'DTSTART:20260320T020000Z\nRRULE:FREQ=DAILY;INTERVAL=1'
Flags:
--due string 截止时间 ISO-8601 (如 2026-03-10T18:00:00+08:00)
--executors string 执行者 userId 列表 (必填)
--priority string 优先级: 10低/20普通/30较高/40紧急
--recurrence string 循环规则 RFC 5545 (DTSTART+RRULE,仅在同时设置 --due 时生效)
--title string 待办标题 (必填)
```
### 查询待办列表
```
Usage:
dws todo task list [flags]
Example:
dws todo task list --page 1 --size 20 --status false
Flags:
--page string 页码 (默认 1)
--size string 每页数量 (默认 20)
--status string true=已完成, false=未完成
```
### 修改待办任务
```
Usage:
dws todo task update [flags]
Example:
dws todo task update --task-id <taskId> --title "新标题"
dws todo task update --task-id <taskId> --priority 40 --due "2026-03-10T18:00:00+08:00"
dws todo task update --task-id <taskId> --done true
Flags:
--done string 完成状态: true/false
--due string 截止时间 ISO-8601 (如 2026-03-10T18:00:00+08:00)
--priority string 优先级: 10低/20普通/30较高/40紧急
--task-id string 待办任务 ID (必填)
--title string 新标题
```
### 修改执行者的待办完成状态
```
Usage:
dws todo task done [flags]
Example:
dws todo task done --task-id <taskId> --status true
dws todo task done --task-id <taskId> --status false
Flags:
--status string 完成状态: true=已完成, false=未完成 (必填)
--task-id string 待办任务 ID (必填)
```
### 待办详情
```
Usage:
dws todo task get [flags]
Example:
dws todo task get --task-id <taskId>
Flags:
--task-id string 待办任务 ID (必填)
```
### 删除待办
```
Usage:
dws todo task delete [flags]
Example:
dws todo task delete --task-id <taskId>
dws todo task delete --task-id <taskId> --yes
Flags:
--task-id string 待办任务 ID (必填)
```
## 意图判断
用户说"加个待办/记一下/TODO" → `task create`
用户说"看看待办/我有啥要做" → `task list`
用户说"改个待办/修改待办标题/改优先级" → `task update`
用户说"做完了/完成待办/标记完成" → `task done`
用户说"看看待办详情" → `task get`
用户说"删除待办/取消待办" → `task delete`
关键区分: todo(个人待办)
## 核心工作流
```bash
# 1. 创建待办 — 提取 todoTaskId
dws todo task create --title "修复线上Bug" --executors userId1,userId2 \
--priority 40 --due "2026-03-10T18:00:00+08:00" --format json
# 2. 查看未完成待办
dws todo task list --page 1 --size 20 --status false --format json
# 3. 查看待办详情
dws todo task get --task-id <taskId> --format json
# 4. 修改待办信息
dws todo task update --task-id <taskId> --title "新标题" --priority 40 --format json
# 5. 标记待办完成
dws todo task done --task-id <taskId> --status true --format json
# 6. 删除待办
dws todo task delete --task-id <taskId> --yes --format json
```
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `task create` | `todoTaskId` | update/done/get/delete 的 --task-id |
| `task list` | `result[].id` | update/done/get/delete 的 --task-id |
## 注意事项
- 优先级值: 10=低, 20=普通, 30=较高, 40=紧急
- `--due` 截止时间使用 ISO-8601 格式(如 2026-03-10T18:00:00+08:00
- `--recurrence` 为 RFC 5545 循环规则(`DTSTART:...\nRRULE:FREQ=DAILY;INTERVAL=1` 这种格式),必须与 `--due` 同时设置才生效
- `task list``--status` 对应 MCP `get_user_todos_in_current_org``todoStatus` 参数
- todo 是个人待办管理产品
- `task update` 可同时修改标题/优先级/截止时间/完成状态
- `task done` 专用于修改执行者的完成状态,与 `task update --done` 作用不同
- `task delete` 为不可逆操作,建议加 `--yes` 并与用户确认
## 自动化脚本
| 脚本 | 场景 | 用法 |
|------|------|------|
| [todo_daily_summary.py](../../scripts/todo_daily_summary.py) | 查看今天/明天/本周未完成待办汇总 | `python todo_daily_summary.py today` |
| [todo_batch_create.py](../../scripts/todo_batch_create.py) | 从 JSON 文件批量创建待办 | `python todo_batch_create.py todos.json` |
| [todo_overdue_check.py](../../scripts/todo_overdue_check.py) | 扫描逾期待办输出逾期清单 | `python todo_overdue_check.py` |
+177
View File
@@ -0,0 +1,177 @@
# 知识库 (wiki) 命令参考
## 命令总览
### 创建知识库
```
Usage:
dws wiki space create [flags]
Example:
dws wiki space create --name "产品文档库" --format json
dws wiki space create --name "技术方案" --description "团队技术方案归档" --format json
Flags:
--name string 知识库名称 (必填,不超过 100 字符)
--description string 知识库描述 (选填,不超过 500 字符)
--icon string 知识库图标标识 (选填)
```
### 查看知识库详情
```
Usage:
dws wiki space get [flags]
Example:
dws wiki space get --id <workspaceId> --format json
dws wiki space get --id "https://alidocs.dingtalk.com/i/spaces/xxx/overview" --format json
Flags:
--id string 知识库 ID 或 URL (必填)
```
支持传入知识库 ID 或知识库 URL,系统自动识别。
知识库 URL 格式:`https://alidocs.dingtalk.com/i/spaces/{workspaceId}/overview`
### 列出知识库
```
Usage:
dws wiki space list [flags]
Example:
dws wiki space list --format json
dws wiki space list --type myWikiSpace --format json
dws wiki space list --type orgWikiSpace --limit 50 --format json
Flags:
--type string 知识库类型: myWikiSpace / orgWikiSpace (默认 orgWikiSpace)
--limit string 每页数量 1-50 (默认 20)
--page-token string 分页游标 (首页留空)
```
- `myWikiSpace`:返回当前用户的「我的文档」个人空间(固定 1 条,不支持分页)
- `orgWikiSpace`(默认):返回组织内有权访问的知识库列表,支持分页
### 搜索知识库
```
Usage:
dws wiki space search [flags]
Example:
dws wiki space search --keyword "产品文档" --format json
dws wiki space search --keyword "技术方案" --limit 20 --format json
dws wiki space search --type myWikiSpace --format json
Flags:
--keyword string 搜索关键词 (--type myWikiSpace 时可省略)
--type string 知识库类型: myWikiSpace 时直接返回「我的文档」,省略则搜索组织知识库
--limit string 返回数量 1-20 (默认 10)
```
`--type myWikiSpace` 时,忽略 `--keyword`,直接返回「我的文档」个人空间。
### 添加知识库成员(容器级授权)
```
Usage:
dws wiki member add [flags]
Example:
dws wiki member add --space <WS_ID> --user uid1 --role READER
dws wiki member add --space <WS_ID> --user uid1,uid2 --role EDITOR
dws wiki member add --space "https://alidocs.dingtalk.com/i/spaces/<WS_ID>/overview" --user uid1 --role MANAGER
Flags:
--space string 目标知识库 ID 或 URL (必填)
--user strings 被加入的用户 userId 列表,逗号分隔 (必填,单次最多 30 个)
--role string 授予的角色 (必填,大小写敏感,必须全大写): MANAGER (管理者) / EDITOR (可编辑) / DOWNLOADER (可下载) / READER (可阅读)
```
> **❗ 重要约束**
> - 仅支持 USER 类型。
> - 角色枚举严格大写:MANAGER / EDITOR / DOWNLOADER / READEROWNER 不可通过此接口添加,知识库创建者默认为所有者)。
> - 操作者需具备知识库的 OWNER 或 MANAGER 权限。
> - 「我的文档」(myWikiSpace) 是个人空间,**不支持容器级成员管理**;后端会直接拒绝。如果你的目标只是把某篇文档分享给别人,请改用 `dws doc permission add` 在节点级别授权。
### 修改知识库成员角色
```
Usage:
dws wiki member update [flags]
Example:
dws wiki member update --space <WS_ID> --user uid1 --role EDITOR
dws wiki member update --space <WS_ID> --user uid1,uid2 --role READER
Flags:
--space string 目标知识库 ID 或 URL (必填)
--user strings 目标用户 userId 列表,逗号分隔 (必填,单次最多 30 个)
--role string 新角色 (必填,大小写敏感,必须全大写): MANAGER / EDITOR / DOWNLOADER / READER
```
### 列出知识库成员
```
Usage:
dws wiki member list [flags]
Example:
dws wiki member list --space <WS_ID>
dws wiki member list --space <WS_ID> --max-results 100
dws wiki member list --space <WS_ID> --filter-role EDITOR
Flags:
--space string 目标知识库 ID 或 URL (必填)
--max-results int 返回数量上限,最大 200 (默认 50)
--filter-role string 按角色过滤: MANAGER / EDITOR / DOWNLOADER / READER (选填)
```
> 接口不支持游标分页,使用 `--max-results` 一次性拉取。
## 意图判断
- 用户说"创建知识库/新建知识库" → `space create`
- 用户说"查看知识库/知识库详情" → `space get`
- 用户说"我的知识库/知识库列表/有哪些知识库" → `space list`
- 用户说"搜索知识库/找知识库" → `space search`
- 用户说"我的文档/个人空间" → `space search --type myWikiSpace``space list --type myWikiSpace`
- 用户说"把知识库分享给某人/给某人加入知识库/邀请进知识库" → `member add`(需 `--space` + `--user` + `--role`
- 用户说"修改某人在知识库的权限/调整成员角色" → `member update`
- 用户说"知识库有哪些成员/查看知识库成员" → `member list`
关键区分:
- wiki(知识库空间级管理:创建/查询/列出/搜索/成员管理) vs doc(文档内容级操作:搜索/读写/编辑/节点级权限)
- wiki space(知识库容器) vs drive(钉盘文件存储/上传/下载)
- **wiki member**(容器级,授权整个知识库)vs **doc permission**(节点级,授权单篇文档)
- 「我的文档」**只能用** `doc permission`,不能用 `wiki member`
## 核心工作流
```bash
# 列出我有权访问的组织知识库
dws wiki space list --format json
# 获取「我的文档」个人空间
dws wiki space list --type myWikiSpace --format json
# 搜索知识库
dws wiki space search --keyword "产品" --format json
# 搜索「我的文档」
dws wiki space search --type myWikiSpace --format json
# 创建知识库
dws wiki space create --name "新项目文档" --description "项目相关文档归档" --format json
# 查看知识库详情
dws wiki space get --id <workspaceId> --format json
# ── 工作流: 给知识库加成员 ──
# 1. 先确认知识库 ID(避免授权到「我的文档」)
dws wiki space list --format json # 注意:不要 --type myWikiSpace
# 2. 添加成员
dws wiki member add --space <WS_ID> --user <UID> --role EDITOR --format json
# 3. 查看当前成员
dws wiki member list --space <WS_ID> --format json
```
## 上下文传递表
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `space create` | `workspaceId` | space get 的 --id / member add 的 --space |
| `space list` | `workspaceId` | space get 的 --id / member add 的 --space |
| `space search` | `workspaceId` | space get 的 --id / member add 的 --space |
| `space get` | `spaceUrl` | 分享给用户 |
| `member list` | `userId` | member update 的 --user |
## 相关产品
- [doc](./doc.md) — 文档内容级操作(搜索/读写/编辑文档、知识库内文档管理)
- [drive](./drive.md) — 钉盘文件存储/上传/下载
@@ -0,0 +1,41 @@
# 工作台 (workbench) 命令参考
> ⚠️ **Draft**:以下命令在当前 CLI 运行时中尚未上线(`dws workbench --help` 回退到根帮助页面),文档仅供预览,待服务端注册后生效。
## 命令总览
### 查看所有工作台应用
```
Usage:
dws workbench app list [flags]
Example:
dws workbench app list
```
### 批量获取应用详情
```
Usage:
dws workbench app get [flags]
Example:
dws workbench app get --ids <APP_ID_1>,<APP_ID_2>
Flags:
--ids string 应用 ID 列表 (必填)
```
## 意图判断
用户说"工作台有什么应用/看看应用" → `app list`
用户说"应用详情" → `app get` (需 appId)
## 核心工作流
```bash
# 查看所有应用 — 提取 appId
dws workbench app list --format json
# 获取应用详情
dws workbench app get --ids app1,app2 --format json
```
## 上下文传递表
| 操作 | 提取 | 用于 |
|------|------|------|
| `app list` | `appId` | app get 的 --ids |
+94
View File
@@ -0,0 +1,94 @@
# Recovery Guide
`dws` 的 recovery 闭环以 `dws recovery execute` 为正式入口。主入口仍是 [SKILL.md](../SKILL.md),错误分类与排查细节可结合 [error-codes.md](./error-codes.md) 和 [global-reference.md](./global-reference.md) 一起使用。
## 标准流程
1. 原始 `dws` 命令失败后,从 stderr 提取 `RECOVERY_EVENT_ID=<event_id>`
2. 执行 `dws recovery execute --event-id <event_id> --format json`
3. 读取返回的 `RecoveryBundle`
4. 先查看 `plan.decision_owner`
5. 当 `decision_owner == "agent"` 时,把完整 `RecoveryBundle` 视为事实包,由 Agent 基于事实包、对应产品文档和 `dws` skill 做整体判断,再决定是否组织下一次 grounded 的 `dws` 恢复尝试
6. 恢复尝试结束后,执行 `dws recovery finalize --event-id <event_id> --outcome recovered|failed|handoff --execution-file <file.json> --format json`
CLI 会把 recovery 过程文件保存在 `DWS_CONFIG_DIR/recovery/` 下,并自动清理 30 天前的旧文件与旧事件记录。
## 如何阅读 `RecoveryBundle`
`RecoveryBundle` 重点字段:
- `status``needs_agent_action``analysis_failed`
- `context`:原始失败上下文
- `replay`:可重放的脱敏命令信息和工具参数
- `plan`:规则分类、`decision_owner``agent_route``doc_search``kb_hits``doc_actions``human_actions`
- `doc_search.request`:CLI 实际发起的开放平台文档检索请求参数
- `doc_search.response`CLI 收到的原始文档检索返回内容块
- `probe_results`:CLI 已完成的只读探测和上下文审计结果
- `agent_task`:给 Agent 的明确工作单
- `finalize_hint`:最终必须回写的 `finalize` 命令模板和 `execution-file` 要求
`status == "analysis_failed"` 时,不要假设 CLI 已经修复问题;应先读取 `analysis_error``doc_search``probe_results`,再判断是否还能继续 grounded 尝试。
`plan.decision_owner == "agent"` 时:
- 必须把 CLI 返回内容视为事实包,而不是已定案的恢复结论
- 优先基于完整 `RecoveryBundle` 做判断;若只能读取 `agent_route.payload`,也必须使用其中的 `context``replay``doc_search``kb_hits``doc_actions``probe_results`
- unknown 场景里,不要把 `should_retry``should_stop``human_actions` 当作 CLI 已经替 Agent 作出的最终决定
## Agent 允许做什么
- 读取 [global-reference.md](./global-reference.md)、[error-codes.md](./error-codes.md) 和对应产品文档
- 基于完整 `RecoveryBundle`,尤其是 `doc_actions``kb_hits``probe_results``context``replay` 做整体判断
- 仅在依据明确时重新发起新的 `dws` 命令
- 将真实尝试过程记录进 `execution-file`,再调用 `finalize`
## Agent 禁止做什么
- 编造 taskId、recordId、threadId、UUID、token、URL 或其他业务参数
- 绕过 `dws` 改用 curl、HTTP API、浏览器或其他未授权手段
- 未确认前把失败命令替换成另一套业务流程
- 因为 `human_actions` 里提到用户步骤,就跳过 bundle 里的其余分析信息
## `execution-file` 最小要求
`execution-file` 必须至少包含:
- `actions`
- `attempts`
- `result`
- `error_summary`
`attempts` 是数组,每次尝试至少记录:
- `command_summary`
- `result`
- `error_summary`
- `source`
兼容旧格式:
- `action` 会被归一化成单元素 `actions`
- 数值型 `attempts` 会被展开为 `legacy_execution_file` 来源的 attempts 记录
- `error` 会被归一化到 `error_summary`
## unknown 参数错误处理
如果 `execute` 进入 unknown 场景,且 `probe_results` 已给出 CLI 检查过的上下文来源,Agent 应:
- 先检查上一步输出、已有上下文、产品文档或 `probe_results` 里是否存在真实参数来源
- 若没有可靠来源,就回写 `handoff`
- 不要盲猜新的 ID、UUID、URL、token 或其他业务参数
对应标准闭环:
```bash
dws recovery execute --event-id <event_id> --format json
dws recovery finalize --event-id <event_id> --outcome handoff --execution-file execution.json --format json
```
## 必读参考
- [error-codes.md](./error-codes.md)
- [global-reference.md](./global-reference.md)
- [intent-guide.md](./intent-guide.md)
- [products/](./products/)