Skip to content

Commit 6b295d1

Browse files
authored
Release v1.1.0
Introduce support for event tags. Add optional eventTags argument to track method signature. Deprecating optional eventValue argument in track method signature.
2 parents 669580c + 3d6ac65 commit 6b295d1

File tree

10 files changed

+477
-41
lines changed

10 files changed

+477
-41
lines changed

CHANGELOG

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
-------------------------------------------------------------------------------
2+
1.1.0
3+
* Introduce support for event tags.
4+
* Add optional eventTags argument to track method signature.
5+
* Deprecating optional eventValue argument in track method signature.
6+
-------------------------------------------------------------------------------
7+
18
-------------------------------------------------------------------------------
29
1.0.2
310
* Change HTTParty version requirement to ~> 0.11, allowing HTTParty v0.14 (thanks @gaganawhad!)

lib/optimizely.rb

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,21 +162,29 @@ def get_variation(experiment_key, user_id, attributes = nil)
162162
@config.get_variation_key_from_id(experiment_key, variation_id)
163163
end
164164

165-
def track(event_key, user_id, attributes = nil, event_value = nil)
165+
def track(event_key, user_id, attributes = nil, event_tags = nil)
166166
# Send conversion event to Optimizely.
167167
#
168168
# event_key - Goal key representing the event which needs to be recorded.
169169
# user_id - String ID for user.
170170
# attributes - Hash representing visitor attributes and values which need to be recorded.
171-
# event_value - Value associated with the event. Can be used to represent revenue in cents.
171+
# event_tags - Hash representing metadata associated with the event.
172172

173173
unless @is_valid
174174
logger = SimpleLogger.new
175175
logger.log(Logger::ERROR, InvalidDatafileError.new('track').message)
176176
return nil
177177
end
178178

179+
if event_tags and event_tags.is_a? Numeric
180+
event_tags = {
181+
'revenue' => event_tags
182+
}
183+
@logger.log(Logger::WARN, 'Event value is deprecated in track call. Use event tags to pass in revenue value instead.')
184+
end
185+
179186
return nil if attributes && !attributes_valid?(attributes)
187+
return nil if event_tags && !event_tags_valid?(event_tags)
180188

181189
experiment_ids = @config.get_experiment_ids_for_goal(event_key)
182190
if experiment_ids.empty?
@@ -202,7 +210,7 @@ def track(event_key, user_id, attributes = nil, event_value = nil)
202210
end
203211

204212
conversion_event = @event_builder.create_conversion_event(event_key, user_id, attributes,
205-
event_value, valid_experiment_keys)
213+
event_tags, valid_experiment_keys)
206214
@logger.log(Logger::INFO,
207215
'Dispatching conversion event to URL %s with params %s.' % [conversion_event.url,
208216
conversion_event.params])
@@ -251,6 +259,15 @@ def attributes_valid?(attributes)
251259
true
252260
end
253261

262+
def event_tags_valid?(event_tags)
263+
unless Helpers::Validator.event_tags_valid?(event_tags)
264+
@logger.log(Logger::ERROR, 'Provided event tags are in an invalid format.')
265+
@error_handler.handle_error(InvalidEventTagFormatError)
266+
return false
267+
end
268+
true
269+
end
270+
254271
def validate_inputs(datafile, skip_json_validation)
255272
unless skip_json_validation
256273
raise InvalidInputError.new('datafile') unless Helpers::Validator.datafile_valid?(datafile)

lib/optimizely/event_builder.rb

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
require_relative './audience'
1717
require_relative './params'
1818
require_relative './version'
19+
require_relative '../optimizely/helpers/event_tag_utils'
1920

2021
module Optimizely
2122
class Event
@@ -89,20 +90,21 @@ def create_impression_event(experiment_key, variation_id, user_id, attributes)
8990
Event.new(:post, IMPRESSION_EVENT_ENDPOINT, @params, POST_HEADERS)
9091
end
9192

92-
def create_conversion_event(event_key, user_id, attributes, event_value, experiment_keys)
93+
def create_conversion_event(event_key, user_id, attributes, event_tags, experiment_keys)
9394
# Create conversion Event to be sent to the logging endpoint.
9495
#
9596
# event_key - Event key representing the event which needs to be recorded.
9697
# user_id - ID for user.
9798
# attributes - Hash representing user attributes and values which need to be recorded.
98-
# event_value - Value associated with the event. Can be used to represent revenue in cents.
99+
# event_tags - Hash representing metadata associated with the event.
99100
# experiment_keys - Array of valid experiment keys for the event
100101
#
101102
# Returns event hash encapsulating the conversion event.
102103

103104
@params = {}
104105
add_common_params(user_id, attributes)
105-
add_conversion_event(event_key, event_value)
106+
add_conversion_event(event_key)
107+
add_event_tags(event_tags)
106108
add_layer_states(user_id, experiment_keys)
107109
Event.new(:post, CONVERSION_EVENT_ENDPOINT, @params, POST_HEADERS)
108110
end
@@ -161,26 +163,47 @@ def add_decision(experiment_key, variation_id)
161163
}
162164
end
163165

