Webhooks
Webhookを使用すると、新しい連絡先の作成、予約の確定、メッセージの受信など、重要なイベントが発生した際に、Your AI Connectorから他のビジネスツールへ自動的に通知を送ることができます。手動で更新を確認する必要はなく、何かが発生した瞬間に接続先のシステムへ即座に通知が届きます。
Webhooksとは?
Webhookは、2つのアプリ間で行われる自動テキストメッセージのようなものだと考えてください。Your AI Connectorで何らかのイベント(新しい連絡先の登録など)が発生すると、プラットフォームは即座に指定した別のシステムへ通知を送信します。通知の送信先となるWebアドレス(「Webhook URL」と呼ばれます)を指定してください。これは通常、CRM、自動化プラットフォーム、または開発者から提供されます。
Webhook ページは Your AI Connector からデータを送信するのみです。 ここで設定する Webhook は、Your AI Connector から他のツールへという一方向の通信となります。新しいリードやその他のデータを取り込む(Web サイトのフォーム、CRM、または GoHighLevel から)には、2 つの選択肢があります。Webhook トリガーを使用した オートメーション を設定すると、フォームやツールから投稿可能な Web アドレスが発行され、そのステップで連絡先の作成やメッセージの送信などを行うことができます。あるいは、API キー を使用して、例えば「連絡先の作成」操作などの API 呼び出し をシステムから直接行うことも可能です。詳細は API アクセス および ファネル を参照してください。
Webhookは一部のプランでのみ利用可能です。 ご利用のプランにWebhookが含まれていない場合、Webhookページは利用できず、イベントも送信されません。以前に保存した設定はアカウントに保持され、Webhookが含まれるプランに変更した時点で送信が再開されます。プランの機能は請求ページで確認できます。どのプランに変更すべきかについては、プロバイダーにお問い合わせください。
注意: Webhookの設定には技術的な構成が必要です。操作に不安がある場合は、このページを開発者に共有するか、Zapier、Make、Pabblyなどの自動化プラットフォームを使用してください。これらを使用すれば、コーディングなしでWebhook URLを取得できます。
一般的な用途は以下の通りです:
- 新しい連絡先をCRMに同期する。
- タグが付与された際に、Zapier、Make、またはPabblyでワークフローをトリガーする。
- 人間による対応が必要になった際に、Slackでチームに通知する。
- 予約が確定した際に、カレンダーシステムを更新する。
- 会話の要約をデータベースに記録する。
Webhookの設定方法
- 左側のサイドバーで、設定(歯車アイコン)をクリックします。
- 設定サイドバーの統合グループの下にあるWebhookをクリックします。
Webhookがまだ設定されていないアカウントでは、ページは次のように表示されます。
- 右上の New webhook をクリックします。ページ内にフォームが開きます:
- 以下を入力します:
- エンドポイントURL — Your AI Connectorがイベント通知を送信するWebアドレス。外部システム(CRM、自動化プラットフォーム、またはカスタムサーバー)から取得します。
- 名前 — 後で判別するためのラベル(例:「Slackアラート」や「CRM同期」など)。自分用の参照ラベルです。
Webhook URLは、パブリックにアクセス可能な
https://アドレスである必要があります。http://アドレス、localhostまたはプライベートネットワークのアドレス、およびプラットフォーム内部のアドレスは、保存時に拒否されます。自分のマシンからテストする場合は、localhostの代わりにパブリックトンネル(webhook.siteやngrokなど)を使用してください。
- イベントの下で、このWebhookで受信したいイベントをクリックします。全24イベントは24のWebhookイベントに記載されています。
- (オプション) 一時的な失敗時に Your AI Connector に再試行させたい場合は、失敗した配信を再試行するをオンにします。失敗した配信の再試行を参照してください。
- Webhookを作成をクリックします。フォームの下のリストに表示され、いつでも行の テスト をクリックして、エンドポイントにサンプルペイロードを送信できます。
権限が必要です。 Webhookの追加、編集、テストには、Integrationsの「編集」権限が必要です(閲覧のみのチームメンバーには、フォームの代わりに読み取り専用の通知が表示されます)。
Webhookの署名を行うには、まずWebhookが保存されている必要があります。既存のWebhookの行を開いて編集すると、編集フォームの下部に署名シークレットパネルが表示されます。作成したばかりの未保存のドラフトには、まだ署名オプションはありません。詳細は以下の署名付きペイロードを参照してください。
すべてのクライアントアカウントに対して1つのWebhookを使用する(代理店向け)
代理店を運営している場合、すべてのクライアントアカウントで同じWebhookを再作成する必要はありません。代理店アカウントのWebhookフォームには、すべてのクライアントアカウントに対しても実行するという追加のトグルがあります。これをオンにすると、このWebhookは代理店配下のすべてのクライアントアカウントで発生したイベントも受信するようになります。1つのエンドポイントで、代理店全体をカバーできます。
動作の仕組み:
userブロックで、イベントがどのクライアントに属しているかを確認できます。 すべての通知には、イベントが発生したアカウントを識別するuserブロックが含まれているため、自動化処理でクライアントごとにルーティングできます。- Webhook自体の設定がどこでも適用されます。 選択したイベント、署名シークレット、および再試行設定は、クライアントアカウントへの配信にも使用されます。
- 重複配信はありません。 クライアントアカウントが同じURLを指す独自のWebhookを持っている場合、そのアカウントのイベントにはそちらが使用されるため、同じイベントが1つのエンドポイントに2回届くことはありません。
- クライアントには表示されません。 このWebhookはクライアントアカウント自身のWebhookページには表示されず、クライアントがオフにすることもできません。管理はあなたが行います。
- 信頼性はクライアントアカウントごとに追跡されます。 エンドポイントでエラーが続く場合、配信に失敗したアカウントに対してのみ自動的にオフになります(Webhookの信頼性を参照)。代理店全体で一度にオフになることはありません。
このトグルは代理店アカウントでのみ表示されます。API経由での設定もサポートされています。Webhooks APIのapply_to_sub_accountsフィールドを参照してください。
利用可能なトリガーイベント
24種類のWebhookイベントは、それぞれ個別に有効または無効にできます。イベントが発生すると、Your AI Connector は関連データを含む通知をWebhook URLに送信します。各イベントの意味とペイロードに含まれる event コードについては、このページの下部にある24のWebhookイベントを参照してください。
知っておくべきこと: タスク作成、タスク更新、タスク完了は完全に選択可能で、正しく保存されます。日次サマリー作成も最近追加されました。そのペイロードの形式については、以下のタスク完了Webhookを参照してください。
タグベースのWebhookトリガー
subscribed_to_tags は、Webhookのイベントをタグでスコープするものではありません。これは、会話の要約通知を生成するタグを絞り込むためのものです。特定のタグが適用されたときにリクエストを受け取るには、エージェントエディターの タグ タブで、そのタグにWebhook URLを設定してください。
Webhookフォーム自体には、新規作成時も編集時もタグピッカーがないため、subscribed_to_tagsはWebhooks APIを通じて読み取りや変更を行うか、サポートに問い合わせる必要があります。
知っておくべきこと:
subscribed_to_tagsリストを持つ既存のWebhookを編集(名前の変更、イベントの変更、再試行の切り替え)しても、そのリストがクリアされることはなくなりました。フォームには送信すべきタグピッカーがないため、このページから保存しても既存のリストはそのまま保持されます。(これは2026年7月21日以前は実際のバグでした。Webhookフォームから保存すると、常に空のタグリストが送信されるため、リストが消去されていました。その日付より前にsubscribed_to_tagsリストが失われたWebhookは、APIを通じて再設定する必要があります。)
タグ付けされた連絡先の要約を生成する
Webhookにsubscribed_to_tagsリストがある場合、サマリーを生成をオンにできます。有効にすると、Your AI Connectorはそれらのタグのいずれかが適用されたときに連絡先の会話サマリーを自動的に生成し、それをWebhookデータに含めます。個別のリクエストなしで完全なコンテキストを取得できます。
Webhookのテスト
- 設定 → 統合 → Webhooks を開きます。
- Webhookの行にある テスト をクリックします。
- 外部システムを確認し、テストデータが受信されたことを確認します。
- データ形式を確認し、システムで正しく解析できることを確かめます。
完全なエンドツーエンドのテストを行うには、設定したイベント(ブロードキャストや接続済みチャネルへの着信メッセージなど)をトリガーするメッセージを送信し、実際のデータでWebhookが実行されることを確認してください。
ヒント: 開発中は webhook.site や RequestBin などのツールを使用して、本番システムに接続する前に生のWebhookデータを確認することをお勧めします。
配信成功の定義
Testをクリックした場合でも、イベントが実際に発生した場合でも、送信される内容は同じです。
- POSTリクエスト(GETは不可)。ボディはJSON形式で、
Content-Type: application/jsonが含まれます。 - 署名付きペイロードに記載されているヘッダー。署名ヘッダーは、署名シークレットを設定した場合にのみ含まれます。
配信が成功したとみなされる条件は以下の通りです。
- エンドポイントが2xxステータス(200、201、204など、すべて有効)で応答すること。
- 30秒以内に応答すること。
意外に思われるかもしれませんが、以下の点にご注意ください。
- レスポンスボディは無視されます。 特定のJSONを返す必要はありません。空の200レスポンスで十分です。
- リダイレクトは失敗とみなされます。 当社ではリダイレクトを追跡しないため、301や302(末尾のスラッシュによるリダイレクトやhttpからhttpsへのリダイレクトを含む)は配信失敗として記録されます。リダイレクト先ではなく、最終的なURLを保存してください。
- クエリ文字列は完全にサポートされています。
https://your-app.com/hook?token=abc123は保存した通りに送信されるため、パスにトークンを含めるのと同様に、クエリ文字列にトークンを含めても機能します。 - URLは
https://であり、公開アクセス可能である必要があります。 Your AI Connector 自体のインフラストラクチャに属するアドレスは拒否されますが、Google Cloud Functions、Cloud Run、App Engine、Firebase Hostingなど、その他の場所にある独自のエンドポイントは問題ありません。 - エンドポイントの前段にあるファイアウォールやボット保護層によって、リクエストがブロックされる可能性があります。 最も一般的なケースはCloudflareです。ゾーンで「Bot Fight Mode」や管理されたチャレンジが有効になっていると、サーバーに到達する代わりに「Just a moment…」というチャレンジページが403エラーで返されます。サーバー間リクエストではブラウザのチャレンジを通過できないため、テストボタンと実際のイベントの両方が同様に失敗します。テストボタンを使用すると、この状況が発生している場合に「Cloudflare is showing a bot challenge to our request(Cloudflareがリクエストに対してボットチャレンジを表示しています)」と通知されます。Cloudflareのセキュリティ/WAFルールで、Webhookパス(または
Webhook-Delivery/1.0ユーザーエージェント)に対するチャレンジをスキップするように設定し、再度テストをクリックしてください。 - ファイアウォールでIP許可リストが必要な場合(Cloudflareの無料プランなど、通常のBot Fight ModeをWAFルールでスキップできず、許可設定されたIPアクセスルールが優先される場合)、当社がサポートいたします。テストボタンからの配信であれライブイベントからの配信であれ、すべての配信は1つの固定IPv4アドレスから送信されます(範囲指定やIPv6、ローテーションはありません)。サポートまでご連絡いただければ、許可リストに登録するアドレスをお伝えします。送信元に関係なくすべてのペイロードを検証できるため、実際の信頼性チェックには署名検証を引き続き使用してください。
- テスト結果には、エンドポイントが回答した内容が正確に表示されます。 テストが失敗した場合、一般的なエラーではなく、実際の理由(エンドポイントが返したHTTPステータス、タイムアウト、またはアドレスに全く到達できなかったこと)が表示されます。また、保存されたWebhookに対するテストは、署名が有効な場合はライブイベントと全く同様に署名付きで送信されます。
n8n、Make、またはZapierの使用(「テストURL」と「本番URL」)
自動化プラットフォームでは通常、2つの異なるWebhookアドレスが提供されますが、これが混乱の原因となることがあります。
- テストURL(n8nでは
/webhook-test/が含まれます)。これは、キャンバスをアクティブに監視しており、かつ Listen for test event(または Test workflow)をクリックした直後にのみデータを受信します。単一のイベントをキャプチャするとリッスンを停止するため、Your AI Connector で テスト を連続してクリックしても、最初の1回しかキャプチャされません(リッスンウィンドウがその瞬間にアクティブな場合のみ)。テストするには、まずn8nで Listen for test event をクリックしてから、Your AI Connector に戻り、テスト を1回クリックしてください。 - 本番URL(n8nでは
/webhook/が含まれ、-testは含まれません)。ライブイベント用に Your AI Connector に貼り付けるのはこちらです。ワークフローが アクティブ に切り替えられた後にのみ機能します。ワークフローがアクティブでない場合、Your AI Connector が正しくデータを送信していても、n8nは「404 / webhook not registered」エラーでリクエストを拒否します。
要約すると、テスト中はテストURLを使用してリッスンを行いますが、Webhookが実際の連絡先で機能し続けるようにするには、本番URL を Your AI Connector に保存し、ワークフローが Active になっていることを確認してください。
Webhookのデータ形式
Webhookが発生すると、Your AI Connectorは構造化データ(JSON)をWebhook URLに送信します。ZapierやMakeのような自動化プラットフォームを使用している場合、データは自動的に解析されます。カスタム統合を構築している場合は、以下に注意してください:
{
"event": "contactCreated",
"contact": { "id": "<contact-id>", "first_name": "Jane", "...": "..." },
"campaign": { "id": "<campaign-id>", "name": "AI Receptionist", "status": "Live" },
"agent": { "id": "<agent-id>", "name": "Front Desk" },
"user": { "id": "<account-id>", "email": "owner@example.com" }
}
| フィールド | 説明 |
|---|---|
event |
通知をトリガーした正確なイベント文字列(例: contactCreated、booked)。これはイベントリストに表示される表示ラベルではありません。各ラベルとそれに対応するコードは24のWebhookイベントに記載されています。 |
contact |
イベントに関連する連絡先、または連絡先に紐付かないイベント(creditsRechargedなど)の場合は null。 |
campaign |
連絡先が属するクラシックキャンペーン、または存在しない場合は null。エージェントが対応する連絡先には null が入ります。 |
agent |
会話を担当するエージェント、または存在しない場合は null。 |
user |
データを所有するアカウントの基本的な識別情報。 |
campaignではなくagentを参照してください。 キャンペーンはAIエージェントとブロードキャストに移行しました(キャンペーンの移行 を参照)。そのため、連絡先はエージェントに紐付けられており、agentによってどのエージェントが会話を担当したかがわかります。campaignフィールドは以前のレシーバーが動作し続けるように送信され続けていますが、通常はnullです。これは、従来のキャンペーンへのリンクを保持している連絡先に対してのみ入力されます。campaignが常に存在すると想定しないでください。
agentブロックは2026年8月15日に導入されました。 これは、会話に関連するイベント(終了したチャット、おやすみモード、再開、アーカイブ解除、AIの一時停止、新規メッセージ、会話の要約、およびタグに設定できるWebhook)においてcampaignと並んで配置され、対応する担当者のidとnameを保持します。担当者が関与していない場合はnullとなります。これは純粋な追加機能であり、すでに受信しているすべてのフィールドに変更はありません。そのため、その日付より前に構築された受信側は、何も更新することなくそのまま動作し続けます。
一部のイベントは、独自のトップレベルブロックを追加します。例えば、予約完了、予約キャンセル、予約変更は appointment ブロックを追加し(予約完了Webhookを参照)、新規メッセージはテキストを含む完全な message ブロックを追加し(新規メッセージWebhookを参照)、配信および既読はメッセージIDとステータスのみを含む短い message ブロックを追加します(配信および既読Webhookを参照)。
Deliveries(配信)と Reads(既読)は、どのメッセージかを示しますが、内容は示しません。 これらにはメッセージの
idとstatusを含むmessageブロックが含まれます。このidは メッセージ送信エンドポイント が返すmessageIdと同じであるため、配信通知や既読通知を送信したメッセージと照合できますが、メッセージ本文は含まれません。Replies(返信)にはmessageブロックは一切含まれません。送信または受信された内容が必要な場合は、それらと併せて New Message(新規メッセージ)をサブスクライブしてください。
レシーバーを作成する前に知っておくべき2つのこと。
timestampフィールドはなく、dataラッパーもありません。すべてのブロックは、上記のようにJSONオブジェクトのトップレベルに配置されます。
24のWebhookイベント
アプリでチェックを入れる表示ラベルと、ペイロードで送信される event コードを含む24のWebhookイベントです。event コードは表示ラベルと一致しない短い文字列であるため、ラベルではなくコードに基づいて受信側の処理を構築してください。
| 表示ラベル(アプリ内) | ペイロード内の event コード |
意味 |
|---|---|---|
| 連絡先作成 | contactCreated |
新しい連絡先がアカウントに追加されました(手動、インポート、またはAPI経由)。 |
| 連絡先一時停止 | contact_paused |
連絡先との会話が一時停止されました(ボットが応答を停止)。 |
| 連絡先再開 | contact_resumed |
一時停止されていた連絡先との会話が再開されました。 |
| 連絡先通知オフ | contact_do_not_disturb_changed |
連絡先の「通知オフ」設定がオンになりました。 |
| 連絡先アーカイブ解除 | contact_unarchived |
アーカイブされていた連絡先から新しいメッセージが届き、アクティブな受信トレイに戻りました。 |
| 新規メッセージ | new_message |
あらゆるチャネルの会話にメッセージが追加されました。連絡先からのメッセージと、AIまたはチームからのメッセージの両方が含まれます。実際のメッセージテキストが含まれる唯一のイベントです(新規メッセージWebhookを参照)。 |
| 返信 | replied |
連絡先がメッセージに返信しました。 |
| 既読 | read |
連絡先がメッセージを既読にしました(既読通知をサポートするチャネルのみ)。既読になったメッセージのIDが含まれます(配信および既読Webhookを参照)。 |
| 配信 | delivered または undelivered |
メッセージが連絡先に正常に配信されました(配信失敗時は undelivered)。メッセージのIDが含まれます(配信および既読Webhookを参照)。 |
| 人間へのアラート | humanAlerted |
AIボットが会話を処理できないと判断し、人間の対応を求めました。 |
| チャット終了 | chat_concluded |
AIボットが会話が終了したと判断しました(予約完了、リードの不適格判定など)。 |
| 予約完了 | booked |
連絡先が予約システムを通じて予約を行いました。 |
| 予約キャンセル | appointment_cancelled |
予約がキャンセルされました(チャット内のAI、アプリ内のユーザー、API、または連携されたGoogleカレンダー経由)。予約完了と同じボディで、appointment.cancelation_reason が含まれます。予約キャンセルおよび変更Webhookを参照してください。 |
| 予約変更 | appointment_rescheduled |
予約が新しい日時に変更されました。予約完了と同じボディに加え、以前の開始・終了時間を含む previous ブロックが追加されます。 |
| クレジット消費 | creditsSpent |
アカウントからクレジットが差し引かれました。 |
| クレジットチャージ | creditsRecharged |
自動チャージまたは手動購入により、アカウントにクレジットが追加されました。 |
| クレジット残高不足 | lowCreditBalance(テスト配信時)、Low Credit Balance(実際の配信時) |
クレジット残高がアラートしきい値(設定しない限り100クレジット)を下回ったという早期警告です。サブアカウントが共通のプールから消費するエージェンシー向けです。連絡先ブロックの代わりに balance、threshold、account_email が含まれ、残高が低い間は最大24時間に1回送信され、残高がしきい値を超えると再有効化されます。 |
| タスク作成 | taskCreated |
タスクが作成されました。 |
| タスク更新 | taskUpdated |
完了ステージに移動せずにタスクが変更されました。 |
| タスク完了 | taskCompleted |
タスクが完了ステージとして設定されたステージに移動しました。 |
| 日次サマリー作成 | dailySummaryCreated |
日次サマリーレポートが生成されました。 |
| チャネル接続 | channelConnected |
まだ送信されません。選択可能ですが、現在は何も出力しません。これに依存した構築は行わないでください。 メッセージングチャネルの接続完了時を想定しています。 |
| 一斉送信開始 | broadcastStarted |
一斉送信が開始されました(ステータスが「送信中」に変更)。開始ごとに1回発生し、一時停止された一斉送信が再開された場合も含まれます。連絡先ブロックの代わりに broadcast ブロック(ID、名前、チャネル、ステータス、前回のステータス、ターゲットリスト(list_id、list_name、is_smart_list)、scheduled_at、total_contacts)が含まれます。 |
| 一斉送信完了 | broadcastCompleted |
一斉送信が完了しました(ステータスが「送信済み」または「失敗」に変更)。同じ broadcast ブロックに加え、completed_at および利用可能な場合は completion_summary(total_sent、permanently_failed、unique_replied、failure_rate、had_errors)が含まれます。これらを使用して、スマート一斉送信リストを外部ツールに接続します。 |
以下の2つのコードは、購読対象ではないためリストには表示されません。contact_tags_updatedは個別のタグに設定されたWebhook URLによって送信され、summary_generatedはWebhookのsubscribed_to_tagsリスト内のタグに対してチャットサマリーが作成されたときに送信されます。
「チャネル接続済み」はまだ送信されません。 イベントリストには表示されますが、現時点では何も発行されません。これに基づいた開発は行わないでください。
タグベースおよびタスクの通知は、それぞれ独自の形式を使用します。Contact Tags Updated および Task Completed を参照してください。
連絡先作成Webhook
連絡先作成イベントが実行されたとき(手動、インポート、またはAPI経由で新しい連絡先が追加されたとき)に送信されます。
イベント名
contactCreated
ペイロード形式
{
"event": "contactCreated",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"human_alert_reason": null,
"is_bot_active": true,
"ad_referral": null,
"ad_attribution": null
},
"campaign": {
"id": "<campaign-id>",
"name": "AI Receptionist",
"status": "Live"
},
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
}
}
| フィールド | 説明 |
|---|---|
event |
このイベントでは常に contactCreated となります。 |
contact.id |
新しい連絡先の一意のIDです。 |
contact.email / contact.phone_number |
連絡先のメールアドレスと電話番号(判明している場合)。チャネルによっては空の場合があります。 |
contact.first_name / contact.last_name |
連絡先の名前(判明している場合)。 |
contact.human_alerted / contact.human_alert_reason |
連絡先が人間の対応を必要とするフラグが立てられているかどうか、およびその理由。 |
contact.is_bot_active |
この連絡先に対してAIボットが現在アクティブかどうか。 |
contact.ad_referral |
連絡先の流入元となったMeta広告(Click-to-WhatsApp、Click-to-Instagram、またはClick-to-Messenger)、または null。詳細は Click-to-WhatsApp広告の属性 を参照してください。 |
contact.ad_attribution |
この連絡先が一致したウェブサイト上の広告クリック、または null。詳細は WhatsAppの広告クリック属性 を参照してください。 |
campaign |
連絡先が作成された従来のキャンペーン、または null(連絡先がエージェントによって処理されるようになった現在の一般的な値)。 |
agent |
連絡先に割り当てられたエージェント、または null。 |
user |
連絡先を所有するアカウントの基本的な識別情報。 |
「テスト」サンプルと実際のイベントは少し異なります。 テストボタンはプレースホルダーデータ(John Doe、サンプルのキャンペーンブロック)を送信します。実際の「連絡先作成」イベントには実際の連絡先の詳細が含まれており、チャネルによっては一部のフィールドが空になる場合があります。
New Message Webhook
このWebhookは、チャネルを問わず、会話にメッセージが追加されるたびに発生します。これは双方向をカバーします。つまり、連絡先から送信されたメッセージと、AIエージェント、チーム、またはブロードキャストから送信されたメッセージの両方が対象です。メッセージ本文を含む唯一のWebhookであるため、会話を外部システムにミラーリングしたい場合に使用してください。
イベント名
new_message
ペイロード形式
{
"event": "new_message",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"human_alert_reason": null,
"is_bot_active": true,
"ad_referral": null,
"ad_attribution": null
},
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
},
"message": {
"id": "<message-id>",
"body": "Hi, are you open on Saturday?",
"direction": "inbound",
"status": "received",
"created_at": "2026-07-30T17:27:06.000Z",
"channel": "whatsapp_web",
"media_url": null,
"media_content_type": null
}
}
| フィールド | 説明 |
|---|---|
event |
このイベントでは常に new_message です。これは送信される正確な文字列であり、「新しいメッセージ」という表示ラベルではないことに注意してください。 |
contact |
メッセージが属する会話の連絡先。連絡先作成 と同じ形式です。 |
agent |
会話を担当するエージェント(id および name)、またはエージェントが関与していない場合は null。 |
user |
会話を所有するアカウントの基本的な識別情報。 |
message.id |
メッセージのユニークID。 |
message.body |
メッセージ本文。添付ファイルがあるメッセージの場合、本文は到着した内容を示す括弧付きの注釈で始まり、その後にキャプションが続きます(例: [THE CONTACT UPLOADED AN IMAGE] Here is my CV, [THE CONTACT UPLOADED A DOCUMENT], [THE CONTACT UPLOADED A VOICE NOTE] - [TRANSCRIPTION: ...])。ボイスメモや動画には文字起こしが含まれます。 |
message.direction |
連絡先からのメッセージは inbound、AIまたはインボックスからチームが送信したメッセージは outbound、ブロードキャスト(従来のキャンペーンを含む)、テンプレート送信、またはAPI経由で送信されたメッセージは outbound-api となります。 |
message.status |
メッセージのライフサイクルにおける現在の状態:受信は received、送信は queued / sent / delivered / read / failed / undelivered です。これはメッセージ作成時点のステータスであるため、送信メッセージは通常 queued または sent としてここに到着し、その後 delivered に到達します。後の遷移が必要な場合は、配信および既読イベントを使用してください。これらはこのブロックと同じ message.id を保持しているため、遷移をこのメッセージと照合できます(配信および既読Webhook を参照)。 |
message.created_at |
メッセージが作成された日時(UTC、ISO 8601形式)。 |
message.channel |
メッセージが通過したチャネル(例: whatsapp, whatsapp_web, sms, instagram, messenger, telegram, email, custom)。 |
message.media_url |
メッセージに添付されたファイル(画像、ボイスメモ、動画、ドキュメント)のダウンロードリンク。ない場合は null。常に存在します。 |
message.media_content_type |
ファイルの種類(例: image/jpeg, audio/ogg, application/pdf)。media_url が null の場合は null となります。 |
このペイロードにはまだ
campaignブロックはありません。 「新しいメッセージ」はcontact,agent,user,messageを送信します。agentブロックは 2026年8月15日 に追加され、どのエージェントが会話を担当しているかを示します。連絡先に関する詳細なコンテキストが必要な場合は、contact.idを使用してAPI経由で検索してください。
添付ファイルは到着後すぐに保存してください。
media_urlリンクは、メッセージが到着してから7日後にすべてのチャネル(WhatsApp Business API、WhatsApp Web、Instagram、Messenger、Telegram、チャットウィジェットなど)で機能しなくなりますが、ファイル自体は保持されます。後で新しいリンクを取得するには、contacts/{contact.id}/messages/{message.id}を指定して メッセージの添付ファイルをダウンロード を呼び出してください。これらのフィールドは 2026年9月13日 に追加されました。
media_urlがnullであるにもかかわらず、本文にファイルが到着したと記載されている場合。 一部の添付ファイルは直接リンクを持たない方法で保存されます。また、共有されたInstagramのリール、投稿、ストーリーのメンションはファイルではなくInstagramへのリンクであるため、これらもnullとして到着します(本文には共有された内容が記載されます)。ファイルを取得するには、メッセージIDを指定して Download a message’s attachment を呼び出し、リンクを取得してください。
インポートされた履歴では、このWebhookはトリガーされません。 WhatsApp Web番号が過去の会話をインポートする場合、それらの古いメッセージは、メッセージごとに「新規メッセージ」通知を発生させることなく保存されます。
内部AIレコードはこのWebhookを発生させません。 プラットフォームは実際のメッセージと並行して、会話内に独自の記録(AIのツール呼び出しや内部的なターン記録)を保持します。これらは送信されません。実際に送受信されたメッセージのみが通知されます。
Deliveries and Reads Webhook
これら2つのイベントは、メッセージが Your AI Connector を離れた後に何が起こったかを報告します。Deliveries(配信)はメッセージが連絡先に到達したとき(または失敗したとき)に発生し、Reads(既読)は既読通知をサポートするチャネルで連絡先がメッセージを開いたときに発生します。
どちらもイベント対象のメッセージIDを含む message ブロックを保持しているため、更新内容を送信した正確なメッセージと照合できます。
イベント名
Deliveries(配信)には delivered と undelivered、Reads(既読)には read が使用されます。
ペイロード形式
{
"event": "delivered",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"ad_referral": null,
"ad_attribution": null
},
"campaign": {
"id": "<campaign-id>",
"name": "AI Receptionist",
"status": "Live"
},
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
},
"message": {
"id": "<message-id>",
"status": "delivered"
}
}
| フィールド | 説明 |
|---|---|
event |
配信の場合は delivered または undelivered、既読の場合は read です。 |
contact |
メッセージの送信先である連絡先。 |
campaign |
連絡先が属する従来のキャンペーン。または null(連絡先がエージェントによって処理されるようになった現在、これが通常の値です)。 |
agent |
会話を担当するエージェント、または null。 |
user |
データを所有するアカウントの基本的な識別情報。 |
message.id |
この更新に関連するメッセージのID。メッセージ送信エンドポイント が messageId として返す値と同じであり、新しいメッセージ 通知が保持する message.id と同じです。 |
message.status |
新しいステータス。event と同じ文字列(delivered, undelivered, read)です。 |
送信したメッセージと更新を照合する方法。 API経由でメッセージを送信したときに返される
messageIdを保存してください。Deliveries(配信)または Reads(既読)通知が届いたら、その保存したIDをペイロード内のmessage.idと照合します。それがそのメッセージに対する配信通知または既読通知です。
ここにメッセージテキストはありません。
messageブロックにはIDとステータスのみが含まれます。本文も必要な場合は New Message をサブスクライブしてください。
messageブロックは、どのメッセージか特定できる場合にのみ存在します。 保存されたメッセージと関連付けられない稀な更新の場合、ブロックは空で送信されるのではなく完全に除外されます。そのため、message.idを読み取る前にmessageが存在することを確認してください。
ステータス変更ごとに1つの通知。 通常、1つの送信メッセージは
delivered通知を生成し、既読通知に対応しているチャネルではその後read通知を生成します。送信に失敗した場合は代わりにundeliveredが生成されます。
Appointment Booked Webhook
連絡先が予約を入れたときに実行されます。AIが会話中に予約した場合、手動で予約した場合、API経由で予約が入った場合のいずれであっても、同じように実行されます。
イベント名
booked
ペイロード形式
{
"event": "booked",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith"
},
"campaign": {
"id": "<campaign-id>",
"name": "AI Receptionist",
"status": "Live"
},
"user": {
"id": "<account-id>",
"email": "owner@example.com"
},
"appointment": {
"appointment_id": "<appointment-id>",
"start_time": "2026-07-20T15:00:00.000Z",
"end_time": "2026-07-20T15:30:00.000Z",
"status": "Confirmed",
"room_name": "Room 1",
"description": "Discovery call",
"summary": "30 min intro",
"google_calendar_event_id": null,
"external_reference": "crm-booking-1042",
"event": {
"id": "<service-id>",
"event_name": "Intro Call",
"slot_duration": 30,
"location": "Zoom",
"meeting_link": "https://...",
"event_type": "online"
}
}
}
| フィールド | 説明 |
|---|---|
event |
このイベントでは常に booked となります。 |
contact |
予約者。チャネルによっては email や phone_number が空になる場合があります。 |
appointment.appointment_id |
予約の一意のID。 |
appointment.start_time / end_time |
予約枠の開始日時と終了日時(UTC、ISO 8601形式)。 |
appointment.status |
予約の現在のステータス。 |
appointment.room_name |
予約が行われた部屋(使用されている場合)。 |
appointment.description / summary |
予約時に取得された自由記述の詳細。 |
appointment.google_calendar_event_id |
同期されたイベントのGoogleカレンダーID。Appointment Booked Webhookでは、カレンダーイベントの作成と通知の送信が同時に行われるため、多くの場合 null となります。必要な場合は、少し時間を置いてから appointment_id で予約を再取得してください。Googleカレンダーが接続されていないアカウントでは、永続的に null となることが予想されます。 |
appointment.external_reference |
API経由で予約を作成した際に使用された、お客様のシステム側のID。または null。 |
appointment.event |
予約されたサービス:名前、枠の長さ、場所、会議リンク、タイプ。 |
このWebhookでは
google_calendar_event_idがnullになることがよくありますが、これは正常です。 Googleカレンダーのイベントはこの通知が送信されるのと同時に作成されるため、通常IDはまだ準備できていません。必要な場合は、少し時間を置いてからappointment_idで予約を再取得してください。アカウントにGoogleカレンダーが接続されていない場合は永久にnullのままとなりますので、いつまでも待機しないようにしてください。
「テスト」ボタンは、架空の値を含むサンプル
appointmentブロックを送信します。 これにより、実際の予約が入る前にデータの形状に合わせた構築が可能になります。
このWebhookが発火しない2つのケース: 外部カレンダーからインポートされた予定、およびFormitable連携を通じて行われた予約。
予約キャンセルおよび変更Webhook
予約キャンセルは予約がキャンセルされたときに発生し、予約変更は新しい開始または終了日時に移動したときに発生します。AIが会話中に処理した場合、アプリで変更した場合、API経由で入った場合、または連携されたGoogleカレンダーで変更された場合でも、どちらも同じように発生します。
イベント名
appointment_cancelled および appointment_rescheduled
ペイロード形式
ボディは予約完了と同じで、変更後の予約内容が含まれます。キャンセル時は appointment.cancelation_reason が追加され、変更時は以前の時間を含むトップレベルの previous ブロックが追加されます:
{
"event": "appointment_rescheduled",
"contact": { "id": "<contact-id>", "email": "jane@example.com", "phone_number": "+15551234567", "first_name": "Jane", "last_name": "Smith" },
"campaign": null,
"agent": { "id": "<agent-id>", "name": "Front desk" },
"user": { "id": "<account-id>", "email": "owner@example.com" },
"appointment": {
"appointment_id": "<appointment-id>",
"start_time": "2026-07-21T09:00:00.000Z",
"end_time": "2026-07-21T09:30:00.000Z",
"status": "Confirmed",
"room_name": "Room 1",
"description": "Discovery call",
"summary": "30 min intro",
"google_calendar_event_id": "<calendar-event-id>",
"external_reference": "crm-booking-1042",
"cancelation_reason": null,
"event": { "id": "<service-id>", "event_name": "Intro Call", "slot_duration": 30 }
},
"previous": {
"start_time": "2026-07-20T15:00:00.000Z",
"end_time": "2026-07-20T15:30:00.000Z"
}
}
| フィールド | 説明 |
|---|---|
event |
appointment_cancelled または appointment_rescheduled。 |
appointment.status |
キャンセル時は Canceled(APIが返す値である l)、変更時は Confirmed。 |
appointment.cancelation_reason |
予約キャンセル時に指定された理由、または null。 |
appointment.start_time / end_time |
変更後のスロット(UTC、ISO 8601形式)。 |
previous.start_time / previous.end_time |
変更時のみ:予約が移動する前のスロット。 |
campaign / agent |
連絡先の現在のキャンペーンとエージェント、または null。 |
1回の変更につき1イベント。 予約のキャンセルは、同じ編集で時間が変更された場合でも「予約キャンセル」のみを送信します。タイトル、メモ、またはルームのみの編集では何も送信されません。同じ予約を2回移動させると、2つの「予約変更」イベントが送信されます。
会話終了Webhook
AIが会話が終了したと判断したとき(予約完了、リードの不適格判定など)に発生します。
イベント名
chat_concluded
ペイロード形式
ペイロードには event、完全な contact、チャットを担当した agent、およびアカウント user が含まれます。また、この会話にいくらのクレジットが消費されたかを示す conversation_cost も含まれるため、n8nやMakeのフローで二度目の呼び出しなしにログを記録できます。
{
"event": "chat_concluded",
"contact": { "id": "abc123", "first_name": "Jane", "channel": "whatsapp" },
"agent": { "id": "agent_1", "name": "Sales Agent" },
"user": { "id": "user_1" },
"conversation_cost": {
"credits": 7.5,
"session_id": "sess_9f2",
"started_at": "2026-09-26T09:14:02.000Z",
"outcome": "contained"
}
}
credits: この会話内で請求されたクレジット(返金分を差し引いたもの)。APIの会話コストレポートと同じ方法でカウントされます。outcome:contained(AIが単独で処理)、handed_off(AIの後にチームメンバーが返信した、またはAIが人間を呼び出した)、またはno_ai。conversation_costは、その時点で数値を算出できない場合は省略されます。オプションとして扱ってください。
コンタクトタグ更新Webhook
連絡先にタグが 適用 され、その連絡先が割り当てられているエージェントにそのタグのWebhook URLが設定されている場合に発生します。
イベント名
contact_tags_updated
トリガー条件
- AIエージェントが割り当てられたコンタクトにタグが適用されている。
- 適用されたタグのうち少なくとも1つに、そのエージェントのエディターのタグタブでWebhook URLが設定されている。
エージェントへの移行前に作成されたクラシックキャンペーンへのリンクを保持しているコンタクトは特殊なケースです。そのキャンペーンのタグにWebhook URLが設定されている場合はそれが使用され、それ以外の場合はエージェントのWebhook URLが使用されます。
異なるWebhook URLを持つ複数のタグが同じ更新で適用された場合、URLごとに1つのリクエストが送信され、それぞれそのURLにマッピングされたタグのみが含まれます。
タグを削除してもリクエストは送信されません。 多くのユーザーは、これらのURLを「デポジットの回収」「スロットの予約」「担当者への通知」といったアクションに向けているため、タグがコンタクトから外れた際にそのアクションが再実行されることを防ぐためです。現在、削除は実行されません。同じURLに送信される適用と同時に削除が発生した場合、削除はremoved_tagsに表示されるため、両方の配列を読み取る自動化ツールであれば全体像を把握できます。ただし、削除のみによってリクエストが引き起こされることは決してありません。(2026年8月12日に変更。それ以前は、削除でもリクエストが送信されていました。)
ペイロード形式
{
"event": "contact_tags_updated",
"contact": {
"id": "<contact-id>",
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"is_bot_active": true,
"ad_referral": {
"ctwa_clid": "ARAbc123...",
"source_id": "120210000000000",
"source_type": "ad",
"source_url": "https://fb.me/xxxx",
"headline": "Get 20% off today",
"body": "Message us now to claim your discount",
"channel": "whatsapp"
},
"ad_attribution": null
},
"added_tags": ["qualified-lead"],
"removed_tags": ["new-lead"],
"agent": {
"id": "<agent-id>",
"name": "Front Desk"
},
"user": {
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
}
}
| フィールド | 説明 |
|---|---|
event |
このWebhookでは常に contact_tags_updated となります。 |
contact.id |
タグが変更された連絡先の一意のIDです。 |
contact.email / contact.phone_number |
連絡先のメールアドレス/電話番号(判明している場合)。 |
contact.first_name / contact.last_name |
連絡先の名前。 |
contact.human_alerted |
連絡先に現在、人間の対応を必要とするフラグが立てられているかどうか。 |
contact.is_bot_active |
この連絡先の会話でAIボットが現在アクティブかどうか。 |
contact.ad_referral |
連絡先がMeta広告(Click-to-WhatsApp、Click-to-Instagram、またはClick-to-Messenger)またはWhatsAppの投稿リファラル経由で到達した場合のみ存在します。それ以外の場合は null となります。詳細は Click-to-WhatsApp広告の属性 を参照してください。 |
contact.ad_attribution |
広告クリックスクリプト によって記録された、ウェブサイトへの広告クリックと連絡先が一致した場合のみ存在します。それ以外の場合は null となります。 |
added_tags |
この更新で適用されたタグ名の配列。空になることはありません。適用がリクエストをトリガーするためです。 |
removed_tags |
同じ更新で削除されたタグ名の配列(存在する場合)。削除のみでは何も送信されません。 |
agent |
連絡先の会話を担当するエージェント(id および name)。エージェントが関与していない場合は null となります。2026年8月15日に追加されました。 |
user |
連絡先を所有するアカウントの基本的な識別情報。 |
タグWebhookのテスト
「タグ」タブのWebhook URLフィールドの横には、テストボタンがあります。このボタンを押すと、サンプルペイロードがそのURLに即座に送信されるため、実際の会話を待たずに自動化ツールがそれを受信できることを確認できます。
このテストでは、上記と同じcontact_tags_updated形式が送信されます。テスト対象のタグがadded_tagsに、空のremoved_tagsが使用され、プレースホルダーの連絡先が使われます。自動化ツールがテストで確認する内容は、本番環境で確認するものと同じです。
知っておくべき2つのこと:
- 先にタグを保存してください。 テストは保存された名前でタグを検索するため、作成したばかりのタグや保存されていない名前の変更はまだテストできません。画面上の名前が保存されたものと一致するまで、ボタンはグレーアウトしたままになります。
- テストの失敗はWebhookのカウントに含まれません。 テストは、Webhookの信頼性で説明されているような、繰り返される失敗による自動オフの対象にはなりません。
テストが失敗した場合、エンドポイントがどのような応答を返したか(例:404や500など)が表示されます。これは通常、誤ったURLや有効になっていないワークフローを特定するのに十分な情報です。
タスク完了Webhook
参考用。 タスクWebhook(データとして)は開発者向けにここに記載されています。タスク作成、タスク更新、タスク完了イベントは、他のイベントと同様にWebhookフォームの標準イベントリストで選択可能です。利用可能なトリガーイベントおよび24のWebhookイベントを参照してください。
このペイロードは、タスクが完了ステージとしてマークされたステージに移行したときに送信されます。完了ステージ以外のステージ間を移動するタスクは、代わりに taskUpdated の形式を送信します。
イベント名
taskCompleted
トリガー条件
- タスクが更新された。
- その
stage値が以前の値と比較して変更された。 - 新しいステージが、アカウントのタスクステージ設定で完了ステージとして構成されている。
ペイロード形式
{
"event": "taskCompleted",
"contact": {
"email": "jane@example.com",
"phone_number": "+15551234567",
"first_name": "Jane",
"last_name": "Smith",
"human_alerted": false,
"human_alert_reason": null
},
"user": {
"email": "owner@example.com",
"first_name": "Alex",
"last_name": "Doe"
},
"message": {
"id": "<task-id>",
"title": "Follow up with Jane",
"description": "Confirm pricing and send proposal",
"type": "follow_up",
"priority": "high",
"stage": "<stage-id>",
"due_date": "2026-01-20T15:00:00Z",
"source": "ai",
"source_detail": "<source-detail>",
"campaign_id": "<campaign-id>",
"linked_human_alert": "<human-alert-id>",
"tags": ["qualified-lead"],
"notes": "Customer requested a callback"
}
}
| フィールド | 説明 |
|---|---|
event |
このWebhookでは常に taskCompleted となります。タスクが完了ステージに入らずに変更された場合、taskUpdated と同じペイロード形式が送信されます。 |
contact |
タスクにリンクされているコンタクト(存在する場合)。リンクされていない場合は null となります。 |
contact.human_alert_reason |
コンタクトが人間による対応が必要とフラグ立てされた理由(該当する場合)。 |
user |
タスクを所有するアカウントの基本的な識別情報。 |
message.id |
タスクの一意のID。 |
message.title / description |
タスクのタイトルと説明。 |
message.type |
タスクの種類(例: follow_up、call、custom)。 |
message.priority |
タスクの優先度(low、medium、high)。 |
message.stage |
タスクが現在存在するステージのID。 |
message.due_date |
タスクの期限(設定されている場合)。 |
message.source |
タスクの作成元: manual、human_alert、ai_tool、api、automation、daily_summary、chat または chat_composer。 |
message.source_detail |
ソースに関する詳細情報。 |
message.campaign_id |
リンクされたクラシックキャンペーンのID、または null。 |
message.linked_human_alert |
リンクされた人間によるアラートのID(存在する場合)。 |
message.tags |
タスクに適用されたタグ。 |
message.notes |
タスクに関する自由形式のメモ。 |
Webhookのオフ(または削除)
すべてのWebhookには、その行にオン/オフのスイッチがあります。オフに切り替えるとイベントの受信は停止しますが、設定した内容(URL、イベント、署名シークレットなど)はすべて保持されます。再度オンに切り替えると、中断したところから再開されます。オフにしていた間に発生したイベントは、後から配信されることはありません。
エンドポイントの再構築中、ノイズの多い統合のデバッグ中、または自動化を一時停止する場合など、一時的に配信を停止したいときに使用してください。
Webhookを削除(行のゴミ箱アイコン)すると、署名シークレットを含めて完全に削除されます。配信を停止したいだけの場合は、代わりにオフに切り替えてください。削除は、エンドポイントを完全に終了する場合に使用します。
これは、Webhookが自動的にオフになることとは異なります。 繰り返し失敗したためにWebhookが無効になった場合(Webhookの信頼性を参照)、上記のトグルをオンにしてもWebhookは復元されません。エンドポイントを修正したら、Webhookを編集してURLを変更して保存する(URLを変更すると自動的に再有効化されます)、またはAPI経由で再有効化エンドポイントを呼び出してください。サポートにお問い合わせいただければ、こちらで再有効化することも可能です。
署名付きペイロード(Webhookが確実に当社から送信されたものであることの検証)
Webhook URLを知っている人は誰でも、偽のリクエストを送信する可能性があります。Webhookに基づいて自動的にアクション(請求の更新、CRMレコードの作成など)を行う場合は、署名を有効にすることで、各リクエストが確実に当社から送信されたものであることを検証できます。
署名はオプションであり、デフォルトではオフになっています。Webhookごとに、そのWebhookの編集ビュー(保存されたWebhookの行を開く)から有効に切り替えます。
署名の有効化
- Webhookを開きます(設定 → 連携 → Webhook → Webhookの行をクリック)。
- 署名シークレットセクションで、生成をクリックします。
- シークレットをコピーし(
whsec_で始まります)、受信システムに保存します。パスワードのように扱ってください。
いつでも同じパネルから、シークレットの表示、コピー、ローテーション、またはオフへの切り替えを行うことができます。
送信される内容
署名が有効になると、Webhookのすべての配信に以下の2つの追加HTTPヘッダーが含まれます:
| ヘッダー | 意味 |
|---|---|
X-Webhook-Signature |
v1=<hex> 形式の署名。 |
X-Webhook-Timestamp |
送信日時(秒単位のUnixタイムスタンプ)。 |
以下の3つは、署名の有無にかかわらずすべての配信に含まれます:
| ヘッダー | 意味 |
|---|---|
X-Webhook-Delivery |
このイベントの一意のID。再試行しても変わらないため、重複排除に使用します。 |
X-Webhook-Attempt |
試行回数(1 が初回)。 |
X-Webhook-Event |
イベント名。ボディを読み取らずにルーティングできます。 |
検証方法
署名は、署名シークレットをキーとして使用し、文字列<timestamp>.<raw request body>をHMAC-SHA256でハッシュ化したものです。
生のリクエストボディ(受信した正確なバイト列)に対して検証してください。 フレームワークがJSONを解析して再シリアル化してからチェックを行うと、バイト列が変化し、署名が一致しなくなります。
Node.jsの例:
const crypto = require("crypto");
function verify(rawBody, headers, secret) {
const timestamp = headers["x-webhook-timestamp"];
const signature = headers["x-webhook-signature"]; // "v1=<hex>"
// Reject anything older than 5 minutes so a captured request can't be replayed later.
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(signature.replace("v1=", "")), Buffer.from(expected));
}
Pythonの例:
import hashlib, hmac, time
def verify(raw_body: bytes, headers, secret: str) -> bool:
timestamp = headers["X-Webhook-Timestamp"]
signature = headers["X-Webhook-Signature"].replace("v1=", "")
# Reject anything older than 5 minutes so a captured request can't be replayed later.
if abs(time.time() - int(timestamp)) > 300:
return False
expected = hmac.new(secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature, expected)
署名の比較には、タイミング攻撃に強い関数 (
timingSafeEqual/compare_digest) を使用し、==は使用しないでください。コストはかからず、巧妙な攻撃を防ぐことができます。
シークレットのローテーション
Rotate(ローテーション)をクリックしてシークレットを置き換えます。切り替えは即座に行われ、次の配信から新しいシークレットのみで署名されます。エンドポイントが稼働中の場合は、新しいシークレットをデプロイするまでの数分間、古いシークレットと新しいシークレットの両方を受け入れるようにしてください。
署名をオフにすると、署名ヘッダーが送信されなくなります。
失敗した配信の再試行
デフォルトでは、失敗した配信は再試行されません。その瞬間にシステムがダウンしていると、そのイベントは取りこぼされます。
Webhookの作成/編集フォームで Retry failed deliveries(失敗した配信を再試行)をオンにすると、以下の通り再試行が行われます。
| 試行回数 | タイミング |
|---|---|
| 1 | 即時 |
| 2 | 1分後 |
| 3 | 5分後 |
| 4 | 30分後 |
| 5 | 2時間後 |
これは合計で約 2時間40分 にわたるため、Webhookはメンテナンス期間や短時間の停止であれば耐えることができます。
再試行の対象: 一時的な問題(サーバーが5xxエラーを返す、タイムアウト、接続失敗など)。
再試行されないケース: エンドポイント自体がリクエストを拒否した場合(4xxエラーなど)、再試行は行われません。同じリクエストを再送しても、同じ拒否結果になるだけだからです。
再試行の対象となるイベント: 2026年9月24日以降のすべてのイベント。これには、タグWebhook(contact_tags_updated)、3つのタスクイベント、日次サマリー、サマリーWebhook、新規メッセージ、チャット終了、連絡先の一時停止、連絡先の再開、連絡先の「応答不可」、連絡先のアーカイブ解除、クレジット残高不足、ブロードキャストイベント、および連絡先とアクティビティのイベント(連絡先作成、予約完了、担当者への通知、返信、既読、配信、クレジット消費、クレジットチャージ)が含まれます。それ以前の日付では、新規メッセージ、チャット終了、連絡先の一時停止、連絡先の再開、連絡先の「応答不可」、連絡先のアーカイブ解除、およびサマリーWebhookは、スイッチの設定に関係なく1回のみ送信されていました。すべてのイベントにX-Webhook-Deliveryが含まれているため、1つの重複排除ルールですべてをカバーできます。
エンドポイントが冪等(べきとう)である場合にのみ、再試行をオンにしてください。 再試行を行うと、同じイベントが複数回届く可能性があります。重複を認識するには
X-Webhook-Deliveryヘッダーを使用してください。これは1つのイベントに対してすべての試行で同じ値が保持されるため、すでに処理済みのIDを安全に無視できます。
再試行は、繰り返し失敗した後の自動停止(Webhookの信頼性を参照)と連携し、期待通りの動作をします。失敗カウンターは配信全体をカウントし、個々の試行ごとではなく、すべての再試行が使い果たされた後にのみカウントされます。
Webhookの信頼性
- Your AI Connectorは安全な接続(HTTPS)経由でWebhookを送信します。指定するWebアドレスがHTTPSを使用していることを確認してください。
- システムがエラーを返した場合、配信は失敗とみなされます。
- イベントの取りこぼしを防ぐため、受信システムの稼働状況を監視してください。
- 重要なワークフローでは、配信失敗時の再試行をオンにし、フォールバックメカニズムの導入も検討してください。
Webhookは、繰り返し失敗すると自動的にオフになります。 Webhook URLが繰り返し失敗した場合(連続して約5回、または設定関連のエラーの場合は連続して3回)、Your AI ConnectorはそのURLへのイベント送信を自動的に停止します。エンドポイントが正常な状態に戻ったら、Webhookを編集してURLを変更して保存する(URLを変更すると自動的に再有効化されます)、またはAPI経由で再有効化エンドポイントを使用してください。同じURLで保存し直すだけでは不十分です。サポートに依頼して再有効化してもらうこともできます。
トラブルシューティング
| 問題 | 解決策 |
|---|---|
| Webhookが発火しない | まず、Webhookが行単位でオフになっていないか確認してください。次に、正しいイベントが選択されていること、およびURLがインターネットから到達可能であることを確認してください。 |
| テストイベントは動作するが実際のイベントは動作しない | 特定のイベントタイプが有効になっていることを確認してください。タグが適用されたときにリクエストを期待している場合、subscribed_to_tags はWebhookのイベントをタグでスコープするものではなく、会話要約通知を生成するタグを絞り込むだけであることに注意してください。特定のタグが適用されたときにリクエストを取得するには、エージェントエディターのタグタブでそのタグにWebhook URLを設定してください。コンタクトタグ更新Webhookを参照してください。 |
| n8n / Make / Zapierに何も届かない | おそらくプラットフォームのテストURLを使用しています。これは「テストイベントをリッスン」をクリックした直後の単一イベントのみをリッスンします。ライブイベントの場合は、本番用URLを保存し、ワークフローをアクティブに切り替えてください。 |
| 重複したイベントを受信する | 同じURLを指す複数のWebhookがないか確認してください。失敗した配信を再試行がオンの場合、エンドポイントがイベントを受け入れたものの時間内に応答できなかった場合に繰り返しが発生することが予想されます。X-Webhook-Delivery で重複排除を行ってください。 |
| 署名チェックが常に失敗する | ほとんどの場合、チェック前にボディが再シリアル化されたことが原因です。生のリクエストボディに対して検証し、<timestamp>.<body> に署名し、最近ローテーションした場合は現在のシークレットを使用していることを確認してください。 |
| 再試行が行われない | 特定のWebhookで有効にされていない限り、再試行はオフです。4xxレスポンスに対しては再試行しません。 |
campaign ブロックが常に null になる |
予想される動作です。コンタクトはキャンペーンではなくAIエージェントに紐付いています。代わりに agent ブロックを読み取ってください。Webhookデータ形式を参照してください。 |
| データが空または不正な形式 | 受信システムがJSONを受け入れることを確認してください。サーバーログで解析エラーを確認してください。 |
| Webhook URLがエラーを返す | Postmanやwebhook.siteなどのツールを使用してURLをテストしてください。 |
| 停止後にWebhookが完全に発火しなくなった | 繰り返し失敗すると、Webhookは自動的に無効になります。再保存しても有効にはなりません。エンドポイントを修正してから、サポートに連絡してください。 |
| 保存またはテストで権限エラーが発生する | 統合の「編集」権限が必要です。アカウント所有者に付与を依頼してください。 |
Webhookの subscribed_to_tags リストが空で返ってきた |
subscribed_to_tags はWebhookのイベントをタグでスコープするものではなく、会話要約通知を生成するタグを絞り込むだけです。Webhookフォームからの編集ではそのリストはクリアされなくなりました(2026年7月21日修正)。それ以前にWebhookがリストを失った場合は、Webhooks API経由で subscribed_to_tags を再度設定してください。タグベースのWebhookトリガーを参照してください。 |
次のステップ
- GoHighLevel統合 — Webhookを使用してYour AI ConnectorとGHLを統合します。
- APIアクセス — WebhookとAPIを組み合わせて強力な自動化を実現します。
- タグを使用した連絡先のラベル付け — Webhookをトリガーするタグを設定します。