From 99b8faafbb48d92f235d208e062e6b3d86ad9b68 Mon Sep 17 00:00:00 2001 From: Sticks Date: Sun, 23 Mar 2025 22:27:44 -0400 Subject: [PATCH] fix: crashing on startup (part 2!) --- api/src/processing/helpers/youtube-session.js | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 api/src/processing/helpers/youtube-session.js diff --git a/api/src/processing/helpers/youtube-session.js b/api/src/processing/helpers/youtube-session.js new file mode 100644 index 0000000..5235c42 --- /dev/null +++ b/api/src/processing/helpers/youtube-session.js @@ -0,0 +1,74 @@ +import * as cluster from "../../misc/cluster.js"; + +import { env } from "../../config.js"; +import { Green, Yellow } from "../../misc/console-text.js"; + +let session; + +const validateSession = (sessionResponse) => { + if (!sessionResponse.potoken) { + throw "no poToken in session response"; + } + + if (!sessionResponse.visitor_data) { + throw "no visitor_data in session response"; + } + + if (!sessionResponse.updated) { + throw "no last update timestamp in session response"; + } + + // https://github.com/iv-org/youtube-trusted-session-generator/blob/c2dfe3f/potoken_generator/main.py#L25 + if (sessionResponse.potoken.length < 160) { + console.error(`${Yellow('[!]')} poToken is too short and might not work (${new Date().toISOString()})`); + } +} + +const updateSession = (newSession) => { + session = newSession; +} + +const loadSession = async () => { + const sessionServerUrl = new URL(env.ytSessionServer); + sessionServerUrl.pathname = "/token"; + + const newSession = await fetch(sessionServerUrl).then(a => a.json()); + validateSession(newSession); + + if (!session || session.updated < newSession?.updated) { + cluster.broadcast({ youtube_session: newSession }); + updateSession(newSession); + } +} + +const wrapLoad = (initial = false) => { + loadSession() + .then(() => { + if (initial) { + console.log(`${Green('[✓]')} poToken & visitor_data loaded successfully!`); + } + }) + .catch((e) => { + console.error(`${Yellow('[!]')} Failed loading poToken & visitor_data at ${new Date().toISOString()}.`); + console.error('Error:', e); + }) +} + +export const getYouTubeSession = () => { + return session; +} + +export const setup = () => { + if (cluster.isPrimary) { + wrapLoad(true); + if (env.ytSessionReloadInterval > 0) { + setInterval(wrapLoad, env.ytSessionReloadInterval * 1000); + } + } else if (cluster.isWorker) { + process.on('message', (message) => { + if ('youtube_session' in message) { + updateSession(message.youtube_session); + } + }); + } +}