class Ahoy::Tracker

Constants

UUID_NAMESPACE

Attributes

controller[R]
request[R]

Public Class Methods

new(**options) click to toggle source
# File lib/ahoy/tracker.rb, line 9
def initialize(**options)
  @store = Ahoy::Store.new(options.merge(ahoy: self))
  @controller = options[:controller]
  @request = options[:request] || @controller.try(:request)
  @visit_token = options[:visit_token]
  @user = options[:user]
  @options = options
end

Public Instance Methods

authenticate(user) click to toggle source
# File lib/ahoy/tracker.rb, line 76
def authenticate(user)
  if exclude?
    debug "Authentication excluded"
  else
    @store.user = user

    data = {
      visit_token: visit_token,
      user_id: user.try(:id)
    }
    @store.authenticate(data)
  end
  true
rescue => e
  report_exception(e)
end
exclude?() click to toggle source
# File lib/ahoy/tracker.rb, line 148
def exclude?
  unless defined?(@exclude)
    @exclude = @store.exclude?
  end
  @exclude
end
geocode(data) click to toggle source
# File lib/ahoy/tracker.rb, line 65
def geocode(data)
  data = {
    visit_token: visit_token
  }.merge(data).select { |_, v| v }

  @store.geocode(data)
  true
rescue => e
  report_exception(e)
end
new_visit?() click to toggle source
# File lib/ahoy/tracker.rb, line 101
def new_visit?
  Ahoy.cookies? ? !existing_visit_token : visit.nil?
end
new_visitor?() click to toggle source
# File lib/ahoy/tracker.rb, line 105
def new_visitor?
  !existing_visitor_token
end
reset() click to toggle source
# File lib/ahoy/tracker.rb, line 137
def reset
  reset_visit
  delete_cookie("ahoy_visitor")
end
reset_visit() click to toggle source
# File lib/ahoy/tracker.rb, line 142
def reset_visit
  delete_cookie("ahoy_visit")
  delete_cookie("ahoy_events")
  delete_cookie("ahoy_track")
end
track(name, properties = {}, options = {}) click to toggle source

can’t use keyword arguments here

# File lib/ahoy/tracker.rb, line 19
def track(name, properties = {}, options = {})
  if exclude?
    debug "Event excluded"
  else
    data = {
      visit_token: visit_token,
      user_id: user.try(:id),
      name: name.to_s,
      properties: properties,
      time: trusted_time(options[:time]),
      event_id: options[:id] || generate_id
    }.select { |_, v| v }

    @store.track_event(data)
  end
  true
rescue => e
  report_exception(e)
end
track_visit(defer: false, started_at: nil) click to toggle source
# File lib/ahoy/tracker.rb, line 39
def track_visit(defer: false, started_at: nil)
  if exclude?
    debug "Visit excluded"
  else
    if defer
      set_cookie("ahoy_track", true, nil, false)
    else
      delete_cookie("ahoy_track")

      data = {
        visit_token: visit_token,
        visitor_token: visitor_token,
        user_id: user.try(:id),
        started_at: trusted_time(started_at)
      }.merge(visit_properties).select { |_, v| v }

      @store.track_visit(data)

      Ahoy::GeocodeV2Job.perform_later(visit_token, data[:ip]) if Ahoy.geocode && data[:ip]
    end
  end
  true
rescue => e
  report_exception(e)
end
user() click to toggle source
# File lib/ahoy/tracker.rb, line 119
def user
  @user ||= @store.user
end
visit() click to toggle source
# File lib/ahoy/tracker.rb, line 93
def visit
  @visit ||= @store.visit
end
visit_id()
Alias for: visit_token
visit_or_create() click to toggle source
# File lib/ahoy/tracker.rb, line 97
def visit_or_create
  @visit ||= @store.visit_or_create
end
visit_properties() click to toggle source
# File lib/ahoy/tracker.rb, line 123
def visit_properties
  @visit_properties ||= request ? Ahoy::VisitProperties.new(request, api: api?).generate : {}
end
visit_token() click to toggle source
# File lib/ahoy/tracker.rb, line 127
def visit_token
  @visit_token ||= ensure_token(visit_token_helper)
