Added current_visitor_id method and switched to UUIDs
Andrew Kane
committed Jun 12, 2014
commit 802a6054dc74928be039fb833d158ba82d073c0d
Showing 6
changed files with
111 additions
and 95 deletions
CHANGELOG.md
+3
-1
| @@ | @@ -1,5 +1,7 @@ |
| - | ## 0.2.3 [unreleased] |
| + | ## 0.3.0 [unreleased] |
| + | - Added `current_visitor_id` method |
| + | - Switched to UUIDs |
| - Quiet endpoint requests | |
| - Skip server-side bot events | |
| - Added `request` argument to `exclude_method` | |
app/controllers/ahoy/visits_controller.rb
+2
-8
| @@ | @@ -2,8 +2,8 @@ module Ahoy |
| class VisitsController < BaseController | |
| def create | |
| - | visit_token = params[:visit_token] || generate_token |
| - | visitor_token = params[:visitor_token] || generate_token |
| + | visit_token = params[:visit_token] || Ahoy.generate_id |
| + | visitor_token = params[:visitor_token] || Ahoy.generate_id |
| visit = | |
| Ahoy.visit_model.new do |v| | |
| @@ | @@ -23,11 +23,5 @@ module Ahoy |
| render json: {visit_token: visit.visit_token, visitor_token: visit.visitor_token} | |
| end | |
| - | protected |
| - | |
| - | def generate_token |
| - | SecureRandom.urlsafe_base64(32).gsub(/[\-_]/, "").first(32) |
| - | end |
| - | |
| end | |
| end | |
ahoy.rb b/lib/ahoy.rb
+66
-0
| @@ | @@ -0,0 +1,66 @@ |
| + | require "addressable/uri" |
| + | require "browser" |
| + | require "geocoder" |
| + | require "referer-parser" |
| + | require "user_agent_parser" |
| + | require "request_store" |
| + | require "ahoy/version" |
| + | require "ahoy/tracker" |
| + | require "ahoy/controller" |
| + | require "ahoy/model" |
| + | require "ahoy/subscribers/active_record" |
| + | require "ahoy/engine" |
| + | require "ahoy/warden" if defined?(Warden) |
| + | |
| + | module Ahoy |
| + | |
| + | def self.generate_id |
| + | SecureRandom.uuid |
| + | end |
| + | |
| + | def self.visit_model |
| + | @visit_model || ::Visit |
| + | end |
| + | |
| + | def self.visit_model=(visit_model) |
| + | @visit_model = visit_model |
| + | end |
| + | |
| + | # TODO private |
| + | # performance hack for referer-parser |
| + | def self.referrer_parser |
| + | @referrer_parser ||= RefererParser::Referer.new("https://github.com/ankane/ahoy") |
| + | end |
| + | |
| + | # performance |
| + | def self.user_agent_parser |
| + | @user_agent_parser ||= UserAgentParser::Parser.new |
| + | end |
| + | |
| + | def self.fetch_user(controller) |
| + | if user_method.respond_to?(:call) |
| + | user_method.call(controller) |
| + | else |
| + | controller.send(user_method) |
| + | end |
| + | end |
| + | |
| + | mattr_accessor :user_method |
| + | self.user_method = proc do |controller| |
| + | (controller.respond_to?(:current_user) && controller.current_user) || (controller.respond_to?(:current_resource_owner, true) && controller.send(:current_resource_owner)) || nil |
| + | end |
| + | |
| + | mattr_accessor :exclude_method |
| + | |
| + | mattr_accessor :subscribers |
| + | self.subscribers = [] |
| + | |
| + | mattr_accessor :track_bots |
| + | self.track_bots = false |
| + | |
| + | mattr_accessor :quiet |
| + | self.quiet = true |
| + | end |
| + | |
| + | ActionController::Base.send :include, Ahoy::Controller |
| + | ActiveRecord::Base.send(:extend, Ahoy::Model) if defined?(ActiveRecord) |
ahoy/controller.rb b/lib/ahoy/controller.rb
+9
-0
| @@ | @@ -4,6 +4,7 @@ module Ahoy |
| def self.included(base) | |
| base.helper_method :current_visit | |
| base.helper_method :ahoy | |
| + | base.before_filter :set_ahoy_visitor_cookie |
| base.before_filter do | |
| RequestStore.store[:ahoy_controller] ||= self | |
| end | |
| @@ | @@ -20,5 +21,13 @@ module Ahoy |
| @ahoy ||= Ahoy::Tracker.new(controller: self) | |
| end | |
| + | def set_ahoy_visitor_cookie |
| + | cookies[:ahoy_visitor] = current_visitor_id if !request.headers["Ahoy-Visitor"] && !cookies[:ahoy_visitor] |
| + | end |
| + | |
| + | def current_visitor_id |
| + | @current_visit_id ||= request.headers["Ahoy-Visitor"] || cookies[:ahoy_visitor] || Ahoy.generate_id |
| + | end |
| + | |
| end | |
| end | |
ahoy_matey.rb b/lib/ahoy_matey.rb
+1
-62
| @@ | @@ -1,62 +1 @@ |
| - | require "addressable/uri" |
| - | require "browser" |
| - | require "geocoder" |
| - | require "referer-parser" |
| - | require "user_agent_parser" |
| - | require "request_store" |
| - | require "ahoy/version" |
| - | require "ahoy/tracker" |
| - | require "ahoy/controller" |
| - | require "ahoy/model" |
| - | require "ahoy/subscribers/active_record" |
| - | require "ahoy/engine" |
| - | require "ahoy/warden" if defined?(Warden) |
| - | |
| - | module Ahoy |
| - | |
| - | def self.visit_model |
| - | @visit_model || ::Visit |
| - | end |
| - | |
| - | def self.visit_model=(visit_model) |
| - | @visit_model = visit_model |
| - | end |
| - | |
| - | # TODO private |
| - | # performance hack for referer-parser |
| - | def self.referrer_parser |
| - | @referrer_parser ||= RefererParser::Referer.new("https://github.com/ankane/ahoy") |
| - | end |
| - | |
| - | # performance |
| - | def self.user_agent_parser |
| - | @user_agent_parser ||= UserAgentParser::Parser.new |
| - | end |
| - | |
| - | def self.fetch_user(controller) |
| - | if user_method.respond_to?(:call) |
| - | user_method.call(controller) |
| - | else |
| - | controller.send(user_method) |
| - | end |
| - | end |
| - | |
| - | mattr_accessor :user_method |
| - | self.user_method = proc do |controller| |
| - | (controller.respond_to?(:current_user) && controller.current_user) || (controller.respond_to?(:current_resource_owner, true) && controller.send(:current_resource_owner)) || nil |
| - | end |
| - | |
| - | mattr_accessor :exclude_method |
| - | |
| - | mattr_accessor :subscribers |
| - | self.subscribers = [] |
| - | |
| - | mattr_accessor :track_bots |
| - | self.track_bots = false |
| - | |
| - | mattr_accessor :quiet |
| - | self.quiet = true |
| - | end |
| - | |
| - | ActionController::Base.send :include, Ahoy::Controller |
| - | ActiveRecord::Base.send(:extend, Ahoy::Model) if defined?(ActiveRecord) |
| + | require "ahoy" |
vendor/assets/javascripts/ahoy.js
+30
-24
| @@ | @@ -1,3 +1,11 @@ |
| + | /* |
| + | * Ahoy.js |
| + | * Simple, powerful JavaScript analytics |
| + | * https://github.com/ankane/ahoy.js |
| + | * v0.1.0 |
| + | * MIT License |
| + | */ |
| + | |
| /*jslint browser: true, indent: 2, plusplus: true, vars: true */ | |
| (function (window) { | |
| @@ | @@ -5,13 +13,14 @@ |
| var ahoy = window.ahoy || window.Ahoy || {}; | |
| var $ = window.jQuery || window.Zepto || window.$; | |
| - | var visitToken, visitorToken; |
| + | var visitId, visitorId; |
| var visitTtl = 4 * 60; // 4 hours | |
| var visitorTtl = 2 * 365 * 24 * 60; // 2 years | |
| var isReady = false; | |
| var queue = []; | |
| var canStringify = typeof(JSON) !== "undefined" && typeof(JSON.stringify) !== "undefined"; | |
| var eventQueue = []; | |
| + | var page = ahoy.page || window.location.pathname; |
| // cookies | |
| @@ | @@ -72,18 +81,12 @@ |
| } | |
| } | |
| - | // https://github.com/klughammer/node-randomstring |
| + | // http://stackoverflow.com/a/2117523/1177228 |
| function generateId() { | |
| - | var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz'; |
| - | var length = 32; |
| - | var string = ''; |
| - | |
| - | for (var i = 0; i < length; i++) { |
| - | var randomNumber = Math.floor(Math.random() * chars.length); |
| - | string += chars.substring(randomNumber, randomNumber + 1); |
| - | } |
| - | |
| - | return string; |
| + | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { |
| + | var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); |
| + | return v.toString(16); |
| + | }); |
| } | |
| function saveEventQueue() { | |
| @@ | @@ -123,35 +126,37 @@ |
| return { | |
| tag: $target.get(0).tagName.toLowerCase(), | |
| id: $target.attr("id"), | |
| - | "class": $target.attr("class") |
| + | "class": $target.attr("class"), |
| + | page: page, |
| + | section: $target.closest("*[data-section]").data("section") |
| }; | |
| } | |
| // main | |
| - | visitToken = getCookie("ahoy_visit"); |
| - | visitorToken = getCookie("ahoy_visitor"); |
| + | visitId = getCookie("ahoy_visit"); |
| + | visitorId = getCookie("ahoy_visitor"); |
| - | if (visitToken && visitorToken) { |
| + | if (visitId && visitorId) { |
| // TODO keep visit alive? | |
| log("Active visit"); | |
| setReady(); | |
| } else { | |
| - | visitToken = generateId(); |
| - | setCookie("ahoy_visit", visitToken, visitTtl); |
| + | visitId = generateId(); |
| + | setCookie("ahoy_visit", visitId, visitTtl); |
| // make sure cookies are enabled | |
| if (getCookie("ahoy_visit")) { | |
| log("Visit started"); | |
| - | if (!visitorToken) { |
| - | visitorToken = generateId(); |
| - | setCookie("ahoy_visitor", visitorToken, visitorTtl); |
| + | if (!visitorId) { |
| + | visitorId = generateId(); |
| + | setCookie("ahoy_visitor", visitorId, visitorTtl); |
| } | |
| var data = { | |
| - | visit_token: visitToken, |
| - | visitor_token: visitorToken, |
| + | visit_token: visitId, |
| + | visitor_token: visitorId, |
| platform: ahoy.platform || "Web", | |
| landing_page: window.location.href, | |
| screen_width: window.screen.width, | |
| @@ | @@ -209,7 +214,8 @@ |
| ahoy.trackView = function () { | |
| var properties = { | |
| url: window.location.href, | |
| - | title: document.title |
| + | title: document.title, |
| + | page: page |
| }; | |
| ahoy.track("$view", properties); | |
| }; | |