MoneyMiner API предназначен для медиации и таргетирования рекламных сетей, используемых в приложениях. Использую систему управления медиацией и таргетированием можно:
Точка входа в API определяется Регистратурой, идентификатор сервиса — «money_miner». Обращения строятся по схеме:
<entry_point>/<method>.<format>?[parameters]
где:
<entry_point>
— точка входа, полученная из Регистратуры<method>
— название метода<format>
— формат ответа, всегда JSON[parameters]
— список параметров метода в виде «ключ=значение», разделенных символом «&»пример обращения:
http://api.peers.tv/money_miner/1/places.json?id=iap-s0321384,iap-d7das7132
Значения всех параметров необходимо кодировать для предотвращения неоднозначной интерпретации так, как это рекомендуется в RFC3986. Кодирование запросов и ответов должно выполняться в кодировке UTF–8.
Для аутентификации пользователя клиент должен передать полученный ранее токен доступа, выданный Auth API контрагента, по схеме аутентификации в соответствии с типом токена.
Для авторизации по типу токена «Bearer» рекомендуется использовать HTTP заголовок Authorization, пример:
Authorization: Bearer 18dasd81230dah12032
Для каждого метода API предусмотрены стандартные коды ответов (RFC2616). Ниже описана интерпретация некоторых кодов:
В случае кодов 401, 403 должен быть передан HTTP заголовок WWW-Authenticate с указанием ожидаемой схемы аутентификации и дополнительнной информации (если применимо). Например, для схемы «Bearer» может быть указан дополнительный атрибут error со значением:
Информационные сервисы, предоставляющие контент, могут передавать список рекламных тэгов, характеризующих контент для рекламных целей.
Для каждой рекламной сети может быть определен унарный предикат — здесь и далее называемый предикатом применимости рекламной сети, определяющий возможность применения данной рекламной сети на контенте. Рекламная сеть может быть применена на контенте, если предикат, примененный к списку рекламных тэгов контента, вернул Истину.
Если для рекламной сети не указан предикат применимости, то рекламная сеть должна использоваться безусловно.
Предикат применимости рекламной сети может быть представлен в конъюктивной или дизъюнктивной форме.
При сериализации:
form
.parts
, в котором:
positive_tags
.negative_tags
.Предикат выражен в конъюнктивной форме следующим образом. Показывать рекламу, если выполнено условие:
(нет метки "Первый канал") И (нет метки "Спорт" ИЛИ есть метка "Новости" ИЛИ есть метка "Детское")
CNF
.нет метки "Первый канал"
negative_tags: ["Первый канал"]
нет метки "Спорт" ИЛИ есть метка "Новости" ИЛИ есть метка "Детское"
нет метки "Спорт"
negative_tags: ["Спорт"]
есть метка "Новости"
и есть метка "Детское"
оформляем в массив positive_tags: ["Новости", "Детское"]
.Получаем результат:
{
"form": 0,
"parts": [
{
"negative_tags": ["Первый канал"]
},
{
"positive_tags": ["Детское", "Новости"],
"negative_tags": ["Спорт"]
}
]
}
Рассмотрим пример. Необходимо для Первого и Пятого канала отключить все рекламные сети, кроме IMHOvi. Для всех остальных каналов данную рекламную сеть нужно запретить.
Чтобы включить рекламную сеть только на нужных каналах, нужно перечислить их, объединяя условия оператором «ИЛИ»:
есть метка "Первый канал" ИЛИ есть метка "Пятый канал"
это можно оформить в виде предиката в конъюктивной форме с одной частью:
{
"form": 0,
"parts": [
{
"positive_tags": ["Первый канал", "Пятый канал"]
}
]
}
или (в полностью аналогичной) дизъюнктивной форме с двумя частями:
{
"form": 1,
"parts": [
{
"positive_tags": ["Первый канал"]
},
{
"positive_tags": ["Пятый канал"]
}
]
}
Для остальных рекламных сетей необходимо запретить их использование для этих каналов. Т.е. использовать выражение, обратное разрешающему:
НЕ (есть метка "Первый канал" ИЛИ есть метка "Пятый канал")
по правилу раскрытия скобок операция НЕ
применяется к каждому условию, а все операторы меняет на противоположные: ИЛИ
на И
, И
на ИЛИ
:
НЕ (есть метка "Первый канал") И НЕ (есть метка "Пятый канал")
Отрицание положительных литералов есть негативный литерал. Получаем каноническую форму:
нет метки "Первый канал" И нет метки "Пятый канал"
Запишем в конъюктивной форме (с двумя частями):
{
"form": 0,
"parts": [
{
"negative_tags": ["Первый канал"]
},
{
"negative_tags": ["Пятый канал"]
}
]
}
И в дизъюнктивной форме с одной частью:
{
"form": 1,
"parts": [
{
"negative_tags": ["Первый канал", "Пятый канал"]
}
]
}
Рассмотрим пример запрета использования рекламных сетей на платных каналах, так как пользователь уже заплатил нам за них. Для примера, названия каналов будут «Наш футбол», «КХЛ» и «Nickelodeon».
По началу кажется, что разрешающий предикат можно записать таким образом:
не канал "Наш футбол" ИЛИ не канал "КХЛ" ИЛИ не канал "Nickelodeon"
Однако данный предикат всегда будет разрешать использование рекламной сети, ассоциированной с ним. Почему?
Все перечисленные тэги описывают каналы, которым принадлежит контент; они являются взаимоисключающими. Таким образом, если контент принадлежит каналу «Наш футбол», то несмотря на ложность части предиката не канал "Наш футбол"
остальные выражения становятся заведомо истинными, а значит и результат их объединения с помощью операции «ИЛИ» является истиной.
Как правильно поступить в таком случае?
Можно описать желаемый результат сначала в запретительной форме. На каких каналах нужно запретить рекламу?
канал "Наш футбол" ИЛИ канал "КХЛ" ИЛИ канал "Nickelodeon"
Но предикат применимости должен описывать все остальные случаи, т.е. должно быть выполнено обратное утверждение:
НЕ (канал "Наш футбол" ИЛИ канал "КХЛ" ИЛИ канал "Nickelodeon")
Убираем скобки. Положительные литералы превращаются в отрицательные, операции заменяем на противоположные:
не канал "Наш футбол" И не канал "КХЛ" И не канал "Nickelodeon"
Записать данный предикат проще в дизъюнктивной форме:
{
"form": 1,
"parts": [
{
"negative_tags": ["Наш футбол", "КХЛ", "Nickelodeon"]
}
]
}
Или в полностью эквивалентной ему конъюктивной:
{
"form": 0,
"parts": [
{
"negative_tags": ["Наш футбол"]
},
{
"negative_tags": ["КХЛ"]
},
{
"negative_tags": ["Nickelodeon"]
}
]
}
Отсутствие рекламных тэгов у контента должно интерпретироваться клиентом как пустой массив рекламных тэгов.
Для управления ограничениями применения рекламных сетей на контенте в панели администратора может быть реализован любой интерфейс, позволяющий добавлять и удалять независимые правила применимости рекламной сети.
При изменении данного списка правил, серверу необходимо построить таблицу истинности применимости рекламной сети, перебрав все возможности по включению или не включению рекламных тэгов, использованных в правилах.
Имея таблицу истинности, можно выбрать подходящую форму для представления предиката, а затем — минимизировать ее с помощью любого известного алгоритма, например, с помощью метода Куайна.
Пример реализации на клиенте можно посмотреть в файле money_miner_predicates_example.
Для корректной работы системы приложение должно:
Каждая рекламная сеть может включать индивидуальный набор параметров инициализации рекламного места.
Параметры:
vast_ad_tag
— шаблон URL, содержащий макросы вида [MACRO]. Известные макросы приложение должно заменить на соответствующее значение, неизвестные — на процент-кодированное по RFC3986 название макроса.skip_time_for_vast2
- время в секундах, после которого рекламу, распространяемую по протоколу старше чем VAST3, можно пропустить. Отсутствие данного параметра или пустое значение данного параметра означает, что реклама не пропускаема. Время большее, чем длительность рекламы, должна интерпретироваться как непропускаемая реклама.banner_id
— идентификатор баннераsite_id
— идентификатор приложенияpartner_id
— идентификатор партнера (соответствует идентификатору ресурса, см. пояснение ниже)block_num
— номер блока (см. пояснение ниже)target_ref
— площадка размещенияpage_ref
— страница перехода (для приложений всегда равно target_ref
)application_id
идентификатор приложенияvast_ad_tag
— шаблон URL, содержащий макросы вида [MACRO]. Известные макросы приложение должно заменить на соответствующее значение, неизвестные — на процент-кодированное по RFC3986 название макросаdomain_id
— идентификатор рекламной площадкиad_server_url
— адрес рекламного сервераslot_id
— идентификатор баннераblock_id
— идентификатор рекламного блокаchannel_id
— идентификатор рекламного блокаplacement_id
— идентификатор рекламного блокаСписок известных макросов для параметра vast_ad_tag
заполняемых на клиенте:
[CACHEBUSTING]
— случайная строка для обхода кэширования[INT_CACHEBUSTING]
- макрос, который позволяет ограничить тип данных к CACHEBUSTING целым числом[USER_ID]
— идентификатор пользователя в формате UUID (рекомендуется использовать IDFA
или ADVERTISING_ID
)[SESSION_ID]
— идентификатор сессии воспроизведения в формате UUID[INSTALL_ID]
— идентификатор установки приложения в формате UUID[CHANNEL_ID]
- идентификатор просматриваемого канала[DEVICE_MODEL]
- модель устройства пользователя. Примеры функций для получения этого параметра на разных платформах приведены ниже.[DEVICE_MANUFACTURER]
- производитель устройства пользователя. Примеры функций для получения этого параметра на разных платформах приведены ниже.[DEVICE_BRAND]
- торговая марка (если есть), специально определенная для этого устройства. На устройствах Android значение берется из Build.Brand, на устройствах не под управлением Android это поле может не заполняться, если нет такой возможности[DEVICE_ID]
- идентификатор пользовательского устройства (доступен не везде)[WATCH_ID]
- идентификатор просмотра контента, связывает событие просмотра с рекламными событиями, которые будут вызваны при просмотре этого контента. Значение генерируется рандомно в момент запуска контента и используется далее для всей рекламы, которая будет показана на этом контенте до момента переключения на другой контент[AD_COUNT]
- количество уже показанной рекламы, которая воспроизводится при просмотре одного и того же контента до переключения на другой. Нумерация начинается с 0. В счёт должны идти все типы рекламы и все рекламные места (прероллы, мидроллы, паузроллы и т.д.). Этот номер должен отправляться на каждый тип рекламного события.[PLAYER_SIZE_WIDTH]
- ширина плеера, значение передаётся в пикселях[PLAYER_SIZE_HEIGHT]
- высота плеера, значение передаётся в пикселях[VOLUME_STATE]
- уровень громкости плеера, принимает значение от 0 до 1, где 0 - минимум, 1 - максимум[IS_MUTE]
- параметр, который указывает, выключен ли звук в плеере. Передаётся значение 0 или 1. Если значение 0, значит в плеере звук отключен (режим mute), если значение 1, то в плеере звук включен[CONTENT_NAMESPACE]
- пространство имен, в котором находится контент[CONTENT_ID]
- id воспроизводимого контента, передается значение в формате целого числа[CONTENT_TYPE]
- тип контента (эфир/архив/timeshift/vod), передаётся число, которое имеет условное обозначение: 0 - просмотр в режиме «конечной» записи; 1 - просмотр эфира; 2 - просмотр непрерывной записи (таймшифт); 3 - просмотр vod-контента[CONTENT_DURATION]
- длительность контента. Если у контента нет конечной длительности, то будет передано –1, значение передаётся в миллисекундах[CONTENT_CATEGORY]
- список идентификаторов категорий контента. Будет передаваться список в формате id1;id2;… Рекомендуется передавать идентификаторы в формате uuid или целым числом, a также не использовать в названии символ ; по причине того, что он служит разграничителем в списке идентификаторов[SESSION_DURATION]
- длительность сессии, отсчитывается с момента запуска приложения, значение передаётся в миллисеундах[EXTERNAL_USER_ID]
- id пользователя, используемый во внешнем приложении, в которое встроен рекламный SDK[SCREEN_SIZE_WIDTH]
- ширина экрана устройства, значение передается в пикселях[SCREEN_SIZE_HEIGHT]
- высота экрана устройства, значение передается в пикселях[SYSTEM_LANGUAGE]
- язык системы на устройстве пользователя, передаётся в формате сокращённого обозначения на латинице в нижнем регистре в формате ISO 639–2: rus/eng…[MAC_ADDRESS]
- MAC-адрес устройства пользователя, который используется при текущем подключении к сети, передаётся строка в верхнем регистре в формате 01:23:45:AB:CD:EF[TIME_ZONE]
- часовой пояс в формате GMT+-hh:mm[TIME_ZONE_ID]
- идентификатор часового пояса, передает обозначение территории из трех символов, а если идентификатор не будет найден, то будет передано GMT[TIME_ZONE_OFFSET]
- возвращает количество времени в миллисекундах, которое необходимо добавить к всемирному координированному времени, чтобы получить стандартное время в этом часовом поясе[OS_NAME]
- название операционной системы, для всех устройств на Android передается Android без определения разновидности[OS_VERSION]
- версия операционной системы на устройстве пользователя[APP_NAME]
- название приложения[APP_BUNDLE]
- bundle id приложения[APP_VERSION]
- версия приложенияСписок макросов, заполняемых на сервере:
[SUBSCRIBER_ID]
- идентификатор пользователя в БД Peers.TV[IP_ADDRESS]
- IP адрес из запроса[REQUEST_UUID]
- идентификатор запроса рекламыИдентификатор запроса рекламы нужен для отладки трекинга между партнером и Peers.TV. Так, в Rambler SSP можно передать идентификатор запроса в параметре eid1 или eid2, после чего сделать выгрузку сырых данных с этими значениями.
Если в VAST-тэге рекламной сети есть макрос [REQUEST_UUID]
, сервер интерпретирует его как серверный и маскирует запрос также, как он это делает с серверными макросами. Но вместо конкректного UUID запроса, он заполняет значение query-параметра request_uuid
специальным значением _GENERATE_UUID_
.
Получая запрос на разворачивание серверных макросов, сервер сначала заполняет request_uuid
случайным UUIDv4 значением, после чего перенаправляет с помощью ответа HTTP 302 запрос на себя же.
Таким образом, мы сможем увидеть request_uuid
в логах API, сопоставить его с данными Tracking API по времени и [INSTALL_ID]
из запроса, а с данными партнера по request_uuid
.
Пояснение по параметрам для Yandex Video SDK:
В панели администратора используются идентификаторы блоков вида R-V-171889-2
, в данном идентификаторе зашит идентификатор партнера 171889
и номер блока 2
.
Примеры получения параметра для макроса [DEVICE_MANUFACTURER]
:
На устройствах Android значение берется из Build.MANUFACTURER.
На устройствах Apple нет специальной функции для получения значения, можно передавать значение Apple.
На smart TV LG нет специального метода для получения значения, можно передавать значение LG Smart TV.
Для smart tv Tizen способ получения:
{
[NoInterfaceObject]
interface SystemInfoBuild : SystemInfoProperty {
readonly attribute DOMString manufacturer;
};
}
Для NetCast можно получить так:
{
var device = document.getElementById(«device»);
manufacturerId = device.manufacturer;
}
Примеры получения параметра для макроса [DEVICE_MODEL]
:
На устройствах Android значение берется из Build.Model.
На устройствах Apple значение можно получить так:
{ var systemInfo = utsname() uname(&systemInfo) let machineMirror = Mirror(reflecting: systemInfo.machine) let identifier = machineMirror.children.reduce(«») { identifier, element in guard let value = element.value as? Int8, value != 0 else { return identifier } return identifier + String(UnicodeScalar(UInt8(value)))} }
Для smart tv Tizen способ получения:
{ [NoInterfaceObject] interface SystemInfoBuild : SystemInfoProperty { readonly attribute DOMString model; }; }
Для webOS необходимо вызвать метод getSystemInfo() с ключом modelName
Для NetCast можно получить так:
{
var device = document.getElementById(«device»);
deviceVersion = device.modelName;
}
Параметры:
параметр | тип данных | значение |
---|---|---|
id |
строки через ',’ | список идентификаторов рекламных мест |
Формат ответа: AdPlaceList
ВАЖНО: метод принимает не более 10 идентификаторов рекламных мест.
Запрос
GET /money_miner/1/places.json?id=JxDBgQmd
Authorization: Bearer 18dasd81230dah12032
Host: api.peers.tv
Ответ
HTTP/1.1 200 OK
Content-Type: application/json
{
"places": [{
"place_id":"JxDBgQmd",
"ad_systems": [{
"type":1,
"name":"Адривер",
"id":370223,
"price":200,
"banner_type":3,
"params": [{
"key":"vast_ad_tag",
"value":"http://ad.adriver.ru/cgi-bin/erle.cgi?sid=170878&sz=test&bn=322&target=top&bt=61&pz=1&rnd=[CACHEBUSTING]"
}]
}],
"request_delay":15
}]
}
message AdPlaceList {
repeated AdPlace places = 1;
}
message AdPlace {
optional string place_id = 1;
repeated AdSystem ad_systems = 2;
optional int32 request_delay = 3 [default = 0];
}
Замечания:
place_id
— идентификатор запрошенного рекламного местаad_systems
— упорядоченный список рекламных сетейrequest_delay
— минимальная задержка между показами рекламы для рекламного места (в секундах)message AdSystem {
message AdSystemParam {
optional string key = 1;
optional string value = 2;
}
enum AdType {
VAST_API = 1;
ADMOB_SDK = 2;
WAPSTART = 3;
YANDEX_VIDEO = 4;
IVENGO_SDK = 5;
IMA_SDK = 6;
YUME_SDK = 7;
MY_TARGET_SDK = 8;
YANDEX_ADS = 9;
SPOTX_SDK = 10;
FACEBOOK_SDK = 11;
}
enum BannerType {
INTERSTITIAL = 1;
GRAPHIC = 2;
VIDEO = 3;
NATIVE = 4;
NATIVE_TEMPLATE = 5;
}
enum PredicateForm {
CNF = 0;
DNF = 1;
}
message PredicatePart {
repeated uint64 positive_tags = 1;
repeated uint64 negative_tags = 2;
}
message Predicate {
optional PredicateForm form = 1;
repeated PredicatePart parts = 7;
}
optional AdType type = 1;
optional string name = 2;
repeated AdSytemParam params = 3;
optional int32 id = 4;
optional int32 price = 5;
optional BannerType banner_type = 6;
optional Predicate predicate = 7;
}
Замечания:
type
— тип SDK для интеграции рекламной сетиname
— название рекламной сетиparams
— параметры для рекламной сетиid
— уникальный идентификатор рекламной сетиprice
— эффективная стоимость размещения на 1000 показов баннера (eCPM)banner_type
— тип баннера:
INTERSTITIAL
— межстраничныйGRAPHIC
— графический или текстовыйVIDEO
— видео-рекламаNATIVE
— нативныйNATIVE_TEMPLATE
— нативный с шаблономpredicate
— предикат применимости рекламной сети
form
— форма записи предиката:
CNF
— конъюктивная формаDNF
— дизъюнктивная формаparts
— конъюктные (для дизъюнктивной формы) или дизъюнктные (дли конъюнктной формы) части предиката
positive_tags
— тэги, входящие в положительные литералыnegative_tags
— тэги, входящие в отрицательные литералыПараметры:
параметр | тип данных | значение |
---|---|---|
network_id |
строка | идентификатор рекламной сети |
place_id |
строка | идентификатор рекламного места |
Важно(!): В body нужно передать vast в формате xml
Запрос
GET /money_miner/1/erid.json?network_id=2&place_id=nncD2og3
Authorization: Bearer 18dasd81230dah12032
Host: api.peers.tv
Content-Type: application/xml
<VAST xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.iab.com/VAST" version="4.0">........
Ответ
HTTP/1.1 200 OK
Content-Type: application/json
{
"erid": {
"id": 5,
"network_id": 2,
"erid_external_id": 1,
"percent_erid_top": 20,
"percent_erid_left": 20,
"background_color_erid": "#FFC1CB",
"font_color_erid": "#FFC1CB",
"font_size_erid": 12,
"erid_value": "2RanykfPadaaS6k"
}
}
{
"erid": null
}
Замечания:
erid_external_id
— id способа передачи erid. На текущий момент доступны: 1 - videocontact, 2 - no erid (erid не передается)percent_erid_top
— Месторасположение левого верхнего угла ERID сверху (в процентах, а не пикселях)percent_erid_left
— Месторасположение левого верхнего угла ERID слева (в процентах, а не пикселях)font_size_erid
— Размер шрифта надписи ERID в пунктах(в пикселях)background_color_erid
— Цвет фона блока ERIDfont_color_erid
— Цвет шрифта блока ERIDerid_value
— Значение ERIDvast_ad_tag
AdPlace
описан атрибут request_delay
, ограничивающий частоту запросов к рекламным сетямAdSystem
добавлен идентификатор рекламной сетиYANDEX_RTB
в YANDEX_VIDEO
(Yandex Video SDK);request_delay
теперь подразумевает ограничение на частоту показов для рекламного места.block_num
для интеграции через Yandex Video SDKprice
для сообщения «AdSystem»[INSTALL_ID]
для параметра vast_ad_tag
banner_type
в примере ответа для метода places.json
PredicatePart
[SUBSCRIBER_ID]
для vast-рекламы.[IP_ADDRESS]
для VAST-рекламы.[REQUEST_UUID]
для VAST-рекламы.