網路連接通知

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

您可以設置 webhook 來在第三方訊息工具或自訂端點收到 HTTP 請求時實時收到通知,而不是手動監視體驗中的所有事件和請求。這樣您就可以自動化通知管理工作流程來減少手動努力處理通知。

網路連接器工作流程

網路連接器可以將資料傳送到 Roblox 或第三方訊息工具,例如 Roblox、Outlook、或資料共享工具,這些工具不需要您設置客戶端應用程式才能向伺服器傳送資料。 與傳統 API 不同,網路連接器會在發生事件時將資料傳送到您的客戶端端口,因此您可以自動化與

當您設置 Web 回聯時,每次發生目標事件時,Roblox 會向您提供的 webhook URL 傳送請求。 webhook 網路上路由請求到您提供的目標事件,因此在網路上路由請求的時候,您可以基於網路上路線的資料來做出行動。這可能包括清除資料,傳送確認給使用者,或觸發其他事件。

支援的觸發器

目前,Roblox 支援通知的事件提示:

  • 訂閱取消了子帳號 - 當使用者取消訂閱時,會傳送包含 訂閱 和訂閱者,以及發出的原因為取消。
  • 訂閱購買完成後 發送訊息,包含訂閱者和訂閱資格。
  • 訂閱資金已退款 - 當使用者收到訂閱資金退款時,訊息包含訂閱資金和訂閱者。
  • 訂閱續期已更新 - 當使用者更新訂閱時,會傳送包含訂閱者和訂閱者的訊息。
  • 重新訂閱訂閱者 - 當使用者重新訂閱訂閱時,訊息包含訂閱者和訂閱者。
  • "被遺忘權利"資料刪除請求在《一般資料保護規範》( GDPR )下。

有關訂閱事件和其他字段的更多資訊,請參閱雲端 API 訂閱參考。

在創作者控制板上設定網路連接器

要透過 webhook 收到通知,您必須要先設定一個 webhook ,訂閱特定事件來啟動通知。對於群組擁有的體驗,只有群組所有者才能設定並收到 webhook 通知。

要設定 webhook:

  1. 導航到 網路連接器 區塊的 創作者面板
  2. 點擊 添加網頁撥款 按鈕。
  3. 完成設定字段:
    1. Webhook URL — 指定您想收到通知的網路連線網址,並接受從第三方網路連線網址暫時接收的網路連線網址。有關需求的更多資訊,請參閱 設定 Webhook URL
    2. 名稱 — 使用自訂名稱來與其他人分開您的設定。 預設值與 Webhook 網路連接器的 URL 相同。
    3. 秘密 (可選) — 提供秘密,如果您想要確認您收到的通知來自 Roblox。For more 資訊,請參閱驗證網路鉤安全
    4. 發動機機制 — 從事件發起機制的列表中選擇一個或多個選項。
  4. 點擊 儲存變更 按鈕。

設定 Webhook 網址

您可以將自訂 HTTP 服務端設定為您的網頁扶手網址,提供它滿足以下要求:

  • 它必須公開可用,處理請求。
  • 它可以處理 POST 請求。
  • 它可以在 5 秒內回應要求以 2XX 個回應。
  • 它可以處理 HTTPS 請求。

當您的端口收到一個 POST 邀請時,它必須能夠:

  • 從 POST 訊息的內容中提取所需的細節。
  • 閱讀 POST 訊息的身體,包含通知和通知與特定事件類型相關的具體細節。

有關更多 POST 請求處手把的 schema 資訊,請參閱 付費資料庫架構圖

交付失敗重試政策

當網路連接斷開、端口不可用或其他錯誤發生時,Roblox 無法將訊息傳送至指定的 URL,因此 Roblox 會發出錯誤訊息,並將訊息傳送到指定的 URL 5 次。如果錯誤訊息仍無法傳送,Roblox 會停止嘗試傳送錯

第三方要求

第三方工具通常有自己的網路連接資料庫要求,您需要跟隨設定網路連接資料庫時查找這些要求。您可以從目標工具的協助或文件資訊網站搜尋關鍵字 "webhook" 來查找這些要求。對於三個支持的第三方工具,請參閱以下內容:

測試網路連接器

