vwo-sdk 1.30.0 → 1.37.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/vwo.rb CHANGED
@@ -25,6 +25,7 @@ require_relative 'vwo/utils/feature'
25
25
  require_relative 'vwo/utils/custom_dimensions'
26
26
  require_relative 'vwo/utils/utility'
27
27
  require_relative 'vwo/utils/data_location_manager'
28
+ require_relative 'vwo/utils/log_message'
28
29
  require_relative 'vwo/constants'
29
30
  require_relative 'vwo/core/variation_decider'
30
31
  require_relative 'vwo/services/batch_events_dispatcher'
@@ -33,8 +34,9 @@ require_relative 'vwo/services/usage_stats'
33
34
 
34
35
  # VWO main file
35
36
  class VWO
36
- attr_accessor :is_instance_valid, :logger, :settings_file_manager, :variation_decider
37
+ attr_accessor :is_instance_valid, :logging, :settings_file_manager, :variation_decider
37
38
  attr_reader :usage_stats
39
+
38
40
  include Enums
39
41
  include Utils::Validations
40
42
  include Utils::Feature
@@ -66,14 +68,16 @@ class VWO
66
68
  settings_file = nil,
67
69
  options = {}
68
70
  )
71
+ @logger = Utils::Logger
72
+ @logger.set_api_name(ApiMethods::LAUNCH)
69
73
  options = convert_to_symbol_hash(options)
70
74
  @is_opted_out = false
71
75
  @account_id = account_id
72
76
  @sdk_key = sdk_key
73
77
  @user_storage = user_storage
74
78
  @is_development_mode = is_development_mode
75
- @logger = VWO::Logger.get_instance(logger)
76
- @logger.instance.level = options[:log_level] if (0..5).include?(options[:log_level])
79
+ @logging = VWO::Logger.get_instance(logger)
80
+ @logging.instance.level = options[:log_level] if (0..5).include?(options[:log_level])
77
81
  usage_stats = {}
78
82
 
79
83
  usage_stats[:cl] = 1 if logger
@@ -82,11 +86,19 @@ class VWO
82
86
  usage_stats[:ig] = 1 if options.key?(:integrations)
83
87
  usage_stats[:eb] = 1 if options.key?(:batch_events)
84
88
 
89
+ unless validate_sdk_config?(@user_storage, is_development_mode, ApiMethods::LAUNCH)
90
+ @is_instance_valid = false
91
+ return
92
+ end
93
+
85
94
  @settings_file_manager = VWO::Services::SettingsFileManager.new(@account_id, @sdk_key)
86
95
  unless valid_settings_file?(get_settings(settings_file))
87
96
  @logger.log(
88
97
  LogLevelEnum::ERROR,
89
- format(LogMessageEnum::ErrorMessages::SETTINGS_FILE_CORRUPTED, file: FILE)
98
+ 'SETTINGS_FILE_CORRUPTED',
99
+ {
100
+ '{file}' => FILE
101
+ }
90
102
  )
91
103
  @is_instance_valid = false
92
104
  return
@@ -99,10 +111,13 @@ class VWO
99
111
  else
100
112
  @logger.log(
101
113
  LogLevelEnum::ERROR,
102
- format(
103
- LogMessageEnum::ErrorMessages::INVALID_GOAL_TYPE,
104
- file: FILE
105
- )
114
+ 'CONFIG_PARAMETER_INVALID',
115
+ {
116
+ '{file}' => FILE,
117
+ '{parameter}' => 'goal_type_to_track',
118
+ '{type}' => 'string(REVENUE, CUSTOM, ALL)',
119
+ '{api}' => 'init'
120
+ }
106
121
  )
107
122
  @is_instance_valid = false
108
123
  return
@@ -114,42 +129,21 @@ class VWO
114
129
  @is_instance_valid = true
115
130
  @config = VWO::Services::SettingsFileProcessor.new(get_settings)
116
131
 
117
- @logger.log(
118
- LogLevelEnum::DEBUG,
119
- format(
120
- LogMessageEnum::DebugMessages::VALID_CONFIGURATION,
121
- file: FILE
122
- )
123
- )
124
-
125
132
  # Process the settings file
126
133
  @config.process_settings_file
127
134
  @settings_file = @config.get_settings_file
128
- DataLocationManager.get_instance().set_settings(@settings_file)
135
+ DataLocationManager.get_instance.set_settings(@settings_file)
129
136
 
130
137
  @usage_stats = VWO::Services::UsageStats.new(usage_stats, @is_development_mode)
131
138
 
132
139
  if options.key?(:batch_events)
133
140
  if options[:batch_events].is_a?(Hash)
134
- unless is_valid_batch_event_settings(options[:batch_events])
141
+ unless valid_batch_event_settings(options[:batch_events], ApiMethods::LAUNCH)
135
142
  @is_instance_valid = false
136
143
  return
137
144
  end
