Skip to content

Commit

Permalink
feat(track): Introducing easier event tracking (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
rashidsp authored and aliabbasrizvi committed Jan 19, 2019
1 parent ce0cf47 commit 4c8b534
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 214 deletions.
50 changes: 6 additions & 44 deletions lib/optimizely.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

#
# Copyright 2016-2018, Optimizely and contributors
# Copyright 2016-2019, Optimizely and contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -201,24 +201,14 @@ def track(event_key, user_id, attributes = nil, event_tags = nil)

return nil unless user_inputs_valid?(attributes, event_tags)

experiment_ids = @config.get_experiment_ids_for_event(event_key)
if experiment_ids.empty?
@config.logger.log(Logger::INFO, "Not tracking user '#{user_id}'.")
event = @config.get_event_from_key(event_key)
unless event
@config.logger.log(Logger::INFO, "Not tracking user '#{user_id}' for event '#{event_key}'.")
return nil
end

# Filter out experiments that are not running or that do not include the user in audience conditions

experiment_variation_map = get_valid_experiments_for_event(event_key, user_id, attributes)

# Don't track events without valid experiments attached
if experiment_variation_map.empty?
@logger.log(Logger::INFO, "There are no valid experiments for event '#{event_key}' to track.")
return nil
end

conversion_event = @event_builder.create_conversion_event(event_key, user_id, attributes,
event_tags, experiment_variation_map)
conversion_event = @event_builder.create_conversion_event(event, user_id, attributes, event_tags)
@config.logger.log(Logger::INFO, "Tracking event '#{event_key}' for user '#{user_id}'.")
@logger.log(Logger::INFO,
"Dispatching conversion event to URL #{conversion_event.url} with params #{conversion_event.params}.")
begin
Expand Down Expand Up @@ -502,34 +492,6 @@ def get_feature_variable_for_type(feature_flag_key, variable_key, variable_type,
variable_value
end

def get_valid_experiments_for_event(event_key, user_id, attributes)
# Get the experiments that we should be tracking for the given event.
#
# event_key - Event key representing the event which needs to be recorded.
# user_id - String ID for user.
# attributes - Map of attributes of the user.
#
# Returns Map where each object contains the ID of the experiment to track and the ID of the variation the user
# is bucketed into.

valid_experiments = {}
experiment_ids = @config.get_experiment_ids_for_event(event_key)
experiment_ids.each do |experiment_id|
experiment_key = @config.get_experiment_key(experiment_id)
variation_key = get_variation(experiment_key, user_id, attributes)

if variation_key.nil?
@logger.log(Logger::INFO, "Not tracking user '#{user_id}' for experiment '#{experiment_key}'.")
next
end

variation_id = @config.get_variation_id_from_key(experiment_key, variation_key)
valid_experiments[experiment_id] = variation_id
end

valid_experiments
end

def user_inputs_valid?(attributes = nil, event_tags = nil)
# Helper method to validate user inputs.
#
Expand Down
30 changes: 9 additions & 21 deletions lib/optimizely/event_builder.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

#
# Copyright 2016-2018, Optimizely and contributors
# Copyright 2016-2019, Optimizely and contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -113,6 +113,7 @@ def get_common_params(user_id, attributes)
anonymize_ip: @config.anonymize_ip,
revision: @config.revision,
client_name: CLIENT_ENGINE,
enrich_decisions: true,
client_version: VERSION
}

Expand Down Expand Up @@ -142,19 +143,18 @@ def create_impression_event(experiment, variation_id, user_id, attributes)
Event.new(:post, ENDPOINT, event_params, POST_HEADERS)
end

def create_conversion_event(event_key, user_id, attributes, event_tags, experiment_variation_map)
def create_conversion_event(event, user_id, attributes, event_tags)
# Create conversion Event to be sent to the logging endpoint.
#
# event_key - +String+ Event key representing the event which needs to be recorded.
# event - +Object+ Event which needs to be recorded.
# user_id - +String+ ID for user.
# attributes - +Hash+ representing user attributes and values which need to be recorded.
# event_tags - +Hash+ representing metadata associated with the event.
# experiment_variation_map - +Map+ of experiment ID to the ID of the variation that the user is bucketed into.
#
# Returns +Event+ encapsulating the conversion event.

event_params = get_common_params(user_id, attributes)
conversion_params = get_conversion_params(event_key, event_tags, experiment_variation_map)
conversion_params = get_conversion_params(event, event_tags)
event_params[:visitors][0][:snapshots] = [conversion_params]

Event.new(:post, ENDPOINT, event_params, POST_HEADERS)
Expand Down Expand Up @@ -190,32 +190,20 @@ def get_impression_params(experiment, variation_id)
impression_event_params
end

def get_conversion_params(event_key, event_tags, experiment_variation_map)
def get_conversion_params(event, event_tags)
# Creates object of params specific to conversion events
#
# event_key - +String+ Key representing the event which needs to be recorded
# event - +Object+ Event which needs to be recorded.
# event_tags - +Hash+ Values associated with the event.
# experiment_variation_map - +Hash+ Map of experiment IDs to bucketed variation IDs
#
# Returns +Hash+ Conversion event params

single_snapshot = {}
single_snapshot[:decisions] = []
experiment_variation_map.each do |experiment_id, variation_id|
next unless variation_id

single_snapshot[:decisions].push(
campaign_id: @config.experiment_id_map[experiment_id]['layerId'],
experiment_id: experiment_id,
variation_id: variation_id
)
end

event_object = {
entity_id: @config.event_key_map[event_key]['id'],
entity_id: event['id'],
timestamp: create_timestamp,
uuid: create_uuid,
key: event_key
key: event['key']
}

if event_tags
Expand Down
12 changes: 6 additions & 6 deletions lib/optimizely/project_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -185,19 +185,19 @@ def get_experiment_key(experiment_id)
nil
end

def get_experiment_ids_for_event(event_key)
# Get experiment IDs for the provided event key.
def get_event_from_key(event_key)
# Get event for the provided event key.
#
# event_key - Event key for which experiment IDs are to be retrieved.
# event_key - Event key for which event is to be determined.
#
# Returns array of all experiment IDs for the event.
# Returns Event corresponding to the provided event key.

event = @event_key_map[event_key]
return event['experimentIds'] if event
return event if event

@logger.log Logger::ERROR, "Event '#{event_key}' is not in datafile."
@error_handler.handle_error InvalidEventError
[]
nil
end

def get_audience_from_id(audience_id)
Expand Down
Loading

0 comments on commit 4c8b534

Please sign in to comment.