Google Sheets JSON 接口:将电子表格用作只读 API

简要回答: 使用经过身份验证的 webhook、Read Range 和 JSON Operations,将 Google Sheets 中获准访问的列作为有数量上限的 JSON 数组返回。生产环境测试记录了一项未通过的信息泄露检查。

状态:已于 2026年10月9日 在 AI Flowi Workflow 1.9.2 上完成生产环境测试(26 个测试用例中有 25 个通过)

作者:Ai Flowi · 发布于 。更新于 2026年10月9日。

任务

Google Sheets JSON 接口接收经过身份验证的 POST 请求,从私有 Google Sheets 电子表格中读取三个获准访问的列,可按条件筛选行,并返回最多包含 100 个对象的 JSON 数组。此模板使用 JSON Operations 和 JQ 构建响应,不含 AI 或 LLM 组件,也不需要第三方 API。

生产环境运行测试了 Read Range、JSON Operations 和 Webhook Response。以下结果记录了 25 个通过的测试用例,以及一项未通过的信息泄露检查。导入副本测试尚无法进行,也暂无可下载的文件。

适用对象

适合向后端应用提供小型内部目录或状态列表的团队。电子表格中应仅包含你打算允许已通过身份验证的调用方读取的数据。选定范围内的全部数据都会读入内存,因此此模板适用于小型电子表格。

输入示例

发送一个空 JSON 对象,即可请求前 100 个非空行:

{}

也可以同时提供两个筛选字段。匹配采用精确匹配,区分大小写,空白字符也会影响匹配结果。

{"filter_field":"status","filter_value":"enabled"}

允许访问的列为 id、label 和 status。两个筛选字段的值都必须是字符串。空的 filter_value 会匹配空单元格。其他请求字段会被拒绝。

设置

  1. 使用可通过现有 Google 连接访问的私有测试电子表格。选定工作表的第一行必须恰好包含三个列标题:id,label,status,顺序也必须一致。使用模拟数据行。
  2. 将 Read Range 的 Spreadsheet ID 和 Range 设置为选定工作表的 A:C 列。私有测试配置使用其自身的工作表名称。公开示例使用 YOUR_TAB。
  3. 将 Universal Webhook 配置为 POST,使用 Platform API Key 身份验证,并采用 From Flow 响应模式。发送方的凭据应保存在其后端。
  4. 将用于合并输入的 JSON Operations 节点配置为 Combine,并使用列表输入。在响应字段投影节点上选择 JQ Expression,并保持查询可见。
  5. 将字段投影结果连接到 Webhook Response 的 Response Definition 输入,使数组直接成为 HTTP 响应体。
  6. 使用下方的 JQ 查询,内容必须完全一致。将 Webhook Response 的默认 Status Code 设置为 200 OK,Content Type 设置为 application/json,Additional Response Headers 设置为空列表。连接的响应定义会提供每次响应的实际状态码和响应体。

节点连接与字段映射

流程图:Universal Webhook 和 Read Range 向 JSON Operations(Combine)提供数据;第二个 JSON Operations 验证合并后的数据并进行字段投影;Webhook Response 根据动态响应定义发送响应。Read Range 是一个独立的根节点,因此即使输入无效,只要通过身份验证,仍可能触发电子表格读取。流程中没有写入电子表格的节点。

四条连接
来源 → 目标输出 → 输入
Universal Webhook → JSON Operations (Combine)request_data → data
Read Range → JSON Operations (Combine)values → data
JSON Operations (Combine) → JSON Operations (JQ)data_output → data
JSON Operations (JQ) → Webhook Responsedata_output → response_definition

Webhook 的 body 包含筛选条件。Read Range 的 values[0] 包含列标题;后续行将 A、B、C 列分别映射到 id、label 和 status。行末缺失的单元格会转换为空字符串。完全空白的行会被省略。先筛选,再限制为最多 100 行,并保留电子表格中的行顺序。响应仅公开这三个字段。

JQ 返回一个包含 body、status_code 和 content_type 的对象。如果将单独的 JQ 数组连接到 Response Body,返回的会是 JSON Operations 包装结构,而非所需的数组。动态响应定义可避免这一包装结构。

