Webhook入力検証で200または422を返す

Webhook入力検証では、Universal Webhook、JSON Operations(JQ)、Verification Router、2つのWebhook Responseノードを使ってJSONイベントを検証します。本番実行では、正規化した入力を返す200レスポンス、または理由を含む422レスポンスが返されました。このテンプレートでは、AIモデル、Google Sheetsノード、サードパーティーの有料APIを使用しません。

ステータス:2026年10月9日にAI Flowi Workflow 1.9.2で本番テスト済み(28件中28件に合格)

執筆:Ai Flowi · 公開日 · 更新日

作業内容

4つの必須テキストフィールドを確認し、前後の空白を除去して、メールアドレスのASCII英字を小文字に変換します。返す入力値はこの4つのフィールドのみです。検証に失敗した場合は、固定の理由を返します。200レスポンスが示すのは検証の成功だけであり、データベースへの書き込みやその他の処理の成功を示すものではありません。

対象者

他の処理に接続する前に、認証付きWebhookの入出力仕様をテストする開発者や自動化の構築担当者向けです。送信側はPlatform API Keyを送信できる必要があります。このテンプレートは、プロバイダーの署名を検証するものではありません。

入力例

{
  "event_id": "  evt-demo-001  ",
  "name": "  Demo Sender  ",
  "email": "  DEMO@EXAMPLE.COM  ",
  "request": "  Validate this event  "
}

設定

  1. AI Flowi Workflowで独立したフローを作成します。Universal Webhook、JSON Operationsノード1つ、Verification Router、Webhook Responseノード2つを追加します。
  2. Universal WebhookをPOSTに、認証をPlatform API Keyに、POST Response ModeをFrom Flowに設定します。保存済みの本文、フォームフィールド、ファイル、レスポンスヘッダーは空にしておきます。
  3. JSON OperationsでJQ Expressionを選択し、以下の検証クエリを貼り付けます。Path Selectionの値はすべて消去します。
  4. 次のセクションに従ってポートを接続します。レスポンスコードを200 OKと422 Unprocessable Entityに設定します。どちらもapplication/jsonを使用し、レスポンスヘッダーとResponse Definitionを空にします。
  5. 自分のフローから本番Webhook URLをコピーします。合成したテストデータをx-api-keyヘッダーとContent-Type: application/jsonを付けて送信します。実行には本番エンドポイントを使用してください。リクエストの取得のみを行うテストエンドポイントでは、グラフの動作を検証できません。

ノードの接続とフィールドのマッピング

5つのノード、4つの接続
接続元出力 → 接続先の入力目的
Universal Webhook → JSON Operationsrequest_data → dataリクエストエンベロープのbodyを検証します。
JSON Operations → Verification Routerdata_output → verification_result最上位の真偽値verifiedに基づいて分岐します。
Verification Router → 200 Webhook Responseverified → body_data検証結果全体を変更せずに返します。
Verification Router → 422 Webhook Responserejected → body_data拒否した値を返さず、固定の理由を返します。
長さは前後の空白を除去した後に確認し、Unicodeコードポイント数で数えます
入力フィールドルール正規化後の出力
body.event_idテキスト、1~100文字data.event_id:前後の空白を除去し、大文字・小文字は保持
body.nameテキスト、1~120文字data.name:前後の空白を除去
body.emailテキスト、1~254文字。基本的なメールアドレス形式data.email:前後の空白を除去し、ASCII英字を小文字に変換
body.requestテキスト、1~2,000文字data.request:前後の空白を除去
検証用のJQ式
def trim: gsub("^\\s+|\\s+$"; "");
def text_ok($v; $max):
  if ($v|type) != "string" then false
  else ($v|trim|length) as $n | ($n > 0 and $n <= $max) end;
