From 92b009fa1eb94b025f53d978cf533f5a6bcb6a03 Mon Sep 17 00:00:00 2001 From: Chris Walsh Date: Thu, 21 Jul 2022 14:57:29 -0700 Subject: [PATCH] Add UTM pageview metrics to API --- pages/api/website/[id]/metrics.js | 49 ++++++++++++++++++- .../analytics/pageview/getPageviewParams.js | 38 ++++++++++++++ queries/index.js | 2 + 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 queries/analytics/pageview/getPageviewParams.js diff --git a/pages/api/website/[id]/metrics.js b/pages/api/website/[id]/metrics.js index 09229408..5df159d6 100644 --- a/pages/api/website/[id]/metrics.js +++ b/pages/api/website/[id]/metrics.js @@ -1,10 +1,11 @@ -import { getPageviewMetrics, getSessionMetrics, getWebsiteById } from 'queries'; +import { getPageviewMetrics, getSessionMetrics, getWebsiteById, getPageviewParams } from 'queries'; import { ok, methodNotAllowed, unauthorized, badRequest } from 'lib/response'; import { allowQuery } from 'lib/auth'; import { useCors } from 'lib/middleware'; const sessionColumns = ['browser', 'os', 'device', 'screen', 'country', 'language']; const pageviewColumns = ['url', 'referrer']; +const paramTypes = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term', 'ref']; function getTable(type) { if (type === 'event') { @@ -39,6 +40,52 @@ export default async (req, res) => { const startDate = new Date(+start_at); const endDate = new Date(+end_at); + if (paramTypes.includes(type)) { + const column = 'url'; + const table = getTable(type); + + let domain; + if (type === 'referrer') { + const website = await getWebsiteById(websiteId); + + if (!website) { + return badRequest(res); + } + + domain = website.domain; + } + + const filters = { + domain, + url: type !== 'url' && table !== 'event' ? url : undefined, + referrer: type !== 'referrer' ? referrer : true, + os: type !== 'os' ? os : undefined, + browser: type !== 'browser' ? browser : undefined, + device: type !== 'device' ? device : undefined, + country: type !== 'country' ? country : undefined, + event_url: type !== 'url' && table === 'event' ? url : undefined, + }; + + let data = await getPageviewParams( + type, + websiteId, + startDate, + endDate, + column, + table, + filters, + ); + + let terms = {}; + new Set(data.map(i => i.param)).forEach(term => (terms[term] = null)); + for (let { param } of data) terms[param] += 1; + + return ok( + res, + Object.keys(terms).map(i => ({ x: i, y: terms[i] })), + ); + } + if (sessionColumns.includes(type)) { let data = await getSessionMetrics(websiteId, startDate, endDate, type, { os, diff --git a/queries/analytics/pageview/getPageviewParams.js b/queries/analytics/pageview/getPageviewParams.js new file mode 100644 index 00000000..b71e2d1f --- /dev/null +++ b/queries/analytics/pageview/getPageviewParams.js @@ -0,0 +1,38 @@ +import { parseFilters, rawQuery } from 'lib/queries'; + +export function getPageviewParams( + param, + website_id, + start_at, + end_at, + column, + table, + filters = {}, +) { + const params = [param, website_id, start_at, end_at]; + const { pageviewQuery, sessionQuery, eventQuery, joinSession } = parseFilters( + table, + column, + filters, + params, + ); + + return rawQuery( + `select * from ( + select + url, split_part(split_part(url, concat($1, '='), 2), '&', 1) param + from + pageview + ${joinSession} + ${pageviewQuery} + ${joinSession && sessionQuery} + ${eventQuery} + where + ${table}.website_id=$2 and ${table}.created_at between $3 and $4 + group by 1, 2 + order by 2 desc + ) q + where q.param <> ''`, + params, + ); +} diff --git a/queries/index.js b/queries/index.js index a3ea9d57..517307f6 100644 --- a/queries/index.js +++ b/queries/index.js @@ -17,6 +17,7 @@ import { getEventMetrics } from './analytics/event/getEventMetrics'; import { getEvents } from './analytics/event/getEvents'; import { saveEvent } from './analytics/event/saveEvent'; import { getPageviewMetrics } from './analytics/pageview/getPageviewMetrics'; +import { getPageviewParams } from './analytics/pageview/getPageviewParams'; import { getPageviews } from './analytics/pageview/getPageviews'; import { getPageviewStats } from './analytics/pageview/getPageviewStats'; import { savePageView } from './analytics/pageview/savePageView'; @@ -48,6 +49,7 @@ export { getEvents, saveEvent, getPageviewMetrics, + getPageviewParams, getPageviews, getPageviewStats, savePageView,