Silme hakkını otomatikleştirmek için web kancaları kullanma

*Bu içerik, yapay zekâ (beta) kullanılarak çevrildi ve hatalar içerebilir. Sayfayı İngilizce görüntülemek için buraya tıkla.

Küresel veri koruma ve gizlilik düzenlemeleri, bireylere verilerini kontrol etme hakkı verir; bu, silinmesini talep etme hakkını (genellikle "silme hakkı" veya "silme hakkı" olarak adlandırılır) içerir. Kullanıcı kimlikleri gibi herhangi bir kişisel veri veya Kişisel Olarak Tanımlanabilir Bilgi (PII) saklıyorsanız, bu bilgiyi bir kullanıcı talebi aldığınızda kalıcı olarak silmekle yükümlüsünüz. Daha fazla bilgi için RTBF ve yaratıcılar sayfasına bakabilirsiniz.

Alternatifleri değerlendirin

Veri depolarındaki kişisel veriler için en kolay otomasyon seçeneği, RTBF silme şablonlarını yapılandırmaktır. Roblox, bir RTBF talebini işlediğinde, özel kod barındırmanıza gerek kalmadan, eşleşen standart veya sıralı veri deposu girişlerini otomatik olarak siler. Şablonları yapılandırmak ve desteklenen desenleri gözden geçirmek için Veri deposu unutulma hakkı (RTBF) sayfasına bakın.

Bu sayfadaki web kancası iş akışı, aşağıdaki durumlarda faydalıdır:

  • Kişisel verileri veri depoları dışında saklıyorsanız.
  • Veri deposu şemanız veya kullanım durumunuz RTBF silme şablonları tarafından desteklenmiyorsa.
  • Özel işleme veya silme mantığına ihtiyacınız varsa.

Yaratıcı web kancası iş akışı

Bu eğitim, bir web kancası kurmayı ve silme hakkı taleplerinin işlenmesini otomatikleştirmek için Veri depoları için Açık Bulut API'sini kullanan yerel olarak çalışan bir Discord botu oluşturmayı gösterir. Bu sürecin iş akışı şu şekildedir:

  1. Roblox Destek, bir kullanıcıdan silme hakkı talebi alır.
  2. Roblox web kancası, yüklemede kullanıcı kimliği ve katıldıkları oyunların Başlangıç Yerleri ID'lerinin bir listesini içeren bir bildirim gönderir.
  3. Botunuz bu web kancası bildirimlerini dinler, kimliklerini doğrular ve veri depolarında saklanan PII verilerini silmek için Açık Bulut API'sini kullanır.
  4. Bot, Discord'daki web kancası mesajına silme durumu ile yanıt verir.

Üçüncü taraf entegrasyonu ile bir web kancası yapılandırma

Bir bot oluşturmadan önce, üçüncü taraf mesajlaşma uygulamasında web kancası entegrasyonu ile bir sunucu kurun. Ardından, Creator Dashboard'da bir web kancası yapılandırmak için bu sunucuyu kullanın.

Bir sunucu kurun

Aşağıdaki adımlar, Discord kullanarak sunucuyu nasıl kuracağınızı gösterir.

  1. Yeni bir Discord sunucusu oluşturun. Süreç hakkında bilginiz yoksa, Discord Destek sayfasına bakın.

  2. Sunucu, varsayılan kanalınız olarak otomatik olarak bir #genel kanalı oluşturur. #genel kanalının Kanalı Düzenle simgesine tıklayın.

  3. İzinler altında, kanalı özel olarak ayarlayın.

  4. Yeni sunucu ile bir web kancası entegrasyonu oluşturun, adını RTBF Hook olarak belirleyin. Süreç hakkında bilginiz yoksa, Discord Destek sayfasına bakın.

  5. Web kancası URL'sini kopyalayın ve güvenli bir yerde saklayın. Sadece güvenilir ekip üyelerinin erişmesine izin verin; URL'nin sızması kötü niyetli kişilerin sahte mesajlar göndermesine ve potansiyel olarak kullanıcı verilerinizi silmesine neden olabilir.

Roblox'ta bir web kancası yapılandırma

Üçüncü taraf sunucu URL'sini aldıktan sonra, bunu Creator Dashboard'da bir web kancası yapılandırmak için kullanın. Aşağıdaki ayarları yaptığınızdan emin olun:

  • Discord sunucu URL'sini Webhook URL'si olarak ekleyin.
  • Özel bir Gizli Anahtar ekleyin. Gizli bir anahtar, yapılandırmayı tamamlamak için isteğe bağlıdır, ancak kötü niyetli kişilerin Roblox'u taklit etmesini ve verilerinizi silmesini önlemek için bir tane eklemelisiniz. Gizli anahtarın kullanımı hakkında daha fazla bilgi için Webhook güvenliğini doğrulama sayfasına bakın.
  • Tetikleyiciler altında Silme Hakkı Talebi seçeneğini seçin.

