kameleoon-client-ruby 2.1.0 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kameleoon/client.rb +79 -133
- data/lib/kameleoon/configuration/rule.rb +1 -1
- data/lib/kameleoon/data/browser.rb +33 -0
- data/lib/kameleoon/data/conversion.rb +26 -0
- data/lib/kameleoon/data/custom_data.rb +53 -0
- data/lib/kameleoon/data/data.rb +35 -0
- data/lib/kameleoon/data/device.rb +26 -0
- data/lib/kameleoon/data/page_view.rb +31 -0
- data/lib/kameleoon/data/user_agent.rb +14 -0
- data/lib/kameleoon/network/activity_event.rb +31 -0
- data/lib/kameleoon/network/experiment_event.rb +35 -0
- data/lib/kameleoon/network/uri_helper.rb +36 -0
- data/lib/kameleoon/network/url_provider.rb +71 -0
- data/lib/kameleoon/request.rb +5 -19
- data/lib/kameleoon/targeting/condition.rb +40 -11
- data/lib/kameleoon/targeting/condition_factory.rb +35 -12
- data/lib/kameleoon/targeting/conditions/browser_condition.rb +71 -0
- data/lib/kameleoon/targeting/conditions/conversion_condition.rb +21 -0
- data/lib/kameleoon/targeting/conditions/custom_datum.rb +60 -65
- data/lib/kameleoon/targeting/conditions/device_condition.rb +21 -0
- data/lib/kameleoon/targeting/conditions/exclusive_experiment.rb +0 -12
- data/lib/kameleoon/targeting/conditions/page_title_condition.rb +21 -0
- data/lib/kameleoon/targeting/conditions/page_url_condition.rb +21 -0
- data/lib/kameleoon/targeting/conditions/sdk_language_condition.rb +65 -0
- data/lib/kameleoon/targeting/conditions/string_value_condition.rb +40 -0
- data/lib/kameleoon/targeting/conditions/target_experiment.rb +4 -8
- data/lib/kameleoon/targeting/conditions/unknown_condition.rb +15 -0
- data/lib/kameleoon/targeting/conditions/visitor_code_condition.rb +16 -0
- data/lib/kameleoon/targeting/models.rb +0 -24
- data/lib/kameleoon/utils.rb +1 -1
- data/lib/kameleoon/version.rb +28 -1
- metadata +22 -3
- data/lib/kameleoon/data.rb +0 -175
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1aef3f7b97d4a32024bec989ed4356cc1d10425c16b419b55f524cf1abfd4f52
|
4
|
+
data.tar.gz: 5705b067a3effc12b7f38ccef23e01ee28e370b99a212fd371ce0c863184c3ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99cc273ca6010c9ce2c451e7a7cb3795e4b264b670fb8009436e5b9ddbaacf388e894f0922926bf92113ebf9f211636f4b4fc2a34fc01babcf848327bba798f8
|
7
|
+
data.tar.gz: 3686a34890b5438e5d0ca878cbb0bfb89386f2150267c73ef27754d207c6f918aad3355a312045251d3dea15fc2faa6558433f172b907ae4e913c7b60cc204f4
|
data/lib/kameleoon/client.rb
CHANGED
@@ -4,9 +4,13 @@ require 'kameleoon/targeting/models'
|
|
4
4
|
require 'kameleoon/request'
|
5
5
|
require 'kameleoon/exceptions'
|
6
6
|
require 'kameleoon/cookie'
|
7
|
+
require 'kameleoon/data/user_agent'
|
7
8
|
require 'kameleoon/configuration/feature_flag'
|
8
9
|
require 'kameleoon/configuration/variation'
|
9
10
|
require 'kameleoon/configuration/settings'
|
11
|
+
require 'kameleoon/network/activity_event'
|
12
|
+
require 'kameleoon/network/experiment_event'
|
13
|
+
require 'kameleoon/network/url_provider'
|
10
14
|
require 'kameleoon/real_time/real_time_configuration_service'
|
11
15
|
require 'kameleoon/storage/variation_storage'
|
12
16
|
require 'kameleoon/hybrid/manager'
|
@@ -39,9 +43,8 @@ module Kameleoon
|
|
39
43
|
@default_timeout = config['default_timeout'] || default_timeout # in ms
|
40
44
|
refresh_interval = config['actions_configuration_refresh_interval']
|
41
45
|
@interval = refresh_interval.nil? ? interval : "#{refresh_interval}m"
|
42
|
-
|
43
|
-
@
|
44
|
-
@events_url = 'https://events.kameleoon.com:8110/'
|
46
|
+
data_api_url = config['tracking_url'] || Network::UrlProvider::DEFAULT_DATA_API_URL
|
47
|
+
@url_provider = Network::UrlProvider.new(@site_code, data_api_url)
|
45
48
|
@real_time_configuration_service = nil
|
46
49
|
@update_configuration_handler = nil
|
47
50
|
@fetch_configuration_update_job = nil
|
@@ -129,22 +132,22 @@ module Kameleoon
|
|
129
132
|
"Experiment #{experiment_id} is not found"
|
130
133
|
end
|
131
134
|
check_site_code_enable(experiment)
|
132
|
-
|
135
|
+
targeted = check_targeting(visitor_code, experiment_id, experiment)
|
136
|
+
if targeted
|
133
137
|
# saved_variation = get_valid_saved_variation(visitor_code, experiment)
|
134
138
|
variation_id = calculate_variation_for_experiment(visitor_code, experiment)
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
else
|
140
|
-
track_experiment(visitor_code, experiment_id, REFERENCE, true)
|
141
|
-
raise Exception::NotAllocated.new(visitor_code),
|
142
|
-
"Experiment #{experiment_id} is not active for visitor #{visitor_code}"
|
143
|
-
end
|
144
|
-
else
|
139
|
+
save_variation(visitor_code, experiment_id, variation_id)
|
140
|
+
end
|
141
|
+
_send_tracking_request(visitor_code, experiment_id, variation_id)
|
142
|
+
unless targeted
|
145
143
|
raise Exception::NotTargeted.new(visitor_code),
|
146
144
|
"Experiment #{experiment_id} is not targeted for visitor #{visitor_code}"
|
147
145
|
end
|
146
|
+
if variation_id.nil?
|
147
|
+
raise Exception::NotAllocated.new(visitor_code),
|
148
|
+
"Experiment #{experiment_id} is not active for visitor #{visitor_code}"
|
149
|
+
end
|
150
|
+
variation_id
|
148
151
|
end
|
149
152
|
|
150
153
|
##
|
@@ -208,7 +211,7 @@ module Kameleoon
|
|
208
211
|
def flush(visitor_code = nil)
|
209
212
|
check_visitor_code(visitor_code) unless visitor_code.nil?
|
210
213
|
if !visitor_code.nil?
|
211
|
-
|
214
|
+
_send_tracking_request(visitor_code)
|
212
215
|
else
|
213
216
|
@data.select { |_, values| values.any? { |data| !data.sent } }.each_key { |key| flush(key) }
|
214
217
|
end
|
@@ -384,7 +387,7 @@ module Kameleoon
|
|
384
387
|
end
|
385
388
|
|
386
389
|
##
|
387
|
-
# The
|
390
|
+
# The get_remote_data method allows you to retrieve data (according to a key passed as argument)
|
388
391
|
# stored on a remote Kameleoon server. Usually data will be stored on our remote
|
389
392
|
# servers via the use of our Data API.
|
390
393
|
# This method, along with the availability of our highly scalable servers for this purpose, provides a convenient
|
@@ -395,11 +398,11 @@ module Kameleoon
|
|
395
398
|
# This field is optional.
|
396
399
|
#
|
397
400
|
# @return [Hash] Hash object of the json object.
|
398
|
-
def
|
401
|
+
def get_remote_data(key, timeout = @default_timeout)
|
399
402
|
connexion_options = { connect_timeout: (timeout.to_f / 1000.0) }
|
400
|
-
|
403
|
+
url = @url_provider.make_api_data_get_request_url(key)
|
401
404
|
log "Retrieve API Data connexion: #{connexion_options.inspect}"
|
402
|
-
response = get_sync(
|
405
|
+
response = get_sync(url, connexion_options)
|
403
406
|
return nil unless successful_sync?(response)
|
404
407
|
|
405
408
|
JSON.parse(response.body) unless response.nil?
|
@@ -409,7 +412,7 @@ module Kameleoon
|
|
409
412
|
# DEPRECATED. Please use `get_feature_variable` instead.
|
410
413
|
def retrieve_data_from_remote_source(key, timeout = @default_timeout)
|
411
414
|
warn '[DEPRECATION] `retrieve_data_from_remote_source` is deprecated. Please use `get_remote_date` instead.'
|
412
|
-
|
415
|
+
get_remote_data(key, timeout)
|
413
416
|
end
|
414
417
|
|
415
418
|
##
|
@@ -490,7 +493,6 @@ module Kameleoon
|
|
490
493
|
|
491
494
|
private
|
492
495
|
|
493
|
-
API_SSX_URL = 'https://api-ssx.kameleoon.com'
|
494
496
|
REFERENCE = 0
|
495
497
|
DEFAULT_ENVIRONMENT = 'production'
|
496
498
|
CACHE_EXPIRATION_TIMEOUT = 5
|
@@ -507,7 +509,7 @@ module Kameleoon
|
|
507
509
|
def fetch_configuration_job(time_stamp = nil)
|
508
510
|
EM.synchrony do
|
509
511
|
begin
|
510
|
-
ok = obtain_configuration(@
|
512
|
+
ok = obtain_configuration(@environment, time_stamp)
|
511
513
|
if !ok && @settings.real_time_update
|
512
514
|
@settings.real_time_update = false
|
513
515
|
log('Switching to polling mode due to failed fetch')
|
@@ -540,10 +542,10 @@ module Kameleoon
|
|
540
542
|
def start_real_time_configuration_service_if_needed
|
541
543
|
return unless @real_time_configuration_service.nil?
|
542
544
|
|
543
|
-
|
545
|
+
url = @url_provider.make_real_time_url
|
544
546
|
fetch_func = proc { |real_time_event| fetch_configuration_job(real_time_event.time_stamp) }
|
545
547
|
@real_time_configuration_service =
|
546
|
-
Kameleoon::RealTime::RealTimeConfigurationService.new(
|
548
|
+
Kameleoon::RealTime::RealTimeConfigurationService.new(url, fetch_func, method(:log))
|
547
549
|
end
|
548
550
|
|
549
551
|
def stop_real_time_configuration_service_if_needed
|
@@ -577,12 +579,10 @@ module Kameleoon
|
|
577
579
|
# { 'field' => field, 'operator' => operator, 'parameters' => parameters }
|
578
580
|
# end
|
579
581
|
|
580
|
-
def obtain_configuration(
|
582
|
+
def obtain_configuration(environment = @environment, time_stamp = nil)
|
581
583
|
log 'Fetching configuration from Client-Config service'
|
582
|
-
|
583
|
-
|
584
|
-
request_path += "&ts=#{time_stamp}" unless time_stamp.nil?
|
585
|
-
request = request_configuration(request_path)
|
584
|
+
url = @url_provider.make_configuration_url(environment, time_stamp)
|
585
|
+
request = request_configuration(url)
|
586
586
|
return false unless request
|
587
587
|
|
588
588
|
configuration = JSON.parse(request.response)
|
@@ -616,8 +616,8 @@ module Kameleoon
|
|
616
616
|
nil
|
617
617
|
end
|
618
618
|
|
619
|
-
def request_configuration(
|
620
|
-
request = EM::Synchrony.sync get({
|
619
|
+
def request_configuration(url)
|
620
|
+
request = EM::Synchrony.sync get({}, url)
|
621
621
|
unless successful?(request)
|
622
622
|
log "Failed to fetch #{request.inspect}"
|
623
623
|
return false
|
@@ -625,37 +625,6 @@ module Kameleoon
|
|
625
625
|
request
|
626
626
|
end
|
627
627
|
|
628
|
-
def get_common_ssx_parameters(visitor_code)
|
629
|
-
{
|
630
|
-
nonce: Kameleoon::Utils.generate_random_string(16),
|
631
|
-
siteCode: @site_code,
|
632
|
-
visitorCode: visitor_code
|
633
|
-
}
|
634
|
-
end
|
635
|
-
|
636
|
-
def get_experiment_register_url(visitor_code, experiment_id, variation_id = nil, none_variation = false)
|
637
|
-
url = "/experimentTracking?#{URI.encode_www_form(get_common_ssx_parameters(visitor_code))}"
|
638
|
-
url += "&experimentId=#{experiment_id}"
|
639
|
-
return url if variation_id.nil?
|
640
|
-
|
641
|
-
url += "&variationId=#{variation_id}"
|
642
|
-
url += '&noneVariation=true' if none_variation
|
643
|
-
|
644
|
-
url
|
645
|
-
end
|
646
|
-
|
647
|
-
def get_data_register_url(visitor_code)
|
648
|
-
"/dataTracking?#{URI.encode_www_form(get_common_ssx_parameters(visitor_code))}"
|
649
|
-
end
|
650
|
-
|
651
|
-
def get_api_data_request_url(key)
|
652
|
-
mapKey = {
|
653
|
-
siteCode: site_code,
|
654
|
-
key: key
|
655
|
-
}
|
656
|
-
"/data?#{URI.encode_www_form(mapKey)}"
|
657
|
-
end
|
658
|
-
|
659
628
|
def find_feature_flag(feature_key)
|
660
629
|
if feature_key.is_a?(String)
|
661
630
|
feature_flag = @feature_flags.select { |ff| ff.feature_key == feature_key }.first
|
@@ -669,67 +638,6 @@ module Kameleoon
|
|
669
638
|
feature_flag
|
670
639
|
end
|
671
640
|
|
672
|
-
def track_experiment(visitor_code, experiment_id, variation_id = nil, none_variation: false)
|
673
|
-
data_not_sent = data_not_sent(visitor_code)
|
674
|
-
options = {
|
675
|
-
path: get_experiment_register_url(visitor_code, experiment_id, variation_id, none_variation),
|
676
|
-
body: (data_not_sent.map(&:obtain_full_post_text_line).join("\n") || '').encode('UTF-8'),
|
677
|
-
head: { 'Content-Type': 'text/plain' }
|
678
|
-
}
|
679
|
-
set_user_agent_to_headers(visitor_code, options[:head])
|
680
|
-
trial = 0
|
681
|
-
success = false
|
682
|
-
log "Start post tracking experiment: #{data_not_sent.inspect}"
|
683
|
-
Thread.new do
|
684
|
-
while trial < 10
|
685
|
-
log "Send Experiment Tracking #{options.inspect}"
|
686
|
-
response = post_sync(options, @tracking_url)
|
687
|
-
log "Response #{response.inspect}"
|
688
|
-
if successful_sync?(response)
|
689
|
-
data_not_sent.each { |it| it.sent = true }
|
690
|
-
success = true
|
691
|
-
break
|
692
|
-
end
|
693
|
-
trial += 1
|
694
|
-
end
|
695
|
-
if success
|
696
|
-
log "Post to experiment tracking is done after #{trial + 1} trials"
|
697
|
-
else
|
698
|
-
log "Post to experiment tracking is failed after #{trial} trials"
|
699
|
-
end
|
700
|
-
end
|
701
|
-
end
|
702
|
-
|
703
|
-
def track_data(visitor_code)
|
704
|
-
Thread.new do
|
705
|
-
trials = 0
|
706
|
-
data_not_sent = data_not_sent(visitor_code)
|
707
|
-
log "Start post tracking data: #{data_not_sent.inspect}"
|
708
|
-
while trials < 10 && !data_not_sent.empty?
|
709
|
-
options = {
|
710
|
-
path: get_data_register_url(visitor_code),
|
711
|
-
body: (data_not_sent.map(&:obtain_full_post_text_line).join("\n") || '').encode('UTF-8'),
|
712
|
-
head: { 'Content-Type': 'text/plain' }
|
713
|
-
}
|
714
|
-
set_user_agent_to_headers(visitor_code, options[:head])
|
715
|
-
log "Post tracking data for visitor_code: #{visitor_code} with options: #{options.inspect}"
|
716
|
-
response = post_sync(options, @tracking_url)
|
717
|
-
log "Response #{response.inspect}"
|
718
|
-
if successful_sync?(response)
|
719
|
-
data_not_sent.each { |it| it.sent = true }
|
720
|
-
success = true
|
721
|
-
break
|
722
|
-
end
|
723
|
-
trials += 1
|
724
|
-
end
|
725
|
-
if success
|
726
|
-
log "Post to data tracking is done after #{trials + 1} trials"
|
727
|
-
else
|
728
|
-
log "Post to data tracking is failed after #{trials} trials"
|
729
|
-
end
|
730
|
-
end
|
731
|
-
end
|
732
|
-
|
733
641
|
def check_site_code_enable(campaign)
|
734
642
|
raise Exception::SiteCodeDisabled.new(site_code), site_code unless campaign.site_enabled
|
735
643
|
end
|
@@ -770,8 +678,17 @@ module Kameleoon
|
|
770
678
|
def get_condition_data(type, visitor_code, campaign_id)
|
771
679
|
condition_data = nil
|
772
680
|
case type
|
773
|
-
when Kameleoon::Targeting::ConditionType::CUSTOM_DATUM
|
681
|
+
when Kameleoon::Targeting::ConditionType::CUSTOM_DATUM,
|
682
|
+
Kameleoon::Targeting::ConditionType::PAGE_TITLE,
|
683
|
+
Kameleoon::Targeting::ConditionType::PAGE_URL,
|
684
|
+
Kameleoon::Targeting::ConditionType::DEVICE_TYPE,
|
685
|
+
Kameleoon::Targeting::ConditionType::BROWSER,
|
686
|
+
Kameleoon::Targeting::ConditionType::CONVERSIONS
|
774
687
|
condition_data = (@data[visitor_code] || []).flatten
|
688
|
+
when Kameleoon::Targeting::ConditionType::SDK_LANGUAGE
|
689
|
+
condition_data = Kameleoon::Targeting::SdkInfo.new(Kameleoon::SDK_NAME, Kameleoon::SDK_VERSION)
|
690
|
+
when Kameleoon::Targeting::ConditionType::VISITOR_CODE
|
691
|
+
condition_data = visitor_code
|
775
692
|
when Kameleoon::Targeting::ConditionType::TARGET_EXPERIMENT
|
776
693
|
condition_data = @variation_storage.get_hash_saved_variation_id(visitor_code)
|
777
694
|
when Kameleoon::Targeting::ConditionType::EXCLUSIVE_EXPERIMENT
|
@@ -790,10 +707,11 @@ module Kameleoon
|
|
790
707
|
variation, rule = _calculate_variation_key_for_feature(visitor_code, feature_flag)
|
791
708
|
variation_key = _get_variation_key(variation, rule, feature_flag)
|
792
709
|
unless rule.nil?
|
793
|
-
|
710
|
+
experiment_id = rule.experiment_id
|
794
711
|
variation_id = variation.variation_id unless variation.nil?
|
795
|
-
|
712
|
+
save_variation(visitor_code, experiment_id, variation_id)
|
796
713
|
end
|
714
|
+
_send_tracking_request(visitor_code, experiment_id, variation_id)
|
797
715
|
[feature_flag, variation_key]
|
798
716
|
end
|
799
717
|
|
@@ -809,11 +727,12 @@ module Kameleoon
|
|
809
727
|
hash_rule = obtain_hash_double_rule(visitor_code, rule.id, rule.respool_time)
|
810
728
|
# check main expostion for rule with hashRule
|
811
729
|
if hash_rule <= rule.exposition
|
730
|
+
return [rule.variation_by_exposition[0], rule] if rule.targeted_delivery_type?
|
731
|
+
|
812
732
|
# uses for variation's expositions
|
813
733
|
hash_variation = obtain_hash_double_rule(visitor_code, rule.experiment_id, rule.respool_time)
|
814
734
|
# get variation key with new hashVariation
|
815
735
|
variation = rule.get_variation(hash_variation)
|
816
|
-
# variation_key can be nil for experiment rules only, for targeted rule will be always exist
|
817
736
|
return [variation, rule] unless variation.nil?
|
818
737
|
# if visitor is targeted for targeted rule then break cycle -> return default
|
819
738
|
elsif rule.targeted_delivery_type?
|
@@ -833,19 +752,46 @@ module Kameleoon
|
|
833
752
|
def _get_variation_key(var_by_exp, rule, feature_flag)
|
834
753
|
return var_by_exp.variation_key unless var_by_exp.nil?
|
835
754
|
|
836
|
-
return Kameleoon::Configuration::VariationType::VARIATION_OFF if !rule.nil? && rule.
|
755
|
+
return Kameleoon::Configuration::VariationType::VARIATION_OFF if !rule.nil? && rule.experimentation_type?
|
837
756
|
|
838
757
|
feature_flag.default_variation_key
|
839
758
|
end
|
840
759
|
|
841
760
|
##
|
842
761
|
# helper method for sending tracking requests for new FF
|
843
|
-
def _send_tracking_request(visitor_code, experiment_id, variation_id)
|
844
|
-
|
845
|
-
|
846
|
-
|
762
|
+
def _send_tracking_request(visitor_code, experiment_id = nil, variation_id = nil)
|
763
|
+
data_not_sent = data_not_sent(visitor_code)
|
764
|
+
if experiment_id.nil? || variation_id.nil?
|
765
|
+
data_not_sent.append(Network::ActivityEvent.new) if data_not_sent.empty?
|
847
766
|
else
|
848
|
-
|
767
|
+
data_not_sent.append(Network::ExperimentEvent.new(experiment_id, variation_id))
|
768
|
+
end
|
769
|
+
options = {
|
770
|
+
body: (data_not_sent.map(&:obtain_full_post_text_line).join("\n") || '').encode('UTF-8'),
|
771
|
+
head: { 'Content-Type': 'text/plain' }
|
772
|
+
}
|
773
|
+
set_user_agent_to_headers(visitor_code, options[:head])
|
774
|
+
url = @url_provider.make_tracking_url(visitor_code)
|
775
|
+
trial = 0
|
776
|
+
success = false
|
777
|
+
log "Start post tracking: #{data_not_sent.inspect}"
|
778
|
+
Thread.new do
|
779
|
+
while trial < 10
|
780
|
+
log "Send tracking #{options.inspect}"
|
781
|
+
response = post_sync(options, url)
|
782
|
+
log "Response #{response.inspect}"
|
783
|
+
if successful_sync?(response)
|
784
|
+
data_not_sent.each { |it| it.sent = true }
|
785
|
+
success = true
|
786
|
+
break
|
787
|
+
end
|
788
|
+
trial += 1
|
789
|
+
end
|
790
|
+
if success
|
791
|
+
log "Post to tracking is done after #{trial + 1} trials"
|
792
|
+
else
|
793
|
+
log "Post to tracking is failed after #{trial} trials"
|
794
|
+
end
|
849
795
|
end
|
850
796
|
end
|
851
797
|
|
@@ -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,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
|