Webhooks
対応プラン: Professional、Business
Formspreeでは、フォームに新しい送信があるたびにトリガーされるWebhookを設定できます。Webhookは、サーバーレス関数、カスタムサーバーコード、またはその他のサードパーティサービスと組み合わせて使用し、フォームの送信に対するカスタム処理を行うことができます。
サーバーレス関数は、フォーム送信を処理する軽量な方法を提供します。フォームの送信を処理するためだけにフルのウェブサーバーを作成する代わりに、単一のサーバーレス関数を作成してサーバーレスプラットフォームにデプロイできます。Cloudflare Workers、AWS Lambda、Google Cloud Functionsなど、関数のホスティングプラットフォームはいくつかあります。以下の例ではCloudflare Workersを使用します。これは寛大な無料枠とコードからデプロイ済みエンドポイントまでの迅速なパスを提供します。
WebhookプラグインをするときPlug機能を有効にすると、WebhookのタイプとしてシンプルWebhook、ビルドフック、RESTフックのいずれかを選択するよう求められます。
シンプルWebhook
これは通常のWebhookです。特別な質問をすることなく、指定されたURLにPOSTリクエストとしてペイロードを送信します。
ビルドフック
Netlifyなどのサードパーティサービスで新しいビルドをトリガーするために使用できるフックです。これは基本的に空のボディを持つWebhookです。
RESTフック
必要な場合に備えて、RESTフックプロトコルに準拠したWebhookも送信しています。これは一部のサービスでサポートされており、Webhookの作成時にハンドシェイクが行われます。
RESTフックのハンドシェイク処理
RESTフックプロトコルを選択すると、Formspreeがwebhookリクエストの送信を開始する前に、X-Hook-Secretヘッダーを含む確認リクエストを送信します。RESTフックのハンドシェイクに関するセキュリティの詳細については、RESTフックのドキュメントをご覧ください。
以下はCloudflare WorkerでRESTフックのハンドシェイクを処理する例です。独自のウェブサーバーで実装する場合も同じ概念が適用されます。
export default {
async fetch(request) {
const url = new URL(request.url);
if (url.pathname !== '/hook') {
return new Response(url.pathname + '\n');
}
const hookSecret = request.headers.get('x-hook-secret');
if (hookSecret) {
// Step 1: Confirm the subscription. This request includes an
// X-Hook-Secret header, and we echo it back to complete the
// handshake.
return new Response(null, {
headers: { 'x-hook-secret': hookSecret },
});
}
// Step 2: Receive webhook requests — do something with the payload!
const payload = await request.json();
console.log('Received webhook!', payload);
return new Response(null, { status: 200 });
},
};
上記のStep 1では、WorkerがRESTフックの初期ハンドシェイクに対して、リクエストのx-hook-secretヘッダーをそのままレスポンスに返します。ボディは空です。
Step 2はカスタム機能を実装する部分です。Cloudflare WorkersはV8アイソレート上で動作し、標準のfetch APIとKV、R2、D1、キューのバインディングを備えています。送信データの保存、別のサービスへの転送、下流のアクションのトリガーなどがここから行えます。デプロイとバインディングの詳細についてはCloudflare Workersのドキュメントをご覧ください。
Webhookのペイロード
Webhookは新しい送信を受け取るたびに送信されます。
ビルドフック(ボディが空)を除いて、Webhookのペイロードは以下の構造を持ちます:
{
"form": "",
"keys": ["keys", "in", "the", "order", "they", "were", "submitted"],
"submission": {
"_date": "2029-12-31T00:00:00",
"field": "value",
"other-fields": "other value"
}
}