amplitude-api 0.0.10 → 0.3.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0e82b9bf2580f2da3bd76a71cb172ca89d051d3f
4
- data.tar.gz: 8d437b02ece1c511b0f5256ee81f4e4b94fa8494
2
+ SHA256:
3
+ metadata.gz: 275373a4c26fc2028070205735f535ab9411dad8c98986c1dae0793e44098106
4
+ data.tar.gz: 5d79d4ff3ebc1218f5ce1ddff49fc5c323b250862db1e4c4e5136f76c3eb6f1e
5
5
  SHA512:
6
- metadata.gz: 0df83a07615c485e264d00522359ab188e93f462e9e30d77ca6053d0dbc771a534062afc2148b60025ca221eddf1378727a8bcac46f25ec2c5f8480a5dd6ab4f
7
- data.tar.gz: e9506a8d285f98d90a80ea28b7e80a337f3749597dbcf3be95f170bb7ca1a66cb5cd810fcbffcb020041ccb620cdb5ee547f6bb382cefd1644f5d10639a25264
6
+ metadata.gz: af5c1085ae807de968a2737ec4eab0da585baca1596ac38caed7960b457d854d7e83e4a0fa0fbf9826164239891d047fbc0e3e1801104696e5323fd05f0e3b7c
7
+ data.tar.gz: 12817cbd4e8929d02cea2b2499bbe309d459fcc1388e9b70003503e6d3df00e974185342bfae02e9d61cdf5d8b4af296616af1dc720db42f91a456b56f70452c
data/.gitignore CHANGED
@@ -34,4 +34,5 @@ build/
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,3 +1,35 @@
1
1
  require: rubocop-rspec
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.4
5
+
2
6
  Metrics/LineLength:
3
7
  Max: 120
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
+
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
24
+ RSpec/ExampleLength:
25
+ Enabled: false
26
+ Metrics/BlockLength:
27
+ Enabled: false
28
+ RSpec/MultipleExpectations:
29
+ Enabled: false
30
+ RSpec/NestedGroups:
31
+ Enabled: false
32
+ RSpec/MessageSpies:
33
+ Enabled: false
34
+ RSpec/ContextWording:
35
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,6 +1,5 @@
1
1
  language: ruby
2
2
  cache: bundler
3
3
  rvm:
