Genel Veri Koruma Yönetmeliği (GDPR) Avrupa'daki veri koruma ve gizlilik yönetmeliğidir. İnsanlar, kişisel verilerinin silinmesini talep etme hakkını kullanır, kişisel verilerinin bilinen ticari olmayan adına erişim olarak bilinir. Eğer kullanıcı
İstekleri manuel olarak işlemek yerine, bir webhook oluşturabilirsiniz ve bir üçüncü parti mesajlaşma uygulamasında botu kullanarak işlemi otomatikleştirebilirsiniz. Veri depolarının en yaygın yolunu oluşturmak için, bu öğretici, Guilded veya Discord'
İş akışı
Bu öğreticiyi tamamladıktan sonra, kullanıcıların silme isteklerinin işlenmesini otomatikleştiren yerel bir özelleştirilmiş program oluşturabilmelisiniz. Bu işlem için iş akış şu şekilde olmalıdır:
- Roblox Destek, bir kullanıcının silme isteğini yerine getirme hakkına sahiptir.
- Roblox webhook'i tetiklenir, kullanıcı kimliğini ve yüklenenlerin katıldığı deneyimler için bir Start Place ID listesini içerir.
- Bot'unuz bu webhook bildirimlerine kulak veriyor, onların gizliliğini doğruluyor ve Open Cloud API for data stores kullanıyor çöp kaynaklarında depolanan PII verilerini silmek için.
- Bot, Discord'ta veya Guilded'de silme durumuyla webhook mesajına yanıt verir.
Üçüncü Taraf Bir Webhook'u Yapılandırma
Bir bot oluşturmadan önce, webhook entegrasyonlu bir sunucu üzerinde üçüncü parti mesajlaşma uygulamasında bir sunucu kurun. Sonra, yaratıcı dashboard'ında bir webhook'ı yapılandırmak için sunucuyu kullanın.
Bir Sunucu Kurulması
Aşağıdaki adımlar, Guilded veya Discord'u kullanarak sunucuyu nasıl ayarlanacağını gösterir.
- Yeni bir Guilded sunucusu oluşturun. Eğer işleme aşina değilseniz, bakın Guilded Destek.
- Gizlilik ayarları altında, sunucuyu özel olarak ayarlayın. Sunucu, varsayılan kanalınız olarak otomatik olarak özel bir <a href="/reference/privacy-and-security"># general</a> kanalı oluşturur.
- Yeni sunucuyla bir webhook entegrasyonu oluşturun ve kolayca anlayabileceğiniz bir isim verin, örneğin GDPR Hook. Eğer işlemle ilgili değilseniz, bakın Lonca Desteği.
- Webhook URL'sini kopyalayın ve güvenli bir dünyasaklayın. Sadece güvenilir takım üyelerinin erişmesine izin verin, çünkü URL'yi açığa çıkarmak kötü aktörlerin gönderdiği sahte mesajları potansiyel olarak kullanıcı verilerinizi silmesine izin verebilir.
Roblox'ta bir Webhook'u yapılandırma
Üçüncü parti sunucu URL'sini aldıktan sonra, Creator Dashboard'ta bir webhook'u yapılandırmak için kullanın. aşağıdaki ayarları yapın:
- Guilded veya Discord sunucu URL'sini Webhook URL olarak ekler.
- Yapılandırmanın tamamlanması için gizli bir Gizli dahil edin. Gizli, Roblox'u tamamlamak için zorunlu değil, ancak kötü aktörlerin Roblox'u kimlik avcısı olmasını önlemek için birini dahil etmelisiniz. Gizli kullanımı hakkında daha fazla bilgi için, Verifying Webhook Security bakın.
- Select Silme İsteği Hakkında Tetikler altında.
Roblox'un Test Cevabı düğmesini kullanarak webhook'u test edebilirsiniz, böylece sunucunuzun genel kanalından bir bildirimi alıp almadığınızı görebilirsiniz. Eğer bildirimi almazsanız, yeniden deneyin veya sunucu ayarlarınızı kontrol ederek hatayı giderebilirsiniz.
Bir Bot'u Yapılandırma
Webhook'ı ekledikten sonra, aşağıdaki adımları kullanarak bot'u yapılandırın:
Simgesine tıklayarak Tüm sunucuları aç listesini aç veya kısayol kullan:
- CtrlS Windows'ta.
- ⌘S Mac'te.
Erişim bildirimleri almak için sunucunuzu seçin.
Expand the list under Sunucunun evine and select Bot yönetimi .
Sunucu, varsayılan kanalınız olarak özel bir # general kanalı otomatik olarak oluşturur.
Bot oluşturma düğmesine tıklayın ve bir bot ismi ekleyin. Guilded'i giriş sayfasına yönlendirir.
Bot yapılandırma sayfasındaki API bölümünü seçin.
Jetonlar bölümünde, Jeton Oluştur düğmesine tıklayın.
Oluşturulan jetonu güvenli bir dünyasaklayın ve saklayın.
Bir Açık Bulut API Anahtarı Oluşturulması
Üçüncü parti botunuzun kullanıcıların Kişisel Tanıtıcı Bilgilerverilerini depolamak için veri depolarınıza erişmesine izin vermek için, bir Open Cloud API anahtarı oluştur ki kullanıcıların deneyimlerine erişebilir ve veri depolarının silme izinini ekleyebil
Deneyimlerin ve Yerlerin Kimliklerini Alın
Botun kullanıcılar tarafından silinmesini istediği PII verilerini bulması için, botu kullanmak için niyettiğiniz tüm deneyimlerinizin aşağıdaki kimliklerini alın:
- Deneyiminizin benzersiz kimliği olan Evren ID'si ,
- Etkinliğin başlangıç yerinin benzersiz kimliği olan Başlangıç Yeri ID 'dir.
Bu kimlikleri almak için, Yaratıcı Dashboard sayfasını açın. Ardından bir deneyim seçin ve Evren ID ve 2>Yer Başlangıcı ID2> kopyalayın.
Script'leri Ekleme
Dahili API'yi, bot'u ve veri depoları için webhook'u, bot'un otomasyon mantığını uygulayan kodları ekledikten sonra kodları kullanıcının kodlarına ekleyin. Aşağıdaki örnek, Python 3'i kullanır:
Python kütüphanelerini şu komutları kullanarak yükle:
Kütüphaneleri Kurpip3 install discordpip3 install guilded.py==1.8.0pip3 install requestspip3 install urllib3==1.26.6Aşağıdaki senaryoları aynı dizinin farklı bölümlerine karşılık olarak kopyalayıp kaydetin:
bot_config.pyDISCORD_BOT_TOKEN = ""GUILDED_BOT_TOKEN = ""OPEN_CLOUD_API_KEY = ""ROBLOX_WEBHOOK_SECRET = ""# Başlangıç Yeri ID'si ile# (evren ID, liste (veri depolarının adı, alanı ve giriş anahtarı)) için# Standart Veri Depoları# Bu girdilerin altında saklanan kullanıcı verileri silinecekSTANDARD_DATA_STORE_ENTRIES = {# Yer Başlangıcı ID111111111: (# Evren ID222222222,[("StandardDataStore1", "Scope1", "Key1_{user_id}"),("StandardDataStore1", "Scope1", "Key2_{user_id}"),("StandardDataStore2", "Scope1", "Key3_{user_id}")]),33333333: (444444444,[("StandardDataStore3", "Scope1", "Key1_{user_id}")])}# Başlangıç Yeri ID'si ile# (evren ID, liste (veri depolarının adı, alanı ve giriş anahtarı)) için# Veri Depoları Sıralandı# Bu girdilerin altında saklanan kullanıcı verileri silinecekORDERED_DATA_STORE_ENTRIES = {111111111: (222222222,[("OrderedDataStore1", "Scope2", "Key4_{user_id}")])}data_stores_api.pyimport requestsimport bot_configfrom collections import defaultdict"""Calls Data Stores Open Cloud API to delete all entries for a user_id configured inSTANDARD_DATA_STORE_ENTRIES. Returns a list of successful deletions and failures to delete."""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.com/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"""Calls Ordered Data Stores Open Cloud API to delete all entries for a user_id configured inORDERED_DATA_STORE_ENTRIES. Returns a list of successful deletions and failures to delete."""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.com/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, failuresi̇leti_yorumlayıcı.pyimport timeimport hmacimport hashlibimport reimport base64import bot_config"""Parses received message for Roblox signature and timestamp, the footer is only set if youconfigured webhook secret"""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"""Verifies Roblox signature with configured secret to check for validity"""def validate_signature(message, signature, timestamp):if not message or not signature or not timestamp:return False# 300 saniye içinde yeniden oynatma saldırısını önlerrequest_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# İşaretleyiciyi geçerli kılartimestamp_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# Geçerli imzareturn True"""Parses a received webhook messaged on Discord or Guilded. Extracts user ID, prevents replay attackbased on timestamp received, and verifies Roblox signature with configured secret to check forvalidity."""def parse_message(message):# Kullanıcı ID ve oyun ID için alınan mesajif 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 "", []guilded_bot.pyimport guildedimport jsonimport bot_configimport data_stores_apiimport message_parserdef run():client = guilded.Client()@client.eventasync def on_ready():print(f"{client.user} is listening to Right to Erasure messages")"""Handler for webhook messages from Roblox"""@client.eventasync def on_message(message):# Mesajı parsleyin ve mesajuser_id, start_place_ids = message_parser.parse_message(message)if not user_id or not start_place_ids:return# Standart veri depolarının kullanıcı verilerini siler[successes, failures] = data_stores_api.delete_standard_data_stores(user_id, start_place_ids)if successes:await message.reply(f"Deleted standard data stores data for " +f"user ID: {user_id}, data: {dict(successes)}")if failures:await message.reply(f"Failed to delete standard data stores data for " +f"user ID: {user_id}, data: {dict(failures)}")# Sıralama verileri kullanıcı verilerini siler[successes, failures] = data_stores_api.delete_ordered_data_stores(user_id, start_place_ids)if successes:await message.reply(f"Deleted ordered data stores data for " +f"user ID: {user_id}, data: {dict(successes)}")if failures:await message.reply(f"Failed to delete ordered data stores data for " +f"user ID: {user_id}, data: {dict(failures)}")client.run(bot_config.GUILDED_BOT_TOKEN)if __name__ == "__main__":run()Bot'un ana yapılandırması için bot_config.py dosyasında:
- Botunuz tarafından oluşturulan jetona DISCORD_BOT_TOKEN veya GUILDED_BOT_TOKEN ayarlayın.
- Yaratmış olduğun API anahtarını OPEN_CLOUD_API_KEY olarak ayarla.
- Yaratıcı Dashboard'ta webhook'u yapılandırırken ayarladığınız gizli ROBLOX_WEBHOOK_SECRET olarak ayarlayın.
- Her kaydın yerini bulmak için STANDARD_DATA_STORE_ENTRIES ve ORDERED_DATA_STORE_ENTRIES sözlüklerindeki kaydı silmek için kaydı bulmak için yerleştirilmiş bir kaydın yerini bulmak için YERLEŞTİRİLDİĞİ YER yerleştirilmiş bir kaydın yerini bulmak için 2>YERLEŞTİRİLDİĞ
- Kopyalanmış Start Place ID'lerinizi anahtar olarak ekleyin.
- Değer dizgesinin ilk elemanı olarak Universe ID'leri ekleyin.
- Topluluğun ikinci elemanını, ismi, alanı, giriş anahtarı ismini ve ilişkili veri depolarınızın kullanıcı kimliğini değiştirin. Eğer farklı bir veri şeması kullanıyorsanız, kendi veri şemanızın şeklini değiştirin.
Bot'u çalıştırmak için aşağıdaki komutu yürütün:
Guilded Bot'u Çalıştırpython3 guilded_bot.pyBot ardından Roblox webhook'larını dinleyin ve doğrulayın ve Open Cloud API'sini çağırın, ilgili veri mağazasilmek için Açık Bulut API'sini çağırın.
Test
Özelleştirilmiş programınızın doğru silme isteklerine ve silme verilerine erişim isteklerine doğru olarak işleyebileceğini doğrulamak için bir test mesajı oluşturup çalıştırabilirsiniz:
Guilded veya Discord webhook sunucunuzla bir HTTP POST istek gönderin, aşağıdaki istek vücut:
Örnek İstekcurl -X POST {serverUrl}-H 'Content-Type: application/json'-d '{"embeds":[{"title":"RightToErasureRequest","description":"You have received a new notification for Right to Erasure for the User Id: {userIds} in the game(s) with Ids: {gameIds}","footer":{"icon_url":"https://create.roblox.com/dashboard/assets/webhooks/roblox_logo_metal.png","text":"Roblox-Signature: {robloxSignature}, Timestamp: {timestamp}"}}]}'Eğer bir webhook'a gizli varsa:
- HMAC-SHA256 kodlanmasını webhook'unuzun gizli anahtarına uygulayarak bir Roblox-Signature oluşturun.
- UTC saati olarak saniye başına Timestamp olarak mevcut zamanı ayarlar.
açıklama adlı öğeyi şu biçimde birleştir:
Description Field Format{Timestamp}. You have received a new notification for Right to Erasure for the User Id: {userId} in the game(s) with Ids: {gameIds}`.Örneğin:
Example Description Field1683927229. You have received a new notification for Right to Erasure for the User Id: 2425654247 in the game(s) with Ids: 10539205763, 13260950955
Programınız, mesajınızı gizli olarak kodladığınızdan beri Roblox'un resmi kaynağından geldiğini tespit etmeyi sağlamalıdır. Ardından, talepilgili PII verilerini silmelidir.
Örnek Vücut
{
"embeds": [
{
"title": "RightToErasureRequest",
"description": "You have received a new notification for Right to Erasure for the User Id: 2425654247 in the game(s) with Ids: 10539205763, 13260950955",
"footer": {
"icon_url": "https://create.roblox.com/ashboard/ assets/ webhook/roblox_logo_metal.png",
"text": "Roblox-Signature: UIe6GJ78MHCmU/zUKBYP3LV0lAqwWRFR6UEfPt1xBFw=, Timestamp: 1683927229"
}
}
]
}