vwo-sdk 1.5.0 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -89,7 +89,7 @@ class VWO
89
89
  # @param [String] :custom_variables_value Value from the custom_variables
90
90
  #
91
91
  # @return [Boolean]
92
- def evaluate_operand?(operand, custom_variables)
92
+ def evaluate_custom_variable?(operand, custom_variables)
93
93
  # Extract custom_variable_key and custom_variables_value from operand
94
94
 
95
95
  operand_key, operand = get_key_value(operand)
@@ -109,6 +109,14 @@ class VWO
109
109
  # Call the self method corresponding to operand_type to evaluate the result
110
110
  public_send("#{operand_type}?", operand_value, custom_variables_value)
111
111
  end
112
+
113
+ def evaluate_user?(operand, custom_variables)
114
+ users = operand.split(',')
115
+ users.each do |user|
116
+ return true if user.strip == custom_variables['_vwo_user_id']
117
+ end
118
+ false
119
+ end
112
120
  end
113
121
  end
114
122
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -50,7 +50,9 @@ class VWO
50
50
  elsif operator == OperatorTypes::OR
51
51
  sub_dsl.any? { |y| evaluate_util(y, custom_variables) }
52
52
  elsif operator == OperandTypes::CUSTOM_VARIABLE
53
- @operand_evaluator.evaluate_operand?(sub_dsl, custom_variables)
53
+ @operand_evaluator.evaluate_custom_variable?(sub_dsl, custom_variables)
54
+ elsif operator == OperandTypes::USER
55
+ @operand_evaluator.evaluate_user?(sub_dsl, custom_variables)
54
56
  end
55
57
  end
56
58
 
@@ -66,35 +68,12 @@ class VWO
66
68
  #
67
69
  def evaluate(campaign_key, user_id, dsl, custom_variables)
68
70
  result = evaluate_util(dsl, custom_variables) if valid_value?(dsl)
69
- if result
70
- @logger.log(
71
- LogLevelEnum::INFO,
72
- format(
73
- LogMessageEnum::InfoMessages::USER_PASSED_PRE_SEGMENTATION,
74
- file: FileNameEnum::SegmentEvaluator,
75
- user_id: user_id,
76
- campaign_key: campaign_key,
77
- custom_variables: custom_variables
78
- )
79
- )
80
- else
81
- @logger.log(
82
- LogLevelEnum::INFO,
83
- format(
84
- LogMessageEnum::InfoMessages::USER_FAILED_PRE_SEGMENTATION,
85
- file: FileNameEnum::SegmentEvaluator,
86
- user_id: user_id,
87
- campaign_key: campaign_key,
88
- custom_variables: custom_variables
89
- )
90
- )
91
- end
92
71
  result
93
72
  rescue StandardError => e
