amplitude-api 0.0.8 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 67727755b54bfef1fc3ffa5889e11c7931420a13
4
- data.tar.gz: 52feec8f51522d7f2c17b0db39d4e033f76efe2b
2
+ SHA256:
3
+ metadata.gz: 59e87e342af629c6e87369ef210a272186236ec4e4ef9f9a101a2a590da59204
4
+ data.tar.gz: 7e207b30db0550982c4280aa0da2d3c225b1598cfd2bcba1971e8a75238e142e
5
5
  SHA512:
6
- metadata.gz: f3b3bf19725cda0082c7cf0acb7ca40614430a63ff5d929e803c3074955d9b35e5674987745a5fb17d2cc0e030fb7319a5903e012d40c98f5e171efea8f3b0f6
7
- data.tar.gz: 09b6ca4ddb4ec2bdbed9980a41356b6f0096feace6819209c98ce37eb2a83722f509ca60762ccd7731a10308693bdce1eddf88f9e5cb27338fdf92be84dffd74
6
+ metadata.gz: 42aa5d35506dcaebb8a9db1e973081f38d0259eacc1da1eeeae6d530fc92055dfc70f749e4b19a4e28e3b726e92abae52e575207f1fadfa483bd2b6d6abba771
7
+ data.tar.gz: 7e97e56ac203bee46e1740e937c0869cb310d8c4edbc88ce6c2603446c5ad0989e52ffbf327be61680813ff2e92808a9ae91e09d0de9e4de5f4cedae590c2415
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,34 @@
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.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
+
28
+ ## 0.0.10 (2017-09-13)
29
+
30
+ * Allow to use "Event Segmentation" via API ([#23](https://github.com/toothrot/amplitude-api/pull/23)).
31
+
32
+ ## Older releases
33
+
34
+ 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,20 +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
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"
11
16
 
12
- USER_WITH_NO_ACCOUNT = "user who doesn't have an account".freeze
17
+ USER_WITH_NO_ACCOUNT = "user who doesn't have an account"
13
18
 
14
19
  class << self
15
- # @!attribute [ rw ] api_key
16
- # @return [ String ] an Amplitude API Key
17
- attr_accessor :api_key
20
+ def config
21
+ Config.instance
22
+ end
23
+
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
18
35
 
19
36
  # ==== Event Tracking related methods
20
37
 
@@ -22,15 +39,17 @@ class AmplitudeAPI
22
39
  #
23
40
  # @param [ String ] event_name a string that describes the event, e.g. "clicked on Home"
24
41
  # @param [ String ] user a string or integer that uniquely identifies a user.
25
- # @param [ Hash ] event_properties a hash that is serialized to JSON,
42
+ # @param [ String ] device a string that uniquely identifies the device.
43
+ # @option options [ Hash ] event_properties a hash that is serialized to JSON,
26
44
  # and can contain any other property to be stored on the Event
27
- # @param [ Hash ] user_properties a hash that is serialized to JSON,
45
+ # @option options [ Hash ] user_properties a hash that is serialized to JSON,
28
46
  # and contains user properties to be associated with the user
29
47
  #
30
- # @return [ Typhoeus::Response ]
31
- def send_event(event_name, user, options = {})
48
+ # @return [ Faraday::Response ]
49
+ def send_event(event_name, user, device, options = {})
32
50
  event = AmplitudeAPI::Event.new(
33
51
  user_id: user,
52
+ device_id: device,
34
53
  event_type: event_name,
35
54
  event_properties: options.fetch(:event_properties, {}),
36
55
  user_properties: options.fetch(:user_properties, {})
@@ -51,10 +70,10 @@ class AmplitudeAPI
51
70
  def track_body(*events)
52
71
  event_body = events.flatten.map(&:to_hash)
53
72
 
54
- {
73
+ JSON.generate(
55
74
  api_key: api_key,
56
- event: JSON.generate(event_body)
57
- }
75
+ events: event_body
76
+ )
58
77
  end
59
78
 
60
79
  # @overload track(event)
@@ -63,17 +82,21 @@ class AmplitudeAPI
63
82
  # @overload track([events])
64
83
  # @param [ Array<AmplitudeAPI::Event> ] Send an array of events in a single request to Amplitude
65
84
  #
66
- # @return [ Typhoeus::Response ]
85
+ # @return [ Faraday::Response ]
67
86
  #
68
87
  # Send one or more Events to the Amplitude API
69
88
  def track(*events)
70
- Typhoeus.post(TRACK_URI_STRING, body: track_body(events))
89
+ Faraday.post(TRACK_URI_STRING, track_body(events), "Content-Type" => "application/json")
71
90
  end
72
91
 
73
92
  # ==== Identification related methods
74
93
 
75
- def send_identify(user_id, user_properties = {})
76
- identification = AmplitudeAPI::Identification.new(user_id: user_id, user_properties: user_properties)
94
+ def send_identify(user_id, device_id, user_properties = {})
95
+ identification = AmplitudeAPI::Identification.new(
96
+ user_id: user_id,
97
+ device_id: device_id,
98
+ user_properties: user_properties
99
+ )
77
100
  identify(identification)
78
101
  end
79
102
 
@@ -102,11 +125,89 @@ class AmplitudeAPI
102
125
  # @overload identify([identifications])
103
126
  # @param [ Array<AmplitudeAPI::Identify> ] Send an array of identifications in a single request to Amplitude
104
127
  #
105
- # @return [ Typhoeus::Response ]
128
+ # @return [ Faraday::Response ]
106
129
  #
107
130
  # Send one or more Identifications to the Amplitude Identify API
108
131
  def identify(*identifications)
109
- Typhoeus.post(IDENTIFY_URI_STRING, body: identify_body(identifications))
132
+ Faraday.post(IDENTIFY_URI_STRING, identify_body(identifications))
133
+ end
134
+
135
+ # ==== Event Segmentation related methods
136
+
137
+ # Get metrics for an event with segmentation.
138
+ #
139
+ # @param [ Hash ] event a hash that defines event.
140
+ # @param [ Time ] start_time a start time.
141
+ # @param [ Time ] end_time a end time.
142
+ # @option options [ String ] m a string that defines aggregate function.
143
+ # For non-property metrics: "uniques", "totals", "pct_dau", or "average" (default: "uniques").
144
+ # For property metrics: "histogram", "sums", or "value_avg"
145
+ # (note: a valid "group_by" value is required in parameter e).
146
+ # @option options [ Integer ] i an integer that defines segmentation interval.
147
+ # Set to -300000, -3600000, 1, 7, or 30 for realtime, hourly, daily, weekly,
148
+ # and monthly counts, respectively (default: 1). Realtime segmentation is capped at 2 days,
149
+ # hourly segmentation is capped at 7 days, and daily at 365 days.
150
+ # @option options [ Array ] s an array that defines segment definitions.
151
+ # @option options [ String ] g a string that defines property to group by.
152
+ # @option options [ Integer ] limit an integer that defines number of Group By values
153
+ # returned (default: 100). The maximum limit is 1000.
154
+ #
155
+ # @return [ Faraday::Response ]
156
+ def segmentation(event, start_time, end_time, **options)
157
+ Faraday.get SEGMENTATION_URI_STRING, userpwd: "#{api_key}:#{secret_key}", params: {
158
+ e: event.to_json,
159
+ m: options[:m],
160
+ start: start_time.strftime("%Y%m%d"),
161
+ end: end_time.strftime("%Y%m%d"),
162
+ i: options[:i],
163
+ s: (options[:s] || []).map(&:to_json),
164
+ g: options[:g],
165
+ limit: options[:limit]
166
+ }.delete_if { |_, value| value.nil? }
167
+ end
168
+
169
+ # Delete a user from amplitude
170
+ #
171
+ # You must pass in either an array of user_ids or an array of amplitude_ids
172
+ #
173
+ # @param [ Array<String> ] (optional) the user_ids to delete
174
+ # based on your database
175
+ # @param [ Array<Integer> ] (optional) the amplitude_ids to delete
176
+ # based on the amplitude database
177
+ # @param [ String ] requester the email address of the person who
178
+ # is requesting the deletion, optional but useful for reporting
179
+ # @param [ Boolean ] (optional) ignore any invalid user IDs(users that do no
180
+ # exist in the project) that were passed in
181
+ # @param [ Boolean ] (optional) delete from the entire org rather than just
182
+ # this project.
183
+ # @return [ Faraday::Response ]
184
+ def delete(user_ids: nil, amplitude_ids: nil, requester: nil, ignore_invalid_id: nil, delete_from_org: nil)
185
+ user_ids = Array(user_ids)
186
+ amplitude_ids = Array(amplitude_ids)
187
+
188
+ faraday = Faraday.new do |conn|
189
+ conn.basic_auth config.api_key, config.secret_key
190
+ end
191
+
192
+ faraday.post(
193
+ DELETION_URI_STRING,
194
+ delete_body(user_ids, amplitude_ids, requester, ignore_invalid_id, delete_from_org),
195
+ "Content-Type" => "application/json"
196
+ )
197
+ end
198
+
199
+ private
200
+
201
+ def delete_body(user_ids, amplitude_ids, requester, ignore_invalid_id, delete_from_org)
202
+ body = {
203
+ amplitude_ids: amplitude_ids,
204
+ user_ids: user_ids,
205
+ requester: requester
206
+ }.delete_if { |_, value| value.nil? || value.empty? }
207
+
208
+ body[:ignore_invalid_id] = ignore_invalid_id.to_s if ignore_invalid_id
209
+ body[:delete_from_org] = delete_from_org.to_s if delete_from_org
210
+ JSON.generate(body)
110
211
  end
111
212
  end
112
213
  end