vwo-sdk 1.3.0 → 1.14.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.
- checksums.yaml +5 -5
- data/lib/vwo.rb +1020 -84
- data/lib/vwo/constants.rb +64 -13
- data/lib/vwo/core/bucketer.rb +10 -14
- data/lib/vwo/core/variation_decider.rb +391 -80
- data/lib/vwo/enums.rb +113 -10
- data/lib/vwo/logger.rb +9 -3
- data/lib/vwo/schemas/settings_file.rb +1 -3
- data/lib/vwo/services/batch_events_dispatcher.rb +110 -0
- data/lib/vwo/services/batch_events_queue.rb +175 -0
- data/lib/vwo/services/event_dispatcher.rb +3 -17
- data/lib/vwo/services/hooks_manager.rb +36 -0
- data/lib/vwo/services/operand_evaluator.rb +122 -0
- data/lib/vwo/services/segment_evaluator.rb +88 -0
- data/lib/vwo/services/settings_file_manager.rb +11 -9
- data/lib/vwo/services/settings_file_processor.rb +6 -3
- data/lib/vwo/services/usage_stats.rb +29 -0
- data/lib/vwo/user_storage.rb +1 -3
- data/lib/vwo/utils/campaign.rb +151 -22
- data/lib/vwo/utils/custom_dimensions.rb +72 -0
- data/lib/vwo/utils/feature.rb +56 -0
- data/lib/vwo/utils/function.rb +6 -3
- data/lib/vwo/utils/impression.rb +76 -7
- data/lib/vwo/utils/request.rb +15 -3
- data/lib/vwo/utils/segment.rb +116 -0
- data/lib/vwo/utils/uuid.rb +3 -5
- data/lib/vwo/utils/validations.rb +96 -4
- metadata +30 -8
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2019 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -12,8 +12,6 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
# frozen_string_literal: true
|
16
|
-
|
17
15
|
require_relative '../logger'
|
18
16
|
require_relative '../enums'
|
19
17
|
require_relative '../utils/request'
|
@@ -50,25 +48,13 @@ class VWO
|
|
50
48
|
|
51
49
|
resp = VWO::Utils::Request.get(impression['url'], modified_event)
|
52
50
|
if resp.code == '200'
|
53
|
-
|
54
|
-
LogLevelEnum::INFO,
|
55
|
-
format(
|
56
|
-
LogMessageEnum::InfoMessages::IMPRESSION_SUCCESS,
|
57
|
-
file: FileNameEnum::EventDispatcher,
|
58
|
-
end_point: impression[:url],
|
59
|
-
campaign_id: impression[:experiment_id],
|
60
|
-
user_id: impression[:uId],
|
61
|
-
account_id: impression[:account_id],
|
62
|
-
variation_id: impression[:combination]
|
63
|
-
)
|
64
|
-
)
|
65
|
-
return true
|
51
|
+
true
|
66
52
|
else
|
67
53
|
@logger.log(
|
68
54
|
LogLevelEnum::ERROR,
|
69
55
|
format(LogMessageEnum::ErrorMessages::IMPRESSION_FAILED, file: FileNameEnum::EventDispatcher, end_point: impression['url'])
|
70
56
|
)
|
71
|
-
|
57
|
+
false
|
72
58
|
end
|
73
59
|
rescue StandardError
|
74
60
|
@logger.log(
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
class VWO
|
16
|
+
module Services
|
17
|
+
class HooksManager
|
18
|
+
# Hooks Manager is responsible for triggering callbacks useful to the end-user based on certain lifecycle events.
|
19
|
+
# Possible use with integrations when the user intends to send an event when a visitor is part of the experiment.
|
20
|
+
def initialize(config)
|
21
|
+
@logger = VWO::Logger.get_instance
|
22
|
+
if config.key?(:integrations) && config[:integrations].key?(:callback) && config[:integrations][:callback].is_a?(Method)
|
23
|
+
@callback = config[:integrations][:callback]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Executes the callback
|
28
|
+
# @param[Hash] properties Properties from the callback
|
29
|
+
def execute(properties)
|
30
|
+
if @callback
|
31
|
+
@callback.call(properties)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require_relative '../utils/function'
|
16
|
+
require_relative '../utils/segment'
|
17
|
+
|
18
|
+
class VWO
|
19
|
+
module Services
|
20
|
+
class OperandEvaluator
|
21
|
+
include VWO::Utils::Function
|
22
|
+
include VWO::Utils::Segment
|
23
|
+
|
24
|
+
# Checks if both values are same after 'down-casing'
|
25
|
+
# i.e. case insensitive check
|
26
|
+
#
|
27
|
+
# @param [String] :operand_value Leaf value from the segments
|
28
|
+
# @param [String] :custom_variables_value Value from the custom_variables
|
29
|
+
#
|
30
|
+
# @return [Boolean]
|
31
|
+
def lower?(operand_value, custom_variables_value)
|
32
|
+
operand_value.downcase == custom_variables_value.downcase
|
33
|
+
end
|
34
|
+
|
35
|
+
# Checks if custom_variables_value contains operand_value
|
36
|
+
#
|
37
|
+
# @param [String] :operand_value Leaf value from the segments
|
38
|
+
# @param [String] :custom_variables_value Value from the custom_variables
|
39
|
+
#
|
40
|
+
# @return [Boolean]
|
41
|
+
def contains?(operand_value, custom_variables_value)
|
42
|
+
custom_variables_value.include?(operand_value)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Checks if custom_variables_value ends with operand_value
|
46
|
+
#
|
47
|
+
# @param [String] :operand_value Leaf value from the segments
|
48
|
+
# @param [String] :custom_variables_value Value from the custom_variables
|
49
|
+
#
|
50
|
+
# @return [Boolean]
|
51
|
+
def starts_with?(operand_value, custom_variables_value)
|
52
|
+
custom_variables_value.end_with?(operand_value)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Checks if custom_variables_value starts with operand_value
|
56
|
+
#
|
57
|
+
# @param [String] :operand_value Leaf value from the segments
|
58
|
+
# @param [String] :custom_variables_value Value from the custom_variables
|
59
|
+
#
|
60
|
+
# @return [Boolean]
|
61
|
+
def ends_with?(operand_value, custom_variables_value)
|
62
|
+
custom_variables_value.start_with?(operand_value)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Checks if custom_variables_value matches the regex specified by operand_value
|
66
|
+
#
|
67
|
+
# @param [String] :operand_value Leaf value from the segments
|
68
|
+
# @param [String] :custom_variables_value Value from the custom_variables
|
69
|
+
#
|
70
|
+
# @return [Boolean]
|
71
|
+
def regex?(operand_value, custom_variables_value)
|
72
|
+
pattern = Regexp.new operand_value
|
73
|
+
custom_variables_value =~ pattern
|
74
|
+
end
|
75
|
+
|
76
|
+
# Checks if both values are exactly same
|
77
|
+
#
|
78
|
+
# @param [String] :operand_value Leaf value from the segments
|
79
|
+
# @param [String] :custom_variables_value Value from the custom_variables
|
80
|
+
#
|
81
|
+
# @return [Boolean]
|
82
|
+
def equals?(operand_value, custom_variables_value)
|
83
|
+
custom_variables_value == operand_value
|
84
|
+
end
|
85
|
+
|
86
|
+
# Identifies the condition stated in the leaf node and evaluates the result
|
87
|
+
#
|
88
|
+
# @param [String] :operand_value Leaf value from the segments
|
89
|
+
# @param [String] :custom_variables_value Value from the custom_variables
|
90
|
+
#
|
91
|
+
# @return [Boolean]
|
92
|
+
def evaluate_custom_variable?(operand, custom_variables)
|
93
|
+
# Extract custom_variable_key and custom_variables_value from operand
|
94
|
+
|
95
|
+
operand_key, operand = get_key_value(operand)
|
96
|
+
|
97
|
+
# Retrieve corresponding custom_variable value from custom_variables
|
98
|
+
custom_variables_value = custom_variables[operand_key]
|
99
|
+
|
100
|
+
# Pre process custom_variable value
|
101
|
+
custom_variables_value = process_custom_variables_value(custom_variables_value)
|
102
|
+
|
103
|
+
# Pre process operand value
|
104
|
+
operand_type, operand_value = process_operand_value(operand)
|
105
|
+
|
106
|
+
# Process the custom_variables_value and operand_value to make them of same type
|
107
|
+
operand_value, custom_variables_value = convert_to_true_types(operand_value, custom_variables_value)
|
108
|
+
|
109
|
+
# Call the self method corresponding to operand_type to evaluate the result
|
110
|
+
public_send("#{operand_type}?", operand_value, custom_variables_value)
|
111
|
+
end
|
112
|
+
|
113
|
+
def evaluate_user?(operand, custom_variables)
|
114
|
+
users = operand.split(',')
|
115
|
+
users.each do |user|
|
116
|
+
return true if user.strip == custom_variables['_vwo_user_id']
|
117
|
+
end
|
118
|
+
false
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require_relative '../logger'
|
16
|
+
require_relative '../enums'
|
17
|
+
require_relative './operand_evaluator'
|
18
|
+
require_relative '../utils/function'
|
19
|
+
require_relative '../utils/segment'
|
20
|
+
require_relative '../utils/validations'
|
21
|
+
|
22
|
+
class VWO
|
23
|
+
module Services
|
24
|
+
class SegmentEvaluator
|
25
|
+
include VWO::Enums
|
26
|
+
include VWO::Utils::Function
|
27
|
+
include VWO::Utils::Segment
|
28
|
+
include VWO::Utils::Validations
|
29
|
+
|
30
|
+
# Initializes this class with VWOLogger and OperandEvaluator
|
31
|
+
def initialize
|
32
|
+
@logger = VWO::Logger.get_instance
|
33
|
+
@operand_evaluator = OperandEvaluator.new
|
34
|
+
end
|
35
|
+
|
36
|
+
# A parser which recursively evaluates the expression tree represented by dsl,
|
37
|
+
# and returns the result
|
38
|
+
#
|
39
|
+
# @param[Hash] :dsl The segments defined in the campaign
|
40
|
+
# @param[Hash] :custom_variables Key/value pair of custom_attributes properties
|
41
|
+
#
|
42
|
+
# @return[Boolean]
|
43
|
+
#
|
44
|
+
def evaluate_util(dsl, custom_variables)
|
45
|
+
operator, sub_dsl = get_key_value(dsl)
|
46
|
+
if operator == OperatorTypes::NOT
|
47
|
+
!evaluate_util(sub_dsl, custom_variables)
|
48
|
+
elsif operator == OperatorTypes::AND
|
49
|
+
sub_dsl.all? { |y| evaluate_util(y, custom_variables) }
|
50
|
+
elsif operator == OperatorTypes::OR
|
51
|
+
sub_dsl.any? { |y| evaluate_util(y, custom_variables) }
|
52
|
+
elsif operator == OperandTypes::CUSTOM_VARIABLE
|
53
|
+
@operand_evaluator.evaluate_custom_variable?(sub_dsl, custom_variables)
|
54
|
+
elsif operator == OperandTypes::USER
|
55
|
+
@operand_evaluator.evaluate_user?(sub_dsl, custom_variables)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Evaluates the custom_variables passed against the pre-segmentation condition defined
|
60
|
+
# in the corresponding campaign.
|
61
|
+
#
|
62
|
+
# @param[String] :campaign_key Running_campaign's key
|
63
|
+
# @param[String] :user_id Unique user identifier
|
64
|
+
# @param[Hash] :dsl Segments provided in the settings_file
|
65
|
+
# @param[Hash] :custom_variables Custom variables provided in the apis
|
66
|
+
#
|
67
|
+
# @return[Boolean] true if user passed pre-segmentation, else false
|
68
|
+
#
|
69
|
+
def evaluate(campaign_key, user_id, dsl, custom_variables)
|
70
|
+
result = evaluate_util(dsl, custom_variables) if valid_value?(dsl)
|
71
|
+
result
|
72
|
+
rescue StandardError => e
|
73
|
+
@logger.log(
|
74
|
+
LogLevelEnum::ERROR,
|
75
|
+
format(
|
76
|
+
LogMessageEnum::ErrorMessages::SEGMENTATION_ERROR,
|
77
|
+
file: FileNameEnum::SegmentEvaluator,
|
78
|
+
user_id: user_id,
|
79
|
+
campaign_key: campaign_key,
|
80
|
+
custom_variables: custom_variables,
|
81
|
+
error_message: e
|
82
|
+
)
|
83
|
+
)
|
84
|
+
false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2019 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -12,8 +12,6 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
# frozen_string_literal: true
|
16
|
-
|
17
15
|
require_relative '../utils/function'
|
18
16
|
require_relative '../utils/request'
|
19
17
|
require_relative '../utils/validations'
|
@@ -27,7 +25,6 @@ class VWO
|
|
27
25
|
|
28
26
|
PROTOCOL = 'https'
|
29
27
|
HOSTNAME = ::VWO::CONSTANTS::ENDPOINTS::BASE_URL
|
30
|
-
PATH = ::VWO::CONSTANTS::ENDPOINTS::ACCOUNT_SETTINGS
|
31
28
|
|
32
29
|
def initialize(account_id, sdk_key)
|
33
30
|
@account_id = account_id
|
@@ -42,15 +39,20 @@ class VWO
|
|
42
39
|
# as received from the server,
|
43
40
|
# nil if no settings_file is found or sdk_key is incorrect
|
44
41
|
|
45
|
-
def get_settings_file
|
42
|
+
def get_settings_file(is_via_webhook = false)
|
46
43
|
is_valid_key = valid_number?(@account_id) || valid_string?(@account_id)
|
47
44
|
|
48
45
|
unless is_valid_key && valid_string?(@sdk_key)
|
49
|
-
|
46
|
+
puts 'account_id and sdk_key are required for fetching account settings. Aborting!'
|
50
47
|
return '{}'
|
51
48
|
end
|
52
49
|
|
53
|
-
|
50
|
+
if is_via_webhook
|
51
|
+
path = ::VWO::CONSTANTS::ENDPOINTS::WEBHOOK_SETTINGS_URL
|
52
|
+
else
|
53
|
+
path = ::VWO::CONSTANTS::ENDPOINTS::SETTINGS_URL
|
54
|
+
end
|
55
|
+
vwo_server_url = "#{PROTOCOL}://#{HOSTNAME}#{path}"
|
54
56
|
|
55
57
|
settings_file_response = ::VWO::Utils::Request.get(vwo_server_url, params)
|
56
58
|
|
@@ -60,12 +62,12 @@ class VWO
|
|
60
62
|
Got Status Code: #{settings_file_response.code}
|
61
63
|
and message: #{settings_file_response.body}.
|
62
64
|
DOC
|
63
|
-
|
65
|
+
puts message
|
64
66
|
return
|
65
67
|
end
|
66
68
|
settings_file_response.body
|
67
69
|
rescue StandardError => e
|
68
|
-
|
70
|
+
puts "Error fetching Settings File #{e}"
|
69
71
|
end
|
70
72
|
|
71
73
|
private
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2019 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -12,8 +12,6 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
# frozen_string_literal: true
|
16
|
-
|
17
15
|
require_relative '../logger'
|
18
16
|
require_relative '../enums'
|
19
17
|
require_relative '../utils/campaign'
|
@@ -46,6 +44,11 @@ class VWO
|
|
46
44
|
)
|
47
45
|
end
|
48
46
|
|
47
|
+
def update_settings_file(settings_file)
|
48
|
+
@settings_file = settings_file
|
49
|
+
process_settings_file
|
50
|
+
end
|
51
|
+
|
49
52
|
def get_settings_file
|
50
53
|
@settings_file
|
51
54
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
class VWO
|
16
|
+
module Services
|
17
|
+
class UsageStats
|
18
|
+
attr_reader :usage_stats
|
19
|
+
# Initialize the UsageStats
|
20
|
+
def initialize(stats, is_development_mode = false)
|
21
|
+
@usage_stats = {}
|
22
|
+
unless is_development_mode
|
23
|
+
@usage_stats = stats
|
24
|
+
@usage_stats[:_l] = 1 if @usage_stats.length > 0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/vwo/user_storage.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2019 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -12,8 +12,6 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
# frozen_string_literal: true
|
16
|
-
|
17
15
|
class VWO
|
18
16
|
# UserStorage Class is used to store user-variation mapping.
|
19
17
|
# Override this class to implement your own functionality.
|
data/lib/vwo/utils/campaign.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2019 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -12,8 +12,6 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
# frozen_string_literal: true
|
16
|
-
|
17
15
|
require_relative '../logger'
|
18
16
|
require_relative '../enums'
|
19
17
|
require_relative '../constants'
|
@@ -25,18 +23,6 @@ class VWO
|
|
25
23
|
include VWO::Enums
|
26
24
|
include VWO::CONSTANTS
|
27
25
|
|
28
|
-
# Finds and Returns campaign from given campaign_key.
|
29
|
-
#
|
30
|
-
# @param[Hash] :settings_file Settings file
|
31
|
-
# @param[String] :campaign_key Campaign identifier key
|
32
|
-
# @return[Hash] :campaign object
|
33
|
-
|
34
|
-
def get_campaign(settings_file, campaign_key)
|
35
|
-
(settings_file['campaigns'] || []).find do |campaign|
|
36
|
-
campaign['key'] == campaign_key
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
26
|
# Sets variation allocation range in the provided campaign
|
41
27
|
#
|
42
28
|
# @param [Hash]: Campaign object
|
@@ -72,23 +58,48 @@ class VWO
|
|
72
58
|
end
|
73
59
|
|
74
60
|
# Returns goal from given campaign_key and gaol_identifier.
|
75
|
-
# @param[
|
76
|
-
# @param[String] :campaign_key Campaign identifier key
|
61
|
+
# @param[String] :campaign Campaign object
|
77
62
|
# @param[String] :goal_identifier Goal identifier
|
78
63
|
#
|
79
64
|
# @return[Hash] Goal corresponding to Goal_identifier in respective campaign
|
80
65
|
|
81
|
-
def get_campaign_goal(
|
82
|
-
return unless
|
83
|
-
|
84
|
-
campaign = get_campaign(settings_file, campaign_key)
|
85
|
-
return unless campaign
|
66
|
+
def get_campaign_goal(campaign, goal_identifier)
|
67
|
+
return unless campaign && goal_identifier
|
86
68
|
|
87
69
|
campaign['goals'].find do |goal|
|
88
70
|
goal['identifier'] == goal_identifier
|
89
71
|
end
|
90
72
|
end
|
91
73
|
|
74
|
+
# Returns segments from the campaign
|
75
|
+
# @param[Hash] campaign Running campaign
|
76
|
+
# @return[Hash] A dsl of segments
|
77
|
+
#
|
78
|
+
def get_segments(campaign)
|
79
|
+
campaign['segments']
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns control variation from a given campaign
|
83
|
+
# @param[Hash] campaign Running campaign
|
84
|
+
# @return[Hash] variation Control variation from the campaign, ie having id = 1
|
85
|
+
|
86
|
+
def get_control_variation(campaign)
|
87
|
+
campaign['variations'].find do |variation|
|
88
|
+
variation['id'] == 1
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns variable from given variables list.
|
93
|
+
# @params[Array] variables List of variables, whether in campaigns or inside variation
|
94
|
+
# @param[String] variable_key Variable identifier
|
95
|
+
# @return[Hash] Variable corresponding to variable_key in given variable list
|
96
|
+
|
97
|
+
def get_variable(variables, variable_key)
|
98
|
+
variables.find do |variable|
|
99
|
+
variable['key'] == variable_key
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
92
103
|
private
|
93
104
|
|
94
105
|
# Returns the bucket size of variation.
|
@@ -120,6 +131,124 @@ class VWO
|
|
120
131
|
variation['name'] == variation_name
|
121
132
|
end
|
122
133
|
end
|
134
|
+
|
135
|
+
# Finds and Returns campaign from given campaign_key.
|
136
|
+
# [Hash] :settings_file Settings file for the project
|
137
|
+
# [String] :campaign_key Campaign identifier key
|
138
|
+
# @return[Hash] Campaign object
|
139
|
+
|
140
|
+
def get_campaign(settings_file, campaign_key)
|
141
|
+
settings_file['campaigns'].find do |campaign|
|
142
|
+
campaign['key'] == campaign_key
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# fetch campaigns from settings
|
147
|
+
#
|
148
|
+
# [string|array|nil] :campaign_key
|
149
|
+
# [Hash] :settings_file
|
150
|
+
# [string] :goal_identifier
|
151
|
+
# [string] :goal_type_to_track
|
152
|
+
# @return[Hash]
|
153
|
+
def get_campaigns(settings_file, campaign_key, goal_identifier, goal_type_to_track = 'ALL')
|
154
|
+
campaigns = []
|
155
|
+
if campaign_key.nil?
|
156
|
+
campaigns = get_campaigns_for_goal(settings_file, goal_identifier, goal_type_to_track)
|
157
|
+
elsif campaign_key.is_a?(Array)
|
158
|
+
campaigns = get_campaigns_from_campaign_keys(campaign_key, settings_file, goal_identifier, goal_type_to_track)
|
159
|
+
elsif campaign_key.is_a?(String)
|
160
|
+
campaign = get_campaign_for_campaign_key_and_goal(campaign_key, settings_file, goal_identifier, goal_type_to_track)
|
161
|
+
if campaign
|
162
|
+
campaigns = [campaign]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
if campaigns.length() == 0
|
166
|
+
VWO::Logger.get_instance.log(
|
167
|
+
LogLevelEnum::ERROR,
|
168
|
+
format(
|
169
|
+
LogMessageEnum::ErrorMessages::NO_CAMPAIGN_FOUND,
|
170
|
+
file: FileNameEnum::CampaignUtil,
|
171
|
+
goal_identifier: goal_identifier
|
172
|
+
)
|
173
|
+
)
|
174
|
+
end
|
175
|
+
return campaigns
|
176
|
+
end
|
177
|
+
|
178
|
+
# fetch all running campaigns (having goal identifier goal_type_to_track and goal type CUSTOM|REVENUE|ALL) from settings
|
179
|
+
#
|
180
|
+
# [Hash] :settings_file
|
181
|
+
# [string] :goal_identifier
|
182
|
+
# [string] :goal_type_to_track
|
183
|
+
# @return[Hash]
|
184
|
+
def get_campaigns_for_goal(settings_file, goal_identifier, goal_type_to_track = 'ALL')
|
185
|
+
campaigns = []
|
186
|
+
if settings_file
|
187
|
+
settings_file['campaigns'].each do |campaign|
|
188
|
+
if campaign.key?(:status) && campaign[:status] != 'RUNNING'
|
189
|
+
next
|
190
|
+
end
|
191
|
+
goal = get_campaign_goal(campaign, goal_identifier)
|
192
|
+
if validate_goal(goal, goal_type_to_track)
|
193
|
+
campaigns.append(campaign)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
campaigns
|
198
|
+
end
|
199
|
+
|
200
|
+
def validate_goal(goal, goal_type_to_track)
|
201
|
+
result = goal && (
|
202
|
+
goal_type_to_track == 'ALL' ||
|
203
|
+
(
|
204
|
+
GOAL_TYPES.has_value?(goal['type']) &&
|
205
|
+
(GOAL_TYPES.key? goal_type_to_track) &&
|
206
|
+
goal['type'] == GOAL_TYPES[goal_type_to_track]
|
207
|
+
)
|
208
|
+
)
|
209
|
+
return result
|
210
|
+
end
|
211
|
+
|
212
|
+
def get_campaigns_from_campaign_keys(campaign_keys, settings_file, goal_identifier, goal_type_to_track = 'ALL')
|
213
|
+
campaigns = []
|
214
|
+
campaign_keys.each do |campaign_key|
|
215
|
+
|
216
|
+
campaign = get_campaign_for_campaign_key_and_goal(campaign_key, settings_file, goal_identifier, goal_type_to_track)
|
217
|
+
if campaign
|
218
|
+
campaigns.append(campaign)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
campaigns
|
222
|
+
end
|
223
|
+
|
224
|
+
def get_campaign_for_campaign_key_and_goal(campaign_key, settings_file, goal_identifier, goal_type_to_track)
|
225
|
+
campaign = get_running_campaign(campaign_key, settings_file)
|
226
|
+
if campaign
|
227
|
+
goal = get_campaign_goal(campaign, goal_identifier)
|
228
|
+
if validate_goal(goal, goal_type_to_track)
|
229
|
+
return campaign
|
230
|
+
end
|
231
|
+
end
|
232
|
+
nil
|
233
|
+
end
|
234
|
+
|
235
|
+
def get_running_campaign(campaign_key, settings_file)
|
236
|
+
campaign = get_campaign(settings_file, campaign_key)
|
237
|
+
if campaign.nil? || (campaign['status'] != 'RUNNING')
|
238
|
+
@logger.log(
|
239
|
+
LogLevelEnum::ERROR,
|
240
|
+
format(
|
241
|
+
LogMessageEnum::ErrorMessages::CAMPAIGN_NOT_RUNNING,
|
242
|
+
file: FILE,
|
243
|
+
campaign_key: campaign_key,
|
244
|
+
api_name: ApiMethods::TRACK
|
245
|
+
)
|
246
|
+
)
|
247
|
+
nil
|
248
|
+
end
|
249
|
+
return campaign
|
250
|
+
end
|
251
|
+
|
123
252
|
end
|
124
253
|
end
|
125
254
|
end
|