164-
def add_conversion_event(event_key, event_value)
166+
def add_event_tags(event_tags)
167+
@params['eventFeatures'] ||= []
168+
@params['eventMetrics'] ||= []
169+
170+
return if event_tags.nil?
171+
172+
event_tags.each_pair do |event_tag_key, event_tag_value|
173+
next if event_tag_value.nil?
174+
175+
event_feature = {
176+
'id' => event_tag_key,
177+
'type' => 'custom',
178+
'value' => event_tag_value,
179+
'shouldIndex' => false,
180+
}
181+
@params['eventFeatures'].push(event_feature)
182+
183+
end
184+
185+
event_value = Helpers::EventTagUtils.get_revenue_value(event_tags)
186+
187+
if event_value
188+
event_metric = {
189+
'name' => 'revenue',
190+
'value' => event_value
191+
}
192+
@params['eventMetrics'].push(event_metric)
193+
end
194+
195+
end
196+
197+
def add_conversion_event(event_key)
165198
# Add conversion event information to the event.
166199
#
167200
# event_key - Event key representing the event which needs to be recorded.
168-
# event_value - Value associated with the event. Can be used to represent revenue in cents.
169201

170202
event_id = @config.event_key_map[event_key]['id']
171203
event_name = @config.event_key_map[event_key]['key']
172204

173205
@params['eventEntityId'] = event_id
174-
@params['eventFeatures'] = []
175206
@params['eventName'] = event_name
176-
@params['eventMetrics'] = []
177-
178-
if event_value
179-
@params['eventMetrics'].push({
180-
'name' => 'revenue',
181-
'value' => event_value,
182-
})
183-
end
184207
end
185208

186209
def add_layer_states(user_id, experiment_keys)
@@ -241,18 +264,21 @@ def create_impression_event(experiment_key, variation_id, user_id, attributes)
241264
Event.new(:get, sprintf(OFFLINE_API_PATH, project_id: @params[Params::PROJECT_ID]), @params, {})
242265
end
243266

244-
def create_conversion_event(event_key, user_id, attributes, event_value, experiment_keys)
267+
def create_conversion_event(event_key, user_id, attributes, event_tags, experiment_keys)
245268
# Create conversion Event to be sent to the logging endpoint.
246269
#
247270
# event_key - Goal key representing the event which needs to be recorded.
248271
# user_id - ID for user.
249272
# attributes - Hash representing user attributes and values which need to be recorded.
250-
# event_value - Value associated with the event. Can be used to represent revenue in cents.
273+
# event_tags - Hash representing metadata associated with the event.
251274
# experiment_keys - Array of valid experiment keys for the goal
252275
#
253276
# Returns event hash encapsulating the conversion event.
254277

255278
@params = {}
279+
280+
event_value = Helpers::EventTagUtils.get_revenue_value(event_tags)
281+
256282
add_common_params(user_id, attributes)
257283
add_conversion_goal(event_key, event_value)
258284
add_experiment_variation_params(user_id, experiment_keys)

lib/optimizely/exceptions.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ def initialize(msg = 'Attributes provided are in an invalid format.')
4040
end
4141
end
4242

43+
class InvalidEventTagFormatError < Error
44+
# Raised when attributes are provided in an invalid format (e.g. not a Hash)
45+
46+
def initialize(msg = 'Event tags provided are in an invalid format.')
47+
super
48+
end
49+
end
50+
4351
class InvalidExperimentError < Error
4452
# Raised when an invalid experiment key is provided
4553

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#
2+
# Copyright 2017, Optimizely and contributors
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
require 'optimizely/logger'
17+
require 'optimizely/helpers/validator'
18+
19+
module Optimizely
20+
module Helpers
21+
module EventTagUtils
22+
module_function
23+
24+
def get_revenue_value(event_tags)
25+
# Grab the revenue value from the event tags. "revenue" is a reserved keyword.
26+
#
27+
# event_tags - Hash representing metadata associated with the event.
28+
# Returns revenue value as an integer number
29+
# Returns nil if revenue can't be retrieved from the event tags.
30+
31+
if event_tags.nil? or !Helpers::Validator.attributes_valid?(event_tags)
32+
return nil
33+
end
34+
35+
unless event_tags.has_key?('revenue')
36+
return nil
37+
end
38+
39+
logger = SimpleLogger.new
40+
raw_value = event_tags['revenue']
41+
42+
unless raw_value.is_a? Numeric
43+
logger.log(Logger::WARN, "Failed to parse revenue value #{raw_value} from event tags.")
44+
return nil
45+
end
46+
47+
if raw_value.is_a? Float
48+
logger.log(Logger::WARN, "Failed to parse revenue value #{raw_value} from event tags.")
49+
return nil
50+
end
51+
52+
logger.log(Logger::INFO, "Parsed revenue value #{raw_value} from event tags.")
53+
raw_value
54+
end
55+
end
56+
end
57+
end

lib/optimizely/helpers/validator.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ def attributes_valid?(attributes)
3232
attributes.is_a?(Hash)
3333
end
3434

35+
def event_tags_valid?(event_tags)
36+
# Determines if provided event tags are valid.
37+
#
38+
# event_tags - Event tags to be validated.
39+
#
40+
# Returns boolean depending on validity of event tags.
41+
42+
event_tags.is_a?(Hash)
43+
end
44+
3545
def datafile_valid?(datafile)
3646
# Determines if a given datafile is valid.
3747
#

lib/optimizely/version.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright 2016, Optimizely and contributors
2+
# Copyright 2016-2017, Optimizely and contributors
33
#
44
# Licensed under the Apache License, Version 2.0 (the "License");
55
# you may not use this file except in compliance with the License.
@@ -14,5 +14,5 @@
1414
# limitations under the License.
1515
#
1616
module Optimizely
17-
VERSION = '1.0.2'.freeze
17+
VERSION = '1.1.0'.freeze
1818
end

0 commit comments

Comments
 (0)