4
- - 2.3.1
5
- - 2.2.2
6
- - 2.1.6
4
+ - 2.6
5
+ - 2.4
data/Changelog.md ADDED
@@ -0,0 +1,41 @@
1
+ # Amplitude API Changelog
2
+
3
+ We would like to think our many [contributors](https://github.com/toothrot/amplitude-api/graphs/contributors) for
4
+ suggestions, ideas and improvements to Amplitude API.
5
+
6
+ ## 0.3.2 (2021-02-23)
7
+ * Creates new properties on initialization
8
+
9
+ ## 0.3.1 (2021-02-23)
10
+ * Allows sending options to Amplitude
11
+ * Solves an error when accessing event properties not been created yet
12
+
13
+ ## 0.3.0 (2021-02-22)
14
+
15
+ * Changes Typhoeus to Faraday to launch requests (**breaking change**)
16
+ * Adds new API fields to Event
17
+ * Event can now include arbitrary properties, so it could be used if the API adds new ones.
18
+
19
+ ## 0.2.0 (2021-02-14)
20
+
21
+ * Updates gem to use HTTP API V2.
22
+
23
+ ## 0.1.1 (2019-01-01)
24
+
25
+ * Fix #41 - Delete API now correctly handles Arrays of IDs.
26
+
27
+ ## 0.1.0 (2019-01-01)
28
+
29
+ * Update Gem dependencies (thanks @kolorahl, @itamar, @krettan)
30
+ * Minimum ruby version is now 2.2
31
+ * Support Delete API (thanks @samjohn)
32
+ * Fix bundle Inline (thanks @jonduarte)
33
+ * Many fixes from @kolorahl
34
+
35
+ ## 0.0.10 (2017-09-13)
36
+
37
+ * Allow to use "Event Segmentation" via API ([#23](https://github.com/toothrot/amplitude-api/pull/23)).
38
+
39
+ ## Older releases
40
+
41
+ Please see the v0.0.9 tag.
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 'https://rubygems.org'
4
+ source "https://rubygems.org"
3
5
 
4
- gem 'typhoeus', '~> 1.0.2'
6
+ gem "faraday", "~> 1.3"
5
7
 
6
8
  group :development, :test do
7
- gem 'pry', '~> 0.9.12.6'
8
- gem 'rake', '>= 10.0'
9
- gem 'rspec', '>= 2.99.0'
10
- gem 'rubocop', '~> 0.37.2', require: false
11
- gem 'rubocop-rspec'
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
@@ -1,58 +1,63 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- ast (2.2.0)
5
- coderay (1.1.1)
6
- diff-lcs (1.2.5)
7
- ethon (0.9.0)
8
- ffi (>= 1.3.0)
9
- ffi (1.9.14)
10
- method_source (0.8.2)
11
- parser (2.3.0.6)
12
- ast (~> 2.2)
13
- powerpack (0.1.1)
14
- pry (0.9.12.6)
15
- coderay (~> 1.0)
16
- method_source (~> 0.8)
17
- slop (~> 3.4)
18
- rainbow (2.1.0)
19
- rake (10.5.0)
20
- rspec (3.4.0)
21
- rspec-core (~> 3.4.0)
22
- rspec-expectations (~> 3.4.0)
23
- rspec-mocks (~> 3.4.0)
24
- rspec-core (3.4.3)
25
- rspec-support (~> 3.4.0)
26
- rspec-expectations (3.4.0)
4
+ ast (2.4.0)
5
+ coderay (1.1.2)
6
+ diff-lcs (1.3)
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)
12
+ jaro_winkler (1.5.2)
13
+ method_source (0.9.2)
14
+ multipart-post (2.1.1)
15
+ parallel (1.17.0)
16
+ parser (2.6.2.0)
17
+ ast (~> 2.4.0)
18
+ pry (0.12.2)
19
+ coderay (~> 1.1.0)
20
+ method_source (~> 0.9.0)
21
+ psych (3.1.0)
22
+ rainbow (3.0.0)
23
+ rake (12.3.3)
24
+ rspec (3.8.0)
25
+ rspec-core (~> 3.8.0)
26
+ rspec-expectations (~> 3.8.0)
27
+ rspec-mocks (~> 3.8.0)
28
+ rspec-core (3.8.0)
29
+ rspec-support (~> 3.8.0)
30
+ rspec-expectations (3.8.2)
27
31
  diff-lcs (>= 1.2.0, < 2.0)
28
- rspec-support (~> 3.4.0)
29
- rspec-mocks (3.4.1)
32
+ rspec-support (~> 3.8.0)
33
+ rspec-mocks (3.8.0)
30
34
  diff-lcs (>= 1.2.0, < 2.0)
31
- rspec-support (~> 3.4.0)
32
- rspec-support (3.4.1)
33
- rubocop (0.37.2)
34
- parser (>= 2.3.0.4, < 3.0)
35
- powerpack (~> 0.1)
36
- rainbow (>= 1.99.1, < 3.0)
35
+ rspec-support (~> 3.8.0)
36
+ rspec-support (3.8.0)
37
+ rubocop (0.66.0)
38
+ jaro_winkler (~> 1.5.1)
39
+ parallel (~> 1.10)
40
+ parser (>= 2.5, != 2.5.1.1)
41
+ psych (>= 3.1.0)
42
+ rainbow (>= 2.2.2, < 4.0)
37
43
  ruby-progressbar (~> 1.7)
38
- unicode-display_width (~> 0.3)
39
- rubocop-rspec (1.4.0)
40
- ruby-progressbar (1.7.5)
41
- slop (3.6.0)
42
- typhoeus (1.0.2)
43
- ethon (>= 0.9.0)
44
- unicode-display_width (0.3.1)
44
+ unicode-display_width (>= 1.4.0, < 1.6)
45
+ rubocop-rspec (1.32.0)
46
+ rubocop (>= 0.60.0)
47
+ ruby-progressbar (1.10.0)
48
+ ruby2_keywords (0.0.4)
49
+ unicode-display_width (1.5.0)
45
50
 
46
51
  PLATFORMS
47
52
  ruby
48
53
 
49
54
  DEPENDENCIES
50
- pry (~> 0.9.12.6)
51
- rake (>= 10.0)
55
+ faraday (~> 1.3)
56
+ pry (~> 0.12.2)
57
+ rake (>= 12.0)
52
58
  rspec (>= 2.99.0)
53
- rubocop (~> 0.37.2)
59
+ rubocop (~> 0.66.0)
54
60
  rubocop-rspec
55
- typhoeus (~> 1.0.2)
56
61
 
57
62
  BUNDLED WITH
58
- 1.10.6
63
+ 1.17.3
data/Rakefile CHANGED
@@ -1,14 +1,16 @@
1
- require 'bundler/gem_tasks'
2
- require 'rubocop/rake_task'
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 'rspec/core/rake_task'
9
+ require "rspec/core/rake_task"
8
10
  RSpec::Core::RakeTask.new(:spec)
9
11
  rescue LoadError
10
- puts 'Unable to load rspec. Have you run `bundle install`?'
12
+ puts "Unable to load rspec. Have you run `bundle install`?"
11
13
  end
12
14
 
13
15
  task(:default).clear
14
- task default: ['rubocop:auto_correct', :spec]
16
+ task default: ["rubocop:auto_correct", :spec]
@@ -1,26 +1,27 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'amplitude_api/version'
5
+ require "amplitude_api/version"
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = 'amplitude-api'
8
+ spec.name = "amplitude-api"
8
9
  spec.version = AmplitudeAPI::VERSION
9
- spec.authors = ['Alex Rakoczy']
10
- spec.email = ['arakoczy@gmail.com']
11
- spec.summary = 'Send events to the Amplitude API'
12
- spec.description = 'Provides an integration for sending events to Amplitude'
13
- spec.homepage = 'https://github.com/toothrot/amplitude-api'
14
- spec.license = 'MIT'
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"
15
16
 
16
17
  spec.files = `git ls-files -z`.split("\x0")
17
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ['lib']
20
+ spec.require_paths = ["lib"]
20
21
 
21
- spec.add_development_dependency 'rspec', '~> 2.99', '>= 2.99.0'
22
- spec.add_development_dependency 'rake', '~> 10.0', '>= 10.0'
23
- spec.add_development_dependency 'pry', '~> 0.9.12.6'
24
- spec.add_dependency 'typhoeus', '~> 1.0.2'
25
- spec.required_ruby_version = '~> 2.0'
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"
26
27
  end
data/lib/amplitude-api.rb CHANGED
@@ -1,4 +1,3 @@
1
- # rubocop:disable Style/FileName
2
- require_relative 'amplitude_api'
3
- # rubocop:enable Style/FileName
4
- # Whoops.
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "amplitude_api"
data/lib/amplitude_api.rb CHANGED
@@ -1,25 +1,37 @@
1
- require 'json'
2
- require 'bundler/setup'
3
- require 'typhoeus'
4
- require_relative 'amplitude_api/event'
5
- require_relative 'amplitude_api/identification'
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "faraday"
6
5
 
7
6
  # AmplitudeAPI
8
7
  class AmplitudeAPI
9
- TRACK_URI_STRING = 'https://api.amplitude.com/httpapi'.freeze
10
- IDENTIFY_URI_STRING = 'https://api.amplitude.com/identify'.freeze
11
- SEGMENTATION_URI_STRING = 'https://amplitude.com/api/2/events/segmentation'.freeze
8
+ require_relative "amplitude_api/config"
9
+ require_relative "amplitude_api/event"
10
+ require_relative "amplitude_api/identification"
11
+
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"
12
16
 
13
- USER_WITH_NO_ACCOUNT = "user who doesn't have an account".freeze
17
+ USER_WITH_NO_ACCOUNT = "user who doesn't have an account"
14
18
 
15
19
  class << self
16
- # @!attribute [ rw ] api_key
17
- # @return [ String ] an Amplitude API Key
18
- attr_accessor :api_key
20
+ def config
21
+ Config.instance
22
+ end
19
23
 
20
- # @!attribute [ rw ] secret_key
21
- # @return [ String ] an Amplitude Secret Key
22
- attr_accessor :secret_key
24
+ def configure
25
+ yield config
26
+ end
27
+
28
+ def api_key
29
+ config.api_key
30
+ end
31
+
32
+ def secret_key
33
+ config.secret_key
34
+ end
23
35
 
24
36
  # ==== Event Tracking related methods
25
37
 
@@ -28,12 +40,12 @@ class AmplitudeAPI
28
40
  # @param [ String ] event_name a string that describes the event, e.g. "clicked on Home"
29
41
  # @param [ String ] user a string or integer that uniquely identifies a user.
30
42
  # @param [ String ] device a string that uniquely identifies the device.
31
- # @param [ Hash ] event_properties a hash that is serialized to JSON,
43
+ # @option options [ Hash ] event_properties a hash that is serialized to JSON,
32
44
  # and can contain any other property to be stored on the Event
33
- # @param [ Hash ] user_properties a hash that is serialized to JSON,
45
+ # @option options [ Hash ] user_properties a hash that is serialized to JSON,
34
46
  # and contains user properties to be associated with the user
35
47
  #
36
- # @return [ Typhoeus::Response ]
48
+ # @return [ Faraday::Response ]
37
49
  def send_event(event_name, user, device, options = {})
38
50
  event = AmplitudeAPI::Event.new(
39
51
  user_id: user,
@@ -58,10 +70,13 @@ class AmplitudeAPI
58
70
  def track_body(*events)
59
71
  event_body = events.flatten.map(&:to_hash)
60
72
 
61
- {
73
+ body = {
62
74
  api_key: api_key,
63
- event: JSON.generate(event_body)
75
+ events: event_body
64
76
  }
77
+ body[:options] = config.options if config.options
78
+
79
+ JSON.generate(body)
65
80
  end
66
81
 
67
82
  # @overload track(event)
@@ -70,11 +85,11 @@ class AmplitudeAPI
70
85
  # @overload track([events])
71
86
  # @param [ Array<AmplitudeAPI::Event> ] Send an array of events in a single request to Amplitude
72
87
  #
73
- # @return [ Typhoeus::Response ]
88
+ # @return [ Faraday::Response ]
74
89
  #
75
90
  # Send one or more Events to the Amplitude API
76
91
  def track(*events)
77
- Typhoeus.post(TRACK_URI_STRING, body: track_body(events))
92
+ Faraday.post(TRACK_URI_STRING, track_body(events), "Content-Type" => "application/json")
78
93
  end
79
94
 
80
95
  # ==== Identification related methods
@@ -113,45 +128,89 @@ class AmplitudeAPI
113
128
  # @overload identify([identifications])
114
129
  # @param [ Array<AmplitudeAPI::Identify> ] Send an array of identifications in a single request to Amplitude
115
130
  #
116
- # @return [ Typhoeus::Response ]
131
+ # @return [ Faraday::Response ]
117
132
  #
118
133
  # Send one or more Identifications to the Amplitude Identify API
119
134
  def identify(*identifications)
120
- Typhoeus.post(IDENTIFY_URI_STRING, body: identify_body(identifications))
135
+ Faraday.post(IDENTIFY_URI_STRING, identify_body(identifications))
121
136
  end
122
137
 
123
138
  # ==== Event Segmentation related methods
124
139
 
125
140
  # Get metrics for an event with segmentation.
126
141
  #
127
- # @param [ Hash ] e a hash that defines event.
142
+ # @param [ Hash ] event a hash that defines event.
128
143
  # @param [ Time ] start_time a start time.
129
144
  # @param [ Time ] end_time a end time.
130
- # @param [ String ] m a string that defines aggregate function.
145
+ # @option options [ String ] m a string that defines aggregate function.
131
146
  # For non-property metrics: "uniques", "totals", "pct_dau", or "average" (default: "uniques").
132
147
  # For property metrics: "histogram", "sums", or "value_avg"
133
148
  # (note: a valid "group_by" value is required in parameter e).
134
- # @param [ Integer ] i an integer that defines segmentation interval.
149
+ # @option options [ Integer ] i an integer that defines segmentation interval.
135
150
  # Set to -300000, -3600000, 1, 7, or 30 for realtime, hourly, daily, weekly,
136
151
  # and monthly counts, respectively (default: 1). Realtime segmentation is capped at 2 days,
137
152
  # hourly segmentation is capped at 7 days, and daily at 365 days.
138
- # @param [ Array ] s an array that defines segment definitions.
139
- # @param [ String ] g a string that defines property to group by.
140
- # @param [ Integer ] limit an integer that defines number of Group By values
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
141
156
  # returned (default: 100). The maximum limit is 1000.
142
157
  #
143
- # @return [ Typhoeus::Response ]
144
- def segmentation(e, start_time, end_time, **options)
145
- Typhoeus.get SEGMENTATION_URI_STRING, userpwd: "#{api_key}:#{secret_key}", params: {
146
- e: e.to_json,
147
- m: options[:m],
148
- start: start_time.strftime('%Y%m%d'),
149
- end: end_time.strftime('%Y%m%d'),
150
- i: options[:i],
151
- s: (options[:s] || []).map(&:to_json),
152
- g: options[:g],
158
+ # @return [ Faraday::Response ]
159
+ def segmentation(event, start_time, end_time, **options)
160
+ Faraday.get SEGMENTATION_URI_STRING, userpwd: "#{api_key}:#{secret_key}", params: {
161
+ e: event.to_json,
162
+ m: options[:m],
163
+ start: start_time.strftime("%Y%m%d"),
164
+ end: end_time.strftime("%Y%m%d"),
165
+ i: options[:i],
166
+ s: (options[:s] || []).map(&:to_json),
167
+ g: options[:g],
153
168
  limit: options[:limit]
154
169
  }.delete_if { |_, value| value.nil? }
155
170
  end
171
+
172
+ # Delete a user from amplitude
173
+ #
174
+ # You must pass in either an array of user_ids or an array of amplitude_ids
175
+ #
176
+ # @param [ Array<String> ] (optional) the user_ids to delete
177
+ # based on your database
178
+ # @param [ Array<Integer> ] (optional) the amplitude_ids to delete
179
+ # based on the amplitude database
180
+ # @param [ String ] requester the email address of the person who
181
+ # is requesting the deletion, optional but useful for reporting
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)
214
+ end
156
215
  end
157
216
  end