vwo-sdk 1.23.2 → 1.28.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: c878b24cefb4bf2da034a1dec355b96d38650c52018dc8516f7e324e8469ae0e
4
- data.tar.gz: ea385bb48e6aebdc4975b08449161cd24dbf075dc582959492f8ff7d7bcc751f
3
+ metadata.gz: 83480c79432c0c6199e03e365b71fcf8b2e0ffaf89b976c94234b3bcfc54e931
4
+ data.tar.gz: a695f06bf66c0186c193b05b9d4a6a931c75b9398f260f7d733b57275a3bfedd
5
5
  SHA512:
6
- metadata.gz: b424bfd4bc9eaab32001d67da2c5acb57b072ab935c9e4f24206ad9329e7a29f76d3498d497224e9adace85b2dcff0d37ade16e9864a651e02c434e8e788443c
7
- data.tar.gz: e16e7e7e276fbb9ccbaa9c605e17790116b1e925a766a5f0252991c187a91bfaa4d00fa2ff1445d5cf98443e02e55fa7516845dce36974dd0e56301a86296e86
6
+ metadata.gz: 63572509c60e9e96c39775bab1fe0bea00dd0ca27f436c46055563886a66bca0d78b3259fe70c2d58e13c8ed0c8e036245760923fcf2187b964628cea2f7741b
7
+ data.tar.gz: f96d84a9c2ae09e474ede155e1187cce8cd9a0dc38f56646531519aae27c07d5883c5373a60fae9fe92eef9fe0da7f23b1af7e3a71ce1a4283fda9ee6533551a
data/lib/vwo/constants.rb CHANGED
@@ -27,7 +27,7 @@ class VWO
27
27
  HTTP_PROTOCOL = 'http://'
28
28
  HTTPS_PROTOCOL = 'https://'
29
29
  URL_NAMESPACE = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'
30
- SDK_VERSION = '1.23.2'
30
+ SDK_VERSION = '1.28.0'
31
31
  SDK_NAME = 'ruby'
32
32
  VWO_DELIMITER = '_vwo_'
33
33
  MAX_EVENTS_PER_REQUEST = 5000
@@ -44,6 +44,7 @@ class VWO
44
44
  TRACK_GOAL = '/server-side/track-goal'
45
45
  PUSH = '/server-side/push'
46
46
  BATCH_EVENTS = '/server-side/batch-events'
47
+ EVENTS = '/events/t'
47
48
  end
48
49
 
49
50
  module EVENTS
@@ -101,6 +102,7 @@ class VWO
101
102
  PUSH = 'push'
102
103
  GET_AND_UPDATE_SETTINGS_FILE = 'get_and_update_settings_file'
103
104
  FLUSH_EVENTS = 'flush_events'
105
+ OPT_OUT = 'opt_out'
104
106
  end
105
107
 
106
108
  module PushApi
@@ -113,5 +115,10 @@ class VWO
113
115
  FEATURE_TEST = 'FEATURE_TEST'
114
116
  FEATURE_ROLLOUT = 'FEATURE_ROLLOUT'
115
117
  end
118
+
119
+ module EventEnum
120
+ VWO_VARIATION_SHOWN = 'vwo_variationShown'
121
+ VWO_SYNC_VISITOR_PROP = 'vwo_syncVisitorProp'
122
+ end
116
123
  end
117
124
  end
@@ -463,10 +463,19 @@ class VWO
463
463
  # @return[Hash]
464
464
 
465
465
  def evaluate_whitelisting(user_id, campaign, api_name, campaign_key, variation_targeting_variables = {}, disable_logs = false)
466
- if variation_targeting_variables.nil?
467
- variation_targeting_variables = { _vwo_user_id: user_id }
466
+ if campaign.key?('isUserListEnabled') && campaign["isUserListEnabled"]
467
+ vwo_user_id = generator_for(user_id, @settings_file['accountId'])
468
+ if variation_targeting_variables.nil?
469
+ variation_targeting_variables = { _vwo_user_id: vwo_user_id }
470
+ else
471
+ variation_targeting_variables[:_vwo_user_id] = vwo_user_id
472
+ end
468
473
  else
469
- variation_targeting_variables[:_vwo_user_id] = user_id
474
+ if variation_targeting_variables.nil?
475
+ variation_targeting_variables = { _vwo_user_id: user_id }
476
+ else
477
+ variation_targeting_variables[:_vwo_user_id] = user_id
478
+ end
470
479
  end
471
480
  targeted_variations = []
472
481
 
data/lib/vwo/enums.rb CHANGED
@@ -114,6 +114,9 @@ class VWO
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
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"
117
+ IMPRESSION_FOR_EVENT_ARCH_TRACK_USER = "(%<file>s): impression built for vwo_variationShown event for account ID:%<a>s, user ID:%<u>s, and campaign ID:%<c>s"
118
+ IMPRESSION_FOR_EVENT_ARCH_TRACK_GOAL = "(%<file>s): impression built for %<goal_identifier>s event for account ID:%<a>s, user ID:%<u>s, and campaign ID:%<c>s"
119
+ IMPRESSION_FOR_EVENT_ARCH_PUSH = "(%<file>s): impression built for visitor property:%<property>s for account ID:%<a>s and user ID:%<u>s"
117
120
  end
