Этот пост в основном о веб-аналитике: о том, как корректно определять источники посетителей вашего сайта, и о моём модуле для Ruby on Rails, который помогает в этом нелёгком деле. В конце есть небольшая часть, на которую я попрошу обратить внимание участников Rails сообщества: она обо мне и Rails. Но давайте по порядку.
Часть первая. О веб-аналитике и определении источников посетителей
Проблема
Есть довольно тривиальная задача: определить источник посетителя, пришедшего на наш сайт. Не знаю как вы, а мы довольно долго паразитировали на теле кук Google Analytics: брали utmz, потрошили её на сорсы да медиумы и жили-не-тужили. Analytics за нас решал вопросы перезаписи источников, учета сессий и вобще избавлял от всяких головняков парсинга рефереров. Но всё хорошее когда-нибудь заканчивается.
Когда гугл выкатил бету Universal стало понятно, что рано или поздно с гугловской печенькой придется попрощаться и научиться всё делать самому. Но поскольку тогда он заявлял о несовместимости Classic и Universal, то пока сидеть можно было ровно: Classic будет поддерживаться ещё долго.
В новой версии GA кука осталась всего одна — с id пользователя. Analytics отправляет её на свой сервер и уже там производит все вычисления. И ни через куки, ни через js информацию об источнике из него теперь не вытянешь.
Но недавно Google начал аккуратно тыкать пользователей палочкой: он выкатил конвертер профилей — Classic → Universal. И вот тут надо начинать шевелить булками: классическому Analytics придет окончательный Reader в момент, когда в Universal придут списки ремаркетингов. А это, думаю, не за горами.
В связи с этим я разродился на самопальный генератор печеньки utmz. И назвал его sourcebuster.
Сначала о форме
Генератор выполнен в формате Mountable engine для Ruby on Rails. Его можно довольно шустро приладить ко всем вашим Rails приложениям в качестве gem’а и обновлять одной командой из консоли. Модуль независимый и делает всё сам. Данные об источнике можно использовать для подмены номеров телефонов, контента на сайте, сохранять их вместе с заявками и использовать для дальнейшей аналитики. По определённым правилам модуль вычисляет источник (и ещё ряд параметров) и сохраняет их в куках посетителя.
Сразу ссылка на GitHub: https://github.com/alexfedoseev/sourcebuster
Я пока не разобрался с оформлением README.rdoc, в процессе, скоро исправлюсь.
Теперь о содержании
Большая часть логики повторяет логику GA, но есть некоторые отличия.
Начнем со структуры данных.
Структура данных
Всего у нас есть 4 главных типа трафика:
- utm — трафик, размеченый utm-метками
- organic — трафик из органической выдачи поисковых систем
- referral — реферальный трафик (ссылки со сторонних ресурсов)
- typein — прямые переходы
Логика фильтрации на изображении ниже:
Таким образом мы расфасовываем посетителей по этим 4 корзинам.
Далее нам нужно сформировать правили перезаписи источников, поскольку один посетитель может переходить на сайт в разное время с разных источников.
Логика перезаписи источников
Логика перезаписи повторяет логику Google Analytics:
Обратите внимание, что в рамках текущей сессии реферальные переходы ничего не перезаписывают. Почему — поясню на примере: часто посетитель в рамках текущего визита переходит на сайт со стороннего ресурса, который реальным источником не является — например из почтового сервиса, где у него была ссылка на активацию регистрации.
В данной системе я решил помимо перезаписанных данных о текущем визите хранить данные о самом первом посещении. То есть в момент совершения конверсии у нас будут данные о первом и текущем источниках посетителя.
Что конкретно можно вытащить с помощью модуля:
- Данные о самом первом источнике:
utm_source, utm_medium, utm_campaign, utm_content, utm_term - Те же данные о текущем источнике
(если пользователь совершил повторный переход из другого источника) - Дата первого посещения
- Точка входа
- Полный реферер, при котором произошла перезапись источника
- ip и user agent пользователя
В Gemfile приложения добавляем:
gem 'sourcebuster', :git => "git@github.com:alexfedoseev/sourcebuster.git"
Устанавливаем:
bundle install
Поскольку это Mountable engine, он существует в изолированном пространстве имён.
Монтируем его в приложение, добавляя в routes.rb:
mount Sourcebuster::Engine => "/sourcebuster"
Далее нам нужно скопировать и выполнить все миграции.
Копируем:
bundle exec rake sourcebuster:install:migrations
И исполняем:
bundle exec rake db:migrate
В вашей базе данных появились 3 новых таблицы:
- sourcebuster_referer_sources
Данные о настраиваемых источниках. - sourcebuster_referer_types
Данные о типах рефераллов (по сути utm_medium для referral трафика). - sourcebuster_settings
Настройки приложения (продолжительность сессии и обработка поддоменов).
С ними ничего делать не надо, там уже есть данные «из коробки» и для них есть интерфейсы.
Более подробно о Mountable engines — http://guides.rubyonrails.org
Модуль почти подключён, остался последний штрих: позволить ему ставить куки в любом месте вашего приложения. Для этого в application_controller.rb вашего приложения добавляем:
class ApplicationController < ActionController::Base
include Sourcebuster::CookieSettersHelper
before_filter :set_sourcebuster_data
helper_method :extract_sourcebuster_data
# some code
private
def set_sourcebuster_data
set_sourcebuster_cookies
end
end
Вроде готово. Engine использует шаблоны главного приложения, поэтому стили вы можете настраивать сами (возможно, я это изменю). Я мог что-то упустить, если что-то не работает — пишите.
Использование
Модуль даёт следующие методы (точнее метод один, но вытасивает разные данные):
# Cамый первый тип источника (utm / organic / referral / typein)
extract_sourcebuster_data(:sb_first, :typ)
# Cамый первый utm_source
extract_sourcebuster_data(:sb_first, :src)
# Cамый первый utm_medium
extract_sourcebuster_data(:sb_first, :mdm)
# Cамый первый utm_campaign
extract_sourcebuster_data(:sb_first, :cmp)
# Cамый первый utm_content
extract_sourcebuster_data(:sb_first, :cnt)
# Cамый первый utm_term
extract_sourcebuster_data(:sb_first, :trm)
# Текущий тип источника (utm / organic / referral / typein)
extract_sourcebuster_data(:sb_current, :typ)
# Текущий utm_source
extract_sourcebuster_data(:sb_current, :src)
# Текущий utm_medium
extract_sourcebuster_data(:sb_current, :mdm)
# Текущий utm_campaign
extract_sourcebuster_data(:sb_current, :cmp)
# Текущий utm_content
extract_sourcebuster_data(:sb_current, :cnt)
# Текущий utm_term
extract_sourcebuster_data(:sb_current, :trm)
# Дата первого посещения сайта
extract_sourcebuster_data(:sb_first_add, :fd)
# Точка входа
extract_sourcebuster_data(:sb_first_add, :ep)
# Полный реферер, при котором произошла перезапись источника
extract_sourcebuster_data(:sb_referer, :ref)
# ip пользователя
extract_sourcebuster_data(:sb_udata, :uip)
# И его user agent
extract_sourcebuster_data(:sb_udata, :uag)
Тестовая страница модуля: http://sandbox.alexfedoseev.com/sourcebuster/showoff
На неё можно переходить с разных источников и смотреть, что наопределял модуль.
Также модуль позволяет настраивать ряд дополнительных параметров.
Стандартные настройки
Интерфейс: http://sandbox.alexfedoseev.com/sourcebuster/settings
Продолжительность сессии
Через какое время после последней активности пользователя его визит считается завершённым. Указывается в минутах, по умолчанию — 30 минут.
Обработка поддоменов
Это по сути аналог _setDomainName в GA. Поясню на примере.
Допустим у вас есть сайт, на котором есть поддомены:
- site.com
- blog.site.com
- shop.site.com
И вы хотите, чтобы переходы со страниц site.com на blog.site.com считались внутренними не-реферальными переходами (то есть при переходе с одного поддомена на другой источник не перезаписывается). Для этого в настройках нужно выставить галочку «I have subdomains and traffic between them should not be a referral» и в поле «Main host» добавить корневой хост сайта, все поддомены которого будут расцениваться модулем как один сайт. В нашем случае там указывается «site.com».
Если в поле указать blog.site.com, то переходы с alex.blog.site.com на blog.site.com будет не-реферальными, а переход с alex.blog.site.com на shop.site.com будет уже реферальным трафиком.
Дополнительные источники
Интерфейс: http://sandbox.alexfedoseev.com/sourcebuster/custom_sources
У системы есть возможность настроить обработку ряда дополнительных источников.
Настройка производится по следующим параметрам:
- Домен
По нему матчится источник, который будем обрабатывать. - Алиас
Красивое / понятное имя источника. - Канал
Можно задать referral, organic или social - Параметр запроса
Параметр ключевого слова в url’е поисковой машины.
Нафига эта таблица нужна проще всего объяснить на примерах.
Пример 1
Вы хотите, чтобы система считала переходы с поиска Bing — органическим трафиком (что вполне справедливо).
Если вы зайдете на bing.com и вобъёте в поисковую строку запрос «apple», то попадёте на страницу выдачи с адресом вида:
www.bing.com/search?q=apple&go=&qs=n&form=QBLH&pq=apple&sc=8-5&sp=-1&sk=&cvid=718ad07527244c319ecebf44aa261f64
На его базе мы создаем новый особый источник:
- Домен: bing.com
- Алиас: bing
Или как вы захотите, можете вобще ничего не писать, тогда будет подставляться хост реферера. - Канал: organic
- Параметр ключевого слова: q
Это символ между конструкциями «?» и «=ваш_запрос» в урле страницы с поисковой выдачей.
Теперь всё, что будет приходить с подобных страниц, будет считаться органическим трафиком.
Пример 2
Вы хотите выделить переходы из соц. сетей в отдельную группу.
Действуем по аналогичной схеме:
- Домен: facebook.com
- Алиас: facebook
- Канал: social
- Параметр ключевого слова: не нужен
Готово. Теперь все переходы по ссылкам из facebook (кроме размеченных utm-метками) будут со значением канала social.
В поле домен необходимо полностью указать зону (.com, .com.ru и т.д.). Если вы укажите значение facebook.com, то под этот фильтр не попадёт трафик с домена facebook.com.ru. А с домена m.facebook.com — попадёт.
Тесты
Исходники: https://github.com/alexfedoseev/sourcebuster/blob/master/test/integration/navigation_test.rb
Львиная доля тестов — это Selenium-тесты для проверки правильности определения и перезаписи источников. Написаны они на Ruby, но реализованы таким образом, чтобы можно было проверить не только код моего модуля, но в принципе любой его реализации (например, если кто-то будет портировать его на php или js). То есть они тестируют не методы, а результат их работы. Кроме того тут не используются суррогатные рефереры, а тестируются реальные переходы с реальных ресурсов. И если Яндекс что-то изменит в выдаче (например, перейдет на https, чем убъёт реферер), то тесты это покажут. Всё по-настоящему короче.
Сейчас в тестах довольно мясо и написаны они скорее под себя, но при желании разобраться можно.
Для того, чтобы протестировать переписанный код, нужно иметь:
- страницу, свёрстанную по определенным правилам
(см. в код тестовой страницы, находите id блоков с данными, если что — задавайте вопросы) - проиндексированную в поисковиках
(яндекс, гугл, третий дополнительный (например, рамблер)) - и находящуюся в топ-5 по определенному запросу
- + ссылки на эту страницу из соц. сети и стороннего (реферального) сайта
В верхнем блоке кода указаны константы, которые нужно настроить перед запуском тестов. Из них понятно, что именно нужно подготовить.
И да, прогон тестов занимает около 20-30 минут.
Часть вторая. Обо мне и Rails
Вот уже 3,5 года я занимаюсь интернет-маркетингом, и не так давно я пришёл к тому, что генерация трафика — это не моё. Хочется генерить смысл, а не трафик. И я начал писать код. Случилось это около 9 месяцев назад. У меня нет никакого айтишно-математического бэкграунда, вникать во всё приходилось с нуля и самому. Помогли мне в этом книги Криса Пайна, Майкла Хартла и прочие интернеты.
В результате я написал себе блог, но около 5 месяцев назад я вынужден был сделать перерыв, и этот модуль — первое, что я написал после простоя. Я прошу участников Rails сообщества покритиковать реализацию и указать на явные и не очень косяки. За всё это время мне так и не удалось ни разу встретить живого человека, который пишет на Ruby, и довольно тяжело самому постигать всё и вся.
Заранее спасибо за критику и надеюсь этот пост будет кому-то полезен. Удач.
Автор: alexfedoseev