オファー作業する

TentuPlayでのオファーとは、一種の購入お勧めシステムとしてゲームの効率とユーザーエクスペリエンスを向上させる目的として使用されます。オファーの使用に必要な2つの作業があり、1つはオファーデータをインポートすることで、もう1つはオファーメッセージに対する反応のアップデートです。この2つの作業に対する方法について説明します。

その後の説明は、以下のような仮定の下で行われます。

  • オファー作成に必要なすべての行動データをアップロードした。

  • REST API通信は2台のサーバー間で行われる。つまり、TentuPlayサーバーでリクエストする主体はゲームクライアントではなくゲームサーバーである。ゲームクライアントプログラムを通じてリクエストしたい場合は、 TentuPlayのDISCORDを通じてお問い合わせください。

TentuPlay REST use offer jp
オファー作業の概要

オファーのインポート

一旦ユーザーの行動データがアップロードされたら、TentuPlayサーバーは定期的にこれを分析し、今後のリクエスト時にアナリティクスやオファー用に使用できるように分析されたデータを保管しておきます。そこで、最初にすべきことはTentuPlayサーバーにあるオファーデータをインポートする作業です。サーバーにインポートしたオファーデータでオファーメッセージを作成できます。

リクエスト

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

ヘッダー

名前 データ型 必須か デフォルト値

TPAuthMode

api_key_plain

string

必須

null

TPClientKey

Client key

string

必須

null

TPPlayerId

Target player’s uuid

string

必須

null

リクエスト

成功

