Money Miner

Статус документа

Оглавление

Введение

MoneyMiner API предназначен для медиации и таргетирования рекламных сетей, используемых в приложениях. Использую систему управления медиацией и таргетированием можно:

Взаимодействие с API

Точка входа в API определяется Регистратурой, идентификатор сервиса — «money_miner». Обращения строятся по схеме:

<entry_point>/<method>.<format>?[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 со значением:

Правила применения рекламных сетей

Информационные сервисы, предоставляющие контент, могут передавать список рекламных тэгов, характеризующих контент для рекламных целей.

Для каждой рекламной сети может быть определен унарный предикат — здесь и далее называемый предикатом применимости рекламной сети, определяющий возможность применения данной рекламной сети на контенте. Рекламная сеть может быть применена на контенте, если предикат, примененный к списку рекламных тэгов контента, вернул Истину.

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

Представление предиката применимости в API

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

  1. Атомарной формулой предиката является принадлежность конкретного тэга множеству тэгов контента. Также это называется «положительным литералом».
  2. Отрицательным литералом, при этом становится отсутствие конкретного тэга в множестве тэгов контента.
  3. Далее, литералы объединяются в промежуточные части: дизъюнкты — с помощью операции логического «ИЛИ» — при представлении в конъюктивной форме; или конъюнкты — операции логического «И» — при представлении в дизъюнктивной форме.
  4. Промежуточные части объединяются в предикат с помощью операции логического «И» — при представлении в конъюктивной форме, или логического «ИЛИ» — в дизъюнктивной форме.

При сериализации:

  1. Форма представления предиката — конъюктивная или дизъюнктивная — передается в параметре form.
  2. Дизъюнкты в конъюктивной форме (или конъюнкты — в дизъюнктивной) передаются в массиве parts, в котором:
    1. Идентификаторы тэгов, принадлежащих положительным литералам, передаются в массиве positive_tags.
    2. Идентификаторы тэгов, принадлежащих отрицательным литералам, — в массиве negative_tags.

Пример

Предикат выражен в конъюнктивной форме следующим образом. Показывать рекламу, если выполнено условие:

(нет метки "Первый канал") И (нет метки "Спорт" ИЛИ есть метка "Новости" ИЛИ есть метка "Детское")
  1. Форма представления — конъюктивная — CNF.
  2. Первый дизъюнкт — нет метки "Первый канал"
    1. Дизъюнкт состоит из одного отрицательного литерала.
    2. Записываем его в массив negative_tags: ["Первый канал"]
  3. Второй дизъюнкт — нет метки "Спорт" ИЛИ есть метка "Новости" ИЛИ есть метка "Детское"
    1. Состоит из одного отрицательного литерала: нет метки "Спорт"
    2. Записываем его в массив negative_tags: ["Спорт"]
    3. Два положительных литерала: есть метка "Новости" и есть метка "Детское" оформляем в массив 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"]
        }
    ]
}

Особенность интерпретации отсутствия рекламных тэгов у контента

Отсутствие рекламных тэгов у контента должно интерпретироваться клиентом как пустой массив рекламных тэгов.

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

  1. Отсутствие предиката должно интерпретироваться клиентом как безусловное разрешение использования рекламной сети.
  2. Пустой предикат в любой форме (конъюктивной или дизъюнктивной) должен интерпретироваться клиентом как всегда истинный, тем самым разрешая использование связанной с ним рекламной сети.
  3. Отсутствие атрибута negative_parts или positive_parts у части предиката должно интерпретироваться клиентом как пустой массив для данного атрибута.
  4. Пустые части предиката (в которых оба атрибута negative_parts и positive_parts являются или интерпретируются как пустые массивы) должны отбрасываться при вычислении значения предиката.
  5. Предикат в любой форме, сводимый к пустому, должен интерпретироваться клиентом как всегда истинный, тем самым разрешая использование связанной с ним рекламной сети.

Формирование предиката на стороне сервера

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

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

Имея таблицу истинности, можно выбрать подходящую форму для представления предиката, а затем — минимизировать ее с помощью любого известного алгоритма, например, с помощью метода Куайна.

Реализация на клиенте

Пример реализации на клиенте можно посмотреть в файле money_miner_predicates_example.

Требования по реализации

Для корректной работы системы приложение должно:

Типы рекламных сетей

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

Параметры:

Список известных макросов для параметра vast_ad_tag заполняемых на клиенте:

Список макросов, заполняемых на сервере:

Пояснение по параметрам для Yandex Video SDK:

В панели администратора используются идентификаторы блоков вида R-V-171889-2, в данном идентификаторе зашит идентификатор партнера 171889 и номер блока 2.

Примеры получения параметра для макроса [DEVICE_MANUFACTURER]:

Примеры получения параметра для макроса [DEVICE_MODEL]:

Методы

places — получение информации по местам баннеров

Параметры:

параметр тип данных значение
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
   }]
}

Описание ответов в формате Google Protocol Buffers

AdPlaceList, AdPlace — рекламной место

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];
}

Замечания:

AdSystem, AdSystemParam — описание рекламной сети

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;
}

Замечания:

erid — получение информации об erid

Параметры:

параметр тип данных значение
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

{
    "erid": null
}

Замечания:

История изменений

Изменения в версии 1.0.0 (TVREC–810)

Изменения в версии 1.0.1

Изменения в версии 1.0.2

Изменения в версии 1.1.0

Изменения в версии 1.1.1

Изменения в версии 1.2.0 (TVREC–892)

Изменения в версии 1.2.1 (TVREC–899)

Изменения в версии 1.2.2

Изменения в версии 1.2.3 (TVREC–785)

Изменения в версии 1.2.4 (PTVANDR–1633, PTVIOS–1520)

Изменения в версии 1.2.5 (PTVANDR–1688)

Изменения в версии 1.3.0

Изменения в версии 1.3.1

Изменения в версии 1.4.0

Изменения в версии 1.4.1 (PTVTUBE–101)

Изменения в версии 1.4.2 (TVREC–1050)

Изменения в версии 1.5.0 (TVREC–1052)

Изменения в версии 1.5.1

Изменения в версии 1.5.2

Изменения в версии 1.5.3 (TVREC–1031)

Изменения в версии 1.6.0 (TVREC–1074)

Изменения в версии 1.6.1

Изменения в версии 1.6.2

Изменения в версии 1.6.3

Изменения в версии 1.6.4

Изменения в версии 1.7.0

Изменения в версии 1.8.0 (PTVRND–1685)

Изменения в версии 1.9.1

Изменения в версии 1.9.2

Изменения в версии 1.9.3