웹훅 알림

*이 콘텐츠는 AI(베타)를 사용해 번역되었으며, 오류가 있을 수 있습니다. 이 페이지를 영어로 보려면 여기를 클릭하세요.

게임에서 모든 이벤트와 사용자 요청을 수동으로 모니터링하는 대신, 웹훅을 설정하여 서드파티 메시징 도구나 HTTP 요청을 수신할 수 있는 사용자 지정 엔드포인트에서 실시간 알림을 받을 수 있습니다. 이를 통해 알림 관리 워크플로를 자동화하여 알림 처리의 수동 노력을 줄일 수 있습니다.

웹훅 워크플로

웹훅은 Roblox와 서드파티 메시징 도구와 같은 두 가지 서로 다른 애플리케이션 또는 서비스 간에 실시간 알림이나 데이터를 전송합니다. 전통적인 API와 달리, 클라이언트 애플리케이션을 설정하여 서버로 요청을 보내 데이터를 수신할 필요가 없이, 웹훅은 이벤트가 발생하는 즉시 클라이언트 엔드포인트에 데이터를 보냅니다. 이들은 팀과 협업하는 데 사용하는 서드파티 애플리케이션 간의 워크플로를 자동화하는 데 유용하며, 실시간 데이터 공유 및 처리를 가능하게 합니다.

웹훅을 설정하면, 타겟 이벤트가 발생할 때마다 Roblox는 제공한 웹훅 URL로 요청을 보냅니다. 그 후 웹훅 URL은 요청을 수신 애플리케이션 또는 사용자 지정 엔드포인트로 리다이렉트하며, 이는 웹훅 페이로드에 포함된 데이터를 기반으로 조치를 취할 수 있습니다. 여기에는 GDPR에 따른 데이터 삭제, 사용자에게 확인 메시지 전송, 또는 다른 이벤트를 트리거하는 것이 포함될 수 있습니다.

지원되는 트리거

Roblox는 현재 다음 이벤트 트리거를 지원합니다.

구독

  • 구독 재구독 - 사용자가 구독을 재구독할 때 구독 및 구독자 정보를 포함하는 메시지가 전송됩니다.
  • 구독 갱신 - 사용자가 구독을 갱신할 때 구독 및 구독자 정보를 포함하는 메시지가 전송됩니다.
  • 구독 환불 - 사용자가 구독에 대한 환불을 받을 때 구독 및 구독자 정보를 포함하는 메시지가 전송됩니다.
  • 구독 구매 - 사용자가 구독을 구매할 때 구독 및 구독자 정보를 포함하는 메시지가 전송됩니다.
  • 구독 취소 - 사용자가 구독을 취소할 때, 구독 및 구독자 정보, 그리고 취소 사유를 포함하는 메시지가 전송됩니다.

구독 이벤트 및 해당 필드에 대한 자세한 내용은 구독 참조를 참조하세요.

준수

상거래

  • 상거래 제품 주문 환불 - 사용자가 상거래 제품 주문에 대한 환불을 받았거나 주문이 취소된 경우.
  • 상거래 제품 주문 결제 - 사용자가 상거래 제품 주문을 결제한 경우. 중복 웹훅 이벤트가 발생할 수 있으므로 고유한 상거래 주문 ID를 사용해 이벤트를 중복 제거해야 합니다.

Creator Dashboard에서 웹훅 구성

웹훅을 통해 알림을 받으려면 특정 이벤트에 대한 알림을 트리거하기 위해 구독하는 웹훅을 구성해야 합니다. 그룹 소유 게임의 경우, 그룹 소유자만 웹훅 알림을 구성하고 받을 수 있습니다.

