Двусторонняя аналитика партнерского iframe-виджета на примере проекта “VIP-зал”
Проект “VIP-зал” решает задачу автоматизированного бронирования вип и бизнес-залов в аэропортах мира и России, и направлен на удовлетворение потребности бизнес и премиум клиентов различных авиакомпаний. Единая база данных тематических услуг в различных аэропортах интересна в первую очередь компаниям, связанным с пассажирскими авиаперевозками, онлайн-трэвел агентствам, а также туристическим компаниям с сайтами в интернете. Для таких компаний был создан виджет “VIP-зал”, позволяющий получить доступ к этой базе данных пользователю любого партнерского сайта.
Виджет устанавливается стандартным образом через iframe, партнеру нужно лишь разместить код у себя на сайте и настроить параметры внешнего вида согласно общей дизайн-концепции. В результате на сайте появляется модуль подбора и бронирования VIP-залов в интересующем аэропорту с доступом к премиум-услугам аэропорта, таким как шаттл (индивидуальный трансфер от зала до самолета), встреча в зале с табличкой, сопровождение сотрудника и доступ на парковку для VIP-клиентов. Процесс бронирования осуществляется за несколько простых шагов, внутри которых пользователь может варьировать содержимое заказа (рис.1).
Рисунок 1 - Внешний вид виджета на сайте
Учитывая вариативность заполнения данных, конечно же встает вопрос отслеживания этого процесса с точки зрения аналитики. Причем веб-анализ интересен как владельцу виджета так и устанавливающему его партнеру, поэтому в ходе разработки появилась задача отслеживания событий внутри виджета и передача их одновременно по двум направлениям:
А. Со всех сайтов, на которых установлен виджет, в веб-аналитику владельца (разработчика).
Б. С сайта, на котором установлен конкретный виджет, в веб-аналитику партнера.
В чем здесь сложность? В основном в том, что партнер берет единый код виджета, который не настраивается под конкретный партнерский сайт, но при этом хочет видеть в аналитике информацию только по своему виджету. Вторая трудность заключается в том, что разработчик (владелец) виджета должен получать данные сразу со всех партнерских сайтов в один счетчик, что идет вразрез с желанием партнера видеть только собственную информацию. В конце концов нужно попросту разграничивать те данные, которые должен видеть партнер, и которые будет видеть владелец. Задачу удалось решить с помощью Google Tag Manager (далее - GTM).
Данный инструмент широко используется для веб-аналитики и управления тегами на сайтах, описывать подробно принцип его действия не имеет смысла, для понимания достаточно ознакомиться с концепцией работы GTM из других статей. В данном случае важно понимать, что Google Tag Manager (рис.2) позволяет консолидировать данные с сайта внутри собственных контейнеров и раздавать их различным счетчикам веб-аналитики с помощью заданных правил.
Рисунок 2 - Окно “Теги” Google Tag Manager с уже настроенными тегами для виджета
Для начала опишем сам алгоритм решения этой задачи, чтобы сразу понимать каким путем мы двигались для достижения результата. Итак:
- Партнер, как и владелец, хочет отслеживать работу виджета одним из двух способов или сразу двумя - с помощью Яндекс.Метрики или Google Analytics.
- Удовлетворяющее решение должно передавать данные в 4 счетчика: Счетчик Метрики владельца, счетчик Google Analytics владельца, счетчик Метрики партнера и счетчик Google Analytics партнера.
- Внутрь виджета устанавливается единый контейнер Google Tag Manager, который будет собирать все данные и распределять их таким образом, чтобы каждый участник получал только нужную ему информацию.
- Идентификаторы счетчиков владельца задаются по умолчанию, идентификаторы партнера должны быть указаны им в момент генерации кода виджета в партнерском кабинете для дальнейшей установки на сайте.
- Поскольку для партнера уже настроен партнерский кабинет, идентификаторы можно задать в нем и пробросить внутрь виджета, чтобы Tag Manager использовал их.
- Внутри GTM происходит подстановка идентификаторов в коды срабатывания целевых событий, а также распределение передачи данных по счетчикам владельца и партнера.
- При этом GTM отправляет все собранные данные в счетчики владельца, а данные по сайту партнера - только в счетчики партнера, т.к. при подстановке идентификаторов отслеживается только заданный партнером сайт.
Для удобства понимания приведем блок-схему процесса (рис.3):
Рисунок 3 - Схема процесса передачи данных
Для начала определимся, что кроме кода Google Tag Manager на сайте также присутствуют автоматически сгенерированные коды счетчиков Яндекс.Метрики и Google Analytics. В них при генерации кода для сайта пробрасываются заданные партнером идентификаторы счетчиков.
Эти коды в виджете можно и не задавать, поскольку возможности GTM позволяют автоматически генерировать их на сайте как соответствующие теги (тип - Пользовательский HTML - рис.4), но в данном случае жёсткое прописывание в код виджета было необходимо - некоторые события на сайте требуют, чтобы счетчик сразу устанавливался внутрь виджета. В основном это события загрузки, появления преролла. Если же у вас нет такого рода событий, то можно генерировать код счетчика через GTM:
Рисунок 4 - Пример передачи кода Метрики на сайт через GTM
Чтобы передавать данные сразу в два счетчика (партнера и владельца), требуется устанавливать не два разных кода Метрики или Analytics, а создавать специальный сдвоенный код. На момент написания статьи правильные коды выглядят так (рис.5):
Рисунок 5 - Верный вариант использования сдвоенных кодов Метрики и GA
Далее нужно передать внутрь кода счетчика идентификатор, заданный партнером. Сложность здесь в том, что код виджета генерируется автоматически для всех сайтов, при этом идентификаторы задаются уже в отдельном партнерском кабинете. Для правильного проброса программистом было реализовано следующее решение:
При инициализации виджета создается iFrame, в параметры которого передаются идентификаторы счетчиков партнера (счетчики передаются в src iFrame, после чего парсятся в виджете из location). iFrame открывает приложение виджета и в хуке created жизненного цикла виджета (SPA) до монтирования обрабатываются входные параметры номеров счетчиков, а в localStorage сохраняются номера (идентификаторы).
Для размещения кода Google Analytics в index.html используется следующая конструкция:
<script> window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'UA-15930803-13'); gtag('config', window[localStorage.getItem('partnerGA')] || 'UA-15930803-14'); </script>
Скрипты с переменным src вставляются динамически при инициализации счетчиков:
let script = document.createElement('script') script.setAttribute('src', `https://www.googletagmanager.com/gtag/js?id=${ga || 'UA-15930803-14'}`) document.head.insertBefore(script, document.head.firstChild)
Здесь UA-15930803-14 – «подставной» счетчик владельца, который используется в том случае если партнером его счетчик не задан. Данная ситуация может возникнуть если партнер не задал идентификаторы счетчиков в целом или задал лишь один идентификатор – всегда должен быть подменный код, чтобы на сайте не возникало ошибок JavaScript, связанных с отсутствием идентификатора для правильного срабатывания кода передачи какого-либо события. UA-15930803-13 в данном случае – основной идентификатор Владельца, в который данные приходят в любом случае и с любого сайта.
Аналогично GA формируется код Яндекс.Метрики, в котором используются заданный идентификатор Метрики владельца, подменный идентификатор счетчика владельца «по умолчанию» и конструкция для передачи идентификатора партнера. Код формируется по схеме, представленной на рис.5 с применением конструкций из примера выше.
Следом за кодами счетчиков нужно пробросить заданные партнером идентификаторы внутрь Google Tag Manager. Внутри контейнера они уже будут использоваться как внутренние переменные, чьи значения можно поставлять в генерируемые события.
Для GTM чаще всего используется методика переменных уровня данных (dataLayer). Уровень данных - это переменная JavaScript, инициализация которой описывается внутри контейнера Google Tag Manager автоматически. С помощью нее можно передавать как происходящие на сайте события типа event, так и задавать для GTM собственные переменные. Делается это с помощью конструкции
dataLayer.push(‘имя_переменной’: ’значение_переменной’);
Срабатывающей после объявления кода GTM на сайте. Однако в нашем случае переменная уровня данных не сработала, возможно дело в сложностях работы именно с iframe. Если задавать конструкцию push() автоматически, то контейнер не получает переменных, а в данном случае хотелось именно такой реализации задачи. Если же пробовать задавать переменную уровня данных вручную (например, по любому клику на сайте), то проброс переменной проходит нормально.
Чтобы не тратить время на разбор процесса, мы использовали альтернативное решение - создание глобальных переменных JavaScript через localStorage.
Свойство localStorage позволяет хранить переменные с заданными значениями не привязываясь к открытой странице сайта, а данные внутри этого хранилища не могут быть просто так удалены. Соответственно, идентификаторы партнерских счетчиков были проброшены путем использования следующих конструкций:
localStorage.setItem('partnerMetrika1', 'УУУУУУУУ'); localStorage.setItem('partnerMetrika2', 'yaCounterУУУУУУУУ'); localStorage.setItem('partnerGA', 'UA-УУУУУУУ-УУ');
Здесь первая конструкция передает сам номер партнерской Метрики, вторая конструкция передает сборное значение yaCounter для удобства создания тега “Событие” в Google Tag Manager (об этом далее), а третья - идентификатор Google Analytics.
На этом передача данных завершена и в дело вступает настройка самого GTM.
Во-первых, определимся с принципом работы Google Tag Manager. В нем представлены 3 уровня взаимодействия:
Тег. Это часть кода, которая может быть размещена на сайте с установленным GTM и может быть выполнена как любой другой код, изменяя содержание сайта или передавая данные в счетчики веб-аналитики.
Тег срабатывает, если на сайте выполняется некоторое условие.
Триггер. Это собственно условие, выполнение которого вызывает за собой срабатывание тега. Это может быть событие (event) на сайте, изменение значения переменных или стандартное действие - например клик или просмотр страницы.
Переменная. Содержит в себе некоторые значения, которые можно передавать различными способами, и используется как поставщик данных для тегов или маркер условия.
Содержание переменных влечет за собой срабатывание триггера, а триггер в свою очередь вызывает соответствующий тег. Идентификаторы партнерских счетчиков задаются именно как переменные, с этого стоит начать формирование данных в контейнере GTM.
Мы создали три основных переменных типа “Собственный код JavaScript” (рис.6):
Рисунок 6 - Пример переменной, берущей партнерский идентификатор Метрики
Здесь значение переменной = то значение, которое мы взяли из localStorage.
Теперь если GTM обратится к переменной, то получит ее значение - идентификатор партнерской Метрики. Точно также мы создали переменные под номер партнерской Метрики и идентификатор партнерского Google Analytics.
Для чего используются такие переменные? Они решают задачу отправки данных о срабатывании событий на сайте в партнерские счетчики. В Google Tag Manager есть стандартная процедура передачи целей в Google Analytics, где в качестве идентификатора счетчика можно использовать значение переменной. А для Метрики используется тег в виде пользовательского HTML-кода, содержащего стандартный JavaScript Метрики:
yaCounterXXXXXX.reachGoal('TARGET_NAME');
Здесь TARGET_NAME - это внутреннее наименование целевого события для Метрики (такие цели создаются в настройках счетчика через тип “JavaScript-событие”), а ХХХХХХ - номер счетчика.
Таким образом, мы создаем для разного вида счетчиков соответствующие теги.
Для Google Analytics:
Тип тега - “Universal Analytics”, идентификатор отслеживания - из нашей переменной.
Рисунок 7 - Пример настройки тега, передающего данные в Google Analytics.
Здесь Категория и Действие - те значения, которые должен поймать Google Analytics в качестве параметров срабатывания цели. Идентификатор отслеживания - заданная ранее переменная, взявшая партнерский идентификатор из localStorage.
Для Яндекс.Метрики:
Тип тега - “Пользовательский HTML” с применением конструкций JavaScript.
Рисунок 8 - Пример настройки тега, передающего данные в Яндекс.Метрику
Здесь {{PartnerMetrikaCounter}} - внутреннее объявление переменной, берущей идентификатор партнерской Метрики из localStorage. С помощью объекта window мы подставляем значение переменной в исполняемый код, и на выходе получаем yaCounterXXXXXXХХ.reachGoal('widget_loading');, где widget_loading - значение, которое ловит Метрика в качестве параметра срабатывания цели.
Остается только задать триггеры, чтобы сработали соответствующие теги. Триггерами в нашем случае стали, к примеру:
- События успешной загрузки виджета;
- События успешного или неуспешного прохождения шага на виджете;
- Заполнение определенных полей;
- Выбор условий А или Б внутри виджета;
- Взаимодействие с формами, кнопками и ссылками.
Далее в настройках счетчиков Метрики и Google Analytics остается лишь создать соответствующие цели:
Рисунок 9 - Пример настройки цели в Яндекс.Метрике
Рисунок 10 - Пример настройки цели в Google Analytics
Задача решена. Сдвоенные коды счетчиков подставляют в идентификаторы Метрики и Analytics партнера заданные им значения, а значения идентификаторов владельца остаются неизменными. В то же время Google Tag Manager пробрасывает срабатывания соответствующих целей в счетчики партнера только в том случае если получает из переменных именно те идентификаторы, которые задал конкретный партнер на своем сайте. Параллельно с этим GTM отправляет владельцу все целевые события со всех сайтов.
Если же партнер не задал один или оба идентификатора, то используются значения по умолчанию - идентификаторы тестовых счетчиков, заданные владельцем заранее.