amplitude-api 0.1.1 → 0.3.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 +4 -4
- data/.rubocop.yml +19 -1
- data/.travis.yml +2 -4
- data/Changelog.md +11 -1
- data/Gemfile +9 -7
- data/Gemfile.lock +10 -8
- data/Rakefile +7 -5
- data/amplitude-api.gemspec +17 -15
- data/lib/amplitude-api.rb +3 -4
- data/lib/amplitude_api.rb +48 -37
- data/lib/amplitude_api/config.rb +25 -4
- data/lib/amplitude_api/event.rb +75 -15
- data/lib/amplitude_api/identification.rb +3 -1
- data/lib/amplitude_api/version.rb +3 -1
- data/readme.md +4 -4
- data/spec/lib/amplitude_api/event_spec.rb +193 -112
- data/spec/lib/amplitude_api/identification_spec.rb +19 -17
- data/spec/lib/amplitude_api_spec.rb +265 -213
- data/spec/spec_helper.rb +7 -5
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59e87e342af629c6e87369ef210a272186236ec4e4ef9f9a101a2a590da59204
|
4
|
+
data.tar.gz: 7e207b30db0550982c4280aa0da2d3c225b1598cfd2bcba1971e8a75238e142e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42aa5d35506dcaebb8a9db1e973081f38d0259eacc1da1eeeae6d530fc92055dfc70f749e4b19a4e28e3b726e92abae52e575207f1fadfa483bd2b6d6abba771
|
7
|
+
data.tar.gz: 7e97e56ac203bee46e1740e937c0869cb310d8c4edbc88ce6c2603446c5ad0989e52ffbf327be61680813ff2e92808a9ae91e09d0de9e4de5f4cedae590c2415
|
data/.rubocop.yml
CHANGED
@@ -1,8 +1,26 @@
|
|
1
1
|
require: rubocop-rspec
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
TargetRubyVersion: 2.4
|
5
|
+
|
2
6
|
Metrics/LineLength:
|
3
7
|
Max: 120
|
4
8
|
|
9
|
+
Style/StringLiterals:
|
10
|
+
EnforcedStyle: double_quotes
|
11
|
+
SupportedStyles:
|
12
|
+
- single_quotes
|
13
|
+
- double_quotes
|
14
|
+
|
15
|
+
Style/BlockDelimiters:
|
16
|
+
Enabled: true
|
17
|
+
Exclude:
|
18
|
+
- spec/**/*
|
19
|
+
|
5
20
|
# Disable some failing rspec cops that fail from upgrading gems until we can clean things up a bit.
|
21
|
+
Naming/FileName:
|
22
|
+
Exclude:
|
23
|
+
- lib/amplitude-api.rb
|
6
24
|
RSpec/ExampleLength:
|
7
25
|
Enabled: false
|
8
26
|
Metrics/BlockLength:
|
@@ -14,4 +32,4 @@ RSpec/NestedGroups:
|
|
14
32
|
RSpec/MessageSpies:
|
15
33
|
Enabled: false
|
16
34
|
RSpec/ContextWording:
|
17
|
-
Enabled: false
|
35
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/Changelog.md
CHANGED
@@ -3,6 +3,16 @@
|
|
3
3
|
We would like to think our many [contributors](https://github.com/toothrot/amplitude-api/graphs/contributors) for
|
4
4
|
suggestions, ideas and improvements to Amplitude API.
|
5
5
|
|
6
|
+
## 0.3.0 (2021-02-22)
|
7
|
+
|
8
|
+
* Changes Typhoeus to Faraday to launch requests
|
9
|
+
* Adds new API fields to Event
|
10
|
+
* Event can now include arbitrary properties, so it could be used if the API adds new ones.
|
11
|
+
|
12
|
+
## 0.2.0 (2021-02-14)
|
13
|
+
|
14
|
+
* Updates gem to use HTTP API V2.
|
15
|
+
|
6
16
|
## 0.1.1 (2019-01-01)
|
7
17
|
|
8
18
|
* Fix #41 - Delete API now correctly handles Arrays of IDs.
|
@@ -10,7 +20,7 @@ suggestions, ideas and improvements to Amplitude API.
|
|
10
20
|
## 0.1.0 (2019-01-01)
|
11
21
|
|
12
22
|
* Update Gem dependencies (thanks @kolorahl, @itamar, @krettan)
|
13
|
-
* Minimum ruby version is now 2.2
|
23
|
+
* Minimum ruby version is now 2.2
|
14
24
|
* Support Delete API (thanks @samjohn)
|
15
25
|
* Fix bundle Inline (thanks @jonduarte)
|
16
26
|
* Many fixes from @kolorahl
|
data/Gemfile
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Generated from /Users/alex/development/amplitude-api/amplitude-api.gemspec
|
2
|
-
source
|
4
|
+
source "https://rubygems.org"
|
3
5
|
|
4
|
-
gem
|
6
|
+
gem "faraday", "~> 1.3"
|
5
7
|
|
6
8
|
group :development, :test do
|
7
|
-
gem
|
8
|
-
gem
|
9
|
-
gem
|
10
|
-
gem
|
11
|
-
gem
|
9
|
+
gem "pry", "~> 0.12.2"
|
10
|
+
gem "rake", ">= 12.0"
|
11
|
+
gem "rspec", ">= 2.99.0"
|
12
|
+
gem "rubocop", "~> 0.66.0", require: false
|
13
|
+
gem "rubocop-rspec"
|
12
14
|
end
|
data/Gemfile.lock
CHANGED
@@ -4,11 +4,14 @@ GEM
|
|
4
4
|
ast (2.4.0)
|
5
5
|
coderay (1.1.2)
|
6
6
|
diff-lcs (1.3)
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
faraday (1.3.0)
|
8
|
+
faraday-net_http (~> 1.0)
|
9
|
+
multipart-post (>= 1.2, < 3)
|
10
|
+
ruby2_keywords
|
11
|
+
faraday-net_http (1.0.1)
|
10
12
|
jaro_winkler (1.5.2)
|
11
13
|
method_source (0.9.2)
|
14
|
+
multipart-post (2.1.1)
|
12
15
|
parallel (1.17.0)
|
13
16
|
parser (2.6.2.0)
|
14
17
|
ast (~> 2.4.0)
|
@@ -17,7 +20,7 @@ GEM
|
|
17
20
|
method_source (~> 0.9.0)
|
18
21
|
psych (3.1.0)
|
19
22
|
rainbow (3.0.0)
|
20
|
-
rake (12.3.
|
23
|
+
rake (12.3.3)
|
21
24
|
rspec (3.8.0)
|
22
25
|
rspec-core (~> 3.8.0)
|
23
26
|
rspec-expectations (~> 3.8.0)
|
@@ -42,20 +45,19 @@ GEM
|
|
42
45
|
rubocop-rspec (1.32.0)
|
43
46
|
rubocop (>= 0.60.0)
|
44
47
|
ruby-progressbar (1.10.0)
|
45
|
-
|
46
|
-
ethon (>= 0.9.0)
|
48
|
+
ruby2_keywords (0.0.4)
|
47
49
|
unicode-display_width (1.5.0)
|
48
50
|
|
49
51
|
PLATFORMS
|
50
52
|
ruby
|
51
53
|
|
52
54
|
DEPENDENCIES
|
55
|
+
faraday (~> 1.3)
|
53
56
|
pry (~> 0.12.2)
|
54
57
|
rake (>= 12.0)
|
55
58
|
rspec (>= 2.99.0)
|
56
59
|
rubocop (~> 0.66.0)
|
57
60
|
rubocop-rspec
|
58
|
-
typhoeus (~> 1.1)
|
59
61
|
|
60
62
|
BUNDLED WITH
|
61
|
-
1.17.
|
63
|
+
1.17.3
|
data/Rakefile
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rubocop/rake_task"
|
3
5
|
|
4
6
|
RuboCop::RakeTask.new
|
5
7
|
|
6
8
|
begin
|
7
|
-
require
|
9
|
+
require "rspec/core/rake_task"
|
8
10
|
RSpec::Core::RakeTask.new(:spec)
|
9
11
|
rescue LoadError
|
10
|
-
puts
|
12
|
+
puts "Unable to load rspec. Have you run `bundle install`?"
|
11
13
|
end
|
12
14
|
|
13
15
|
task(:default).clear
|
14
|
-
task default: [
|
16
|
+
task default: ["rubocop:auto_correct", :spec]
|
data/amplitude-api.gemspec
CHANGED
@@ -1,25 +1,27 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require
|
5
|
+
require "amplitude_api/version"
|
4
6
|
|
5
7
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
8
|
+
spec.name = "amplitude-api"
|
7
9
|
spec.version = AmplitudeAPI::VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
10
|
-
spec.summary =
|
11
|
-
spec.description =
|
12
|
-
spec.homepage =
|
13
|
-
spec.license =
|
10
|
+
spec.authors = ["Alex Rakoczy"]
|
11
|
+
spec.email = ["arakoczy@gmail.com"]
|
12
|
+
spec.summary = "Send events to the Amplitude API"
|
13
|
+
spec.description = "Provides an integration for sending events to Amplitude"
|
14
|
+
spec.homepage = "https://github.com/toothrot/amplitude-api"
|
15
|
+
spec.license = "MIT"
|
14
16
|
|
15
17
|
spec.files = `git ls-files -z`.split("\x0")
|
16
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
-
spec.require_paths = [
|
20
|
+
spec.require_paths = ["lib"]
|
19
21
|
|
20
|
-
spec.add_development_dependency
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_dependency
|
24
|
-
spec.required_ruby_version =
|
22
|
+
spec.add_development_dependency "pry", "~> 0.12.2"
|
23
|
+
spec.add_development_dependency "rake", "~> 12.0", ">= 12.0"
|
24
|
+
spec.add_development_dependency "rspec", "~> 2.99", ">= 2.99.0"
|
25
|
+
spec.add_dependency "faraday", "~> 1.3"
|
26
|
+
spec.required_ruby_version = ">= 2.4"
|
25
27
|
end
|
data/lib/amplitude-api.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
# Whoops.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "amplitude_api"
|
data/lib/amplitude_api.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
require "faraday"
|
3
5
|
|
4
6
|
# AmplitudeAPI
|
5
7
|
class AmplitudeAPI
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
8
|
+
require_relative "amplitude_api/config"
|
9
|
+
require_relative "amplitude_api/event"
|
10
|
+
require_relative "amplitude_api/identification"
|
9
11
|
|
10
|
-
TRACK_URI_STRING =
|
11
|
-
IDENTIFY_URI_STRING =
|
12
|
-
SEGMENTATION_URI_STRING =
|
13
|
-
DELETION_URI_STRING =
|
12
|
+
TRACK_URI_STRING = "https://api.amplitude.com/2/httpapi"
|
13
|
+
IDENTIFY_URI_STRING = "https://api.amplitude.com/identify"
|
14
|
+
SEGMENTATION_URI_STRING = "https://amplitude.com/api/2/events/segmentation"
|
15
|
+
DELETION_URI_STRING = "https://amplitude.com/api/2/deletions/users"
|
14
16
|
|
15
|
-
USER_WITH_NO_ACCOUNT = "user who doesn't have an account"
|
17
|
+
USER_WITH_NO_ACCOUNT = "user who doesn't have an account"
|
16
18
|
|
17
19
|
class << self
|
18
20
|
def config
|
@@ -43,7 +45,7 @@ class AmplitudeAPI
|
|
43
45
|
# @option options [ Hash ] user_properties a hash that is serialized to JSON,
|
44
46
|
# and contains user properties to be associated with the user
|
45
47
|
#
|
46
|
-
# @return [
|
48
|
+
# @return [ Faraday::Response ]
|
47
49
|
def send_event(event_name, user, device, options = {})
|
48
50
|
event = AmplitudeAPI::Event.new(
|
49
51
|
user_id: user,
|
@@ -68,10 +70,10 @@ class AmplitudeAPI
|
|
68
70
|
def track_body(*events)
|
69
71
|
event_body = events.flatten.map(&:to_hash)
|
70
72
|
|
71
|
-
|
73
|
+
JSON.generate(
|
72
74
|
api_key: api_key,
|
73
|
-
|
74
|
-
|
75
|
+
events: event_body
|
76
|
+
)
|
75
77
|
end
|
76
78
|
|
77
79
|
# @overload track(event)
|
@@ -80,11 +82,11 @@ class AmplitudeAPI
|
|
80
82
|
# @overload track([events])
|
81
83
|
# @param [ Array<AmplitudeAPI::Event> ] Send an array of events in a single request to Amplitude
|
82
84
|
#
|
83
|
-
# @return [
|
85
|
+
# @return [ Faraday::Response ]
|
84
86
|
#
|
85
87
|
# Send one or more Events to the Amplitude API
|
86
88
|
def track(*events)
|
87
|
-
|
89
|
+
Faraday.post(TRACK_URI_STRING, track_body(events), "Content-Type" => "application/json")
|
88
90
|
end
|
89
91
|
|
90
92
|
# ==== Identification related methods
|
@@ -123,11 +125,11 @@ class AmplitudeAPI
|
|
123
125
|
# @overload identify([identifications])
|
124
126
|
# @param [ Array<AmplitudeAPI::Identify> ] Send an array of identifications in a single request to Amplitude
|
125
127
|
#
|
126
|
-
# @return [
|
128
|
+
# @return [ Faraday::Response ]
|
127
129
|
#
|
128
130
|
# Send one or more Identifications to the Amplitude Identify API
|
129
131
|
def identify(*identifications)
|
130
|
-
|
132
|
+
Faraday.post(IDENTIFY_URI_STRING, identify_body(identifications))
|
131
133
|
end
|
132
134
|
|
133
135
|
# ==== Event Segmentation related methods
|
@@ -150,13 +152,13 @@ class AmplitudeAPI
|
|
150
152
|
# @option options [ Integer ] limit an integer that defines number of Group By values
|
151
153
|
# returned (default: 100). The maximum limit is 1000.
|
152
154
|
#
|
153
|
-
# @return [
|
155
|
+
# @return [ Faraday::Response ]
|
154
156
|
def segmentation(event, start_time, end_time, **options)
|
155
|
-
|
157
|
+
Faraday.get SEGMENTATION_URI_STRING, userpwd: "#{api_key}:#{secret_key}", params: {
|
156
158
|
e: event.to_json,
|
157
159
|
m: options[:m],
|
158
|
-
start: start_time.strftime(
|
159
|
-
end: end_time.strftime(
|
160
|
+
start: start_time.strftime("%Y%m%d"),
|
161
|
+
end: end_time.strftime("%Y%m%d"),
|
160
162
|
i: options[:i],
|
161
163
|
s: (options[:s] || []).map(&:to_json),
|
162
164
|
g: options[:g],
|
@@ -174,29 +176,38 @@ class AmplitudeAPI
|
|
174
176
|
# based on the amplitude database
|
175
177
|
# @param [ String ] requester the email address of the person who
|
176
178
|
# is requesting the deletion, optional but useful for reporting
|
177
|
-
#
|
178
|
-
#
|
179
|
-
|
179
|
+
# @param [ Boolean ] (optional) ignore any invalid user IDs(users that do no
|
180
|
+
# exist in the project) that were passed in
|
181
|
+
# @param [ Boolean ] (optional) delete from the entire org rather than just
|
182
|
+
# this project.
|
183
|
+
# @return [ Faraday::Response ]
|
184
|
+
def delete(user_ids: nil, amplitude_ids: nil, requester: nil, ignore_invalid_id: nil, delete_from_org: nil)
|
180
185
|
user_ids = Array(user_ids)
|
181
186
|
amplitude_ids = Array(amplitude_ids)
|
182
|
-
|
187
|
+
|
188
|
+
faraday = Faraday.new do |conn|
|
189
|
+
conn.basic_auth config.api_key, config.secret_key
|
190
|
+
end
|
191
|
+
|
192
|
+
faraday.post(
|
183
193
|
DELETION_URI_STRING,
|
184
|
-
|
185
|
-
|
186
|
-
headers: { 'Content-Type': 'application/json' }
|
194
|
+
delete_body(user_ids, amplitude_ids, requester, ignore_invalid_id, delete_from_org),
|
195
|
+
"Content-Type" => "application/json"
|
187
196
|
)
|
188
197
|
end
|
189
198
|
|
190
199
|
private
|
191
200
|
|
192
|
-
def delete_body(user_ids, amplitude_ids, requester)
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
201
|
+
def delete_body(user_ids, amplitude_ids, requester, ignore_invalid_id, delete_from_org)
|
202
|
+
body = {
|
203
|
+
amplitude_ids: amplitude_ids,
|
204
|
+
user_ids: user_ids,
|
205
|
+
requester: requester
|
206
|
+
}.delete_if { |_, value| value.nil? || value.empty? }
|
207
|
+
|
208
|
+
body[:ignore_invalid_id] = ignore_invalid_id.to_s if ignore_invalid_id
|
209
|
+
body[:delete_from_org] = delete_from_org.to_s if delete_from_org
|
210
|
+
JSON.generate(body)
|
200
211
|
end
|
201
212
|
end
|
202
213
|
end
|
data/lib/amplitude_api/config.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "singleton"
|
2
4
|
|
3
5
|
class AmplitudeAPI
|
4
6
|
# AmplitudeAPI::Config
|
@@ -13,13 +15,32 @@ class AmplitudeAPI
|
|
13
15
|
end
|
14
16
|
|
15
17
|
class << self
|
18
|
+
def base_properties
|
19
|
+
%i[event_type event_properties user_properties user_id device_id]
|
20
|
+
end
|
21
|
+
|
22
|
+
def revenue_properties
|
23
|
+
%i[revenue_type product_id revenue price quantity]
|
24
|
+
end
|
25
|
+
|
26
|
+
def optional_properties
|
27
|
+
%i[
|
28
|
+
time
|
29
|
+
ip platform country insert_id
|
30
|
+
groups app_version os_name os_version
|
31
|
+
device_brand device_manufacturer device_model
|
32
|
+
carrier region city dma language
|
33
|
+
location_lat location_lng
|
34
|
+
idfa idfv adid android_id
|
35
|
+
event_id session_id
|
36
|
+
]
|
37
|
+
end
|
38
|
+
|
16
39
|
def defaults
|
17
40
|
{
|
18
41
|
api_key: nil,
|
19
42
|
secret_key: nil,
|
20
|
-
whitelist:
|
21
|
-
event_properties user_properties time ip platform country insert_id
|
22
|
-
revenue_type price quantity product_id],
|
43
|
+
whitelist: base_properties + revenue_properties + optional_properties,
|
23
44
|
time_formatter: ->(time) { time ? time.to_i * 1_000 : nil },
|
24
45
|
event_properties_formatter: ->(props) { props || {} },
|
25
46
|
user_properties_formatter: ->(props) { props || {} }
|
data/lib/amplitude_api/event.rb
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This class is 115 lines long. It's on the limit, it should be refactored before
|
4
|
+
# including more code.
|
5
|
+
#
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
1
7
|
class AmplitudeAPI
|
2
8
|
# AmplitudeAPI::Event
|
3
9
|
class Event
|
@@ -7,13 +13,43 @@ class AmplitudeAPI
|
|
7
13
|
|
8
14
|
# Create a new Event
|
9
15
|
#
|
10
|
-
# See (Amplitude HTTP API Documentation)[https://amplitude.
|
16
|
+
# See (Amplitude HTTP API Documentation)[https://developers.amplitude.com/docs/http-api-v2]
|
11
17
|
# for a list of valid parameters and their types.
|
12
18
|
def initialize(attributes = {})
|
13
19
|
attributes.each do |k, v|
|
14
20
|
send("#{k}=", v) if respond_to?("#{k}=")
|
15
21
|
end
|
16
22
|
validate_arguments
|
23
|
+
@extra_properties = []
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing(method_name, *args)
|
27
|
+
super if block_given?
|
28
|
+
|
29
|
+
property_name = method_name.to_s.delete_suffix("=")
|
30
|
+
|
31
|
+
@extra_properties << property_name
|
32
|
+
|
33
|
+
create_setter property_name
|
34
|
+
create_getter property_name
|
35
|
+
|
36
|
+
send("#{property_name}=".to_sym, *args)
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_setter(attribute_name)
|
40
|
+
self.class.send(:define_method, "#{attribute_name}=".to_sym) do |value|
|
41
|
+
instance_variable_set("@" + attribute_name.to_s, value)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_getter(attribute_name)
|
46
|
+
self.class.send(:define_method, attribute_name.to_sym) do
|
47
|
+
instance_variable_get("@" + attribute_name.to_s)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def respond_to_missing?(method_name, *args)
|
52
|
+
@extra_properties.include?(method_name) || @extra_properties.include?("#{method_name}=") || super
|
17
53
|
end
|
18
54
|
|
19
55
|
def user_id=(value)
|
@@ -36,28 +72,42 @@ class AmplitudeAPI
|
|
36
72
|
}
|
37
73
|
event[:user_id] = user_id if user_id
|
38
74
|
event[:device_id] = device_id if device_id
|
39
|
-
event.merge(optional_properties).merge(revenue_hash)
|
75
|
+
event.merge(optional_properties).merge(revenue_hash).merge(extra_properties)
|
40
76
|
end
|
41
77
|
alias to_h to_hash
|
42
78
|
|
43
79
|
# @return [ Hash ] Optional properties
|
80
|
+
#
|
81
|
+
# Returns optional properties (belong to the API but are optional)
|
44
82
|
def optional_properties
|
45
|
-
|
83
|
+
AmplitudeAPI::Config.optional_properties.map do |prop|
|
46
84
|
val = prop == :time ? formatted_time : send(prop)
|
47
85
|
val ? [prop, val] : nil
|
48
86
|
end.compact.to_h
|
49
87
|
end
|
50
88
|
|
89
|
+
# @return [ Hash ] Extra properties
|
90
|
+
#
|
91
|
+
# Returns optional properties (not belong to the API, are assigned by the user)
|
92
|
+
# This way, if the API is updated with new properties, the gem will be able
|
93
|
+
# to work with the new specification until the code is modified
|
94
|
+
def extra_properties
|
95
|
+
@extra_properties.map do |prop|
|
96
|
+
val = send(prop)
|
97
|
+
val ? [prop.to_sym, val] : nil
|
98
|
+
end.compact.to_h
|
99
|
+
end
|
100
|
+
|
51
101
|
# @return [ true, false ]
|
52
102
|
#
|
53
103
|
# Returns true if the event type matches one reserved by Amplitude API.
|
54
104
|
def reserved_event?(type)
|
55
|
-
[
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
105
|
+
["[Amplitude] Start Session",
|
106
|
+
"[Amplitude] End Session",
|
107
|
+
"[Amplitude] Revenue",
|
108
|
+
"[Amplitude] Revenue (Verified)",
|
109
|
+
"[Amplitude] Revenue (Unverified)",
|
110
|
+
"[Amplitude] Merged User"].include?(type)
|
61
111
|
end
|
62
112
|
|
63
113
|
# @return [ true, false ]
|
@@ -89,15 +139,23 @@ class AmplitudeAPI
|
|
89
139
|
end
|
90
140
|
|
91
141
|
def validate_required_arguments
|
92
|
-
raise ArgumentError,
|
93
|
-
raise ArgumentError,
|
94
|
-
raise ArgumentError,
|
142
|
+
raise ArgumentError, "You must provide user_id or device_id (or both)" unless user_id || device_id
|
143
|
+
raise ArgumentError, "You must provide event_type" unless event_type
|
144
|
+
raise ArgumentError, "Invalid event_type - cannot match a reserved event name" if reserved_event?(event_type)
|
95
145
|
end
|
96
146
|
|
97
147
|
def validate_revenue_arguments
|
98
|
-
return
|
99
|
-
|
100
|
-
|
148
|
+
return true if !revenue_type && !product_id
|
149
|
+
return true if revenue || price
|
150
|
+
|
151
|
+
raise ArgumentError, revenue_error_message
|
152
|
+
end
|
153
|
+
|
154
|
+
def revenue_error_message
|
155
|
+
error_field = "product_id" if product_id
|
156
|
+
error_field = "revenue_type" if revenue_type
|
157
|
+
|
158
|
+
"You must provide a price or a revenue in order to use the field #{error_field}"
|
101
159
|
end
|
102
160
|
|
103
161
|
def revenue_hash
|
@@ -106,6 +164,7 @@ class AmplitudeAPI
|
|
106
164
|
revenue_hash[:revenueType] = revenue_type if revenue_type
|
107
165
|
revenue_hash[:quantity] = quantity if quantity
|
108
166
|
revenue_hash[:price] = price if price
|
167
|
+
revenue_hash[:revenue] = revenue if revenue
|
109
168
|
revenue_hash
|
110
169
|
end
|
111
170
|
|
@@ -114,3 +173,4 @@ class AmplitudeAPI
|
|
114
173
|
end
|
115
174
|
end
|
116
175
|
end
|
176
|
+
# rubocop:enable Metrics/ClassLength
|