118
121
 
119
122
  # Info Messages
@@ -128,6 +131,7 @@ class VWO
128
131
  AUDIENCE_CONDITION_NOT_MET = '(%<file>s): userId:%<user_id>s does not become part of campaign because of not meeting audience conditions'
129
132
  GOT_VARIATION_FOR_USER = '(%<file>s): userId:%<user_id>s for campaign:%<campaign_key>s got variationName:%<variation_name>s'
130
133
  USER_GOT_NO_VARIATION = '(%<file>s): userId:%<user_id>s for campaign:%<campaign_key>s did not allot any variation'
134
+ IMPRESSION_SUCCESS_FOR_EVENT_ARCH = '(%<file>s): Impression for %<event>s - %<url>s was successfully received by VWO for account ID:%<a>s'
131
135
  IMPRESSION_SUCCESS = '(%<file>s): Impression event - %<end_point>s was successfully received by VWO having main keys: accountId:%<account_id>s campaignId:%<campaign_id>s and variationId:%<variation_id>s'
132
136
  MAIN_KEYS_FOR_IMPRESSION = '(%<file>s): Having main keys: accountId:%<account_id>s campaignId:%<campaign_id>s and variationId:%<variation_id>s}'
133
137
  MAIN_KEYS_FOR_PUSH_API = '(%<file>s): Having main keys: accountId:%<account_id>s u:%<u>s and tags:%<tags>s}'
@@ -160,6 +164,8 @@ class VWO
160
164
  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
165
  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
166
  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"
167
+ OPT_OUT_API_CALLED = "(%<file>s): You have opted out for not tracking i.e. all API calls will stop functioning and will simply early return"
168
+ API_NOT_ENABLED = "(%<file>s): %<api>s API is disabled as you opted out for tracking. Reinitialize the SDK to enable the normal functioning of all APIs."
163
169
  end
164
170
 
165
171
  # Warning Messages
@@ -201,7 +207,6 @@ class VWO
201
207
  TAG_KEY_LENGTH_EXCEEDED = '(%<file>s): In API: %<api_name>s, the length of tag_key:%<tag_key>s and userID: %<user_id>s can not be greater than 255'
202
208
  TRACK_API_MISSING_PARAMS = '(%<file>s): "track" API got bad parameters. It expects campaignKey(null/String/array) as first, userId(String/Number) as second and goalIdentifier (string) as third argument. options is revenueValue(Float/Number/String) and is required for revenue goal only.'
203
209
  NO_CAMPAIGN_FOUND = '(%<file>s): No campaign found for goal_identifier:%<goal_identifier>s. Please verify from VWO app.'
204
- INVALID_TRACK_RETURNING_USER_VALUE = '(%<file>s): should_track_returning_user should be boolean'
205
210
  INVALID_GOAL_TYPE = '(%<file>s): goal_type_to_track should be certain strings'
206
211
  EVENT_BATCHING_NOT_OBJECT = '(%<file>s): Batch events settings are not of type object.'
207
212
  EVENTS_PER_REQUEST_INVALID = '(%<file>s): events_per_request should be an integer'
@@ -26,6 +26,9 @@ class VWO
26
26
  accountId: {
27
27
  type: %w[number string]
28
28
  },
29
+ isEventArchEnabled: {
30
+ type: ['boolean']
31
+ },
29
32
  campaigns: {
30
33
  if: {
31
34
  type: 'array'
@@ -95,6 +98,7 @@ class VWO
95
98
  }
96
99
  },
97
100
  isBucketingSeedEnabled: ['boolean'],
101
+ isUserListEnabled: ['boolean'],
98
102
  minItems: 2
99
103
  }
100
104
  },
@@ -15,11 +15,13 @@
15
15
  require_relative '../logger'
16
16
  require_relative '../enums'
17
17
  require_relative '../utils/request'
18
+ require_relative '../constants'
18
19
 
19
20
  class VWO
20
21
  module Services
21
22
  class EventDispatcher
22
23
  include VWO::Enums
24
+ include VWO::CONSTANTS
23
25
 
24
26
  EXCLUDE_KEYS = ['url'].freeze
25
27
 
@@ -63,6 +65,38 @@ class VWO
63
65
  )
64
66
  false
65
67
  end
