// tautulli's events. The tool runtime imports this once the broker is bound. It watches Tautulli's // history and announces each newly recorded watch. // // Emits (novox/hq ADR 0041/0042): // module.tautulli.watch.recorded — a play appeared in Tautulli's history // // Diffed on the history row id and primed silently on the first look, so a restart does not // re-announce the whole existing history as freshly watched. import { emit } from "@novox/mesh-sdk/events"; import { TautulliClient, type TautulliWatch } from "./client.js"; // Constructed lazily so an unconfigured node (no API key) loads this entrypoint without crashing // the events host — it simply watches nothing. let tautulli: TautulliClient | undefined; try { tautulli = TautulliClient.fromEnv(); } catch (err) { console.log(`[tautulli] not configured, not watching history: ${err}`); } const seen = new Set(); let primed = false; async function pollHistory(client: TautulliClient): Promise { const history = await client.getHistory(25); for (const w of history) { if (w.id === 0 || seen.has(w.id)) continue; if (primed) await emitWatch(w); seen.add(w.id); } primed = true; } async function emitWatch(w: TautulliWatch): Promise { await emit("watch.recorded", { title: w.title, user: w.user, mediaType: w.mediaType, watchedStatus: w.watchedStatus, percentComplete: w.percentComplete, at: w.date, }); } if (tautulli) { const client = tautulli; const run = (): void => void pollHistory(client).catch((err) => console.error(`[tautulli] ${err}`)); setInterval(run, 60_000); run(); console.log("[tautulli] watching watch history"); }