概要:アドネットワークは、広告がクリックされるたびにコストを送信できます。
広告主は、AppsFlyer管理画面のデータを基に広告予算の配分を判断し、どこに投資すべきかを把握しています。その判断において自社のアドネットワークを評価してもらうには、AppsFlyerへのコストデータの共有が欠かせません。
広告主は、パートナーをROI順に並べ替えて、成果の高いパートナーを確認することがよくあります。コストデータのないパートナーは、常に一覧の下位に表示されます。
コストの共有方法
AppsFlyerのアトリビューションURLでユーザーレベルのコストデータを送信する方法には、暗号化せずに送信する方法と、暗号化して送信する方法の2つがあります。暗号化して送信する場合、パートナーはクリックのアトリビューションURLにコストの値を含められます。
暗号化しないコストデータは、クリックURLに次の3つのパラメータを直接指定することで送信できます。
- af_cost_model=CPI(現在、AppsFlyerのレポートで表示できるコストモデルはCPIのみです)
-
af_cost_value={insert CPI value, for example: 1.00}(CPIの値を指定します。例:1.00)
注意:1未満の値には、小数点の前に0が必要です。例:0.05。 - 3文字の通貨コードを指定します(af_cost_currency={insert 3 letter currency code. If blank we will assume USD})。空欄の場合はUSDとして扱われます。
注意:アトリビューションリンクではどのコストモデルも送信できますが、管理画面でコストデータの表示に対応しているのは、現在CPIのみです。その他のコストモデルは、ローデータレポートで確認できます。
暗号化せずにコストを送信するアトリビューションリンクの例:
https://app.appsflyer.com/id554782625?pid=mediasource_int&c=campaignName&idfa=ABCDEFGH-ABCD-ABCD-ABCD-
A12345678910&af_siteid=12345&af_cost_model=CPI&af_cost_value=1.00&af_cost_currency=USD暗号化したコストデータ
アトリビューションURLに実際のコストの値を表示したくない場合は、コストのパラメータを暗号化できます。コストデータの暗号化には、AESベースの暗号化方式を使用します。暗号化したコストの値を生成するには、コストモデル、金額、通貨に加え、アドネットワーク固有のキーが必要です。
暗号化の手順:
- 担当のPSEチームに、アドネットワークの暗号化キーの発行を依頼します。お問い合わせには、Partner Assistantウィジェットを使用してください。
- 以下のAES暗号化方式を使用して、必要な4つの値(アドネットワークのキー、コストの金額、コストモデル、コストの通貨)を暗号化します。
- 生成された暗号化済みの値を、AppsFlyerのアトリビューションURLのaf_enc_data=パラメータに追加します。
暗号化した値を送信するアトリビューションリンクの例:
https://app.appsflyer.com/id554782625?pid=mediasource_int&c=campaignName&idfa=ABCDEFGH-ABCD-ABCD-ABCD-A12345678910&af_siteid=12345&af_enc_data=DvVvQRow%2F2N0LiQGZh0wvwucFygbll9IwAMSN%2B%2BDQxo%3D
注意:広告主のアトリビューションリンクで暗号化したコストデータを送信するには、アドネットワークがAppsFlyerとのコスト暗号化連携を完了している必要があります。
AESによる暗号化の処理
暗号化には、AESアルゴリズムを使用し、ブロックモードはECB、パディング方式はPKCS5を指定します。その後、暗号化したデータをBase64エンコードし、最後にその結果をURLエンコードします。
実装に使用する技術や言語は問いません。以下に、PHP、Java、Pythonの例を示します。
PHP
<?php
$f = fopen( 'php://stdin', 'r' );
echo "Enter private key: ";
$private_key = trim(fgets($f));
echo "Enter cost model: ";
$cost_model = trim(fgets($f));
echo "Enter cost value : ";
$cost_value = trim(fgets($f));
echo "Enter cost currency : ";
$cost_currency = trim(fgets($f));
$params = array(
'af_cost_model' => $cost_model,
'af_cost_value' => $cost_value,
'af_cost_currency' => $cost_currency
);
$query_str = http_build_query($params);
$block_size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$padding_size = $block_size - (strlen($query_str) % $block_size);
$padded_query_str = $query_str . str_repeat(chr($padding_size), $padding_size);
$enc_raw = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $private_key, $padded_query_str, "ecb");
$enc_b64 = base64_encode($enc_raw);
$enc_url_encoded = urlencode($enc_b64);
echo "\n\n\r";
echo "Private key: " . $private_key . "\r\n";
echo "Query string: " . $query_str . "\r\n";
echo "\n\r";
echo "Encrypted query string: " . $enc_url_encoded . "\r\n";
fclose( $f );
?>Java
private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
private static final String encryptionKey = "XXXXXXXXXXXXXXXX"; // secret key provided by appsflyer
private static final SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes(), "AES");
public static void main(String[] args) throws Exception {
String queryParams = "bid_value=0.01&bid_type=cpc";
String cipher = encrypt(queryParams);
System.out.println(cipher);
}
public static String encrypt(String str) throws Exception {
Cipher cipherEncrypt = Cipher.getInstance(CIPHER_ALGORITHM);
cipherEncrypt.init(Cipher.ENCRYPT_MODE, key);
byte[] cipher = cipherEncrypt.doFinal(str.getBytes("UTF-8"));
String b64 = encode64(cipher);
String result = urlencode(b64);
return result;
}Python
import sys
import base64
import urllib
from Crypto.Cipher import AES
def read_number(t):
try:
start = input("enter " + t + ": ")
start = float(start)
return start
except ValueError:
print("\n\r" + t + " must be a number")
exit()
def encrypt (secret_key, msg):
cipher = AES.new(secret_key, AES.MODE_ECB)
ciphertext = cipher.encrypt(msg)
return ciphertext
def padding (data):
length = 16 - (len(data) % 16)
data += chr(length)*length
return data
secret_key = input("enter secret key: ").strip()
currency = input("enter cost currency: ").strip()
model = "CPI"
if len(currency) == 3:
currency = currency.upper()
else:
print("currency must have 3 character (e.g. USD)")
exit()
start = read_number("starting value")
end = read_number("final value")
step = read_number("step")
if end >= start:
while start <= end:
msg = "af_cost_currency=%s&af_cost_model=%s&af_cost_value=%.2f" % (currency, model, start)
msg = padding(msg)
enc = encrypt(secret_key, msg)
start += step
print(msg)
print(urllib.quote_plus(base64.b64encode(enc)))
コスト送信に対応しているアドネットワーク
アトリビューションリンクでのコスト送信に対応しているアドネットワークの一覧は、こちらを参照してください。
API経由のコスト送信に対応しているアドネットワークの一覧は、こちらを参照してください。