vwo-sdk 1.16.0 → 1.22.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '084660e0c3fcb3c07826944ba8d83988711b59165ea54a54b1e47042a889bbf5'
4
- data.tar.gz: 62c4ae889870a381d2973967412f0916baa0d25ce377604aa096c5f4dd0a8e79
3
+ metadata.gz: 84d01560f605a69e8ed011a19ba4e3aae0f67341fd653a562d817801d6a55073
4
+ data.tar.gz: b1355bef1b2b095774c702a6757c1a7141e2cf9758d0a1b8a0510111a8ee597a
5
5
  SHA512:
6
- metadata.gz: 67fd788b416ac54e9d27999ca757662eb88a123a804ccf3c93538e58787a3fd1181686543a7abdbb94dbd7d66f5d1c63421ae21d1b3e794b93cff6951355fdd2
7
- data.tar.gz: 7950a38da6e5993575ff46e1c1ba2f901d98fa4112e54070297c78846e2b29eacdae4042c51d03f1e9e8b05d55aa4e60b698fa70af43c7d1ae2167953aaaec6c
6
+ metadata.gz: cc2c8a411e3c0a674ab2bc00e540b3e49a8dd943ec50aa04fba04839ef6f3e255fc275529f872aa5ca73dfe893cb43e8853a0875cc3dda9330554b6491590947
7
+ data.tar.gz: 5482e79564a365ec8fe4012b25997096352129e915daca28774c790c416a528302ea1f0bb685ef559b9ee0846b0229957a8f6ab77008f4e48222a7cae5892699
data/lib/abc.txt ADDED
@@ -0,0 +1,28 @@
1
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
2
+ GOT_ELIGIBLE_CAMPAIGNS
3
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
4
+ GOT_ELIGIBLE_CAMPAIGNS
5
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
6
+ GOT_ELIGIBLE_CAMPAIGNS
7
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
8
+ GOT_ELIGIBLE_CAMPAIGNS
9
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
10
+ GOT_ELIGIBLE_CAMPAIGNS
11
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
12
+ GOT_ELIGIBLE_CAMPAIGNS
13
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
14
+ GOT_ELIGIBLE_CAMPAIGNS
15
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
16
+ GOT_ELIGIBLE_CAMPAIGNS
17
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
18
+ GOT_ELIGIBLE_CAMPAIGNS
19
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
20
+ GOT_ELIGIBLE_CAMPAIGNS
21
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
22
+ GOT_ELIGIBLE_CAMPAIGNS
23
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
24
+ GOT_ELIGIBLE_CAMPAIGNS
25
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
26
+ GOT_ELIGIBLE_CAMPAIGNS
27
+ {"user_id"=>"Ashley", "variation_name"=>"Control", "campaign_key"=>"DEV_TEST_162"}
28
+ GOT_ELIGIBLE_CAMPAIGNS
data/lib/vwo/constants.rb CHANGED
@@ -19,6 +19,7 @@ class VWO
19
19
  SEED_VALUE = 1
20
20
  MAX_TRAFFIC_PERCENT = 100
21
21
  MAX_TRAFFIC_VALUE = 10_000
22
+ MAX_RANGE = 10000
22
23
  STATUS_RUNNING = 'RUNNING'
23
24
  # rubocop:disable Style/ExpandPathArguments
24
25
  LIBRARY_PATH = File.expand_path('../..', __FILE__)
@@ -26,7 +27,7 @@ class VWO
26
27
  HTTP_PROTOCOL = 'http://'
27
28
  HTTPS_PROTOCOL = 'https://'
28
29
  URL_NAMESPACE = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'
29
- SDK_VERSION = '1.16.0'
30
+ SDK_VERSION = '1.22.0'
30
31
  SDK_NAME = 'ruby'
31
32
  VWO_DELIMITER = '_vwo_'
32
33
  MAX_EVENTS_PER_REQUEST = 5000
