image
Привет!

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

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

Избежать проблемы легко — подключить Google Analytics 360, но дорого.
Давайте научи��ся собирать сырые данные, используя бесплатный Google Analytics.

// эта инструкция — не решение всех ваших проблем, знакомимся с технологией!


Как строятся отчеты в Google Analytics


Чтобы отобразить отчеты в интерфейсе Google Analytics (далее GA), происходит следующее: сбор данных, обработка данных, формирование отчета.

image

Сбор данных
По протоколу 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” и посмотреть подробную информацию по запросу.

image

То есть, через 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 имеет вид:
<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:

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 }}:

image



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

Настройка хранилища


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

Создаем таблицу, задаем имена колонкам. Имена должны соответствовать названию параметров из Query String, котор��е будет отправлять трекер Google Analytics:

image

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



Добавляем скрипт, который при каждом 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, но и в ваше хранилище.



Посмотрите как это работает в реалтайме:
  1. Откройте таблицу.
  2. Откройте тестовый сайт.
  3. Походите по сайту + следите за обновлениями в таблице.


Не все данные


Так как некоторые данные (например, IP-адрес) прилетают не через гет параметр, а в заголовках запроса можно их парсить на стороне принимающего скрипта.

С source / medium — тоже можно поработать, достать его из Pageurl и раскидать по разным колонкам.

На этом останавливаться не будем, думаю, что мысль понятна.

Зачем это всё?


  • Избавляемся от семплирования при построении отчетов.
  • Теперь нет ограничений на кастомные поля: что нужно отправляйте/получайте/взаимодействуйте.
  • Можно использовать эти данные, как условия для триггеров: просмотры страниц, совершение действия. Сопоставляем с имейлом и отправляем письма/пуши.
  • Для системы рекомендаций: также интересуются/покупают.
  • Анализируйте поведение пользователей: как они ходят по вашему сайту, в разрезе каждой сессии и вообще, за все время!
  • Анализируйте источники трафика, смотрите последовательности, каналы, которые ведут к конверсиям.
  • Отслеживайте мошенников в CPA-сетях. Тут вы увидите внезапные переходы, например, когда человек просто учит новые Слова в тренажере, а страница перезагружается и проставляются партнерские куки.
  • И сказка для маркетологов — кастомные списки ремаркетинга. Выделяете сегмент по поведению, выгружайте cid и отправляйте в GA.