optimizely-sdk 3.9.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +202 -202
  3. data/lib/optimizely/audience.rb +127 -97
  4. data/lib/optimizely/bucketer.rb +156 -156
  5. data/lib/optimizely/condition_tree_evaluator.rb +123 -123
  6. data/lib/optimizely/config/datafile_project_config.rb +539 -508
  7. data/lib/optimizely/config/proxy_config.rb +34 -34
  8. data/lib/optimizely/config_manager/async_scheduler.rb +95 -95
  9. data/lib/optimizely/config_manager/http_project_config_manager.rb +330 -321
  10. data/lib/optimizely/config_manager/project_config_manager.rb +24 -24
  11. data/lib/optimizely/config_manager/static_project_config_manager.rb +53 -47
  12. data/lib/optimizely/decide/optimizely_decide_option.rb +28 -28
  13. data/lib/optimizely/decide/optimizely_decision.rb +60 -60
  14. data/lib/optimizely/decide/optimizely_decision_message.rb +26 -26
  15. data/lib/optimizely/decision_service.rb +563 -500
  16. data/lib/optimizely/error_handler.rb +39 -39
  17. data/lib/optimizely/event/batch_event_processor.rb +235 -234
  18. data/lib/optimizely/event/entity/conversion_event.rb +44 -43
  19. data/lib/optimizely/event/entity/decision.rb +38 -38
  20. data/lib/optimizely/event/entity/event_batch.rb +86 -86
  21. data/lib/optimizely/event/entity/event_context.rb +50 -50
  22. data/lib/optimizely/event/entity/impression_event.rb +48 -47
  23. data/lib/optimizely/event/entity/snapshot.rb +33 -33
  24. data/lib/optimizely/event/entity/snapshot_event.rb +48 -48
  25. data/lib/optimizely/event/entity/user_event.rb +22 -22
  26. data/lib/optimizely/event/entity/visitor.rb +36 -35
  27. data/lib/optimizely/event/entity/visitor_attribute.rb +38 -37
  28. data/lib/optimizely/event/event_factory.rb +156 -155
  29. data/lib/optimizely/event/event_processor.rb +25 -25
  30. data/lib/optimizely/event/forwarding_event_processor.rb +44 -43
  31. data/lib/optimizely/event/user_event_factory.rb +88 -88
  32. data/lib/optimizely/event_builder.rb +221 -228
  33. data/lib/optimizely/event_dispatcher.rb +71 -71
  34. data/lib/optimizely/exceptions.rb +135 -139
  35. data/lib/optimizely/helpers/constants.rb +415 -397
  36. data/lib/optimizely/helpers/date_time_utils.rb +30 -30
  37. data/lib/optimizely/helpers/event_tag_utils.rb +132 -132
  38. data/lib/optimizely/helpers/group.rb +31 -31
  39. data/lib/optimizely/helpers/http_utils.rb +65 -64
  40. data/lib/optimizely/helpers/validator.rb +183 -183
  41. data/lib/optimizely/helpers/variable_type.rb +67 -67
  42. data/lib/optimizely/logger.rb +46 -45
  43. data/lib/optimizely/notification_center.rb +174 -176
  44. data/lib/optimizely/optimizely_config.rb +271 -272
  45. data/lib/optimizely/optimizely_factory.rb +181 -181
  46. data/lib/optimizely/optimizely_user_context.rb +204 -107
  47. data/lib/optimizely/params.rb +31 -31
  48. data/lib/optimizely/project_config.rb +99 -91
  49. data/lib/optimizely/semantic_version.rb +166 -166
  50. data/lib/optimizely/{custom_attribute_condition_evaluator.rb → user_condition_evaluator.rb} +391 -369
  51. data/lib/optimizely/user_profile_service.rb +35 -35
  52. data/lib/optimizely/version.rb +21 -21
  53. data/lib/optimizely.rb +1130 -1117
  54. metadata +13 -13