@@ -60,7 +60,7 @@ class VWO
60
60
  end
61
61
 
62
62
  traffic_allocation = campaign['percentTraffic']
63
- value_assigned_to_user = get_bucket_value_for_user(user_id)
63
+ value_assigned_to_user = get_bucket_value_for_user(user_id, campaign)
64
64
  is_user_part = (value_assigned_to_user != 0) && value_assigned_to_user <= traffic_allocation
65
65
  @logger.log(
66
66
  LogLevelEnum::INFO,
@@ -94,7 +94,11 @@ class VWO
94
94
  return
95
95
  end
96
96
 
97
- hash_value = MurmurHash3::V32.str_hash(user_id, SEED_VALUE) & U_MAX_32_BIT
97
+ user_id_for_hash_value = user_id
98
+ if campaign[:isBucketingSeedEnabled]
99
+ user_id_for_hash_value = campaign[:id].to_s + "_" + user_id
100
+ end
101
+ hash_value = MurmurHash3::V32.str_hash(user_id_for_hash_value, SEED_VALUE) & U_MAX_32_BIT
98
102
  normalize = MAX_TRAFFIC_VALUE.to_f / campaign['percentTraffic']
99
103
  multiplier = normalize / 100
100
104
  bucket_value = get_bucket_value(
@@ -136,10 +140,17 @@ class VWO
136
140
  # User by hashing the userId by murmurHash and scaling it down.
137
141
  #
138
142
  # @param[String] :user_id The unique ID assigned to User
143
+ # @param[String] :campaign Campaign data
139
144
  # @return[Integer] The bucket Value allotted to User
140
145
  # (between 1 to $this->$MAX_TRAFFIC_PERCENT)
141
- def get_bucket_value_for_user(user_id)
142
- hash_value = MurmurHash3::V32.str_hash(user_id, SEED_VALUE) & U_MAX_32_BIT
146
+ def get_bucket_value_for_user(user_id, campaign = {}, group_id = nil, disable_logs = false)
147
+ user_id_for_hash_value = user_id
148
+ if group_id
149
+ user_id_for_hash_value = group_id.to_s + "_" + user_id
150
+ elsif campaign[:isBucketingSeedEnabled]
151
+ user_id_for_hash_value = campaign[:id].to_s + "_" + user_id
152
+ end
153
+ hash_value = MurmurHash3::V32.str_hash(user_id_for_hash_value, SEED_VALUE) & U_MAX_32_BIT
143
154
  bucket_value = get_bucket_value(hash_value, MAX_TRAFFIC_PERCENT)
144
155
 
145
156
  @logger.log(
@@ -150,7 +161,8 @@ class VWO
150
161
  hash_value: hash_value,
151
162
  bucket_value: bucket_value,
152
163
  user_id: user_id
153
- )
164
+ ),
165
+ disable_logs
154
166
  )
155
167
  bucket_value
156
168
  end
@@ -168,6 +180,22 @@ class VWO
168
180
  multiplied_value = (max_value * ratio + 1) * multiplier
169
181
  multiplied_value.to_i
170
182
  end
183
+
184
+ # Returns a campaign by checking the Start and End Bucket Allocations of each campaign.
185
+ #
186
+ # @param[Integer] :range_for_campaigns the bucket value of the user
187
+ # @param[Hash] :campaigns The bucket Value of the user
188
+ # @return[Hash|nil]
189
+ #
190
+ def get_campaign_using_range(range_for_campaigns, campaigns)
191
+ range_for_campaigns = range_for_campaigns * 100
192
+ campaigns.each do |campaign|
193
+ if campaign["max_range"] && campaign["max_range"] >= range_for_campaigns && campaign["min_range"] <= range_for_campaigns
194
+ return campaign
195
+ end
196
+ end
197
+ nil
198
+ end
171
199
  end
172
200
  end
173
201
  end
