vwo-fme-ruby-sdk 1.0.0 → 1.2.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 +13 -0
- data/lib/resources/error_messages.json +30 -0
- data/lib/resources/info_messages.json +33 -0
- data/lib/resources/warn_messages.json +1 -0
- data/lib/vwo/api/get_flag.rb +236 -0
- data/lib/vwo/api/set_attribute.rb +57 -0
- data/lib/vwo/api/track_event.rb +77 -0
- data/lib/vwo/constants/constants.rb +54 -0
- data/lib/vwo/decorators/storage_decorator.rb +86 -0
- data/lib/vwo/{utils/logger_helper.rb → enums/api_enum.rb} +5 -10
- data/lib/vwo/enums/campaign_type_enum.rb +19 -0
- data/lib/vwo/enums/decision_types_enum.rb +18 -0
- data/lib/vwo/enums/event_enum.rb +19 -0
- data/lib/vwo/enums/headers_enum.rb +20 -0
- data/lib/vwo/enums/hooks_enum.rb +17 -0
- data/lib/vwo/enums/http_method_enum.rb +18 -0
- data/lib/vwo/enums/log_level_enum.rb +21 -0
- data/lib/vwo/enums/status_enum.rb +19 -0
- data/lib/vwo/enums/storage_enum.rb +22 -0
- data/lib/vwo/enums/url_enum.rb +21 -0
- data/lib/vwo/models/campaign/campaign_model.rb +192 -0
- data/lib/vwo/models/campaign/feature_model.rb +111 -0
- data/lib/vwo/models/campaign/impact_campaign_model.rb +38 -0
- data/lib/vwo/models/campaign/metric_model.rb +44 -0
- data/lib/vwo/models/campaign/rule_model.rb +56 -0
- data/lib/vwo/models/campaign/variable_model.rb +51 -0
- data/lib/vwo/models/campaign/variation_model.rb +137 -0
- data/lib/vwo/models/gateway_service_model.rb +39 -0
- data/lib/vwo/models/schemas/settings_schema_validation.rb +102 -0
- data/lib/vwo/models/settings/settings_model.rb +85 -0
- data/lib/vwo/models/storage/storage_data_model.rb +44 -0
- data/lib/vwo/models/user/context_model.rb +100 -0
- data/lib/vwo/models/user/context_vwo_model.rb +38 -0
- data/lib/vwo/{utils/feature_flag_response.rb → models/user/get_flag_response.rb} +14 -14
- data/lib/vwo/models/vwo_options_model.rb +107 -0
- data/lib/vwo/packages/decision_maker/decision_maker.rb +60 -0
- data/lib/vwo/packages/logger/core/log_manager.rb +90 -0
- data/lib/vwo/packages/logger/core/transport_manager.rb +87 -0
- data/lib/vwo/packages/logger/log_message_builder.rb +70 -0
- data/lib/vwo/packages/logger/logger.rb +38 -0
- data/lib/vwo/packages/logger/transports/console_transport.rb +49 -0
- data/lib/vwo/packages/network_layer/client/network_client.rb +107 -0
- data/lib/vwo/packages/network_layer/handlers/request_handler.rb +37 -0
- data/lib/vwo/packages/network_layer/manager/network_manager.rb +78 -0
- data/lib/vwo/packages/network_layer/models/global_request_model.rb +105 -0
- data/lib/vwo/packages/network_layer/models/request_model.rb +145 -0
- data/lib/vwo/packages/network_layer/models/response_model.rb +45 -0
- data/lib/vwo/packages/segmentation_evaluator/core/segmentation_manager.rb +76 -0
- data/lib/vwo/packages/segmentation_evaluator/enums/segment_operand_regex_enum.rb +29 -0
- data/lib/vwo/packages/segmentation_evaluator/enums/segment_operand_value_enum.rb +26 -0
- data/lib/vwo/packages/segmentation_evaluator/enums/segment_operator_value_enum.rb +30 -0
- data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_evaluator.rb +210 -0
- data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_operand_evaluator.rb +198 -0
- data/lib/vwo/packages/segmentation_evaluator/utils/segment_util.rb +44 -0
- data/lib/vwo/{constants.rb → packages/storage/connector.rb} +12 -10
- data/lib/vwo/packages/storage/storage.rb +45 -0
- data/lib/vwo/services/campaign_decision_service.rb +153 -0
- data/lib/vwo/services/hooks_service.rb +51 -0
- data/lib/vwo/services/logger_service.rb +83 -0
- data/lib/vwo/services/settings_service.rb +120 -0
- data/lib/vwo/services/storage_service.rb +65 -0
- data/lib/vwo/utils/campaign_util.rb +249 -0
- data/lib/vwo/utils/data_type_util.rb +105 -0
- data/lib/vwo/utils/decision_util.rb +253 -0
- data/lib/vwo/utils/function_util.rb +123 -0
- data/lib/vwo/utils/gateway_service_util.rb +101 -0
- data/lib/vwo/utils/impression_util.rb +49 -0
- data/lib/vwo/utils/log_message_util.rb +42 -0
- data/lib/vwo/utils/meg_util.rb +350 -0
- data/lib/vwo/utils/network_util.rb +235 -0
- data/lib/vwo/utils/rule_evaluation_util.rb +57 -0
- data/lib/vwo/utils/settings_util.rb +38 -0
- data/lib/vwo/utils/url_util.rb +46 -0
- data/lib/vwo/utils/uuid_util.rb +55 -0
- data/lib/vwo/vwo_builder.rb +156 -11
- data/lib/vwo/vwo_client.rb +163 -113
- data/lib/vwo.rb +49 -31
- metadata +191 -9
- data/lib/vwo/utils/request.rb +0 -89
@@ -0,0 +1,46 @@
|
|
1
|
+
# Copyright 2025 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_relative '../services/settings_service'
|
16
|
+
|
17
|
+
class UrlUtil
|
18
|
+
@collection_prefix = nil
|
19
|
+
|
20
|
+
class << self
|
21
|
+
attr_accessor :collection_prefix
|
22
|
+
|
23
|
+
# Initializes the UrlUtil with an optional collection prefix.
|
24
|
+
#
|
25
|
+
# @param collection_prefix [String] Optional prefix for URL collections.
|
26
|
+
# @return [UrlUtil] The singleton instance of UrlUtil with updated properties.
|
27
|
+
def init(collection_prefix: nil)
|
28
|
+
@collection_prefix = collection_prefix if collection_prefix.is_a?(String)
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
# Retrieves the base URL.
|
33
|
+
#
|
34
|
+
# @return [String] The base URL.
|
35
|
+
def get_base_url
|
36
|
+
base_url = SettingsService.instance.hostname
|
37
|
+
|
38
|
+
return base_url if SettingsService.instance.is_gateway_service_provided
|
39
|
+
|
40
|
+
# Construct URL with collection_prefix if it exists
|
41
|
+
return "#{base_url}/#{@collection_prefix}" if @collection_prefix
|
42
|
+
|
43
|
+
base_url
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Copyright 2025 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 'uuidtools'
|
16
|
+
require 'securerandom'
|
17
|
+
|
18
|
+
SEED_URL = 'https://vwo.com' # Replace with actual SEED_URL
|
19
|
+
|
20
|
+
class UUIDUtil
|
21
|
+
# Generates a random UUID based on an API key.
|
22
|
+
#
|
23
|
+
# @param sdk_key [String] The API key used to generate a namespace for the UUID.
|
24
|
+
# @return [String] A random UUID string.
|
25
|
+
def self.get_random_uuid(sdk_key)
|
26
|
+
namespace = UUIDTools::UUID.sha1_create(UUIDTools::UUID_DNS_NAMESPACE, sdk_key)
|
27
|
+
random_uuid = UUIDTools::UUID.sha1_create(namespace, SecureRandom.uuid)
|
28
|
+
random_uuid.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
# Generates a UUID for a user based on their user_id and account_id.
|
32
|
+
#
|
33
|
+
# @param user_id [String] The user's ID.
|
34
|
+
# @param account_id [String] The account ID associated with the user.
|
35
|
+
# @return [String] A UUID string formatted without dashes and in uppercase.
|
36
|
+
def self.get_uuid(user_id, account_id)
|
37
|
+
vwo_namespace = UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, SEED_URL)
|
38
|
+
user_id_namespace = generate_uuid(account_id, vwo_namespace)
|
39
|
+
uuid_for_user_id_account_id = generate_uuid(user_id, user_id_namespace)
|
40
|
+
|
41
|
+
uuid_for_user_id_account_id.to_s.delete('-').upcase
|
42
|
+
end
|
43
|
+
|
44
|
+
# Helper function to generate a UUID v5 based on a name and a namespace.
|
45
|
+
#
|
46
|
+
# @param name [String] The name from which to generate the UUID.
|
47
|
+
# @param namespace [UUIDTools::UUID] The namespace used to generate the UUID.
|
48
|
+
# @return [UUIDTools::UUID] A UUID string or nil if inputs are invalid.
|
49
|
+
def self.generate_uuid(name, namespace)
|
50
|
+
return nil if name.nil? || namespace.nil?
|
51
|
+
# Convert name to string to handle integer inputs
|
52
|
+
name_str = name.to_s
|
53
|
+
UUIDTools::UUID.sha1_create(namespace, name_str)
|
54
|
+
end
|
55
|
+
end
|
data/lib/vwo/vwo_builder.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright 2025 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,18 +12,163 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
# require 'json'
|
16
|
+
# require 'uri'
|
17
|
+
require_relative './enums/log_level_enum'
|
18
|
+
require_relative 'vwo_client'
|
19
|
+
require_relative './services/settings_service'
|
20
|
+
require_relative './packages/storage/storage'
|
21
|
+
require_relative './packages/network_layer/manager/network_manager'
|
22
|
+
require_relative './packages/segmentation_evaluator/core/segmentation_manager'
|
23
|
+
require_relative './services/logger_service'
|
17
24
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
25
|
+
class VWOBuilder
|
26
|
+
attr_reader :settings, :storage, :log_manager, :is_settings_fetch_in_progress, :vwo_instance
|
27
|
+
|
28
|
+
# Initialize the VWOBuilder with the given options
|
29
|
+
# @param options [Hash] The options for the VWOBuilder
|
30
|
+
def initialize(options)
|
31
|
+
@options = options
|
32
|
+
@settings = nil
|
33
|
+
@storage = nil
|
34
|
+
@log_manager = nil
|
35
|
+
@is_settings_fetch_in_progress = false
|
36
|
+
@vwo_instance = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# Set the network manager
|
40
|
+
# @return [VWOBuilder] The VWOBuilder instance
|
41
|
+
def set_network_manager
|
42
|
+
begin
|
43
|
+
network_instance = NetworkManager.instance(@options[:threading] || {})
|
44
|
+
network_instance.attach_client(@options[:network][:client]) if @options[:network] && @options[:network][:client]
|
45
|
+
LoggerService.log(LogLevelEnum::DEBUG, "SERVICE_INITIALIZED", {service: "Network Layer"})
|
46
|
+
network_instance.get_config.set_development_mode(@options[:is_development_mode]) if @options[:is_development_mode]
|
47
|
+
self
|
48
|
+
rescue StandardError => e
|
49
|
+
LoggerService.log(LogLevelEnum::ERROR, "Failed to initialize network manager: #{e.message}", nil)
|
50
|
+
self
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Set the segmentation manager
|
55
|
+
# @return [VWOBuilder] The VWOBuilder instance
|
56
|
+
def set_segmentation
|
57
|
+
SegmentationManager.instance.attach_evaluator(@options[:segmentation]) if @options[:segmentation]
|
58
|
+
LoggerService.log(LogLevelEnum::DEBUG, "SERVICE_INITIALIZED", {service: "Segmentation Evaluator"})
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
# Fetch the settings from the server
|
63
|
+
# @param force [Boolean] Whether to force the fetch of settings
|
64
|
+
# @return [Hash] The settings
|
65
|
+
def fetch_settings(force = false)
|
66
|
+
return @settings if !force && @settings
|
67
|
+
|
68
|
+
@is_settings_fetch_in_progress = true
|
69
|
+
settings = SettingsService.new(@options).get_settings(force)
|
70
|
+
@is_settings_fetch_in_progress = false
|
71
|
+
@settings = settings unless force
|
72
|
+
settings
|
73
|
+
end
|
74
|
+
|
75
|
+
# Get the settings from the server
|
76
|
+
# @param force [Boolean] Whether to force the fetch of settings
|
77
|
+
# @return [Hash] The settings
|
78
|
+
def get_settings(force = false)
|
79
|
+
return @settings if !force && @settings
|
80
|
+
|
81
|
+
begin
|
82
|
+
fetch_settings(force)
|
83
|
+
rescue StandardError => e
|
84
|
+
LoggerService.log(LogLevelEnum::ERROR, "Failed to fetch settings: #{e.message}", nil)
|
85
|
+
{}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Set the storage
|
90
|
+
# @return [VWOBuilder] The VWOBuilder instance
|
91
|
+
def set_storage
|
92
|
+
@storage = @options[:storage] ? Storage.instance.attach_connector(@options[:storage]) : nil
|
93
|
+
LoggerService.log(LogLevelEnum::DEBUG, "SERVICE_INITIALIZED", {service: "Storage"})
|
94
|
+
self
|
95
|
+
end
|
96
|
+
|
97
|
+
# Set the settings service
|
98
|
+
# @return [VWOBuilder] The VWOBuilder instance
|
99
|
+
def set_settings_service
|
100
|
+
@settings_service = SettingsService.new(@options)
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
# Set the logger
|
105
|
+
# @return [VWOBuilder] The VWOBuilder instance
|
106
|
+
def set_logger
|
107
|
+
begin
|
108
|
+
@log_manager = LoggerService.new(@options[:logger] || {})
|
109
|
+
LoggerService.log(LogLevelEnum::DEBUG, "SERVICE_INITIALIZED", {service: "Logger"})
|
110
|
+
rescue => e
|
111
|
+
puts "Got error while setting logger: #{e.message}"
|
112
|
+
end
|
113
|
+
self
|
114
|
+
end
|
115
|
+
|
116
|
+
# Initialize the polling
|
117
|
+
# @return [VWOBuilder] The VWOBuilder instance
|
118
|
+
def init_polling
|
119
|
+
return self unless @options[:poll_interval]
|
120
|
+
|
121
|
+
unless @options[:poll_interval].is_a?(Numeric)
|
122
|
+
LoggerService.log(LogLevelEnum::ERROR, "INIT_OPTIONS_INVALID", {
|
123
|
+
key: 'poll_interval',
|
124
|
+
correctType: 'number'
|
125
|
+
})
|
126
|
+
return self
|
22
127
|
end
|
23
128
|
|
24
|
-
#
|
25
|
-
|
26
|
-
|
129
|
+
# Check if the polling interval is greater than or equal to 1000
|
130
|
+
unless @options[:poll_interval] >= 1000
|
131
|
+
LoggerService.log(LogLevelEnum::ERROR, "INIT_OPTIONS_INVALID", {
|
132
|
+
key: 'poll_interval',
|
133
|
+
correctType: 'number'
|
134
|
+
})
|
135
|
+
return self
|
136
|
+
end
|
137
|
+
|
138
|
+
check_and_poll
|
139
|
+
self
|
140
|
+
end
|
141
|
+
|
142
|
+
# Build the VWO instance
|
143
|
+
# @param settings [Hash] The settings for the VWO instance
|
144
|
+
# @return [VWOClient] The VWO instance
|
145
|
+
def build(settings)
|
146
|
+
@vwo_instance = VWOClient.new(settings, @options)
|
147
|
+
@vwo_instance
|
148
|
+
end
|
149
|
+
|
150
|
+
# This method is used to check and poll the settings from the server
|
151
|
+
# @return [VWOBuilder] The VWOBuilder instance
|
152
|
+
def check_and_poll
|
153
|
+
polling_interval = @options[:poll_interval]
|
154
|
+
|
155
|
+
@thread_pool = NetworkManager.instance.get_client.get_thread_pool
|
156
|
+
@thread_pool.post do
|
157
|
+
loop do
|
158
|
+
sleep(polling_interval / 1000.0)
|
159
|
+
begin
|
160
|
+
latest_settings = fetch_settings(true)
|
161
|
+
if latest_settings.to_json != @settings.to_json
|
162
|
+
@settings = latest_settings
|
163
|
+
LoggerService.log(LogLevelEnum::INFO, "POLLING_SET_SETTINGS")
|
164
|
+
@vwo_instance.update_settings(latest_settings.clone, false) if @vwo_instance
|
165
|
+
else
|
166
|
+
LoggerService.log(LogLevelEnum::INFO, "POLLING_NO_CHANGE_IN_SETTINGS")
|
167
|
+
end
|
168
|
+
rescue StandardError => e
|
169
|
+
LoggerService.log(LogLevelEnum::ERROR, "POLLING_FETCH_SETTINGS_FAILED")
|
170
|
+
end
|
171
|
+
end
|
27
172
|
end
|
28
173
|
end
|
29
|
-
end
|
174
|
+
end
|
data/lib/vwo/vwo_client.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright 2025 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,131 +12,181 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
|
16
|
-
require_relative '
|
17
|
-
require_relative '
|
18
|
-
require_relative '
|
19
|
-
require_relative '
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
15
|
+
require_relative 'services/settings_service'
|
16
|
+
require_relative 'models/user/context_model'
|
17
|
+
require_relative 'api/get_flag'
|
18
|
+
require_relative 'api/set_attribute'
|
19
|
+
require_relative 'api/track_event'
|
20
|
+
require_relative 'utils/url_util'
|
21
|
+
require_relative 'utils/settings_util'
|
22
|
+
require_relative 'services/logger_service'
|
23
|
+
require_relative 'enums/log_level_enum'
|
24
|
+
require_relative 'utils/network_util'
|
25
|
+
require_relative 'models/schemas/settings_schema_validation'
|
26
|
+
|
27
|
+
class VWOClient
|
28
|
+
attr_accessor :settings, :original_settings
|
29
|
+
attr_reader :options
|
30
|
+
|
31
|
+
def initialize(settings, options)
|
32
|
+
@options = options
|
33
|
+
@settings = settings
|
34
|
+
@original_settings = settings.dup
|
35
|
+
|
36
|
+
begin
|
37
|
+
set_settings_and_add_campaigns_to_rules(settings, self)
|
38
|
+
UrlUtil.init(collection_prefix: @settings.get_collection_prefix)
|
39
|
+
rescue StandardError => e
|
40
|
+
LoggerService.log(LogLevelEnum::ERROR, "Error setting and adding campaigns to rules message: #{e.message}", nil)
|
33
41
|
end
|
42
|
+
LoggerService.log(LogLevelEnum::INFO, "CLIENT_INITIALIZED")
|
43
|
+
self
|
44
|
+
end
|
34
45
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
# Send a POST request to retrieve the feature flag.
|
60
|
-
response = Utils::Request.send_post_request(endpoint, context)
|
61
|
-
|
62
|
-
# If a response is received, parse it and return a FeatureFlagResponse.
|
63
|
-
if response
|
64
|
-
parsed_response = JSON.parse(response)
|
65
|
-
return FeatureFlagResponse.new(parsed_response['isEnabled'], parsed_response['variables'])
|
66
|
-
else
|
67
|
-
# Return a default disabled response if no response was received.
|
68
|
-
return FeatureFlagResponse.new(false, [])
|
46
|
+
# Get the flag for a given feature key and context
|
47
|
+
# @param feature_key [String] The key of the feature to get the flag for
|
48
|
+
# @param context [Hash] The context of the user
|
49
|
+
# @return [GetFlagResponse] The flag for the given feature key and context
|
50
|
+
def get_flag(feature_key, context)
|
51
|
+
api_name = 'get_flag'
|
52
|
+
error_response = GetFlagResponse.new(false, [])
|
53
|
+
|
54
|
+
begin
|
55
|
+
hooks_service = HooksService.new(@options)
|
56
|
+
LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
|
57
|
+
|
58
|
+
unless feature_key.is_a?(String) && !feature_key.empty?
|
59
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'feature_key', type: feature_key.class.name , correctType: 'String'})
|
60
|
+
raise TypeError, 'feature_key should be a non-empty string'
|
61
|
+
end
|
62
|
+
unless SettingsSchema.new.is_settings_valid(@original_settings)
|
63
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_SETTING_INVALID")
|
64
|
+
raise TypeError, 'Invalid Settings'
|
65
|
+
end
|
66
|
+
unless context.is_a?(Hash)
|
67
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_CONTEXT_INVALID")
|
68
|
+
raise TypeError, 'Invalid context'
|
69
69
|
end
|
70
|
+
unless context[:id].is_a?(String) && !context[:id].empty?
|
71
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'context.id', type: context[:id].class.name, correctType: 'String'})
|
72
|
+
raise TypeError, 'Invalid context, id should be a non-empty string'
|
73
|
+
end
|
74
|
+
|
75
|
+
context_model = ContextModel.new.model_from_dictionary(context)
|
76
|
+
FlagApi.new.get(feature_key, @settings, context_model, hooks_service)
|
70
77
|
rescue StandardError => e
|
71
|
-
|
72
|
-
|
73
|
-
return FeatureFlagResponse.new(false, [])
|
78
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_THROW_ERROR", {apiName: api_name, err: e.message})
|
79
|
+
error_response
|
74
80
|
end
|
81
|
+
end
|
75
82
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
83
|
+
# Track an event with given properties and context
|
84
|
+
# @param event_name [String] The name of the event to track
|
85
|
+
# @param context [Hash] The context of the user
|
86
|
+
# @param event_properties [Hash] The properties of the event
|
87
|
+
# @return [Hash] The result of the event tracking
|
88
|
+
def track_event(event_name, context, event_properties = {})
|
89
|
+
api_name = 'track_event'
|
90
|
+
|
91
|
+
begin
|
92
|
+
hooks_service = HooksService.new(@options)
|
93
|
+
LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
|
94
|
+
|
95
|
+
unless event_name.is_a?(String) && !event_name.empty?
|
96
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'event_name', type: event_name.class.name, correctType: 'String'})
|
97
|
+
raise TypeError, 'event_name should be a non-empty string'
|
98
|
+
end
|
99
|
+
unless event_properties.is_a?(Hash)
|
100
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'event_properties', type: event_properties.class.name, correctType: 'Hash'})
|
101
|
+
raise TypeError, 'event_properties should be a hash'
|
102
|
+
end
|
103
|
+
unless SettingsSchema.new.is_settings_valid(@original_settings)
|
104
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_SETTING_INVALID")
|
105
|
+
raise TypeError, 'Invalid Settings'
|
106
|
+
end
|
107
|
+
unless context[:id].is_a?(String) && !context[:id].empty?
|
108
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'context.id', type: context[:id].class.name, correctType: 'String'})
|
109
|
+
raise TypeError, 'Invalid context, id should be a non-empty string'
|
110
|
+
end
|
111
|
+
|
112
|
+
context_model = ContextModel.new.model_from_dictionary(context)
|
113
|
+
TrackApi.new.track(@settings, event_name, context_model, event_properties, hooks_service)
|
105
114
|
rescue StandardError => e
|
106
|
-
|
107
|
-
|
115
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_THROW_ERROR", {apiName: api_name, err: e.message})
|
116
|
+
{ event_name: false }
|
108
117
|
end
|
118
|
+
end
|
109
119
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
120
|
+
# Set attributes for a given context
|
121
|
+
# @param attributes [Hash] The attributes to set
|
122
|
+
# @param context [Hash] The context of the user
|
123
|
+
# @return [Hash] The result of the attribute setting
|
124
|
+
def set_attribute(attributes, context = nil)
|
125
|
+
api_name = 'set_attribute'
|
126
|
+
|
127
|
+
begin
|
128
|
+
LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
|
129
|
+
|
130
|
+
unless attributes.is_a?(Hash) && !attributes.empty?
|
131
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'attributes', type: attributes.class.name, correctType: 'Hash'})
|
132
|
+
raise TypeError, 'Attributes should be a hash with key-value pairs and non-empty'
|
133
|
+
end
|
134
|
+
unless context.is_a?(Hash)
|
135
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'context', type: context.class.name, correctType: 'Hash'})
|
136
|
+
raise TypeError, 'Invalid context'
|
137
|
+
end
|
138
|
+
unless context[:id].is_a?(String) && !context[:id].empty?
|
139
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'context.id', type: context[:id].class.name, correctType: 'String'})
|
140
|
+
raise TypeError, 'Invalid context, id should be a non-empty string'
|
141
|
+
end
|
142
|
+
unless SettingsSchema.new.is_settings_valid(@original_settings)
|
143
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_SETTING_INVALID")
|
144
|
+
raise TypeError, 'Invalid Settings'
|
145
|
+
end
|
146
|
+
|
147
|
+
context_model = ContextModel.new.model_from_dictionary(context)
|
148
|
+
SetAttributeApi.new.set_attribute(@settings, attributes, context_model)
|
149
|
+
rescue StandardError => e
|
150
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_THROW_ERROR", {apiName: api_name, err: e.message})
|
151
|
+
end
|
152
|
+
end
|
127
153
|
|
128
|
-
|
129
|
-
|
130
|
-
|
154
|
+
# Update the settings of the VWO client instance
|
155
|
+
# @param settings [Hash] The settings to update with (optional)
|
156
|
+
# @param is_via_webhook [Boolean] Whether the update is via webhook (default: true)
|
157
|
+
# @return [void]
|
158
|
+
def update_settings(settings = nil, is_via_webhook = true)
|
159
|
+
api_name = 'update_settings'
|
160
|
+
|
161
|
+
begin
|
162
|
+
LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
|
163
|
+
|
164
|
+
# Fetch settings from server or use provided settings if not empty
|
165
|
+
settings_to_update = if settings.nil? || settings.empty?
|
166
|
+
SettingsService.instance.fetch_settings(is_via_webhook)
|
167
|
+
else
|
168
|
+
settings
|
169
|
+
end
|
131
170
|
|
132
|
-
#
|
133
|
-
|
171
|
+
# Validate settings schema
|
172
|
+
unless SettingsSchema.new.is_settings_valid(settings_to_update)
|
173
|
+
LoggerService.log(LogLevelEnum::ERROR, "API_SETTING_INVALID")
|
174
|
+
raise TypeError, 'Invalid Settings'
|
175
|
+
end
|
134
176
|
|
135
|
-
#
|
136
|
-
|
177
|
+
# Set the settings on the client instance
|
178
|
+
set_settings_and_add_campaigns_to_rules(settings_to_update, self)
|
179
|
+
LoggerService.log(LogLevelEnum::INFO, "SETTINGS_UPDATED", {apiName: api_name, isViaWebhook: is_via_webhook})
|
137
180
|
rescue StandardError => e
|
138
|
-
|
139
|
-
|
181
|
+
LoggerService.log(
|
182
|
+
LogLevelEnum::ERROR,
|
183
|
+
"SETTINGS_FETCH_FAILED",
|
184
|
+
{
|
185
|
+
apiName: api_name,
|
186
|
+
isViaWebhook: is_via_webhook,
|
187
|
+
err: e.message
|
188
|
+
}
|
189
|
+
)
|
140
190
|
end
|
141
191
|
end
|
142
192
|
end
|