サーバー間(Server-to-Server) - モバイルアプリS2Sガイド

概要

このガイドでは、共通のS2Sの仕組みの上に重なる、モバイル固有のアトリビューションシグナルを扱います。具体的には、Apple Search Ads、Google PlayおよびMetaのインストールリファラー、アンインストール計測、そしてiOSインストールレシートです。セッションとイベントをサーバー間(server-to-server)で報告するiOSおよびAndroidアプリの連携に適用されます。

始める前に: これらの機能は共通のS2Sリクエストフローの上に構築されています。中核的な概念についてはS2Sファンダメンタルズのハブを、認証と共通パラメータについてはSESSIONエンドポイントリファレンスおよびEVENTエンドポイントリファレンスをご覧ください。

関連するモバイルガイド: キャンペーンからアプリにユーザーを誘導するには、S2S を介したディープリンクおよびディファードディープリンクについてディープリンクガイドを参照してください。


Apple Search Adsアトリビューション

iOS Search Adsの連携

Apple Search Adsは自己アトリビューションネットワーク(SAN)であり、Appleのフレームワークを介したプラットフォーム固有のアトリビューション実装が必要です。

フレームワークのサポート:

  • AdServices(iOS 14.3以降): AdServices フレームワーク. 現在の推奨される連携方法です。
  • iAd(iOS 14.2以前): iAd フレームワーク. Apple により非推奨となったレガシーフレームワークで、新規連携には推奨されません。

詳細ガイド: Apple Search Ads連携ドキュメント


AdServicesフレームワークの実装

iOS 14.3以降向けに、AdServicesフレームワークを介してアトリビューショントークンを取得して送信します。

ステップ1:アトリビューショントークンを取得する

Objective-C
#import <AdServices/AdServices.h>

NSError *error = nil;
Class AAAttributionClass = NSClassFromString(@"AAAttribution");
if (AAAttributionClass) {
    NSString *attributionToken = [AAAttributionClass attributionTokenWithError:&error];
    if (!error && attributionToken) {
        // Handle attributionToken
    }
}

トークンの特性:

  • デバイス上で生成される
  • 5分間キャッシュされる—有効期限後に attributionToken() が呼び出されると新しいトークンが生成される
  • 24時間有効

ステップ2:Singularに送信する

トークンをURLエンコードし、すべてのインストールおよび再インストール後の最初のセッションで、 SESSIONエンドポイント attribution_token パラメータとして付加します。


Google Playインストールリファラー

Androidインストールアトリビューション

Google Playインストールリファラーは、Playストアに到達する前のユーザーの発生元に関する情報を含んでおり、最も正確なAndroidインストールアトリビューションを提供します。

次の場合に必須:

詳細情報: Googleインストールリファラードキュメント

実装手順:

  1. Play Install Referrer API を使用して、最初のアプリ起動時にインストールリファラーを取得する
  2. 必須の属性を含む install_ref JSONパラメータを含めて、 SESSIONエンドポイント を介してセッションを報告する

install_refの属性:

パラメータ 詳細
referrer

Play Install Referrer APIからのリファラー値(JSONオブジェクト—文字列としてエンコードする)

referrer_source

serviceを指定する

clickTimestampSeconds

APIからのクリックタイムスタンプ(例:1550420123

installBeginTimestampSeconds

APIからのインストール開始時刻

current_device_time

現在のデバイス時刻(ミリ秒単位、例:1550420454906


Metaインストールリファラー

Facebookアトリビューションの強化

2025年6月18日時点: Metaの Advanced Mobile Measurement(AMM) により、Metaインストールリファラーの実装が不要になりました。AMMが有効な場合は推奨されません。

MetaリファラーはAndroid固有の計測ソリューションで、Google PlayインストールリファラーとMetaインストールリファラーの技術を組み合わせることで、アプリインストールに関する詳細なユーザーレベルのアトリビューションデータを提供します。

詳細はこちら: MetaリファラーFAQ

実装手順:

  1. Metaのドキュメント に従って、最初のアプリ起動時にMetaインストールリファラーを取得する
  2. 必須の属性を含む meta_ref JSONパラメータを含めて、 SESSIONエンドポイント を介してセッションを報告する

meta_refの属性:

パラメータ 詳細
is_ct

Metaインストールリファラーからのis_ct(0または1

install_referrer

Metaインストールリファラーからのinstall_referrer

actual_timestamp

Metaインストールリファラーからのactual_timestamp(例:1693978124


アンインストール計測

サイレントプッシュ通知の設定

すべてのセッション通知でプッシュトークンを送信することにより、デバイスのサイレントプッシュ通知を使用してアンインストールを計測します。

設定要件:

  1. プラットフォーム固有のアンインストール計測の設定に従ってください:
  2. プラットフォーム固有のトークンをSESSIONリクエストに付加してください:
    • iOS: apns_token (APNsデバイストークン)
    • Android: fcm (FCMデバイストークン)

iOSインストールレシート

レシートの検証

iOSセッションを報告する際に、 install_receipt パラメータでiOSインストールレシートを渡します。

Swift
import Foundation
import StoreKit

class ReceiptManager {
    static func getInstallReceipt() -> String? {
        if #available(iOS 18.0, *) {
            let semaphore = DispatchSemaphore(value: 0)
            var result: String?

            Task {
                do {
                    let transaction = try await AppTransaction.shared
                    result = transaction.jwsRepresentation
                    semaphore.signal()
                } catch {
                    debugPrint("Failed to get app transaction: \(error.localizedDescription)")
                    semaphore.signal()
                }
            }

            semaphore.wait()
            return result

        } else {
            guard let receiptURL = Bundle.main.appStoreReceiptURL else {
                debugPrint("Receipt URL not found")
                return nil
            }

            do {
                let receiptData = try Data(contentsOf: receiptURL, options: .uncached)
                return receiptData.base64EncodedString(options: [])
            } catch {
                debugPrint("Failed to read receipt: \(error.localizedDescription)")
                return nil
            }
        }
    }
}