Files
2026-09-02 11:44:52 +08:00

385 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# workflow — 自动化工作流管理
创建 / 更新 / 启停 / 手动执行 / 查询执行历史 / 查看 / 列出 Base 下的自动化工作流("当 X 时自动 Y" 流程)。
适用场景:用户要求创建自动化、修改流程、停掉或恢复流程、立即执行流程、核对执行结果或查询已有流程。
## 命令一览
| 命令 | 用途 |
|------|------|
| `workflow edit-example` | 获取工作流编辑文档与 workflow-dsl/v1 示例 |
| `workflow create` | 创建并发布自动化工作流 |
| `workflow update` | 更新并发布已有自动化工作流 |
| `workflow list` | 列出 Base 下所有工作流(含状态/创建人/最后修改时间),支持分页 |
| `workflow get` | 获取单个工作流详情(含 flowSchema 完整节点定义) |
| `workflow enable` | 启用指定工作流(按配置的触发条件自动执行) |
| `workflow disable` | 禁用指定工作流(高危,建议 `--yes` 二次确认) |
| `workflow run` | 立即执行指定工作流(会产生真实副作用,需确认) |
| `workflow history` | 按状态、时间和分页条件查询工作流执行历史 |
> `workflow edit-example` 无参数;其他子命令的 `--base-id` 必填(可用隐藏别名 `--base`)。
## DSL 入参格式与最小 Demo
先运行 `workflow edit-example` 获取服务端提供的最新编辑文档和示例。`workflow create/update``--dsl` 接收钉钉 AI 表格 `workflow-dsl/v1` JSON object。
复杂工作流还应注意:
1. 使用 `workflow edit-example` 获取最新 DSL Guide、结构和示例。
2. 涉及数据表、字段或视图的节点,先用 `table get` / `field get` / `view list` 确认真实 `sheetId``fieldId``viewId`
3. create 和 update 都提交完整的 workflow-dsl/v1 JSON object,并检查所有 `next``loopEntry`、branch `to` 和 ref。
以下 Demo 表示“每天 09:00 触发,并向 Base 所有者发送消息”,不依赖数据表、字段或视图 ID:
```json
{
"version": "workflow-dsl/v1",
"name": "每日提醒",
"description": "可选说明",
"trigger": "start",
"steps": {
"start": {
"type": "Scheduled",
"next": "send",
"data": {
"mode": "daily",
"time": "09:00",
"timezone": "GMT+08:00"
}
},
"send": {
"type": "SendMessage",
"data": {
"title": "定时任务已触发",
"to": {
"users": [{"ref": "$.system_node.ownerUserId"}]
}
}
}
}
}
```
将上述 JSON 保存为 `workflow.json` 后创建工作流:
```bash
dws aitable workflow create \
--base-id BASE_ID \
--dsl @workflow.json \
--locale zh-CN \
--format json
```
保存创建结果中的 `data.flowId`。更新时修改 `workflow.json` 中的完整目标定义,例如修改 `name``description` 或消息 `title`,然后调用:
```bash
dws aitable workflow update \
--base-id BASE_ID \
--workflow-id FLOW_ID \
--dsl @workflow.json \
--locale zh-CN \
--format json
```
create 和 update 都必须同时满足 `status=success``data.valid=true``data.issues=[]` 才表示发布成功;update 返回的 `data.flowId` 应与传入的 `FLOW_ID` 一致。以上仅为最小 Demo,复杂节点的 `type``data` 结构以钉钉 AI 表格 MCP 最新 DSL 文档为准。
## 命令详情
### workflow edit-example — 获取编辑文档与示例
```bash
dws aitable workflow edit-example --format json
```
该命令无业务参数,调用 `aitable/edit_workflow_example` 返回服务端提供的工作流编辑文档和示例。创建或更新复杂工作流前优先调用它,避免依赖可能过期的本地 DSL 结构。
### workflow create — 创建并发布工作流
```bash
# 大 DSL 推荐从文件读取
dws aitable workflow create \
--base-id BASE_ID \
--dsl @workflow.json \
--locale zh-CN \
--format json
# 也支持 stdin
cat workflow.json | dws aitable workflow create --base-id BASE_ID --dsl - --format json
```
| flag | 必填 | 说明 |
|------|------|------|
| `--base-id` | 是 | 所属 Base ID |
| `--dsl` | 是 | workflow-dsl/v1 JSON object;支持内联 JSON、`@filepath``-` stdin |
| `--locale` | 否 | 请求语言,如 `zh-CN` / `zh_CN` |
创建成功返回发布结果:
```json
{
"status": "success",
"data": {
"valid": true,
"flowId": "G-FLOW-XXXXXX",
"flowSchema": {},
"stepNodeIds": {},
"referenceMap": {},
"issues": []
}
}
```
关键语义:
- `create` 非幂等,CLI 不自动重试。若网络中断导致结果不确定,先 `workflow list` 按名称确认是否已创建,再决定是否重试。
- `status=success` 只说明 workflow-edit 正常返回;如果 `data.valid=false`,仍表示 DSL 未通过校验或发布,必须读取 `issues` 修正。
- 创建并发布后,用 `workflow list` 确认 `status`;需要运行但状态为 `STOP` 时再调用 `workflow enable`
### workflow update — 更新并发布工作流
```bash
# 先留底现有详情,再提交完整目标 DSL
dws aitable workflow get --base-id BASE_ID --workflow-id WORKFLOW_ID --format json > /tmp/workflow-backup.json
dws aitable workflow update \
--base-id BASE_ID \
--workflow-id WORKFLOW_ID \
--dsl @workflow.json \
--locale zh_CN \
--format json
```
| flag | 必填 | 说明 |
|------|------|------|
| `--base-id` | 是 | 所属 Base ID |
| `--workflow-id` | 是 | 目标工作流 ID,对应 list 的 `flowId` |
| `--dsl` | 是 | 完整目标 workflow-dsl/v1 JSON object;支持内联、`@filepath``-` stdin |
| `--locale` | 否 | 请求语言,如 `zh-CN` / `zh_CN` |
返回结构与 create 相同,成功时 `flowId` 应为目标工作流。update 使用 AI 表格瞬态错误重试;最终仍必须检查 `data.valid``issues`,并用 `workflow get/list` 验证发布结果与运行状态。
### workflow run — 立即执行工作流
```bash
# 记录类触发器
dws aitable workflow run --base-id BASE_ID --workflow-id WORKFLOW_ID \
--table-id TABLE_ID --record-ids RECORD_ID_1,RECORD_ID_2
# 定时触发器不传 table-id / record-ids
dws aitable workflow run --base-id BASE_ID --workflow-id WORKFLOW_ID
```
| flag | 必填 | 说明 |
|------|------|------|
| `--base-id` | 是 | 所属 Base ID |
| `--workflow-id` | 是 | 目标工作流 ID |
| `--table-id` | 条件必填 | 记录类触发器绑定的数据表;必须与触发器配置一致 |
| `--record-ids` | 条件必填 | 记录类触发器的记录 ID,1–5 个、逗号分隔且不可重复 |
`run` 启动真实异步执行,工作流中的发消息、写记录等动作会实际发生;执行前必须取得用户确认。返回项中的 `executionId` 是本次执行标识,可与 `workflow history` 项目的 `instanceId` 匹配。网络结果不确定时不要直接重复执行,先按该标识查询历史。
### workflow history — 查询执行历史
```bash
dws aitable workflow history --base-id BASE_ID --workflow-id WORKFLOW_ID \
--status failed --after-time 1786000000000 --before-time 1787000000000 \
--page 0 --size 50
```
| flag | 说明 |
|------|------|
| `--base-id` | 必填 |
| `--workflow-id` | 必填;CLI 会映射为 MCP 的 `flowId` |
| `--status` | 可选:`success` / `failed` / `running` / `break` / `untrigger` |
| `--after-time` | 可选,Unix 毫秒开始时间 |
| `--before-time` | 可选,Unix 毫秒结束时间;与 after-time 同传时必须更大 |
| `--page` | 可选,从 0 开始,默认 0 |
| `--size` | 可选,默认 20,范围 `[1, 100]` |
返回 `totalCount``list``running` 是非终态;`success``failed``break``untrigger` 是终态。
### workflow list — 列出工作流
```bash
dws aitable workflow list --base-id BASE_ID --format json
dws aitable workflow list --base-id BASE_ID --limit 50 --offset 100
```
| flag | 说明 |
|------|------|
| `--base-id` | 必填 |
| `--limit` | 可选,分页大小 `[1, 100]`,不传走服务端默认 20 |
| `--offset` | 可选,分页偏移量 `>= 0`,不传走服务端默认 0 |
返回结构:
```json
{
"data": {
"list": [
{
"flowId": "G-FLOW-XXXXXX", // ★ 注意字段名是 flowId
"name": "流程1",
"description": "当创建记录时,就更新记录",
"status": "RUNNING", // RUNNING / STOP
"creatorStaffId": "281493",
"lastModifier": { "name": "李普阳", "staffId": "281493" },
"gmtModified": 1780318540000,
"versionId": "G-FLOW-VER-XXXXXX",
"icons": ["..."], // 触发器+动作的图标
"isSubFlow": false,
"opPermissions": { "canEdit": true }
}
],
"recordCount": 1, // Base 下总数
"runningCount": 1 // RUNNING 状态的数量
}
}
```
**注意**
- 标识字段服务端在 `list` 里叫 **`flowId`**,但在 `enable` / `disable` 出参里叫 **`workflowId`**。CLI `--workflow-id` 传任一即可(同值)。
- `status` 是字符串枚举:`RUNNING`(启用中)/ `STOP`(已禁用),**不是** boolean。
- `runningCount` 是当前 Base 下 status=RUNNING 的工作流数,方便快速判断「有几个流程在跑」。
### workflow get — 获取单个工作流详情
```bash
dws aitable workflow get --base-id BASE_ID --workflow-id WORKFLOW_ID --format json
```
| flag | 说明 |
|------|------|
| `--base-id` | 必填 |
| `--workflow-id` | 必填,对应 list 出参里的 `flowId` |
返回完整工作流配置:
```json
{
"data": {
"name": "流程1",
"namespace": "...",
"status": "RUNNING",
"versionId": "G-FLOW-VER-XXXXXX",
"versionNo": 14,
"versionStatus": "...",
"accessor": {...}, // 访问者信息
"corpId": "...",
"flowAttribute": {...}, // 流程顶层属性
"flowSchema": {...}, // ★ 流程节点定义(触发器/动作/分支等)
"gmtCreate": 1780317804000,
"gmtModified": 1780318540000
}
}
```
`flowSchema` 是完整的节点 DAG,结构因流程而异(条件触发器 vs 定时触发器、单分支 vs 多分支等)。agent 应按需读取关心字段,不要试图建静态 schema。
### workflow enable — 启用工作流
```bash
dws aitable workflow enable --base-id BASE_ID --workflow-id WORKFLOW_ID --format json
```
返回 `{workflowId, enabled: true}` —— **`enabled: true` 是动作确认,不是当前状态查询**。要确认真启用了,必须再 `workflow list``status` 是否变成 `"RUNNING"``runningCount` 是否加 1。
### workflow disable — 禁用工作流(高危)
```bash
dws aitable workflow disable --base-id BASE_ID --workflow-id WORKFLOW_ID --yes --format json
```
返回 `{workflowId, disabled: true}` —— 同样是动作确认。禁用后该工作流不再自动触发。
**风险**:直接影响业务自动化(如停掉「记录创建后自动发通知」会让通知断流)。建议:
- 操作前先 `workflow get` 留底当前配置
- 脚本场景显式传 `--yes`;交互场景让用户在 prompt 中再次确认
## 能力边界
| 能力 | 状态 |
|------|------|
| 新建工作流 | ✅ 创建并发布 |
| 修改工作流配置 | ✅ 更新并发布 |
| 列出工作流 | ✅ |
| 看工作流详情(含 flowSchema | ✅ |
| 启用/禁用 | ✅ |
| 查看运行历史/执行日志 | ✅ `workflow history` |
| 手动触发/单次运行 | ✅ `workflow run`(需确认) |
| 删除工作流 | ❌ 暂未开放 |
## 错误码速查
| 场景 | code | type | 备注 |
|------|------|------|------|
| create/update 返回 `valid=false` | — | success envelope | 读取 `data.issues` 修正 DSL,不能当作发布成功 |
| create 下游失败 | `CREATE_WORKFLOW_ERROR` | `SYSTEM_ERROR` | create 不自动重试;先 list 排查是否已创建 |
| update 下游失败 | `UPDATE_WORKFLOW_ERROR` | `SYSTEM_ERROR` | update 会重试瞬态错误,最终失败时保留 DSL 和 workflowId 排查 |
| `workflow-id` 不存在调 get | `GET_WORKFLOW_ERROR` | `SYSTEM_ERROR` | message 可能为 null,先 `workflow list` 核对 ID |
| `workflow-id` 不存在调 enable | `ENABLE_WORKFLOW_ERROR` | `SYSTEM_ERROR` | message 含 "场域中不存在该 namespace" |
| `workflow-id` 不存在调 disable | `DISABLE_WORKFLOW_ERROR` | `SYSTEM_ERROR` | 同上 |
| `--limit` < 1 或 > 100 | CLI 层拦截) | — | `--limit 必须在 [1, 100] 范围内,got N` |
| `--offset` < 0 | CLI 层拦截) | — | `--offset 必须 >= 0got N` |
> 拿到 `*_WORKFLOW_ERROR / SYSTEM_ERROR` 时,先 `workflow list` 自查目标 ID 是否还存在、是否在当前 Base 下。
## 典型工作流
### 创建并确认一个工作流
```bash
# 1. 按本文 DSL Demo 生成 /tmp/workflow.json
dws aitable workflow create --base-id BASE_ID --dsl @/tmp/workflow.json --locale zh-CN --format json \
| tee /tmp/workflow-result.json
# 2. valid 必须为 true;保存 flowId
jq '{valid: .data.valid, flowId: .data.flowId, issues: .data.issues}' /tmp/workflow-result.json
# 3. 确认运行状态,需要时显式启用
FLOW_ID=$(jq -r '.data.flowId' /tmp/workflow-result.json)
dws aitable workflow list --base-id BASE_ID --format json \
| jq --arg id "$FLOW_ID" '.data.list[] | select(.flowId == $id) | {flowId, name, status}'
```
### 看看 Base 里有哪些自动化在跑
```bash
dws aitable workflow list --base-id BASE_ID --format json | jq '.data | {total: .recordCount, running: .runningCount, items: .list | map({name, status, flowId})}'
```
### 临时停掉某个流程做调试
```bash
# 1. 留底当前状态
dws aitable workflow get --base-id BASE_ID --workflow-id WORKFLOW_ID --format json > /tmp/wf-backup.json
# 2. 禁用
dws aitable workflow disable --base-id BASE_ID --workflow-id WORKFLOW_ID --yes --format json
# 3. 调试做完后重启
dws aitable workflow enable --base-id BASE_ID --workflow-id WORKFLOW_ID --format json
# 4. 确认 status=RUNNING
dws aitable workflow list --base-id BASE_ID --format json | jq '.data.list[] | select(.flowId == "WORKFLOW_ID") | .status'
```
### 批量关掉某个 Base 下所有 workflow(调试 / 迁移前清场)
```bash
for WF in $(dws aitable workflow list --base-id BASE_ID --limit 100 --format json | jq -r '.data.list[] | select(.status == "RUNNING") | .flowId'); do
dws aitable workflow disable --base-id BASE_ID --workflow-id "$WF" --yes --format json | jq .status
done
```
## 注意事项
- `--workflow-id` 接受的就是 `list` 返回里的 `flowId`(同值,CLI 屏蔽了服务端字段名差异)。
- create / update 的 `--dsl` 必须是 JSON object,不能传数组、字符串化的二次 JSON 或 FlowSchema。
- 本文 Demo 可直接用于最小定时消息工作流;复杂节点应以钉钉 AI 表格 MCP 最新 DSL 文档为准。
- `status=success``data.valid=false` 仍是 DSL 校验失败;`issues` 才是下一步修复依据。
- create 不自动重试;update 仅对网络/5xx/`retryable:true` 瞬态错误自动重试。
- enable / disable 出参里的 `enabled` / `disabled`**动作确认 flag**,不是当前状态字段。要确认真生效请走 `workflow list``status`
- `workflow get``flowSchema` 结构随触发器/动作类型变化,不要假设固定字段。
- `workflow run` 不自动重试;结果不确定时用 `workflow history` 按 executionId / instanceId 核对。
- 删除工作流当前仍未开放。