vwo-sdk 1.30.0 → 1.37.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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