.body as $b
| if ($b|type) != "object" then
    {verified: false, error: "Validation failed", reasons: ["body must be a JSON object"]}
  else [
    (if text_ok($b.event_id; 100) then empty else "event_id must be text of 1 to 100 characters after trimming" end),
    (if text_ok($b.name; 120) then empty else "name must be text of 1 to 120 characters after trimming" end),
    (if text_ok($b.email; 254) then
       if ($b.email|trim|test("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$")) then empty else "email must have a basic address format" end
     else "email must be text of 1 to 254 characters after trimming" end),
    (if text_ok($b.request; 2000) then empty else "request must be text of 1 to 2000 characters after trimming" end)
  ] as $reasons
  | if ($reasons|length) > 0 then {verified: false, error: "Validation failed", reasons: $reasons}
    else {verified: true, data: {event_id: ($b.event_id|trim), name: ($b.name|trim),
      email: ($b.email|trim|ascii_downcase), request: ($b.request|trim)}} end
  end

機密情報を除いたリクエストとレスポンスの例

リクエストコマンドの説明用の例です。URLを置き換え、キーは非公開の状態で指定してください。以下の例は意図する入出力仕様を示すものであり、記録されたテストレスポンスではありません。

curl -X POST "https://workflow.aiflowi.com/api/v1/webhook/YOUR_FLOW_ID" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $FLOWI_API_KEY" \
  --data '{"event_id":"evt-demo-001","name":"Demo Sender","email":"demo@example.com","request":"Validate this event"}'

期待されるHTTP 200:

{"verified":true,"data":{"event_id":"evt-demo-001","name":"Demo Sender","email":"demo@example.com","request":"Validate this event"}}

期待されるHTTP 422(emailを省略した場合):

{"verified":false,"error":"Validation failed","reasons":["email must be text of 1 to 254 characters after trimming"]}

検証と失敗時の動作

本文はJSONオブジェクトのみ受け付けます。フィールドが未指定、null、テキスト以外、空、空白のみ、または上限超過の場合は、event_id、name、email、requestの順に理由が返されます。基本的なメールアドレスのチェックでは、@とその後のドットが必要で、空白は許可されません。未知のフィールドは破棄されます。意図するレスポンスには、ヘッダー、生のリクエストデータ、拒否した値は含まれません。

Platform API Keyが未指定または無効の場合は403が返されました。この本番実行では、不正なJSONに対して、本文がオブジェクトでなければならないという検証理由を含む422が返されました。パーサーのバージョンが異なると、グラフ実行前に不正なJSONを400で拒否する場合があります。グラフは、自身の実行前に生成されたレスポンスを上書きできません。

有効なリクエストを繰り返し送信した場合、同じ正規化済みの入力が返される想定です。イベントIDは繰り返しの実行を防ぎません。実行時例外、アカウントのアクセス障害、タイムアウトでは、プラットフォームの別のエラーが返される場合があります。ルーターはこれらを捕捉しません。

テスト結果

2026年10月9日 MYTの本番リクエストでは、全28件に合格しました。各レスポンスは、期待されるJSON本文とJSONのコンテンツタイプに一致しました。情報を伏せる前の記録では、秘密の値、想定外の入力値の返却、内部エラーの漏えいは確認されませんでした。一時的なテスト用認証は削除済みです。この検証フローには永続化ノードがないため、シートの行数は対象外です。

個別に記録した28件。境界値テストのIDにはフィールド名を含みます
テストケース期待されるHTTP実際のHTTP判定
T01 有効な入力200200合格
T02 前後の空白除去とメールアドレスの小文字化200200合格
T03 email未指定422422合格
T04 nameが数値422422合格
T05 不正なJSON422422合格
T06 キー未指定403403合格
T07 無効なキー403403合格
T08 不正なメールアドレス形式422422合格
T09 nameが空白のみ422422合格
T10 event_idがnull422422合格
T11 requestがネストされた値422422合格
T12 全フィールド未指定422422合格
T13 bodyが配列422422合格
T14 bodyがnull422422合格
T15 bodyがスカラー値422422合格
T16 未知のフィールドを破棄200200合格
T17 繰り返し配信200200合格
T18 nameにUnicode文字200200合格
T19 email内の空白を拒否422422合格
T20 空の本文422422合格
T21 event_idが上限値200200合格
T22 event_idが上限超過422422合格
T21 nameが上限値200200合格
T22 nameが上限超過422422合格
T21 emailが上限値200200合格
T22 emailが上限超過422422合格
T21 requestが上限値200200合格
T22 requestが上限超過422422合格

テストしたプラットフォームのバージョン:1.9.2。本番テスト日:2026年10月9日 MYT。実測したノード実行数と課金トークン数:未測定。インポートしたコピーの検証:この検証記録には記載なし。

