vwo-sdk 1.15.0 → 1.23.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.
@@ -66,6 +66,8 @@ class VWO
66
66
 
67
67
  return unless campaign
68
68
 
69
+ is_campaign_part_of_group = @settings_file && is_part_of_group(@settings_file, campaign["id"])
70
+
69
71
  @has_stored_variation = false
70
72
  decision = {
71
73
  :campaign_id => campaign['id'],
@@ -93,62 +95,17 @@ class VWO
93
95
  :vwo_user_id => generator_for(user_id, @settings_file['accountId'])
94
96
  }
95
97
 
96
- if campaign['isForcedVariationEnabled']
97
- variation = evaluate_whitelisting(
98
- user_id,
99
- campaign,
100
- api_name,
101
- campaign_key,
102
- variation_targeting_variables
103
- )
104
- status = if variation
105
- StatusEnum::PASSED
106
- else
107
- StatusEnum::FAILED
108
- end
109
-
110
- @logger.log(
111
- LogLevelEnum::INFO,
112
- format(
113
- LogMessageEnum::InfoMessages::SEGMENTATION_STATUS,
114
- file: FILE,
115
- campaign_key: campaign_key,
116
- user_id: user_id,
117
- status: status,
118
- custom_variables: variation_targeting_variables,
119
- variation_name: status == StatusEnum::PASSED ? "and #{variation['name']} is Assigned" : ' ',
120
- segmentation_type: SegmentationTypeEnum::WHITELISTING,
121
- api_name: api_name
122
- )
123
- )
124
-
125
- if variation
126
- if campaign['type'] == CampaignTypes::VISUAL_AB || campaign['type'] == CampaignTypes::FEATURE_TEST
127
- decision[:variation_name] = variation['name']
128
- decision[:variation_id] = variation['id']
129
- if campaign['type'] == CampaignTypes::FEATURE_TEST
130
- decision[:is_feature_enabled] = variation['isFeatureEnabled']
131
- elsif campaign['type'] == CampaignTypes::VISUAL_AB
132
- decision[:is_user_whitelisted] = !!variation['name']
133
- end
134
- end
135
- @hooks_manager.execute(decision)
136
- end
137
-
138
- return variation if variation && variation['name']
139
- else
140
- @logger.log(
141
- LogLevelEnum::INFO,
142
- format(
143
- LogMessageEnum::InfoMessages::WHITELISTING_SKIPPED,
144
- file: FILE,
145
- campaign_key: campaign_key,
146
- user_id: user_id,
147
- api_name: api_name
148
- )
149
- )
98
+ if is_campaign_part_of_group
99
+ group_id = @settings_file["campaignGroups"][campaign["id"].to_s]
100
+ decision[:group_id] = group_id
101
+ group_name = @settings_file["groups"][group_id.to_s]["name"]
102
+ decision[:group_name] = group_name
150
103
  end
151
104
 
105
+ # evaluate whitelisting
106
+ variation = get_variation_if_whitelisting_passed(user_id, campaign, variation_targeting_variables, api_name, decision, true)
107
+ return variation if variation && variation['name']
108
+
152
109
  user_campaign_map = get_user_storage(user_id, campaign_key)
153
110
  variation = get_stored_variation(user_id, campaign_key, user_campaign_map) if valid_hash?(user_campaign_map)
154
111
 
@@ -194,8 +151,7 @@ class VWO
194
151
  )
195
152
  )
196
153
 
