kameleoon-client-ruby 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -3
- data/lib/kameleoon.rb +1 -1
- data/lib/kameleoon/client.rb +39 -27
- data/lib/kameleoon/exceptions.rb +7 -2
- data/lib/kameleoon/factory.rb +2 -2
- data/lib/kameleoon/request.rb +11 -1
- data/lib/kameleoon/version.rb +3 -0
- 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: 1acddc80101273c13cdf39b6cf2fb497716e947981dbffcf4d31540ea1f62edc
|
4
|
+
data.tar.gz: c00f33ed4eb494f7b1f2b4009005e84492ccad9cc366ac8fd34888c6aa63e2eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b4a67c7e0f8315aaeb2e46c15c2961840099a40a874d56c821bfc5407aa4f506ea732cf90cad13abb406e1c2f6d98bea62fb07a9b7bf427798ad27a15ef11e3
|
7
|
+
data.tar.gz: a62a96d1a772835c9e4db7ad8c968c302339dae2b9937204c37bbd2d8f22f23d6c76dae15b8f8577a0e692e1a181d27177635e64fba0f1b090290c870c0f9034
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ This is the repository for the Kameleoon Ruby SDK.
|
|
6
6
|
#### Prerequisite:
|
7
7
|
* [Install ruby](https://www.ruby-lang.org/en/documentation/installation)
|
8
8
|
|
9
|
-
#### Build and install:
|
9
|
+
#### Build and install the gem:
|
10
10
|
* Run `./buildAndInstallGem.sh`
|
11
11
|
|
12
12
|
### How to run tests
|
@@ -14,5 +14,9 @@ This is the repository for the Kameleoon Ruby SDK.
|
|
14
14
|
* Build and install Kameleoon Gem locally (infos above).
|
15
15
|
* Install rake: `gem install rake`
|
16
16
|
|
17
|
-
####
|
18
|
-
|
17
|
+
#### Run Tests:
|
18
|
+
##### Unit
|
19
|
+
* Run `./test.sh -u`
|
20
|
+
##### Integration
|
21
|
+
Make sure you kill manually the server test app after the tests are done.
|
22
|
+
* Run `./test.sh -i`
|
data/lib/kameleoon.rb
CHANGED
data/lib/kameleoon/client.rb
CHANGED
@@ -19,16 +19,17 @@ module Kameleoon
|
|
19
19
|
|
20
20
|
##
|
21
21
|
# You should create Client with the Client Factory only.
|
22
|
+
#
|
22
23
|
def initialize(site_code, path_config_file, blocking, interval, default_timeout, client_id = nil, client_secret = nil)
|
23
24
|
config = YAML.load_file(path_config_file)
|
24
25
|
@site_code = site_code
|
25
26
|
@blocking = blocking
|
26
|
-
@default_timeout = config['default_timeout'] || default_timeout
|
27
|
-
@interval = config['actions_configuration_refresh_interval'] || interval
|
27
|
+
@default_timeout = config['default_timeout'] || default_timeout # in ms
|
28
|
+
@interval = config['actions_configuration_refresh_interval'].to_s + 'm' || interval
|
28
29
|
@tracking_url = config['tracking_url'] || "https://api-ssx.kameleoon.com"
|
29
30
|
@client_id = client_id || config['client_id']
|
30
31
|
@client_secret = client_secret || config['client_secret']
|
31
|
-
@data_maximum_size = config['visitor_data_maximum_size'] || 500
|
32
|
+
@data_maximum_size = config['visitor_data_maximum_size'] || 500 # mb
|
32
33
|
@experiments = []
|
33
34
|
@feature_flags = []
|
34
35
|
@data = {}
|
@@ -37,7 +38,6 @@ module Kameleoon
|
|
37
38
|
##
|
38
39
|
# Obtain a visitor code.
|
39
40
|
#
|
40
|
-
#
|
41
41
|
# This method should be called to obtain the Kameleoon visitor_code for the current visitor.
|
42
42
|
# This is especially important when using Kameleoon in a mixed front-end and back-end environment,
|
43
43
|
# where user identification consistency must be guaranteed.
|
@@ -51,10 +51,9 @@ module Kameleoon
|
|
51
51
|
# In any case, the server-side (via HTTP header) kameleoonVisitorCode cookie is set with the value. Then this
|
52
52
|
# identifier value is finally returned by the method.
|
53
53
|
#
|
54
|
-
#
|
55
54
|
# @param [Hash] cookies Cookies of the request.
|
56
55
|
# @param [String] top_level_domain Top level domain of your website, settled while writing cookie.
|
57
|
-
# @param [String]
|
56
|
+
# @param [String] default_visitor_code - Optional - Define your default visitor_code (maximum length 100 chars).
|
58
57
|
#
|
59
58
|
# @return [String] visitor code
|
60
59
|
#
|
@@ -68,6 +67,7 @@ module Kameleoon
|
|
68
67
|
|
69
68
|
##
|
70
69
|
# Trigger an experiment.
|
70
|
+
#
|
71
71
|
# If such a visitor_code has never been associated with any variation, the SDK returns a randomly selected variation.
|
72
72
|
# If a user with a given visitor_code is already registered with a variation, it will detect the previously
|
73
73
|
# registered variation and return the variation_id.
|
@@ -77,20 +77,21 @@ module Kameleoon
|
|
77
77
|
# @param [String] visitor_code Visitor code
|
78
78
|
# @param [Integer] experiment_id Id of the experiment you want to trigger.
|
79
79
|
#
|
80
|
-
# @return [Integer]
|
80
|
+
# @return [Integer] Id of the variation
|
81
81
|
#
|
82
|
-
# @raise [Kameleoon::Exception::
|
82
|
+
# @raise [Kameleoon::Exception::ExperimentConfigurationNotFound] Raise when experiment configuration is not found
|
83
83
|
# @raise [Kameleoon::Exception::NotActivated] The visitor triggered the experiment, but did not activate it. Usually, this happens because the user has been associated with excluded traffic
|
84
84
|
# @raise [Kameleoon::Exception::NotTargeted] The visitor is not targeted by the experiment, as the associated targeting segment conditions were not fulfilled. He should see the reference variation
|
85
|
+
#
|
85
86
|
def trigger_experiment(visitor_code, experiment_id, timeout = @default_timeout)
|
86
87
|
experiment = @experiments.find { |experiment| experiment['id'].to_s == experiment_id.to_s }
|
87
88
|
if experiment.nil?
|
88
|
-
raise Exception::
|
89
|
+
raise Exception::ExperimentConfigurationNotFound.new(experiment_id)
|
89
90
|
end
|
90
91
|
if @blocking
|
91
92
|
variation_id = nil
|
92
93
|
EM.synchrony do
|
93
|
-
connexion_options = { :connect_timeout => timeout }
|
94
|
+
connexion_options = { :connect_timeout => (timeout.to_f / 1000.0) }
|
94
95
|
body = @data.values.flatten.select { |data| !data.sent }.map { |data| data.obtain_full_post_text_line }
|
95
96
|
.join("\n") || ""
|
96
97
|
path = get_experiment_register_url(visitor_code, experiment_id)
|
@@ -99,7 +100,7 @@ module Kameleoon
|
|
99
100
|
if is_successful(request)
|
100
101
|
variation_id = request.response
|
101
102
|
else
|
102
|
-
raise Exception::
|
103
|
+
raise Exception::ExperimentConfigurationNotFound.new(experiment_id) if variation_id.nil?
|
103
104
|
end
|
104
105
|
EM.stop
|
105
106
|
end
|
@@ -128,7 +129,9 @@ module Kameleoon
|
|
128
129
|
end
|
129
130
|
|
130
131
|
##
|
131
|
-
# Associate various data to a visitor.
|
132
|
+
# Associate various data to a visitor.
|
133
|
+
#
|
134
|
+
# Note that this method doesn't return any value and doesn't interact with the
|
132
135
|
# Kameleoon back-end servers by itself. Instead, the declared data is saved for future sending via the flush method.
|
133
136
|
# This reduces the number of server calls made, as data is usually grouped into a single server call triggered by
|
134
137
|
# the execution of the flush method.
|
@@ -151,13 +154,14 @@ module Kameleoon
|
|
151
154
|
|
152
155
|
##
|
153
156
|
# Track conversions on a particular goal
|
157
|
+
#
|
154
158
|
# This method requires visitor_code and goal_id to track conversion on this particular goal.
|
155
159
|
# In addition, this method also accepts revenue as a third optional argument to track revenue. The visitor_code usually is identical to the one that was used when triggering the experiment.
|
156
160
|
# The track_conversion method doesn't return any value. This method is non-blocking as the server call is made asynchronously.
|
157
161
|
#
|
158
162
|
# @param [String] visitor_code Visitor code
|
159
163
|
# @param [Integer] goal_id Id of the goal
|
160
|
-
# @param [Float] revenue Revenue of the conversion.
|
164
|
+
# @param [Float] revenue Optional - Revenue of the conversion.
|
161
165
|
#
|
162
166
|
def track_conversion(visitor_code, goal_id, revenue = 0.0)
|
163
167
|
add_data(visitor_code, Conversion.new(goal_id, revenue))
|
@@ -166,6 +170,7 @@ module Kameleoon
|
|
166
170
|
|
167
171
|
##
|
168
172
|
# Flush the associated data.
|
173
|
+
#
|
169
174
|
# The data added with the method add_data, is not directly sent to the kameleoon servers.
|
170
175
|
# It's stored and accumulated until it is sent automatically by the trigger_experiment or track_conversion methods.
|
171
176
|
# With this method you can manually send it.
|
@@ -178,6 +183,7 @@ module Kameleoon
|
|
178
183
|
|
179
184
|
##
|
180
185
|
# Obtain variation associated data.
|
186
|
+
#
|
181
187
|
# To retrieve JSON data associated with a variation, call the obtain_variation_associated_data method of our SDK.
|
182
188
|
# The JSON data usually represents some metadata of the variation, and can be configured on our web application
|
183
189
|
# interface or via our Automation API.
|
@@ -186,20 +192,21 @@ module Kameleoon
|
|
186
192
|
#
|
187
193
|
# @param [Integer] variation_id
|
188
194
|
#
|
189
|
-
# @return [
|
195
|
+
# @return [Hash] Hash object of the json object.
|
190
196
|
#
|
191
197
|
# @raise [Kameleoon::Exception::VariationNotFound] Raise exception if the variation is not found.
|
198
|
+
#
|
192
199
|
def obtain_variation_associated_data(variation_id)
|
193
200
|
variation = @experiments.map { |experiment| experiment['variations'] }.flatten.select { |variation| variation['id'].to_i == variation_id.to_i }.first
|
194
201
|
if variation.nil?
|
195
202
|
raise Exception::VariationNotFound.new(variation_id)
|
196
203
|
else
|
197
|
-
variation['customJson']
|
204
|
+
variation['customJson']
|
198
205
|
end
|
199
206
|
end
|
200
207
|
|
201
208
|
#
|
202
|
-
#
|
209
|
+
# Activate a feature toggle.
|
203
210
|
#
|
204
211
|
# This method takes a visitor_code and feature_key (or feature_id) as mandatory arguments to check if the specified feature will be active for a given user.
|
205
212
|
# If such a user has never been associated with this feature flag, the SDK returns a boolean value randomly (true if the user should have this feature or false if not). If a user with a given visitorCode is already registered with this feature flag, it will detect the previous featureFlag value.
|
@@ -208,15 +215,16 @@ module Kameleoon
|
|
208
215
|
# @param [String] visitor_code
|
209
216
|
# @param [String | Integer] feature_key
|
210
217
|
#
|
211
|
-
# @raise [Kameleoon::Exception::
|
218
|
+
# @raise [Kameleoon::Exception::FeatureConfigurationNotFound]
|
212
219
|
# @raise [Kameleoon::Exception::NotTargeted]
|
220
|
+
#
|
213
221
|
def activate_feature(visitor_code, feature_key, timeout = @default_timeout)
|
214
222
|
feature_flag = get_feature_flag(feature_key)
|
215
223
|
id = feature_flag['id']
|
216
224
|
if @blocking
|
217
225
|
result = nil
|
218
226
|
EM.synchrony do
|
219
|
-
connexion_options = { :connect_timeout => timeout }
|
227
|
+
connexion_options = { :connect_timeout => (timeout.to_f / 1000.0) }
|
220
228
|
request_options = {
|
221
229
|
:path => get_experiment_register_url(visitor_code, id),
|
222
230
|
:body => (select_data_to_sent(visitor_code).values.map { |data| data.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8")
|
@@ -227,7 +235,7 @@ module Kameleoon
|
|
227
235
|
end
|
228
236
|
EM.stop
|
229
237
|
end
|
230
|
-
raise Exception::
|
238
|
+
raise Exception::FeatureConfigurationNotFound.new(id) if result.nil?
|
231
239
|
result.to_s != "null"
|
232
240
|
|
233
241
|
else
|
@@ -248,17 +256,21 @@ module Kameleoon
|
|
248
256
|
end
|
249
257
|
|
250
258
|
##
|
251
|
-
#
|
259
|
+
# Retrieve a feature variable.
|
260
|
+
#
|
261
|
+
# A feature variable can be changed easily via our web application.
|
252
262
|
#
|
253
263
|
# @param [String | Integer] feature_key
|
254
264
|
# @param [String ] variable_key
|
255
265
|
#
|
256
|
-
# @raise [Kameleoon::Exception::
|
266
|
+
# @raise [Kameleoon::Exception::FeatureConfigurationNotFound]
|
267
|
+
# @raise [Kameleoon::Exception::FeatureVariableNotFound]
|
268
|
+
#
|
257
269
|
def obtain_feature_variable(feature_key, variable_key)
|
258
270
|
feature_flag = get_feature_flag(feature_key)
|
259
271
|
custom_json = feature_flag["variations"].first['customJson'][variable_key.to_s]
|
260
272
|
if custom_json.nil?
|
261
|
-
raise Exception::
|
273
|
+
raise Exception::FeatureVariableNotFound.new("Feature variable not found")
|
262
274
|
end
|
263
275
|
case custom_json['type']
|
264
276
|
when "Boolean"
|
@@ -268,9 +280,9 @@ module Kameleoon
|
|
268
280
|
when "Number"
|
269
281
|
return custom_json['value'].to_f
|
270
282
|
when "Json"
|
271
|
-
return custom_json['value']
|
283
|
+
return custom_json['value']
|
272
284
|
else
|
273
|
-
raise
|
285
|
+
raise TypeError.new("Unknown type for feature variable")
|
274
286
|
end
|
275
287
|
end
|
276
288
|
|
@@ -300,8 +312,8 @@ module Kameleoon
|
|
300
312
|
@feature_flags ||= []
|
301
313
|
else
|
302
314
|
site_id = site.first['id']
|
303
|
-
@experiments = obtain_tests(site_id)
|
304
|
-
@feature_flags = obtain_feature_flags(site_id)
|
315
|
+
@experiments = obtain_tests(site_id) || @experiments
|
316
|
+
@feature_flags = obtain_feature_flags(site_id) || @feature_flags
|
305
317
|
end
|
306
318
|
EM.stop
|
307
319
|
end
|
@@ -446,7 +458,7 @@ module Kameleoon
|
|
446
458
|
raise TypeError.new("Feature key should be a String or an Integer.")
|
447
459
|
end
|
448
460
|
if feature_flag.nil?
|
449
|
-
raise Exception::
|
461
|
+
raise Exception::FeatureConfigurationNotFound.new(feature_key)
|
450
462
|
end
|
451
463
|
feature_flag
|
452
464
|
end
|
data/lib/kameleoon/exceptions.rb
CHANGED
@@ -15,16 +15,21 @@ module Kameleoon
|
|
15
15
|
super("Variation " + id.to_s)
|
16
16
|
end
|
17
17
|
end
|
18
|
-
class
|
18
|
+
class ExperimentConfigurationNotFound < NotFound
|
19
19
|
def initialize(id = "")
|
20
20
|
super("Experiment " + id.to_s)
|
21
21
|
end
|
22
22
|
end
|
23
|
-
class
|
23
|
+
class FeatureConfigurationNotFound < NotFound
|
24
24
|
def initialize(id = "")
|
25
25
|
super("Feature flag " + id.to_s)
|
26
26
|
end
|
27
27
|
end
|
28
|
+
class FeatureVariableNotFound < NotFound
|
29
|
+
def initialize(key = "")
|
30
|
+
super("Feature variable " + key.to_s)
|
31
|
+
end
|
32
|
+
end
|
28
33
|
class CredentialsNotFound < NotFound
|
29
34
|
def initialize
|
30
35
|
super("Credentials")
|
data/lib/kameleoon/factory.rb
CHANGED
@@ -2,9 +2,9 @@ require 'kameleoon/client'
|
|
2
2
|
|
3
3
|
module Kameleoon
|
4
4
|
module ClientFactory
|
5
|
-
CONFIGURATION_UPDATE_INTERVAL=
|
5
|
+
CONFIGURATION_UPDATE_INTERVAL = '60m'
|
6
6
|
CONFIG_PATH = "/etc/kameleoon/client-ruby.yaml"
|
7
|
-
DEFAULT_TIMEOUT =
|
7
|
+
DEFAULT_TIMEOUT = 2000 #milli-seconds
|
8
8
|
|
9
9
|
##
|
10
10
|
# Create a kameleoon client object, each call create a new client.
|
data/lib/kameleoon/request.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "em-synchrony/em-http"
|
2
|
+
require "kameleoon/version"
|
2
3
|
|
3
4
|
module Kameleoon
|
4
5
|
# @api private
|
@@ -22,7 +23,8 @@ module Kameleoon
|
|
22
23
|
private
|
23
24
|
|
24
25
|
def request(method, request_options, url, connexion_options)
|
25
|
-
|
26
|
+
#connexion_options[:tls] = {verify_peer: true}
|
27
|
+
add_user_agent(request_options)
|
26
28
|
case method
|
27
29
|
when Method::POST then
|
28
30
|
return EventMachine::HttpRequest.new(url, connexion_options).apost request_options
|
@@ -37,6 +39,14 @@ module Kameleoon
|
|
37
39
|
def is_successful(request)
|
38
40
|
!request.nil? && request != false && /20\d/.match(request.response_header.status.to_s)
|
39
41
|
end
|
42
|
+
|
43
|
+
def add_user_agent(request_options)
|
44
|
+
if request_options[:head].nil?
|
45
|
+
request_options[:head] = {'User-Agent' => 'kameleoon-client-ruby/' + Kameleoon::VERSION}
|
46
|
+
else
|
47
|
+
request_options[:head].store('User-Agent', 'kameleoon-client-ruby/' + Kameleoon::VERSION)
|
48
|
+
end
|
49
|
+
end
|
40
50
|
end
|
41
51
|
end
|
42
52
|
|
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: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kameleoon - Guillaume Grandjean
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-04-
|
11
|
+
date: 2021-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: em-http-request
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- lib/kameleoon/targeting/models.rb
|
74
74
|
- lib/kameleoon/targeting/tree_builder.rb
|
75
75
|
- lib/kameleoon/utils.rb
|
76
|
+
- lib/kameleoon/version.rb
|
76
77
|
homepage: https://developers.kameleoon.com/ruby-sdk.html
|
77
78
|
licenses:
|
78
79
|
- GPL-3.0
|