การเพิกถอนสิทธิ์โดยอัตโนมัติ

*เนื้อหานี้แปลโดยใช้ AI (เวอร์ชัน Beta) และอาจมีข้อผิดพลาด หากต้องการดูหน้านี้เป็นภาษาอังกฤษ ให้คลิกที่นี่

ความเป็นส่วนตัว(GDPR) เป็นกฎหมายการคุ้มครองข้อมูลส่วนบุคคลของยุโรป มันให้สิทธิให้ผู้ใช้ร้องขอให้ข้อมูลส่ว

แทนที่จะจัดการคำขอด้วยมือโดยใช้คำขอแบบเรียกแห่งเวลา คุณสามารถ ติดตั้งปลั๊กอินเว็บhook และใช้บอทในแอปพลิเคชันของบุคคลที

กระบวนการ

เมื่อเสร็จสิ้นการดูแลตัวอักษรในวิดีโอนี้คุณควรสามารถสร้างโปรแกรมที่ดำเนินการในพื้นที่เดียวที่จัดการการจัดการของตัวอักษรโดยอัตโนมัติจากผู้ใช้ กระบวนการนี้เป็นด้วยวิธีต่อไปนี้:

  1. Roblox Support ได้รับสิทธิ์ในการลบข้อมูลจากผู้ใช้
  2. เว็บไซต์ของ Roblox จะถูกเรียกใช้ โดยมี User ID และรายการ Start Place IDs สำหรับประสบการณ์ที่พวกเขาเข้าร่วมในโหลด
  3. บอทของคุณฟังสำหรับการแจ้งเตือนเหล่านี้ของ webhook ตรวจสอบความถูกต้องของพวกเขาและใช้ เปิด API เมฆสำหรับคลังข้อมูลเพื่อเก็บข้อมูลในคลังข้อมูล เพื่อลบข้อมูล PII ที่เก็บไว้ในคลังข้อมูล
  4. บอทตอบสนองต่อข้อความ webhook ใน Discord หรือ Guilded ด้วยสถานะการลบ

การกำหนดค่า Webhook ด้วยการผสานของบุคคลที่สาม

ก่อนสร้างบอทให้ตั้งค่าเซิร์ฟเวอร์ด้วยการใช้งาน webhook บนแอปพลิเคชันการส่งข้อความระหว่างผู้สร้างกับผู้ใช้ จากนั้นใช้เซิร์ฟเวอร์เพื่อกำหนด webhook ใน Dashboard ของผู้สร้าง

การติดตั้งเซิร์ฟเวอร์

ขั้นตอนต่อไปแสดงให้เห็นวิธีการติดตั้งเซิร์ฟเวอร์โดยใช้ Guilded หรือ Discord

  1. สร้างเซิร์ฟเวอร์ใหม่ หากคุณไม่คุ้นเคยกับกระบวนการนี้ให้ดู การสนับสนุนแบบกิลด์
  2. ภายใต้การตั้งค่า ความเป็นส่วนตัว ให้เซิร์ฟเวอร์เป็นส่วนตัว เซิร์ฟเวอร์จะสร้างช่อง # ส่วนตัวโดยอัตโนมัติเป็นช่องเริ่มต้นของคุณ
  3. สร้างการผสาน webhook กับเซิร์ฟเวอร์ใหม่และให้ชื่อที่คุณสามารถเข้าใจได้อย่างง่ายดายเช่น GDPR Hook หากคุณไม่คุ้นเคยกับกระบวนการนี้ให้ดู การสนับสนุนของกิลด์
  4. คัดลอก URL ของ webhook และเก็บไว้ในสถานที่ที่ปลอดภัย อนุญาตให้สมาชิกทีมที่ไว้วางใจเท่านั้นที่เข้าถึงได้ เนื่องจากการเปิดเผย URL สามารถเปิดเผยข้อความปลอมและอาจลบข้อมูลผู้ใช้ของคุณ

การกำหนดค่า Webhook บน Roblox

