kameleoon-client-ruby 2.0.0 → 2.1.1

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/kameleoon/client.rb +277 -260
  3. data/lib/kameleoon/configuration/feature_flag.rb +13 -24
  4. data/lib/kameleoon/configuration/rule.rb +17 -5
  5. data/lib/kameleoon/configuration/settings.rb +20 -0
  6. data/lib/kameleoon/cookie.rb +3 -3
  7. data/lib/kameleoon/data/browser.rb +33 -0
  8. data/lib/kameleoon/data/conversion.rb +26 -0
  9. data/lib/kameleoon/data/custom_data.rb +53 -0
  10. data/lib/kameleoon/data/data.rb +35 -0
  11. data/lib/kameleoon/data/device.rb +26 -0
  12. data/lib/kameleoon/data/page_view.rb +31 -0
  13. data/lib/kameleoon/data/user_agent.rb +14 -0
  14. data/lib/kameleoon/hybrid/manager.rb +60 -0
  15. data/lib/kameleoon/network/activity_event.rb +31 -0
  16. data/lib/kameleoon/network/experiment_event.rb +35 -0
  17. data/lib/kameleoon/network/uri_helper.rb +36 -0
  18. data/lib/kameleoon/network/url_provider.rb +71 -0
  19. data/lib/kameleoon/real_time/real_time_configuration_service.rb +98 -0
  20. data/lib/kameleoon/real_time/real_time_event.rb +22 -0
  21. data/lib/kameleoon/real_time/sse_client.rb +111 -0
  22. data/lib/kameleoon/real_time/sse_message.rb +23 -0
  23. data/lib/kameleoon/real_time/sse_request.rb +59 -0
  24. data/lib/kameleoon/request.rb +5 -19
  25. data/lib/kameleoon/storage/cache.rb +84 -0
  26. data/lib/kameleoon/storage/cache_factory.rb +23 -0
  27. data/lib/kameleoon/targeting/condition.rb +41 -12
  28. data/lib/kameleoon/targeting/condition_factory.rb +35 -12
  29. data/lib/kameleoon/targeting/conditions/browser_condition.rb +71 -0
  30. data/lib/kameleoon/targeting/conditions/conversion_condition.rb +21 -0
  31. data/lib/kameleoon/targeting/conditions/custom_datum.rb +64 -34
  32. data/lib/kameleoon/targeting/conditions/device_condition.rb +21 -0
  33. data/lib/kameleoon/targeting/conditions/exclusive_experiment.rb +0 -12
  34. data/lib/kameleoon/targeting/conditions/page_title_condition.rb +21 -0
  35. data/lib/kameleoon/targeting/conditions/page_url_condition.rb +21 -0
  36. data/lib/kameleoon/targeting/conditions/sdk_language_condition.rb +65 -0
  37. data/lib/kameleoon/targeting/conditions/string_value_condition.rb +40 -0
  38. data/lib/kameleoon/targeting/conditions/target_experiment.rb +5 -9
  39. data/lib/kameleoon/targeting/conditions/unknown_condition.rb +15 -0
  40. data/lib/kameleoon/targeting/conditions/visitor_code_condition.rb +16 -0
  41. data/lib/kameleoon/targeting/models.rb +0 -24
  42. data/lib/kameleoon/utils.rb +1 -1
  43. data/lib/kameleoon/version.rb +28 -1
  44. metadata +45 -4
  45. data/lib/kameleoon/configuration/feature_flag_v2.rb +0 -30
  46. data/lib/kameleoon/data.rb +0 -169
@@ -1,40 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'experiment'
3
+ require_relative 'rule'
4
+ require_relative 'variation'
4
5
 
5
6
  module Kameleoon
6
7
  # Module which contains all internal data of SDK
7
8
  module Configuration
8
- # Class for manage all experiments and old feature flags
9
- class FeatureFlag < Experiment
10
- STATUS_ACTIVE = 'ACTIVE'
11
- FEATURE_STATUS_DEACTIVATED = 'DEACTIVATED'
12
- attr_accessor :identification_key, :feature_status, :schedules, :exposition_rate
9
+ # Class for manage all feature flags with rules
10
+ class FeatureFlag
11
+ attr_accessor :id, :feature_key, :variations, :default_variation_key, :rules
13
12
 