94
73
  @logger.log(
95
74
  LogLevelEnum::ERROR,
96
75
  format(
97
- LogMessageEnum::ErrorMessages::PRE_SEGMENTATION_ERROR,
76
+ LogMessageEnum::ErrorMessages::SEGMENTATION_ERROR,
98
77
  file: FileNameEnum::SegmentEvaluator,
99
78
  user_id: user_id,
100
79
  campaign_key: campaign_key,
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -25,7 +25,6 @@ class VWO
25
25
 
26
26
  PROTOCOL = 'https'
27
27
  HOSTNAME = ::VWO::CONSTANTS::ENDPOINTS::BASE_URL
28
- PATH = ::VWO::CONSTANTS::ENDPOINTS::ACCOUNT_SETTINGS
29
28
 
30
29
  def initialize(account_id, sdk_key)
31
30
  @account_id = account_id
@@ -40,7 +39,7 @@ class VWO
40
39
  # as received from the server,
41
40
  # nil if no settings_file is found or sdk_key is incorrect
42
41
 
43
- def get_settings_file
42
+ def get_settings_file(is_via_webhook = false)
44
43
  is_valid_key = valid_number?(@account_id) || valid_string?(@account_id)
45
44
 
46
45
  unless is_valid_key && valid_string?(@sdk_key)
@@ -48,7 +47,12 @@ class VWO
48
47
  return '{}'
49
48
  end
50
49
 
51
- vwo_server_url = "#{PROTOCOL}://#{HOSTNAME}#{PATH}"
50
+ if is_via_webhook
51
+ path = ::VWO::CONSTANTS::ENDPOINTS::WEBHOOK_SETTINGS_URL
52
+ else
53
+ path = ::VWO::CONSTANTS::ENDPOINTS::SETTINGS_URL
54
+ end
55
+ vwo_server_url = "#{PROTOCOL}://#{HOSTNAME}#{path}"
52
56
 
53
57
  settings_file_response = ::VWO::Utils::Request.get(vwo_server_url, params)
54
58
 
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -44,6 +44,11 @@ class VWO
44
44
  )
45
45
  end
46
46
 
47
+ def update_settings_file(settings_file)
48
+ @settings_file = settings_file
49
+ process_settings_file
50
+ end
51
+
47
52
  def get_settings_file
48
53
  @settings_file
49
54
  end
@@ -0,0 +1,29 @@
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ class VWO
16
+ module Services
17
+ class UsageStats
18
+ attr_reader :usage_stats
19
+ # Initialize the UsageStats
20
+ def initialize(stats, is_development_mode = false)
21
+ @usage_stats = {}
22
+ unless is_development_mode
23
+ @usage_stats = stats
24
+ @usage_stats[:_l] = 1 if @usage_stats.length > 0
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -142,6 +142,113 @@ class VWO
142
142
  campaign['key'] == campaign_key
143
143
  end
144
144
  end
145
+
146
+ # fetch campaigns from settings
147
+ #
148
+ # [string|array|nil] :campaign_key
149
+ # [Hash] :settings_file
150
+ # [string] :goal_identifier
151
+ # [string] :goal_type_to_track
152
+ # @return[Hash]
153
+ def get_campaigns(settings_file, campaign_key, goal_identifier, goal_type_to_track = 'ALL')
154
+ campaigns = []
155
+ if campaign_key.nil?
156
+ campaigns = get_campaigns_for_goal(settings_file, goal_identifier, goal_type_to_track)
157
+ elsif campaign_key.is_a?(Array)
158
+ campaigns = get_campaigns_from_campaign_keys(campaign_key, settings_file, goal_identifier, goal_type_to_track)
159
+ elsif campaign_key.is_a?(String)
160
+ campaign = get_campaign_for_campaign_key_and_goal(campaign_key, settings_file, goal_identifier, goal_type_to_track)
161
+ if campaign
162
+ campaigns = [campaign]
163
+ end
164
+ end
165
+ if campaigns.length() == 0
166
+ VWO::Logger.get_instance.log(
167
+ LogLevelEnum::ERROR,
168
+ format(
169
+ LogMessageEnum::ErrorMessages::NO_CAMPAIGN_FOUND,
170
+ file: FileNameEnum::CampaignUtil,
171
+ goal_identifier: goal_identifier
172
+ )
173
+ )
174
+ end
175
+ return campaigns
176
+ end
177
+
178
+ # fetch all running campaigns (having goal identifier goal_type_to_track and goal type CUSTOM|REVENUE|ALL) from settings
179
+ #
180
+ # [Hash] :settings_file
181
+ # [string] :goal_identifier
182
+ # [string] :goal_type_to_track
183
+ # @return[Hash]
184
+ def get_campaigns_for_goal(settings_file, goal_identifier, goal_type_to_track = 'ALL')
185
+ campaigns = []
186
+ if settings_file
187
+ settings_file['campaigns'].each do |campaign|
188
+ if campaign.key?(:status) && campaign[:status] != 'RUNNING'
189
+ next
190
+ end
191
+ goal = get_campaign_goal(campaign, goal_identifier)
192
+ if validate_goal(goal, goal_type_to_track)
193
+ campaigns.push(campaign)
194
+ end
195
+ end
196
+ end
197
+ campaigns
198
+ end
199
+
200
+ def validate_goal(goal, goal_type_to_track)
201
+ result = goal && (
202
+ goal_type_to_track == 'ALL' ||
203
+ (
204
+ GOAL_TYPES.has_value?(goal['type']) &&
205
+ (GOAL_TYPES.key? goal_type_to_track) &&
206
+ goal['type'] == GOAL_TYPES[goal_type_to_track]
207
+ )
208
+ )
209
+ return result
210
+ end
211
+
212
+ def get_campaigns_from_campaign_keys(campaign_keys, settings_file, goal_identifier, goal_type_to_track = 'ALL')
213
+ campaigns = []
214
+ campaign_keys.each do |campaign_key|
215
+
216
+ campaign = get_campaign_for_campaign_key_and_goal(campaign_key, settings_file, goal_identifier, goal_type_to_track)
217
+ if campaign
218
+ campaigns.push(campaign)
219
+ end
220
+ end
221
+ campaigns
222
+ end
223
+
224
+ def get_campaign_for_campaign_key_and_goal(campaign_key, settings_file, goal_identifier, goal_type_to_track)
225
+ campaign = get_running_campaign(campaign_key, settings_file)
226
+ if campaign
227
+ goal = get_campaign_goal(campaign, goal_identifier)
228
+ if validate_goal(goal, goal_type_to_track)
229
+ return campaign
230
+ end
231
+ end
232
+ nil
233
+ end
234
+
235
+ def get_running_campaign(campaign_key, settings_file)
236
+ campaign = get_campaign(settings_file, campaign_key)
237
+ if campaign.nil? || (campaign['status'] != 'RUNNING')
238
+ @logger.log(
239
+ LogLevelEnum::ERROR,
240
+ format(
241
+ LogMessageEnum::ErrorMessages::CAMPAIGN_NOT_RUNNING,
242
+ file: FILE,
243
+ campaign_key: campaign_key,
244
+ api_name: ApiMethods::TRACK
245
+ )
246
+ )
247
+ nil
248
+ end
249
+ return campaign
250
+ end
251
+
145
252
  end
146
253
  end
147
254
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -26,13 +26,36 @@ class VWO
26
26
  include VWO::Enums
27
27
  include VWO::Utils::Impression
28
28
 
29
- def get_url_params(settings_file, tag_key, tag_value, user_id)
29
+ def get_url_params(settings_file, tag_key, tag_value, user_id, sdk_key)
30
30
  url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL + ENDPOINTS::PUSH
31
31
  tag = { 'u' => {} }
32
32
  tag['u'][tag_key] = tag_value
33
33
 
34
34
  params = get_common_properties(user_id, settings_file)
35
- params.merge!('url' => url, 'tags' => JSON.generate(tag))
35
+ params.merge!('url' => url, 'tags' => JSON.generate(tag), 'env' => sdk_key)
36
+
37
+ VWO::Logger.get_instance.log(
38
+ LogLevelEnum::DEBUG,
39
+ format(
40
+ LogMessageEnum::DebugMessages::PARAMS_FOR_PUSH_CALL,
41
+ file: FileNameEnum::CustomDimensionsUtil,
42
+ properties: JSON.generate(params)
43
+ )
44
+ )
45
+ params
46
+ end
47
+
48
+ def get_batch_event_url_params(settings_file, tag_key, tag_value, user_id)
49
+ tag = { 'u' => {} }
50
+ tag['u'][tag_key] = tag_value
51
+
52
+ account_id = settings_file['accountId']
53
+ params = {
54
+ 'eT' => 3,
55
+ 't' => JSON.generate(tag),
56
+ 'u' => generator_for(user_id, account_id),
57
+ 'sId' => get_current_unix_timestamp
58
+ }
36
59
 
37
60
  VWO::Logger.get_instance.log(
38
61
  LogLevelEnum::DEBUG,
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -31,16 +31,17 @@ class VWO
31
31
 
32
32
  # Creates the impression from the arguments passed
33
33
  #
34
- # @param[Hash] :settings_file Settings file object
34
+ # @param[Hash] :settings_file Settings file object
35
35
  # @param[String] :campaign_id Campaign identifier
36
36
  # @param[String] :variation_id Variation identifier
37
37
  # @param[String] :user_id User identifier
38
+ # @param[String] :sdk_key SDK Key
38
39
  # @param[String] :goal_id Goal identifier, if building track impression
39
40
  # @param[String|Float|Integer|nil) :revenue Number value, in any representation, if building track impression
40
41
  #
41
42
  # @return[nil|Hash] None if campaign ID or variation ID is invalid,
42
43
  # Else Properties(dict)
43
- def create_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil)
44
+ def create_impression(settings_file, campaign_id, variation_id, user_id, sdk_key, goal_id = nil, revenue = nil, usage_stats = {})
44
45
  return unless valid_number?(campaign_id) && valid_string?(user_id)
45
46
 
46
47
  is_track_user_api = true
@@ -51,17 +52,19 @@ class VWO
51
52
  account_id: account_id,
52
53
  experiment_id: campaign_id,
53
54
  ap: PLATFORM,
54
- uId: CGI.escape(user_id.encode('utf-8')),
55
55
  combination: variation_id,
56
56
  random: get_random_number,
57
57
  sId: get_current_unix_timestamp,
58
- u: generator_for(user_id, account_id)
58
+ u: generator_for(user_id, account_id),
59
+ env: sdk_key
59
60
  }
