Реклама в Интернете проходит сразу по нескольким каналам и размещается на множестве площадок для охвата как можно большей аудитории. Управление кампаниями осуществляется через интерфейсы различных рекламных систем (Яндекс.Директ, Google AdWords, система размещения Вконтакте и проч.). Каждый раз для просмотра статистики необходимо логиниться, переключаться, а в случае, если возникает потребность сравнить статистики разных площадок, приходится ещё и агрегировать данные в таблицах Excel или вручную импортировать данные в Google Analytics.
Realweb как никто знает о необходимости удобной и эффективной работы с данными онлайн-рекламы: мы ведём сотни клиентов с десятками тысяч кампаний, поэтому наглядное представление статистики для нас – критичный фактор. Для этого мы используем систему сбора рекламной статистики AdHands. Это своеобразный дашборд: информация по всем рекламным кампаниям агрегируется в едином интерфейсе. Такой подход обеспечивает удобство, широкие аналитические возможности и точное понимание того, какая реклама эффективна, а какая – нет.
В случае размещения рекламы в Интернете оценить «выхлоп» от неё крайне сложно. На дворе XXI век, господа! И для измерений показателей работы рекламы в интернете есть интересные функциональные инструменты, готовые работать через API со всеми сервисами.
AdHands – длинные руки онлайн-рекламы
AdHands – одно из таких решений. Это система, которая подключается к площадкам онлайн-рекламы (Яндекс.Директ, Яндекс.Маркет, Google Adwords, Вконтакте, Target@Mail.ru, DoubleClick Bid Manager, Яндекс.Аукцион и др.) посредством API.
Мы долго думали, какой же должна быть единая система управления рекламными кампаниями в Интернете. В итоге было принято решение разработать систему, которая способна преодолеть сразу несколько проблем. Первой и главной особенностью AdHands стал единый интерфейс доступа ко всем собранным статистикам – такое решение позволило отказаться от необходимости каждый раз логиниться, работать в разных GUI. Получилась единая удобная панель, дашборд, на котором доступно представлены все необходимые показатели рекламы.
Разумеется, ни одна статистика не имеет практической ценности, если она не агрегируется и не обрабатывается должным образом. В систему были добавлены возможности автоматического расчёта стоимости цели, заказа, звонка, подсчёт ROI. Было внедрено медиапланирование – ценная функция для тех, кто ведёт чужие бюджеты или имеет жесткую систему бизнес-планирования в компании, в рамках которой необходимо заранее просчитывать маркетинговый и рекламный бюджет.
AdHands работает на конечного пользователя, делая его жизнь намного проще. Однако при создании самой системы возникает ряд сложностей, связанных с тем, что приходиться взаимодействовать с различными внешними системами.
Работа с API – строим мосты
Всем известно, насколько сложен мир программирования и разработки – несмотря на создание постоянных описаний стандартов и попытки договориться, каждый разработчик привносит в код что-то своё. В случае с API это порой озадачивает разработчиков внешних систем, например, AdHands. Расскажем подробнее о том, с чем мы столкнулись, используя чужие API при создании нашей системы управления онлайн-рекламой.
Работая со сторонними системами, мы выработали ряд критериев, по которым мы определяем, насколько удобна система, которую мы подключаем к AdHands. Если говорить широко, то такая система должна быть прежде всего удобна с точки зрения разработчика. А если рассмотреть в частности, то важно, чтобы подключаемая система соответствовала нескольким параметрам.
- Стабильность системы – её доступность в 99,9% времени в году. Наверное, излишне объяснять насколько это важно для системы, собирающей и передающей данные рекламных онлайн-кампаний, которые транслируются ежесекундно по всему Интернету.
- Наличие документации – абсолютно критичное требование. Понять API без документации чрезвычайно сложно, особенно, если приходится обрабатывать ошибки и внештатные ситуации. Нужно понимать, что API – фактически чужой код, и смотря на стремление крупнейших онлайн-площадок к универсальности, счастливое будущее ещё далеко и API обязательно должно сопровождаться детальной девелоперской документацией, так, например, как это реализовано у Google AdWords и Яндекс.Директ.
- Поддержка авторизации OAuth 2.0 – удобного и безопасного открытого протокола авторизации.
- Отзывчивая техническая поддержка системы, безусловно, не может быть требованием, но это пожелание – к сожалению, не всегда удается быстро получить квалифицированный ответ. А решение проблем в таких системах как AdHands, требует максимальной оперативности во избежание потери лояльности клиентов.
- Понятность – методы и функционал API должны по семантике соответствовать тому, что выполняют. Например, метод «добавить пользователя» должен добавлять пользователя, не решая при этом ещё ряд задач.
Безусловно, в идеале хотелось бы, чтобы все подключаемые системы имели единообразное универсальное API и можно было бы использовать один код для всех систем. Уже сделаны определенные шаги в эту сторону, однако до полной унификации столь далеко, что пока она кажется невозможной.
Работа с API – поговорим о проблемах
Расхождение в терминологии API площадок – у разных систем сущности могут отсутствовать или по-разному называться. Например, недавно Яндекс.Директ ввёл сущность «группа объявлении?», а долгое время до этого такая сущность была только у AdWords. Похожая ситуация возникает, например, с термином «креатив», который встречается у БаЯна и у DBM, но по факту для разработчика креатив в этих двух системах – разные сущности. Преодоление таких расхождений требует времени и поэтому приходится искать решение c помощью построения особой архитектуры AdHands. Однако эта проблема не столь значительна, как остальные.
Различия в структуре данных – проблема, вытекающая из различий в структуре самих площадок (опять же, например, может не быть групп объявлений). Это важный вопрос для AdHands, ведь мы не копируем интерфейсы систем в одном приложении, а собираем данные для их представления пользователю. Не хочется каждый раз менять структуру страниц, подстраиваясь к системам. Мы обходим проблему, приводя данные из различных источников к единой структуре. Фактически мы создаём близкие по структуре иерархии и гибридные решения, когда сущность остаётся доступной при выборе одной системы и закрытой для других. AdHands добивается единообразия и удобства интерфейса путём абстрагирования сущностей.
Все разработчики относятся к документации по-разному: кто-то досконально документирует каждую переменную, кто-то описывает в общих чертах, а некоторые и вовсе отказываются от какой-либо документации. При работе с API внешней системы наличие детальной документации — залог успеха. Однако даже при наличии подробных мануалов и коммьюнити разработчиков возникают проблемы, среди которых главная — несоответствие документации и реального положения дел: иногда случается, что расходятся документация, программный интерфейс и графический пользовательский интерфейс. Как правило, это связано с тем, что API меняется и дополняется достаточно быстро, а документация обновляется медленнее, поэтому в ней можно найти устаревшие функции или не найти что-то из новых возможностей. Идеально, если релиз новой версии API происходит одновременно с релизом документации.
По опыту Realweb можем сказать, что практически не встречается документации, не соответствующей действительности. Однако здесь вступает в действие человеческий фактор, и иногда из-за отсутствия уведомлений и рассылок об изменениях удаётся узнать не сразу.
У каждой системы API периодически изменяется и дорабатывается. Постоянное изменение API само по себе явление необходимое – программный интерфейс развивается вместе с системой. Плохо, если выходят изменения, но, допустим, не поменялась сигнатура методов. Хорошо, если бы при обновлении API все библиотеки обновлялись по расписанию.
Расхождение API и интерфейса – проблема не очень распространённая. Безусловно, поставщик API понимает, что и для программного интефейса, и для интерфейса пользователя сущности должны быть одинаковы. Бывает, API не предоставляет методов для некоторых элементов графического интерфейса. Если какие-то сущности в программном интерфейсе отсутствуют, приходится создавать псевдосущности – связку для того, чтобы вписаться в универсальную структуру AdHands.
Крайне редко, но всё же случается, что API отсутствует вовсе. Например, с такой ситуацией мы столкнулись, работая с системой размещения КМС баннеров Яндекса. В таких случаях приходится парсить интерфейс с помощью краулера и заходить как пользователь через связку логин/пароль. Здесь основной камень преткновения возникает, если меняется графический интерфейс пользователя – меняется вёрстка, парсер возвращает ошибки. Но, в основном, все современные системы предоставляют доступ через API. А вот те, кто не готов предоставить адекватные библиотеки и документацию, рискует остаться за гранью конкуренции.
Отсутствие удобной и универсальной OAuth 2.0 авторизации – проблема, которая продолжает встречаться. Как известно, протокол авторизации OAuth 2.0 находится в стадии доработки спецификации, однако он уже вполне готов прийти на смену OAuth. Это удобный протокол, который отличает простота в использовании, отсутствие длинной цепочки запросов и сложных схем подписи. Некоторые площадки и агрегаторы рекламы его пока не используют, видимо, в ожидании стабильной спецификации. Это значительно усложняет процесс авторизации и аутентификации при запросе данных внешних систем и передаче данных. Например, БаЯн от Яндекса работает на токенизации по логину/паролю. С точки зрения разработчика это не вполне безопасно, поскольку способно нанести ощутимый ущерб в случае компрометации базы, в которой хранятся логины и пароли доступа к БаЯну.
Сейчас большинство крупных систем уже перешли на OAuth 2.0. Кроме того, что это безопасно, это ещё всеобщий стандарт и гарантия быстрого подключения системы к AdHands.
Отсутствие единого универсального протокола обмена данными – ещё одна проблема. В случае, если бы он существовал, AdHands просто пробрасывал бы данные системы как единый пульт управления. Однако в случае создания подобного протокола на рынке возникнет множество компаний, готовых построить бизнес на инновации, как это обычно происходит. А это может привести к появлению непродуманных решений, которые скомпрометируют серьёзные системы в глазах конечного пользователя. К тому, же создание единого протокола не очень выгодно крупным площадкам, которые не готовы и не собираются отказываться от своих графических интерфейсов.
Ещё одна проблема, на которую мы можем мало влиять, это лимиты API – ограниченное количество запросов в день, которое устанавливают рекламные системы. У каждого метода API есть свой лимит обращений, который определяется ресурсоёмкостью и «тяжестью» метода. В принципе, у Google AdWords и Яндекс.Директ число запросов столь велико, что ощутить ограничение сложно, но есть и проблемные сервисы, например, Яндекс.Маркет, обращение к методам которого порой напоминает попытку достать талончик к нужному врачу. Площадки часто идут навстречу и расширяют лимиты, однако при этом внимание уделяется и структуре самих систем-агрегаторов, которые могут не оптимально использовать запросы.
Конечно, это далеко не полный список проблем и мелких препятствий, с которыми разработчикам AdHands приходится сталкиваться ежедневно. Мы всегда ищем компромиссы и не боимся использовать в коде решения, которые кому-то могут показаться не очень изящными. Это обусловлено большим количеством присоединяющихся систем, разнообразием их GUI и API. Мы пишем парсеры для систем без API, создаём лишние сущности, привносим куски кода с проверками, реализуем новый функционал, не заложенный в AdHands. Все эти решения могут оказывать влияние на управляемость и удобство администрирования системы, на её быстродействие. Но вместе с тем мы непрерывно оптимизируем код, подстраиваемся под систему лимитов и делаем всё для удобства наших пользователей.
В последнее время наметилась тенденция к унификации API крупных площадок. Например, прототип API Яндекс.Метрики в части Core reporting копирует API Google Analytics. Мы надеемся, что и другие провайдеры API не будут жить своей жизнью, а присмотрятся к лучшим практикам и последуют не модному, а весьма полезному тренду. А совместными усилиями мы сделаем лучше для тех, ради кого всё затевалось, – для конечных пользователей, рекламных агентств и рекламодателей. Большинство из них не знает об API и его проблемах, им нужно быстро, удобно и понятно. Наше дело это обеспечить.
Комментарии (7)
Itimora
15.07.2015 11:46+2Ребята из Realweb, спасибо за пост и освещение проблемы. Сами постоянно сталкиваемся с проблемами совместимости, документации и имён данных. Понимаю, что размещать код ваших сущностей и «подпорок» вам невыгодно, но ход решения проблем совершенно ясен, взяли на вооружение идею с псевдопеременными. Что касается унификации, то да, она протекает очень медленно и это требует немыслимых сил на поддержку API.
meeshaeel
15.07.2015 11:48А в какую БД складываются данные от всех API? Какой объем данных в ней хранится и какой поток операций она обрабатывает?
RealWeb Автор
15.07.2015 13:39+2Складываем в MySQL, причём в два. Один MySQL (MyISAM с партицированием по месяцам) используется для хранения статистики по ROLAP. Второй MySQL (InnoDB) для хранения нестатистических данных, таких как имена рекламных кампаний и т. п. На данный момент обе базы занимают около 1ТБ на жёстком диске. Данные от API обрабатываем в пакетном режиме, при обработке пакета пишем где-то 100 записей в секунду, но так как пакеты маленькие (100000 записей), то нагрузка на базу непостоянная. Пакеты маленькие, потому что, в основном, это статистика за прошедший или текущий день.
Mistx
15.07.2015 15:45Вам предстоит создать архитектуру вида Фабрика адаптеров. Для каждого адаптера будут определены стандартные действия, в виде классов. Объём кода при подключении очередного адаптера существенно сократится при использовании абстрактных классов адаптеров и действий с выделением общих методов взаимодействия с API.
arturgspb
15.07.2015 16:01Я не работаю в AdHands, но как человек, работавший с API Директа v4, Google AdWords 2013+, ВКонтакте, Begun могу сказать, что они настолько разные, что у вас либо будет выбираться слишком много данных из БД, чтобы сохранить интерфейсы простыми и будут проблемы с потерей remote id добавленых объектов, либо запросы к api будут неэффективными.
Поясню детально: в апи Директа до v5 добавлять и редактировать объявления можно только сразу передавая все параметры объявления, все ключевые слова, ставки и настроки по ним — просто адское кол-во данных (https://tech.yandex.ru/direct/doc/dg-v4/reference/CreateOrUpdateBanners-docpage/). Слава богу они в v5 это поправили и сделали более менее как в гугле. Доходило до того, что чтобы не затереть автопроставленные минус слова на фразах нам приходилось скачивать обявление из api, менять то, что нам нужно и отправлять обратно.
Что касается гугла, то тут наоборот — на каждый пук, извините, вызов метода. Например — добавить объявление, добавить допссылку, связать допссылку с объявлением. Хотя стоит отметить, что это лучший api, с которым мне пришлось работать по уровню свободы действий и в целом эффективности запросов к нему. Он на soap (xml), но работает раз в 5 быстрее чем json у api директа v4.
Ну и прикиньте еще, что будет у вас в «общих» методах. Еще вспомните о том, что программы падают, сеть пропадает и происходит много чего, что может вызвать добавление объектов во внешних сиетемах, но при этом упадет до сохранения полученных remote id объектов у вас в системе.
А еще в разных внешних системах не всегда совпадает иерархия объектов и вообще их наличие, настройки, иерархия настроек.
В общем-то я не против общих методов, они полезны, но иногда их поддержка стоит дороже, чем отдельная реализация.
forgotten
И что, где же заявленные истории «преодоления сложностей»? Или цель была просто заявить «смотрите, какие мы крутые»?
Кому и зачем нужен ваш пост на Хабре?
Analitik_Telecom
Я вот как разработчик понимаю, почему в статье даны лишь намёки на решения :-) Однако все проблемы и вопросы подняты максимально чётко и откровенно. А как известно, правильная постановка вопроса — половина решения. Пост годный, на самом деле.