README.md
# Referrer
[![Build Status](https://api.travis-ci.org/salkar/referrer.svg?branch=master)](http://travis-ci.org/salkar/referrer)
[![Code Climate](https://codeclimate.com/github/salkar/referrer.svg)](https://codeclimate.com/github/salkar/referrer)
Referrer tracks sources with which users visit your site, converts them into utm markup, computes priority of these sources and provides linking for sources with tracked model's records (orders/requests/etc).
Sample questions which Referrer can help to answer:
- Where did this user come from?
- `{utm_source: 'google', utm_medium: 'organic', utm_campaign: '(none)', utm_content: '(none)', utm_term: 'user search query', kind: 'organic'}`
<br /><br />
- Where did users come from last month?
- `[{utm_source: 'google', utm_medium: 'organic', utm_campaign: '(none)', utm_content: '(none)', utm_term: 'user search query', kind: 'organic', count: 1}, {utm_source: 'google', utm_campaign: 'adv_campaign', utm_medium: 'cpc', utm_content: 'adv 1', utm_term: 'some text', kind: 'utm', count: 2}, etc...]`
<br /><br />
- Where did user who make purchase come from?
- `{utm_source: 'twitter.com', utm_medium: 'referral', utm_campaign: '(none)', utm_content: '/some_path', utm_term: '(none)', kind: 'referral'}`
<br /><br />
- Where did users who left some requests come from last week?
- `[{utm_source: '(direct)', utm_medium: '(none)', utm_campaign: '(none)', utm_content: '(none)', utm_term: '(none)', kind: 'direct', count: 3}, {utm_source: 'google', utm_campaign: 'adv_campaign', utm_medium: 'cpc', utm_content: 'adv 2', utm_term: 'another text', kind: 'utm', count: 5}, etc...]`
## Installation
### Basic setup
1. Add Referrer to your Gemfile:
```ruby
gem 'referrer'
```
2. Run the bundle command to install it:
```bash
bundle install
```
3. Copy migrations from engine:
```bash
rake referrer:install:migrations
```
4. Migrate your database:
```bash
rake db:migrate
```
5. Mount engine's routes at `config/routes.rb`
```ruby
mount Referrer::Engine => '/referrer'
```
6. Require engine's js in your `application.js` file:
```ruby
//= require referrer/application
```
7. Add to your ApplicationController:
```ruby
include Referrer::ControllerAdditions
```
8. If your `current_user` method has another name, add to `config/initializers/referrer.rb`:
```ruby
Referrer.current_user_method_name = :your_method_name
```
### Setup your statistics owners
Add to your models which objects may be returned from `current_user` (or your same method, specified in `Referrer.current_user_method_name`) `include Referrer::OwnerModelAdditions`. For sample if your `current_user` return `User` objects:
```ruby
class User < ActiveRecord::Base
include Referrer::OwnerModelAdditions
#...
end
```
### Setup your tracked models
1. Add to models you want to track `include Referrer::TrackedModelAdditions`. For sample if you want to track where users who make orders come from (`Order` class):
```ruby
class Order < ActiveRecord::Base
include Referrer::TrackedModelAdditions
#...
end
```
2. After you create tracked model record next time you can link record with current source. For sample (with `Order` object):
```ruby
# OrdersControllers#create
#...
if @order.save
@order.referrer_link_with(referrer_user) # referrer_user defined in Referrer::TrackedModelAdditions
else
#...
```
## Settings
Referrer settings can be changed in initializers. For sample, you can create `config/initializers/referrer.rb` and add your custom settings to it.
###Settings list
1. **current_user_method_name** - method name in ApplicationController which return current logged in object.
```ruby
:current_user
```
2. **js_settings** - options passes to js part of Referrer.
```ruby
{}
```
Available options:
* cookies
```javascript
{prefix: 'referrer',
domain: null,
path: '/'}
```
* object
```javascript
{name: 'referrer'}
```
* callback
```javascript
null
```
3. **js_csrf_token** - js code to get CSRF token if it is used.
```ruby
<<-JS
var tokenContainer = document.querySelector("meta[name=csrf-token]");
return tokenContainer ? tokenContainer.content : null;
JS
```
4. **markup_generator_settings** - options for Referrer::MarkupGenerator.
```ruby
{}
```
Available options:
* organics
```ruby
[{host: 'search.daum.net', param: 'q'},
{host: 'search.naver.com', param: 'query'},
{host: 'search.yahoo.com', param: 'p'},
{host: /^(www\.)?google\.[a-z]+$/, param: 'q', display: 'google'},
{host: 'www.bing.com', param: 'q'},
{host: 'search.aol.com', params: 'q'},
{host: 'search.lycos.com', param: 'q'},
{host: 'edition.cnn.com', param: 'text'},
{host: 'index.about.com', param: 'q'},
{host: 'mamma.com', param: 'q'},
{host: 'ricerca.virgilio.it', param: 'qs'},
{host: 'www.baidu.com', param: 'wd'},
{host: /^(www\.)?yandex\.[a-z]+$/, param: 'text', display: 'yandex'},
{host: 'search.seznam.cz', param: 'oq'},
{host: 'www.search.com', param: 'q'},
{host: 'search.yam.com', param: 'k'},
{host: 'www.kvasir.no', param: 'q'},
{host: 'buscador.terra.com', param: 'query'},
{host: 'nova.rambler.ru', param: 'query'},
{host: 'go.mail.ru', param: 'q'},
{host: 'www.ask.com', param: 'q'},
{host: 'searches.globososo.com', param: 'q'},
{host: 'search.tut.by', param: 'query'}]
```
* referrals
```ruby
[{host: /^(www\.)?t\.co$/, display: 'twitter.com'},
{host: /^(www\.)?plus\.url\.google\.com$/, display: 'plus.google.com'}]
```
* utm_synonyms
```ruby
{'utm_source'=>[], 'utm_medium'=>[], 'utm_campaign'=>[], 'utm_content'=>[], 'utm_term'=>[]}
```
* array_params_joiner
```ruby
', '
```
5. **session_duration** - after this duration left, new session will be created and its sources priorities will be computed without regard to past sessions sources.
```ruby
3.months
```
6. **sources_overwriting_schema** - source's kind priorities for priority source computation.
```ruby
{direct: %w(direct),
referral: %w(direct referral organic utm),
organic: %w(direct referral organic utm),
utm: %w(direct referral organic utm)}
```
## Usage
### Sources owner
#### referrer_markups
Get markups for application user. Returns hash where:
* **first** - user's first source
* **priority** - user's last priority source, computed using `sources_overwriting_schema`
* **last** - user's last source
```ruby
user.referrer_markups
=> {first: {utm_source: 'google', utm_medium: 'organic', utm_campaign: '(none)', utm_content: '(none)', utm_term: 'user search query', kind: 'organic'},
priority: {utm_source: 'google', utm_campaign: 'adv_campaign', utm_medium: 'cpc', utm_content: 'adv 1', utm_term: 'some text', kind: 'utm'},
last: {utm_source: '(direct)', utm_medium: '(none)', utm_campaign: '(none)', utm_content: '(none)', utm_term: '(none)', kind: 'direct'}}
```
### Tracked model
#### referrer_markup
Get markup for tracked model's object. Returns markup hash:
```ruby
user.referrer_markup
=> {utm_source: 'test.com', utm_campaign: '(none)', utm_medium: 'referral', utm_content: '/',
utm_term: '(none)', kind: 'referral'}}
```
#### referrer_link_with(r_user, linked_at: nil) [referrer_link_with!(r_user, linked_at: nil)]
Link tracked model's object to referrer's data. Parameters:
* `r_user` - `Referrer::User` object, in controller can be got by `referrer_user` (requires Referrer::ControllerAdditions be included).
* `linked_at` - custom linking `DateTime`.
### Statistics
#### Referrer::Statistics.sources_markup(from, to)
Get markup of visits occurred in the specified period. Parameters:
* `from` - DateTime of period start
* `to` - DateTime of period end
Sample:
```ruby
Referrer::Statistics.sources_markup(10.days.ago, 2.days.ago)
=> [{utm_source: 'first', utm_campaign: '(none)', utm_medium: '(none)', utm_content: '(none)',
utm_term: '(none)', kind: 'utm', count: 2},
{utm_source: 'second', utm_campaign: '(none)', utm_medium: '(none)', utm_content: '(none)',
utm_term: '(none)', kind: 'utm', count: 1},
{utm_source: '(direct)', utm_campaign: '(none)', utm_medium: '(none)', utm_content: '(none)',
utm_term: '(none)', kind: 'direct', count: 1}]
```
#### Referrer::Statistics.tracked_objects_markup(from, to, type: nil)
Get markup associated with tracked model objects, in the specified period. Parameters:
* `from` - DateTime of period start
* `to` - DateTime of period end
* `type` - tracked model name. If specified, response will contain markup associated only with this model objects.
Sample:
```ruby
Referrer::Statistics.tracked_objects_markup(10.days.ago, 2.days.ago)
=> [{utm_source: 'first', utm_campaign: '(none)', utm_medium: '(none)', utm_content: '(none)',
utm_term: '(none)', kind: 'utm', count: 2},
{utm_source: 'second', utm_campaign: '(none)', utm_medium: '(none)', utm_content: '(none)',
utm_term: '(none)', kind: 'utm', count: 1}]
```
## License
This project rocks and uses MIT-LICENSE.