您可以測試您設定的網路通知創作者儀表板是否能正確收到通知:

  1. 前往 Webhook 設定頁面。

  2. 選擇您想要測試的網路連接器從配置的網路連接器列表中選取。

  3. 點擊目標網路上的筆記號圖示。

    The pencil icon next to an example webhook
  4. 點擊 測試回應 按鈕。

系統會發送通知,並在 SampleNotification 輸入型中包含使用者啟動通知的 User ID ,如下示例示例示例所示:

示例通知庫

Body: {
"NotificationId": "string",
"EventType": "SampleNotification",
"EventTime": "2023-12-30T16:24:24.2118874Z", // 類型:ISO 8601 時戳
"EventPayload": {
"UserId": 1 // 類型:長
}
}

如果您正在集成 webhook 與第三方服務,您可以使用第三方網頁檢查 (以下稱為第三方網頁檢查) 來確認服務可以從您的 webhook 收到通知。如果您在 webhook 的設定中提供秘密資訊,它還會生成一個 roblox-signature ,您可以使用它來測試 webhook 的論理。

確認網路針對安全

一旦您設定您的服務器接收載入,它就會開始偵聽任何載入發送到端點的付費。 如果您在設定您的網頁樣式時設置了一個秘密,Roblox 會以 roblox-signature 一起提供每個網頁樣式通知來幫助保

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. 提取時間戳 和 簽名值。 所有 webhook 的秘密都使用相同的格式,作為 CSV 字串,這兩個值跟隨簽名前:

    • t : 通知傳送時的時戳值。
    • v1 : 使用創作者面板設定提供的秘密生成的簽名值。您可以使用 split() 函數,將這兩個值提取,使用 , 角色基於字元分隔符的字串。
  2. 重新建立 roblox-signature 的基本字串,並且:

    1. 串時間為字符字串。
    2. 期間字符 .
    3. 請求身體的 JSON 字串。
  3. 使用秘密您在設置中定義的鑰匙和基本字串作為您的鑰匙,並使用 SHA256 哈希函數計算一個基於哈希的訊息認證碼 (HMAC)。將結果轉換為 Base64 格式以取得預期的簽名。

  4. 比較已取得的簽名值與預期的簽名值。如果您正確生成了簽名,值應該一樣。

  5. (可選) 為了防止重播攻擊,一種可以讓攻擊者擷取並重新傳送資料以獲得未授權存取或執行惡意操作的黑客攻擊,它的幫助是比較提取時間戳值與當前時間戳值,並確認它落在合理時間限制內。 例如,10分鐘窗戶通常是個很好的合理時間限制。

付款計算條件

當您的網頁撥發器的目標事件發生時,它會向您的網頁撥發器的 URL 發送請求,包括關於事件的載入資料的信息。所有載入資料的網頁撥發器都會分享相同的資料結構,這使您的應用程序處理和使用資料更容易。

固定載入資料庫 可以幫助維護所有 webhook 請求的一致性,並提供以下可用的字段:

  1. NotificationId , string : 發送的每個通知的獨一標識。如果同一個 NotificationId 被收到兩次,它將被視為重複。
  2. EventTypestring:代表通知已觸發的事件類型。
  3. EventTime , timestamp : 準確的時戳表示發生了什麼事件。

變量載入極體 schema 欄 提供了適應各種類型的事件的方便,這包括:

  1. EventPayload , object : 包含與網路連接相關的資訊。EventType 發生時的網路連接類型會因類型而異。

下列示例顯示了 Right To Erasure Request 事件的載入資料庫:

右邊清除請求示例資料庫

Body:{
"NotificationId": "string",
"EventType": "RightToErasureRequest",
"EventTime": "2023-12-30T16:24:24.2118874Z",
"EventPayload": {
"UserId": 1, // 類型:長
"GameIds": [ // 類型:一個長度為長度的陣列
1234, 2345
]
}
}

處理通知

如果您存儲任何個人身份資訊(PII),例如用戶的User ID,您必須刪除此信息,當用戶提交此

如果您使用自訂端口作為您的網頁扁平軟件服務器而不是第三方工具,您可以從網頁載入頁面中提取資料,並且建立自己的自動化解決方案。以下代碼示例提供了一個範例解決方案,並且通過檢查請求來確認來自 Roblox 的請求是否來自 Roblox 來添加防止重播攻擊的防護。

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')
})