diff --git a/packages/spacecat-shared-rum-api-client/src/common/aggregateFns.js b/packages/spacecat-shared-rum-api-client/src/common/aggregateFns.js index fc02e012..9180b21f 100644 --- a/packages/spacecat-shared-rum-api-client/src/common/aggregateFns.js +++ b/packages/spacecat-shared-rum-api-client/src/common/aggregateFns.js @@ -10,7 +10,7 @@ * governing permissions and limitations under the License. */ -import { extractTrafficHints, classifyUTMSource } from './traffic.js'; +import { extractTrafficHints, classifyReferrer, getSecondLevelDomain } from './traffic.js'; /** * Calculates the total page views by URL from an array of bundles. @@ -55,7 +55,7 @@ function getCTRByUrl(bundles) { } /** - * Calculates the Click-Through Rate (CTR) by URL and Referrer obtained from utm_source. + * Calculates the Click-Through Rate (CTR) by URL and Referrer. * CTR is defined as the total number of sessions with at least one click event per referrer. * divided by the total number of pageviews for each URL per referrer. * @@ -67,7 +67,8 @@ function getCTRByUrlAndChannel(bundles) { const aggregated = bundles.reduce((acc, bundle) => { const { url } = bundle; const trafficHints = extractTrafficHints(bundle); - const channel = classifyUTMSource(trafficHints.utmSource); + const referrerDomain = getSecondLevelDomain(trafficHints.referrer); + const channel = classifyReferrer(referrerDomain); if (!acc[url]) { acc[url] = { sessionsWithClick: 0, totalPageviews: 0, channels: {} }; } @@ -90,9 +91,14 @@ function getCTRByUrlAndChannel(bundles) { }, {}); return Object.entries(aggregated) .reduce((acc, [url, { sessionsWithClick, totalPageviews, channels }]) => { + if (!acc[url]) { + acc[url] = { value: 0, channels: {} }; + } acc[url].value = (sessionsWithClick / totalPageviews); acc[url].channels = Object.entries(channels) - .reduce((_acc, [source, { _sessionsWithClick, _totalPageviews }]) => { + .reduce((_acc, [source, { + sessionsWithClick: _sessionsWithClick, totalPageviews: _totalPageviews, + }]) => { // eslint-disable-next-line no-param-reassign _acc[source] = (_sessionsWithClick / _totalPageviews); return _acc; diff --git a/packages/spacecat-shared-rum-api-client/src/common/traffic.js b/packages/spacecat-shared-rum-api-client/src/common/traffic.js index e03c8e6e..bbe73efe 100644 --- a/packages/spacecat-shared-rum-api-client/src/common/traffic.js +++ b/packages/spacecat-shared-rum-api-client/src/common/traffic.js @@ -24,7 +24,7 @@ import URI from 'urijs'; * @returns {string} The second-level domain of the given URL, or the original * URL if it does not contain any text. */ -function getSecondLevelDomain(url) { +export function getSecondLevelDomain(url) { if (!hasText(url)) return url; const uri = new URI(url); const domain = uri.domain(); @@ -39,7 +39,7 @@ function getSecondLevelDomain(url) { // Referrer related const referrers = { search: /google|yahoo|bing|yandex|baidu|duckduckgo|brave|ecosia|aol|startpage|ask/, - social: /^\b(x)\b|(.*(facebook|tiktok|snapchat|x|twitter|pinterest|reddit|linkedin|threads|quora|discord|tumblr|mastodon|bluesky|instagram).*)$/, + social: /^\b(x)\b|(.*(facebook|tiktok|snapchat|twitter|pinterest|reddit|linkedin|threads|quora|discord|tumblr|mastodon|bluesky|instagram).*)$/, ad: /googlesyndication|2mdn|doubleclick|syndicatedsearch/, video: /youtube|vimeo|twitch|dailymotion|wistia/, }; @@ -68,14 +68,12 @@ const sources = { email: /sfmc|email/, }; -// Indexes of the mathcing groups in the regexes above, to obtain the utm source string -const sourceGroupingIndex = { +// Indexes of the mathcing groups for the regexes in referrer +const referrerGroupingIndex = { + search: [0], social: [1, 3], - search: [1, 3], + ad: [0], video: [0], - display: [0], - affiliate: [0], - email: [0], }; // Tracking params - based on the checkpoints we have in rum-enhancer now @@ -189,25 +187,22 @@ export function extractTrafficHints(bundle) { } /** - * Returns the name of the utm source as single word, for example: facebook instead of facebook.com - * @param {*} utmSource + * Returns the name of the referrer as single word. + * For example: facebook instead of www.facebook.com + * @param {*} referrerString */ -export function classifyUTMSource(utmSource) { - if (!utmSource) return ''; - let classifiedSource = ''; - for (const [source, regex] of Object.entries(sources)) { - const match = utmSource.match(regex); +export function classifyReferrer(referrerString) { + if (!referrerString) return ''; + let classifiedReferrer = ''; + for (const [referrer, regex] of Object.entries(referrers)) { + const match = referrerString.match(regex); if (match) { - const indexes = sourceGroupingIndex[source]; - const classifiedSourceIndex = indexes.find((index) => match[index]); - if (classifiedSourceIndex === undefined) { - classifiedSource = ''; - } else { - classifiedSource = match[classifiedSourceIndex]; - } + const indexes = referrerGroupingIndex[referrer]; + const classifiedReferrerIndex = indexes.find((index) => match[index]); + classifiedReferrer = match[classifiedReferrerIndex]; } } - return classifiedSource; + return classifiedReferrer; } export function classifyTrafficSource(url, referrer, utmSource, utmMedium, trackingParams) { @@ -224,7 +219,7 @@ export function classifyTrafficSource(url, referrer, utmSource, utmMedium, track && rule.utmMedium(sanitize(utmMedium)) && rule.tracking(trackingParams) )); - const channel = classifyUTMSource(utmSource); + const channel = classifyReferrer(referrerDomain); return { type, diff --git a/packages/spacecat-shared-rum-api-client/src/functions/opportunities/high-organic-low-ctr.js b/packages/spacecat-shared-rum-api-client/src/functions/opportunities/high-organic-low-ctr.js index 5a00d469..9ba2b265 100644 --- a/packages/spacecat-shared-rum-api-client/src/functions/opportunities/high-organic-low-ctr.js +++ b/packages/spacecat-shared-rum-api-client/src/functions/opportunities/high-organic-low-ctr.js @@ -23,9 +23,11 @@ function convertToOpportunity(traffic) { url, total, ctr, paid, owned, earned, channels, siteAvgCTR, ctrByUrlAndChannel, } = traffic; + console.log('channels', channels); + const topChannels = Object.entries(channels) .sort((a, b) => b[1].total - a[1].total).slice(0, CHANNELS_TO_CONSIDER); - + console.log('topChannels', topChannels); const opportunity = { type: 'high-organic-low-ctr', page: url, @@ -53,18 +55,19 @@ function convertToOpportunity(traffic) { }], }; opportunity.metrics.push(...topChannels.map(([channel, { - _total, _owned, _earned, _paid, + total: _total, owned: _owned, earned: _earned, paid: _paid, }]) => { const trafficMetrics = { type: 'traffic', referrer: channel, value: { - _total, - _owned, - _earned, - _paid, + total: _total, + owned: _owned, + earned: _earned, + paid: _paid, }, }; + console.log('trafficMetrics', trafficMetrics); const ctrMetrics = { type: 'ctr', referrer: channel, @@ -90,7 +93,9 @@ function handler(bundles, opts = {}) { const { interval = 7 } = opts; const trafficByUrl = trafficAcquisition.handler(bundles); + console.log('trafficByUrl', trafficByUrl); const ctrByUrlAndChannel = getCTRByUrlAndChannel(bundles); + console.log('ctrByUrlAndChannel', ctrByUrlAndChannel); const siteAvgCTR = getSiteAvgCTR(bundles); return trafficByUrl.filter((traffic) => traffic.total > interval * DAILY_PAGEVIEW_THRESHOLD) diff --git a/packages/spacecat-shared-rum-api-client/src/functions/traffic-acquisition.js b/packages/spacecat-shared-rum-api-client/src/functions/traffic-acquisition.js index 16978a38..48d2532b 100644 --- a/packages/spacecat-shared-rum-api-client/src/functions/traffic-acquisition.js +++ b/packages/spacecat-shared-rum-api-client/src/functions/traffic-acquisition.js @@ -68,6 +68,8 @@ function handler(bundles) { }) .reduce(collectByUrlAndTrafficSource, {}); + console.log('trafficSources before transform', trafficSources); + return transformFormat(trafficSources) .sort((a, b) => b.total - a.total); // sort desc by total views } diff --git a/packages/spacecat-shared-rum-api-client/test/common/traffic.test.js b/packages/spacecat-shared-rum-api-client/test/common/traffic.test.js index 512c4f89..a459360f 100644 --- a/packages/spacecat-shared-rum-api-client/test/common/traffic.test.js +++ b/packages/spacecat-shared-rum-api-client/test/common/traffic.test.js @@ -27,54 +27,54 @@ describe('Traffic classification', () => { it('paid search', () => { const expected = { type: 'paid', category: 'search', channel: '' }; - assert(expected, { referrer: 'https://www.bing.com/', utmSource: 'some-source', utmMedium: 'paidsearch', tracking: null }); - assert(expected, { referrer: 'https://www.google.co.uk/', utmSource: 'some-source', utmMedium: 'sea', tracking: null }); - assert(expected, { referrer: 'https://yahoo.com/', utmSource: 'some-source', utmMedium: 'paidsearch', tracking: null }); - assert(expected, { referrer: 'https://google.com/', utmSource: 'some-source', utmMedium: 'paidsearch', tracking: 'paid' }); - assert({ ...expected, channel: 'goo' }, { referrer: 'https://googleads.g.doubleclick.net/', utmSource: 'goo', utmMedium: 'gsea', tracking: null }); - assert({ ...expected, channel: 'goo' }, { referrer: '', utmSource: 'goo', utmMedium: 'sem', tracking: null }); + assert({ ...expected, channel: 'bing' }, { referrer: 'https://www.bing.com/', utmSource: 'some-source', utmMedium: 'paidsearch', tracking: null }); + assert({ ...expected, channel: 'google' }, { referrer: 'https://www.google.co.uk/', utmSource: 'some-source', utmMedium: 'sea', tracking: null }); + assert({ ...expected, channel: 'yahoo' }, { referrer: 'https://yahoo.com/', utmSource: 'some-source', utmMedium: 'paidsearch', tracking: null }); + assert({ ...expected, channel: 'google' }, { referrer: 'https://google.com/', utmSource: 'some-source', utmMedium: 'paidsearch', tracking: 'paid' }); + assert({ ...expected, channel: 'doubleclick' }, { referrer: 'https://googleads.g.doubleclick.net/', utmSource: 'goo', utmMedium: 'gsea', tracking: null }); + assert({ ...expected, channel: '' }, { referrer: '', utmSource: 'goo', utmMedium: 'sem', tracking: null }); assert({ ...expected, channel: 'google' }, { referrer: 'https://www.google.com/', utmSource: 'googlemaps', utmMedium: 'seomaps', tracking: null }); - assert({ ...expected, channel: 'sea' }, { referrer: '', utmSource: 'gsea', utmMedium: 'sea', tracking: null }); + assert({ ...expected, channel: '' }, { referrer: '', utmSource: 'gsea', utmMedium: 'sea', tracking: null }); }); it('paid social', () => { const expected = { type: 'paid', category: 'social', channel: '' }; - assert(expected, { referrer: 'https://www.facebook.com/', utmSource: 'some-source', utmMedium: 'facebook', tracking: null }); - assert(expected, { referrer: 'https://www.tiktok.com/', utmSource: 'some-source', utmMedium: 'paidsocial', tracking: null }); - assert(expected, { referrer: 'https://snapchat.com/', utmSource: 'some-source', utmMedium: 'social', tracking: null }); - assert(expected, { referrer: 'https://x.com/', utmSource: 'some-source', utmMedium: '', tracking: 'paid' }); - assert({ ...expected, channel: 'meta' }, { referrer: '', utmSource: 'meta', utmMedium: 'paidsocial', tracking: null }); - assert(expected, { referrer: 'https://www.tiktok.com/', utmSource: 'tt', utmMedium: 'soci', tracking: null }); - assert({ ...expected, channel: 'reddit' }, { referrer: '', utmSource: 'reddit', utmMedium: 'social', tracking: null }); - assert({ ...expected, channel: 'soc' }, { referrer: '', utmSource: 'soc', utmMedium: 'fbig', tracking: null }); - assert({ ...expected, channel: 'instagram' }, { referrer: '', utmSource: 'instagram', utmMedium: 'social', tracking: null }); + assert({ ...expected, channel: 'facebook' }, { referrer: 'https://www.facebook.com/', utmSource: 'some-source', utmMedium: 'facebook', tracking: null }); + assert({ ...expected, channel: 'tiktok' }, { referrer: 'https://www.tiktok.com/', utmSource: 'some-source', utmMedium: 'paidsocial', tracking: null }); + assert({ ...expected, channel: 'snapchat' }, { referrer: 'https://snapchat.com/', utmSource: 'some-source', utmMedium: 'social', tracking: null }); + assert({ ...expected, channel: 'x' }, { referrer: 'https://x.com/', utmSource: 'some-source', utmMedium: '', tracking: 'paid' }); + assert({ ...expected, channel: '' }, { referrer: '', utmSource: 'meta', utmMedium: 'paidsocial', tracking: null }); + assert({ ...expected, channel: 'tiktok' }, { referrer: 'https://www.tiktok.com/', utmSource: 'tt', utmMedium: 'soci', tracking: null }); + assert({ ...expected, channel: '' }, { referrer: '', utmSource: 'reddit', utmMedium: 'social', tracking: null }); + assert({ ...expected, channel: '' }, { referrer: '', utmSource: 'soc', utmMedium: 'fbig', tracking: null }); + assert({ ...expected, channel: '' }, { referrer: '', utmSource: 'instagram', utmMedium: 'social', tracking: null }); }); it('paid video', () => { const expected = { type: 'paid', category: 'video', channel: '' }; - assert(expected, { referrer: 'https://www.youtube.com/', utmSource: 'some-source', utmMedium: 'cpc', tracking: null }); - assert(expected, { referrer: 'https://www.youtube.com/', utmSource: 'some-source', utmMedium: 'ppc', tracking: null }); - assert(expected, { referrer: 'https://www.dailymotion.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: 'paid' }); - assert(expected, { referrer: 'https://www.twitch.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: 'paid' }); - assert({ ...expected, channel: 'youtube' }, { referrer: '', utmSource: 'youtube', utmMedium: 'video', tracking: null }); + assert({ ...expected, channel: 'youtube' }, { referrer: 'https://www.youtube.com/', utmSource: 'some-source', utmMedium: 'cpc', tracking: null }); + assert({ ...expected, channel: 'youtube' }, { referrer: 'https://www.youtube.com/', utmSource: 'some-source', utmMedium: 'ppc', tracking: null }); + assert({ ...expected, channel: 'dailymotion' }, { referrer: 'https://www.dailymotion.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: 'paid' }); + assert({ ...expected, channel: 'twitch' }, { referrer: 'https://www.twitch.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: 'paid' }); + assert({ ...expected, channel: '' }, { referrer: '', utmSource: 'youtube', utmMedium: 'video', tracking: null }); }); it('paid display', () => { const expected = { type: 'paid', category: 'display', channel: '' }; assert(expected, { referrer: 'not-empty', utmSource: 'some-source', utmMedium: 'cpc', tracking: null }); - assert(expected, { referrer: 'https://hebele.hebele.googlesyndication.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: null }); - assert({ ...expected, channel: 'gdn' }, { referrer: 'not-empty', utmSource: 'gdn', utmMedium: 'some-medium', tracking: null }); + assert({ ...expected, channel: 'googlesyndication' }, { referrer: 'https://hebele.hebele.googlesyndication.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: null }); + assert(expected, { referrer: 'not-empty', utmSource: 'gdn', utmMedium: 'some-medium', tracking: null }); assert(expected, { referrer: 'not-empty', utmSource: 'some-source', utmMedium: 'pp', tracking: null }); assert(expected, { referrer: 'not-empty', utmSource: 'some-source', utmMedium: 'display', tracking: null }); - assert({ ...expected, channel: 'dv360' }, { referrer: '', utmSource: 'dv360', utmMedium: 'some-medium', tracking: null }); + assert(expected, { referrer: '', utmSource: 'dv360', utmMedium: 'some-medium', tracking: null }); assert(expected, { referrer: '', utmSource: 'some-source', utmMedium: 'cpc', tracking: null }); assert(expected, { referrer: 'some-referrer', utmSource: 'some-source', utmMedium: 'some-medium', tracking: 'paid' }); assert(expected, { referrer: '', utmSource: '', utmMedium: '', tracking: 'paid' }); - assert({ ...expected, channel: 'newsshowcase' }, { referrer: 'https://www.google.com/', utmSource: 'newsshowcase', utmMedium: 'discover', tracking: null }); - assert(expected, { referrer: 'https://googleads.g.doubleclick.net/', utmSource: 'some', utmMedium: 'some', tracking: null }); + assert({ ...expected, channel: 'google' }, { referrer: 'https://www.google.com/', utmSource: 'newsshowcase', utmMedium: 'discover', tracking: null }); + assert({ ...expected, channel: 'doubleclick' }, { referrer: 'https://googleads.g.doubleclick.net/', utmSource: 'some', utmMedium: 'some', tracking: null }); assert({ ...expected, channel: 'google' }, { referrer: 'https://www.google.com/', utmSource: 'google', utmMedium: 'businesslistings', tracking: null }); }); @@ -87,27 +87,27 @@ describe('Traffic classification', () => { it('earned search', () => { const expected = { type: 'earned', category: 'search', channel: '' }; - assert(expected, { referrer: 'https://www.bing.com/', utmSource: '', utmMedium: '', tracking: null }); - assert(expected, { referrer: 'https://www.google.co.uk/', utmSource: '', utmMedium: '', tracking: null }); - assert(expected, { referrer: 'https://yahoo.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: 'some' }); - assert(expected, { referrer: 'https://google.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: 'some' }); + assert({ ...expected, channel: 'bing' }, { referrer: 'https://www.bing.com/', utmSource: '', utmMedium: '', tracking: null }); + assert({ ...expected, channel: 'google' }, { referrer: 'https://www.google.co.uk/', utmSource: '', utmMedium: '', tracking: null }); + assert({ ...expected, channel: 'yahoo' }, { referrer: 'https://yahoo.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: 'some' }); + assert({ ...expected, channel: 'google' }, { referrer: 'https://google.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: 'some' }); assert({ ...expected, channel: 'google' }, { referrer: 'https://www.google.com/', utmSource: 'google', utmMedium: 'organicgmb', tracking: null }); }); it('earned social', () => { const expected = { type: 'earned', category: 'social', channel: '' }; - assert(expected, { referrer: 'https://www.facebook.com/', utmSource: '', utmMedium: '', tracking: null }); - assert(expected, { referrer: 'https://www.tiktok.com/', utmSource: '', utmMedium: '', tracking: null }); + assert({ ...expected, channel: 'facebook' }, { referrer: 'https://www.facebook.com/', utmSource: '', utmMedium: '', tracking: null }); + assert({ ...expected, channel: 'tiktok' }, { referrer: 'https://www.tiktok.com/', utmSource: '', utmMedium: '', tracking: null }); assert(expected, { referrer: 'https://some-site.com/', utmSource: 'some-source', utmMedium: 'organicsocial', tracking: null }); }); it('earned video', () => { const expected = { type: 'earned', category: 'video', channel: '' }; - assert(expected, { referrer: 'https://www.youtube.com/', utmSource: '', utmMedium: '', tracking: null }); - assert(expected, { referrer: 'https://www.youtube.com/', utmSource: '', utmMedium: '', tracking: null }); - assert(expected, { referrer: 'https://www.dailymotion.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: null }); + assert({ ...expected, channel: 'youtube' }, { referrer: 'https://www.youtube.com/', utmSource: '', utmMedium: '', tracking: null }); + assert({ ...expected, channel: 'youtube' }, { referrer: 'https://www.youtube.com/', utmSource: '', utmMedium: '', tracking: null }); + assert({ ...expected, channel: 'dailymotion' }, { referrer: 'https://www.dailymotion.com/', utmSource: 'some-source', utmMedium: 'some-medium', tracking: null }); }); it('earned referral', () => { diff --git a/packages/spacecat-shared-rum-api-client/test/fixtures/bundles-with-traffic-source.json b/packages/spacecat-shared-rum-api-client/test/fixtures/bundles-with-traffic-source.json index aee47eb7..9a1913ee 100644 --- a/packages/spacecat-shared-rum-api-client/test/fixtures/bundles-with-traffic-source.json +++ b/packages/spacecat-shared-rum-api-client/test/fixtures/bundles-with-traffic-source.json @@ -13,6 +13,12 @@ "checkpoint": "paid", "source": "gclid", "target": "google" + }, + { + "checkpoint": "enter", + "target": "visible", + "source": "https://www.google.com/", + "timeDelta": 1007 } ] }, @@ -661,7 +667,25 @@ "url": "https://www.spacecat.com/about-us", "userAgent": "desktop:mac", "weight": 100, - "events": [] + "events": [ + { + "checkpoint": "paid", + "target": "ttclid", + "source": "tiktok", + "timeDelta": 1018 + }, + { + "checkpoint": "enter", + "target": "visible", + "source": "https://www.tiktok.com/", + "timeDelta": 1007 + }, + { + "checkpoint": "click", + "source": ".some-block", + "target": "some-url" + } + ] }, { "id": "51vtsh15kn", @@ -750,7 +774,20 @@ "url": "https://www.spacecat.com/about-us", "userAgent": "mobile:android", "weight": 100, - "events": [] + "events": [ + { + "checkpoint": "paid", + "target": "ttclid", + "source": "tiktok", + "timeDelta": 1018 + }, + { + "checkpoint": "enter", + "target": "visible", + "source": "https://www.tiktok.com/", + "timeDelta": 1007 + } + ] }, { "id": "32i721xsw1b", @@ -834,7 +871,20 @@ "url": "https://www.spacecat.com/about-us", "userAgent": "mobile:android", "weight": 100, - "events": [] + "events": [ + { + "checkpoint": "paid", + "target": "ttclid", + "source": "tiktok", + "timeDelta": 1018 + }, + { + "checkpoint": "enter", + "target": "visible", + "source": "https://www.tiktok.com/", + "timeDelta": 1007 + } + ] }, { "id": "bl2v3z6olbo", diff --git a/packages/spacecat-shared-rum-api-client/test/fixtures/bundles.json b/packages/spacecat-shared-rum-api-client/test/fixtures/bundles.json index f5b29d5f..cd8edc21 100644 --- a/packages/spacecat-shared-rum-api-client/test/fixtures/bundles.json +++ b/packages/spacecat-shared-rum-api-client/test/fixtures/bundles.json @@ -6154,6 +6154,18 @@ "checkpoint": "top", "target": "visible", "timeDelta": 705.5 + }, + { + "checkpoint": "paid", + "target": "ttclid", + "source": "tiktok", + "timeDelta": 1018 + }, + { + "checkpoint": "enter", + "target": "visible", + "source": "https://www.tiktok.com/", + "timeDelta": 1007 } ] }, diff --git a/packages/spacecat-shared-rum-api-client/test/fixtures/high-organic-low-ctr.json b/packages/spacecat-shared-rum-api-client/test/fixtures/high-organic-low-ctr.json index 89b5bc8b..eb3a1e3e 100644 --- a/packages/spacecat-shared-rum-api-client/test/fixtures/high-organic-low-ctr.json +++ b/packages/spacecat-shared-rum-api-client/test/fixtures/high-organic-low-ctr.json @@ -4,26 +4,47 @@ "page": "https://www.spacecat.com/about-us", "screenshot": "", "trackedPageKPIName": "Click Through Rate", - "trackedPageKPIValue": 0.14099783080260303, + "trackedPageKPIValue": 0.14316702819956617, "pageViews": 46100, "samples": 46100, + "siteAverage": 0.40828402366863903, "metrics": [ { "type": "traffic", + "referrer": "*", "value": { "total": 46100, - "paid": 0, - "owned": 46100, + "paid": 300, + "owned": 45800, "earned": 0 } }, { "type": "ctr", + "referrer": "*", "value": { - "page": 0.14099783080260303, - "siteAverage": 0.4077909270216962 + "page": 0.14316702819956617 } - } + }, + [ + { + "type": "traffic", + "referrer": "tiktok", + "value": { + "total": 300, + "owned": 0, + "earned": 0, + "paid": 300 + } + }, + { + "type": "ctr", + "referrer": "tiktok", + "value": { + "page": 0.3333333333333333 + } + } + ] ] } ] diff --git a/packages/spacecat-shared-rum-api-client/test/fixtures/trafficSources.json b/packages/spacecat-shared-rum-api-client/test/fixtures/trafficSources.json index 916b1051..0f0368c3 100644 --- a/packages/spacecat-shared-rum-api-client/test/fixtures/trafficSources.json +++ b/packages/spacecat-shared-rum-api-client/test/fixtures/trafficSources.json @@ -3,18 +3,36 @@ "url": "https://www.aem.live/home", "total": 2620, "earned": 400, - "owned": 2220, - "paid": 0, + "owned": 2120, + "paid": 100, "sources": [ { "type": "owned:direct", - "views": 2220 + "views": 2120 }, { "type": "earned:search", "views": 400 + }, + { + "type": "paid:social", + "views": 100 } - ] + ], + "channels": { + "google": { + "total": 400, + "owned": 0, + "earned": 400, + "paid": 0 + }, + "tiktok": { + "total": 100, + "owned": 0, + "earned": 0, + "paid": 100 + } + } }, { "url": "https://www.aem.live/developer/block-collection", @@ -27,7 +45,8 @@ "type": "owned:direct", "views": 2000 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/", @@ -44,7 +63,8 @@ "type": "earned:referral", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/tools/rum/explorer.html", @@ -61,7 +81,8 @@ "type": "earned:referral", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/tutorial", @@ -78,7 +99,8 @@ "type": "earned:referral", "views": 200 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/anatomy-of-a-franklin-project", @@ -91,7 +113,8 @@ "type": "owned:direct", "views": 1200 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/indexing", @@ -104,7 +127,8 @@ "type": "owned:direct", "views": 1000 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/custom-headers", @@ -117,7 +141,8 @@ "type": "owned:direct", "views": 900 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/spreadsheets", @@ -130,7 +155,8 @@ "type": "owned:direct", "views": 900 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/dev-collab-and-good-practices", @@ -143,7 +169,8 @@ "type": "owned:direct", "views": 700 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/go-live-checklist", @@ -156,7 +183,8 @@ "type": "owned:direct", "views": 600 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/markup-sections-blocks", @@ -169,7 +197,8 @@ "type": "owned:direct", "views": 510 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/favicon", @@ -182,7 +211,8 @@ "type": "owned:direct", "views": 500 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/keeping-it-100", @@ -195,7 +225,8 @@ "type": "owned:direct", "views": 500 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/tools/sidekick/", @@ -208,7 +239,8 @@ "type": "owned:direct", "views": 410 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/placeholders", @@ -221,7 +253,8 @@ "type": "owned:direct", "views": 403 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/byo-cdn-cloudflare-worker-setup", @@ -234,7 +267,8 @@ "type": "owned:direct", "views": 400 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/byo-dns", @@ -247,7 +281,8 @@ "type": "owned:direct", "views": 400 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/byo-cdn-fastly-setup", @@ -260,7 +295,8 @@ "type": "owned:direct", "views": 300 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/davidsmodel", @@ -277,7 +313,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/setup-customer-sharepoint", @@ -290,7 +327,8 @@ "type": "owned:direct", "views": 300 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/sitemap", @@ -303,7 +341,8 @@ "type": "owned:direct", "views": 300 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/byo-cdn-akamai-setup", @@ -316,7 +355,8 @@ "type": "owned:direct", "views": 300 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/redirects", @@ -329,7 +369,8 @@ "type": "owned:direct", "views": 300 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/bulk-metadata", @@ -342,7 +383,8 @@ "type": "owned:direct", "views": 300 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/some-other-page", @@ -355,7 +397,8 @@ "type": "owned:direct", "views": 300 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/authoring", @@ -368,7 +411,8 @@ "type": "owned:direct", "views": 210 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/sidekick", @@ -381,7 +425,8 @@ "type": "owned:direct", "views": 200 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/web-components", @@ -394,7 +439,8 @@ "type": "owned:direct", "views": 200 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/authentication-setup-site", @@ -411,7 +457,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/rum", @@ -428,7 +475,8 @@ "type": "earned:referral", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/faq", @@ -441,7 +489,8 @@ "type": "owned:direct", "views": 200 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/placeholders", @@ -454,7 +503,8 @@ "type": "owned:direct", "views": 200 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/block-collection/section-metadata", @@ -467,7 +517,8 @@ "type": "owned:direct", "views": 200 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/vip/intake", @@ -480,7 +531,8 @@ "type": "owned:direct", "views": 200 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/new-exp-page", @@ -493,7 +545,8 @@ "type": "owned:direct", "views": 200 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/sidekick-extension", @@ -510,7 +563,15 @@ "type": "owned:direct", "views": 10 } - ] + ], + "channels": { + "google": { + "total": 100, + "owned": 0, + "earned": 100, + "paid": 0 + } + } }, { "url": "https://www.aem.live/docs/rum", @@ -523,7 +584,8 @@ "type": "owned:direct", "views": 110 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/target-integration", @@ -536,7 +598,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/architecture", @@ -549,7 +612,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/block-collection/breadcrumbs", @@ -562,7 +626,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/block-collection/headings", @@ -575,7 +640,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/cdn-guide", @@ -588,7 +654,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/tools/bot/setup", @@ -601,7 +668,8 @@ "type": "earned:referral", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/github-actions", @@ -614,7 +682,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/importer", @@ -627,7 +696,8 @@ "type": "earned:referral", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/configuring-aem-assets-sidekick-plugin", @@ -640,7 +710,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/tools/rum/list.html", @@ -653,7 +724,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/setup-byo-cdn-push-invalidation", @@ -666,7 +738,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/forms", @@ -679,7 +752,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/", @@ -692,7 +766,8 @@ "type": "owned:direct", "views": 100 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/admin.html", @@ -705,7 +780,8 @@ "type": "owned:direct", "views": 20 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/community-feeds.json", @@ -718,7 +794,8 @@ "type": "owned:direct", "views": 10 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/global", @@ -731,7 +808,8 @@ "type": "owned:direct", "views": 10 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/franklin-video-series-advanced", @@ -744,7 +822,8 @@ "type": "owned:direct", "views": 10 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/markup-reference", @@ -757,7 +836,8 @@ "type": "owned:direct", "views": 10 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/byo-cdn-cloudflare-setup", @@ -770,7 +850,8 @@ "type": "owned:direct", "views": 10 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/developer/franklin-video-series", @@ -783,7 +864,8 @@ "type": "owned:direct", "views": 10 } - ] + ], + "channels": {} }, { "url": "https://www.aem.live/docs/aem-assets-sidekick-plugin", @@ -796,6 +878,7 @@ "type": "owned:direct", "views": 10 } - ] + ], + "channels": {} } ] diff --git a/packages/spacecat-shared-rum-api-client/test/functions.test.js b/packages/spacecat-shared-rum-api-client/test/functions.test.js index 8f6b91bf..0cc88702 100644 --- a/packages/spacecat-shared-rum-api-client/test/functions.test.js +++ b/packages/spacecat-shared-rum-api-client/test/functions.test.js @@ -53,7 +53,6 @@ describe('Query functions', () => { it('crunches traffic acquisition', async () => { const trafficSourcesResult = await trafficAcquisition.handler(bundles.rumBundles); - console.log(JSON.stringify(trafficSourcesResult, null, 2)); expect(expectedTrafficSourcesResult).to.eql(trafficSourcesResult); }); @@ -70,6 +69,7 @@ describe('Query functions', () => { bundlesWithTraffic.rumBundles, { interval: 7 }, ); + console.log(JSON.stringify(highInorganicHighBounceResult, null, 2)); expect(expectedHighOrganicLowCTRResult).to.eql(highInorganicHighBounceResult); }); });