JQ 验证与数组响应

def reject($message): {status_code: 422, content_type: "application/json", body: {error: $message}};
.body as $b
| if ($b|type) != "object" then reject("Request body must be a JSON object")
  elif (($b|keys) - ["filter_field","filter_value"] | length) > 0 then reject("Unknown request field")
  elif ($b|has("filter_field")) != ($b|has("filter_value")) then reject("filter_field and filter_value must be supplied together")
  elif ($b|has("filter_field")) and (($b.filter_field|type) != "string" or ($b.filter_value|type) != "string") then reject("Filter fields must be text")
  elif ($b|has("filter_field")) and (["id","label","status"]|index($b.filter_field)) == null then reject("Unknown filter_field")
  elif (.values|type) != "array" then error("Sheet values unavailable")
  elif .values[0] != ["id","label","status"] then {status_code: 502, content_type: "application/json", body: {error: "Invalid sheet headers"}}
  else ([.values[1:][] | select(any(.[]; . != "" and . != null))
     | {id: (.[0] // "" | tostring), label: (.[1] // "" | tostring), status: (.[2] // "" | tostring)}
     | select(if ($b|has("filter_field")) then .[$b.filter_field] == $b.filter_value else true end)] | .[:100]) as $rows
     | {status_code: 200, content_type: "application/json", body: $rows}
  end

脱敏后的请求与响应示例

请求格式如下;请在本地替换尖括号中的值。示例不包含实际端点或凭据。

POST https://workflow.aiflowi.com/api/v1/webhook/<your-flow-id>
Content-Type: application/json
x-api-key: <your-platform-api-key>

{"filter_field":"status","filter_value":"enabled"}

以下是一个匹配的模拟数据行对应的成功响应示例(并非留存的测试响应):

HTTP 200
Content-Type: application/json

[{"id":"row-001","label":"Item 1","status":"enabled"}]

没有匹配结果,或电子表格有效但仅含列标题时:实际观察到 HTTP 200,响应体为 []。

提供 {"filter_field":"status"} 时:实际观察到 HTTP 422,响应体为:

{"error":"filter_field and filter_value must be supplied together"}

验证与失败行为

  • JSON 不是对象或格式错误:实际观察到 422,错误消息为 Request body must be a JSON object。
  • 仅提供一个筛选字段:实际观察到 422。筛选值为数字、null、布尔值、对象或数组时:实际观察到 422,错误消息为 Filter fields must be text。
  • 请求包含未知属性:实际观察到 422,错误消息为 Unknown request field。列名未知或为空:实际观察到 422,错误消息为 Unknown filter_field。
  • Platform API Key 缺失或无效:实际观察到 HTTP 403。未测量流程图节点的用量统计情况。
  • 电子表格列标题不正确:实际观察到 502,响应体为 {"error":"Invalid sheet headers"}。
  • 已知平台限制:T20(无法访问的电子表格)返回了 HTTP 404,原始平台错误包含私有电子表格标识符,因此未通过无泄露检查。AI Flowi Workflow 1.9.2 不支持在流程内设置 Google 异常处理分支。不要向终端用户直接展示端点的原始响应;应通过可信后端返回脱敏后的错误。成功执行 JQ 字段投影并不能对异常响应进行脱敏。

测试结果

生产环境运行共完成 26 次请求:25 个测试用例通过,T20 未通过无泄露检查。全部 26 个用例均通过了状态码、JSON 内容类型和响应体检查;这些检查没有要求对 T20 的错误响应体进行脱敏。每次请求后,选定电子表格中的值均未改变,包括 T20。已确认删除临时 API 密钥。下方返回对象的数量依据与预期响应体的精确比对结果;未保留原始响应体。

生产环境结果 — 2026年10月9日 MYT
测试用例实际 HTTP 状态码结论
T1 有效请求,无筛选(已检查 100 个返回对象)200通过
T2 缺少 filter_value422通过
T2b 缺少 filter_field422通过
T3 筛选字段类型错误422通过
T3-0 filter_value 不是文本422通过
T3-1 filter_value 不是文本422通过
T3-2 filter_value 不是文本422通过
T3b filter_field 不是文本422通过
T4 JSON 格式错误422通过
T5 缺少 API 密钥403通过
T6 API 密钥无效403通过
T7 精确筛选(已检查 52 个返回对象)200通过
T8 无匹配结果(已检查 0 个返回对象)200通过
T9 区分大小写(已检查 0 个返回对象)200通过
T10 未知列422通过
T10b 空列名422通过
T11 请求体不是对象422通过
T12 筛选值为 null422通过
T13 未知请求字段422通过
T14 范围仅含列标题(已检查 0 个返回对象)200通过
T15 先筛选再限制数量;单元格不齐的行(已检查 1 个返回对象)200通过
T16 空文本筛选值(已检查 1 个返回对象)200通过
T17 空白字符影响匹配(已检查 0 个返回对象)200通过
T18 包含引号的 Unicode 单元格(已检查 1 个返回对象)200通过
T19 电子表格列标题无效502通过
T20 无法访问的电子表格404失败 — 无泄露检查未通过;原始平台错误包含私有电子表格标识符

下载

暂无可下载的导入文件。添加下载链接前,请先对导出文件进行脱敏,再导入并重新测试。向终端用户提供响应前,应先在可信后端解决原始错误泄露问题。

所需配置

已获授权的 Google 连接;你的私有 Spreadsheet ID;选定工作表及 A:C 范围;完全一致的 id,label,status 列标题;Read Range;Webhook 的 POST 和 From Flow 设置;以及 Platform API Key 身份验证。只读流程图不会缩减现有 Google 连接的 OAuth 权限。电子表格无需发布到网络。

测试版本与日期

生产环境测试证据记录
已测试的平台版本AI Flowi Workflow 1.9.2
生产环境测试日期2026年10月9日 (MYT)
导入与重新测试所提供的证据中未进行此项测试

流程覆盖范围与用量

Go、Plus、Pro 100、Pro 200 和 Pro 500 均支持已连接的工作流。请根据流程需求比较各套餐包含的 Flowi Tokens 和功能。每次节点运行消耗 1 个 Flowi Token。

预计成功路径和验证拒绝路径各运行五个节点:Webhook、读取、合并、JQ 和响应。列标题验证也使用五个节点。身份验证被拒绝时返回 403;流程图运行零个节点仍只是基于结构的估算,用量统计情况未测量。读取失败可能在部分节点运行后终止,实际用量未知。

规划示例:每次完成的请求运行五个节点
请求数涵盖步骤
100读取获准列、筛选行并返回 JSON。
1,000读取获准列、筛选行并返回 JSON。
10,000读取获准列、筛选行并返回 JSON。

假设没有重试、没有额外分支,且每次请求只读取一次 Google 电子表格范围。一次完成的 26 用例测试运行还会额外执行 27 次独立的单节点回读;读取失败的用量仍未知。不包含模型用量,也不需要使用模型。套餐不包含第三方 API/模型用量。

限制

  • 缓存与速率限制:未知。未规定缓存、TTL、刷新保证或每分钟请求数。
  • 最多返回 100 个匹配对象。不提供分页、总数、排序控制或截断标记。仍会读取整个选定范围。
  • 仅公开三个文本字段。Google 渲染后的值会转换为字符串;这不是具有数据类型定义的数据库 API。
  • 未实现写入、删除、upsert、公开匿名访问、事务隔离或可控的 Google 异常响应。T20 证明了原始 HTTP 404 错误会泄露私有标识符;不要向终端用户直接展示端点的原始响应。
  • 同时进行的手动编辑可能改变结果。快照比对仅覆盖读取时选定列中的值;无法检测两次读取之间的改动或范围外的编辑。

后续步骤

在你自己的模拟数据电子表格上重新运行这些测试用例。在可信后端处理原始平台错误,并在部署前验证经过脱敏的导入副本。缓存、速率限制和运行时节点用量仍未知。配置背景可参阅 Google Sheets 集成和组件目录。Webhook 与 Google 连接的设置背景可参阅 Webhook 到 Google Sheets 教程。