แทนที่จะติดตามเหตุการณ์ทั้งหมดในเกมและคำขอจากผู้ใช้ด้วยตนเอง คุณสามารถตั้งค่า Webhook เพื่อรับการแจ้งเตือนแบบเรียลไทม์บนเครื่องมือการส่งข้อความของบุคคลที่สามหรือจุดสิ้นสุดที่กำหนดเองของคุณที่สามารถรับคำขอ HTTP ได้ สิ่งนี้ช่วยให้คุณทำให้การจัดการการแจ้งเตือนของคุณเป็นไปโดยอัตโนมัติเพื่อลดความพยายามในการจัดการการแจ้งเตือนด้วยตนเอง
การทำงานของ Webhook
Webhook จะส่งการแจ้งเตือนหรือข้อมูลแบบเรียลไทม์ระหว่างแอปพลิเคชันหรือบริการที่แตกต่างกันสองตัว เช่น Roblox และเครื่องมือการส่งข้อความของบุคคลที่สาม ต่างจาก API แบบดั้งเดิมซึ่งต้องการให้คุณตั้งค่าแอปพลิเคชันลูกค้าเพื่อส่งคำขอไปยังเซิร์ฟเวอร์เพื่อรับข้อมูล Webhook จะส่งข้อมูลไปยังจุดสิ้นสุดของลูกค้าของคุณทันทีที่เกิดเหตุการณ์ขึ้น ซึ่งเป็นประโยชน์ในการทำงานอัตโนมัติระหว่าง Roblox และแอปพลิเคชันของบุคคลที่สามที่คุณใช้ในการทำงานร่วมกับทีมของคุณ เนื่องจากช่วยให้การแชร์และประมวลผลข้อมูลแบบเรียลไทม์
เมื่อคุณตั้งค่า Webhook ทุกครั้งที่เหตุการณ์เป้าหมายเกิดขึ้น Roblox จะส่งคำขอไปยัง URL ของ Webhook ที่คุณจัดเตรียมไว้ จากนั้น URL ของ Webhook จะส่งต่อคำขอไปยังแอปพลิเคชันที่คุณรับข้อมูลหรือจุดสิ้นสุดที่กำหนดเองซึ่งสามารถดำเนินการตามข้อมูลที่รวมอยู่ใน Payload ของ Webhook สิ่งนี้อาจรวมถึงการลบข้อมูลเพื่อให้เป็นไปตาม RTBF หรือส่งการยืนยันไปยังผู้ใช้ หรือกระตุ้นเหตุการณ์อื่น
ทริกเกอร์ที่รองรับ
Roblox รองรับทริกเกอร์เหตุการณ์ดังต่อไปนี้ในปัจจุบัน
การสมัครสมาชิก
- Subscription Resubscribed - เมื่อผู้ใช้สมัครสมาชิกใหม่ การแจ้งเตือนจะถูกส่งพร้อมด้วยข้อมูลการสมัครสมาชิกและผู้สมัคร
- Subscription Renewed - เมื่อผู้ใช้ต่ออายุการสมัครสมาชิก การแจ้งเตือนจะถูกส่งพร้อมด้วยข้อมูลการสมัครสมาชิกและผู้สมัคร
- Subscription Refunded - เมื่อผู้ใช้ได้รับเงินคืนสำหรับการสมัครสมาชิก การแจ้งเตือนจะถูกส่งพร้อมด้วยข้อมูลการสมัครสมาชิกและผู้สมัคร
- Subscription Purchased - เมื่อผู้ใช้ซื้อการสมัครสมาชิก การแจ้งเตือนจะถูกส่งพร้อมด้วยข้อมูลการสมัครสมาชิกและผู้สมัคร
- Subscription Cancelled - เมื่อผู้ใช้ยกเลิกการ สมัครสมาชิก การแจ้งเตือนจะถูกส่งพร้อมด้วยข้อมูลการสมัครสมาชิกและผู้สมัคร รวมถึงเหตุผลที่ให้สำหรับการยกเลิก
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเหตุการณ์การสมัครสมาชิกและฟิลด์ต่างๆ โปรดดูที่ Subscription
การปฏิบัติตาม
- Right to Erasure / Deletion Request - เมื่อผู้ใช้ใช้สิทธิในการลบข้อมูลส่วนบุคคลที่ต้องการลบอย่างถาวรตามกฎหมายการปกป้องข้อมูลและความเป็นส่วนตัวที่เกี่ยวข้อง ข้อมูลเพิ่มเติมสามารถพบได้ใน RTBF and Creators
การค้า
- Commerce Product Order Refunded - เมื่อผู้ใช้ได้รับเงินคืนสำหรับการสั่งซื้อผลิตภัณฑ์เชิงพาณิชย์ หรือคำสั่งซื้อนั้นถูกยกเลิก
- Commerce Product Order Paid - เมื่อผู้ใช้ชำระเงินสำหรับการสั่งซื้อผลิตภัณฑ์เชิงพาณิชย์ โปรดทราบว่าการแจ้งเตือน Webhook ซ้ำมีความเป็นไปได้ ดังนั้นคุณต้องห้ามการแจ้งเตือนซ้ำโดยใช้รหัสคำสั่งซื้อเชิงพาณิชย์ที่ไม่ซ้ำกัน
ตั้งค่า Webhook บน Creator Dashboard
หากต้องการรับการแจ้งเตือนผ่าน Webhook คุณต้องกำหนดค่า Webhook ที่สมัครสมาชิกสำหรับเหตุการณ์เฉพาะเพื่อกระตุ้นการแจ้งเตือน สำหรับเกมที่เป็นของกลุ่ม เจ้าของกลุ่มเท่านั้นที่สามารถกำหนดค่าและรับการแจ้งเตือน Webhook ได้
เพื่อทำการตั้งค่า Webhook:
เลือกประสบการณ์ของคุณใน Creator Hub
ภายใต้ Configure ให้เลือก Webhooks และคลิก Add Webhook
URL ของ Webhook มาจากผู้ให้บริการของคุณ ตัวอย่างเช่น URL ของ Slack อาจมีลักษณะดังนี้:
https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXXป้อน URL ของ Webhook และชื่อ
(ไม่บังคับ) รวมลับซึ่งช่วยรับรองว่าการแจ้งเตือนที่คุณได้รับมาจาก Roblox สำหรับข้อมูลเพิ่มเติม โปรดดูที่ Verify webhook security
เลือกหนึ่งตัวเลือกหรือมากกว่าจากรายการของเหตุการณ์ supported triggers ที่คุณต้องการรับการแจ้งเตือน
(ไม่บังคับ) ใช้ปุ่ม Test Response เพื่อตรวจสอบว่าบริการของคุณสามารถรับคำขอตัวอย่างได้หรือไม่
คลิก Save Changes
ตั้งค่า URL ของ Webhook
คุณสามารถตั้งค่าจุดสิ้นสุดบริการ HTTP ที่กำหนดเองเป็น URL ของ Webhook ของคุณ โดยมีข้อกำหนดดังต่อไปนี้:
- ต้องเข้าถึงได้ต่อสาธารณะเพื่อจัดการคำขอ
- ต้องจัดการคำขอ POST ได้
- ต้องตอบสนองต่อคำขอด้วยการตอบกลับ 2XX ภายใน 5 วินาที
- ต้องจัดการคำขอ HTTPS
เมื่อจุดสิ้นสุดของคุณได้รับคำขอ POST จะต้องสามารถ:
- สกัดรายละเอียดที่จำเป็นเกี่ยวกับการแจ้งเตือนจากเนื้อหาของข้อความ POST
- อ่านเนื้อหาของข้อความ POST ด้วยรายละเอียดทั่วไปเกี่ยวกับการแจ้งเตือนและรายละเอียดเฉพาะที่เกี่ยวข้องกับประเภทของเหตุการณ์ในการแจ้งเตือน
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสคีมาของคำขอ POST ที่ต้องจัดการ โปรดดูที่ Payload Schema
นโยบายการลองใหม่เมื่อการส่งไม่สำเร็จ
เมื่อการแจ้งเตือน Webhook ไม่สามารถเข้าถึง URL ที่คุณระบุได้เนื่องจากข้อผิดพลาดเช่นจุดสิ้นสุดไม่สามารถใช้ได้ Roblox จะลองส่งข้อความไปยัง URL ที่กำหนด 5 ครั้งโดยใช้ขนาดหน้าต่างคงที่ หากการแจ้งเตือนยังคงไม่สามารถส่งได้หลังจากลอง 5 ครั้ง Roblox จะหยุดพยายามส่งการแจ้งเตือนและสันนิษฐานว่า URL นั้นไม่ได้ผลอีกต่อไป ในสถานการณ์นี้คุณต้องอัปเดตการกำหนดค่า Webhook ของคุณด้วย URL ใหม่ที่สามารถเข้าถึงได้และสามารถรับการแจ้งเตือนได้ เพื่อแก้ไขปัญหาและยืนยันว่า URL ของ Webhook ของคุณสามารถรับการแจ้งเตือนได้สำเร็จ โปรดดูที่ Test webhooks
ข้อกำหนดของบุคคลที่สาม
เครื่องมือของบุคคลที่สามมักมีข้อกำหนดของตนเองสำหรับ Webhook ที่คุณต้องปฏิบัติตามเมื่อกำหนดค่า URL ของ Webhook ของคุณ คุณสามารถค้นหาข้อกำหนดเหล่านี้ได้โดยการค้นหาคำว่า "webhook" บนเว็บไซต์สนับสนุนหรือเอกสารของเครื่องมือเป้าหมาย สำหรับเครื่องมือบุคคลที่สามที่รองรับให้ดูที่ต่อไปนี้:
ทดสอบ Webhook
คุณสามารถทดสอบว่า Webhook ที่คุณได้กำหนดค่าไว้สามารถรับการแจ้งเตือนได้สำเร็จบน Creator Dashboard:
- นำทางไปยังหน้า Webhooks การกำหนดค่า
- เลือก Webhook ที่คุณต้องการทดสอบจากรายการ Webhook ที่กำหนดค่าไว้
- คลิกที่ไอคอนดินสอถัดจาก Webhook เป้าหมาย
- คลิกปุ่ม Test Response
ระบบจะส่งเหตุการณ์ SampleNotification ซึ่งรวมถึง User ID ของผู้ใช้ที่กระตุ้นการแจ้งเตือน ดังที่แสดงไว้ที่นี่:
{
"NotificationId": "string",
"EventType": "SampleNotification",
"EventTime": "2023-12-30T16:24:24.2118874Z",
"EventPayload": {
"UserId": 1
}
}หากคุณกำลังรวม Webhook ของคุณกับบริการของบุคคลที่สาม คุณสามารถทดสอบมันโดยใช้ URL ของบุคคลที่สามเพื่อยืนยันว่าบริการสามารถรับการแจ้งเตือนจาก Webhook ของคุณได้สำเร็จ หากคุณให้ความลับเมื่อกำหนดค่า Webhook มันจะสร้าง roblox-signature ที่คุณสามารถใช้เพื่อทดสอบตรรกะ roblox-signature ได้
ตรวจสอบความปลอดภัยของ Webhook
หลังจากคุณกำหนดค่าเซิร์ฟเวอร์ของคุณเพื่อรับ Payload มันจะเริ่มฟัง Payload ใด ๆ ที่ส่งไปยังจุดสิ้นสุด หากคุณตั้งค่าความลับเมื่อกำหนดค่า Webhook ของคุณ Roblox จะส่ง roblox-signature ในแต่ละการแจ้งเตือน Webhook เพื่อให้แน่ใจว่าคำขอจริงมาจาก Roblox ลายเซ็นจะอยู่ในส่วนหัวของ Payload สำหรับจุดสิ้นสุดที่กำหนดเองและในส่วนท้ายสำหรับเซิร์ฟเวอร์ของบุคคลที่สาม
t=<timestamp>,v1=<signature>หากคุณไม่ได้ตั้งค่าความลับสำหรับ Webhook ของคุณ ลายเซ็นจะมีเพียงเวลาติดป้ายเมื่อการแจ้งเตือนถูกส่ง:
t=<timestamp>ในการตรวจสอบลายเซ็น:
ดึงค่าเวลาและลายเซ็นทั้งหมด ลายเซ็นทั้งหมดสำหรับ Webhook ที่มีความลับแชร์รูปแบบเดียวกันในรูปแบบสตริง CSV โดยมีสองค่าที่ตามด้วยพรีฟิกซ์:
- t: เวลาเมื่อการแจ้งเตือนถูกส่ง
- v1: ค่าเซ็นชื่อที่สร้างขึ้นโดยใช้ความลับที่ให้โดยการกำหนดค่าจาก Creator Dashboard
สร้างสตริงฐานของ roblox-signature โดยการต่อ:
- ค่าเวลาในรูปแบบสตริง
- จุด (.)
- สตริง JSON ของเนื้อหาคำขอ
คำนวณรหัสยืนยันข้อความตามแฮช (HMAC) ด้วยฟังก์ชันแฮช SHA256 โดยใช้ความลับที่คุณกำหนดขึ้นในระหว่างการกำหนดค่าเป็นกุญแจและสตริงฐานที่คุณสร้างขึ้นผ่านขั้นตอนที่ 2 เป็นข้อความ เปลี่ยนผลลัพธ์เป็นรูปแบบ Base64 เพื่อให้ได้ลายเซ็นที่คาดหวัง
เปรียบเทียบค่าลายเซ็นที่สกัดมาเพื่อลายเซ็นที่คาดหวัง หากคุณสร้างลายเซ็นได้อย่างถูกต้อง ค่าจะต้องเหมือนกัน
(ไม่บังคับ) เพื่อป้องกันการโจมตีแบบ Replay ซึ่งเป็นประเภทของการโจมตีทางไซเบอร์ที่ผู้โจมตีดักฟังและส่งข้อมูลอีกครั้งเพื่อให้เข้าถึงโดยไม่ได้รับอนุญาตหรือดำเนินการอย่างมุ่งร้าย เป็นการดีที่จะเปรียบเทียบค่าลายเซ็นที่สกัดมาเพื่อลายเซ็นที่คาดหวังกับเวลาในปัจจุบันเพื่อให้แน่ใจว่าตกอยู่ภายในขอบเขตเวลาที่เหมาะสม ตัวอย่างเช่น ขอบเขตเวลา 10 นาทีมักจะเป็นขอบเขตเวลาที่สะดวก
สคีมาของ Payload
เมื่อเหตุการณ์เป้าหมายของ Webhook ของคุณถูกกระตุ้น มันจะส่งคำขอไปยัง URL ของ Webhook ของคุณโดยมีข้อมูลเกี่ยวกับเหตุการณ์ใน Payload ฟิลด์ Payload ของคำขอทั้งหมดจะแบ่งปันสคีมาที่ประกอบด้วยฟิลด์คงที่และฟิลด์ที่เปลี่ยนแปลง นี้ช่วยในการรับประกันว่าข้อมูลที่ส่งใน Payload มีโครงสร้างและสอดคล้องกันทำให้สามารถประมวลผลและใช้ข้อมูลในแอปพลิเคชันที่รับข้อมูลได้ง่ายขึ้น
ฟิลด์ สคีมาของ Payload คงที่ สามารถช่วยรักษาความสอดคล้องในทุกคำขอ Webhook โดยมีฟิลด์ดังต่อไปนี้:
- NotificationId (string): รหัสเฉพาะสำหรับการแจ้งเตือนแต่ละรายการที่ถูกส่ง หากได้รับ NotificationId เดียวกันสองครั้ง ถือว่าซ้ำกัน
- EventType (string): ระบุประเภทของเหตุการณ์ที่กระตุ้นการแจ้งเตือน
- EventTime (string): เวลาเมื่อเหตุการณ์ถูกกระตุ้น
ฟิลด์ สคีมาของ Payload ที่เปลี่ยนแปลงได้ ให้ความยืดหยุ่นสำหรับ Webhook เพื่อรองรับประเภทของเหตุการณ์ที่แตกต่างกันซึ่งรวมถึง:
- EventPayload (object): ประกอบด้วยข้อมูลเฉพาะสำหรับ EventType ที่กระตุ้น Webhook โครงสร้างของสคีมาของ EventPayload จะแตกต่างกันไปตามประเภทของเหตุการณ์
ตัวอย่างต่อไปนี้แสดงสคีมาของ Payload สำหรับเหตุการณ์ Request ขสิทธิในการลบข้อมูล:
{
"NotificationId": "string",
"EventType": "RightToErasureRequest",
"EventTime": "2023-12-30T16:24:24.2118874Z",
"EventPayload": {
"UserId": 1,
"GameIds": [
1234, 2345
]
}
}จัดการการแจ้งเตือน
หากคุณเก็บข้อมูล ข้อมูลส่วนบุคคลที่สามารถระบุตัวตนได้ (PII) ของผู้ใช้ เช่น User IDs คุณควรประเมินคำขอในแง่ของหน้าที่ทางกฎหมายของคุณ ข้อมูลเพิ่มเติมสามารถพบได้ใน RTBF and Creators คุณสามารถสร้างบอตเพื่อจัดการกับการแจ้งเตือนจาก Webhook และช่วยทำให้การลบข้อมูลเป็นไปโดยอัตโนมัติได้หากคุณเก็บ PII ในที่เก็บข้อมูล ดู Automating Right to Erasure Requests Deletion สำหรับตัวอย่างวิธีการสร้างบอตภายใน Discord ที่ใช้ Open Cloud API for data stores เพื่อลบข้อมูล PII ในฐานะโซลูชันการทำงานอัตโนมัติ ตัวอย่างนี้สามารถปรับใช้ได้สำหรับการจัดการการแจ้งเตือนอื่นๆ เช่น เหตุการณ์การสมัครสมาชิก
หากคุณใช้จุดสิ้นสุดที่กำหนดเองเป็นเซิร์ฟเวอร์ Webhook ของคุณแทนที่จะเป็นเครื่องมือของบุคคลที่สาม คุณสามารถสกัดข้อมูลที่ต้องลบออกจาก Payload ของ Webhook และสร้างโซลูชันอัตโนมัติของตัวเอง ตัวอย่างรหัสต่อไปนี้เป็นตัวอย่างของเซิร์ฟเวอร์ที่มีการป้องกันการโจมตี Replay โดยการตรวจสอบค่าของช่วงเวลาและให้แน่ใจว่าคำขอกำลังมาจาก Roblox:
const crypto = require('crypto');
const express = require('express');
const secret = '<your_secret>' // Can be set as an environment variable
let app = express();
app.use(express.json());
app.all('/*', function (req, res) {
console.log('มีคำขอใหม่เข้ามา');
// สกัดช่วงเวลาและลายเซ็นจากส่วนหัว
const signatureHeader = req.headers['roblox-signature'].split(',');
const timestamp = signatureHeader.find(e => e.startsWith('t=')).substring(2);
const signature = signatureHeader.find(e => e.startsWith('v1=')).substring(3);
// ตรวจสอบให้แน่ใจว่าคำขอมาจากภายใน 300 วินาทีเพื่อป้องกันการโจมตี Replay
const requestTimestampMs = timestamp * 1000;
const windowTimeMs = 300 * 1000;
const oldestTimestampAllowed = Date.now() - windowTimeMs;
if (requestTimestampMs < oldestTimestampAllowed) {
return res.status(403).send('คำขอหมดอายุ');
}
// ตรวจสอบลายเซ็น
const message = `${timestamp}.${JSON.stringify(req.body)}`;
const hmac = crypto.createHmac('sha256', secret);
const calculatedSignature = hmac.update(message).digest('base64');
if (signature !== calculatedSignature) {
return res.status(401).send('คำขอไม่ได้รับอนุญาต');
}
// โลจิกของคุณในการจัดการ Payload
const payloadBody = req.body;
const eventType = payloadBody['EventType'];
if (eventType === 'RightToErasureRequest'){
const userId = payloadBody['EventPayload']['UserId'];
const gameIds = payloadBody['EventPayload']['GameIds'];
console.log(`ข้อมูล Payload: UserId=${userId} และ GameIds=${gameIds}`);
// หากคุณเก็บ PII ในที่เก็บข้อมูล ใช้ UserId และ GameIds เพื่อลบข้อมูลจากที่เก็บข้อมูล
}
return res.json({ message: 'ประมวลผลข้อความสำเร็จ' });
});
app.listen(8080, function () {
console.log('เซิร์ฟเวอร์เริ่มต้นขึ้น');
});