amplitude-api 0.1.0 → 0.3.3
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 +5 -4
- data/.rubocop.yml +19 -1
- data/.travis.yml +2 -3
- data/Changelog.md +32 -0
- data/Gemfile +3 -12
- data/Rakefile +7 -5
- data/amplitude-api.gemspec +17 -15
- data/lib/amplitude-api.rb +3 -4
- data/lib/amplitude_api.rb +71 -45
- data/lib/amplitude_api/config.rb +27 -5
- data/lib/amplitude_api/event.rb +77 -16
- data/lib/amplitude_api/identification.rb +3 -1
- data/lib/amplitude_api/version.rb +3 -1
- data/readme.md +38 -6
- data/spec/lib/amplitude_api/event_spec.rb +212 -112
- data/spec/lib/amplitude_api/identification_spec.rb +19 -17
- data/spec/lib/amplitude_api_spec.rb +328 -188
- data/spec/spec_helper.rb +7 -5
- metadata +6 -7
- data/Gemfile.lock +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4372cbca5a551be9721be89fbbe3ee80dc9216d8fa44fba7b0031a5e62785cd
|
4
|
+
data.tar.gz: ee6056b7e64c2b51f9365a8e57c90a1b4b8fc5edc406b1f7cbabf4caf831b7ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f55a3e558f985bac1d78ac842532dfd5dfc69290f7ece8f9c197c71f155ae802de8a00649c5be9bcdd4a67e995e59eaf9cbcc3586808ddfedbb00aba259cf39b
|
7
|
+
data.tar.gz: 3e6d679080a879ccf02ab29b3f13839b29c78bfb28cd48793275345ca41b77a61d09231e82d3cc4132319d14eef0ac807e5fa589330a1e0f84486fa534f875a4
|
data/.gitignore
CHANGED
@@ -27,11 +27,12 @@ build/
|
|
27
27
|
|
28
28
|
# for a library or gem, you might want to ignore these files since the code is
|
29
29
|
# intended to run in multiple environments; otherwise, check them in:
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
Gemfile.lock
|
31
|
+
.ruby-version
|
32
|
+
.ruby-gemset
|
33
33
|
|
34
34
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
35
35
|
.rvmrc
|
36
36
|
|
37
|
-
.idea
|
37
|
+
.idea
|
38
|
+
amplitude-api.iml
|
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,38 @@
|
|
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.3 (2021-02-24)
|
7
|
+
* Relaxes Faraday dependency
|
8
|
+
|
9
|
+
## 0.3.2 (2021-02-23)
|
10
|
+
* Creates new properties on initialization
|
11
|
+
|
12
|
+
## 0.3.1 (2021-02-23)
|
13
|
+
* Allows sending options to Amplitude
|
14
|
+
* Solves an error when accessing event properties not been created yet
|
15
|
+
|
16
|
+
## 0.3.0 (2021-02-22)
|
17
|
+
|
18
|
+
* Changes Typhoeus to Faraday to launch requests (**breaking change**)
|
19
|
+
* Adds new API fields to Event
|
20
|
+
* Event can now include arbitrary properties, so it could be used if the API adds new ones.
|
21
|
+
|
22
|
+
## 0.2.0 (2021-02-14)
|
23
|
+
|
24
|
+
* Updates gem to use HTTP API V2.
|
25
|
+
|
26
|
+
## 0.1.1 (2019-01-01)
|
27
|
+
|
28
|
+
* Fix #41 - Delete API now correctly handles Arrays of IDs.
|
29
|
+
|
30
|
+
## 0.1.0 (2019-01-01)
|
31
|
+
|
32
|
+
* Update Gem dependencies (thanks @kolorahl, @itamar, @krettan)
|
33
|
+
* Minimum ruby version is now 2.2
|
34
|
+
* Support Delete API (thanks @samjohn)
|
35
|
+
* Fix bundle Inline (thanks @jonduarte)
|
36
|
+
* Many fixes from @kolorahl
|
37
|
+
|
6
38
|
## 0.0.10 (2017-09-13)
|
7
39
|
|
8
40
|
* Allow to use "Event Segmentation" via API ([#23](https://github.com/toothrot/amplitude-api/pull/23)).
|
data/Gemfile
CHANGED
@@ -1,12 +1,3 @@
|
|
1
|
-
#
|
2
|
-
source
|
3
|
-
|
4
|
-
gem 'typhoeus', '~> 1.1'
|
5
|
-
|
6
|
-
group :development, :test do
|
7
|
-
gem 'pry', '~> 0.12.2'
|
8
|
-
gem 'rake', '>= 12.0'
|
9
|
-
gem 'rspec', '>= 2.99.0'
|
10
|
-
gem 'rubocop', '~> 0.66.0', require: false
|
11
|
-
gem 'rubocop-rspec'
|
12
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
source "https://rubygems.org"
|
3
|
+
gemspec
|
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.0"
|
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
|
@@ -38,12 +40,12 @@ class AmplitudeAPI
|
|
38
40
|
# @param [ String ] event_name a string that describes the event, e.g. "clicked on Home"
|
39
41
|
# @param [ String ] user a string or integer that uniquely identifies a user.
|
40
42
|
# @param [ String ] device a string that uniquely identifies the device.
|
41
|
-
# @
|
43
|
+
# @option options [ Hash ] event_properties a hash that is serialized to JSON,
|
42
44
|
# and can contain any other property to be stored on the Event
|
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,13 @@ class AmplitudeAPI
|
|
68
70
|
def track_body(*events)
|
69
71
|
event_body = events.flatten.map(&:to_hash)
|
70
72
|
|
71
|
-
{
|
73
|
+
body = {
|
72
74
|
api_key: api_key,
|
73
|
-
|
75
|
+
events: event_body
|
74
76
|
}
|
77
|
+
body[:options] = config.options if config.options
|
78
|
+
|
79
|
+
JSON.generate(body)
|
75
80
|
end
|
76
81
|
|
77
82
|
# @overload track(event)
|
@@ -80,11 +85,11 @@ class AmplitudeAPI
|
|
80
85
|
# @overload track([events])
|
81
86
|
# @param [ Array<AmplitudeAPI::Event> ] Send an array of events in a single request to Amplitude
|
82
87
|
#
|
83
|
-
# @return [
|
88
|
+
# @return [ Faraday::Response ]
|
84
89
|
#
|
85
90
|
# Send one or more Events to the Amplitude API
|
86
91
|
def track(*events)
|
87
|
-
|
92
|
+
Faraday.post(TRACK_URI_STRING, track_body(events), "Content-Type" => "application/json")
|
88
93
|
end
|
89
94
|
|
90
95
|
# ==== Identification related methods
|
@@ -123,40 +128,40 @@ class AmplitudeAPI
|
|
123
128
|
# @overload identify([identifications])
|
124
129
|
# @param [ Array<AmplitudeAPI::Identify> ] Send an array of identifications in a single request to Amplitude
|
125
130
|
#
|
126
|
-
# @return [
|
131
|
+
# @return [ Faraday::Response ]
|
127
132
|
#
|
128
133
|
# Send one or more Identifications to the Amplitude Identify API
|
129
134
|
def identify(*identifications)
|
130
|
-
|
135
|
+
Faraday.post(IDENTIFY_URI_STRING, identify_body(identifications))
|
131
136
|
end
|
132
137
|
|
133
138
|
# ==== Event Segmentation related methods
|
134
139
|
|
135
140
|
# Get metrics for an event with segmentation.
|
136
141
|
#
|
137
|
-
# @param [ Hash ]
|
142
|
+
# @param [ Hash ] event a hash that defines event.
|
138
143
|
# @param [ Time ] start_time a start time.
|
139
144
|
# @param [ Time ] end_time a end time.
|
140
|
-
# @
|
145
|
+
# @option options [ String ] m a string that defines aggregate function.
|
141
146
|
# For non-property metrics: "uniques", "totals", "pct_dau", or "average" (default: "uniques").
|
142
147
|
# For property metrics: "histogram", "sums", or "value_avg"
|
143
148
|
# (note: a valid "group_by" value is required in parameter e).
|
144
|
-
# @
|
149
|
+
# @option options [ Integer ] i an integer that defines segmentation interval.
|
145
150
|
# Set to -300000, -3600000, 1, 7, or 30 for realtime, hourly, daily, weekly,
|
146
151
|
# and monthly counts, respectively (default: 1). Realtime segmentation is capped at 2 days,
|
147
152
|
# hourly segmentation is capped at 7 days, and daily at 365 days.
|
148
|
-
# @
|
149
|
-
# @
|
150
|
-
# @
|
153
|
+
# @option options [ Array ] s an array that defines segment definitions.
|
154
|
+
# @option options [ String ] g a string that defines property to group by.
|
155
|
+
# @option options [ Integer ] limit an integer that defines number of Group By values
|
151
156
|
# returned (default: 100). The maximum limit is 1000.
|
152
157
|
#
|
153
|
-
# @return [
|
158
|
+
# @return [ Faraday::Response ]
|
154
159
|
def segmentation(event, start_time, end_time, **options)
|
155
|
-
|
160
|
+
Faraday.get SEGMENTATION_URI_STRING, userpwd: "#{api_key}:#{secret_key}", params: {
|
156
161
|
e: event.to_json,
|
157
162
|
m: options[:m],
|
158
|
-
start: start_time.strftime(
|
159
|
-
end: end_time.strftime(
|
163
|
+
start: start_time.strftime("%Y%m%d"),
|
164
|
+
end: end_time.strftime("%Y%m%d"),
|
160
165
|
i: options[:i],
|
161
166
|
s: (options[:s] || []).map(&:to_json),
|
162
167
|
g: options[:g],
|
@@ -164,27 +169,48 @@ class AmplitudeAPI
|
|
164
169
|
}.delete_if { |_, value| value.nil? }
|
165
170
|
end
|
166
171
|
|
167
|
-
#
|
168
|
-
|
169
|
-
# Delete a user from amplitude when they request it to comply with GDPR
|
172
|
+
# Delete a user from amplitude
|
173
|
+
#
|
170
174
|
# You must pass in either an array of user_ids or an array of amplitude_ids
|
171
175
|
#
|
172
|
-
# @param [
|
176
|
+
# @param [ Array<String> ] (optional) the user_ids to delete
|
173
177
|
# based on your database
|
174
|
-
# @param [
|
178
|
+
# @param [ Array<Integer> ] (optional) the amplitude_ids to delete
|
175
179
|
# based on the amplitude database
|
176
|
-
# @param [
|
180
|
+
# @param [ String ] requester the email address of the person who
|
177
181
|
# is requesting the deletion, optional but useful for reporting
|
178
|
-
#
|
179
|
-
#
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
182
|
+
# @param [ Boolean ] (optional) ignore any invalid user IDs(users that do no
|
183
|
+
# exist in the project) that were passed in
|
184
|
+
# @param [ Boolean ] (optional) delete from the entire org rather than just
|
185
|
+
# this project.
|
186
|
+
# @return [ Faraday::Response ]
|
187
|
+
def delete(user_ids: nil, amplitude_ids: nil, requester: nil, ignore_invalid_id: nil, delete_from_org: nil)
|
188
|
+
user_ids = Array(user_ids)
|
189
|
+
amplitude_ids = Array(amplitude_ids)
|
190
|
+
|
191
|
+
faraday = Faraday.new do |conn|
|
192
|
+
conn.basic_auth config.api_key, config.secret_key
|
193
|
+
end
|
194
|
+
|
195
|
+
faraday.post(
|
196
|
+
DELETION_URI_STRING,
|
197
|
+
delete_body(user_ids, amplitude_ids, requester, ignore_invalid_id, delete_from_org),
|
198
|
+
"Content-Type" => "application/json"
|
199
|
+
)
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
def delete_body(user_ids, amplitude_ids, requester, ignore_invalid_id, delete_from_org)
|
205
|
+
body = {
|
206
|
+
amplitude_ids: amplitude_ids,
|
207
|
+
user_ids: user_ids,
|
208
|
+
requester: requester
|
209
|
+
}.delete_if { |_, value| value.nil? || value.empty? }
|
210
|
+
|
211
|
+
body[:ignore_invalid_id] = ignore_invalid_id.to_s if ignore_invalid_id
|
212
|
+
body[:delete_from_org] = delete_from_org.to_s if delete_from_org
|
213
|
+
JSON.generate(body)
|
188
214
|
end
|
189
215
|
end
|
190
216
|
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
|
@@ -6,20 +8,40 @@ class AmplitudeAPI
|
|
6
8
|
include Singleton
|
7
9
|
|
8
10
|
attr_accessor :api_key, :secret_key, :whitelist, :time_formatter,
|
9
|
-
:event_properties_formatter, :user_properties_formatter
|
11
|
+
:event_properties_formatter, :user_properties_formatter,
|
12
|
+
:options
|
10
13
|
|
11
14
|
def initialize
|
12
15
|
self.class.defaults.each { |k, v| send("#{k}=", v) }
|
13
16
|
end
|
14
17
|
|
15
18
|
class << self
|
19
|
+
def base_properties
|
20
|
+
%i[event_type event_properties user_properties user_id device_id]
|
21
|
+
end
|
22
|
+
|
23
|
+
def revenue_properties
|
24
|
+
%i[revenue_type product_id revenue price quantity]
|
25
|
+
end
|
26
|
+
|
27
|
+
def optional_properties
|
28
|
+
%i[
|
29
|
+
time
|
30
|
+
ip platform country insert_id
|
31
|
+
groups app_version os_name os_version
|
32
|
+
device_brand device_manufacturer device_model
|
33
|
+
carrier region city dma language
|
34
|
+
location_lat location_lng
|
35
|
+
idfa idfv adid android_id
|
36
|
+
event_id session_id
|
37
|
+
]
|
38
|
+
end
|
39
|
+
|
16
40
|
def defaults
|
17
41
|
{
|
18
42
|
api_key: nil,
|
19
43
|
secret_key: nil,
|
20
|
-
whitelist:
|
21
|
-
event_properties user_properties time ip platform country insert_id
|
22
|
-
revenue_type price quantity product_id],
|
44
|
+
whitelist: base_properties + revenue_properties + optional_properties,
|
23
45
|
time_formatter: ->(time) { time ? time.to_i * 1_000 : nil },
|
24
46
|
event_properties_formatter: ->(props) { props || {} },
|
25
47
|
user_properties_formatter: ->(props) { props || {} }
|