itly-sdk 0.1.0
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 +7 -0
- data/.rspec +1 -0
- data/Gemfile +12 -0
- data/Steepfile +9 -0
- data/bin/console +15 -0
- data/bin/rspec +18 -0
- data/bin/setup +8 -0
- data/itly-sdk.gemspec +29 -0
- data/lib/itly-sdk.rb +15 -0
- data/lib/itly/event.rb +58 -0
- data/lib/itly/exceptions.rb +10 -0
- data/lib/itly/itly.rb +404 -0
- data/lib/itly/loggers.rb +55 -0
- data/lib/itly/options.rb +114 -0
- data/lib/itly/options/environment.rb +24 -0
- data/lib/itly/options/validation.rb +17 -0
- data/lib/itly/plugin.rb +116 -0
- data/lib/itly/plugin_call_options.rb +18 -0
- data/lib/itly/plugin_options.rb +22 -0
- data/lib/itly/plugins.rb +25 -0
- data/lib/itly/validation_response.rb +41 -0
- data/lib/itly/version.rb +6 -0
- data/sig/aliases.rbs +3 -0
- data/sig/event.rbs +16 -0
- data/sig/exceptions.rbs +11 -0
- data/sig/itly.rbs +32 -0
- data/sig/lib/monitor_mixin.rbs +3 -0
- data/sig/loggers.rbs +8 -0
- data/sig/options.rbs +18 -0
- data/sig/options/environment.rbs +8 -0
- data/sig/options/validation.rbs +10 -0
- data/sig/plugin.rbs +21 -0
- data/sig/plugin_call_options.rbs +4 -0
- data/sig/plugin_options.rbs +10 -0
- data/sig/plugins.rbs +4 -0
- data/sig/validation_response.rbs +13 -0
- metadata +85 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f956ac42d9761509feed18e020c4c5afee5cfa5928f099e1895b982e59dd5d10
|
4
|
+
data.tar.gz: e980e7b80fab1c12ce52ec928afbd264221a1d0ba9d1ba9570c69c849e9a42a9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 85ab4bfde5fc16accc2629d83417ca697dfbdd6511ad26b95bfdde8cdff39346f76034897ae028916d452ed1a37afe8a37e4a2a406cf19187dbfbfd9352cd20e
|
7
|
+
data.tar.gz: 5b90b6d14135f194aa63c1b3d0cd09119a11d1b84cae7b3f93d84455220a97c7236f51606250c7aadd2309aef085df334c6e1cfbd72e8d7dd9ac476b148a1777
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/Gemfile
ADDED
data/Steepfile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'itly-sdk'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start(__FILE__)
|
data/bin/rspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Configure and load RBS
|
5
|
+
unless ENV['DISABLE_TYPE_CHECKING']
|
6
|
+
ENV['RBS_TEST_TARGET'] = 'Itly::*, AcceptancePlugin, AcceptancePluginCallOptions, FakeCallOptions'
|
7
|
+
ENV['RBS_TEST_LOGLEVEL'] = 'warn'
|
8
|
+
ENV['RBS_TEST_DOUBLE_SUITE'] = 'rspec'
|
9
|
+
ENV['RBS_TEST_OPT'] = '-I./sig -I./spec/sig'
|
10
|
+
|
11
|
+
require 'rbs/test/setup'
|
12
|
+
end
|
13
|
+
|
14
|
+
# Start RSpec
|
15
|
+
require 'rspec/core'
|
16
|
+
|
17
|
+
ENV['RSPEC_RUN_FROM_SCRIPT'] = 'true'
|
18
|
+
RSpec::Core::Runner.invoke
|
data/bin/setup
ADDED
data/itly-sdk.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/itly/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'itly-sdk'
|
7
|
+
spec.version = Itly::VERSION
|
8
|
+
spec.authors = ['Iteratively', 'Benjamin Bouchet', 'Justin Fiedler', 'Andrey Sokolov']
|
9
|
+
spec.email = ['support@iterative.ly']
|
10
|
+
|
11
|
+
spec.summary = 'Iteratively SDK for Ruby'
|
12
|
+
spec.description = 'Track and validate analytics with a unified, extensible interface ' \
|
13
|
+
'that works with all your 3rd party analytics providers.'
|
14
|
+
spec.homepage = 'https://github.com/iterativelyhq/itly-sdk-ruby'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.6.0')
|
17
|
+
|
18
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
|
19
|
+
|
20
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
21
|
+
spec.metadata['source_code_uri'] = 'https://github.com/iterativelyhq/itly-sdk-ruby/sdk'
|
22
|
+
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
26
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
27
|
+
end
|
28
|
+
spec.require_paths = ['lib']
|
29
|
+
end
|
data/lib/itly-sdk.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'itly/version'
|
4
|
+
require_relative 'itly/options/environment'
|
5
|
+
require_relative 'itly/options/validation'
|
6
|
+
require_relative 'itly/exceptions'
|
7
|
+
require_relative 'itly/validation_response'
|
8
|
+
require_relative 'itly/plugin_call_options'
|
9
|
+
require_relative 'itly/plugin_options'
|
10
|
+
require_relative 'itly/plugins'
|
11
|
+
require_relative 'itly/plugin'
|
12
|
+
require_relative 'itly/options'
|
13
|
+
require_relative 'itly/event'
|
14
|
+
require_relative 'itly/itly'
|
15
|
+
require_relative 'itly/loggers'
|
data/lib/itly/event.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Itly
|
4
|
+
##
|
5
|
+
# Event object used to communicate data between Itly core SDK and its plugins
|
6
|
+
#
|
7
|
+
# Properties:
|
8
|
+
# +name+: The event's name.
|
9
|
+
# +properties+: The event's properties.
|
10
|
+
# +id+: The event's unique ID in Iteratively.
|
11
|
+
# +version+: The event's version, e.g. 2.0.1.
|
12
|
+
# +plugins+: Granular Event Destinations: to control to which plugin to forward this event to
|
13
|
+
#
|
14
|
+
class Event
|
15
|
+
attr_reader :name, :properties, :id, :version, :plugins
|
16
|
+
|
17
|
+
##
|
18
|
+
# Create a new Event object
|
19
|
+
#
|
20
|
+
# @param [String] name: The event's name.
|
21
|
+
# @param [Hash] properties: The event's properties.
|
22
|
+
# @param [String] id: The event's unique ID in Iteratively.
|
23
|
+
# @param [String] version: The event's version, e.g. 2.0.1.
|
24
|
+
# @param [Hash] plugins: Granular Event Destinations: to control to which plugin to forward this event to
|
25
|
+
#
|
26
|
+
def initialize(name:, properties: {}, id: nil, version: nil, plugins: {})
|
27
|
+
@name = name
|
28
|
+
@properties = properties
|
29
|
+
@id = id
|
30
|
+
@version = version
|
31
|
+
@plugins = plugins.transform_keys(&:to_s)
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Describe the object
|
36
|
+
#
|
37
|
+
# @return [String] the object description
|
38
|
+
#
|
39
|
+
def to_s
|
40
|
+
str = "#<#{self.class.name}: name: #{name}, "
|
41
|
+
str += "id: #{id}, " unless id.nil?
|
42
|
+
str += "version: #{version}, " unless version.nil?
|
43
|
+
str + "properties: #{properties}>"
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Compare the object to another
|
48
|
+
#
|
49
|
+
# @param [Object] other: the object to compare to
|
50
|
+
#
|
51
|
+
# @return [True/False] are the objects similar
|
52
|
+
#
|
53
|
+
def ==(other)
|
54
|
+
other.class == self.class && [name, properties, id, version] ==
|
55
|
+
[other.name, other.properties, other.id, other.version]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/itly/itly.rb
ADDED
@@ -0,0 +1,404 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
##
|
4
|
+
# Itly main class
|
5
|
+
#
|
6
|
+
class Itly
|
7
|
+
include Itly::Plugins
|
8
|
+
|
9
|
+
##
|
10
|
+
# Create a new Itly object.
|
11
|
+
#
|
12
|
+
# The +is_initialized+ instance variable is a True/False flag indicating
|
13
|
+
# if the +load+ method was called on the object.
|
14
|
+
#
|
15
|
+
def initialize
|
16
|
+
@is_initialized = false
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Load options ans the plugins. It must be called only once on an object.
|
21
|
+
#
|
22
|
+
# Accept an optional block to define the options. The variable yielded in
|
23
|
+
# the block is of type `Itly::Options`.
|
24
|
+
#
|
25
|
+
# Calls the +load+ method of each plugin passing the +options+ object as an argument.
|
26
|
+
#
|
27
|
+
# @param [Hash, nil] context: to assign to the "context" Event object. Default to nil
|
28
|
+
#
|
29
|
+
def load(context: nil)
|
30
|
+
# Ensure #load was not already called on this object
|
31
|
+
raise InitializationError, 'Itly is already initialized.' if @is_initialized
|
32
|
+
|
33
|
+
# Create a new Options object and yield it is a block is provided
|
34
|
+
@options = Itly::Options.new
|
35
|
+
yield @options if block_given?
|
36
|
+
|
37
|
+
# Create the context event
|
38
|
+
@context = context.nil? ? nil : Itly::Event.new(name: 'context', properties: context)
|
39
|
+
|
40
|
+
# Log
|
41
|
+
logger&.info 'load()'
|
42
|
+
logger&.info 'Itly is disabled!' unless enabled?
|
43
|
+
logger&.warn 'No plugin enabled!' if options.plugins.empty?
|
44
|
+
|
45
|
+
# pass options to plugins
|
46
|
+
run_on_plugins { |plugin| plugin.load options: options.for_plugin } if enabled?
|
47
|
+
|
48
|
+
# Mark that the #load method was called on this object
|
49
|
+
@is_initialized = true
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Identify a user in your application and associate all future events with
|
54
|
+
# their identity, or to set their traits.
|
55
|
+
#
|
56
|
+
# Validates the +properties+ with all registered plugins first.
|
57
|
+
# Raises a Itly::ValidationError if one of the validations failed and
|
58
|
+
# if your set the +options.validation+ value to +ERROR_ON_INVALID+.
|
59
|
+
#
|
60
|
+
# Call +identify+ on all plugins and call +post_identify+ on all plugins.
|
61
|
+
#
|
62
|
+
# Example:
|
63
|
+
#
|
64
|
+
# itly.identify user_id: 'MyUser123', role: 'admin'
|
65
|
+
#
|
66
|
+
# @param [String] user_id: the id of the user in your application
|
67
|
+
# @param [Hash] properties: the user's traits to pass to your application
|
68
|
+
# @param [Hash] options: plugin specific option. The keys must correspond
|
69
|
+
# to a plugin id, and the values will be passed only to the plugin identified by the key.
|
70
|
+
#
|
71
|
+
def identify(user_id:, properties: {}, options: {})
|
72
|
+
# Run only if the object is enabled and was initialized
|
73
|
+
return unless was_initialized? && enabled?
|
74
|
+
|
75
|
+
# Log
|
76
|
+
log = Itly::Loggers.vars_to_log user_id: user_id, properties: properties, options: options
|
77
|
+
logger&.info "identify(#{log})"
|
78
|
+
|
79
|
+
# Validate and run on all plugins
|
80
|
+
event = Event.new name: 'identify', properties: properties
|
81
|
+
|
82
|
+
action = ->(plugin, combined_event) {
|
83
|
+
plugin.identify(
|
84
|
+
user_id: user_id, properties: combined_event.properties, options: options[plugin.id]
|
85
|
+
)
|
86
|
+
}
|
87
|
+
|
88
|
+
post_action = ->(plugin, combined_event, validation_results) {
|
89
|
+
plugin.post_identify(
|
90
|
+
user_id: user_id, properties: combined_event.properties, validation_results: validation_results
|
91
|
+
)
|
92
|
+
}
|
93
|
+
|
94
|
+
validate_and_send_to_plugins event: event, action: action, post_action: post_action
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# Associate a user with their group (for example, their department or company),
|
99
|
+
# or to set the group's traits.
|
100
|
+
#
|
101
|
+
# Validates the +properties+ with all registered plugins first.
|
102
|
+
# Raises a Itly::ValidationError if one of the validations failed and
|
103
|
+
# if your set the +options.validation+ value to +ERROR_ON_INVALID+.
|
104
|
+
#
|
105
|
+
# Call +group+ on all plugins and call +post_group+ on all plugins.
|
106
|
+
#
|
107
|
+
# Example:
|
108
|
+
#
|
109
|
+
# itly.group user_id: 'MyUser123', group_id: 'MyGroup456', name: 'Iteratively, Inc.'
|
110
|
+
#
|
111
|
+
# @param [String] user_id: the id of the user in your application
|
112
|
+
# @param [String] group_id: the id of the group in your application
|
113
|
+
# @param [Hash] properties: The list of properties to pass to your application
|
114
|
+
# @param [Hash] options: plugin specific option. The keys must correspond
|
115
|
+
# to a plugin id, and the values will be passed only to the plugin identified by the key.
|
116
|
+
#
|
117
|
+
def group(user_id:, group_id:, properties: {}, options: {})
|
118
|
+
# Run only if the object is enabled and was initialized
|
119
|
+
return unless was_initialized? && enabled?
|
120
|
+
|
121
|
+
# Log
|
122
|
+
log = Itly::Loggers.vars_to_log user_id: user_id, group_id: group_id, properties: properties, options: options
|
123
|
+
logger&.info "group(#{log})"
|
124
|
+
|
125
|
+
# Validate and run on all plugins
|
126
|
+
event = Event.new name: 'group', properties: properties
|
127
|
+
|
128
|
+
action = ->(plugin, combined_event) {
|
129
|
+
plugin.group(
|
130
|
+
user_id: user_id, group_id: group_id, properties: combined_event.properties,
|
131
|
+
options: options[plugin.id]
|
132
|
+
)
|
133
|
+
}
|
134
|
+
|
135
|
+
post_action = ->(plugin, combined_event, validation_results) {
|
136
|
+
plugin.post_group(
|
137
|
+
user_id: user_id, group_id: group_id, properties: combined_event.properties,
|
138
|
+
validation_results: validation_results
|
139
|
+
)
|
140
|
+
}
|
141
|
+
|
142
|
+
validate_and_send_to_plugins event: event, action: action, post_action: post_action
|
143
|
+
end
|
144
|
+
|
145
|
+
##
|
146
|
+
# The Page method lets you record page views, along with optional extra information about
|
147
|
+
# the page viewed by the user.
|
148
|
+
#
|
149
|
+
# Validates the +properties+ with all registered plugins first.
|
150
|
+
# Raises a Itly::ValidationError if one of the validations failed and
|
151
|
+
# if your set the +options.validation+ value to +ERROR_ON_INVALID+.
|
152
|
+
#
|
153
|
+
# Call +page+ on all plugins and call +post_page+ on all plugins.
|
154
|
+
#
|
155
|
+
# Example:
|
156
|
+
#
|
157
|
+
# itly.page user_id: 'MyUser123', category: 'Products', name: 'MyPage456', name: 'Iteratively, Inc.'
|
158
|
+
#
|
159
|
+
# @param [String] user_id: the id of the user in your application
|
160
|
+
# @param [String] category: the category of the page
|
161
|
+
# @param [String] name: the name of the page.
|
162
|
+
# @param [Hash] properties: The list of properties to pass to your application
|
163
|
+
# @param [Hash] options: plugin specific option. The keys must correspond
|
164
|
+
# to a plugin id, and the values will be passed only to the plugin identified by the key.
|
165
|
+
#
|
166
|
+
def page(user_id:, category: nil, name: nil, properties: {}, options: {})
|
167
|
+
# Run only if the object is enabled and was initialized
|
168
|
+
return unless was_initialized? && enabled?
|
169
|
+
|
170
|
+
# Log
|
171
|
+
log = Itly::Loggers.vars_to_log(
|
172
|
+
user_id: user_id, category: category, name: name, properties: properties, options: options
|
173
|
+
)
|
174
|
+
logger&.info "page(#{log})"
|
175
|
+
|
176
|
+
# Validate and run on all plugins
|
177
|
+
event = Event.new name: 'page', properties: properties
|
178
|
+
|
179
|
+
action = ->(plugin, combined_event) {
|
180
|
+
plugin.page(
|
181
|
+
user_id: user_id, category: category, name: name, properties: combined_event.properties,
|
182
|
+
options: options[plugin.id]
|
183
|
+
)
|
184
|
+
}
|
185
|
+
|
186
|
+
post_action = ->(plugin, combined_event, validation_results) {
|
187
|
+
plugin.post_page(
|
188
|
+
user_id: user_id, category: category, name: name, properties: combined_event.properties,
|
189
|
+
validation_results: validation_results
|
190
|
+
)
|
191
|
+
}
|
192
|
+
|
193
|
+
validate_and_send_to_plugins event: event, action: action, post_action: post_action
|
194
|
+
end
|
195
|
+
|
196
|
+
##
|
197
|
+
# Track an event, call the event's corresponding function on plugins.
|
198
|
+
#
|
199
|
+
# Validates the +properties+ of the +Event+ object passed as parameter
|
200
|
+
# with all registered plugins first.
|
201
|
+
# Raises a Itly::ValidationError if one of the validations failed and
|
202
|
+
# if your set the +options.validation+ value to +ERROR_ON_INVALID+.
|
203
|
+
#
|
204
|
+
# The properties of the +context+ instance attribute passed when called #load
|
205
|
+
# are merged with the +event+ parameter before validation and calling the event
|
206
|
+
# on your application.
|
207
|
+
#
|
208
|
+
# Call +track+ on all plugins and call +post_track+ on all plugins.
|
209
|
+
#
|
210
|
+
# Example:
|
211
|
+
#
|
212
|
+
# event = Itly::Event.new name: 'watched_video', properties: {'video_id' => 'MyVider123', watch_time: '123456'}
|
213
|
+
# itly.track user_id: 'MyUser123', event: event
|
214
|
+
#
|
215
|
+
# @param [String] user_id: the id of the user in your application
|
216
|
+
# @param [Event] event: the Event object to pass to your application
|
217
|
+
# @param [Hash] options: plugin specific option. The keys must correspond
|
218
|
+
# to a plugin id, and the values will be passed only to the plugin identified by the key.
|
219
|
+
#
|
220
|
+
def track(user_id:, event:, options: {})
|
221
|
+
# Run only if the object is enabled and was initialized
|
222
|
+
return unless was_initialized? && enabled?
|
223
|
+
|
224
|
+
# Log
|
225
|
+
log = Itly::Loggers.vars_to_log(
|
226
|
+
user_id: user_id, event: event&.name, properties: event&.properties, options: options
|
227
|
+
)
|
228
|
+
logger&.info "track(#{log})"
|
229
|
+
|
230
|
+
# Validate and run on all plugins
|
231
|
+
action = ->(plugin, combined_event) {
|
232
|
+
plugin.track user_id: user_id, event: combined_event, options: options[plugin.id]
|
233
|
+
}
|
234
|
+
|
235
|
+
post_action = ->(plugin, combined_event, validation_results) {
|
236
|
+
plugin.post_track user_id: user_id, event: combined_event, validation_results: validation_results
|
237
|
+
}
|
238
|
+
|
239
|
+
validate_and_send_to_plugins event: event, context: @context, action: action, post_action: post_action
|
240
|
+
end
|
241
|
+
|
242
|
+
##
|
243
|
+
# Associate one user ID with another (typically a known user ID with an anonymous one).
|
244
|
+
#
|
245
|
+
# Call +alias+ on all plugins and call +post_alias+ on all plugins.
|
246
|
+
#
|
247
|
+
# @param [String] user_id: The ID that the user will be identified by going forward. This is
|
248
|
+
# typically the user's database ID (as opposed to an anonymous ID), or their updated ID
|
249
|
+
# (for example, if the ID is an email address which the user just updated).
|
250
|
+
# @param [String] previous_id: The ID the user has been identified by so far.
|
251
|
+
# @param [Hash] options: plugin specific option. The keys must correspond
|
252
|
+
# to a plugin id, and the values will be passed only to the plugin identified by the key.
|
253
|
+
#
|
254
|
+
def alias(user_id:, previous_id:, options: {})
|
255
|
+
# Run only if the object is enabled and was initialized
|
256
|
+
return unless was_initialized? && enabled?
|
257
|
+
|
258
|
+
# Log
|
259
|
+
log = Itly::Loggers.vars_to_log user_id: user_id, previous_id: previous_id, options: options
|
260
|
+
logger&.info "alias(#{log})"
|
261
|
+
|
262
|
+
# Run on all plugins
|
263
|
+
run_on_plugins do |plugin|
|
264
|
+
plugin.alias user_id: user_id, previous_id: previous_id, options: options[plugin.id]
|
265
|
+
end
|
266
|
+
run_on_plugins do |plugin|
|
267
|
+
plugin.post_alias user_id: user_id, previous_id: previous_id
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
##
|
272
|
+
# Send +flush+ to your plugins.
|
273
|
+
#
|
274
|
+
# Call +flush+ on all plugins.
|
275
|
+
#
|
276
|
+
def flush
|
277
|
+
# Run only if the object is enabled and was initialized
|
278
|
+
return unless was_initialized? && enabled?
|
279
|
+
|
280
|
+
# Log
|
281
|
+
logger&.info 'flush()'
|
282
|
+
|
283
|
+
# Run on all plugins
|
284
|
+
run_on_plugins(&:flush)
|
285
|
+
end
|
286
|
+
|
287
|
+
##
|
288
|
+
# Send +shutdown+ to your plugins.
|
289
|
+
#
|
290
|
+
# Call +shutdown+ on all plugins.
|
291
|
+
#
|
292
|
+
def shutdown
|
293
|
+
# Run only if the object is enabled and was initialized
|
294
|
+
return unless was_initialized? && enabled?
|
295
|
+
|
296
|
+
# Log
|
297
|
+
logger&.info 'shutdown()'
|
298
|
+
|
299
|
+
# Run on all plugins
|
300
|
+
run_on_plugins(&:shutdown)
|
301
|
+
end
|
302
|
+
|
303
|
+
##
|
304
|
+
# Reset the SDK's (and all plugins') state. This method is usually called when a user logs out.
|
305
|
+
#
|
306
|
+
# Call +reset+ on all plugins.
|
307
|
+
#
|
308
|
+
def reset
|
309
|
+
# Run only if the object is enabled and was initialized
|
310
|
+
return unless was_initialized? && enabled?
|
311
|
+
|
312
|
+
# Log
|
313
|
+
logger&.info 'reset()'
|
314
|
+
|
315
|
+
# Run on all plugins
|
316
|
+
run_on_plugins(&:reset)
|
317
|
+
end
|
318
|
+
|
319
|
+
##
|
320
|
+
# Validate an Event
|
321
|
+
#
|
322
|
+
# Call +event+ on all plugins and collect their return values.
|
323
|
+
#
|
324
|
+
# @param [Event] event: the event to validate
|
325
|
+
#
|
326
|
+
# @return [Array] array of Itly::ValidationResponse objects that were generated by the plugins
|
327
|
+
#
|
328
|
+
def validate(event:)
|
329
|
+
return unless was_initialized? && validation_enabled?
|
330
|
+
|
331
|
+
# Log
|
332
|
+
log = Itly::Loggers.vars_to_log event: event
|
333
|
+
logger&.info "validate(#{log})"
|
334
|
+
|
335
|
+
# Run on all plugins
|
336
|
+
run_on_plugins { |plugin| plugin.validate event: event }
|
337
|
+
end
|
338
|
+
|
339
|
+
def is_loaded?
|
340
|
+
!!@is_initialized
|
341
|
+
end
|
342
|
+
|
343
|
+
private
|
344
|
+
|
345
|
+
def was_initialized?
|
346
|
+
@is_initialized ? true : raise(InitializationError, 'Itly is not initialized. Call #load { |options| ... }')
|
347
|
+
end
|
348
|
+
|
349
|
+
def validate_and_send_to_plugins(action:, post_action:, event:, context: nil)
|
350
|
+
# Perform validation on the context and the event
|
351
|
+
context_validations, event_validations, is_valid = validate_context_and_event context, event
|
352
|
+
validations = context_validations + event_validations
|
353
|
+
|
354
|
+
# Call the action on all plugins
|
355
|
+
event.properties.merge! context.properties if context
|
356
|
+
|
357
|
+
if is_valid || @options.validation == Itly::Options::Validation::TRACK_INVALID
|
358
|
+
run_on_plugins do |plugin|
|
359
|
+
action.call(plugin, event) unless event.plugins[plugin.id].is_a?(FalseClass)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
# Log all errors
|
364
|
+
log_validation_errors validations, event
|
365
|
+
|
366
|
+
# Call the post_action on all plugins
|
367
|
+
run_on_plugins do |plugin|
|
368
|
+
post_action.call(plugin, event, validations) unless event.plugins[plugin.id].is_a?(FalseClass)
|
369
|
+
end
|
370
|
+
|
371
|
+
# Throw an exception if requested
|
372
|
+
raise_validation_errors is_valid, validations, event
|
373
|
+
end
|
374
|
+
|
375
|
+
def validate_context_and_event(context, event)
|
376
|
+
# Validate the context
|
377
|
+
context_validations = (validate event: context if context) || []
|
378
|
+
|
379
|
+
# Validate the event
|
380
|
+
event_validations = validate(event: event) || []
|
381
|
+
|
382
|
+
# Check if all validation succeeded
|
383
|
+
is_valid = (context_validations + event_validations).all?(&:valid)
|
384
|
+
|
385
|
+
[context_validations, event_validations, is_valid]
|
386
|
+
end
|
387
|
+
|
388
|
+
def log_validation_errors(validations, event)
|
389
|
+
validations.reject(&:valid).each do |response|
|
390
|
+
@options.logger&.error %(Validation error for "#{event.name}" )\
|
391
|
+
"in #{response.plugin_id}. Message: #{response.message}"
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
def raise_validation_errors(is_valid, validations, event)
|
396
|
+
return unless !is_valid && @options.validation == Itly::Options::Validation::ERROR_ON_INVALID
|
397
|
+
|
398
|
+
messages = validations.reject(&:valid).collect(&:message)
|
399
|
+
messages = messages.select { |m| !m.nil? && m.length.positive? }
|
400
|
+
messages << "Unknown error validating #{event.name}" if messages.empty?
|
401
|
+
|
402
|
+
raise ValidationError, messages.join('. ')
|
403
|
+
end
|
404
|
+
end
|