diff options
Diffstat (limited to 'app/assets/javascripts/tracking')
-rw-r--r-- | app/assets/javascripts/tracking/constants.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/tracking/index.js | 7 | ||||
-rw-r--r-- | app/assets/javascripts/tracking/tracking.js | 40 | ||||
-rw-r--r-- | app/assets/javascripts/tracking/utils.js | 24 |
4 files changed, 73 insertions, 2 deletions
diff --git a/app/assets/javascripts/tracking/constants.js b/app/assets/javascripts/tracking/constants.js index 598111e4086..062a3404355 100644 --- a/app/assets/javascripts/tracking/constants.js +++ b/app/assets/javascripts/tracking/constants.js @@ -24,3 +24,7 @@ export const LOAD_ACTION_ATTR_SELECTOR = '[data-track-action="render"]'; export const DEPRECATED_EVENT_ATTR_SELECTOR = '[data-track-event]'; export const DEPRECATED_LOAD_EVENT_ATTR_SELECTOR = '[data-track-event="render"]'; + +export const URLS_CACHE_STORAGE_KEY = 'gl-snowplow-pseudonymized-urls'; + +export const REFERRER_TTL = 24 * 60 * 60 * 1000; diff --git a/app/assets/javascripts/tracking/index.js b/app/assets/javascripts/tracking/index.js index 5417e2d969b..7e99ecb4f4e 100644 --- a/app/assets/javascripts/tracking/index.js +++ b/app/assets/javascripts/tracking/index.js @@ -1,3 +1,4 @@ +import { getAllExperimentContexts } from '~/experimentation/utils'; import { DEFAULT_SNOWPLOW_OPTIONS } from './constants'; import getStandardContext from './get_standard_context'; import Tracking from './tracking'; @@ -38,10 +39,14 @@ export function initDefaultTrackers() { const opts = { ...DEFAULT_SNOWPLOW_OPTIONS, ...window.snowplowOptions }; + // must be before initializing the trackers + Tracking.setAnonymousUrls(); + window.snowplow('enableActivityTracking', 30, 30); // must be after enableActivityTracking const standardContext = getStandardContext(); - window.snowplow('trackPageView', null, [standardContext]); + const experimentContexts = getAllExperimentContexts(); + window.snowplow('trackPageView', null, [standardContext, ...experimentContexts]); if (window.snowplowOptions.formTracking) { Tracking.enableFormTracking(opts.formTrackingConfig); diff --git a/app/assets/javascripts/tracking/tracking.js b/app/assets/javascripts/tracking/tracking.js index a1f745bc172..657e0a79911 100644 --- a/app/assets/javascripts/tracking/tracking.js +++ b/app/assets/javascripts/tracking/tracking.js @@ -1,7 +1,14 @@ import { LOAD_ACTION_ATTR_SELECTOR, DEPRECATED_LOAD_EVENT_ATTR_SELECTOR } from './constants'; import { dispatchSnowplowEvent } from './dispatch_snowplow_event'; import getStandardContext from './get_standard_context'; -import { getEventHandlers, createEventPayload, renameKey, addExperimentContext } from './utils'; +import { + getEventHandlers, + createEventPayload, + renameKey, + addExperimentContext, + getReferrersCache, + addReferrersCacheEntry, +} from './utils'; export default class Tracking { static queuedEvents = []; @@ -159,6 +166,37 @@ export default class Tracking { } /** + * Replaces the URL and referrer for the default web context + * if the replacements are available. + * + * @returns {undefined} + */ + static setAnonymousUrls() { + const { snowplowPseudonymizedPageUrl: pageUrl } = window.gl; + + if (!pageUrl) { + return; + } + + const referrers = getReferrersCache(); + const pageLinks = Object.seal({ url: '', referrer: '', originalUrl: window.location.href }); + + pageLinks.url = `${pageUrl}${window.location.hash}`; + window.snowplow('setCustomUrl', pageLinks.url); + + if (document.referrer) { + const node = referrers.find((links) => links.originalUrl === document.referrer); + + if (node) { + pageLinks.referrer = node.url; + window.snowplow('setReferrerUrl', pageLinks.referrer); + } + } + + addReferrersCacheEntry(referrers, pageLinks); + } + + /** * Returns an implementation of this class in the form of * a Vue mixin. * diff --git a/app/assets/javascripts/tracking/utils.js b/app/assets/javascripts/tracking/utils.js index 1189b2168ad..3507872b511 100644 --- a/app/assets/javascripts/tracking/utils.js +++ b/app/assets/javascripts/tracking/utils.js @@ -6,6 +6,8 @@ import { LOAD_ACTION_ATTR_SELECTOR, DEPRECATED_EVENT_ATTR_SELECTOR, DEPRECATED_LOAD_EVENT_ATTR_SELECTOR, + URLS_CACHE_STORAGE_KEY, + REFERRER_TTL, } from './constants'; export const addExperimentContext = (opts) => { @@ -100,3 +102,25 @@ export const renameKey = (o, oldKey, newKey) => { return ret; }; + +export const filterOldReferrersCacheEntries = (cache) => { + const now = Date.now(); + + return cache.filter((entry) => entry.timestamp && entry.timestamp > now - REFERRER_TTL); +}; + +export const getReferrersCache = () => { + try { + const referrers = JSON.parse(window.localStorage.getItem(URLS_CACHE_STORAGE_KEY) || '[]'); + + return filterOldReferrersCacheEntries(referrers); + } catch { + return []; + } +}; + +export const addReferrersCacheEntry = (cache, entry) => { + const referrers = JSON.stringify([{ ...entry, timestamp: Date.now() }, ...cache]); + + window.localStorage.setItem(URLS_CACHE_STORAGE_KEY, referrers); +}; |