Skip to content

Commit

Permalink
Merge pull request #34 from samjohn/add-gdpr-compliance
Browse files Browse the repository at this point in the history
Add method to delete users in order to comply with GDPR
  • Loading branch information
Samjohn authored Jul 17, 2018
2 parents fc9ef72 + 55bd5b8 commit 40903ce
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 2 deletions.
24 changes: 24 additions & 0 deletions lib/amplitude_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class AmplitudeAPI
TRACK_URI_STRING = 'https://api.amplitude.com/httpapi'.freeze
IDENTIFY_URI_STRING = 'https://api.amplitude.com/identify'.freeze
SEGMENTATION_URI_STRING = 'https://amplitude.com/api/2/events/segmentation'.freeze
DELETION_URI_STRING = 'https://amplitude.com/api/2/deletions/users'.freeze

USER_WITH_NO_ACCOUNT = "user who doesn't have an account".freeze

Expand Down Expand Up @@ -162,5 +163,28 @@ def segmentation(e, start_time, end_time, **options)
limit: options[:limit]
}.delete_if { |_, value| value.nil? }
end

# ==== GDPR compliance methods

# Delete a user from amplitude when they request it to comply with GDPR
# You must pass in either an array of user_ids or an array of amplitude_ids
#
# @param [ user_ids ] (optional) the user_ids to delete
# based on your database
# @param [ amplitude_ids ] (optional) the amplitude_ids to delete
# based on the amplitude database
# @param [ requester ] the email address of the person who
# is requesting the deletion, optional but useful for reporting
#
# @return [ Typhoeus::Response ]
def delete(user_ids:nil, amplitude_ids:nil, requester:nil)
Typhoeus.post DELETION_URI_STRING,
userpwd: "#{api_key}:#{config.secret_key}",
body: {
amplitude_ids: amplitude_ids,
user_ids: user_ids,
requester: requester
}.delete_if { |_, value| value.nil? }
end
end
end
4 changes: 2 additions & 2 deletions lib/amplitude_api/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ def defaults
api_key: nil,
secret_key: nil,
whitelist: %i(user_id device_id event_type time
event_properties user_properties time ip platform country insert_id
revenue_type price quantity product_id),
event_properties user_properties time ip platform country insert_id
revenue_type price quantity product_id),
time_formatter: ->(time) { time ? time.to_i * 1_000 : nil },
event_properties_formatter: ->(props) { props || {} },
user_properties_formatter: ->(props) { props || {} }
Expand Down
16 changes: 16 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ event = AmplitudeAPI::Event.new({
AmplitudeAPI.track(event)
```

## GDPR Compliance

The following code snippet will delete a user from amplitude

```ruby
# Configure your Amplitude API key
AmplitudeAPI.config.api_key = "abcdef123456"

# Configure your Amplitude Secret Key
AmplitudeAPI.config.secret_key = "secretMcSecret"

AmplitudeAPI.delete(user_ids: [233],
requester: "privacy@mycompany.com"
)
```

Currently, we are using this in Rails and using ActiveJob to dispatch events asynchronously. I plan on moving background/asynchronous support into this gem.

## What's Next
Expand Down
72 changes: 72 additions & 0 deletions spec/lib/amplitude_api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,78 @@
end
end

describe '.delete' do
context 'with user_ids' do
it 'sends the deletion to Amplitude' do
user_ids = [123, 456, 555]
body = {
user_ids: user_ids
}

expect(Typhoeus).to receive(:post).with(
AmplitudeAPI::DELETION_URI_STRING,
userpwd: "#{described_class.api_key}:#{described_class.config.secret_key}",
body: body)
described_class.delete(user_ids: user_ids)
end

context 'with amplitude_ids' do
it 'sends the deletion to Amplitude' do
user_ids = [123, 456, 555]
amplitude_ids = [122, 456]
body = {
user_ids: user_ids,
amplitude_ids: amplitude_ids
}

expect(Typhoeus).to receive(:post).with(
AmplitudeAPI::DELETION_URI_STRING,
userpwd: "#{described_class.api_key}:#{described_class.config.secret_key}",
body: body)
described_class.delete(
amplitude_ids: amplitude_ids,
user_ids: user_ids
)
end
end
end

context 'with amplitude_ids' do
it 'sends the deletion to Amplitude' do
amplitude_ids = [122, 456]
body = {
amplitude_ids: amplitude_ids
}

expect(Typhoeus).to receive(:post).with(
AmplitudeAPI::DELETION_URI_STRING,
userpwd: "#{described_class.api_key}:#{described_class.config.secret_key}",
body: body)
described_class.delete(amplitude_ids: amplitude_ids)
end
end

context 'with requester' do
it 'sends the deletion to Amplitude' do
amplitude_ids = [122, 456]

body = {
amplitude_ids: amplitude_ids,
requester: 'privacy@gethopscotch.com'
}
userpwd = "#{described_class.api_key}:#{described_class.config.secret_key}"

expect(Typhoeus).to receive(:post).with(AmplitudeAPI::DELETION_URI_STRING,
userpwd: userpwd,
body: body)
described_class.delete(
amplitude_ids: amplitude_ids,
requester: 'privacy@gethopscotch.com'
)
end
end
end

describe '#body' do
it 'adds an api key' do
event = AmplitudeAPI::Event.new(
Expand Down
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@

config.before(:suite) do
AmplitudeAPI.config.api_key = 'stub api key'
AmplitudeAPI.config.secret_key = 'stub secret key'
end
end

0 comments on commit 40903ce

Please sign in to comment.