kameleoon-client-ruby 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3462fcc69d821034025ac9299b880f4e63ed5debca86aa85bcb5236b9658b0cb
4
- data.tar.gz: 0eaf3a74b42adfb6b561048e9934ebf529047ea5307551f795a630a855b19404
3
+ metadata.gz: 4f1490fd854e391fea3b908cad394e328a3540b6368942b72c1a9979c9002b87
4
+ data.tar.gz: 3abf894648cd3662a1a3a3453254014fa20c5405af28f6e01c8e336c810c6031
5
5
  SHA512:
6
- metadata.gz: 157327482deee68063a881afca8d8b576f854d1fff756d589f4021e1793c7e1966ddfdd9120c36df189e51522518e6fb678f523373ee1525abf4aa932599b906
7
- data.tar.gz: 8bfbf4b4917773954aba26163c3252a10f1890b49c047c46724c8e4eff4d1cdcefc64150ff801e4920d7ddb47479a4c5f3fc0c771299283a12af625f78b5de24
6
+ metadata.gz: 76f8eb07daaf102c292c9ed04a6d788dfcef4a7cf757875603a68d2a1272b8e543dbfabd89226a6f775cd71d243998b8b897e6339c616d0a87b03624054720e3
7
+ data.tar.gz: d8f94272a6afa522a6ea5c48e3c0f9b91fec6bd1b2382e0ff2a9a94cfbdfb3c23d9f278a5bf143d4161a05cff385ad335d278a5634e8f3a23f4f63373c6da281
@@ -6,16 +6,19 @@ module Kameleoon
6
6
  # KameleoonConfigurationSettings is used for saving setting's parameters, e.g
7
7
  # state of real time update for site code and etc
8
8
  class Settings
9
- attr_accessor :real_time_update, :is_consent_required
9
+ attr_accessor :real_time_update
10
+ attr_reader :is_consent_required, :data_api_domain
10
11
 
11
12
  def initialize
12
13
  @real_time_update = false
13
14
  @is_consent_required = false
15
+ @data_api_domain = nil
14
16
  end
15
17
 
16
18
  def update(configuration)
17
19
  @real_time_update = configuration['realTimeUpdate'] || false
18
20
  @is_consent_required = configuration['consentType'] == 'REQUIRED'
21
+ @data_api_domain = configuration['dataApiDomain']
19
22
  end
20
23
  end
21
24
  end
@@ -10,10 +10,12 @@ require 'kameleoon/data/manager/visitor_manager'
10
10
  require 'kameleoon/configuration/feature_flag'
11
11
  require 'kameleoon/configuration/variation'
12
12
  require 'kameleoon/configuration/data_file'
13
+ require 'kameleoon/network/access_token_source'
13
14
  require 'kameleoon/network/activity_event'
14
- require 'kameleoon/network/url_provider'
15
15
  require 'kameleoon/network/network_manager'
16
+ require 'kameleoon/network/url_provider'
16
17
  require 'kameleoon/network/cookie/cookie_manager'
18
+ require 'kameleoon/managers/warehouse/warehouse_manager'
17
19
  require 'kameleoon/real_time/real_time_configuration_service'
18
20
  require 'kameleoon/hybrid/manager'
19
21
  require 'kameleoon/storage/cache_factory'
@@ -50,9 +52,11 @@ module Kameleoon
50
52
  @network_manager = Network::NetworkManager.new(
51
53
  config.environment,
52
54
  config.default_timeout_millisecond,
53
- Network::UrlProvider.new(site_code, Network::UrlProvider::DEFAULT_DATA_API_URL),
55
+ Network::AccessTokenSourceFactory.new(config.client_id, config.client_secret, method(:log)),
56
+ Network::UrlProvider.new(site_code),
54
57
  method(:log)
55
58
  )
59
+ @warehouse_manager = Managers::Warehouse::WarehouseManager.new(@network_manager, @visitor_manager, method(:log))
56
60
  @cookie_manager = Network::Cookie::CookieManager.new(config.top_level_domain)
57
61
  @readiness = ClientReadiness.new
58
62
  end
@@ -264,7 +268,7 @@ module Kameleoon
264
268
  # way to quickly store massive amounts of data that can be later retrieved for each of your visitors / users.
