vwo-sdk 1.5.0 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/vwo/constants.rb +26 -3
- data/lib/vwo/core/bucketer.rb +4 -6
- data/lib/vwo/core/variation_decider.rb +337 -45
- data/lib/vwo/enums.rb +49 -9
- data/lib/vwo/logger.rb +1 -1
- data/lib/vwo/schemas/settings_file.rb +1 -1
- data/lib/vwo/services/batch_events_dispatcher.rb +110 -0
- data/lib/vwo/services/batch_events_queue.rb +175 -0
- data/lib/vwo/services/event_dispatcher.rb +1 -13
- data/lib/vwo/services/hooks_manager.rb +36 -0
- data/lib/vwo/services/operand_evaluator.rb +10 -2
- data/lib/vwo/services/segment_evaluator.rb +5 -26
- data/lib/vwo/services/settings_file_manager.rb +8 -4
- data/lib/vwo/services/settings_file_processor.rb +6 -1
- data/lib/vwo/services/usage_stats.rb +29 -0
- data/lib/vwo/user_storage.rb +1 -1
- data/lib/vwo/utils/campaign.rb +108 -1
- data/lib/vwo/utils/custom_dimensions.rb +26 -3
- data/lib/vwo/utils/feature.rb +1 -1
- data/lib/vwo/utils/function.rb +1 -1
- data/lib/vwo/utils/impression.rb +58 -7
- data/lib/vwo/utils/request.rb +15 -1
- data/lib/vwo/utils/segment.rb +1 -1
- data/lib/vwo/utils/uuid.rb +1 -1
- data/lib/vwo/utils/validations.rb +85 -1
- data/lib/vwo.rb +586 -203
- metadata +36 -13
data/lib/vwo/utils/request.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2019-
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -24,6 +24,20 @@ class VWO
|
|
24
24
|
uri.query = URI.encode_www_form(params)
|
25
25
|
Net::HTTP.get_response(uri)
|
26
26
|
end
|
27
|
+
|
28
|
+
def self.post(url, params, post_data)
|
29
|
+
uri = URI.parse(url)
|
30
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
31
|
+
http.use_ssl = true
|
32
|
+
uri.query = URI.encode_www_form(params)
|
33
|
+
headers = {
|
34
|
+
'Authorization'=>params[:env],
|
35
|
+
'Content-Type' =>'application/json',
|
36
|
+
'Accept'=>'application/json'
|
37
|
+
}
|
38
|
+
response = http.post(uri, post_data.to_json, headers)
|
39
|
+
response
|
40
|
+
end
|
27
41
|
end
|
28
42
|
end
|
29
43
|
end
|
data/lib/vwo/utils/segment.rb
CHANGED
data/lib/vwo/utils/uuid.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2019-
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -15,6 +15,9 @@
|
|
15
15
|
require 'json'
|
16
16
|
require 'json-schema'
|
17
17
|
require_relative '../schemas/settings_file'
|
18
|
+
require_relative '../logger'
|
19
|
+
require_relative '../enums'
|
20
|
+
require_relative '../constants'
|
18
21
|
|
19
22
|
class VWO
|
20
23
|
module Utils
|
@@ -59,6 +62,87 @@ class VWO
|
|
59
62
|
def valid_basic_data_type?(val)
|
60
63
|
valid_number?(val) || valid_string?(val) || valid_boolean?(val)
|
61
64
|
end
|
65
|
+
|
66
|
+
# Validates if the value passed batch_events has correct data type and values or not.
|
67
|
+
#
|
68
|
+
# Args: batch_events [Hash]: value to be tested
|
69
|
+
#
|
70
|
+
# @return: [Boolean]: True if all conditions are passed else False
|
71
|
+
def is_valid_batch_event_settings(batch_events)
|
72
|
+
logger = VWO::Logger.get_instance
|
73
|
+
events_per_request = batch_events[:events_per_request]
|
74
|
+
request_time_interval = batch_events[:request_time_interval]
|
75
|
+
|
76
|
+
unless events_per_request || request_time_interval
|
77
|
+
logger.log(
|
78
|
+
VWO::LogLevelEnum::ERROR,
|
79
|
+
format(
|
80
|
+
VWO::LogMessageEnum::ErrorMessages::EVENT_BATCHING_INSUFFICIENT,
|
81
|
+
file: VWO::FileNameEnum::ValidateUtil
|
82
|
+
)
|
83
|
+
)
|
84
|
+
return false
|
85
|
+
end
|
86
|
+
|
87
|
+
if (request_time_interval && !valid_number?(request_time_interval))
|
88
|
+
logger.log(
|
89
|
+
VWO::LogLevelEnum::ERROR,
|
90
|
+
format(
|
91
|
+
VWO::LogMessageEnum::ErrorMessages::REQUEST_TIME_INTERVAL_INVALID,
|
92
|
+
file: VWO::FileNameEnum::ValidateUtil
|
93
|
+
)
|
94
|
+
)
|
95
|
+
return false
|
96
|
+
end
|
97
|
+
|
98
|
+
if (events_per_request && !valid_number?(events_per_request))
|
99
|
+
logger.log(
|
100
|
+
VWO::LogLevelEnum::ERROR,
|
101
|
+
format(
|
102
|
+
VWO::LogMessageEnum::ErrorMessages::EVENTS_PER_REQUEST_INVALID,
|
103
|
+
file: VWO::FileNameEnum::ValidateUtil
|
104
|
+
)
|
105
|
+
)
|
106
|
+
return false
|
107
|
+
end
|
108
|
+
|
109
|
+
if events_per_request && (events_per_request < VWO::MIN_EVENTS_PER_REQUEST || events_per_request > VWO::MAX_EVENTS_PER_REQUEST)
|
110
|
+
logger.log(
|
111
|
+
VWO::LogLevelEnum::ERROR,
|
112
|
+
format(
|
113
|
+
VWO::LogMessageEnum::ErrorMessages::EVENTS_PER_REQUEST_OUT_OF_BOUNDS,
|
114
|
+
file: VWO::FileNameEnum::ValidateUtil,
|
115
|
+
min_value: VWO::MIN_EVENTS_PER_REQUEST,
|
116
|
+
max_value: VWO::MAX_EVENTS_PER_REQUEST
|
117
|
+
)
|
118
|
+
)
|
119
|
+
return false
|
120
|
+
end
|
121
|
+
|
122
|
+
if request_time_interval && request_time_interval < VWO::MIN_REQUEST_TIME_INTERVAL
|
123
|
+
logger.log(
|
124
|
+
VWO::LogLevelEnum::ERROR,
|
125
|
+
format(
|
126
|
+
VWO::LogMessageEnum::ErrorMessages::REQUEST_TIME_INTERVAL_OUT_OF_BOUNDS,
|
127
|
+
file: VWO::FileNameEnum::ValidateUtil,
|
128
|
+
min_value: VWO::MIN_REQUEST_TIME_INTERVAL
|
129
|
+
)
|
130
|
+
)
|
131
|
+
return false
|
132
|
+
end
|
133
|
+
|
134
|
+
if batch_events.key?(:flushCallback) && !batch_events[:flushCallback].is_a?(Method)
|
135
|
+
logger.log(
|
136
|
+
VWO::LogLevelEnum::ERROR,
|
137
|
+
format(
|
138
|
+
VWO::LogMessageEnum::ErrorMessages::FLUSH_CALLBACK_INVALID,
|
139
|
+
file: VWO::FileNameEnum::ValidateUtil
|
140
|
+
)
|
141
|
+
)
|
142
|
+
return false
|
143
|
+
end
|
144
|
+
true
|
145
|
+
end
|
62
146
|
end
|
63
147
|
end
|
64
148
|
end
|
data/lib/vwo.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2019-
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -25,11 +25,14 @@ require_relative 'vwo/utils/feature'
|
|
25
25
|
require_relative 'vwo/utils/custom_dimensions'
|
26
26
|
require_relative 'vwo/constants'
|
27
27
|
require_relative 'vwo/core/variation_decider'
|
28
|
+
require_relative 'vwo/services/batch_events_dispatcher'
|
29
|
+
require_relative 'vwo/services/batch_events_queue'
|
30
|
+
require_relative 'vwo/services/usage_stats'
|
28
31
|
|
29
32
|
# VWO main file
|
30
33
|
class VWO
|
31
|
-
attr_accessor :is_instance_valid, :logger
|
32
|
-
|
34
|
+
attr_accessor :is_instance_valid, :logger, :settings_file_manager, :variation_decider
|
35
|
+
attr_reader :usage_stats
|
33
36
|
include Enums
|
34
37
|
include Utils::Validations
|
35
38
|
include Utils::Feature
|
@@ -65,7 +68,15 @@ class VWO
|
|
65
68
|
@is_development_mode = is_development_mode
|
66
69
|
@logger = VWO::Logger.get_instance(logger)
|
67
70
|
@logger.instance.level = options[:log_level] if (0..5).include?(options[:log_level])
|
71
|
+
usage_stats = {}
|
72
|
+
|
73
|
+
usage_stats[:cl] = 1 if logger
|
74
|
+
usage_stats[:ll] = 1 if options[:log_level]
|
75
|
+
usage_stats[:ss] = 1 if @user_storage
|
76
|
+
usage_stats[:ig] = 1 if options.key?(:integrations)
|
77
|
+
usage_stats[:eb] = 1 if options.key?(:batch_events)
|
68
78
|
|
79
|
+
@settings_file_manager = VWO::Services::SettingsFileManager.new(@account_id, @sdk_key)
|
69
80
|
unless valid_settings_file?(get_settings(settings_file))
|
70
81
|
@logger.log(
|
71
82
|
LogLevelEnum::ERROR,
|
@@ -74,6 +85,45 @@ class VWO
|
|
74
85
|
@is_instance_valid = false
|
75
86
|
return
|
76
87
|
end
|
88
|
+
|
89
|
+
if options.key?(:should_track_returning_user)
|
90
|
+
if [true, false].include? options[:should_track_returning_user]
|
91
|
+
@should_track_returning_user = options[:should_track_returning_user]
|
92
|
+
usage_stats[:tr] = 1 if @should_track_returning_user
|
93
|
+
else
|
94
|
+
@logger.log(
|
95
|
+
LogLevelEnum::ERROR,
|
96
|
+
format(
|
97
|
+
LogMessageEnum::ErrorMessages::INVALID_TRACK_RETURNING_USER_VALUE,
|
98
|
+
file: FILE
|
99
|
+
)
|
100
|
+
)
|
101
|
+
@is_instance_valid = false
|
102
|
+
return
|
103
|
+
end
|
104
|
+
else
|
105
|
+
@should_track_returning_user = false
|
106
|
+
end
|
107
|
+
|
108
|
+
if options.key?(:goal_type_to_track)
|
109
|
+
if GOAL_TYPES.key? options[:goal_type_to_track]
|
110
|
+
@goal_type_to_track = options[:goal_type_to_track]
|
111
|
+
usage_stats[:gt] = 1
|
112
|
+
else
|
113
|
+
@logger.log(
|
114
|
+
LogLevelEnum::ERROR,
|
115
|
+
format(
|
116
|
+
LogMessageEnum::ErrorMessages::INVALID_GOAL_TYPE,
|
117
|
+
file: FILE
|
118
|
+
)
|
119
|
+
)
|
120
|
+
@is_instance_valid = false
|
121
|
+
return
|
122
|
+
end
|
123
|
+
else
|
124
|
+
@goal_type_to_track = 'ALL'
|
125
|
+
end
|
126
|
+
|
77
127
|
@is_instance_valid = true
|
78
128
|
@config = VWO::Services::SettingsFileProcessor.new(get_settings)
|
79
129
|
|
@@ -89,8 +139,54 @@ class VWO
|
|
89
139
|
@config.process_settings_file
|
90
140
|
@settings_file = @config.get_settings_file
|
91
141
|
|
142
|
+
@usage_stats = VWO::Services::UsageStats.new(usage_stats, @is_development_mode)
|
143
|
+
|
144
|
+
if options.key?(:batch_events)
|
145
|
+
if options[:batch_events].is_a?(Hash)
|
146
|
+
unless is_valid_batch_event_settings(options[:batch_events])
|
147
|
+
@is_instance_valid = false
|
148
|
+
return
|
149
|
+
end
|
150
|
+
@batch_event_dispatcher = VWO::Services::BatchEventsDispatcher.new
|
151
|
+
def dispatcher (events, callback)
|
152
|
+
@batch_event_dispatcher.dispatch(
|
153
|
+
{
|
154
|
+
ev: events
|
155
|
+
},
|
156
|
+
callback,
|
157
|
+
{
|
158
|
+
a: @account_id,
|
159
|
+
sd: SDK_NAME,
|
160
|
+
sv: SDK_VERSION,
|
161
|
+
env: @sdk_key
|
162
|
+
}.merge(@usage_stats.usage_stats)
|
163
|
+
)
|
164
|
+
end
|
165
|
+
@batch_events_queue = VWO::Services::BatchEventsQueue.new(
|
166
|
+
options[:batch_events].merge(
|
167
|
+
{
|
168
|
+
account_id: @account_id,
|
169
|
+
dispatcher: method(:dispatcher)
|
170
|
+
}
|
171
|
+
)
|
172
|
+
)
|
173
|
+
@batch_events_queue.flush(manual: true)
|
174
|
+
@batch_events = options[:batch_events]
|
175
|
+
else
|
176
|
+
@logger.log(
|
177
|
+
LogLevelEnum::ERROR,
|
178
|
+
format(
|
179
|
+
LogMessageEnum::ErrorMessages::EVENT_BATCHING_NOT_OBJECT,
|
180
|
+
file: FILE
|
181
|
+
)
|
182
|
+
)
|
183
|
+
@is_instance_valid = false
|
184
|
+
return
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
92
188
|
# Assign VariationDecider to VWO
|
93
|
-
@variation_decider = VWO::Core::VariationDecider.new(@settings_file, user_storage)
|
189
|
+
@variation_decider = VWO::Core::VariationDecider.new(@settings_file, user_storage, options)
|
94
190
|
|
95
191
|
if is_development_mode
|
96
192
|
@logger.log(
|
@@ -118,9 +214,55 @@ class VWO
|
|
118
214
|
|
119
215
|
# VWO get_settings method to get settings for a particular account_id
|
120
216
|
def get_settings(settings_file = nil)
|
121
|
-
@
|
122
|
-
settings_file ||
|
123
|
-
@
|
217
|
+
@settings_file ||=
|
218
|
+
settings_file || @settings_file_manager.get_settings_file
|
219
|
+
@settings_file
|
220
|
+
end
|
221
|
+
|
222
|
+
# This API method: fetch the latest settings file and update it
|
223
|
+
|
224
|
+
# VWO get_settings method to get settings for a particular account_id
|
225
|
+
def get_and_update_settings_file
|
226
|
+
|
227
|
+
unless @is_instance_valid
|
228
|
+
@logger.log(
|
229
|
+
LogLevelEnum::ERROR,
|
230
|
+
format(
|
231
|
+
LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
|
232
|
+
file: FILE,
|
233
|
+
api_name: ApiMethods.GET_AND_UPDATE_SETTINGS_FILE
|
234
|
+
)
|
235
|
+
)
|
236
|
+
return
|
237
|
+
end
|
238
|
+
|
239
|
+
latest_settings = @settings_file_manager.get_settings_file(true)
|
240
|
+
latest_settings = JSON.parse(latest_settings)
|
241
|
+
if latest_settings == @settings_file
|
242
|
+
@logger.log(
|
243
|
+
LogLevelEnum::INFO,
|
244
|
+
format(
|
245
|
+
LogMessageEnum::InfoMessages::SETTINGS_NOT_UPDATED,
|
246
|
+
api_name: ApiMethods::GET_AND_UPDATE_SETTINGS_FILE,
|
247
|
+
file: FILE
|
248
|
+
)
|
249
|
+
)
|
250
|
+
end
|
251
|
+
|
252
|
+
@config.update_settings_file(latest_settings)
|
253
|
+
@settings_file = @config.get_settings_file
|
254
|
+
@settings_file
|
255
|
+
rescue StandardError => e
|
256
|
+
@logger.log(
|
257
|
+
LogLevelEnum::ERROR,
|
258
|
+
format(
|
259
|
+
LogMessageEnum::ErrorMessages::API_NOT_WORKING,
|
260
|
+
file: FILE,
|
261
|
+
api_name: ApiMethods::GET_AND_UPDATE_SETTINGS_FILE,
|
262
|
+
exception: e
|
263
|
+
)
|
264
|
+
)
|
265
|
+
nil
|
124
266
|
end
|
125
267
|
|
126
268
|
# This API method: Gets the variation assigned for the user
|
@@ -136,34 +278,37 @@ class VWO
|
|
136
278
|
#
|
137
279
|
# @param[String] :campaign_key Unique campaign key
|
138
280
|
# @param[String] :user_id ID assigned to a user
|
139
|
-
# @param[Hash]
|
281
|
+
# @param[Hash] :options Options for custom variables required for segmentation
|
140
282
|
# @return[String|None] If variation is assigned then variation-name
|
141
283
|
# otherwise null in case of user not becoming part
|
142
284
|
|
143
285
|
def activate(campaign_key, user_id, options = {})
|
144
|
-
|
145
|
-
custom_variables = options['custom_variables'] || options[:custom_variables]
|
146
|
-
|
147
|
-
# Validate input parameters
|
148
|
-
unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables))
|
286
|
+
unless @is_instance_valid
|
149
287
|
@logger.log(
|
150
288
|
LogLevelEnum::ERROR,
|
151
289
|
format(
|
152
|
-
LogMessageEnum::ErrorMessages::
|
153
|
-
|
154
|
-
|
290
|
+
LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
|
291
|
+
file: FILE,
|
292
|
+
api_name: ApiMethods::ACTIVATE
|
155
293
|
)
|
156
294
|
)
|
157
295
|
return
|
158
296
|
end
|
159
297
|
|
160
|
-
|
298
|
+
# Retrieve custom variables
|
299
|
+
custom_variables = options['custom_variables'] || options[:custom_variables]
|
300
|
+
variation_targeting_variables = options['variation_targeting_variables'] || options[:variation_targeting_variables]
|
301
|
+
|
302
|
+
should_track_returning_user = get_should_track_returning_user(options)
|
303
|
+
# Validate input parameters
|
304
|
+
unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
|
305
|
+
(variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables)) && [true, false].include?(should_track_returning_user)
|
161
306
|
@logger.log(
|
162
307
|
LogLevelEnum::ERROR,
|
163
308
|
format(
|
164
|
-
LogMessageEnum::ErrorMessages::
|
165
|
-
|
166
|
-
|
309
|
+
LogMessageEnum::ErrorMessages::ACTIVATE_API_MISSING_PARAMS,
|
310
|
+
api_name: ApiMethods::ACTIVATE,
|
311
|
+
file: FILE
|
167
312
|
)
|
168
313
|
)
|
169
314
|
return
|
@@ -208,11 +353,14 @@ class VWO
|
|
208
353
|
|
209
354
|
# Once the matching RUNNING campaign is found, assign the
|
210
355
|
# deterministic variation to the user_id provided
|
356
|
+
|
211
357
|
variation = @variation_decider.get_variation(
|
212
358
|
user_id,
|
213
359
|
campaign,
|
360
|
+
ApiMethods::ACTIVATE,
|
214
361
|
campaign_key,
|
215
|
-
custom_variables
|
362
|
+
custom_variables,
|
363
|
+
variation_targeting_variables
|
216
364
|
)
|
217
365
|
|
218
366
|
# Check if variation_name has been assigned
|
@@ -229,15 +377,56 @@ class VWO
|
|
229
377
|
return
|
230
378
|
end
|
231
379
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
380
|
+
if is_eligible_to_send_impression(should_track_returning_user)
|
381
|
+
if defined?(@batch_events)
|
382
|
+
impression = create_bulk_event_impression(
|
383
|
+
@settings_file,
|
384
|
+
campaign['id'],
|
385
|
+
variation['id'],
|
386
|
+
user_id
|
387
|
+
)
|
388
|
+
@batch_events_queue.enqueue(impression)
|
389
|
+
else
|
390
|
+
# Variation found, dispatch it to server
|
391
|
+
impression = create_impression(
|
392
|
+
@settings_file,
|
393
|
+
campaign['id'],
|
394
|
+
variation['id'],
|
395
|
+
user_id,
|
396
|
+
@sdk_key,
|
397
|
+
nil, # goal_id
|
398
|
+
nil, # revenue
|
399
|
+
usage_stats: @usage_stats.usage_stats
|
400
|
+
)
|
401
|
+
if @event_dispatcher.dispatch(impression)
|
402
|
+
@logger.log(
|
403
|
+
LogLevelEnum::INFO,
|
404
|
+
format(
|
405
|
+
LogMessageEnum::InfoMessages::IMPRESSION_SUCCESS,
|
406
|
+
file: FILE,
|
407
|
+
sdk_key: @sdk_key,
|
408
|
+
account_id: @account_id,
|
409
|
+
campaign_id: campaign['id'],
|
410
|
+
variation_id: variation['id'],
|
411
|
+
end_point: EVENTS::TRACK_USER
|
412
|
+
)
|
413
|
+
)
|
414
|
+
end
|
415
|
+
end
|
416
|
+
variation['name']
|
417
|
+
else
|
418
|
+
@logger.log(
|
419
|
+
LogLevelEnum::INFO,
|
420
|
+
format(
|
421
|
+
LogMessageEnum::InfoMessages::USER_ALREADY_TRACKED,
|
422
|
+
file: FILE,
|
423
|
+
user_id: user_id,
|
424
|
+
campaign_key: campaign_key,
|
425
|
+
api_name: ApiMethods::ACTIVATE
|
426
|
+
)
|
427
|
+
)
|
428
|
+
nil
|
429
|
+
end
|
241
430
|
rescue StandardError => e
|
242
431
|
@logger.log(
|
243
432
|
LogLevelEnum::ERROR,
|
@@ -248,7 +437,7 @@ class VWO
|
|
248
437
|
exception: e
|
249
438
|
)
|
250
439
|
)
|
251
|
-
|
440
|
+
e
|
252
441
|
end
|
253
442
|
|
254
443
|
# This API method: Gets the variation name assigned for the
|
@@ -269,28 +458,30 @@ class VWO
|
|
269
458
|
# Otherwise null in case of user not becoming part
|
270
459
|
#
|
271
460
|
def get_variation_name(campaign_key, user_id, options = {})
|
272
|
-
|
273
|
-
custom_variables = options['custom_variables'] || options[:custom_variables]
|
274
|
-
|
275
|
-
# Validate input parameters
|
276
|
-
unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables))
|
461
|
+
unless @is_instance_valid
|
277
462
|
@logger.log(
|
278
463
|
LogLevelEnum::ERROR,
|
279
464
|
format(
|
280
|
-
LogMessageEnum::ErrorMessages::
|
281
|
-
|
282
|
-
|
465
|
+
LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
|
466
|
+
file: FILE,
|
467
|
+
api_name: ApiMethods::GET_VARIATION_NAME
|
283
468
|
)
|
284
469
|
)
|
285
470
|
return
|
286
471
|
end
|
287
|
-
|
472
|
+
# Retrieve custom variables
|
473
|
+
custom_variables = options['custom_variables'] || options[:custom_variables]
|
474
|
+
variation_targeting_variables = options['variation_targeting_variables'] || options[:variation_targeting_variables]
|
475
|
+
|
476
|
+
# Validate input parameters
|
477
|
+
unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
|
478
|
+
(variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
|
288
479
|
@logger.log(
|
289
480
|
LogLevelEnum::ERROR,
|
290
481
|
format(
|
291
|
-
LogMessageEnum::ErrorMessages::
|
292
|
-
|
293
|
-
|
482
|
+
LogMessageEnum::ErrorMessages::GET_VARIATION_NAME_API_INVALID_PARAMS,
|
483
|
+
api_name: ApiMethods::GET_VARIATION_NAME,
|
484
|
+
file: FILE
|
294
485
|
)
|
295
486
|
)
|
296
487
|
return
|
@@ -330,7 +521,7 @@ class VWO
|
|
330
521
|
return
|
331
522
|
end
|
332
523
|
|
333
|
-
variation = @variation_decider.get_variation(user_id, campaign, campaign_key, custom_variables)
|
524
|
+
variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::GET_VARIATION_NAME, campaign_key, custom_variables, variation_targeting_variables)
|
334
525
|
|
335
526
|
# Check if variation_name has been assigned
|
336
527
|
unless valid_value?(variation)
|
@@ -372,33 +563,11 @@ class VWO
|
|
372
563
|
# @param[String] :campaign_key Unique campaign key
|
373
564
|
# @param[String] :user_id ID assigned to a user
|
374
565
|
# @param[String] :goal_identifier Unique campaign's goal identifier
|
375
|
-
# @param[
|
566
|
+
# @param[Hash] :options Contains revenue value and custom variables
|
376
567
|
# @param[Numeric|String] :revenue_value It is the revenue generated on triggering the goal
|
377
568
|
#
|
378
|
-
def track(campaign_key, user_id, goal_identifier, *args)
|
379
|
-
if args[0].is_a?(Hash)
|
380
|
-
revenue_value = args[0]['revenue_value'] || args[0][:revenue_value]
|
381
|
-
custom_variables = args[0]['custom_variables'] || args[0][:custom_variables]
|
382
|
-
elsif args.is_a?(Array)
|
383
|
-
revenue_value = args[0]
|
384
|
-
custom_variables = nil
|
385
|
-
end
|
386
|
-
|
387
|
-
# Check for valid args
|
388
|
-
unless valid_string?(campaign_key) && valid_string?(user_id) && valid_string?(goal_identifier) &&
|
389
|
-
(custom_variables.nil? || valid_hash?(custom_variables)) || (revenue_value.nil? || valid_basic_data_type?(revenue_value))
|
390
|
-
# log invalid params
|
391
|
-
@logger.log(
|
392
|
-
LogLevelEnum::ERROR,
|
393
|
-
format(
|
394
|
-
LogMessageEnum::ErrorMessages::TRACK_API_INVALID_PARAMS,
|
395
|
-
file: FILE,
|
396
|
-
api_name: ApiMethods.TRACK
|
397
|
-
)
|
398
|
-
)
|
399
|
-
return false
|
400
|
-
end
|
401
569
|
|
570
|
+
def track(campaign_key, user_id, goal_identifier, options = {})
|
402
571
|
unless @is_instance_valid
|
403
572
|
@logger.log(
|
404
573
|
LogLevelEnum::ERROR,
|
@@ -411,98 +580,187 @@ class VWO
|
|
411
580
|
return false
|
412
581
|
end
|
413
582
|
|
414
|
-
|
415
|
-
|
583
|
+
revenue_value = options['revenue_value'] || options[:revenue_value]
|
584
|
+
custom_variables = options['custom_variables'] || options[:custom_variables]
|
585
|
+
variation_targeting_variables = options['variation_targeting_variables'] || options[:variation_targeting_variables]
|
586
|
+
should_track_returning_user = get_should_track_returning_user(options)
|
587
|
+
goal_type_to_track = get_goal_type_to_track(options)
|
416
588
|
|
417
|
-
#
|
418
|
-
|
419
|
-
|
589
|
+
# Check for valid args
|
590
|
+
unless (valid_string?(campaign_key) || campaign_key.is_a?(Array) || campaign_key.nil?) && valid_string?(user_id) && valid_string?(goal_identifier) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
|
591
|
+
(variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables)) && [true, false].include?(should_track_returning_user) && (GOAL_TYPES.key? (goal_type_to_track))
|
592
|
+
# log invalid params
|
420
593
|
@logger.log(
|
421
594
|
LogLevelEnum::ERROR,
|
422
595
|
format(
|
423
|
-
LogMessageEnum::ErrorMessages::
|
596
|
+
LogMessageEnum::ErrorMessages::TRACK_API_INVALID_PARAMS,
|
424
597
|
file: FILE,
|
425
|
-
campaign_key: campaign_key,
|
426
598
|
api_name: ApiMethods::TRACK
|
427
599
|
)
|
428
600
|
)
|
429
601
|
return false
|
430
602
|
end
|
431
603
|
|
432
|
-
|
604
|
+
# Get campaigns settings
|
605
|
+
campaigns = get_campaigns(@settings_file, campaign_key, goal_identifier, goal_type_to_track)
|
433
606
|
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
format(
|
438
|
-
LogMessageEnum::ErrorMessages::INVALID_API,
|
439
|
-
file: FILE,
|
440
|
-
api_name: ApiMethods::TRACK,
|
441
|
-
user_id: user_id,
|
442
|
-
campaign_key: campaign_key,
|
443
|
-
campaign_type: campaign_type
|
444
|
-
)
|
445
|
-
)
|
446
|
-
return false
|
607
|
+
# Validate campaign
|
608
|
+
if campaigns.nil?
|
609
|
+
return nil
|
447
610
|
end
|
448
611
|
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
612
|
+
result = {}
|
613
|
+
campaigns.each do |campaign|
|
614
|
+
begin
|
615
|
+
campaign_type = campaign['type']
|
616
|
+
|
617
|
+
if campaign_type == CampaignTypes::FEATURE_ROLLOUT
|
618
|
+
@logger.log(
|
619
|
+
LogLevelEnum::ERROR,
|
620
|
+
format(
|
621
|
+
LogMessageEnum::ErrorMessages::INVALID_API,
|
622
|
+
file: FILE,
|
623
|
+
api_name: ApiMethods::TRACK,
|
624
|
+
user_id: user_id,
|
625
|
+
campaign_key: campaign['key'],
|
626
|
+
campaign_type: campaign_type
|
627
|
+
)
|
463
628
|
)
|
464
|
-
|
465
|
-
|
466
|
-
|
629
|
+
result[campaign['key']] = false
|
630
|
+
next
|
631
|
+
end
|
632
|
+
|
633
|
+
variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::TRACK, campaign['key'], custom_variables, variation_targeting_variables, goal_identifier)
|
634
|
+
|
635
|
+
if variation
|
636
|
+
goal = get_campaign_goal(campaign, goal_identifier)
|
637
|
+
if goal.nil? || !goal["id"]
|
638
|
+
@logger.log(
|
639
|
+
LogLevelEnum::ERROR,
|
640
|
+
format(
|
641
|
+
LogMessageEnum::ErrorMessages::TRACK_API_GOAL_NOT_FOUND,
|
642
|
+
file: FILE,
|
643
|
+
goal_identifier: goal_identifier,
|
644
|
+
user_id: user_id,
|
645
|
+
campaign_key: campaign['key'],
|
646
|
+
api_name: ApiMethods::TRACK
|
647
|
+
)
|
648
|
+
)
|
649
|
+
result[campaign['key']] = false
|
650
|
+
next
|
651
|
+
elsif goal['type'] == GoalTypes::REVENUE && !valid_value?(revenue_value)
|
652
|
+
@logger.log(
|
653
|
+
LogLevelEnum::ERROR,
|
654
|
+
format(
|
655
|
+
LogMessageEnum::ErrorMessages::TRACK_API_REVENUE_NOT_PASSED_FOR_REVENUE_GOAL,
|
656
|
+
file: FILE,
|
657
|
+
user_id: user_id,
|
658
|
+
goal_identifier: goal_identifier,
|
659
|
+
campaign_key: campaign['key'],
|
660
|
+
api_name: ApiMethods::TRACK
|
661
|
+
)
|
662
|
+
)
|
663
|
+
result[campaign['key']] = false
|
664
|
+
next
|
665
|
+
elsif goal['type'] == GoalTypes::CUSTOM
|
666
|
+
revenue_value = nil
|
667
|
+
end
|
668
|
+
|
669
|
+
if variation['goal_identifier']
|
670
|
+
identifiers = variation['goal_identifier'].split(VWO_DELIMITER)
|
671
|
+
else
|
672
|
+
variation['goal_identifier'] = ''
|
673
|
+
identifiers = []
|
674
|
+
end
|
675
|
+
|
676
|
+
if !identifiers.include? goal_identifier
|
677
|
+
updated_goal_identifier = variation['goal_identifier']
|
678
|
+
updated_goal_identifier += VWO_DELIMITER + goal_identifier
|
679
|
+
@variation_decider.save_user_storage(user_id, campaign['key'], variation['name'], updated_goal_identifier) if variation['name']
|
680
|
+
# set variation at user storage
|
681
|
+
elsif !should_track_returning_user
|
682
|
+
@logger.log(
|
683
|
+
LogLevelEnum::INFO,
|
684
|
+
format(
|
685
|
+
LogMessageEnum::InfoMessages::GOAL_ALREADY_TRACKED,
|
686
|
+
file: FILE,
|
687
|
+
user_id: user_id,
|
688
|
+
campaign_key: campaign['key'],
|
689
|
+
goal_identifier: goal_identifier,
|
690
|
+
api_name: ApiMethods::TRACK
|
691
|
+
)
|
692
|
+
)
|
693
|
+
result[campaign['key']] = false
|
694
|
+
next
|
695
|
+
end
|
696
|
+
|
697
|
+
if defined?(@batch_events)
|
698
|
+
impression = create_bulk_event_impression(
|
699
|
+
@settings_file,
|
700
|
+
campaign['id'],
|
701
|
+
variation['id'],
|
702
|
+
user_id,
|
703
|
+
goal['id'],
|
704
|
+
revenue_value
|
705
|
+
)
|
706
|
+
@batch_events_queue.enqueue(impression)
|
707
|
+
else
|
708
|
+
impression = create_impression(
|
709
|
+
@settings_file,
|
710
|
+
campaign['id'],
|
711
|
+
variation['id'],
|
712
|
+
user_id,
|
713
|
+
@sdk_key,
|
714
|
+
goal['id'],
|
715
|
+
revenue_value
|
716
|
+
)
|
717
|
+
if @event_dispatcher.dispatch(impression)
|
718
|
+
@logger.log(
|
719
|
+
LogLevelEnum::INFO,
|
720
|
+
format(
|
721
|
+
LogMessageEnum::InfoMessages::IMPRESSION_SUCCESS,
|
722
|
+
file: FILE,
|
723
|
+
sdk_key: @sdk_key,
|
724
|
+
account_id: @account_id,
|
725
|
+
campaign_id: campaign['id'],
|
726
|
+
variation_id: variation['id'],
|
727
|
+
end_point: EVENTS::TRACK_GOAL
|
728
|
+
)
|
729
|
+
)
|
730
|
+
@logger.log(
|
731
|
+
LogLevelEnum::INFO,
|
732
|
+
format(
|
733
|
+
LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_IMPRESSION,
|
734
|
+
file: FILE,
|
735
|
+
sdk_key: @sdk_key,
|
736
|
+
campaign_id: impression[:experiment_id],
|
737
|
+
account_id: impression[:account_id],
|
738
|
+
variation_id: impression[:combination]
|
739
|
+
)
|
740
|
+
)
|
741
|
+
end
|
742
|
+
end
|
743
|
+
result[campaign['key']] = true
|
744
|
+
next
|
745
|
+
end
|
746
|
+
result[campaign['key']] = false
|
747
|
+
rescue StandardError => e
|
467
748
|
@logger.log(
|
468
749
|
LogLevelEnum::ERROR,
|
469
750
|
format(
|
470
|
-
|
751
|
+
e.message,
|
471
752
|
file: FILE,
|
472
|
-
|
473
|
-
goal_identifier: goal_identifier,
|
474
|
-
campaign_key: campaign_key,
|
475
|
-
api_name: ApiMethods::TRACK
|
753
|
+
exception: e
|
476
754
|
)
|
477
755
|
)
|
478
|
-
return false
|
479
|
-
elsif goal['type'] == GoalTypes::CUSTOM
|
480
|
-
revenue_value = nil
|
481
756
|
end
|
482
|
-
|
483
|
-
@settings_file,
|
484
|
-
campaign['id'],
|
485
|
-
variation['id'],
|
486
|
-
user_id,
|
487
|
-
goal['id'],
|
488
|
-
revenue_value
|
489
|
-
)
|
490
|
-
@event_dispatcher.dispatch(impression)
|
757
|
+
end
|
491
758
|
|
492
|
-
|
493
|
-
|
494
|
-
format(
|
495
|
-
LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_IMPRESSION,
|
496
|
-
file: FILE,
|
497
|
-
campaign_id: impression[:experiment_id],
|
498
|
-
user_id: impression[:uId],
|
499
|
-
account_id: impression[:account_id],
|
500
|
-
variation_id: impression[:combination]
|
501
|
-
)
|
502
|
-
)
|
503
|
-
return true
|
759
|
+
if result.length() == 0
|
760
|
+
return nil
|
504
761
|
end
|
505
|
-
|
762
|
+
|
763
|
+
result
|
506
764
|
rescue StandardError => e
|
507
765
|
@logger.log(
|
508
766
|
LogLevelEnum::ERROR,
|
@@ -530,28 +788,40 @@ class VWO
|
|
530
788
|
# @return[Boolean] true if user becomes part of feature test/rollout, otherwise false.
|
531
789
|
|
532
790
|
def feature_enabled?(campaign_key, user_id, options = {})
|
533
|
-
|
534
|
-
custom_variables = options['custom_variables'] || options[:custom_variables]
|
535
|
-
|
536
|
-
# Validate input parameters
|
537
|
-
unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables))
|
791
|
+
unless @is_instance_valid
|
538
792
|
@logger.log(
|
539
793
|
LogLevelEnum::ERROR,
|
540
794
|
format(
|
541
|
-
LogMessageEnum::ErrorMessages::
|
542
|
-
|
543
|
-
|
795
|
+
LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
|
796
|
+
file: FILE,
|
797
|
+
api_name: ApiMethods::IS_FEATURE_ENABLED
|
544
798
|
)
|
545
799
|
)
|
546
800
|
return false
|
547
801
|
end
|
548
|
-
|
802
|
+
|
803
|
+
# Retrieve custom variables
|
804
|
+
custom_variables = options['custom_variables'] || options[:custom_variables]
|
805
|
+
variation_targeting_variables = options['variation_targeting_variables'] || options[:variation_targeting_variables]
|
806
|
+
should_track_returning_user = get_should_track_returning_user(options)
|
807
|
+
@logger.log(
|
808
|
+
LogLevelEnum::INFO,
|
809
|
+
format(
|
810
|
+
LogMessageEnum::InfoMessages::API_CALLED,
|
811
|
+
file: FILE,
|
812
|
+
api_name: ApiMethods::IS_FEATURE_ENABLED,
|
813
|
+
user_id: user_id
|
814
|
+
)
|
815
|
+
)
|
816
|
+
# Validate input parameters
|
817
|
+
unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
|
818
|
+
(variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables)) && [true, false].include?(should_track_returning_user)
|
549
819
|
@logger.log(
|
550
820
|
LogLevelEnum::ERROR,
|
551
821
|
format(
|
552
|
-
LogMessageEnum::ErrorMessages::
|
553
|
-
|
554
|
-
|
822
|
+
LogMessageEnum::ErrorMessages::IS_FEATURE_ENABLED_API_INVALID_PARAMS,
|
823
|
+
api_name: ApiMethods::IS_FEATURE_ENABLED,
|
824
|
+
file: FILE
|
555
825
|
)
|
556
826
|
)
|
557
827
|
return false
|
@@ -594,57 +864,84 @@ class VWO
|
|
594
864
|
end
|
595
865
|
|
596
866
|
# Get variation
|
597
|
-
variation = @variation_decider.get_variation(user_id, campaign, campaign_key, custom_variables)
|
867
|
+
variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::IS_FEATURE_ENABLED, campaign_key, custom_variables, variation_targeting_variables)
|
598
868
|
|
599
869
|
# If no variation, did not become part of feature_test/rollout
|
600
870
|
return false unless variation
|
601
871
|
|
602
872
|
# if campaign type is feature_test Send track call to server
|
603
873
|
if campaign_type == CampaignTypes::FEATURE_TEST
|
604
|
-
|
605
|
-
@
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
874
|
+
if is_eligible_to_send_impression(should_track_returning_user)
|
875
|
+
if defined?(@batch_events)
|
876
|
+
impression = create_bulk_event_impression(
|
877
|
+
@settings_file,
|
878
|
+
campaign['id'],
|
879
|
+
variation['id'],
|
880
|
+
user_id
|
881
|
+
)
|
882
|
+
@batch_events_queue.enqueue(impression)
|
883
|
+
else
|
884
|
+
impression = create_impression(
|
885
|
+
@settings_file,
|
886
|
+
campaign['id'],
|
887
|
+
variation['id'],
|
888
|
+
user_id,
|
889
|
+
@sdk_key,
|
890
|
+
goal_id: nil,
|
891
|
+
revenue: nil,
|
892
|
+
usage_stats: @usage_stats.usage_stats
|
893
|
+
)
|
610
894
|
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
)
|
623
|
-
result = variation['isFeatureEnabled']
|
624
|
-
if result
|
625
|
-
@logger.log(
|
626
|
-
LogLevelEnum::INFO,
|
627
|
-
format(
|
628
|
-
LogMessageEnum::InfoMessages::FEATURE_ENABLED_FOR_USER,
|
629
|
-
file: FILE,
|
630
|
-
user_id: user_id,
|
631
|
-
feature_key: campaign_key,
|
632
|
-
api_name: ApiMethods::IS_FEATURE_ENABLED
|
895
|
+
@event_dispatcher.dispatch(impression)
|
896
|
+
@logger.log(
|
897
|
+
LogLevelEnum::INFO,
|
898
|
+
format(
|
899
|
+
LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_IMPRESSION,
|
900
|
+
file: FILE,
|
901
|
+
campaign_id: impression[:experiment_id],
|
902
|
+
sdk_key: @sdk_key,
|
903
|
+
account_id: impression[:account_id],
|
904
|
+
variation_id: impression[:combination]
|
905
|
+
)
|
633
906
|
)
|
634
|
-
|
907
|
+
end
|
908
|
+
result = variation['isFeatureEnabled']
|
909
|
+
if result
|
910
|
+
@logger.log(
|
911
|
+
LogLevelEnum::INFO,
|
912
|
+
format(
|
913
|
+
LogMessageEnum::InfoMessages::FEATURE_ENABLED_FOR_USER,
|
914
|
+
file: FILE,
|
915
|
+
user_id: user_id,
|
916
|
+
feature_key: campaign_key,
|
917
|
+
api_name: ApiMethods::IS_FEATURE_ENABLED
|
918
|
+
)
|
919
|
+
)
|
920
|
+
else
|
921
|
+
@logger.log(
|
922
|
+
LogLevelEnum::INFO,
|
923
|
+
format(
|
924
|
+
LogMessageEnum::InfoMessages::FEATURE_NOT_ENABLED_FOR_USER,
|
925
|
+
file: FILE,
|
926
|
+
user_id: user_id,
|
927
|
+
feature_key: campaign_key,
|
928
|
+
api_name: ApiMethods::IS_FEATURE_ENABLED
|
929
|
+
)
|
930
|
+
)
|
931
|
+
end
|
932
|
+
return result
|
635
933
|
else
|
636
934
|
@logger.log(
|
637
935
|
LogLevelEnum::INFO,
|
638
936
|
format(
|
639
|
-
LogMessageEnum::InfoMessages::
|
937
|
+
LogMessageEnum::InfoMessages::USER_ALREADY_TRACKED,
|
640
938
|
file: FILE,
|
641
939
|
user_id: user_id,
|
642
|
-
|
940
|
+
campaign_key: campaign_key,
|
643
941
|
api_name: ApiMethods::IS_FEATURE_ENABLED
|
644
942
|
)
|
645
943
|
)
|
646
944
|
end
|
647
|
-
return result
|
648
945
|
end
|
649
946
|
true
|
650
947
|
rescue StandardError => e
|
@@ -680,29 +977,30 @@ class VWO
|
|
680
977
|
#
|
681
978
|
|
682
979
|
def get_feature_variable_value(campaign_key, variable_key, user_id, options = {})
|
683
|
-
|
684
|
-
custom_variables = options['custom_variables'] || options[:custom_variables]
|
685
|
-
|
686
|
-
unless valid_string?(campaign_key) && valid_string?(variable_key) && valid_string?(user_id) &&
|
687
|
-
(custom_variables.nil? || valid_hash?(custom_variables))
|
980
|
+
unless @is_instance_valid
|
688
981
|
@logger.log(
|
689
982
|
LogLevelEnum::ERROR,
|
690
983
|
format(
|
691
|
-
LogMessageEnum::ErrorMessages::
|
984
|
+
LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
|
692
985
|
file: FILE,
|
693
|
-
api_name: ApiMethods
|
986
|
+
api_name: ApiMethods.GET_FEATURE_VARIABLE_VALUE
|
694
987
|
)
|
695
988
|
)
|
696
989
|
return
|
697
990
|
end
|
698
991
|
|
699
|
-
|
992
|
+
# Retrieve custom variables
|
993
|
+
custom_variables = options['custom_variables'] || options[:custom_variables]
|
994
|
+
variation_targeting_variables = options['variation_targeting_variables'] || options[:variation_targeting_variables]
|
995
|
+
|
996
|
+
unless valid_string?(campaign_key) && valid_string?(variable_key) && valid_string?(user_id) &&
|
997
|
+
(custom_variables.nil? || valid_hash?(custom_variables)) && (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
|
700
998
|
@logger.log(
|
701
999
|
LogLevelEnum::ERROR,
|
702
1000
|
format(
|
703
|
-
LogMessageEnum::ErrorMessages::
|
1001
|
+
LogMessageEnum::ErrorMessages::GET_FEATURE_VARIABLE_VALUE_API_INVALID_PARAMS,
|
704
1002
|
file: FILE,
|
705
|
-
api_name: ApiMethods
|
1003
|
+
api_name: ApiMethods::GET_FEATURE_VARIABLE_VALUE
|
706
1004
|
)
|
707
1005
|
)
|
708
1006
|
return
|
@@ -743,7 +1041,7 @@ class VWO
|
|
743
1041
|
return
|
744
1042
|
end
|
745
1043
|
|
746
|
-
variation = @variation_decider.get_variation(user_id, campaign, campaign_key, custom_variables)
|
1044
|
+
variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::GET_FEATURE_VARIABLE_VALUE, campaign_key, custom_variables, variation_targeting_variables)
|
747
1045
|
|
748
1046
|
# Check if variation has been assigned to user
|
749
1047
|
return unless variation
|
@@ -832,6 +1130,18 @@ class VWO
|
|
832
1130
|
# @return true if call is made successfully, else false
|
833
1131
|
|
834
1132
|
def push(tag_key, tag_value, user_id)
|
1133
|
+
unless @is_instance_valid
|
1134
|
+
@logger.log(
|
1135
|
+
LogLevelEnum::ERROR,
|
1136
|
+
format(
|
1137
|
+
LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
|
1138
|
+
file: FILE,
|
1139
|
+
api_name: ApiMethods.PUSH
|
1140
|
+
)
|
1141
|
+
)
|
1142
|
+
return
|
1143
|
+
end
|
1144
|
+
|
835
1145
|
unless valid_string?(tag_key) && valid_string?(tag_value) && valid_string?(user_id)
|
836
1146
|
@logger.log(
|
837
1147
|
LogLevelEnum::ERROR,
|
@@ -872,32 +1182,105 @@ class VWO
|
|
872
1182
|
return false
|
873
1183
|
end
|
874
1184
|
|
875
|
-
|
876
|
-
|
877
|
-
|
1185
|
+
if defined?(@batch_events)
|
1186
|
+
impression = get_batch_event_url_params(@settings_file, tag_key, tag_value, user_id)
|
1187
|
+
@batch_events_queue.enqueue(impression)
|
1188
|
+
else
|
1189
|
+
impression = get_url_params(@settings_file, tag_key, tag_value, user_id, @sdk_key)
|
1190
|
+
@event_dispatcher.dispatch(impression)
|
878
1191
|
|
1192
|
+
@logger.log(
|
1193
|
+
LogLevelEnum::INFO,
|
1194
|
+
format(
|
1195
|
+
LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_PUSH_API,
|
1196
|
+
file: FILE,
|
1197
|
+
sdk_key: @sdk_key,
|
1198
|
+
u: impression['u'],
|
1199
|
+
account_id: impression['account_id'],
|
1200
|
+
tags: impression['tags']
|
1201
|
+
)
|
1202
|
+
)
|
1203
|
+
end
|
1204
|
+
true
|
1205
|
+
rescue StandardError => e
|
879
1206
|
@logger.log(
|
880
|
-
LogLevelEnum::
|
1207
|
+
LogLevelEnum::ERROR,
|
881
1208
|
format(
|
882
|
-
LogMessageEnum::
|
1209
|
+
LogMessageEnum::ErrorMessages::API_NOT_WORKING,
|
883
1210
|
file: FILE,
|
884
|
-
|
885
|
-
|
886
|
-
account_id: impression['account_id'],
|
887
|
-
tags: impression['tags']
|
1211
|
+
api_name: ApiMethods::PUSH,
|
1212
|
+
exception: e
|
888
1213
|
)
|
889
1214
|
)
|
890
|
-
|
1215
|
+
false
|
1216
|
+
end
|
1217
|
+
|
1218
|
+
def get_should_track_returning_user(options)
|
1219
|
+
if !options.key?(:should_track_returning_user)
|
1220
|
+
options[:should_track_returning_user] = @should_track_returning_user
|
1221
|
+
elsif ![true, false].include?(options[:should_track_returning_user])
|
1222
|
+
@logger.log(
|
1223
|
+
LogLevelEnum::ERROR,
|
1224
|
+
format(
|
1225
|
+
LogMessageEnum::ErrorMessages::INVALID_TRACK_RETURNING_USER_VALUE,
|
1226
|
+
file: FILE
|
1227
|
+
)
|
1228
|
+
)
|
1229
|
+
end
|
1230
|
+
options[:should_track_returning_user]
|
1231
|
+
end
|
1232
|
+
|
1233
|
+
def is_eligible_to_send_impression(should_track_returning_user = false)
|
1234
|
+
!@user_storage || !@variation_decider.has_stored_variation || should_track_returning_user
|
1235
|
+
end
|
1236
|
+
|
1237
|
+
def flush_events
|
1238
|
+
unless @is_instance_valid
|
1239
|
+
@logger.log(
|
1240
|
+
LogLevelEnum::ERROR,
|
1241
|
+
format(
|
1242
|
+
LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
|
1243
|
+
file: FILE,
|
1244
|
+
api_name: ApiMethods::FLUSH_EVENTS
|
1245
|
+
)
|
1246
|
+
)
|
1247
|
+
return
|
1248
|
+
end
|
1249
|
+
result = @batch_events_queue.flush(manual: true)
|
1250
|
+
@batch_events_queue.kill_thread
|
1251
|
+
result
|
891
1252
|
rescue StandardError => e
|
892
1253
|
@logger.log(
|
893
1254
|
LogLevelEnum::ERROR,
|
894
1255
|
format(
|
895
1256
|
LogMessageEnum::ErrorMessages::API_NOT_WORKING,
|
896
1257
|
file: FILE,
|
897
|
-
api_name: ApiMethods::
|
1258
|
+
api_name: ApiMethods::FLUSH_EVENTS,
|
898
1259
|
exception: e
|
899
1260
|
)
|
900
1261
|
)
|
901
1262
|
false
|
902
1263
|
end
|
1264
|
+
|
1265
|
+
def get_goal_type_to_track(options)
|
1266
|
+
goal_type_to_track = nil
|
1267
|
+
if !options.key?(:goal_type_to_track)
|
1268
|
+
if @goal_type_to_track
|
1269
|
+
goal_type_to_track = @goal_type_to_track
|
1270
|
+
else
|
1271
|
+
goal_type_to_track = GOAL_TYPES['ALL']
|
1272
|
+
end
|
1273
|
+
elsif GOAL_TYPES.key? options[:goal_type_to_track]
|
1274
|
+
goal_type_to_track = options[:goal_type_to_track]
|
1275
|
+
else
|
1276
|
+
@logger.log(
|
1277
|
+
LogLevelEnum::ERROR,
|
1278
|
+
format(
|
1279
|
+
LogMessageEnum::ErrorMessages::INVALID_GOAL_TYPE,
|
1280
|
+
file: FILE
|
1281
|
+
)
|
1282
|
+
)
|
1283
|
+
end
|
1284
|
+
goal_type_to_track
|
1285
|
+
end
|
903
1286
|
end
|