@@ -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)
282
-
283
- if variation && variation['name']
284
- save_user_storage(user_id, campaign_key, variation['name'], goal_identifier) if variation['name']
270
+ if variation.nil?
271
+ variation = get_variation_allotted(user_id, campaign)
285
272
 
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,10 +454,11 @@ 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
463
  variation_targeting_variables = { '_vwo_user_id' => user_id }
464
464
  else
@@ -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
@@ -488,7 +488,8 @@ class VWO
488
488
  variation_name: 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,277 @@ 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.append(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.append(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.append(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,
869
+ variation_name: status == StatusEnum::PASSED ? "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
+ elsif campaign['type'] == CampaignTypes::VISUAL_AB
883
+ decision[:is_user_whitelisted] = !!variation['name']
884
+ end
885
+ end
886
+ @hooks_manager.execute(decision)
887
+ end
888
+
889
+ return variation if variation && variation['name']
890
+ else
891
+ @logger.log(
892
+ LogLevelEnum::INFO,
893
+ format(
894
+ LogMessageEnum::InfoMessages::WHITELISTING_SKIPPED,
895
+ file: FILE,
896
+ campaign_key: campaign_key,
897
+ user_id: user_id,
898
+ api_name: api_name
899
+ ),
900
+ disable_logs
901
+ )
902
+ end
903
+ nil
904
+ end
905
+
620
906
  end
621
907
  end
622
908
  end
data/lib/vwo/enums.rb CHANGED
@@ -113,6 +113,7 @@ class VWO
113
113
  BULK_NOT_PROCESSED = "(%<file>s): Batch events couldn't be received by VWO. Calling Flush Callback with error and data."
114
114
  BEFORE_FLUSHING = '(%<file>s): Flushing events queue %<manually>s having %<length>s events %<timer>s queue summary: %<queue_metadata>s'
115
115
  EVENT_BATCHING_INSUFFICIENT = '(%<file>s): %<key>s not provided, assigning default value'
116
+ GOT_ELIGIBLE_CAMPAIGNS = "(%<file>s): Campaigns:%<eligible_campaigns_key>s are eligible, %<ineligible_campaigns_log_text>s are ineligible from the Group:%<group_name>s for the User ID:%<user_id>s"
116
117
  end
117
118
 
118
119
  # Info Messages
@@ -152,9 +153,13 @@ class VWO
152
153
  CAMPAIGN_NOT_ACTIVATED = '(%<file>s): Activate the campaign:%<campaign_key>s for User ID:%<user_id>s to %<reason>s.'
153
154
  GOAL_ALREADY_TRACKED = '(%<file>s): Goal:%<goal_identifier>s of Campaign:%<campaign_key>s for User ID:%<user_id>s has already been tracked earlier. Skipping now'
154
155
  USER_ALREADY_TRACKED = '(%<file>s): User ID:%<user_id>s for Campaign:%<campaign_key>s has already been tracked earlier for "%<api_name>s" API. Skipping now'
155
- API_CALLED = '(%<file>s): API: {api_name} called for UserId:%<user_id>s'
156
+ API_CALLED = '(%<file>s): API: %<api_name>s called for UserId:%<user_id>s'
156
157
  BULK_IMPRESSION_SUCCESS = '(%<file>s): Impression event - %<end_point>s was successfully received by VWO having accountId:%<a>s'
157
158
  AFTER_FLUSHING = '(%<file>s): Events queue having %<length>s events has been flushed %<manually>s queue summary: %<queue_metadata>s'
159
+ GOT_WINNER_CAMPAIGN = "(%<file>s): Campaign:%<campaign_key>s is selected from the mutually exclusive group:%<group_name>s for the User ID:%<user_id>s"
160
+ GOT_ELIGIBLE_CAMPAIGNS = "(%<file>s): Got %<no_of_eligible_campaigns>s eligible winners out of %<no_of_group_campaigns>s from the Group:%<group_name>s and for User ID:%<user_id>s"
161
+ CALLED_CAMPAIGN_NOT_WINNER = "(%<file>s): Campaign:%<campaign_key>s does not qualify from the mutually exclusive group:%<group_name>s for User ID:%<user_id>s"
162
+ OTHER_CAMPAIGN_SATISFIES_WHITELISTING_OR_STORAGE = "(%<file>s): Campaign:%<campaign_key>s of Group:%<group_name>s satisfies %<type>s for User ID:%<user_id>s"
158
163
  end
159
164
 
160
165
  # Warning Messages
data/lib/vwo/logger.rb CHANGED
@@ -28,8 +28,10 @@ class VWO
28
28
  end
29
29
 
30
30
  # Override this method to handle logs in a custom manner
31
- def log(level, message)
32
- @@logger_instance.log(level, message)
31
+ def log(level, message, disable_logs = false)
32
+ unless disable_logs
33
+ @@logger_instance.log(level, message)
34
+ end
33
35
  end
34
36
 
35
37
  def instance
@@ -91,6 +91,7 @@ class VWO
91
91
  '$ref' => '#/definitions/variables_schema'
92
92
  }
93
93
  },
94
+ isBucketingSeedEnabled: ['boolean'],
94
95
  minItems: 2
95
96
  }
