Webhook

Webhook APIを使用すると、貴社の連携機能がインストールされている場合にHubSpotアカウント上で発生するイベントにサブスクライブできます。接続されたアカウントでイベントが発生したときにAPI呼び出しを実行する代わりに、構成したエンドポイントにHubSpotからHTTPリクエストを送信することができます。サブスクライブするイベントは、アプリの設定、または以下で詳述するエンドポイントを使用して構成できます。Webhookは、定期的な変更のポーリングよりも拡張性に優れる傾向があります(特にインストールベースの大規模なアプリにおいて)。
 

Webhook APIを使用するには次の要件があります。

  • 通知を受けるイベントをサブスクライブし、通知の送信先URLを指定することにより、Webhookを使用するHubSpotアプリを設定してあること。アプリの作成の詳細については、前提条件ドキュメント(英語)をご覧ください。
  • このドキュメントに規定されたWebhookペイロードを処理できる、公開URLのセキュア(HTTPS)エンドポイントが展開されていること。

Webhookは、アカウント単位ではなくHubSpotアプリ(英語)用としてセットアップされます。(OAuthフロー(英語)に従って)アプリをインストールするアカウントがWebhookサブスクリプションに登録されます。

 

スコープ

Webhookを使用するには、contactsスコープを求めるようにアプリを構成する必要があります。このスコープはWebhookサブスクリプションを作成する前にセットアップする必要があり、アプリ設定の開発者アカウントから、またはWebhook APIを使用してサブスクリプションを構成するときに設定します。スコープの詳細およびアプリの認証URLの設定については、OAuthのドキュメント(英語)を参照してください。

アプリがすでにWebhookを使用している場合、アプリからすべてのWebhookサブスクリプションを削除するまで、contactsスコープを削除できなくなります。

 

Webhookのセットアップ

注:Webhook設定は最大5分までキャッシュできます。Webhook URL、レート制限、またはサブスクリプション設定を変更すると、変更が有効になるまでに最大5分かかる場合があります。

 

Webhook URLとレート制限

Webhookサブスクリプションを設定する前に、これらの通知の送信先URLを指定する必要があります。また、エンドポイントがリクエストを処理できるようにレートを調整することもできます。

このレート制限を設定すると、APIに過大な負荷をかけずに通知をできるだけ早く送信するために役立ちます。

  • 制限が低すぎると、APIに送信された通知が多すぎた場合にこの制限が数秒間飽和状態になり、通知がタイムアウトすることがあります。その結果、通知を受け取るまでに遅延が発生します。
  • 制限が高すぎると、エンドポイントで利用可能なリソースが飽和状態になり、レスポンスの低速化、通知の遅延、またはエンドポイントの応答不可といった問題が発生することがあります。

 

UIでの管理

開発者アカウント上のアプリの設定ページで、URLとレート制限設定を管理できます。

1.アプリダッシュボードでWebhookをセットアップするアプリを選択します。
app_id_list

2.左側のナビゲーション項目で[Webhook]を選択します。この画面に、ターゲットURLとイベントスロットリング制限を設定するインターフェイスが表示されます。

2-webhook_settings

API経由の管理

これらのエンドポイントを使用すると、プログラムによってアプリのWebhookを設定することが可能です。アプリをセットアップする際にはUIを使用することをお勧めします。これらのエンドポイントへのリクエストを行うときには、開発者APIキーを使用する必要があります。

設定フィールド

設定オブジェクトには次のフィールドがあります。

  • webhookUrl - Webhook通知の送信先URL。HTTPS経由で提供する必要があります。
  • maxConcurrentRequests - このURLの同時接続制限は「Webhook URLと同時接続制限」で説明します。
設定の表示

貴社のアプリ用に現在セットアップされたWebhook設定がある場合は次のエンドポイントでアクセスします。

GET https://api.hubapi.com/webhooks/v1/{appId}/settings

結果は次のようになります。

{
"webhookUrl": "https://testing.com/webhook",
"maxConcurrentRequests":20
}

設定の更新

これらの設定を変更するには、次のエンドポイントを使用できます。

PUT https://api.hubapi.com/webhooks/v1/{appId}/settings

リクエスト本文は次のようになります。

{
"webhookUrl": "https://testing.com/webhook-modified",
"maxConcurrentRequests":25
}
 

検証:

  • webhookUrlはHTTPS経由で提供される有効なURLである必要があります。
  • maxConcurrentRequestsは5より大きい数字でなければなりません。

 

Webhookサブスクリプション