265
269
  #
266
270
  # @param [String] key Key you want to retrieve data. This field is mandatory.
267
- # @param [Int] timeout Timeout for request (in milliseconds). Equals default_timeout in a config file.
271
+ # @param [Integer] timeout Timeout for request (in milliseconds). Equals default_timeout in a config file.
268
272
  # This field is optional.
269
273
  #
270
274
  # @return [Hash] Hash object of the json object.
@@ -282,7 +286,7 @@ module Kameleoon
282
286
  # This field is mandatory.
283
287
  # @param [Bool] add_data A boolean indicating whether the method should automatically add retrieved data
284
288
  # for a visitor. If not specified, the default value is `True`. This field is optional.
285
- # @param [Int] timeout Timeout for request (in milliseconds). Equals default_timeout in a config file.
289
+ # @param [Integer] timeout Timeout for request (in milliseconds). Equals default_timeout in a config file.
286
290
  # This field is optional.
287
291
  #
288
292
  # @return [Array] An array of data assigned to the given visitor.
@@ -293,6 +297,33 @@ module Kameleoon
293
297
  data_array
294
298
  end
295
299
 
300
+ ##
301
+ # Retrieves data associated with a visitor's warehouse audiences and adds it to the visitor.
302
+ # Retrieves all audience data associated with the visitor in your data warehouse using the specified
303
+ # `visitor_code` and `warehouse_key`. The `warehouse_key` is typically your internal user ID.
304
+ # The `custom_data_index` parameter corresponds to the Kameleoon custom data that Kameleoon uses to target your
305
+ # visitors. You can refer to the
306
+ # <a href="https://help.kameleoon.com/warehouse-audience-targeting/">warehouse targeting documentation</a>
307
+ # for additional details. The method returns a `CustomData` object, confirming
308
+ # that the data has been added to the visitor and is available for targeting purposes.
309
+ #
310
+ # @param [String] visitor_code A unique visitor identification string, can't exceed 255 characters length.
311
+ # This field is mandatory.
312
+ # @param [Integer] custom_data_index An integer representing the index of the custom data you want to use to target
313
+ # your BigQuery Audiences. This field is mandatory.
314
+ # @param [String] warehouse_key A key to identify the warehouse data, typically your internal user ID.
315
+ # This field is optional.
316
+ # @param [Integer] timeout Timeout for request (in milliseconds). Equals default_timeout in a config file.
317
+ # This field is optional.
318
+ #
319
+ # @raise [Kameleoon::Exception::VisitorCodeInvalid] If the visitor code is empty or longer than 255 chars.
320
+ # @raise [JSON::ParserError]
321
+ #
322
+ # @return [Kameleoon::CustomData] A `CustomData` instance confirming that the data has been added to the visitor.
323
+ def get_visitor_warehouse_audience(visitor_code, custom_data_index, timeout = nil, warehouse_key: nil)
324
+ @warehouse_manager.get_visitor_warehouse_audience(visitor_code, custom_data_index, warehouse_key, timeout)
325
+ end
326
+
296
327
  ##
297
328
  # Returns a list of all feature flag keys
298
329
  #
@@ -443,6 +474,7 @@ module Kameleoon
443
474
  @data_file = Configuration::DataFile.new(@config.environment).init(configuration)
444
475
  @cookie_manager.consent_required =
445
476
  @data_file.settings.is_consent_required && !@data_file.has_any_targeted_delivery_rule
477
+ @network_manager.url_provider.apply_data_api_domain(@data_file.settings.data_api_domain)
446
478
 
447
479
  call_update_handler_if_needed(!time_stamp.nil?)
