![[解説] ContentfulのWebhook機能: コンテンツの変更を外部システムと連携する方法](https://images.ctfassets.net/ct0aopd36mqt/wp-thumbnail-8beecab904b921be1883d37122b4b7de/6478424b580263afa8369e5b5c8c7715/contentful.jpg)
[解説] ContentfulのWebhook機能: コンテンツの変更を外部システムと連携する方法
ヘッドレスCMSのContentfulには、コンテンツの変更を外部システムに通知する「Webhook」機能があります。この機能を活用することで、コンテンツ更新時にウェブサイトの自動再構築やチャットアプリへの通知送信など、様々な自動化が可能になります。
本記事では、ContentfulのWebhook機能について、基本概念から実装例まで解説します。
ContentfulのWebhookとは
Webhookとは、特定のイベントが発生した際に外部のシステムに自動的に通知を送る仕組みです。ContentfulにおけるWebhookは、コンテンツデータが変更された際にHTTPコールバックを使用して外部システムに通知を送信し、それによって様々な処理を自動的にトリガーすることができます。
主な活用シナリオ
ContentfulのWebhookは、以下のようなシナリオで特に役立ちます:
- ウェブサイトの自動再構築:コンテンツが更新されたタイミングで、Webサイトのビルドやデプロイを自動的にトリガー
- 通知の送信:SlackやTeamsなどのチャットアプリに通知
- キャッシュの更新:CDNやキャッシュの自動パージ
- データの同期:他のシステムやデータベースとContentfulのデータを同期
- ワークフローの自動化:コンテンツの公開時に関連するタスクを自動実行
Webhookを活用することで、コンテンツ管理と外部システムの連携が効率化され、手動操作の手間を削減できます。
設定内容の全体像
まずは設定内容の全項目です。
設定内容の詳細
Webhookが送信するリクエストの内容はカスタマイズが可能です。
リクエストメソッドとURL
デフォルトは POST で、GET, PUT, PATCH, DELETEも利用可能です。
同時にWebhookの通知先となるエンドポイントURLを指定します。ContentfulからのイベントデータがこのURLに送信されます。
トリガー
どのようなイベント(コンテンツの作成、更新、公開など)が発生した時にWebhookを起動するかを選択します。コンテンツタイプごとに細かく設定可能です。
save
とauto_save
の違い
Contentfulでは、コンテンツの保存方法によって異なるタイプのWebhookがトリガーされます。
トリガーのタイミング:
auto_save
: コンソールでの編集中の自動保存時、またはApp SDKのsdk.entry.save()
呼び出し時- ※Contentfulのコンソールは5秒ごとに編集中のドキュメントを自動保存します。
save
: Content Management API経由の更新時、またはAppによる更新時
この仕組みにより、下書き中の頻繁な変更ではなく、APIを通じた明示的な保存操作のみに反応するワークフローを構築できます。
フィルター
Webhookをトリガーしたエンティティのプロパティに基づいてフィルタリングすることで、より細かな制御が可能になります。
一般的なフィルタリングの例としては以下があります:
- 環境IDによるフィルタリング:特定の環境(例:
staging
)の変更に対してのみCIサービスを起動 - エンティティIDによるフィルタリング:特定のエントリ、アセット、またはコンテンツタイプIDに対してのみトリガー
- コンテンツタイプIDによるフィルタリング:特定のコンテンツタイプのエントリに対してのみトリガー
フィルターの注意点
フィルターが評価するプロパティがエンティティに存在しない場合、評価結果はfalse
となりWebhookはトリガーされません。
例えば、Entry.publish
とAsset.publish
のトピックに対して特定のコンテンツタイプIDでフィルタリングするWebhookを設定した場合、アセットにはコンテンツタイプが存在しないため、Asset.publish
によってトリガーされるはずのWebhookはすべてフィルターによって抑制されてしまいます。
ヘッダー
リクエストに追加するカスタムHTTPヘッダーを設定できます。認証情報や識別子などを含めることができます。
コンテンツタイプ
リクエストのコンテンツタイプヘッダーを指定します。デフォルトはContentful独自の形式ですが、application/json
など他の形式も選択可能です。
Content-Length
リクエストボディのサイズをContent-Lengthヘッダーに自動的に設定するかどうかを選択します。
ペイロード
Webhookが送信する通知には、イベントに関する詳細情報が含まれています。この情報は「ペイロード」と呼ばれ、JSONオブジェクトの形式で送信されます。
ペイロードの確認方法
Contentfulでは、エンティティのJSONオブジェクトを以下の方法で確認できます:
- コンテンツタイプ:コンテンツタイプエディタで [JSON Preview] を開く
- エントリ:JSON Viewerアプリを使用してエントリのJSONをプレビュー
ペイロードの例
以下は、エントリが公開された際のWebhookペイロードの例です:
{
"sys": {
"type": "Entry",
"id": "blog-post-1",
"space": {
"sys": {
"type": "Link",
"linkType": "Space",
"id": "example-space-id"
}
},
"environment": {
"sys": {
"type": "Link",
"linkType": "Environment",
"id": "master"
}
},
"contentType": {
"sys": {
"type": "Link",
"linkType": "ContentType",
"id": "blogPost"
}
},
"revision": 2,
"createdAt": "2023-01-15T09:30:00Z",
"updatedAt": "2023-01-15T10:45:00Z"
},
"fields": {
"title": {
"en-US": "Getting Started with Contentful"
},
"body": {
"en-US": "This is a sample blog post about Contentful..."
},
"author": {
"en-US": {
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "author-1"
}
}
}
}
}
このようなペイロードを受け取ることで、外部システムはどのコンテンツが変更されたのか、どのような変更が行われたのかを把握し、適切な処理を実行できます。
ペイロードのカスタマイズ
変数などを使って、独自のペイロードも定義できます。
例:
{
"entityId": "{ /payload/sys/id }",
"spaceId": "{ /payload/sys/space/sys/id }",
"parameters": {
"text": "Entity version: { /payload/sys/version }"
}
}
Activity logでWebhookの実行履歴を確認する
Webhookの実行履歴は Activity log で確認できます。Webhookが正しく動作しているか、エラーが発生していないかを簡単に監視できます。
Activity logでは以下の情報を確認できます:
- リクエストとレスポンス、それぞれのHeaderとBody
- Webhookの実行日時
- トリガーとなったイベントの種類
- 送信先URL
- レスポンスステータスコード
- エラーメッセージ(失敗した場合)
Webhook利用にあたって注意すべきポイント
リトライポリシーとべき等性
Webhookの信頼性を確保するためには、リトライポリシーとべき等性の理解が重要です。
デフォルトのリトライポリシー
ContentfulのWebhookは、デフォルトのリトライポリシーを使用しています。このポリシーでは:
- Webhookの配信を試み、429(レート制限)または5xx(サーバーエラー)のレスポンスを受け取った場合
- 約30秒の間隔を空けて、最大2回の追加配信を試みます
- これにより、合計3回の試行が1分間のウィンドウ内で行われます
- その後も失敗する場合は、配信失敗と見なされます
このリトライメカニズムにより、一時的なネットワーク障害やサーバーの過負荷状態でもWebhookの配信確率が向上します。
べき等性(Idempotency)の確保
Contentfulは、各イベントに対してWebhookが正確に1回だけ配信されるよう最善を尽くしていますが、サーバー障害などのまれなケースでは、同じイベントに対して複数回Webhookが送信される可能性があります。
このような重複処理を防ぐため、Webhookコンシューマーを**べき等※**に設定することが推奨されています。
※同じイベントに対して重複したWebhookリクエストを受信しても、作業を正確に1回だけ実行すること
X-Contentful-Idempotency-Key
ヘッダーの活用
べき等性を実現するには、X-Contentful-Idempotency-Key
ヘッダーを活用します。このヘッダーには、Webhookイベントの一意のSHA256ハッシュが含まれており、サーバーに送信されるリクエストの重複を排除するために使用できます。
タイムアウトと非同期処理
Webhookの処理時間は、安定した運用のために重要な要素です。
Webhookのタイムアウト設定
ContentfulのWebhookリクエストは、受信サーバーが最大30秒以内に応答しない場合にタイムアウトします。タイムアウトしたWebhookリクエストは失敗とみなされ、リトライされません。
このタイムアウト制限があるため、Webhookの処理は非同期で行うことが強く推奨 されています。
30秒以上の処理を実装したい場合、Contentful Backend Appなどで独自に実装する必要があります。
IPアドレスによるフィルタリング
Webhookを受信するコンシューマー側では、セキュリティと安定性確保のため、Contentful外からのリクエストを制限することも重要です。
Contentfulは特定のIPアドレス範囲からWebhookリクエストを送信します。これらのIPアドレスをホワイトリスト化することで、不正なリクエストをブロックできます。
まとめ
本記事では、ContentfulのWebhook機能について解説してみました。Webhookを活用することで、コンテンツの変更を外部システムに自動的に通知し、様々な自動化を実現することができます。