Webhook 通知

*このコンテンツは、ベータ版のAI(人工知能)を使用して翻訳されており、エラーが含まれている可能性があります。このページを英語で表示するには、 こちら をクリックしてください。

エクスペリエンス内のすべてのイベントとユーザーからのリクエストを手動で監視するのではなく、Webhook を設定して、サードパーティのメッセージツールまたは HTTP リクエストを受信できるカスタムエンドポイントで、リアルタイム通知を受け取ることができます。これにより、通知管理ワークフローを自動化して、手動で処理される通知の負担を軽減できます。

Webhook ワークフロー

Webhook は、Roblox や第三者のメッセージツールなど、2つの異なるアプリケーションまたはサービス間でリアルタイム通知やデータを送信します。伝統的な APIとは異なり、クライアントアプリケーションを設定してサーバーにリクエストを送り、データを受信する必要があるのとは異なり、ウェブホックはイベントが発生するとすぐにクライアントエンドポイントにデータを送信します。Roblox とチームとのコラボレーションに使用するサードパーティのアプリケーション間のワークフローを自動化するのに役立ち、リアルタイムデータ共有と処理を可能にするためです。

Webhook を設定したら、ターゲットイベントが発生するたびに、Roblox は提供した Webhook URL にリクエストを送信します。その後、Webhook URL はリクエストを受信アプリケーションまたはカスタムエンドポイントにリダイレクトし、Webhook ペイロードに含まれるデータに基づいてアクションを実行できます。これには、GDPR のデータを消去する、ユーザーに確認を送信する、または別のイベントをトリガーするなどが含まれます。

サポートされるトリガー

Roblox は現在、通知のための次のイベントトリガーをサポートしています:

  • サブスクリプションがキャンセルされた - ユーザーがサブスクリプションをキャンセルしたとき、サブスクリプションとサブスクライバー、キャンセル理由が含まれたメッセージが送信される
  • サブスクリプション購入 - ユーザーがサブスクリプションを購入すると、サブスクリプションとサブスクライバーを含むメッセージが送信されます。
  • サブスクリプション返金 - ユーザーがサブスクリプションの返金を受け取ったとき、サブスクリプションとサブスクライバーを含むメッセージが送信されます。
  • サブスクリプション更新 - ユーザーがサブスクリプションを更新すると、サブスクリプションとサブスクライバーを含むメッセージが送信されます。
  • サブスクリプション再購読 - ユーザーがサブスクリプションに再購読すると、サブスクリプションとサブスクライバーを含むメッセージが送信されます。
  • 「忘れられる権利」 一般データ保護規則 ( GDPR ) の下でのデータ削除リクエスト。

サブスクリプションイベントとそのフィールドに関する詳細は、クラウド API サブスクリプション 参照を参照してください。

クリエイターダッシュボードで Webhook を構成する

Webhook を介して通知を受信するには、トリガーになる特定のイベントにサブスクライブする Webhook を構成する必要があります。グループ所有のエクスペリエンスの場合、グループ所有者だけが Webhook 通知を設定して受信できます。

Webhook を設定するには:

  1. ナビゲート to the Webhooks セクション of the クリエイターダッシュボード.
  2. クリックする Webhook 追加 ボタン。
  3. 構成フィールドを完了する:
    1. Webhook URL — 通知を受信し、第三者のエンティティから受信された Webhook URLを承認したい URLを指定します。要件に関する詳細は、ウェブホック URL の設定 を参照してください。
    2. 名前 — カスタム名を使用して、他の構成と区別します。デフォルトでは、値は Webhook URL と同じです。
    3. 秘密 (オプション) — 受信した通知が RoblRoblox(ロブロックス) から来ていることを確認するには、秘密を供給します。詳しくは、Webhook のセキュリティを認証する を参照してください。
    4. トリガー — イベントの通知を受信したいのに、リストの サポートされるトリガー の中から1つまたは複数のオプションを選択します。
  4. クリックする [変更を保存] ボタン。

Webhook URL を設定する

次の要件を満たしている限り、ウェブホック URL としてカスタム HTTP サービスエンドポイントを設定できます:

  • リクエストの処理に公開アクセスする必要があります。
  • POST リクエストを処理できます。
  • 5秒以内に 2XX 応答でリクエストに応答できます。
  • HTTPSリクエストを処理できます。

エンドポイントがポストリクエストを受信したとき、次のことができなければなりません:

  • ポストメッセージの体から、通知に必要な詳細を抽出します。
  • 通知の一般的な詳細と通知に関連するイベントタイプに関する特定の詳細を使って、POST メッセージの本文を読みます。