Webhook'u test etmek için Test Yanıtı düğmesini kullanarak Roblox'tan sunucunuzun #genel kanalında bir bildirim alıp almadığınızı kontrol edebilirsiniz. Bildirimi almazsanız, tekrar deneyin veya hata ayıklamak için sunucu ayarlarınızı kontrol edin.

Bir bot yapılandırma

Webhook'u ekledikten sonra, botu yapılandırmak için aşağıdaki adımları izleyin. Daha fazla bilgi için Discord belgelerine bakın.

  1. Yeni bir uygulama oluşturun ve adını RTBF Bot olarak belirleyin.
  2. Sistem sizi botun Genel Bilgiler ayarlarına yönlendirir. Uygulama kimliğini güvenli bir yerde kopyalayın ve saklayın.
  3. Ayarlar menüsünden OAuth2 seçeneğini seçin.
  4. OAuth2 ayarlarına gidin
    1. bot kapsamını etkinleştirin, ek Bot İzinleri listesi görüntülenecektir.
    2. Yönetici iznini ekleyin. Değişikliklerinizi kaydedin.
    3. Oluşturulan URL'yi kaydedin.
  5. Oluşturulan URL'yi kopyalayın. Uygulama ayarları sayfasını kapatmayın.
  6. Oluşturulan URL'ye gidin. Hedef sunucuyu seçin. Devam Et düğmesine ve ardından Yetkilendir düğmesine tıklayın.
  7. Uygulama ayarları sayfasına geri dönün ve Bot ayarlarına gidin.
  8. Özel Geçit Niyetleri bölümünde Mesaj İçeriği Niyeti'ni etkinleştirin.
  9. Bot ayarları > Bot Oluştur bölümünde, sonraki adımlar için bot token'ını güvenli bir yerde saklayın. Token'ı görmüyorsanız, yeni bir tane oluşturmak için Token'ı Sıfırla düğmesine tıklayın.

Açık Bulut API anahtarı oluşturma

Üçüncü taraf botunuzun kullanıcıların PII verilerini saklamak için veri depolarınıza erişmesine izin vermek için, oyunlarınıza erişebilen bir Açık Bulut API anahtarı oluşturun ve veri silme işlemleri için veri depolarının Giriş Sil iznini ekleyin. PII verilerini saklamak için sıralı veri depoları kullanıyorsanız, sıralı veri depolarının Yazma iznini de eklemeniz gerekir. Tamamlandıktan sonra, API anahtarını güvenli bir yerde kopyalayın ve saklayın.

Oyun ve yerlerin tanımlayıcılarını elde etme

Botun, kullanıcılar tarafından silinmesi talep edilen PII verilerini bulabilmesi için, botu kullanmayı düşündüğünüz tüm oyunların aşağıdaki tanımlayıcılarını elde edin:

  • Oyununuza ait Evrensel ID, oyununuzun benzersiz tanımlayıcısı.
  • Oyun başlangıç yeri için Başlangıç Yeri ID, oyunun başlangıç yerinin benzersiz tanımlayıcısı.

Bu tanımlayıcıları elde etmek için:

  1. Creator Dashboard sayfasına gidin.

  2. Bir oyunun küçük resminin üzerine gelin, düğmesine tıklayın ve sırasıyla Evrensel ID'yi Kopyala ve Başlangıç Yeri ID'sini Kopyala seçeneklerini seçin.

Betikler ekleyin

