amplitude-api 0.0.10 → 0.3.2

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