197
- if ([ApiMethods::TRACK, ApiMethods::GET_VARIATION_NAME, ApiMethods::GET_FEATURE_VARIABLE_VALUE].include? api_name) &&
198
- @user_storage_service && campaign['type'] != CampaignTypes::FEATURE_ROLLOUT
154
+ if ([ApiMethods::TRACK, ApiMethods::GET_VARIATION_NAME, ApiMethods::GET_FEATURE_VARIABLE_VALUE].include? api_name) && @user_storage_service
199
155
  @logger.log(
200
156
  LogLevelEnum::DEBUG,
201
157
  format(
@@ -223,82 +179,106 @@ class VWO
223
179
  end
224
180
 
225
181
  # Pre-segmentation
182
+ is_presegmentation = check_presegmentation(campaign, user_id, custom_variables, api_name)
183
+ is_presegmentation_and_traffic_passed = is_presegmentation && @bucketer.user_part_of_campaign?(user_id, campaign)
184
+ unless is_presegmentation_and_traffic_passed
185
+ return nil
186
+ end
226
187
 
227
- segments = get_segments(campaign)
228
- is_valid_segments = valid_value?(segments)
188
+ if is_presegmentation_and_traffic_passed && is_campaign_part_of_group
189
+ group_campaigns = get_group_campaigns(@settings_file, group_id)
190
+
191
+ if group_campaigns
192
+ is_any_campaign_whitelisted_or_stored = check_whitelisting_or_storage_for_grouped_campaigns(user_id, campaign, group_campaigns, group_name, variation_targeting_variables, true)
193
+
194
+ if is_any_campaign_whitelisted_or_stored
195
+ @logger.log(
196
+ LogLevelEnum::INFO,
197
+ format(
198
+ LogMessageEnum::InfoMessages::CALLED_CAMPAIGN_NOT_WINNER,
199
+ file: FILE,
200
+ campaign_key: campaign_key,
201
+ user_id: user_id,
202
+ group_name: group_name
203
+ )
204
+ )
205
+ return nil
206
+ end
207
+
208
+ eligible_campaigns = get_eligible_campaigns(user_id, group_campaigns, campaign, custom_variables)
209
+ non_eligible_campaigns_key = get_non_eligible_campaigns_key(eligible_campaigns, group_campaigns)
210
+
211
+ @logger.log(
212
+ LogLevelEnum::DEBUG,
213
+ format(
214
+ LogMessageEnum::DebugMessages::GOT_ELIGIBLE_CAMPAIGNS,
215
+ file: FILE,
216
+ user_id: user_id,
217
+ eligible_campaigns_key: get_eligible_campaigns_key(eligible_campaigns).join(","),
218
+ ineligible_campaigns_log_text: non_eligible_campaigns_key ? ("campaigns:" + non_eligible_campaigns_key.join("'")) : "no campaigns",
219
+ group_name: group_name
220
+ )
221
+ )
229
222
 
230
- if is_valid_segments
231
- unless custom_variables
232
223
  @logger.log(
233
224
  LogLevelEnum::INFO,
234
225
  format(
235
- LogMessageEnum::InfoMessages::NO_CUSTOM_VARIABLES,
226
+ LogMessageEnum::InfoMessages::GOT_ELIGIBLE_CAMPAIGNS,
236
227
  file: FILE,
237
- campaign_key: campaign_key,
238
228
  user_id: user_id,
239
- api_name: api_name
229
+ no_of_eligible_campaigns: eligible_campaigns.length,
230
+ no_of_group_campaigns: group_campaigns.length,
231
+ group_name: group_name
240
232
  )
241
233
  )
242
- custom_variables = {}
243
- end
244
- unless @segment_evaluator.evaluate(campaign_key, user_id, segments, custom_variables)
234
+
235
+ winner_campaign = get_winner_campaign(user_id, eligible_campaigns, group_id)
245
236
  @logger.log(
246
237
  LogLevelEnum::INFO,
247
238
  format(
248
- LogMessageEnum::InfoMessages::USER_FAILED_SEGMENTATION,
249
- file: FileNameEnum::SegmentEvaluator,
239
+ LogMessageEnum::InfoMessages::GOT_WINNER_CAMPAIGN,
240
+ file: FILE,
250
241
  user_id: user_id,
251
- campaign_key: campaign_key,
252
- custom_variables: custom_variables
242
+ campaign_key: winner_campaign["key"],
243
+ group_name: group_name
253
244
  )
254
245
  )
255
- return
246
+
247
+ if winner_campaign && winner_campaign["id"] == campaign["id"]
248
+ variation = get_variation_allotted(user_id, campaign, true)
249
+ if variation && variation['name']
250
+ save_user_storage(user_id, campaign_key, campaign['type'], variation['name'], goal_identifier, true) if variation['name']
251
+ else
252
+ return nil
253
+ end
254
+ else
255
+ @logger.log(
256
+ LogLevelEnum::INFO,
257
+ format(
258
+ LogMessageEnum::InfoMessages::CALLED_CAMPAIGN_NOT_WINNER,
259
+ file: FILE,
260
+ campaign_key: campaign_key,
261
+ user_id: user_id,
262
+ group_name: group_name
263
+ )
264
+ )
265
+ return nil
266
+ end
256
267
  end
257
- @logger.log(
258
- LogLevelEnum::INFO,
259
- format(
260
- LogMessageEnum::InfoMessages::USER_PASSED_SEGMENTATION,
261
- file: FileNameEnum::SegmentEvaluator,
262
- user_id: user_id,
263
- campaign_key: campaign_key,
264
- custom_variables: custom_variables
265
- )
266
- )
267
- else
268
- @logger.log(
269
- LogLevelEnum::INFO,
270
- format(
271
- LogMessageEnum::InfoMessages::SKIPPING_SEGMENTATION,
272
- file: FILE,
273
- campaign_key: campaign_key,
274
- user_id: user_id,
275
- api_name: api_name,
276
- variation: ''
277
- )
278
- )
279
268
  end
280
269
 
281
- variation = get_variation_allotted(user_id, campaign)
270
+ if variation.nil?
271
+ variation = get_variation_allotted(user_id, campaign)
282
272
 
283
- if variation && variation['name']
284
- save_user_storage(user_id, campaign_key, variation['name'], goal_identifier) if variation['name']
285
-
286
- @logger.log(
287
- LogLevelEnum::INFO,
288
- format(
289
- LogMessageEnum::InfoMessages::VARIATION_ALLOCATED,
290
- file: FILE,
291
- campaign_key: campaign_key,
292
- user_id: user_id,
293
- variation_name: variation['name'],
294
- campaign_type: campaign['type']
273
+ if variation && variation['name']
274
+ save_user_storage(user_id, campaign_key, campaign['type'], variation['name'], goal_identifier) if variation['name']
275
+ else
276
+ @logger.log(
277
+ LogLevelEnum::INFO,
278
+ format(LogMessageEnum::InfoMessages::NO_VARIATION_ALLOCATED, file: FILE, campaign_key: campaign_key, user_id: user_id)
295
279
  )
296
- )
297
- else
298
- @logger.log(
299
- LogLevelEnum::INFO,
300
- format(LogMessageEnum::InfoMessages::NO_VARIATION_ALLOCATED, file: FILE, campaign_key: campaign_key, user_id: user_id)
301
- )
280
+ end
281
+
302
282
  end
303
283
 
304
284
  if variation
@@ -321,7 +301,7 @@ class VWO
321
301
  #
322
302
  # @return[Hash]
323
303
 
324
- def get_variation_allotted(user_id, campaign)
304
+ def get_variation_allotted(user_id, campaign, disable_logs = false)
325
305
  unless valid_value?(user_id)
326
306
  @logger.log(
327
307
  LogLevelEnum::ERROR,
@@ -341,7 +321,8 @@ class VWO
341
321
  user_id: user_id,
342
322
  campaign_key: campaign['key'],
343
323
  method: 'get_variation_allotted'
344
- )
324
+ ),
325
+ disable_logs
345
326
  )
346
327
  variation
347
328
  else
@@ -354,7 +335,8 @@ class VWO
354
335
  user_id: user_id,
355
336
  campaign_key: nil,
356
337
  method: 'get_variation_allotted'
357
- )
338
+ ),
339
+ disable_logs
358
340
  )