Webhook, bot ve veri depoları için API anahtarını ayarladıktan sonra, bunları botun otomasyon mantığını uygulayan betiklere ekleyin. Aşağıdaki örnek Python 3 kullanmaktadır.

  1. Aşağıdaki komutları kullanarak Python kütüphanelerini yükleyin:

    Kütüphaneleri Yükle
    pip3 install discord
    pip3 install requests
    pip3 install urllib3==1.26.6
  2. Aşağıdaki betikleri bot mantığının farklı bölümlerine karşılık gelen şekilde aynı dizine kopyalayın ve kaydedin:

    bot_config.py
    BOT_TOKEN = ""
    OPEN_CLOUD_API_KEY = ""
    ROBLOX_WEBHOOK_SECRET = ""
    # Başlangıç yeri ID'sinin
    # (evrensel ID, (veri deposu adı, kapsam ve giriş anahtarı) listesi) için
    # Standart Veri Depoları
    # Bu girişler altında saklanan kullanıcı verileri silinecektir
    STANDARD_DATA_STORE_ENTRIES = {
    # Başlangıç Yeri ID'si
    111111111: (
    # Evrensel ID
    222222222,
    [
    ("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'sinin
    # (evrensel ID, (veri deposu adı, kapsam ve giriş anahtarı) listesi) için
    # Sıralı Veri Depoları
    # Bu girişler altında saklanan kullanıcı verileri silinecektir
    ORDERED_DATA_STORE_ENTRIES = {
    111111111: (
    222222222,
    [
    ("OrderedDataStore1", "Scope2", "Key4_{user_id}")
    ]
    )
    }
    data_stores_api.py
    import requests
    import bot_config
    from collections import defaultdict
    """
    Kullanıcı_id'si için yapılandırılan tüm girişleri silmek için Veri Depoları Açık Bulut API'sini çağırır
    STANDARD_DATA_STORE_ENTRIES. Başarılı silmelerin ve silme hatalarının bir listesini döndürür.
    """
    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:
    continue
    universe_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
    """
    Kullanıcı_id'si için yapılandırılan tüm girişleri silmek için Sıralı Veri Depoları Açık Bulut API'sini çağırır
    ORDERED_DATA_STORE_ENTRIES. Başarılı silmelerin ve silme hatalarının bir listesini döndürür.
    """
    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:
    continue
    universe_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, failures
    message_parser.py
    import time
    import hmac
    import hashlib
    import re
    import base64
    import bot_config
    """
    Alınan mesajı Roblox imzası ve zaman damgası için ayrıştırır, alt bilgi yalnızca
    yapılandırılmış web kancası gizli anahtarı varsa ayarlanır
    """
    def parse_footer(message):
    if not message.embeds[0].footer or \
    not message.embeds[0].footer.text:
    return "", 0
    footer_match = re.match(
    r"Roblox-Signature: (.*), Timestamp: (.*)",
    message.embeds[0].footer.text
    )
    if not footer_match:
    return "", 0
    else:
    signature = footer_match.group(1)
    timestamp = int(footer_match.group(2))
    return signature, timestamp
    """
    Geçerliliği kontrol etmek için yapılandırılmış gizli anahtar ile Roblox imzasını doğrular
    """
    def validate_signature(message, signature, timestamp):
    if not message or not signature or not timestamp:
    return False
    # 300 saniyelik bir pencerede yeniden oynatma saldırılarını önler
    request_timestamp_ms = timestamp * 1000
    window_time_ms = 300 * 1000
    oldest_timestamp_allowed = round(time.time() * 1000) - window_time_ms
    if request_timestamp_ms < oldest_timestamp_allowed:
    return False
    # İmzanın doğruluğunu kontrol eder
    timestamp_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 imza
    return True
    """
    Discord'da alınan bir web kancası mesajını ayrıştırır. Kullanıcı kimliğini çıkarır, zaman damgasına
    dayalı olarak yeniden oynatma saldırılarını önler ve geçerliliği kontrol etmek için yapılandırılmış
    gizli anahtar ile Roblox imzasını doğrular.
    """
    def parse_message(message):
    # Alınan mesajı kullanıcı kimliği ve oyun kimliği için ayrıştırır
    if len(message.embeds) != 1 or \
    not message.embeds[0].description:
    return "", []
    description_match = re.match(
    r"Silme Hakkı için Kullanıcı Kimliği: (.*) olan yeni bir bildirim aldınız " +
    r"oyun\(lar\) ile Kimlikler: (.*)",
    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_ids
    else:
    return "", []
    discord_bot.py
    import discord
    import bot_config
    import data_stores_api
    import message_parser
    def run():
    intents = discord.Intents.default()
    intents.message_content = True
    client = discord.Client(intents=intents)
    @client.event
    async def on_ready():
    print(f"{client.user} Silme Hakkı mesajlarını dinliyor")
    """
    Roblox'tan gelen web kancası mesajları için işleyici
    """
    @client.event
    async def on_message(message):
    # Mesajı ayrıştırır ve doğrular
    user_id, start_place_ids = message_parser.parse_message(message)
    if not user_id or not start_place_ids:
    return
    # Standart veri depolarındaki kullanıcı verilerini siler
    [successes, failures] = data_stores_api.delete_standard_data_stores(user_id, start_place_ids)
    if successes:
    await message.reply(f"Standart veri depolarındaki veriler silindi " +
    f"kullanıcı kimliği: {user_id}, veriler: {dict(successes)}")
    if failures:
    await message.reply(f"Standart veri depolarındaki verileri silme başarısız oldu " +
    f"kullanıcı kimliği: {user_id}, veriler: {dict(failures)}")
    # Sıralı veri depolarındaki kullanıcı verilerini siler
    [successes, failures] = data_stores_api.delete_ordered_data_stores(user_id, start_place_ids)
    if successes:
    await message.reply(f"Sıralı veri depolarındaki veriler silindi " +
    f"kullanıcı kimliği: {user_id}, veriler: {dict(successes)}")
    if failures:
    await message.reply(f"Sıralı veri depolarındaki verileri silme başarısız oldu " +
    f"kullanıcı kimliği: {user_id}, veriler: {dict(failures)}")
    client.run(bot_config.BOT_TOKEN)
    if __name__ == "__main__":
    run()
  3. bot_config.py dosyasında botun ana yapılandırması için:

    1. BOT_TOKEN'ı botunuz tarafından üretilen token ile ayarlayın.
    2. OPEN_CLOUD_API_KEY'i oluşturduğunuz API anahtarı olarak ayarlayın.
    3. ROBLOX_WEBHOOK_SECRET'i Creator Dashboard'da web kancasını yapılandırırken belirlediğiniz gizli anahtar olarak ayarlayın.
    4. Silinecek her kaydın veri deposunu bulmak için STANDARD_DATA_STORE_ENTRIES ve ORDERED_DATA_STORE_ENTRIES sözlüklerinde:
      1. Kopyaladığınız Başlangıç Yeri ID'lerini anahtar olarak ekleyin.
      2. Evrensel ID'leri, demetin ilk elemanı olarak ekleyin.
      3. Demetin ikinci elemanını, veri depolarınızın adı, kapsamı, giriş anahtarı adı ve ilişkili Kullanıcı ID'si ile değiştirin. Farklı bir veri şeması kullanıyorsanız, kendi veri şemanıza uyması için değiştirin.
  4. Botu çalıştırmak için aşağıdaki komutu yürütün:

    Discord Botunu Çalıştır
    python3 discord_bot.py
  5. Bot, silme hakkı talepleri için Roblox web kancalarını dinlemeye başlar ve ilgili veri deposunu silmek için Açık Bulut uç noktasını çağırır.

Test

Özel programınızın silme hakkı taleplerini düzgün bir şekilde işleyip PII verilerini silebildiğini doğrulamak için bir test mesajı oluşturabilir ve çalıştırabilirsiniz:

  1. Discord web kancası sunucunuza aşağıdaki istek gövdesi ile bir HTTP POST isteği gönderin:

    Örnek İstek
    curl -X POST {serverUrl}
    -H 'Content-Type: application/json'
    -d '{
    "embeds":[{
    "title":"SilmeHakkıTalebi",
    "description":"Kullanıcı Kimliği: {userIds} olan yeni bir Silme Hakkı bildirimi aldınız, oyun(lar) ile Kimlikler: {gameIds}",
    "footer":{
    "icon_url":"https://create.roblox.com/dashboard/assets/webhooks/roblox_logo_metal.png",
    "text":"Roblox-Signature: {robloxSignature}, Timestamp: {timestamp}"
    }
    }]
    }'
  2. Eğer bir web kancası gizli anahtarınız varsa:

    1. Web kancası gizli anahtarınıza HMAC-SHA256 kodlaması uygulayarak bir Roblox-Signature oluşturun.
    2. Timestamp olarak UTC zaman damgasını saniye cinsinden ayarlayın.
  3. description'ı aşağıdaki formatta birleştirin:

    Açıklama Alanı Formatı
    {Timestamp}. Kullanıcı Kimliği: {userId} olan yeni bir Silme Hakkı bildirimi aldınız, oyun(lar) ile Kimlikler: {gameIds}`.

    Örneğin:

    Örnek Açıklama Alanı
    1683927229. Kullanıcı Kimliği: 2425654247 olan yeni bir Silme Hakkı bildirimi aldınız, oyun(lar) ile Kimlikler: 10539205763, 13260950955

Programınız, mesajınızın resmi Roblox kaynağından geldiğini tanımlayabilmelidir, çünkü mesajı gizli anahtarınızla kodladınız. Ardından, talebinizle ilişkili PII verilerini silmelidir.

Örnek Gövde
{
"embeds": [
{
"title": "SilmeHakkıTalebi",
"description": "Kullanıcı Kimliği: 2425654247 olan yeni bir Silme Hakkı bildirimi aldınız, oyun(lar) ile Kimlikler: 10539205763, 13260950955",
"footer": {
"icon_url": "https://create.roblox.com/dashboard/assets/webhooks/roblox_logo_metal.png",
"text": "Roblox-Signature: UIe6GJ78MHCmU/zUKBYP3LV0lAqwWRFR6UEfPt1xBFw=, Timestamp: 1683927229"
}
}
]
}
©2026 Roblox Corporation. Roblox, the Roblox logo and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.