Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(packages/sui-segment-wrapper): send init event once per session #1884

Merged
merged 2 commits into from
Dec 17, 2024
Merged
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
4 changes: 0 additions & 4 deletions packages/sui-segment-wrapper/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import initTcfTracking from './tcf.js'
import {getUserDataAndNotify} from './universalId.js'
import {loadGoogleAnalytics, getCampaignDetails} from './repositories/googleRepository.js'

const DEFAULT_GA_INIT_EVENT = 'sui'

// Initialize TCF Tracking with Segment
initTcfTracking()

Expand All @@ -36,7 +34,6 @@ const addMiddlewares = () => {
if (isClient && window.analytics) {
// Initialize Google Analtyics if needed
const googleAnalyticsMeasurementId = getConfig('googleAnalyticsMeasurementId')
const googleAnalyticsInitEvent = getConfig('googleAnalyticsInitEvent') ?? DEFAULT_GA_INIT_EVENT

if (googleAnalyticsMeasurementId) {
const googleAnalyticsConfig = getConfig('googleAnalyticsConfig')
Expand All @@ -55,7 +52,6 @@ if (isClient && window.analytics) {
...googleAnalyticsConfig,
...getCampaignDetails()
})
window.gtag('event', googleAnalyticsInitEvent)

loadGoogleAnalytics().catch(error => {
console.error(error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ const FIELDS = {
clientId: 'client_id',
sessionId: 'session_id'
}

const STC = {
QUERY: 'stc',
SPLIT_SYMBOL: '-',
CAMPAIGN_SPLIT_SYMBOL: ':'
}

const STC_MEDIUM_TRANSFORMATIONS = {
aff: 'affiliate',
dis: 'display',
Expand All @@ -24,8 +22,8 @@ const STC_MEDIUM_TRANSFORMATIONS = {
pn: 'push-notification',
cs: 'cross-sites'
}

const STC_INVALID_CONTENT = 'na'
const DEFAULT_GA_INIT_EVENT = 'sui'

const loadScript = async src =>
new Promise(function (resolve, reject) {
Expand All @@ -48,14 +46,38 @@ export const loadGoogleAnalytics = async () => {
return loadScript(gtagScript)
}

// Trigger GA init event just once per session.
const triggerGoogleAnalyticsInitEvent = sessionId => {
const eventName = getConfig('googleAnalyticsInitEvent') ?? DEFAULT_GA_INIT_EVENT
const eventPrefix = `ga_event_${eventName}_`
const eventKey = `${eventPrefix}${sessionId}`

// Check if the event has already been sent in this session.
if (!localStorage.getItem(eventKey)) {
// If not, send it.
window.gtag('event', eventName)
console.log(`Sending GA4 event "${eventName}" for the session "${sessionId}"`)

// And then save a new GA session hit in local storage.
localStorage.setItem(eventKey, 'true')
}

// Clean old GA sessions hits from the storage.
Object.keys(localStorage).forEach(key => {
if (key.startsWith(eventPrefix) && key !== eventKey) {
localStorage.removeItem(key)
}
})
}

const getGoogleField = async field => {
const googleAnalyticsMeasurementId = getConfig('googleAnalyticsMeasurementId')

// If `googleAnalyticsMeasurementId` is not present, don't load anything
// If `googleAnalyticsMeasurementId` is not present, don't load anything.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but I'm very pro to treat comments as sentences 🙏 https://nedbatchelder.com/blog/201401/comments_should_be_sentences.html

if (!googleAnalyticsMeasurementId) return Promise.resolve()

return new Promise(resolve => {
// if not, get it from the `GoogleAnalytics` tag
// If it is, get it from `gtag`.
window.gtag?.('get', googleAnalyticsMeasurementId, field, resolve)
})
}
Expand Down Expand Up @@ -83,8 +105,14 @@ export const getCampaignDetails = ({needsTransformation = true} = {}) => {
}
}

export const getGoogleClientID = () => getGoogleField(FIELDS.clientId)
export const getGoogleSessionID = () => getGoogleField(FIELDS.sessionId)
export const getGoogleClientId = async () => getGoogleField(FIELDS.clientId)
export const getGoogleSessionId = async () => {
const sessionId = await getGoogleField(FIELDS.sessionId)

triggerGoogleAnalyticsInitEvent(sessionId)

return sessionId
}

export const setGoogleUserId = userId => {
const googleAnalyticsMeasurementId = getConfig('googleAnalyticsMeasurementId')
Expand Down
6 changes: 3 additions & 3 deletions packages/sui-segment-wrapper/src/segmentWrapper.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @ts-check

import {getAdobeMCVisitorID} from './repositories/adobeRepository.js'
import {getGoogleClientID, getGoogleSessionID, setGoogleUserId} from './repositories/googleRepository.js'
import {getGoogleClientId, getGoogleSessionId, setGoogleUserId} from './repositories/googleRepository.js'
import {getConfig} from './config.js'
import {checkAnalyticsGdprIsAccepted, getGdprPrivacyValue} from './tcf.js'
import {getXandrId} from './repositories/xandrRepository.js'
Expand Down Expand Up @@ -42,8 +42,8 @@ const getTrackIntegrations = async ({gdprPrivacyValue, event}) => {
try {
;[marketingCloudVisitorId, clientId, sessionId] = await Promise.all([
getAdobeMCVisitorID(),
getGoogleClientID(),
getGoogleSessionID()
getGoogleClientId(),
getGoogleSessionId()
])
} catch (error) {
console.error(error)
Expand Down
6 changes: 3 additions & 3 deletions packages/sui-segment-wrapper/test/stubs.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,18 @@ export const stubFetch = ({responses = [{urlRe: /^http/, fetchResponse: {}}]} =
}

export const stubGoogleAnalytics = () => {
const savedFields = {
const fakeFields = {
client_id: 'fakeClientId',
session_id: 'fakeSessionId'
}

window.gtag = (key, id, field, done) => {
if (key === 'get') {
return done(savedFields?.[field])
return done(fakeFields?.[field])
}

if (key === 'set') {
savedFields[id] = field
fakeFields[id] = field
}
}
}
Expand Down
Loading