Skip to content

Commit

Permalink
Added #identify_user method to grab existing __utma identifier from c…
Browse files Browse the repository at this point in the history
…ookies

Fixes #3

Gabba will continue to work as normal if identify_user is not called, or if
it is passed a nil value - ie random strings & date are used for the utma
value.

Some annoying diff-cruft due to whitespace. Sorry!
  • Loading branch information
tomblomfield committed Apr 1, 2012
1 parent bcc0d52 commit fec0860
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 27 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
gabba (0.1.1)
gabba (0.2.0)

GEM
remote: http://rubygems.org/
Expand Down
10 changes: 10 additions & 0 deletions README
Expand Up @@ -14,6 +14,16 @@ HOW TO USE:

Gabba::Gabba.new("UT-1234", "mydomain.com").event("Videos", "Play", "ID", "123", true)

* Works with existing client-side Google Analytics cookies

gabba = Gabba::Gabba.new("UT-1234", "mydomain.com")

# grab the __utma unique identifier
gabba.identify_user(cookies[:__utma])

# trigger actions as normal
gabba.page_view("something", "track/me")

* Setting custom vars

# Index: 1 through 5
Expand Down
26 changes: 21 additions & 5 deletions lib/gabba/gabba.rb
Expand Up @@ -150,9 +150,9 @@ def page_view_params(title, page, utmhid = random_id)
# Public: Record an event in Google Analytics
# (http://code.google.com/apis/analytics/docs/gaJS/gaJSApiEventTracking.html)
#
# category -
# action -
# label -
# category -
# action -
# label -
# value -
# utmni -
# utmhid -
Expand Down Expand Up @@ -279,9 +279,25 @@ def item_params(order_id, item_sku, name, category, price, quantity, utmhid)
}
end

# Public: provide the user's __utma attribute from analytics cookie, allowing
# better tracking of user flows
#
# Called before page_view etc
#
# Examples:
# g = Gabba::Gabba.new("UT-1234", "mydomain.com")
# g.identify_user(cookies[:__utma])
# g.page_view("something", "track/me")
#
def identify_user(utma)
@utma = utma
end

# create magical cookie params used by GA for its own nefarious purposes
def cookie_params(utma1 = random_id, utma2 = rand(1147483647) + 1000000000, today = Time.now)
"__utma=1.#{utma1}00145214523.#{utma2}.#{today.to_i}.#{today.to_i}.15;+__utmz=1.#{today.to_i}.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);"
utma = @utma
utma ||= "1.#{utma1}00145214523.#{utma2}.#{today.to_i}.#{today.to_i}.15"
"__utma=#{utma};+__utmz=1.#{today.to_i}.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);"
end

# sanity check that we have needed params to even call GA
Expand Down Expand Up @@ -313,7 +329,7 @@ def escape(t)
return t if !t || (/\w/ !~ t.to_s)

