Files
open-gsio/packages/cloudflare-workers/analytics/analytics_worker.js
2025-06-24 17:32:59 -04:00

90 lines
2.6 KiB
JavaScript

addEventListener('fetch', event => {
event.respondWith(handleRequest(event));
});
async function handleRequest(event) {
const url = new URL(event.request.url);
const { request } = event;
const { headers } = request;
const referer = headers.get('Referer') || '';
const userAgent = headers.get('User-Agent');
const refHost = (() => {
try {
return new URL(referer).hostname;
} catch (e) {
return '';
}
})();
const uuid = getOrCreateUuid(headers);
event.waitUntil(logAnalyticsData(event, url, uuid, userAgent, referer));
const response = new Response(null, {
status: 204,
statusText: 'No Content',
});
if (!headers.get('cookie')?.includes('uuid=')) {
response.headers.set(
'Set-Cookie',
`uuid=${uuid}; Expires=${new Date(Date.now() + 365 * 86400 * 30 * 1000).toUTCString()}; Path='/';`,
);
}
return response;
}
function shouldBlockRequest(refHost, userAgent, url) {
if (!refHost || !userAgent || !url.search.includes('ga=')) {
return true;
}
return false;
}
function getOrCreateUuid(headers) {
const cookie = headers.get('cookie') || '';
const uuidMatch = cookie.match(/uuid=([^;]+)/);
if (uuidMatch) {
return uuidMatch[1];
}
return crypto.randomUUID();
}
async function logAnalyticsData(event, url, uuid, userAgent, pageUrl) {
// - This is defined in the workers runtime
// eslint-disable-next-line no-undef
const { ANALYTICS_ENGINE } = globalThis;
const params = url.searchParams;
const dataPoint = {
blobs: [
pageUrl, // Page URL
userAgent, // User Agent
params.get('dt') || '', // Page Title
params.get('de') || '', // Document Encoding
params.get('dr') || '', // Document Referrer
params.get('ul') || '', // User Language
params.get('sd') || '', // Screen Colors
params.get('sr') || '', // Screen Resolution
params.get('vp') || '', // Viewport Size
uuid, // Client ID
],
doubles: [
parseFloat(params.get('plt') || '0'), // Page Load Time
parseFloat(params.get('dns') || '0'), // DNS Time
parseFloat(params.get('pdt') || '0'), // Page Download Time
parseFloat(params.get('rrt') || '0'), // Redirect Response Time
parseFloat(params.get('tcp') || '0'), // TCP Connect Time
parseFloat(params.get('srt') || '0'), // Server Response Time
parseFloat(params.get('dit') || '0'), // DOM Interactive Time
parseFloat(params.get('clt') || '0'), // Content Loaded Time
],
indexes: [
event.request.headers.get('CF-Connecting-IP') || '', // User IP
],
};
ANALYTICS_ENGINE.writeDataPoint(dataPoint);
}