From 97d05cdd85573b8bb387e086a94534ed7ba4119f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matu=CC=81s=CC=8C=20Tomlein?= Date: Fri, 8 Nov 2024 12:09:27 +0100 Subject: [PATCH] Add appVersion configuration option to track a context entity with the application version --- .../browser-tracker/browser-tracker.api.md | 1 + .../browser-tracker.trackerconfiguration.md | 2 +- ...-application_context_2024-11-08-11-09.json | 10 +++++ .../browser-tracker-core/src/tracker/index.ts | 22 ++++++++-- .../src/tracker/schemata.ts | 1 + .../browser-tracker-core/src/tracker/types.ts | 6 +++ .../test/tracker/application_context.test.ts | 44 +++++++++++++++++++ 7 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 common/changes/@snowplow/browser-tracker-core/issue-application_context_2024-11-08-11-09.json create mode 100644 libraries/browser-tracker-core/test/tracker/application_context.test.ts diff --git a/api-docs/docs/browser-tracker/browser-tracker.api.md b/api-docs/docs/browser-tracker/browser-tracker.api.md index e571532a5..845ae2966 100644 --- a/api-docs/docs/browser-tracker/browser-tracker.api.md +++ b/api-docs/docs/browser-tracker/browser-tracker.api.md @@ -523,6 +523,7 @@ export type TrackerConfiguration = { cookieLifetime?: number; sessionCookieTimeout?: number; appId?: string; + appVersion?: string; platform?: Platform; respectDoNotTrack?: boolean; crossDomainLinker?: (elt: HTMLAnchorElement | HTMLAreaElement) => boolean; diff --git a/api-docs/docs/browser-tracker/markdown/browser-tracker.trackerconfiguration.md b/api-docs/docs/browser-tracker/markdown/browser-tracker.trackerconfiguration.md index 89fb83857..c3ede1535 100644 --- a/api-docs/docs/browser-tracker/markdown/browser-tracker.trackerconfiguration.md +++ b/api-docs/docs/browser-tracker/markdown/browser-tracker.trackerconfiguration.md @@ -18,6 +18,7 @@ type TrackerConfiguration = { cookieLifetime?: number; sessionCookieTimeout?: number; appId?: string; + appVersion?: string; platform?: Platform; respectDoNotTrack?: boolean; crossDomainLinker?: (elt: HTMLAnchorElement | HTMLAreaElement) => boolean; @@ -44,6 +45,5 @@ newTracker('sp1', 'collector.my-website.com', { plugins: [ PerformanceTimingPlugin(), AdTrackingPlugin() ], stateStorageStrategy: 'cookieAndLocalStorage' }); - ``` diff --git a/common/changes/@snowplow/browser-tracker-core/issue-application_context_2024-11-08-11-09.json b/common/changes/@snowplow/browser-tracker-core/issue-application_context_2024-11-08-11-09.json new file mode 100644 index 000000000..c87290991 --- /dev/null +++ b/common/changes/@snowplow/browser-tracker-core/issue-application_context_2024-11-08-11-09.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@snowplow/browser-tracker-core", + "comment": "Add appVersion configuration option to track a context entity with the application version", + "type": "none" + } + ], + "packageName": "@snowplow/browser-tracker-core" +} \ No newline at end of file diff --git a/libraries/browser-tracker-core/src/tracker/index.ts b/libraries/browser-tracker-core/src/tracker/index.ts index 555b0a240..ed07096db 100755 --- a/libraries/browser-tracker-core/src/tracker/index.ts +++ b/libraries/browser-tracker-core/src/tracker/index.ts @@ -65,7 +65,7 @@ import { emptyIdCookie, eventIndexFromIdCookie, } from './id_cookie'; -import { CLIENT_SESSION_SCHEMA, WEB_PAGE_SCHEMA, BROWSER_CONTEXT_SCHEMA } from './schemata'; +import { CLIENT_SESSION_SCHEMA, WEB_PAGE_SCHEMA, BROWSER_CONTEXT_SCHEMA, APPLICATION_CONTEXT_SCHEMA } from './schemata'; import { getBrowserProperties } from '../helpers/browser_props'; import { asyncCookieStorage, syncCookieStorage } from './cookie_storage'; @@ -149,13 +149,13 @@ export function Tracker( if (typeof config.anonymousTracking === 'boolean') { return false; } - return config.anonymousTracking?.withSessionTracking === true ?? false; + return config.anonymousTracking?.withSessionTracking === true; }, getAnonymousServerTracking = (config: TrackerConfiguration) => { if (typeof config.anonymousTracking === 'boolean') { return false; } - return config.anonymousTracking?.withServerAnonymisation === true ?? false; + return config.anonymousTracking?.withServerAnonymisation === true; }, getAnonymousTracking = (config: TrackerConfiguration) => !!config.anonymousTracking, isBrowserContextAvailable = trackerConfiguration?.contexts?.browser ?? false, @@ -203,6 +203,8 @@ export function Tracker( configPlatform = trackerConfiguration.platform ?? 'web', // Site ID configTrackerSiteId = trackerConfiguration.appId ?? '', + // Application version + configAppVersion = trackerConfiguration.appVersion, // Document URL configCustomUrl: string, // Document title @@ -323,6 +325,20 @@ export function Tracker( core.addPayloadPair('cd', colorDepth); if (timeZone) core.addPayloadPair('tz', timeZone); + // Add the application version context entity + if (configAppVersion) { + core.addPlugin({ + plugin: { + contexts: () => [ + { + schema: APPLICATION_CONTEXT_SCHEMA, + data: { version: configAppVersion }, + }, + ], + }, + }); + } + /* * Initialize tracker */ diff --git a/libraries/browser-tracker-core/src/tracker/schemata.ts b/libraries/browser-tracker-core/src/tracker/schemata.ts index 59e0482d4..9c2ffd85e 100644 --- a/libraries/browser-tracker-core/src/tracker/schemata.ts +++ b/libraries/browser-tracker-core/src/tracker/schemata.ts @@ -1,3 +1,4 @@ export const WEB_PAGE_SCHEMA = 'iglu:com.snowplowanalytics.snowplow/web_page/jsonschema/1-0-0'; export const BROWSER_CONTEXT_SCHEMA = 'iglu:com.snowplowanalytics.snowplow/browser_context/jsonschema/2-0-0'; export const CLIENT_SESSION_SCHEMA = 'iglu:com.snowplowanalytics.snowplow/client_session/jsonschema/1-0-2'; +export const APPLICATION_CONTEXT_SCHEMA = 'iglu:com.snowplowanalytics.snowplow/application/jsonschema/1-0-0'; diff --git a/libraries/browser-tracker-core/src/tracker/types.ts b/libraries/browser-tracker-core/src/tracker/types.ts index 2e95aa451..6ebf47660 100755 --- a/libraries/browser-tracker-core/src/tracker/types.ts +++ b/libraries/browser-tracker-core/src/tracker/types.ts @@ -117,6 +117,12 @@ export type TrackerConfiguration = { sessionCookieTimeout?: number; /** The app id to send with each event */ appId?: string; + /** + * Version of the application tracked as a context entity with all events. + * Can be a semver-like structure (e.g 1.1.0) or a Git commit SHA hash. + * Entity schema: iglu:com.snowplowanalytics.snowplow/application/jsonschema/1-0-0 + */ + appVersion?: string; /** * The platform the event is being sent from * @defaultValue web diff --git a/libraries/browser-tracker-core/test/tracker/application_context.test.ts b/libraries/browser-tracker-core/test/tracker/application_context.test.ts new file mode 100644 index 000000000..f490dd262 --- /dev/null +++ b/libraries/browser-tracker-core/test/tracker/application_context.test.ts @@ -0,0 +1,44 @@ +import { APPLICATION_CONTEXT_SCHEMA } from '../../src/tracker/schemata'; +import { createTracker } from '../helpers'; + +describe('Application context:', () => { + it('Adds the entity when the appVersion option is configured', (done) => { + const tracker = createTracker({ + appVersion: '1.0.2-beta.2', + plugins: [ + { + filter: (payload) => { + const { data: payloadData } = JSON.parse(payload.co as string); + const appContext = payloadData.find((context: any) => context.schema.match(APPLICATION_CONTEXT_SCHEMA)); + expect(appContext).toBeTruthy(); + expect(appContext.data.version).toBe('1.0.2-beta.2'); + done(); + return false; + }, + }, + ], + }); + + tracker?.trackPageView(); + }); + + it('Does not attach the entity if not configured', (done) => { + const tracker = createTracker({ + plugins: [ + { + filter: (payload) => { + const { data: payloadData } = JSON.parse(payload.co as string); + const applicationContext = payloadData.find((context: any) => + context.schema.match(APPLICATION_CONTEXT_SCHEMA) + ); + expect(applicationContext).toBeUndefined(); + done(); + return false + }, + }, + ], + }); + + tracker?.trackPageView(); + }); +});