vwo-sdk 1.38.0 → 1.41.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: a0e08961757aa3ab300766b7c2fd27429d0c3edb97c8e2609d3b41fb8e9b3362
4
- data.tar.gz: dda836f16065c27aed8102c2e7f666b47645c20fe38c9830c02f0c9c1a32b959
3
+ metadata.gz: b18f93260e450a83532607a0432354fcc931c6454bf830bf4a366091759f19cf
4
+ data.tar.gz: 93f40c73199b2dc5e3bd0c30afdac2c8873792aa28a58907244569b43bc10c8b
5
5
  SHA512:
6
- metadata.gz: cd96894eaf16020bddfc7246ee287ae7dbaaa9df40e9dc17ec09b0af31379a05a6d1b682665599f4f45d495ceecd5c66409cb753c7f4e59dd72d25e9037e3ef2
7
- data.tar.gz: 56a9930a525ed16aab574920cffe787da6b2ecf8225d0a8bf03edea1ab67b331e433537da35af6b70715787c61abc132e9b04b032da1950a0bc39af085c9fce2
6
+ metadata.gz: 6922959894100f9b3fcfcebe806ae9ab28953e5252af1e21e837339825fca0ae457b2d7cfe69e1d4ac885e3f8bca973b38d1c2ff0a3d47425168b3baf052701d
7
+ data.tar.gz: a3fe60c8cdb778c94d0168613281227e441543efbeb10cbbbec906022282c06b781fd089a1db50e90e802c054552df632c795899e5f59ef15f6129898171509a
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.38.0'
30
+ SDK_VERSION = '1.41.0'
31
31
  SDK_NAME = 'ruby'
32
32
  VWO_DELIMITER = '_vwo_'
33
33
  MAX_EVENTS_PER_REQUEST = 5000
data/lib/vwo/enums.rb CHANGED
@@ -21,6 +21,10 @@ class VWO
21
21
  WILDCARD = 'wildcard'
22
22
  LOWER = 'lower'
23
23
  EQUALS = 'equals'
24
+ GREATER_THAN="gt"
25
+ LESS_THAN="lt"
26
+ GREATER_THAN_EQUAL_TO="gte"
27
+ LESS_THAN_EQUAL_TO="lte"
24
28
  end
25
29
 
26
30
  module OperandValueTypes
@@ -30,6 +34,10 @@ class VWO
30
34
  ENDS_WITH = 'ends_with'
31
35
  REGEX = 'regex'
32
36
  EQUALS = 'equals'
37
+ LESS_THAN = 'less_than'
38
+ GREATER_THAN = 'greater_than'
39
+ LESS_THAN_EQUAL_TO = 'less_than_equal_to'
40
+ GREATER_THAN_EQUAL_TO = 'greater_than_equal_to'
33
41
  end
34
42
 
35
43
  module OperatorTypes
@@ -88,11 +88,11 @@ class VWO
88
88
  false
89
89
  end
90
90
 
91
- def dispatch_event_arch_post(params, post_data)
91
+ def dispatch_event_arch_post(params, post_data, options = {})
92
92
  return true if @is_development_mode
93
93
 
94
94
  url = HTTPS_PROTOCOL + get_url(ENDPOINTS::EVENTS)
95
- resp = VWO::Utils::Request.event_post(url, params, post_data, SDK_NAME)
95
+ resp = VWO::Utils::Request.event_post(url, params, post_data, SDK_NAME, options)
96
96
  if resp.code == '200'
