vwo-sdk 1.30.0 → 1.37.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|