@@ -1,88 +1,88 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # Copyright 2019-2020, Optimizely and contributors
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- require_relative 'entity/conversion_event'
19
- require_relative 'entity/impression_event'
20
- require_relative 'entity/event_context'
21
- require_relative 'event_factory'
22
- module Optimizely
23
- class UserEventFactory
24
- # UserEventFactory builds ImpressionEvent and ConversionEvent objects from a given user_event.
25
- def self.create_impression_event(project_config, experiment, variation_id, metadata, user_id, user_attributes)
26
- # Create impression Event to be sent to the logging endpoint.
27
- #
28
- # project_config - Instance of ProjectConfig
29
- # experiment - Instance Experiment for which impression needs to be recorded.
30
- # variation_id - String ID for variation which would be presented to user.
31
- # user_id - String ID for user.
32
- # attributes - Hash Representing user attributes and values which need to be recorded.
33
- #
34
- # Returns Event encapsulating the impression event.
35
- event_context = Optimizely::EventContext.new(
36
- account_id: project_config.account_id,
37
- project_id: project_config.project_id,
38
- anonymize_ip: project_config.anonymize_ip,
39
- revision: project_config.revision,
40
- client_name: CLIENT_ENGINE,
41
- client_version: VERSION
42
- ).as_json
43
-
44
- visitor_attributes = Optimizely::EventFactory.build_attribute_list(user_attributes, project_config)
45
- experiment_layer_id = experiment['layerId']
46
- Optimizely::ImpressionEvent.new(
47
- event_context: event_context,
48
- user_id: user_id,
49
- experiment_layer_id: experiment_layer_id,
50
- experiment_id: experiment['id'],
51
- variation_id: variation_id,
52
- metadata: metadata,
53
- visitor_attributes: visitor_attributes,
54
- bot_filtering: project_config.bot_filtering
55
- )
56
- end
57
-
58
- def self.create_conversion_event(project_config, event, user_id, user_attributes, event_tags)
59
- # Create conversion Event to be sent to the logging endpoint.
60
- #
61
- # project_config - Instance of ProjectConfig
62
- # event - Event which needs to be recorded.
63
- # user_id - String ID for user.
64
- # attributes - Hash Representing user attributes and values which need to be recorded.
65
- # event_tags - Hash representing metadata associated with the event.
66
- #
67
- # Returns Event encapsulating the conversion event.
68
-
69
- event_context = Optimizely::EventContext.new(
70
- account_id: project_config.account_id,
71
- project_id: project_config.project_id,
72
- anonymize_ip: project_config.anonymize_ip,
73
- revision: project_config.revision,
74
- client_name: CLIENT_ENGINE,
75
- client_version: VERSION
76
- ).as_json
77
-
78
- Optimizely::ConversionEvent.new(
79
- event_context: event_context,
80
- event: event,
81
- user_id: user_id,
82
- visitor_attributes: Optimizely::EventFactory.build_attribute_list(user_attributes, project_config),
83
- tags: event_tags,
84
- bot_filtering: project_config.bot_filtering
85
- )
86
- end
87
- end
88
- end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright 2019-2020, Optimizely and contributors
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ require_relative 'entity/conversion_event'
19
+ require_relative 'entity/impression_event'
20
+ require_relative 'entity/event_context'
21
+ require_relative 'event_factory'
22
+ module Optimizely
23
+ class UserEventFactory
24
+ # UserEventFactory builds ImpressionEvent and ConversionEvent objects from a given user_event.
25
+ def self.create_impression_event(project_config, experiment, variation_id, metadata, user_id, user_attributes)
26
+ # Create impression Event to be sent to the logging endpoint.
27
+ #
28
+ # project_config - Instance of ProjectConfig
29
+ # experiment - Instance Experiment for which impression needs to be recorded.
30
+ # variation_id - String ID for variation which would be presented to user.
31
+ # user_id - String ID for user.
32
+ # attributes - Hash Representing user attributes and values which need to be recorded.
33
+ #
34
+ # Returns Event encapsulating the impression event.
35
+ event_context = Optimizely::EventContext.new(
36
+ account_id: project_config.account_id,
37
+ project_id: project_config.project_id,
38
+ anonymize_ip: project_config.anonymize_ip,
39
+ revision: project_config.revision,
40
+ client_name: CLIENT_ENGINE,
41
+ client_version: VERSION
42
+ ).as_json
43
+
44
+ visitor_attributes = Optimizely::EventFactory.build_attribute_list(user_attributes, project_config)
45
+ experiment_layer_id = experiment['layerId']
46
+ Optimizely::ImpressionEvent.new(
47
+ event_context: event_context,
48
+ user_id: user_id,
49
+ experiment_layer_id: experiment_layer_id,
50
+ experiment_id: experiment['id'],
51
+ variation_id: variation_id,
52
+ metadata: metadata,
53
+ visitor_attributes: visitor_attributes,
54
+ bot_filtering: project_config.bot_filtering
55
+ )
56
+ end
57
+
58
+ def self.create_conversion_event(project_config, event, user_id, user_attributes, event_tags)
59
+ # Create conversion Event to be sent to the logging endpoint.
60
+ #
61
+ # project_config - Instance of ProjectConfig
62
+ # event - Event which needs to be recorded.
63
+ # user_id - String ID for user.
64
+ # attributes - Hash Representing user attributes and values which need to be recorded.
65
+ # event_tags - Hash representing metadata associated with the event.
66
+ #
67
+ # Returns Event encapsulating the conversion event.
68
+
69
+ event_context = Optimizely::EventContext.new(
70
+ account_id: project_config.account_id,
71
+ project_id: project_config.project_id,
72
+ anonymize_ip: project_config.anonymize_ip,
73
+ revision: project_config.revision,
74
+ client_name: CLIENT_ENGINE,
75
+ client_version: VERSION
76
+ ).as_json
77
+
78
+ Optimizely::ConversionEvent.new(
79
+ event_context: event_context,
80
+ event: event,
81
+ user_id: user_id,
82
+ visitor_attributes: Optimizely::EventFactory.build_attribute_list(user_attributes, project_config),
83
+ tags: event_tags,
84
+ bot_filtering: project_config.bot_filtering
85
+ )
86
+ end
87
+ end
88
+ end
@@ -1,228 +1,221 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # Copyright 2016-2019, Optimizely and contributors
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- require_relative 'audience'
19
- require_relative 'helpers/constants'
20
- require_relative 'helpers/event_tag_utils'
21
- require_relative 'params'
22
- require_relative 'version'
23
-
24
- require 'securerandom'
25
-
26
- module Optimizely
27
- class Event
28
- # Representation of an event which can be sent to the Optimizely logging endpoint.
29
-
30
- attr_reader :http_verb
31
- attr_reader :params
32
- attr_reader :url
33
- attr_reader :headers
34
-
35
- def initialize(http_verb, url, params, headers)
36
- @http_verb = http_verb
37
- @url = url
38
- @params = params
39
- @headers = headers
40
- end
41
-
42
- # Override equality operator to make two events with the same contents equal for testing purposes
43
- def ==(other)
44
- @http_verb == other.http_verb && @url == other.url && @params == other.params && @headers == other.headers
45
- end
46
- end
47
-
48
- class BaseEventBuilder
49
- CUSTOM_ATTRIBUTE_FEATURE_TYPE = 'custom'
50
-
51
- def initialize(logger)
52
- @logger = logger
53
- end
54
-
55
- private
56
-
57
- def get_common_params(project_config, user_id, attributes)
58
- # Get params which are used in both conversion and impression events.
59
- #
60
- # project_config - +Object+ Instance of ProjectConfig
61
- # user_id - +String+ ID for user
62
- # attributes - +Hash+ representing user attributes and values which need to be recorded.
63
- #
64
- # Returns +Hash+ Common event params
65
-
66
- visitor_attributes = []
67
-
68
- attributes&.keys&.each do |attribute_key|
69
- # Omit attribute values that are not supported by the log endpoint.
70
- attribute_value = attributes[attribute_key]
71
- if Helpers::Validator.attribute_valid?(attribute_key, attribute_value)
72
- attribute_id = project_config.get_attribute_id attribute_key
73
- if attribute_id
74
- visitor_attributes.push(
75
- entity_id: attribute_id,
76
- key: attribute_key,
77
- type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
78
- value: attribute_value
79
- )
80
- end
81
- end
82
- end
83
- # Append Bot Filtering Attribute
84
- if project_config.bot_filtering == true || project_config.bot_filtering == false
85
- visitor_attributes.push(
86
- entity_id: Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BOT_FILTERING'],
87
- key: Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BOT_FILTERING'],
88
- type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
89
- value: project_config.bot_filtering
90
- )
91
- end
92
-
93
- common_params = {
94
- account_id: project_config.account_id,
95
- project_id: project_config.project_id,
96
- visitors: [
97
- {
98
- attributes: visitor_attributes,
99
- snapshots: [],
100
- visitor_id: user_id
101
- }
102
- ],
103
- anonymize_ip: project_config.anonymize_ip,
104
- revision: project_config.revision,
105
- client_name: CLIENT_ENGINE,
106
- enrich_decisions: true,
107
- client_version: VERSION
108
- }
109
-
110
- common_params
111
- end
112
- end
113
-
114
- class EventBuilder < BaseEventBuilder
115
- ENDPOINT = 'https://logx.optimizely.com/v1/events'
116
- POST_HEADERS = {'Content-Type' => 'application/json'}.freeze
117
- ACTIVATE_EVENT_KEY = 'campaign_activated'
118
-
119
- def create_impression_event(project_config, experiment, variation_id, user_id, attributes)
120
- # Create impression Event to be sent to the logging endpoint.
121
- #
122
- # project_config - +Object+ Instance of ProjectConfig
123
- # experiment - +Object+ Experiment for which impression needs to be recorded.
124
- # variation_id - +String+ ID for variation which would be presented to user.
125
- # user_id - +String+ ID for user.
126
- # attributes - +Hash+ representing user attributes and values which need to be recorded.
127
- #
128
- # Returns +Event+ encapsulating the impression event.
129
-
130
- event_params = get_common_params(project_config, user_id, attributes)
131
- impression_params = get_impression_params(project_config, experiment, variation_id)
132
- event_params[:visitors][0][:snapshots].push(impression_params)
133
-
134
- Event.new(:post, ENDPOINT, event_params, POST_HEADERS)
135
- end
136
-
137
- def create_conversion_event(project_config, event, user_id, attributes, event_tags)
138
- # Create conversion Event to be sent to the logging endpoint.
139
- #
140
- # project_config - +Object+ Instance of ProjectConfig
141
- # event - +Object+ Event which needs to be recorded.
142
- # user_id - +String+ ID for user.
143
- # attributes - +Hash+ representing user attributes and values which need to be recorded.
144
- # event_tags - +Hash+ representing metadata associated with the event.
145
- #
146
- # Returns +Event+ encapsulating the conversion event.
147
-
148
- event_params = get_common_params(project_config, user_id, attributes)
149
- conversion_params = get_conversion_params(event, event_tags)
150
- event_params[:visitors][0][:snapshots] = [conversion_params]
151
-
152
- Event.new(:post, ENDPOINT, event_params, POST_HEADERS)
153
- end
154
-
155
- private
156
-
157
- def get_impression_params(project_config, experiment, variation_id)
158
- # Creates object of params specific to impression events
159
- #
160
- # project_config - +Object+ Instance of ProjectConfig
161
- # experiment - +Hash+ experiment for which impression needs to be recorded
162
- # variation_id - +string+ ID for variation which would be presented to user
163
- #
164
- # Returns +Hash+ Impression event params
165
-
166
- experiment_key = experiment['key']
167
- experiment_id = experiment['id']
168
-
169
- impression_event_params = {
170
- decisions: [{
171
- campaign_id: project_config.experiment_key_map[experiment_key]['layerId'],
172
- experiment_id: experiment_id,
173
- variation_id: variation_id
174
- }],
175
- events: [{
176
- entity_id: project_config.experiment_key_map[experiment_key]['layerId'],
177
- timestamp: create_timestamp,
178
- key: ACTIVATE_EVENT_KEY,
179
- uuid: create_uuid
180
- }]
181
- }
182
-
183
- impression_event_params
184
- end
185
-
186
- def get_conversion_params(event, event_tags)
187
- # Creates object of params specific to conversion events
188
- #
189
- # event - +Object+ Event which needs to be recorded.
190
- # event_tags - +Hash+ Values associated with the event.
191
- #
192
- # Returns +Hash+ Conversion event params
193
-
194
- single_snapshot = {}
195
- event_object = {
196
- entity_id: event['id'],
197
- timestamp: create_timestamp,
198
- uuid: create_uuid,
199
- key: event['key']
200
- }
201
-
202
- if event_tags
203
- revenue_value = Helpers::EventTagUtils.get_revenue_value(event_tags, @logger)
204
- event_object[:revenue] = revenue_value if revenue_value
205
-
206
- numeric_value = Helpers::EventTagUtils.get_numeric_value(event_tags, @logger)
207
- event_object[:value] = numeric_value if numeric_value
208
-
209
- event_object[:tags] = event_tags unless event_tags.empty?
210
- end
211
-
212
- single_snapshot[:events] = [event_object]
213
- single_snapshot
214
- end
215
-
216
- def create_timestamp
217
- # Returns +Integer+ Current timestamp
218
-
219
- (Time.now.to_f * 1000).to_i
220
- end
221
-
222
- def create_uuid
223
- # Returns +String+ Random UUID
224
-
225
- SecureRandom.uuid
226
- end
227
- end
228
- end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright 2016-2019, 2022, Optimizely and contributors
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ require_relative 'audience'
19
+ require_relative 'helpers/constants'
20
+ require_relative 'helpers/event_tag_utils'
21
+ require_relative 'params'
22
+ require_relative 'version'
23
+
24
+ require 'securerandom'
25
+
26
+ module Optimizely
27
+ class Event
28
+ # Representation of an event which can be sent to the Optimizely logging endpoint.
29
+
30
+ attr_reader :http_verb, :params, :url, :headers
31
+
32
+ def initialize(http_verb, url, params, headers)
33
+ @http_verb = http_verb
34
+ @url = url
35
+ @params = params
36
+ @headers = headers
37
+ end
38
+
39
+ # Override equality operator to make two events with the same contents equal for testing purposes
40
+ def ==(other)
41
+ @http_verb == other.http_verb && @url == other.url && @params == other.params && @headers == other.headers
42
+ end
43
+ end
44
+
45
+ class BaseEventBuilder
46
+ CUSTOM_ATTRIBUTE_FEATURE_TYPE = 'custom'
47
+
48
+ def initialize(logger)
49
+ @logger = logger
50
+ end
51
+
52
+ private
53
+
54
+ def get_common_params(project_config, user_id, attributes)
55
+ # Get params which are used in both conversion and impression events.
56
+ #
57
+ # project_config - +Object+ Instance of ProjectConfig
58
+ # user_id - +String+ ID for user
59
+ # attributes - +Hash+ representing user attributes and values which need to be recorded.
60
+ #
61
+ # Returns +Hash+ Common event params
62
+
63
+ visitor_attributes = []
64
+
65
+ attributes&.keys&.each do |attribute_key|
66
+ # Omit attribute values that are not supported by the log endpoint.
67
+ attribute_value = attributes[attribute_key]
68
+ if Helpers::Validator.attribute_valid?(attribute_key, attribute_value)
69
+ attribute_id = project_config.get_attribute_id attribute_key
70
+ if attribute_id
71
+ visitor_attributes.push(
72
+ entity_id: attribute_id,
73
+ key: attribute_key,
74
+ type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
75
+ value: attribute_value
76
+ )
77
+ end
78
+ end
79
+ end
80
+ # Append Bot Filtering Attribute
81
+ if project_config.bot_filtering == true || project_config.bot_filtering == false
82
+ visitor_attributes.push(
83
+ entity_id: Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BOT_FILTERING'],
84
+ key: Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BOT_FILTERING'],
85
+ type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
86
+ value: project_config.bot_filtering
87
+ )
88
+ end
89
+
90
+ {
91
+ account_id: project_config.account_id,
92
+ project_id: project_config.project_id,
93
+ visitors: [
94
+ {
95
+ attributes: visitor_attributes,
96
+ snapshots: [],
97
+ visitor_id: user_id
98
+ }
99
+ ],
100
+ anonymize_ip: project_config.anonymize_ip,
101
+ revision: project_config.revision,
102
+ client_name: CLIENT_ENGINE,
103
+ enrich_decisions: true,
104
+ client_version: VERSION
105
+ }
106
+ end
107
+ end
108
+
109
+ class EventBuilder < BaseEventBuilder
110
+ ENDPOINT = 'https://logx.optimizely.com/v1/events'
111
+ POST_HEADERS = {'Content-Type' => 'application/json'}.freeze
112
+ ACTIVATE_EVENT_KEY = 'campaign_activated'
113
+
114
+ def create_impression_event(project_config, experiment, variation_id, user_id, attributes)
115
+ # Create impression Event to be sent to the logging endpoint.
116
+ #
117
+ # project_config - +Object+ Instance of ProjectConfig
118
+ # experiment - +Object+ Experiment for which impression needs to be recorded.
119
+ # variation_id - +String+ ID for variation which would be presented to user.
120
+ # user_id - +String+ ID for user.
121
+ # attributes - +Hash+ representing user attributes and values which need to be recorded.
122
+ #
123
+ # Returns +Event+ encapsulating the impression event.
124
+
125
+ event_params = get_common_params(project_config, user_id, attributes)
126
+ impression_params = get_impression_params(project_config, experiment, variation_id)
127
+ event_params[:visitors][0][:snapshots].push(impression_params)
128
+
129
+ Event.new(:post, ENDPOINT, event_params, POST_HEADERS)
130
+ end
131
+
132
+ def create_conversion_event(project_config, event, user_id, attributes, event_tags)
133
+ # Create conversion Event to be sent to the logging endpoint.
134
+ #
135
+ # project_config - +Object+ Instance of ProjectConfig
136
+ # event - +Object+ Event which needs to be recorded.
137
+ # user_id - +String+ ID for user.
138
+ # attributes - +Hash+ representing user attributes and values which need to be recorded.
139
+ # event_tags - +Hash+ representing metadata associated with the event.
140
+ #
141
+ # Returns +Event+ encapsulating the conversion event.
142
+
143
+ event_params = get_common_params(project_config, user_id, attributes)
144
+ conversion_params = get_conversion_params(event, event_tags)
145
+ event_params[:visitors][0][:snapshots] = [conversion_params]
146
+
147
+ Event.new(:post, ENDPOINT, event_params, POST_HEADERS)
148
+ end
149
+
150
+ private
151
+
152
+ def get_impression_params(project_config, experiment, variation_id)
153
+ # Creates object of params specific to impression events
154
+ #
155
+ # project_config - +Object+ Instance of ProjectConfig
156
+ # experiment - +Hash+ experiment for which impression needs to be recorded
157
+ # variation_id - +string+ ID for variation which would be presented to user
158
+ #
159
+ # Returns +Hash+ Impression event params
160
+
161
+ experiment_key = experiment['key']
162
+ experiment_id = experiment['id']
163
+
164
+ {
165
+ decisions: [{
166
+ campaign_id: project_config.experiment_key_map[experiment_key]['layerId'],
167
+ experiment_id: experiment_id,
168
+ variation_id: variation_id
169
+ }],
170
+ events: [{
171
+ entity_id: project_config.experiment_key_map[experiment_key]['layerId'],
172
+ timestamp: create_timestamp,
173
+ key: ACTIVATE_EVENT_KEY,
174
+ uuid: create_uuid
175
+ }]
176
+ }
177
+ end
178
+
179
+ def get_conversion_params(event, event_tags)
180
+ # Creates object of params specific to conversion events
181
+ #
182
+ # event - +Object+ Event which needs to be recorded.
183
+ # event_tags - +Hash+ Values associated with the event.
184
+ #
185
+ # Returns +Hash+ Conversion event params
186
+
187
+ single_snapshot = {}
188
+ event_object = {
189
+ entity_id: event['id'],
190
+ timestamp: create_timestamp,
191
+ uuid: create_uuid,
192
+ key: event['key']
193
+ }
194
+
195
+ if event_tags
196
+ revenue_value = Helpers::EventTagUtils.get_revenue_value(event_tags, @logger)
197
+ event_object[:revenue] = revenue_value if revenue_value
198
+
199
+ numeric_value = Helpers::EventTagUtils.get_numeric_value(event_tags, @logger)
200
+ event_object[:value] = numeric_value if numeric_value
201
+
202
+ event_object[:tags] = event_tags unless event_tags.empty?
203
+ end
204
+
205
+ single_snapshot[:events] = [event_object]
206
+ single_snapshot
207
+ end
208
+
209
+ def create_timestamp
210
+ # Returns +Integer+ Current timestamp
211
+
212
+ (Time.now.to_f * 1000).to_i
213
+ end
214
+
215
+ def create_uuid
216
+ # Returns +String+ Random UUID
217
+
218
+ SecureRandom.uuid
219
+ end
220
+ end
221
+ end