359
341
  nil
360
342
  end
@@ -413,13 +395,15 @@ class VWO
413
395
  # @param[String] :campaign_key Unique campaign identifier
414
396
  # @param[String] :variation_name Variation identifier
415
397
  # @param[String] :goal_identifier The unique campaign's goal identifier
398
+ # @param[Boolean] :disable_logs optional: disable logs if True
416
399
  # @return[Boolean] true if found otherwise false
417
400
 
418
- def save_user_storage(user_id, campaign_key, variation_name, goal_identifier)
401
+ def save_user_storage(user_id, campaign_key, campaign_type, variation_name, goal_identifier, disable_logs = false)
419
402
  unless @user_storage_service
420
403
  @logger.log(
421
404
  LogLevelEnum::DEBUG,
422
- format(LogMessageEnum::DebugMessages::NO_USER_STORAGE_SERVICE_SAVE, file: FILE)
405
+ format(LogMessageEnum::DebugMessages::NO_USER_STORAGE_SERVICE_SAVE, file: FILE),
406
+ disable_logs
423
407
  )
424
408
  return false
425
409
  end
@@ -435,13 +419,28 @@ class VWO
435
419
 
436
420
  @logger.log(
437
421
  LogLevelEnum::INFO,
438
- format(LogMessageEnum::InfoMessages::SAVING_DATA_USER_STORAGE_SERVICE, file: FILE, user_id: user_id)
422
+ format(LogMessageEnum::InfoMessages::SAVING_DATA_USER_STORAGE_SERVICE, file: FILE, user_id: user_id),
423
+ disable_logs
424
+ )
425
+
426
+ @logger.log(
427
+ LogLevelEnum::INFO,
428
+ format(
429
+ LogMessageEnum::InfoMessages::VARIATION_ALLOCATED,
430
+ file: FILE,
431
+ campaign_key: campaign_key,
432
+ user_id: user_id,
433
+ variation_name: variation_name,
434
+ campaign_type: campaign_type
435
+ ),
436
+ disable_logs
439
437
  )