448
480
  log "Feature flags are fetched: #{response.inspect}"
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kameleoon/data/custom_data'
4
+ require 'kameleoon/utils'
5
+
6
+ module Kameleoon
7
+ module Managers
8
+ module Warehouse
9
+ class WarehouseManager
10
+ WAREHOUSE_AUDIENCES_FIELD_NAME = 'warehouseAudiences'
11
+
12
+ def initialize(network_manager, visitor_manager, log_func = nil)
13
+ @network_manager = network_manager
14
+ @visitor_manager = visitor_manager
15
+ @log_func = log_func
16
+ end
17
+
18
+ def get_visitor_warehouse_audience(visitor_code, custom_data_index, warehouse_key = nil, timeout = nil)
19
+ Utils::VisitorCode.validate(visitor_code)
20
+ remote_data_key = warehouse_key.nil? || warehouse_key.empty? ? visitor_code : warehouse_key
21
+ response = @network_manager.get_remote_data(remote_data_key, timeout)
22
+ remote_data = response.is_a?(String) ? JSON.parse(response) : nil
23
+ warehouse_audiences = remote_data.is_a?(Hash) ? remote_data[WAREHOUSE_AUDIENCES_FIELD_NAME] : nil
24
+ data_values = warehouse_audiences.is_a?(Hash) ? warehouse_audiences.keys : []
25
+ warehouse_audiences_data = CustomData.new(custom_data_index, *data_values)
26
+ visitor = @visitor_manager.get_or_create_visitor(visitor_code)
27
+ visitor.add_data(@log_func, warehouse_audiences_data)
28
+ warehouse_audiences_data
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'net/http'
5
+ require 'time'
6
+
7
+ module Kameleoon
8
+ module Network
9
+ class AccessTokenSource
10
+ TOKEN_EXPIRATION_GAP = 60 # in seconds
11
+ TOKEN_OBSOLESCENCE_GAP = 1800 # in seconds
12
+ JWT_ACCESS_TOKEN_FIELD = 'access_token'
13
+ JWT_EXPIRES_IN_FIELD = 'expires_in'
14
+
15
+ def initialize(network_manager, client_id, client_secret, log_func)
16
+ @network_manager = network_manager
17
+ @client_id = client_id
18
+ @client_secret = client_secret
19
+ @fetching = false
20
+ @log_func = log_func
21
+ end
22
+
23
+ def get_token
24
+ now = Time.new.to_i
25
+ token = @cached_token
26
+ return fetch_token if token.nil? || token.expired?(now)
27
+
28
+ Thread.new { fetch_token } if !@fetching && token.obsolete?(now)
29
+ token.value
30
+ end
31
+
32
+ def discard_token(token)
33
+ @cached_token = nil if @cached_token&.value == token
34
+ end
35
+
36
+ private
37
+
38
+ def fetch_token
39
+ @fetching = true
40
+ response_content = @network_manager.fetch_access_jwtoken(@client_id, @client_secret)
41
+ unless response_content
42
+ @log_func&.call('Failed to fetch access JWT')
43
+ return nil
44
+ end
45
+ begin
46
+ jwt = JSON.parse(response_content)
47
+ token = jwt[JWT_ACCESS_TOKEN_FIELD]
48
+ expires_in = jwt[JWT_EXPIRES_IN_FIELD]
49
+ rescue JSON::ParserError => e
50
+ @log_func&.call("Failed to parse access JWT: #{e}")
51
+ return nil
52
+ end
53
+ unless token.is_a?(String) && !token.empty? && expires_in.is_a?(Integer) && expires_in.positive?
54
+ @log_func&.call('Failed to read access JWT')
55
+ return nil
56
+ end
57
+ handle_fetched_token(token, expires_in)
58
+ ensure
59
+ @fetching = false
60
+ end
61
+
62
+ def handle_fetched_token(token, expires_in)
63
+ now = Time.new.to_i
64
+ exp_time = now + expires_in - TOKEN_EXPIRATION_GAP
65
+ if expires_in > TOKEN_OBSOLESCENCE_GAP
66
+ obs_time = now + expires_in - TOKEN_OBSOLESCENCE_GAP
67
+ else
68
+ obs_time = exp_time
69
+ unless @log_func.nil?
70
+ issue = expires_in <= TOKEN_EXPIRATION_GAP ? 'cache the token' : 'refresh cached token in background'
71
+ @log_func.call("Access token life time (#{expires_in}s) is not long enough to #{issue}")
72
+ end
73
+ end
74
+ @cached_token = ExpiringToken.new(token, exp_time, obs_time)
75
+ token
76
+ end
77
+ end
78
+
79
+ class ExpiringToken
80
+ attr_reader :value, :expiration_time, :obsolescence_time
81
+
82
+ def initialize(value, expiration_time, obsolescence_time)
83
+ @value = value
84
+ @expiration_time = expiration_time
85
+ @obsolescence_time = obsolescence_time
86
+ end
87
+
88
+ def expired?(now)
89
+ now >= @expiration_time
90
+ end
91
+
92
+ def obsolete?(now)
93
+ now >= @obsolescence_time
94
+ end
95
+ end
96
+
97
+ class AccessTokenSourceFactory
98
+ def initialize(client_id, client_secret, log_func)
99
+ @client_id = client_id
100
+ @client_secret = client_secret
101
+ @log_func = log_func
102
+ end
103
+
104
+ def create(network_manager)
105
+ AccessTokenSource.new(network_manager, @client_id, @client_secret, @log_func)
106
+ end
107
+ end
108
+ end
109
+ end
@@ -8,7 +8,7 @@ require 'kameleoon/exceptions'
8
8
  module Kameleoon
