diff --git a/plugin-server/functional_tests/webhooks.test.ts b/plugin-server/functional_tests/webhooks.test.ts index 0fb7155790034..82f1bfe9bf186 100644 --- a/plugin-server/functional_tests/webhooks.test.ts +++ b/plugin-server/functional_tests/webhooks.test.ts @@ -199,6 +199,7 @@ test.concurrent(`webhooks: fires zapier REST webhook`, async () => { properties: { $creator_event_uuid: eventUuid, $initial_current_url: 'http://localhost:8000', + $current_url: 'http://localhost:8000', email: 't@t.com', }, uuid: expect.any(String), @@ -208,6 +209,7 @@ test.concurrent(`webhooks: fires zapier REST webhook`, async () => { $sent_at: expect.any(String), $set: { email: 't@t.com', + $current_url: 'http://localhost:8000', }, $set_once: { $initial_current_url: 'http://localhost:8000', diff --git a/plugin-server/src/utils/db/utils.ts b/plugin-server/src/utils/db/utils.ts index 49db8914194f6..9e4eb0a3c11b7 100644 --- a/plugin-server/src/utils/db/utils.ts +++ b/plugin-server/src/utils/db/utils.ts @@ -39,7 +39,22 @@ export function timeoutGuard( }, timeout) } -const campaignParams = new Set([ +const eventToPersonProperties = new Set([ + // mobile params + '$app_build', + '$app_name', + '$app_namespace', + '$app_version', + // web params + '$browser', + '$browser_version', + '$device_type', + '$current_url', + '$pathname', + '$os', + '$referring_domain', + '$referrer', + // campaign params 'utm_source', 'utm_medium', 'utm_campaign', @@ -50,31 +65,29 @@ const campaignParams = new Set([ 'fbclid', 'msclkid', ]) -const initialParams = new Set([ - '$browser', - '$browser_version', - '$device_type', - '$current_url', - '$pathname', - '$os', - '$referring_domain', - '$referrer', -]) -const combinedParams = new Set([...campaignParams, ...initialParams]) /** If we get new UTM params, make sure we set those **/ export function personInitialAndUTMProperties(properties: Properties): Properties { const propertiesCopy = { ...properties } - const maybeSet = Object.entries(properties).filter(([key]) => campaignParams.has(key)) - const maybeSetInitial = Object.entries(properties) - .filter(([key]) => combinedParams.has(key)) - .map(([key, value]) => [`$initial_${key.replace('$', '')}`, value]) - if (Object.keys(maybeSet).length > 0) { + const propertiesForPerson: [string, any][] = Object.entries(properties).filter(([key]) => + eventToPersonProperties.has(key) + ) + + // all potential params are checked for $initial_ values and added to $set_once + const maybeSetOnce: [string, any][] = propertiesForPerson.map(([key, value]) => [ + `$initial_${key.replace('$', '')}`, + value, + ]) + + // all found are also then added to $set + const maybeSet: [string, any][] = propertiesForPerson + + if (maybeSet.length > 0) { propertiesCopy.$set = { ...(properties.$set || {}), ...Object.fromEntries(maybeSet) } } - if (Object.keys(maybeSetInitial).length > 0) { - propertiesCopy.$set_once = { ...(properties.$set_once || {}), ...Object.fromEntries(maybeSetInitial) } + if (maybeSetOnce.length > 0) { + propertiesCopy.$set_once = { ...(properties.$set_once || {}), ...Object.fromEntries(maybeSetOnce) } } return propertiesCopy } diff --git a/plugin-server/tests/main/process-event.test.ts b/plugin-server/tests/main/process-event.test.ts index 2e0440d454bf8..b35c51fb0b5d0 100644 --- a/plugin-server/tests/main/process-event.test.ts +++ b/plugin-server/tests/main/process-event.test.ts @@ -315,7 +315,7 @@ test('capture new person', async () => { let persons = await hub.db.fetchPersons() expect(persons[0].version).toEqual(0) expect(persons[0].created_at).toEqual(now) - let expectedProps = { + let expectedProps: Record = { $creator_event_uuid: uuid, $initial_browser: 'Chrome', $initial_browser_version: '95', @@ -329,6 +329,12 @@ test('capture new person', async () => { msclkid: 'BING ADS ID', $initial_referrer: 'https://google.com/?q=posthog', $initial_referring_domain: 'https://google.com', + $browser: 'Chrome', + $browser_version: '95', + $current_url: 'https://test.com', + $os: 'Mac OS X', + $referrer: 'https://google.com/?q=posthog', + $referring_domain: 'https://google.com', } expect(persons[0].properties).toEqual(expectedProps) @@ -343,7 +349,17 @@ test('capture new person', async () => { expect(events[0].properties).toEqual({ $ip: '127.0.0.1', $os: 'Mac OS X', - $set: { utm_medium: 'twitter', gclid: 'GOOGLE ADS ID', msclkid: 'BING ADS ID' }, + $set: { + utm_medium: 'twitter', + gclid: 'GOOGLE ADS ID', + msclkid: 'BING ADS ID', + $browser: 'Chrome', + $browser_version: '95', + $current_url: 'https://test.com', + $os: 'Mac OS X', + $referrer: 'https://google.com/?q=posthog', + $referring_domain: 'https://google.com', + }, token: 'THIS IS NOT A TOKEN FOR TEAM 2', $browser: 'Chrome', $set_once: { @@ -412,6 +428,12 @@ test('capture new person', async () => { msclkid: 'BING ADS ID', $initial_referrer: 'https://google.com/?q=posthog', $initial_referring_domain: 'https://google.com', + $browser: 'Firefox', + $browser_version: 80, + $current_url: 'https://test.com/pricing', + $os: 'Mac OS X', + $referrer: 'https://google.com/?q=posthog', + $referring_domain: 'https://google.com', } expect(persons[0].properties).toEqual(expectedProps) @@ -425,6 +447,9 @@ test('capture new person', async () => { expect(events[1].properties.$set).toEqual({ utm_medium: 'instagram', + $browser: 'Firefox', + $browser_version: 80, + $current_url: 'https://test.com/pricing', }) expect(events[1].properties.$set_once).toEqual({ $initial_browser: 'Firefox', @@ -481,6 +506,9 @@ test('capture new person', async () => { expect(persons[0].version).toEqual(1) expect(events[2].properties.$set).toEqual({ + $browser: 'Firefox', + $current_url: 'https://test.com/pricing', + utm_medium: 'instagram', }) expect(events[2].properties.$set_once).toEqual({ diff --git a/plugin-server/tests/utils/db/utils.test.ts b/plugin-server/tests/utils/db/utils.test.ts index 5201b8e60b803..420c645472ff3 100644 --- a/plugin-server/tests/utils/db/utils.test.ts +++ b/plugin-server/tests/utils/db/utils.test.ts @@ -17,41 +17,74 @@ describe('personInitialAndUTMProperties()', () => { { tag_name: 'a', nth_child: 1, nth_of_type: 2, attr__class: 'btn btn-sm' }, { tag_name: 'div', nth_child: 1, nth_of_type: 2, $el_text: '💻' }, ], + $app_build: 2, + $app_name: 'my app', + $app_namespace: 'com.posthog.myapp', + $app_version: '1.2.3', } - expect(personInitialAndUTMProperties(properties)).toEqual({ - distinct_id: 2, - $browser: 'Chrome', - $current_url: 'https://test.com', - $os: 'Mac OS X', - $browser_version: '95', - $referring_domain: 'https://google.com', - $referrer: 'https://google.com/?q=posthog', - utm_medium: 'twitter', - gclid: 'GOOGLE ADS ID', - msclkid: 'BING ADS ID', - $elements: [ - { - tag_name: 'a', - nth_child: 1, - nth_of_type: 2, - attr__class: 'btn btn-sm', + expect(personInitialAndUTMProperties(properties)).toMatchInlineSnapshot(` + Object { + "$app_build": 2, + "$app_name": "my app", + "$app_namespace": "com.posthog.myapp", + "$app_version": "1.2.3", + "$browser": "Chrome", + "$browser_version": "95", + "$current_url": "https://test.com", + "$elements": Array [ + Object { + "attr__class": "btn btn-sm", + "nth_child": 1, + "nth_of_type": 2, + "tag_name": "a", }, - { tag_name: 'div', nth_child: 1, nth_of_type: 2, $el_text: '💻' }, - ], - $set: { utm_medium: 'twitter', gclid: 'GOOGLE ADS ID', msclkid: 'BING ADS ID' }, - $set_once: { - $initial_browser: 'Chrome', - $initial_current_url: 'https://test.com', - $initial_os: 'Mac OS X', - $initial_browser_version: '95', - $initial_utm_medium: 'twitter', - $initial_gclid: 'GOOGLE ADS ID', - $initial_msclkid: 'BING ADS ID', - $initial_referring_domain: 'https://google.com', - $initial_referrer: 'https://google.com/?q=posthog', - }, - }) + Object { + "$el_text": "💻", + "nth_child": 1, + "nth_of_type": 2, + "tag_name": "div", + }, + ], + "$os": "Mac OS X", + "$referrer": "https://google.com/?q=posthog", + "$referring_domain": "https://google.com", + "$set": Object { + "$app_build": 2, + "$app_name": "my app", + "$app_namespace": "com.posthog.myapp", + "$app_version": "1.2.3", + "$browser": "Chrome", + "$browser_version": "95", + "$current_url": "https://test.com", + "$os": "Mac OS X", + "$referrer": "https://google.com/?q=posthog", + "$referring_domain": "https://google.com", + "gclid": "GOOGLE ADS ID", + "msclkid": "BING ADS ID", + "utm_medium": "twitter", + }, + "$set_once": Object { + "$initial_app_build": 2, + "$initial_app_name": "my app", + "$initial_app_namespace": "com.posthog.myapp", + "$initial_app_version": "1.2.3", + "$initial_browser": "Chrome", + "$initial_browser_version": "95", + "$initial_current_url": "https://test.com", + "$initial_gclid": "GOOGLE ADS ID", + "$initial_msclkid": "BING ADS ID", + "$initial_os": "Mac OS X", + "$initial_referrer": "https://google.com/?q=posthog", + "$initial_referring_domain": "https://google.com", + "$initial_utm_medium": "twitter", + }, + "distinct_id": 2, + "gclid": "GOOGLE ADS ID", + "msclkid": "BING ADS ID", + "utm_medium": "twitter", + } + `) }) it('initial current domain regression test', () => { @@ -62,6 +95,7 @@ describe('personInitialAndUTMProperties()', () => { expect(personInitialAndUTMProperties(properties)).toEqual({ $current_url: 'https://test.com', $set_once: { $initial_current_url: 'https://test.com' }, + $set: { $current_url: 'https://test.com' }, }) }) }) diff --git a/plugin-server/tests/worker/ingestion/event-pipeline/event-pipeline-integration.test.ts b/plugin-server/tests/worker/ingestion/event-pipeline/event-pipeline-integration.test.ts index 837079da765eb..343826d81a4f2 100644 --- a/plugin-server/tests/worker/ingestion/event-pipeline/event-pipeline-integration.test.ts +++ b/plugin-server/tests/worker/ingestion/event-pipeline/event-pipeline-integration.test.ts @@ -105,6 +105,7 @@ describe('Event Pipeline integration test', () => { $set: { personProp: 'value', anotherValue: 2, + $browser: 'Chrome', }, $set_once: { $initial_browser: 'Chrome', @@ -118,6 +119,7 @@ describe('Event Pipeline integration test', () => { expect(persons[0].properties).toEqual({ $creator_event_uuid: event.uuid, $initial_browser: 'Chrome', + $browser: 'Chrome', personProp: 'value', anotherValue: 2, }) diff --git a/plugin-server/tests/worker/ingestion/event-pipeline/processPersonsStep.test.ts b/plugin-server/tests/worker/ingestion/event-pipeline/processPersonsStep.test.ts index 71d495bcf9bce..d2ce3aa76e383 100644 --- a/plugin-server/tests/worker/ingestion/event-pipeline/processPersonsStep.test.ts +++ b/plugin-server/tests/worker/ingestion/event-pipeline/processPersonsStep.test.ts @@ -85,6 +85,7 @@ describe.each([[true], [false]])('processPersonsStep()', (poEEmbraceJoin) => { $browser: 'Chrome', $set: { someProp: 'value', + $browser: 'Chrome', }, $set_once: { $initial_browser: 'Chrome', @@ -95,7 +96,12 @@ describe.each([[true], [false]])('processPersonsStep()', (poEEmbraceJoin) => { expect.objectContaining({ id: expect.any(Number), uuid: expect.any(String), - properties: { $initial_browser: 'Chrome', someProp: 'value', $creator_event_uuid: expect.any(String) }, + properties: { + $initial_browser: 'Chrome', + someProp: 'value', + $creator_event_uuid: expect.any(String), + $browser: 'Chrome', + }, version: 0, is_identified: false, })