Использование AppsFlyer с TWA

Краткий обзор. Используйте AppsFlyer с Trusted Web Activities (TWA) для измерения количества установок и регистрации событий в приложении.

Введение

Что такое Trusted Web Activities?

Trusted Web Activities (TWA) — это новый способ интеграции веб-контента в приложение для Android. Сложность с TWA заключается в том, чтобы иметь возможность регистрировать события в приложении. Эта проблема рассматривается в данной статье. Более подробную информацию о TWA смотрите здесь.

TWA также можно использовать с Progressive Web Apps.

Что такое Progressive Web Apps?

Progressive Web Apps (PWA) — это приложения, которые выглядят для пользователя как приложения, но на самом деле полностью основаны на веб-технологиях. Одним из видов PWA является приложение для Android, активность которого основана на TWA. Именно эта форма PWA рассматривается в данной статье. TWA позволяет встроить PWA в отдельное приложение для Android, что дает вам возможность представить ваше PWA-приложение в Play Store.

Другая форма, исключительно веб-ориентированная, в этой статье не рассматривается. Более подробную информацию о PWA можно найти здесь.

На этой вкладке рассматриваются PWA, встроенные в Trusted Web Activity, полноэкранный веб-браузер в приложении. Такие приложения относятся к глобальному классу приложений Android, но их деятельность осуществляется исключительно через веб (браузер).

Эта форма PWA позволяет измерять количество установок. Другая разновидность PWA — те, что основаны исключительно на веб-технологиях, — не дает возможности измерять количество установок.

TWA

Отправка событий в приложении из TWA

События в приложении отправляются с помощью AppsFlyer SDK из активностей нативного приложения. Поскольку TWA имеет веб-основу, а не нативные активности, вы не можете отправлять события в приложении с помощью AppsFlyer SDK. В качестве альтернативы можно использовать события внутри приложения от сервера к серверу. Следуйте приведенным ниже инструкциям, чтобы отправить события с сервера на сервер с помощью TWA.

Необходимые условия

Прежде чем начать отправлять события из TWA в AppsFlyer, выполните следующие действия:

  1. Добавьте следующий репозиторий в файл gradle на уровне проекта:
    maven { url "https://jitpack.io"}
  2. Добавьте следующие строки:
    • Для библиотек android.support:
      • Добавьте следующее в файл build.gradle:
        implementation 'com.github.GoogleChrome.custom-tabs-client:customtabs:91b4a1270b'
      • Импортируйте следующие библиотеки:
        import android.support.customtabs.CustomTabsClient;
        import android.support.customtabs.CustomTabsIntent;
        import android.support.customtabs.CustomTabsServiceConnection;
        import android.support.customtabs.CustomTabsSession;
        import android.support.customtabs.trusted.TrustedWebActivityIntentBuilder;
        import static android.support.customtabs.TrustedWebUtils.EXTRA_LAUNCH_AS_TRUSTED_WEB_ACTIVITY
    • Для библиотек androidX:
      • Добавьте следующее в файл build.gradle:
        implementation 'com.github.GoogleChrome:android-browser-helper:ff8dfc4ed3'
      • Импортируйте следующие библиотеки:
        import androidx.browser.customtabs.CustomTabsClient;
        import androidx.browser.customtabs.CustomTabsIntent;
        import androidx.browser.customtabs.CustomTabsServiceConnection;
        import androidx.browser.customtabs.CustomTabsSession;
        import androidx.browser.trusted.TrustedWebActivityIntentBuilder;
        

Получение идентификатора AppsFlyer ID

Чтобы отправлять события с сервера на сервер, вам нужен идентификатор AppsFlyer. Вы можете получить AppsFlyer ID из SDK AppsFlyer для Android. 

Во-первых, убедитесь, что SDK AppsFlyer для Android интегрирован. Затем вы можете получить идентификатор AppsFlyer, используя следующий API SDK:

String appsflyerId = AppsFlyerLib.getInstance().getAppsFlyerUID(this);

Отправка AppsFlyer ID в TWA

Вы можете отправить идентификатор AppsFlyer одним из двух способов:

Добавьте идентификатор AppsFlyer и идентификатор клиента в URL

Когда вы создаете намерение для trusted web activity, вы можете передавать параметры в его URL:

private void launchTwa(String cuid, String af_id) {

    CustomTabsServiceConnection customTabsServiceonnection = new CustomTabsServiceConnection() {

        @Override
        public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
            Log.d(LOG_TAG, "onCustomTabsServiceConnected");

            // Setting up CustomTabsSession that is used to build an intent
            mClient = client;
            CustomTabsSession session = mClient.newSession(null);

            // Creating the intent to launch TWA using URL with query params that can be read by the Web App
            TrustedWebActivityIntentBuilder twaIntentBuilder = new TrustedWebActivityIntentBuilder(Uri.parse(defaultUri + "?cuid=" + cuid + "&appsflyer_id=" + af_id));
            Intent twaIntent = twaIntentBuilder.build(session);

            startActivity(twaIntent);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(LOG_TAG, "onCustomTabsServiceDisconnected");
        }
    };

    CustomTabsClient.bindCustomTabsService(getApplicationContext(), "com.android.chrome", customTabsServiceonnection);
}

Получение идентификатора AppsFlyer ID

После запуска веб-активности вы можете получить идентификатор AppsFlyer с помощью простого фрагмента JavaScript:

let url = new URL(document.location.href);
    let appsflyerID;
url.searchParams.forEach((value, key) => {
    if(key === 'appsflyer_id') {
    	appsflyerID = value;
    }
})

Получив идентификатор AppsFlyer, сохраните его в локальном хранилище, чтобы использовать в дальнейшем.

Отправка идентификатора AppsFlyer через пользовательские заголовки

Вы можете передавать пользовательские заголовки в trusted web activities. Сервер получает эти заголовки, записывает их в cookie и отправляет в браузер. Затем вы можете получить идентификатор AppsFlyer с помощью javascript:

private void launchTwa(String cuid, String af_id) { 
        CustomTabsServiceConnection customTabsServiceonnection = new CustomTabsServiceConnection() {

        @Override
        public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
            Log.d(LOG_TAG, "onCustomTabsServiceConnected");

            // Setting up CustomTabsSession that is used to build an intent
            mClient = client;
            CustomTabsSession session = mClient.newSession(null);

            // Creating the intent to launch TWA using URL with query params that can be read by the Web App
            TrustedWebActivityIntentBuilder twaIntentBuilder = new TrustedWebActivityIntentBuilder(Uri.parse(defaultUri);
            Intent twaIntent = twaIntentBuilder.build(session);

            // Passing additional custom headers to the intent so they can be read by the Web App
            Bundle customHeaders = new Bundle();
            customHeaders.putString("twa_params", "cuid=" + cuid + "&=appsflyer_id" + af_id");
            twaIntent.putExtra(Browser.EXTRA_HEADERS, customHeaders);
            startActivity(twaIntent);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(LOG_TAG, "onCustomTabsServiceDisconnected");
        }
    };

    CustomTabsClient.bindCustomTabsService(getApplicationContext(), "com.android.chrome", customTabsServiceonnection);
}

Получение идентификатора AppsFlyer ID

JavaScript не предоставляет API, позволяющего разработчикам получать доступ к заголовкам. Поэтому сервер должен отправить данные о конверсии обратно в веб-активность в виде cookie. Сервер получает пользовательские заголовки, содержащие идентификатор AppsFlyer, анализирует эти данные и отправляет их на веб-страницу в виде cookie.

Необходимо установить фрагмент JavaScript, чтобы получать cookie с AppsFlyer ID при загрузке страницы.

// get the conversion data cookie 
// function taken from https://plainjs.com/javascript/utilities/set-cookie-get-cookie-and-delete-cookie-5/
function getCookie(name) {
    var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
    return v ? v[2] : null;
}

// get the cookie
var conversionData = JSON.parse(getCookie('appsflyer_id'));
console.log(appsflyer_id);


Отправка события в приложении

Чтобы отправлять события в приложении, вам нужно отправить данные о событии на ваш сервер, а ваш сервер должен отправить событие в AppsFlyer. Есть еще несколько условий для отправки событий в приложении:

  • Ключ разработчика SDKВажно! Ключ разработчика SDK является конфиденциальным значением и не должен присутствовать в TWA. Если вы собираетесь использовать TWA и отправлять события внутри приложения с сервера на сервер, всегда храните ключ разработчика SDK в безопасном месте на стороне сервера.
  • App ID — идентификатор приложения, как он отображается в файле Manifest.xml в Android.

Получив эти три параметра (идентификатор AppsFlyer, ключ разработчика SDK, идентификатор приложения), вы можете отправить внутреннее событие приложения. Всякий раз, когда в веб-активности происходит событие, вы должны отправить запрос вашему веб-серверу на обработку этого события. Веб-сервер получает данные, относящиеся к событию, составляет событие и отправляет его в AppsFlyer.

Примеры отправки событий в приложении от сервера к серверу смотрите здесь.

Настройка веб-контента с помощью данных о конверсии

AppsFlyer SDK предоставляет вам данные о конверсии через два API:

  • Get conversion data вызывается при первом запуске приложения после установки и при последующих запусках приложения.
  • On app open attribution вызывается при переходе пользователя в приложение по диплинку на основе OneLink.

Вы можете использовать данные о конверсии для настройки веб-контента.

Отправка данных о конверсии в TWA

Получив данные о конверсии любым из вышеперечисленных способов, вы можете отправить их на свой веб-сервер. Для этого используйте пользовательские заголовки:

private void launchTwa(Map<String, String> conversionData, String cuid, String af_id) { 
        CustomTabsServiceConnection customTabsServiceonnection = new CustomTabsServiceConnection() {

        @Override
        public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
            Log.d(LOG_TAG, "onCustomTabsServiceConnected");

            // Setting up CustomTabsSession that is used to build an intent
            mClient = client;
            CustomTabsSession session = mClient.newSession(null);

            // Creating the intent to launch TWA using URL with query params that can be read by the Web App
            TrustedWebActivityIntentBuilder twaIntentBuilder = new TrustedWebActivityIntentBuilder(Uri.parse(defaultUri);
            Intent twaIntent = twaIntentBuilder.build(session);

            // Passing additional custom headers to the intent so they can be read by the Web App
            Bundle customHeaders = new Bundle();
            customHeaders.putString("twa_params", "cuid=" + cuid + "&=" + af_id");
            customHeaders.putString("conversion_data", conversionData);
            twaIntent.putExtra(Browser.EXTRA_HEADERS, customHeaders);
            startActivity(twaIntent);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(LOG_TAG, "onCustomTabsServiceDisconnected");
        }
    };

    CustomTabsClient.bindCustomTabsService(getApplicationContext(), "com.android.chrome", customTabsServiceonnection);
}

Получение данных о конверсии со стороны клиента

JavaScript не предоставляет API, позволяющего разработчикам получать доступ к заголовкам. Поэтому сервер должен отправить данные о конверсии обратно в веб-активность в виде cookie. Сервер получает пользовательские заголовки, содержащие данные о конверсии, анализирует их и отправляет на веб-страницу в виде cookie.

Следует установить фрагмент JavaScript, который при загрузке страницы будет получать cookie с данными о конверсии и соответствующим образом настраивать контент. Например, если пользователь устанавливает приложение в результате кампании, посвященной предложениям на авиабилеты, вы можете наполнить веб-активность контентом, относящимся к этим предложениям.

// get the conversion data cookie 
// function taken from https://plainjs.com/javascript/utilities/set-cookie-get-cookie-and-delete-cookie-5/
function getCookie(name) {
    var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
    return v ? v[2] : null;
}

// get the cookie
var conversionData = JSON.parse(getCookie('conversion_data'));
console.log(conversionData);
/*
conversion data example:
{ 
        campaign: "CAMPAIGN_NAME", // "None" if not specified on the link
        media_source: "MEDIA_SOURCE", //"None" if not specified on the link     
        cost_cents_USD : "0",
        is_first_launch: true,
        install_time: "2018-12-30 23:59:39.330",
        orig_cost: "0.0",
        af_click_lookback: "7d",
        click_time: "2018-12-30 23:59:09",
        cost_cents_USD: "0",
        af_status: "Non-organic"
}
*/

Подробнее о вариантах использования данных о конверсии читайте здесь.

PWA

Измерение количества установок для PWA

Как и в случае с любым другим приложением для Android, вы можете интегрировать AppsFlyer SDK в приложение, чтобы измерять количество установок и получать данные о конверсии.

Для измерения установок достаточно интегрировать SDK, следуя инструкциям здесь

Персонализация контента с использованием данных о конверсии

Вы можете настроить веб-контент в соответствии с кампанией, которая побуждает пользователя установить ваше приложение. Например, если пользователь устанавливает приложение из кампании, которая дает ему скидку 20% на товары из вашего интернет-магазина. Вы можете получить данные о конверсии и применить скидку, как только приложение откроет веб-активность.

Чтобы узнать, как использовать данные о конверсии для настройки веб-контента, следуйте инструкциям здесь.

Запись событий в PWA

PWA использует TWA, которые по сути являются веб-активностями. Поскольку TWA имеет веб-основу, а не нативные активности, вы не можете отправлять события в приложении с помощью AppsFlyer SDK. В качестве альтернативы можно использовать события внутри приложения от сервера к серверу.

Следуйте инструкциям здесь, чтобы узнать, как отправлять события в приложении для PWA.