Как создать серверный тег

Вы уже имеете общее представление о добавлении тегов на стороне сервера с помощью Менеджера тегов. Вы знаете, что такое "клиент" и в чем заключаются его функции. Клиенты получают данные о событиях с устройств ваших пользователей и преобразуют их для использования остальными составляющими контейнера. В этой статье объясняется, как обрабатывать такие данные в тегах на стороне сервера.

В серверном контейнере теги получают входящие данные о событиях от ваших клиентов, преобразуют их и отправляют обратно для сбора и анализа. При этом данные можно отправлять в любой указанный вами объект назначения, который может принимать HTTP-запросы.

Серверные контейнеры имеют три встроенных тега, которые можно использовать без пользовательской конфигурации:

  • Google Аналитика 4;
  • Google Аналитика: Universal Analytics;
  • HTTP-запрос.

Если вы хотите отправлять данные не в Google Аналитику или вам требуется больше функций, чем предлагает тег HTTP-запроса, используйте другой тег. Дополнительные теги можно найти в галерее общедоступных шаблонов или создать самостоятельно. В этом руководстве представлены основы создания собственных тегов для серверного контейнера.

Цели

  • Узнать, какие API используются для чтения данных о событиях, отправки HTTP-запросов и записи файлов cookie в браузере.
  • Ознакомиться с рекомендациями по созданию параметров конфигурации тега.
  • Узнать, чем данные, которые указывает пользователь, отличаются от тех, которые собираются автоматически, и почему эти отличия важны.
  • Определить роль тега в серверном контейнере. Понять, какие функции должен выполнять тег, а какие – нет.
  • Узнать, когда следует добавить шаблон тега в галерею общедоступных шаблонов.

Требования

Тег Baz Analytics

С помощью этого руководства вы научитесь создавать тег, который отправляет данные в сервис, который мы назовем Baz Analytics.

Это простой сервис аналитики, который передает данные по адресу https://example.com/baz_analytics с помощью запросов HTTP GET. Ниже приведены его параметры.

Параметр Пример Описание
Идентификатор BA-1234 Идентификатор вашей учетной записи Baz Analytics.
en click Название события.
l https://www.google.com/search?q=sgtm URL страницы, на которой произошло событие.
u 2384294892 Идентификатор пользователя, выполнившего действие. Используется для связывания нескольких действий с одним пользователем.

Конфигурация тега

Сначала создадим шаблон тега. Перейдите в раздел контейнера Шаблоны и нажмите Создать в разделе Шаблоны тегов. Добавьте название и описание тега.

Затем в редакторе шаблонов перейдите на вкладку Поля и добавьте остальные параметры конфигурации для тега. Какие именно? Тег можно создать тремя способами, которые описаны ниже.

  1. Полная конфигурация: поле конфигурации добавляется для каждого параметра. Пользователю необходимо указывать все явным образом.
  2. Без конфигурации: параметры тега не добавляются. Все данные берутся непосредственно из события.
  3. Выборочная конфигурация: поля добавляются только для некоторых параметров.

Добавив поля для каждого параметра, пользователи могут полностью управлять конфигурацией тега. Однако в таком случае приходится выполнять много повторяющихся действий. Например, для тега Baz Analytics имеет смысл ввести универсальный и однозначный параметр l, в котором содержится URL страницы. А вводить одни и те же неизменные данные при каждой конфигурации тега может и компьютер.

Возможно, лучшим решением будет тег, который только получает данные из события. Его проще всего настроить, поскольку пользователю, по сути, ничего не нужно делать. Но с другой стороны, этот способ предусматривает больше всего ограничений и является самым уязвимым вариантом. Пользователи не могут изменить поведение тега, даже если в этом есть необходимость. Например, на сайте и в Google Аналитике событие может называться purchase, а в Baz Analytics – buy. Или структура входящих данных о событиях может не отвечать ожиданиям тега. В любом случае возникнут сложности.

Как это часто бывает, оптимальное решение находится где-то между двумя крайностями. Некоторые данные лучше всегда получать из события, другие – настраивать самостоятельно. Как выбрать подходящий способ? Для этого необходимо подробнее рассмотреть данные, которые поступают в контейнер.

Откуда берутся данные?

Данные, которые поступают в серверный контейнер из тега Google Аналитики 4, можно примерно разделить на две категории: указанные пользователем и собранные автоматически.

К первой категории относятся данные, которые пользователь указывает в команде gtag.js event. Представим себе такую команду:

gtag('event', 'search', {
  search_term: 'beets',
});

В этом случае в серверном контейнере будут заданы такие параметры:

{
  event_name: 'search',
  search_term: 'beets',
}

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

Однако контейнер получает не только эти данные, но и автоматически собранные тегом Google Analytics 4 в браузере. К ним относятся:

  • ip_override
  • language
  • page_location
  • page_referrer
  • page_title
  • screen_resolution
  • user_agent

Кроме того, если запрос к серверу поступает из веб-браузера, в API getCookieValue могут также быть доступны файлы cookie.

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

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

Имея это в виду, рассмотрим еще раз параметры для тега Baz Analytics.

  • Идентификатор потока данных (id) не собирается автоматически, поэтому пользователь должен указать это значение во время настройки тега.
  • Название события (en) можно получить непосредственно из параметра event_name. Однако, поскольку это значение указывает пользователь, лучше предоставить возможность при необходимости переопределять его.
  • URL страницы (l) можно получить из параметра page_location, значение которого автоматически собирается тегом Google Аналитики 4 в браузере для каждого события. Поэтому пользователю не нужно указывать его вручную.
  • Идентификатор пользователя (u) в серверном теге Baz Analytics не указывается пользователем и не собирается автоматически с помощью тега на странице. Параметр u хранится в файлах cookie браузера, поэтому пользователей можно идентифицировать при каждом посещении сайта. В разделе о реализации тегов ниже указано, что именно серверный тег Baz Analytics использует API setCookie для записи файлов cookie. Это значит, что только тег Baz Analytics знает, где и как хранятся файлы cookie. Как и в случае с l, значения параметра u должны собираться автоматически.

