amplitude-api 0.1.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|