Webhook URlとレート制限設定をセットアップしたら、1つ以上のサブスクリプションを作成する必要があります。Webhookサブスクリプションは、特定のアプリが受信するイベントをHubSpotに伝える仕組みです。現在、次のタイプのサブスクリプションをサポートしています。

 

サブスクリプションについては、以下の点にご注意ください。

プロパティー変更サブスクリプションの場合、通知するプロパティーを指定する必要があります。複数のプロパティー変更サブスクリプションを指定できます。サブスクリプションで指定されたプロパティーが顧客のアカウント上にない場合、この顧客からはそのプロパティーのWebhookを取得できません。

一部のプロパティーは、プロパティー変更サブスクリプションでは使用できません。該当するプロパティーは次のとおりです。


コンタクトのプロパティー:

  • days_to_close
  • recent_conversion_event_name
  • recent_conversion_date
  • first_conversion_event_name
  • first_conversion_date
  • num_unique_conversion_events
  • num_conversion_events

取引のプロパティー:

  • num_associated_contacts

サブスクリプションは、貴社の連携機能をインストールしたすべての顧客に適用されます。つまり、必要なサブスクリプションを指定するのは一度だけでよいことになります。アプリのサブスクリプションを有効にすると、貴社のアプリをインストールしたすべての顧客のWebhookが自動的に開始され、連携機能をインストールした新しい顧客からのWebhookの取得は自動的に開始されます。

サブスクリプションの作成または変更を行ってから変更が有効になるまでに、最大5分の遅延が生じる場合があります。

 

UIでのサブスクリプション管理

Webhookサブスクリプションは、開発者アカウント上で作成できます。

  1. 開発者アプリダッシュボードで、Webhookを送信するアプリを選択します。
  2. [Webhookサブスクリプション]ナビゲーション項目を選択します。
  3. [サブスクリプションを作成]をクリックします。
    3-webhook_settings
  4. オブジェクトタイプ(例:コンタクト、会社、取引)とイベントタイプ(例:作成、変更、削除)を選択します。 :プライバシーのための削除は、選択されたオブジェクトタイプが「コンタクト」のみである場合にのみ選択できます。
    4-create_webhook_subscription
  5. (任意)プロパティー変更イベントの場合、対象のプロパティーを選択します。注:プロパティー名を手動で入力することもできるので、カスタムプロパティーを使用できます。
    5-webhook_select_properties

注:新しいサブスクリプションは一時停止状態で作成されます。送信には、Webhookのサブスクリプションを有効化する必要があります。

6-activate_subscription

API経由のサブスクリプション管理

これらのエンドポイントを使用すると、プログラムによってサブスクリプションを作成することが可能です。UIでできることとエンドポイントでできることの間に違いはないため、アプリの設定にはUIを使用することをお勧めします。これらのエンドポイントへのリクエストを行うときには、開発者APIキーを使用する必要があります。

サブスクリプションフィールド

サブスクリプションオブジェクトには次のフィールドがあります。

  • id - サブスクリプションごとのIDを表す数値。
  • createdAt - このサブスクリプションが作成された時点のミリ秒単位のタイムスタンプ。
  • createdBy - このサブスクリプションを作成したユーザーのユーザーID。
  • enabled - このサブスクリプションが現在有効で通知のトリガーが行われるかどうか。
  • subscriptionDetails - このサブスクリプションによってリスニングされるイベントのタイプを表します。
  • subscriptionType - 下記の「サブスクリプションタイプ」で定義されたサブスクリプションタイプを表す文字列。
  • propertyName -プロパティーの変更にのみ必要。変更のリスニング対象となるプロパティーの名前。単一のプロパティー名のみ指定可能です。

 

サブスクリプションタイプ

subscriptionTypeプロパティーは次のいずれかの値になります。

  • contact.creation - 顧客のアカウントでコンタクトが作成された場合に通知を受け取る。
  • contact.deletion - 顧客のアカウントでコンタクトが削除された場合に通知を受け取る。
  • contact.privacyDeletion - プライバシー規則への遵守を理由としてコンタクトが削除された場合に通知を受け取る。 詳細はこちら(英語)を参照してください。
  • contact.propertyChange - 顧客のアカウント上のすべてのコンタクトについて、指定したプロパティーが変更された場合に通知を受け取る。
  • company.creation - 顧客のアカウント上で会社が作成された場合に通知を受け取る。
  • company.deletion - 顧客のアカウント上で会社が削除された場合に通知を受け取る。
  • company.propertyChange - 顧客のアカウントのすべての会社について、指定したプロパティーが変更された場合に通知を受け取る。
  • deal.creation - 顧客のアカウント上で取引が作成された場合に通知を受け取る。
  • deal.deletion - 顧客のアカウント上で取引が削除された場合に通知を受け取る
  • deal.propertyChange -顧客のアカウント上のすべての取引について、指定したプロパティーが変更された場合に通知を受け取る。

 