68
+
69
+ def dispatch_event_arch_post(params, post_data)
70
+ return true if @is_development_mode
71
+
72
+ url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL + ENDPOINTS::EVENTS
73
+ resp = VWO::Utils::Request.event_post(url, params, post_data, SDK_NAME)
74
+ if resp.code == '200'
75
+ @logger.log(
76
+ LogLevelEnum::INFO,
77
+ format(
78
+ LogMessageEnum::InfoMessages::IMPRESSION_SUCCESS_FOR_EVENT_ARCH,
79
+ file: FileNameEnum::EventDispatcher,
80
+ event: 'visitor property:' + JSON.generate(post_data[:d][:visitor][:props]),
81
+ url: url,
82
+ a: params[:a]
83
+ )
84
+ )
85
+ true
86
+ else
87
+ @logger.log(
88
+ LogLevelEnum::ERROR,
89
+ format(LogMessageEnum::ErrorMessages::IMPRESSION_FAILED, file: FileNameEnum::EventDispatcher, end_point: url)
90
+ )
91
+ false
92
+ end
93
+ rescue StandardError
94
+ @logger.log(
95
+ LogLevelEnum::ERROR,
96
+ format(LogMessageEnum::ErrorMessages::IMPRESSION_FAILED, file: FileNameEnum::EventDispatcher, end_point: url)
97
+ )
98
+ false
99
+ end
66
100
  end
67
101
  end
68
102
  end
@@ -33,6 +33,11 @@ class VWO
33
33
  Time.now.to_i
34
34
  end
35
35
 
36
+ # @return[Integer]
37
+ def get_current_unix_timestamp_in_millis
38
+ (Time.now.to_f * 1000).to_i
39
+ end
40
+
36
41
  # @return[any, any]
37
42
  def get_key_value(obj)
38
43
  [obj.keys[0], obj.values[0]]
@@ -164,6 +164,186 @@ class VWO
164
164
  end
165
165
  impression
166
166
  end
167
+
168
+ # Builds generic properties for different tracking calls required by VWO servers.
169
+ #
170
+ # @param[Hash] :settings_file
171
+ # @param[String] :sdk_key
172
+ # @param[String] :event_name
173
+ # @param[Hash] :usage_stats
174
+ # @return[Hash] :properties
175
+ #
176
+ def get_events_base_properties(settings_file, event_name, usage_stats = {})
177
+ properties = {
178
+ en: event_name,
179
+ a: settings_file['accountId'],
180
+ env: settings_file['sdkKey'],
181
+ eTime: get_current_unix_timestamp_in_millis,
182
+ random: get_random_number,
183
+ p: "FS"
184
+ }
185
+
186
+ if event_name == EventEnum::VWO_VARIATION_SHOWN
187
+ properties = properties.merge(usage_stats)
188
+ end
189
+ properties
190
+ end
191
+
192
+ # Builds generic payload required by all the different tracking calls.
193
+ #
194
+ # @param[Hash] :settings_file
195
+ # @param[String] :user_id
196
+ # @param[String] :event_name
197
+ # @param[Hash] :usage_stats
198
+ # @return[Hash] :properties
199
+ #
200
+ def get_event_base_payload(settings_file, user_id, event_name, usage_stats = {})
201
+ uuid = generator_for(user_id, (settings_file['accountId']))
202
+ sdk_key = settings_file['sdkKey']
203
+
204
+ props = {
205
+ sdkName: SDK_NAME,
206
+ sdkVersion: SDK_VERSION,
207
+ '$visitor': {
208
+ props: {
209
+ vwo_fs_environment: sdk_key
210
+ }
211
+ }
212
+ }
213
+
214
+ # if usage_stats
215
+ # props = props.merge(usage_stats)
216
+ # end
217
+
218
+ properties = {
219
+ d: {
220
+ msgId: uuid + '_' + Time.now.to_i.to_s,
221
+ visId: uuid,
222
+ sessionId: Time.now.to_i,
223
+ event: {
224
+ props: props,
225
+ name: event_name,
226
+ time: get_current_unix_timestamp_in_millis
227
+ },
228
+ visitor: {
229
+ props: {
230
+ vwo_fs_environment: sdk_key
231
+ }
232
+ }
233
+ }
234
+ }
235
+
236
+ properties
237
+ end
238
+
239
+ # Builds payload to track the visitor.
240
+ #
241
+ # @param[Hash] :settings_file
242
+ # @param[String] :user_id
243
+ # @param[String] :event_name
244
+ # @param[Integer] :campaign_id
245
+ # @param[Integer] :variation_id
246
+ # @param[Hash] :usage_stats
247
+ # @return[Hash] :properties
248
+ #
249
+ def get_track_user_payload_data(settings_file, user_id, event_name, campaign_id, variation_id, usage_stats = {})
250
+ properties = get_event_base_payload(settings_file, user_id, event_name)
251
+ properties[:d][:event][:props][:id] = campaign_id
252
+ properties[:d][:event][:props][:variation] = variation_id
253
+
254
+ #this is currently required by data-layer team, we can make changes on DACDN and remove it from here
255
+ properties[:d][:event][:props][:isFirst] = 1
256
+
257
+ logger = VWO::Logger.get_instance
258
+ logger.log(
259
+ LogLevelEnum::DEBUG,
260
+ format(
261
+ LogMessageEnum::DebugMessages::IMPRESSION_FOR_EVENT_ARCH_TRACK_USER,
262
+ file: FileNameEnum::ImpressionUtil,
263
+ a: settings_file['accountId'],
264
+ u: user_id,
265
+ c: campaign_id.to_s
266
+ )
267
+ )
268
+ properties
269
+ end
270
+
271
+ # Builds payload to track the Goal.
272
+ #
273
+ # @param[Hash] :settings_file
274
+ # @param[String] :user_id
275
+ # @param[String] :event_name
276
+ # @param[Integer] :revenue_value
277
+ # @param[Hash] :metric_map
278
+ # @param[Array] :revenue_props
279
+ #
280
+ # @return[Hash] :properties
281
+ #
282
+ def get_track_goal_payload_data(settings_file, user_id, event_name, revenue_value, metric_map, revenue_props = [])
283
+ properties = get_event_base_payload(settings_file, user_id, event_name)
284
+
285
+ logger = VWO::Logger.get_instance
286
+ metric = {}
287
+ metric_map.each do |campaign_id, goal_id|
288
+ metric[('id_' + campaign_id.to_s).to_sym] = ['g_' + goal_id.to_s]
289
+ logger.log(
290
+ LogLevelEnum::DEBUG,
291
+ format(
292
+ LogMessageEnum::DebugMessages::IMPRESSION_FOR_EVENT_ARCH_TRACK_GOAL,
293
+ file: FileNameEnum::ImpressionUtil,
294
+ goal_identifier: event_name,
295
+ a: settings_file['accountId'],
296
+ u: user_id,
297
+ c: campaign_id
298
+ )
299
+ )
300
+ end
301
+
302
+ properties[:d][:event][:props][:vwoMeta] = {
303
+ metric: metric
304
+ }
305
+
306
+ if revenue_props.length() != 0 && revenue_value
307
+ revenue_props.each do |revenue_prop|
308
+ properties[:d][:event][:props][:vwoMeta][revenue_prop.to_sym] = revenue_value
309
+ end
310
+ end
311
+
312
+ properties[:d][:event][:props][:isCustomEvent] = true
313
+ properties
314
+ end
315
+
316
+ # Builds payload to appply post segmentation on VWO campaign reports.
317
+ #
318
+ # @param[Hash] :settings_file
319
+ # @param[String] :user_id
320
+ # @param[String] :event_name
321
+ # @param[Hash] :custom_dimension_map
322
+ #
323
+ # @return[Hash] :properties
324
+ #
325
+ def get_push_payload_data(settings_file, user_id, event_name, custom_dimension_map = {})
326
+ properties = get_event_base_payload(settings_file, user_id, event_name)
327
+ properties[:d][:event][:props][:isCustomEvent] = true
328
+
329
+ custom_dimension_map.each do |tag_key, tag_value|
330
+ properties[:d][:event][:props][('$visitor'.to_sym)][:props][tag_key] = tag_value
331
+ properties[:d][:visitor][:props][tag_key] = tag_value
332
+ end
333
+
334
+ logger = VWO::Logger.get_instance
335
+ logger.log(
336
+ LogLevelEnum::DEBUG,
337
+ format(
338
+ LogMessageEnum::DebugMessages::IMPRESSION_FOR_EVENT_ARCH_PUSH,
339
+ file: FileNameEnum::ImpressionUtil,
340
+ a: settings_file['accountId'],
341
+ u: user_id,
342
+ property: JSON.generate(custom_dimension_map)
343
+ )
344
+ )
345
+ properties
346
+ end
167
347
  end
