Google Sheets 更新行状态

Google Sheets 更新行状态:通过 webhook 接收事件 ID 和状态,校验输入,查找 Google Sheets 中已有的行,并写入该行的状态单元格。找不到 ID 时走单独的响应分支,不执行写入。此模板不使用 AI 模型。

状态:已于 2026年10月9日 在 AI Flowi Workflow 1.9.2 上完成生产环境测试(34 个案例全部通过)

作者:Ai Flowi · 发布于 。更新于 2026年10月9日。生产环境测试日期:2026年10月9日 (MYT)。

任务

接收通过身份验证的 HTTP POST 请求,其中包含 {event_id,status}。在已有行中查找与 event_id 完全一致的值,匹配时区分大小写。实测结果为:写入状态后返回 HTTP 200 和 {"status":"updated"};查找不到行时返回 HTTP 404 和 {"status":"not-found"}。未找到行的分支不包含写入组件。

适用对象

适合在电子表格中保存事件或任务记录,并需要由发送方将已有记录标记为排队中、进行中或已完成的团队。状态由发送方提供。此工作流接受自由填写的状态文本,不推断状态,也不强制执行业务状态转换规则。

输入示例

{"event_id":"demo-event-001","status":"complete"}

两个字段都必须是字符串,长度为 1–100 个 Unicode 码点,且至少包含一个非空白字符。空白字符会保留。ID 区分大小写:001 与 1 不同。请求中的额外字段会在校验时丢弃。

设置

  1. 使用填有模拟数据的私有测试电子表格,以及已获授权的 Google 连接。
  2. 创建工作表标签页 YOUR_TAB。将 A1 设为 event_id、B1 设为 status,并将 C1 设为 note 用于测试。发送更新前先填入记录。正常使用时,ID 应为纯文本,文本单元格应有值,且 ID 应唯一。
  3. 将 Universal Webhook 设为 POST,身份验证方式设为 Platform API Key,响应模式设为 From Flow。发送方的密钥应保密。
  4. 配置 Search Row:Key Column 设为 event_id,Header Row 设为 1,启用 Case Sensitive Key Match,Sheet Name 设为 YOUR_TAB。将 Update Range 配置为 RAW,并禁用 Include Object Headers。
  5. 按下表连接节点。让 JSON Operations 已选择的操作字段和 JQ 字段保持可见。将 Combine 节点的 JSON 输入设为接受列表。处理请求期间,不要移动、排序、插入或删除工作表中的行。
  6. 在私有标签页上重新运行本文记录的测试。每次请求后检查响应和整个工作表,再将工作流用于真实记录。

节点连接与字段映射

此流程图有 13 个节点:Universal Webhook;用于校验的 JSON Operations;用于有效输入的 Verification Router;Search Row;使用 Combine 操作的 JSON Operations;用于评估查找结果的 JSON Operations;用于已找到行的 Verification Router;Data to Message;Update Range;用于成功结果的 JSON Operations;以及分别用于 200、404 和 422 响应的三个 Webhook Response 节点。

源节点.output → 目标节点.input
源节点输出目标节点输入映射
Universal Webhook.request_dataValidation.data读取 .body;输入有效时,仅输出 verified、event_id 和 status。
Validation.data_outputValid router.verification_result使用顶层布尔值 verified。
Valid router.verifiedSearch Row.row_data查找 event_id;此组件不执行写入。
Valid router.verifiedCombine.data保留传入的 status 和 event_id。
Search Row.resultCombine.data将 found、key_value 和 row_number 加入保留的输入。
Combine.data_outputLookup JSON Operations.data要求 found 为布尔值;匹配成功时,准备 row_number 和 values:[[status]]。
Lookup.data_outputFound router.verification_resultverified 表示查找结果;未找到行时携带响应定义。
Found router.verifiedData to Message.data模板:'YOUR_TAB'!B{row_number}。
Data to Message.textUpdate Range.range_name由 Message 提供状态单元格的精确范围。
Found router.verifiedUpdate Range.values使用包含一个状态值的 values 包装对象。
Update Range.resultSuccess JSON Operations.data要求 updatedCells == 1;仅投影出 {status:"updated"}。
Success.data_output200 response.body_dataHTTP 200 application/json。
Found router.rejected404 response.response_definition{status_code:404,body:{status:"not-found"}};不执行写入。
Valid router.rejected422 response.body_data返回校验错误;不执行查找或写入。