サブスクリプションの取得

サブスクリプションのリストは次のように取得します。

GET https://api.hubapi.com/webhooks/v1/{appId}/subscriptions

レスポンスはサブスクリプションを表すオブジェクトの配列です。各オブジェクトには、ID、作成日、タイプ、現在有効になっているかどうかなどのサブスクリプションに関する情報が含まれます。レスポンスの例を次に示します。

JSON
//[
{
"id": 25,
"createdAt": 1461704185000,
"createdBy": 529872,
"subscriptionDetails": {
"subscriptionType": "contact.propertyChange",
"propertyName": "lifecyclestage"
},
"enabled": true
},
{
"id": 59,
"createdAt": 1462388498000,
"createdBy": 529872,
"subscriptionDetails": {
"subscriptionType": "company.creation"
},
"enabled": false
},
{
"id": 108,
"createdAt": 1463423132000,
"createdBy": 529872,
"subscriptionDetails": {
"subscriptionType": "deal.creation"
},
"enabled": true
}
]
新規サブスクリプションの作成

新しいサブスクリプションは次のように作成します。

POST https://api.hubapi.com/webhooks/v1/{appId}/subscriptions

リクエスト本文は次のようになります。

JSON
//{
"subscriptionDetails": {
"subscriptionType": "company.propertyChange",
"propertyName": "companyname"
},
"enabled": false
}
リクエスト本文のフィールドは「サブスクリプションフィールド」で定義されたフィールドと一致します。ただしidcreatedAtcreatedByフィールドは自動的に設定されるので、このエンドポイントでは指定できません。

検証:

subscriptionTypeには、上記の「サブスクリプションタイプ」で定義された有効なサブスクリプションタイプが必要です。

propertyNameは有効なプロパティー名である必要があります。顧客がこの値に一致するプロパティーを定義していない場合、このサブスクリプションの通知は行われません。

enabledtrueまたはfalseでなければなりません。

 
サブスクリプションの更新

更新できるのはサブスクリプションのenabledフラグのみです。そのためには、次のエンドポイントを使用します。

PUT https://api.hubapi.com/webhooks/v1/{appId}/subscriptions/{subscriptionId}

リクエスト本文:

{ "enabled" : false }

サブスクリプションの削除

サブスクリプションを削除するには、次のエンドポイントを呼び出すことができます。

DELETE https://api.hubapi.com/webhooks/v1/{appId}/subscriptions/{subscriptionId}

 

Webhookペイロード

Webhook設定で指定したURLのエンドポイントには、次のようなリクエストが届きます。

メソッドタイプ:POST

Headers:

Content-Type:Application/Json
X-HubSpot-Signature: {アプリシークレットとリクエスト本文のハッシュ。詳細はこちら(英語)を参照。}


リクエスト本文の例:

JSON
//[
{
"objectId": 1246965,
"propertyName": "lifecyclestage",
"propertyValue": "subscriber",
"changeSource": "ACADEMY",
"eventId": 3816279340,
"subscriptionId": 25,
"portalId": 33,
"appId": 1160452,
"occurredAt": 1462216307945,
"subscriptionType": "contact.propertyChange",
"attemptNumber": 0
},
{
"objectId": 1246978,
"changeSource": "IMPORT",
"eventId": 3816279480,
"subscriptionId": 22,
"portalId": 33,
"appId": 1160452,
"occurredAt": 1462216307945,
"subscriptionType": "contact.creation",
"attemptNumber": 0
}
]

リクエストフィールド:

  • objectId:作成/変更/削除されたオブジェクトのID。これは、コンタクトの場合はvid、会社の場合はcompanyId、取引の場合はdealIdです。
    propertyName:プロパティー変更に関する通知の場合にのみ送信されます。これは変更されたプロパティーの名前です。
  • propertyValue:プロパティー変更に関する通知の場合にのみ送信されます。これは、この通知をトリガーしたこのプロパティーに新たに設定された値です。
  • changeSource:この変更のソース。コンタクトのプロパティー履歴で確認可能ないずれかの変更ソースです。
  • eventId:この通知をトリガーしたイベントの一意のID。
  • subscriptionId:このイベントの通知を送信したサブスクリプションのID。
  • portalId:このイベントの発生元となった顧客のポータルID。
  • appId:貴社のアプリのID(貴社の複数のアプリが同じWebhook URLを示している場合)。
  • occurredAt:このイベントが発生した時点のミリ秒単位のタイムスタンプ。
  • subscriptionType:この通知のイベントタイプ。上記の「サブスクリプションタイプ」のリストを参照してください。
  • attemptNumber:貴社のサービスに通知するイベントの試行番号(0で始まる)。下の「再試行」に記載のサービスタイムアウトまたはエラーが発生した場合、貴社のサービスに対し通知の再送信が試行されます。

 