168
348
  end
169
349
  end
@@ -38,6 +38,20 @@ class VWO
38
38
  response = http.post(uri, post_data.to_json, headers)
39
39
  response
40
40
  end
41
+
42
+ def self.event_post(url, params, post_data, user_agent_value)
43
+ uri = URI.parse(url)
44
+ http = Net::HTTP.new(uri.host, uri.port)
45
+ http.use_ssl = true
46
+ uri.query = URI.encode_www_form(params)
47
+ headers = {
48
+ 'User-Agent' => user_agent_value,
49
+ 'Content-Type' =>'application/json',
50
+ 'Accept'=>'application/json'
51
+ }
52
+ response = http.post(uri, post_data.to_json, headers)
53
+ response
54
+ end
41
55
  end
42
56
  end
43
57
  end
data/lib/vwo.rb CHANGED
@@ -65,6 +65,7 @@ class VWO
65
65
  options = {}
66
66
  )
67
67
  options = convert_to_symbol_hash(options)
68
+ @is_opted_out = false
68
69
  @account_id = account_id
69
70
  @sdk_key = sdk_key
70
71
  @user_storage = user_storage
@@ -89,25 +90,6 @@ class VWO
89
90
  return
90
91
  end
91
92
 
92
- if options.key?(:should_track_returning_user)
93
- if [true, false].include? options[:should_track_returning_user]
94
- @should_track_returning_user = options[:should_track_returning_user]
95
- usage_stats[:tr] = 1 if @should_track_returning_user
96
- else
97
- @logger.log(
98
- LogLevelEnum::ERROR,
99
- format(
100
- LogMessageEnum::ErrorMessages::INVALID_TRACK_RETURNING_USER_VALUE,
101
- file: FILE
102
- )
103
- )
104
- @is_instance_valid = false
105
- return
106
- end
107
- else
108
- @should_track_returning_user = false
109
- end
110
-
111
93
  if options.key?(:goal_type_to_track)
