주요 콘텐츠로 건너뛰기

플레이어 검증 웹훅

Aghanim은 플레이어 검증 웹훅을 활용하여 플레이어 로그인에 대한 정보를 게임에 알리고, 게임 허브에 대한 액세스를 허용하거나 거부하기 위해 웹훅 서버에서 확인을 요구합니다. 이 문서는 이러한 웹훅의 운영에 대한 정보를 제공합니다.

웹훅은 게임에서 플레이어의 등록을 확인하고 Game Hub와의 플레이어 상호작용 중 여러 번 호출될 수 있습니다.

플레이어 흐름 이미지 확인
플레이어 흐름 이미지 확인

요구 사항

Aghanim에서 플레이어 검증 웹훅을 사용하려면 다음과 같이 웹훅 서버를 구성해야 합니다:

구성

다음은 Aghanim에서 생성한 플레이어 검증 이벤트를 처리하는 엔드포인트용 함수 템플릿입니다:

import fastapi, hashlib, hmac, json, typing 

app = fastapi.FastAPI()

@app.post("/webhook")
async def webhook(request: fastapi.Request) -> dict[str, typing.Any]:
secret_key = "<YOUR_S2S_KEY>" # 실제 웹훅 비밀 키로 교체하세요

raw_payload = await request.body()
payload = raw_payload.decode()
timestamp = request.headers["x-aghanim-signature-timestamp"]
received_signature = request.headers["x-aghanim-signature"]

if not verify_signature(secret_key, payload, timestamp, received_signature):
raise fastapi.HTTPException(status_code=403, detail="Invalid signature")

data = json.loads(payload)
event_type = data["event_type"]
event_data = data["event_data"]

if event_type == "player.verify":
player_data = verify_player(event_data)
if not player_data:
raise fastapi.HTTPException( status_code=401, detail="Player verification failed")
return player_data

raise fastapi.HTTPException(status_code=400, detail="Unknown event type")

def verify_signature(secret_key: str, payload: str, timestamp: str, received_signature: str) -> bool:
signature_data = f"{timestamp}.{payload}"
computed_hash = hmac.new(secret_key.encode(), signature_data.encode(), hashlib.sha256)
computed_signature = computed_hash.hexdigest()
return hmac.compare_digest(computed_signature, received_signature)

def verify_player(event_data: dict[str, typing.Any]) -> dict[str, typing.Any]:
# 플레이어 데이터를 가져오는 데 사용되는 자리 표시자 로직입니다.
# 실제 애플리케이션에서는 이 함수가 데이터베이스나 사용자 관리 시스템과 상호작용합니다.
return {
"player_id": "r2d2-c3po",
"name": "Molly",
"attributes": {"level": 2},
"country": "US"
}

함수가 준비되면:

  1. 엔드포인트를 사용 가능하게 설정하세요.
  2. Aghanim 계정 내에서 엔드포인트를 등록하세요 → 게임웹훅새로운 웹훅에서 플레이어 검증 이벤트 유형을 선택하여 등록하세요.

대안으로, 웹후크 생성 API 방법을 사용하여 Aghanim 내에서 엔드포인트를 등록할 수 있습니다.

요청 스키마

아래는 예시입니다 player.verify 웹훅 요청:

POST /your/webhook/uri HTTP/1.1
Content-Type: application/json
Host: your-webhook-endpoint.com
User-Agent: Aghanim/0.1.0
X-Aghanim-Signature: 2e45ed4dede5e09506717490655d2f78e96d4261040ef48cc623a780bda38812
X-Aghanim-Signature-Timestamp: 1725548450

{
"event_type": "player.verify",
"event_data": {
"player_id": "2D2R-OP3C"
},
"event_time": 1725548450,
"event_id": "whevt_eCacGbJVbvToOgzjXUgOCitkQE",
"idempotency_key": null,
"request_id": "d1593e9c-c291-4004-8846-6679c2e5810b",
"sandbox": false,
"trigger": "hub.login",
"transaction_id": "whtx_eCacGbJVbvT",
"context": null,
"game_id": "gm_exTAyxPsVwh"
}

이벤트 스키마

Key유형설명
event_idstringAghanim에 의해 생성된 고유 이벤트 ID.
game_idstringAghanim 시스템에서의 귀하의 게임 ID.
event_typestring이벤트의 유형, player.verify 이럴 경우.
event_timenumber유닉스 에포크 시간으로 된 이벤트 날짜.
event_dataEventData이벤트 특정 데이터가 포함되어 있으며, 상속된 객체에 대한 가능한 키가 포함됩니다.
idempotency_keystring|null웹훅 작업이 재시도되어도 한 번만 실행되도록 보장합니다. 일 수 있습니다 null 이벤트 유형에 따라 달라집니다.
request_idstring|null이벤트가 API 요청에 의해 트리거된 경우, 요청 ID가 포함됩니다.
sandboxboolean이 이벤트가 샌드박스 게임 환경에서 전송되었는지를 표시합니다.
triggerstring|nullThe trigger that caused the event to be sent.
transaction_idstringAghanim이 생성한 거래 ID입니다. 이 ID는 동일한 거래 내에서 발생한 여러 이벤트에서 동일할 수 있습니다.
contextobject|null이벤트에 대한 컨텍스트 정보.

EventData 스키마

Key유형설명
player_idstring플레이어 인증을 위해 선택된 고유한 플레이어 ID.

트리거 값