440
438
  true
441
439
  rescue StandardError
442
440
  @logger.log(
443
441
  LogLevelEnum::ERROR,
444
- format(LogMessageEnum::ErrorMessages::SAVE_USER_STORAGE_SERVICE_FAILED, file: FILE, user_id: user_id)
442
+ format(LogMessageEnum::ErrorMessages::SAVE_USER_STORAGE_SERVICE_FAILED, file: FILE, user_id: user_id),
443
+ disable_logs
445
444
  )
446
445
  false
447
446
  end
@@ -455,14 +454,15 @@ class VWO
455
454
  # @param[String] :api_name The key Passed to identify the calling API
456
455
  # @param[String] :campaign_key Unique campaign key
457
456
  # @param[Hash] :variation_targeting_variables Key/value pair of Whitelisting Custom Attributes
457
+ # @param[Boolean] :disable_logs optional: disable logs if True
458
458
  #
459
459
  # @return[Hash]
460
460
 
461
- def evaluate_whitelisting(user_id, campaign, api_name, campaign_key, variation_targeting_variables = {})
461
+ def evaluate_whitelisting(user_id, campaign, api_name, campaign_key, variation_targeting_variables = {}, disable_logs = false)
462
462
  if variation_targeting_variables.nil?
463
- variation_targeting_variables = { '_vwo_user_id' => user_id }
463
+ variation_targeting_variables = { _vwo_user_id: user_id }
464
464
  else
465
- variation_targeting_variables['_vwo_user_id'] = user_id
465
+ variation_targeting_variables[:_vwo_user_id] = user_id
466
466
  end
467
467
  targeted_variations = []
468
468
 
@@ -470,7 +470,7 @@ class VWO
470
470
  segments = get_segments(variation)
471
471
  is_valid_segments = valid_value?(segments)
472
472
  if is_valid_segments
473
- if @segment_evaluator.evaluate(campaign_key, user_id, segments, variation_targeting_variables)
473
+ if @segment_evaluator.evaluate(campaign_key, user_id, segments, variation_targeting_variables, disable_logs)
474
474
  targeted_variations.push(variation)
