vwo-sdk 1.30.0 → 1.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/vwo/constants.rb +3 -2
- data/lib/vwo/core/bucketer.rb +50 -48
- data/lib/vwo/core/variation_decider.rb +427 -428
- data/lib/vwo/enums.rb +17 -154
- data/lib/vwo/logger.rb +8 -5
- data/lib/vwo/schemas/settings_file.rb +7 -6
- data/lib/vwo/services/batch_events_dispatcher.rb +45 -38
- data/lib/vwo/services/batch_events_queue.rb +52 -68
- data/lib/vwo/services/event_dispatcher.rb +46 -16
- data/lib/vwo/services/hooks_manager.rb +8 -12
- data/lib/vwo/services/segment_evaluator.rb +17 -15
- data/lib/vwo/services/settings_file_manager.rb +5 -5
- data/lib/vwo/services/settings_file_processor.rb +7 -4
- data/lib/vwo/services/usage_stats.rb +5 -4
- data/lib/vwo/utils/campaign.rb +61 -64
- data/lib/vwo/utils/custom_dimensions.rb +14 -14
- data/lib/vwo/utils/data_location_manager.rb +2 -9
- data/lib/vwo/utils/feature.rb +7 -10
- data/lib/vwo/utils/impression.rb +80 -79
- data/lib/vwo/utils/log_message.rb +69 -0
- data/lib/vwo/utils/request.rb +7 -9
- data/lib/vwo/utils/utility.rb +45 -28
- data/lib/vwo/utils/uuid.rb +12 -10
- data/lib/vwo/utils/validations.rb +124 -49
- data/lib/vwo.rb +472 -620
- metadata +11 -10
data/lib/vwo/utils/impression.rb
CHANGED
@@ -14,9 +14,9 @@
|
|
14
14
|
|
15
15
|
require 'json'
|
16
16
|
require 'cgi'
|
17
|
-
require_relative '../logger'
|
18
17
|
require_relative '../enums'
|
19
18
|
require_relative '../constants'
|
19
|
+
require_relative './log_message'
|
20
20
|
require_relative 'function'
|
21
21
|
require_relative 'uuid'
|
22
22
|
require_relative 'utility'
|
@@ -57,7 +57,7 @@ class VWO
|
|
57
57
|
combination: variation_id,
|
58
58
|
random: get_random_number,
|
59
59
|
sId: get_current_unix_timestamp,
|
60
|
-
u: generator_for(user_id, account_id),
|
60
|
+
u: generator_for(user_id, account_id, true),
|
61
61
|
env: sdk_key
|
62
62
|
}
|
63
63
|
# Version and SDK constants
|
@@ -67,30 +67,28 @@ class VWO
|
|
67
67
|
|
68
68
|
impression = usage_stats.merge(impression)
|
69
69
|
|
70
|
-
logger = VWO::Logger.get_instance
|
71
|
-
|
72
70
|
if is_track_user_api
|
73
71
|
impression['ed'] = JSON.generate(p: 'server')
|
74
72
|
impression['url'] = HTTPS_PROTOCOL + get_url(ENDPOINTS::TRACK_USER)
|
75
|
-
|
73
|
+
Logger.log(
|
76
74
|
LogLevelEnum::DEBUG,
|
77
|
-
|
78
|
-
|
79
|
-
file
|
80
|
-
properties
|
81
|
-
|
75
|
+
'IMPRESSION_FOR_TRACK_USER',
|
76
|
+
{
|
77
|
+
'{file}' => FileNameEnum::IMPRESSION_UTIL,
|
78
|
+
'{properties}' => remove_sensitive_properties(impression)
|
79
|
+
}
|
82
80
|
)
|
83
81
|
else
|
84
82
|
impression['url'] = HTTPS_PROTOCOL + get_url(ENDPOINTS::TRACK_GOAL)
|
85
83
|
impression['goal_id'] = goal_id
|
86
84
|
impression['r'] = revenue if revenue
|
87
|
-
|
85
|
+
Logger.log(
|
88
86
|
LogLevelEnum::DEBUG,
|
89
|
-
|
90
|
-
|
91
|
-
file
|
92
|
-
properties
|
93
|
-
|
87
|
+
'IMPRESSION_FOR_TRACK_GOAL',
|
88
|
+
{
|
89
|
+
'{file}' => FileNameEnum::IMPRESSION_UTIL,
|
90
|
+
'{properties}' => JSON.generate(impression)
|
91
|
+
}
|
94
92
|
)
|
95
93
|
end
|
96
94
|
impression
|
@@ -110,7 +108,7 @@ class VWO
|
|
110
108
|
'sdk-v' => SDK_VERSION,
|
111
109
|
'ap' => PLATFORM,
|
112
110
|
'sId' => get_current_unix_timestamp,
|
113
|
-
'u' => generator_for(user_id, account_id),
|
111
|
+
'u' => generator_for(user_id, account_id, true),
|
114
112
|
'account_id' => account_id
|
115
113
|
}
|
116
114
|
end
|
@@ -129,6 +127,7 @@ class VWO
|
|
129
127
|
# Else Properties(dict)
|
130
128
|
def create_bulk_event_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil)
|
131
129
|
return unless valid_number?(campaign_id) && valid_string?(user_id)
|
130
|
+
|
132
131
|
is_track_user_api = true
|
133
132
|
is_track_user_api = false unless goal_id.nil?
|
134
133
|
account_id = settings_file['accountId']
|
@@ -136,29 +135,29 @@ class VWO
|
|
136
135
|
eT: is_track_user_api ? 1 : 2,
|
137
136
|
e: campaign_id,
|
138
137
|
c: variation_id,
|
139
|
-
u: generator_for(user_id, account_id),
|
138
|
+
u: generator_for(user_id, account_id, true),
|
140
139
|
sId: get_current_unix_timestamp
|
141
140
|
}
|
142
|
-
|
141
|
+
|
143
142
|
if is_track_user_api
|
144
|
-
|
143
|
+
Logger.log(
|
145
144
|
LogLevelEnum::DEBUG,
|
146
|
-
|
147
|
-
|
148
|
-
file
|
149
|
-
properties
|
150
|
-
|
145
|
+
'IMPRESSION_FOR_TRACK_USER',
|
146
|
+
{
|
147
|
+
'{file}' => FileNameEnum::IMPRESSION_UTIL,
|
148
|
+
'{properties}' => remove_sensitive_properties(impression)
|
149
|
+
}
|
151
150
|
)
|
152
151
|
else
|
153
152
|
impression['g'] = goal_id
|
154
153
|
impression['r'] = revenue if revenue
|
155
|
-
|
154
|
+
Logger.log(
|
156
155
|
LogLevelEnum::DEBUG,
|
157
|
-
|
158
|
-
|
159
|
-
file
|
160
|
-
properties
|
161
|
-
|
156
|
+
'IMPRESSION_FOR_TRACK_GOAL',
|
157
|
+
{
|
158
|
+
'{file}' => FileNameEnum::IMPRESSION_UTIL,
|
159
|
+
'{properties}' => JSON.generate(impression)
|
160
|
+
}
|
162
161
|
)
|
163
162
|
end
|
164
163
|
impression
|
@@ -171,7 +170,7 @@ class VWO
|
|
171
170
|
# @param[String] :event_name
|
172
171
|
# @param[Hash] :usage_stats
|
173
172
|
# @return[Hash] :properties
|
174
|
-
#
|
173
|
+
#
|
175
174
|
def get_events_base_properties(settings_file, event_name, usage_stats = {})
|
176
175
|
properties = {
|
177
176
|
en: event_name,
|
@@ -179,12 +178,10 @@ class VWO
|
|
179
178
|
env: settings_file['sdkKey'],
|
180
179
|
eTime: get_current_unix_timestamp_in_millis,
|
181
180
|
random: get_random_number,
|
182
|
-
p:
|
181
|
+
p: 'FS'
|
183
182
|
}
|
184
183
|
|
185
|
-
if event_name == EventEnum::VWO_VARIATION_SHOWN
|
186
|
-
properties = properties.merge(usage_stats)
|
187
|
-
end
|
184
|
+
properties = properties.merge(usage_stats) if event_name == EventEnum::VWO_VARIATION_SHOWN
|
188
185
|
properties
|
189
186
|
end
|
190
187
|
|
@@ -193,11 +190,11 @@ class VWO
|
|
193
190
|
# @param[Hash] :settings_file
|
194
191
|
# @param[String] :user_id
|
195
192
|
# @param[String] :event_name
|
196
|
-
# @param[Hash] :
|
193
|
+
# @param[Hash] :_usage_stats
|
197
194
|
# @return[Hash] :properties
|
198
|
-
#
|
199
|
-
def get_event_base_payload(settings_file, user_id, event_name,
|
200
|
-
uuid = generator_for(user_id, (settings_file['accountId']))
|
195
|
+
#
|
196
|
+
def get_event_base_payload(settings_file, user_id, event_name, _usage_stats = {})
|
197
|
+
uuid = generator_for(user_id, (settings_file['accountId']), true)
|
201
198
|
sdk_key = settings_file['sdkKey']
|
202
199
|
|
203
200
|
props = {
|
@@ -211,12 +208,12 @@ class VWO
|
|
211
208
|
}
|
212
209
|
|
213
210
|
# if usage_stats
|
214
|
-
# props = props.merge(
|
211
|
+
# props = props.merge(_usage_stats)
|
215
212
|
# end
|
216
213
|
|
217
|
-
|
214
|
+
{
|
218
215
|
d: {
|
219
|
-
msgId: uuid + '_' + Time.now.to_i
|
216
|
+
msgId: "#{uuid} + '_' + #{Time.now.to_i}",
|
220
217
|
visId: uuid,
|
221
218
|
sessionId: Time.now.to_i,
|
222
219
|
event: {
|
@@ -231,8 +228,6 @@ class VWO
|
|
231
228
|
}
|
232
229
|
}
|
233
230
|
}
|
234
|
-
|
235
|
-
properties
|
236
231
|
end
|
237
232
|
|
238
233
|
# Builds payload to track the visitor.
|
@@ -242,27 +237,26 @@ class VWO
|
|
242
237
|
# @param[String] :event_name
|
243
238
|
# @param[Integer] :campaign_id
|
244
239
|
# @param[Integer] :variation_id
|
245
|
-
# @param[Hash] :
|
240
|
+
# @param[Hash] :_usage_stats
|
246
241
|
# @return[Hash] :properties
|
247
242
|
#
|
248
|
-
def get_track_user_payload_data(settings_file, user_id, event_name, campaign_id, variation_id,
|
243
|
+
def get_track_user_payload_data(settings_file, user_id, event_name, campaign_id, variation_id, _usage_stats = {})
|
249
244
|
properties = get_event_base_payload(settings_file, user_id, event_name)
|
250
245
|
properties[:d][:event][:props][:id] = campaign_id
|
251
246
|
properties[:d][:event][:props][:variation] = variation_id
|
252
247
|
|
253
|
-
#this is currently required by data-layer team, we can make changes on DACDN and remove it from here
|
248
|
+
# this is currently required by data-layer team, we can make changes on DACDN and remove it from here
|
254
249
|
properties[:d][:event][:props][:isFirst] = 1
|
255
250
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
)
|
251
|
+
Logger.log(
|
252
|
+
LogLevelEnum::DEBUG,
|
253
|
+
'IMPRESSION_FOR_EVENT_ARCH_TRACK_USER',
|
254
|
+
{
|
255
|
+
'{file}' => FileNameEnum::IMPRESSION_UTIL,
|
256
|
+
'{accountId}' => settings_file['accountId'],
|
257
|
+
'{userId}' => user_id,
|
258
|
+
'{campaignId}' => campaign_id.to_s
|
259
|
+
}
|
266
260
|
)
|
267
261
|
properties
|
268
262
|
end
|
@@ -281,20 +275,19 @@ class VWO
|
|
281
275
|
def get_track_goal_payload_data(settings_file, user_id, event_name, revenue_value, metric_map, revenue_props = [])
|
282
276
|
properties = get_event_base_payload(settings_file, user_id, event_name)
|
283
277
|
|
284
|
-
logger = VWO::Logger.get_instance
|
285
278
|
metric = {}
|
286
279
|
metric_map.each do |campaign_id, goal_id|
|
287
|
-
metric[
|
288
|
-
|
280
|
+
metric["id_#{campaign_id}".to_sym] = ["g_#{goal_id}"]
|
281
|
+
Logger.log(
|
289
282
|
LogLevelEnum::DEBUG,
|
290
|
-
|
291
|
-
|
292
|
-
file
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
283
|
+
'IMPRESSION_FOR_EVENT_ARCH_TRACK_GOAL',
|
284
|
+
{
|
285
|
+
'{file}' => FileNameEnum::IMPRESSION_UTIL,
|
286
|
+
'{accountId}' => settings_file['accountId'],
|
287
|
+
'{goalName}' => event_name,
|
288
|
+
'{userId}' => user_id,
|
289
|
+
'{campaignId}' => campaign_id.to_s
|
290
|
+
}
|
298
291
|
)
|
299
292
|
end
|
300
293
|
|
@@ -302,7 +295,7 @@ class VWO
|
|
302
295
|
metric: metric
|
303
296
|
}
|
304
297
|
|
305
|
-
if revenue_props.length
|
298
|
+
if revenue_props.length != 0 && revenue_value
|
306
299
|
revenue_props.each do |revenue_prop|
|
307
300
|
properties[:d][:event][:props][:vwoMeta][revenue_prop.to_sym] = revenue_value
|
308
301
|
end
|
@@ -330,19 +323,27 @@ class VWO
|
|
330
323
|
properties[:d][:visitor][:props][tag_key] = tag_value
|
331
324
|
end
|
332
325
|
|
333
|
-
|
334
|
-
logger.log(
|
326
|
+
Logger.log(
|
335
327
|
LogLevelEnum::DEBUG,
|
336
|
-
|
337
|
-
|
338
|
-
file
|
339
|
-
|
340
|
-
|
341
|
-
property
|
342
|
-
|
328
|
+
'IMPRESSION_FOR_EVENT_ARCH_PUSH',
|
329
|
+
{
|
330
|
+
'{file}' => FileNameEnum::IMPRESSION_UTIL,
|
331
|
+
'{accountId}' => settings_file['accountId'],
|
332
|
+
'{userId}' => user_id,
|
333
|
+
'{property}' => JSON.generate(custom_dimension_map)
|
334
|
+
}
|
343
335
|
)
|
344
336
|
properties
|
345
337
|
end
|
338
|
+
|
339
|
+
def get_batch_event_query_params(account_id, sdk_key, usage_stats = {})
|
340
|
+
{
|
341
|
+
a: account_id,
|
342
|
+
sd: SDK_NAME,
|
343
|
+
sv: SDK_VERSION,
|
344
|
+
env: sdk_key
|
345
|
+
}.merge(usage_stats)
|
346
|
+
end
|
346
347
|
end
|
347
348
|
end
|
348
349
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# Copyright 2019-2022 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
|
+
require 'vwo_log_messages'
|
16
|
+
|
17
|
+
require_relative '../logger'
|
18
|
+
|
19
|
+
class VWO
|
20
|
+
module Utils
|
21
|
+
class Logger
|
22
|
+
DEBUG = ::Logger::DEBUG
|
23
|
+
INFO = ::Logger::INFO
|
24
|
+
ERROR = ::Logger::ERROR
|
25
|
+
WARN = ::Logger::WARN
|
26
|
+
|
27
|
+
@@logs = nil
|
28
|
+
@@api_name = 'api_name'
|
29
|
+
|
30
|
+
def self.set_api_name(api_name)
|
31
|
+
@@api_name = api_name
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.get_log_message(logs_type, message_type)
|
35
|
+
@@logs = VwoLogMessages.getMessage if @@logs.nil?
|
36
|
+
|
37
|
+
return message_type unless @@logs[logs_type].key?(message_type)
|
38
|
+
|
39
|
+
@@logs[logs_type][message_type]
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.log(level, message_type, params, disable_logs = false)
|
43
|
+
return if disable_logs
|
44
|
+
|
45
|
+
message = case level
|
46
|
+
when DEBUG
|
47
|
+
get_log_message('debug_logs', message_type)
|
48
|
+
when INFO
|
49
|
+
get_log_message('info_logs', message_type)
|
50
|
+
when ERROR
|
51
|
+
get_log_message('error_logs', message_type)
|
52
|
+
when WARN
|
53
|
+
get_log_message('warning_logs', message_type)
|
54
|
+
else
|
55
|
+
''
|
56
|
+
end
|
57
|
+
message = message.dup
|
58
|
+
|
59
|
+
if message && !message.empty?
|
60
|
+
params.each do |key, value|
|
61
|
+
message[key.to_s] = value.to_s if message.include? key
|
62
|
+
end
|
63
|
+
end
|
64
|
+
message = "[#{@@api_name}] #{message}"
|
65
|
+
VWO::Logger.get_instance.log(level, message)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/vwo/utils/request.rb
CHANGED
@@ -31,12 +31,11 @@ class VWO
|
|
31
31
|
http.use_ssl = true
|
32
32
|
uri.query = URI.encode_www_form(params)
|
33
33
|
headers = {
|
34
|
-
'Authorization'=>params[:env],
|
35
|
-
'Content-Type' =>'application/json',
|
36
|
-
'Accept'=>'application/json'
|
34
|
+
'Authorization' => params[:env],
|
35
|
+
'Content-Type' => 'application/json',
|
36
|
+
'Accept' => 'application/json'
|
37
37
|
}
|
38
|
-
|
39
|
-
response
|
38
|
+
http.post(uri, post_data.to_json, headers)
|
40
39
|
end
|
41
40
|
|
42
41
|
def self.event_post(url, params, post_data, user_agent_value)
|
@@ -46,11 +45,10 @@ class VWO
|
|
46
45
|
uri.query = URI.encode_www_form(params)
|
47
46
|
headers = {
|
48
47
|
'User-Agent' => user_agent_value,
|
49
|
-
'Content-Type' =>'application/json',
|
50
|
-
'Accept'=>'application/json'
|
48
|
+
'Content-Type' => 'application/json',
|
49
|
+
'Accept' => 'application/json'
|
51
50
|
}
|
52
|
-
|
53
|
-
response
|
51
|
+
http.post(uri, post_data.to_json, headers)
|
54
52
|
end
|
55
53
|
end
|
56
54
|
end
|
data/lib/vwo/utils/utility.rb
CHANGED
@@ -19,37 +19,54 @@ require_relative '../constants'
|
|
19
19
|
|
20
20
|
# Generic utility module
|
21
21
|
class VWO
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
module Utils
|
23
|
+
module Utility
|
24
|
+
include Validations
|
25
|
+
include VWO::Utils
|
26
|
+
include VWO::CONSTANTS
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
28
|
+
# converting hash with keys as strings into hash with keys as strings
|
29
|
+
# @param[Hash]
|
30
|
+
# @return[Hash]
|
31
|
+
def convert_to_symbol_hash(hash_object)
|
32
|
+
hash_object ||= {}
|
33
|
+
converted_hash = {}
|
34
|
+
hash_object.each do |key, value|
|
35
|
+
converted_hash[key.to_sym] = if valid_hash?(value)
|
36
|
+
convert_to_symbol_hash(value)
|
37
|
+
else
|
38
|
+
value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
converted_hash
|
42
|
+
end
|
43
|
+
|
44
|
+
def remove_sensitive_properties(properties)
|
45
|
+
properties.delete('env')
|
46
|
+
properties.delete('env'.to_sym)
|
47
|
+
JSON.generate(properties)
|
48
|
+
end
|
43
49
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
50
|
+
def get_url(endpoint)
|
51
|
+
DataLocationManager.get_instance.get_data_location + endpoint
|
52
|
+
end
|
53
|
+
|
54
|
+
def prepare_push_response(custom_dimension_map, resp, result)
|
55
|
+
custom_dimension_map.each do |tag_key, _tag_value|
|
56
|
+
result[tag_key] = resp
|
57
|
+
end
|
58
|
+
result
|
59
|
+
end
|
49
60
|
|
50
|
-
|
51
|
-
|
52
|
-
|
61
|
+
def get_variation_identifiers(variation)
|
62
|
+
if variation['goal_identifier']
|
63
|
+
identifiers = variation['goal_identifier'].split(VWO_DELIMITER)
|
64
|
+
else
|
65
|
+
variation['goal_identifier'] = ''
|
66
|
+
identifiers = []
|
53
67
|
end
|
68
|
+
identifiers
|
69
|
+
end
|
54
70
|
end
|
71
|
+
end
|
55
72
|
end
|
data/lib/vwo/utils/uuid.rb
CHANGED
@@ -13,9 +13,9 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
require 'digest'
|
16
|
-
require_relative '../logger'
|
17
16
|
require_relative '../enums'
|
18
17
|
require_relative '../constants'
|
18
|
+
require_relative './log_message'
|
19
19
|
|
20
20
|
# Utility module for generating uuid
|
21
21
|
class VWO
|
@@ -53,10 +53,11 @@ class VWO
|
|
53
53
|
#
|
54
54
|
# @param[Integer|String] :user_id User identifier
|
55
55
|
# @param[Integer|String] :account_id Account identifier
|
56
|
+
# @param[Boolean] :disable_logs if true, do not log log-message
|
56
57
|
#
|
57
58
|
# @return[Integer] Desired UUID
|
58
59
|
#
|
59
|
-
def generator_for(user_id, account_id)
|
60
|
+
def generator_for(user_id, account_id, disable_logs = false)
|
60
61
|
user_id = user_id.to_s
|
61
62
|
account_id = account_id.to_s
|
62
63
|
user_id_namespace = generate(VWO_NAMESPACE, account_id)
|
@@ -64,15 +65,16 @@ class VWO
|
|
64
65
|
|
65
66
|
desired_uuid = uuid_for_account_user_id.delete('-').upcase
|
66
67
|
|
67
|
-
|
68
|
+
Logger.log(
|
68
69
|
LogLevelEnum::DEBUG,
|
69
|
-
|
70
|
-
|
71
|
-
file
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
70
|
+
'USER_UUID',
|
71
|
+
{
|
72
|
+
'{file}' => FILE,
|
73
|
+
'{userId}' => user_id,
|
74
|
+
'{accountId}' => account_id,
|
75
|
+
'{uuid}' => desired_uuid
|
76
|
+
},
|
77
|
+
disable_logs
|
76
78
|
)
|
77
79
|
desired_uuid
|
78
80
|
end
|