class Land::Tracker

Constants

ATTRIBUTION_KEYS
KEYS

Compact the session by shortening names

TRACKED_PARAMS
TRACKING_KEYS
TRACKING_PARAMS

@todo Cake: SUB ID => s1, s2, s3, s4, s5? www.affluent.io/blog/affiliate-sub-campaign-sid-tracking-guide/

strackr.com/subid

TRACKING_PARAMS_TRANSFORM
UUID_REGEX
UUID_REGEX_V4

Attributes

controller[R]
events[R]
status[RW]
visit[R]

Public Class Methods

for(controller) click to toggle source
# File lib/land/tracker.rb, line 102
def for(controller)
  type = Land::UserAgent[controller.request.user_agent].try(:user_agent_type)
  type = 'noop' unless Land.config.enabled
  type = 'user' if type.nil?

  # override
  type = 'user' if controller.request.query_parameters.with_indifferent_access.slice(*TRACKING_KEYS).any?

  "Land::Trackers::#{type.classify}Tracker".constantize.new(controller)
end
new(controller) click to toggle source
# File lib/land/tracker.rb, line 114
def initialize(controller)
  # Allow subclasses to super from initialize
  fail NotImplementedError, "You must subclass Land::Tracker" if self.class == Tracker
  @controller = controller
  @events     = []
  @start_time = Time.now
  @status     = nil
end

Public Instance Methods

create_event(type, meta = {}) click to toggle source
# File lib/land/tracker.rb, line 123
def create_event(type, meta = {})
  return unless tracking?

  Event.new(visit_id: @visit_id, event_type: type, meta: meta).tap do |event|
    @events << event
  end
end
track() click to toggle source
# File lib/land/tracker.rb, line 131
def track
  fail NotImplementedError, "You must subclass Land::Tracker" if self.class == Tracker
end

Protected Instance Methods

attribution() click to toggle source
# File lib/land/tracker.rb, line 190
def attribution
  @attribution ||= Attribution.lookup attribution_params
end
attribution?() click to toggle source
# File lib/land/tracker.rb, line 223
def attribution?
  attribution_params.any?
end
attribution_changed?() click to toggle source
# File lib/land/tracker.rb, line 194
def attribution_changed?
  attribution? && attribution_hash != @attribution_hash
end
attribution_hash() click to toggle source
# File lib/land/tracker.rb, line 198
def attribution_hash
  Attribution.digest attribution_params
end
attribution_params() click to toggle source
# File lib/land/tracker.rb, line 268
def attribution_params
  @attribution_params ||= tracking_params.with_indifferent_access.slice(*ATTRIBUTION_KEYS)
end
cookies() click to toggle source
# File lib/land/tracker.rb, line 137
def cookies
  request.cookie_jar
end
create_visit() click to toggle source
# File lib/land/tracker.rb, line 231
def create_visit
  @visit = Visit.new
  visit.attribution   = attribution
  visit.cookie_id     = @cookie_id
  visit.referer_id    = referer.try(:id)
  visit.user_agent_id = user_agent.id
  visit.ip_address    = remote_ip
  visit.save!

  @visit_id = @visit.id
end
external_referer?() click to toggle source
# File lib/land/tracker.rb, line 247
def external_referer?
  referer_uri && referer_uri.host != request.host
end
extract_tracking(params) click to toggle source
# File lib/land/tracker.rb, line 251
def extract_tracking(params)
  hash = {}

  TRACKING_PARAMS.each do |key, names|
    param = names.find { |name| params.key?(name) }
    next unless param
    hash[key] = params[param]
  end

  TRACKING_PARAMS_TRANSFORM.each do |key, transform|
    next unless hash.key? key
    hash[key] = transform[hash[key]] if transform.key? hash[key]
  end

  hash
end
new_visit?() click to toggle source
# File lib/land/tracker.rb, line 243
def new_visit?
  @visit_id.nil? || referer_changed? || attribution_changed? || user_agent_changed? || visit_stale?
end
query_params() click to toggle source
# File lib/land/tracker.rb, line 272
def query_params
  @query_params ||= request.query_parameters.with_indifferent_access
end
record_visit() click to toggle source
# File lib/land/tracker.rb, line 227
def record_visit
  create_visit if new_visit?
end
referer() click to toggle source
# File lib/land/tracker.rb, line 164
def referer
  return @referer if @referer
  return unless referer_uri

  params      = Rack::Utils.parse_query referer_uri.query
  attribution = Attribution.lookup params.slice(*ATTRIBUTION_KEYS)
  query       = params.except(*ATTRIBUTION_KEYS)

  begin
    @referer = Referer.where(domain_id:       Domain[referer_uri.host],
                             path_id:         Path[referer_uri.path],
                             query_string_id: QueryString[query.to_query],
                             attribution_id:  attribution.id).first_or_create
  rescue ActiveRecord::RecordNotUnique
    retry
  end
end
referer_changed?() click to toggle source
# File lib/land/tracker.rb, line 182
def referer_changed?
  external_referer? && referer_hash != @referer_hash
end
referer_hash() click to toggle source
# File lib/land/tracker.rb, line 219
def referer_hash
  Digest::SHA2.base64digest request.referer
end
referer_uri() click to toggle source
# File lib/land/tracker.rb, line 186
def referer_uri
  @referer_uri ||= URI(URI.encode(request.referer)) if request.referer
end
tracking?() click to toggle source
# File lib/land/tracker.rb, line 276
def tracking?
  !!@visit_id
end
tracking_params() click to toggle source
# File lib/land/tracker.rb, line 280
def tracking_params
  @tracking_params ||= extract_tracking(query_params)
end
untracked_params() click to toggle source
# File lib/land/tracker.rb, line 284
def untracked_params
  query_params.except(*TRACKED_PARAMS)
end
user_agent() click to toggle source
# File lib/land/tracker.rb, line 202
def user_agent
  return @user_agent if @user_agent

  user_agent = request.user_agent
  user_agent = Land.config.blank_user_agent_string if user_agent.blank?

  @user_agent = UserAgent[user_agent]
end
user_agent_changed?() click to toggle source
# File lib/land/tracker.rb, line 215
def user_agent_changed?
  user_agent_hash != @user_agent_hash
end
user_agent_hash() click to toggle source
# File lib/land/tracker.rb, line 211
def user_agent_hash
  Digest::SHA2.base64digest user_agent.user_agent
end
visit_stale?() click to toggle source
# File lib/land/tracker.rb, line 288
def visit_stale?
  return false unless @last_visit_time
  Time.current - @last_visit_time > Land.config.visit_timeout
end