475
475
  status = StatusEnum::PASSED
476
476
  else
@@ -485,10 +485,11 @@ class VWO
485
485
  user_id: user_id,
486
486
  status: status,
487
487
  custom_variables: variation_targeting_variables,
488
- variation_name: variation['name'],
488
+ variation_name: status == StatusEnum::PASSED ? (campaign['type'] == CampaignTypes::FEATURE_ROLLOUT ? 'and hence becomes part of the rollout' : "for " + variation['name']) : '',
489
489
  segmentation_type: SegmentationTypeEnum::WHITELISTING,
490
490
  api_name: api_name
491
- )
491
+ ),
492
+ disable_logs
492
493
  )
493
494
  else
494
495
  @logger.log(
@@ -500,7 +501,8 @@ class VWO
500
501
  user_id: user_id,
501
502
  api_name: api_name,
502
503
  variation: variation['name']
503
- )
504
+ ),
505
+ disable_logs
504
506
  )
505
507
  end
506
508
  end
@@ -525,7 +527,8 @@ class VWO
525
527
  whitelisted_variation = @bucketer.get_variation(
526
528
  targeted_variations_deep_clone,
527
529
  @bucketer.get_bucket_value_for_user(
528
- user_id
530
+ user_id,
531
+ campaign
529
532
  )
530
533
  )
531
534
  else
@@ -553,18 +556,26 @@ class VWO
553
556
  end
554
557
  end
555
558
 
559
+ def scale_campaigns_weight(campaigns)
560
+ normalize_weight = 100/campaigns.length
561
+ campaigns.each do |campaign|
562
+ campaign['weight'] = normalize_weight
563
+ end
564
+ end
556
565
  # Get the UserStorageData after looking up into get method
557
566
  # Being provided via UserStorageService
558
567
  #
559
568
  # @param[String]: Unique user identifier
560
569
  # @param[String]: Unique campaign key
570
+ # @param[Boolean] :disable_logs if True
561
571
  # @return[Hash|Boolean]: user_storage data
562
572
 
563
- def get_user_storage(user_id, campaign_key)
573
+ def get_user_storage(user_id, campaign_key, disable_logs = false)
564
574
  unless @user_storage_service
565
575
  @logger.log(
566
576
  LogLevelEnum::DEBUG,
567
- format(LogMessageEnum::DebugMessages::NO_USER_STORAGE_SERVICE_LOOKUP, file: FILE)
577
+ format(LogMessageEnum::DebugMessages::NO_USER_STORAGE_SERVICE_LOOKUP, file: FILE),
578
+ disable_logs
568
579
  )
569
580
  return false
570
581
  end
@@ -577,13 +588,15 @@ class VWO
577
588
  file: FILE,
578
589
  user_id: user_id,
579
590
  status: data.nil? ? 'Not Found' : 'Found'
580
- )
591
+ ),
592
+ disable_logs
581
593
  )
582
594
  data
583
595
  rescue StandardError
584
596
  @logger.log(
585
597
  LogLevelEnum::ERROR,
586
- format(LogMessageEnum::ErrorMessages::LOOK_UP_USER_STORAGE_SERVICE_FAILED, file: FILE, user_id: user_id)
598
+ format(LogMessageEnum::ErrorMessages::LOOK_UP_USER_STORAGE_SERVICE_FAILED, file: FILE, user_id: user_id),
599
+ disable_logs
587
600
  )
588
601
  false
589
602
  end
@@ -593,10 +606,11 @@ class VWO
593
606
  # @param[String] :user_id
594
607
  # @param[String] :campaign_key campaign identified
595
608
  # @param[Hash] :user_campaign_map BucketMap consisting of stored user variation
609
+ # @param[Boolean] :disable_logs if True
596
610
  #
597
611
  # @return[Object, nil] if found then variation settings object otherwise None
598
612
 
