페이지 가져오기 웹훅
page.get 웹훅은 Game Hub 페이지의 레이아웃, 즉 렌더링할 블록의 행과 선택적으로 그 블록을 채울 스토어 아이템을 가져옵니다. 페이지 내용을 Hub Builder에서 구성하는 대신 게임 로직으로 결정하려는 경우에 유용합니다.
이 웹훅은 page.get 웹훅에 연결된 페이지를 플레이어가 열 때 트리거됩니다. 이러한 페이지는 자체 블록을 갖지 않습니다. Aghanim에 저장된 블록은 항상 비어 있으며, 플레이어에게 보이는 것은 고객사 서버가 반환한 레이아웃입니다.
이 웹훅은 구매를 검증하는 동안에도 요청되어, 플레이어가 구매하려는 아이템이 동일한 조건으로 여전히 판매 중인지 확인합니다. 그러한 요청에서는 레이아웃이 무시되고 아이템만 사용됩니다.
요구 사항
Aghanim의 page.get 웹훅을 사용하려면 웹훅 서버를 다음과 같이 구성해야 합니다:
- POST 웹훅 요청을 수락하는 HTTPS 엔드포인트.
- Aghanim이 생성하고 서명한 이벤트를 수신합니다.
- 성공적으로 처리되었음을 알리려면 2xx 상태 코드로, 거부 또는 오류의 경우 4xx 또는 5xx로 응답합니다.
- 10초 이내에 응답합니다. 플레이어가 페이지를 기다리는 동안 웹훅이 요청됩니다.
- 요청을 동기적으로 처리합니다.
player.verify,store.get,daily_reward.get과 마찬가지로page.get은 단일 시도로 전달되며 재시도 일정의 적용 대상이 아닙니다.
구성
page.get웹훅 처리를 위한 함수를 개발합니다.- 엔드포인트를 사용 가능하게 설정합니다.
- Aghanim 계정 내에서 Game → Webhooks → Add webhook에서
page.get이벤트 유형을 선택하여 엔드포인트를 등록합니다. - Game Hub Builder의 섹션 설정에서 Advanced → Webhook으로 웹훅을 선택하면 페이지가 그 웹훅에서 레이아웃을 받아옵니다.
이 설정은 섹션 사이드바 하단의 Add section으로 열 수 있으며, 이 경우 페이지 생성과 웹훅 선택이 한 번에 이루어집니다. 기존 섹션은 해당 행의 ⋯ 메뉴 → Edit로 엽니다. 웹훅을 연결하면 해당 페이지에 만든 블록은 삭제되며 복구할 수 없습니다.
또는, Create Webhook API 방법으로 Aghanim 내에서 엔드포인트를 등록하고, Update Page API 방법으로 webhook_id를 설정하여 페이지를 연결할 수 있습니다. 페이지 응답의 layout_source 필드는 읽기 전용입니다.
응답은 캐시되지 않습니다. 웹훅은 페이지를 볼 때마다 요청되므로 레이아웃을 플레이어별, 요청별로 다르게 할 수 있습니다.
트리거 값
| 값 | 설명 |
|---|---|
hub.page.open | 플레이어가 웹훅 레이아웃 페이지를 열 때. |
hub.purchase | 플레이어가 이 웹훅에서 온 아이템의 구매를 시작할 때. |
order.captured | 해당 아이템의 결제가 확정될 때. |
test | Dashboard에서 "Send test event"를 사용할 때. |
hub.purchase와 order.captured에서는 요청에 페이지 정보가 포함되지 않습니다. id와 slug는 비어 있으며, Aghanim은 응답의 아이템만 모든 블록에서 한 번에 읽습니다. 플레이어에게 보여준 것과 동일한 아이템을 동일한 조건으로 반환하세요. 응답에 없는 아이템이나 조건이 다른 아이템은 구매에 실패합니다.
페이지가 없으면 Aghanim은 어떤 웹훅이 레이아웃을 제공했는지 알 수 없어 게임에서 활성화된 첫 번째 page.get 웹훅에 요청합니다. 웹훅이 여러 개인 게임에서는 페이지를 제공하지 않은 웹훅으로 구매가 검증될 수 있습니다.
page.get이 다른 이벤트 유형과 어떻게 관련되는지에 대해서는 전체 이벤트 및 트리거 매트릭스를 참조하세요.
요청 스키마
아래는 예시입니다 page.get 웹훅 요청:
- HTTP
- cURL
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": "page.get",
"event_data": {
"player_id": "2D2R-OP3C",
"is_anonymous": false,
"locale": "en",
"id": "pg_2eAeXgQGcaie",
"slug": "daily-offers"
},
"event_time": 1725548450,
"event_id": "whevt_eCacGbJVbvToOgzjXUgOCitkQE",
"idempotency_key": null,
"request_id": "d1593e9c-c291-4004-8846-6679c2e5810b",
"sandbox": false,
"trigger": "hub.page.open",
"transaction_id": "whtx_eCacGbJVbvT",
"context": null,
"game_id": "gm_exTAyxPsVwh"
}
curl "https://your-webhook-endpoint.com/your/webhook/uri" \
-X POST \
-H "Content-Type: application/json" \
-H "User-Agent: Aghanim/0.1.0" \
-H "X-Aghanim-Signature: 2e45ed4dede5e09506717490655d2f78e96d4261040ef48cc623a780bda38812" \
-H "X-Aghanim-Signature-Timestamp: 1725548450" \
-d '{
"event_type": "page.get",
"event_data": {
"player_id": "2D2R-OP3C",
"is_anonymous": false,
"locale": "en",
"id": "pg_2eAeXgQGcaie",
"slug": "daily-offers"
},
"event_time": 1725548450,
"event_id": "whevt_eCacGbJVbvToOgzjXUgOCitkQE",
"idempotency_key": null,
"request_id": "d1593e9c-c291-4004-8846-6679c2e5810b",
"sandbox": false,
"trigger": "hub.page.open",
"transaction_id": "whtx_eCacGbJVbvT",
"context": null,
"game_id": "gm_exTAyxPsVwh"
}'
이벤트 스키마
| Key | 유형 | 설명 |
|---|---|---|
event_id | string | Aghanim에 의해 생성된 고유 이벤트 ID. |
game_id | string | Aghanim 시스템에서의 귀하의 게임 ID. |
event_type | string | 이벤트의 유형, page.get 이럴 경우. |
event_time | number | The time the event was sent, in Unix epoch time. May differ across duplicate deliveries of the same event. |
event_data | EventData | 이벤트 특정 데이터가 포함되어 있으며, 상속된 객체에 대한 가능한 키가 포함됩니다. |
idempotency_key | string|null | 웹훅 작업이 재시도되어도 한 번만 실행되도록 보장합니다. 일 수 있습니다 null 이벤트 유형에 따라 달라집니다. |
request_id | string|null | 이벤트가 API 요청에 의해 트리거된 경우, 요청 ID가 포함됩니다. |
sandbox | boolean | 이 이벤트가 샌드박스 게임 환경에서 전송되었는지를 표시합니다. |
trigger | string|null | 이벤트가 전송된 원인이 된 트리거입니다. |
transaction_id | string | Aghanim이 생성한 거래 ID입니다. 이 ID는 동일한 거래 내에서 발생한 여러 이벤트에서 동일할 수 있습니다. |
context | EventContext|null | 이벤트에 대한 컨텍스트 정보. |
EventContext 스키마
| Key | 유형 | 설명 |
|---|---|---|
order | OrderContext|null | 해당되는 경우 이벤트와 관련된 주문 정보입니다. |
player | PlayerContext|null | 플레이어 정보를 추가하려면 웹훅 설정에서 "플레이어 컨텍스트 추가"를 활성화하세요. |
EventData 스키마
| Key | 유형 | 설명 |
|---|---|---|
player_id | string | 플레이어 인증을 위해 선택된 고유한 플레이어 ID. 게임이 복합 인증을 사용하지 않는 경우에 전송됩니다. |
player | object | 복합 인증을 사용할 때의 플레이어 ID 구성 요소. player_id 대신 전송됩니다. |
is_anonymous | boolean | 현재 사용자가 인증되지 않음(익명)인지 여부를 나타냅니다. |
locale | string | 현재 플레이어의 로케일 코드(ISO 639-1)입니다. 가능한 로케일의 전체 목록은 Locales에서 확인하세요. |
id | string | Aghanim이 생성한 고유한 페이지 ID입니다. 요청이 페이지 조회와 관련되지 않은 경우 비어 있습니다. |
slug | string | 플레이어가 요청한 페이지의 slug입니다. 요청이 페이지 조회와 관련되지 않은 경우 비어 있습니다. |
응답 스키마
성공적으로 처리된 경우 서버는 2xx 범위의 상태 코드와 다음 JSON 페이로드를 반환해야 합니다:
| Key | 유형 | 설명 | 필수 여부 |
|---|---|---|---|
blocks | [[Block]] | 위에서 아래로 렌더링되는 블록의 행. 최대 50행, 행당 최대 10개 블록. | 예 |
페이지 구성은 고객사 서버가 완전히 제어합니다. blocks의 각 항목이 하나의 행이며, 행의 순서와 행 안 블록의 순서가 플레이어에게 보이는 순서입니다. 예를 들어 [[ImageBannerBlock], [StoreBlock]]은 스토어 위에 배너를 렌더링하고, [[StoreBlock], [ImageBannerBlock]]은 스토어를 먼저 렌더링합니다.
block 필드로 구분되는 세 가지 블록 유형이 지원됩니다: StoreBlock, ImageBannerBlock, DailyRewardsBlock. 그 외의 블록 유형이 포함된 응답은 거부되며, 페이지는 블록 없이 렌더링됩니다.
StoreBlock 스키마
| Key | 유형 | 설명 | 필수 여부 |
|---|---|---|---|
block | string | 블록 유형 구분자. StoreBlock이어야 합니다. | 예 |
id | string | 블록에 대한 고객사의 식별자. | 아니오 |
store_key | string | 블록이 렌더링하는 스토어의 키. 블록에 items가 있으면 필수입니다. | 아니오 |
items | [Item|BundleItem] | 블록의 아이템으로, store.get 응답과 동일한 형식입니다. 블록당 최대 300개. | 아니오 |
store_key가 없으면 블록은 Aghanim에 구성된 게임의 스토어 설정을 렌더링합니다.
ImageBannerBlock 스키마
| Key | 유형 | 설명 | 필수 여부 |
|---|---|---|---|
block | string |