Skip to content

Commit

Permalink
feat: Enable some Amplitude autocapture events (#3731)
Browse files Browse the repository at this point in the history
  • Loading branch information
spalmurray-codecov authored Feb 13, 2025
1 parent cb3fe37 commit 7eded14
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 2 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
},
"dependencies": {
"@amplitude/analytics-browser": "^2.11.9",
"@amplitude/analytics-types": "^2.8.4",
"@hookform/resolvers": "^2.8.5",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-checkbox": "^1.1.1",
Expand Down
1 change: 1 addition & 0 deletions src/services/events/__mocks__/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { EventTracker } from '../types'
//

const MOCK_EVENT_TRACKER: EventTracker = {
context: {},
identify: vi.fn(),
track: vi.fn(),
setContext: vi.fn(),
Expand Down
56 changes: 55 additions & 1 deletion src/services/events/amplitude/amplitude.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { Config, CoreClient, Event } from '@amplitude/analytics-types'

import config from 'config'

import { AmplitudeEventTracker, initAmplitude } from './amplitude'
import {
AmplitudeEventTracker,
initAmplitude,
pageViewTrackingSanitization,
} from './amplitude'

const mockIdentifySet = vi.hoisted(() => vi.fn())
const mockIdentifyConstructor = vi.hoisted(() => vi.fn())
Expand All @@ -14,6 +20,7 @@ const mockAmplitude = vi.hoisted(() => {
}
}
return {
add: vi.fn(),
init: vi.fn(),
track: vi.fn(),
identify: vi.fn(),
Expand Down Expand Up @@ -52,6 +59,53 @@ describe('when initAmplitude is called', () => {
})
})

describe('pageViewTrackingSanitization', () => {
it('removes sensitive info from Page Viewed event properties', async () => {
const plugin = pageViewTrackingSanitization()

if (plugin.setup) {
plugin?.setup({} as Config, {} as CoreClient)
}

if (plugin.execute) {
const event = await plugin.execute({
event_type: '[Amplitude] Page Viewed',
event_properties: {
'[Amplitude] Page Counter': 1,
'[Amplitude] Page Domain': 'app.codecov.io',
'[Amplitude] Page Path': '/sensitive/info',
'[Amplitude] Page Location': 'https://app.codecov.io/sensitive/info',
},
} as Event)
expect(event?.event_properties).toMatchObject({
'[Amplitude] Page Counter': 1,
'[Amplitude] Page Domain': 'app.codecov.io',
path: undefined,
})
}
})

it('does not touch other event types', async () => {
const plugin = pageViewTrackingSanitization()

if (plugin.setup) {
plugin?.setup({} as Config, {} as CoreClient)
}

if (plugin.execute) {
const event = await plugin.execute({
event_type: 'Button Clicked',
event_properties: {
'[Amplitude] Page Path': '/sensitive/info',
},
} as Event)
expect(event?.event_properties).toMatchObject({
'[Amplitude] Page Path': '/sensitive/info',
})
}
})
})

describe('AmplitudeEventTracker', () => {
describe('identify', () => {
describe('when identify is called', () => {
Expand Down
34 changes: 33 additions & 1 deletion src/services/events/amplitude/amplitude.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,53 @@
import * as amplitude from '@amplitude/analytics-browser'
import { EnrichmentPlugin } from '@amplitude/analytics-types'

import config from 'config'

import { providerToInternalProvider } from 'shared/utils/provider'

import { eventTracker } from '../events'
import { Event, EventContext, EventTracker, Identity } from '../types'

export const pageViewTrackingSanitization = (): EnrichmentPlugin => {
return {
name: 'page-view-tracking-sanitization',
type: 'enrichment',
setup: async () => undefined,
execute: async (event) => {
if (event.event_type === '[Amplitude] Page Viewed') {
/* eslint-disable camelcase */
event.event_properties = {
'[Amplitude] Page Counter':
event.event_properties?.['[Amplitude] Page Counter'],
'[Amplitude] Page Domain':
event.event_properties?.['[Amplitude] Page Domain'],
path: eventTracker().context.path,
}
}

return event
},
}
}

export function initAmplitude() {
const apiKey = config.AMPLITUDE_API_KEY
if (!apiKey) {
throw new Error(
'AMPLITUDE_API_KEY is not defined. Amplitude events will not be tracked.'
)
}
amplitude.add(pageViewTrackingSanitization())
amplitude.init(apiKey, {
// Disable all autocapture - may change this in the future
autocapture: false,
autocapture: {
attribution: true,
pageViews: true,
sessions: true,
formInteractions: false,
fileDownloads: false,
elementInteractions: false,
},
minIdLength: 1, // Necessary to accommodate our owner ids
serverUrl: 'https://amplitude.codecov.io/2/httpapi',
})
Expand Down
2 changes: 2 additions & 0 deletions src/services/events/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { AmplitudeEventTracker, initAmplitude } from './amplitude/amplitude'
import { Event, EventContext, EventTracker, Identity } from './types'

export class StubbedEventTracker implements EventTracker {
context: EventContext = {}

identify(_identity: Identity): void {}
track(_event: Event): void {}
setContext(_context: EventContext): void {}
Expand Down
2 changes: 2 additions & 0 deletions src/services/events/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ export type EventContext = {
}

export abstract class EventTracker {
context: EventContext = {}

// Identifies the user this session belongs to.
identify(_identity: Identity): void {
throw new Error(
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9053,6 +9053,7 @@ __metadata:
dependencies:
"@acemarke/react-prod-sourcemaps": "npm:^0.3.1"
"@amplitude/analytics-browser": "npm:^2.11.9"
"@amplitude/analytics-types": "npm:^2.8.4"
"@babel/eslint-parser": "npm:^7.25.9"
"@babel/plugin-proposal-private-property-in-object": "npm:^7.21.11"
"@chromatic-com/storybook": "npm:^1"
Expand Down

0 comments on commit 7eded14

Please sign in to comment.