vwo-sdk 1.15.0 → 1.23.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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