138
- @batch_event_dispatcher = VWO::Services::BatchEventsDispatcher.new
139
- def dispatcher (events, callback)
140
- @batch_event_dispatcher.dispatch(
141
- {
142
- ev: events
143
- },
144
- callback,
145
- {
146
- a: @account_id,
147
- sd: SDK_NAME,
148
- sv: SDK_VERSION,
149
- env: @sdk_key
150
- }.merge(@usage_stats.usage_stats)
151
- )
152
- end
145
+ @batch_event_dispatcher = VWO::Services::BatchEventsDispatcher.new(@is_development_mode)
146
+
153
147
  @batch_events_queue = VWO::Services::BatchEventsQueue.new(
154
148
  options[:batch_events].merge(
155
149
  {
@@ -163,10 +157,13 @@ class VWO
163
157
  else
164
158
  @logger.log(
165
159
  LogLevelEnum::ERROR,
166
- format(
167
- LogMessageEnum::ErrorMessages::EVENT_BATCHING_NOT_OBJECT,
168
- file: FILE
169
- )
160
+ 'CONFIG_PARAMETER_INVALID',
161
+ {
162
+ '{file}' => FILE,
163
+ '{parameter}' => 'batch_events',
164
+ '{type}' => 'hash',
165
+ '{api}' => 'init'
166
+ }
170
167
  )
171
168
  @is_instance_valid = false
172
169
  return
@@ -176,25 +173,29 @@ class VWO
176
173
  # Assign VariationDecider to VWO
177
174
  @variation_decider = VWO::Core::VariationDecider.new(@settings_file, user_storage, options)
178
175
 
179
- if is_development_mode
180
- @logger.log(
181
- LogLevelEnum::DEBUG,
182
- format(
183
- LogMessageEnum::DebugMessages::SET_DEVELOPMENT_MODE,
184
- file: FILE
185
- )
186
- )
187
- end
188
176
  # Assign event dispatcher
189
177
  @event_dispatcher = VWO::Services::EventDispatcher.new(is_development_mode)
190
178
 
191
179
  # Successfully initialized VWO SDK
192
180
  @logger.log(
193
- LogLevelEnum::DEBUG,
194
- format(
195
- LogMessageEnum::DebugMessages::SDK_INITIALIZED,
196
- file: FILE
197
- )
181
+ LogLevelEnum::INFO,
182
+ 'SDK_INITIALIZED',
183
+ { '{file}' => FILE }
184
+ )
185
+ end
186
+
187
+ def dispatcher(events, callback)
188
+ @batch_event_dispatcher.dispatch(
189
+ {
190
+ ev: events
191
+ },
192
+ callback,
193
+ {
194
+ a: @account_id,
195
+ sd: SDK_NAME,
196
+ sv: SDK_VERSION,
197
+ env: @sdk_key
198
+ }.merge(@usage_stats.usage_stats)
198
199
  )
199
200
  end
200
201
 
@@ -211,19 +212,17 @@ class VWO
211
212
 
212
213
  # VWO get_settings method to get settings for a particular account_id
213
214
  def get_and_update_settings_file
214
-
215
- if is_opted_out(ApiMethods::GET_AND_UPDATE_SETTINGS_FILE)
216
- return false
217
- end
215
+ @logger.set_api_name(ApiMethods::GET_AND_UPDATE_SETTINGS_FILE)
216
+ return false if opted_out?(ApiMethods::GET_AND_UPDATE_SETTINGS_FILE)
218
217
 
219
218
  unless @is_instance_valid
220
219
  @logger.log(
221
220
  LogLevelEnum::ERROR,
222
- format(
223
- LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
224
- file: FILE,
225
- api_name: ApiMethods.GET_AND_UPDATE_SETTINGS_FILE
226
- )
221
+ 'CONFIG_CORRUPTED',
222
+ {
223
+ '{file}' => FILE,
224
+ '{api}' => ApiMethods::GET_AND_UPDATE_SETTINGS_FILE
225
+ }
227
226
  )
228
227
  return false
229
228
  end
@@ -232,12 +231,12 @@ class VWO
232
231
  latest_settings = JSON.parse(latest_settings)
233
232
  if latest_settings == @settings_file
234
233
  @logger.log(
235
- LogLevelEnum::INFO,
236
- format(
237
- LogMessageEnum::InfoMessages::SETTINGS_NOT_UPDATED,
238
- api_name: ApiMethods::GET_AND_UPDATE_SETTINGS_FILE,
239
- file: FILE
240
- )
234
+ LogLevelEnum::DEBUG,
235
+ 'SETTINGS_FILE_PROCESSED',
236
+ {
237
+ '{file}' => FILE,
238
+ '{accountId}' => @settings_file['accountId']
239
+ }
241
240
  )
242
241
  end
243
242
 
@@ -247,12 +246,11 @@ class VWO
247
246
  rescue StandardError => e
248
247
  @logger.log(
249
248
  LogLevelEnum::ERROR,
250
- format(
251
- LogMessageEnum::ErrorMessages::API_NOT_WORKING,
252
- file: FILE,
253
- api_name: ApiMethods::GET_AND_UPDATE_SETTINGS_FILE,
254
- exception: e
255
- )
249
+ "({file}): {api} API error: #{e.message}",
250
+ {
251
+ '{file}' => FILE,
252
+ '{api}' => ApiMethods::GET_AND_UPDATE_SETTINGS_FILE
253
+ }
256
254
  )
257
255
  nil
258
256
  end
@@ -275,18 +273,17 @@ class VWO
275
273
  # otherwise null in case of user not becoming part
276
274
 
277
275
  def activate(campaign_key, user_id, options = {})
278
- if is_opted_out(ApiMethods::ACTIVATE)
279
- return nil
280
- end
276
+ @logger.set_api_name(ApiMethods::ACTIVATE)
277
+ return nil if opted_out?(ApiMethods::ACTIVATE)
281
278
 
282
279
  unless @is_instance_valid
283
280
  @logger.log(
284
281
  LogLevelEnum::ERROR,
285
- format(
286
- LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
287
- file: FILE,
288
- api_name: ApiMethods::ACTIVATE
289
- )
282
+ 'CONFIG_CORRUPTED',
283
+ {
284
+ '{file}' => FILE,
285
+ '{api}' => ApiMethods::ACTIVATE
286
+ }
290
287
  )
291
288
  return
292
289
  end
@@ -298,14 +295,14 @@ class VWO
298
295
 
299
296
  # Validate input parameters
300
297
  unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
301
- (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
298
+ (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
302
299
  @logger.log(
303
300
  LogLevelEnum::ERROR,
304
- format(
305
- LogMessageEnum::ErrorMessages::ACTIVATE_API_MISSING_PARAMS,
306
- api_name: ApiMethods::ACTIVATE,
307
- file: FILE
308
- )
301
+ 'API_BAD_PARAMETERS',
302
+ {
303
+ '{file}' => FILE,
304
+ '{api}' => ApiMethods::ACTIVATE
305
+ }
309
306
  )
310
307
  return
311
308
  end
@@ -317,13 +314,13 @@ class VWO
317
314
  unless campaign && campaign['status'] == STATUS_RUNNING
318
315
  # Log Campaign as invalid
319
316
  @logger.log(
320
- LogLevelEnum::ERROR,
321
- format(
322
- LogMessageEnum::ErrorMessages::CAMPAIGN_NOT_RUNNING,
323
- file: FILE,
324
- campaign_key: campaign_key,
325
- api_name: ApiMethods::ACTIVATE
326
- )
317
+ LogLevelEnum::WARNING,
318
+ 'CAMPAIGN_NOT_RUNNING',
319
+ {
320
+ '{file}' => FILE,
321
+ '{campaignKey}' => campaign_key,
322
+ '{api}' => ApiMethods::ACTIVATE
323
+ }
327
324
  )
328
325
  return
329
326
  end
@@ -335,14 +332,14 @@ class VWO
335
332
  if campaign_type != CampaignTypes::VISUAL_AB
336
333
  @logger.log(
337
334
  LogLevelEnum::ERROR,
338
- format(
339
- LogMessageEnum::ErrorMessages::INVALID_API,
340
- file: FILE,
341
- api_name: ApiMethods::ACTIVATE,
342
- user_id: user_id,
343
- campaign_key: campaign_key,
344
- campaign_type: campaign_type
345
- )
335
+ 'API_NOT_APPLICABLE',
336
+ {
337
+ '{file}' => FILE,
338
+ '{api}' => ApiMethods::ACTIVATE,
339
+ '{userId}' => user_id,
340
+ '{campaignKey}' => campaign_key,
341
+ '{campaignType}' => campaign_type
342
+ }
346
343
  )
347
344
  return
348
345
  end
@@ -360,20 +357,9 @@ class VWO
360
357
  )
361
358
 
362
359
  # Check if variation_name has been assigned
363
- if variation.nil?
364
- @logger.log(
365
- LogLevelEnum::INFO,
366
- format(
367
- LogMessageEnum::InfoMessages::INVALID_VARIATION_KEY,
368
- file: FILE,
369
- user_id: user_id,
370
- campaign_key: campaign_key
371
- )
372
- )
373
- return
374
- end
360
+ return if variation.nil?
375
361
 
376
- if is_eligible_to_send_impression()
362
+ if eligible_to_send_impression?
377
363
  if defined?(@batch_events)
378
364
  impression = create_bulk_event_impression(
379
365
  @settings_file,
@@ -382,7 +368,7 @@ class VWO
382
368
  user_id
383
369
  )
384
370
  @batch_events_queue.enqueue(impression)
385
- elsif is_event_arch_enabled
371
+ elsif event_arch_enabled?
386
372
  properties = get_events_base_properties(@settings_file, EventEnum::VWO_VARIATION_SHOWN, @usage_stats.usage_stats)
387
373
  payload = get_track_user_payload_data(@settings_file, user_id, EventEnum::VWO_VARIATION_SHOWN, campaign['id'], variation['id'])
388
374
  @event_dispatcher.dispatch_event_arch_post(properties, payload)
@@ -398,42 +384,30 @@ class VWO
398
384
  nil, # revenue
399
385
  usage_stats: @usage_stats.usage_stats
400
386
  )
401
- if @event_dispatcher.dispatch(impression)
402
- @logger.log(
403
- LogLevelEnum::INFO,
404
- format(
405
- LogMessageEnum::InfoMessages::IMPRESSION_SUCCESS,
406
- file: FILE,
407
- account_id: @account_id,
408
- campaign_id: campaign['id'],
409
- variation_id: variation['id'],
410
- end_point: EVENTS::TRACK_USER
411
- )
412
- )
413
- end
387
+ main_keys = { 'campaignId' => campaign['id'], 'variationId' => variation['id'] }
388
+ @event_dispatcher.dispatch(impression, main_keys, EVENTS::TRACK_USER)
414
389
  end
415
390
  else
416
391
  @logger.log(
417
392
  LogLevelEnum::INFO,
418
- format(
419
- LogMessageEnum::InfoMessages::USER_ALREADY_TRACKED,
420
- file: FILE,
421
- user_id: user_id,
422
- campaign_key: campaign_key,
423
- api_name: ApiMethods::ACTIVATE
424
- )
393
+ 'CAMPAIGN_USER_ALREADY_TRACKED',
394
+ {
395
+ '{file}' => FILE,
396
+ '{userId}' => user_id,
397
+ '{campaignKey}' => campaign_key,
398
+ '{api}' => ApiMethods::ACTIVATE
399
+ }
425
400
  )
426
401
  end
427
402
  variation['name']
428
403
  rescue StandardError => e
429
404
  @logger.log(
430
405
  LogLevelEnum::ERROR,
431
- format(
432
- LogMessageEnum::ErrorMessages::API_NOT_WORKING,
433
- file: FILE,
434
- api_name: ApiMethods::ACTIVATE,
435
- exception: e
436
- )
406
+ "({file}): {api} API error: #{e.message}",
407
+ {
408
+ '{file}' => FILE,
409
+ '{api}' => ApiMethods::ACTIVATE
410
+ }
437
411
  )
438
412
  e
439
413
  end
@@ -456,18 +430,17 @@ class VWO
456
430
  # Otherwise null in case of user not becoming part
457
431
  #
458
432
  def get_variation_name(campaign_key, user_id, options = {})
459
- if is_opted_out(ApiMethods::GET_VARIATION_NAME)
460
- return nil
461
- end
433
+ @logger.set_api_name(ApiMethods::GET_VARIATION_NAME)
434
+ return nil if opted_out?(ApiMethods::GET_VARIATION_NAME)
462
435
 
463
436
  unless @is_instance_valid
464
437
  @logger.log(
465
438
  LogLevelEnum::ERROR,
466
- format(
467
- LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
468
- file: FILE,
469
- api_name: ApiMethods::GET_VARIATION_NAME
470
- )
439
+ 'CONFIG_CORRUPTED',
440
+ {
441
+ '{file}' => FILE,
442
+ '{api}' => ApiMethods::GET_VARIATION_NAME
443
+ }
471
444
  )
472
445
  return
473
446
  end
@@ -478,14 +451,14 @@ class VWO
478
451
 
479
452
  # Validate input parameters
480
453
  unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
481
- (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
454
+ (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
482
455
  @logger.log(
483
456
  LogLevelEnum::ERROR,
484
- format(
485
- LogMessageEnum::ErrorMessages::GET_VARIATION_NAME_API_INVALID_PARAMS,
486
- api_name: ApiMethods::GET_VARIATION_NAME,
487
- file: FILE
488
- )
457
+ 'API_BAD_PARAMETERS',
458
+ {
459
+ '{file}' => FILE,
460
+ '{api}' => ApiMethods::GET_VARIATION_NAME
461
+ }
489
462
  )
490
463
  return
491
464
  end
@@ -496,13 +469,13 @@ class VWO
496
469
  # Validate campaign
497
470
  if campaign.nil? || campaign['status'] != STATUS_RUNNING
498
471
  @logger.log(
499
- LogLevelEnum::ERROR,
500
- format(
501
- LogMessageEnum::ErrorMessages::CAMPAIGN_NOT_RUNNING,
502
- file: FILE,
503
- campaign_key: campaign_key,
504
- api_name: ApiMethods::GET_VARIATION_NAME
505
- )
472
+ LogLevelEnum::WARNING,
473
+ 'CAMPAIGN_NOT_RUNNING',
474
+ {
475
+ '{file}' => FILE,
476
+ '{campaignKey}' => campaign_key,
477
+ '{api}' => ApiMethods::GET_VARIATION_NAME
478
+ }
506
479
  )
507
480
  return
508
481
  end
@@ -512,45 +485,48 @@ class VWO
512
485
  if campaign_type == CampaignTypes::FEATURE_ROLLOUT
513
486
  @logger.log(
514
487
  LogLevelEnum::ERROR,
515
- format(
516
- LogMessageEnum::ErrorMessages.INVALID_API,
517
- file: FILE,
518
- api_name: ApiMethods::GET_VARIATION_NAME,
519
- user_id: user_id,
520
- campaign_key: campaign_key,
521
- campaign_type: campaign_type
522
- )
488
+ 'API_NOT_APPLICABLE',
489
+ {
490
+ '{file}' => FILE,
491
+ '{api}' => ApiMethods::GET_VARIATION_NAME,
492
+ '{userId}' => user_id,
493
+ '{campaignKey}' => campaign_key,
494
+ '{campaignType}' => campaign_type
495
+ }
523
496
  )
524
497
  return
525
498
  end
526
499
 
527
- variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::GET_VARIATION_NAME, campaign_key, custom_variables, variation_targeting_variables)
528
-
529
- # Check if variation_name has been assigned
530
- unless valid_value?(variation)
531
- # log invalid variation key
500
+ case campaign_type
501
+ when CampaignTypes::FEATURE_ROLLOUT
532
502
  @logger.log(
533
- LogLevelEnum::INFO,
534
- format(
535
- LogMessageEnum::InfoMessages::INVALID_VARIATION_KEY,
536
- file: FILE,
537
- user_id: user_id,
538
- campaign_key: campaign_key
539
- )
503
+ LogLevelEnum::ERROR,
504
+ 'API_NOT_APPLICABLE',
505
+ {
506
+ '{file}' => FILE,
507
+ '{api}' => ApiMethods::GET_VARIATION_NAME,
508
+ '{userId}' => user_id,
509
+ '{campaignKey}' => campaign_key,
510
+ '{campaignType}' => campaign_type
511
+ }
540
512
  )
541
513
  return
542
514
  end
543
515
 
516
+ variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::GET_VARIATION_NAME, campaign_key, custom_variables, variation_targeting_variables)
517
+
518
+ # Check if variation_name has been assigned
519
+ return unless valid_value?(variation)
520
+
544
521
  variation['name']
545
522
  rescue StandardError => e
546
523
  @logger.log(
547
524
  LogLevelEnum::ERROR,
548
- format(
549
- LogMessageEnum::ErrorMessages::API_NOT_WORKING,
550
- file: FILE,
551
- api_name: ApiMethods::GET_VARIATION_NAME,
552
- exception: e
553
- )
525
+ "({file}): {api} API error: #{e.message}",
526
+ {
527
+ '{file}' => FILE,
528
+ '{api}' => ApiMethods::GET_VARIATION_NAME
529
+ }
554
530
  )
555
531
  nil
556
532
  end
@@ -566,23 +542,21 @@ class VWO
566
542
  # @param[String] :campaign_key Unique campaign key
567
543
  # @param[String] :user_id ID assigned to a user
568
544
  # @param[String] :goal_identifier Unique campaign's goal identifier
569
- # @param[Hash] :options Contains revenue value and custom variables
570
- # @param[Numeric|String] :revenue_value It is the revenue generated on triggering the goal
545
+ # @param[Hash] :options Contains revenue value and custom variables
571
546
  #
572
547
 
573
548
  def track(campaign_key, user_id, goal_identifier, options = {})
574
- if is_opted_out(ApiMethods::TRACK)
575
- return false
576
- end
549
+ @logger.set_api_name(ApiMethods::TRACK)
550
+ return false if opted_out?(ApiMethods::TRACK)
577
551
 
578
552
  unless @is_instance_valid
579
553
  @logger.log(
580
554
  LogLevelEnum::ERROR,
581
- format(
582
- LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
583
- file: FILE,
584
- api_name: ApiMethods::TRACK
585
- )
555
+ 'CONFIG_CORRUPTED',
556
+ {
557
+ '{file}' => FILE,
558
+ '{api}' => ApiMethods::TRACK
559
+ }
586
560
  )
587
561
  return false
588
562
  end
@@ -594,204 +568,91 @@ class VWO
594
568
  goal_type_to_track = get_goal_type_to_track(options)
595
569
 
596
570
  # Check for valid args
597
- 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)) &&
598
- (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables)) && (GOAL_TYPES.key? (goal_type_to_track))
599
- # log invalid params
600
- @logger.log(
601
- LogLevelEnum::ERROR,
602
- format(
603
- LogMessageEnum::ErrorMessages::TRACK_API_INVALID_PARAMS,
604
- file: FILE,
605
- api_name: ApiMethods::TRACK
606
- )
607
- )
608
- return false
609
- end
571
+ return false unless valid_track_api_params?(user_id, campaign_key, custom_variables, variation_targeting_variables, goal_type_to_track, goal_identifier)
610
572
 