Combine 节点接收两个字段名互不相同的 JSON 对象。查找投影在路由前校验匹配行的行号和键值。查找使用 event_id 表头;写入使用状态列 B。如果更改列顺序,也要更新范围模板。Update Range 只更改一个单元格,事件 ID、备注及该范围之外的其他单元格均保持不变。

JSON Operations 设置

校验、查找和成功结果处理均选择 JQ Expression。只有双输入的 Combine 节点选择 Combine。让所选字段保持可见。

相关内容:Google Sheets 定时写入:每天记录状态行。

校验查询

def valid_text: if type == "string" then length >= 1 and length <= 100 and test("\\S") else false end;
.body as $b | if ($b|type) != "object" then
{verified:false,error:"Request body must be a JSON object with event_id and status."}
else [ (if ($b.event_id|valid_text) then empty else "event_id must be non-blank text between 1 and 100 characters" end),
       (if ($b.status|valid_text) then empty else "status must be non-blank text between 1 and 100 characters" end) ] as $errors
| if ($errors|length) > 0 then {verified:false,error:"Validation failed",details:$errors}
else {verified:true,event_id:$b.event_id,status:$b.status} end end

查找查询

if (.found|type) != "boolean" then error("Unexpected search result")
elif .found == false then {verified:false,status_code:404,body:{status:"not-found"}}
elif (.row_number|type) != "number" then error("Invalid matched row")
elif .row_number < 2 or (.row_number|floor) != .row_number or .key_value != .event_id then error("Invalid matched row")
else {verified:true,row_number:.row_number,values:[[.status]]} end

成功结果查询

if .updatedCells == 1 then {status:"updated"} else error("Unexpected update result") end

脱敏的请求与响应示例

这些响应示例与使用模拟数据进行的生产环境测试结果一致。

POST <production-webhook-url>
Content-Type: application/json
x-api-key: <private-platform-api-key>

{"event_id":"demo-event-001","status":"complete"}

Expected: HTTP 200
{"status":"updated"}
{"event_id":"demo-event-absent","status":"complete"}

Expected: HTTP 404; sheet unchanged
{"status":"not-found"}
{"event_id":"demo-event-001"}

Expected: HTTP 422; sheet unchanged
{"verified":false,"error":"Validation failed","details":["status must be non-blank text between 1 and 100 characters"]}

校验与失败处理行为

在生产环境测试案例中,缺失字段、null 值、类型错误、空字符串、仅含空白字符的字符串,以及超过 100 个 Unicode 码点的字符串,都会在查找或写入前返回 422。非对象请求体和格式错误的 JSON 在生产环境测试案例中也返回 422,并附带 {"verified":false,"error":"Request body must be a JSON object with event_id and status."}。平台密钥缺失或无效时返回 403;身份验证响应体的具体内容由平台控制。

只有成功执行 Search Row 且结果为 found:false 时,才会产生 not-found。Google 访问错误会中断工作流,并可能暴露未经处理的平台错误。当前配置中没有组件捕获这些异常。查找结果结构不符合预期,或更新结果并非恰好更新一个单元格时,都会抛出错误,不会声称已完成更新。

测试结果

全部 34 个生产环境 HTTP 测试案例均通过,并在请求后回读整个标签页进行验证。工作表始终保留七行数据。成功更新只更改首个匹配行的状态单元格;查找未命中和输入被拒绝时,所有值保持不变。重复发送相同更新后,值保持不变。已确认删除临时 API 密钥。