หลังจากได้รับ URL ของเซิร์ฟเวอร์บุคคลที่สาม, ใช้มันเพื่อ กำหนดเวลาเรื่องกิจกรรมของเว็บไซต์ ใน แดชบอร์ดครีเอเตอร์โปรดทำตามการตั้งค่าต่อไปนี้:

  • เพิ่ม URL เซิร์ฟเวอร์ Guilded หรือ Discord เป็น URL เว็บของของเรา * รวมถึงรหัสลับ ที่ซ่อนอยู่ แม้ว่ารหัสลับจะเป็นตัวเลือกสำหรับการเสร็จสิ้นการกำหนดค่า แต่คุณควรรวมอย่างน้อยหนึ่งรหัสเพื่อป้องกันการปลอมตัวของ Roblox และการลบข้อมูล
  • เลือก สิทธิ์ในการลบข้อมูลของฉัน ภายใต้ การเรียกร้องของการลบข้อมูล คุณสามารถทดสอบข้อมูลเกี่ยวกับเว็บไซต์ของคุณโดยใช้ปุ่ม ตอบกลับการทดสอบ เพื่อดูว่าคุณจะได้รับการแจ้งเตือนในช่อง # general ของเซิร์ฟเวอร์จาก Roblox หากคุณไม่ได้รับก
Example notification on Guilded

การกำหนดตัวบอท

หลังจากเพิ่มตัวแปร webhook ให้ใช้มันเพื่อกำหนดบอทด้วยขั้นตอนต่อไปนี้:

  1. เปิดรายการ เซิร์ฟเวอร์ทั้งหมด โดยการคลิกไอคอนของมันหรือใช้ทางลัด:

    • CtrlS บน Windows
    • S บน Mac
  2. เลือกเซิร์ฟเวอร์ของคุณเพื่อรับการแจ้งเตือนเมื่อถูกลบ

  3. ขยายรายการใต้ หน้าเวิร์เตอร์ และเลือก จัดการบอท

  4. เซิร์ฟเวอร์จะสร้างช่อง # general เป็นช่องปกติของคุณโดยอัตโนมัติ

  5. คลิกปุ่ม สร้างบอท และเพิ่มชื่อบอท ปุ่มนี้จะเปลี่ยนคุณเป็นเซิร์ฟเวอร์บอทที่การีนามคุณไปยังหน้าการกำหนดค่าบอท

  6. เลือกส่วน API บนหน้าการกำหนดค่าบอท

  7. ในส่วน โทเค็น คลิกปุ่ม สร้างโทเค็น

  8. บันทึกและเก็บตั๋วที่สร้างขึ้นในสถานที่ที่ปลอดภัย

การสร้างรหัส คีย์ API

เพื่อให้บอทของบุคคลที่สามของคุณสามารถเข้าถึงข้อมูลของคุณเพื่อเก็บข้อมูล ข้อมูลที่ใช้ระบุตัวบุคคลได้ (PII)ของผู้ใช้ได้, สร้างกุญแจ Open Cloud API ที่สามารถ

รับรหัสของประสบการณ์และสถานที่

สำหรับบอทที่จะค้นหาข้อมูล PII ที่ต้องการโดยผู้ใช้สำหรับการลบรับรหัสตัวตนของทุกประสบการณ์ที่คุณตั้งใจจะใช้บอทสำหรับ:

  • รหัสจักรวาล ซึ่งเป็นรหัสอธิบายอย่างเฉพาะของประสบการณ์ของคุณ
  • ตัวระบุสถานที่เริ่มต้น ซึ่งเป็นรหัสไม่ซ้ำกันของสถานที่เริ่มต้นของประสบการณ์

เพื่อรับรหัสเหล่านี้ให้เปิดหน้า สร้าง ที่ ครีเอเตอร์ดาชาร์ดเดสก์ แล้วเลือกประสบการณ์และคัดลอก รหัสจักรวาล และ 2>สถานที่เริ่มต้น2>

Copy Universe ID and Copy Start Place ID options from Creator Dashboard