웹훅을 설정하려면:

  1. Creator Hub에서 경험을 선택합니다.

  2. 구성 아래에서 웹훅을 선택하고 웹훅 추가를 클릭합니다.

    웹훅 URL은 제공업체에서 가져옵니다. 예를 들어, Slack URL은 다음과 같이 보일 수 있습니다:


    https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
  3. 웹훅 URL과 이름을 입력합니다.

  4. (선택 사항) 비밀을 포함하여, 수신하는 알림이 Roblox에서 오는지 확인하는 데 도움이 됩니다. 더 자세한 내용은 웹훅 보안 확인을 참조하세요.

  5. 알림을 받고자 하는 지원되는 트리거 목록에서 하나 이상의 옵션을 선택합니다.

  6. (선택 사항) 테스트 응답 버튼을 사용하여 서비스가 샘플 요청을 수신할 수 있는지 확인합니다.

  7. 변경 사항 저장을 클릭합니다.

웹훅 URL 설정

웹훅 URL로 사용할 사용자 지정 HTTP 서비스 엔드포인트를 설정할 수 있으며, 다음 요구 사항을 충족해야 합니다:

  • 요청을 처리할 수 있도록 공개적으로 접근 가능해야 합니다.
  • POST 요청을 처리할 수 있어야 합니다.
  • 요청에 대해 5초 이내에 2XX 응답을 반환할 수 있어야 합니다.
  • HTTPS 요청을 처리할 수 있어야 합니다.

엔드포인트가 POST 요청을 수신하면 다음을 수행할 수 있어야 합니다:

  • POST 메시지 본문에서 알림에 대한 필요한 세부정보를 추출합니다.
  • POST 메시지 본문을 읽어서 알림에 대한 일반 세부정보와 이벤트 유형과 관련된 구체적인 세부정보를 포함합니다.

처리할 POST 요청의 스키마에 대한 자세한 내용은 페이로드 스키마를 참조하세요.

배달 실패 재시도 정책

웹훅 알림이 엔드포인트 불가 등의 오류로 인해 지정된 URL에 도달하지 못하면, Roblox는 구성된 URL로 메시지를 5번 재시도합니다. 5번의 시도 후에도 알림이 여전히 전달되지 않으면, Roblox는 더 이상 알림을 전송하려 하지 않고 URL이 더 이상 유효하지 않다고 가정합니다. 이 경우, 알림을 수신할 수 있는 새로운 URL로 웹훅 구성을 업데이트해야 합니다. 웹훅 URL이 성공적으로 알림을 수신할 수 있는지 확인하려면 웹훅 테스트를 참조하세요.

서드파티 요구 사항

서드파티 도구는 일반적으로 웹훅에 대한 자체 요구 사항이 있으며, 웹훅 URL을 설정할 때 따라야 합니다. 이러한 요구 사항은 대상 도구의 지원 또는 문서 사이트에서 "웹훅"이라는 키워드를 검색하여 찾을 수 있습니다. 지원되는 서드파티 도구는 다음과 같습니다:

웹훅 테스트

구성한 웹훅이 Creator Dashboard에서 알림을 성공적으로 수신할 수 있는지 테스트할 수 있습니다:

  1. 웹훅 구성 페이지로 이동합니다.
  2. 구성된 웹훅 목록에서 테스트하려는 웹훅을 선택합니다.
  3. 대상 웹훅 옆에 있는 연필 아이콘을 클릭합니다.
  4. 테스트 응답 버튼을 클릭합니다.

그러면 시스템이 SampleNotification 이벤트를 전송하며, 이 이벤트에는 알림을 트리거한 사용자의 사용자 ID가 포함됩니다. 아래와 같이 나타납니다:

SampleNotification 스키마

{
"NotificationId": "string",
"EventType": "SampleNotification",
"EventTime": "2023-12-30T16:24:24.2118874Z",
"EventPayload": {
"UserId": 1
}
}

서드파티 서비스와 웹훅을 통합하는 경우, 서비스를 확인하기 위해 서드파티 URL을 사용하여 알림을 성공적으로 수신할 수 있는지를 테스트할 수 있습니다. 웹훅 설정 시 비밀을 제공하면, roblox-signature도 생성되어 roblox-signature 로직을 테스트하는 데 사용할 수 있습니다.

