Skip to content

Commit

Permalink
[MWPW-158749] Enhance Interact call efficiency and defer non-essentia… (
Browse files Browse the repository at this point in the history
#3258)

* move common snippets to helper, add defer logic and make interact call the 1st thing in the flow for signed out users

* toggle FPID and ECID logic, re-organise exports, dont fire if consent cookie present

* Pre merge branch (#5)

move methods utils , use async load of helper, review comments

* move try catch block as per promise

* Pre merge branch (#6)

* Test remove martech logic (#7)

fix delay logic, fix pr comments

* Test remove martech logic (#8)

change uuid logic, promise structure, alloy response logic, requestid,

* Final local branch (#9)

fix review comments, add test cases

* fix coverage for if check

* fix coverage errors

* add test case for martech helpers

* send full cookie flag added post testing round 1
  • Loading branch information
swamu authored Dec 4, 2024
1 parent b632a21 commit d9ddd17
Show file tree
Hide file tree
Showing 7 changed files with 986 additions and 83 deletions.
126 changes: 114 additions & 12 deletions libs/features/personalization/personalization.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/* eslint-disable no-underscore-dangle */
/* eslint-disable no-console */

import { createTag, getConfig, loadLink, loadScript, localizeLink } from '../../utils/utils.js';
import {
createTag, getConfig, loadLink, loadScript, localizeLink, enablePersonalizationV2,
} from '../../utils/utils.js';
import { getFederatedUrl } from '../../utils/federated.js';

/* c8 ignore start */
Expand Down Expand Up @@ -467,7 +469,7 @@ function getSelectedElements(sel, rootEl, forceRootEl) {
try {
els = root.querySelectorAll(modifiedSelector);
} catch (e) {
/* eslint-disable-next-line no-console */
/* eslint-disable-next-line no-console */
log('Invalid selector: ', selector);
return null;
}
Expand Down Expand Up @@ -773,7 +775,11 @@ async function getPersonalizationVariant(manifestPath, variantNames = [], varian

let userEntitlements = [];
if (hasEntitlementTag) {
userEntitlements = await config.entitlements();
if (enablePersonalizationV2()) {
userEntitlements = [];
} else {
userEntitlements = await config.entitlements();
}
}

const hasMatch = (name) => {
Expand Down Expand Up @@ -1111,9 +1117,7 @@ export const combineMepSources = async (persEnabled, promoEnabled, mepParam) =>
return persManifests;
};

async function callMartech(config) {
const { getTargetPersonalization } = await import('../../martech/martech.js');
const { targetManifests, targetPropositions } = await getTargetPersonalization();
function updateManifestsAndPropositions({ config, targetManifests, targetPropositions }) {
config.mep.targetManifests = targetManifests;
if (targetPropositions?.length && window._satellite) {
window._satellite.track('propositionDisplay', targetPropositions);
Expand All @@ -1124,6 +1128,97 @@ async function callMartech(config) {
}
return targetManifests;
}

function roundToQuarter(num) {
return Math.ceil(num / 250) / 4;
}

function calculateResponseTime(responseStart) {
const responseTime = Date.now() - responseStart;
return roundToQuarter(responseTime);
}

function sendTargetResponseAnalytics(failure, responseStart, timeoutLocal, message) {
// temporary solution until we can decide on a better timeout value
const responseTime = calculateResponseTime(responseStart);
const timeoutTime = roundToQuarter(timeoutLocal);
let val = `target response time ${responseTime}:timed out ${failure}:timeout ${timeoutTime}`;
if (message) val += `:${message}`;
// eslint-disable-next-line no-underscore-dangle
window._satellite?.track?.('event', {
documentUnloading: true,
xdm: {
eventType: 'web.webinteraction.linkClicks',
web: {
webInteraction: {
linkClicks: { value: 1 },
type: 'other',
name: val,
},
},
},
data: { _adobe_corpnew: { digitalData: { primaryEvent: { eventInfo: { eventName: val } } } } },
});
}

const handleAlloyResponse = (response) => ((response.propositions || response.decisions))
?.map((i) => i.items)
?.flat()
?.map((item) => {
const content = item?.data?.content;
if (!content || !(content.manifestLocation || content.manifestContent)) return null;

return {
manifestPath: content.manifestLocation || content.manifestPath,
manifestUrl: content.manifestLocation,
manifestData: content.manifestContent?.experiences?.data || content.manifestContent?.data,
manifestPlaceholders: content.manifestContent?.placeholders?.data,
manifestInfo: content.manifestContent?.info.data,
name: item.meta['activity.name'],
variantLabel: item.meta['experience.name'] && `target-${item.meta['experience.name']}`,
meta: item.meta,
};
})
?.filter(Boolean) ?? [];

async function handleMartechTargetInteraction(
{ config, targetInteractionPromise, calculatedTimeout },
) {
let targetManifests = [];
let targetPropositions = [];
if (enablePersonalizationV2() && targetInteractionPromise) {
try {
const { targetInteractionData, respTime, respStartTime } = await targetInteractionPromise;
sendTargetResponseAnalytics(false, respStartTime, calculatedTimeout);

const roundedResponseTime = roundToQuarter(respTime);
performance.clearMarks();
performance.clearMeasures();
try {
window.lana.log(`target response time: ${roundedResponseTime}`, { tags: 'martech', errorType: 'i' });
} catch (e) {
// eslint-disable-next-line no-console
console.error('Error logging target response time:', e);
}
targetManifests = handleAlloyResponse(targetInteractionData.result);
targetPropositions = targetInteractionData.result?.propositions || [];
} catch (err) {
console.log('Oops!! Interact Call didnt go through', err);
}
}

return updateManifestsAndPropositions({ config, targetManifests, targetPropositions });
}

async function callMartech(config) {
const { getTargetPersonalization } = await import('../../martech/martech.js');
const {
targetManifests,
targetPropositions,
} = await getTargetPersonalization({ handleAlloyResponse, sendTargetResponseAnalytics });
return updateManifestsAndPropositions({ config, targetManifests, targetPropositions });
}

const awaitMartech = () => new Promise((resolve) => {
const listener = (event) => resolve(event.detail);
window.addEventListener(MARTECH_RETURNED_EVENT, listener, { once: true });
Expand All @@ -1132,7 +1227,8 @@ const awaitMartech = () => new Promise((resolve) => {
export async function init(enablements = {}) {
let manifests = [];
const {
mepParam, mepHighlight, mepButton, pzn, promo, target, postLCP,
mepParam, mepHighlight, mepButton, pzn, promo,
target, targetInteractionPromise, calculatedTimeout, postLCP,
} = enablements;
const config = getConfig();
if (postLCP) {
Expand All @@ -1157,11 +1253,17 @@ export async function init(enablements = {}) {
if (pzn) loadLink(getXLGListURL(config), { as: 'fetch', crossorigin: 'anonymous', rel: 'preload' });
}

if (target === true) manifests = manifests.concat(await callMartech(config));
if (target === 'postlcp') callMartech(config);
if (postLCP) {
if (!config.mep.targetManifests) await awaitMartech();
manifests = config.mep.targetManifests;
if (enablePersonalizationV2()) {
manifests = manifests.concat(await handleMartechTargetInteraction(
{ config, targetInteractionPromise, calculatedTimeout },
));
} else {
if (target === true) manifests = manifests.concat(await callMartech(config));
if (target === 'postlcp') callMartech(config);
if (postLCP) {
if (!config.mep.targetManifests) await awaitMartech();
manifests = config.mep.targetManifests;
}
}
if (!manifests || !manifests.length) return;
try {
Expand Down
Loading

0 comments on commit d9ddd17

Please sign in to comment.