Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Save app properties and others to Person from events #17393

Merged
merged 9 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions plugin-server/functional_tests/webhooks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: '[email protected]',
},
uuid: expect.any(String),
Expand All @@ -208,6 +209,7 @@ test.concurrent(`webhooks: fires zapier REST webhook`, async () => {
$sent_at: expect.any(String),
$set: {
email: '[email protected]',
$current_url: 'http://localhost:8000',
},
$set_once: {
$initial_current_url: 'http://localhost:8000',
Expand Down
51 changes: 32 additions & 19 deletions plugin-server/src/utils/db/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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
}
Expand Down
32 changes: 30 additions & 2 deletions plugin-server/tests/main/process-event.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, any> = {
$creator_event_uuid: uuid,
$initial_browser: 'Chrome',
$initial_browser_version: '95',
Expand All @@ -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)

Expand All @@ -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: {
Expand Down Expand Up @@ -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)

Expand All @@ -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',
Expand Down Expand Up @@ -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({
Expand Down
98 changes: 66 additions & 32 deletions plugin-server/tests/utils/db/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand All @@ -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' },
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ describe('Event Pipeline integration test', () => {
$set: {
personProp: 'value',
anotherValue: 2,
$browser: 'Chrome',
},
$set_once: {
$initial_browser: 'Chrome',
Expand All @@ -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,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ describe.each([[true], [false]])('processPersonsStep()', (poEEmbraceJoin) => {
$browser: 'Chrome',
$set: {
someProp: 'value',
$browser: 'Chrome',
},
$set_once: {
$initial_browser: 'Chrome',
Expand All @@ -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,
})
Expand Down