9
9
  module Network
10
10
  class NetProvider
11
- def make_request(_request)
11
+ def make_request(request)
12
12
  raise KameleoonError, 'Call of not implemented method!'
13
13
  end
14
14
 
@@ -16,6 +16,7 @@ module Kameleoon
16
16
 
17
17
  def collect_headers(request)
18
18
  headers = request.extra_headers || {}
19
+ headers['Authorization'] = "Bearer #{request.access_token}" unless request.access_token.nil?
19
20
  headers['Content-Type'] = request.content_type
20
21
  headers['User-Agent'] = request.user_agent unless request.user_agent.nil?
21
22
  headers
@@ -29,30 +30,28 @@ module Kameleoon
29
30
  class SyncNetProvider < NetProvider
30
31
  def make_request(request)
31
32
  resp = nil
32
- begin
33
- case request.method
34
- when Method::GET
35
- req = Net::HTTP::Get.new(request.url)
36
- when Method::POST
37
- req = Net::HTTP::Post.new(request.url)
38
- req.body = request.data
39
- else
40
- return unknown_method_response(request.method, request)
41
- end
42
- timeout = request.timeout.to_f / 1000.0
43
- headers = collect_headers(request)
44
- headers.each { |k, v| req[k] = v }
45
- uri = URI(request.url)
46
- Net::HTTP.start(uri.hostname, uri.port, use_ssl: true, open_timeout: timeout,
47
- read_timeout: timeout, ssl_timeout: timeout) do |http|
48
- resp = http.request(req)
49
- end
50
- rescue => e
51
- return Response.new(e, nil, nil, request)
33
+ case request.method
34
+ when Method::GET
35
+ req = Net::HTTP::Get.new(request.url)
36
+ when Method::POST
37
+ req = Net::HTTP::Post.new(request.url)
38
+ req.body = request.data
39
+ else
40
+ return unknown_method_response(request.method, request)
41
+ end
42
+ timeout = request.timeout.to_f / 1000.0
43
+ headers = collect_headers(request)
44
+ headers.each { |k, v| req[k] = v }
45
+ uri = URI(request.url)
46
+ Net::HTTP.start(uri.hostname, uri.port, use_ssl: true, open_timeout: timeout,
47
+ read_timeout: timeout, ssl_timeout: timeout) do |http|
48
+ resp = http.request(req)
52
49
  end
53
50
  body = resp.body
54
51
  body = nil if body&.empty?
55
52
  Response.new(nil, resp.code.to_i, body, request)
53
+ rescue => e
54
+ Response.new(e, nil, nil, request)
56
55
  end
57
56
  end
58
57
  end
@@ -4,6 +4,7 @@ require 'kameleoon/network/content_type'
4
4
  require 'kameleoon/network/method'
5
5
  require 'kameleoon/network/request'
6
6
  require 'kameleoon/network/net_provider'
7
+ require 'kameleoon/network/uri_helper'
7
8
  require 'kameleoon/version'
8
9
 
9
10
  module Kameleoon
@@ -11,17 +12,19 @@ module Kameleoon
11
12
  ##
12
13
  # NetworkManager is used to make API calls.
13
14
  class NetworkManager
