Files
lst_v3/backend/notification/notification.controller.ts

154 lines
3.5 KiB
TypeScript

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