import { Resend } from 'resend' import { state } from './state.js' import { queuePodcastChecklistWrite, queueCalendarEventsWrite } from './data.js' import { DEFAULT_RESEND_FROM, DEFAULT_RESEND_TO } from './config.js' function toDateKey(date) { return date.toISOString().slice(0, 10) } export function startReminderScheduler() { checkReminders() setInterval(checkReminders, 60 * 60 * 1000) } async function checkReminders() { const todayKey = toDateKey(new Date()) // Episodes const episodes = state.podcastChecklist?.episodes if (Array.isArray(episodes)) { let changed = false for (const ep of episodes) { if (!ep.datePublished || !(ep.reminderDays > 0) || ep.reminderSentAt) continue const publish = new Date(ep.datePublished + 'T12:00:00Z') if (isNaN(publish.getTime())) continue const reminderDate = new Date(publish) reminderDate.setUTCDate(reminderDate.getUTCDate() - ep.reminderDays) if (todayKey >= toDateKey(reminderDate) && todayKey <= toDateKey(publish)) { const sent = await sendReminderEmail({ label: ep.episodeNumber ? `Episode ${ep.episodeNumber}` : 'Episode', title: ep.title || 'Untitled', series: ep.series, date: ep.datePublished, reminderDays: ep.reminderDays, type: 'episode', }) if (sent) { ep.reminderSentAt = new Date().toISOString(); changed = true } } } if (changed) queuePodcastChecklistWrite() } // Calendar events const events = state.calendarEvents if (Array.isArray(events)) { let changed = false for (const ev of events) { if (!ev.date || !(ev.reminderDays > 0) || ev.reminderSentAt) continue const publish = new Date(ev.date + 'T12:00:00Z') if (isNaN(publish.getTime())) continue const reminderDate = new Date(publish) reminderDate.setUTCDate(reminderDate.getUTCDate() - ev.reminderDays) if (todayKey >= toDateKey(reminderDate) && todayKey <= toDateKey(publish)) { const sent = await sendReminderEmail({ label: ev.type.charAt(0).toUpperCase() + ev.type.slice(1), title: ev.title, series: null, date: ev.date, reminderDays: ev.reminderDays, type: ev.type, }) if (sent) { ev.reminderSentAt = new Date().toISOString(); changed = true } } } if (changed) queueCalendarEventsWrite() } } const TYPE_ICONS = { episode: '📅', general: '📌', recording: '🎙️', social: '📱', task: '✅' } async function sendReminderEmail({ label, title, series, date, reminderDays, type }) { if (!process.env.RESEND_API_KEY) return false try { const resend = new Resend(process.env.RESEND_API_KEY) const from = process.env.RESEND_FROM ?? DEFAULT_RESEND_FROM const to = process.env.RESEND_TO ?? DEFAULT_RESEND_TO const eventDate = new Date(date + 'T12:00:00Z') const msLeft = eventDate.getTime() - Date.now() const daysLeft = Math.max(0, Math.ceil(msLeft / (1000 * 60 * 60 * 24))) const seriesStr = series ? ` (${series})` : '' const daysText = daysLeft === 0 ? 'today' : daysLeft === 1 ? 'in 1 day' : `in ${daysLeft} days` const icon = TYPE_ICONS[type] ?? '📅' const subject = `Reminder: ${label}: ${title} — ${daysText}` const html = `
${label}: ${title}${seriesStr}
Scheduled for ${date} — ${daysText}
This reminder was set ${reminderDays} day${reminderDays === 1 ? '' : 's'} before the date. To change or remove it, open the Calendar in your admin panel.