生产环境结果 — 2026年10月9日 MYT
案例HTTP 结果对工作表的影响判定
T1 — 有效的已有行200数据行数 7 -> 7。仅更新首个匹配行的状态单元格;其他单元格不变。通过
T2a — 缺少 status422数据行数 7 -> 7。所有值不变;不执行写入。通过
T2b — 缺少 event_id422数据行数 7 -> 7。所有值不变;不执行写入。通过
T3a — status 为数值422数据行数 7 -> 7。所有值不变;不执行写入。通过
T3b — event_id 为数值422数据行数 7 -> 7。所有值不变;不执行写入。通过
T4 — JSON 格式错误422数据行数 7 -> 7。所有值不变;不执行写入。通过
T5 — 缺少 API 密钥403数据行数 7 -> 7。所有值不变;不执行写入。通过
T6 — API 密钥无效403数据行数 7 -> 7。所有值不变;不执行写入。通过
T7 — event_id 不存在404数据行数 7 -> 7。所有值不变;不执行写入。通过
T8a — 重复发送相同更新200数据行数 7 -> 7。重复更新;值不变。通过
T8b — 再次更改状态200数据行数 7 -> 7。仅更新首个匹配行的状态单元格;其他单元格不变。通过
T9a — 大小写不匹配404数据行数 7 -> 7。所有值不变;不执行写入。通过
T9b — 前导空格不匹配404数据行数 7 -> 7。所有值不变;不执行写入。通过
T9c — 带前导零的文本 ID200数据行数 7 -> 7。仅更新首个匹配行的状态单元格;其他单元格不变。通过
T10 — 忽略额外字段200数据行数 7 -> 7。仅更新首个匹配行的状态单元格;其他单元格不变。通过
T11a — status 为 null422数据行数 7 -> 7。所有值不变;不执行写入。通过
T11b — status 为空字符串422数据行数 7 -> 7。所有值不变;不执行写入。通过
T11c — status 仅含空白字符422数据行数 7 -> 7。所有值不变;不执行写入。通过
T11d — event_id 为 null422数据行数 7 -> 7。所有值不变;不执行写入。通过
T11e — event_id 为空字符串422数据行数 7 -> 7。所有值不变;不执行写入。通过
T11f — event_id 仅含空白字符422数据行数 7 -> 7。所有值不变;不执行写入。通过
T12a — status 长度为 100 个字符200数据行数 7 -> 7。仅更新首个匹配行的状态单元格;其他单元格不变。通过
T12b — status 长度为 101 个字符422数据行数 7 -> 7。所有值不变;不执行写入。通过
T12c — 预先填入的 ID 长度为 100 个字符200数据行数 7 -> 7。仅更新首个匹配行的状态单元格;其他单元格不变。通过
T12d — ID 长度为 101 个字符422数据行数 7 -> 7。所有值不变;不执行写入。通过
T13a — 请求体为数组422数据行数 7 -> 7。所有值不变;不执行写入。通过
T13b — 请求体为 null422数据行数 7 -> 7。所有值不变;不执行写入。通过
T13c — 请求体为字符串422数据行数 7 -> 7。所有值不变;不执行写入。通过
T14 — 使用 RAW 写入类似公式的状态文本200数据行数 7 -> 7。仅更新首个匹配行的状态单元格;其他单元格不变。通过
T15 — 保留空白字符200数据行数 7 -> 7。仅更新首个匹配行的状态单元格;其他单元格不变。通过
T16 — 键值重复时只更新首个匹配行200数据行数 7 -> 7。仅更新首个匹配行的状态单元格;其他单元格不变。通过
T17a — 预先填入的 ID 带空白字符200数据行数 7 -> 7。仅更新首个匹配行的状态单元格;其他单元格不变。通过
T17b — 未去除首尾空白导致不匹配404数据行数 7 -> 7。所有值不变;不执行写入。通过
T18 — Unicode 状态长度边界200数据行数 7 -> 7。仅更新首个匹配行的状态单元格;其他单元格不变。通过

