Skip to content

Commit

Permalink
add _requirePersonProcessing function
Browse files Browse the repository at this point in the history
Use for alias, identify, group, setGroupPropertiesForFlags, setPersonProperties, setPersonPropertiesForFlags
  • Loading branch information
robbie-c committed Apr 9, 2024
1 parent 05a115a commit 67635fc
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 26 deletions.
21 changes: 17 additions & 4 deletions src/__tests__/personProcessing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('person processing', () => {
// assert
expect(jest.mocked(logger).error).toBeCalledTimes(1)
expect(jest.mocked(logger).error).toHaveBeenCalledWith(
'posthog.identify was called, but the process_person configuration is set to "never". This call will be ignored.'
'posthog.identify was called, but process_person is set to "never". This call will be ignored.'
)
expect(onCapture).toBeCalledTimes(0)
})
Expand Down Expand Up @@ -198,6 +198,11 @@ describe('person processing', () => {
posthog.capture('custom event after group')

// assert
expect(jest.mocked(logger).error).toBeCalledTimes(1)
expect(jest.mocked(logger).error).toHaveBeenCalledWith(
'posthog.group was called, but process_person is set to "never". This call will be ignored.'
)

expect(onCapture).toBeCalledTimes(2)
const eventBeforeGroup = onCapture.mock.calls[0]
expect(eventBeforeGroup[1].properties.$process_person).toEqual(false)
Expand All @@ -216,6 +221,10 @@ describe('person processing', () => {

// assert
expect(onCapture).toBeCalledTimes(0)
expect(jest.mocked(logger).error).toBeCalledTimes(1)
expect(jest.mocked(logger).error).toHaveBeenCalledWith(
'posthog.setPersonProperties was called, but process_person is set to "never". This call will be ignored.'
)
})

it("should send a $set event if process_person is set to 'always'", async () => {
Expand All @@ -238,14 +247,14 @@ describe('person processing', () => {

// act
posthog.capture('custom event before alias')
posthog.group('groupType', 'groupKey', { prop: 'value' })
posthog.alias('alias')
posthog.capture('custom event after alias')

// assert
const eventBeforeGroup = onCapture.mock.calls[0]
expect(eventBeforeGroup[1].properties.$process_person).toEqual(false)
const groupIdentify = onCapture.mock.calls[1]
expect(groupIdentify[0]).toEqual('$groupidentify')
expect(groupIdentify[0]).toEqual('$create_alias')
expect(groupIdentify[1].properties.$process_person).toEqual(true)
const eventAfterGroup = onCapture.mock.calls[2]
expect(eventAfterGroup[1].properties.$process_person).toEqual(true)
Expand All @@ -256,10 +265,14 @@ describe('person processing', () => {
const { posthog, onCapture } = await setup('never')

// act
posthog.group('groupType', 'groupKey', { prop: 'value' })
posthog.alias('alias')

// assert
expect(onCapture).toBeCalledTimes(0)
expect(jest.mocked(logger).error).toBeCalledTimes(1)
expect(jest.mocked(logger).error).toHaveBeenCalledWith(
'posthog.alias was called, but process_person is set to "never". This call will be ignored.'
)
})
})
})
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const POSTHOG_QUOTA_LIMITED = '$posthog_quota_limited'
export const CLIENT_SESSION_PROPS = '$client_session_props'
export const INITIAL_CAMPAIGN_PARAMS = '$initial_campaign_params'
export const INITIAL_REFERRER_INFO = '$initial_referrer_info'
export const ENABLE_PERSON_PROCESSING = '$epp'

// These are properties that are reserved and will not be automatically included in events
export const PERSISTENCE_RESERVED_PROPERTIES = [
Expand All @@ -50,4 +51,5 @@ export const PERSISTENCE_RESERVED_PROPERTIES = [
CLIENT_SESSION_PROPS,
INITIAL_CAMPAIGN_PARAMS,
INITIAL_REFERRER_INFO,
ENABLE_PERSON_PROCESSING,
]
67 changes: 47 additions & 20 deletions src/posthog-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ import { assignableWindow, document, location, userAgent, window } from './utils
import { autocapture } from './autocapture'
import { PostHogFeatureFlags } from './posthog-featureflags'
import { PostHogPersistence } from './posthog-persistence'
import { ALIAS_ID_KEY, FLAG_CALL_REPORTED, PEOPLE_DISTINCT_ID_KEY, SESSION_RECORDING_IS_SAMPLED } from './constants'
import {
ALIAS_ID_KEY,
ENABLE_PERSON_PROCESSING,
FLAG_CALL_REPORTED,
PEOPLE_DISTINCT_ID_KEY,
SESSION_RECORDING_IS_SAMPLED,
} from './constants'
import { SessionRecording } from './extensions/replay/sessionrecording'
import { Decide } from './decide'
import { Toolbar } from './extensions/toolbar'
Expand Down Expand Up @@ -1207,10 +1213,7 @@ export class PostHog {
return
}

if (this.config.__preview_process_person === 'never') {
logger.error(
'posthog.identify was called, but the process_person configuration is set to "never". This call will be ignored.'
)
if (!this._requirePersonProcessing('posthog.identify')) {
return
}

Expand Down Expand Up @@ -1285,12 +1288,14 @@ export class PostHog {
return
}

if (!this._requirePersonProcessing('posthog.setPersonProperties')) {
return
}

// Update current user properties
this.setPersonPropertiesForFlags(userPropertiesToSet || {})

if (this._hasPersonProcessing()) {
this.capture('$set', { $set: userPropertiesToSet || {}, $set_once: userPropertiesToSetOnce || {} })
}
this.capture('$set', { $set: userPropertiesToSet || {}, $set_once: userPropertiesToSetOnce || {} })
}

/**
Expand All @@ -1306,6 +1311,10 @@ export class PostHog {
return
}

if (!this._requirePersonProcessing('posthog.group')) {
return
}

const existingGroups = this.getGroups()

// if group key changes, remove stored group properties
Expand All @@ -1316,13 +1325,11 @@ export class PostHog {
this.register({ $groups: { ...existingGroups, [groupType]: groupKey } })

if (groupPropertiesToSet) {
if (this._hasPersonProcessing()) {
this.capture('$groupidentify', {
$group_type: groupType,
$group_key: groupKey,
$group_set: groupPropertiesToSet,
})
}
this.capture('$groupidentify', {
$group_type: groupType,
$group_key: groupKey,
$group_set: groupPropertiesToSet,
})
this.setGroupPropertiesForFlags({ [groupType]: groupPropertiesToSet })
}

Expand Down Expand Up @@ -1350,6 +1357,9 @@ export class PostHog {
* to update user properties.
*/
setPersonPropertiesForFlags(properties: Properties, reloadFeatureFlags = true): void {
if (!this._requirePersonProcessing('posthog.setPersonPropertiesForFlags')) {
return
}
this.featureFlags.setPersonPropertiesForFlags(properties, reloadFeatureFlags)
}

Expand All @@ -1366,6 +1376,9 @@ export class PostHog {
* setGroupPropertiesForFlags({'organization': { name: 'CYZ', employees: '11' } })
*/
setGroupPropertiesForFlags(properties: { [type: string]: Properties }, reloadFeatureFlags = true): void {
if (!this._requirePersonProcessing('posthog.setGroupPropertiesForFlags')) {
return
}
this.featureFlags.setGroupPropertiesForFlags(properties, reloadFeatureFlags)
}

Expand Down Expand Up @@ -1488,10 +1501,7 @@ export class PostHog {
logger.critical('Attempting to create alias for existing People user - aborting.')
return -2
}
if (this.config.__preview_process_person === 'never') {
logger.error(
'posthog.alias was called, but the process_person configuration is set to "never". This call will be ignored.'
)
if (!this._requirePersonProcessing('posthog.alias')) {
return
}

Expand Down Expand Up @@ -1798,10 +1808,27 @@ export class PostHog {
(this.config.__preview_process_person === 'identified_only' &&
!this._isIdentified() &&
_isEmptyObject(this.getGroups()) &&
!this.persistence?.props?.[ALIAS_ID_KEY])
!this.persistence?.props?.[ALIAS_ID_KEY] &&
!this.persistence?.props?.[ENABLE_PERSON_PROCESSING])
)
}

/**
* Enables person processing if possible, returns true if it does so or already enabled, false otherwise
*
* @param function_name
*/
_requirePersonProcessing(function_name: string): boolean {
if (this.config.__preview_process_person === 'never') {
logger.error(
function_name + ' was called, but process_person is set to "never". This call will be ignored.'
)
return false
}
this._register_single(ENABLE_PERSON_PROCESSING, true)
return true
}

// perform some housekeeping around GDPR opt-in/out state
_gdpr_init(): void {
const is_localStorage_requested = this.config.opt_out_capturing_persistence_type === 'localStorage'
Expand Down
4 changes: 2 additions & 2 deletions src/storage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { _extend } from './utils'
import { PersistentStore, Properties } from './types'
import { DISTINCT_ID, SESSION_ID, SESSION_RECORDING_IS_SAMPLED } from './constants'
import { DISTINCT_ID, ENABLE_PERSON_PROCESSING, SESSION_ID, SESSION_RECORDING_IS_SAMPLED } from './constants'

import { _isNull, _isUndefined } from './utils/type-utils'
import { logger } from './utils/logger'
Expand Down Expand Up @@ -248,7 +248,7 @@ export const localStore: PersistentStore = {
// Use localstorage for most data but still use cookie for COOKIE_PERSISTED_PROPERTIES
// This solves issues with cookies having too much data in them causing headers too large
// Also makes sure we don't have to send a ton of data to the server
const COOKIE_PERSISTED_PROPERTIES = [DISTINCT_ID, SESSION_ID, SESSION_RECORDING_IS_SAMPLED]
const COOKIE_PERSISTED_PROPERTIES = [DISTINCT_ID, SESSION_ID, SESSION_RECORDING_IS_SAMPLED, ENABLE_PERSON_PROCESSING]

export const localPlusCookieStore: PersistentStore = {
...localStore,
Expand Down

0 comments on commit 67635fc

Please sign in to comment.