kameleoon-client-ruby 3.14.0 → 3.15.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/configuration/data_file.rb +13 -11
- data/lib/kameleoon/data/data.rb +1 -0
- data/lib/kameleoon/data/manager/visitor.rb +23 -1
- data/lib/kameleoon/data/targeted_segment.rb +30 -0
- data/lib/kameleoon/kameleoon_client.rb +24 -3
- data/lib/kameleoon/targeting/conditions/segment_condition.rb +3 -3
- data/lib/kameleoon/targeting/models.rb +3 -2
- data/lib/kameleoon/targeting/targeting_manager.rb +12 -16
- 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: 07240065fc16f98169c01fd4367321b2f633d79373f293b0bcf110f68d920d46
|
4
|
+
data.tar.gz: 52b83806f28aa0035eb8df2db89f84b98b774e2a53b0fd8a7c5abd71b0a59ac4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88e8da4ec50eca784dd49b5861f373d84e60eaa521894d095104c10d6d469cb8e20d4fbf98416a473790fe77842411e4021beed153a4a4bb784603b90360abd0
|
7
|
+
data.tar.gz: 9068a2d4b8dfaff1020933c9e38e133965486ef0ddc722db19dd7eeee28a0327926d4d3beb1b17460615da176620699a2f7dcc5ada1dc63db4e6696aaa080131
|
@@ -11,9 +11,9 @@ require 'kameleoon/targeting/models'
|
|
11
11
|
module Kameleoon
|
12
12
|
module Configuration
|
13
13
|
class DataFile
|
14
|
-
attr_reader :last_modified, :settings, :
|
15
|
-
:
|
16
|
-
:experiment_ids_with_js_css_variable, :holdout
|
14
|
+
attr_reader :last_modified, :settings, :segments, :audience_tracking_segments, :feature_flags, :me_groups,
|
15
|
+
:has_any_targeted_delivery_rule, :feature_flag_by_id, :rule_info_by_exp_id, :variation_by_id,
|
16
|
+
:custom_data_info, :experiment_ids_with_js_css_variable, :holdout
|
17
17
|
|
18
18
|
def to_s
|
19
19
|
'DataFile{' \
|
@@ -70,9 +70,9 @@ module Kameleoon
|
|
70
70
|
def init(configuration)
|
71
71
|
Logging::KameleoonLogger.debug('CALL: DataFile.init(configuration: %s)', configuration)
|
72
72
|
@settings = Settings.new(configuration['configuration'])
|
73
|
-
segments = parse_segments(configuration)
|
73
|
+
@segments, @audience_tracking_segments = parse_segments(configuration)
|
74
74
|
@custom_data_info = CustomDataInfo.new(configuration['customData'])
|
75
|
-
@feature_flags = parse_feature_flags(configuration,
|
75
|
+
@feature_flags = parse_feature_flags(configuration, @custom_data_info)
|
76
76
|
@me_groups = make_me_groups(@feature_flags)
|
77
77
|
@has_any_targeted_delivery_rule = any_targeted_delivery_rule?
|
78
78
|
@holdout = Experiment.from_json(configuration['holdout']) if configuration.include?('holdout')
|
@@ -80,15 +80,20 @@ module Kameleoon
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def parse_segments(configuration)
|
83
|
-
|
83
|
+
audience_tracking_segments = []
|
84
|
+
segments = configuration['segments'].to_h do |raw_seg|
|
84
85
|
seg = Targeting::Segment.new(raw_seg)
|
86
|
+
audience_tracking_segments.push(seg) if seg.audience_tracking
|
85
87
|
[seg.id, seg]
|
86
88
|
end
|
89
|
+
segments.freeze
|
90
|
+
audience_tracking_segments.freeze
|
91
|
+
[segments, audience_tracking_segments]
|
87
92
|
end
|
88
93
|
|
89
|
-
def parse_feature_flags(configuration,
|
94
|
+
def parse_feature_flags(configuration, cdi)
|
90
95
|
configuration['featureFlags'].to_h do |raw_ff|
|
91
|
-
ff = FeatureFlag.new(raw_ff, segments, cdi)
|
96
|
+
ff = FeatureFlag.new(raw_ff, @segments, cdi)
|
92
97
|
[ff.feature_key, ff]
|
93
98
|
end
|
94
99
|
end
|
@@ -99,7 +104,6 @@ module Kameleoon
|
|
99
104
|
|
100
105
|
def collect_indices
|
101
106
|
@feature_flag_by_id = {}
|
102
|
-
@rule_by_segment_id = {}
|
103
107
|
@rule_info_by_exp_id = {}
|
104
108
|
@variation_by_id = {}
|
105
109
|
@experiment_ids_with_js_css_variable = Set.new
|
@@ -110,7 +114,6 @@ module Kameleoon
|
|
110
114
|
|
111
115
|
has_feature_flag_variable_js_css = feature_flag_variable_js_css?(feature_flag)
|
112
116
|
feature_flag.rules.each do |rule|
|
113
|
-
@rule_by_segment_id[rule.segment_id] = rule
|
114
117
|
@rule_info_by_exp_id[rule.experiment.id] = RuleInfo.new(feature_flag, rule)
|
115
118
|
rule.experiment.variations_by_exposition.each do |variation|
|
116
119
|
@variation_by_id[variation.variation_id] = variation
|
@@ -119,7 +122,6 @@ module Kameleoon
|
|
119
122
|
end
|
120
123
|
end
|
121
124
|
@feature_flag_by_id.freeze
|
122
|
-
@rule_by_segment_id.freeze
|
123
125
|
@variation_by_id.freeze
|
124
126
|
@experiment_ids_with_js_css_variable.freeze
|
125
127
|
end
|
data/lib/kameleoon/data/data.rb
CHANGED
@@ -10,6 +10,7 @@ require 'kameleoon/data/device'
|
|
10
10
|
require 'kameleoon/data/kcs_heat'
|
11
11
|
require 'kameleoon/data/page_view'
|
12
12
|
require 'kameleoon/data/personalization'
|
13
|
+
require 'kameleoon/data/targeted_segment'
|
13
14
|
require 'kameleoon/data/unique_identifier'
|
14
15
|
require 'kameleoon/data/user_agent'
|
15
16
|
require 'kameleoon/data/manager/assigned_variation'
|
@@ -186,6 +187,14 @@ module Kameleoon
|
|
186
187
|
personalizations
|
187
188
|
end
|
188
189
|
|
190
|
+
def targeted_segments
|
191
|
+
targeted_segments = @data.targeted_segments
|
192
|
+
Logging::KameleoonLogger.debug(
|
193
|
+
'CALL/RETURN: Visitor.targeted_segments -> (targeted_segments: %s)', targeted_segments
|
194
|
+
)
|
195
|
+
targeted_segments
|
196
|
+
end
|
197
|
+
|
189
198
|
def get_forced_feature_variation(feature_key)
|
190
199
|
Logging::KameleoonLogger.debug("CALL: Visitor.get_forced_feature_variation(feature_key: '%s')", feature_key)
|
191
200
|
variation = @data.get_from_map(@data.simulated_variations, feature_key)
|
@@ -241,6 +250,8 @@ module Kameleoon
|
|
241
250
|
@data.add_variation(data, overwrite)
|
242
251
|
when Personalization
|
243
252
|
@data.add_personalization(data, overwrite)
|
253
|
+
when TargetedSegment
|
254
|
+
@data.add_targeted_segment(data)
|
244
255
|
when ForcedFeatureVariation
|
245
256
|
@data.add_forced_feature_variation(data)
|
246
257
|
when ForcedExperimentVariation
|
@@ -329,6 +340,7 @@ module Kameleoon
|
|
329
340
|
@custom_data_map&.each { |_, cd| blk.call(cd) }
|
330
341
|
@page_view_visits&.each { |_, pvv| blk.call(pvv.page_view) }
|
331
342
|
@variations&.each { |_, av| blk.call(av) }
|
343
|
+
@targeted_segments&.each { |_, ts| blk.call(ts) }
|
332
344
|
@conversions&.each { |c| blk.call(c) }
|
333
345
|
end
|
334
346
|
end
|
@@ -344,8 +356,9 @@ module Kameleoon
|
|
344
356
|
count += 1 unless @visitor_visits.nil?
|
345
357
|
count += @custom_data_map.size unless @custom_data_map.nil?
|
346
358
|
count += @page_view_visits.size unless @page_view_visits.nil?
|
347
|
-
count += @conversions.size unless @conversions.nil?
|
348
359
|
count += @variations.size unless @variations.nil?
|
360
|
+
count += @targeted_segments.size unless @targeted_segments.nil?
|
361
|
+
count += @conversions.size unless @conversions.nil?
|
349
362
|
end
|
350
363
|
Logging::KameleoonLogger.debug('RETURN: VisitorData.count_sendable_data -> (count: %s)', count)
|
351
364
|
count
|
@@ -371,6 +384,10 @@ module Kameleoon
|
|
371
384
|
DataMapStorage.new(@mutex, @personalizations)
|
372
385
|
end
|
373
386
|
|
387
|
+
def targeted_segments
|
388
|
+
DataMapStorage.new(@mutex, @targeted_segments)
|
389
|
+
end
|
390
|
+
|
374
391
|
def set_device(device, overwrite)
|
375
392
|
@device = device if overwrite || @device.nil?
|
376
393
|
end
|
@@ -389,6 +406,11 @@ module Kameleoon
|
|
389
406
|
end
|
390
407
|
end
|
391
408
|
|
409
|
+
def add_targeted_segment(targeted_segment)
|
410
|
+
@targeted_segments ||= {}
|
411
|
+
@targeted_segments[targeted_segment.id] = targeted_segment
|
412
|
+
end
|
413
|
+
|
392
414
|
def set_browser(browser, overwrite)
|
393
415
|
@browser = browser if overwrite || @browser.nil?
|
394
416
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kameleoon/data/data'
|
4
|
+
require 'kameleoon/network/uri_helper'
|
5
|
+
|
6
|
+
module Kameleoon
|
7
|
+
class TargetedSegment < DuplicationUnsafeData
|
8
|
+
EVENT_TYPE = 'targetingSegment'
|
9
|
+
|
10
|
+
attr_reader :id
|
11
|
+
|
12
|
+
def initialize(id)
|
13
|
+
super(DataType::TARGETED_SEGMENT)
|
14
|
+
@id = id
|
15
|
+
end
|
16
|
+
|
17
|
+
def obtain_full_post_text_line
|
18
|
+
params = {
|
19
|
+
eventType: EVENT_TYPE,
|
20
|
+
id: @id,
|
21
|
+
nonce: nonce
|
22
|
+
}
|
23
|
+
Network::UriHelper.encode_query(params)
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
"TargetedSegment{id:#{@id}}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -758,6 +758,27 @@ module Kameleoon
|
|
758
758
|
)
|
759
759
|
end
|
760
760
|
|
761
|
+
##
|
762
|
+
# Evaluates the visitor against all available Audiences Explorer segments and tracks those that match.
|
763
|
+
# A detailed analysis of segment performance can then be performed directly in Audiences Explorer.
|
764
|
+
#
|
765
|
+
# @param [String] visitor_code The unique visitor code identifying the visitor.
|
766
|
+
#
|
767
|
+
# @raise [Kameleoon::Exception::VisitorCodeInvalid] The provided **visitor code** is invalid.
|
768
|
+
def evaluate_audiences(visitor_code)
|
769
|
+
Logging::KameleoonLogger.info("CALL: KameleoonClient.evaluate_audiences(visitor_code: '%s')", visitor_code)
|
770
|
+
Utils::VisitorCode.validate(visitor_code)
|
771
|
+
segments = @data_manager.data_file.audience_tracking_segments.select do |seg|
|
772
|
+
check_targeting(visitor_code, nil, seg)
|
773
|
+
end
|
774
|
+
unless segments.empty?
|
775
|
+
segments.map! { |seg| TargetedSegment.new(seg.id) }
|
776
|
+
@visitor_manager.add_data(visitor_code, *segments)
|
777
|
+
end
|
778
|
+
@tracking_manager.add_visitor_code(visitor_code)
|
779
|
+
Logging::KameleoonLogger.info("RETURN: KameleoonClient.evaluate_audiences(visitor_code: '%s')", visitor_code)
|
780
|
+
end
|
781
|
+
|
761
782
|
private
|
762
783
|
|
763
784
|
HYBRID_EXPIRATION_TIME = 5
|
@@ -904,8 +925,8 @@ module Kameleoon
|
|
904
925
|
# nil
|
905
926
|
# end
|
906
927
|
|
907
|
-
def check_targeting(visitor_code, campaign_id,
|
908
|
-
@targeting_manager.check_targeting(visitor_code, campaign_id,
|
928
|
+
def check_targeting(visitor_code, campaign_id, segment)
|
929
|
+
@targeting_manager.check_targeting(visitor_code, campaign_id, segment)
|
909
930
|
end
|
910
931
|
|
911
932
|
def get_variation_info(visitor_code, feature_flag, track)
|
@@ -1106,7 +1127,7 @@ module Kameleoon
|
|
1106
1127
|
break
|
1107
1128
|
end
|
1108
1129
|
# check if visitor is targeted for rule, else next rule
|
1109
|
-
next unless check_targeting(visitor_code, rule.experiment.id, rule)
|
1130
|
+
next unless check_targeting(visitor_code, rule.experiment.id, rule.targeting_segment)
|
1110
1131
|
|
1111
1132
|
unless forced_variation.nil?
|
1112
1133
|
# Forcing experiment variation in targeting-only mode
|
@@ -19,10 +19,10 @@ module Kameleoon
|
|
19
19
|
private
|
20
20
|
|
21
21
|
def check_targeting(segment_info)
|
22
|
-
|
23
|
-
return false
|
22
|
+
segment = segment_info.data_file.segments[@segment_id]
|
23
|
+
return false if segment.nil?
|
24
24
|
|
25
|
-
|
25
|
+
segment.check_tree(->(type) { segment_info.condition_data(type) })
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -8,10 +8,10 @@ module Kameleoon
|
|
8
8
|
module Targeting
|
9
9
|
class Segment
|
10
10
|
include TreeBuilder
|
11
|
-
attr_accessor :id, :tree
|
11
|
+
attr_accessor :id, :tree, :audience_tracking
|
12
12
|
|
13
13
|
def to_s
|
14
|
-
@
|
14
|
+
"Segment{id:#{@id},audience_tracking:#{@audience_tracking}}"
|
15
15
|
end
|
16
16
|
|
17
17
|
def initialize(*args)
|
@@ -28,6 +28,7 @@ module Kameleoon
|
|
28
28
|
if hash['conditionsData'].nil?
|
29
29
|
raise Kameleoon::Exception::NotFound.new(hash['conditionsData']), 'hash[\'conditionsData\']'
|
30
30
|
end
|
31
|
+
@audience_tracking = hash['audienceTracking'] || false
|
31
32
|
@tree = create_tree(hash['conditionsData'])
|
32
33
|
elsif args.length == 2
|
33
34
|
@id = args[0]
|
@@ -19,25 +19,19 @@ module Kameleoon
|
|
19
19
|
@visitor_manager = visitor_manager
|
20
20
|
end
|
21
21
|
|
22
|
-
def check_targeting(visitor_code, campaign_id,
|
22
|
+
def check_targeting(visitor_code, campaign_id, segment)
|
23
23
|
Logging::KameleoonLogger.debug(
|
24
|
-
"CALL: TargetingManager.check_targeting(visitor_code: '%s', campaign_id: %s,
|
25
|
-
visitor_code, campaign_id,
|
24
|
+
"CALL: TargetingManager.check_targeting(visitor_code: '%s', campaign_id: %s, segment: %s)",
|
25
|
+
visitor_code, campaign_id, segment
|
26
26
|
)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
'(targeting: true)', visitor_code, campaign_id, exp_ff_rule
|
32
|
-
)
|
33
|
-
return true
|
27
|
+
targeting = true
|
28
|
+
unless segment.nil?
|
29
|
+
visitor = @visitor_manager.get_visitor(visitor_code)
|
30
|
+
targeting = segment.check_tree(->(type) { get_condition_data(type, visitor, visitor_code, campaign_id) })
|
34
31
|
end
|
35
|
-
|
36
|
-
visitor = @visitor_manager.get_visitor(visitor_code)
|
37
|
-
targeting = segment.check_tree(->(type) { get_condition_data(type, visitor, visitor_code, campaign_id) })
|
38
32
|
Logging::KameleoonLogger.debug(
|
39
|
-
"RETURN: TargetingManager.check_targeting(visitor_code: '%s', campaign_id: %s,
|
40
|
-
'(targeting: %s)', visitor_code, campaign_id,
|
33
|
+
"RETURN: TargetingManager.check_targeting(visitor_code: '%s', campaign_id: %s, segment: %s) -> " \
|
34
|
+
'(targeting: %s)', visitor_code, campaign_id, segment, targeting
|
41
35
|
)
|
42
36
|
targeting
|
43
37
|
end
|
@@ -86,7 +80,9 @@ module Kameleoon
|
|
86
80
|
when ConditionType::TARGET_PERSONALIZATION
|
87
81
|
condition_data = TargetPersonalizationInfo.new(visitor&.personalizations)
|
88
82
|
when ConditionType::EXCLUSIVE_EXPERIMENT
|
89
|
-
|
83
|
+
unless campaign_id.nil?
|
84
|
+
condition_data = ExclusiveExperimentInfo.new(campaign_id, visitor&.variations, visitor&.personalizations)
|
85
|
+
end
|
90
86
|
when ConditionType::FIRST_VISIT,
|
91
87
|
ConditionType::LAST_VISIT,
|
92
88
|
ConditionType::VISITS,
|
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.15.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-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: em-http-request
|
@@ -108,6 +108,7 @@ files:
|
|
108
108
|
- lib/kameleoon/data/operating_system.rb
|
109
109
|
- lib/kameleoon/data/page_view.rb
|
110
110
|
- lib/kameleoon/data/personalization.rb
|
111
|
+
- lib/kameleoon/data/targeted_segment.rb
|
111
112
|
- lib/kameleoon/data/unique_identifier.rb
|
112
113
|
- lib/kameleoon/data/user_agent.rb
|
113
114
|
- lib/kameleoon/data/visitor_visits.rb
|