kameleoon-client-ruby 3.0.0 → 3.1.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 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