14
13
  def self.create_from_array(array)
15
14
  array&.map { |it| FeatureFlag.new(it) }
16
15
  end
17
16
 
18
- def initialize(feature_flag_hash)
19
- super(feature_flag_hash)
20
- @feature_status = feature_flag_hash['featureStatus']
21
- @identification_key = feature_flag_hash['identificationKey'] if feature_flag_hash['identificationKey']
22
- @exposition_rate = feature_flag_hash['expositionRate']
23
- @schedules = feature_flag_hash['schedules'] unless feature_flag_hash['schedules'].nil?
17
+ def initialize(hash)
18
+ @id = hash['id']
19
+ @feature_key = hash['featureKey']
20
+ @default_variation_key = hash['defaultVariationKey']
21
+ @variations = Variation.create_from_array(hash['variations'])
22
+ @rules = Rule.create_from_array(hash['rules'])
24
23
  end
25
24
 
26
- def is_scheduled_active(date)
27
- current_status = @status == STATUS_ACTIVE
28
- if @feature_status == FEATURE_STATUS_DEACTIVATED || @schedules.empty?
29
- return current_status
30
- end
31
- @schedules.each do |schedule|
32
- if (schedule['dateStart'].nil? || Time.parse(schedule['dateStart']).to_i < date) &&
33
- (schedule['dateEnd'].nil? || Time.parse(schedule['dateEnd']).to_i > date)
34
- return true
35
- end
36
- end
37
- false
25
+ def get_variation_key(key)
26
+ variations.select { |v| v.key == key }.first
38
27
  end
39
28
  end
40
29
  end
@@ -14,25 +14,29 @@ module Kameleoon
14
14
 
15
15
  # Rule is a class for new rules of feature flags
16
16
  class Rule
17
- attr_accessor :type, :exposition, :experiment_id, :variation_by_exposition, :targeting_segment
17
+ attr_reader :id, :order, :type, :exposition, :experiment_id, :variation_by_exposition, :respool_time
18
+ attr_accessor :targeting_segment
18
19
 
19
20
  def self.create_from_array(array)
20
21
  array&.map { |it| Rule.new(it) }
21
22
  end
22
23
 
23
24
  def initialize(hash)
25
+ @id = hash['id']
26
+ @order = hash['order']
24
27
  @type = hash['type']
25
28
  @exposition = hash['exposition']
26
29
  @experiment_id = hash['experimentId']
30
+ @respool_time = hash['respoolTime']
27
31
  @variation_by_exposition = VariationByExposition.create_from_array(hash['variationByExposition'])
28
32
  @targeting_segment = Kameleoon::Targeting::Segment.new((hash['segment'])) if hash['segment']
29
33
  end
30
34
 
31
- def get_variation_key(hash_double)
35
+ def get_variation(hash_double)
32
36
  total = 0.0
33
- variation_by_exposition.each do |element|
34
- total += element.exposition
35
- return element.variation_key if total >= hash_double
37
+ variation_by_exposition.each do |var_by_exp|
38
+ total += var_by_exp.exposition
39
+ return var_by_exp if total >= hash_double
36
40
  end
37
41
  nil
38
42
  end
@@ -40,6 +44,14 @@ module Kameleoon
40
44
  def get_variation_id_by_key(key)
41
45
  variation_by_exposition.select { |v| v.variation_key == key }.first&.variation_id
42
46
  end
47
+
48
+ def experimentation_type?
49
+ @type == RuleType::EXPERIMENTATION
50
+ end
51
+
52
+ def targeted_delivery_type?
53
+ @type == RuleType::TARGETED_DELIVERY
54
+ end
43
55
  end
44
56
  end
45
57
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kameleoon
4
+ # Module which contains all internal data of SDK
5
+ module Configuration
6
+ # KameleoonConfigurationSettings is used for saving setting's parameters, e.g
7
+ # state of real time update for site code and etc
8
+ class Settings
9
+ attr_accessor :real_time_update
10
+
11
+ def initialize
12
+ @real_time_update = false
13
+ end
14
+
15
+ def update(configuration)
16
+ @real_time_update = configuration['realTimeUpdate'] || false
17
+ end
18
+ end
19
+ end
20
+ end
@@ -26,7 +26,7 @@ module Kameleoon
26
26
  obtain_hash_double_helper(visitor_code, respool_times, container_id, '')
