vwo-fme-ruby-sdk 1.8.0 → 1.9.0
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/resources/debug_messages.json +2 -1
- data/lib/vwo/api/get_flag.rb +3 -3
- data/lib/vwo/api/set_attribute.rb +1 -3
- data/lib/vwo/api/track_event.rb +1 -3
- data/lib/vwo/constants/constants.rb +2 -1
- data/lib/vwo/models/settings/settings_model.rb +6 -1
- data/lib/vwo/models/user/context_model.rb +3 -3
- data/lib/vwo/models/user/get_flag_response.rb +33 -21
- data/lib/vwo/utils/network_util.rb +39 -6
- data/lib/vwo/utils/uuid_util.rb +44 -3
- data/lib/vwo/vwo_client.rb +40 -19
- data/lib/vwo.rb +16 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f6cd54e4729aaae54bea625e05ebba1990f2a4295b3b04352cda862d06b92603
|
|
4
|
+
data.tar.gz: c1664141b090c9f2fea0c456a562daadc13ca66ab971fd2cb86c3af0e1c08574
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 196e6e75933ee4670db874874a43428eb7b0abddeb5b8b013c513b410d1e539dc395a884a84ffcfe2d018127acb28933d26edf1305df9f8462991b7a52935853
|
|
7
|
+
data.tar.gz: 47bb55030326b0eac4694f2cffa50ab85063e08c88f27462b027e0d4327221b3dfb0b6f30f15d283484a1b11a4d0a2924e24a6ddde8b11b73b7fbb0b9390ef21
|
|
@@ -16,5 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
"EVENT_BATCH_BEFORE_FLUSHING": "Flushing event queue {manually} having {length} events for Account ID:{accountId}. {timer}",
|
|
18
18
|
"EVENT_BATCH_FLUSH": "Manually flushing batch events for Account ID:{accountId} having {queueLength} events",
|
|
19
|
-
"BATCH_QUEUE_EMPTY": "Batch queue is empty. Nothing to flush."
|
|
19
|
+
"BATCH_QUEUE_EMPTY": "Batch queue is empty. Nothing to flush.",
|
|
20
|
+
"WEB_UUID_FOUND": "VWO Web Testing identified UUID {uuid} as the Context ID for API {apiName}"
|
|
20
21
|
}
|
data/lib/vwo/api/get_flag.rb
CHANGED
|
@@ -65,7 +65,7 @@ class FlagApi
|
|
|
65
65
|
|
|
66
66
|
if variation
|
|
67
67
|
LoggerService.log(LogLevelEnum::INFO, "STORED_VARIATION_FOUND", {variationKey: variation.get_key, userId: context.get_id, experimentKey: stored_data[:experiment_key], experimentType: "experiment"})
|
|
68
|
-
return GetFlagResponse.new(true, variation.get_variables)
|
|
68
|
+
return GetFlagResponse.new(true, variation.get_variables, context.get_uuid, context.get_session_id)
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
elsif stored_data && stored_data[:rollout_key] && stored_data[:rollout_id]
|
|
@@ -91,7 +91,7 @@ class FlagApi
|
|
|
91
91
|
|
|
92
92
|
if feature.nil?
|
|
93
93
|
LoggerService.log(LogLevelEnum::ERROR, "FEATURE_NOT_FOUND", {featureKey: feature_key, an: ApiEnum::GET_FLAG, sId: context.get_session_id, uuid: context.get_uuid})
|
|
94
|
-
return GetFlagResponse.new(false, [])
|
|
94
|
+
return GetFlagResponse.new(false, [], context.get_uuid, context.get_session_id)
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
# Segmentation evaluation
|
|
@@ -219,7 +219,7 @@ class FlagApi
|
|
|
219
219
|
end
|
|
220
220
|
|
|
221
221
|
# Return final evaluated feature flag
|
|
222
|
-
return GetFlagResponse.new(is_enabled, experiment_variation_to_return&.get_variables || rollout_variation_to_return&.get_variables || [])
|
|
222
|
+
return GetFlagResponse.new(is_enabled, experiment_variation_to_return&.get_variables || rollout_variation_to_return&.get_variables || [], context.get_uuid, context.get_session_id)
|
|
223
223
|
end
|
|
224
224
|
|
|
225
225
|
private
|
|
@@ -40,11 +40,9 @@ class SetAttributeApi
|
|
|
40
40
|
|
|
41
41
|
# Construct payload data for multiple attributes
|
|
42
42
|
payload = NetworkUtil.get_attribute_payload_data(
|
|
43
|
-
context.id,
|
|
44
43
|
EventEnum::VWO_SYNC_VISITOR_PROP,
|
|
45
44
|
attributes,
|
|
46
|
-
context
|
|
47
|
-
context.ip_address
|
|
45
|
+
context
|
|
48
46
|
)
|
|
49
47
|
|
|
50
48
|
# check if batching is enabled
|
data/lib/vwo/api/track_event.rb
CHANGED
|
@@ -63,11 +63,9 @@ class TrackApi
|
|
|
63
63
|
|
|
64
64
|
# Prepare the payload for the track goal
|
|
65
65
|
payload = NetworkUtil.get_track_goal_payload_data(
|
|
66
|
-
context.id,
|
|
67
66
|
event_name,
|
|
68
67
|
event_properties,
|
|
69
|
-
context
|
|
70
|
-
context.ip_address
|
|
68
|
+
context
|
|
71
69
|
)
|
|
72
70
|
|
|
73
71
|
# check if batching is enabled
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
# Define the Constants module
|
|
18
18
|
module Constants
|
|
19
19
|
SDK_NAME = 'vwo-fme-ruby-sdk'.freeze
|
|
20
|
-
SDK_VERSION = '1.
|
|
20
|
+
SDK_VERSION = '1.9.0'.freeze
|
|
21
21
|
|
|
22
22
|
MAX_TRAFFIC_PERCENT = 100
|
|
23
23
|
MAX_TRAFFIC_VALUE = 10_000
|
|
@@ -31,6 +31,7 @@ module Constants
|
|
|
31
31
|
MIN_EVENTS_PER_REQUEST = 1
|
|
32
32
|
|
|
33
33
|
SEED_URL = 'https://vwo.com'.freeze # Define SEED_URL
|
|
34
|
+
WEB_UUID_REGEX = /\A[DJ][0-9A-Fa-f]{32}\z/.freeze
|
|
34
35
|
HTTP_PROTOCOL = 'http'.freeze
|
|
35
36
|
HTTPS_PROTOCOL = 'https'.freeze
|
|
36
37
|
|
|
@@ -18,7 +18,7 @@ require_relative '../../constants/constants'
|
|
|
18
18
|
|
|
19
19
|
class SettingsModel
|
|
20
20
|
attr_reader :sdk_key, :account_id, :usage_stats_account_id, :version, :collection_prefix,
|
|
21
|
-
:features, :campaigns, :campaign_groups, :groups, :poll_interval
|
|
21
|
+
:features, :campaigns, :campaign_groups, :groups, :poll_interval, :is_web_connectivity_enabled
|
|
22
22
|
|
|
23
23
|
def initialize(settings)
|
|
24
24
|
@sdk_key = settings["sdkKey"]
|
|
@@ -31,6 +31,7 @@ class SettingsModel
|
|
|
31
31
|
@campaigns = []
|
|
32
32
|
@campaign_groups = settings["campaignGroups"] || {}
|
|
33
33
|
@groups = settings["groups"] || {}
|
|
34
|
+
@is_web_connectivity_enabled = settings.fetch("isWebConnectivityEnabled", true)
|
|
34
35
|
|
|
35
36
|
process_features(settings)
|
|
36
37
|
process_campaigns(settings)
|
|
@@ -93,4 +94,8 @@ class SettingsModel
|
|
|
93
94
|
@campaigns << CampaignModel.new.model_from_dictionary(campaign)
|
|
94
95
|
end
|
|
95
96
|
end
|
|
97
|
+
|
|
98
|
+
def get_is_web_connectivity_enabled
|
|
99
|
+
@is_web_connectivity_enabled
|
|
100
|
+
end
|
|
96
101
|
end
|
|
@@ -53,9 +53,9 @@ class ContextModel
|
|
|
53
53
|
@post_segmentation_variables = context[:postSegmentationVariables] if context.key?(:postSegmentationVariables)
|
|
54
54
|
@vwo = ContextVWOModel.new.model_from_dictionary(context[:_vwo]) if context.key?(:_vwo)
|
|
55
55
|
|
|
56
|
-
# check if sessionId is present in context and should be non null and non empty
|
|
57
|
-
if context.key?(:sessionId) && context[:sessionId].
|
|
58
|
-
@session_id = context[:sessionId]
|
|
56
|
+
# check if sessionId is present in context and should be non null and non empty
|
|
57
|
+
if context.key?(:sessionId) && !context[:sessionId].nil? && !context[:sessionId].to_s.empty?
|
|
58
|
+
@session_id = context[:sessionId].to_i
|
|
59
59
|
else
|
|
60
60
|
@session_id = Time.now.to_i
|
|
61
61
|
end
|
|
@@ -13,26 +13,38 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
class GetFlagResponse
|
|
16
|
-
|
|
16
|
+
attr_reader :is_enabled, :get_variables, :get_variable, :get_uuid, :get_session_id
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
def initialize(is_enabled, variables = [], uuid = nil, session_id = nil)
|
|
19
|
+
@is_enabled = is_enabled
|
|
20
|
+
@variables = variables
|
|
21
|
+
@uuid = uuid
|
|
22
|
+
@session_id = session_id
|
|
23
|
+
end
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
# Define method for is_enabled
|
|
26
|
+
def is_enabled
|
|
27
|
+
@is_enabled
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Define method for get_variables
|
|
31
|
+
def get_variables
|
|
32
|
+
@variables
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Define method for get_variable
|
|
36
|
+
def get_variable(key, default_value = nil)
|
|
37
|
+
variable = @variables.find { |var| var.key == key }
|
|
38
|
+
variable ? variable.value : default_value
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Define method for get_uuid
|
|
42
|
+
def get_uuid
|
|
43
|
+
@uuid
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Define method for get_session_id
|
|
47
|
+
def get_session_id
|
|
48
|
+
@session_id
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -157,6 +157,17 @@ class NetworkUtil
|
|
|
157
157
|
|
|
158
158
|
properties = _get_event_base_payload(user_id, event_name, visitor_user_agent, ip_address)
|
|
159
159
|
|
|
160
|
+
# use sessionId from context if present
|
|
161
|
+
if context.get_session_id
|
|
162
|
+
properties[:d][:sessionId] = context.get_session_id
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# use uuid from context if present
|
|
166
|
+
if context.get_uuid && !context.get_uuid.empty?
|
|
167
|
+
properties[:d][:visId] = context.get_uuid
|
|
168
|
+
properties[:d][:msgId] = "#{context.get_uuid}-#{get_current_unix_timestamp_in_millis}"
|
|
169
|
+
end
|
|
170
|
+
|
|
160
171
|
properties[:d][:event][:props][:id] = campaign_id
|
|
161
172
|
properties[:d][:event][:props][:variation] = variation_id
|
|
162
173
|
properties[:d][:event][:props][:isFirst] = 1
|
|
@@ -191,10 +202,21 @@ class NetworkUtil
|
|
|
191
202
|
end
|
|
192
203
|
|
|
193
204
|
# Constructs payload for tracking goals with custom event properties
|
|
194
|
-
def get_track_goal_payload_data(
|
|
195
|
-
properties = _get_event_base_payload(
|
|
205
|
+
def get_track_goal_payload_data(event_name, event_properties, context)
|
|
206
|
+
properties = _get_event_base_payload(context.id, event_name, context.user_agent, context.ip_address)
|
|
196
207
|
properties[:d][:event][:props][:isCustomEvent] = true
|
|
197
208
|
|
|
209
|
+
# use sessionId from context if present
|
|
210
|
+
if context.get_session_id
|
|
211
|
+
properties[:d][:sessionId] = context.get_session_id
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# use uuid from context if present
|
|
215
|
+
if context.get_uuid && !context.get_uuid.empty?
|
|
216
|
+
properties[:d][:visId] = context.get_uuid
|
|
217
|
+
properties[:d][:msgId] = "#{context.get_uuid}-#{get_current_unix_timestamp_in_millis}"
|
|
218
|
+
end
|
|
219
|
+
|
|
198
220
|
if SettingsService.instance.is_gateway_service_provided
|
|
199
221
|
properties[:d][:event][:props][:variation] = 1
|
|
200
222
|
properties[:d][:event][:props][:id] = 1 # Temporary value for ID
|
|
@@ -207,16 +229,27 @@ class NetworkUtil
|
|
|
207
229
|
LoggerService.log(LogLevelEnum::DEBUG, "IMPRESSION_FOR_TRACK_GOAL", {
|
|
208
230
|
eventName: event_name,
|
|
209
231
|
accountId: SettingsService.instance.account_id,
|
|
210
|
-
userId:
|
|
232
|
+
userId: context.id
|
|
211
233
|
})
|
|
212
234
|
|
|
213
235
|
properties
|
|
214
236
|
end
|
|
215
237
|
|
|
216
|
-
def get_attribute_payload_data(
|
|
217
|
-
properties = _get_event_base_payload(
|
|
238
|
+
def get_attribute_payload_data(event_name, event_properties, context)
|
|
239
|
+
properties = _get_event_base_payload(context.id, event_name, context.user_agent, context.ip_address)
|
|
218
240
|
properties[:d][:event][:props][:isCustomEvent] = true
|
|
219
241
|
|
|
242
|
+
# use sessionId from context if present
|
|
243
|
+
if context.get_session_id
|
|
244
|
+
properties[:d][:sessionId] = context.get_session_id
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# use uuid from context if present
|
|
248
|
+
if context.get_uuid && !context.get_uuid.empty?
|
|
249
|
+
properties[:d][:visId] = context.get_uuid
|
|
250
|
+
properties[:d][:msgId] = "#{context.get_uuid}-#{get_current_unix_timestamp_in_millis}"
|
|
251
|
+
end
|
|
252
|
+
|
|
220
253
|
if event_properties.is_a?(Hash) && !event_properties.empty?
|
|
221
254
|
event_properties.each { |key, value| properties[:d][:visitor][:props][key] = value }
|
|
222
255
|
end
|
|
@@ -224,7 +257,7 @@ class NetworkUtil
|
|
|
224
257
|
LoggerService.log(LogLevelEnum::DEBUG, "IMPRESSION_FOR_SYNC_VISITOR_PROP", {
|
|
225
258
|
eventName: event_name,
|
|
226
259
|
accountId: SettingsService.instance.account_id,
|
|
227
|
-
userId:
|
|
260
|
+
userId: context.id
|
|
228
261
|
})
|
|
229
262
|
properties
|
|
230
263
|
end
|
data/lib/vwo/utils/uuid_util.rb
CHANGED
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
require 'uuidtools'
|
|
16
16
|
require 'securerandom'
|
|
17
|
-
|
|
18
|
-
SEED_URL = 'https://vwo.com' # Replace with actual SEED_URL
|
|
17
|
+
require_relative '../constants/constants'
|
|
19
18
|
|
|
20
19
|
class UUIDUtil
|
|
21
20
|
# Generates a random UUID based on an API key.
|
|
@@ -34,7 +33,7 @@ class UUIDUtil
|
|
|
34
33
|
# @param account_id [String] The account ID associated with the user.
|
|
35
34
|
# @return [String] A UUID string formatted without dashes and in uppercase.
|
|
36
35
|
def self.get_uuid(user_id, account_id)
|
|
37
|
-
vwo_namespace = UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, SEED_URL)
|
|
36
|
+
vwo_namespace = UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, Constants::SEED_URL)
|
|
38
37
|
user_id_namespace = generate_uuid(account_id, vwo_namespace)
|
|
39
38
|
uuid_for_user_id_account_id = generate_uuid(user_id, user_id_namespace)
|
|
40
39
|
|
|
@@ -52,4 +51,46 @@ class UUIDUtil
|
|
|
52
51
|
name_str = name.to_s
|
|
53
52
|
UUIDTools::UUID.sha1_create(namespace, name_str)
|
|
54
53
|
end
|
|
54
|
+
|
|
55
|
+
# Checks if the given ID is a valid Web UUID.
|
|
56
|
+
#
|
|
57
|
+
# @param id [String] The ID to check.
|
|
58
|
+
# @return [Boolean] True if the ID is a valid Web UUID, false otherwise.
|
|
59
|
+
def self.web_uuid?(id)
|
|
60
|
+
return false unless id.is_a?(String)
|
|
61
|
+
|
|
62
|
+
!!(id =~ Constants::WEB_UUID_REGEX)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Generates a UUID for a user based on their user_id and account_id.
|
|
66
|
+
#
|
|
67
|
+
# @param settings [SettingsModel] The settings of the VWO client.
|
|
68
|
+
# @param context [Hash] The context of the user.
|
|
69
|
+
# @param api_name [String] The name of the API called.
|
|
70
|
+
# @return [String] A UUID string formatted without dashes and in uppercase.
|
|
71
|
+
def self.get_uuid_from_context(settings, context, api_name)
|
|
72
|
+
if settings.get_is_web_connectivity_enabled != false
|
|
73
|
+
# if web connectivity is enabled, check if context[:id] is a valid web UUID
|
|
74
|
+
if context && web_uuid?(context[:id])
|
|
75
|
+
# if context[:id] is a valid web UUID, set it as uuid
|
|
76
|
+
LoggerService.log(LogLevelEnum::DEBUG, "WEB_UUID_FOUND", {apiName: api_name, uuid: context[:id]})
|
|
77
|
+
return context[:id]
|
|
78
|
+
else
|
|
79
|
+
# if context[:useIdForWeb] is true and context[:id] is not a valid web UUID, throw error
|
|
80
|
+
if context && context[:useIdForWeb] == true
|
|
81
|
+
raise StandardError, 'UUID passed in context.id is not a valid UUID'
|
|
82
|
+
end
|
|
83
|
+
return get_uuid(
|
|
84
|
+
context[:id].to_s,
|
|
85
|
+
SettingsService.instance.account_id.to_s
|
|
86
|
+
)
|
|
87
|
+
end
|
|
88
|
+
else
|
|
89
|
+
# if web connectivity is disabled, fallback to server-side UUID derivation
|
|
90
|
+
return get_uuid(
|
|
91
|
+
context[:id].to_s,
|
|
92
|
+
SettingsService.instance.account_id.to_s
|
|
93
|
+
)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
55
96
|
end
|
data/lib/vwo/vwo_client.rb
CHANGED
|
@@ -24,6 +24,7 @@ require_relative 'utils/network_util'
|
|
|
24
24
|
require_relative 'models/schemas/settings_schema_validation'
|
|
25
25
|
require_relative 'services/batch_event_queue'
|
|
26
26
|
require_relative 'enums/api_enum'
|
|
27
|
+
require_relative 'utils/uuid_util'
|
|
27
28
|
|
|
28
29
|
class VWOClient
|
|
29
30
|
attr_accessor :settings, :original_settings
|
|
@@ -49,11 +50,30 @@ class VWOClient
|
|
|
49
50
|
# @return [GetFlagResponse] The flag for the given feature key and context
|
|
50
51
|
def get_flag(feature_key, context)
|
|
51
52
|
api_name = 'get_flag'
|
|
52
|
-
|
|
53
|
+
uuid = nil
|
|
54
|
+
session_id = nil
|
|
55
|
+
|
|
56
|
+
# check if sessionId is present in context and should be non null and non empty
|
|
57
|
+
if context.is_a?(Hash) && context.key?(:sessionId) && !context[:sessionId].nil? && !context[:sessionId].to_s.empty?
|
|
58
|
+
session_id = context[:sessionId].to_i
|
|
59
|
+
else
|
|
60
|
+
session_id = Time.now.to_i
|
|
61
|
+
end
|
|
53
62
|
|
|
54
63
|
begin
|
|
55
64
|
hooks_service = HooksService.new(@options)
|
|
56
65
|
LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
|
|
66
|
+
unless context.is_a?(Hash)
|
|
67
|
+
raise TypeError, 'Invalid context'
|
|
68
|
+
end
|
|
69
|
+
unless context[:id].is_a?(String) && !context[:id].empty?
|
|
70
|
+
raise TypeError, 'Invalid context, id should be a non-empty string'
|
|
71
|
+
end
|
|
72
|
+
# make a copy of the context to avoid modifying the original context
|
|
73
|
+
context_copy = context.dup
|
|
74
|
+
uuid = UUIDUtil.get_uuid_from_context(@settings, context_copy, api_name)
|
|
75
|
+
# add the uuid to the context copy
|
|
76
|
+
context_copy[:uuid] = uuid
|
|
57
77
|
|
|
58
78
|
unless feature_key.is_a?(String) && !feature_key.empty?
|
|
59
79
|
raise TypeError, 'feature_key should be a non-empty string'
|
|
@@ -61,18 +81,12 @@ class VWOClient
|
|
|
61
81
|
unless SettingsService.instance.is_settings_valid
|
|
62
82
|
raise TypeError, 'Invalid Settings'
|
|
63
83
|
end
|
|
64
|
-
unless context.is_a?(Hash)
|
|
65
|
-
raise TypeError, 'Invalid context'
|
|
66
|
-
end
|
|
67
|
-
unless context[:id].is_a?(String) && !context[:id].empty?
|
|
68
|
-
raise TypeError, 'Invalid context, id should be a non-empty string'
|
|
69
|
-
end
|
|
70
84
|
|
|
71
|
-
context_model = ContextModel.new.model_from_dictionary(
|
|
85
|
+
context_model = ContextModel.new.model_from_dictionary(context_copy)
|
|
72
86
|
FlagApi.new.get(feature_key, @settings, context_model, hooks_service)
|
|
73
87
|
rescue StandardError => e
|
|
74
88
|
LoggerService.log(LogLevelEnum::ERROR, "EXECUTION_FAILED", {apiName: api_name, err: e.message, an: ApiEnum::GET_FLAG})
|
|
75
|
-
|
|
89
|
+
GetFlagResponse.new(false, [], uuid, session_id)
|
|
76
90
|
end
|
|
77
91
|
end
|
|
78
92
|
|
|
@@ -87,7 +101,14 @@ class VWOClient
|
|
|
87
101
|
begin
|
|
88
102
|
hooks_service = HooksService.new(@options)
|
|
89
103
|
LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
|
|
90
|
-
|
|
104
|
+
|
|
105
|
+
unless context.is_a?(Hash) && context[:id].is_a?(String) && !context[:id].empty?
|
|
106
|
+
raise TypeError, 'Invalid context, id should be a non-empty string'
|
|
107
|
+
end
|
|
108
|
+
# make a copy of the context to avoid modifying the original context
|
|
109
|
+
context_copy = context.dup
|
|
110
|
+
context_copy[:uuid] = UUIDUtil.get_uuid_from_context(@settings, context_copy, api_name)
|
|
111
|
+
|
|
91
112
|
unless event_name.is_a?(String) && !event_name.empty?
|
|
92
113
|
raise TypeError, 'event_name should be a non-empty string'
|
|
93
114
|
end
|
|
@@ -97,11 +118,8 @@ class VWOClient
|
|
|
97
118
|
unless SettingsService.instance.is_settings_valid
|
|
98
119
|
raise TypeError, 'Invalid Settings'
|
|
99
120
|
end
|
|
100
|
-
unless context[:id].is_a?(String) && !context[:id].empty?
|
|
101
|
-
raise TypeError, 'Invalid context, id should be a non-empty string'
|
|
102
|
-
end
|
|
103
121
|
|
|
104
|
-
context_model = ContextModel.new.model_from_dictionary(
|
|
122
|
+
context_model = ContextModel.new.model_from_dictionary(context_copy)
|
|
105
123
|
TrackApi.new.track(@settings, event_name, context_model, event_properties, hooks_service)
|
|
106
124
|
rescue StandardError => e
|
|
107
125
|
LoggerService.log(LogLevelEnum::ERROR, "EXECUTION_FAILED", {apiName: api_name, err: e.message, an: ApiEnum::TRACK_EVENT})
|
|
@@ -118,21 +136,24 @@ class VWOClient
|
|
|
118
136
|
|
|
119
137
|
begin
|
|
120
138
|
LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
|
|
121
|
-
|
|
122
|
-
unless attributes.is_a?(Hash) && !attributes.empty?
|
|
123
|
-
raise TypeError, 'Attributes should be a hash with key-value pairs and non-empty'
|
|
124
|
-
end
|
|
125
139
|
unless context.is_a?(Hash)
|
|
126
140
|
raise TypeError, 'Invalid context'
|
|
127
141
|
end
|
|
128
142
|
unless context[:id].is_a?(String) && !context[:id].empty?
|
|
129
143
|
raise TypeError, 'Invalid context, id should be a non-empty string'
|
|
130
144
|
end
|
|
145
|
+
# make a copy of the context to avoid modifying the original context
|
|
146
|
+
context_copy = context.dup
|
|
147
|
+
context_copy[:uuid] = UUIDUtil.get_uuid_from_context(@settings, context_copy, api_name)
|
|
148
|
+
|
|
149
|
+
unless attributes.is_a?(Hash) && !attributes.empty?
|
|
150
|
+
raise TypeError, 'Attributes should be a hash with key-value pairs and non-empty'
|
|
151
|
+
end
|
|
131
152
|
unless SettingsService.instance.is_settings_valid
|
|
132
153
|
raise TypeError, 'Invalid Settings'
|
|
133
154
|
end
|
|
134
155
|
|
|
135
|
-
context_model = ContextModel.new.model_from_dictionary(
|
|
156
|
+
context_model = ContextModel.new.model_from_dictionary(context_copy)
|
|
136
157
|
SetAttributeApi.new.set_attribute(attributes, context_model)
|
|
137
158
|
rescue StandardError => e
|
|
138
159
|
LoggerService.log(LogLevelEnum::ERROR, "EXECUTION_FAILED", {apiName: api_name, err: e.message, an: ApiEnum::SET_ATTRIBUTE})
|
data/lib/vwo.rb
CHANGED
|
@@ -106,4 +106,20 @@ class VWO
|
|
|
106
106
|
puts "[ERROR]: VWO-SDK: Got error while initializing VWO: #{e.message}"
|
|
107
107
|
end
|
|
108
108
|
end
|
|
109
|
+
|
|
110
|
+
# Generates a UUID for a user based on their user_id and account_id.
|
|
111
|
+
#
|
|
112
|
+
# @param user_id [String] The user's ID.
|
|
113
|
+
# @param account_id [String] The account ID associated with the user.
|
|
114
|
+
# @return [String] A UUID string formatted without dashes and in uppercase.
|
|
115
|
+
def self.get_uuid(user_id, account_id)
|
|
116
|
+
# check if user_id and account_id are non-empty strings
|
|
117
|
+
if !user_id.is_a?(String) || user_id.empty? || !account_id.is_a?(String) || account_id.empty?
|
|
118
|
+
puts "User ID and account ID must be non-empty strings"
|
|
119
|
+
return nil
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# generate and return a new uuid based on user_id and account_id
|
|
123
|
+
return UUIDUtil.get_uuid(user_id, account_id)
|
|
124
|
+
end
|
|
109
125
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vwo-fme-ruby-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- VWO
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-02-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: uuidtools
|