Skip to content
Draft
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
7 changes: 7 additions & 0 deletions global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ interface ImpactQueueFunction {
a?: unknown[][]
}

interface RewardfulGlobal {
referral?: string
affiliate?: { id?: string; token?: string; name?: string }
campaign?: { id?: string; name?: string }
}

type GtagGetFieldName = 'client_id' | 'session_id' | 'session_number'

interface GtagGetFieldValueMap {
Expand Down Expand Up @@ -63,6 +69,7 @@ interface Window {
gtag?: GtagFunction
ire_o?: string
ire?: ImpactQueueFunction
Rewardful?: RewardfulGlobal
}

interface Navigator {
Expand Down
1 change: 1 addition & 0 deletions src/platform/telemetry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ export interface CheckoutAttributionMetadata {
ga_session_id?: string
ga_session_number?: string
im_ref?: string
rewardful_referral?: string
utm_source?: string
utm_medium?: string
utm_campaign?: string
Expand Down
44 changes: 44 additions & 0 deletions src/platform/telemetry/utils/__tests__/checkoutAttribution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ describe('getCheckoutAttribution', () => {
}
window.gtag = undefined
window.ire = undefined
window.Rewardful = undefined
window.history.pushState({}, '', '/')
})

Expand Down Expand Up @@ -228,4 +229,47 @@ describe('getCheckoutAttribution', () => {

expect(attribution.im_ref).toBeUndefined()
})

it('captures Rewardful referral from window.Rewardful', async () => {
window.Rewardful = {
referral: 'rwd-abc-123'
}

const attribution = await getCheckoutAttribution()

expect(attribution.rewardful_referral).toBe('rwd-abc-123')
})

it('returns undefined Rewardful referral when window.Rewardful is absent', async () => {
const attribution = await getCheckoutAttribution()

expect(attribution.rewardful_referral).toBeUndefined()
})

it('returns undefined Rewardful referral when window.Rewardful.referral is empty', async () => {
window.Rewardful = { referral: '' }

const attribution = await getCheckoutAttribution()

expect(attribution.rewardful_referral).toBeUndefined()
})

it('captures Rewardful referral alongside Impact attribution', async () => {
window.history.pushState(
{},
'',
'/?im_ref=impact-url-id&utm_source=affiliate'
)
window.Rewardful = {
referral: 'rwd-xyz-789'
}

const attribution = await getCheckoutAttribution()

expect(attribution).toMatchObject({
im_ref: 'impact-url-id',
utm_source: 'affiliate',
rewardful_referral: 'rwd-xyz-789'
})
})
})
9 changes: 8 additions & 1 deletion src/platform/telemetry/utils/checkoutAttribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ async function getGeneratedClickId(): Promise<string | undefined> {
}
}

function getRewardfulReferral(): string | undefined {
if (typeof window === 'undefined') return undefined
return asNonEmptyString(window.Rewardful?.referral)
}

export function captureCheckoutAttributionFromSearch(search: string): void {
const fromUrl = readAttributionFromUrl(search)
const storedAttribution = readStoredAttribution()
Expand Down Expand Up @@ -213,11 +218,13 @@ export async function getCheckoutAttribution(): Promise<CheckoutAttributionMetad
}

const gaIdentity = await getGaIdentity()
const rewardfulReferral = getRewardfulReferral()

return {
...attribution,
ga_client_id: gaIdentity?.client_id,
ga_session_id: gaIdentity?.session_id,
ga_session_number: gaIdentity?.session_number
ga_session_number: gaIdentity?.session_number,
rewardful_referral: rewardfulReferral
}
}
Loading