Инструкция по отправке событий о депозитах в Facebook/Appsflyer

Что у нас есть:

  • android-приложение со встроенным SDK Facebook/Appsflyer
  • сервер с базой данных, который обрабатывает GET- и POST-запросы
  • кампания в Keitaro
  • партнерка:)

Что надо сделать:

  • настроить отстреливание постбеков из Keitaro на наш сервер и отправку событий о депозитах после запроса приложения на этот сервер и получения данных.

Инструкция:

В android-приложении при первом запуске генерируем для пользователя уникальный хэш, который остается неизменным для него вплоть до удаления приложения.

String hash = randomString(30);
private String randomString(int len) {
 StringBuilder sb = new StringBuilder(len);
 for (int i = 0; i < len; i++)
 sb.append("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".charAt(rnd.nextInt("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".length())));
 return sb.toString();
}
При открытии в вебвью нашей трекерной ссылки, подставляем в query-строку параметром этот уникальный хэш, чтобы он прокидывался и сохранялся на трекере.
mWebView.loadUrl(url + "?hash=" + hash;

В Keitaro заходим в Обслуживание => Настройки. Назначаем наш query-параметр hash на параметр Keitaro, который будем использовать как макрос.

Предполагается, что у нас настроены постбеки из партнерки на трекер:

Предполагается, что у нас настроены постбеки из партнерки на трекер:

Таким образом, Кейтаро связывает каждую совершенную конверсию с определенным уникальным hash пользователя. Теперь настроим Postback на сервер.

В кампании Кейтаро откроем вкладку S2S Postback.

Настроим POST-запрос на наш сервер.

Настроим POST-запрос на наш сервер.

Уточнение: в данном случае Кейтаро отправляет все параметры в query, а не в body, несмотря на тип запроса. Поэтому сервер должен принимать параметры именно из query-строки.

https://{адрес сервера}/?hash={sub_id_13}&app_id=com.rangeroller.push

Тут все просто, в hash - наш уникальный хэш пользователя, в значении которого настроенный нами макрос, app_id - package name приложения. Схема такая - приходит постбек о депозите из партнерки в Кейтаро, Кейтаро отправляет постбек на сервер. Теперь сервер будет хранить запись о первом депозите пользователя, информацию о котором получит приложение при запросе на сервер.

  • В приложении создадим функцию, которая будет совершать GET-запрос на сервер и проверять, есть ли запись о депозите у этого уникального хэша. Если подробнее, работает она так: запускается при старте компонента с вебвью. Затем проверяет, отправлены ли события ранее о депозите. Если отправлены, заканчивает работу. Если нет, каждую минуту делает GET-запрос на сервер с такими параметрами: hash (в нем передается уникальный хэш пользователя), app_id (package name приложения). Предполагается, что сервер возвращает ответ в формате JSON, в виде массива. Если на сервере есть записи о депозитах этого пользователя, массив вернется не пустой. Делаем соответствующую проверку в функции. Если длина массива > 0, отправляем события Appsflyer и Facebook. Далее сохраняем метку в SharedPreferences о том, что события отправлены.Если массив приходит пустой, через минуту функция повторяет запрос на сервер.
private void checkDep() {
   if (!DeeplinkKeeper.getisFirstDeposit()) {
       Timer timer = new Timer();
       timer.schedule( new TimerTask() {
           public void run() {
               if (!DeeplinkKeeper.getisFirstDeposit()) {
                   try {
                       new OkHttpClient();
                       OkHttpClient client;
                       String uid = DeeplinkKeeper.getParam("hash");
                       HttpUrl.Builder urlBuilder = HttpUrl.parse("адрес сервера").newBuilder();
                       urlBuilder.addQueryParameter("hash", uid);
                       urlBuilder.addQueryParameter("app_id", BuildConfig.APPLICATION_ID);
                       String urlString = urlBuilder.build().toString();
                       client = new OkHttpClient.Builder()
                               .connectTimeout(60, TimeUnit.SECONDS)
                               .writeTimeout(60, TimeUnit.SECONDS)
                               .readTimeout(60, TimeUnit.SECONDS)
                               .build();
                       Request request = new Request.Builder()
                               .url(urlString)
                               .build();
                       Response response = client.newCall(request).execute();
                       JSONArray dataResponce  = new JSONArray(response.body().string());
                       boolean state = dataResponce.length() > 0;
                       if (state) {
                           Map<String, Object> eventValues = new HashMap<>();
                           AppsFlyerLib.getInstance().trackEvent(getApplicationContext(), "first_deposit", eventValues);
                           AppEventsLogger logger = AppEventsLogger.newLogger(getApplicationContext());
                           logger.logEvent("first_deposit");
                           DeeplinkKeeper.setisFirstDeposit(true);
                       }
                   } catch (Exception e) {
                       e.printStackTrace();
                   }
               }
           }
       }, 0, 60*1000);
   }
}

Запускаем эту функцию при старте компонента с вебвью.

DeeplinkKeeper.getisFirstDeposit() - здесь (в SharedPreferences) мы храним метку о том, отправлено ли уже событие о первом депозите. Если отправлено, нет смысла больше запускать функцию проверки.

DeeplinkKeeper.getParam("hash") - здесь у нас хранится хэш.