vwo-sdk 1.16.0 → 1.23.2

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