t.to_s.gsub(/[\*'!\)]/) do |m|
"'#{ESCAPES.index(m)}"
"'#{ESCAPES.index(m)}"
end
end

Expand Down
56 changes: 35 additions & 21 deletions spec/gabba_spec.rb
@@ -1,23 +1,23 @@
require File.dirname(__FILE__) + '/spec_helper'

describe Gabba::Gabba do

describe "when tracking page views" do
before do
@gabba = Gabba::Gabba.new("abc", "123")
@gabba.utmn = "1009731272"
@gabba.utmcc = ''
stub_analytics @gabba.page_view_params("title", "/page/path", "6783939397")
end

it "must require GA account" do
lambda {Gabba::Gabba.new(nil, nil).page_view("thing", "thing")}.must_raise(Gabba::NoGoogleAnalyticsAccountError)
end

it "must require GA domain" do
lambda {Gabba::Gabba.new("abs", nil).page_view("thing", "thing")}.must_raise(Gabba::NoGoogleAnalyticsDomainError)
end

it "must be able to create page_view_params" do
@gabba.page_view_params("hiya", "/tracker/page")[:utmdt].must_equal("hiya")
end
Expand All @@ -34,23 +34,23 @@
@gabba.utmcc = ''
stub_analytics @gabba.event_params("cat1", "act1", "lab1", "val1", false, "6783939397")
end

it "must require GA account" do
lambda {Gabba::Gabba.new(nil, nil).event("cat1", "act1", "lab1", "val1")}.must_raise(Gabba::NoGoogleAnalyticsAccountError)
end

it "must require GA domain" do
lambda {Gabba::Gabba.new("abs", nil).event("cat1", "act1", "lab1", "val1")}.must_raise(Gabba::NoGoogleAnalyticsDomainError)
end

it "must be able to create event data" do
@gabba.event_data("cat1", "act1", "lab1", "val1").must_equal("5(cat1*act1*lab1)(val1)")
end

it "must be able to create event data with only category and action" do
@gabba.event_data("cat1", "act1").must_equal("5(cat1*act1)")
end

it "must do event request to google" do
@gabba.event("cat1", "act1", "lab1", "val1", false, "6783939397").code.must_equal("200")
end
Expand All @@ -60,90 +60,104 @@
end

end

describe "when tracking an item" do
before do
@gabba = Gabba::Gabba.new("abc", "123")
@gabba.utmn = "1009731272"
@gabba.utmcc = ''
stub_analytics @gabba.item_params("orderid", "1234", "widget", "widgets", "9.99", "1", "6783939397")
end

it "must require GA account" do
lambda {Gabba::Gabba.new(nil, nil).add_item("orderid", "1234", "widget", "widgets", "9.99", "1", "6783939397")}.must_raise(Gabba::NoGoogleAnalyticsAccountError)
end

it "must require GA domain" do
lambda {Gabba::Gabba.new("abs", nil).add_item("orderid", "1234", "widget", "widgets", "9.99", "1", "6783939397")}.must_raise(Gabba::NoGoogleAnalyticsDomainError)
end

it "must do add item request to google" do
@gabba.add_item("orderid", "1234", "widget", "widgets", "9.99", "1", "6783939397").code.must_equal("200")
end
end

describe "when tracking a transaction" do
before do
@gabba = Gabba::Gabba.new("abc", "123")
@gabba.utmn = "1009731272"
@gabba.utmcc = ''
stub_analytics @gabba.transaction_params("orderid", "9.99", "acme stores", ".25", "1.00", "San Jose", "CA", "United States", "6783939397")
end

it "must require GA account" do
lambda {Gabba::Gabba.new(nil, nil).transaction("orderid", "9.99", "acme stores", ".25", "1.00", "San Jose", "CA", "United States", "6783939397")}.must_raise(Gabba::NoGoogleAnalyticsAccountError)
end

it "must require GA domain" do
lambda {Gabba::Gabba.new("abs", nil).transaction("orderid", "9.99", "acme stores", ".25", "1.00", "San Jose", "CA", "United States", "6783939397")}.must_raise(Gabba::NoGoogleAnalyticsDomainError)
end

it "must do transaction request to google" do
@gabba.transaction("orderid", "9.99", "acme stores", ".25", "1.00", "San Jose", "CA", "United States", "6783939397").code.must_equal("200")
end
end

describe "when using identify_user" do
before do
@gabba = Gabba::Gabba.new("abc", "123")
@gabba.utmn = "1009731272"
@gabba.utmcc = ''
end
it "must use the supplied utma in cookie_params" do
# This is how the Google cookie is named
cookies = { __utma: "long_code"}
@gabba.identify_user(cookies[:__utma])
@gabba.cookie_params.must_match /utma=long_code;/
end
end

describe "setting a custom var" do
before do
@gabba = Gabba::Gabba.new("abc", "123")
@gabba.utmn = "1009731272"
@gabba.utmcc = ''
end

it "must return data for a valid var" do
@gabba.set_custom_var 1, 'A (B*\'!)', 'Yes', Gabba::Gabba::SESSION
@gabba.custom_var_data.must_equal "8(A (B'2'0'1'3)9(Yes)11(2)"
end

it "must return data for several valid vards" do
@gabba.set_custom_var 1, 'A', 'Yes', Gabba::Gabba::SESSION
@gabba.set_custom_var 2, 'B', 'No', Gabba::Gabba::VISITOR
@gabba.custom_var_data.must_equal "8(A*B)9(Yes*No)11(2*1)"
end

it "must return an empty string if vars aren't set" do
@gabba.custom_var_data.must_equal ""
end

it "must not include var with an empty value" do
@gabba.set_custom_var 1, 'A', 'Yes', Gabba::Gabba::SESSION
@gabba.set_custom_var 2, 'B', '', Gabba::Gabba::VISITOR
@gabba.set_custom_var 3, 'C', ' ', Gabba::Gabba::VISITOR
@gabba.set_custom_var 4, 'D', nil, Gabba::Gabba::VISITOR
@gabba.custom_var_data.must_equal "8(A)9(Yes)11(2)"
end

it "must mention index of the var if non sequential" do
@gabba.set_custom_var 2, 'A', 'Y', Gabba::Gabba::SESSION
@gabba.set_custom_var 4, 'D', 'N', Gabba::Gabba::VISITOR
@gabba.custom_var_data.must_equal "8(2!A*4!D)9(2!Y*4!N)11(2!2*4!1)"
end

it "must raise an error if index is outside the 1-5 (incl) range" do
lambda { @gabba.set_custom_var(0, 'A', 'B', 1) }.must_raise(RuntimeError)
lambda { @gabba.set_custom_var(6, 'A', 'B', 1) }.must_raise(RuntimeError)
end

it "must raise an error if scope is outside the 1-3 (incl) range" do
lambda { @gabba.set_custom_var(1, 'A', 'B', 0) }.must_raise(RuntimeError)
lambda { @gabba.set_custom_var(1, 'A', 'B', 4) }.must_raise(RuntimeError)
Expand All @@ -156,14 +170,14 @@
@gabba.utmn = "1009731272"
@gabba.utmcc = ''
end

it "must return data for a valid var" do
@gabba.set_custom_var 1, 'A (B*\'!)', 'Yes', Gabba::Gabba::SESSION
@gabba.delete_custom_var 1
@gabba.custom_var_data.must_equal ""
end
end

def stub_analytics(expected_params)
s = stub_request(:get, /www.google-analytics.com\/__utm.gif\?utmac=#{expected_params[:utmac]}&.*/).
to_return(:status => 200, :body => "", :headers => {})
Expand Down

0 comments on commit fec0860

Please sign in to comment.