测试的平台版本:AI Flowi Workflow 1.9.2。测试日期:2026年10月9日 (MYT)。各分支实测节点运行次数:未测量。导入及重新测试结果:所提供的证据中未执行。

下载

工作流导入文件下载:暂不可用;未测试导入后的副本。只有完成脱敏导出并测试导入后的副本,才能添加公开导入文件。上文已记录节点配置。

必需配置

  • 在两个 Sheets 组件中配置已获授权的 Google 连接和 Spreadsheet ID。
  • 标签页 YOUR_TAB,第 1 行的表头 event_id,以及 B 列中的状态。
  • 预先存在的文本 ID,以及执行期间保持稳定的行布局。
  • 生产环境 webhook URL,以及发送方的 Platform API Key。
  • 双输入 Combine 配置、查找结果路由,以及独立的 200、404 和 422 响应。

测试版本与日期

测试版本:AI Flowi Workflow 1.9.2。测试日期:2026年10月9日 (MYT)。所提供的证据涵盖此生产环境流程图和模拟测试数据,不能据此确认导入后副本的测试结果。

用量与费用假设

套餐:Go 年付方案每月 USD8 起(月付 USD10),Plus 年付方案每月 USD16 起(月付 USD20),Pro 100 年付方案每月 USD80 起(月付 USD100),Pro 200 年付方案每月 USD160 起(月付 USD200),Pro 500 年付方案每月 USD400 起(月付 USD500),每月包含 5,000 至 250,000 个 Flowi Tokens,并支持充值;每次节点运行消耗 1 个 token;不包含第三方 API 和模型使用费用。

此设计不使用 AI 或 LLM 组件,也不使用第三方付费 API。仍需具备 Google 账号和工作表访问权限,并受服务配额限制。以下估算假设每个经过的节点运行一次、路由器只选择一个分支、不重试,也没有回读验证流程。生产环境的实际用量统计尚待确认。

设计估算,非实测费用
分支每次请求的节点数100 次请求1,000 次请求10,000 次请求
更新行111,10011,000110,000
未找到行88008,00080,000
校验拒绝44004,00040,000
进入流程图前身份验证被拒绝预计为 0预计为 0预计为 0预计为 0

每次验证性读取都增加一次节点运行。重复投递会再次执行工作流;即使状态相同,仍会触发写入。失败尝试和重试可能消耗额外的令牌。套餐不包含第三方 API/模型用量。

限制

  • 查找与写入是两次独立调用。在两次调用之间排序、插入或删除行,可能使已保存的行号指向其他行。请保持布局稳定;如果需要并发更改结构,应使用支持事务的数据存储。
  • 查找选择首个匹配行。重复 ID 不会消除;正常使用时应保持 ID 唯一。
  • 并发写入状态可能相互覆盖。没有冲突检测或状态转换策略。
  • 状态列必须保持为 B 列。RAW 将类似公式的状态文本按原文存储,不会将其作为公式执行。
  • Google 错误在工作流中没有脱敏响应。即使响应丢失,写入也可能已成功;对于结果不确定的投递,请先检查工作表再重试。
  • 34 个生产环境测试案例已通过;节点用量统计和脱敏副本导入后的运行仍未经验证。回读只比较值,不比较工作表格式或权限。

后续步骤

在你自己的私有配置上重新运行所有案例,并检查完整的行内容。检查并发行更改及未经处理的 Google 错误。完成导入后副本的测试,再添加脱敏的导入文件下载。参阅 Universal Webhook、Google 连接设置和常见错误。有关 webhook 和 Google 连接设置的背景说明,请参阅通过 Webhook 写入 Google Sheets 的教程。

相关内容:Google Sheets 按邮箱查询:查找匹配行。