Work on offers

An offer in TentuPlay is a type of recommendation system to improve users' efficiency and experience in the game. If you want to use the offer system, there are two main tasks to be done that are getting offer data and updating reaction to offer message. Let’s learn how to do the tasks

The explanations on this section are based on the following assumptions:

  • You have uploaded the all the necessary behavioral data required for offer generation.

  • The REST API commnication is achieved between two servers. Namely, it is not your game client but game server that makes requests to TentuPlay server. If you want your game client application to act as a requestor, contact us at TentuPlay Discord for more information.

TentuPlay REST use offer en
Overview of tasks about offers

Retrieve offer data

Once you complete the data upload pertaining to user actions, TentuPlay server periodically analyzes them and stores the processed data to be consumed at request for analytics and offers. The first thing you need to do is to retrieve valid offer data that TentuPlay server retains. You then can construct and create an offer message by using the offer data from the server.

Request

GET https://api.tentuplay.io/v2021.4/offers HTTP/1.1
Content-Type:application/json

Headers

Name Value Type Required Default

TPAuthMode

api_key_plain

string

required

null

TPClientKey

Client key

string

required

null

TPPlayerId

Target player’s uuid

string

required

null

Response

Success

HTTP/1.1 200 OK
Content-Type:application/json
Body example
{
  "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
    }
  ]
}

Construct offers

Once you get a response to your offer request, you need to check the validity of offer data first and then generate offer message for its recipient. The following explanations are based on the sample response body in the preceding section.

Check offer’s validity

Examine the elements in the following table to make sure that you can use the offer correctly:

Components Description Note

Common

offer_type

is_offer_active

Use the offer only when is_offer_active is either true or 1

first_opened_at

It shows when the offer was opened for the first time. The null means the offer is never opened or updated yet

valid_until, valid_for, first_opened_at

Calculate the offer’s expiry date by using them

create_datetime

It denotes when the offer was created in UTC

recommendations
(for AI offer only)

start_datetime, end_datetime

Check whether the product is still on sale by using them

The values for AI offers are created only when you upload the product information file.

product_index, purchasable_slug

Check whether the player is allowed to purchase the product by one or more of them

store

Construct the offer that runs correctly on player’s device OS on the basis of store's value

Build offers

The next step is to parse the corresponding body contents and put them into the offer’s graphical user interface (GUI) so that users can consume the offer by interacting with it.

This step assumes that you already have contructed a GUI for offer presentation that consists of a message window, text fields, and other control elements (for example, buttons and check boxes). Note that there are basic UI templates available in Unity SDK for creating an offer message (AI offer template, Personalized offer template).

Build AI in-game shop offers

  1. Arrange the display contents (title, messeage, background_url, and toggle_message under display_parameters) on the UI by language.

  2. Add the product information (product_index, purchasable_slug, and purchase_link under recommendations) to offers so that users can purchase the recommended products presented on offer message. (Steps on Unity SDK described)

Build personalized offers

  1. Indentify the value in message_layout to select a page origentation (h: landscapte, v: portrait).

  2. Arrange the display contents (title, url, and image under message) on the UI by language.

Update offer state

If something happens to an offer, you need to reflect the change in the offer’s state to the server. An offer state update is required for one of the following events:

  • When you retrieve offers for users from the TentuPlay server

  • When the users interact with the offers such as open, close, or proceed

When an offer is exposed

The first step is to let the server know that the offer reaches you successfully on your request. This state is called "impress".

Request

POST https://api.tentuplay.io/v2021.4/logs HTTP/1.1
Content-Type:application/json
Headers
Name Value Type Required Default

TPAuthMode

api_key_plain

string

required

null

TPClientKey

Client key

string

required

null

Body
Body example
{
  "players_offers": [
    {
      "player_slug": "TentuPlayer",
      "offer_id": 999,
			"message_status": "impress",
			"message_detail": "this_purchasable_slug",
      "event_timestamp": 1647504609
    }
  ],
  ...
}
Body parameters
Name Description Type Required Notes

player_slug

The player’s unique ID

string

required

In Unity SDK, it is player_uuid

offer_id

Unique ID assigned to the offer

int

required

message_status

Events happened to the offer

  • impress: The offer is retrieved successfully

  • open: The player opened the offer

  • dismiss: The player clicked the close button on the offer UI

  • interact: The player took the next step on the offer by clicking an associated button such as Purchase

string

required

message_detail

Unique ID of in-game contents related to an advertisement in an offer (for example, advertised in-game item, DLC product, and in-game gift card)

string

optional

event_timestamp

Unix time by UTC

int

required

When an offer is consumed

When an offer message is ready, the message will be sent to target users under predefined conditions. If the offer message is delivered to the users successfully, they can give a reaction to it like opening or just ignoring. This kind of user interaction will change the message status and you need to reflect the change, if applicable, to the same of the server. When the resource state of offer message is updated, the metric for the offer accomplishment will be updated as well.

Update when an offer is first opened

When the offer is opened by the user for the first time, you need to inform the server of this event including its timestamp. This will attach a time value to the first_opened_at attribute of the offer in the server. It is usually used to calculate the offer’s validity period.

Request scheme
POST https://api.tentuplay.io/v2021.4/offers HTTP/1.1
Content-Type:application/json
Request headers
Name Value Type Required Note

TPAuthMode

api_key_plain

string

required

TPClientKey

Client key

string

required

TPOfferId

Offer ID

int

required

TPPlayerId

Player ID

string

required

TPOpenedAt

The timestamp when the offer is opened for the first time

string

required

Example: 2022-08-19 13:32:08

If you get an offer that has never been opened (namely, first_opened_at is null) and update its first_opened_at value, you have to download the offer again from the server.

Update when a user consumes an offer

There are three types of user interactions with an offer in TentuPlay that can be illustrated by message_status.

  • open: The player opened the offer.

  • dismiss: The player clicked the close button on the offer UI.

  • interact: The player took the next step on the offer by clicking an associated button such as Purchase.

Request scheme
POST https://api.tentuplay.io/v2021.4/logs HTTP/1.1
Content-Type:application/json
Request headers
Name Value Type Required Default

TPAuthMode

api_key_plain

string

required

null

TPClientKey

Client key

string

required

null

Body example
  • Open

  • Dismiss

  • Interact

{
  "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
    }
  ],
  ...
}
Sample code for offer state update
  • Open

  • Dismiss

  • Interact

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);