vwo-sdk 1.6.0 → 1.16.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 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.
@@ -44,6 +44,11 @@ class VWO
44
44
  )
45
45
  end
46
46
 
47
+ def update_settings_file(settings_file)
48
+ @settings_file = settings_file
49
+ process_settings_file
50
+ end
51
+
47
52
  def get_settings_file
48
53
  @settings_file
49
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-2020 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.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 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.
@@ -142,6 +142,113 @@ class VWO
142
142
  campaign['key'] == campaign_key
143
143
  end
144
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.push(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.push(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
+
145
252
  end
146
253
  end
147
254
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 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.
@@ -26,13 +26,36 @@ class VWO
26
26
  include VWO::Enums
27
27
  include VWO::Utils::Impression
28
28
 
29
- def get_url_params(settings_file, tag_key, tag_value, user_id)
29
+ def get_url_params(settings_file, tag_key, tag_value, user_id, sdk_key)
30
30
  url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL + ENDPOINTS::PUSH
31
31
  tag = { 'u' => {} }
32
32
  tag['u'][tag_key] = tag_value
33
33
 
34
34
  params = get_common_properties(user_id, settings_file)
35
- params.merge!('url' => url, 'tags' => JSON.generate(tag))
35
+ params.merge!('url' => url, 'tags' => JSON.generate(tag), 'env' => sdk_key)
36
+
37
+ VWO::Logger.get_instance.log(
38
+ LogLevelEnum::DEBUG,
39
+ format(
40
+ LogMessageEnum::DebugMessages::PARAMS_FOR_PUSH_CALL,
41
+ file: FileNameEnum::CustomDimensionsUtil,
42
+ properties: JSON.generate(params)
43
+ )
44
+ )
45
+ params
46
+ end
47
+
48
+ def get_batch_event_url_params(settings_file, tag_key, tag_value, user_id)
49
+ tag = { 'u' => {} }
50
+ tag['u'][tag_key] = tag_value
51
+
52
+ account_id = settings_file['accountId']
53
+ params = {
54
+ 'eT' => 3,
55
+ 't' => JSON.generate(tag),
56
+ 'u' => generator_for(user_id, account_id),
57
+ 'sId' => get_current_unix_timestamp
58
+ }
36
59
 
37
60
  VWO::Logger.get_instance.log(
38
61
  LogLevelEnum::DEBUG,
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 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.
@@ -38,6 +38,8 @@ class VWO
38
38
  return value.to_f if variable_type == VariableTypes::DOUBLE
39
39
 
40
40
  return !value || value == 0 ? false : true if variable_type == VariableTypes.BOOLEAN
41
+
42
+ return value if variable_type == VariableTypes::JSON
41
43
  rescue StandardError => _e
42
44
  VWO::Logger.get_instance.log(
43
45
  LogLevelEnum::ERROR,
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 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.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 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.
@@ -31,16 +31,17 @@ class VWO
31
31
 
32
32
  # Creates the impression from the arguments passed
33
33
  #
34
- # @param[Hash] :settings_file Settings file object
34
+ # @param[Hash] :settings_file Settings file object
35
35
  # @param[String] :campaign_id Campaign identifier
36
36
  # @param[String] :variation_id Variation identifier
37
37
  # @param[String] :user_id User identifier
38
+ # @param[String] :sdk_key SDK Key
38
39
  # @param[String] :goal_id Goal identifier, if building track impression
39
40
  # @param[String|Float|Integer|nil) :revenue Number value, in any representation, if building track impression
40
41
  #
41
42
  # @return[nil|Hash] None if campaign ID or variation ID is invalid,
42
43
  # Else Properties(dict)
43
- def create_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil)
44
+ def create_impression(settings_file, campaign_id, variation_id, user_id, sdk_key, goal_id = nil, revenue = nil, usage_stats = {})
44
45
  return unless valid_number?(campaign_id) && valid_string?(user_id)
45
46
 
46
47
  is_track_user_api = true
@@ -51,17 +52,19 @@ class VWO
51
52
  account_id: account_id,
52
53
  experiment_id: campaign_id,
53
54
  ap: PLATFORM,
54
- uId: CGI.escape(user_id.encode('utf-8')),
55
55
  combination: variation_id,
56
56
  random: get_random_number,
57
57
  sId: get_current_unix_timestamp,
58
- u: generator_for(user_id, account_id)
58
+ u: generator_for(user_id, account_id),
59
+ env: sdk_key
59
60
  }
60
61
  # Version and SDK constants
61
62
  sdk_version = Gem.loaded_specs['vwo_sdk'] ? Gem.loaded_specs['vwo_sdk'].version : VWO::SDK_VERSION
62
63
  impression['sdk'] = 'ruby'
63
64
  impression['sdk-v'] = sdk_version
64
65
 
66
+ impression = usage_stats.merge(impression)
67
+
65
68
  url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL
66
69
  logger = VWO::Logger.get_instance
67
70
 
@@ -107,9 +110,57 @@ class VWO
107
110
  'ap' => PLATFORM,
108
111
  'sId' => get_current_unix_timestamp,
109
112
  'u' => generator_for(user_id, account_id),
110
- 'account_id' => account_id,
111
- 'uId' => CGI.escape(user_id.encode('utf-8'))
113
+ 'account_id' => account_id
114
+ }
115
+ end
116
+
117
+ # Creates properties for the bulk impression event
118
+ #
119
+ # @param[Hash] :settings_file Settings file object
120
+ # @param[String] :campaign_id Campaign identifier
121
+ # @param[String] :variation_id Variation identifier
122
+ # @param[String] :user_id User identifier
123
+ # @param[String] :sdk_key SDK Key
124
+ # @param[String] :goal_id Goal identifier, if building track impression
125
+ # @param[String|Float|Integer|nil) :revenue Number value, in any representation, if building track impression
126
+ #
127
+ # @return[nil|Hash] None if campaign ID or variation ID is invalid,
128
+ # Else Properties(dict)
129
+ def create_bulk_event_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil)
130
+ return unless valid_number?(campaign_id) && valid_string?(user_id)
131
+ is_track_user_api = true
132
+ is_track_user_api = false unless goal_id.nil?
133
+ account_id = settings_file['accountId']
134
+ impression = {
135
+ eT: is_track_user_api ? 1 : 2,
136
+ e: campaign_id,
137
+ c: variation_id,
138
+ u: generator_for(user_id, account_id),
139
+ sId: get_current_unix_timestamp
112
140
  }