112
94
  if GOAL_TYPES.key? options[:goal_type_to_track]
113
95
  @goal_type_to_track = options[:goal_type_to_track]
@@ -227,6 +209,10 @@ class VWO
227
209
  # VWO get_settings method to get settings for a particular account_id
228
210
  def get_and_update_settings_file
229
211
 
212
+ if is_opted_out(ApiMethods::GET_AND_UPDATE_SETTINGS_FILE)
213
+ return false
214
+ end
215
+
230
216
  unless @is_instance_valid
231
217
  @logger.log(
232
218
  LogLevelEnum::ERROR,
@@ -236,7 +222,7 @@ class VWO
236
222
  api_name: ApiMethods.GET_AND_UPDATE_SETTINGS_FILE
237
223
  )
238
224
  )
239
- return
225
+ return false
240
226
  end
241
227
 
242
228
  latest_settings = @settings_file_manager.get_settings_file(true)
@@ -286,6 +272,10 @@ class VWO
286
272
  # otherwise null in case of user not becoming part
287
273
 
288
274
  def activate(campaign_key, user_id, options = {})
275
+ if is_opted_out(ApiMethods::ACTIVATE)
276
+ return nil
277
+ end
278
+
289
279
  unless @is_instance_valid
290
280
  @logger.log(
291
281
  LogLevelEnum::ERROR,
@@ -303,10 +293,9 @@ class VWO
303
293
  custom_variables = options[:custom_variables]
304
294
  variation_targeting_variables = options[:variation_targeting_variables]
305
295
 
306
- should_track_returning_user = get_should_track_returning_user(options)
307
296
  # Validate input parameters
308
297
  unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
309
- (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables)) && [true, false].include?(should_track_returning_user)
298
+ (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
310
299
  @logger.log(
311
300
  LogLevelEnum::ERROR,
312
301
  format(
@@ -381,7 +370,7 @@ class VWO
381
370
  return
382
371
  end
383
372
 
384
- if is_eligible_to_send_impression(should_track_returning_user)
373
+ if is_eligible_to_send_impression()
385
374
  if defined?(@batch_events)
386
375
  impression = create_bulk_event_impression(
387
376
  @settings_file,
@@ -390,6 +379,10 @@ class VWO
390
379
  user_id
391
380
  )
392
381
  @batch_events_queue.enqueue(impression)
382
+ elsif is_event_arch_enabled
383
+ properties = get_events_base_properties(@settings_file, EventEnum::VWO_VARIATION_SHOWN, @usage_stats.usage_stats)
384
+ payload = get_track_user_payload_data(@settings_file, user_id, EventEnum::VWO_VARIATION_SHOWN, campaign['id'], variation['id'])
385
+ @event_dispatcher.dispatch_event_arch_post(properties, payload)
393
386
  else
394
387
  # Variation found, dispatch it to server
395
388
  impression = create_impression(
@@ -460,6 +453,10 @@ class VWO
460
453
  # Otherwise null in case of user not becoming part
461
454
  #
462
455
  def get_variation_name(campaign_key, user_id, options = {})
456
+ if is_opted_out(ApiMethods::GET_VARIATION_NAME)
457
+ return nil
458
+ end
459
+
463
460
  unless @is_instance_valid
464
461
  @logger.log(
465
462
  LogLevelEnum::ERROR,
@@ -571,6 +568,10 @@ class VWO
571
568
  #
572
569
 
573
570
  def track(campaign_key, user_id, goal_identifier, options = {})
571
+ if is_opted_out(ApiMethods::TRACK)
572
+ return false
573
+ end
574
+
574
575
  unless @is_instance_valid
575
576
  @logger.log(
576
577
  LogLevelEnum::ERROR,
@@ -587,12 +588,11 @@ class VWO
587
588
  revenue_value = options[:revenue_value]
588
589
  custom_variables = options[:custom_variables]
589
590
  variation_targeting_variables = options[:variation_targeting_variables]
590
- should_track_returning_user = get_should_track_returning_user(options)
591
591
  goal_type_to_track = get_goal_type_to_track(options)
592
592
 
593
593
  # Check for valid args
594
594
  unless (valid_string?(campaign_key) || campaign_key.is_a?(Array) || campaign_key.nil?) && valid_string?(user_id) && valid_string?(goal_identifier) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
595
- (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables)) && [true, false].include?(should_track_returning_user) && (GOAL_TYPES.key? (goal_type_to_track))
595
+ (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables)) && (GOAL_TYPES.key? (goal_type_to_track))
596
596
  # log invalid params
597
597
  @logger.log(
598
598
  LogLevelEnum::ERROR,
@@ -613,6 +613,8 @@ class VWO
613
613
  return nil
614
614
  end
615
615
 
616
+ metric_map = {}
617
+ revenue_props = []
616
618
  result = {}
617
619
  campaigns.each do |campaign|
618
620
  begin
@@ -682,7 +684,7 @@ class VWO
682
684
  updated_goal_identifier += VWO_DELIMITER + goal_identifier
683
685
  @variation_decider.save_user_storage(user_id, campaign['key'], campaign['name'], variation['name'], updated_goal_identifier) if variation['name']
684
686
  # set variation at user storage
685
- elsif !should_track_returning_user
687
+ else
686
688
  @logger.log(
687
689
  LogLevelEnum::INFO,
688
690
  format(
@@ -708,6 +710,11 @@ class VWO
708
710
  revenue_value
709
711
  )
710
712
  @batch_events_queue.enqueue(impression)
713
+ elsif is_event_arch_enabled
714
+ metric_map[campaign['id']] = goal['id']
715
+ if goal['type'] == GoalTypes::REVENUE && !(revenue_props.include? goal['revenueProp'])
716
+ revenue_props << goal['revenueProp']
717
+ end
711
718
  else
712
719
  impression = create_impression(
713
720
  @settings_file,
@@ -758,6 +765,12 @@ class VWO
758
765
  end
759
766
  end
760
767
 
768
+ if is_event_arch_enabled
769
+ properties = get_events_base_properties(@settings_file, goal_identifier)
770
+ payload = get_track_goal_payload_data(@settings_file, user_id, goal_identifier, revenue_value, metric_map, revenue_props)
771
+ @event_dispatcher.dispatch_event_arch_post(properties, payload)
772
+ end
773
+
761
774
  if result.length() == 0
762
775
  return nil
763
776
  end
@@ -790,6 +803,10 @@ class VWO
790
803
  # @return[Boolean] true if user becomes part of feature test/rollout, otherwise false.
791
804
 
792
805
  def feature_enabled?(campaign_key, user_id, options = {})
806
+ if is_opted_out(ApiMethods::IS_FEATURE_ENABLED)
807
+ return false
808
+ end
809
+
793
810
  unless @is_instance_valid
794
811
  @logger.log(
795
812
  LogLevelEnum::ERROR,
@@ -806,7 +823,6 @@ class VWO
806
823
  # Retrieve custom variables
807
824
  custom_variables = options[:custom_variables]
808
825
  variation_targeting_variables = options[:variation_targeting_variables]
809
- should_track_returning_user = get_should_track_returning_user(options)
810
826
  @logger.log(
811
827
  LogLevelEnum::INFO,
812
828
  format(
@@ -818,7 +834,7 @@ class VWO
818
834
  )
819
835
  # Validate input parameters
820
836
  unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
821
- (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables)) && [true, false].include?(should_track_returning_user)
837
+ (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
822
838
  @logger.log(
823
839
  LogLevelEnum::ERROR,
824
840
  format(
@@ -874,7 +890,7 @@ class VWO
874
890
 
875
891
  # if campaign type is feature_test Send track call to server
876
892
 
877
- if is_eligible_to_send_impression(should_track_returning_user)
893
+ if is_eligible_to_send_impression()
878
894
  if defined?(@batch_events)
879
895
  impression = create_bulk_event_impression(
880
896
  @settings_file,
@@ -883,6 +899,10 @@ class VWO
883
899
  user_id
884
900
  )
885
901
  @batch_events_queue.enqueue(impression)
902
+ elsif is_event_arch_enabled
903
+ properties = get_events_base_properties(@settings_file, EventEnum::VWO_VARIATION_SHOWN, @usage_stats.usage_stats)
904
+ payload = get_track_user_payload_data(@settings_file, user_id, EventEnum::VWO_VARIATION_SHOWN, campaign['id'], variation['id'])
905
+ @event_dispatcher.dispatch_event_arch_post(properties, payload)
886
906
  else
887
907
  impression = create_impression(
888
908
  @settings_file,
@@ -984,13 +1004,17 @@ class VWO
984
1004
  #
985
1005
 
986
1006
  def get_feature_variable_value(campaign_key, variable_key, user_id, options = {})
1007
+ if is_opted_out(ApiMethods::GET_FEATURE_VARIABLE_VALUE)
1008
+ return nil
1009
+ end
1010
+
987
1011
  unless @is_instance_valid
988
1012
  @logger.log(
989
1013
  LogLevelEnum::ERROR,
990
1014
  format(
991
1015
  LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
992
1016
  file: FILE,
993
- api_name: ApiMethods.GET_FEATURE_VARIABLE_VALUE
1017
+ api_name: ApiMethods::GET_FEATURE_VARIABLE_VALUE
994
1018
  )
995
1019
  )
996
1020
  return
@@ -1132,25 +1156,38 @@ class VWO
1132
1156
  # This API method: Makes a call to our server to store the tag_values
1133
1157
  # 1. Validates the arguments being passed
1134
1158
  # 2. Send a call to our server
1135
- # @param[String] :tag_key key name of the tag
1136
- # @param[String] :tag_value Value of the tag
1159
+ # @param[String|Hash] :tag_key key name of the tag OR tagKey/tagValue pair(custom dimension map)
1160
+ # @param[String] :tag_value Value of the tag OR userId if TagKey is hash
1137
1161
  # @param[String] :user_id ID of the user for which value should be stored
1138
1162
  # @return true if call is made successfully, else false
1139
1163
 
1140
- def push(tag_key, tag_value, user_id)
1164
+ def push(tag_key, tag_value, user_id = nil)
1165
+ if is_opted_out(ApiMethods::PUSH)
1166
+ return false
1167
+ end
1168
+
1141
1169
  unless @is_instance_valid
1142
1170
  @logger.log(
1143
1171
  LogLevelEnum::ERROR,
1144
1172
  format(
1145
1173
  LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
1146
1174
  file: FILE,
1147
- api_name: ApiMethods.PUSH
1175
+ api_name: ApiMethods::PUSH
1148
1176
  )
1149
1177
  )
1150
- return
1178
+ return false
1179
+ end
1180
+
1181
+ # Argument reshuffling.
1182
+ custom_dimension_map = {}
1183
+ if user_id.nil? || tag_key.is_a?(Hash)
1184
+ custom_dimension_map = convert_to_symbol_hash(tag_key)
1185
+ user_id = tag_value
1186
+ else
1187
+ custom_dimension_map[tag_key.to_sym] = tag_value
1151
1188
  end
1152
1189
 
1153
- unless valid_string?(tag_key) && valid_string?(tag_value) && valid_string?(user_id)
1190
+ unless (valid_string?(tag_key) || valid_hash?(tag_key)) && valid_string?(tag_value) && valid_string?(user_id)
1154
1191
  @logger.log(
1155
1192
  LogLevelEnum::ERROR,
1156
1193
  format(
@@ -1162,51 +1199,61 @@ class VWO
1162
1199
  return false
1163
1200
  end
1164
1201
 
1165
- if tag_key.length > PushApi::TAG_KEY_LENGTH
1166
- @logger.log(
1167
- LogLevelEnum::ERROR,
1168
- format(
1169
- LogMessageEnum::ErrorMessages::TAG_KEY_LENGTH_EXCEEDED,
1170
- file: FILE,
1171
- user_id: user_id,
1172
- tag_key: tag_key,
1173
- api_name: ApiMethods::PUSH
1202
+ custom_dimension_map.each do |tag_key, tag_value|
1203
+ if tag_key.length > PushApi::TAG_KEY_LENGTH
1204
+ @logger.log(
1205
+ LogLevelEnum::ERROR,
1206
+ format(
1207
+ LogMessageEnum::ErrorMessages::TAG_KEY_LENGTH_EXCEEDED,
1208
+ file: FILE,
1209
+ user_id: user_id,
1210
+ tag_key: tag_key,
1211
+ api_name: ApiMethods::PUSH
1212
+ )
1174
1213
  )
1175
- )
1176
- return false
1177
- end
1214
+ return false
1215
+ end
1178
1216
 
1179
- if tag_value.length > PushApi::TAG_VALUE_LENGTH
1180
- @logger.log(
1181
- LogLevelEnum::ERROR,
1182
- format(
1183
- LogMessageEnum::ErrorMessages::TAG_VALUE_LENGTH_EXCEEDED,
1184
- file: FILE,
1185
- user_id: user_id,
1186
- tag_value: tag_value,
1187
- api_name: ApiMethods::PUSH
1217
+ if tag_value.length > PushApi::TAG_VALUE_LENGTH
1218
+ @logger.log(
1219
+ LogLevelEnum::ERROR,
1220
+ format(
1221
+ LogMessageEnum::ErrorMessages::TAG_VALUE_LENGTH_EXCEEDED,
1222
+ file: FILE,
1223
+ user_id: user_id,
1224
+ tag_value: tag_value,
1225
+ api_name: ApiMethods::PUSH
1226
+ )
1188
1227
  )
1189
- )
1190
- return false
1228
+ return false
1229
+ end
1191
1230
  end
1192
1231
 
1193
1232
  if defined?(@batch_events)
1194
- impression = get_batch_event_url_params(@settings_file, tag_key, tag_value, user_id)
1195
- @batch_events_queue.enqueue(impression)
1233
+ custom_dimension_map.each do |tag_key, tag_value|
1234
+ impression = get_batch_event_url_params(@settings_file, tag_key, tag_value, user_id)
1235
+ @batch_events_queue.enqueue(impression)
1236
+ end
1237
+ elsif is_event_arch_enabled
1238
+ properties = get_events_base_properties(@settings_file, EventEnum::VWO_SYNC_VISITOR_PROP)
1239
+ payload = get_push_payload_data(@settings_file, user_id, EventEnum::VWO_SYNC_VISITOR_PROP, custom_dimension_map)
1240
+ @event_dispatcher.dispatch_event_arch_post(properties, payload)
1196
1241
  else
1197
- impression = get_url_params(@settings_file, tag_key, tag_value, user_id, @sdk_key)
1198
- @event_dispatcher.dispatch(impression)
1242
+ custom_dimension_map.each do |tag_key, tag_value|
1243
+ impression = get_url_params(@settings_file, tag_key, tag_value, user_id, @sdk_key)
1244
+ @event_dispatcher.dispatch(impression)
1199
1245
 
1200
- @logger.log(
1201
- LogLevelEnum::INFO,
1202
- format(
1203
- LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_PUSH_API,
1204
- file: FILE,
1205
- u: impression['u'],
1206
- account_id: impression['account_id'],
1207
- tags: impression['tags']
1246
+ @logger.log(
1247
+ LogLevelEnum::INFO,
1248
+ format(
1249
+ LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_PUSH_API,
1250
+ file: FILE,
1251
+ u: impression['u'],
1252
+ account_id: impression['account_id'],
1253
+ tags: impression['tags']
1254
+ )
1208
1255
  )
1209
- )
1256
+ end
1210
1257
  end
1211
1258
  true
1212
1259
  rescue StandardError => e
@@ -1222,26 +1269,15 @@ class VWO
1222
1269
  false
1223
1270
  end
1224
1271
 
1225
- def get_should_track_returning_user(options)
1226
- if !options.key?(:should_track_returning_user)
1227
- options[:should_track_returning_user] = @should_track_returning_user
1228
- elsif ![true, false].include?(options[:should_track_returning_user])
1229
- @logger.log(
1230
- LogLevelEnum::ERROR,
1231
- format(
1232
- LogMessageEnum::ErrorMessages::INVALID_TRACK_RETURNING_USER_VALUE,
1233
- file: FILE
1234
- )
1235
- )
1236
- end
1237
- options[:should_track_returning_user]
1238
- end
1239
-
1240
- def is_eligible_to_send_impression(should_track_returning_user = false)
1241
- !@user_storage || !@variation_decider.has_stored_variation || should_track_returning_user
1272
+ def is_eligible_to_send_impression()
1273
+ !@user_storage || !@variation_decider.has_stored_variation
1242
1274
  end
1243
1275
 
1244
1276
  def flush_events
1277
+ if is_opted_out(ApiMethods::FLUSH_EVENTS)
1278
+ return false
1279
+ end
1280
+
1245
1281
  unless @is_instance_valid
1246
1282
  @logger.log(
1247
1283
  LogLevelEnum::ERROR,
@@ -1251,10 +1287,13 @@ class VWO
1251
1287
  api_name: ApiMethods::FLUSH_EVENTS
1252
1288
  )
1253
1289
  )
1254
- return
1290
+ return false
1291
+ end
1292
+ result = false
1293
+ if defined?(@batch_events) && !@batch_events_queue.nil?
1294
+ result = @batch_events_queue.flush(manual: true)
1295
+ @batch_events_queue.kill_thread
1255
1296
  end
1256
- result = @batch_events_queue.flush(manual: true)
1257
- @batch_events_queue.kill_thread
1258
1297
  result
1259
1298
  rescue StandardError => e
1260
1299
  @logger.log(
@@ -1290,4 +1329,57 @@ class VWO
1290
1329
  end
1291
1330
  goal_type_to_track
1292
1331
  end
1332
+
1333
+ # Manually opting out of VWO SDK, No tracking will happen
1334
+ #
1335
+ # return[bool]
1336
+ #
1337
+ def set_opt_out
1338
+ @logger.log(
1339
+ LogLevelEnum::INFO,
1340
+ format(
1341
+ LogMessageEnum::InfoMessages::OPT_OUT_API_CALLED,
1342
+ file: FILE
1343
+ )
1344
+ )
1345
+ if defined?(@batch_events) && !@batch_events_queue.nil?
1346
+ @batch_events_queue.flush(manual: true)
1347
+ @batch_events_queue.kill_thread
1348
+ end
1349
+
1350
+ @is_opted_out = true
1351
+ @settings_file = nil
1352
+ @user_storage = nil
1353
+ @event_dispatcher = nil
1354
+ @variation_decider = nil
1355
+ @config = nil
1356
+ @usage_stats = nil
1357
+ @batch_event_dispatcher = nil
1358
+ @batch_events_queue = nil
1359
+ @batch_events = nil
1360
+
1361
+ return @is_opted_out
1362
+ end
1363
+
1364
+
1365
+ # Check if VWO SDK is manually opted out
1366
+ # @param[String] :api_name api_name is used in logging
1367
+ # @return[bool]
1368
+ def is_opted_out(api_name)
1369
+ if @is_opted_out
1370
+ @logger.log(
1371
+ LogLevelEnum::INFO,
1372
+ format(
1373
+ LogMessageEnum::InfoMessages::API_NOT_ENABLED,
1374
+ file: FILE,
1375
+ api: api_name
1376
+ )
1377
+ )
1378
+ end
1379
+ return @is_opted_out
1380
+ end
1381
+
1382
+ def is_event_arch_enabled
1383
+ return @settings_file.key?('isEventArchEnabled') && @settings_file['isEventArchEnabled']
1384
+ end
1293
1385
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vwo-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.23.2
4
+ version: 1.28.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VWO
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-30 00:00:00.000000000 Z
11
+ date: 2021-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: codecov