Skip to content

Commit 7eded14

Browse files
feat: Enable some Amplitude autocapture events (#3731)
1 parent cb3fe37 commit 7eded14

File tree

7 files changed

+95
-2
lines changed

7 files changed

+95
-2
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
},
3232
"dependencies": {
3333
"@amplitude/analytics-browser": "^2.11.9",
34+
"@amplitude/analytics-types": "^2.8.4",
3435
"@hookform/resolvers": "^2.8.5",
3536
"@radix-ui/react-accordion": "^1.1.2",
3637
"@radix-ui/react-checkbox": "^1.1.1",

src/services/events/__mocks__/events.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { EventTracker } from '../types'
88
//
99

1010
const MOCK_EVENT_TRACKER: EventTracker = {
11+
context: {},
1112
identify: vi.fn(),
1213
track: vi.fn(),
1314
setContext: vi.fn(),

src/services/events/amplitude/amplitude.test.tsx

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
import { Config, CoreClient, Event } from '@amplitude/analytics-types'
2+
13
import config from 'config'
24

3-
import { AmplitudeEventTracker, initAmplitude } from './amplitude'
5+
import {
6+
AmplitudeEventTracker,
7+
initAmplitude,
8+
pageViewTrackingSanitization,
9+
} from './amplitude'
410

511
const mockIdentifySet = vi.hoisted(() => vi.fn())
612
const mockIdentifyConstructor = vi.hoisted(() => vi.fn())
@@ -14,6 +20,7 @@ const mockAmplitude = vi.hoisted(() => {
1420
}
1521
}
1622
return {
23+
add: vi.fn(),
1724
init: vi.fn(),
1825
track: vi.fn(),
1926
identify: vi.fn(),
@@ -52,6 +59,53 @@ describe('when initAmplitude is called', () => {
5259
})
5360
})
5461

62+
describe('pageViewTrackingSanitization', () => {
63+
it('removes sensitive info from Page Viewed event properties', async () => {
64+
const plugin = pageViewTrackingSanitization()
65+
66+
if (plugin.setup) {
67+
plugin?.setup({} as Config, {} as CoreClient)
68+
}
69+
70+
if (plugin.execute) {
71+
const event = await plugin.execute({
72+
event_type: '[Amplitude] Page Viewed',
73+
event_properties: {
74+
'[Amplitude] Page Counter': 1,
75+
'[Amplitude] Page Domain': 'app.codecov.io',
76+
'[Amplitude] Page Path': '/sensitive/info',
77+
'[Amplitude] Page Location': 'https://app.codecov.io/sensitive/info',
78+
},
79+
} as Event)
80+
expect(event?.event_properties).toMatchObject({
81+
'[Amplitude] Page Counter': 1,
82+
'[Amplitude] Page Domain': 'app.codecov.io',
83+
path: undefined,
84+
})
85+
}
86+
})
87+
88+
it('does not touch other event types', async () => {
89+
const plugin = pageViewTrackingSanitization()
90+
91+
if (plugin.setup) {
92+
plugin?.setup({} as Config, {} as CoreClient)
93+
}
94+
95+
if (plugin.execute) {
96+
const event = await plugin.execute({
97+
event_type: 'Button Clicked',
98+
event_properties: {
99+
'[Amplitude] Page Path': '/sensitive/info',
100+
},
101+
} as Event)
102+
expect(event?.event_properties).toMatchObject({
103+
'[Amplitude] Page Path': '/sensitive/info',
104+
})
105+
}
106+
})
107+
})
108+
55109
describe('AmplitudeEventTracker', () => {
56110
describe('identify', () => {
57111
describe('when identify is called', () => {

src/services/events/amplitude/amplitude.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,53 @@
11
import * as amplitude from '@amplitude/analytics-browser'
2+
import { EnrichmentPlugin } from '@amplitude/analytics-types'
23

34
import config from 'config'
45

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

8+
import { eventTracker } from '../events'
79
import { Event, EventContext, EventTracker, Identity } from '../types'
810

11+
export const pageViewTrackingSanitization = (): EnrichmentPlugin => {
12+
return {
13+
name: 'page-view-tracking-sanitization',
14+
type: 'enrichment',
15+
setup: async () => undefined,
16+
execute: async (event) => {
17+
if (event.event_type === '[Amplitude] Page Viewed') {
18+
/* eslint-disable camelcase */
19+
event.event_properties = {
20+
'[Amplitude] Page Counter':
21+
event.event_properties?.['[Amplitude] Page Counter'],
22+
'[Amplitude] Page Domain':
23+
event.event_properties?.['[Amplitude] Page Domain'],
24+
path: eventTracker().context.path,
25+
}
26+
}
27+
28+
return event
29+
},
30+
}
31+
}
32+
933
export function initAmplitude() {
1034
const apiKey = config.AMPLITUDE_API_KEY
1135
if (!apiKey) {
1236
throw new Error(
1337
'AMPLITUDE_API_KEY is not defined. Amplitude events will not be tracked.'
1438
)
1539
}
40+
amplitude.add(pageViewTrackingSanitization())
1641
amplitude.init(apiKey, {
1742
// Disable all autocapture - may change this in the future
18-
autocapture: false,
43+
autocapture: {
44+
attribution: true,
45+
pageViews: true,
46+
sessions: true,
47+
formInteractions: false,
48+
fileDownloads: false,
49+
elementInteractions: false,
50+
},
1951
minIdLength: 1, // Necessary to accommodate our owner ids
2052
serverUrl: 'https://amplitude.codecov.io/2/httpapi',
2153
})

src/services/events/events.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { AmplitudeEventTracker, initAmplitude } from './amplitude/amplitude'
66
import { Event, EventContext, EventTracker, Identity } from './types'
77

88
export class StubbedEventTracker implements EventTracker {
9+
context: EventContext = {}
10+
911
identify(_identity: Identity): void {}
1012
track(_event: Event): void {}
1113
setContext(_context: EventContext): void {}

src/services/events/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ export type EventContext = {
5656
}
5757

5858
export abstract class EventTracker {
59+
context: EventContext = {}
60+
5961
// Identifies the user this session belongs to.
6062
identify(_identity: Identity): void {
6163
throw new Error(

yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9053,6 +9053,7 @@ __metadata:
90539053
dependencies:
90549054
"@acemarke/react-prod-sourcemaps": "npm:^0.3.1"
90559055
"@amplitude/analytics-browser": "npm:^2.11.9"
9056+
"@amplitude/analytics-types": "npm:^2.8.4"
90569057
"@babel/eslint-parser": "npm:^7.25.9"
90579058
"@babel/plugin-proposal-private-property-in-object": "npm:^7.21.11"
90589059
"@chromatic-com/storybook": "npm:^1"

0 commit comments

Comments
 (0)