UTM report.

This commit is contained in:
Mike Cao 2024-03-14 02:45:00 -07:00
parent e602aedd21
commit bca9c87021
25 changed files with 379 additions and 39 deletions

View file

@ -0,0 +1,120 @@
import clickhouse from 'lib/clickhouse';
import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db';
import prisma from 'lib/prisma';
export async function getUTM(
...args: [
websiteId: string,
filters: {
startDate: Date;
endDate: Date;
timezone?: string;
},
]
) {
return runQuery({
[PRISMA]: () => relationalQuery(...args),
[CLICKHOUSE]: () => clickhouseQuery(...args),
});
}
async function relationalQuery(
websiteId: string,
filters: {
startDate: Date;
endDate: Date;
timezone?: string;
},
): Promise<
{
date: string;
day: number;
visitors: number;
returnVisitors: number;
percentage: number;
}[]
> {
const { startDate, endDate } = filters;
const { rawQuery } = prisma;
return rawQuery(
`
select url_query, count(*) as "num"
from website_event
where website_id = {{websiteId::uuid}}
and created_at between {{startDate}} and {{endDate}}
and url_query is not null
group by 1
`,
{
websiteId,
startDate,
endDate,
},
).then(results => {
return results;
});
}
async function clickhouseQuery(
websiteId: string,
filters: {
startDate: Date;
endDate: Date;
timezone?: string;
},
): Promise<
{
date: string;
day: number;
visitors: number;
returnVisitors: number;
percentage: number;
}[]
> {
const { startDate, endDate } = filters;
const { rawQuery } = clickhouse;
return rawQuery(
`
select url_query, count(*) as "num"
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and url_query != ''
group by 1
`,
{
websiteId,
startDate,
endDate,
},
).then(result => parseParameters(result as any[]));
}
function parseParameters(result: any[]) {
return Object.values(result).reduce((data, { url_query, num }) => {
const params = url_query.split('&').map(n => decodeURIComponent(n));
for (const param of params) {
const [key, value] = param.split('=');
const match = key.match(/^utm_(\w+)$/);
if (match) {
const group = match[1];
const name = decodeURIComponent(value);
if (!data[group]) {
data[group] = { [name]: +num };
} else if (!data[group][name]) {
data[group][name] = +num;
} else {
data[group][name] += +num;
}
}
}
return data;
}, {});
}

View file

@ -14,6 +14,7 @@ export * from './analytics/events/saveEvent';
export * from './analytics/reports/getFunnel';
export * from './analytics/reports/getRetention';
export * from './analytics/reports/getInsights';
export * from './analytics/reports/getUTM';
export * from './analytics/pageviews/getPageviewMetrics';
export * from './analytics/pageviews/getPageviewStats';
export * from './analytics/sessions/createSession';