웹훅 보안 확인

페이로드를 수신하도록 서버를 구성한 후, 이를 위해 엔드포인트로 전송되는 모든 페이로드를 수신하기 시작합니다. 웹훅 구성 시 비밀을 설정하면, Roblox는 각 웹훅 알림에 roblox-signature를 전송하여 요청이 실제로 Roblox에서 온 것인지 확인합니다. 서드파티 서버의 경우 페이로드 헤더에 서명이 포함되고, 사용자 지정 엔드포인트의 경우 푸터에 포함됩니다.

사용자 지정 엔드포인트를 위한 비밀이 포함된 서명 형식

t=<timestamp>,v1=<signature>

웹훅에 대한 비밀을 설정하지 않은 경우, 서명은 알림이 전송된 시간의 타임스탬프만 포함됩니다:

비밀이 없는 사용자 지정 엔드포인트를 위한 서명 형식

t=<timestamp>

서명을 확인하려면:

  1. 타임스탬프 및 서명 값을 추출합니다. 비밀이 있는 웹훅의 모든 서명은 다음 두 값이 콤마로 구분된 CSV 문자열의 같은 형식을 따릅니다:

    • t: 알림이 전송된 시간의 타임스탬프.
    • v1: Creator Dashboard 구성에서 제공한 비밀을 사용하여 생성된 서명 값.
  2. 다음을 연결하여 roblox-signature의 기본 문자열을 재구성합니다:

    1. 타임스탬프를 문자열로.
    2. 마침표 문자 ..
    3. 요청 본문의 JSON 문자열.
  3. 구성할 때 정의한 비밀을 키로 사용하여 SHA256 해시 함수를 사용해 HMAC을 계산하여 2단계에서 생성한 기본 문자열을 메시지로 변환합니다. 결과를 Base64 형식으로 변환하여 예상 서명을 얻습니다.

  4. 추출한 서명 값을 예상 서명과 비교합니다. 서명을 올바르게 생성했다면, 값이 같아야 합니다.

  5. (선택 사항) 재생 공격을 방지하기 위해, 해커가 데이터를 가로채고 재전송하여 무단 접근을 얻거나 악의적인 행동을 수행하는 사이버 공격의 일종으로, 추출한 타임스탬프 값을 현재 타임스탬프와 비교하여 합리적인 시간 제한 내에 있는지 확인하는 것이 좋습니다. 예를 들어, 10분 정도의 창은 일반적으로 합리적인 시간 제한으로 좋습니다.

페이로드 스키마

웹훅의 타겟 이벤트가 트리거되면 웹훅 URL로 요청을 전송하며, 페이로드 내에 이벤트에 대한 정보가 포함됩니다. 모든 요청의 페이로드는 고정 필드와 가변 필드로 구성된 동일한 스키마를 공유합니다. 이는 페이로드에 전송되는 데이터가 구조화되고 일관성을 유지하도록 하여 수신 애플리케이션이 데이터를 처리하고 사용하는 데 용이하게 합니다.

고정 페이로드 스키마 필드는 모든 웹훅 요청에서 일관성을 유지하는 데 도움을 주며, 사용 가능한 필드는 다음과 같습니다:

  1. NotificationId (string): 전송된 각 알림에 대한 고유 식별자. 동일한 NotificationId가 두 번 수신되면 중복으로 간주됩니다.
  2. EventType (string): 알림이 트리거된 이벤트 유형을 나타냅니다.
  3. EventTime (string): 이벤트가 트리거된 시간의 타임스탬프입니다.

가변 페이로드 스키마 필드는 다양한 유형의 이벤트를 수용하기 위해 웹훅에 유연성을 제공하며, 다음을 포함합니다:

  1. EventPayload (object): 웹훅을 트리거한 EventType에 대한 정보를 포함합니다. EventPayload 스키마의 구조는 이벤트 유형에 따라 달라집니다.