14
- FETCH_CONFIGURATION_ATTEMPT_NUMBER = 4
15
- TRACKING_CALL_ATTEMPT_NUMBER = 4
15
+ FETCH_CONFIGURATION_ATTEMPT_NUMBER = 3
16
+ TRACKING_CALL_ATTEMPT_NUMBER = 3
16
17
  TRACKING_CALL_RETRY_DELAY = 5.0 # in seconds
17
18
  SDK_TYPE_HEADER = 'X-Kameleoon-SDK-Type'
18
19
  SDK_VERSION_HEADER = 'X-Kameleoon-SDK-Version'
20
+ ACCESS_TOKEN_GRANT_TYPE = 'client_credentials'
19
21
 
20
- attr_reader :environment, :default_timeout, :url_provider
22
+ attr_reader :environment, :default_timeout, :access_token_source, :url_provider
21
23
 
22
- def initialize(environment, default_timeout, url_provider, log_func = nil)
24
+ def initialize(environment, default_timeout, access_token_source_factory, url_provider, log_func = nil)
23
25
  @environment = environment
24
26
  @default_timeout = default_timeout
27
+ @access_token_source = access_token_source_factory.create(self)
25
28
  @url_provider = url_provider
26
29
  @sync_net_provider = SyncNetProvider.new
27
30
  @log_func = log_func
@@ -32,31 +35,21 @@ module Kameleoon
32
35
  timeout = ensure_timeout(timeout)
33
36
  sdk_headers = { SDK_TYPE_HEADER => SDK_NAME, SDK_VERSION_HEADER => SDK_VERSION }
34
37
  request = Request.new(Method::GET, url, ContentType::JSON, timeout, extra_headers: sdk_headers)
35
- attempts_left = FETCH_CONFIGURATION_ATTEMPT_NUMBER
36
- while attempts_left.positive?
37
- response = @sync_net_provider.make_request(request)
38
- result = handle_response(response)
39
- return result if result
40
-
41
- attempts_left -= 1
42
- end
43
- false
38
+ make_call(request, false, FETCH_CONFIGURATION_ATTEMPT_NUMBER - 1)
44
39
  end
45
40
 
46
41
  def get_remote_data(key, timeout = nil)
47
42
  url = @url_provider.make_api_data_get_request_url(key)
48
43
  timeout = ensure_timeout(timeout)
49
44
  request = Request.new(Method::GET, url, ContentType::JSON, timeout)
50
- response = @sync_net_provider.make_request(request)
51
- handle_response(response)
45
+ make_call(request, true)
52
46
  end
53
47
 
54
48
  def get_remote_visitor_data(visitor_code, timeout = nil)
55
49
  url = @url_provider.make_visitor_data_get_url(visitor_code)
56
50
  timeout = ensure_timeout(timeout)
57
51
  request = Request.new(Method::GET, url, ContentType::JSON, timeout)
58
- response = @sync_net_provider.make_request(request)
59
- handle_response(response)
52
+ make_call(request, true)
60
53
  end
61
54
 
62
55
  def send_tracking_data(visitor_code, lines, user_agent, timeout = nil)
@@ -67,23 +60,55 @@ module Kameleoon
67
60
  data = (lines.map(&:obtain_full_post_text_line).join("\n") || '').encode('UTF-8')
68
61
  request = Request.new(Method::POST, url, ContentType::TEXT, timeout, user_agent: user_agent, data: data)
69
62
  Thread.new do
70
- attempts_left = TRACKING_CALL_ATTEMPT_NUMBER
71
- loop do
72
- response = @sync_net_provider.make_request(request)
73
- if handle_response(response) != false
74
- lines.each(&:mark_as_sent)
75
- break
76
- end
77
- attempts_left -= 1
78
- break unless attempts_left.positive?
79
-
80
- delay(TRACKING_CALL_RETRY_DELAY)
81
- end
63
+ result = make_call(request, true, TRACKING_CALL_ATTEMPT_NUMBER - 1, TRACKING_CALL_RETRY_DELAY)
64
+ lines.each(&:mark_as_sent) if result != false
82
65
  end
83
66
  end
84
67
 
