Google Sheetsのステータス更新:既存行を更新する
Google Sheetsのステータス更新では、WebhookでイベントIDとステータスを受け取り、入力を検証して既存の行を検索し、ステータスセルに書き込みます。IDが見つからない場合は、書き込みを行わず、別の応答経路に進みます。このテンプレートはAIモデルを使用しません。
検証状況:2026年10月9日にAI Flowi Workflow 1.9.2の本番環境でテスト済み(34件中34件合格)
執筆:Ai Flowi · 公開日 。更新日 2026年10月9日。本番環境でのテスト日: 2026年10月9日 (MYT)。
タスク
{event_id,status}を含む、認証済みのHTTP POSTを受け付けます。既存の行から、大文字と小文字を区別してevent_idの完全一致を検索します。テストでは、ステータスの書き込み後にHTTP 200と{"status":"updated"}が返され、行が見つからない場合はHTTP 404と{"status":"not-found"}が返されました。行が見つからない場合の分岐には、書き込みコンポーネントがありません。
対象となるチーム
イベントやジョブの記録をスプレッドシートで管理し、送信側から既存の記録を待機中、進行中、完了などに更新する必要があるチーム向けです。ステータスは送信側が指定します。このワークフローは任意のステータス文字列を受け付けます。ステータスを推測したり、業務上の状態遷移のルールを強制したりすることはありません。
入力例
{"event_id":"demo-event-001","status":"complete"}
両方のフィールドは、Unicodeコードポイント数が1~100で、空白以外の文字を少なくとも1文字含む文字列である必要があります。空白は保持されます。IDは大文字と小文字を区別します。001と1は異なるIDです。余分なリクエストフィールドは検証時に破棄されます。
設定
- 架空のテストデータを入れた非公開のスプレッドシートと、認可済みのGoogle接続を使用します。
- タブ
YOUR_TABを作成します。テスト用に、A1をevent_id、B1をstatus、C1をnoteに設定します。更新を送信する前に、記録を登録しておきます。通常の運用では、IDをプレーンテキストにし、テキストセルに値を入力し、IDを一意にします。 - Universal WebhookのメソッドをPOST、認証方式をPlatform API Key、応答モードをFrom Flowに設定します。送信側のキーは非公開にしてください。
- Search Rowで、Key Columnを
event_id、Header Rowを1、Sheet NameをYOUR_TABに設定し、Case Sensitive Key Matchを有効にします。Update RangeをRAWに設定し、Include Object Headersを無効にします。 - 以下のノードを接続します。JSON Operationsで選択した操作とJQフィールドは表示したままにします。CombineノードのJSON入力を、リストを受け付けるように設定します。リクエストの処理中は、シートの行を移動、並べ替え、挿入、削除しないでください。
- 非公開のタブで、記載されているテストを再実行します。実際の記録にワークフローを使用する前に、各リクエストの後で応答とシート全体を確認してください。
ノードの接続とフィールドの対応
このグラフには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用の3個のWebhook Responseノードです。
| 接続元の出力 | 接続先の入力 | 対応関係 |
|---|---|---|
Universal Webhook.request_data | Validation.data | .bodyを読み取り、有効な入力の場合はverified、event_id、statusのみを出力します。 |
Validation.data_output | Valid router.verification_result | 最上位のverifiedの真偽値を使用します。 |
Valid router.verified | Search Row.row_data | event_idを検索します。このコンポーネントは書き込みを行いません。 |
Valid router.verified | Combine.data | 受信したstatusとevent_idを保持します。 |
Search Row.result | Combine.data | 保持した入力にfound、key_value、row_numberを追加します。 |
Combine.data_output | Lookup JSON Operations.data | foundが真偽値であることを確認します。一致した場合はrow_numberとvalues:[[status]]を用意します。 |
Lookup.data_output | Found router.verification_result | verifiedは検索結果を示します。行が見つからない場合は応答定義を含めます。 |
Found router.verified | Data to Message.data | テンプレート:'YOUR_TAB'!B{row_number}。 |
Data to Message.text | Update Range.range_name | Messageでステータスセルの正確な範囲を指定します。 |
Found router.verified | Update Range.values | 1個のステータス値を含むvaluesラッパーを使用します。 |
Update Range.result | Success JSON Operations.data | updatedCells == 1であることを確認し、{status:"updated"}のみを出力します。 |
Success.data_output | 200 response.body_data | HTTP 200 application/json. |
Found router.rejected | 404 response.response_definition | {status_code:404,body:{status:"not-found"}}。書き込みは行いません。 |
Valid router.rejected | 422 response.body_data | 検証エラーを返します。検索も書き込みも行いません。 |
Combineノードは、フィールド名が重複しない2個のJSONオブジェクトを受け取ります。検索結果の整形処理では、振り分ける前に一致した行の行番号とキーを検証します。検索にはevent_idヘッダーを使用し、書き込みにはステータス列Bを使用します。列の順序を変更する場合は、範囲テンプレートも更新してください。Update Rangeは1個のセルを変更し、イベントID、メモ、その他の範囲外のセルは変更しません。
JSON Operationsの設定
入力検証、検索結果の評価、成功判定ではJQ Expressionを選択します。Combineは、2入力の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、型の不一致、空文字列、空白のみの文字列、Unicodeコードポイント数が100を超える文字列に対して、検索や書き込みの前に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へのアクセスエラーが発生するとワークフローは中断され、プラットフォームの未加工のエラーが表示される可能性があります。設定されているコンポーネントには、これらの例外を捕捉するものがありません。検索結果が想定外の形式の場合や、更新されたセル数が1以外の場合は、更新成功とはせずにエラーを発生させます。
テスト結果
本番環境のHTTPテスト34件は、タブ全体を再読み取りして確認した結果、すべて合格しました。シートのデータ行数はテストを通して7行のままでした。更新成功時は、最初に一致した行のステータスセルだけが変更されました。検索で一致がなかった場合と入力が拒否された場合は、すべての値が変わりませんでした。同一の更新を繰り返した場合も、値は変わりませんでした。一時的なAPIキーが削除されたことも確認しました。
| ケース | HTTPの結果 | シートへの影響 | 判定 |
|---|---|---|---|
| T1 — 有効な既存行 | 200 | データ行数は7 -> 7。最初に一致した行のステータスセルだけを更新し、他のセルは変更なし。 | 合格 |
| T2a — statusの欠落 | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T2b — event_idの欠落 | 422 | データ行数は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 — 先頭にゼロがある文字列ID | 200 | データ行数は7 -> 7。最初に一致した行のステータスセルだけを更新し、他のセルは変更なし。 | 合格 |
| T10 — 余分なフィールドを無視 | 200 | データ行数は7 -> 7。最初に一致した行のステータスセルだけを更新し、他のセルは変更なし。 | 合格 |
| T11a — nullのstatus | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T11b — 空文字列のstatus | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T11c — 空白のみのstatus | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T11d — nullのevent_id | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T11e — 空文字列のevent_id | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T11f — 空白のみのevent_id | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T12a — 100文字のstatus | 200 | データ行数は7 -> 7。最初に一致した行のステータスセルだけを更新し、他のセルは変更なし。 | 合格 |
| T12b — 101文字のstatus | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T12c — 事前登録した100文字のID | 200 | データ行数は7 -> 7。最初に一致した行のステータスセルだけを更新し、他のセルは変更なし。 | 合格 |
| T12d — 101文字のID | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T13a — 配列の本文 | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T13b — nullの本文 | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T13c — 文字列の本文 | 422 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T14 — RAWによる数式のようなstatusの保存 | 200 | データ行数は7 -> 7。最初に一致した行のステータスセルだけを更新し、他のセルは変更なし。 | 合格 |
| T15 — 空白の保持 | 200 | データ行数は7 -> 7。最初に一致した行のステータスセルだけを更新し、他のセルは変更なし。 | 合格 |
| T16 — キーが重複する場合は最初の一致のみ更新 | 200 | データ行数は7 -> 7。最初に一致した行のステータスセルだけを更新し、他のセルは変更なし。 | 合格 |
| T17a — 空白を含む事前登録済みID | 200 | データ行数は7 -> 7。最初に一致した行のステータスセルだけを更新し、他のセルは変更なし。 | 合格 |
| T17b — 空白を除去しないことによる不一致 | 404 | データ行数は7 -> 7。すべての値に変更なし。書き込みなし。 | 合格 |
| T18 — Unicodeのstatusの境界値 | 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を用意します。
- 2入力の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回につき1トークン。サードパーティのAPIとモデルの利用料金は含まれません。
この設計はAIやLLMのコンポーネントも、サードパーティの有料APIも使用しません。Googleアカウントとシートへのアクセス権が必要で、サービスの利用上限も適用されます。以下の概算は、通過する各ノードを1回実行し、ルーターの分岐を1つ選択し、再試行と再読み取りによる検証フローを行わない前提です。本番環境での消費量の計測は未完了です。
| 経路 | リクエスト1件あたりのノード数 | 100件のリクエスト | 1,000件のリクエスト | 10,000件のリクエスト |
|---|---|---|---|---|
| 行を更新 | 11 | 1,100 | 11,000 | 110,000 |
| 行が見つからない場合 | 8 | 800 | 8,000 | 80,000 |
| 入力検証で拒否 | 4 | 400 | 4,000 | 40,000 |
| グラフの実行前に認証で拒否 | 0の見込み | 0の見込み | 0の見込み | 0の見込み |
検証のための読み取り1回につき、ノード実行が1回増えます。同じリクエストが再送されるとワークフローは再び実行され、ステータスが同一でも書き込みが行われます。失敗した実行や再試行で、追加のトークンを消費する場合があります。サードパーティのAPIやモデルの利用料はプランに含まれません。
制約
- 検索と書き込みは別々の呼び出しです。その間に並べ替え、行の挿入、削除が行われると、保存した行番号が別の行を指す可能性があります。行の配置を固定してください。同時に構造を変更する必要がある場合は、トランザクションに対応したデータストアを使用してください。
- 検索は最初に一致した行を選択します。重複するIDはそのまま残るため、通常の運用ではIDを一意にしてください。
- ステータスを同時に書き込むと、互いに上書きされる可能性があります。競合の検出やステータス遷移のポリシーはありません。
- ステータス列はB列のままにする必要があります。RAWは数式のようなステータス文字列を文字列のまま保存し、数式として実行しません。
- Google側で障害が発生した場合、フロー内では機密情報を除去した応答を返しません。応答が失われても書き込み自体は成功している可能性があるため、処理結果が不明なリクエストを再送する前にシートを確認してください。
- 本番環境のテスト34件は合格しましたが、ノード実行に伴う使用量の計測と、機密情報を除去したコピーをインポートして実行するテストは未検証です。再読み取りでは値を比較し、シートの書式や権限は比較しません。
次のステップ
ご自身で用意した非公開の設定を使って全ケースを再実行し、行の内容全体を確認してください。同時に行が変更される場合や、Googleの未加工のエラーが発生する場合も確認してください。インポートしたコピーをテストした後に、機密情報を除去したインポート用ダウンロードを追加してください。Universal Webhook、Google接続の設定、よくあるエラーを参照してください。WebhookとGoogle接続の設定については、WebhookからGoogle Sheetsへデータを送るチュートリアルを参照してください。