|
| 1 | +# Create Analytics Event |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +This document outlines the process for creating a new analytics event in MetaMask (Extension and Mobile) |
| 6 | + |
| 7 | +## Prerequisites |
| 8 | + |
| 9 | +- Before you begin, please refer to this [Working with Event Metrics](https://www.notion.so/consensys/Working-with-Event-Metrics-3b0b5a4308e64649a54a2864886c0412) and make sure you understand the context of the analytics events. |
| 10 | +- Users must opt into MetaMetrics for events to be tracked, this can be configured when onboarding and in settings `Privacy & Security` => `Participate in MetaMetrics` |
| 11 | + |
| 12 | + |
| 13 | +## Creating a New Analytics Event |
| 14 | + |
| 15 | +### 1. Define the Event Schema |
| 16 | + |
| 17 | +First, create a schema for your event following the [Segment Schema guidelines](https://github.com/Consensys/segment-schema/blob/main/CONTRIBUTING.md). Your event should: |
| 18 | + |
| 19 | +- Have a clear, descriptive name (e.g., `wallet_connected`) |
| 20 | +- Include relevant properties and context |
| 21 | +- Follow the naming conventions |
| 22 | + |
| 23 | +### 2. Implement a New Event in the Extension |
| 24 | + |
| 25 | +#### 2.1. Add the Event Name to the Segment Schema |
| 26 | + |
| 27 | +Add your new event name as a string literal type to the `MetaMetricsEventName` enum in `shared/constants/metametrics.ts`. |
| 28 | +And please check `MetaMetricsEventPayload` inside `shared/constants/metametrics.ts`for the details of the parameters. |
| 29 | + |
| 30 | +#### 2.2. Implement the Event in the Extension |
| 31 | + |
| 32 | +To implement an analytics event in the extension, you'll need to use the `MetaMetricsContext` and its `trackEvent` function. This context provides a standardized way to track events while handling opt-in status and data anonymization automatically. Below is an example showing how to implement event tracking in a React component: |
| 33 | + |
| 34 | +```typescript |
| 35 | +// 1. Import the required types and context |
| 36 | +import { MetaMetricsContext } from '../../../shared/contexts/metametrics'; |
| 37 | +import { |
| 38 | + MetaMetricsEventName, |
| 39 | + MetaMetricsEventCategory, |
| 40 | + MetaMetricsEventFragment, |
| 41 | +} from '../../../shared/constants/metametrics'; |
| 42 | + |
| 43 | +// 2. Use the context in your component |
| 44 | +function YourComponent() { |
| 45 | + const { trackEvent } = useContext(MetaMetricsContext); |
| 46 | + |
| 47 | + const handleAction = () => { |
| 48 | + trackEvent({ |
| 49 | + event: MetaMetricsEventName.YourNewEventName, |
| 50 | + category: MetaMetricsEventCategory.YourCategory, |
| 51 | + properties: { |
| 52 | + // Add properties that provide context about the event |
| 53 | + property_one: 'value_one', |
| 54 | + property_two: 'value_two', |
| 55 | + }, |
| 56 | + sensitiveProperties: { |
| 57 | + // Add properties that might contain sensitive data |
| 58 | + // These will be automatically anonymized |
| 59 | + wallet_address: '0x...', |
| 60 | + }, |
| 61 | + }); |
| 62 | + }; |
| 63 | + |
| 64 | + return <button onClick={handleAction}>Perform Action</button>; |
| 65 | +} |
| 66 | +``` |
| 67 | + |
| 68 | +#### 2.3 E2E Testing |
| 69 | + |
| 70 | +For implementing analytics event mocks in E2E tests using `testSpecificMock`, please refer to recording in notion of [Extension Codebase - E2E tests (mocking)](https://www.notion.so/metamask-consensys/f649ecf027cc41db858d3a3574fe3a99?v=da4af5e48f0e44d7b4536c4e2e911f36). |
| 71 | + |
| 72 | +Example E2E test implementation: |
| 73 | + |
| 74 | +```typescript |
| 75 | +// Mock the analytics endpoint |
| 76 | +async function mockAnalyticsEndpoint(mockServer) { |
| 77 | + return await mockServer |
| 78 | + .forPost('https://api.segment.io/v1/batch') |
| 79 | + .withJsonBodyIncluding({ |
| 80 | + batch: [ |
| 81 | + { |
| 82 | + type: 'track', |
| 83 | + event: MetaMetricsEventName.YourNewEventName, |
| 84 | + properties: { |
| 85 | + property_one: 'value_one', |
| 86 | + property_two: 'value_two', |
| 87 | + }, |
| 88 | + }, |
| 89 | + ], |
| 90 | + }) |
| 91 | + .thenCallback(() => ({ statusCode: 200 })); |
| 92 | +} |
| 93 | + |
| 94 | +describe('YourNewEventName Analytics', () => { |
| 95 | + it('should track the event with correct properties', async () => { |
| 96 | + await withFixtures( |
| 97 | + { |
| 98 | + fixtures: new FixtureBuilder() |
| 99 | + .withMetaMetricsController({ |
| 100 | + participateInMetaMetrics: true, |
| 101 | + }) |
| 102 | + .build(), |
| 103 | + testSpecificMock: async (mockServer) => [ |
| 104 | + await mockAnalyticsEndpoint(mockServer), |
| 105 | + ], |
| 106 | + }, |
| 107 | + async ({ driver, mockedEndpoints }) => { |
| 108 | + // Test implementation |
| 109 | + const events = await getEventPayloads(driver, mockedEndpoints); |
| 110 | + assert.equal(events[0].properties.property_one, 'value_one'); |
| 111 | + assert.equal(events[0].properties.property_two, 'value_two'); |
| 112 | + }, |
| 113 | + ); |
| 114 | + }); |
| 115 | +}); |
| 116 | +``` |
| 117 | + |
| 118 | +#### 2.4. Validate the Event |
| 119 | + |
| 120 | +To validate your analytics event implementation: |
| 121 | + |
| 122 | +1. Run the extension locally in development mode |
| 123 | +2. Open Chrome DevTools |
| 124 | +3. Navigate to the Network tab |
| 125 | +4. Perform the action that should trigger your analytics event |
| 126 | +5. Look for a `batch` request in the Network tab |
| 127 | +6. Inspect the request payload to verify: |
| 128 | + - The event name matches your implementation |
| 129 | + - All expected properties are present and correctly formatted |
| 130 | + - Property values are being captured as intended |
| 131 | + |
| 132 | + |
| 133 | + |
| 134 | +#### 2.5. Opt-out Handling |
| 135 | + |
| 136 | +The tracking system automatically respects user privacy settings: |
| 137 | + |
| 138 | +- Events are only tracked if the user has opted into MetaMetrics |
| 139 | +- Sensitive data is automatically anonymized |
| 140 | +- You don't need to check opt-in status before calling trackEvent |
| 141 | + |
| 142 | +### 3. Implement the Event in the Mobile App |
| 143 | + |
| 144 | +TODO: Add instructions for the mobile app |
0 commit comments