Ниже приведен пример конфигурации тега после настройки.

Конфигурация тега Baz Analytics

Реализация тега

Настроив конфигурацию тега, можно приступать к реализации его поведения в изолированном JavaScript.

Тег должен выполнять четыре функции, указанные ниже.

  1. Получать название события из конфигурации тега.
  2. Получать URL страницы из свойства page_location события.
  3. Определять идентификатор пользователя с помощью файла cookie _bauid. Если такого файла cookie нет, тег определяет новое значение и хранит его для последующих запросов.
  4. Создавать URL и отправлять запрос серверу сбора данных Baz Analytics.

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

  • проверять событие с целью определить, нужно ли ему выполняться (для этого есть триггер);
  • активировать контейнер с помощью API runContainer (это должен делать клиент);
  • пытаться взаимодействовать непосредственно с запросом или ответом, за исключением файлов cookie (это также задача клиента).

Если шаблон тега будет выполнять одну из указанных выше функций, это введет пользователей тега в заблуждение. Например, если тег будет отправлять ответ на входящий запрос, клиент не сможет сделать то же самое. Такое поведение контейнера не будет соответствовать ожиданиям пользователей.

Ниже представлен пример реализации тега в изолированной среде JavaScript с комментариями.

const encodeUriComponent = require('encodeUriComponent');
const generateRandom = require('generateRandom');
const getCookieValues = require('getCookieValues');
const getEventData = require('getEventData');
const logToConsole = require('logToConsole');
const makeString = require('makeString');
const sendHttpGet = require('sendHttpGet');
const setCookie = require('setCookie');

const USER_ID_COOKIE = '_bauid';
const MAX_USER_ID = 1000000000;

// The event name is taken from either the tag's configuration or from the
// event. Configuration data comes into the sandboxed code as a predefined
// variable called 'data'.
const eventName = data.eventName || getEventData('event_name');

// page_location is automatically collected by the Google Analytics 4 tag.
// Therefore, it's safe to take it directly from event data rather than require
// the user to specify it. Use the getEventData API to retrieve a single data
// point from the event. There's also a getAllEventData API that returns the
// entire event.
const pageLocation = getEventData('page_location');
const userId = getUserId();

const url = 'https://www.example.com/baz_analytics?' +
    'id=' + encodeUriComponent(data.measurementId) +
    'en=' + encodeUriComponent(eventName) +
    (pageLocation ? 'l=' + encodeUriComponent(pageLocation) : '') +
    'u=' + userId;

// The sendHttpGet API takes a URL and returns a promise that resolves with the
// result once the request completes. You must call data.gtmOnSuccess() or
// data.gtmOnFailure() so that the container knows when the tag has finished
// executing.
sendHttpGet(url).then((result) => {
  if (result.statusCode >= 200 && result.statusCode < 300) {
    data.gtmOnSuccess();
  } else {
    data.gtmOnFailure();
  }
});

// The user ID is taken from a cookie, if present. If it's not present, a new ID
// is randomly generated and stored for later use.
//
// Generally speaking, tags should not interact directly with the request or
// response. This prevents different tags from conflicting with each other.
// Cookies, however, are an exception. Tags are the only container entities that
// know which cookies they need to read or write. Therefore, it's okay for tags
// to interact with them directly.
function getUserId() {
  const userId = getCookieValues(USER_ID_COOKIE)[0] || generateRandom(0, MAX_USER_ID);
  // The setCookie API adds a value to the 'cookie' header on the response.
  setCookie(USER_ID_COOKIE, makeString(userId), {
    'max-age': 3600 * 24 * 365 * 2,
    domain: 'auto',
    path: '/',
    httpOnly: true,
    secure: true,
  });

  return userId;
}

Тег реализован, но прежде чем использовать его, необходимо правильно настроить разрешения для его API. В редакторе шаблонов перейдите на вкладку Разрешения и укажите следующие разрешения:

  • Чтение значений файлов cookie: _bauid
  • Чтение данных о событиях: event_name и page_location
  • Отправка HTTP-запросов: https://www.example.com/*
  • Запись файлов cookie: _bauid

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

И наконец, не забудьте хотя бы один раз проверить тег, нажав кнопку Выполнить код. Это предотвратит появление множества мелких ошибок на сервере.

Вы приложили много усилий, чтобы создать, протестировать и реализовать новый тег. Почему бы не поделиться им с остальными? Если вы считаете, что ваш тег может пригодиться другим пользователям, добавьте его в галерею общедоступных шаблонов.

Заключение

Теперь вы можете создавать теги для серверного контейнера. Из этого руководства вы узнали:

  • какие API используются для чтения данных о событиях, отправки HTTP-запросов и записи файлов cookie в браузере;
  • рекомендации по созданию параметров конфигурации тега;
  • чем данные, которые указывает пользователь, отличаются от тех, что собираются автоматически, и почему эти отличия важны;
  • роль тега в контейнере: какие функции он должен выполнять, а какие – нет;
  • когда следует добавить шаблон тега в галерею общедоступных шаблонов и как это сделать.