Как исключить дублирование транзакций в Google Analytics с помощью customTask

Недавно в своём телеграм-канале Дмитрий Осиюк дал ссылку на статью Simo Ahava о том, как исключить дублирование транзакций в Google Analytics с помощью customTask. Мы решили перевести данное руководство, чтобы даже у тех, у кого нет времени разбираться с английским, была возможность решить данный вопрос.

Одной из наибольших проблем в модели данных Google Analytics является неизменность исторических данных. При записи информации в таблицу данных она остается там практически навсегда.

Это явление особенно раздражает в двух случаях: при спаме и фиктивных заказах электронной коммерции.

Первый случай является общепризнанной проблемой с открытым и общедоступным протоколом сбора данных. Во втором случае попросту возникает раздражение, которое может привести к полномасштабному саботажу (например, вы можете использовать Measurement Protocol для отправки сотен транзакций в Google Analytics вашего конкурента).

Проблема заключается в дублировании транзакций. На вашем сайте, как и на большинстве других, скорее всего есть страница оплаты, которую можно просмотреть через кеш или историю браузера. При повторном посещении страницы оплаты часто случается, что детали транзакции снова записываются в dataLayer(или отправляются с помощью метода ga()), что приводит к дублированию данных вашей электронной коммерции.

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

  • удаляете тестовые транзакции;
  • редактируете состав транзакций;
  • удаляете отменённые заказы.

Я принял решение об использовании customTask, поскольку это позволяет избежать использования лишних триггеров или логической переменной. Мы выполним настройку с помощью Google Tag Manager, однако ничто не мешает вам сделать то же самое прямо в коде analytics.js.

Чтобы проверить есть ли в вашем аккаунте такая проблема:

1) перейдите в Google Query Explorer по этой ссылке;
2) авторизуйтесь в свой Google аккаунт;
3) выберите представление данных, которое хотите проверить;
4) нажмите кнопку Run Query.

Если в полученном отчете будет 0 результатов — у вас не было замечено такой проблемы за последние 30 дней. Если же в отчете есть данные — у вас обнаружены дублирующиеся транзакции в выбранном представлении данных.

Оглавление

  • Как это работает
  • Переменная customTask
  • Триггеры и переменные для стандартной электронной коммерции
    • DataLayer-переменная для идентификатора транзакции
    • 1st Party Cookie для списка идентификаторов транзакций
    • Пользовательская переменная JavaScript для проверки наличия идентификатора в списке
    • Триггер исключения
  • Выводы

Как это работает

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

Во время активации метод ищет ключ &ti, соответствующий значению идентификатора транзакции.

Затем он ищет в вашем браузере уже отправленные идентификаторы транзакций.

  • Если требуемый ID транзакций найден в хранилище браузера, customTask  выполняет блокировку для предотвращения попадания дублирующейся информации в Google Analytics.
  • Если требуемый идентификатор не найден в хранилище браузера, то customTaskотправляет информацию в GA в обычном режиме, но сохраняет ID транзакции в списке уже записанных. Таким образом, в будущем он блокирует отправку любой информации с этим идентификатором.

Важно! Эта функция автоматической блокировки работает только с расширенной версией Электронной торговли. В стандартной электронной торговле customTaskобновляет только хранилище браузера, но при этом ничего не блокирует. В этом случае вам придется использовать дополнительные триггеры. О том, как их настроить, я расскажу дальше.

Переменная customTask

Скопируйте и вставьте приведенный ниже код в переменную Собственный код JavaScript (ниже приведена подробная инструкция). Переменная Собственный код JavaScript должна выглядеть следующим образом:

