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.
@@ -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
- @logger.log(
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
- return false
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
- STDERR.puts 'account_id and sdk_key are required for fetching account settings. Aborting!'
46
+ puts 'account_id and sdk_key are required for fetching account settings. Aborting!'
50
47
  return '{}'
51
48
  end
52
49
 
53
- vwo_server_url = "#{PROTOCOL}://#{HOSTNAME}#{PATH}"
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
- STDERR.puts message
65
+ puts message
64
66
  return
65
67
  end
66
68
  settings_file_response.body
67
69
  rescue StandardError => e
68
- STDERR.puts "Error fetching Settings File #{e}"
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
@@ -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.
@@ -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[Hash] :settings_file Settings file
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(settings_file, campaign_key, goal_identifier)
82
- return unless settings_file && campaign_key && goal_identifier
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