HTTP/1.1 200 OK
Content-Type:application/json
Bodyの例
{
  "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の例を基準とした説明です。

オファー有効性の検証

オファーを正しく使用するには、以下の表にある項目を点検する必要があります。

構成要素 説明 備考

共通

offer_type

is_offer_active

is_offer_activetrueであるか、1のオファーのみ使用してください

first_opened_at

オファーを初めて開いた時間を示します。この値がnullの場合、オファーが開封されたことがないか、当該プロパティがアップデートされたことがないことを意味します。

valid_until, valid_for, first_opened_at

オファーの有効期間を算定するのに使用されます。

create_datetime

UTC基準でオファーが作成された時間を示します。

recommendations
(AIオファーのみ該当)

start_datetime, end_datetime

当該商品が販売中であることを確認するのに使用されます。

AIオファーの値は、 商品情報ファイルをアップロードした場合のみ作成されます。

product_index, purchasable_slug

この値のうち一つを利用してプレイヤーが当該商品を購入できるか確認します。

store

storeの値を確認してプレイヤーデバイスOSで実行されるオファーを実装します。

オファーを作成する

オファーのbodyコンテンツをパーシングして、これをオファーのGUI(graphical user interface)に入れることで、ユーザーがオファーとの相互作用によりオファーを消費できるようにします。

本段階は、オファーを表現するためにメッセージ画面や本文フィールド、その他画面の制御要素(例:ボタン、チェックボックス)で構成されたGUIを既に実装していると仮定して行われます。参考までに、Unity SDKにはオファーメッセージを作成するための基本UIテンプレートが提供されています(AIオファーテンプレートパーソナライズされたオファーテンプレート)。

AIインゲームショップオファーを作成する

  1. 画面表示コンテンツ(display_parameters以下のtitlemesseagebackground_urltoggle_message)を言語別にUIに配置します。

  2. 商品情報(recommendations以下のproduct_indexpurchasable_slugpurchase_link)をオファーに追加してユーザーがオファーメッセージに紹介されたお勧め商品を購入できるようにします。(Unity SDKでの当該説明)

パーソナライズされたオファーを作成する

  1. message_layoutの値を確認してページ方向を決めます。(h:横、v:縦)

  2. 画面表示コンテンツ(message`以下の`titleurlimage)を言語別にUIに配置します。

オファー状態を変更する

オファーにあるイベントが発生すると、オファーの状態変化をサーバーに反映する必要があります。オファー状態のアップデートは、以下のようなイベント発生時に必要です。

  • ユーザーに伝達するオファーをサーバーからインポートした場合

  • ユーザーがオファーに何らかの反応をした場合(例:開く、無視する、以下の段階に進む)

オファーが表示された場合

まずサーバーにオファーリクエスト後、これの受信に成功したことを知らせる必要があります。この時、オファーの状態は「impress」に変わります。

リクエスト

POST https://api.tentuplay.io/v2021.4/logs HTTP/1.1
Content-Type:application/json
ヘッダー
名前 データ型 必須か デフォルト値

TPAuthMode

api_key_plain

string

必須

null

TPClientKey

Client key

string

必須

null

Body
Bodyの例
{
  "players_offers": [
    {
      "player_slug": "TentuPlayer",
      "offer_id": 999,
			"message_status": "impress",
			"message_detail": "this_purchasable_slug",
      "event_timestamp": 1647504609
    }
  ],
  ...
}
Bodyパラメーター
名前 説明 データ型 必須か 備考

player_slug

プレイヤーの固有ID

string

必須

Unity SDKのplayer_uuidと同じ

offer_id

オファーの固有ID

int

必須

message_status

オファーに発生したイベント

  • impress:オファーのインポートに成功する

  • open:プレイヤーがオファーを確認する

  • dismiss:プレイヤーがオファーUIの閉じるボタンをクリックする

  • interact:プレイヤーが購入のような関連ボタンをクリックして次の段階に進む

string

必須

message_detail

オファーに広告関連インゲームコンテンツの固有ID(例:広告されたインゲームアイテム、DLC商品、インゲームギフトカード)

string

オプション

event_timestamp

UTC基準のUNIX時間

int

必須

オファーが消費された場合

作成されたオファーメッセージは、予め定義された条件が満たされると、対象ユーザーに送信されます。オファーメッセージのユーザーへの伝達に成功すれば、ユーザーはこのメッセージを確認したり、無視するなどの反応を見せる可能性があります。このような相互作用でオファーメッセージの状態が変わることがありますが、もし変更が発生した場合は、これをサーバーにある同じメッセージの状態にも反映する必要があります。オファーメッセージのリソース状態もアップデートされたため、オファー成果の指標もアップデートされます。

オファーを初めてオープンしたときにアップデート

ユーザーが初めてオファーを開くと、当該イベントを発生時間と共にサーバーに知らせる必要があります。これによりサーバーのfirst_opened_atプロパティに時間値が入ります。この値は主にオファーの有効時間を計算することに使用されます。

リクエスト形式
POST https://api.tentuplay.io/v2021.4/offers HTTP/1.1
Content-Type:application/json
リクエストヘッダー
名前 データ型 必須か 備考

TPAuthMode

api_key_plain

string

必須

TPClientKey

Client key

string

必須

TPOfferId

オファーID

int

必須

TPPlayerId

プレイヤーID

string

必須

TPOpenedAt

オファーをはじめてオープンしたときのタイムスタンプ

string

必須

例: 2022-08-19 13:32:08

開封したことのない、あるオファー(つまり、first_opened_at値がnullのオファー)をインポートし、first_opened_at値をアップデートしたら、そのオファーをサーバーから再取得する必要があります。

オファーを消費したときにアップデート

TentuPlayでは、オファーとの相互作用を以下のとおりに3つのタイプで区分し、これはmessage_statusの値になります。

  • open:プレイヤーがオファーを確認する

  • dismiss:プレイヤーがオファーUIの閉じるボタンをクリックする

  • interact:プレイヤーが購入のような関連ボタンをクリックして次の段階に進む

リクエスト形式
POST https://api.tentuplay.io/v2021.4/logs HTTP/1.1
Content-Type:application/json
リクエストヘッダー
名前 データ型 必須か デフォルト値

TPAuthMode

api_key_plain

string

必須

null

TPClientKey

Client key

string

必須

null

Bodyの例
  • 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
    }
  ],
  ...
}
オファー状態の更新のコード例
  • 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);