Rather than manually monitoring all events in your experience and requests from users, you can set up webhooks to receive real-time notifications on a third-party messaging tool or your custom endpoint that can receive HTTP requests. This helps you automate your notification management workflow to reduce manual effort handling notifications.
Webhook Workflow
A webhook is a mechanism for sending real-time notifications or data between two different applications or services over the internet, such as Roblox and a third-party messaging tool. Webhooks are useful for automating workflows between Roblox and third-party applications that you use for collaborating with your team, as they allow for real-time data sharing and processing
Once you set up a webhook, whenever a target event occurs, Roblox sends a request to the webhook URL that you configured. Currently, the only supported event is when a user submits a request to erase their "Right to be forgotten" data.
The webhook URL then redirects the request to your receiving application or custom endpoint, which can take action based on the data included in the webhook payload, such as erasing the data, sending a confirmation to the user, or triggering another event.
Unlike traditional APIs, which require you to set up a client application to send requests to a server to receive data, webhooks initiate the sending of data to a client application as soon as an event occurs, allowing the Roblox server to send data without the need for a request. This results in faster data transfer and processing times, making webhooks ideal for real-time or high-volume data processing scenarios.
Configuring Webhooks on Creator Dashboard
To receive notifications through webhooks, you need to configure a webhook that subscribes to certain events for triggering notifications. You can set up a webhook on Creator Dashboard with the following steps:
Navigate to the Creator Dashboard.
Click the dropdown menu on your account and select Settings from the list.
From the SETTINGS menu, select Webhooks.
Click the Add Webhook button.
Complete configuration fields, include:
- Webhook URL: Specify the URL where you want to receive notifications and accept incoming webhook URLs from third-party entities. For more information on the requirements, see Setting up Webhook URLs.
- Name: Use a custom name to differentiate your configuration from others. By default the value is the same as the Webhook URL.
- Secret (optional): Supply a secret if you want to verify that notifications you receive are coming from Roblox. For more information, see Verifying Webhook Security.
- Triggers: Choose one or more options from the list of supported triggers of events for which you want to receive notifications. Currently, the only supported event to trigger is Right To Erasure Request that occurs when a user submits a request to erase their "Right to be forgotten" data.
Click the SAVE CHANGES button.
Setting up Webhook URLs
You can set up a custom HTTP service endpoint as your webhook URL with the following requirements:
- It must be publicly accessible for handling requests.
- It can handle POST requests.
- It can respond to the request with a 2XX response within 5 seconds.
- It can handle HTTPS requests.
When your endpoint receives a POST request, it must be able to:
- Extract the details required about the notification from the body of the POST message.
- Read the body of the POST message with the generic details on the notification and specific details related to the event type on the notification.
For more information of the schema of POST requests to handle, see the Payload Schema.
Delivery Failure Retry Policy
When a webhook notification fails to reach your specified URL due to errors such as endpoint unavailability, Roblox retries sending the message to the configured URL 5 times using a fixed window size. If the notification still fails to be delivered after 5 attempts, Roblox stops trying to send the notification and assumes that the URL is no longer valid. In this situation, you need to update your webhook configuration with a new URL that is reachable and able to receive notifications. To troubleshoot and validate your webhook URL can successfully receive notifications, see Testing Webhooks.
Third-Party Requirements
Third-party tools usually have their own requirements for webhooks that you need to follow when setting up your webhook URL. You can find these requirements by searching for the keyword "webhook" on the support or documentation site of the target tool.
For the three verified tools, you can find this information by searching in the following sources:
Testing Webhooks
You can test whether the webhook you've configured can successfully receive notifications on Creator Dashboard with the following steps:
Navigate to the Webhooks configuration page on Creator Dashboard.
Select the webhook you want to test from the list of configured webhooks.
Click the pencil icon next to the target webhook.
Click the TEST RESPONSE button.
The system then sends a notification in the SampleNotification type, which includes the User ID of the user who triggers the notification, as the following example schema shows:
SampleNotification Schema
Body: {"NotificationId": "string","EventType": "SampleNotification","EventTime": "2023-12-30T16:24:24.2118874Z", // Type: ISO 8601 Timestamp"EventPayload": {"UserId": 1 // Type: Long}}
If you are integrating your webhook with a third-party service, you can test it using the third-party URL to confirm that the service can successfully receive notifications from your webhook. If you provide a secret when configuring the webhook, it also generates a roblox-signature that you can use to test the roblox-signature logic.
Verifying Webhook Security
Once you configure your server to receive payloads, it starts to listen for any payload sent to the endpoint. If you set a secret when configuring your webhook, Roblox sends a roblox-signature in the header for every webhook notification to help protect your data security. This way, you can use the roblox-signature header to verify that the notification is from Roblox and limit your server to only receive requests originating from Roblox.
Header Format with Signature
"roblox-signature": "t=<timestamp>,v1=<signature>"
If you don't have a secret for your webhook, the header you receive only contains the timestamp value on when the notification is sent:
Header Format without Signature
"roblox-signature": "t=<timestamp>"
To verify the signature in the header if you receive one:
Extract the timestamp and signature values from the header. All roblox-signature headers share the same format as a CSV string with these two values following by the prefixes:
- t: The timestamp value on when the notification is sent.
- v1: The signature value generated using the secret provided by the Creator Dashboard configuration. You can extract these two values using the split() function, which separates the string based on a delimiter, in this case, the , character.
Re-create the base string of roblox-signature by concatenating:
- The timestamp as a string.
- The period character ..
- The JSON string of the request body.
Compute a Hash-based message authentication code (HMAC) with the SHA256 hash function using the secret you defined during the configuration as the key and the base string you generated through step 2 as the message. Convert the result to Base64 format to get the expected signature.
Compare the extracted signature value to the expected signature. If you generated the signature correctly, the value should be the same.
(Optional) To prevent replay attacks, a type of cyber attack where attackers intercept and resend data to gain unauthorized access or perform malicious actions, it's helpful to compare the extracted timestamp value with the current timestamp and ensure it falls within a reasonable time limit. For example, 10 minutes window is usually a good reasonable time limit.
Payload Schema
When the target event of your webhook is triggered, it sends a request to your webhook URL, including information about the event in the payload. All payloads of requests share the same schema that consists of fixed and variable fields. This ensures that the data transmitted in the payload is structured and consistent, making it easier for the receiving application to process and use the data.
The fixed payload schema fields can help maintain consistency across all webhook requests, with the following fields available:
- NotificationId, string: A unique identifier for each notification sent. If the same NotificationId is received twice, it is considered a duplicate.
- EventType, string: A string represents the type of event for which the notification was triggered.
- EventTime, timestamp: An approximate timestamp indicating when the event was triggered.
The variable payload schema fields provides flexibility for webhooks to accommodate various types of events, which include:
- EventPayload, object: Contains information specific to the EventType that triggered the webhook. The structure of the EventPayload schema varies based on the type of event.
The following example shows the payload schema of the Right To Erasure Request event:
Example Schema for Right to Erasure Request
Body:{"NotificationId": "string","EventType": "RightToErasureRequest","EventTime": "2023-12-30T16:24:24.2118874Z","EventPayload": {"UserId": 1, // Type: Long"GameIds": [ // Type: An array of Longs1234, 2345]}}
Extracting Data from Payload
If you store any Personally Identifiable Information (PII) of your users, such as their User IDs, you must delete this information when a user submits such a request to comply with the GDPR "Right to be forgotten" compliance requirements. To extract the data subject to deletion from the webhook payload, you can use the following code sample as a reference, which also verifies that the request is coming from Roblox and adds prevention to replay attacks.
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')
})
Handling Requests for Third-Party Tools
If you use a third-party messaging tool for receiving your webhook notifications, such as Discord, Guilded, or Slack, you can create a bot on that tool to handle the request payload. You can find more information on how to create a bot and grant permissions for each tool on the following sources:
Handling Data Deletion
Once you have extracted the PII from the webhook payload, you can use it to delete the corresponding data. If you store PII in data stores, you can create an Open Cloud API key with Read Entry and Delete Entry permissions for the specific experience where you have the PII stored. This way, you can use the extracted information to delete the corresponding data store every time you receive a webhook notification on your server or third-party tool. If you store PII in other tools, you can also use the extracted PII to locate the data subject to deletion and proceed with the deletion process.