...

суббота, 4 января 2014 г.

[Из песочницы] Модуль определения источников посетителей сайта для Ruby on Rails

Этот пост в основном о веб-аналитике: о том, как корректно определять источники посетителей вашего сайта, и о моём модуле для 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 главных типа трафика:


  1. utm — трафик, размеченый utm-метками

  2. organic — трафик из органической выдачи поисковых систем

  3. referral — реферальный трафик (ссылки со сторонних ресурсов)

  4. typein — прямые переходы




Логика фильтрации на изображении ниже:

image

Таким образом мы расфасовываем посетителей по этим 4 корзинам.

Далее нам нужно сформировать правили перезаписи источников, поскольку один посетитель может переходить на сайт в разное время с разных источников.


Логика перезаписи источников



Логика перезаписи повторяет логику Google Analytics:

image

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

В данной системе я решил помимо перезаписанных данных о текущем визите хранить данные о самом первом посещении. То есть в момент совершения конверсии у нас будут данные о первом и текущем источниках посетителя.


Что конкретно можно вытащить с помощью модуля:



  • Данные о самом первом источнике:

    utm_source, utm_medium, utm_campaign, utm_content, utm_term

  • Те же данные о текущем источнике

    (если пользователь совершил повторный переход из другого источника)

  • Дата первого посещения

  • Точка входа

  • Полный реферер, при котором произошла перезапись источника

  • ip и user agent пользователя


Установка модуля
Закладываемся, что вас уже есть rails-приложение, к которому вы хотите прикрутить модуль.

В 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, и довольно тяжело самому постигать всё и вся.


Заранее спасибо за критику и надеюсь этот пост будет кому-то полезен. Удач.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers.


Комментариев нет:

Отправить комментарий