141
+ logger = VWO::Logger.get_instance
142
+ if is_track_user_api
143
+ logger.log(
144
+ LogLevelEnum::DEBUG,
145
+ format(
146
+ LogMessageEnum::DebugMessages::IMPRESSION_FOR_TRACK_USER,
147
+ file: FileNameEnum::ImpressionUtil,
148
+ properties: JSON.generate(impression)
149
+ )
150
+ )
151
+ else
152
+ impression['g'] = goal_id
153
+ impression['r'] = revenue if revenue
154
+ logger.log(
155
+ LogLevelEnum::DEBUG,
156
+ format(
157
+ LogMessageEnum::DebugMessages::IMPRESSION_FOR_TRACK_GOAL,
158
+ file: FileNameEnum::ImpressionUtil,
159
+ properties: JSON.generate(impression)
160
+ )
161
+ )
162
+ end
163
+ impression
113
164
  end
114
165
  end
115
166
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 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.
@@ -24,6 +24,20 @@ class VWO
24
24
  uri.query = URI.encode_www_form(params)
25
25
  Net::HTTP.get_response(uri)
26
26
  end
27
+
28
+ def self.post(url, params, post_data)
29
+ uri = URI.parse(url)
30
+ http = Net::HTTP.new(uri.host, uri.port)
31
+ http.use_ssl = true
32
+ uri.query = URI.encode_www_form(params)
33
+ headers = {
34
+ 'Authorization'=>params[:env],
35
+ 'Content-Type' =>'application/json',
36
+ 'Accept'=>'application/json'
37
+ }
38
+ response = http.post(uri, post_data.to_json, headers)
39
+ response
40
+ end
27
41
  end
28
42
  end