599
- def get_stored_variation(user_id, campaign_key, user_campaign_map)
613
+ def get_stored_variation(user_id, campaign_key, user_campaign_map, disable_logs = false)
600
614
  return unless user_campaign_map['campaign_key'] == campaign_key
601
615
 
602
616
  variation_name = user_campaign_map['variation_name']
@@ -608,7 +622,8 @@ class VWO
608
622
  campaign_key: campaign_key,
609
623
  user_id: user_id,
610
624
  variation_name: variation_name
611
- )
625
+ ),
626
+ disable_logs
612
627
  )
613
628
 
614
629
  get_campaign_variation(
@@ -617,6 +632,276 @@ class VWO
617
632
  variation_name
618
633
  )
619
634
  end
635
+
636
+ # this function check whether pre-segmentation is passed or not
637
+ #
638
+ # @param[String] :user_id The unique key assigned to User
639
+ # @param[Hash] :campaign Campaign hash for Unique campaign key
640
+ # @param[Hash] :custom_variables Key/value pair for segmentation
641
+ # @param[String] :api_name The key Passed to identify the calling API
642
+ # @param[Boolean] :disable_logs optional: disable logs if True
643
+ #
644
+ # @return[Boolean]
645
+ def check_presegmentation(campaign, user_id, custom_variables, api_name, disable_logs = false)
646
+ campaign_key = campaign['key']
647
+ segments = get_segments(campaign)
648
+ is_valid_segments = valid_value?(segments)
649
+
650
+ if is_valid_segments
651
+ unless custom_variables
652
+ @logger.log(
653
+ LogLevelEnum::INFO,
654
+ format(
655
+ LogMessageEnum::InfoMessages::NO_CUSTOM_VARIABLES,
656
+ file: FILE,
657
+ campaign_key: campaign_key,
658
+ user_id: user_id,
659
+ api_name: api_name
660
+ ),
661
+ disable_logs
662
+ )
663
+ custom_variables = {}
664
+ end
665
+ unless @segment_evaluator.evaluate(campaign_key, user_id, segments, custom_variables, disable_logs)
666
+ @logger.log(
667
+ LogLevelEnum::INFO,
668
+ format(
669
+ LogMessageEnum::InfoMessages::USER_FAILED_SEGMENTATION,
670
+ file: FileNameEnum::SegmentEvaluator,
671
+ user_id: user_id,
672
+ campaign_key: campaign_key,
673
+ custom_variables: custom_variables
674
+ ),
675
+ disable_logs
676
+ )
677
+ return false
678
+ end
679
+ @logger.log(
680
+ LogLevelEnum::INFO,
681
+ format(
682
+ LogMessageEnum::InfoMessages::USER_PASSED_SEGMENTATION,
683
+ file: FileNameEnum::SegmentEvaluator,
684
+ user_id: user_id,
685
+ campaign_key: campaign_key,
686
+ custom_variables: custom_variables
687
+ ),
688
+ disable_logs
689
+ )
690
+ else
691
+ @logger.log(
692
+ LogLevelEnum::INFO,
693
+ format(
694
+ LogMessageEnum::InfoMessages::SKIPPING_SEGMENTATION,
695
+ file: FILE,
696
+ campaign_key: campaign_key,
697
+ user_id: user_id,
698
+ api_name: api_name,
699
+ variation: ''
700
+ ),
701
+ disable_logs
702
+ )
703
+ end
704
+ true
705
+ end
706
+
707
+ # Finds and returns eligible campaigns from group_campaigns.
708
+ #
709
+ # @param[String] :user_id The unique key assigned to User
710
+ # @param[Hash] :called_campaign campaign for which api is called
711
+ # @param[Array] :group_campaigns campaigns part of group
712
+ # @param[String] :custom_variables Key/value pair for segmentation
713
+ #
714
+ # @return[Array]
715
+ def get_eligible_campaigns(user_id, group_campaigns, called_campaign, custom_variables)
716
+ eligible_campaigns = []
717
+
718
+ group_campaigns.each do |campaign|
719
+ if called_campaign["id"] == campaign["id"] || check_presegmentation(campaign, user_id, custom_variables, '', true) && @bucketer.user_part_of_campaign?(user_id, campaign)
720
+ eligible_campaigns.push(campaign)
721
+ end
722
+ end
723
+ return eligible_campaigns
724
+ end
725
+
726
+ # Finds and returns the winner campaign from eligible_campaigns list.
727
+ #
728
+ # @param[String] :user_id The unique key assigned to User
729
+ # @param[Array] :eligible_campaigns campaigns part of group which were eligible to be winner
730
+ #
731
+ # @return[Hash]
732
+ def get_winner_campaign(user_id, eligible_campaigns, group_id)
733
+ if eligible_campaigns.length == 1
734
+ return eligible_campaigns[0]
735
+ end
736
+
737
+ eligible_campaigns = scale_campaigns_weight(eligible_campaigns)
738
+ eligible_campaigns = set_campaign_allocation(eligible_campaigns)
739
+ bucket_value = @bucketer.get_bucket_value_for_user(user_id, {}, group_id, true)
740
+ return @bucketer.get_campaign_using_range(bucket_value, eligible_campaigns)
741
+ end
742
+
743
+ # Get campaign keys of all eligible Campaigns.
744
+ #
745
+ # @param[Array] :eligible_campaigns campaigns part of group which were eligible to be winner
746
+ #
747
+ # @return[Array]
748
+ def get_eligible_campaigns_key(eligible_campaigns)
749
+ eligible_campaigns_key = []
750
+ eligible_campaigns.each do |campaign|
751
+ eligible_campaigns_key.push(campaign["key"])
752
+ end
753
+ eligible_campaigns_key
754
+ end
755
+
756
+ # Get campaign keys of all non eligible Campaigns.
757
+ #
758
+ # @param[Array] :eligible_campaigns campaigns part of group which were eligible to be winner
759
+ # @param[Array] :group_campaigns campaigns part of group
760
+ #
761
+ # @return[Array]
762
+ def get_non_eligible_campaigns_key(eligible_campaigns, group_campaigns)
763
+ non_eligible_campaigns_key = []
764
+ group_campaigns.each do |campaign|
765
+ unless eligible_campaigns.include? campaign
766
+ non_eligible_campaigns_key.push(campaign["key"])
767
+ end
768
+ end
769
+ non_eligible_campaigns_key
770
+ end
771
+
772
+ # Checks if any other campaign in groupCampaigns satisfies whitelisting or is in user storage.
773
+ #
774
+ # @param[String] :user_id the unique ID assigned to User
775
+ # @param[Hash] :called_campaign campaign for which api is called
776
+ # @param[Array] :group_campaigns campaigns part of group
777
+ # @param[String] :group_name group name
778
+ # @param[Hash] :variation_targeting_variables Key/value pair of Whitelisting Custom Attributes
779
+ # @param[Boolean] :disable_logs optional: disable logs if True
780
+ # @return[Boolean]
781
+
782
+ def check_whitelisting_or_storage_for_grouped_campaigns(user_id, called_campaign, group_campaigns, group_name, variation_targeting_variables, disable_logs = false)
783
+ group_campaigns.each do |campaign|
784
+ if called_campaign["id"] != campaign["id"]
785
+ targeted_variation = evaluate_whitelisting(
786
+ user_id,
787
+ campaign,
788
+ '',
789
+ campaign["key"],
790
+ variation_targeting_variables,
791
+ true
792
+ )
793
+ if targeted_variation
794
+ @logger.log(
795
+ LogLevelEnum::INFO,
796
+ format(
797
+ LogMessageEnum::InfoMessages::OTHER_CAMPAIGN_SATISFIES_WHITELISTING_OR_STORAGE,
798
+ file: FILE,
799
+ campaign_key: campaign["key"],
800
+ user_id: user_id,
801
+ group_name: group_name,
802
+ type: "whitelisting"
803
+ ),
804
+ disable_logs
805
+ )
806
+ return true
807
+ end
808
+ end
809
+ end
810
+
811
+ group_campaigns.each do |campaign|
812
+ if called_campaign["id"] != campaign["id"]
813
+ user_storage_data = get_user_storage(user_id, campaign["key"], true)
814
+ if user_storage_data
815
+ @logger.log(
816
+ LogLevelEnum::INFO,
817
+ format(
818
+ LogMessageEnum::InfoMessages::OTHER_CAMPAIGN_SATISFIES_WHITELISTING_OR_STORAGE,
819
+ file: FILE,
820
+ campaign_key: campaign["key"],
821
+ user_id: user_id,
822
+ group_name: group_name,
823
+ type: "user storage"
824
+ ),
825
+ disable_logs
826
+ )
827
+ return true
828
+ end
829
+ end
830
+ end
831
+ false
832
+ end
833
+
834
+ # Get variation if whitelisting passes
835
+ #
836
+ # @param[String] :user_id the unique ID assigned to User
837
+ # @param[Hash] :campaign campaign for which checking whitelisting
838
+ # @param[Hash] :variation_targeting_variables Key/value pair of Whitelisting Custom Attributes
839
+ # @param[String] :api_name The key Passed to identify the calling API
840
+ # @param[Hash] :decision data containing campaign info passed to hooks manager
841
+ # @param[Boolean] :disable_logs optional: disable logs if True
842
+ # @return[Hash]
843
+ def get_variation_if_whitelisting_passed(user_id, campaign, variation_targeting_variables, api_name, decision, disable_logs = false)
844
+ campaign_key = campaign['key']
845
+ if campaign['isForcedVariationEnabled']
846
+ variation = evaluate_whitelisting(
847
+ user_id,
848
+ campaign,
849
+ api_name,
850
+ campaign_key,
851
+ variation_targeting_variables,
852
+ disable_logs
853
+ )
854
+ status = if variation
855
+ StatusEnum::PASSED
856
+ else
857
+ StatusEnum::FAILED
858
+ end
859
+
860
+ @logger.log(
861
+ LogLevelEnum::INFO,
862
+ format(
863
+ LogMessageEnum::InfoMessages::SEGMENTATION_STATUS,
864
+ file: FILE,
865
+ campaign_key: campaign_key,
866
+ user_id: user_id,
867
+ status: status,
868
+ custom_variables: variation_targeting_variables ? variation_targeting_variables : {},
869
+ variation_name: (status == StatusEnum::PASSED && campaign['type'] != CampaignTypes::FEATURE_ROLLOUT) ? "and #{variation['name']} is Assigned" : ' ',
870
+ segmentation_type: SegmentationTypeEnum::WHITELISTING,
871
+ api_name: api_name
872
+ ),
873
+ disable_logs
874
+ )
875
+
876
+ if variation
877
+ if campaign['type'] == CampaignTypes::VISUAL_AB || campaign['type'] == CampaignTypes::FEATURE_TEST
878
+ decision[:variation_name] = variation['name']
879
+ decision[:variation_id] = variation['id']
880
+ if campaign['type'] == CampaignTypes::FEATURE_TEST
881
+ decision[:is_feature_enabled] = variation['isFeatureEnabled']
882
+ end
883
+ end
884
+ decision[:is_user_whitelisted] = true
885
+ @hooks_manager.execute(decision)
886
+ end
887
+
888
+ return variation if variation && variation['name']
889
+ else
890
+ @logger.log(
891
+ LogLevelEnum::INFO,
892
+ format(
893
+ LogMessageEnum::InfoMessages::WHITELISTING_SKIPPED,
894
+ file: FILE,
895
+ campaign_key: campaign_key,
896
+ user_id: user_id,
897
+ api_name: api_name
898
+ ),
899
+ disable_logs
900
+ )
901
+ end
902
+ nil
903
+ end
904
+
620
905
  end
621
906
  end
622
907
  end