一括処理に関する注意:上記のように、1つのリクエストに対し複数の通知が届きます。一括処理のサイズはさまざまですが、通知は100件未満になります。複数の通知が送信されるのは、短時間に多数のイベントが発生した場合に限られます。例えば、新しいコンタクトにサブスクライブしている状態で、顧客が多数のコンタクトをインポートした場合、リクエストに対して1つではなく、一括でインポートされたコンタクトに対して複数の通知が送信されます。

順序に関する注意:このような通知の発生順序どおりの取得は保証されません。通知発生のタイミングを判定するには、各通知のoccurredAtプロパティーを使用してください。

一意性に関する注意:イベントごとに1件の通知のみが取得されるかどうかは保証されません。非常にまれですが、同じ通知の送信が複数回行われる場合があります。

 

プライバシー規則に準拠したコンタクト削除の処理

HubSpotユーザーは、プライバシーに関する法律に準拠するためにコンタクトレコードを完全に削除することができます。この機能の詳細については次のヘルプ記事を参照してください。https://knowledge.hubspot.com/jp/articles/kcs_article/contacts/how-do-i-perform-a-gdpr-compliant-delete-in-hubspot

contact.privacyDeletionサブスクリプションタイプをサブスクライブすることにより、ユーザーがプライバシー遵守のためのコンタクト削除を実行したときにWebhook通知を受信できます。

注:プライバシー削除通知には特別な動作があります。
  • プライバシー削除イベントによって通常のcontact.deleteイベントもトリガーされるため、両方のイベントをサブスクライブしている場合は2つの通知を受け取ります。
  • これらの通知の送信順序は保証されず、1つの一括メッセージとして送信される場合もあります。個別のメッセージとの照合にはobjectIdを使用する必要があります。

 

セキュリティー

注:WebhookではX-HubSpot-Signatureヘッダーのv1バージョンが使用されます。このバージョンの署名の検証の詳細については、こちらのページ(英語)を参照してください。リクエストの検証全般の詳細については、こちらのページ(英語)を参照してください。

Webhookのエンドポイントで取得しているリクエストが実際にHubSpotから送信されたことを保証するために、X-HubSpot-Signatureヘッダーには、貴社のアプリのアプリシークレットと、送信するリクエスト本文を連結した文字列に対するSHA-256ハッシュが示されます。

この署名を検証するには、貴社のアプリのアプリシークレットと処理中のリクエストにある構文未解析のリクエスト本文を連結し、その結果のSHA-256ハッシュを取得します。結果のハッシュとX-HubSpot-Signatureの値を比較します。この値が一致する場合、リクエストがHubSpotから送信されたことが検証されます(でなければ、他の誰かがアプリシークレットを知っていることになります。この値の機密保持は重要です)。これらの値が一致しない場合、転送中のリクエストの改ざん、またはエンドポイントに対するWebhook通知のなりすましが発生したおそれがあります。

再試行

貴社のサービスに通知の処理の問題が発生した場合はいつでも、最大10回、失敗した通知の再送が試みられます。

再試行は次の場合に行われます。

接続に失敗 - 指定されたWebhook URLへのhttp接続を開始できない場合
タイムアウト - 貴社のサービスから一括の通知に対するレスポンスを戻すのに5秒を超える時間がかかった場合
エラーコード - 貴社のサービスがHTTPステータスコード(4xxまたは5xx)でレスポンスした場合

再試行は、次のattemptNumberに基づいてエクスポネンシャルバックオフ方式で行われます。つまり、最初の再試行は2秒で、2回目の再試行は4秒、3回目は8秒というように実行されます。

制限

1つのアプリあたり最大1,000件のサブスクリプションを作成できます。この制限を超えて作成しようとすると、以下の本文とともに400 bad requestが戻されます。

JSON
//{
"status": "error",
"message": "Couldn't create another subscription. You've reached the maximum number allowed per application (1000).",
"correlationId": "2c9beb86-387b-4ff6-96f7-dbb486c00a95",
"requestId": "919c4c84f66769e53b2c5713d192fca7"
}