96
97
  },
@@ -63,10 +63,11 @@ class VWO
63
63
  # @param[String] :user_id Unique user identifier
64
64
  # @param[Hash] :dsl Segments provided in the settings_file
65
65
  # @param[Hash] :custom_variables Custom variables provided in the apis
66
+ # @param[Boolean] :disable_logs disable logs if True
66
67
  #
67
68
  # @return[Boolean] true if user passed pre-segmentation, else false
68
69
  #
69
- def evaluate(campaign_key, user_id, dsl, custom_variables)
70
+ def evaluate(campaign_key, user_id, dsl, custom_variables, disable_logs = false)
70
71
  result = evaluate_util(dsl, custom_variables) if valid_value?(dsl)
71
72
  result
72
73
  rescue StandardError => e
@@ -79,7 +80,8 @@ class VWO
79
80
  campaign_key: campaign_key,
80
81
  custom_variables: custom_variables,
81
82
  error_message: e
82
- )
83
+ ),
84
+ disable_logs
83
85
  )
84
86
  false
85
87
  end
@@ -57,6 +57,26 @@ class VWO
57
57
  end
58
58
  end
59
59
 
60
+ # Sets campaign allocation range in the provided campaigns list
61
+ #
62
+ # @param [Array]: Array of Campaigns
63
+ def set_campaign_allocation(campaigns)
64
+ current_allocation = 0
65
+ campaigns.each do |campaign|
66
+ step_factor = get_variation_bucketing_range(campaign['weight'])
67
+ if step_factor > 0
68
+ start_range = current_allocation + 1
69
+ end_range = current_allocation + step_factor
70
+ campaign['min_range'] = start_range
71
+ campaign['max_range'] = end_range
72
+ current_allocation += step_factor
73
+ else
74
+ campaign['min_range'] = -1
75
+ campaign['max_range'] = -1
76
+ end
77
+ end
78
+ end
79
+
60
80
  # Returns goal from given campaign_key and gaol_identifier.
61
81
  # @param[String] :campaign Campaign object
62
82
  # @param[String] :goal_identifier Goal identifier
@@ -249,6 +269,44 @@ class VWO
249
269
  return campaign
250
270
  end
251
271
 