処理する POST リクエストのスキームの詳細については、Payload スキーム を参照してください。

配信失敗再試プライバシーポリシーポリシー

エンドポイントの不可用などのエラーにより、指定された URLに Webhook 通知が到達できない場合、Roblox は固定のウィンドウサイズを使用して、配信されたメッセージを設定された URLに 5回送信し直します。通知が 5回の試行後にまだ配信されない場合、Roblox は通知を送信しようとしなくなり、URLが無効であると仮定します。この状況では、リーチ可能で通知を受信できる新しい URL で Webhook 構成を更新する必要があります。Webhook URL が通知を受信できるかをトラブルシュートし、確認するには、Webhook テスト を参照してください。

第三者の要件

サードパーティのツールは通常、ウェブホック URL を設定するときに従う必要があるウェブホックの要件があります。ターゲットツールのサポートまたはドキュメントサイトで「webhook」というキーワードを検索して、これらの要件を見つけることができます。サポートされている 3 つのサードパーティツールについては、以フォロー中を参照してください:

テスト Web ホック

設定したウェブホックが クリエイターダッシュボード で通知を受信できるかどうかをテストできます:

  1. ナビゲート to the Webhooks 設定ページ。
  2. 設定されたウェブホックのリストから、テストしたいウェブホックを選択します。
  3. ターゲットの Webhook の隣にあるペンアイコンをクリックします。
  4. クリックする テスト応答 ボタン。

システムはその後、通知を SampleNotification タイプ入力送信し、通知をトリガーするユーザーの ユーザーID を含む通知を、以下の例のスキームで示します:

サンプル通知スキーム

Body: {
"NotificationId": "string",
"EventType": "SampleNotification",
"EventTime": "2023-12-30T16:24:24.2118874Z", // タイプ: ISO 8601 タイムスタンプ
"EventPayload": {
"UserId": 1 // タイプ: 長
}
}

ウェブホックをサードパーティのサービスと統合している場合、サードパーティの URL を使用してテストして、サービスがウェブホックからの通知を受信できるかどうかを確認できます。Webhook を構成するときに秘密を提供すると、roblox-signature ロジックをテストするために使用できる roblox-signature も生成されます。

Webhook のセキュリティを認証する

サーバーを配信された負荷を受信するように構成したら、エンドポイントに送信された負荷を聞き始めます。Webhook を構成するときに秘密を設定すると、Roblox はデータセキュリティを保護するために、すべての Webhook 通知とともに roblox-signature を送信します。この方法では、通知が RRoblox(ロブロックス)blox から来ていることを確認し、サーバーを Roblox からのリクエストにのみ受信するように制限することができます。署名は、カスタムエンドポイントのペイロードヘッダーと第三者サーバーのフッターにあります。

Signature Format with Secret for Custom Endpoints

"roblox-signature": "t=<timestamp>,v1=<signature>"

Webhook の秘密がない場合、受信した署名には通知が送信されたときのタイムスタンプ値のみが含まれています:

Signature Format without Secret for Custom Endpoints

"roblox-signature": "t=<timestamp>"

署名を検証するには:

  1. タイムスタンプと署名値を抽出する。秘密を持つウェブホックのすべての署名は、プレフィックスに続いてこれらの 2つの値が付いた CSV 文字列と同じ形式を共有します:

    • t : 通知が送信されたときのタイムスタンプ値。
    • v1 : クリエイターダッシュボード構成によって生成された秘密を使用して生成された署名値。これらの 2つの値を抽出するには、split() 関数を使用して、文字列を区切符に基づいて分離し、この場合、, 文字です。
  2. 再結合して roblox-signature のベースストリングを再作成する:

    1. 文字列としてのタイムスタンプ。
    2. 期間文字 .
    3. リクエストボディの JSON 文字列。
  3. 設定中に定義した秘密と、ステップ 2 で生成したメッセージのベース文字列を使用して、SHA256 ハッシュ関数を使用してハッシュベースのメッセージ認証コード (HMAC) を計算します。結果を Base64 形式に変換して、期待される署名を取得する

  4. 抽出された署名値と期待される署名を比較します。署名を正しく生成した場合、値は同じであるはずです。

  5. (オプション) リプレイ攻撃を防ぐには、攻撃者がデータをインターセプトして再送して無許可アクセスを獲得したり、悪意のあるアクションを実行したりするタイプのサイバー攻撃で、抽出されたタイムスタンプ値と現在のタイムスタンプを比較して、適切な期間内に含まれることを確認することが有用です。たとえば、10分のウィンドウは通常、良い適切な制限時間です。

ペイロードスキーム

