Skip to content

Commit b28c45d

Browse files
authored
refactor: Simplify cookie sync manager (#963)
1 parent 61ce006 commit b28c45d

File tree

6 files changed

+304
-401
lines changed

6 files changed

+304
-401
lines changed

src/cookieSyncManager.ts

Lines changed: 74 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { Dictionary, isEmpty, replaceAmpWithAmpersand, replaceMPID } from './utils';
1+
import {
2+
Dictionary,
3+
isEmpty,
4+
createCookieSyncUrl,
5+
} from './utils';
26
import Constants from './constants';
37
import { MParticleWebSDK } from './sdkRuntimeModels';
48
import { MPID } from '@mparticle/web-sdk';
@@ -25,7 +29,6 @@ export interface IPixelConfiguration {
2529
}
2630
export interface ICookieSyncManager {
2731
attemptCookieSync: (
28-
previousMPID: MPID,
2932
mpid: MPID,
3033
mpidIsNotInCookies?: boolean
3134
) => void;
@@ -34,9 +37,6 @@ export interface ICookieSyncManager {
3437
moduleId: string,
3538
mpid: MPID,
3639
cookieSyncDates: CookieSyncDates,
37-
filteringConsentRuleValues: IConsentRules,
38-
mpidIsNotInCookies: boolean,
39-
requiresConsent: boolean
4040
) => void;
4141
combineUrlWithRedirect: (
4242
mpid: MPID,
@@ -45,20 +45,6 @@ export interface ICookieSyncManager {
4545
) => string;
4646
}
4747

48-
const hasFrequencyCapExpired = (
49-
frequencyCap: number,
50-
lastSyncDate?: number,
51-
): boolean => {
52-
if (!lastSyncDate) {
53-
return true;
54-
}
55-
56-
return (
57-
new Date().getTime() >
58-
new Date(lastSyncDate).getTime() + frequencyCap * DAYS_IN_MILLISECONDS
59-
);
60-
}
61-
6248
export default function CookieSyncManager(
6349
this: ICookieSyncManager,
6450
mpInstance: MParticleWebSDK
@@ -67,100 +53,74 @@ export default function CookieSyncManager(
6753

6854
// Public
6955
this.attemptCookieSync = (
70-
previousMPID: MPID,
7156
mpid: MPID,
7257
mpidIsNotInCookies?: boolean
7358
): void => {
74-
if (!mpid || mpInstance._Store.webviewBridgeEnabled) {
59+
const { pixelConfigurations, webviewBridgeEnabled } = mpInstance._Store;
60+
61+
if (!mpid || webviewBridgeEnabled) {
7562
return;
7663
}
7764

78-
const { pixelConfigurations } = mpInstance._Store;
7965
const persistence = mpInstance._Persistence.getPersistence();
8066

67+
if (isEmpty(persistence)) {
68+
return;
69+
}
70+
8171
pixelConfigurations.forEach((pixelSettings: IPixelConfiguration) => {
8272
// set requiresConsent to false to start each additional pixel configuration
8373
// set to true only if filteringConsenRuleValues.values.length exists
8474
let requiresConsent = false;
85-
8675
// Filtering rules as defined in UI
87-
const { filteringConsentRuleValues } = pixelSettings;
76+
const {
77+
filteringConsentRuleValues,
78+
pixelUrl,
79+
redirectUrl,
80+
moduleId,
81+
// Tells you how often we should do a cookie sync (in days)
82+
frequencyCap,
83+
} = pixelSettings;
8884
const { values } = filteringConsentRuleValues || {};
8985

86+
if (isEmpty(pixelUrl)) {
87+
return;
88+
}
89+
9090
if (!isEmpty(values)) {
9191
requiresConsent = true;
9292
}
9393

94-
// Kit Module ID
95-
const moduleId = pixelSettings.moduleId.toString();
96-
97-
// Tells you how often we should do a cookie sync (in days)
98-
const frequencyCap = pixelSettings.frequencyCap;
94+
// If MPID is new to cookies, we should not try to perform the cookie sync
95+
// because a cookie sync can only occur once a user either consents or doesn't.
96+
// we should not check if it's enabled if the user has a blank consent
97+
if (requiresConsent && mpidIsNotInCookies) {
98+
return;
99+
}
99100

100-
// Url for cookie sync pixel
101-
const pixelUrl = replaceAmpWithAmpersand(pixelSettings.pixelUrl);
101+
const { isEnabledForUserConsent } = mpInstance._Consent;
102102

103-
const redirectUrl = pixelSettings.redirectUrl
104-
? replaceAmpWithAmpersand(pixelSettings.redirectUrl)
105-
: null;
103+
if (!isEnabledForUserConsent(filteringConsentRuleValues, mpInstance.Identity.getCurrentUser())) {
104+
return;
105+
}
106106

107-
const urlWithRedirect = this.combineUrlWithRedirect(
108-
mpid,
109-
pixelUrl,
110-
redirectUrl
111-
);
107+
const cookieSyncDates: CookieSyncDates = persistence[mpid]?.csd ?? {};
108+
const lastSyncDateForModule: number = cookieSyncDates[moduleId] || null;
112109

113-
if (previousMPID && previousMPID !== mpid) {
114-
if (persistence && persistence[mpid]) {
115-
if (!persistence[mpid].csd) {
116-
persistence[mpid].csd = {};
117-
}
118-
self.performCookieSync(
119-
urlWithRedirect,
120-
moduleId,
121-
mpid,
122-
persistence[mpid].csd,
123-
filteringConsentRuleValues,
124-
mpidIsNotInCookies,
125-
requiresConsent
126-
);
127-
}
110+
if (!isLastSyncDateExpired(frequencyCap, lastSyncDateForModule)) {
128111
return;
129-
} else {
130-
if (!persistence || !persistence[mpid]) {
131-
return;
132-
}
133-
134-
if (!persistence[mpid].csd) {
135-
persistence[mpid].csd = {};
136-
}
137-
138-
const lastSyncDateForModule = persistence[mpid].csd[moduleId] || null;
139-
140-
// Check to see if we need to refresh cookieSync
141-
if (hasFrequencyCapExpired(frequencyCap, lastSyncDateForModule)) {
142-
self.performCookieSync(
143-
urlWithRedirect,
144-
moduleId,
145-
mpid,
146-
persistence[mpid].csd,
147-
filteringConsentRuleValues,
148-
mpidIsNotInCookies,
149-
requiresConsent
150-
);
151-
}
152112
}
153-
});
154-
};
155113

156-
this.combineUrlWithRedirect = (
157-
mpid: MPID,
158-
pixelUrl: string,
159-
redirectUrl: string,
160-
): string => {
161-
const url = replaceMPID(pixelUrl, mpid);
162-
const redirect = redirectUrl ? replaceMPID(redirectUrl, mpid) : '';
163-
return url + encodeURIComponent(redirect);
114+
// Url for cookie sync pixel
115+
const fullUrl = createCookieSyncUrl(mpid, pixelUrl, redirectUrl)
116+
117+
self.performCookieSync(
118+
fullUrl,
119+
moduleId.toString(),
120+
mpid,
121+
cookieSyncDates
122+
);
123+
});
164124
};
165125

166126
// Private
@@ -169,35 +129,34 @@ export default function CookieSyncManager(
169129
moduleId: string,
170130
mpid: MPID,
171131
cookieSyncDates: CookieSyncDates,
172-
filteringConsentRuleValues: IConsentRules,
173-
mpidIsNotInCookies: boolean,
174-
requiresConsent: boolean
175132
): void => {
176-
// if MPID is new to cookies, we should not try to perform the cookie sync
177-
// because a cookie sync can only occur once a user either consents or doesn't
178-
// we should not check if its enabled if the user has a blank consent
179-
if (requiresConsent && mpidIsNotInCookies) {
180-
return;
181-
}
133+
const img = document.createElement('img');
182134

183-
if (
184-
// https://go.mparticle.com/work/SQDSDKS-5009
185-
mpInstance._Consent.isEnabledForUserConsent(
186-
filteringConsentRuleValues,
187-
mpInstance.Identity.getCurrentUser()
188-
)
189-
) {
190-
const img = document.createElement('img');
191-
192-
mpInstance.Logger.verbose(InformationMessages.CookieSync);
193-
img.onload = function() {
194-
cookieSyncDates[moduleId] = new Date().getTime();
195-
mpInstance._Persistence.saveUserCookieSyncDatesToPersistence(
196-
mpid,
197-
cookieSyncDates
198-
);
199-
};
200-
img.src = url;
201-
}
135+
mpInstance.Logger.verbose(InformationMessages.CookieSync);
136+
img.onload = function() {
137+
cookieSyncDates[moduleId] = new Date().getTime();
138+
139+
mpInstance._Persistence.saveUserCookieSyncDatesToPersistence(
140+
mpid,
141+
cookieSyncDates
142+
);
143+
};
144+
img.src = url;
202145
};
203146
}
147+
148+
export const isLastSyncDateExpired = (
149+
frequencyCap: number,
150+
lastSyncDate?: number
151+
): boolean => {
152+
// If there is no lastSyncDate, then there is no previous cookie sync, so we should sync the cookie
153+
if (!lastSyncDate) {
154+
return true;
155+
}
156+
157+
// Otherwise, compare the last sync date to determine if it should do a cookie sync again
158+
return (
159+
new Date().getTime() >
160+
new Date(lastSyncDate).getTime() + frequencyCap * DAYS_IN_MILLISECONDS
161+
);
162+
};

src/identity.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,10 +1230,7 @@ export default function Identity(mpInstance) {
12301230
this.getUserIdentities().userIdentities,
12311231
mpInstance._APIClient.prepareForwardingStats
12321232
);
1233-
mpInstance._CookieSyncManager.attemptCookieSync(
1234-
null,
1235-
this.getMPID()
1236-
);
1233+
mpInstance._CookieSyncManager.attemptCookieSync(this.getMPID());
12371234
},
12381235
isLoggedIn: function() {
12391236
return isLoggedIn;
@@ -1562,7 +1559,6 @@ export default function Identity(mpInstance) {
15621559
);
15631560

15641561
mpInstance._CookieSyncManager.attemptCookieSync(
1565-
previousMPID,
15661562
identityApiResult.mpid,
15671563
mpidIsNotInCookies
15681564
);

src/utils.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,23 @@ const replaceMPID = (value: string, mpid: MPID): string => value.replace('%%mpid
180180

181181
const replaceAmpWithAmpersand = (value: string): string => value.replace(/&/g, '&');
182182

183+
const createCookieSyncUrl = (
184+
mpid: MPID,
185+
pixelUrl: string,
186+
redirectUrl?: string
187+
): string => {
188+
const modifiedPixelUrl = replaceAmpWithAmpersand(pixelUrl);
189+
const modifiedDirectUrl = redirectUrl
190+
? replaceAmpWithAmpersand(redirectUrl)
191+
: null;
192+
193+
const url = replaceMPID(modifiedPixelUrl, mpid);
194+
const redirect = modifiedDirectUrl
195+
? replaceMPID(modifiedDirectUrl, mpid)
196+
: '';
197+
return url + encodeURIComponent(redirect);
198+
};
199+
183200
// FIXME: REFACTOR for V3
184201
// only used in store.js to sanitize server-side formatting of
185202
// booleans when checking for `isDevelopmentMode`
@@ -341,6 +358,7 @@ const getHref = (): string => {
341358
export {
342359
createCookieString,
343360
revertCookieString,
361+
createCookieSyncUrl,
344362
valueof,
345363
converted,
346364
decoded,

0 commit comments

Comments
 (0)