60
61
  # Version and SDK constants
61
62
  sdk_version = Gem.loaded_specs['vwo_sdk'] ? Gem.loaded_specs['vwo_sdk'].version : VWO::SDK_VERSION
62
63
  impression['sdk'] = 'ruby'
63
64
  impression['sdk-v'] = sdk_version
64
65
 
66
+ impression = usage_stats.merge(impression)
67
+
65
68
  url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL
66
69
  logger = VWO::Logger.get_instance
67
70
 
@@ -107,9 +110,57 @@ class VWO
107
110
  'ap' => PLATFORM,
108
111
  'sId' => get_current_unix_timestamp,
109
112
  'u' => generator_for(user_id, account_id),
110
- 'account_id' => account_id,
111
- 'uId' => CGI.escape(user_id.encode('utf-8'))
113
+ 'account_id' => account_id
114
+ }
115
+ end
116
+
117
+ # Creates properties for the bulk impression event
118
+ #
119
+ # @param[Hash] :settings_file Settings file object
120
+ # @param[String] :campaign_id Campaign identifier
121
+ # @param[String] :variation_id Variation identifier
122
+ # @param[String] :user_id User identifier
123
+ # @param[String] :sdk_key SDK Key
124
+ # @param[String] :goal_id Goal identifier, if building track impression
125
+ # @param[String|Float|Integer|nil) :revenue Number value, in any representation, if building track impression
126
+ #
127
+ # @return[nil|Hash] None if campaign ID or variation ID is invalid,
128
+ # Else Properties(dict)
129
+ def create_bulk_event_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil)
130
+ return unless valid_number?(campaign_id) && valid_string?(user_id)
131
+ is_track_user_api = true
132
+ is_track_user_api = false unless goal_id.nil?
133
+ account_id = settings_file['accountId']
134
+ impression = {
135
+ eT: is_track_user_api ? 1 : 2,
136
+ e: campaign_id,
137
+ c: variation_id,
138
+ u: generator_for(user_id, account_id),
139
+ sId: get_current_unix_timestamp
112
140
  }
141
+ logger = VWO::Logger.get_instance
142
+ if is_track_user_api
143
+ logger.log(
144
+ LogLevelEnum::DEBUG,
145
+ format(
146
+ LogMessageEnum::DebugMessages::IMPRESSION_FOR_TRACK_USER,
147
+ file: FileNameEnum::ImpressionUtil,
148
+ properties: JSON.generate(impression)
149
+ )
150
+ )
151
+ else
152
+ impression['g'] = goal_id
153
+ impression['r'] = revenue if revenue
154
+ logger.log(
155
+ LogLevelEnum::DEBUG,
156
+ format(
157
+ LogMessageEnum::DebugMessages::IMPRESSION_FOR_TRACK_GOAL,
158
+ file: FileNameEnum::ImpressionUtil,
159
+ properties: JSON.generate(impression)
160
+ )
161
+ )
162
+ end
163
+ impression
113
164
  end
114
165
  end
115
166
  end