오퍼 작업하기
텐투플레이에서 오퍼란 일종의 구매 추천 시스템으로서 플레이어의 게임 효율과 사용자 경험을 향상시키는 목적으로 사용됩니다. 오퍼 사용에 필요한 두 가지 작업이 있는데 하나는 오퍼 데이터 가져오기이고 다른 하나는 오퍼 메시지에 대한 반응 업데이트하기입니다. 이 두 가지 작업에 대한 방법을 알아보겠습니다.
이후 설명은 다음과 같은 가정 하에 진행됩니다.
|
오퍼 데이터 가져오기
일단 사용자 행동 데이터가 업로드되면 텐투플레이 서버는 정기적으로 이를 분석하고 향후 요청 시 애널리틱스나 오퍼용으로 사용될 수 있도록 분석된 데이터를 보관해 둡니다. 이에 첫번째로 해야할 일은 텐투플레이 서버에 있는 오퍼 데이터를 가져오는 작업입니다. 서버에 가져온 오퍼 데이터로 오퍼 메시지를 만들 수 있습니다.
요청
GET https://api.tentuplay.io/v2021.4/offers HTTP/1.1
Content-Type:application/json
요청
성공
HTTP/1.1 200 OK
Content-Type:application/json
{
"status": 200,
"reason": "OK",
"data": [
{
"offer_id": 2,
"player_slug": "TentuPlayer",
"offer":
"{
\"offer_type\": \"ai\",
\"is_offer_active\": true,
\"recommendations\": [
{
\"store\": \"ios\",
\"product_list\": [
{
\"end_datetime\": null,
\"product_index\": \"00000\",
\"purchase_link\": \"https://tentuplay.io/\",
\"start_datetime\": null,
\"purchasable_slug\": \"BombBow\"
}
]
}
],
\"display_parameters\":
{
\"en\":
{
\"title\": \"A Special Recommendation For EXPLOSIVE Growth!\",
\"message\": \"Congratulations on reaching <color=#FFD84F>explosive growth!</color>\\n In 3 days you earned 1000 coins,\\n and reached level 7!\\n If you buy the following product, you can grow more efficiently.\",
\"background_url\": \"https://tentuplay-static.s3.ap-northeast-2.amazonaws.com/black_background.png\",
\"toggle_message\": \"Don't Show Again Today\"
},
\"ko\":
{
\"title\": \"폭풍성장 플레이어를 위한 특별한 정보!\",
\"message\": \"<color=#FFD84F>폭풍성장</color> 등급 달성을 축하합니다.\\n 3일 동안 코인을 1000만큼 획득하고,\\n 7레벨 성장하셨습니다!\\n 다음의 상품을 구매하면 효율을 더욱 높일 수 있습니다.\",
\"background_url\": \"https://tentuplay-static.s3.ap-northeast-2.amazonaws.com/black_background.png\",
\"toggle_message\": \"오늘 다시보지 않기\"
}
}
}",
"create_datetime": "2021-11-08 06:36:07",
"valid_until": null,
"valid_for": null,
"valid_open_count": null,
"first_opened_at": null,
"is_offer_active": 1
},
{
"offer_id": 1,
"player_slug": "TentuPlayer",
"offer":
"{
\"price\": 99.99,
\"message\":
{
\"en\":
{
\"url\": \"https://tentuplay.io/en/\",
\"image\": \"https://tentuplay-static.s3.ap-northeast-2.amazonaws.com/offer_demo_image_landscape.png\",
\"title\": \"english campaign\"
},
\"ko\":
{
\"url\": \"https://tentuplay.io/ko/\",
\"image\": \"https://tentuplay-static.s3.ap-northeast-2.amazonaws.com/offer_demo_image_landscape.png\",
\"title\": \"한글 캠페인\"
}
},
\"product_id\": null,
\"product_name\": null,
\"discount_rate\": 10,
\"discount_price\": 89.99,
\"message_layout\": \"h\"
}",
"create_datetime": "2021-11-08 06:36:07",
"valid_until": null,
"valid_for": null,
"valid_open_count": null,
"first_opened_at": null,
"is_offer_active": 1
}
]
}
오퍼 구현하기
오퍼 요청에 대한 응답을 받으면 먼저 오퍼 데이터의 유효성을 확인하고 그 다음 수신인에게 전달할 오퍼 메시지를 생성해야 합니다. 다음은 이전 섹션의 응답 body 예시를 기준으로 한 설명입니다.
오퍼 유효성 검증
오퍼를 올바르게 사용하려면 다음 표에 있는 항목들을 점검해야 합니다.
구성요소 | 설명 | 비고 | |
---|---|---|---|
공통 |
|
|
|
|
|
||
|
오퍼를 처음 열어본 시간을 나타냅니다. 이 값이 |
||
|
오퍼의 유효 기간을 산정하는 데 사용됩니다. |
||
|
UTC 기준으로 오퍼가 생성된 시간을 나타냅니다. |
||
|
|
해당 상품이 판매 중임을 확인하는데 사용됩니다. |
AI 오퍼의 값들은 상품 정보 파일을 업로드했을 경우에만 생성됩니다. |
|
이 값들 중 하나를 이용해 플레이어가 해당 상품을 구입할 수 있는지 확인합니다. |
||
|
|
오퍼 만들기
이제 오퍼의 body 콘텐츠를 파싱하여 이를 오퍼의 GUI(graphical user interface)에 넣음으로써 사용자가 오퍼와의 상호작용을 통해 오퍼를 소비할 수 있도록 합니다.
본 단계는 오퍼를 표현하기 위해 메시지 창이나 본문 필드, 기타 화면 제어 요소(예: 버튼, 체크 박스)들로 구성된 GUI를 이미 구현했다는 가정하에 진행됩니다. 참고로 유니티 SDK에는 오퍼 메시지를 생성하기 위한 기본 UI 템플릿이 제공되고 있습니다(AI 오퍼 템플릿, 개인화 오퍼 템플릿).
AI 인게임 상점 오퍼 만들기
-
화면 표시 콘텐츠(
display_parameters
아래title
,messeage
,background_url
,toggle_message
)를 언어별로 UI에 배치합니다. -
상품 정보(
recommendations
아래product_index
,purchasable_slug
,purchase_link
)를 오퍼에 추가하여 사용자가 오퍼 메시지에 소개된 추천 상품을 구입할 수 있도록 합니다. (유니티 SDK에서의 해당 설명)
오퍼 상태 업데이트하기
오퍼에 어떤 이벤트가 발생하면 오퍼의 상태 변화를 서버에 반영해 주어야 합니다. 오퍼 상태 업데이트는 다음과 같은 이벤트 발생시 필요합니다.
-
사용자에게 전달할 오퍼를 서버에서 가져왔을 때
-
사용자가 오퍼에 어떤 반응을 하였을 때 (예: 열기, 무시하기, 다음 단계로 진행하기)
오퍼가 노출되었을 때
먼저 서버에 오퍼 요청 후 이를 성공적으로 받았음을 알려주어야 합니다. 이 때 오퍼의 상태는 "impress"로 바뀝니다.
요청
POST https://api.tentuplay.io/v2021.4/logs HTTP/1.1
Content-Type:application/json
Body
{
"players_offers": [
{
"player_slug": "TentuPlayer",
"offer_id": 999,
"message_status": "impress",
"message_detail": "this_purchasable_slug",
"event_timestamp": 1647504609
}
],
...
}
이름 | 설명 | 자료형 | 필수여부 | 비고 |
---|---|---|---|---|
player_slug |
플레이어의 고유 ID |
string |
필수 |
Unity SDK의 |
offer_id |
오퍼의 고유 ID |
int |
필수 |
|
message_status |
오퍼에 발생한 이벤트
|
string |
필수 |
|
message_detail |
오퍼에서 광고 관련 인게임 콘텐츠의 고유 ID (예: 광고된 인게임 아이템, DLC 상품, 인게임 기프트 카드) |
string |
선택 |
|
event_timestamp |
UTC 기준 유닉스 시간 |
int |
필수 |
오퍼가 소비되었을 때
생성된 오퍼 메시지는 미리 정의된 조건이 충족되면 대상 사용자에게 전송됩니다. 오퍼 메시지가 성공적으로 사용자에게 전달되면 사용자는 이 메시지를 열어보거나 그냥 무시하는 등의 반응을 보일 수 있습니다. 이러한 상호 작용으로 오퍼 메시지의 상태가 바뀔 수 있는데 만약 변경이 발생했다면 이를 서버에 있는 동일한 메시지 상태에도 이를 반영해 줘야 합니다. 이제 오퍼 메시지의 리소스 상태도 업데이트되었으므로 오퍼 성과에 대한 지표도 따라서 업데이트됩니다.
오퍼 최초 개봉 시 업데이트
사용자가 처음으로 오퍼를 열어보게 되면 해당 이벤트를 발생 시간과 함께 서버에 알려야 합니다. 이로써 서버의 first_opened_at
속성에 시간 값이 들어갑니다. 이 값은 주로 오퍼의 유효 시간을 계산하는데 사용됩니다.
POST https://api.tentuplay.io/v2021.4/offers HTTP/1.1
Content-Type:application/json
이름 | 값 | 자료형 | 필수여부 | 비고 |
---|---|---|---|---|
TPAuthMode |
|
string |
필수 |
|
TPClientKey |
string |
필수 |
||
TPOfferId |
오퍼 ID |
int |
필수 |
|
TPPlayerId |
플레이어 ID |
string |
필수 |
|
TPOpenedAt |
오퍼 최초 개봉 시 타임 스탬프 |
string |
필수 |
예: |
개봉된 적이 없는 어떤 오퍼(즉, |
오퍼 소비 시 업데이트
텐투플레이에서는 오퍼와의 상호 작용을 아래와 같이 세가지 유형으로 구분하고 있으며 이는 message_status
의 값이 됩니다.
-
open
: 플레이어가 오퍼를 열어봄 -
dismiss
: 플레이어가 오퍼 UI의 닫기 버튼을 클릭함 -
interact
: 플레이어가 구매와 같은 관련 버튼을 클릭하여 다음 단계로 넘어감
POST https://api.tentuplay.io/v2021.4/logs HTTP/1.1
Content-Type:application/json
이름 | 값 | 자료형 | 필수여부 | 기본값 |
---|---|---|---|---|
TPAuthMode |
|
string |
필수 |
null |
TPClientKey |
string |
필수 |
null |
Body 예시
{
"players_offers": [
{
"player_slug": "TentuPlayer",
"offer_id": 999,
"message_status": "open",
"message_detail": "this_purchasable_slug",
"event_timestamp": 1647504609
}
],
...
}
{
"players_offers": [
{
"player_slug": "TentuPlayer",
"offer_id": 999,
"message_status": "dismiss",
"message_detail": "this_purchasable_slug",
"event_timestamp": 1647504609
}
],
...
}
{
"players_offers": [
{
"player_slug": "TentuPlayer",
"offer_id": 999,
"message_status": "interact",
"message_detail": "this_purchasable_slug",
"event_timestamp": 1647504609
}
],
...
}
오퍼 상태 업데이트에 대한 샘플 코드
TPStashEvent myStashEvent = new TPStashEvent();
myStashEvent.StashOfferEvent(
player_uuid: player_id, offer_id: thisOffer.offer_id,
message_status: messageStatus.Open, message_detail: purchasable_slug);
myPerOffer.OfferOpened(thisOffer.offer_id, (response) =>
{
});
int r = new TPStashEvent().StashOfferEvent(
player_uuid: thisPlayerUUID, offer_id: thisOffer.offer_id, message_status: messageStatus.Dismiss,
message_detail: purchasable_slug);
new TPUploadData().UploadData(toCheckInterval: false);
int r = new TPStashEvent().StashOfferEvent(
player_uuid: thisPlayerUUID, offer_id: thisOffer.offer_id, message_status: messageStatus.Interact,
message_detail: purchasable_slug);
new TPUploadData().UploadData(toCheckInterval: false);