68
+ def fetch_access_jwtoken(client_id, client_secret, timeout = nil)
69
+ url = @url_provider.make_access_token_url
70
+ timeout = ensure_timeout(timeout)
71
+ data_map = {
72
+ grant_type: ACCESS_TOKEN_GRANT_TYPE,
73
+ client_id: client_id,
74
+ client_secret: client_secret
75
+ }
76
+ data = UriHelper.encode_query(data_map).encode('UTF-8')
77
+ request = Request.new(Method::POST, url, ContentType::FORM, timeout, data: data)
78
+ make_call(request, false)
79
+ end
80
+
85
81
  private
86
82
 
83
+ def make_call(request, try_access_token_auth, retry_limit = 0, retry_delay = 0)
84
+ attempt = 0
85
+ success = false
86
+ while !success && (attempt <= retry_limit)
87
+ delay(retry_delay) if attempt.positive? && retry_delay.positive?
88
+ try_authorize(request) if try_access_token_auth
89
+ response = @sync_net_provider.make_request(request)
90
+ if !response.error.nil?
91
+ log_failure(response.request, "Error occurred during request: #{response.error}")
92
+ elsif response.code / 100 != 2
93
+ if ((response.code == 401) || (response.code == 403)) && response.request.access_token
94
+ @log_func&.call("Unexpected rejection of access token '#{response.request.access_token}'")
95
+ @access_token_source.discard_token(response.request.access_token)
96
+ if attempt == retry_limit
97
+ try_access_token_auth = false
98
+ retry_delay = 0
99
+ request.authorize(nil)
100
+ attempt -= 1
101
+ end
102
+ end
103
+ log_failure(response.request, "Received unexpected status code '#{response.code}'")
104
+ else
105
+ success = true
106
+ end
107
+ attempt += 1
108
+ end
109
+ success ? response.body : false
110
+ end
111
+
87
112
  def log_failure(request, message)
88
113
  return if @log_func.nil?
89
114
 
@@ -100,15 +125,11 @@ module Kameleoon
100
125
  timeout.nil? ? @default_timeout : timeout
101
126
  end
102
127
 
103
- def handle_response(response)
104
- if !response.error.nil?
105
- log_failure(response.request, "Error occurred during request: #{response.error}")
106
- elsif response.code / 100 != 2
107
- log_failure(response.request, "Received unexpected status code '#{response.code}'")
108
- else
109
- return response.body
110
- end
111
- false
128
+ def try_authorize(request)
129
+ token = @access_token_source.get_token
130
+ return if request.authorize(token)
131
+
132
+ @log_func&.call("Failed to authorize #{request.method} call '#{request.url}'")
112
133
  end
113
134
  end
114
135
  end
@@ -5,7 +5,7 @@ module Kameleoon
5
5
  ##
6
6
  # Request represents HTTP request.
7
7
  class Request
8
- attr_reader :method, :url, :content_type, :timeout, :user_agent, :extra_headers, :data
8
+ attr_reader :method, :url, :content_type, :timeout, :user_agent, :extra_headers, :data, :access_token
9
9
 
10
10
  def initialize(method, url, content_type, timeout, user_agent: nil, extra_headers: nil, data: nil)
11
11
  @method = method
@@ -16,6 +16,10 @@ module Kameleoon
16
16
  @extra_headers = extra_headers
17
17
  @data = !data.nil? && data.is_a?(String) ? data.encode('UTF-8') : data
18
18
  end
19
+
20
+ def authorize(access_token)
21
+ @access_token = access_token
22
+ end
19
23
  end
20
24
  end
21
25
  end
@@ -12,17 +12,29 @@ module Kameleoon
12
12
  VISITOR_DATA_PATH = '/visit/visitor'
13
13
  GET_DATA_PATH = '/map/map'
14
14
  POST_DATA_PATH = '/map/maps'
15
+ ACCESS_TOKEN_PATH = '/oauth/token'
16
+
15
17
  CONFIGURATION_API_URL_FORMAT = 'https://sdk-config.kameleoon.eu/%s'
16
18
  RT_CONFIGURATION_URL = 'https://events.kameleoon.com:8110/sse'
19
+ DEFAULT_DATA_API_DOMAIN = 'data.kameleoon.io'
20
+ TEST_DATA_API_DOMAIN = 'data.kameleoon.net'
21
+ DEFAULT_AUTOMATION_API_DOMAIN = 'api.kameleoon.com'
22
+ TEST_AUTOMATION_API_DOMAIN = 'api.kameleoon.net'
17
23
 