설명
hub.login플레이어가 게임 허브를 열 때.
hub.interact플레이어가 이전 방문 후 6시간 뒤에 데이터를 새로 고치기 위해 허브로 돌아올 때.
hub.purchase플레이어가 상점에서 구매 버튼을 클릭하여 아이템이 여전히 사용 가능한지 플레이어의 속성 기준으로 확인할 때.
order.captured구매 시점에 플레이어의 속성을 기반으로 해당 아이템이 여전히 사용 가능한지 확인하기 위해.
hub.store.open상점이 열릴 때, 상점 규칙에 플레이어 검증 작업이 포함되어 있는 경우.
liveops.execute_actionLiveOps 작업이 실행될 때.
testDashboard에서 "Send test event"를 사용할 때.

응답 스키마

player.verify 웹훅을 수신하면 서버는 적절한 HTTP 상태 코드와 JSON 페이로드로 응답해야 합니다.

성공 응답

플레이어가 성공적으로 확인되면 플레이어 데이터가 포함된 JSON 페이로드와 함께 2xx 상태 코드를 반환합니다:

Key유형설명필수 여부
player_idstring플레이어 인증을 위해 선택된 고유한 플레이어 ID.
namestring플레이어의 닉네임.
attributesAttributesAghanim이 기대하는 기본 플레이어 속성.
avatar_urlstring플레이어의 아바타 URL.아니오
emailstring플레이어의 이메일 주소.아니오
bannedboolean플레이어가 게임에서 금지되었는지 여부를 나타냅니다.아니오
segmentsstring[]플레이어가 속한 세그먼트.아니오
countrystringISO 3166‑1에 따른 두 자리 국가 코드.아니오
custom_attributesCustomAttributes사용자 정의 플레이어 속성.아니오
balancesBalance[]플레이어의 재화 잔액.아니요

Balance 객체

Balance 객체는 다음 필드를 포함합니다:

Key유형설명필수 여부
skustring재화와 연동된 아이템 SKU가 게임 측과 Aghanim 측 모두에서 일치해야 합니다.
quantitynumber플레이어의 화폐 잔액입니다.

Attributes 객체

Attributes 객체는 다음 필드를 포함합니다:

Key유형설명필수 여부
levelnumber게임에서 플레이어의 레벨.
platformstring플레이어가 게임 허브를 사용하는 플랫폼입니다. 가능한 값: ios, android.아니요
marketplacestring플레이어 유입 경로로 사용된 마켓플레이스. 가능한 값: app_store, google_play, other.아니오
soft_currency_amountnumber플레이어의 소프트 재화 잔액.아니오
hard_currency_amountnumber플레이어의 하드 재화 잔액.아니요

CustomAttributes 객체

CustomAttributes 객체에는 키-값 쌍이 포함되어 있습니다. 예:

{
"is_premium": true,
"age": 25,
"favorite_color": "blue",
"install_date": 1704070800
}

이러한 속성은 나중에 특정 플레이어 세그먼트를 타겟으로 하기 위해 LiveOps 또는 세분화 에서 로직 조건을 구성할 때 사용될 수 있습니다.

경고

중요: 사용자 정의 속성은 게임플레이어 속성에서 선언해야 합니다.

성공적인 응답 예시

{
"player_id": "2D2R-OP3C",
"name": "비비에이트",
"avatar_url": "https://static-platform.aghanim.com/images/bb8.jpg",
"attributes": {"level": 2},
"country": "US"
}

오류 응답

플레이어 확인에 실패하면 서버는 다음 JSON 구조와 함께 4xx 상태 코드를 반환해야 합니다:

{
"status": "error",
"code": "<error_code>",
"message": "<optional human-readable description>"
}

Aghanim은 오류를 어떻게 처리할지 결정하기 위해 code 필드를 사용합니다. message 필드는 선택 사항이며 로깅 목적으로만 사용됩니다.

HTTP 상태코드설명Hub 동작
403player_banned플레이어가 게임에서 차단되었습니다.강제 로그아웃. 플레이어에 표시: "게임 계정이 정지되었습니다."
404player_not_found플레이어가 존재하지 않습니다.강제 로그아웃. 플레이어에 표시: "게임 계정을 찾을 수 없습니다. 게임을 통해 다시 로그인해 주세요."
410player_deleted플레이어는 이전에 존재했지만 삭제되었습니다.강제 로그아웃. 플레이어에 표시: "게임 계정이 더 이상 활성화되어 있지 않습니다."
422player_not_eligible플레이어가 Hub에 액세스하기 위한 요구 사항(예: 레벨, 플레이 시간, 완료한 퀘스트)을 충족하지 못했습니다.로그아웃 없이 액세스를 차단합니다. 플레이어에 표시: "아직 Hub를 잠금 해제하지 않았습니다. 계속 플레이해서 액세스 권한을 획득하세요!"

오류 응답 예시

{
"status": "error",
"code": "player_banned",
"message": "Player is banned"
}
{
"status": "error",
"code": "player_not_eligible",
"message": "Player has not reached the required level"
}
경고

Aghanim은 위에서 설명한 예상 JSON 형식과 일치하는 오류 응답에만 동작합니다. 응답 본문이 유효한 JSON이 아니거나 code 필드를 포함하지 않으면(예: Cloudflare, WAF 또는 리버스 프록시가 반환한 HTML 오류 페이지) Aghanim은 이를 인프라 수준 오류로 처리하며 플레이어를 강제 로그아웃하지 않습니다.

서버 오류

예기치 않은 서버 측 장애(예: 데이터베이스를 사용할 수 없음, 내부 예외)에 대해서만 5xx 상태 코드를 반환합니다. 플레이어 수준의 확인 결과를 전달하기 위해 5xx 코드를 사용하지 마세요. Aghanim은 5xx 응답을 받은 player.verify 요청을 재시도하지 않습니다.

도움이 필요하세요?
통합팀에 문의하십시오 [email protected]