272
+ # Checks whether a campaign is part of a group.
273
+ #
274
+ # @param[Hash] :settings_file Settings file for the project
275
+ # @param[Integer] :campaign_id Id of campaign which is to be checked
276
+ # @return[Boolean]
277
+ def is_part_of_group(settings_file, campaign_id)
278
+ if settings_file["campaignGroups"] && (settings_file["campaignGroups"].has_key?(campaign_id.to_s))
279
+ return true
280
+ end
281
+ false
282
+ end
283
+
284
+ # Returns campaigns which are part of given group using group_id.
285
+ #
286
+ # @param[Hash] :settings_file Settings file for the project
287
+ # @param[Integer] :group_id id of group whose campaigns are to be return
288
+ # @return[Array]
289
+ def get_group_campaigns(settings_file, group_id)
290
+ group_campaign_ids = []
291
+ group_campaigns = []
292
+ groups = settings_file["groups"]
293
+
294
+ if groups && groups.has_key?(group_id.to_s)
295
+ group_campaign_ids = groups[group_id.to_s]["campaigns"]
296
+ end
297
+
298
+ if group_campaign_ids
299
+ group_campaign_ids.each do |campaign_id|
300
+ settings_file["campaigns"].each do |campaign|
301
+ if campaign["id"] == campaign_id && campaign["status"] == STATUS_RUNNING
302
+ group_campaigns.append(campaign)
303
+ end
304
+ end
305
+ end
306
+ end
307
+ group_campaigns
308
+ end
309
+
252
310
  end
253
311
  end
254
312
  end
data/lib/vwo.rb CHANGED
@@ -413,7 +413,6 @@ class VWO
413
413
  )
414
414
  end
415
415
  end
416
- variation['name']
417
416
  else
418
417
  @logger.log(
419
418
  LogLevelEnum::INFO,
@@ -425,8 +424,8 @@ class VWO
425
424
  api_name: ApiMethods::ACTIVATE
426
425
  )
427
426
  )
428
- nil
429
427
  end
428
+ variation['name']
430
429
  rescue StandardError => e
