- PVSM.RU - https://www.pvsm.ru -
Задача: определить какие события превышают payload size Google Analytics
Решение: логирование хитов Google Analytics (включая payload size) в Google Sheets при помощи Google Tag Manager, без участия разработчиков
Если вам доводилось имплементировать Enhanced Ecommerce для Google Analytics (GA) через Google Tag Manager (GTM) и затем дебажить это дело с помощью Google Analytics debugger [1], то вероятно вы сталкивались с тем, что некоторые события «почему-то» не доходят в GA и появляется ошибка: Payload size is to large (9000). Max allowed is 8192
Дело в том, что библиотека analytics.js не принимает хиты более 8192 байт [2]. Если размер хита больше, то в GA он не дойдет и в отчетах по событиям будет пусто.
Пример ситуации:
Веб аналитик просит разработчика запихинуть (или сам запихивает) все product impressions в один хит. В результате хит не доходит т.к. в листинге на одной странице более 50 товаров. Или в корзину добавляется 50+ различных товаров, в результате возникают проблемы с событиями checkout step и transaction.
Старайтесь всегда оптимизировать структуру данных хита (т.е. например, отправлять хиты по мере появления товара в поле зрения юзера, не пихать в хит ненужные переменные (variant, category, brand), не использовать длинных названий товаров и т.п.) — это, во-первых, увеличит скорость отправки хита; во-вторых, позволит избежать проблем с payload size.
Если оптимизировать невозможно, то существует несколько костылей способов обойти эти ограничения:
Но прежде чем приступить к нарезке хитов и оптимизации контента, определим, какие именно события превышают payload size. Данный материал посвящен решению этой задачи.
Создаем новую таблицу.
В хедер (1 строка), записываем имена параметров, которые хотим извлечь из хита (будьте внимательны, названия указываете в точности такие же, которые затем будете использовать в JS скрипте в GTM). В качестве примера извлечем такие данные:
Пример мапинга колонок для логирования payload в Google Sheet
Порядок параметров в колонках неважен. Колонки с параметрами cid и ti отформатируйте как Plain text (Format > Number > Plain text), во избежание ошибок с автоформатированием.
При желании можете добавить/убрать необходимые параметры, (не забудьте затем изменить список переменных в JS скрипте в GTM). Список возможных полей и параметров analytics.js [5]
Далее, открываем script editor и добавляем код (оригинал скрипта принадлежит Martin Hawksey https://gist.github.com/mhawksey/1276293 [6]):
function doGet(e){
return handleResponse(e);
}
function doPost(e){
return handleResponse(e);
}
function handleResponse(e) {
var lock = LockService.getPublicLock();
lock.waitLock(30000); // wait 30 seconds before conceding defeat.
try {
// next set where we write the data - you could write to multiple/alternate destinations
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// we'll assume header is in row 1 but you can override with header_row in GET/POST data
var headRow = e.parameter.header_row || 1;
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
// loop through the header columns
for (i in headers){
if (headers[i] == "timestamp"){ // special case if you include a 'timestamp' column
row.push(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MMM d yyyy HH:mm:ss"));
} else { // else use header name to get data
row.push(e.parameter[headers[i]]);
}
}
// more efficient to set values as [][] array than individually
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
// return json success results
return ContentService
.createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
.setMimeType(ContentService.MimeType.JSON);
} catch(e){
// if error return this
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
} finally { //release lock
lock.releaseLock();
}
}
Разворачиваем скрипт как веб приложение (Publish > Deploy as web app...). Права доступа — anyone, even anonymous. Публикуем.
Настройки Google Script editor
В дальнейшем нам будет нужен URL нашего веб приложения (Current web app URL), поэтому вкладку пока не закрывайте.
Создадим 2 custom JavaScript variables:
Пример JavaScript variable в GTM
Первая JS variable, для определения времени отправки хита (timestamp). Эта переменная будет использоваться во второй JS variable.
function() {
// Get local time as ISO string with offset at the end
var now = new Date();
var tzo = -now.getTimezoneOffset();
var dif = tzo >= 0 ? ' Timezone: +' : ' Timezone: -';
var pad = function(num) {
var norm = Math.abs(Math.floor(num));
return (norm < 10 ? '0' : '') + norm;
};
return now.getFullYear()
+ '-' + pad(now.getMonth()+1)
+ '-' + pad(now.getDate())
+ ' Time' + pad(now.getHours())
+ ':' + pad(now.getMinutes())
+ ':' + pad(now.getSeconds())
+ dif + pad(tzo / 60)
+ ':' + pad(tzo % 60);
}
Вторая JS variable, для отлова нужных хитов и передачи их в Google Sheet (за основу взят код из этого материала [7]).
function sendHitTask(){
return function(model) {
var payLoad = model.get('hitPayload');
var trackingBaseUrls = ['https://www.google-analytics.com/collect', 'https://script.google.com/macros/s/AKfycbxJLy3eYBLpPu_S_eNccxzn_GwHXkZWr-93feMuBaAZelk3fj01yB/exec'];
for (i = 0; i < trackingBaseUrls.length; i++) { var baseUrl = trackingBaseUrls[i]; if (trackingBaseUrls[i].indexOf('collect') > -1) {
var req = new XMLHttpRequest();
req.open('POST', baseUrl, true);
req.send(payLoad);
} else if (payLoad.length > 7500){
var payLoadExtract = payLoad.split('&');
var payLoadArray = {};
// Push values to array for later access
for (i = 0; i < payLoadExtract.length; i++){
var splitArray = payLoadExtract[i].split('=');
payLoadArray[splitArray[0].trim()] = splitArray[1].trim();
}
// Specify values to be sent to Google Sheets from array
var tid = 'tid=' + payLoadArray.tid,
cid = '&cid=' + payLoadArray.cid,
uid = '&uid=' + payLoadArray.uid,
t = '&t=' + payLoadArray.t,
pa = '&pa=' + payLoadArray.pa,
ni = '&ni=' + payLoadArray.ni,
dl = '&dl=' + payLoadArray.dl,
dp = '&dp=' + payLoadArray.dp,
dt = '&dt=' + payLoadArray.dt,
ec = '&ec=' + payLoadArray.ec,
ea = '&ea=' + payLoadArray.ea,
el = '&el=' + payLoadArray.el,
ti = '&ti=' + payLoadArray.ti,
tr = '&tr=' + payLoadArray.tr,
timestamp = '×tamp=' + {{v_EE_timestamp}},
payLoadLength = '&payLoadLength=' + payLoad.length;
var collectPayLoad = tid + cid + uid + t + pa + ni + dl + dp + dt + ec + ea + el + ti + tr + timestamp + payLoadLength;
// Send Values to Google Sheets
var collectUrl = baseUrl +'?'+ collectPayLoad;
var myImage = new Image();
myImage.src = collectUrl;
}
}
}
}
Что необходимо настроить:
Теперь, находим в своем контейнере тег(теги) отвечающие за отправку событий Enhanced Ecommerce в GA и добавляем в Fields to Set поле sendHitTask и название JS variable (в нашем случае v_EE_mimic GA payload). Поле sendHitTaks используется, в данном случае, для чтения payload'a и отправки данных о хите в Google Sheet (если он превышает заданный уровень).
Настройки тега Enhanced Ecommerce в GTM
Сохраняем тег, публикуем новую версию GTM контейнера.
Теперь, при срабатывании тега Enhance Ecommerce, также будет отрабатывать скрипт v_EE_mimic GA payload. Если при заданных настройках payload превышает свои значения, произойдет запись этого хита в Google Sheet.
Собирая логи по хитам, можно определить какое конкретно событие не дошло в GA, где это произошло, в каком браузере и т.д. (см. список возможных полей и параметров analytics.js [5]).
Спасибо за внимание!
Надеюсь, данный материал вам пригодится и облегчит жизнь с дебагом Google Analytics.
P.S. Кто умеет/знает как автоматизировать проверку GTM тегов (автотесты для тегов), пожалуйста отзовитесь! Когда-то давно Симо написал статью про это www.simoahava.com/analytics/automated-tests-for-google-tag-managers-datalayer [8] но разобраться в ней не смог, может кто пробовал/знает другие способы. Буду очень благодарен советам и помощи в этом вопросе.
Автор: alunet
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/google-analytics/280359
Ссылки в тексте:
[1] Google Analytics debugger: https://chrome.google.com/webstore/detail/google-analytics-debugger/jnkmfdileelhofjcijamephohjechhna?hl=en
[2] библиотека analytics.js не принимает хиты более 8192 байт: https://developers.google.com/analytics/devguides/collection/protocol/v1/reference#using-post
[3] порезать хит на несколько частей и отправлять его кусками: https://www.savio.no/analytics/easier-enhanced-ecommerce-product-promo-tracking
[4] подргружать хиты через Data import (пушим в хит только id товара, остальное подгружаем через data import): https://support.google.com/analytics/answer/6014867?hl=en
[5] Список возможных полей и параметров analytics.js: https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference
[6] https://gist.github.com/mhawksey/1276293: https://gist.github.com/mhawksey/1276293
[7] этого материала: https://stickler.de/en/information/analytics-tag-manager/send-analytics-hits-to-your-own-server-endpoint?filter_tag[0]=
[8] www.simoahava.com/analytics/automated-tests-for-google-tag-managers-datalayer: https://www.simoahava.com/analytics/automated-tests-for-google-tag-managers-datalayer/
[9] Источник: https://habr.com/post/358754/?utm_campaign=358754
Нажмите здесь для печати.