Code Monkey home page Code Monkey logo

rack-tracker's Introduction

Rack::Tracker

Code Climate Build Status

Rationale

Most of the applications we're working on are using some sort of tracking/analytics service, Google Analytics comes first but its likely that more are added as the project grows. Normally you'd go ahead and add some partials to your application that will render out the needed tracking codes. As time passes by you'll find yourself with lots of tracking snippets, that will clutter your codebase :) When just looking at Analytics there are solutions like rack-google-analytics but they just soley tackle the existence of one service.

We wanted a solution that ties all services together in one place and offers an easy interface to drop in new services. This is why we created rack-tracker, a rack middleware that can be hooked up to multiple services and exposing them in a unified fashion. It comes in two parts, the first one is the actual middleware that you can add to the middleware stack the second part are the service-handlers that you're going to use in your application. It's easy to add your own custom handlers, but to get you started we're shipping support for the following services out of the box:

Installation

Add this line to your application's Gemfile:

gem 'rack-tracker'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rack-tracker

Usage

Add it to your middleware stack

config.middleware.use(Rack::Tracker) do
  handler :google_analytics, { tracker: 'U-XXXXX-Y' }
end

This will add Google Analytics as a tracking handler.

Sinatra / Rack

You can even use Rack::Tracker with Sinatra or respectively with every Rack application

Just insert the Tracker in your Rack stack:

web = Rack::Builder.new do
  use Rack::Tracker do
    handler :google_analytics, { tracker: 'U-XXXXX-Y' }
  end
  run Sinatra::Web
end

run web

Although you cannot use the Rails controller extensions for obvious reasons, its easy to inject arbitrary events into the request environment.

request.env['tracker'] = {
  'google_analytics' => [
    { 'class_name' => 'Send', 'category' => 'Users', 'action' => 'Login', 'label' => 'Standard' }
  ]
}

Google Analytics

Events

To issue Events from the server side just call the tracker method in your controller.

  def show
    tracker do |t|
      t.google_analytics :send, { type: 'event', category: 'button', action: 'click', label: 'nav-buttons', value: 'X' }
    end
  end

It will render the following to the site source:

  ga('send', { 'hitType': 'event', 'eventCategory': 'button', 'eventAction': 'click', 'eventLabel': 'nav-buttons', 'value': 'X' })

Parameters

You can set parameters in your controller too:

  def show
    tracker do |t|
      t.google_analytics :parameter, { dimension1: 'pink' }
    end
  end

Will render this:

  ga('set', 'dimension1', 'pink');

Enhanced Ecommerce

You can set parameters in your controller:

  def show
    tracker do |t|
      t.google_analytics :enhanced_ecommerce, {
        type: 'addItem',
        id: '1234',
        name: 'Fluffy Pink Bunnies',
        sku: 'DD23444',
        category: 'Party Toys',
        price: '11.99',
        quantity: '1'
      }
    end
  end

Will render this:

  ga("ec:addItem", {"id": "1234", "name": "Fluffy Pink Bunnies", "sku": "DD23444", "category": "Party Toys", "price": "11.99", "quantity": "1"});

Ecommerce

You can even trigger ecommerce directly from within your controller:

  def show
    tracker do |t|
      t.google_analytics :ecommerce, { type: 'addItem', id: '1234', affiliation: 'Acme Clothing', revenue: '11.99', shipping: '5', tax: '1.29' }
    end
  end

Will give you this:

  ga('ecommerce:addItem', { 'id': '1234', 'affiliation': 'Acme Clothing', 'revenue': '11.99', 'shipping': '5', 'tax': '1.29'  })

To load the ecommerce-plugin, add some configuration to the middleware initialization. This is not needed for the above to work, but recommened, so you don't have to take care of the plugin on your own.

  config.middleware.use(Rack::Tracker) do
    handler :google_analytics, { tracker: 'U-XXXXX-Y', ecommerce: true }
  end

Google Tag Manager

Google Tag manager code snippet doesn't support any option other than the container id

  config.middleware.use(Rack::Tracker) do
    handler :google_tag_manager, { container: 'GTM-XXXXXX' }
  end

Data Layer

GTM supports a dataLayer for pushing events as well as variables.

To add events or variables to the dataLayer from the server side, just call the tracker method in your controller.

  def show
    tracker do |t|
      t.google_tag_manager :push, { name: 'price', value: 'X' }
    end
  end

Facebook

Conversions

To track Conversions from the server side just call the tracker method in your controller.

  def show
    tracker do |t|
      t.facebook :track, { id: '123456789', value: 1, currency: 'EUR' }
    end
  end

Will result in the following:

  window._fbq.push(["track", "123456789", {'value': 1, 'currency': 'EUR'}]);

Visual website Optimizer (VWO)

Just integrate the handler with your matching account_id and you will be ready to go

  use Rack::Tracker do
    handler :vwo, { account_id: 'YOUR_ACCOUNT_ID' }
  end

GoSquared

To enable GoSquared tracking:

config.middleware.use(Rack::Tracker) do
  handler :go_squared, { tracker: 'ABCDEFGH' }
end

This will add the tracker to the page like so:

  _gs('ABCDEFGH');

