import { eq } from "drizzle-orm"; import { db } from "../db/db.controller.js"; import { notifications } from "../db/schema/notifications.schema.js"; import { notificationSub } from "../db/schema/notifications.sub.schema.js"; import { createLogger } from "../logger/logger.controller.js"; import { minutesToCron } from "../utils/croner.minConvert.js"; import { createCronJob, stopCronJob } from "../utils/croner.utils.js"; import { tryCatch } from "../utils/trycatch.utils.js"; const log = createLogger({ module: "notifications", subModule: "start" }); export const startNotifications = async () => { // get active notification const { data, error } = await tryCatch( db.select().from(notifications).where(eq(notifications.active, true)), ); if (error) { log.error( { error: error }, "There was an error when getting notifications.", ); return; } if (data) { if (data.length === 0) { log.info( {}, "There are know currently active notifications to start up.", ); return; } // get the subs and see if we have any subs currently so we can fire up the notification const { data: sub, error: subError } = await tryCatch( db.select().from(notificationSub), ); if (subError) { log.error( { error: error }, "There was an error when getting subscriptions.", ); return; } if (sub.length === 0) { log.info({}, "There are know currently active subscriptions."); return; } const emailString = [ ...new Set( sub.flatMap((e) => e.emails?.map((email) => email.trim().toLowerCase()), ), ), ].join(";"); for (const n of data) { createCronJob( n.name, minutesToCron(parseInt(n.interval ?? "15", 10)), async () => { try { const { default: runFun } = await import( `./notification.${n.name.trim()}.js` ); await runFun(n, emailString); } catch (error) { log.error( { error: error }, "There was an error starting the notification", ); } }, ); } } }; export const modifiedNotification = async (id: string) => { // when a notifications subscribed to, updated, deleted we want to get the info and rerun the startup on the single notification. const { data, error } = await tryCatch( db.select().from(notifications).where(eq(notifications.id, id)), ); if (error) { log.error( { error: error }, "There was an error when getting notifications.", ); return; } if (data) { if (!data[0]?.active) { stopCronJob(data[0]?.name ?? ""); return; } // get the subs for the specific id as we only want to up the modified one const { data: sub, error: subError } = await tryCatch( db .select() .from(notificationSub) .where(eq(notificationSub.notificationId, id)), ); if (subError) { log.error( { error: error }, "There was an error when getting subscriptions.", ); return; } if (sub.length === 0) { log.info({}, "There are know currently active subscriptions."); stopCronJob(data[0]?.name ?? ""); return; } const emailString = [ ...new Set( sub.flatMap((e) => e.emails?.map((email) => email.trim().toLowerCase()), ), ), ].join(";"); createCronJob( data[0].name, minutesToCron(parseInt(data[0].interval ?? "15", 10)), async () => { try { const { default: runFun } = await import( `./notification.${data[0]?.name.trim()}.js` ); await runFun(data[0], emailString); } catch (error) { log.error( { error: error }, "There was an error starting the notification", ); } }, ); } };