611
573
  # Get campaigns settings
612
574
  campaigns = get_campaigns(@settings_file, campaign_key, goal_identifier, goal_type_to_track)
613
575
 
614
576
  # Validate campaign
615
- if campaigns.nil?
616
- return nil
617
- end
577
+ return nil if campaigns.nil?
618
578
 
619
579
  metric_map = {}
620
580
  revenue_props = []
621
581
  result = {}
582
+ batch_event_data = { 'ev' => [] }
622
583
  campaigns.each do |campaign|
623
584
  begin
624
585
  campaign_type = campaign['type']
586
+ result[campaign['key']] = false
625
587
 
626
- if campaign_type == CampaignTypes::FEATURE_ROLLOUT
627
- @logger.log(
628
- LogLevelEnum::ERROR,
629
- format(
630
- LogMessageEnum::ErrorMessages::INVALID_API,
631
- file: FILE,
632
- api_name: ApiMethods::TRACK,
633
- user_id: user_id,
634
- campaign_key: campaign['key'],
635
- campaign_type: campaign_type
636
- )
637
- )
638
- result[campaign['key']] = false
639
- next
640
- end
588
+ next unless valid_campaign_for_track_api?(user_id, campaign_key, campaign_type)
641
589
 
642
590
  variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::TRACK, campaign['key'], custom_variables, variation_targeting_variables, goal_identifier)
