Краткий обзор: API межсерверных событий (S2S) для мобильных устройств отправляет в AppsFlyer данные о событиях, которые происходят вне вашего приложения. События S2S атрибутируются аналогично событиям SDK и доступны на всей платформе.
API межсерверных событий для мобильных устройств
Платформа AppsFlyer атрибутирует и записывает события мобильных приложений, отправленных через SDK AppsFlyer и по API. Используйте API S2S для сообщения о событиях, происходящих вне приложения; например, пользователь продлевает свою подписку, используя ваш веб-интерфейс. После регистрации события S2S доступны на всей платформе, включая дэшборды, сырые данные и аналитику. Для веб-событий PBA см. Web S2S для PBA.
AppsFlyer заполняет события S2S следующими значениями:
- Значения, отправленные в сообщении S2S
- Некоторые значения атрибуции установок AppsFlyer, например, время установки и медиа-источник.
Инструкции по использованию API
Создайте свой вызов API, используя информацию, содержащуюся в следующих разделах.
Факты о S2S API
Конечная точка API |
|
HTTP-метод | POST |
Принятый тип контента | application/json |
Авторизация |
|
Серверы в разрешенном списке для получения ответных сообщений | |
Ограничение размера JSON |
Размер файла JSON: до 1 KB |
Ограничение предоставления данных |
Объем ограничения POST: 60 000 POST в минуту. Чтобы повысить этот лимит, обратитесь к своему менеджеру по работе с клиентами. |
Инструкции по программированию |
|
Кодирование URL |
Закодируйте зарезервированные процентом символы (https://tools.ietf.org/html/rfc3986#section-2.1) перед формированием URL метода. |
TLS |
Используйте TLS 1.2 или выше. Поддерживаемые шифры |
Параметры полезных данных
- В параметры полезных данных входят один или несколько идентификаторов устройств (в зависимости от ОС).
-
Что делать, если я не могу отправить идентификатор устройства?
- You may be unable to send the identifier for a reason out of your control, for example, because the user has limited ad tracking (LAT) or uses iOS 14, and did not give ATT consent. If IDFV is available send it.
- Not sending an advertising ID/device identifier can cause:
- Postback issues: The media source will receive the postback but without a device identifier; consequently the media source can't associate it with a user.
- Ошибка сегментации аудиторий и применения правил. Для корректной работы наборов правил необходимы идентификаторы. Отправьте идентификатор устройства или идентификатор клиента, в зависимости от типа идентификатора, который используется в вашем наборе правил.
Операционные системы | Имя идентификатора | Описание |
---|---|---|
iOS.
|
idfa |
Когда доступно, введите IDFA устройства. Формат: строка Например: |
idfv |
Когда доступно, введите IDFV устройства. Формат: строка |
|
Android; |
advertising_id |
Когда доступно, введите GAID устройства (рекламный ID) Формат: строка Например: |
oaid |
Формат: строка Например: |
|
amazon_aid |
Формат: строка |
|
imei |
Формат: строка Например: |
Имя параметра | Обязательный | Описание | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
appsflyer_id |
Да |
Уникальный идентификатор, генерируемый AppsFlyer при первом запуске приложения.
|
|||||||||
customer_user_id |
Нет |
Идентификатор клиента, уникальный идентификатор пользователя, заданный владельцем приложения.
|
|||||||||
att |
Нет |
iOS Статус авторизации ATTrackingManager
Внимание! We recommend that you populate |
|||||||||
ip |
Нет |
IP-адрес мобильного устройства во время события.
|
|||||||||
Устаревшее |
|
||||||||||
eventName |
Да |
Определите имя события. Убедитесь, что имена событий соответствуют требованиям маркетолога.
|
|||||||||
Значение события |
Да |
If you send an event without a value then send:
|
|||||||||
app_version_name |
Нет |
Версия вашего приложения или идентификатор.
|
|||||||||
app_store |
Нет |
Эквивалентно AF_STORE в приложениях для Android. Магазин, из которого было скачано приложение.
|
|||||||||
Event Time (Время события) |
Нет |
Время, когда произошло событие, используя часовой пояс UTC.
Закрытие дня:
Пример
|
|||||||||
eventCurrency |
Нет |
Код валюты с использованием 3-символьных кодов ISO 4217 и BCN (биткойн)
|
|||||||||
bundleIdentifier |
Нет* |
Уникальный идентификатор приложения. В сырых данных параметр заполняет Bundle ID (идентификатор пакета). [Рекомендация] Всегда заполняйте этот параметр. Многие рекламные сети требуют это значение для оптимизации кампаний.
|
|||||||||
sharing_filter |
Нет |
Фильтр общего доступа блокирует доступ к событиям S2S через постбэки / API для интегрированных партнеров и других сторонних интеграций. Используйте фильтр для соблюдения нормативных требований, таких как GDPR и CCPA, для реализации механизмов отказа пользователей от предоставления данных и по другим причинам бизнес-логики. У sharing_filter есть следующие параметры:
Чтобы получить список идентификаторов партнеров, обратитесь к вашему CSM или в службу поддержки AppsFlyer. |
|||||||||
custom_dimension |
Нет |
Зарезервировано AppsFlyer для использования в будущем |
|||||||||
app_type |
Нет |
Для приложений iOS. Допустимое значение: Если пользовательское событие происходит в app_clip, отправьте параметр. Во всех остальных случаях параметр отправлять не нужно. |
|||||||||
custom_data |
Нет |
Send custom data to the AppsFlyer platform. Similar to sending data from the SDK using In raw data: populates Format: JSON, illustrated in the example that follows. Example:
|
|||||||||
*Необходим многим рекламным сетям для оптимизации |
Пример curl
curl --location --request POST 'https://api2.appsflyer.com/inappevent/<app_id_placeholder>' \
--header 'authentication: <dev_key_placeholder>
' \
--header 'Content-Type: application/json' \
--data-raw '{
"appsflyer_id": "9999999999999-9999999999999999999",
"advertising_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"customer_user_id" : "example_customer_id_123",
"ip": "199.0.2.1",
"app_version_name" : "example_version_name",
"eventTime" : "2020-02-25 12:00.000",
"eventName": "af_purchase",
"eventCurrency": "ZAR",
"eventValue":
"{
\"af_revenue\": \"1006\",
\"af_content_type\": \"wallets\",
\"af_content_id\": \"15854\",
\"af_quantity\" :\"1\"
}"
}
'
Коды ответа
Код ответа | Сообщение | Способ устранения |
---|---|---|
200 | OK |
При получении сообщения выполняется минимальная валидация данных. Таким образом, вы можете получить ответ ОК, даже если событие не будет полностью записано в AppsFlyer. Для отладки событий:
|
400 | Failed to Authenticate | Убедитесь, что ключ аутентификации правильный. |
400 | appsflyer_id is a mandatory field |
|
401 | Не авторизовано | Когда ключ, предоставленный в заголовке аутентификации, не является ключом <dev_key> для этого приложения. |
400 | Bad request |
Когда запрос не прошел как минимум один из критериев валидации. |
400 | Payload is missing or failed to parse |
|
500 | Internal Server Error | Убедитесь, что данные JSON преобразованы в строки и правильно отформатированы. |
Тестирование
Рассмотрим:
- Для тестирования используйте идентификатор AppsFlyer для неорганической установки, чтобы тестировать атрибуты событий в реальном времени. Органические события атрибутируются с задержкой в несколько часов.
- Некоторые поля события заполняются с использованием события атрибуции установки пользователем. Например, время установки и медиа-источник.
Чтобы атрибутировать тестовое устройство как неорганическую установку:
- Prepare a custom attribution link for testing S2S messages. Set the media source parameter on the link as to s2s_test and set advertising id (GAID, IDFA, etc) on the link as illustrated in the example attribution link snippets.
- Регистрация тестового устройства
- Удалите приложение с тестового устройства.
- Отправьте ссылку на тестовое устройство.
- Щелкните ссылку.
- Установите и запустите приложение.
- На дэшборде проверьте, что установка атрибутирована.
- Получите AppsFlyer ID для использования в вашем сообщении S2S.
Чтобы отправить тестовое сообщение S2S:
- Подготовьте сообщение S2S, используя назначенный идентификатор AppsFlyer. См. ниже примеры кода.
- Отправьте сообщение.
- Выполните одно из следующих действий, чтобы увидеть, как сообщение записывается в AppsFlyer:
- Загрузите отчетсырых данных о внутренних событиях приложения. После отправки события, данные о нем появятся в отчете сырых данных через 15 минут.
- Push API (рассмотрите возможность использования таких инструментов, как Postman и Webhook).
- Проверьте и просмотрите, что:
- Значения, отправленные в сообщении S2S, правильно заполняют отчет. Обратите особое внимание на поля «Дата события», «Валюта события», «Доход от события» и «Значение события».
- Источник атрибуции и время установки заполняются AppsFlyer.
- Значения, предоставляемые самим SDK, такие как версия SDK, не заполняются.
Example attribution link
Android;
https://app.appsflyer.com/<app_id>?pid=s2s_test&c=test&advertising_id=<GAID>
iOS.
https://app.appsflyer.com/<app_id>?pid=s2s_test&c=test&idfa=<IDFA>
Пример кода для отправки сообщений S2S
/* using the okhttp package
install from maven https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp */
import okhttp3.*;
import java.io.IOException;
public class SendRequest {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "" +
"{\r\n\t\"appsflyer_id\": \"<APPS_FLYER_ID>\"," +
"\r\n\t\"customer_user_id\": \"123456\",\r\n\t\"eventName\": \"af_purchase\",\r\n\t\"" +
"eventValue\": \"{\\\"af_revenue\\\":\\\"6\\\" ,\\\"af_content_id\\\":\\\"15854\\\"}\",\r\n\t\"" +
"eventCurrency\": \"USD\",\r\n\t\"" +
"eventTime\": \"2018-08-10 4:17:00.000\",\r\n\t\"");
Request request = new Request.Builder()
.url("https://api2.appsflyer.com/inappevent/<APP_ID>")
.post(body)
.addHeader("Content-Type", "application/json")
.addHeader("authentication", "<YOUR_DEV_KEY>")
.build();
try {
Response response = client.newCall(request).execute();
System.out.println(response.code());
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
''' using the requests python package, install using pip install requests '''
import requests
url = "https://api2.appsflyer.com/inappevent/[Insert app ID here]"
payload = "{\r\n \"appsflyer_id\": \"9999999999999999999999\",\r\n\t\"IDFA\":\"999999999999999999999999\",\r\n\t\"customer_user_id\" : \"14mar\",\r\n\t\"ip\": \"10.0.0.1\",\r\n\t\"app_version_name\" : \"example_version_name\",\r\n\t\"eventTime\" : \"2020-04-25 08:59:01.23\",\r\n\t\"eventName\": \"gaf_purchase\",\r\n\t\"eventCurrency\": \"ZAR\",\r\n\t\"eventValue\": \r\n\t\"{\r\n\t\t\\\"af_revenue\\\": \\\"1000\\\",\r\n\t\t\\\"af_content_type\\\": \\\"wallets\\\",\r\n\t\t\\\"af_content_id\\\": \\\"15854\\\",\r\n\t\t\\\"af_quantity\\\" :\\\"1\\\"\r\n }\"\r\n}"
headers = {
'authentication': '[Insert web dev key]',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data = payload)
print(response.text.encode('utf8'))
/* using the request npm package, install using npm install request */
var request = require("request");
var options = { method: 'POST',
url: 'https://api2.appsflyer.com/inappevent/<APP_ID>',
headers:
{
"authentication": '<YOUR_DEV_KEY>',
'Content-Type': 'application/json'
},
body:
{ appsflyer_id: '<APPS_FLYER_ID>',
customer_user_id: '123456',
eventName: 'node_js',
eventValue: '{"node_js":"6" ,"af_content_id":"15854"}',
eventCurrency: 'USD',
ip: '1.0.0.0',
eventTime: '2018-07-09 4:17:00.000'
},
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
/* using the RestSharp package, install using NuGet */
using System;
using RestSharp;
namespace CS
{
class Event
{
static void Main(string[] args)
{
var client = new RestClient("https://api2.appsflyer.com/inappevent/<APP_ID>");
var request = new RestRequest(Method.POST);
request.AddHeader("authentication", "<YOUR_DEV_KEY>");
request.AddHeader("Content-Type", "application/json");
var body = "{\"appsflyer_id\": \"<APPS_FLYER_ID>\"," +
"\"customer_user_id\": \"123456\"," +
"\"eventName\": \"af_purchase\"," +
"\"eventValue\": \"{\\\"af_revenue\\\":\\\"6\\\" ,\\\"af_content_id\\\":\\\"15854\\\"}\"," +
"\"eventCurrency\": \"USD\"," +
"\"eventTime\": \"2018-07-08 4:17:00.000\"
}";
request.AddParameter("undefined", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
// handle response by reading response.StatusCode
Console.WriteLine(response.Content);
}
}
}
$purchase_event = array(
'appsflyer_id' => <APPS_FLYER_DEVICE_ID>,
'idfa' => <IDFA>,
'eventCurrency' => <PURCHASE_CURRENCY>,
'ip' => <DEVICE_ID_ADDRESS>,
'eventTime' => date("Y-m-d H:i:s.000", time())
);
$purchase_event['eventName'] = 'af_purchase';
$purchase_event['eventValue'] = json_encode(array('af_revenue' => <PURCHASE_REVENUE>,
'af_price' => <PURCHASE_PRICE>,
'af_order_id' => <PURCHASE_ORDER_ID>,
'af_currency' => <PURCHASE_CURRENCY>,
'af_content_type' => <PURCHASE_TYPE>,
'af_quantity' => <PURCHASE_QUANTITY>,
'af_content' => <PRODUCT_NAME>,
'af_content_id' => <PRODUCT_ID>)
);
$data_string = json_encode($purchase_event);
$ch = curl_init('https://api2.appsflyer.com/inappevent/<YOUR_APP_ID>');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'authentication: <YOUR_APPS_FLYER_DEV_TOKEN>',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
$curl = curl_init();
Отправка рекламного идентификатора / идентификатора устройства важна
- Рекламный идентификатор / идентификатор устройства является обязательным для отправки постбэков в сети SRN, такие как Facebook и Google Ads. Если вы не можете отправить идентификатор, примите во внимание, что нельзя отправлять постбэки.
- Если вы отправите только идентификатор AppsFlyer, внутренние события приложения будут записываться и атрибутироваться правильно.
Заполнение параметров
Разница между органическими и неорганическими событиями
Когда AppsFlyer обрабатывает события S2S в приложении, поля атрибуции заполняются с помощью идентификатора AppsFlyer, чтобы определить соответствующее событие установки, которое предшествовало событиям в приложении.
Это означает, что некоторые данные, которые AppsFlyer связывает с неорганическими S2S-событиями, не будут связаны с органическими S2S-событиями в приложении.
Пример
Например, если сравнить отчеты о необработанных данных для неорганических и органических S2S-событий, можно заметить, что неорганические события содержат данные, которых нет в органических событиях.
Неорганические внутренние события приложения содержат данные о медиа-источнике, кампании, атрибутированном типе и времени взаимодействия.
Что касается органических событий приложения, то они происходят после органической установки. Органические установки не содержат данных о кампании, медиа-источнике, атрибутированном типе взаимодействия и времени установки.
Сопоставление идентификатора AppsFlyer ID с идентификатором клиента (CUID)
Логическая схема на стороне сервера необходима для того, чтобы получить определенные значения для указанного параметра. Ниже описано, как вы можете получить идентификатор AppsFlyer:
- Идентификатор AppsFlyer является обязательным и используется для атрибуции событий.
- Он генерируется, когда пользователь впервые устанавливает мобильное приложение.
- Чтобы вы могли сопоставить свой CUID с идентификатором AppsFlyer, вам нужно установить CUID в приложении.
Простой способ сопоставления пользователей с выполненными ими событиями приведен ниже.
- Задайте идентификатор клиента при установке приложения пользователем.
- Отчеты по сырым данным AppsFlyer содержат CUID и идентификатор AppsFlyer. Используйте один из инструментов доставки данных или AppsFlyer Push API.
- Используйте отчеты о сырых данных, чтобы сопоставить CUID с идентификатором AppsFlyer.
- Идентификаторы AppsFlyer можно получить с помощью SDK AppsFlyer, интегрированных в ваши приложения (Android / IOS).
- Сопоставьте идентификатор AppsFlyer с идентификатором клиента во внутренних системах (важно для использования в будущем).
Сопоставив идентификатор AppsFlyer с CUID, вы можете определить пользователя, выполнившего события. Затем вы сможете получить другие значения (значение события, валюту события, время события и т.д.) и отправить внутреннее событие приложения от сервера к серверу.
Пример тела запроса
{
"appsflyer_id": "1415211453000-6513894",
"advertising_id": "38412345-8cf0-aa78-b23e-10b96e40000d",
"eventName": "af_purchase",
"eventValue":
"{
\"af_revenue\": \"6\",
\"af_content_type\": \"wallets\",
\"af_content_id\": \"15854\",
\"af_quantity\" :\"1\"
}",
"eventCurrency": "USD",
"ip": "1.2.3.4",
"eventTime": "2014-05-15 12:17:00.000"
}
В этом случае AppsFlyer получает межсерверное (S2S) внутреннее событие, которое представляет собой покупку с доходом, вместе с дополнительными свойствами, например, тип контента и пр.
Получение идентификатора AppsFlyer ID
В сообщениях межсерверных событий параметр appsflyer_id
является обязательным. AppsFlyer использует данный параметр для атрибуции события исходному устройству и атрибутированному медиа-источнику. Вы можете получить ID одним из следующих способов:
- С мобильного устройства с помощью вызова AppsFlyer SDK API: Android, iOS
- От платформы AppsFlyer с использованием одного из следующих способов: Pull API, Push API, Экспорт отчета по сырым данным об установках
Совет
Если при тестировании сообщений S2S вы используете сырые данные, ищите запись с медиа-источником "s2s_test". Это ваше тестовое устройство, а его идентификатор устройства AppsFlyer — это необходимый ID.
Отправка данных об отрицательной выручке
События с отрицательным значением дохода могут быть отправлены. Например, если покупка была отменена. Параметр af_revenue
может иметь отрицательные значения для записи этого события.
Если вы заполняете af_quantity
, возможно, вы захотите заполнить его отрицательным значением в зависимости от логики вашей системы. AppsFlyer не использует af_quantity
.
Примеры данных об отрицательной выручке
{
"eventName": "cancel_purchase",
"eventValue":
"{
\"af_revenue\": \"-6\",
\"af_content_type\": \"wallets\",
\"af_content_id\": \"15854\",
\"af_quantity\" :\"1\"
}",
"eventCurrency": "USD",
}
Отправка событий без значения события
Если нужно отправить событие без значения события, просто передайте в качестве значения события пустую строку: "event_value":""
Теперь AppsFlyer может отправлять подобные rich in-app события медиа источникам для улучшения таргетинга, оптимизации и создания аудитории соответственно настройкам рекламодателя.
Устранение неполадок
События не отображаются в дэшборде
- Конечная точка: убедитесь, что используемая конечная точка верна.
- Убедитесь, что полезные данные содержат обязательные параметры. См. здесь.
- Убедитесь, что AppsFlyer ID, используемый для запуска события, является действительным идентификатором appsflyer_id, который установлен в конкретном приложении. Что это не тестовый идентификатор, представленный в документации. См. здесь.
- Для S2S-событий групповая отправка событий в одном запросе S2S не поддерживается. Каждое событие необходимо отправлять отдельно.
- На обзорном дэшборде диапазон дат относится к дате установки приложения (LTV), а не к дате события.
- Убедитесь, что вы ввели правильный диапазон дат.
- Убедитесь, что диапазон дат на дэшборде соответствует дате установки устройства (appsflyer_id), а не дате события.
- Отчет по сырым данным о событиях: диапазон дат относится к дате события, а не дате установки.
События не содержат доход
Если после отправки S2S-событий окажется, что данные о доходе не записаны, убедитесь, что отправленные данные в формате JSON преобразованы в строки. Самое важное — это значение параметра события в формате JSON. Он должен быть преобразован в строку, как показано на следующем примере.
"{\"af_revenue\":\"6\" ,\"af_content_type\":\"wallets\"}"
Если значение события не преобразовано в строку, оно обрабатывается неправильно и величина дохода не записывается.
Значения дохода не должны быть отформатированы каким-либо образом. Они могут содержать десятичный разделитель, но это не обязательно. Не используйте знаки/коды валют или разделители ,
. Доход может иметь префикс -
- Пример допустимых значений:
123
,-123.45
,123.456
- Примеры недопустимых значений:
1,234.56
,1,234
В событиях S2S заполнены не все поля
Поля сырых данных заполняются с использованием значения, отправленного в вызове S2S, а некоторые поля заполняются с помощью события установки. Аналогичное поведение, но не идентичное, наблюдается для событий в приложении, сообщаемых с помощью AppsFlyer SDK. Существуют некоторые различия, в частности, следующие поля не заполняются для событий S2S:
- wifi
- operator
- language
- Тип устройства
- Категория устройства
- Версия приложения: используйте
app_version_name
. - Имя приложения