Files
shd.build/src/lib/server/automated-messages.ts
T

71 lines
2.7 KiB
TypeScript

import { randomUUID } from 'node:crypto';
import { getDatabase } from '$lib/server/database';
import { createNotification } from '$lib/server/notifications';
export const AUTOMATED_MESSAGE_EVENTS = [
{ value: 'account.created', label: 'ACCOUNT CREATED', description: 'After a new SHD.build account is created' }
] as const;
export type AutomatedMessageEvent = (typeof AUTOMATED_MESSAGE_EVENTS)[number]['value'];
type MessageRow = Record<string, unknown>;
function parseActions(value: unknown): Array<{ label: string; href: string }> {
try {
const parsed = JSON.parse(String(value ?? '[]'));
if (!Array.isArray(parsed)) return [];
return parsed
.filter((item) => item && typeof item.label === 'string' && typeof item.href === 'string')
.map((item) => ({ label: item.label.slice(0, 60), href: item.href.slice(0, 500) }))
.slice(0, 8);
} catch {
return [];
}
}
async function deliver(message: MessageRow, deliveryId: string, userId: string) {
const notificationId = await createNotification({
userId,
category: 'isac',
source: String(message.source),
title: String(message.title),
body: String(message.body),
link: typeof message.link === 'string' ? message.link : null,
actions: parseActions(message.actions_json),
mandatory: true
});
if (!notificationId) return;
const database = await getDatabase();
await (await database.prepare(`UPDATE automated_system_message_deliveries
SET delivered_at=?,notification_id=? WHERE id=? AND delivered_at IS NULL`))
.run(new Date().toISOString(), notificationId, deliveryId);
}
export async function triggerAutomatedSystemMessages(input: {
eventKey: AutomatedMessageEvent;
userId: string;
eventId: string;
}) {
const database = await getDatabase();
const messages = await (await database.prepare(
'SELECT * FROM automated_system_messages WHERE event_key=? AND enabled=1 ORDER BY name'
)).all(input.eventKey);
const now = new Date();
for (const message of messages) {
const existing = await (await database.prepare(`SELECT id FROM automated_system_message_deliveries
WHERE message_id=? AND user_id=? AND event_key=? AND event_id=?`))
.get(message.id, input.userId, input.eventKey, input.eventId);
if (existing) continue;
const deliveryId = randomUUID();
const scheduledFor = new Date(now.getTime() + Number(message.send_delay_minutes ?? 0) * 60_000);
await (await database.prepare(`INSERT OR IGNORE INTO automated_system_message_deliveries
(id,message_id,user_id,event_key,event_id,scheduled_for,created_at)
VALUES(?,?,?,?,?,?,?)`)).run(
deliveryId, message.id, input.userId, input.eventKey, input.eventId,
scheduledFor.toISOString(), now.toISOString()
);
if (Number(message.send_delay_minutes ?? 0) === 0) {
await deliver(message, deliveryId, input.userId);
}
}
}