function() {
  // customTask Builder by Simo Ahava
  //
  // More information about customTask: https://www.simoahava.com/analytics/customtask-the-guide/
  //
  // Change the default values for the settings below.

  // transactionDeduper: Configuration object for preventing duplicate transactions from being recorded.
  // https://bit.ly/2AvSZ2Y
  var transactionDeduper = {
    keyName: '_transaction_ids',
    cookieExpiresDays: 365
  };

  // DO NOT EDIT ANYTHING BELOW THIS LINE
  var readFromStorage = function(key) {
    if (!window.Storage) {
      // From: https://stackoverflow.com/a/15724300/2367037
      var value = '; ' + document.cookie;
      var parts = value.split('; ' + key + '=');
      if (parts.length === 2) return parts.pop().split(';').shift();
    } else {
      return window.localStorage.getItem(key);
    }
  };

  var writeToStorage = function(key, value, expireDays) {
    if (!window.Storage) {
      var expiresDate = new Date();
      expiresDate.setDate(expiresDate.getDate() + expireDays);
      document.cookie = key + '=' + value + ';expires=' + expiresDate.toUTCString();
    } else {
      window.localStorage.setItem(key, value);
    }
  };

  var globalSendHitTaskName   = '_ga_originalSendHitTask';

  return function(customTaskModel) {

    window[globalSendHitTaskName] = window[globalSendHitTaskName] || customTaskModel.get('sendHitTask');
    var tempFieldObject, dimensionIndex, count, ga, tracker, decorateTimer, decorateIframe, iframe;

    customTaskModel.set('sendHitTask', function(sendHitTaskModel) {

      var originalSendHitTaskModel = sendHitTaskModel,
          originalSendHitTask      = window[globalSendHitTaskName],
          canSendHit               = true;

      var hitPayload, hitPayloadParts, param, val, regexI, trackingId, snowplowVendor, snowplowVersion, snowplowPath, request, originalTrackingId, hitType, nonInteraction, d, transactionId, storedIds;

      try {

        // transactionDeduper
        if (typeof transactionDeduper === 'object' && transactionDeduper.hasOwnProperty('keyName') && transactionDeduper.hasOwnProperty('cookieExpiresDays') && typeof sendHitTaskModel.get('&ti') !== 'undefined') {
          transactionId = sendHitTaskModel.get('&ti');
          storedIds = JSON.parse(readFromStorage(transactionDeduper.keyName) || '[]');
          if (storedIds.indexOf(transactionId) > -1 && ['transaction', 'item'].indexOf(sendHitTaskModel.get('hitType')) === -1) {
            canSendHit = false;
          } else if (storedIds.indexOf(transactionId) === -1) {
            storedIds.push(transactionId);
            writeToStorage(transactionDeduper.keyName, JSON.stringify(storedIds), transactionDeduper.cookieExpiresDays);
          }
        }
        // /transactionDeduper

        if (canSendHit) {
          originalSendHitTask(sendHitTaskModel);
        }

      } catch(e) {
        originalSendHitTask(originalSendHitTaskModel);
      }

    });

  };
}

В переменной transactionDeduper есть объект конфигурации, который при необходимости может быть изменен. Он должен иметь как keyName, так и cookieExpiresDays кодом.

Задайте необходимое keyNameдля файла cookie или ключа localStorage. Значением по умолчанию является _transaction_ids

Установите для cookieExpiresDays кодом необходимое количество дней существования cookie.

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

Реализация основной логики происходит ближе к концу блока кода, где я поместил решение с помощью // transactionDeduperи // /transactionDeduper.

Все действительно довольно просто, и наблюдается определенное соответствие процессу, который я описал выше.

В случае использования расширенной электронной торговли, customTaskзаботится обо всем за вас. Если ID транзакции будет найден в списке сохраненных идентификаторов, он просто заблокирует повторную отправку информации в Google Analytics.

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

В любом случае вам нужно добавить эту переменную customTaskво все теги расширенной электронной коммерции и/или Теги транзакций, которые могут отправлять информацию о покупках в Google Analytics. 

Как добавить customTask в ваши тэги электронной торговли?

Чтобы добавить customTask в Google Tag Manager вам необходимо создать пользовательскую переменную:

Тип переменной “Собственный код JavaScript”:

В появившееся поля ввода необходимо скопировать код, приведённый выше и дать переменной имя customTask.

Должно получиться так:

Сохраните переменную.

Теперь необходимо подключить во всех тэгах Электронной торговли данную переменную.
Перейдите в раздел “Тэги” и откройте тэг Электронной торговли:

В настройках необходимо проделать следующие операции:

1. Включить переопределение настроек
2. Раскрыть поля “Дополнительные настройки” и “Поля, которые необходимо задать”
3. Ввести название поля customTask
4. Дать ссылку на переменную customTask, которую мы создали ранее.
В нашем случае это {{customTask}}

Сохраните изменения в тэге.

Если код Universal Analytics (analytics.js) установлен непосредственно на сайте, то необходимо проделать следующие операции:

1. Определить функцию JavaScript _customTask — её код приведён выше.

Начало кода выглядит так:

function() {

 // customTask Builder by Simo Ahava
...

Необходимо в начале дописать:

var _customTask = function() {

 // customTask Builder by Simo Ahava
...

2. Установить customTask

ga('create', 'UA-XXXXX-Y');
ga('require', 'ec');

ga('ec:addProduct', {
 'id': 'P12345',
 'name': 'Android Warhol T-Shirt',
 'category': 'Apparel',
 'brand': 'Google',
 'variant': 'black',
 'price': '29.20',
 'quantity': 1
});

ga('ec:setAction', 'purchase', {
 'id': 'T12345',
 'affiliation': 'Google Store - Online',
 'revenue': '37.39',
 'tax': '2.85',
 'shipping': '5.34',
 'coupon': 'SUMMER2013'    
});

ga('set', 'customTask', _customTask()); //С помощью данной функции запускаем customTask
ga('send', 'pageview');

Триггеры и переменные для Стандартной электронной торговли

Т. к. в стандартной электронной торговле передача информации о покупке делится на хит транзакции и хит информации о товаре, логику блокировки было бы крайне сложно автоматизировать в customTask. Вот почему вам необходимо создать триггер исключения для вашего тега транзакции: он будет блокировать запуск тега, если ID транзакции найден в списке сохраненных идентификаторов.

Переменная уровня данных для идентификатора транзакции

Создайте переменную уровня данных для транзакции, например:

1st Party Cookie для списка идентификаторов транзакций

Создайте переменную 1st Party Cookie для списка ID транзакций, используя keyName, которое вы указали в customTask. Вот как будет выглядеть настройка по умолчанию:

Пользовательская переменная JavaScript для проверки наличия идентификатора в списке

Наконец, создайте переменную Собственный код JavaScript, которая возвращает true, если идентификатор транзакции найден в списке.

function() {
  // Change this to match the keyName you added to customTask:
  var keyName = '_transaction_ids';
  
  var ids = JSON.parse((!!window.Storage ? window.localStorage.getItem(keyName) : {{Cookie - _transaction_ids}}) || '[]');
  return ids.indexOf({{DLV - transactionId}}) > -1;
}

Назовите переменную. Например, {{JS — transactionId sent}}.

Триггер исключения

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

В условиях триггера проверьте, является ли {{JS — transactionId sent}} равным значению true. Таким образом, триггер исключения заблокирует тег, если ID транзакции найден в списке уже записанных идентификаторов.

Вот пример того, как выглядит исключение с триггером пользовательского события, и как оно добавляется в тег:

Выводы

Поиски по усовершенствованию качества данных Google Analytics с помощью customTaskпродолжаются до сих пор.

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

Однако каждый дополнительный customTaskснижает прозрачность вашей настройки, что не позволит сказать с первого взгляда, какую задачу решает тот или иной тег.

Понравилась статья? Делитесь ей в соцсетях!

Оставляйте ваши вопросы на нашей странице в Facebook

Оцените статью

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (2 оценок, среднее: 5,00 из 5)
Загрузка...

Поделитесь в соцсетях

Похожие публикации

Увеличили число конверсий на 50% с помощью смарт-баннеров и товарных кампаний на основе фида – кейс в автотематике

О клиенте Клиент предоставляет услуги в автомобильной сфере: аренду транспорта, страхование, постановку на учет и т.д. Задача от клиента Запустить новые рекламные кампании с целью увеличения количества лидов и снижения их стоимости. Цели проекта Тестирование типичных для e-commerce (а не B2B услуг) инструментов Яндекс.Директа. Увеличение числа конверсий с помощью смарт-баннеров и товарных кампаний на основе […]

Продвижение бренда EKONIKA с помощью нового формата рекламы Layer by Sber

Клиент EKONIKA – это коллекции обуви и аксессуаров, разработанные российскими дизайнерами. Сверхудобная колодка, натуральные материалы, безупречное качество и актуальный дизайн – неотъемлемые составляющие fashion-бренда. Цель Протестировать новый медийный инструмент и оценить его привлекательность с точки зрения текущей маркетинговой стратегии. Как работает сервис Layer by Sber  В основе сервиса лежит механизм компьютерного зрения.  Работает это так: […]

Кейс GATE31: как при возврате неактивных пользователей снизить ДРР на 59% и получить х4 конверсий в покупку

Краткая информация — Продвижение: Контекстная реклама Яндекс Директ. — Используемые форматы продвижения в Яндекс.Директ: Товарная кампания, МК, Поиск, РСЯ, Смарт-баннеры, DSA, МКБ. — Самые эффективные форматы: ТК, Смарт-баннеры, РСЯ, Поиск. Основная ЦА – женщины от 25 до 45 с достатком выше среднего Воронка – коммерческая: касание – корзина – покупка. В чем сложность – высокая […]