amplitude-api 0.1.0 → 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/.gitignore +2 -1
- data/.rubocop.yml +19 -1
- data/.travis.yml +2 -3
- data/Changelog.md +22 -0
- 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/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/lib/amplitude_api.rb +69 -46
- data/readme.md +7 -6
- 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 +278 -188
- 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/.gitignore
CHANGED
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,28 @@
|
|
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
|
+
|
16
|
+
## 0.1.1 (2019-01-01)
|
17
|
+
|
18
|
+
* Fix #41 - Delete API now correctly handles Arrays of IDs.
|
19
|
+
|
20
|
+
## 0.1.0 (2019-01-01)
|
21
|
+
|
22
|
+
* Update Gem dependencies (thanks @kolorahl, @itamar, @krettan)
|
23
|
+
* Minimum ruby version is now 2.2
|
24
|
+
* Support Delete API (thanks @samjohn)
|
25
|
+
* Fix bundle Inline (thanks @jonduarte)
|
26
|
+
* Many fixes from @kolorahl
|
27
|
+
|
6
28
|
## 0.0.10 (2017-09-13)
|
7
29
|
|
8
30
|
* Allow to use "Event Segmentation" via API ([#23](https://github.com/toothrot/amplitude-api/pull/23)).
|
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/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
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class AmplitudeAPI
|
2
4
|
# AmplitudeAPI::Identification
|
3
5
|
class Identification
|
@@ -16,7 +18,7 @@ class AmplitudeAPI
|
|
16
18
|
# @param [ String ] user_id a user_id to associate with the identification
|
17
19
|
# @param [ String ] device_id a device_id to associate with the identification
|
18
20
|
# @param [ Hash ] user_properties various properties to attach to the user identification
|
19
|
-
def initialize(user_id:
|
21
|
+
def initialize(user_id: "", device_id: nil, user_properties: {})
|
20
22
|
self.user_id = user_id
|
21
23
|
self.device_id = device_id if device_id
|
22
24
|
self.user_properties = user_properties
|