다음 예시는 삭제 요청 권리 이벤트의 페이로드 스키마를 보여줍니다:

삭제 요청을 위한 예시 스키마

{
"NotificationId": "string",
"EventType": "RightToErasureRequest",
"EventTime": "2023-12-30T16:24:24.2118874Z",
"EventPayload": {
"UserId": 1,
"GameIds": [
1234, 2345
]
}
}

알림 처리

사용자의 사용자 ID와 같은 **개인 식별 정보 (PII)**를 저장하는 경우, 사용자가 GDPR 삭제 요청 권리 준수 요구 사항에 따라 그러한 요청을 제출할 때 이 정보를 삭제해야 합니다. 웹훅 알림을 처리하고 데이터 삭제를 자동화하는 봇을 생성할 수 있으며, 제공하는 데이터 저장소에 PII를 저장하는 경우 가능합니다. Discord 내에서 Open Cloud API for data stores를 사용하여 PII 데이터를 삭제하는 봇을 만드는 방법에 대한 예제를 보려면 삭제 요청 자동화를 참조하십시오. 이 예제는 구독 이벤트와 같은 다른 알림을 처리하는 데 적응할 수 있습니다.

서드파티 도구 대신 사용자 지정 엔드포인트를 웹훅 서버로 사용하는 경우, 웹훅 페이로드에서 삭제 대상 데이터를 추출하고 자신만의 자동화 솔루션을 구축할 수 있습니다. 다음 코드 샘플은 로블록스에서 오는 요청임을 확인하고 타임스탬프를 검증하여 재생 공격을 방지하는 서버의 예입니다:

페이로드에서 PII 추출

const crypto = require('crypto');
const express = require('express');
const secret = '<your_secret>' // 이를 환경 변수로 설정할 수 있습니다.
let app = express();
app.use(express.json());
app.all('/*', function (req, res) {
console.log('새 요청 수신');
// 헤더에서 타임스탬프 및 서명 추출
const signatureHeader = req.headers['roblox-signature'].split(',');
const timestamp = signatureHeader.find(e => e.startsWith('t=')).substring(2);
const signature = signatureHeader.find(e => e.startsWith('v1=')).substring(3);
// 재생 공격을 방지하기 위한 요청이 300초 이내에 수신되었는지 확인합니다.
const requestTimestampMs = timestamp * 1000;
const windowTimeMs = 300 * 1000;
const oldestTimestampAllowed = Date.now() - windowTimeMs;
if (requestTimestampMs < oldestTimestampAllowed) {
return res.status(403).send('만료된 요청');
}
// 서명 검증
const message = `${timestamp}.${JSON.stringify(req.body)}`;
const hmac = crypto.createHmac('sha256', secret);
const calculatedSignature = hmac.update(message).digest('base64');
if (signature !== calculatedSignature) {
return res.status(401).send('인증되지 않은 요청');
}
// 페이로드 처리 로직
const payloadBody = req.body;
const eventType = payloadBody['EventType'];
if (eventType === 'RightToErasureRequest'){
const userId = payloadBody['EventPayload']['UserId'];
const gameIds = payloadBody['EventPayload']['GameIds'];
console.log(`페이로드 데이터: UserId=${userId} 및 GameIds=${gameIds}`);
// 데이터 저장소에 PII를 저장하는 경우, UserId 및 GameIds를 사용하여 데이터 저장소에서 정보를 삭제하십시오.
}
return res.json({ message: '메시지를 성공적으로 처리했습니다.' });
});
app.listen(8080, function () {
console.log('서버 시작됨');
});
©2026 Roblox Corporation. Roblox 및 Roblox 로고, 'Powering Imagination'은 미국 및 기타 국가 내 당사의 등록 및 미등록 상표입니다.