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); }