643
591
 
644
592
  if variation
645
593
  goal = get_campaign_goal(campaign, goal_identifier)
646
- if goal.nil? || !goal["id"]
647
- @logger.log(
648
- LogLevelEnum::ERROR,
649
- format(
650
- LogMessageEnum::ErrorMessages::TRACK_API_GOAL_NOT_FOUND,
651
- file: FILE,
652
- goal_identifier: goal_identifier,
653
- user_id: user_id,
654
- campaign_key: campaign['key'],
655
- api_name: ApiMethods::TRACK
656
- )
657
- )
658
- result[campaign['key']] = false
659
- next
660
- elsif goal['type'] == GoalTypes::REVENUE && !valid_value?(revenue_value)
661
- @logger.log(
662
- LogLevelEnum::ERROR,
663
- format(
664
- LogMessageEnum::ErrorMessages::TRACK_API_REVENUE_NOT_PASSED_FOR_REVENUE_GOAL,
665
- file: FILE,
666
- user_id: user_id,
667
- goal_identifier: goal_identifier,
668
- campaign_key: campaign['key'],
669
- api_name: ApiMethods::TRACK
670
- )
671
- )
672
- result[campaign['key']] = false
673
- next
674
- elsif goal['type'] == GoalTypes::CUSTOM
675
- revenue_value = nil
676
- end
594
+ next unless valid_goal?(goal, campaign, user_id, goal_identifier, revenue_value)
677
595
 
678
- if variation['goal_identifier']
679
- identifiers = variation['goal_identifier'].split(VWO_DELIMITER)
680
- else
681
- variation['goal_identifier'] = ''
682
- identifiers = []
683
- end
596
+ revenue_value = nil if goal['type'] == GoalTypes::CUSTOM
597
+ identifiers = get_variation_identifiers(variation)
684
598
 
685
- if !identifiers.include? goal_identifier
686
- updated_goal_identifier = variation['goal_identifier']
687
- updated_goal_identifier += VWO_DELIMITER + goal_identifier
688
- @variation_decider.save_user_storage(user_id, campaign['key'], campaign['name'], variation['name'], updated_goal_identifier) if variation['name']
689
- # set variation at user storage
690
- else
691
- @logger.log(
692
- LogLevelEnum::INFO,
693
- format(
694
- LogMessageEnum::InfoMessages::GOAL_ALREADY_TRACKED,
695
- file: FILE,
696
- user_id: user_id,
697
- campaign_key: campaign['key'],
698
- goal_identifier: goal_identifier,
699
- api_name: ApiMethods::TRACK
700
- )
701
- )
702
- result[campaign['key']] = false
703
- next
704
- end
599
+ next if campaign_goal_already_tracked?(user_id, campaign, identifiers, goal_identifier)
600
+
601
+ @variation_decider.update_goal_identifier(user_id, campaign, variation, goal_identifier)
602
+ # set variation at user storage
705
603
 
706
604
  if defined?(@batch_events)
707
- impression = create_bulk_event_impression(
708
- @settings_file,
709
- campaign['id'],
710
- variation['id'],
711
- user_id,
712
- goal['id'],
713
- revenue_value
714
- )
605
+ impression = create_bulk_event_impression(@settings_file, campaign['id'], variation['id'], user_id, goal['id'], revenue_value)
715
606
  @batch_events_queue.enqueue(impression)
716
- elsif is_event_arch_enabled
607
+ elsif event_arch_enabled?
717
608
  metric_map[campaign['id']] = goal['id']
718
- if goal['type'] == GoalTypes::REVENUE && !(revenue_props.include? goal['revenueProp'])
719
- revenue_props << goal['revenueProp']
720
- end
609
+ revenue_props << goal['revenueProp'] if goal['type'] == GoalTypes::REVENUE && !(revenue_props.include? goal['revenueProp'])
610
+ elsif campaigns.count == 1
611
+ impression = create_impression(@settings_file, campaign['id'], variation['id'], user_id, @sdk_key, goal['id'], revenue_value)
612
+ main_keys = { 'campaignId' => campaign['id'], 'variationId' => variation['id'], 'goalId' => goal['id'] }
613
+ @event_dispatcher.dispatch(impression, main_keys, EVENTS::TRACK_GOAL)
721
614
  else
722
- impression = create_impression(
723
- @settings_file,
724
- campaign['id'],
725
- variation['id'],
726
- user_id,
727
- @sdk_key,
728
- goal['id'],
729
- revenue_value
730
- )
731
- if @event_dispatcher.dispatch(impression)
732
- @logger.log(
733
- LogLevelEnum::INFO,
734
- format(
735
- LogMessageEnum::InfoMessages::IMPRESSION_SUCCESS,
736
- file: FILE,
737
- account_id: @account_id,
738
- campaign_id: campaign['id'],
739
- variation_id: variation['id'],
740
- end_point: EVENTS::TRACK_GOAL
741
- )
742
- )
743
- @logger.log(
744
- LogLevelEnum::INFO,
745
- format(
746
- LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_IMPRESSION,
747
- file: FILE,
748
- campaign_id: impression[:experiment_id],
749
- account_id: impression[:account_id],
750
- variation_id: impression[:combination]
751
- )
752
- )
753
- end
615
+ batch_event_data['ev'] << create_bulk_event_impression(@settings_file, campaign['id'], variation['id'], user_id, goal['id'], revenue_value)
754
616
  end
755
617
  result[campaign['key']] = true
756
618
  next
757
619
  end
758
- result[campaign['key']] = false
759
620
  rescue StandardError => e
760
621
  @logger.log(
761
622
  LogLevelEnum::ERROR,
762
- format(
763
- e.message,
764
- file: FILE,
765
- exception: e
766
- )
623
+ "({file}): {api} API error: #{e.message}",
624
+ {
625
+ '{file}' => FILE,
626
+ '{api}' => ApiMethods::TRACK
627
+ }
767
628
  )
768
629
  end
769
630
  end
770
631
 
771
- if is_event_arch_enabled
632
+ if event_arch_enabled?
772
633
  properties = get_events_base_properties(@settings_file, goal_identifier)
773
634
  payload = get_track_goal_payload_data(@settings_file, user_id, goal_identifier, revenue_value, metric_map, revenue_props)
774
635
  @event_dispatcher.dispatch_event_arch_post(properties, payload)
636
+ elsif batch_event_data['ev'].count != 0
637
+ paramters = get_batch_event_query_params(@settings_file['accountId'], @sdk_key, @usage_stats.usage_stats)
638
+ batch_events_dispatcher = VWO::Services::BatchEventsDispatcher.new(@is_development_mode)
639
+ return nil unless batch_events_dispatcher.dispatch(batch_event_data, nil, paramters)
775
640
  end
776
641
 
777
- if result.length() == 0
778
- return nil
779
- end
642
+ return nil if result.length == 0
780
643
 
781
644
  result
782
645
  rescue StandardError => e