27
27
  end
28
28
 
29
- def obtain_hash_double_v2(visitor_code, container_id = '', suffix = '')
29
+ def obtain_hash_double_rule(visitor_code, container_id = '', suffix = '')
30
30
  obtain_hash_double_helper(visitor_code, {}, container_id, suffix)
31
31
  end
32
32
 
@@ -37,8 +37,8 @@ module Kameleoon
37
37
  identifier += respool_times.sort.to_h.values.join.to_s if !respool_times.nil? && !respool_times.empty?
38
38
  (Digest::SHA256.hexdigest(identifier.encode('UTF-8')).to_i(16) / (BigDecimal('2')**BigDecimal('256'))).round(16)
39
39
  end
40
-
41
- def check_visitor_code(visitor_code)
40
+
41
+ def check_visitor_code(visitor_code)
42
42
  if visitor_code.nil?
43
43
  check_default_visitor_code('')
44
44
  elsif
@@ -0,0 +1,33 @@
1
+ require 'json'
2
+ require_relative 'data'
3
+
4
+ module Kameleoon
5
+ module BrowserType
6
+ CHROME = 0
7
+ INTERNET_EXPLORER = 1
8
+ FIREFOX = 2
9
+ SAFARI = 3
10
+ OPERA = 4
11
+ OTHER = 5
12
+ end
13
+
14
+ # Represents browser data for tracking calls
15
+ class Browser < Data
16
+ attr_reader :type, :version
17
+
18
+ # @param [BrowserType] browser_type Browser type, can be: CHROME, INTERNET_EXPLORER, FIREFOX, SAFARI, OPERA, OTHER
19
+ # @param [float] version Version of browser
20
+ def initialize(browser_type, version = Float::NAN)
21
+ super(DataType::BROWSER)
22
+ @type = browser_type
23
+ @version = version
24
+ end
25
+
26
+ def obtain_full_post_text_line
27
+ nonce = Kameleoon::Utils.generate_random_string(NONCE_LENGTH)
28
+ url = "eventType=staticData&browserIndex=#{@type}&nonce=#{nonce}"
29
+ url.concat("&browserVersion=#{@version}") if @version.is_a?(Integer) || (@version.is_a?(Float) && !@version.nan?)
30
+ url
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require_relative 'data'
5
+
6
+ module Kameleoon
7
+ # Conversion class uses for tracking conversion
8
+ class Conversion < Data
9
+ attr_reader :goal_id, :revenue, :negative
10
+
11
+ # @param [Integer] goal_id Id of the goal associated to the conversion
12
+ # @param [Float] revenue Optional field - Revenue associated to the conversion.
13
+ # @param [Boolean] negative Optional field - If the revenue is negative. By default it's positive.
14
+ def initialize(goal_id, revenue = 0.0, negative = false)
15
+ super(DataType::CONVERSION)
16
+ @goal_id = goal_id
17
+ @revenue = revenue || 0.0
18
+ @negative = negative || false
19
+ end
20
+
21
+ def obtain_full_post_text_line
22
+ nonce = Kameleoon::Utils.generate_random_string(NONCE_LENGTH)
23
+ "eventType=conversion&goalId=#{@goal_id}&revenue=#{@revenue}&negative=#{@negative}&nonce=#{nonce}"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require_relative 'data'
5
+
6
+ module Kameleoon
7
+ # Represents any custom data for targeting conditions
8
+ class CustomData < Data
9
+ attr_reader :id, :values
10
+
11
+ # @param [Integer] id Id of the custom data
12
+ # @param [String] value Value of the custom data
13
+ # @param [Array] values Array of values of the custom data
14
+ #
15
+ # @overload
16
+ # @param [Hash] hash Json value encoded in a hash.
17
+ # rubocop:disable Metrics/MethodLength
18
+ def initialize(arg0, *args)
19
+ super(DataType::CUSTOM)
20
+ if arg0.is_a?(Hash)
21
+ hash = arg0
22
+ id = hash['id']
23
+ raise Kameleoon::Exception::NotFound.new('id'), '"id" is mandatory' if id.nil?
24
+
25
+ @id = id.to_s
26
+ value = hash['value']
27
+ values = hash['values']
28
+ if values.nil? && value.nil?
29
+ raise Kameleoon::Exception::NotFound.new('value or values'), '"value" or "values" is mandatory'
30
+ end
31
+
32
+ if values.nil?
33
+ @values = [value]
34
+ else
35
+ @values = values.is_a?(Array) ? values.dup : [values]
36
+ @values.append(value) unless value.nil?
37
+ end
38
+ else
39
+ @id = arg0.to_s
40
+ @values = args
41
+ end
42
+ end
43
+ # rubocop:enable Metrics/MethodLength
44
+
45
+ def obtain_full_post_text_line
46
+ return '' if @values.empty?
47
+
48
+ str_values = JSON.generate(Hash[@values.collect { |k| [k, 1] }])
49
+ nonce = Kameleoon::Utils.generate_random_string(NONCE_LENGTH)
50
+ "eventType=customData&index=#{@id}&valuesCountMap=#{self.class.encode(str_values)}&overwrite=true&nonce=#{nonce}"
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'kameleoon/exceptions'
5
+
6
+ module Kameleoon
7
+ NONCE_LENGTH = 16
8
+
9
+ module DataType
10
+ CUSTOM = 'CUSTOM'
11
+ BROWSER = 'BROWSER'
12
+ CONVERSION = 'CONVERSION'
13
+ DEVICE = 'DEVICE'
14
+ PAGE_VIEW = 'PAGE_VIEW'
15
+ end
16
+
17
+ # Represents base class for any Kameleoon data
18
+ class Data
19
+ attr_reader :instance
20
+ attr_accessor :sent
21
+
22
+ def initialize(data_type)
23
+ @instance = data_type
24
+ @sent = false
25
+ end
26
+
27
+ def obtain_full_post_text_line
28
+ raise KameleoonError.new('ToDo: implement this method.'), 'ToDo: implement this method.'
29
+ end
30
+
31
+ def self.encode(url)
32
+ Network::UriHelper.encode_uri(url)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require_relative 'data'
5
+
6
+ module Kameleoon
7
+ module DeviceType
8
+ PHONE = 'PHONE'
9
+ TABLET = 'TABLET'
10
+ DESKTOP = 'DESKTOP'
11
+ end
12
+
13
+ # Device uses for sending deviceType parameter for tracking calls
14
+ class Device < Data
15
+ attr_reader :device_type
16
+ def initialize(device_type)
17
+ super(DataType::DEVICE)
18
+ @device_type = device_type
19
+ end
20
+
21
+ def obtain_full_post_text_line
22
+ nonce = Kameleoon::Utils.generate_random_string(NONCE_LENGTH)
23
+ "eventType=staticData&deviceType=#{@device_type}&nonce=#{nonce}"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require_relative 'data'
5
+
6
+ module Kameleoon
7
+ # Represents page view data for tracking calls
8
+ class PageView < Data
9
+ attr_reader :url, :title, :referrer
10
+
11
+ # @param [String] url Url of the page
12
+ # @param [String] title Title of the page
13
+ # @param [Array] referrers Optional field - Referrer ids
14
+ def initialize(url, title, referrers = nil)
15
+ super(DataType::PAGE_VIEW)
16
+ @url = url || ''
17
+ @title = title || ''
18
+ @referrers = referrers.instance_of?(Integer) ? [referrers] : referrers
19
+ end
20
+
21
+ def obtain_full_post_text_line
22
+ nonce = Kameleoon::Utils.generate_random_string(NONCE_LENGTH)
23
+ referrer_text = if !@referrers.nil? && !@referrers.empty?
24
+ "&referrersIndices=%5B#{@referrers.each(&:to_s).join('%2C')}%5D"
25
+ else
26
+ ''
27
+ end
28
+ "eventType=page&href=#{self.class.encode(@url)}&title=#{self.class.encode(@title)}#{referrer_text}&nonce=#{nonce}"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Kameleoon
6
+ # UserAgent uses for changing User-Agent header for tracking calls
7
+ class UserAgent
8
+ attr_reader :value
9
+
10
+ def initialize(value)
11
+ @value = value
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kameleoon
4
+ module Hybrid
5
+ TC_INIT = 'window.kameleoonQueue=window.kameleoonQueue||[];'
6
+ TC_ASSIGN_VARIATION_FORMAT = "window.kameleoonQueue.push(['Experiments.assignVariation',%d,%d]);"
7
+ TC_TRIGGER_FORMAT = "window.kameleoonQueue.push(['Experiments.trigger',%d,true]);"
8
+ TC_ASSIGN_VARIATION_TRIGGER_FORMAT = TC_ASSIGN_VARIATION_FORMAT + TC_TRIGGER_FORMAT
9
+
10
+ # Will be useful for Ruby 3.0
11
+ # Abstract Manager class (interface)
12
+ class Manager
13
+ def add_variation(_visitor, _experiment_id, _variation_id)
14
+ raise 'Abstract method `add` called'
15
+ end
16
+
17
+ def get_engine_tracking_code(_visitor)
18
+ raise 'Abstract method `get_engine_tracking_code` called'
19
+ end
20
+ end
21
+
22
+ # Implementation of Cache with auto cleaning feature
23
+ class ManagerImpl < Manager
24
+ def initialize(expiration_time, cleaning_interval, cache_factory, log_func)
25
+ super()
26
+ # synchronization is necessary for adding same visitor_code from different threads
27
+ @mutex = Mutex.new
28
+ @expiration_time = expiration_time
29
+ @cache_factory = cache_factory
30
+ @log = log_func
31
+ # it's recommend to use cleaning_interval 3-4 times more than experiation_time for more performance
32
+ # in this case on every cleaning iteration storage will be cleaned 2/3 - 3/4 of volume
33
+ @cache = cache_factory.create(expiration_time, cleaning_interval)
34
+ @log.call('Hybrid Manager was successfully initialized')
35
+ end
36
+
37
+ def add_variation(visitor_code, experiment_id, variation_id)
38
+ @mutex.synchronize do
39
+ visitor_cache = @cache.get(visitor_code)
40
+ visitor_cache = @cache_factory.create(@expiration_time, 0) if visitor_cache.nil?
41
+ visitor_cache.set(experiment_id, variation_id)
42
+ @cache.set(visitor_code, visitor_cache)
43
+ end
44
+ @log.call("Hybrid Manager successfully added variation for visitor_code: #{visitor_code}, " \
45
+ "experiment: #{experiment_id}, variation: #{variation_id}")
46
+ end
47
+
48
+ def get_engine_tracking_code(visitor_code)
49
+ tracking_code = TC_INIT
50
+ visitor_cache = @cache.get(visitor_code)
51
+ return tracking_code if visitor_cache.nil?
52
+
53
+ visitor_cache.active_items.each_pair do |key, value|
54
+ tracking_code += format(TC_ASSIGN_VARIATION_TRIGGER_FORMAT, key, value, key)
55
+ end
56
+ tracking_code
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require 'kameleoon/data/data'
5
+ require 'kameleoon/utils'
6
+ require 'kameleoon/network/uri_helper'
7
+
8
+ module Kameleoon
9
+ module Network
10
+ ##
11
+ # ActivityEvent represents an activity tracking event.
12
+ class ActivityEvent
13
+ EVENT_TYPE = 'activity'
14
+
15
+ attr_accessor :sent
16
+
17
+ def initialize
18
+ @sent = false
19
+ @nonce = Kameleoon::Utils.generate_random_string(Kameleoon::NONCE_LENGTH)
20
+ end
21
+
22
+ def obtain_full_post_text_line
23
+ params = {
24
+ eventType: EVENT_TYPE,
25
+ nonce: @nonce
26
+ }
27
+ UriHelper.encode_query(params)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require 'kameleoon/data/data'
5
+ require 'kameleoon/utils'
6
+ require 'kameleoon/network/uri_helper'
7
+
8
+ module Kameleoon
9
+ module Network
10
+ ##
11
+ # ExperimentEvent represents an experiment tracking event.
12
+ class ExperimentEvent
13
+ EVENT_TYPE = 'experiment'
14
+
15
+ attr_accessor :sent
16
+
17
+ def initialize(experiment_id, variation_id)
18
+ @sent = false
19
+ @experiment_id = experiment_id
20
+ @variation_id = variation_id
21
+ @nonce = Kameleoon::Utils.generate_random_string(Kameleoon::NONCE_LENGTH)
22
+ end
23
+
24
+ def obtain_full_post_text_line
25
+ params = {
26
+ eventType: EVENT_TYPE,
27
+ id: @experiment_id,
28
+ variationId: @variation_id,
29
+ nonce: @nonce
30
+ }
31
+ UriHelper.encode_query(params)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+ require 'uri'
5
+
6
+ module Kameleoon
7
+ module Network
8
+ ##
9
+ # UriHelper contains functions which helps working with URIs.
10
+ module UriHelper
11
+ def self.encode_uri(uri)
12
+ encoded = CGI.escape(uri)
13
+ encoded.gsub!(/%21|%27|%28|%29|%2A|\+/,
14
+ '%21' => '!',
15
+ '%27' => "'",
16
+ '%28' => '(',
17
+ '%29' => ')',
18
+ '%2A' => '*',
19
+ '+' => '%20')
20
+ encoded
21
+ end
22
+
23
+ def self.encode_query(params)
24
+ encoded = URI.encode_www_form(params)
25
+ encoded.gsub!(/%21|%27|%28|%29|%7E|\+/,
26
+ '%21' => '!',
27
+ '%27' => "'",
28
+ '%28' => '(',
29
+ '%29' => ')',
30
+ '%7E' => '~',
31
+ '+' => '%20')
32
+ encoded
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kameleoon/version'
4
+ require 'kameleoon/network/uri_helper'
5
+
6
+ module Kameleoon
7
+ module Network
8
+ ##
9
+ # UrlProvider is used as a source of URLs for network calls.
10
+ class UrlProvider
11
+ TRACKING_PATH = '/visit/events'
12
+ VISITOR_DATA_PATH = '/visit/visitor'
13
+ GET_DATA_PATH = '/map/map'
14
+ POST_DATA_PATH = '/map/maps'
15
+ CONFIGURATION_API_URL = 'https://client-config.kameleoon.com/mobile'
16
+ RT_CONFIGURATION_URL = 'https://events.kameleoon.com:8110/sse'
17
+
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
22
+
23
+ def initialize(site_code, data_api_url)
24
+ @site_code = site_code
25
+ @data_api_url = data_api_url
26
+ end
27
+
28
+ def make_tracking_url(visitor_code)
29
+ params = {
30
+ sdkName: SDK_NAME,
31
+ sdkVersion: SDK_VERSION,
32
+ siteCode: @site_code,
33
+ visitorCode: visitor_code
34
+ }
35
+ "#{@data_api_url}#{TRACKING_PATH}?#{UriHelper.encode_query(params)}"
36
+ end
37
+
38
+ def make_visitor_data_get_url(visitor_code)
39
+ params = {
40
+ siteCode: @site_code,
41
+ visitorCode: visitor_code,
42
+ currentVisit: true,
43
+ maxNumberPreviousVisits: 1,
44
+ customData: true,
45
+ version: 0
46
+ }
47
+ "#{@data_api_url}#{VISITOR_DATA_PATH}?#{UriHelper.encode_query(params)}"
48
+ end
49
+
50
+ def make_api_data_get_request_url(key)
51
+ params = {
52
+ siteCode: @site_code,
53
+ key: key
54
+ }
55
+ "#{@data_api_url}#{GET_DATA_PATH}?#{UriHelper.encode_query(params)}"
56
+ end
57
+
58
+ def make_configuration_url(environment = nil, timestamp = nil)
59
+ params = { siteCode: @site_code }
60
+ params[:environment] = environment unless environment.nil?
61
+ params[:ts] = timestamp unless timestamp.nil?
62
+ "#{CONFIGURATION_API_URL}?#{UriHelper.encode_query(params)}"
63
+ end
64
+
65
+ def make_real_time_url
66
+ params = { siteCode: @site_code }
67
+ "#{RT_CONFIGURATION_URL}?#{UriHelper.encode_query(params)}"
68
+ end
69
+ end
70
+ end
71
+ end