การเพิ่มสคริปต์

หลังจากที่คุณเสร็จสิ้นการติดตั้ง webhook, bot, และ API Key สำหรับคลังข้อมูลข้อมูล, เพิ่มพวกเขาในสคริปที่เรียกใช้โลจิกส์อัตโนมัติของบอท ตัวอย่างต่อไปใช้ Python 3:

  1. ติดตั้งห้องสมุด Python โดยใช้คำสั่งต่อไปนี้:

    ติดตั้งห้องสมุด

    pip3 install discord
    pip3 install guilded.py==1.8.0
    pip3 install requests
    pip3 install urllib3==1.26.6
  2. คัดลอกและบันทึกสคริปต์ต่อไปนี้ที่เกี่ยวข้องกับแต่ละส่วนของโบร็ตโลจิกในไดเรกทอรีเดียวกัน:

    bot_config.py

    DISCORD_BOT_TOKEN = ""
    GUILDED_BOT_TOKEN = ""
    OPEN_CLOUD_API_KEY = ""
    ROBLOX_WEBHOOK_SECRET = ""
    # พจนานุกรมของ Start ที่
    # (รหัสจักรวาล, รายการ (ชื่อเก็บข้อมูล, ขอบเขต, คีย์)) สำหรับ
    # ห้องเก็บข้อมูลมาตรฐาน
    # ข้อมูลผู้ใช้ที่เก็บไว้ภายใต้รายการเหล่านี้จะถูกลบออก
    STANDARD_DATA_STORE_ENTRIES = {
    # รหัสสถานที่เริ่มต้น
    111111111: (
    # รหัสจักรวาล
    222222222,
    [
    ("StandardDataStore1", "Scope1", "Key1_{user_id}"),
    ("StandardDataStore1", "Scope1", "Key2_{user_id}"),
    ("StandardDataStore2", "Scope1", "Key3_{user_id}")
    ]
    ),
    33333333: (
    444444444,
    [
    ("StandardDataStore3", "Scope1", "Key1_{user_id}")
    ]
    )
    }
    # พจนานุกรมของ Start ที่
    # (รหัสจักรวาล, รายการ (ชื่อเก็บข้อมูล, ขอบเขต, คีย์)) สำหรับ
    # ร้านค้าข้อมูล
    # ข้อมูลผู้ใช้ที่เก็บไว้ภายใต้รายการเหล่านี้จะถูกลบออก
    ORDERED_DATA_STORE_ENTRIES = {
    111111111: (
    222222222,
    [
    ("OrderedDataStore1", "Scope2", "Key4_{user_id}")
    ]
    )
    }
    data_stores_api

    import requests
    import bot_config
    from collections import defaultdict
    """
    Calls Data Stores Open Cloud API to delete all entries for a user_id configured in
    STANDARD_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:
    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
    """
    Calls Ordered Data Stores Open Cloud API to delete all entries for a user_id configured in
    ORDERED_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:
    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
    ข้อความ_ผู้ประมวลผล.py

    import time
    import hmac
    import hashlib
    import re
    import base64
    import bot_config
    """
    Parses received message for Roblox signature and timestamp, the footer is only set if you
    configured webhook secret
    """
    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
    """
    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 วินาที
    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
    # รับรองลายเซ็น
    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
    # ตราที่ถูกต้อง
    return True
    """
    Parses a received webhook messaged on Discord or Guilded. Extracts user ID, prevents replay attack
    based on timestamp received, and verifies Roblox signature with configured secret to check for
    validity.
    """
    def parse_message(message):
    # รับข้อความสำหรับ ID ผู้ใช้และ ID เกม
    if 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_ids
    else:
    return "", []
    guilded_bot.py

    import guilded
    import json
    import bot_config
    import data_stores_api
    import message_parser
    def run():
    client = guilded.Client()
    @client.event
    async def on_ready():
    print(f"{client.user} is listening to Right to Erasure messages")
    """
    Handler for webhook messages from Roblox
    """
    @client.event
    async def on_message(message):
    # รับและตรวจสอบข้อความ
    user_id, start_place_ids = message_parser.parse_message(message)
    if not user_id or not start_place_ids:
    return
    # ลบข้อมูลผู้ใช้จากระเบียนผู้ใช้
    [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)}")
    # ลบข้อมูลที่เก็บไว้ของผู้ใช้
    [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()
  3. ในไฟล์ bot_config.py สำหรับการกำหนดค่าหลักของบอท:

    1. ตั้ง DISCORD_BOT_TOKEN หรือ GUILDED_BOT_TOKEN ให้เป็นโทเค็นที่สร้างโดยบอตของคุณ
    2. ตั้ง OPEN_CLOUD_API_KEY ให้เป็นรหัส API ที่คุณสร้างขึ้น
    3. ตั้ง ROBLOX_WEBHOOK_SECRET แดชบอร์ดครีเอเตอร์บนหน้าผู้ใช้
    4. ใน STANDARD_DATA_STORE_ENTRIES และ ORDERED_DATA_STORE_ENTRIES พจนานุกรมสำหรับการค้นหาคลังข้อมูลของแต่ละบันทึกเพื่อลบ:
      1. เพิ่มรหัส Start Place ที่คุณเคยคัดลอกเป็นสี่สัญลักษณ์
      2. เพิ่มรหัสจักรวาลเป็นองค์ประกอบแรกของค่าตัวต้นแบบ
      3. แทนส่วนที่สองของตารางด้วยชื่อ ขอบเขต ชื่อกุญแจเข้าถึง และรหัสผู้ใช้ที่เกี่ยวข้องของร้านค้าข้อมูลของคุณ หากคุณใช้รูปแบบข้อมูลที่แตกต่างกันโปรดปรับแต่งตามลำดับตามลำดับตามลำดับตามลำดับตามลำ
  4. ประเภทคำสั่งต่อไปนี้เพื่อดำเนินการบอท:

    ดำเนินการบอทกิลด์

    python3 guilded_bot.py
  5. บอทจะเริ่มต้นที่จะฟังและยืนยัน Roblox webhook สำหรับสิทธิ์ในการลบขอและโทรที่ Open Cloud ร้านค้า

การทดสอบ

คุณสามารถสร้างและดำเนินการข้อความทดสอบเพื่อยืนยันว่าโปรแกรมของคุณสามารถจัดการกับคำขอลบที่เหมาะสมและลบข้อมูล PII ได้:

  1. ส่งคำขอ HTTP POST ไปยังเซิร์ฟเวอร์ของคุณ Guilded หรือ Discord webhook ร่างกาย:

    คำขอตัวอย่าง

    curl -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}"
    }
    }]
    }'
  2. หากคุณมีคําสั่งเว็บขูกขั้นสูง:

    1. สร้าง Roblox-Signature โดยการใช้การเข้ารหัส HMAC-SHA256 คีย์
    2. ตั้งเวลาปัจจุบันโดยใช้เวลายืนยัน UTC ในวินาทีเป็น Timestamp
  3. วาง คำอธิบาย ในรูปแบบต่อไปนี้:

    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}`.

    เช่น:

    Example Description Field

    1683927229. You have received a new notification for Right to Erasure for the User Id: 2425654247 in the game(s) with Ids: 10539205763, 13260950955

โปรแกรมของคุณควรสามารถระบุได้ว่าข้อความของคุณมาจากที่ที่ Roblox ทางการแล้วเนื่องจากคุณเข้ารหัสข้อความด้วยความลับของคุณ จึงควรลบข้อมูล PII ที่เกี่ยวข้องกับคำขอของคุณ

ตัวอย่างบอดี้

{
"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/dash/ assets/webhook/roblox_logo_metal.png",
"text": "Roblox-Signature: UIe6GJ78MHCmU/zUKBYP3LV0lAqwWRFR6UEfPt1xBFw=, Timestamp: 1683927229"
}
}
]
}