From f17e59d163314786785aedbb65d95e1ad5278eb6 Mon Sep 17 00:00:00 2001 From: vdua Date: Fri, 30 May 2025 14:18:09 +0530 Subject: [PATCH 1/3] feat: adding probable cta information in a form page --- .../package.json | 2 +- .../src/functions/form-vitals.js | 49 ++++++++++++++++--- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/packages/spacecat-shared-rum-api-client/package.json b/packages/spacecat-shared-rum-api-client/package.json index ab1f21c4b..3f6c389fd 100644 --- a/packages/spacecat-shared-rum-api-client/package.json +++ b/packages/spacecat-shared-rum-api-client/package.json @@ -51,4 +51,4 @@ "sinon-chai": "4.0.0", "typescript": "5.8.3" } -} +} \ No newline at end of file diff --git a/packages/spacecat-shared-rum-api-client/src/functions/form-vitals.js b/packages/spacecat-shared-rum-api-client/src/functions/form-vitals.js index f0820c4f7..4c209548b 100644 --- a/packages/spacecat-shared-rum-api-client/src/functions/form-vitals.js +++ b/packages/spacecat-shared-rum-api-client/src/functions/form-vitals.js @@ -10,9 +10,11 @@ * governing permissions and limitations under the License. */ -import { DataChunks } from '@adobe/rum-distiller'; +import { DataChunks, facetFns, facets } from '@adobe/rum-distiller'; import { generateKey, DELIMITER, loadBundles } from '../utils.js'; +const { checkpointSource } = facetFns; +const { checkpoint: checkpointFacet, url: urlFacet } = facets; const METRICS = ['formview', 'formengagement', 'formsubmit']; const CHECKPOINTS = ['viewblock', 'click', 'fill', 'formsubmit', 'navigate', 'viewmedia']; const KEYWORDS_TO_FILTER = ['search']; @@ -89,8 +91,8 @@ function populateFormsInternalNavigation(bundles, formVitals) { const formVital = findByUrl(formVitals, bundle.url); if (formInternalNav && formVital - && !formVital.forminternalnavigation - .some((e) => e.url === formInternalNav.source)) { + && !formVital.forminternalnavigation + .some((e) => e.url === formInternalNav.source)) { const fv = findByUrl(formVitals, formInternalNav.source); formVital.forminternalnavigation.push({ url: formInternalNav.source, @@ -134,6 +136,42 @@ function findFormCTAForInternalNavigation(bundles, formVitals) { }); } +function findFormCTAWithinPage(bundles, formVitals) { + return formVitals.map((item) => { + const { url, formsource } = item; + const dataChunks = new DataChunks(); + dataChunks.load([{ rumBundles: bundles }]); + dataChunks.addFacet('viewblock.source', checkpointSource('viewblock')); + dataChunks.addFacet('checkpoint', checkpointFacet); + dataChunks.addFacet('url', urlFacet); + dataChunks.filter = { checkpoint: ['click', 'viewblock'], url: [url], 'viewblock.source': [formsource] }; + const sortedBundles = dataChunks.filtered.sort((a, b) => a.timeDelta - b.timeDelta); + const sources = sortedBundles.map((a) => { + const { events } = a; + const viewblock = events.find(({ checkpoint, source }) => checkpoint === 'viewblock' && source === formsource); + const viewblockTime = viewblock.timeDelta; + + const clicks = events.filter((e) => e.checkpoint === 'click') + // clicks within 1 second of viewblock + .filter((e) => Math.abs(e.timeDelta - viewblockTime) < 1000) + // ignore form clicks + .filter((e) => e.source && !e.source.match(/\bform\b/i)); + + return clicks.map((_) => _.source); + }).filter((_) => _.length > 0).flat(); + if (sources.length > 0) { + return { + ...item, + cta: { + sources, + form: item.url, + }, + }; + } + return item; + }); +} + function containsFormVitals(row) { return METRICS.some((metric) => Object.keys(row[metric]).length > 0); } @@ -179,7 +217,6 @@ function getParentPageVitalsGroupedByIFrame(bundles, dataChunks, iframeParentMap populateFormsInternalNavigation(bundles, parentWebVitals); findFormCTAForInternalNavigation(bundles, Object.values(parentWebVitals)); - const iframeParentVitalsMap = {}; for (const vitals of Object.values(parentWebVitals)) { iframeParentVitalsMap[vitals.iframeSrc] = vitals; @@ -279,8 +316,9 @@ function handler(bundles) { // filter out pages with no form vitals const filteredFormVitals = Object.values(formVitals).filter(containsFormVitals); findFormCTAForInternalNavigation(bundles, filteredFormVitals); + const formVitalsWithCTA = findFormCTAWithinPage(bundles, filteredFormVitals); - const updatedFormVitals = filteredFormVitals.map((formVital) => { + const updatedFormVitals = formVitalsWithCTA.map((formVital) => { const formVitalCopy = { ...formVital }; const parentFormVital = iframeParentVitalsMap[formVital.url]; if (parentFormVital) { @@ -294,7 +332,6 @@ function handler(bundles) { url, pageview: { ...pageview }, forminternalnavigation, - iframeSrc, }); } From 583889f3523f5331882349ab22056178ede2d65f Mon Sep 17 00:00:00 2001 From: vdua Date: Fri, 30 May 2025 15:18:24 +0530 Subject: [PATCH 2/3] making the form cta unique and removing redundant info --- .../src/functions/form-vitals.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/spacecat-shared-rum-api-client/src/functions/form-vitals.js b/packages/spacecat-shared-rum-api-client/src/functions/form-vitals.js index 3a74e0ca3..971f00266 100644 --- a/packages/spacecat-shared-rum-api-client/src/functions/form-vitals.js +++ b/packages/spacecat-shared-rum-api-client/src/functions/form-vitals.js @@ -163,10 +163,7 @@ function findFormCTAWithinPage(bundles, formVitals) { if (sources.length > 0) { return { ...item, - cta: { - sources, - form: item.url, - }, + formCTAWithinPage: [...new Set(sources)], }; } return item; From 8a8382bdde14e06b7825d4bdc27ba0ed90f6ed4a Mon Sep 17 00:00:00 2001 From: vdua Date: Mon, 2 Jun 2025 06:44:20 +0530 Subject: [PATCH 3/3] adding newline back into package.json --- packages/spacecat-shared-rum-api-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/spacecat-shared-rum-api-client/package.json b/packages/spacecat-shared-rum-api-client/package.json index b0f0ff048..6cef74a7b 100644 --- a/packages/spacecat-shared-rum-api-client/package.json +++ b/packages/spacecat-shared-rum-api-client/package.json @@ -51,4 +51,4 @@ "sinon-chai": "4.0.0", "typescript": "5.8.3" } -} \ No newline at end of file +}