29
43
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 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.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 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.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 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.
@@ -15,6 +15,9 @@
15
15
  require 'json'
16
16
  require 'json-schema'
17
17
  require_relative '../schemas/settings_file'
18
+ require_relative '../logger'
19
+ require_relative '../enums'
20
+ require_relative '../constants'
18
21
 
19
22
  class VWO
20
23
  module Utils
@@ -59,6 +62,87 @@ class VWO
59
62
  def valid_basic_data_type?(val)
60
63
  valid_number?(val) || valid_string?(val) || valid_boolean?(val)
61
64
  end
65
+
66
+ # Validates if the value passed batch_events has correct data type and values or not.
67
+ #
68
+ # Args: batch_events [Hash]: value to be tested
69
+ #
70
+ # @return: [Boolean]: True if all conditions are passed else False
71
+ def is_valid_batch_event_settings(batch_events)
72
+ logger = VWO::Logger.get_instance
73
+ events_per_request = batch_events[:events_per_request]
74
+ request_time_interval = batch_events[:request_time_interval]
75
+
76
+ unless events_per_request || request_time_interval
77
+ logger.log(
78
+ VWO::LogLevelEnum::ERROR,
79
+ format(
80
+ VWO::LogMessageEnum::ErrorMessages::EVENT_BATCHING_INSUFFICIENT,
81
+ file: VWO::FileNameEnum::ValidateUtil
82
+ )
83
+ )
84
+ return false
85
+ end
86
+
87
+ if (request_time_interval && !valid_number?(request_time_interval))
88
+ logger.log(
89
+ VWO::LogLevelEnum::ERROR,
90
+ format(
91
+ VWO::LogMessageEnum::ErrorMessages::REQUEST_TIME_INTERVAL_INVALID,
92
+ file: VWO::FileNameEnum::ValidateUtil
93
+ )
94
+ )
95
+ return false
96
+ end
97
+
98
+ if (events_per_request && !valid_number?(events_per_request))
99
+ logger.log(
100
+ VWO::LogLevelEnum::ERROR,
101
+ format(
102
+ VWO::LogMessageEnum::ErrorMessages::EVENTS_PER_REQUEST_INVALID,
103
+ file: VWO::FileNameEnum::ValidateUtil
104
+ )
105
+ )
106
+ return false
107
+ end
108
+
109
+ if events_per_request && (events_per_request < VWO::MIN_EVENTS_PER_REQUEST || events_per_request > VWO::MAX_EVENTS_PER_REQUEST)
110
+ logger.log(
111
+ VWO::LogLevelEnum::ERROR,
112
+ format(
113
+ VWO::LogMessageEnum::ErrorMessages::EVENTS_PER_REQUEST_OUT_OF_BOUNDS,
114
+ file: VWO::FileNameEnum::ValidateUtil,
115
+ min_value: VWO::MIN_EVENTS_PER_REQUEST,
116
+ max_value: VWO::MAX_EVENTS_PER_REQUEST
117
+ )
118
+ )
119
+ return false
120
+ end
121
+
122
+ if request_time_interval && request_time_interval < VWO::MIN_REQUEST_TIME_INTERVAL
123
+ logger.log(
124
+ VWO::LogLevelEnum::ERROR,
125
+ format(
126
+ VWO::LogMessageEnum::ErrorMessages::REQUEST_TIME_INTERVAL_OUT_OF_BOUNDS,
127
+ file: VWO::FileNameEnum::ValidateUtil,
128
+ min_value: VWO::MIN_REQUEST_TIME_INTERVAL
129
+ )
130
+ )
131
+ return false
132
+ end
133
+
134
+ if batch_events.key?(:flushCallback) && !batch_events[:flushCallback].is_a?(Method)
135
+ logger.log(
136
+ VWO::LogLevelEnum::ERROR,
137
+ format(
138
+ VWO::LogMessageEnum::ErrorMessages::FLUSH_CALLBACK_INVALID,
139
+ file: VWO::FileNameEnum::ValidateUtil
140
+ )
141
+ )
142
+ return false
143
+ end
144
+ true
145
+ end
62
146
  end
63
147
  end
64
148
  end