431
430
  @logger.log(
432
431
  LogLevelEnum::ERROR,
@@ -676,7 +675,7 @@ class VWO
676
675
  if !identifiers.include? goal_identifier
677
676
  updated_goal_identifier = variation['goal_identifier']
678
677
  updated_goal_identifier += VWO_DELIMITER + goal_identifier
679
- @variation_decider.save_user_storage(user_id, campaign['key'], variation['name'], updated_goal_identifier) if variation['name']
678
+ @variation_decider.save_user_storage(user_id, campaign['key'], campaign['name'], variation['name'], updated_goal_identifier) if variation['name']
680
679
  # set variation at user storage
681
680
  elsif !should_track_returning_user
682
681
  @logger.log(
@@ -870,80 +869,85 @@ class VWO
870
869
  return false unless variation
871
870
 
872
871
  # if campaign type is feature_test Send track call to server
873
- if campaign_type == CampaignTypes::FEATURE_TEST
874
- if is_eligible_to_send_impression(should_track_returning_user)
875
- if defined?(@batch_events)
876
- impression = create_bulk_event_impression(
877
- @settings_file,
878
- campaign['id'],
879
- variation['id'],
880
- user_id
881
- )
882
- @batch_events_queue.enqueue(impression)
883
- else
884
- impression = create_impression(
885
- @settings_file,
886
- campaign['id'],
887
- variation['id'],
888
- user_id,
889
- @sdk_key,
890
- goal_id: nil,
891
- revenue: nil,
892
- usage_stats: @usage_stats.usage_stats
893
- )
894
872
 
895
- @event_dispatcher.dispatch(impression)
896
- @logger.log(
897
- LogLevelEnum::INFO,
898
- format(
899
- LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_IMPRESSION,
900
- file: FILE,
901
- campaign_id: impression[:experiment_id],
902
- sdk_key: @sdk_key,
903
- account_id: impression[:account_id],
904
- variation_id: impression[:combination]
905
- )
906
- )
907
- end
908
- result = variation['isFeatureEnabled']
909
- if result
910
- @logger.log(
911
- LogLevelEnum::INFO,
912
- format(
913
- LogMessageEnum::InfoMessages::FEATURE_ENABLED_FOR_USER,
914
- file: FILE,
915
- user_id: user_id,
916
- feature_key: campaign_key,
917
- api_name: ApiMethods::IS_FEATURE_ENABLED
918
- )
919
- )
920
- else
921
- @logger.log(
922
- LogLevelEnum::INFO,
923
- format(
924
- LogMessageEnum::InfoMessages::FEATURE_NOT_ENABLED_FOR_USER,
925
- file: FILE,
926
- user_id: user_id,
927
- feature_key: campaign_key,
928
- api_name: ApiMethods::IS_FEATURE_ENABLED
929
- )
930
- )
931
- end
932
- return result
873
+ if is_eligible_to_send_impression(should_track_returning_user)
874
+ if defined?(@batch_events)
875
+ impression = create_bulk_event_impression(
876
+ @settings_file,
877
+ campaign['id'],
878
+ variation['id'],
879
+ user_id
880
+ )
881
+ @batch_events_queue.enqueue(impression)
933
882
  else
883
+ impression = create_impression(
884
+ @settings_file,
885
+ campaign['id'],
886
+ variation['id'],
887
+ user_id,
888
+ @sdk_key,
889
+ nil,
890
+ nil,
891
+ usage_stats: @usage_stats.usage_stats
892
+ )
893
+
894
+ @event_dispatcher.dispatch(impression)
934
895
  @logger.log(
935
896
  LogLevelEnum::INFO,
936
897
  format(
937
- LogMessageEnum::InfoMessages::USER_ALREADY_TRACKED,
898
+ LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_IMPRESSION,
938
899
  file: FILE,
939
- user_id: user_id,
940
- campaign_key: campaign_key,
941
- api_name: ApiMethods::IS_FEATURE_ENABLED
900
+ campaign_id: impression[:experiment_id],
901
+ sdk_key: @sdk_key,
902
+ account_id: impression[:account_id],
903
+ variation_id: impression[:combination]
942
904
  )
943
905
  )
944
906
  end
907
+
908
+ else
909
+ @logger.log(
910
+ LogLevelEnum::INFO,
911
+ format(
912
+ LogMessageEnum::InfoMessages::USER_ALREADY_TRACKED,
913
+ file: FILE,
914
+ user_id: user_id,
915
+ campaign_key: campaign_key,
916
+ api_name: ApiMethods::IS_FEATURE_ENABLED
917
+ )
918
+ )
945
919
  end
946
- true
920
+ if campaign_type == CampaignTypes::FEATURE_ROLLOUT
921
+ result = true
922
+ else
923
+ result = variation['isFeatureEnabled']
924
+ end
925
+
926
+ if result
927
+ @logger.log(
928
+ LogLevelEnum::INFO,
929
+ format(
930
+ LogMessageEnum::InfoMessages::FEATURE_ENABLED_FOR_USER,
931
+ file: FILE,
932
+ user_id: user_id,
933
+ feature_key: campaign_key,
934
+ api_name: ApiMethods::IS_FEATURE_ENABLED
935
+ )
936
+ )
937
+ else
938
+ @logger.log(
939
+ LogLevelEnum::INFO,
940
+ format(
941
+ LogMessageEnum::InfoMessages::FEATURE_NOT_ENABLED_FOR_USER,
942
+ file: FILE,
943
+ user_id: user_id,
944
+ feature_key: campaign_key,
945
+ api_name: ApiMethods::IS_FEATURE_ENABLED
946
+ )
947
+ )
948
+ end
949
+
950
+ result
947
951
  rescue StandardError => e
948
952
  @logger.log(
949
953
  LogLevelEnum::ERROR,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vwo-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.0
4
+ version: 1.22.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VWO
@@ -87,6 +87,7 @@ executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
+ - lib/abc.txt
90
91
  - lib/vwo.rb
91
92
  - lib/vwo/constants.rb
92
93
  - lib/vwo/core/bucketer.rb