diff --git a/packages/destination-actions/src/destinations/mixpanel/alias/__tests__/index.test.ts b/packages/destination-actions/src/destinations/mixpanel/alias/__tests__/index.test.ts index 9300b7fb61..70461022d1 100644 --- a/packages/destination-actions/src/destinations/mixpanel/alias/__tests__/index.test.ts +++ b/packages/destination-actions/src/destinations/mixpanel/alias/__tests__/index.test.ts @@ -70,6 +70,35 @@ describe('Mixpanel.alias', () => { ) }) + it('should use IN server URL', async () => { + const event = createTestEvent({ previousId: 'test-prev-id' }) + nock('https://api-in.mixpanel.com').post('/track').reply(200, {}) + const responses = await testDestination.testAction('alias', { + event, + useDefaultMappings: true, + settings: { + projectToken: MIXPANEL_PROJECT_TOKEN, + apiSecret: MIXPANEL_API_SECRET, + apiRegion: ApiRegions.IN + } + }) + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.body).toMatchObject( + new URLSearchParams({ + data: JSON.stringify({ + event: '$create_alias', + properties: { + distinct_id: 'test-prev-id', + alias: 'user1234', + token: MIXPANEL_PROJECT_TOKEN + } + }) + }) + ) + }) + it('should default to US endpoint if apiRegion setting is undefined', async () => { const event = createTestEvent({ previousId: 'test-prev-id' }) diff --git a/packages/destination-actions/src/destinations/mixpanel/common/utils.ts b/packages/destination-actions/src/destinations/mixpanel/common/utils.ts index 5063aad50b..460732a3f3 100644 --- a/packages/destination-actions/src/destinations/mixpanel/common/utils.ts +++ b/packages/destination-actions/src/destinations/mixpanel/common/utils.ts @@ -1,6 +1,7 @@ export enum ApiRegions { US = 'US 🇺🇸', - EU = 'EU 🇪🇺' + EU = 'EU 🇪🇺', + IN = 'IN 🇮🇳' } export enum StrictMode { @@ -16,7 +17,10 @@ export function getApiServerUrl(apiRegion: string | undefined) { if (apiRegion == ApiRegions.EU) { return 'https://api-eu.mixpanel.com' } - return 'https://api.mixpanel.com' + if (apiRegion == ApiRegions.IN) { + return 'https://api-in.mixpanel.com' + } + return 'https://api.mixpanel.com' // Default US endpoint } export function getBrowser(userAgent: string): string { diff --git a/packages/destination-actions/src/destinations/mixpanel/generated-types.ts b/packages/destination-actions/src/destinations/mixpanel/generated-types.ts index b76732453d..b79a6b6502 100644 --- a/packages/destination-actions/src/destinations/mixpanel/generated-types.ts +++ b/packages/destination-actions/src/destinations/mixpanel/generated-types.ts @@ -10,7 +10,7 @@ export interface Settings { */ apiSecret: string /** - * Learn about [EU data residency](https://help.mixpanel.com/hc/en-us/articles/360039135652-Data-Residency-in-EU) + * Learn about [EU data residency](https://docs.mixpanel.com/docs/privacy/eu-residency) and [India data residency](https://docs.mixpanel.com/docs/privacy/in-residency) */ apiRegion?: string /** diff --git a/packages/destination-actions/src/destinations/mixpanel/groupIdentifyUser/__tests__/index.test.ts b/packages/destination-actions/src/destinations/mixpanel/groupIdentifyUser/__tests__/index.test.ts index cc0c70c541..e93d2120dd 100644 --- a/packages/destination-actions/src/destinations/mixpanel/groupIdentifyUser/__tests__/index.test.ts +++ b/packages/destination-actions/src/destinations/mixpanel/groupIdentifyUser/__tests__/index.test.ts @@ -156,6 +156,40 @@ describe('Mixpanel.groupIdentifyUser', () => { ) }) + it('should use IN server URL', async () => { + const event = createTestEvent({ + timestamp, + groupId: 'test-group-id', + traits: { hello: 'world', company: 'Mixpanel' } + }) + nock('https://api-in.mixpanel.com').post('/groups').reply(200, {}) + const responses = await testDestination.testAction('groupIdentifyUser', { + event, + useDefaultMappings: true, + settings: { + projectToken: MIXPANEL_PROJECT_TOKEN, + apiSecret: MIXPANEL_API_SECRET, + apiRegion: ApiRegions.IN + } + }) + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.body).toMatchObject( + new URLSearchParams({ + data: JSON.stringify({ + $token: MIXPANEL_PROJECT_TOKEN, + $group_key: '$group_id', + $group_id: 'test-group-id', + $set: { + hello: 'world', + company: 'Mixpanel' + } + }) + }) + ) + }) + it('should default to US endpoint if apiRegion setting is undefined', async () => { const event = createTestEvent({ timestamp, diff --git a/packages/destination-actions/src/destinations/mixpanel/identifyUser/__tests__/index.test.ts b/packages/destination-actions/src/destinations/mixpanel/identifyUser/__tests__/index.test.ts index 97ba7a649a..7b6ded7bed 100644 --- a/packages/destination-actions/src/destinations/mixpanel/identifyUser/__tests__/index.test.ts +++ b/packages/destination-actions/src/destinations/mixpanel/identifyUser/__tests__/index.test.ts @@ -217,6 +217,50 @@ describe('Mixpanel.identifyUser', () => { ) }) + it('should use IN server URL', async () => { + const event = createTestEvent({ timestamp, traits: { abc: '123' } }) + nock('https://api-in.mixpanel.com').post('/engage').reply(200, {}) + nock('https://api-in.mixpanel.com').post('/track').reply(200, {}) + const responses = await testDestination.testAction('identifyUser', { + event, + useDefaultMappings: true, + settings: { + projectToken: MIXPANEL_PROJECT_TOKEN, + apiSecret: MIXPANEL_API_SECRET, + apiRegion: ApiRegions.IN + } + }) + expect(responses.length).toBe(2) + expect(responses[0].status).toBe(200) + expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.body).toMatchObject( + new URLSearchParams({ + data: JSON.stringify({ + event: '$identify', + properties: { + $identified_id: 'user1234', + $anon_id: event.anonymousId, + token: MIXPANEL_PROJECT_TOKEN + } + }) + }) + ) + expect(responses[1].status).toBe(200) + expect(responses[1].data).toMatchObject({}) + expect(responses[1].options.body).toMatchObject( + new URLSearchParams({ + data: JSON.stringify({ + $token: MIXPANEL_PROJECT_TOKEN, + $distinct_id: 'user1234', + $ip: '8.8.8.8', + $set: { + abc: '123' + } + }) + }) + ) + }) + it('should default to US endpoint if apiRegion setting is undefined', async () => { const event = createTestEvent({ timestamp, traits: { abc: '123' } }) diff --git a/packages/destination-actions/src/destinations/mixpanel/incrementProperties/__test__/index.test.ts b/packages/destination-actions/src/destinations/mixpanel/incrementProperties/__test__/index.test.ts index f7927ce76e..4b89cd7432 100644 --- a/packages/destination-actions/src/destinations/mixpanel/incrementProperties/__test__/index.test.ts +++ b/packages/destination-actions/src/destinations/mixpanel/incrementProperties/__test__/index.test.ts @@ -42,6 +42,38 @@ describe('Mixpanel.incrementProperties', () => { ) }) + it('should use IN server URL', async () => { + const event = createTestEvent({ timestamp, event: 'search', properties: defaultProperties }) + + nock('https://api-in.mixpanel.com').post('/engage').reply(200, {}) + nock('https://api-in.mixpanel.com').post('/track').reply(200, {}) + + const responses = await testDestination.testAction('incrementProperties', { + event, + useDefaultMappings: true, + settings: { + projectToken: MIXPANEL_PROJECT_TOKEN, + apiSecret: MIXPANEL_API_SECRET, + apiRegion: ApiRegions.IN + } + }) + + expect(responses[0].status).toBe(200) + expect(responses[0].data).toMatchObject({}) + expect(responses[0].options.body).toMatchObject( + new URLSearchParams({ + data: JSON.stringify({ + $token: MIXPANEL_PROJECT_TOKEN, + $distinct_id: 'user1234', + $ip: '8.8.8.8', + $add: { + searches: 1 + } + }) + }) + ) + }) + it('should default to US endpoint if apiRegion setting is undefined', async () => { const event = createTestEvent({ timestamp, event: 'search', properties: defaultProperties }) diff --git a/packages/destination-actions/src/destinations/mixpanel/index.ts b/packages/destination-actions/src/destinations/mixpanel/index.ts index c7090bb533..28477fcce4 100644 --- a/packages/destination-actions/src/destinations/mixpanel/index.ts +++ b/packages/destination-actions/src/destinations/mixpanel/index.ts @@ -91,7 +91,7 @@ const destination: DestinationDefinition = { apiRegion: { label: 'Data Residency', description: - 'Learn about [EU data residency](https://help.mixpanel.com/hc/en-us/articles/360039135652-Data-Residency-in-EU)', + 'Learn about [EU data residency](https://docs.mixpanel.com/docs/privacy/eu-residency) and [India data residency](https://docs.mixpanel.com/docs/privacy/in-residency)', type: 'string', choices: Object.values(ApiRegions).map((apiRegion) => ({ label: apiRegion, value: apiRegion })), default: ApiRegions.US 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 1fa99ed9d3..343a8de7a0 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 @@ -71,6 +71,31 @@ describe('Mixpanel.trackEvent', () => { ]) }) + it('should use IN server URL', async () => { + const event = createTestEvent({ timestamp, event: 'Test Event' }) + + nock('https://api-in.mixpanel.com').post('/import?strict=1').reply(200, {}) + + const responses = await testDestination.testAction('trackEvent', { + event, + useDefaultMappings: true, + settings: { + projectToken: MIXPANEL_PROJECT_TOKEN, + apiSecret: MIXPANEL_API_SECRET, + apiRegion: ApiRegions.IN + } + }) + 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) + } + ]) + }) + it('should default to US endpoint if apiRegion setting is undefined', async () => { const event = createTestEvent({ timestamp, event: 'Test Event' }) diff --git a/packages/destination-actions/src/destinations/mixpanel/trackPurchase/__tests__/index.test.ts b/packages/destination-actions/src/destinations/mixpanel/trackPurchase/__tests__/index.test.ts index 005a8653ea..d3a83cdbae 100644 --- a/packages/destination-actions/src/destinations/mixpanel/trackPurchase/__tests__/index.test.ts +++ b/packages/destination-actions/src/destinations/mixpanel/trackPurchase/__tests__/index.test.ts @@ -106,6 +106,24 @@ describe('Mixpanel.trackPurchase', () => { expect(responses[0].status).toBe(200) }) + it('should use IN server URL', async () => { + const event = createTestEvent(orderCompletedEvent) + + nock('https://api-in.mixpanel.com').post('/import?strict=1').reply(200, {}) + + const responses = await testDestination.testAction('trackPurchase', { + event, + useDefaultMappings: true, + settings: { + projectToken: MIXPANEL_PROJECT_TOKEN, + apiSecret: MIXPANEL_API_SECRET, + apiRegion: ApiRegions.IN + } + }) + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + }) + it('should default to US endpoint if apiRegion setting is undefined', async () => { const event = createTestEvent(orderCompletedEvent)