783
646
  @logger.log(
784
647
  LogLevelEnum::ERROR,
785
- format(
786
- LogMessageEnum::ErrorMessages::API_NOT_WORKING,
787
- file: FILE,
788
- api_name: ApiMethods::TRACK,
789
- exception: e
790
- )
648
+ "({file}): {api} API error: #{e.message}",
649
+ {
650
+ '{file}' => FILE,
651
+ '{api}' => ApiMethods::TRACK
652
+ }
791
653
  )
792
654
  false
793
655
  end
794
-
795
656
  # This API method: Identifies whether the user becomes a part of feature rollout/test or not.
796
657
  # 1. Validates the arguments being passed
797
658
  # 2. Checks if user is eligible to get bucketed into the feature test/rollout,
@@ -806,18 +667,17 @@ class VWO
806
667
  # @return[Boolean] true if user becomes part of feature test/rollout, otherwise false.
807
668
 
808
669
  def feature_enabled?(campaign_key, user_id, options = {})
809
- if is_opted_out(ApiMethods::IS_FEATURE_ENABLED)
810
- return false
811
- end
670
+ @logger.set_api_name(ApiMethods::IS_FEATURE_ENABLED)
671
+ return false if opted_out?(ApiMethods::IS_FEATURE_ENABLED)
812
672
 
813
673
  unless @is_instance_valid
814
674
  @logger.log(
815
675
  LogLevelEnum::ERROR,
816
- format(
817
- LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
818
- file: FILE,
819
- api_name: ApiMethods::IS_FEATURE_ENABLED
820
- )
676
+ 'CONFIG_CORRUPTED',
677
+ {
678
+ '{file}' => FILE,
679
+ '{api}' => ApiMethods::IS_FEATURE_ENABLED
680
+ }
821
681
  )
822
682
  return false
823
683
  end
@@ -826,25 +686,17 @@ class VWO
826
686
  # Retrieve custom variables
827
687
  custom_variables = options[:custom_variables]
828
688
  variation_targeting_variables = options[:variation_targeting_variables]
829
- @logger.log(
830
- LogLevelEnum::INFO,
831
- format(
832
- LogMessageEnum::InfoMessages::API_CALLED,
833
- file: FILE,
834
- api_name: ApiMethods::IS_FEATURE_ENABLED,
835
- user_id: user_id
836
- )
837
- )
689
+
838
690
  # Validate input parameters
839
691
  unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