97
97
  @logger.log(
98
98
  LogLevelEnum::INFO,
@@ -83,6 +83,43 @@ class VWO
83
83
  custom_variables_value == operand_value
84
84
  end
85
85
 
86
+ # Checks if custom_variables_value matches the regex specified by operand_value
87
+ #
88
+ # @param [String] operand_value Leaf value from the segments
89
+ # @param [Numeric] custom_variables_value Value from the custom_variables
90
+ # @return [Boolean] True or False
91
+ def less_than?(operand_value, custom_variables_value)
92
+ custom_variables_value.to_f < operand_value.to_f
93
+ end
94
+
95
+ # Checks if custom_variable_value is greater than operand_value
96
+ #
97
+ # @param [String] operand_value Leaf value from the segments
98
+ # @param [Numeric] custom_variables_value Value from the custom_variables
99
+ # @return [Boolean] True or False
100
+ def greater_than?(operand_value, custom_variables_value)
101
+ custom_variables_value.to_f > operand_value.to_f
102
+ end
103
+
104
+ # Checks if custom_variable_value is less than or equal to operand_value
105
+ #
106
+ # @param [String] operand_value Leaf value from the segments
107
+ # @param [Numeric] custom_variables_value Value from the custom_variables
108
+ # @return [Boolean] True or False
109
+ def less_than_equal_to?(operand_value, custom_variables_value)
110
+ custom_variables_value.to_f <= operand_value.to_f
111
+ end
112
+
113
+ # Checks if custom_variable_value is greater than or equal to operand_value
114
+ #
115
+ # @param [String] operand_value Leaf value from the segments
116
+ # @param [Numeric] custom_variables_value Value from the custom_variables
117
+ # @return [Boolean] True or False
118
+ def greater_than_equal_to?(operand_value, custom_variables_value)
119
+ custom_variables_value.to_f >= operand_value.to_f
120
+ end
121
+
122
+
86
123
  # Identifies the condition stated in the leaf node and evaluates the result
87
124
  #
88
125
  # @param [String] :operand_value Leaf value from the segments
@@ -125,7 +125,7 @@ class VWO
125
125
  #
126
126
  # @return[nil|Hash] None if campaign ID or variation ID is invalid,
127
127
  # Else Properties(dict)
128
- def create_bulk_event_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil)
128
+ def create_bulk_event_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil, event_properties = {} ,options = {})
129
129
  return unless valid_number?(campaign_id) && valid_string?(user_id)
130
130
 
131
131
  is_track_user_api = true
@@ -139,6 +139,15 @@ class VWO
139
139
  sId: get_current_unix_timestamp
140
140
  }
141
141
 
142
+ # Check if user_agent is provided
143
+ if options[:user_agent]
144
+ impression['visitor_ua'] = options[:user_agent]
145
+ end
146
+ # Check if user_ip_address is provided
147
+ if options[:user_ip_address]
148
+ impression['visitor_ip'] = options[:user_ip_address]
149
+ end
150
+
142
151
  if is_track_user_api
