data endpoint for entity 90008 (aka. a website)
1import { updateLastPosts } from '$lib/bluesky'; 2import { lastFmReadLast, lastFmUpdateNowPlaying } from '$lib/lastfm'; 3import { steamReadLastGame, steamUpdateNowPlaying } from '$lib/steam'; 4import { updateCommits } from '$lib/activity'; 5import { cancelJob, scheduleJob, scheduledJobs } from 'node-schedule'; 6import { 7 incrementFakeVisitCount, 8 incrementLegitVisitCount, 9 pushMetric, 10 sendAllMetrics 11} from '$lib/metrics'; 12import { 13 addLastVisitor, 14 decrementVisitCount, 15 incrementVisitCount, 16 notifyDarkVisitors, 17 removeLastVisitor 18} from '$lib/visits'; 19import { testUa } from '$lib/robots'; 20import { error } from '@sveltejs/kit'; 21import { _fetchEntries } from './routes/(site)/guestbook/+page.server'; 22 23const UPDATE_LAST_JOB_NAME = 'update steam game, lastfm track, bsky posts, git activity'; 24 25if (UPDATE_LAST_JOB_NAME in scheduledJobs) { 26 console.log(`${UPDATE_LAST_JOB_NAME} is already running, cancelling so we can start a new one`); 27 cancelJob(UPDATE_LAST_JOB_NAME); 28} 29 30await steamReadLastGame(); 31await lastFmReadLast(); 32 33console.log(`starting ${UPDATE_LAST_JOB_NAME} job...`); 34scheduleJob(UPDATE_LAST_JOB_NAME, '*/1 * * * *', async () => { 35 console.log(`running ${UPDATE_LAST_JOB_NAME} job...`); 36 try { 37 await Promise.all([ 38 steamUpdateNowPlaying(), 39 lastFmUpdateNowPlaying(), 40 updateLastPosts(), 41 _fetchEntries(), 42 updateCommits(), 43 sendAllMetrics() // send all metrics every minute 44 ]); 45 } catch (err) { 46 console.log(`error while running ${UPDATE_LAST_JOB_NAME} job: ${err}`); 47 } 48}).invoke(); // invoke once immediately 49 50export const handle = async ({ event, resolve }) => { 51 notifyDarkVisitors(event.url, event.request); // no await so it doesnt block 52 53 const isPrefetch = () => { 54 return ( 55 event.request.headers.get('Sec-Purpose')?.includes('prefetch') || 56 event.request.headers.get('Purpose')?.includes('prefetch') || 57 event.request.headers.get('x-purpose')?.includes('preview') || 58 event.request.headers.get('x-moz')?.includes('prefetch') 59 ); 60 }; 61 const isApi = () => { 62 return event.url.pathname.startsWith('/_api'); 63 }; 64 const isRss = () => { 65 return event.url.pathname.endsWith('/_rss'); 66 }; 67 68 // block any requests if the user agent is disallowed by our robots txt 69 const isFakeVisit = 70 (await testUa(event.url.toString(), event.request.headers.get('user-agent') ?? '')) === false; 71 if (isFakeVisit) { 72 pushMetric({ gazesys_visit_fake_total: await incrementFakeVisitCount() }); 73 throw error(403, 'get a better user agent silly'); 74 } 75 76 // only push metric if legit page visit (still want rss to count here though) 77 const isPageVisit = !isApi() && !isPrefetch(); 78 if (isPageVisit) pushMetric({ gazesys_visit_real_total: await incrementLegitVisitCount() }); 79 80 // only add visitors if its a "legit" page visit 81 let id = null; 82 let valid = false; 83 if (isPageVisit && !isRss()) { 84 id = addLastVisitor(event.request, event.cookies); 85 valid = await incrementVisitCount(event.request, event.cookies); 86 } 87 88 // actually resolve event 89 const resp = await resolve(event); 90 // remove visitors if it was a 404 91 if (resp.status === 404) { 92 if (id !== null) removeLastVisitor(id); 93 if (valid) decrementVisitCount(); 94 } 95 96 return resp; 97};