vwo-fme-ruby-sdk 1.12.0 → 1.55.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 +4 -3
- data/lib/resources/error_messages.json +5 -5
- data/lib/resources/info_messages.json +10 -9
- data/lib/vwo.rb +19 -104
- data/lib/{vwo → wingify}/api/get_flag.rb +33 -3
- data/lib/{vwo → wingify}/api/set_attribute.rb +3 -3
- data/lib/{vwo → wingify}/api/track_event.rb +1 -1
- data/lib/{vwo → wingify}/constants/constants.rb +24 -2
- data/lib/{vwo → wingify}/decorators/storage_decorator.rb +1 -1
- data/lib/{vwo → wingify}/enums/api_enum.rb +1 -1
- data/lib/{vwo → wingify}/enums/campaign_type_enum.rb +1 -1
- data/lib/{vwo → wingify}/enums/debug_category_enum.rb +1 -1
- data/lib/{vwo → wingify}/enums/decision_types_enum.rb +1 -1
- data/lib/{vwo → wingify}/enums/event_enum.rb +7 -6
- data/lib/{vwo → wingify}/enums/headers_enum.rb +1 -1
- data/lib/{vwo → wingify}/enums/hooks_enum.rb +1 -1
- data/lib/{vwo → wingify}/enums/http_method_enum.rb +1 -1
- data/lib/{vwo → wingify}/enums/log_level_enum.rb +1 -1
- data/lib/{vwo → wingify}/enums/log_level_to_number.rb +1 -1
- data/lib/{vwo → wingify}/enums/status_enum.rb +1 -1
- data/lib/{vwo → wingify}/enums/storage_enum.rb +1 -1
- data/lib/{vwo → wingify}/enums/url_enum.rb +1 -1
- data/lib/{vwo → wingify}/models/campaign/campaign_model.rb +1 -1
- data/lib/{vwo → wingify}/models/campaign/feature_model.rb +1 -1
- data/lib/{vwo → wingify}/models/campaign/impact_campaign_model.rb +1 -1
- data/lib/{vwo → wingify}/models/campaign/metric_model.rb +1 -1
- data/lib/{vwo → wingify}/models/campaign/rule_model.rb +1 -1
- data/lib/{vwo → wingify}/models/campaign/variable_model.rb +1 -1
- data/lib/{vwo → wingify}/models/campaign/variation_model.rb +1 -1
- data/lib/{vwo → wingify}/models/gateway_service_model.rb +1 -1
- data/lib/{vwo → wingify}/models/schemas/settings_schema_validation.rb +1 -1
- data/lib/{vwo → wingify}/models/settings/settings_model.rb +7 -2
- data/lib/{vwo → wingify}/models/storage/storage_data_model.rb +1 -1
- data/lib/{vwo → wingify}/models/user/context_model.rb +1 -1
- data/lib/{vwo → wingify}/models/user/context_vwo_model.rb +1 -1
- data/lib/{vwo → wingify}/models/user/get_flag_response.rb +1 -1
- data/lib/{vwo → wingify}/models/vwo_options_model.rb +1 -1
- data/lib/{vwo → wingify}/packages/decision_maker/decision_maker.rb +1 -1
- data/lib/{vwo → wingify}/packages/logger/core/log_manager.rb +1 -1
- data/lib/{vwo → wingify}/packages/logger/core/transport_manager.rb +1 -1
- data/lib/{vwo → wingify}/packages/logger/log_message_builder.rb +1 -1
- data/lib/{vwo → wingify}/packages/logger/logger.rb +1 -1
- data/lib/{vwo → wingify}/packages/logger/transports/console_transport.rb +1 -1
- data/lib/{vwo → wingify}/packages/network_layer/client/network_client.rb +2 -2
- data/lib/{vwo → wingify}/packages/network_layer/handlers/request_handler.rb +1 -1
- data/lib/{vwo → wingify}/packages/network_layer/manager/network_manager.rb +1 -1
- data/lib/{vwo → wingify}/packages/network_layer/models/global_request_model.rb +1 -1
- data/lib/{vwo → wingify}/packages/network_layer/models/request_model.rb +1 -1
- data/lib/{vwo → wingify}/packages/network_layer/models/response_model.rb +1 -1
- data/lib/{vwo → wingify}/packages/segmentation_evaluator/core/segmentation_manager.rb +1 -1
- data/lib/{vwo → wingify}/packages/segmentation_evaluator/enums/segment_operand_regex_enum.rb +1 -1
- data/lib/{vwo → wingify}/packages/segmentation_evaluator/enums/segment_operand_value_enum.rb +1 -1
- data/lib/{vwo → wingify}/packages/segmentation_evaluator/enums/segment_operator_value_enum.rb +1 -1
- data/lib/{vwo → wingify}/packages/segmentation_evaluator/evaluators/segment_evaluator.rb +1 -1
- data/lib/{vwo → wingify}/packages/segmentation_evaluator/evaluators/segment_operand_evaluator.rb +1 -1
- data/lib/{vwo → wingify}/packages/segmentation_evaluator/utils/segment_util.rb +1 -1
- data/lib/{vwo → wingify}/packages/storage/connector.rb +1 -1
- data/lib/{vwo → wingify}/packages/storage/storage.rb +1 -1
- data/lib/{vwo → wingify}/services/batch_event_queue.rb +1 -1
- data/lib/{vwo → wingify}/services/campaign_decision_service.rb +1 -1
- data/lib/{vwo → wingify}/services/hooks_service.rb +1 -1
- data/lib/{vwo → wingify}/services/logger_service.rb +21 -10
- data/lib/{vwo → wingify}/services/settings_service.rb +18 -5
- data/lib/{vwo → wingify}/services/storage_service.rb +1 -1
- data/lib/{vwo → wingify}/utils/batch_event_dispatcher_util.rb +5 -5
- data/lib/wingify/utils/brand_context.rb +33 -0
- data/lib/wingify/utils/brand_util.rb +53 -0
- data/lib/{vwo → wingify}/utils/campaign_util.rb +1 -1
- data/lib/{vwo → wingify}/utils/data_type_util.rb +1 -1
- data/lib/{vwo → wingify}/utils/debugger_service_util.rb +2 -2
- data/lib/{vwo → wingify}/utils/decision_util.rb +1 -1
- data/lib/{vwo → wingify}/utils/event_util.rb +5 -5
- data/lib/{vwo → wingify}/utils/function_util.rb +1 -1
- data/lib/{vwo → wingify}/utils/gateway_service_util.rb +2 -2
- data/lib/{vwo → wingify}/utils/impression_util.rb +38 -3
- data/lib/{vwo → wingify}/utils/log_message_util.rb +1 -1
- data/lib/{vwo → wingify}/utils/meg_util.rb +1 -1
- data/lib/{vwo → wingify}/utils/network_util.rb +43 -16
- data/lib/{vwo → wingify}/utils/rule_evaluation_util.rb +1 -1
- data/lib/{vwo → wingify}/utils/settings_util.rb +1 -1
- data/lib/{vwo → wingify}/utils/usage_stats_util.rb +1 -1
- data/lib/{vwo → wingify}/utils/uuid_util.rb +1 -1
- data/lib/{vwo/vwo_builder.rb → wingify/wingify_builder.rb} +11 -11
- data/lib/{vwo/vwo_client.rb → wingify/wingify_client.rb} +2 -2
- data/lib/wingify.rb +117 -0
- metadata +141 -82
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 15f3001a8b2112b59b1f97dc24f09735e4cb4c28de642f62f18c76a7f7d67d08
|
|
4
|
+
data.tar.gz: d14170568fbcfcc5677488737641e50f1949240a2788d5345d640516881eef83
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 78d65f005620ce3c1b285f356255e992176d546e9b0518a22f37d740760c6abcbe99a0acfc8e5558372a58b50d6e9dfcb996d17795193210d1dea060a161a10c
|
|
7
|
+
data.tar.gz: bf913d055a768cf1bb36e3608fc8b86f1e22fbd96aa107bff99a327b4c643b38d3d30031587bdc05fd7dfd3ecfd0e803b6594c8f4a7fbc0426d625214b8c2035
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"API_CALLED": "API - {apiName} called",
|
|
3
|
-
"SERVICE_INITIALIZED": "
|
|
3
|
+
"SERVICE_INITIALIZED": "{brand} {service} initialized while creating an instance of SDK",
|
|
4
4
|
"USING_POLL_INTERVAL_FROM_SETTINGS": "key: poll_interval not found or invalid. Using poll_interval from {source} ({pollInterval})",
|
|
5
5
|
|
|
6
6
|
"EXPERIMENTS_EVALUATION_WHEN_ROLLOUT_PASSED": "Rollout rule got passed for user {userId}. Hence, evaluating experiments",
|
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
"USER_BUCKET_TO_VARIATION": "User ID:{userId} for experiment:{campaignKey} having percent traffic:{percentTraffic} got bucket-value:{bucketValue} and hash-value:{hashValue}",
|
|
10
10
|
|
|
11
|
-
"IMPRESSION_FOR_TRACK_USER": "Impression built for vwo_variationShown(
|
|
11
|
+
"IMPRESSION_FOR_TRACK_USER": "Impression built for vwo_variationShown({brand} standard event for tracking user) event haivng Account ID:{accountId}, User ID:{userId}, and experiment ID:{campaignId}",
|
|
12
12
|
"IMPRESSION_FOR_TRACK_GOAL": "Impression built for event:{eventName} event having Account ID:{accountId}, and user ID:{userId}",
|
|
13
|
-
"IMPRESSION_FOR_SYNC_VISITOR_PROP": "Impression built for {eventName}(
|
|
13
|
+
"IMPRESSION_FOR_SYNC_VISITOR_PROP": "Impression built for {eventName}({brand} internal event) event for Account ID:{accountId}, and user ID:{userId}",
|
|
14
|
+
"IMPRESSION_FOR_USAGE_TRACKING": "Impression built for vwo_feTrackUsage({brand} standard event for usage tracking call) event having Account ID:{accountId}, and user ID:{userId}",
|
|
14
15
|
|
|
15
16
|
"CONFIG_BATCH_EVENT_LIMIT_EXCEEDED": "Impression event - {endPoint} failed due to exceeding payload size. Parameter eventsPerRequest in batchEvents config in init API has value:{eventsPerRequest} for account ID:{accountId}. Please read the official documentation for knowing the size limits",
|
|
16
17
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"EXECUTION_FAILED": "API - {apiName} failed to execute. Error:{err}",
|
|
3
|
-
"INVALID_OPTIONS": "[ERROR]:
|
|
4
|
-
"INVALID_SDK_KEY_IN_OPTIONS": "[ERROR]:
|
|
5
|
-
"INVALID_ACCOUNT_ID_IN_OPTIONS": "[ERROR]:
|
|
3
|
+
"INVALID_OPTIONS": "[ERROR]: {log_prefix} {date} Options should be of type object",
|
|
4
|
+
"INVALID_SDK_KEY_IN_OPTIONS": "[ERROR]: {log_prefix} {date} Please provide the sdkKey in the options and should be a of type string",
|
|
5
|
+
"INVALID_ACCOUNT_ID_IN_OPTIONS": "[ERROR]: {log_prefix} {date} Please provide {brand} account ID in the options and should be a of type string|number",
|
|
6
6
|
|
|
7
7
|
"ERROR_ADDING_CAMPAIGNS_TO_RULES": "Error setting and adding campaigns to rules. Error: {err}",
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"INVALID_SETTINGS_SCHEMA": "Settings are not valid for account ID: {accountId} and SDK key: {sdkKey}. Got settings as {settings}",
|
|
13
13
|
|
|
14
14
|
"ERROR_UPDATING_SETTINGS": "Error while updating settings. Error: {err}",
|
|
15
|
-
"UPDATING_CLIENT_INSTANCE_FAILED_WHEN_WEBHOOK_TRIGGERED": "Failed to fetch settings and hence
|
|
15
|
+
"UPDATING_CLIENT_INSTANCE_FAILED_WHEN_WEBHOOK_TRIGGERED": "Failed to fetch settings and hence {brand} client instance couldn't be updated when API: {apiName} got called having isViaWebhook param as {isViaWebhook}. Error: {err}",
|
|
16
16
|
|
|
17
17
|
"INVALID_PARAM": "Key:{key} passed to API:{apiName} is not of valid type. Got type:{type}, should be:{correctType}",
|
|
18
18
|
"INVALID_CONTEXT": "Context should be an object and must contain a mandatory key - id, which is User ID",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"ERROR_READING_DATA_FROM_STORAGE": "Error while reading data from storage. Error: {err}",
|
|
25
25
|
"ERROR_STORING_DATA_IN_STORAGE": "Error while storing data in storage. Error: {err}",
|
|
26
26
|
|
|
27
|
-
"INVALID_GATEWAY_URL": "Please provide a valid URL for
|
|
27
|
+
"INVALID_GATEWAY_URL": "Please provide a valid URL for {brand} Gateway Service while initializing the SDK",
|
|
28
28
|
"INVALID_RETRY_CONFIG": "Retry config is invalid. Should be of type:object",
|
|
29
29
|
|
|
30
30
|
"NETWORK_CALL_FAILED": "Error occurred for {method} request. Error:{err}",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
-
"ON_INIT_ALREADY_RESOLVED": "[INFO]:
|
|
3
|
-
"ON_INIT_SETTINGS_FAILED": "[INFO]:
|
|
2
|
+
"ON_INIT_ALREADY_RESOLVED": "[INFO]: {log_prefix} {date} {apiName} already resolved",
|
|
3
|
+
"ON_INIT_SETTINGS_FAILED": "[INFO]: {log_prefix} {date} {brand} settings could not be fetched",
|
|
4
4
|
|
|
5
|
-
"POLLING_SET_SETTINGS": "There's a change in settings from the last settings fetched. Hence, instantiating a new
|
|
6
|
-
"POLLING_NO_CHANGE_IN_SETTINGS": "No change in settings with the last settings fetched. Hence, not instantiating new
|
|
5
|
+
"POLLING_SET_SETTINGS": "There's a change in settings from the last settings fetched. Hence, instantiating a new {brand} client internally",
|
|
6
|
+
"POLLING_NO_CHANGE_IN_SETTINGS": "No change in settings with the last settings fetched. Hence, not instantiating new {brand} client",
|
|
7
7
|
|
|
8
8
|
"SETTINGS_FETCH_SUCCESS": "Settings fetched successfully",
|
|
9
9
|
|
|
10
|
-
"CLIENT_INITIALIZED": "
|
|
10
|
+
"CLIENT_INITIALIZED": "{brand} Client initialized",
|
|
11
11
|
|
|
12
12
|
"STORED_VARIATION_FOUND": "Variation {variationKey} found in storage for the user {userId} for the {experimentType} experiment:{experimentKey}",
|
|
13
13
|
|
|
@@ -28,14 +28,15 @@
|
|
|
28
28
|
"MEG_CAMPAIGN_FOUND_IN_STORAGE": "Campaign {campaignKey} found in storage for user ID:{userId}",
|
|
29
29
|
"MEG_CAMPAIGN_ELIGIBLE": "Campaign {campaignKey} is eligible for user ID:{userId}",
|
|
30
30
|
"MEG_WINNER_CAMPAIGN": "MEG: Campaign {campaignKey} is the winner for group {groupId} for user ID:{userId} {algo}",
|
|
31
|
-
"SETTINGS_UPDATED": "Settings fetched and updated successfully on the current
|
|
32
|
-
"NETWORK_CALL_SUCCESS": "Impression for {event} - {endPoint} was successfully received by
|
|
31
|
+
"SETTINGS_UPDATED": "Settings fetched and updated successfully on the current {brand} client instance when API: {apiName} got called having isViaWebhook param as {isViaWebhook}",
|
|
32
|
+
"NETWORK_CALL_SUCCESS": "Impression for {event} - {endPoint} was successfully received by {brand} having Account ID:{accountId}, UUID: {uuid}",
|
|
33
|
+
"USAGE_TRACKING_DISPATCHED": "FE track usage call dispatched for Account ID:{accountId}, User ID:{userId}, and feature key:{featureKey}",
|
|
33
34
|
|
|
34
35
|
"EVENT_BATCH_DEFAULTS": "{parameter} in SDK configuration is missing or invalid (should be greater than {minLimit}). Using default value: {defaultValue}",
|
|
35
36
|
"EVENT_QUEUE": "Event with payload:{event} pushed to the {queueType} queue",
|
|
36
37
|
"EVENT_BATCH_After_FLUSHING": "Event queue having {length} events has been flushed {manually}",
|
|
37
|
-
"IMPRESSION_BATCH_SUCCESS": "Impression event - {endPoint} was successfully received by
|
|
38
|
-
"IMPRESSION_BATCH_FAILED": "Batch events couldn\"t be received by
|
|
38
|
+
"IMPRESSION_BATCH_SUCCESS": "Impression event - {endPoint} was successfully received by {brand} having Account ID:{accountId}",
|
|
39
|
+
"IMPRESSION_BATCH_FAILED": "Batch events couldn\"t be received by {brand}. Calling Flush Callback with error and data",
|
|
39
40
|
"EVENT_BATCH_MAX_LIMIT": "{parameter} passed in SDK configuration is greater than the maximum limit of {maxLimit}. Setting it to the maximum limit",
|
|
40
41
|
"GATEWAY_AND_BATCH_EVENTS_CONFIG_MISMATCH": "Batch Events config passed in SDK configuration will not work as the gatewayService is already configured. Please check the documentation for more details",
|
|
41
42
|
"NETWORK_CALL_SUCCESS_WITH_RETRIES": "Network call for {extraData} succeeded after {attempts} retry attempt(s). Previous attempts failed with error: {err}",
|
data/lib/vwo.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2024-
|
|
1
|
+
# Copyright 2024-2026 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.
|
|
@@ -12,114 +12,29 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
require_relative '
|
|
18
|
-
require_relative 'vwo/vwo_client'
|
|
19
|
-
require_relative 'vwo/utils/event_util'
|
|
20
|
-
require_relative 'vwo/services/settings_service'
|
|
15
|
+
require_relative 'wingify'
|
|
16
|
+
require_relative 'wingify/wingify_client'
|
|
17
|
+
require_relative 'wingify/wingify_builder'
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def initialize(options)
|
|
27
|
-
self.class.set_instance(options)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def self.set_instance(options)
|
|
31
|
-
options_vwo_builder = options[:vwo_builder]
|
|
32
|
-
@@vwo_builder = options_vwo_builder || VWOBuilder.new(options)
|
|
33
|
-
|
|
34
|
-
@@instance = @@vwo_builder
|
|
35
|
-
.set_logger
|
|
36
|
-
.set_settings_service
|
|
37
|
-
.set_storage
|
|
38
|
-
.set_network_manager
|
|
39
|
-
.set_segmentation
|
|
40
|
-
.init_polling
|
|
41
|
-
.init_usage_stats
|
|
42
|
-
.init_batch
|
|
43
|
-
|
|
44
|
-
if options[:settings]
|
|
45
|
-
return @@vwo_builder.build(options[:settings])
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
settings = @@vwo_builder.get_settings
|
|
49
|
-
@@instance = @@vwo_builder.build(settings)
|
|
50
|
-
@@instance
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def self.instance
|
|
54
|
-
@@instance
|
|
55
|
-
end
|
|
19
|
+
# Map existing VWO classes to Wingify aliases to maintain 100% backward compatibility
|
|
20
|
+
VWOClient = WingifyClient
|
|
21
|
+
VWOBuilder = WingifyBuilder
|
|
56
22
|
|
|
23
|
+
module VWO
|
|
24
|
+
# Backward compatible VWO facade
|
|
25
|
+
# It intercepts the init call, forces the is_via_vwo flag, and forwards to Wingify core.
|
|
57
26
|
def self.init(options)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
unless options.is_a?(Hash)
|
|
61
|
-
puts "[ERROR]: VWO-SDK: Please provide the options as a hash"
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
unless options[:sdk_key]&.is_a?(String) && !options[:sdk_key].empty?
|
|
65
|
-
puts "[ERROR]: VWO-SDK: Please provide the sdkKey in the options and should be a of type string"
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
unless options[:account_id] && (options[:account_id].is_a?(Integer) || (options[:account_id].is_a?(String) && !options[:account_id].empty?))
|
|
69
|
-
puts "[ERROR]: VWO-SDK: Please provide VWO account ID in the options and should be a of type string|number"
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# store the current time in milliseconds
|
|
73
|
-
sdk_init_start_time = (Time.now.to_f * 1000).to_i
|
|
74
|
-
# initialize the vwo instance
|
|
75
|
-
new(options)
|
|
76
|
-
# store the time after initializing the vwo instance in milliseconds
|
|
77
|
-
sdk_init_end_time = (Time.now.to_f * 1000).to_i
|
|
78
|
-
# calculate the time taken for initializing the vwo instance
|
|
79
|
-
time_taken_for_init = sdk_init_end_time - sdk_init_start_time
|
|
80
|
-
# get sdkMetaInfo from settings file to check if the sdk was initialized earlier
|
|
81
|
-
sdk_meta_info = nil
|
|
82
|
-
was_initialized_earlier = false
|
|
83
|
-
|
|
84
|
-
begin
|
|
85
|
-
if @@instance && @@instance.original_settings && @@instance.original_settings.is_a?(Hash)
|
|
86
|
-
sdk_meta_info = @@instance.original_settings["sdkMetaInfo"]
|
|
87
|
-
was_initialized_earlier = sdk_meta_info && sdk_meta_info.is_a?(Hash) ? sdk_meta_info["wasInitializedEarlier"] : false
|
|
88
|
-
end
|
|
89
|
-
rescue StandardError => e
|
|
90
|
-
was_initialized_earlier = false
|
|
91
|
-
end
|
|
92
|
-
if !was_initialized_earlier && SettingsService.instance.is_settings_valid
|
|
93
|
-
# send the sdk init info to vwo server
|
|
94
|
-
send_sdk_init_event(SettingsService.instance.settings_fetch_time, time_taken_for_init.to_s)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# send the usage stats event to vwo server
|
|
98
|
-
# get usage stats account id from settings
|
|
99
|
-
usage_stats_account_id = @@instance.original_settings["usageStatsAccountId"]
|
|
100
|
-
if usage_stats_account_id
|
|
101
|
-
send_sdk_usage_stats_event(usage_stats_account_id)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
@@instance
|
|
105
|
-
rescue StandardError => e
|
|
106
|
-
puts "[ERROR]: VWO-SDK: Got error while initializing VWO: #{e.message}"
|
|
107
|
-
end
|
|
27
|
+
options[:is_via_vwo] = true
|
|
28
|
+
Wingify.init(options)
|
|
108
29
|
end
|
|
109
30
|
|
|
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
31
|
def self.get_uuid(user_id, account_id)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return UUIDUtil.get_uuid(user_id, account_id)
|
|
32
|
+
Wingify.get_uuid(user_id, account_id)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Keep VWO.new backward compatible for any customers manually instantiating it,
|
|
36
|
+
# although standard docs recommend VWO.init
|
|
37
|
+
def self.new(options)
|
|
38
|
+
init(options)
|
|
124
39
|
end
|
|
125
40
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2024-
|
|
1
|
+
# Copyright 2024-2026 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.
|
|
@@ -40,6 +40,10 @@ class FlagApi
|
|
|
40
40
|
rollout_variation_to_return = nil
|
|
41
41
|
experiment_variation_to_return = nil
|
|
42
42
|
should_check_for_experiments_rules = false
|
|
43
|
+
# Flag to check if variation shown event has been fired
|
|
44
|
+
is_variation_shown_fired = false
|
|
45
|
+
# Flag to check if tracking usage is enabled
|
|
46
|
+
is_tracking_usage_enabled = settings.get_is_tracking_usage_enabled
|
|
43
47
|
|
|
44
48
|
passed_rules_information = {} # for storing integration callback
|
|
45
49
|
evaluated_feature_map = {}
|
|
@@ -65,6 +69,8 @@ class FlagApi
|
|
|
65
69
|
|
|
66
70
|
if variation
|
|
67
71
|
LoggerService.log(LogLevelEnum::INFO, "STORED_VARIATION_FOUND", {variationKey: variation.get_key, userId: context.get_id, experimentKey: stored_data[:experiment_key], experimentType: "experiment"})
|
|
72
|
+
# Send usage tracking call when user is served from storage
|
|
73
|
+
send_tracking_usage(settings, context, is_tracking_usage_enabled, feature_key)
|
|
68
74
|
return GetFlagResponse.new(true, variation.get_variables, context.get_uuid, context.get_session_id)
|
|
69
75
|
end
|
|
70
76
|
end
|
|
@@ -91,6 +97,8 @@ class FlagApi
|
|
|
91
97
|
|
|
92
98
|
if feature.nil?
|
|
93
99
|
LoggerService.log(LogLevelEnum::ERROR, "FEATURE_NOT_FOUND", {featureKey: feature_key, an: ApiEnum::GET_FLAG, sId: context.get_session_id, uuid: context.get_uuid})
|
|
100
|
+
# Send usage tracking call when feature is not found
|
|
101
|
+
send_tracking_usage(settings, context, is_tracking_usage_enabled, feature_key)
|
|
94
102
|
return GetFlagResponse.new(false, [], context.get_uuid, context.get_session_id)
|
|
95
103
|
end
|
|
96
104
|
|
|
@@ -106,6 +114,12 @@ class FlagApi
|
|
|
106
114
|
rollout_rules.each do |rule|
|
|
107
115
|
result = evaluate_rule(settings, feature, rule, context, evaluated_feature_map, nil, storage_service, decision)
|
|
108
116
|
pre_segmentation_result = result[:pre_segmentation_result]
|
|
117
|
+
whitelisted_object = result[:whitelisted_object]
|
|
118
|
+
|
|
119
|
+
if whitelisted_object.is_a?(Hash) && !whitelisted_object.empty?
|
|
120
|
+
is_variation_shown_fired = true
|
|
121
|
+
end
|
|
122
|
+
|
|
109
123
|
updated_decision = result[:updated_decision]
|
|
110
124
|
decision.merge!(updated_decision) if updated_decision
|
|
111
125
|
|
|
@@ -131,6 +145,8 @@ class FlagApi
|
|
|
131
145
|
update_integrations_decision_object(passed_rollout_campaign, variation, passed_rules_information, decision)
|
|
132
146
|
|
|
133
147
|
create_and_send_impression_for_variation_shown(settings, passed_rollout_campaign.get_id, variation.get_id, context, feature_key)
|
|
148
|
+
# set is_variation_shown_fired to true since we already sent variation shown call for rollout
|
|
149
|
+
is_variation_shown_fired = true
|
|
134
150
|
end
|
|
135
151
|
end
|
|
136
152
|
elsif rollout_rules.empty?
|
|
@@ -147,11 +163,16 @@ class FlagApi
|
|
|
147
163
|
result = evaluate_rule(settings, feature, rule, context, evaluated_feature_map, meg_group_winner_campaigns, storage_service, decision)
|
|
148
164
|
pre_segmentation_result = result[:pre_segmentation_result]
|
|
149
165
|
whitelisted_object = result[:whitelisted_object]
|
|
166
|
+
|
|
167
|
+
if whitelisted_object.is_a?(Hash) && !whitelisted_object.empty?
|
|
168
|
+
is_variation_shown_fired = true
|
|
169
|
+
end
|
|
170
|
+
|
|
150
171
|
updated_decision = result[:updated_decision]
|
|
151
172
|
decision.merge!(updated_decision) if updated_decision
|
|
152
173
|
|
|
153
174
|
if pre_segmentation_result
|
|
154
|
-
if whitelisted_object.nil?
|
|
175
|
+
if whitelisted_object.nil? || whitelisted_object.empty?
|
|
155
176
|
experiment_rules_to_evaluate << rule
|
|
156
177
|
else
|
|
157
178
|
is_enabled = true
|
|
@@ -176,6 +197,8 @@ class FlagApi
|
|
|
176
197
|
update_integrations_decision_object(campaign, variation, passed_rules_information, decision)
|
|
177
198
|
|
|
178
199
|
create_and_send_impression_for_variation_shown(settings, campaign.get_id, variation.get_id, context, feature_key)
|
|
200
|
+
# set is_variation_shown_fired to true since we already sent variation shown call for experiment
|
|
201
|
+
is_variation_shown_fired = true
|
|
179
202
|
end
|
|
180
203
|
end
|
|
181
204
|
end
|
|
@@ -216,8 +239,15 @@ class FlagApi
|
|
|
216
239
|
context,
|
|
217
240
|
feature_key
|
|
218
241
|
)
|
|
242
|
+
# set is_variation_shown_fired to true since we already sent variation shown call for impact analysis
|
|
243
|
+
is_variation_shown_fired = true
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Send usage tracking call when no primary variation_shown event was dispatched.
|
|
247
|
+
# If a primary variation_shown event was fired, the server already has the usage tracking signal.
|
|
248
|
+
if !is_variation_shown_fired
|
|
249
|
+
send_tracking_usage(settings, context, is_tracking_usage_enabled, feature_key)
|
|
219
250
|
end
|
|
220
|
-
|
|
221
251
|
# Return final evaluated feature flag
|
|
222
252
|
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
253
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2024-
|
|
1
|
+
# Copyright 2024-2026 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.
|
|
@@ -33,14 +33,14 @@ class SetAttributeApi
|
|
|
33
33
|
def create_impression_for_attributes(attributes, context)
|
|
34
34
|
# Retrieve base properties for the event
|
|
35
35
|
properties = NetworkUtil.get_events_base_properties(
|
|
36
|
-
EventEnum::
|
|
36
|
+
EventEnum::SYNC_VISITOR_PROP,
|
|
37
37
|
URI.encode_www_form_component(context.user_agent),
|
|
38
38
|
context.ip_address
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
# Construct payload data for multiple attributes
|
|
42
42
|
payload = NetworkUtil.get_attribute_payload_data(
|
|
43
|
-
EventEnum::
|
|
43
|
+
EventEnum::SYNC_VISITOR_PROP,
|
|
44
44
|
attributes,
|
|
45
45
|
context
|
|
46
46
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2024-
|
|
1
|
+
# Copyright 2024-2026 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.
|
|
@@ -17,7 +17,29 @@
|
|
|
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.55.0'.freeze
|
|
21
|
+
|
|
22
|
+
# --- Brand-specific constants ---
|
|
23
|
+
|
|
24
|
+
# SDK gem names (sent in every network request as the sdk name identifier)
|
|
25
|
+
VWO_SDK_NAME = 'vwo-fme-ruby-sdk'.freeze
|
|
26
|
+
WINGIFY_SDK_NAME = 'wingify-fme-ruby-sdk'.freeze
|
|
27
|
+
|
|
28
|
+
# Settings fetch hostnames
|
|
29
|
+
VWO_HOST_NAME = 'dev.visualwebsiteoptimizer.com'.freeze
|
|
30
|
+
WINGIFY_SETTINGS_HOST_NAME = 'edge.wingify.net'.freeze
|
|
31
|
+
|
|
32
|
+
# Collect / events hostnames (used for ALL outbound POST calls)
|
|
33
|
+
WINGIFY_COLLECTION_HOST_NAME = 'collect.wingify.net'.freeze
|
|
34
|
+
# Note: VWO uses VWO_HOST_NAME for both settings and events
|
|
35
|
+
|
|
36
|
+
# Log prefixes shown in every log line
|
|
37
|
+
VWO_LOG_PREFIX = 'VWO-SDK'.freeze
|
|
38
|
+
WINGIFY_LOG_PREFIX = 'Wingify-SDK'.freeze
|
|
39
|
+
|
|
40
|
+
# Human-readable brand display names (used in log messages and error output)
|
|
41
|
+
VWO_BRAND_DISPLAY_NAME = 'VWO'.freeze
|
|
42
|
+
WINGIFY_BRAND_DISPLAY_NAME = 'Wingify'.freeze
|
|
21
43
|
|
|
22
44
|
MAX_TRAFFIC_PERCENT = 100
|
|
23
45
|
MAX_TRAFFIC_VALUE = 10_000
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2024-
|
|
1
|
+
# Copyright 2024-2026 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.
|
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
# Event types
|
|
16
16
|
module EventEnum
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
VARIATION_SHOWN = 'vwo_variationShown'
|
|
18
|
+
SYNC_VISITOR_PROP = 'vwo_syncVisitorProp'
|
|
19
|
+
DEBUGGER_EVENT = 'vwo_sdkDebug'
|
|
20
|
+
INIT_CALLED = 'vwo_fmeSdkInit'
|
|
21
|
+
USAGE_STATS = 'vwo_sdkUsageStats'
|
|
22
|
+
USER_EVALUATED = 'vwo_feTrackUsage'
|
|
22
23
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2024-
|
|
1
|
+
# Copyright 2024-2026 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.
|
|
@@ -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, :is_web_connectivity_enabled
|
|
21
|
+
:features, :campaigns, :campaign_groups, :groups, :poll_interval, :is_web_connectivity_enabled, :is_tracking_usage_enabled
|
|
22
22
|
|
|
23
23
|
def initialize(settings)
|
|
24
24
|
@sdk_key = settings["sdkKey"]
|
|
@@ -32,6 +32,7 @@ class SettingsModel
|
|
|
32
32
|
@campaign_groups = settings["campaignGroups"] || {}
|
|
33
33
|
@groups = settings["groups"] || {}
|
|
34
34
|
@is_web_connectivity_enabled = settings.fetch("isWebConnectivityEnabled", true)
|
|
35
|
+
@is_tracking_usage_enabled = settings.fetch("isMAU", false)
|
|
35
36
|
|
|
36
37
|
process_features(settings)
|
|
37
38
|
process_campaigns(settings)
|
|
@@ -98,4 +99,8 @@ class SettingsModel
|
|
|
98
99
|
def get_is_web_connectivity_enabled
|
|
99
100
|
@is_web_connectivity_enabled
|
|
100
101
|
end
|
|
102
|
+
|
|
103
|
+
def get_is_tracking_usage_enabled
|
|
104
|
+
@is_tracking_usage_enabled
|
|
105
|
+
end
|
|
101
106
|
end
|