143
152
  Logger.log(
144
153
  LogLevelEnum::DEBUG,
@@ -151,6 +160,11 @@ class VWO
151
160
  else
152
161
  impression['g'] = goal_id
153
162
  impression['r'] = revenue if revenue
163
+
164
+ if settings_file.key?('isEventArchEnabled') && settings_file['isEventArchEnabled']
165
+ impression['eventProps'] = event_properties
166
+ end
167
+
154
168
  Logger.log(
155
169
  LogLevelEnum::DEBUG,
156
170
  'IMPRESSION_FOR_TRACK_GOAL',
@@ -198,13 +212,9 @@ class VWO
198
212
  sdk_key = settings_file['sdkKey']
199
213
 
200
214
  props = {
201
- sdkName: SDK_NAME,
202
- sdkVersion: SDK_VERSION,
203
- '$visitor': {
204
- props: {
205
- vwo_fs_environment: sdk_key
206
- }
207
- }
215
+ vwo_sdkName: SDK_NAME,
216
+ vwo_sdkVersion: SDK_VERSION,
217
+
208
218
  }
209
219
 
210
220
  # if usage_stats
@@ -213,7 +223,7 @@ class VWO
213
223
 
214
224
  {
215
225
  d: {
216
- msgId: "#{uuid} + '_' + #{Time.now.to_i}",
226
+ msgId: "#{uuid}-#{get_current_unix_timestamp_in_millis}",
217
227
  visId: uuid,
218
228
  sessionId: Time.now.to_i,
219
229
  event: {
@@ -269,10 +279,11 @@ class VWO
269
279
  # @param[Integer] :revenue_value
270
280
  # @param[Hash] :metric_map
271
281
  # @param[Array] :revenue_props
282
+ # @param[Hash] :properties associated with the event.
272
283
  #
273
284
  # @return[Hash] :properties
274
285
  #
275
- def get_track_goal_payload_data(settings_file, user_id, event_name, revenue_value, metric_map, revenue_props = [])
286
+ def get_track_goal_payload_data(settings_file, user_id, event_name, revenue_value, metric_map, revenue_props = [], event_properties)
276
287
  properties = get_event_base_payload(settings_file, user_id, event_name)
277
288
 
278
289
  metric = {}
@@ -302,6 +313,13 @@ class VWO
302
313
  end
303
314
 
304
315
  properties[:d][:event][:props][:isCustomEvent] = true
316
+
317
+ if event_properties && event_properties.any?
318
+ event_properties.each do |prop, value|
319
+ properties[:d][:event][:props][prop] = value
320
+ end
321
+ end
322
+
305
323
  properties
306
324
  end
307
325
 
@@ -319,7 +337,7 @@ class VWO
319
337
  properties[:d][:event][:props][:isCustomEvent] = true
320
338
 
321
339
  custom_dimension_map.each do |tag_key, tag_value|
322
- properties[:d][:event][:props][('$visitor'.to_sym)][:props][tag_key] = tag_value
340
+ properties[:d][:event][:props][tag_key] = tag_value
323
341
  properties[:d][:visitor][:props][tag_key] = tag_value
324
342
  end
325
343
 
@@ -25,7 +25,7 @@ class VWO
25
25
  Net::HTTP.get_response(uri)
26
26
  end
27
27
 
28
- def self.post(url, params, post_data)
28
+ def self.post(url, params, post_data, options = {})
29
29
  uri = URI.parse(url)
30
30
  http = Net::HTTP.new(uri.host, uri.port)
31
31
  http.use_ssl = true
@@ -35,10 +35,18 @@ class VWO
35
35
  'Content-Type' => 'application/json',
36
36
  'Accept' => 'application/json'
37
37
  }
38
+ # Check if user_agent is provided
39
+ if options[:user_agent]
40
+ headers['X-Device-User-Agent'] = options[:user_agent]
41
+ end
42
+ # Check if user_ip_address is provided
43
+ if options[:user_ip_address]
44
+ headers['VWO-X-Forwarded-For'] = options[:user_ip_address]
45
+ end
38
46
  http.post(uri, post_data.to_json, headers)
39
47
  end
40
48
 
41
- def self.event_post(url, params, post_data, user_agent_value)
49
+ def self.event_post(url, params, post_data, user_agent_value, options = {})
42
50
  uri = URI.parse(url)
43
51
  http = Net::HTTP.new(uri.host, uri.port)
44
52
  http.use_ssl = true
@@ -48,6 +56,14 @@ class VWO
48
56
  'Content-Type' => 'application/json',
49
57
  'Accept' => 'application/json'
50
58
  }
59
+ # Check if user_agent is provided
60
+ if options[:user_agent]
61
+ headers['X-Device-User-Agent'] = options[:user_agent]
62
+ end
63
+ # Check if user_ip_address is provided
64
+ if options[:user_ip_address]
65
+ headers['VWO-X-Forwarded-For'] = options[:user_ip_address]
66
+ end
51
67
  http.post(uri, post_data.to_json, headers)
52
68
  end
53
69
  end
@@ -101,6 +101,14 @@ class VWO
101
101
  else
102
102
  OperandValueTypes::EQUALS
103
103
  end
104
+ elsif operand_type_name == OperandValueTypesName::GREATER_THAN
105
+ operand_type = OperandValueTypes::GREATER_THAN
106
+ elsif operand_type_name == OperandValueTypesName::LESS_THAN
107
+ operand_type = OperandValueTypes::LESS_THAN
108
+ elsif operand_type_name == OperandValueTypesName::GREATER_THAN_EQUAL_TO
109
+ operand_type = OperandValueTypes::GREATER_THAN_EQUAL_TO
110
+ elsif operand_type_name == OperandValueTypesName::LESS_THAN_EQUAL_TO
111
+ operand_type = OperandValueTypes::LESS_THAN_EQUAL_TO
104
112
  end
105
113
 
106
114
  # In case there is an abnormal patter, it would have passed all the above if cases, which means it
@@ -153,7 +153,7 @@ class VWO
153
153
  )
154
154
  end
155
155
 
156
- def valid_goal?(goal, campaign, user_id, goal_identifier, revenue_value)
156
+ def valid_goal?(goal, campaign, user_id, goal_identifier, revenue_value, is_event_arch_enabled)
157
157
  if goal.nil? || !goal['id']
158
158
  Logger.log(
159
159
  LogLevelEnum::ERROR,
@@ -166,7 +166,7 @@ class VWO
166
166
  }
167
167
  )
168
168
  return false
169
- elsif goal['type'] == GoalTypes::REVENUE && !valid_value?(revenue_value)
169
+ elsif goal['type'] == GoalTypes::REVENUE && !valid_value?(revenue_value) && !is_event_arch_enabled
170
170
  Logger.log(
171
171
  LogLevelEnum::ERROR,
172
172
  'TRACK_API_REVENUE_NOT_PASSED_FOR_REVENUE_GOAL',
data/lib/vwo.rb CHANGED
@@ -365,13 +365,14 @@ class VWO
365
365
  @settings_file,
366
366
  campaign['id'],
367
367
  variation['id'],
368
- user_id
368
+ user_id, nil, nil, nil,
369
+ options
369
370
  )
370
371
  @batch_events_queue.enqueue(impression)
371
372
  elsif event_arch_enabled?
372
373
  properties = get_events_base_properties(@settings_file, EventEnum::VWO_VARIATION_SHOWN, @usage_stats.usage_stats)
373
374
  payload = get_track_user_payload_data(@settings_file, user_id, EventEnum::VWO_VARIATION_SHOWN, campaign['id'], variation['id'])
374
- @event_dispatcher.dispatch_event_arch_post(properties, payload)
375
+ @event_dispatcher.dispatch_event_arch_post(properties, payload, options)
375
376
  else
376
377
  # Variation found, dispatch it to server
377
378
  impression = create_impression(
@@ -565,6 +566,7 @@ class VWO
565
566
  revenue_value = options[:revenue_value]
566
567
  custom_variables = options[:custom_variables]
567
568
  variation_targeting_variables = options[:variation_targeting_variables]
569
+ event_properties = options[:event_properties]
568
570
  goal_type_to_track = get_goal_type_to_track(options)
569
571
 
570
572
  # Check for valid args
@@ -591,7 +593,7 @@ class VWO
591
593
 
592
594
  if variation
593
595
  goal = get_campaign_goal(campaign, goal_identifier)
594
- next unless valid_goal?(goal, campaign, user_id, goal_identifier, revenue_value)
596
+ next unless valid_goal?(goal, campaign, user_id, goal_identifier, revenue_value, event_arch_enabled?)
595
597
 
596
598
  revenue_value = nil if goal['type'] == GoalTypes::CUSTOM
597
599
  identifiers = get_variation_identifiers(variation)
@@ -601,8 +603,55 @@ class VWO
601
603
  @variation_decider.update_goal_identifier(user_id, campaign, variation, goal_identifier)
602
604
  # set variation at user storage
603
605
 
606
+ if goal['type'] == GoalTypes::REVENUE && revenue_value.nil?
607
+ # mca implementation
608
+ if event_arch_enabled?
609
+ if goal['mca'] != -1
610
+ # Check if eventProperties contain revenueProp for mca != -1
611
+ if event_properties.nil?
612
+ # Log error if revenueProp is not found in eventProperties
613
+ @logger.log(
614
+ LogLevelEnum::ERROR,
615
+ 'Revenue property not found in event properties for revenue goal',
616
+ {
617
+ '{file}' => FILE,
618
+ '{api}' => ApiMethods::TRACK,
619
+ '{userId}' => user_id,
620
+ '{goalIdentifier}' => goal_identifier,
621
+ '{campaignKey}' => campaign['key']
622
+ }
623
+ )
624
+ result[campaign['key']] = false
625
+ next
626
+ end
627
+ elsif goal['type'] == GoalTypes::REVENUE && goal['mca'] == -1
628
+ # Check if revenueProp is defined but not found in eventProperties
629
+ if goal['revenueProp'] && event_properties.nil?
630
+ # Log error if revenueProp is defined but not found in eventProperties
631
+ @logger.log(
632
+ LogLevelEnum::ERROR,
633
+ 'Revenue property defined but not found in event properties for revenue goal',
634
+ {
635
+ '{file}' => FILE,
636
+ '{api}' => ApiMethods::TRACK,
637
+ '{userId}' => user_id,
638
+ '{goalIdentifier}' => goal_identifier,
639
+ '{campaignKey}' => campaign['key']
640
+ }
641
+ )
642
+ result[campaign['key']] = false
643
+ next
644
+ end
645
+ end
646
+ end
647
+ end
604
648
  if defined?(@batch_events)
605
- impression = create_bulk_event_impression(@settings_file, campaign['id'], variation['id'], user_id, goal['id'], revenue_value)
649
+ if event_arch_enabled?
650
+ if goal['type'] == GoalTypes::REVENUE && goal['revenueProp'] && event_properties && event_properties.key?(goal['revenueProp'])
651
+ revenue_value = event_properties[goal['revenueProp']]
652
+ end
653
+ end
654
+ impression = create_bulk_event_impression(@settings_file, campaign['id'], variation['id'], user_id, goal['id'], revenue_value, event_properties, options)
606
655
  @batch_events_queue.enqueue(impression)
607
656
  elsif event_arch_enabled?
608
657
  metric_map[campaign['id']] = goal['id']
@@ -612,7 +661,7 @@ class VWO
612
661
  main_keys = { 'campaignId' => campaign['id'], 'variationId' => variation['id'], 'goalId' => goal['id'] }
613
662
  @event_dispatcher.dispatch(impression, main_keys, EVENTS::TRACK_GOAL)
614
663
  else
615
- batch_event_data['ev'] << create_bulk_event_impression(@settings_file, campaign['id'], variation['id'], user_id, goal['id'], revenue_value)
664
+ batch_event_data['ev'] << create_bulk_event_impression(@settings_file, campaign['id'], variation['id'], user_id, goal['id'], revenue_value, nil, options)
616
665
  end
617
666
  result[campaign['key']] = true
618
667
  next
@@ -631,8 +680,8 @@ class VWO
631
680
 
632
681
  if event_arch_enabled?
633
682
  properties = get_events_base_properties(@settings_file, goal_identifier)
634
- payload = get_track_goal_payload_data(@settings_file, user_id, goal_identifier, revenue_value, metric_map, revenue_props)
635
- @event_dispatcher.dispatch_event_arch_post(properties, payload)
683
+ payload = get_track_goal_payload_data(@settings_file, user_id, goal_identifier, revenue_value, metric_map, revenue_props, event_properties)
684
+ @event_dispatcher.dispatch_event_arch_post(properties, payload, options)
636
685
  elsif batch_event_data['ev'].count != 0
637
686
  paramters = get_batch_event_query_params(@settings_file['accountId'], @sdk_key, @usage_stats.usage_stats)
638
687
  batch_events_dispatcher = VWO::Services::BatchEventsDispatcher.new(@is_development_mode)
@@ -751,13 +800,14 @@ class VWO
751
800
  @settings_file,
752
801
  campaign['id'],
753
802
  variation['id'],
754
- user_id
803
+ user_id, nil, nil, nil,
804
+ options
755
805
  )
756
806
  @batch_events_queue.enqueue(impression)
757
807
  elsif event_arch_enabled?
758
808
  properties = get_events_base_properties(@settings_file, EventEnum::VWO_VARIATION_SHOWN, @usage_stats.usage_stats)
759
809
  payload = get_track_user_payload_data(@settings_file, user_id, EventEnum::VWO_VARIATION_SHOWN, campaign['id'], variation['id'])
760
- @event_dispatcher.dispatch_event_arch_post(properties, payload)
810
+ @event_dispatcher.dispatch_event_arch_post(properties, payload, options)
761
811
  else
762
812
  impression = create_impression(
763
813
  @settings_file,
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.38.0
4
+ version: 1.41.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VWO
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-27 00:00:00.000000000 Z
11
+ date: 2024-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: codecov
@@ -139,7 +139,7 @@ metadata:
139
139
  documentation_uri: https://developers.vwo.com/docs/ruby-sdk-reference
140
140
  homepage_uri: https://github.com/wingify/vwo-ruby-sdk
141
141
  source_code_uri: https://github.com/wingify/vwo-ruby-sdk
142
- post_install_message:
142
+ post_install_message:
143
143
  rdoc_options: []
144
144
  require_paths:
145
145
  - lib
@@ -154,8 +154,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
154
  - !ruby/object:Gem::Version
155
155
  version: '0'
156
156
  requirements: []
157
- rubygems_version: 3.0.6
158
- signing_key:
157
+ rubygems_version: 3.0.3.1
158
+ signing_key:
159
159
  specification_version: 4
160
160
  summary: Ruby SDK for VWO FullStack testing
161
161
  test_files: []