
Привет!
Если у вас посещаемый сайт (более 500 тысяч сессий за отчетный период) или вы строите какие-то сложные отчеты через интерфейс (сегментирование, подключение дополнительных параметров, частое изменение отчетного периода) — Google Analytics начинает экономить свои ресурсы и включает семплирование данных. Подробности хорошо описаны в официальной справке. То есть, чтобы подготовить вам отчёт, берутся не все данные, а какая-то часть, например 30%, и потом пропорционально показатели подгоняются под 100% и отображаются у вас в отчете.
Конечно, в таких случаях будет расхождение по количеству оплат, суммам транзакций и в количестве конверсий. Проверить легко — сравнить с цифрами из базы данных или CRM.
Избежать проблемы легко — подключить Google Analytics 360, но дорого.
Давайте научи��ся собирать сырые данные, используя бесплатный Google Analytics.
// эта инструкция — не решение всех ваших проблем, знакомимся с технологией!
Как строятся отчеты в Google Analytics
Чтобы отобразить отчеты в интерфейсе Google Analytics (далее GA), происходит следующее: сбор данных, обработка данных, формирование отчета.

Сбор данных
По протоколу Measurement Protocol GA собирает информацию о всех взаимодействиях: просмотры страниц, пользовательские события, транзакции.
Обработка информации
На основании полученной информации о взаимодействиях (просмотры страниц, другие события) GA:
- разделяет их на сессии: если разница между взаимодействиями больше 30 минут (при базовых настройках),
- рассчитывает кол-во просмотров на сессию, показатель отказов,
- достаёт информацию об источниках из utm-меток и так далее,
- Применяет фильтры, если вы их настраивали на уровне представления.
Формирование отчета
Когда вы открываете отчет через веб-интерфейс GA или по API, в зависимости от выбранного отчета, система достает данные из хранилища и возвращает информацию.
Как GA собирает данные — техническая сторона
Вы добавляете код, который предоставляет вам GA, или создаете тег через Google Tag Manager.
Когда этот код срабатывает в браузере пользователя, создается объект ga с трекером. Далее через этот трекер фиксируется взаимодействие — просмотр страницы.
Фиксируется взаимодействие, значит отправляется информация на сервер Google Analytics используя Measurement Protocol.
Если максимально упростить: информация на сервер GA передается через GET-запрос формата:
https://www.google-analytics.com/collect?v=1&_v=j67&a=1998834664&t=pageview&_s=1&dl=https%3A%2F%2Fhabrahabr.ru%2Ftop%2F&ul=en-us&de=UTF-8&dt=%D0%9B%D1%83%D1%87%D1%88%D0%B8%D0%B5%20%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8%20%D0%B7%D0%B0%20%D1%81%D1%83%D1%82%D0%BA%D0%B8%20%2F%20%D0%A5%D0%B0%D0%B1%D1%80%D0%B0%D1%85%D0%B0%D0%B1%D1%80&sd=24-bit&sr=1920x1080&vp=1841x341&je=0&_u=SCCAgEADQ~&jid=&gjid=&cid=2098823486.1505375017&tid=UA-726094-1&_gid=1797204180.1524028566&cd1=habrauser&cd2=other&cd4=no&z=1479651106
Можете открыть в браузере Панель для разработчиков, вкладка Network, сделать фильтр по слову “collect” и посмотреть подробную информацию по запросу.

То есть, через Query String в Google Analytics передаются данные:
v:1
_v:j50
a:643761009
t:pageview
_s:1
dl:https://habrahabr.ru/
ul:en-us
de:UTF-8
dt:Лучшие публикации за сутки / Хабрахабр
sd:24-bit
sr:1920x1080
vp:1109x966
je:0
fl:25.0 r0
_u:QCCAgEAB~
jid:1630561303
cid:774042187.1492148509
tid:UA-726094-1
cd1:guest
cd4:no
cd5:other
z:1998272259
Также каждый запрос сопровождается передачей ip-адреса, реферера, информацией о user agent.
Любые другие взаимодействия: события, транзакции также отправляются через этот трекер. То есть, трекер один и через него отправляется информация о всех взаимодействиях (стандартные + те, которые вы настроили самостоятельно).
Собираем сырые данные
Мы уже разобрались, как GA отправляет себе данные. Было бы здорово дублировать эти данные и сохранять их себе в хранилище.
Написать парсер, который будет собирать ��се параметры, которые собирает Google Analytics, подключить ко всем событиям… Нет, никаких велосипедов!
Прежде чем отправить информацию, скрипт GA выполняет серию заданий. Как раз отправка информации на сервер — это одно из заданий. И к нашей радости, эти задания можно модифицировать — отправлять данные не только в Google, но и на произвольный URL.
Как это сделать
Выберите вариант, через который у вас подключен счетчик Google Analytics:
Analytics.js
Стандартный код установки analytics.js имеет вид:
Дорабатываем задание customTask, в итоге получается:
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXXX-X', 'auto');
ga('send', 'pageview');
</script>
Дорабатываем задание customTask, в итоге получается:
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXXX-X', 'auto');
// определяем customTask
ga('set', 'customTask', function(tracker) {
// Сохраняем стандартную функцию sendHitTask.
var originalSendHitTask = tracker.get('sendHitTask');
// Вносим изменения в функцию sendHitTask
tracker.set('sendHitTask', function(model) {
// отправляем стандартный запрос на www.google-analytics.com/collect
originalSendHitTask(model);
// создаем новый запрос для отправки в своё хранилище
var custom_tracking_url = 'ССЫЛКА НА ВАШ ПРИНИМАЮЩИЙ СКРИПТ',
hitPayLoad = '?' + model.get('hitPayload'),
user_agent = '&user_agent='+ encodeURIComponent(navigator.userAgent),
referrer = '&referrer='+encodeURIComponent(document.referrer);
var final_tracking_url = custom_tracking_url + hitPayLoad + user_agent + referrer
document.createElement("img").src = final_tracking_url;
});
});
ga('send', 'pageview');
</script>
Google Tag Manager
Нужно создать переменную customTask типа Custom JavaScript:
Теперь нужно к вашему тегу Universal Analytics добавить поле customTask со значением {{ customTask }}:

function () {
return function(tracker) {
// Сохраняем стандартную функцию sendHitTask.
var originalSendHitTask = tracker.get('sendHitTask');
// Вносим изменения в функцию sendHitTask
tracker.set('sendHitTask', function(model) {
// отправляем стандартный запрос на www.google-analytics.com/collect
originalSendHitTask(model);
// создаем новый запрос для отправки в своё хранилище
var custom_tracking_url = 'ССЫЛКА НА ВАШ ПРИНИМАЮЩИЙ СКРИПТ',
hitPayLoad = '?' + model.get('hitPayload'),
user_agent = '&user_agent='+ encodeURIComponent(navigator.userAgent),
referrer = '&referrer='+encodeURIComponent(document.referrer);
var final_tracking_url = custom_tracking_url + hitPayLoad + user_agent + referrer
document.createElement("img").src = final_tracking_url;
});
}
}
Теперь нужно к вашему тегу Universal Analytics добавить поле customTask со значением {{ customTask }}:

В итоге получается, что мы добавили новую задачу в трекер Google Analytics и при каждом взаимодействии информация будет отправляться не только в Google Analytics, но и на вашу точку входа.
Настройка хранилища
Для простоты я в качестве хранилища возьму Таблицы Гугл. Конечно, для большого количества данных это вообще не вариант. Но мы тут с технологией знакомимся, поэтому для примера подойдет.
Создаем таблицу, задаем имена колонкам. Имена должны соответствовать названию параметров из Query String, котор��е будет отправлять трекер Google Analytics:

Открываем редактирование скриптов:

Добавляем скрипт, который при каждом GET-запросе будет парсить Query String и добавлять значения в таблицу:
function doGet(e) {
record_data(e);
}
var SCRIPT_PROP = PropertiesService.getScriptProperties();
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
function record_data(e) {
try {
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName('Sheet1'); // select the responses sheet
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [ new Date() ]; // first element in the row should always be a timestamp
// loop through the header columns
for (var i = 1; i < headers.length; i++) { // start at 1 to avoid Timestamp column
if(headers[i].length > 0) {
if(!e.parameter[headers[i]]) {
e.parameter[headers[i]] = '';
}
row.push(e.parameter[headers[i]]); // add data to row
}
}
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
}
catch(error) {
Logger.log(e);
}
finally {
return;
}
}
Запускаем функцию setup() и даем доступы на выполнение скрипта:

В опции “Who has access to the app” выбираем “Anyone, even anonymous”.
В итоге вы получите ссылку вашего Web App:

Скопируйте ссылку и перенесите ее в скрипт CustomTask, в переменную custom_tracking_url.
Теперь при всех настроенных взаимодействиях данные будут попадать не только в GA, но и в ваше хранилище.

Посмотрите как это работает в реалтайме:
- Откройте таблицу.
- Откройте тестовый сайт.
- Походите по сайту + следите за обновлениями в таблице.
Не все данные
Так как некоторые данные (например, IP-адрес) прилетают не через гет параметр, а в заголовках запроса можно их парсить на стороне принимающего скрипта.
С source / medium — тоже можно поработать, достать его из Pageurl и раскидать по разным колонкам.
На этом останавливаться не будем, думаю, что мысль понятна.
Зачем это всё?
- Избавляемся от семплирования при построении отчетов.
- Теперь нет ограничений на кастомные поля: что нужно отправляйте/получайте/взаимодействуйте.
- Можно использовать эти данные, как условия для триггеров: просмотры страниц, совершение действия. Сопоставляем с имейлом и отправляем письма/пуши.
- Для системы рекомендаций: также интересуются/покупают.
- Анализируйте поведение пользователей: как они ходят по вашему сайту, в разрезе каждой сессии и вообще, за все время!
- Анализируйте источники трафика, смотрите последовательности, каналы, которые ведут к конверсиям.
- Отслеживайте мошенников в CPA-сетях. Тут вы увидите внезапные переходы, например, когда человек просто учит новые Слова в тренажере, а страница перезагружается и проставляются партнерские куки.
- И сказка для маркетологов — кастомные списки ремаркетинга. Выделяете сегмент по поведению, выгружайте cid и отправляйте в GA.