end
Also aliased as: visit_id
visitor_id()
Alias for: visitor_token
visitor_token() click to toggle source
# File lib/ahoy/tracker.rb, line 132
def visitor_token
  @visitor_token ||= ensure_token(visitor_token_helper)
end
Also aliased as: visitor_id

Protected Instance Methods

api?() click to toggle source
# File lib/ahoy/tracker.rb, line 157
def api?
  @options[:api]
end
debug(message) click to toggle source
# File lib/ahoy/tracker.rb, line 276
def debug(message)
  Ahoy.log message
end
ensure_token(token) click to toggle source
# File lib/ahoy/tracker.rb, line 271
def ensure_token(token)
  token = Ahoy::Utils.ensure_utf8(token)
  token.to_s.gsub(/[^a-z0-9\-]/i, "").first(64) if token
end
existing_visit_token() click to toggle source
# File lib/ahoy/tracker.rb, line 225
def existing_visit_token
  @existing_visit_token ||= begin
    token = visit_header
    token ||= visit_cookie if Ahoy.cookies? && !(api? && Ahoy.protect_from_forgery)
    token ||= visit_param if api?
    token
  end
end
existing_visitor_token() click to toggle source
# File lib/ahoy/tracker.rb, line 234
def existing_visitor_token
  @existing_visitor_token ||= begin
    token = visitor_header
    token ||= visitor_cookie if Ahoy.cookies? && !(api? && Ahoy.protect_from_forgery)
    token ||= visitor_param if api?
    token
  end
end
generate_id() click to toggle source
# File lib/ahoy/tracker.rb, line 203
def generate_id
  @store.generate_id
end
missing_params?() click to toggle source

private, but used by API

# File lib/ahoy/tracker.rb, line 162
def missing_params?
  if Ahoy.cookies? && api? && Ahoy.protect_from_forgery
    !(existing_visit_token && existing_visitor_token)
  else
    false
  end
end
report_exception(e) click to toggle source
# File lib/ahoy/tracker.rb, line 194
def report_exception(e)
  if defined?(ActionDispatch::RemoteIp::IpSpoofAttackError) && e.is_a?(ActionDispatch::RemoteIp::IpSpoofAttackError)
    debug "Tracking excluded due to IP spoofing"
  else
    raise e if !defined?(Rails) || Rails.env.development? || Rails.env.test?
    Safely.report_exception(e)
  end
end
trusted_time(time = nil) click to toggle source
# File lib/ahoy/tracker.rb, line 186
def trusted_time(time = nil)
  if !time || (api? && !(1.minute.ago..Time.now).cover?(time))
    Time.current
  else
    time
  end
end
visit_header() click to toggle source
# File lib/ahoy/tracker.rb, line 255
def visit_header
  @visit_header ||= request && request.headers["Ahoy-Visit"]
end
visit_param() click to toggle source
# File lib/ahoy/tracker.rb, line 263
def visit_param
  @visit_param ||= request && request.params["visit_token"]
end
visit_token_helper() click to toggle source
# File lib/ahoy/tracker.rb, line 207
def visit_token_helper
  @visit_token_helper ||= begin
    token = existing_visit_token
    token ||= visit&.visit_token unless Ahoy.cookies?
    token ||= generate_id unless Ahoy.api_only
    token
  end
end
visitor_anonymity_set() click to toggle source
# File lib/ahoy/tracker.rb, line 243
def visitor_anonymity_set
  @visitor_anonymity_set ||= Digest::UUID.uuid_v5(UUID_NAMESPACE, ["visitor", Ahoy.mask_ip(request.remote_ip), request.user_agent].join("/"))
end
visitor_header() click to toggle source
# File lib/ahoy/tracker.rb, line 259
def visitor_header
  @visitor_header ||= request && request.headers["Ahoy-Visitor"]
end
visitor_param() click to toggle source
# File lib/ahoy/tracker.rb, line 267
def visitor_param
  @visitor_param ||= request && request.params["visitor_token"]
end
visitor_token_helper() click to toggle source
# File lib/ahoy/tracker.rb, line 216
def visitor_token_helper
  @visitor_token_helper ||= begin
    token = existing_visitor_token
    token ||= visitor_anonymity_set unless Ahoy.cookies?
    token ||= generate_id unless Ahoy.api_only
    token
  end
end