lib/staccato/v4/tracker.rb
module Staccato::V4
# The `Tracker` class has methods to create all `Hit` types
# using the tracker and client id
#
# @author Tony Pitale
class Tracker
attr_accessor :events
attr_reader :measurement_id, :api_secret
# sets up a new tracker
# @param measurement_id [String] the measurement id from GA
# @param api_secret [String] the required api secret key
# @param client_id [String, nil] unique value to track user sessions
# @param options [Hash]
def initialize(measurement_id, api_secret, client_id = nil, options = {})
@measurement_id = measurement_id
@api_secret = api_secret
@client_id = client_id
@adapters = []
self.events = []
end
def adapter=(adapter)
@adapters = [adapter]
end
def add_adapter(adapter)
@adapters << adapter
end
# The unique client id
# @return [String]
def client_id
@client_id ||= Staccato.build_client_id
end
# Add an Event instance to the events to be sent
def add(event_klass, options)
# TODO raise if events reach batch size?
events << event_klass.new(self, options)
end
# dynamically define methods for events
Staccato::V4::Event.events.each do |event_name, event_klass|
define_method event_name do |options|
add(event_klass, options)
end
end
# post the hit to GA collection endpoint
# @return [Net::HTTPOK] the GA api always returns 200 OK
def track
post
end
def validate!
Staccato::V4.validation_adapter.new(
default_adapter,
validation_uri
).post_with_body(params, body)
end
def default_uri
Staccato::V4.ga_collection_uri
end
def validation_uri
Staccato::V4.validation_uri
end
private
# @private
def params
{
measurement_id: @measurement_id,
api_secret: @api_secret
}
end
# @private
def body
Staccato::V4.encode_body(client_id, events.map {|event| event.as_json})
end
# @private
def single_adapter?
adapters.length == 1
end
# @private
def post
single_adapter? ? post_first : post_all
end
# @private
def post_first
adapters.first.post_with_body(params, body)
end
# @private
def post_all
adapters.map {|adapter| adapter.post_with_body(params, body)}
end
# @private
def adapters
@adapters.empty? ? [default_adapter] : @adapters
end
# @private
def default_adapter
@default_adapter ||= Staccato.default_adapter.new(default_uri)
end
end
# A tracker which does no tracking
# Useful in testing
class NoopTracker
attr_accessor :hit_defaults
# (see Tracker#initialize)
def initialize(measurement_id = nil, client_id = nil, options = {})
self.events = []
end
def adapter=(*)
[]
end
def add_adapter(*)
[]
end
# (see Tracker#id)
def measurement_id
nil
end
# (see Tracker#client_id)
def client_id
nil
end
# (see Tracker#track)
def track(events)
end
def default_uri
Staccato::V4.ga_collection_uri
end
end
end