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