From 5531b0d9369a5e98342618c1cb57aa26d458f524 Mon Sep 17 00:00:00 2001 From: Nuno Sousa Date: Thu, 16 Jan 2025 11:04:19 +0000 Subject: [PATCH] Fix Mixpanel distinct_id for anonymous events --- .../trackEvent/__tests__/index.test.ts | 30 +++++++++++++++++++ .../mixpanel/trackEvent/functions.ts | 14 ++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/destination-actions/src/destinations/mixpanel/trackEvent/__tests__/index.test.ts b/packages/destination-actions/src/destinations/mixpanel/trackEvent/__tests__/index.test.ts index 343a8de7a0..901b6195e8 100644 --- a/packages/destination-actions/src/destinations/mixpanel/trackEvent/__tests__/index.test.ts +++ b/packages/destination-actions/src/destinations/mixpanel/trackEvent/__tests__/index.test.ts @@ -263,6 +263,36 @@ describe('Mixpanel.trackEvent', () => { } }) + it('should allow an empty, but present, distinct_id', async () => { + const event = createTestEvent({ timestamp, event: 'Test Event' }) + + nock('https://api.mixpanel.com').post('/import?strict=1').reply(200, {}) + + const responses = await testDestination.testAction('trackEvent', { + event, + settings: { + projectToken: MIXPANEL_PROJECT_TOKEN, + apiSecret: MIXPANEL_API_SECRET + }, + useDefaultMappings: true, + mapping: { + distinct_id: '' // Map an empty distinct_id for the action. + } + }) + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.json).toMatchObject([ + { + event: 'Test Event', + properties: expect.objectContaining({ + ...expectedProperties, + distinct_id: '' // Expect an empty string `distinct_id` returned. + }) + } + ]) + }) + it('should invoke performBatch for batches', async () => { const events = [ createTestEvent({ timestamp, event: 'Test Event1' }), diff --git a/packages/destination-actions/src/destinations/mixpanel/trackEvent/functions.ts b/packages/destination-actions/src/destinations/mixpanel/trackEvent/functions.ts index f175949209..fdcf24c5e8 100644 --- a/packages/destination-actions/src/destinations/mixpanel/trackEvent/functions.ts +++ b/packages/destination-actions/src/destinations/mixpanel/trackEvent/functions.ts @@ -17,12 +17,24 @@ export function getEventProperties(payload: Payload, settings: Settings): Mixpan browserVersion = getBrowserVersion(payload.userAgent) } const integration = payload.context?.integration as Record + + // When the `distinct_id` property is undefined we add the property in as a blank string, + // so that we can support Mixpanel events that aren't tied to a specific user. + // + // The `distinct_id` property is, according to documentation, supposed to + // ALWAYS be present, either with an identifying value or with an empty + // string value to denote that the event should be excluded from behavioral + // analysis. + // + // @see https://developer.mixpanel.com/reference/import-events#propertiesdistinct_id + const distinct_id = payload.distinct_id ?? '' + return { time: time, ip: payload.ip, id: payload.distinct_id, $anon_id: payload.anonymous_id, - distinct_id: payload.distinct_id, + distinct_id, $app_build_number: payload.app_build, $app_version_string: payload.app_version, $app_namespace: payload.app_namespace,