ウェブホックのターゲットイベントがトリガーされると、ペイロード内のイベント情報を含むウェブホック URLにリクエストが送信されます。リクエストのすべてのペイロードは、固定および変数のフィールドで構成される同じスキームを共有します。これにより、ペイロードで送信されたデータが構造化されて一貫しているため、受信アプリケーションがデータを処理して使用するのが簡単になります。 固定ペイロードスキームフィールド は、次のフィールドが利用可能で、すべての Webhook リクエストの一貫性を維持するのに役立つことができます:

  1. NotificationId , string : 各送信された通知のユニークな識別子。同じ NotificationId が 2 回受信された場合、それは重複と見なされます。

  2. EventType , string : 文字列は、通知がトリガーされたイベントの種類を表します。

  3. EventTime , timestamp : イベントがトリガーされた時刻を示す大まかなタイムスタンプ。 変数ペイロードスキームフィールド は、ウェブホックが対応できるさまざまな種類のイベントを含む柔軟性を提供します:

  4. EventPayload , object : ウェブホックをトリガーにした EventType に関する情報を含むEventPayload スキームの構造は、イベントの種類によって異なります。

次の例では、 削除リクエスト イベントのペイロードスキームを示しています:

消去リクエストの右側のスキームの例

Body:{
"NotificationId": "string",
"EventType": "RightToErasureRequest",
"EventTime": "2023-12-30T16:24:24.2118874Z",
"EventPayload": {
"UserId": 1, // タイプ: 長
"GameIds": [ // タイプ: 長の配列
1234, 2345
]
}
}

通知を処理する

ユーザーのユーザーIDなどの個人識別情報を保存している場合は、ユーザーがGDPRの消去権要件に従うために、この情報を削除する必要があります。データストアに PII を保存している限り、Webhook 通知を処理し、データ削除を自動化するためのボッ保管を作成できます。「消去リクエストの自動化」で、Guilded または Discord 内のボットを作成する方法の例として、オープンクラウド API for data stores を使用して、PII データを自動化ソリューションとして削除する方法を見てください。この例は、サブスクリプションイベントなどの他の通知の処理に適応できます。

サードパーティのツールではなく、カスタムエンドポイントをウェブホックサーバーとして使用する場合、ウェブホックペイロードから削除対象のデータを抽出し、自分の自動化ソリューションを構築できます。次のコードサンプルは、例の解決策を提供し、リクエストが RRoblox(ロブロックス)blox から来ていることを確認して、リプレイ攻撃を防ぎます:

Extracting PII from Payload

const crypto = require('crypto')
const express = require('express');
let app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// This is a sample only code
app.all('/*', function (req, res) {
console.log('-------- New Request Seen -------');
// 1. Extract the timestamp and signature
const shared_secret = '<Your secret>' // This can be set as an environment variable
const hmac = crypto.createHmac('sha256', shared_secret)
const roblox_signature_header = req.headers['roblox-signature'].split(',')
// 'roblox-signature' is present in all requests:
// Timestamp(t) is present in all requests, however signature value(v1) is not set unless a secret is shared during the webhook configuration.
// Fetch header component at Index 0 -> 't=' and Index 1 -> 'v1='
const timestamp = roblox_signature_header.find(e => e.startsWith('t=')).substring(2);
const extracted_signature = roblox_signature_header.find(e => e.startsWith('v1='));
// 2. Prevent Replay attack: 300 seconds window
const request_timestamp_ms = timestamp * 1000;
const window_time_ms = 300 * 1000
const oldest_timestamp_allowed = Date.now() - window_time_ms;
if (request_timestamp_ms < oldest_timestamp_allowed) {
res.status(403).send('Expired Request')
}
// 3. Validate Signature
if (extracted_signature !== undefined) {
const signature_v1 = extracted_signature.substring(3);
const message = `${timestamp}.${JSON.stringify(req.body)}`
const base64_signature = hmac.update(message).digest('base64')
if (signature_v1 !== base64_signature) {
res.status(401).send('Unauthorized Request')
}
}
// 4. Your logic to handle payload
const payloadBody = req.body
const eventType = payloadBody['EventType']
if (eventType === 'RightToErasureRequest'){
const userId = payloadBody['EventPayload']['UserId']
const gameIds = payloadBody['EventPayload']['GameIds']
const gameIdString = gameIds.toString()
console.log(`The payload: UserId=${userId} and GameIds=${gameIdString}`)
// If you store PII in data stores, use the UserId and GameIds to make a data store call to delete the information.
}
// 5. Return Response
res.json({ message: 'Processed the message Successfully' });
})
app.listen(8080, function () {
console.log('This is a Sample application')
})