840
- (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
692
+ (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
841
693
  @logger.log(
842
694
  LogLevelEnum::ERROR,
843
- format(
844
- LogMessageEnum::ErrorMessages::IS_FEATURE_ENABLED_API_INVALID_PARAMS,
845
- api_name: ApiMethods::IS_FEATURE_ENABLED,
846
- file: FILE
847
- )
695
+ 'API_BAD_PARAMETERS',
696
+ {
697
+ '{file}' => FILE,
698
+ '{api}' => ApiMethods::IS_FEATURE_ENABLED
699
+ }
848
700
  )
849
701
  return false
850
702
  end
@@ -856,13 +708,13 @@ class VWO
856
708
  unless campaign && campaign['status'] == STATUS_RUNNING
857
709
  # log error
858
710
  @logger.log(
859
- LogLevelEnum::ERROR,
860
- format(
861
- LogMessageEnum::ErrorMessages::CAMPAIGN_NOT_RUNNING,
862
- file: FILE,
863
- campaign_key: campaign_key,
864
- api_name: ApiMethods::IS_FEATURE_ENABLED
865
- )
711
+ LogLevelEnum::WARNING,
712
+ 'CAMPAIGN_NOT_RUNNING',
713
+ {
714
+ '{file}' => FILE,
715
+ '{campaignKey}' => campaign_key,
716
+ '{api}' => ApiMethods::IS_FEATURE_ENABLED
717
+ }
866
718
  )
867
719
  return false
868
720
  end
@@ -873,14 +725,14 @@ class VWO
873
725
  if campaign_type == CampaignTypes::VISUAL_AB
874
726
  @logger.log(
875
727
  LogLevelEnum::ERROR,
876
- format(
877
- LogMessageEnum::ErrorMessages::INVALID_API,
878
- file: FILE,
879
- api_name: ApiMethods::IS_FEATURE_ENABLED,
880
- user_id: user_id,
881
- campaign_key: campaign_key,
882
- campaign_type: campaign_type
883
- )
728
+ 'API_NOT_APPLICABLE',
729
+ {
730
+ '{file}' => FILE,
731
+ '{api}' => ApiMethods::IS_FEATURE_ENABLED,
732
+ '{userId}' => user_id,
733
+ '{campaignKey}' => campaign_key,
734
+ '{campaignType}' => campaign_type
735
+ }
884
736
  )
885
737
  return false
886
738
  end
@@ -893,7 +745,7 @@ class VWO
893
745
 
894
746
  # if campaign type is feature_test Send track call to server
895
747
 
896
- if is_eligible_to_send_impression()
748
+ if eligible_to_send_impression?
897
749
  if defined?(@batch_events)
898
750
  impression = create_bulk_event_impression(
899
751
  @settings_file,
@@ -902,7 +754,7 @@ class VWO
902
754
  user_id
903
755
  )
904
756
  @batch_events_queue.enqueue(impression)
905
- elsif is_event_arch_enabled
757
+ elsif event_arch_enabled?
906
758
  properties = get_events_base_properties(@settings_file, EventEnum::VWO_VARIATION_SHOWN, @usage_stats.usage_stats)
907
759
  payload = get_track_user_payload_data(@settings_file, user_id, EventEnum::VWO_VARIATION_SHOWN, campaign['id'], variation['id'])
908
760
  @event_dispatcher.dispatch_event_arch_post(properties, payload)
@@ -918,58 +770,49 @@ class VWO
918
770
  usage_stats: @usage_stats.usage_stats
919
771
  )
920
772
 
921
- @event_dispatcher.dispatch(impression)
922
- @logger.log(
923
- LogLevelEnum::INFO,
924
- format(
925
- LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_IMPRESSION,
926
- file: FILE,
927
- campaign_id: impression[:experiment_id],
928
- account_id: impression[:account_id],
929
- variation_id: impression[:combination]
930
- )
931
- )
773
+ main_keys = { 'campaignId' => impression[:experiment_id] }
774
+ @event_dispatcher.dispatch(impression, main_keys, EVENTS::TRACK_USER)
932
775
  end
933
776
 
934
777
  else
935
778
  @logger.log(
936
779
  LogLevelEnum::INFO,
937
- format(
938
- LogMessageEnum::InfoMessages::USER_ALREADY_TRACKED,
939
- file: FILE,
940
- user_id: user_id,
941
- campaign_key: campaign_key,
942
- api_name: ApiMethods::IS_FEATURE_ENABLED
943
- )
780
+ 'CAMPAIGN_USER_ALREADY_TRACKED',
781
+ {
782
+ '{file}' => FILE,
783
+ '{userId}' => user_id,
784
+ '{campaignKey}' => campaign_key,
785
+ '{api}' => ApiMethods::IS_FEATURE_ENABLED
786
+ }
944
787
  )
945
788
  end
946
- if campaign_type == CampaignTypes::FEATURE_ROLLOUT
947
- result = true
948
- else
949
- result = variation['isFeatureEnabled']
950
- end
789
+ result = if campaign_type == CampaignTypes::FEATURE_ROLLOUT
790
+ true
791
+ else
792
+ variation['isFeatureEnabled']
793
+ end
951
794
 
952
795
  if result
953
796
  @logger.log(
954
797
  LogLevelEnum::INFO,
955
- format(
956
- LogMessageEnum::InfoMessages::FEATURE_ENABLED_FOR_USER,
957
- file: FILE,
958
- user_id: user_id,
959
- feature_key: campaign_key,
960
- api_name: ApiMethods::IS_FEATURE_ENABLED
961
- )
798
+ 'FEATURE_STATUS',
799
+ {
800
+ '{file}' => FILE,
801
+ '{userId}' => user_id,
802
+ '{campaignKey}' => campaign_key,
803
+ '{status}' => 'enabled'
804
+ }
962
805
  )
963
806
  else
964
807
  @logger.log(
965
808
  LogLevelEnum::INFO,
966
- format(
967
- LogMessageEnum::InfoMessages::FEATURE_NOT_ENABLED_FOR_USER,
968
- file: FILE,
969
- user_id: user_id,
970
- feature_key: campaign_key,
971
- api_name: ApiMethods::IS_FEATURE_ENABLED
972
- )
809
+ 'FEATURE_STATUS',
810
+ {
811
+ '{file}' => FILE,
812
+ '{userId}' => user_id,
813
+ '{campaignKey}' => campaign_key,
814
+ '{status}' => 'disabled'
815
+ }
973
816
  )
974
817
  end
975
818
 
@@ -977,12 +820,11 @@ class VWO
977
820
  rescue StandardError => e
978
821
  @logger.log(
979
822
  LogLevelEnum::ERROR,
980
- format(
981
- LogMessageEnum::ErrorMessages::API_NOT_WORKING,
982
- file: FILE,
983
- api_name: ApiMethods::IS_FEATURE_ENABLED,
984
- exception: e
985
- )
823
+ "({file}): {api} API error: #{e.message}",
824
+ {
825
+ '{file}' => FILE,
826
+ '{api}' => ApiMethods::IS_FEATURE_ENABLED
827
+ }
986
828
  )
987
829
  false
988
830
  end
@@ -1007,18 +849,17 @@ class VWO
1007
849
  #
1008
850
 
1009
851
  def get_feature_variable_value(campaign_key, variable_key, user_id, options = {})
1010
- if is_opted_out(ApiMethods::GET_FEATURE_VARIABLE_VALUE)
1011
- return nil
1012
- end
852
+ @logger.set_api_name(ApiMethods::GET_FEATURE_VARIABLE_VALUE)
853
+ return nil if opted_out?(ApiMethods::GET_FEATURE_VARIABLE_VALUE)
1013
854
 
1014
855
  unless @is_instance_valid
1015
856
  @logger.log(
1016
857
  LogLevelEnum::ERROR,
1017
- format(
1018
- LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
1019
- file: FILE,
1020
- api_name: ApiMethods::GET_FEATURE_VARIABLE_VALUE
1021
- )
858
+ 'CONFIG_CORRUPTED',
859
+ {
860
+ '{file}' => FILE,
861
+ '{api}' => ApiMethods::GET_FEATURE_VARIABLE_VALUE
862
+ }
1022
863
  )
1023
864
  return
1024
865
  end
@@ -1029,14 +870,14 @@ class VWO
1029
870
  variation_targeting_variables = options[:variation_targeting_variables]
1030
871
 
1031
872
  unless valid_string?(campaign_key) && valid_string?(variable_key) && valid_string?(user_id) &&
1032
- (custom_variables.nil? || valid_hash?(custom_variables)) && (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
873
+ (custom_variables.nil? || valid_hash?(custom_variables)) && (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
1033
874
  @logger.log(
1034
875
  LogLevelEnum::ERROR,
1035
- format(
1036
- LogMessageEnum::ErrorMessages::GET_FEATURE_VARIABLE_VALUE_API_INVALID_PARAMS,
1037
- file: FILE,
1038
- api_name: ApiMethods::GET_FEATURE_VARIABLE_VALUE
1039
- )
876
+ 'API_BAD_PARAMETERS',
877
+ {
878
+ '{file}' => FILE,
879
+ '{api}' => ApiMethods::GET_FEATURE_VARIABLE_VALUE
880
+ }
1040
881
  )
1041
882
  return
1042
883
  end
@@ -1048,13 +889,13 @@ class VWO
1048
889
  unless campaign && campaign['status'] == STATUS_RUNNING
1049
890
  # log error
1050
891
  @logger.log(
1051
- LogLevelEnum::ERROR,
1052
- format(
1053
- LogMessageEnum::ErrorMessages::CAMPAIGN_NOT_RUNNING,
1054
- file: FILE,
1055
- campaign_key: campaign_key,
1056
- api_name: ApiMethods::GET_FEATURE_VARIABLE_VALUE
1057
- )
892
+ LogLevelEnum::WARNING,
893
+ 'CAMPAIGN_NOT_RUNNING',
894
+ {
895
+ '{file}' => FILE,
896
+ '{campaignKey}' => campaign_key,
897
+ '{api}' => ApiMethods::GET_FEATURE_VARIABLE_VALUE
898
+ }
1058
899
  )
1059
900
  return
1060
901
  end
@@ -1064,14 +905,14 @@ class VWO
1064
905
  if campaign_type == CampaignTypes::VISUAL_AB
1065
906
  @logger.log(
1066
907
  LogLevelEnum::ERROR,
1067
- format(
1068
- LogMessageEnum::ErrorMessages::INVALID_API,
1069
- file: FILE,
1070
- api_name: ApiMethods::GET_FEATURE_VARIABLE_VALUE,
1071
- campaign_key: campaign_key,
1072
- campaign_type: campaign_type,
1073
- user_id: user_id
1074
- )
908
+ 'API_NOT_APPLICABLE',
909
+ {
910
+ '{file}' => FILE,
911
+ '{api}' => ApiMethods::GET_FEATURE_VARIABLE_VALUE,
912
+ '{userId}' => user_id,
913
+ '{campaignKey}' => campaign_key,
914
+ '{campaignType}' => campaign_type
915
+ }
1075
916
  )
1076
917
  return
1077
918
  end
@@ -1081,31 +922,32 @@ class VWO
1081
922
  # Check if variation has been assigned to user
1082
923
  return unless variation
1083
924
 
1084
- if campaign_type == CampaignTypes::FEATURE_ROLLOUT
925
+ case campaign_type
926
+ when CampaignTypes::FEATURE_ROLLOUT
1085
927
  variables = campaign['variables']
1086
- elsif campaign_type == CampaignTypes::FEATURE_TEST
928
+ when CampaignTypes::FEATURE_TEST
1087
929
  if !variation['isFeatureEnabled']
1088
930
  @logger.log(
1089
931
  LogLevelEnum::INFO,
1090
- format(
1091
- LogMessageEnum::InfoMessages::FEATURE_NOT_ENABLED_FOR_USER,
1092
- file: FILE,
1093
- feature_key: campaign_key,
1094
- user_id: user_id,
1095
- api_name: ApiMethods::GET_FEATURE_VARIABLE_VALUE
1096
- )
932
+ 'FEATURE_STATUS',
933
+ {
934
+ '{file}' => FILE,
935
+ '{userId}' => user_id,
936
+ '{campaignKey}' => campaign_key,
937
+ '{status}' => 'disabled'
938
+ }
1097
939
  )
1098
940
  variation = get_control_variation(campaign)
1099
941
  else
1100
942
  @logger.log(
1101
943
  LogLevelEnum::INFO,
1102
- format(
1103
- LogMessageEnum::InfoMessages::FEATURE_ENABLED_FOR_USER,
1104
- file: FILE,
1105
- feature_key: campaign_key,
1106
- user_id: user_id,
1107
- api_name: ApiMethods::GET_FEATURE_VARIABLE_VALUE
1108
- )
944
+ 'FEATURE_STATUS',
945
+ {
946
+ '{file}' => FILE,
947
+ '{userId}' => user_id,
948
+ '{campaignKey}' => campaign_key,
949
+ '{status}' => 'enabled'
950
+ }
1109
951
  )
1110
952
  end
1111
953
  variables = variation['variables']
@@ -1115,43 +957,37 @@ class VWO
1115
957
  unless variable
1116
958
  # Log variable not found
1117
959
  @logger.log(
1118
- LogLevelEnum::ERROR,
1119
- format(
1120
- LogMessageEnum::ErrorMessages::VARIABLE_NOT_FOUND,
1121
- file: FILE,
1122
- variable_key: variable_key,
1123
- campaign_key: campaign_key,
1124
- campaign_type: campaign_type,
1125
- user_id: user_id,
1126
- api_name: ApiMethods::GET_FEATURE_VARIABLE_VALUE
1127
- )
960
+ LogLevelEnum::INFO,
961
+ 'FEATURE_VARIABLE_DEFAULT_VALUE',
962
+ {
963
+ '{file}' => FILE,
964
+ '{variableKey}' => variable_key,
965
+ '{variationName}' => variation['name']
966
+ }
1128
967
  )
1129
968
  return
1130
969
  end
1131
970
 
1132
971
  @logger.log(
1133
972
  LogLevelEnum::INFO,
1134
- format(
1135
- LogMessageEnum::InfoMessages::VARIABLE_FOUND,
1136
- file: FILE,
1137
- variable_key: variable_key,
1138
- variable_value: variable['value'],
1139
- campaign_key: campaign_key,
1140
- campaign_type: campaign_type,
1141
- user_id: user_id,
1142
- api_name: ApiMethods::GET_FEATURE_VARIABLE_VALUE
1143
- )
973
+ 'FEATURE_VARIABLE_VALUE',
974
+ {
975
+ '{file}' => FILE,
976
+ '{variableKey}' => variable_key,
977
+ '{variableValue}' => variable['value'],
978
+ '{campaignKey}' => campaign_key,
979
+ '{userId}' => user_id
980
+ }
1144
981
  )
1145
982
  get_type_casted_feature_value(variable['value'], variable['type'])
1146
983
  rescue StandardError => e
1147
984
  @logger.log(
1148
985
  LogLevelEnum::ERROR,
1149
- format(
1150
- LogMessageEnum::ErrorMessages::API_NOT_WORKING,
1151
- file: FILE,
1152
- api_name: ApiMethods::GET_FEATURE_VARIABLE_VALUE,
1153
- exception: e
1154
- )
986
+ "({file}): {api} API error: #{e.message}",
987
+ {
988
+ '{file}' => FILE,
989
+ '{api}' => ApiMethods::GET_FEATURE_VARIABLE_VALUE
990
+ }
1155
991
  )
1156
992
  nil
1157
993
  end
@@ -1165,20 +1001,19 @@ class VWO
1165
1001
  # @return true if call is made successfully, else false
1166
1002
 
1167
1003
  def push(tag_key, tag_value, user_id = nil)
1168
- if is_opted_out(ApiMethods::PUSH)
1169
- return false
1170
- end
1004
+ @logger.set_api_name(ApiMethods::PUSH)
1005
+ return {} if opted_out?(ApiMethods::PUSH)
1171
1006
 
1172
1007
  unless @is_instance_valid
1173
1008
  @logger.log(
1174
1009
  LogLevelEnum::ERROR,
1175
- format(
1176
- LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
1177
- file: FILE,
1178
- api_name: ApiMethods::PUSH
1179
- )
1010
+ 'CONFIG_CORRUPTED',
1011
+ {
1012
+ '{file}' => FILE,
1013
+ '{api}' => ApiMethods::PUSH
1014
+ }
1180
1015
  )
1181
- return false
1016
+ return {}
1182
1017
  end
1183
1018
 
1184
1019
  # Argument reshuffling.
@@ -1190,105 +1025,124 @@ class VWO
1190
1025
  custom_dimension_map[tag_key.to_sym] = tag_value
1191
1026
  end
1192
1027
 
1193
- unless (valid_string?(tag_key) || valid_hash?(tag_key)) && valid_string?(tag_value) && valid_string?(user_id)
1028
+ unless (valid_string?(tag_key) || valid_hash?(tag_key)) && valid_string?(user_id)
1194
1029
  @logger.log(
1195
1030
  LogLevelEnum::ERROR,
1196
- format(
1197
- LogMessageEnum::ErrorMessages::PUSH_API_INVALID_PARAMS,
1198
- file: FILE,
1199
- api_name: ApiMethods::PUSH
1200
- )
1031
+ 'API_BAD_PARAMETERS',
1032
+ {
1033
+ '{file}' => FILE,
1034
+ '{api}' => ApiMethods::PUSH
1035
+ }
1201
1036
  )
1202
- return false
1037
+ return {}
1203
1038
  end
1204
1039
 
1205
- custom_dimension_map.each do |tag_key, tag_value|
1206
- if tag_key.length > PushApi::TAG_KEY_LENGTH
1207
- @logger.log(
1208
- LogLevelEnum::ERROR,
1209
- format(
1210
- LogMessageEnum::ErrorMessages::TAG_KEY_LENGTH_EXCEEDED,
1211
- file: FILE,
1212
- user_id: user_id,
1213
- tag_key: tag_key,
1214
- api_name: ApiMethods::PUSH
1215
- )
1216
- )
1217
- return false
1040
+ result = {}
1041
+ custom_dimension_map.each do |tagkey, tagvalue|
1042
+ if !tagkey.is_a?(Symbol) || !tagvalue.is_a?(String)
1043
+ custom_dimension_map.delete(tagkey)
1044
+ result[tagkey] = false
1045
+ next
1218
1046
  end
1219
1047
 
1220
- if tag_value.length > PushApi::TAG_VALUE_LENGTH
1048
+ if tagkey.length > PushApi::TAG_KEY_LENGTH || tagkey.length == 0
1221
1049
  @logger.log(
1222
1050
  LogLevelEnum::ERROR,
1223
- format(
1224
- LogMessageEnum::ErrorMessages::TAG_VALUE_LENGTH_EXCEEDED,
1225
- file: FILE,
1226
- user_id: user_id,
1227
- tag_value: tag_value,
1228
- api_name: ApiMethods::PUSH
1229
- )
1051
+ 'TAG_KEY_LENGTH_EXCEEDED',
1052
+ {
1053
+ '{file}' => FILE,
1054
+ '{userId}' => user_id,
1055
+ '{tagKey}' => tagkey
1056
+ }
1230
1057
  )
1231
- return false
1058
+ custom_dimension_map.delete(tagkey)
1059
+ result[tagkey] = false
1060
+ next
1232
1061
  end
1062
+
1063
+ next unless tagvalue.length > PushApi::TAG_VALUE_LENGTH || tagvalue.length == 0
1064
+
1065
+ @logger.log(
1066
+ LogLevelEnum::ERROR,
1067
+ 'TAG_VALUE_LENGTH_EXCEEDED',
1068
+ {
1069
+ '{file}' => FILE,
1070
+ '{userId}' => user_id,
1071
+ '{tagKey}' => tagkey,
1072
+ '{tagValue}' => tagvalue
1073
+ }
1074
+ )
1075
+ custom_dimension_map.delete(tagkey)
1076
+ result[tagkey] = false
1077
+ end
1078
+
1079
+ if custom_dimension_map.count == 0
1080
+ @logger.log(
1081
+ LogLevelEnum::ERROR,
1082
+ 'API_BAD_PARAMETERS',
1083
+ {
1084
+ '{file}' => FILE,
1085
+ '{api}' => ApiMethods::PUSH
1086
+ }
1087
+ )
1088
+ return result
1233
1089
  end
1234
1090
 
1235
1091
  if defined?(@batch_events)
1236
- custom_dimension_map.each do |tag_key, tag_value|
1237
- impression = get_batch_event_url_params(@settings_file, tag_key, tag_value, user_id)
1092
+ custom_dimension_map.each do |tagkey, tagvalue|
1093
+ impression = get_batch_event_url_params(@settings_file, tagkey, tagvalue, user_id)
1238
1094
  @batch_events_queue.enqueue(impression)
1239
1095
  end
1240
- elsif is_event_arch_enabled
1096
+ resp = true
1097
+ elsif event_arch_enabled?
1241
1098
  properties = get_events_base_properties(@settings_file, EventEnum::VWO_SYNC_VISITOR_PROP)
1242
1099
  payload = get_push_payload_data(@settings_file, user_id, EventEnum::VWO_SYNC_VISITOR_PROP, custom_dimension_map)
1243
- @event_dispatcher.dispatch_event_arch_post(properties, payload)
1100
+ resp = @event_dispatcher.dispatch_event_arch_post(properties, payload)
1101
+ elsif custom_dimension_map.count == 1
1102
+ custom_dimension_map.each do |tagkey, tagvalue|
1103
+ impression = get_url_params(@settings_file, tagkey, tagvalue, user_id, @sdk_key)
1104
+ main_keys = { 'tags' => impression['tags'] }
1105
+ result[tagkey] = @event_dispatcher.dispatch(impression, main_keys, EVENTS::PUSH)
1106
+ end
1107
+ resp = true
1244
1108
  else
1245
- custom_dimension_map.each do |tag_key, tag_value|
1246
- impression = get_url_params(@settings_file, tag_key, tag_value, user_id, @sdk_key)
1247
- @event_dispatcher.dispatch(impression)
1248
-
1249
- @logger.log(
1250
- LogLevelEnum::INFO,
1251
- format(
1252
- LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_PUSH_API,
1253
- file: FILE,
1254
- u: impression['u'],
1255
- account_id: impression['account_id'],
1256
- tags: impression['tags']
1257
- )
1258
- )
1109
+ batch_event_data = { 'ev' => [] }
1110
+ custom_dimension_map.each do |tagkey, tagvalue|
1111
+ batch_event_data['ev'] << get_batch_event_url_params(@settings_file, tagkey, tagvalue, user_id)
1259
1112
  end
1113
+ paramters = get_batch_event_query_params(@settings_file['accountId'], @sdk_key, @usage_stats.usage_stats)
1114
+ batch_events_dispatcher = VWO::Services::BatchEventsDispatcher.new(@is_development_mode)
1115
+ resp = batch_events_dispatcher.dispatch(batch_event_data, nil, paramters)
1260
1116
  end
1261
- true
1117
+
1118
+ prepare_push_response(custom_dimension_map, resp, result)
1262
1119
  rescue StandardError => e
1263
1120
  @logger.log(
1264
1121
  LogLevelEnum::ERROR,
1265
- format(
1266
- LogMessageEnum::ErrorMessages::API_NOT_WORKING,
1267
- file: FILE,
1268
- api_name: ApiMethods::PUSH,
1269
- exception: e
1270
- )
1122
+ "({file}): push API error: #{e.message}",
1123
+ { '{file}' => FILE }
1271
1124
  )
1272
1125
  false
1273
1126
  end
1274
1127
 
1275
- def is_eligible_to_send_impression()
1128
+ def eligible_to_send_impression?
1276
1129
  !@user_storage || !@variation_decider.has_stored_variation
1277
1130
  end
1278
1131
 
1132
+ # Manually flush impression events to VWO which are queued in batch queue as per batchEvents config
1133
+ # @return[bool]
1279
1134
  def flush_events
1280
- if is_opted_out(ApiMethods::FLUSH_EVENTS)
1281
- return false
1282
- end
1135
+ @logger.set_api_name(ApiMethods::FLUSH_EVENTS)
1136
+ return false if opted_out?(ApiMethods::FLUSH_EVENTS)
1283
1137
 
1284
1138
  unless @is_instance_valid
1285
1139
  @logger.log(
1286
1140
  LogLevelEnum::ERROR,
1287
- format(
1288
- LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
1289
- file: FILE,
1290
- api_name: ApiMethods::FLUSH_EVENTS
1291
- )
1141
+ 'CONFIG_CORRUPTED',
1142
+ {
1143
+ '{file}' => FILE,
1144
+ '{api}' => ApiMethods::FLUSH_EVENTS
1145
+ }
1292
1146
  )
1293
1147
  return false
1294
1148
  end
@@ -1301,12 +1155,11 @@ class VWO
1301
1155
  rescue StandardError => e
1302
1156
  @logger.log(
1303
1157
  LogLevelEnum::ERROR,
1304
- format(
1305
- LogMessageEnum::ErrorMessages::API_NOT_WORKING,
1306
- file: FILE,
1307
- api_name: ApiMethods::FLUSH_EVENTS,
1308
- exception: e
1309
- )
1158
+ "({file}): {api} API error: #{e.message}",
1159
+ {
1160
+ '{file}' => FILE,
1161
+ '{api}' => ApiMethods::FLUSH_EVENTS
1162
+ }
1310
1163
  )
1311
1164
  false
1312
1165
  end
@@ -1314,20 +1167,19 @@ class VWO
1314
1167
  def get_goal_type_to_track(options)
1315
1168
  goal_type_to_track = nil
1316
1169
  if !options.key?(:goal_type_to_track)
1317
- if @goal_type_to_track
1318
- goal_type_to_track = @goal_type_to_track
1319
- else
1320
- goal_type_to_track = GOAL_TYPES['ALL']
1321
- end
1170
+ goal_type_to_track = @goal_type_to_track || GOAL_TYPES['ALL']
1322
1171
  elsif GOAL_TYPES.key? options[:goal_type_to_track]
1323
1172
  goal_type_to_track = options[:goal_type_to_track]
1324
1173
  else
1325
1174
  @logger.log(
1326
1175
  LogLevelEnum::ERROR,
1327
- format(
1328
- LogMessageEnum::ErrorMessages::INVALID_GOAL_TYPE,
1329
- file: FILE
1330
- )
1176
+ 'CONFIG_PARAMETER_INVALID',
1177
+ {
1178
+ '{file}' => FILE,
1179
+ '{parameter}' => 'goal_type_to_track',
1180
+ '{type}' => 'string(REVENUE, CUSTOM, ALL)',
1181
+ '{api}' => 'init'
1182
+ }
1331
1183
  )
1332
1184
  end
1333
1185
  goal_type_to_track
@@ -1338,51 +1190,51 @@ class VWO
1338
1190
  # return[bool]
1339
1191
  #
1340
1192
  def set_opt_out
1193
+ @logger.set_api_name(ApiMethods::OPT_OUT)
1341
1194
  @logger.log(
1342
- LogLevelEnum::INFO,
1343
- format(
1344
- LogMessageEnum::InfoMessages::OPT_OUT_API_CALLED,
1345
- file: FILE
1346
- )
1347
- )
1348
- if defined?(@batch_events) && !@batch_events_queue.nil?
1349
- @batch_events_queue.flush(manual: true)
1350
- @batch_events_queue.kill_thread
1351
- end
1195
+ LogLevelEnum::INFO,
1196
+ 'OPT_OUT_API_CALLED',
1197
+ {
1198
+ '{file}' => FILE
1199
+ }
1200
+ )
1201
+ if defined?(@batch_events) && !@batch_events_queue.nil?
1202
+ @batch_events_queue.flush(manual: true)
1203
+ @batch_events_queue.kill_thread
1204
+ end
1352
1205
 
1353
- @is_opted_out = true
1354
- @settings_file = nil
1355
- @user_storage = nil
1356
- @event_dispatcher = nil
1357
- @variation_decider = nil
1358
- @config = nil
1359
- @usage_stats = nil
1360
- @batch_event_dispatcher = nil
1361
- @batch_events_queue = nil
1362
- @batch_events = nil
1363
-
1364
- return @is_opted_out
1206
+ @is_opted_out = true
1207
+ @settings_file = nil
1208
+ @user_storage = nil
1209
+ @event_dispatcher = nil
1210
+ @variation_decider = nil
1211
+ @config = nil
1212
+ @usage_stats = nil
1213
+ @batch_event_dispatcher = nil
1214
+ @batch_events_queue = nil
1215
+ @batch_events = nil
1216
+
1217
+ @is_opted_out
1365
1218
  end
1366
1219
 
1367
-
1368
1220
  # Check if VWO SDK is manually opted out
1369
1221
  # @param[String] :api_name api_name is used in logging
1370
1222
  # @return[bool]
1371
- def is_opted_out(api_name)
1223
+ def opted_out?(api_name)
1372
1224
  if @is_opted_out
1373
1225
  @logger.log(
1374
1226
  LogLevelEnum::INFO,
1375
- format(
1376
- LogMessageEnum::InfoMessages::API_NOT_ENABLED,
1377
- file: FILE,
1378
- api: api_name
1379
- )
1227
+ 'API_NOT_ENABLED',
1228
+ {
1229
+ '{file}' => FILE,
1230
+ '{api}' => api_name
1231
+ }
1380
1232
  )
1381
1233
  end
1382
- return @is_opted_out
1234
+ @is_opted_out
1383
1235
  end
1384
1236
 
1385
- def is_event_arch_enabled
1386
- return @settings_file.key?('isEventArchEnabled') && @settings_file['isEventArchEnabled']
1237
+ def event_arch_enabled?
1238
+ @settings_file.key?('isEventArchEnabled') && @settings_file['isEventArchEnabled']
1387
1239
  end
1388
1240
  end