You can also set multiple named trackers if need be:

config.middleware.use(Rack::Tracker) do
  handler :go_squared, {
    trackers: {
      primaryTracker: 'ABCDEFGH',
      secondaryTracker: '1234567',
    }
  }
end

This will add the specified trackers to the page like so:

  _gs('ABCDEFGH', 'primaryTracker');
  _gs('1234567', 'secondaryTracker');

You can set a variety of options by passing the following settings. If you don't set any of the following options, they will be omitted from the rendered code.

  • :anonymize_ip
  • :cookie_domain
  • :use_cookies
  • :track_hash
  • :track_local
  • :track_params

Visitor Name

To track the visitor name from the server side, just call the tracker method in your controller.

  def show
    tracker do |t|
      t.go_squared :visitor_name, { name: 'John Doe' }
    end
  end

It will render the following to the site source:

  _gs("set", "visitorName", "John Doe");

Visitor Properties

To track visitor properties from the server side, just call the tracker method in your controller.

  def show
    tracker do |t|
      t.go_squared :visitor_info, { age: 35, favorite_food: 'pizza' }
    end
  end

It will render the following to the site source:

  _gs("set", "visitor", { "age": 35, "favorite_food": "pizza" });

Criteo

Criteo retargeting service.

Basic configuration

config.middleware.use(Rack::Tracker) do
  handler :criteo, { set_account: '1234' }
end

Other global criteo handler options are:

  • set_customer_id: 'x'
  • set_site_type: 'd' - possible values are m (mobile), t (tablet), d (desktop)

Option values can be either static or dynamic by providing a lambda being reevaluated for each request, e.g. set_customer_id: lambda { |env| env['rack.session']['user_id'] }

Tracking events

This will track a basic event:

def show
  tracker do |t|
    t.criteo :view_item, { item: 'P0001' }
  end
end

This will render to the follwing code in the JS:

window.criteo_q.push({"event": "viewItem", "item": "P001" });

The first argument for t.criteo is always the criteo event (e.g. :view_item, :view_list, :track_transaction, :view_basket) and the second argument are additional properties for the event.

Another example

t.criteo :track_transaction, { id: 'id', item: { id: "P0038", price: "6.54", quantity: 1 } }

Zanox

Zanox

Basic Configuration

config.middleware.use(Rack::Tracker) do
  handler :zanox, { account_id: '1234' }
end

Mastertag

This is an example of a mastertag:

def show
  tracker do |t|
    t.zanox :mastertag, { id: "25GHTE9A07DF67DFG90T", category: 'Swimming', amount: '3.50' }
  end
end

This will render to the follwing code in the JS:

window._zx.push({"id": "25GHTE9A07DF67DFG90T"});

and the following variables:

zx_category = 'Swimming';
zx_amount = '3.50';

#### Conversion tracking

This is an example of a lead event:

def show tracker do |t| t.zanox :lead, { order_i_d: 'DEFC-4321' } end end


This is an example of a sale event:

def show tracker do |t| t.zanox :sale, { customer_i_d: '123456', order_i_d: 'DEFC-4321', currency_symbol: 'EUR', total_price: '150.00' } end end


### Custom Handlers

Tough we give you handlers for a few tracking services right out of the box, you might
be interested adding support for your custom tracking/analytics service.

Writing a handler is straight forward ;) and there are just a couple of methods that
your class needs to implement.

Start with a plain ruby class that inherits from `Rack::Tracker::Handler`

```ruby
class MyHandler <  Rack::Tracker::Handler
  ...
end

Second we need a method called #render which will take care of rendering a template.

def render
  Tilt.new( File.join( File.dirname(__FILE__), 'template', 'my_handler.erb') ).render(self)
end

This will render the template/my_handler.erb and inject the result into the source. You can be creative about where the template is stored, but we tend to have them around our actual handler code.

<script>
  console.log('my tracker: ' + <%= options.to_json %>)
</script>

Lets give it a try! We need to mount our new handler in the Rack::Tracker middleware

  config.middleware.use(Rack::Tracker) do
    handler MyHandler, { awesome: true }
  end

Everything you're passing to the handler will be available as #options in your template, so you'll also gain access to the env-hash belonging to the current request.

Run your application and make a request, the result of the above template can be found right before </head>. You can change the position in your handler-code:

class MyHandler <  Rack::Tracker::Handler
  self.position = :body

  ...
end

The snippit will then be rendered right before </body>.

To enable the tracker dsl functionality in your controllers you need to implement the track class method on your handler:

def self.track(name, *event)
  # do something with the event(s) to prepare them for your template
  # and return a hash with a signature like { name => event }
end

Checkout the existing handlers in lib/rack/tracker for some inspiration. :)

Contributing

First of all, thank you for your help! 💚

If you want a feature implemented, the best way to get it done is to submit a pull request that implements it. Tests, readme and changelog entries would be nice.

  1. Fork it ( http://github.com/railslove/rack-tracker/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

rack-tracker's People

Contributors

donschado avatar jhilden avatar mnin avatar mortro avatar namxam avatar pjkelly avatar remi avatar salimhb avatar stephanpavlovic avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.