kameleoon-client-ruby 3.9.0 → 3.10.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/kameleoon/data/cbscores.rb +58 -0
- data/lib/kameleoon/data/geolocation.rb +0 -1
- data/lib/kameleoon/data/kcs_heat.rb +3 -3
- data/lib/kameleoon/data/manager/visitor.rb +14 -1
- data/lib/kameleoon/kameleoon_client.rb +47 -8
- data/lib/kameleoon/kameleoon_client_config.rb +8 -4
- data/lib/kameleoon/managers/remote_data/remote_visitor_data.rb +28 -5
- data/lib/kameleoon/network/network_manager.rb +8 -4
- data/lib/kameleoon/network/url_provider.rb +45 -15
- data/lib/kameleoon/types/remote_visitor_data_filter.rb +5 -3
- data/lib/kameleoon/utils.rb +36 -11
- data/lib/kameleoon/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1831531ee6a40f0fbd32f110f9a9c9c1a33f71569c8b8de842bc01c06250d6d5
|
4
|
+
data.tar.gz: 6e6f8f9d0ee511c2a27fc63ff040e6155b90df66925989d1d08bd473f86c071b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f575eb2b6e12302ffa5cdb067582d994ab890edcab12f174732d396adc4248fc96a9e27935c008db52f59a93b5e0c713530356acab47711727651d2a4d48e3a
|
7
|
+
data.tar.gz: '058e6a5284550663cf20223eca099728a9ca0985aacfcfa829e585070228a83b38b4facda77d38a7f3ae17ae8fad37cc7898e47e2519826364a46b3205b33452'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kameleoon
|
4
|
+
class CBScores
|
5
|
+
# keys = experiment IDs / values = list of variation IDs ordered descending
|
6
|
+
# by score (there may be several variation ids with same score)
|
7
|
+
attr_reader :values
|
8
|
+
|
9
|
+
def initialize(cbs_map)
|
10
|
+
values = cbs_map.transform_values { |cbs_value| extract_var_ids(cbs_value) }
|
11
|
+
values.freeze
|
12
|
+
@values = values
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
str_values = @values.transform_values { |vgs| vgs.map(&:to_s) }
|
17
|
+
"CBScores{values:#{str_values}}"
|
18
|
+
end
|
19
|
+
|
20
|
+
class ScoredVarId
|
21
|
+
attr_reader :variation_id, :score
|
22
|
+
|
23
|
+
def initialize(variation_id, score)
|
24
|
+
@variation_id = variation_id
|
25
|
+
@score = score
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class VarGroup
|
30
|
+
attr_reader :ids
|
31
|
+
|
32
|
+
def initialize(ids)
|
33
|
+
ids.sort!
|
34
|
+
ids.freeze
|
35
|
+
@ids = ids
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
"VarGroup{ids:#{@ids}}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def extract_var_ids(scores)
|
46
|
+
grouped = {}
|
47
|
+
scores.each do |score|
|
48
|
+
glist = grouped[score.score]
|
49
|
+
if glist
|
50
|
+
glist.push(score.variation_id)
|
51
|
+
else
|
52
|
+
grouped[score.score] = [score.variation_id]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
grouped.sort_by { |score, _| -score }.collect { |_, glist| VarGroup.new(glist) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'concurrent'
|
4
4
|
require 'kameleoon/data/browser'
|
5
|
+
require 'kameleoon/data/cbscores'
|
5
6
|
require 'kameleoon/data/conversion'
|
6
7
|
require 'kameleoon/data/custom_data'
|
7
8
|
require 'kameleoon/data/device'
|
@@ -106,6 +107,12 @@ module Kameleoon
|
|
106
107
|
kcs_heat
|
107
108
|
end
|
108
109
|
|
110
|
+
def cbscores
|
111
|
+
cbs = @data.cbscores
|
112
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.cbscores -> (cbs: %s)', cbs)
|
113
|
+
cbs
|
114
|
+
end
|
115
|
+
|
109
116
|
def visitor_visits
|
110
117
|
visitor_visits = @data.visitor_visits
|
111
118
|
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.visitor_visits -> (visitor_visits: %s)', visitor_visits)
|
@@ -242,6 +249,8 @@ module Kameleoon
|
|
242
249
|
@data.set_geolocation(data, overwrite)
|
243
250
|
when KcsHeat
|
244
251
|
@data.kcs_heat = data
|
252
|
+
when CBScores
|
253
|
+
@data.set_cbscores(data, overwrite)
|
245
254
|
when VisitorVisits
|
246
255
|
@data.visitor_visits = data
|
247
256
|
when UniqueIdentifier
|
@@ -267,7 +276,7 @@ module Kameleoon
|
|
267
276
|
|
268
277
|
class VisitorData
|
269
278
|
attr_reader :mutex, :device, :browser, :geolocation, :operating_system
|
270
|
-
attr_accessor :last_activity_time, :legal_consent, :user_agent, :cookie, :kcs_heat, :visitor_visits,
|
279
|
+
attr_accessor :last_activity_time, :legal_consent, :user_agent, :cookie, :kcs_heat, :cbscores, :visitor_visits,
|
271
280
|
:mapping_identifier, :forced_variations, :simulated_variations
|
272
281
|
|
273
282
|
def initialize
|
@@ -398,6 +407,10 @@ module Kameleoon
|
|
398
407
|
@operating_system = operating_system if overwrite || @operating_system.nil?
|
399
408
|
end
|
400
409
|
|
410
|
+
def set_cbscores(cbs, overwrite)
|
411
|
+
@cbscores = cbs if overwrite || @cbscores.nil?
|
412
|
+
end
|
413
|
+
|
401
414
|
def add_forced_feature_variation(forced_variation)
|
402
415
|
@simulated_variations ||= {}
|
403
416
|
@simulated_variations[forced_variation.feature_key] = forced_variation
|
@@ -67,7 +67,7 @@ module Kameleoon
|
|
67
67
|
config.environment,
|
68
68
|
config.default_timeout_millisecond,
|
69
69
|
Network::AccessTokenSourceFactory.new(config.client_id, config.client_secret),
|
70
|
-
Network::UrlProvider.new(site_code)
|
70
|
+
Network::UrlProvider.new(site_code, config.network_domain)
|
71
71
|
)
|
72
72
|
@tracking_manager = Managers::Tracking::TrackingManager.new(
|
73
73
|
@data_manager, @network_manager, @visitor_manager, config.tracking_interval_second, @scheduler
|
@@ -1032,6 +1032,42 @@ module Kameleoon
|
|
1032
1032
|
visitor&.mapping_identifier || visitor_code
|
1033
1033
|
end
|
1034
1034
|
|
1035
|
+
def evaluate_cbscores(visitor, visitor_code, rule)
|
1036
|
+
return nil if visitor&.cbscores.nil?
|
1037
|
+
|
1038
|
+
Logging::KameleoonLogger.debug(
|
1039
|
+
"CALL: KameleoonClient.evaluate_cbscores(visitor, visitor_code: '%s', rule: %s)", visitor_code, rule
|
1040
|
+
)
|
1041
|
+
eval_exp = nil
|
1042
|
+
var_id_group_by_scores = visitor.cbscores.values[rule.experiment.id]
|
1043
|
+
if var_id_group_by_scores
|
1044
|
+
var_by_exp_in_cbs = nil
|
1045
|
+
var_id_group_by_scores.each do |var_group|
|
1046
|
+
var_by_exp_in_cbs = rule.experiment.variations_by_exposition.filter do |var_by_exp|
|
1047
|
+
var_group.ids.include?(var_by_exp.variation_id)
|
1048
|
+
end
|
1049
|
+
break unless var_by_exp_in_cbs.empty?
|
1050
|
+
end
|
1051
|
+
if (var_by_exp_in_cbs&.size || 0).positive?
|
1052
|
+
size = var_by_exp_in_cbs.size
|
1053
|
+
if size > 1
|
1054
|
+
code_for_hash = get_code_for_hash(visitor, visitor_code)
|
1055
|
+
variation_hash = Utils::Hasher.obtain(code_for_hash, rule.experiment.id, rule.respool_time)
|
1056
|
+
Logging::KameleoonLogger.debug("Calculated CBS hash %s for code '%s'", variation_hash, code_for_hash)
|
1057
|
+
idx = [(variation_hash * size).to_i, size - 1].min
|
1058
|
+
else
|
1059
|
+
idx = 0
|
1060
|
+
end
|
1061
|
+
eval_exp = EvaluatedExperiment.from_var_by_exp_rule(var_by_exp_in_cbs[idx], rule)
|
1062
|
+
end
|
1063
|
+
end
|
1064
|
+
Logging::KameleoonLogger.debug(
|
1065
|
+
"RETURN: KameleoonClient.evaluate_cbscores(visitor, visitor_code: '%s', rule: %s) -> (eval_exp: %s)",
|
1066
|
+
visitor_code, rule, eval_exp
|
1067
|
+
)
|
1068
|
+
eval_exp
|
1069
|
+
end
|
1070
|
+
|
1035
1071
|
##
|
1036
1072
|
# helper method for calculate variation key for feature flag
|
1037
1073
|
def _calculate_variation_key_for_feature(visitor_code, feature_flag)
|
@@ -1042,12 +1078,12 @@ module Kameleoon
|
|
1042
1078
|
visitor = @visitor_manager.get_visitor(visitor_code)
|
1043
1079
|
code_for_hash = get_code_for_hash(visitor, visitor_code)
|
1044
1080
|
# no rules -> return default_variation_key
|
1045
|
-
|
1081
|
+
eval_exp = nil
|
1046
1082
|
feature_flag.rules.each do |rule|
|
1047
1083
|
forced_variation = visitor&.get_forced_experiment_variation(rule.experiment.id)
|
1048
1084
|
if forced_variation&.force_targeting
|
1049
1085
|
# Forcing experiment variation in force-targeting mode
|
1050
|
-
|
1086
|
+
eval_exp = EvaluatedExperiment.from_var_by_exp_rule(forced_variation.var_by_exp, rule)
|
1051
1087
|
break
|
1052
1088
|
end
|
1053
1089
|
# check if visitor is targeted for rule, else next rule
|
@@ -1055,7 +1091,7 @@ module Kameleoon
|
|
1055
1091
|
|
1056
1092
|
unless forced_variation.nil?
|
1057
1093
|
# Forcing experiment variation in targeting-only mode
|
1058
|
-
|
1094
|
+
eval_exp = EvaluatedExperiment.from_var_by_exp_rule(forced_variation.var_by_exp, rule)
|
1059
1095
|
break
|
1060
1096
|
end
|
1061
1097
|
# uses for rule exposition
|
@@ -1063,8 +1099,11 @@ module Kameleoon
|
|
1063
1099
|
Logging::KameleoonLogger.debug("Calculated rule hash %s for code '%s'", hash_rule, code_for_hash)
|
1064
1100
|
# check main expostion for rule with hashRule
|
1065
1101
|
if hash_rule <= rule.exposition
|
1102
|
+
eval_exp = evaluate_cbscores(visitor, visitor_code, rule)
|
1103
|
+
break unless eval_exp.nil?
|
1104
|
+
|
1066
1105
|
if rule.targeted_delivery_type?
|
1067
|
-
|
1106
|
+
eval_exp = EvaluatedExperiment.from_var_by_exp_rule(rule.experiment.variations_by_exposition.first, rule)
|
1068
1107
|
break
|
1069
1108
|
end
|
1070
1109
|
# uses for variation's expositions
|
@@ -1073,7 +1112,7 @@ module Kameleoon
|
|
1073
1112
|
# get variation key with new hashVariation
|
1074
1113
|
variation = rule.experiment.get_variation(hash_variation)
|
1075
1114
|
unless variation.nil?
|
1076
|
-
|
1115
|
+
eval_exp = EvaluatedExperiment.from_var_by_exp_rule(variation, rule)
|
1077
1116
|
break
|
1078
1117
|
end
|
1079
1118
|
# if visitor is targeted for targeted rule then break cycle -> return default
|
@@ -1083,9 +1122,9 @@ module Kameleoon
|
|
1083
1122
|
end
|
1084
1123
|
Logging::KameleoonLogger.debug(
|
1085
1124
|
"RETURN: KameleoonClient._calculate_variation_key_for_feature(visitor_code: '%s', feature_flag: %s) " \
|
1086
|
-
'-> (eval_exp: %s)', visitor_code, feature_flag,
|
1125
|
+
'-> (eval_exp: %s)', visitor_code, feature_flag, eval_exp
|
1087
1126
|
)
|
1088
|
-
|
1127
|
+
eval_exp
|
1089
1128
|
end
|
1090
1129
|
|
1091
1130
|
def calculate_variation_key(eval_exp, default_value)
|
@@ -14,7 +14,7 @@ module Kameleoon
|
|
14
14
|
|
15
15
|
attr_reader :client_id, :client_secret, :refresh_interval_second, :session_duration_second,
|
16
16
|
:default_timeout_millisecond, :tracking_interval_second, :environment, :top_level_domain,
|
17
|
-
:verbose_mode
|
17
|
+
:verbose_mode, :network_domain
|
18
18
|
|
19
19
|
def to_s
|
20
20
|
'KameleoonClientConfig{' \
|
@@ -25,7 +25,8 @@ module Kameleoon
|
|
25
25
|
"environment:'#{@environment}'," \
|
26
26
|
"default_timeout_millisecond:#{@default_timeout_millisecond}," \
|
27
27
|
"top_level_domain:'#{@top_level_domain}'," \
|
28
|
-
"verbose_mode:#{verbose_mode}" \
|
28
|
+
"verbose_mode:#{verbose_mode}," \
|
29
|
+
"network_domain:'#{@network_domain}'" \
|
29
30
|
'}'
|
30
31
|
end
|
31
32
|
|
@@ -39,7 +40,8 @@ module Kameleoon
|
|
39
40
|
tracking_interval_millisecond: DEFAULT_TRACKING_INTERVAL_MILLISECONDS,
|
40
41
|
environment: nil,
|
41
42
|
top_level_domain: nil,
|
42
|
-
verbose_mode: nil
|
43
|
+
verbose_mode: nil,
|
44
|
+
network_domain: nil
|
43
45
|
)
|
44
46
|
raise Exception::ConfigCredentialsInvalid, 'Client ID is not specified' if client_id&.empty? != false
|
45
47
|
raise Exception::ConfigCredentialsInvalid, 'Client secret is not specified' if client_secret&.empty? != false
|
@@ -114,6 +116,7 @@ module Kameleoon
|
|
114
116
|
)
|
115
117
|
end
|
116
118
|
@top_level_domain = Utils::Domain.validate_top_level_domain(top_level_domain)
|
119
|
+
@network_domain = Utils::Domain.validate_network_domain(network_domain)
|
117
120
|
end
|
118
121
|
|
119
122
|
def self.read_from_yaml(path)
|
@@ -131,7 +134,8 @@ module Kameleoon
|
|
131
134
|
tracking_interval_millisecond: yaml['tracking_interval_millisecond'],
|
132
135
|
environment: yaml['environment'],
|
133
136
|
top_level_domain: yaml['top_level_domain'],
|
134
|
-
verbose_mode: yaml['verbose_mode']
|
137
|
+
verbose_mode: yaml['verbose_mode'],
|
138
|
+
network_domain: yaml['network_domain']
|
135
139
|
)
|
136
140
|
end
|
137
141
|
end
|
@@ -1,22 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'kameleoon/data/manager/page_view_visit'
|
4
|
-
require 'kameleoon/data/manager/assigned_variation'
|
5
|
-
require 'kameleoon/data/visitor_visits'
|
6
3
|
require 'kameleoon/data/browser'
|
7
|
-
require 'kameleoon/data/
|
4
|
+
require 'kameleoon/data/cbscores'
|
8
5
|
require 'kameleoon/data/conversion'
|
9
6
|
require 'kameleoon/data/custom_data'
|
7
|
+
require 'kameleoon/data/device'
|
10
8
|
require 'kameleoon/data/geolocation'
|
11
9
|
require 'kameleoon/data/kcs_heat'
|
12
10
|
require 'kameleoon/data/page_view'
|
11
|
+
require 'kameleoon/data/visitor_visits'
|
12
|
+
require 'kameleoon/data/manager/page_view_visit'
|
13
|
+
require 'kameleoon/data/manager/assigned_variation'
|
13
14
|
|
14
15
|
module Kameleoon
|
15
16
|
module Managers
|
16
17
|
module RemoteData
|
17
18
|
class RemoteVisitorData
|
18
19
|
attr_reader :custom_data_dict, :page_view_visits, :conversions, :experiments, :device, :browser,
|
19
|
-
:operating_system, :geolocation, :previous_visitor_visits, :kcs_heat, :visitor_code
|
20
|
+
:operating_system, :geolocation, :previous_visitor_visits, :kcs_heat, :cbs, :visitor_code
|
20
21
|
|
21
22
|
def initialize(hash)
|
22
23
|
current_visit = hash['currentVisit']
|
@@ -33,6 +34,7 @@ module Kameleoon
|
|
33
34
|
@previous_visitor_visits = VisitorVisits.new(times_started)
|
34
35
|
end
|
35
36
|
@kcs_heat = parse_kcs_heat(hash['kcs'])
|
37
|
+
@cbs = parse_cbscores(hash['cbs'])
|
36
38
|
end
|
37
39
|
|
38
40
|
def collect_data_to_add
|
@@ -40,6 +42,7 @@ module Kameleoon
|
|
40
42
|
data_to_add.concat(@custom_data_dict.values) unless @custom_data_dict.nil?
|
41
43
|
data_to_add.push(@previous_visitor_visits) unless @previous_visitor_visits.nil?
|
42
44
|
data_to_add.push(@kcs_heat) unless @kcs_heat.nil?
|
45
|
+
data_to_add.push(@cbs) unless @cbs.nil?
|
43
46
|
data_to_add.concat(@page_view_visits.values) unless @page_view_visits.nil?
|
44
47
|
data_to_add.concat(@experiments.values) unless @experiments.nil?
|
45
48
|
data_to_add.concat(conversions_single_objects)
|
@@ -184,6 +187,26 @@ module Kameleoon
|
|
184
187
|
end
|
185
188
|
KcsHeat.new(value_map)
|
186
189
|
end
|
190
|
+
|
191
|
+
def parse_cbscores(cbs)
|
192
|
+
return nil if cbs.nil?
|
193
|
+
|
194
|
+
cbs_map = {}
|
195
|
+
cbs.each do |str_exp_id, scored_var_entries|
|
196
|
+
next unless str_exp_id.is_a?(String) && scored_var_entries.is_a?(Hash)
|
197
|
+
|
198
|
+
entries = []
|
199
|
+
scored_var_entries.each do |str_var_id, score|
|
200
|
+
next unless str_var_id.is_a?(String) && (score.is_a?(Float) || score.is_a?(Integer))
|
201
|
+
|
202
|
+
var_id = str_var_id.to_i
|
203
|
+
entries.push(CBScores::ScoredVarId.new(var_id, score))
|
204
|
+
end
|
205
|
+
exp_id = str_exp_id.to_i
|
206
|
+
cbs_map[exp_id] = entries
|
207
|
+
end
|
208
|
+
CBScores.new(cbs_map)
|
209
|
+
end
|
187
210
|
end
|
188
211
|
end
|
189
212
|
end
|
@@ -88,13 +88,13 @@ module Kameleoon
|
|
88
88
|
if response.success?
|
89
89
|
success = true
|
90
90
|
elsif !response.error.nil?
|
91
|
-
log_level = attempt
|
91
|
+
log_level = get_log_level(attempt, retry_limit)
|
92
92
|
Logging::KameleoonLogger.log(log_level, "%s call '%s' failed: Error occurred during request: %s",
|
93
93
|
request.method, request.url, response.error)
|
94
94
|
else
|
95
|
-
log_level = attempt
|
96
|
-
Logging::KameleoonLogger.log(log_level, "%s call '%s' failed: Received unexpected status code
|
97
|
-
request.method, request.url, response.code)
|
95
|
+
log_level = get_log_level(attempt, retry_limit)
|
96
|
+
Logging::KameleoonLogger.log(log_level, "%s call '%s' failed: Received unexpected status code: %s, body: %s",
|
97
|
+
request.method, request.url, response.code, response.body)
|
98
98
|
if response.code == 401 && request.access_token
|
99
99
|
Logging::KameleoonLogger.warning("Unexpected rejection of access token '#{request.access_token}'")
|
100
100
|
@access_token_source.discard_token(request.access_token)
|
@@ -113,6 +113,10 @@ module Kameleoon
|
|
113
113
|
success ? response.body : false
|
114
114
|
end
|
115
115
|
|
116
|
+
def get_log_level(attempt, attempt_count)
|
117
|
+
return log_level = attempt < attempt_count ? Logging::LogLevel::WARNING : Logging::LogLevel::ERROR
|
118
|
+
end
|
119
|
+
|
116
120
|
def delay(period)
|
117
121
|
sleep(period)
|
118
122
|
end
|
@@ -14,27 +14,43 @@ module Kameleoon
|
|
14
14
|
POST_DATA_PATH = '/map/maps'
|
15
15
|
ACCESS_TOKEN_PATH = '/oauth/token'
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
DEFAULT_EVENTS_DOMAIN = 'events.kameleoon.eu'
|
18
|
+
DEFAULT_CONFIGURATION_DOMAIN = 'sdk-config.kameleoon.eu'
|
19
|
+
DEFAULT_ACCESS_TOKEN_DOMAIN = 'api.kameleoon.com'
|
19
20
|
DEFAULT_DATA_API_DOMAIN = 'data.kameleoon.io'
|
21
|
+
|
22
|
+
CONFIGURATION_API_URL_FORMAT = 'https://%s/%s'
|
23
|
+
DATA_API_URL_FORMAT = 'https://%s%s?%s'
|
24
|
+
RT_CONFIGURATION_URL_FORMAT = 'https://%s:8110/sse?%s'
|
25
|
+
ACCESS_TOKEN_URL_FORMAT = 'https://%s/oauth/token'
|
26
|
+
|
20
27
|
TEST_DATA_API_DOMAIN = 'data.kameleoon.net'
|
21
|
-
DEFAULT_AUTOMATION_API_DOMAIN = 'api.kameleoon.com'
|
22
28
|
TEST_AUTOMATION_API_DOMAIN = 'api.kameleoon.net'
|
23
29
|
|
24
|
-
attr_reader :site_code, :data_api_domain, :
|
30
|
+
attr_reader :site_code, :data_api_domain, :events_domain, :configuration_domain, :access_token_domain
|
25
31
|
|
26
32
|
def initialize(
|
27
33
|
site_code,
|
28
|
-
|
29
|
-
automation_api_domain = DEFAULT_AUTOMATION_API_DOMAIN
|
34
|
+
network_domain = nil
|
30
35
|
)
|
31
36
|
@site_code = site_code
|
32
|
-
@data_api_domain =
|
33
|
-
@
|
37
|
+
@data_api_domain = DEFAULT_DATA_API_DOMAIN
|
38
|
+
@events_domain = DEFAULT_EVENTS_DOMAIN
|
39
|
+
@configuration_domain = DEFAULT_CONFIGURATION_DOMAIN
|
40
|
+
@access_token_domain = DEFAULT_ACCESS_TOKEN_DOMAIN
|
41
|
+
@is_custom_domain = false
|
42
|
+
update_domains(network_domain)
|
34
43
|
end
|
35
44
|
|
36
45
|
def apply_data_api_domain(domain)
|
37
|
-
|
46
|
+
return if domain.nil? || domain.empty?
|
47
|
+
|
48
|
+
if @is_custom_domain
|
49
|
+
sub_domain = domain.split('.').first
|
50
|
+
@data_api_domain = @data_api_domain.sub(/^[^.]+/, sub_domain)
|
51
|
+
else
|
52
|
+
@data_api_domain = domain
|
53
|
+
end
|
38
54
|
end
|
39
55
|
|
40
56
|
def make_tracking_url
|
@@ -44,7 +60,7 @@ module Kameleoon
|
|
44
60
|
siteCode: @site_code,
|
45
61
|
bodyUa: true
|
46
62
|
}
|
47
|
-
|
63
|
+
format(DATA_API_URL_FORMAT, @data_api_domain, TRACKING_PATH, UriHelper.encode_query(params))
|
48
64
|
end
|
49
65
|
|
50
66
|
def make_visitor_data_get_url(visitor_code, filter, is_unique_identifier = false)
|
@@ -60,7 +76,8 @@ module Kameleoon
|
|
60
76
|
params[:experiment] = true if filter.experiments
|
61
77
|
params[:page] = true if filter.page_views
|
62
78
|
params[:staticData] = true if filter.device || filter.browser || filter.operating_system
|
63
|
-
|
79
|
+
params[:cbs] = true if filter.cbs
|
80
|
+
format(DATA_API_URL_FORMAT, @data_api_domain, VISITOR_DATA_PATH, UriHelper.encode_query(params))
|
64
81
|
end
|
65
82
|
|
66
83
|
def make_api_data_get_request_url(key)
|
@@ -68,11 +85,11 @@ module Kameleoon
|
|
68
85
|
siteCode: @site_code,
|
69
86
|
key: key
|
70
87
|
}
|
71
|
-
|
88
|
+
format(DATA_API_URL_FORMAT, @data_api_domain, GET_DATA_PATH, UriHelper.encode_query(params))
|
72
89
|
end
|
73
90
|
|
74
91
|
def make_configuration_url(environment = nil, timestamp = nil)
|
75
|
-
url = format(CONFIGURATION_API_URL_FORMAT, @site_code)
|
92
|
+
url = format(CONFIGURATION_API_URL_FORMAT, @configuration_domain, @site_code)
|
76
93
|
params = {}
|
77
94
|
params[:environment] = environment unless environment.nil?
|
78
95
|
params[:ts] = timestamp unless timestamp.nil?
|
@@ -82,11 +99,24 @@ module Kameleoon
|
|
82
99
|
|
83
100
|
def make_real_time_url
|
84
101
|
params = { siteCode: @site_code }
|
85
|
-
|
102
|
+
format(RT_CONFIGURATION_URL_FORMAT, @events_domain, UriHelper.encode_query(params))
|
86
103
|
end
|
87
104
|
|
88
105
|
def make_access_token_url
|
89
|
-
|
106
|
+
format(ACCESS_TOKEN_URL_FORMAT, @access_token_domain)
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def update_domains(network_domain)
|
112
|
+
return if network_domain.nil? || network_domain.empty?
|
113
|
+
|
114
|
+
@is_custom_domain = true
|
115
|
+
|
116
|
+
@data_api_domain = "data.#{network_domain}"
|
117
|
+
@events_domain = "events.#{network_domain}"
|
118
|
+
@configuration_domain = "sdk-config.#{network_domain}"
|
119
|
+
@access_token_domain = "api.#{network_domain}"
|
90
120
|
end
|
91
121
|
end
|
92
122
|
end
|
@@ -5,7 +5,7 @@ module Kameleoon
|
|
5
5
|
module Types
|
6
6
|
class RemoteVisitorDataFilter
|
7
7
|
attr_reader :previous_visit_amount, :current_visit, :custom_data, :page_views, :geolocation, :device, :browser,
|
8
|
-
:operating_system, :conversions, :experiments, :kcs, :visitor_code
|
8
|
+
:operating_system, :conversions, :experiments, :kcs, :visitor_code, :cbs
|
9
9
|
|
10
10
|
def to_s
|
11
11
|
"RemoteVisitorDataFilter{previous_visit_amount:#{@previous_visit_amount}," \
|
@@ -19,13 +19,14 @@ module Kameleoon
|
|
19
19
|
"conversions:#{@conversions}," \
|
20
20
|
"experiments:#{@experiments}," \
|
21
21
|
"kcs:#{@kcs}," \
|
22
|
-
"visitor_code:#{@visitor_code}}"
|
22
|
+
"visitor_code:#{@visitor_code}}" \
|
23
|
+
"cbs:#{@cbs}}"
|
23
24
|
end
|
24
25
|
|
25
26
|
def initialize(
|
26
27
|
previous_visit_amount: 1, current_visit: true, custom_data: true, page_views: false,
|
27
28
|
geolocation: false, device: false, browser: false, operating_system: false, conversions: false,
|
28
|
-
experiments: false, kcs: false, visitor_code: true
|
29
|
+
experiments: false, kcs: false, visitor_code: true, cbs: false
|
29
30
|
)
|
30
31
|
@previous_visit_amount = previous_visit_amount
|
31
32
|
@current_visit = current_visit
|
@@ -39,6 +40,7 @@ module Kameleoon
|
|
39
40
|
@experiments = experiments
|
40
41
|
@kcs = kcs
|
41
42
|
@visitor_code = visitor_code
|
43
|
+
@cbs = cbs
|
42
44
|
end
|
43
45
|
end
|
44
46
|
end
|
data/lib/kameleoon/utils.rb
CHANGED
@@ -77,17 +77,7 @@ module Kameleoon
|
|
77
77
|
def self.validate_top_level_domain(top_level_domain)
|
78
78
|
return nil if top_level_domain.nil? || top_level_domain.empty?
|
79
79
|
|
80
|
-
top_level_domain = top_level_domain.downcase
|
81
|
-
|
82
|
-
[HTTP, HTTPS].each do |protocol|
|
83
|
-
next unless top_level_domain.start_with?(protocol)
|
84
|
-
|
85
|
-
top_level_domain = top_level_domain[protocol.length..]
|
86
|
-
Logging::KameleoonLogger.warning(
|
87
|
-
"The top-level domain contains '%s'. Domain after protocol trimming: '%s'", protocol, top_level_domain
|
88
|
-
)
|
89
|
-
break
|
90
|
-
end
|
80
|
+
top_level_domain = check_and_trim_protocol(top_level_domain.downcase)
|
91
81
|
|
92
82
|
if !REGEX_DOMAIN.match?(top_level_domain) && top_level_domain != LOCALHOST
|
93
83
|
Logging::KameleoonLogger.error(
|
@@ -100,6 +90,41 @@ module Kameleoon
|
|
100
90
|
|
101
91
|
top_level_domain
|
102
92
|
end
|
93
|
+
|
94
|
+
def self.validate_network_domain(network_domain)
|
95
|
+
return nil if network_domain.nil? || network_domain.empty?
|
96
|
+
|
97
|
+
network_domain = check_and_trim_protocol(network_domain.downcase)
|
98
|
+
|
99
|
+
# remove first and last dot
|
100
|
+
network_domain = network_domain.gsub(/^\.+|\.+$/, '')
|
101
|
+
|
102
|
+
if !REGEX_DOMAIN.match?(network_domain) && network_domain != LOCALHOST
|
103
|
+
Logging::KameleoonLogger.error(
|
104
|
+
"The network domain '%s' is invalid.",
|
105
|
+
network_domain
|
106
|
+
)
|
107
|
+
return nil
|
108
|
+
end
|
109
|
+
|
110
|
+
network_domain
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def self.check_and_trim_protocol(domain)
|
116
|
+
[HTTP, HTTPS].each do |protocol|
|
117
|
+
next unless domain.start_with?(protocol)
|
118
|
+
|
119
|
+
domain = domain[protocol.length..]
|
120
|
+
Logging::KameleoonLogger.warning(
|
121
|
+
"The domain contains '%s'. Domain after protocol trimming: '%s'", protocol, domain
|
122
|
+
)
|
123
|
+
break
|
124
|
+
end
|
125
|
+
|
126
|
+
domain
|
127
|
+
end
|
103
128
|
end
|
104
129
|
end
|
105
130
|
end
|
data/lib/kameleoon/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kameleoon-client-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kameleoon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: em-http-request
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- lib/kameleoon/configuration/variation.rb
|
88
88
|
- lib/kameleoon/configuration/variation_exposition.rb
|
89
89
|
- lib/kameleoon/data/browser.rb
|
90
|
+
- lib/kameleoon/data/cbscores.rb
|
90
91
|
- lib/kameleoon/data/conversion.rb
|
91
92
|
- lib/kameleoon/data/cookie.rb
|
92
93
|
- lib/kameleoon/data/custom_data.rb
|