-
Notifications
You must be signed in to change notification settings - Fork 222
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add deep link tracking to the React Native tracker (#1398)
- Loading branch information
1 parent
45212f0
commit d6a87a0
Showing
12 changed files
with
262 additions
and
13 deletions.
There are no files selected for viewing
13 changes: 13 additions & 0 deletions
13
...-tracker/markdown/react-native-tracker.deeplinkconfiguration.deeplinkcontext.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [@snowplow/react-native-tracker](./react-native-tracker.md) > [DeepLinkConfiguration](./react-native-tracker.deeplinkconfiguration.md) > [deepLinkContext](./react-native-tracker.deeplinkconfiguration.deeplinkcontext.md) | ||
|
||
## DeepLinkConfiguration.deepLinkContext property | ||
|
||
Whether to track the deep link context entity with information from the deep link received event on the first screen view event. | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
deepLinkContext?: boolean; | ||
``` |
20 changes: 20 additions & 0 deletions
20
...ocs/react-native-tracker/markdown/react-native-tracker.deeplinkconfiguration.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [@snowplow/react-native-tracker](./react-native-tracker.md) > [DeepLinkConfiguration](./react-native-tracker.deeplinkconfiguration.md) | ||
|
||
## DeepLinkConfiguration interface | ||
|
||
Configuration for deep link tracking | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
export interface DeepLinkConfiguration | ||
``` | ||
|
||
## Properties | ||
|
||
| Property | Type | Description | | ||
| --- | --- | --- | | ||
| [deepLinkContext?](./react-native-tracker.deeplinkconfiguration.deeplinkcontext.md) | boolean | <i>(Optional)</i> Whether to track the deep link context entity with information from the deep link received event on the first screen view event. | | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
.../changes/@snowplow/react-native-tracker/issue-rn-deep-link-tracking_2024-12-09-14-17.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"changes": [ | ||
{ | ||
"packageName": "@snowplow/react-native-tracker", | ||
"comment": "Add deep link tracking to the React Native tracker", | ||
"type": "none" | ||
} | ||
], | ||
"packageName": "@snowplow/react-native-tracker" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,11 @@ | ||
export const FOREGROUND_EVENT_SCHEMA = 'iglu:com.snowplowanalytics.snowplow/application_foreground/jsonschema/1-0-0'; | ||
export const BACKGROUND_EVENT_SCHEMA = 'iglu:com.snowplowanalytics.snowplow/application_background/jsonschema/1-0-0'; | ||
export const DEEP_LINK_RECEIVED_EVENT_SCHEMA = 'iglu:com.snowplowanalytics.mobile/deep_link_received/jsonschema/1-0-0'; | ||
export const SCREEN_VIEW_EVENT_SCHEMA = 'iglu:com.snowplowanalytics.mobile/screen_view/jsonschema/1-0-0'; | ||
|
||
export const CLIENT_SESSION_ENTITY_SCHEMA ='iglu:com.snowplowanalytics.snowplow/client_session/jsonschema/1-0-2' | ||
export const MOBILE_CONTEXT_SCHEMA = 'iglu:com.snowplowanalytics.snowplow/mobile_context/jsonschema/1-0-3'; | ||
export const DEEP_LINK_ENTITY_SCHEMA = 'iglu:com.snowplowanalytics.mobile/deep_link/jsonschema/1-0-0'; | ||
|
||
export const PAGE_URL_PROPERTY = 'url'; | ||
export const PAGE_REFERRER_PROPERTY = 'refr'; |
68 changes: 68 additions & 0 deletions
68
trackers/react-native-tracker/src/plugins/deep_links/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { buildSelfDescribingEvent, CorePluginConfiguration, PayloadBuilder, TrackerCore } from '@snowplow/tracker-core'; | ||
import { DeepLinkConfiguration, DeepLinkReceivedProps, EventContext } from '../../types'; | ||
import { DEEP_LINK_ENTITY_SCHEMA, DEEP_LINK_RECEIVED_EVENT_SCHEMA, PAGE_REFERRER_PROPERTY, PAGE_URL_PROPERTY, SCREEN_VIEW_EVENT_SCHEMA } from '../../constants'; | ||
import { getUsefulSchema } from '../../utils'; | ||
|
||
interface DeepLinksPlugin extends CorePluginConfiguration { | ||
trackDeepLinkReceivedEvent: (argmap: DeepLinkReceivedProps, contexts?: EventContext[]) => void; | ||
} | ||
|
||
export function newDeepLinksPlugin( | ||
{ deepLinkContext = true }: DeepLinkConfiguration, | ||
core: TrackerCore | ||
): DeepLinksPlugin { | ||
let lastDeepLink: DeepLinkReceivedProps | undefined; | ||
|
||
const beforeTrack = (payloadBuilder: PayloadBuilder) => { | ||
const schema = getUsefulSchema(payloadBuilder); | ||
|
||
if (schema == SCREEN_VIEW_EVENT_SCHEMA && lastDeepLink) { | ||
const { url, referrer } = lastDeepLink; | ||
if (url) { | ||
payloadBuilder.add(PAGE_URL_PROPERTY, url); | ||
} | ||
if (referrer) { | ||
payloadBuilder.add(PAGE_REFERRER_PROPERTY, referrer); | ||
} | ||
|
||
if (deepLinkContext) { | ||
payloadBuilder.addContextEntity({ | ||
schema: DEEP_LINK_ENTITY_SCHEMA, | ||
data: lastDeepLink, | ||
}); | ||
} | ||
|
||
// Clear the last deep link since we only add it to the first screen view event | ||
lastDeepLink = undefined; | ||
} | ||
}; | ||
|
||
const trackDeepLinkReceivedEvent = (argmap: DeepLinkReceivedProps, contexts?: EventContext[]) => { | ||
lastDeepLink = argmap; | ||
|
||
const payload = buildSelfDescribingEvent({ | ||
event: { | ||
schema: DEEP_LINK_RECEIVED_EVENT_SCHEMA, | ||
data: argmap, | ||
}, | ||
}); | ||
|
||
// Add atomic event properties | ||
const { url, referrer } = argmap; | ||
if (url) { | ||
payload.add(PAGE_URL_PROPERTY, url); | ||
} | ||
if (referrer) { | ||
payload.add(PAGE_REFERRER_PROPERTY, referrer); | ||
} | ||
|
||
core.track(payload, contexts); | ||
}; | ||
|
||
return { | ||
trackDeepLinkReceivedEvent, | ||
plugin: { | ||
beforeTrack, | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
trackers/react-native-tracker/test/plugins/deep_links.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import { | ||
DEEP_LINK_ENTITY_SCHEMA, | ||
DEEP_LINK_RECEIVED_EVENT_SCHEMA, | ||
SCREEN_VIEW_EVENT_SCHEMA, | ||
} from '../../src/constants'; | ||
import { newDeepLinksPlugin } from '../../src/plugins/deep_links'; | ||
import { buildSelfDescribingEvent, Payload, trackerCore } from '@snowplow/tracker-core'; | ||
|
||
describe('Deep Link plugin', () => { | ||
it('adds the url and refr properties on the deep link event', () => { | ||
const payloads: Payload[] = []; | ||
const tracker = trackerCore({ | ||
callback: (pb) => payloads.push(pb.build()), | ||
base64: false, | ||
}); | ||
const deepLinksPlugin = newDeepLinksPlugin({}, tracker); | ||
tracker.addPlugin(deepLinksPlugin); | ||
|
||
deepLinksPlugin.trackDeepLinkReceivedEvent({ | ||
url: 'http://url.com', | ||
referrer: 'http://referrer.com', | ||
}); | ||
|
||
expect(payloads.length).toBe(1); | ||
const [{ url, refr, ue_pr }] = payloads as any; | ||
expect(url).toBe('http://url.com'); | ||
expect(refr).toBe('http://referrer.com'); | ||
|
||
const { data } = JSON.parse(ue_pr); | ||
expect(data.schema).toBe(DEEP_LINK_RECEIVED_EVENT_SCHEMA); | ||
expect(data.data.url).toBe('http://url.com'); | ||
expect(data.data.referrer).toBe('http://referrer.com'); | ||
}); | ||
|
||
it('adds the deep link context to the first screen view event', () => { | ||
const payloads: Payload[] = []; | ||
const tracker = trackerCore({ | ||
callback: (pb) => payloads.push(pb.build()), | ||
base64: false, | ||
}); | ||
const deepLinksPlugin = newDeepLinksPlugin({}, tracker); | ||
tracker.addPlugin(deepLinksPlugin); | ||
|
||
deepLinksPlugin.trackDeepLinkReceivedEvent({ | ||
url: 'http://url.com', | ||
referrer: 'http://referrer.com', | ||
}); | ||
tracker.track( | ||
buildSelfDescribingEvent({ | ||
event: { | ||
schema: SCREEN_VIEW_EVENT_SCHEMA, | ||
data: {}, | ||
}, | ||
}) | ||
); | ||
tracker.track( | ||
buildSelfDescribingEvent({ | ||
event: { | ||
schema: SCREEN_VIEW_EVENT_SCHEMA, | ||
data: {}, | ||
}, | ||
}) | ||
); | ||
|
||
expect(payloads.length).toBe(3); | ||
const [, { url, refr, co }, { co: co2 }] = payloads as any; | ||
expect(url).toBe('http://url.com'); | ||
expect(refr).toBe('http://referrer.com'); | ||
expect(co).not.toBeUndefined(); | ||
const entities = JSON.parse(co).data; | ||
const deepLinkEntity = entities.find((entity: any) => entity.schema === DEEP_LINK_ENTITY_SCHEMA); | ||
expect(deepLinkEntity).not.toBeUndefined(); | ||
expect(deepLinkEntity.data.url).toBe('http://url.com'); | ||
expect(deepLinkEntity.data.referrer).toBe('http://referrer.com'); | ||
|
||
expect(co2 ?? '').not.toContain(DEEP_LINK_ENTITY_SCHEMA); | ||
}); | ||
|
||
it('does not add the deep link entity if disabled', () => { | ||
const payloads: Payload[] = []; | ||
const tracker = trackerCore({ | ||
callback: (pb) => payloads.push(pb.build()), | ||
base64: false, | ||
}); | ||
const deepLinksPlugin = newDeepLinksPlugin({ deepLinkContext: false }, tracker); | ||
tracker.addPlugin(deepLinksPlugin); | ||
|
||
deepLinksPlugin.trackDeepLinkReceivedEvent({ | ||
url: 'http://url.com', | ||
referrer: 'http://referrer.com', | ||
}); | ||
tracker.track( | ||
buildSelfDescribingEvent({ | ||
event: { | ||
schema: SCREEN_VIEW_EVENT_SCHEMA, | ||
data: {}, | ||
}, | ||
}) | ||
); | ||
|
||
expect(payloads.length).toBe(2); | ||
const [, { url, refr, co }] = payloads as any; | ||
expect(url).toBe('http://url.com'); | ||
expect(refr).toBe('http://referrer.com'); | ||
expect(co ?? '').not.toContain(DEEP_LINK_ENTITY_SCHEMA); | ||
}); | ||
}); |