mirror of
https://github.com/larksuite/cli.git
synced 2026-07-03 14:02:43 +08:00
feat(base): optimize workflow skills (#345)
Change-Id: I70bce656feea6af54b3366db3e71eea8f1d5b47b
This commit is contained in:
committed by
GitHub
parent
5f3915b25c
commit
d7363b0481
@@ -19,7 +19,7 @@ var BaseWorkflowCreate = common.Shortcut{
|
||||
AuthTypes: []string{"user", "bot"},
|
||||
Flags: []common.Flag{
|
||||
{Name: "base-token", Desc: "base token", Required: true},
|
||||
{Name: "json", Desc: `workflow body JSON, e.g. {"title":"My Workflow","steps":[...]}; or @path/to/file.json for large definitions`, Required: true},
|
||||
{Name: "json", Desc: `workflow body JSON, e.g. {"title":"My Workflow","steps":[...]}`, Required: true},
|
||||
},
|
||||
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
|
||||
if strings.TrimSpace(runtime.Str("base-token")) == "" {
|
||||
|
||||
@@ -20,7 +20,7 @@ var BaseWorkflowUpdate = common.Shortcut{
|
||||
Flags: []common.Flag{
|
||||
{Name: "base-token", Desc: "base token", Required: true},
|
||||
{Name: "workflow-id", Desc: "workflow ID (wkf... prefix)", Required: true},
|
||||
{Name: "json", Desc: `workflow body JSON, e.g. {"title":"New Title","steps":[...]}; or @path/to/file.json for large definitions`, Required: true},
|
||||
{Name: "json", Desc: `workflow body JSON, e.g. {"title":"New Title","steps":[...]}`, Required: true},
|
||||
},
|
||||
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
|
||||
if strings.TrimSpace(runtime.Str("base-token")) == "" {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: lark-base
|
||||
version: 1.2.0
|
||||
description: "当需要用 lark-cli 操作飞书多维表格(Base)时调用:适用于建表、字段管理、记录读写、视图配置、历史查询,以及角色/表单/仪表盘管理;也适用于把旧的 +table / +field / +record 写法改成当前命令写法。涉及字段设计、公式字段、查找引用、跨表计算、行级派生指标、数据分析需求时也必须使用本 skill。"
|
||||
description: "当需要用 lark-cli 操作飞书多维表格(Base)时调用:适用于建表、字段管理、记录读写、视图配置、历史查询,以及角色/表单/仪表盘管理/工作流;也适用于把旧的 +table / +field / +record 写法改成当前命令写法。涉及字段设计、公式字段、查找引用、跨表计算、行级派生指标、数据分析需求时也必须使用本 skill。"
|
||||
metadata:
|
||||
requires:
|
||||
bins: ["lark-cli"]
|
||||
@@ -85,19 +85,24 @@ metadata:
|
||||
|
||||
## Workflow 专项规则
|
||||
|
||||
1. **执行任何 workflow 命令前,必须先读两份文档:对应的命令文档 + [lark-base-workflow-schema.md](references/lark-base-workflow-schema.md)**
|
||||
- `+workflow-create` → 先读 [lark-base-workflow-create.md](references/lark-base-workflow-create.md) + schema
|
||||
- `+workflow-update` → 先读 [lark-base-workflow-update.md](references/lark-base-workflow-update.md) + schema
|
||||
- `+workflow-list` → 先读 [lark-base-workflow-list.md](references/lark-base-workflow-list.md) + schema
|
||||
- `+workflow-get` → 先读 [lark-base-workflow-get.md](references/lark-base-workflow-get.md) + schema
|
||||
- `+workflow-enable` → 先读 [lark-base-workflow-enable.md](references/lark-base-workflow-enable.md) + schema
|
||||
- `+workflow-disable` → 先读 [lark-base-workflow-disable.md](references/lark-base-workflow-disable.md) + schema
|
||||
- schema 中定义了所有 StepType 枚举、步骤结构、Trigger/Action/Branch/Loop 的 data 格式、值引用语法等
|
||||
- 禁止凭自然语言猜测 `type` 值(如把"新增记录"猜成 `CreateTrigger`),必须从 schema 的 StepType 枚举中复制准确的类型名称
|
||||
|
||||
2. **创建前确认依赖信息**
|
||||
- 先通过 `+table-list` / `+field-list` 获取真实的表名、字段名
|
||||
1. **执行任何 workflow 命令前,必须先读对应的命令文档**
|
||||
- **创建**: 先读 [workflow-create.md](references/lark-base-workflow-create.md)(它会引导你读 schema)
|
||||
- **修改**: 先读 [workflow-update.md](references/lark-base-workflow-update.md) + [workflow-get.md](references/lark-base-workflow-get.md) 获取现有配置
|
||||
- **查询/批量操作**: 先读 [workflow-list.md](references/lark-base-workflow-list.md)(注意场景适用性)
|
||||
- **获取详情**: 先读 [workflow-get.md](references/lark-base-workflow-get.md),用于获取完整 workflow 定义(含 steps 结构)
|
||||
- **启用**: 先读 [workflow-enable.md](references/lark-base-workflow-enable.md),启用处于 `disabled` 状态的工作流
|
||||
- **禁用**: 先读 [workflow-disable.md](references/lark-base-workflow-disable.md),禁用处于 `enabled` 状态的工作流
|
||||
2. **禁止凭自然语言猜测 `type` 值**
|
||||
- 必须从 schema 的 StepType 枚举中复制准确的类型名称
|
||||
- 如 `AddRecordTrigger` 不是 `CreateTrigger`
|
||||
3. **创建前确认依赖信息**
|
||||
- 通过 `+table-list` / `+field-list` 获取真实的表名、字段名
|
||||
- 禁止凭自然语言猜测表名/字段名填入 workflow 配置
|
||||
4. **workflow_id 与 table_id 区分**
|
||||
- `workflow_id` 以 `wkf` 开头,从 `+workflow-list` 或 URL 的 `?table=wkf...` 参数获取
|
||||
- `table_id` 以 `tbl` 开头,两者在 URL 的 `?table=` 参数里都会出现,需根据前缀判断
|
||||
5. **启用/禁用为写入操作**
|
||||
- `+workflow-enable` / `+workflow-disable` 执行前必须向用户确认 base-token 和 workflow-id
|
||||
|
||||
## Dashboard(仪表盘/数据看板)模块
|
||||
**当用户提到 "仪表盘、dashboard、数据看板、图表、可视化、block、组件、添加组件、创建图表" 等仪表盘相关的关键词时,必须阅读** [lark-base-dashboard.md](references/lark-base-dashboard.md) 这个指引文档,了解仪表盘模块的命令和能力后再进行后续操作。
|
||||
|
||||
@@ -4,18 +4,31 @@
|
||||
|
||||
在 Base 中创建一个新的自动化工作流。新建后状态为 `disabled`,需调用 `+workflow-enable` 才能启用。
|
||||
|
||||
## ⚠️ 执行前必读
|
||||
|
||||
创建工作流前请按顺序完成:
|
||||
|
||||
1. **先读本文档**,了解 `--json` 参数格式和 `client_token` 的必填要求
|
||||
2. **阅读 [workflow-guide.md](lark-base-workflow-guide.md)**,获取 Loop、IfElseBranch、SwitchBranch 等**完整示例**
|
||||
3. **参考 [workflow-schema.md](lark-base-workflow-schema.md)**,查询具体字段定义
|
||||
4. **不需要先调用 `+workflow-list`**,创建操作不依赖现有工作流列表
|
||||
5. **按需调用 `+table-list` 和 `+field-list`** 获取表名和字段名(只在需要时调用)
|
||||
6. **若遇到单多选字段,可调用`+field-get`命令**来获取选项详情
|
||||
7. **调用命令时,请将 body 数据直接通过 --json 传入,禁止创建任何的临时文件,即禁止使用 --json @filename**
|
||||
|
||||
**常见错误**:
|
||||
- ❌ 缺少 `client_token` → 报错: `client token is empty`
|
||||
- ❌ 猜测 StepType → 报错: `unknown step type 'CreateTrigger'`(应该是 `AddRecordTrigger`)
|
||||
- ❌ 字段引用路径错误 → 报错: `prompt references an unknown reference`
|
||||
|
||||
> 💡 **提示**: 复杂场景(循环、分支、多步骤组合)的完整示例请直接阅读 [workflow-guide.md](lark-base-workflow-guide.md),本文档只包含基础用法。
|
||||
|
||||
## 推荐命令
|
||||
|
||||
```bash
|
||||
# 内联 JSON(简单工作流)
|
||||
lark-cli base +workflow-create \
|
||||
--base-token BascXxxxxx \
|
||||
--json '{"client_token":"1700000000","title":"新订单自动通知","steps":[{"id":"trigger_1","type":"AddRecordTrigger","title":"监控新订单","next":"action_1","data":{"table_name":"订单表","watched_field_name":"订单号"}},{"id":"action_1","type":"LarkMessageAction","title":"发送通知","next":null,"data":{"receiver":[{"value_type":"user","value":"ou_xxxx"}],"send_to_everyone":false,"title":[{"value_type":"text","value":"新订单提醒"}],"content":[{"value_type":"text","value":"收到新订单"}],"btn_list":[]}}]}'
|
||||
|
||||
# 从文件读取(推荐用于复杂工作流)
|
||||
lark-cli base +workflow-create \
|
||||
--base-token BascXxxxxx \
|
||||
--json @workflow.json
|
||||
--json '{"client_token":"1704067200","title":"新订单自动通知","steps":[{"id":"trigger_1","type":"AddRecordTrigger","title":"监控新订单","next":"action_1","data":{"table_name":"订单表","watched_field_name":"订单号"}},{"id":"action_1","type":"LarkMessageAction","title":"发送通知","next":null,"data":{"receiver":[{"value_type":"user","value":{"id":"ou_xxxx"}}],"send_to_everyone":false,"title":[{"value_type":"text","value":"新订单提醒"}],"content":[{"value_type":"text","value":"收到新订单"}],"btn_list":[]}}]}'
|
||||
```
|
||||
|
||||
## 参数
|
||||
@@ -23,7 +36,7 @@ lark-cli base +workflow-create \
|
||||
| 参数 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `--base-token <token>` | 是 | 多维表格 Base Token(`Basc` 开头) |
|
||||
| `--json <body>` | 是 | 工作流 body JSON,包含 `title` 和/或 `steps`;支持 `@path/to/file.json` 从文件读取 |
|
||||
| `--json <body>` | 是 | 工作流 body JSON,包含 `title` 和 `steps` |
|
||||
|
||||
## 如何从链接中提取参数
|
||||
|
||||
@@ -82,12 +95,12 @@ POST /open-apis/base/v3/bases/:base_token/workflows
|
||||
"title": "发送通知",
|
||||
"next": null,
|
||||
"data": {
|
||||
"receiver": [{ "value_type": "user", "value": "ou_xxxx" }],
|
||||
"receiver": [{ "value_type": "user", "value": {"id": "ou_xxxx"} }],
|
||||
"send_to_everyone": false,
|
||||
"title": [{ "value_type": "text", "value": "新订单提醒" }],
|
||||
"content": [
|
||||
{ "value_type": "text", "value": "收到新订单,客户:" },
|
||||
{ "value_type": "ref", "value": { "path": "$.trigger_1.客户名称" } }
|
||||
{ "value_type": "ref", "value": "$.trigger_1.fldCustomerName" }
|
||||
],
|
||||
"btn_list": []
|
||||
}
|
||||
@@ -117,7 +130,7 @@ POST /open-apis/base/v3/bases/:base_token/workflows
|
||||
{
|
||||
"ok": true,
|
||||
"data": {
|
||||
"workflow_id": "wkfxxxxxx",
|
||||
"workflow_id": "wkfosaYTS1V6rhjF",
|
||||
"title": "新订单自动通知",
|
||||
"status": "disabled",
|
||||
"steps": [...],
|
||||
@@ -135,16 +148,25 @@ POST /open-apis/base/v3/bases/:base_token/workflows
|
||||
> 这是**写入操作** — 执行前必须向用户确认。
|
||||
|
||||
1. 与用户确认 `--base-token` 和工作流定义(`--json` 内容)
|
||||
2. 对于复杂工作流,建议先将 JSON 写入文件,再用 `@file.json` 传入
|
||||
3. 执行命令,报告返回的 `workflow_id`(`wkf` 开头)
|
||||
4. 提示用户:新建工作流初始状态为 `disabled`,需调用 `+workflow-enable --workflow-id <返回的 workflow_id>` 才会生效
|
||||
2. 执行命令,报告返回的 `workflow_id`(`wkf` 开头)
|
||||
3. 提示用户:新建工作流初始状态为 `disabled`,需调用 `+workflow-enable --workflow-id <返回的 workflow_id>` 才会生效
|
||||
|
||||
## 坑点
|
||||
|
||||
- ⚠️ **client_token 必传**:缺失会返回 `[code=800004006] client token is empty`,这不是权限问题,是 JSON body 缺字段。每次请求传唯一值即可(如 `"$(date +%s)"`)
|
||||
> ⚠️ **【重要】client_token 必传**:缺失会返回 `[code=800004006] client token is empty`,这**不是权限问题**,是 **JSON body 缺字段**。每次请求传唯一值即可(如 `"$(date +%s)"` 或 `"1743078000"`)
|
||||
|
||||
- ⚠️ **新建后默认禁用**:`status` 固定返回 `disabled`,需要额外调用 `+workflow-enable` 才能让工作流生效;不要误报"创建成功即启用"
|
||||
- ⚠️ **steps 中 id 字段必须唯一**:每个步骤的 `id` 由调用方指定,且在工作流内必须唯一;`next` 和 `children.links[].to` 引用的 ID 必须在同一 steps 数组中存在,否则服务端返回 `[2200] Internal Error`
|
||||
- ⚠️ **@file 路径限制**:`--json @workflow.json` 会读取文件内容,复杂 workflow 强烈建议用文件而不是命令行内联。CLI 强制要求相对路径(如 `@./workflow.json`),绝对路径(包括 `/tmp/xxx` 和 `/Users/.../xxx`)会被拒绝
|
||||
- ⚠️ **字段类型校验**:设置字段值时,`value_type` 必须与字段实际类型匹配:
|
||||
- **select 类型字段**(单选/多选/流程):必须用 `option`,不能用 `text`
|
||||
```json
|
||||
// ✅ 正确
|
||||
{ "field_name": "大区", "value": [{"value_type": "option", "value": {"name": "华东"}}] }
|
||||
// ❌ 错误 - 会报错 valueType 'text' not allowed for fieldType '3'
|
||||
{ "field_name": "大区", "value": [{"value_type": "text", "value": "华东"}] }
|
||||
```
|
||||
- **SetRecordTrigger 的 field_watch_info** 同样受此限制,select 类型字段的 value 必须用 `option`
|
||||
常见 action 输出:`FindRecordAction` → `$.step_id.recordNum`(记录数)、`$.step_id.fieldRecords`(查找到的记录列表);`AddRecordAction` → `$.step_id.recordId`
|
||||
- ⚠️ **权限不足**:如遇 `permission denied`,先确认当前身份(bot 或 user)是否对该 Base 有编辑权限,再检查 scope 是否已开通。参考 [lark-shared](../../lark-shared/SKILL.md) 中的权限不足处理流程
|
||||
- ⚠️ **user_id_type**:涉及用户的 `value_type: "user"` 的 value 字段传 OpenID,服务端会根据 `user_id_type`(默认 `open_id`)解析;如需传 `user_id` 格式需在 body 里显式声明 `"user_id_type": "user_id"`
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# base +workflow-get
|
||||
|
||||
> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
|
||||
> **必读参考:** 获取到的 `steps` 列表的具体节点结构和各触发器/动作组件的完整配置项,请参见 [`lark-base-workflow-schema.md`](lark-base-workflow-schema.md)。
|
||||
> 💡 **按需查阅:** 如需深入理解返回的 `steps` 节点结构,可参考 [workflow-schema.md](lark-base-workflow-schema.md)。简单统计(如节点数量)无需阅读 schema。
|
||||
|
||||
获取一个 workflow 的完整定义,包括标题、状态、所有步骤(steps)及其配置。
|
||||
|
||||
|
||||
718
skills/lark-base/references/lark-base-workflow-guide.md
Normal file
718
skills/lark-base/references/lark-base-workflow-guide.md
Normal file
@@ -0,0 +1,718 @@
|
||||
# Workflow 构造指南
|
||||
|
||||
本文档提供 Workflow 的完整构造示例、常见模式和错误避免指南。
|
||||
|
||||
> **配套文档**:
|
||||
> - Workflow 的数据结构参考:[lark-base-workflow-schema.md](lark-base-workflow-schema.md)
|
||||
> - 创建命令:[lark-base-workflow-create.md](lark-base-workflow-create.md)
|
||||
> - 更新命令:[lark-base-workflow-update.md](lark-base-workflow-update.md)
|
||||
|
||||
---
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 最简单的 Workflow
|
||||
|
||||
新增记录时发送消息通知:
|
||||
|
||||
```json
|
||||
{
|
||||
"client_token": "1704067200",
|
||||
"title": "新订单自动通知",
|
||||
"steps": [
|
||||
{
|
||||
"id": "trigger_1",
|
||||
"type": "AddRecordTrigger",
|
||||
"title": "监控新订单",
|
||||
"next": "action_1",
|
||||
"data": {
|
||||
"table_name": "订单表",
|
||||
"watched_field_name": "订单号"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "action_1",
|
||||
"type": "LarkMessageAction",
|
||||
"title": "发送通知",
|
||||
"next": null,
|
||||
"data": {
|
||||
"receiver": [{ "value_type": "user", "value": {"id": "ou_xxxx", "name": "张三"} }],
|
||||
"send_to_everyone": false,
|
||||
"title": [{ "value_type": "text", "value": "新订单提醒" }],
|
||||
"content": [
|
||||
{ "value_type": "text", "value": "收到新订单" }
|
||||
],
|
||||
"btn_list": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 场景速查表
|
||||
|
||||
| 场景 | 步骤组合 | 示例 |
|
||||
|------|---------|------|
|
||||
| 新增触发+通知 | AddRecordTrigger → LarkMessageAction | [下方](#示例1-新增记录触发--发送消息) |
|
||||
| 定时+循环 | TimerTrigger → FindRecordAction → Loop → LarkMessageAction | [下方](#示例2-定时触发--查找记录--循环遍历--发送消息) |
|
||||
| 条件判断 | ... → IfElseBranch → 分支处理 | [下方](#示例3-条件分支-ifelsebranch) |
|
||||
| 多路分类 | ... → SwitchBranch → 多分支处理 | [下方](#示例4-多路分支-switchbranch) |
|
||||
| 复杂组合 | 定时+查找+循环+分支+消息 | [下方](#示例5-组合场景-定时查找循环分支消息) |
|
||||
|
||||
---
|
||||
|
||||
## 完整示例
|
||||
|
||||
### 示例 1: 新增记录触发 + 发送消息
|
||||
|
||||
**场景**: 当订单表新增记录时,发送飞书消息通知负责人。
|
||||
|
||||
```json
|
||||
{
|
||||
"client_token": "1704067201",
|
||||
"title": "新订单自动通知",
|
||||
"steps": [
|
||||
{
|
||||
"id": "step_trigger",
|
||||
"type": "AddRecordTrigger",
|
||||
"title": "新增订单时触发",
|
||||
"next": "step_notify",
|
||||
"data": {
|
||||
"table_name": "订单表",
|
||||
"watched_field_name": "订单号",
|
||||
"condition_list": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_notify",
|
||||
"type": "LarkMessageAction",
|
||||
"title": "发送订单通知",
|
||||
"next": null,
|
||||
"data": {
|
||||
"receiver": [{ "value_type": "ref", "value": "$.step_trigger.fldManager" }],
|
||||
"send_to_everyone": false,
|
||||
"title": [{ "value_type": "text", "value": "新订单提醒" }],
|
||||
"content": [
|
||||
{ "value_type": "text", "value": "客户 " },
|
||||
{ "value_type": "ref", "value": "$.step_trigger.fldCustomer" },
|
||||
{ "value_type": "text", "value": " 创建了新订单,金额:¥" },
|
||||
{ "value_type": "ref", "value": "$.step_trigger.fldAmount" }
|
||||
],
|
||||
"btn_list": [
|
||||
{
|
||||
"text": "查看订单",
|
||||
"btn_action": "openLink",
|
||||
"link": [{ "value_type": "ref", "value": "$.step_trigger.recordLink" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**关键点**:
|
||||
- `AddRecordTrigger` 监控 `table_name` 表的 `watched_field_name` 字段
|
||||
- 使用 `ref` 引用触发器输出的字段值(注意是 fieldId,不是字段名)
|
||||
- `recordLink` 是触发器内置输出,表示记录链接
|
||||
|
||||
---
|
||||
|
||||
### 示例 2: 定时触发 + 查找记录 + 循环遍历 + 发送消息
|
||||
|
||||
**场景**: 每天早上 9 点,查找所有待处理订单,给每个客户发送提醒。
|
||||
|
||||
```json
|
||||
{
|
||||
"client_token": "1704067202",
|
||||
"title": "每日待处理订单提醒",
|
||||
"steps": [
|
||||
{
|
||||
"id": "step_timer",
|
||||
"type": "TimerTrigger",
|
||||
"title": "每天早上9点触发",
|
||||
"next": "step_find_orders",
|
||||
"data": {
|
||||
"rule": "DAILY",
|
||||
"start_time": "2025-01-01 09:00",
|
||||
"is_never_end": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_find_orders",
|
||||
"type": "FindRecordAction",
|
||||
"title": "查找所有待处理订单",
|
||||
"next": "step_loop_customers",
|
||||
"data": {
|
||||
"table_name": "订单表",
|
||||
"field_names": ["客户名称", "订单金额", "客户联系方式"],
|
||||
"should_proceed_when_no_results": false,
|
||||
"filter_info": {
|
||||
"conjunction": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"field_name": "状态",
|
||||
"operator": "is",
|
||||
"value": [{ "value_type": "option", "value": { "name": "待处理" } }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_loop_customers",
|
||||
"type": "Loop",
|
||||
"title": "遍历每个订单",
|
||||
"children": {
|
||||
"links": [
|
||||
{ "kind": "loop_start", "to": "step_send_reminder" }
|
||||
]
|
||||
},
|
||||
"next": null,
|
||||
"data": {
|
||||
"loop_mode": "continue",
|
||||
"max_loop_times": 100,
|
||||
"data": [{
|
||||
"value_type": "ref",
|
||||
"value": "$.step_find_orders.fieldRecords"
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_send_reminder",
|
||||
"type": "LarkMessageAction",
|
||||
"title": "发送催办消息",
|
||||
"next": null,
|
||||
"data": {
|
||||
"receiver": [{
|
||||
"value_type": "ref",
|
||||
"value": "$.step_loop_customers.item.fldContact"
|
||||
}],
|
||||
"send_to_everyone": false,
|
||||
"title": [{ "value_type": "text", "value": "订单处理提醒" }],
|
||||
"content": [
|
||||
{ "value_type": "text", "value": "您好,您的订单 " },
|
||||
{ "value_type": "ref", "value": "$.step_loop_customers.item.fldName" },
|
||||
{ "value_type": "text", "value": " 金额 ¥" },
|
||||
{ "value_type": "ref", "value": "$.step_loop_customers.item.fldAmount" },
|
||||
{ "value_type": "text", "value": " 正在处理中。" }
|
||||
],
|
||||
"btn_list": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**关键点**:
|
||||
- `Loop.data` 必须传入 `ref` 类型的数据源(通常是 FindRecordAction 的 `fieldRecords`)
|
||||
- `Loop.children.links` 必须包含 `kind: "loop_start"` 的链接指向循环体
|
||||
- 循环体内用 `$.{loopStepId}.item.{fieldId}` 引用当前遍历记录的字段
|
||||
- `$.{loopStepId}.index` 获取当前索引(从 0 开始)
|
||||
|
||||
---
|
||||
|
||||
### 示例 3: 条件分支(IfElseBranch)
|
||||
|
||||
**场景**: 根据订单金额判断,大额订单通知主管审批,小额订单自动通过。
|
||||
|
||||
```json
|
||||
{
|
||||
"client_token": "1704067203",
|
||||
"title": "订单金额自动判断",
|
||||
"steps": [
|
||||
{
|
||||
"id": "step_trigger",
|
||||
"type": "AddRecordTrigger",
|
||||
"title": "新增订单时触发",
|
||||
"next": "step_check_amount",
|
||||
"data": {
|
||||
"table_name": "订单表",
|
||||
"watched_field_name": "订单金额"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_check_amount",
|
||||
"type": "IfElseBranch",
|
||||
"title": "判断是否为大额订单",
|
||||
"children": {
|
||||
"links": [
|
||||
{ "kind": "if_true", "to": "step_notify_manager", "label": "high", "desc": "金额>=10000" },
|
||||
{ "kind": "if_false", "to": "step_auto_approve", "label": "normal", "desc": "金额<10000" }
|
||||
]
|
||||
},
|
||||
"next": "step_log",
|
||||
"data": {
|
||||
"condition": {
|
||||
"conjunction": "or",
|
||||
"conditions": [
|
||||
{
|
||||
"conjunction": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"left_value": { "value_type": "ref", "value": "$.step_trigger.fldAmount" },
|
||||
"operator": "isGreaterEqual",
|
||||
"right_value": [{ "value_type": "number", "value": 10000 }]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_notify_manager",
|
||||
"type": "LarkMessageAction",
|
||||
"title": "通知主管审批大额订单",
|
||||
"next": "step_log",
|
||||
"data": {
|
||||
"receiver": [{ "value_type": "user", "value": {"id": "ou_manager", "name": "主管"} }],
|
||||
"send_to_everyone": false,
|
||||
"title": [{ "value_type": "text", "value": "大额订单待审批" }],
|
||||
"content": [
|
||||
{ "value_type": "text", "value": "有大额订单 ¥" },
|
||||
{ "value_type": "ref", "value": "$.step_trigger.fldAmount" },
|
||||
{ "value_type": "text", "value": " 需要您审批" }
|
||||
],
|
||||
"btn_list": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_auto_approve",
|
||||
"type": "SetRecordAction",
|
||||
"title": "自动标记小额订单为已审核",
|
||||
"next": "step_log",
|
||||
"data": {
|
||||
"table_name": "订单表",
|
||||
"ref_info": { "step_id": "step_trigger" },
|
||||
"field_values": [
|
||||
{
|
||||
"field_name": "审批状态",
|
||||
"value": [{ "value_type": "option", "value": { "name": "已自动审核" } }]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_log",
|
||||
"type": "GenerateAiTextAction",
|
||||
"title": "生成订单处理日志",
|
||||
"next": null,
|
||||
"data": {
|
||||
"prompt": [
|
||||
{ "value_type": "text", "value": "请生成订单处理日志,金额:" },
|
||||
{ "value_type": "ref", "value": "$.step_trigger.fldAmount" }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**关键点**:
|
||||
- `IfElseBranch.children.links` 必须包含 `if_true` 和 `if_false` 两个分支
|
||||
- `next` 指向两个分支汇合后的步骤(可选,为 null 则分支结束)
|
||||
- `condition` 使用 OrGroup 结构,支持 `(A and B) or (C and D)` 的复杂条件
|
||||
- 分支内可以用 `ref_info` 引用触发记录,用 `filter_info` 批量筛选记录
|
||||
|
||||
---
|
||||
|
||||
### 示例 4: 多路分支(SwitchBranch)
|
||||
|
||||
**场景**: 根据订单优先级(P0/P1/P2)执行不同的处理流程。
|
||||
|
||||
```json
|
||||
{
|
||||
"client_token": "1704067204",
|
||||
"title": "按优先级分类处理订单",
|
||||
"steps": [
|
||||
{
|
||||
"id": "step_trigger",
|
||||
"type": "AddRecordTrigger",
|
||||
"title": "新增订单时触发",
|
||||
"next": "step_classify",
|
||||
"data": {
|
||||
"table_name": "订单表",
|
||||
"watched_field_name": "优先级"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_classify",
|
||||
"type": "SwitchBranch",
|
||||
"title": "按优先级分类",
|
||||
"children": {
|
||||
"links": [
|
||||
{ "kind": "case", "to": "step_p0_handler", "label": "p0", "desc": "P0-紧急" },
|
||||
{ "kind": "case", "to": "step_p1_handler", "label": "p1", "desc": "P1-高优先级" },
|
||||
{ "kind": "case", "to": "step_p2_handler", "label": "p2", "desc": "P2-普通" },
|
||||
{ "kind": "case", "to": "step_other_handler", "label": "other", "desc": "其他" }
|
||||
]
|
||||
},
|
||||
"next": null,
|
||||
"data": {
|
||||
"mode": "exclusive",
|
||||
"no_match_action": "classifyToOther",
|
||||
"child_branch_list": [
|
||||
{
|
||||
"name": "P0-紧急",
|
||||
"condition": {
|
||||
"conjunction": "or",
|
||||
"conditions": [
|
||||
{
|
||||
"conjunction": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"left_value": { "value_type": "ref", "value": "$.step_trigger.fldPriority" },
|
||||
"operator": "is",
|
||||
"right_value": [{ "value_type": "option", "value": { "name": "P0" } }]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "P1-高优先级",
|
||||
"condition": {
|
||||
"conjunction": "or",
|
||||
"conditions": [
|
||||
{
|
||||
"conjunction": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"left_value": { "value_type": "ref", "value": "$.step_trigger.fldPriority" },
|
||||
"operator": "is",
|
||||
"right_value": [{ "value_type": "option", "value": { "name": "P1" } }]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "P2-普通",
|
||||
"condition": {
|
||||
"conjunction": "or",
|
||||
"conditions": [
|
||||
{
|
||||
"conjunction": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"left_value": { "value_type": "ref", "value": "$.step_trigger.fldPriority" },
|
||||
"operator": "is",
|
||||
"right_value": [{ "value_type": "option", "value": { "name": "P2" } }]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_p0_handler",
|
||||
"type": "LarkMessageAction",
|
||||
"title": "P0紧急处理",
|
||||
"next": null,
|
||||
"data": {
|
||||
"receiver": [{ "value_type": "user", "value": {"id": "ou_director", "name": "总监"} }],
|
||||
"send_to_everyone": false,
|
||||
"title": [{ "value_type": "text", "value": "🚨 P0 紧急订单" }],
|
||||
"content": [{ "value_type": "text", "value": "有新的 P0 紧急订单需要立即处理" }],
|
||||
"btn_list": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_p1_handler",
|
||||
"type": "SetRecordAction",
|
||||
"title": "标记高优先级",
|
||||
"next": null,
|
||||
"data": {
|
||||
"table_name": "订单表",
|
||||
"ref_info": { "step_id": "step_trigger" },
|
||||
"field_values": [
|
||||
{ "field_name": "处理状态", "value": [{ "value_type": "text", "value": "高优先级待处理" }] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_p2_handler",
|
||||
"type": "Delay",
|
||||
"title": "普通订单延迟处理",
|
||||
"next": null,
|
||||
"data": { "duration": 60 }
|
||||
},
|
||||
{
|
||||
"id": "step_other_handler",
|
||||
"type": "SetRecordAction",
|
||||
"title": "标记其他订单",
|
||||
"next": null,
|
||||
"data": {
|
||||
"table_name": "订单表",
|
||||
"ref_info": { "step_id": "step_trigger" },
|
||||
"field_values": [
|
||||
{ "field_name": "处理状态", "value": [{ "value_type": "text", "value": "待分类" }] }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**关键点**:
|
||||
- `SwitchBranch` 适合 3 路及以上的分支场景(少于 3 路用 `IfElseBranch` 更简洁)
|
||||
- `children.links` 中 `kind: "case"` 的 `label` 对应 `child_branch_list` 中的条件
|
||||
- `mode: "exclusive"` 表示排他执行(第一个匹配的分支执行后停止)
|
||||
- `no_match_action: "classifyToOther"` 表示无匹配时走最后一个 `case`(兜底分支)
|
||||
|
||||
---
|
||||
|
||||
### 示例 5: 组合场景(定时+查找+循环+分支+消息)
|
||||
|
||||
**场景**: 每天早上 9 点,查找昨天的订单,按金额分级,给不同级别的销售发送不同的通知。
|
||||
|
||||
```json
|
||||
{
|
||||
"client_token": "1704067205",
|
||||
"title": "每日订单分级通知",
|
||||
"steps": [
|
||||
{
|
||||
"id": "step_timer",
|
||||
"type": "TimerTrigger",
|
||||
"title": "每天早上9点触发",
|
||||
"next": "step_find_orders",
|
||||
"data": {
|
||||
"rule": "DAILY",
|
||||
"start_time": "2025-01-01 09:00",
|
||||
"is_never_end": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_find_orders",
|
||||
"type": "FindRecordAction",
|
||||
"title": "查找昨天所有订单",
|
||||
"next": "step_loop",
|
||||
"data": {
|
||||
"table_name": "订单表",
|
||||
"field_names": ["订单号", "客户名称", "金额", "销售负责人"],
|
||||
"should_proceed_when_no_results": false,
|
||||
"filter_info": {
|
||||
"conjunction": "and",
|
||||
"conditions": [
|
||||
{ "field_name": "创建时间", "operator": "isGreaterEqual", "value": [{ "value_type": "date", "value": "yesterday" }] }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_loop",
|
||||
"type": "Loop",
|
||||
"title": "遍历每个订单",
|
||||
"children": {
|
||||
"links": [
|
||||
{ "kind": "loop_start", "to": "step_classify" }
|
||||
]
|
||||
},
|
||||
"next": "step_summary",
|
||||
"data": {
|
||||
"loop_mode": "continue",
|
||||
"max_loop_times": 500,
|
||||
"data": [{ "value_type": "ref", "value": "$.step_find_orders.fieldRecords" }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_classify",
|
||||
"type": "SwitchBranch",
|
||||
"title": "按金额分类",
|
||||
"children": {
|
||||
"links": [
|
||||
{ "kind": "case", "to": "step_vip_notify", "label": "vip", "desc": "VIP >= 10万" },
|
||||
{ "kind": "case", "to": "step_normal_notify", "label": "normal", "desc": "普通 < 10万" }
|
||||
]
|
||||
},
|
||||
"next": null,
|
||||
"data": {
|
||||
"mode": "exclusive",
|
||||
"no_match_action": "fail",
|
||||
"child_branch_list": [
|
||||
{
|
||||
"name": "VIP订单",
|
||||
"condition": {
|
||||
"conjunction": "or",
|
||||
"conditions": [
|
||||
{
|
||||
"conjunction": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"left_value": { "value_type": "ref", "value": "$.step_loop.item.fldAmount" },
|
||||
"operator": "isGreaterEqual",
|
||||
"right_value": [{ "value_type": "number", "value": 100000 }]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "普通订单",
|
||||
"condition": {
|
||||
"conjunction": "or",
|
||||
"conditions": [
|
||||
{
|
||||
"conjunction": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"left_value": { "value_type": "ref", "value": "$.step_loop.item.fldAmount" },
|
||||
"operator": "isLess",
|
||||
"right_value": [{ "value_type": "number", "value": 100000 }]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_vip_notify",
|
||||
"type": "LarkMessageAction",
|
||||
"title": "VIP订单通知",
|
||||
"next": null,
|
||||
"data": {
|
||||
"receiver": [{ "value_type": "ref", "value": "$.step_loop.item.fldSales" }],
|
||||
"send_to_everyone": false,
|
||||
"title": [{ "value_type": "text", "value": "🌟 VIP大额订单" }],
|
||||
"content": [
|
||||
{ "value_type": "text", "value": "恭喜!您有一笔 VIP 订单 ¥" },
|
||||
{ "value_type": "ref", "value": "$.step_loop.item.fldAmount" },
|
||||
{ "value_type": "text", "value": ",客户:" },
|
||||
{ "value_type": "ref", "value": "$.step_loop.item.fldCustomer" }
|
||||
],
|
||||
"btn_list": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_normal_notify",
|
||||
"type": "LarkMessageAction",
|
||||
"title": "普通订单通知",
|
||||
"next": null,
|
||||
"data": {
|
||||
"receiver": [{ "value_type": "ref", "value": "$.step_loop.item.fldSales" }],
|
||||
"send_to_everyone": false,
|
||||
"title": [{ "value_type": "text", "value": "新订单通知" }],
|
||||
"content": [
|
||||
{ "value_type": "text", "value": "您有一笔新订单 ¥" },
|
||||
{ "value_type": "ref", "value": "$.step_loop.item.fldAmount" }
|
||||
],
|
||||
"btn_list": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "step_summary",
|
||||
"type": "GenerateAiTextAction",
|
||||
"title": "生成日报",
|
||||
"next": null,
|
||||
"data": {
|
||||
"prompt": [
|
||||
{ "value_type": "text", "value": "请生成昨日订单处理日报" }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 构造技巧
|
||||
|
||||
### Loop 构造要点
|
||||
|
||||
1. **数据源**: `Loop.data` 必须传入 `ref` 类型,通常是 `FindRecordAction` 的 `fieldRecords`
|
||||
2. **循环体**: `children.links` 必须包含 `kind: "loop_start"` 指向循环体入口
|
||||
3. **引用**: 循环体内用 `$.{loopStepId}.item.{fieldId}` 引用当前元素
|
||||
4. **索引**: 用 `$.{loopStepId}.index` 获取当前索引(从 0 开始)
|
||||
|
||||
### 分支构造要点
|
||||
|
||||
1. **IfElseBranch**:
|
||||
- 适合二元判断(是/否、大于/小于)
|
||||
- `children.links` 必须包含 `if_true` 和 `if_false`
|
||||
- 可以用 `next` 指向汇合点
|
||||
|
||||
2. **SwitchBranch**:
|
||||
- 适合多路分类(3路及以上)
|
||||
- `label` 对应 `child_branch_list` 中的条件顺序
|
||||
- 建议加一个兜底分支(其他)
|
||||
|
||||
### 字段值构造
|
||||
|
||||
| 字段类型 | value_type | 示例 |
|
||||
|---------|------------|------|
|
||||
| 文本 | `text` | `{"value_type": "text", "value": "张三"}` |
|
||||
| 数字 | `number` | `{"value_type": "number", "value": 100}` |
|
||||
| 单选 | `option` | `{"value_type": "option", "value": {"name": "已完成"}}` |
|
||||
| 人员 | `user` | `{"value_type": "user", "value": {"id": "ou_xxxx"}}` |
|
||||
| 引用 | `ref` | `{"value_type": "ref", "value": "$.step_1.fldxxx"}` |
|
||||
|
||||
---
|
||||
|
||||
## 常见错误避免
|
||||
|
||||
### Top 10 高频错误
|
||||
|
||||
| # | 错误信息 | 原因 | 解决方案 |
|
||||
|---|---------|------|---------|
|
||||
| 1 | `path "xxx" does not exist in the output path tree` | ref 引用路径错误或 stepId 不存在 | 检查 stepId 是否在 steps 数组中;使用 fieldId 而非字段名;确保路径以 `$.` 开头 |
|
||||
| 2 | `recordInfo.conditions must be non-empty` | `condition_list` 为空数组 `[]` | 改用 `null` 或省略该字段 |
|
||||
| 3 | `At least one of filter info and ref info is required` | SetRecordAction/FindRecordAction 缺少定位条件 | 必须提供 `filter_info` 或 `ref_info` 之一 |
|
||||
| 4 | `client token is empty` | 缺少 `client_token` | 每次请求传入唯一值(时间戳或随机字符串) |
|
||||
| 5 | `valueType 'text' not allowed for fieldType '3'` | select 类型字段值格式错误 | 改用 `option` 类型 |
|
||||
| 6 | `Undefined Step Type` | 使用了不支持的 StepType | 使用 `AddRecordTrigger` 而非 `CreateRecordTrigger` |
|
||||
| 7 | `prompt references an unknown reference from step` | 引用的 stepId 不存在 | 确保引用的 step 在同一 workflow 的 steps 数组中 |
|
||||
| 8 | `[2200] Internal Error` | 1. steps[].id 重复 2. next/children.links 引用了不存在的 step | 确保所有 step id 唯一;检查引用关系 |
|
||||
| 9 | 工作流结构不完整 | Branch/Loop 节点缺少 `children` | 仅 Branch(IfElseBranch/SwitchBranch)和 Loop 节点需要 `children`,Trigger/Action 节点无需设置 |
|
||||
| 10 | 嵌套分支过于复杂 | 多层 IfElseBranch 嵌套 | 3+ 路分支用 SwitchBranch 替代嵌套 IfElseBranch |
|
||||
|
||||
### 其他常见错误
|
||||
|
||||
**1. condition_list 为空数组**
|
||||
```json
|
||||
// ❌ 错误
|
||||
{ "condition_list": [] }
|
||||
|
||||
// ✅ 正确
|
||||
{ "condition_list": null }
|
||||
// 或省略该字段
|
||||
```
|
||||
|
||||
**2. filter_info 和 ref_info 同时提供**
|
||||
```json
|
||||
// ❌ 错误
|
||||
{ "filter_info": {...}, "ref_info": {...} }
|
||||
|
||||
// ✅ 正确(二选一)
|
||||
{ "filter_info": {...}, "ref_info": null }
|
||||
{ "filter_info": null, "ref_info": {...} }
|
||||
```
|
||||
|
||||
**3. 使用字段名而非 fieldId**
|
||||
```json
|
||||
// ❌ 错误
|
||||
{ "value": "$.step_1.客户名称" }
|
||||
|
||||
// ✅ 正确
|
||||
{ "value": "$.step_1.fldXXXXXXXX" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 参考
|
||||
|
||||
- [lark-base-workflow-schema.md](lark-base-workflow-schema.md) — 字段定义参考
|
||||
- [lark-base-workflow-create.md](lark-base-workflow-create.md) — 创建命令
|
||||
- [lark-base-workflow-update.md](lark-base-workflow-update.md) — 更新命令
|
||||
@@ -98,6 +98,18 @@ POST /open-apis/base/v3/bases/:base_token/workflows/list
|
||||
}
|
||||
```
|
||||
|
||||
## ⚡ 性能提示
|
||||
### 场景适用性
|
||||
**✅ 需要先 list 的场景**:
|
||||
- 批量操作:启用/停用多个工作流(先 list,再批量 enable/disable)
|
||||
- 查询统计:统计定时触发的工作流数量(先 list,再筛选)
|
||||
- 修改操作:修改指定名称的工作流(先 list ,从列表中找到对应名称工作流的 workflow_id,再 get/update)
|
||||
**❌ 不需要先 list 的场景**:
|
||||
- **创建工作流**:直接调用 `+workflow-create`,不需要先 list
|
||||
- 查看指定工作流详情:如果已知 workflow_id,直接 `+workflow-get`
|
||||
### 缓存策略
|
||||
同一会话中处理多个工作流时,只需调用一次 `+workflow-list` 获取全部结果,然后从中筛选所需的工作流,避免重复查询。
|
||||
|
||||
## 坑点
|
||||
|
||||
- ⚠️ **列表用 POST 不用 GET**:`/workflows/list` 是 POST 接口,`page_token` 放在 Request Body 里而不是 Query 参数,常见误区
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
# Workflow 数据结构参考
|
||||
|
||||
本文档定义 `+workflow-create` / `+workflow-update` 命令 `--json` body 的完整数据结构(V2 协议)。
|
||||
本文档定义 Workflow 的完整数据结构,适用于:
|
||||
- **查询场景**:理解 `+workflow-get` 返回的 `steps` 结构
|
||||
- **创建/修改场景**:构造 `+workflow-create` / `+workflow-update` 的 `--json` body
|
||||
> 💡 **本文档是纯字段参考**。如需**创建/修改**工作流的完整示例,请阅读 [workflow-guide.md](lark-base-workflow-guide.md)。
|
||||
---
|
||||
## 📖 快速导航
|
||||
|
||||
根据你的需求跳转到对应章节:
|
||||
|
||||
| 需求 | 章节 |
|
||||
|------|------|
|
||||
| 了解 Step 基础结构 | [WorkflowStep 基础结构](#workflowstep-基础结构) |
|
||||
| 查询 Trigger 类型及 data 字段 | [Trigger data](#trigger-data-详细结构) |
|
||||
| 查询 Action 类型及 data 字段 | [Action data](#action-data-详细结构) |
|
||||
| 查询 Branch/Loop 结构 | [Branch data](#branch-data-详细结构) / [System data](#system-data-详细结构) |
|
||||
| 查询 ValueInfo/Condition 等公共类型 | [公共类型](#公共类型) |
|
||||
|
||||
---
|
||||
|
||||
@@ -128,6 +143,7 @@
|
||||
|
||||
## Trigger data 详细结构
|
||||
|
||||
|
||||
### AddRecordTrigger
|
||||
|
||||
```json
|
||||
@@ -178,13 +194,13 @@
|
||||
```
|
||||
|
||||
| 字段 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `table_name` | 是 | 监控的数据表名 |
|
||||
| `record_watch_conjunction` | 否 | 记录筛选组合方式:`and` / `or`,默认 `and` |
|
||||
| `record_watch_info` | 否 | 记录级过滤条件(修改前值匹配),为空则监听全部 |
|
||||
| `field_watch_info` | 否 | 字段级监控条件列表,至少一个 |
|
||||
| `trigger_control_list` | 否 | 触发控制,可选值:`pasteUpdate` / `automationBatchUpdate` / `syncUpdate` / `appendImport` |
|
||||
| `condition_list` | 否 | 过滤条件数组,数组中每个元素为 AndCondition 结构,多个 AndCondition 之间为 OR 关系 |
|
||||
|------|----|------|
|
||||
| `table_name` | 是 | 监控的数据表名 |
|
||||
| `record_watch_conjunction` | 否 | 记录筛选组合方式:`and` / `or`,默认 `and` |
|
||||
| `record_watch_info` | 否 | 记录级过滤条件(修改前值匹配),为空则监听全部 |
|
||||
| `field_watch_info` | 是 | 字段级监控条件列表,至少一个 |
|
||||
| `trigger_control_list` | 否 | 触发控制,可选值:`pasteUpdate` / `automationBatchUpdate` / `syncUpdate` / `appendImport` |
|
||||
| `condition_list` | 否 | 过滤条件数组,数组中每个元素为 AndCondition 结构,多个 AndCondition 之间为 OR 关系 |
|
||||
|
||||
`FieldWatchItem`:
|
||||
|
||||
@@ -245,7 +261,7 @@
|
||||
```json
|
||||
{
|
||||
"receive_scene": "group",
|
||||
"receiver": [{ "value_type": "group", "value": "测试群" }],
|
||||
"receiver": [{ "value_type": "group", "value": {"id": "oc_xxxx", "name": "测试群"} }],
|
||||
"scope": "all",
|
||||
"filter": {
|
||||
"conjunction": "and",
|
||||
@@ -349,12 +365,12 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"receiver": [{ "value_type": "user", "value": "ou_xxxx" }],
|
||||
"receiver": [{ "value_type": "user", "value": {"id": "ou_xxxx"} }],
|
||||
"send_to_everyone": false,
|
||||
"title": [{ "value_type": "text", "value": "新订单通知" }],
|
||||
"content": [
|
||||
{ "value_type": "text", "value": "客户 " },
|
||||
{ "value_type": "ref", "value": "$.trigger_1.fieldIdxxx" },
|
||||
{ "value_type": "ref", "value": "$.trigger_1.fldCustomerName" },
|
||||
{ "value_type": "text", "value": " 创建了新订单" }
|
||||
],
|
||||
"btn_list": [
|
||||
@@ -435,6 +451,8 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "exclusive",
|
||||
"no_match_action": "classifyToOther",
|
||||
"child_branch_list": [
|
||||
{
|
||||
"name": "高优先级",
|
||||
@@ -460,6 +478,10 @@
|
||||
|
||||
| 字段 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `mode` | 否 | 分支模式。`exclusive`:排他模式,仅执行一个满足条件的子分支;`parallel`:并行模式,执行所有满足条件的子分支。默认 `exclusive` |
|
||||
| `no_match_action` | 否 | `mode=exclusive` 时使用,无匹配时的处理策略。`classifyToOther`:归类到其他分支;`fail`:报错终止。默认 `classifyToOther` |
|
||||
| `fail_mode` | 否 | `mode=parallel` 时使用,部分分支出错时策略。`partialSuccess`:部分成功即继续;`fail`:任一失败即终止。默认 `partialSuccess` |
|
||||
| `match_mode` | 否 | `mode=parallel` 时使用,所有分支不满足时策略。`noneMatchSkip`:跳过继续;`noneMatchFail`:报错终止。默认 `noneMatchSkip` |
|
||||
| `child_branch_list` | 是 | BranchItem[],1-10 个条件分支 |
|
||||
|
||||
`BranchItem`:
|
||||
@@ -480,7 +502,7 @@
|
||||
{
|
||||
"loop_mode": "continue",
|
||||
"max_loop_times": 100,
|
||||
"data": [{ "value_type": "ref", "value": "$.find_record_stepIdxxx.records" }]
|
||||
"data": [{ "value_type": "ref", "value": "$.find_record_stepIdxxx.fieldRecords" }]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -593,18 +615,18 @@ $.{stepId}.{pathId}.{childPathId}.{grandChildPathId}
|
||||
|
||||
##### FindRecordAction(查找记录)
|
||||
|
||||
| pathId | 说明 | 引用示例 |
|
||||
|--------|------|----------|
|
||||
| `fieldRecords` | 所有找到的记录的引用(可用于 Loop 遍历) | 不支持引用 |
|
||||
| `firstfieldsRecord` | 第一条匹配记录 | `$.{stepId}.firstfieldsRecord` |
|
||||
| `firstfieldsRecord.{fieldId}` | 首条记录的字段值,可下钻字段属性 | `$.{stepId}.firstfieldsRecord.{fieldId}` |
|
||||
| `firstfieldsRecord.recordId` | 记录 ID 数组 | `$.{stepId}.firstfieldsRecord.recordId` |
|
||||
| `fields` | 查找到的所有记录某列值 | 不支持引用 |
|
||||
| `fields.{fieldId}` | 用户选择的字段 | `$.{stepId}.fields.{fieldId}` |
|
||||
| `fields.{fieldId}.fieldId` | 用户选择的字段id数组 | `$.{stepId}.fields.{fieldId}.fieldId` |
|
||||
| `fields.{fieldId}.fieldName` | 用户选择的字段名数组 | `$.{stepId}.fields.{fieldId}.fieldName` |
|
||||
| `fields.recordId` | 记录 ID 数组 | `$.{stepId}.fields.recordId` |
|
||||
| `recordNum` | 找到记录总数 | `$.{stepId}.recordNum` |
|
||||
| pathId | 说明 | 引用示例|
|
||||
|--------|------|-------|
|
||||
| `fieldRecords` | 所有找到的记录的引用(可用于 Loop 遍历) | `$.{stepId}.fieldRecords`|
|
||||
| `firstfieldsRecord` | 第一条匹配记录 | `$.{stepId}.firstfieldsRecord`|
|
||||
| `firstfieldsRecord.{fieldId}` | 首条记录的字段值,可下钻字段属性 | `$.{stepId}.firstfieldsRecord.{fieldId}`|
|
||||
| `firstfieldsRecord.recordId` | 记录 ID 数组 | `$.{stepId}.firstfieldsRecord.recordId`|
|
||||
| `fields` | 查找到的所有记录某列值 | 不支持引用|
|
||||
| `fields.{fieldId}` | 用户选择的字段 | `$.{stepId}.fields.{fieldId}`|
|
||||
| `fields.{fieldId}.fieldId` | 用户选择的字段id数组 | `$.{stepId}.fields.{fieldId}.fieldId`|
|
||||
| `fields.{fieldId}.fieldName` | 用户选择的字段名数组 | `$.{stepId}.fields.{fieldId}.fieldName`|
|
||||
| `fields.recordId` | 记录 ID 数组 | `$.{stepId}.fields.recordId`|
|
||||
| `recordNum` | 找到记录总数 | `$.{stepId}.recordNum`|
|
||||
|
||||
##### AddRecordAction(新增记录)
|
||||
|
||||
|
||||
@@ -4,22 +4,23 @@
|
||||
|
||||
全量替换 Base 中一个已有工作流的定义(`title` 和/或 `steps`)。使用 PUT 语义,传入的内容会完整覆盖原有定义。
|
||||
|
||||
> 如果只想修改标题,用 `+workflow-patch`(PATCH 接口,仅支持 `title` 字段)更合适。
|
||||
## ⚠️ 执行前必读
|
||||
|
||||
更新工作流前请按顺序完成:
|
||||
|
||||
1. **先读本文档**,了解 `--json` 参数格式和 PUT 全量覆盖的语义
|
||||
2. **阅读 [workflow-guide.md](lark-base-workflow-guide.md)**,获取 Loop、IfElseBranch、SwitchBranch 等**完整示例**(与创建场景共用相同的步骤结构)
|
||||
3. **参考 [workflow-schema.md](lark-base-workflow-schema.md)**,查询具体字段定义
|
||||
4. **按需调用 `+workflow-list`** 获取工作流 ID(`wkf` 开头)
|
||||
5. **如需基于现有工作流修改**,先调用 `+workflow-get` 导出当前定义,在此基础上修改
|
||||
|
||||
## 推荐命令
|
||||
|
||||
```bash
|
||||
# 从文件读取(推荐,工作流 JSON 通常较大)
|
||||
lark-cli base +workflow-update \
|
||||
--base-token BascXxxxxx \
|
||||
--workflow-id wkfxxxxxx \
|
||||
--json @workflow.json
|
||||
|
||||
# 内联 JSON(仅修改标题,steps 置空)
|
||||
lark-cli base +workflow-update \
|
||||
--base-token BascXxxxxx \
|
||||
--workflow-id wkfxxxxxx \
|
||||
--json '{"title":"新标题"}'
|
||||
--workflow-id wkfosaYTS1V6rhjF \
|
||||
--json '{"title":"新标题","steps":[{"id":"trigger_1","type":"AddRecordTrigger","title":"监控新订单","next":"action_1","data":{"table_name":"订单表","watched_field_name":"订单号"}},{"id":"action_1","type":"LarkMessageAction","title":"发送通知","next":null,"data":{"receiver":[{"value_type":"user","value":{"id":"ou_xxxx"}}],"send_to_everyone":false,"title":[{"value_type":"text","value":"新订单提醒"}],"content":[{"value_type":"text","value":"收到新订单"}],"btn_list":[]}}]}'
|
||||
```
|
||||
|
||||
## 参数
|
||||
@@ -28,7 +29,7 @@ lark-cli base +workflow-update \
|
||||
|------|------|------|
|
||||
| `--base-token <token>` | 是 | 多维表格 Base Token(`Basc` 开头) |
|
||||
| `--workflow-id <id>` | 是 | 工作流 ID(`wkf` 开头),可从 `+workflow-list` 获取 |
|
||||
| `--json <body>` | 是 | 工作流 body JSON,包含 `title` 和/或 `steps`;支持 `@path/to/file.json` 从文件读取 |
|
||||
| `--json <body>` | 是 | 工作流 body JSON,包含 `title` 和/或 `steps`|
|
||||
|
||||
## 如何从链接中提取参数
|
||||
|
||||
@@ -90,12 +91,12 @@ PUT /open-apis/base/v3/bases/:base_token/workflows/:workflow_id
|
||||
"title": "发送通知",
|
||||
"next": null,
|
||||
"data": {
|
||||
"receiver": [{ "value_type": "user", "value": "ou_xxxx" }],
|
||||
"receiver": [{ "value_type": "user", "value": {"id": "ou_xxxx"} }],
|
||||
"send_to_everyone": false,
|
||||
"title": [{ "value_type": "text", "value": "新订单提醒" }],
|
||||
"content": [
|
||||
{ "value_type": "text", "value": "收到新订单,客户:" },
|
||||
{ "value_type": "ref", "value": { "path": "$.trigger_1.客户名称" } }
|
||||
{ "value_type": "ref", "value": "$.trigger_1.fldCustomerName" }
|
||||
],
|
||||
"btn_list": []
|
||||
}
|
||||
@@ -104,6 +105,8 @@ PUT /open-apis/base/v3/bases/:base_token/workflows/:workflow_id
|
||||
}
|
||||
```
|
||||
|
||||
> **注意**:Trigger 和 Action 节点不应设置 `children` 字段,只有 Branch(如 IfElseBranch、SwitchBranch)和 System(如 Loop)节点才需要 `children` 来描述分支或循环结构。
|
||||
|
||||
## API 出参详情
|
||||
|
||||
**Response `data` 字段:**
|
||||
@@ -125,7 +128,7 @@ PUT /open-apis/base/v3/bases/:base_token/workflows/:workflow_id
|
||||
{
|
||||
"ok": true,
|
||||
"data": {
|
||||
"workflow_id": "wkfxxxxxx",
|
||||
"workflow_id": "wkfosaYTS1V6rhjF",
|
||||
"title": "新订单自动通知(更新版)",
|
||||
"status": "disabled",
|
||||
"steps": [...],
|
||||
@@ -144,8 +147,7 @@ PUT /open-apis/base/v3/bases/:base_token/workflows/:workflow_id
|
||||
|
||||
1. 确认 `--base-token` 和 `--workflow-id`(建议先用 `+workflow-list` 查出 ID)
|
||||
2. 确认 `--json` 的完整内容 — PUT 会全量覆盖,漏传 `steps` 会清空所有步骤
|
||||
3. 对于复杂工作流,建议先将 JSON 写入文件,用 `@file.json` 传入
|
||||
4. 执行命令,报告返回的 `workflow_id` 和 `update_time`
|
||||
3. 执行命令,报告返回的 `workflow_id` 和 `update_time`
|
||||
|
||||
## 坑点
|
||||
|
||||
@@ -153,12 +155,11 @@ PUT /open-apis/base/v3/bases/:base_token/workflows/:workflow_id
|
||||
- ⚠️ **workflow_id 前缀**:以 `wkf` 开头,从 URL 的 `?table=wkf...` 提取;和 table_id(`tbl` 开头)混淆会导致 `[2200] Internal Error`
|
||||
- ⚠️ **steps 中 id 字段必须唯一**:每个步骤的 `id` 在同一工作流内必须唯一;`next` 和 `children.links[].to` 引用的 ID 必须在 steps 数组中存在
|
||||
- ⚠️ **更新不影响 enabled 状态**:`+workflow-update` 不会改变工作流的 `enabled/disabled` 状态;需要另外调用 `+workflow-enable` / `+workflow-disable`
|
||||
- ⚠️ **scope 待确认**:内部文档未列出权限名称,代码中使用 `base:workflow:write`,如遇 `[230013] permission denied` 需核对实际 scope
|
||||
- ⚠️ **@file 支持**:`--json @workflow.json` 会读取文件内容,复杂 workflow 强烈建议用文件
|
||||
|
||||
## 参考
|
||||
|
||||
- [lark-base-workflow-schema.md](lark-base-workflow-schema.md) — 完整 Workflow 数据结构
|
||||
- [lark-base-workflow-schema.md](lark-base-workflow-schema.md) — Workflow 数据结构参考
|
||||
- [lark-base-workflow-guide.md](lark-base-workflow-guide.md) — **完整示例、构造技巧、常见错误**
|
||||
- [lark-base-workflow-create](lark-base-workflow-create.md) — 创建工作流
|
||||
- [lark-base-workflow-enable](lark-base-workflow-enable.md) — 启用工作流
|
||||
- [lark-base-workflow-list](lark-base-workflow-list.md) — 列出全部工作流
|
||||
|
||||
Reference in New Issue
Block a user