18
- DEFAULT_DATA_API_URL = 'https://data.kameleoon.io'
19
- TEST_DATA_API_URL = 'https://data.kameleoon.net'
20
-
21
- attr_reader :site_code, :data_api_url
24
+ attr_reader :site_code, :data_api_domain, :automation_api_domain
22
25
 
23
- def initialize(site_code, data_api_url)
26
+ def initialize(
27
+ site_code,
28
+ data_api_domain = DEFAULT_DATA_API_DOMAIN,
29
+ automation_api_domain = DEFAULT_AUTOMATION_API_DOMAIN
30
+ )
24
31
  @site_code = site_code
25
- @data_api_url = data_api_url
32
+ @data_api_domain = data_api_domain
33
+ @automation_api_domain = automation_api_domain
34
+ end
35
+
36
+ def apply_data_api_domain(domain)
37
+ @data_api_domain = domain if domain.is_a?(String)
26
38
  end
27
39
 
28
40
  def make_tracking_url(visitor_code)
@@ -32,7 +44,7 @@ module Kameleoon
32
44
  siteCode: @site_code,
33
45
  visitorCode: visitor_code
34
46
  }
35
- "#{@data_api_url}#{TRACKING_PATH}?#{UriHelper.encode_query(params)}"
47
+ "https://#{@data_api_domain}#{TRACKING_PATH}?#{UriHelper.encode_query(params)}"
36
48
  end
37
49
 
38
50
  def make_visitor_data_get_url(visitor_code)
@@ -44,7 +56,7 @@ module Kameleoon
44
56
  customData: true,
45
57
  version: 0
46
58
  }
47
- "#{@data_api_url}#{VISITOR_DATA_PATH}?#{UriHelper.encode_query(params)}"
59
+ "https://#{@data_api_domain}#{VISITOR_DATA_PATH}?#{UriHelper.encode_query(params)}"
48
60
  end
49
61
 
50
62
  def make_api_data_get_request_url(key)
@@ -52,7 +64,7 @@ module Kameleoon
52
64
  siteCode: @site_code,
53
65
  key: key
54
66
  }
55
- "#{@data_api_url}#{GET_DATA_PATH}?#{UriHelper.encode_query(params)}"
67
+ "https://#{@data_api_domain}#{GET_DATA_PATH}?#{UriHelper.encode_query(params)}"
56
68
  end
57
69
 
58
70
  def make_configuration_url(environment = nil, timestamp = nil)
@@ -68,6 +80,10 @@ module Kameleoon
68
80
  params = { siteCode: @site_code }
69
81
  "#{RT_CONFIGURATION_URL}?#{UriHelper.encode_query(params)}"
70
82
  end
83
+
84
+ def make_access_token_url
85
+ "https://#{@automation_api_domain}#{ACCESS_TOKEN_PATH}"
86
+ end
71
87
  end
72
88
  end
73
89
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'kameleoon/real_time/sse_message'
4
4
 
5
+ # TODO: Fix hanging (https://project.kameleoon.net/issues/26520)
6
+
5
7
  module Kameleoon
6
8
  module RealTime
7
9
  ##
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kameleoon
4
4
  SDK_NAME = 'RUBY'
5
- SDK_VERSION = '3.0.0'
5
+ SDK_VERSION = '3.1.0'
6
6
 
7
7
  # SdkManager is a helper method for fetching / obtaining version of SDK from string
8
8
  class SdkVersion
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.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kameleoon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-13 00:00:00.000000000 Z
11
+ date: 2024-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: em-http-request
@@ -101,6 +101,8 @@ files:
101
101
  - lib/kameleoon/kameleoon_client.rb
102
102
  - lib/kameleoon/kameleoon_client_config.rb
103
103
  - lib/kameleoon/kameleoon_client_factory.rb
104
+ - lib/kameleoon/managers/warehouse/warehouse_manager.rb
105
+ - lib/kameleoon/network/access_token_source.rb
104
106
  - lib/kameleoon/network/activity_event.rb
105
107
  - lib/kameleoon/network/content_type.rb
106
108
  - lib/kameleoon/network/cookie/cookie_manager.rb