ダウンロード

このテンプレートには、インポート可能なワークフローのダウンロードは用意されていません。検証記録では本番リクエストの動作を確認できますが、インポート後の再テストは記録されていません。上記の設定手順とJQ式を使用してください。ワークフローファイルを共有する前に、機密情報を除いたエクスポートをインポートし、動作を検証してください。

必要な設定

  • 利用権限と十分なFlowi TokensがあるAI Flowi Workflowアカウント。
  • 自分の本番Webhook URLと、非公開のPlatform API Key。
  • 上記の4つのフィールドと、指定どおりのポート接続。
  • このワークフローには、Google接続、スプレッドシート、シートタブ、AIモデルのキー、サードパーティーAPIの契約は不要です。

テストしたバージョンと日付

AI Flowi Workflow 1.9.2で、2026年10月9日 MYTに本番テスト済みです。テンプレートのドキュメント更新日:2026年10月9日。

使用量と費用の前提

ノードの実行1回につき1 Flowi Tokenを消費します。プラン:Goは年払いで月額USD8から(月払いUSD10)、全5プランでPro 500まで。全プランは料金ページに掲載しています。

設計上、有効な入力の経路とスキーマ検証で拒否される経路では、それぞれUniversal Webhook、JSON Operations、Verification Router、Webhook Responseの1つを実行し、リクエスト1件あたり4回のノード実行となります。保存されるノードは5つですが、実行されるレスポンス分岐は1つのみの想定です。グラフ実行前の認証失敗とパーサーの失敗では、ノード実行数は0回の想定です。これらは設計上の回数であり、課金の実測値ではありません。実際に確認された不正なJSONへのレスポンスは、本文がオブジェクトではない場合の422拒否経路を使用したため、この設計では4回の実行として数えます。この28件のテストでは、ルーティングされた26件のリクエスト × 4 = 推定104 Flowi Tokensです。認証で拒否された2件は、ノード実行数0回と仮定しています。

全リクエストがグラフを経由し、再試行や追加処理がない場合
月間リクエスト数設計上のノード実行数 / Flowi TokensPlusの月間10,000トークンとの比較
100400枠内
1,0004,000枠内
10,00040,000Plusの月間付与枠を30,000 Flowi Tokens超過。追加購入はPlusが3回でUSD90(サブスクリプション料金は別)。Pro 100の50,000トークンなら枠内です

ルーティングされる再試行1回ごとに、設計上のノード実行がさらに4回増えます。モデルやサードパーティーAPIの呼び出しは設定されていません。サードパーティーのAPI・モデル使用料はプランに含まれません。枠を超えた場合の単価や総費用は仮定していません。

制限事項

  • 不正なJSONに422を返すケースを含め、本番の全28件に合格しました。インポートの検証とノードの課金は記録されていません。パーサーの動作はバージョンによって異なる場合があります。
  • メールアドレスのチェックは基本的な形式確認です。そのメールアドレスの所有、配信可否、メール規格への完全な準拠を確認するものではありません。
  • 書き込み、永続的な受領記録、重複排除、プロバイダーの署名検証、業務固有の認可は行いません。
  • 前後の空白除去はJQの正規表現における空白の定義に従います。長さはコードポイント数で数え、バイト数や見た目の文字単位である書記素クラスター数では数えません。
  • フィールドの上限は、受信するHTTP本文のサイズを制限しません。リクエストサイズ、レート制限、保持期間は別途設定してください。プラットフォームは、取得したリクエストや実行ログを保持する場合があります。テストには合成データを使用し、機密性の高い値を送る前に保持方針を確認してください。

次の手順

自分で設定したフローでこれらのケースを再実行し、機密情報を除いたエクスポートをインポートした後に検証してください。イベントの入出力仕様に合わせてフィールドのルールを調整し、本番の送信元を接続する前にレスポンスを確認します。

関連情報:コンポーネントカタログ、Universal Webhook、Webhook Response、別途テスト済みのWebhookからGoogle Sheetsへ送信するチュートリアル。

設定したバージョンのノード実行数、再試行、外部APIの使用量と併せて、AI Flowi Workflowの料金を確認してください。