mirror of
https://github.com/renee-png/acmcc.git
synced 2026-06-21 01:40:01 +00:00
183fe0a93c
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
122 lines
4.5 KiB
TypeScript
122 lines
4.5 KiB
TypeScript
import { createClient } from "https://esm.sh/@supabase/supabase-js@2";
|
|
|
|
const corsHeaders = {
|
|
"Access-Control-Allow-Origin": "*",
|
|
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
|
|
};
|
|
|
|
Deno.serve(async (req) => {
|
|
if (req.method === "OPTIONS") {
|
|
return new Response(null, { headers: corsHeaders });
|
|
}
|
|
|
|
try {
|
|
const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
|
|
const serviceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
|
|
const supabase = createClient(supabaseUrl, serviceKey);
|
|
|
|
const now = new Date();
|
|
const in24h = new Date(now.getTime() + 24 * 60 * 60 * 1000);
|
|
|
|
// Find reminders due within 24 hours that haven't been notified recently
|
|
const { data: reminders, error } = await supabase
|
|
.from("reminders")
|
|
.select("*")
|
|
.neq("status", "completed")
|
|
.lte("due_date", in24h.toISOString())
|
|
.gte("due_date", now.toISOString());
|
|
|
|
if (error) throw error;
|
|
if (!reminders || reminders.length === 0) {
|
|
return new Response(JSON.stringify({ success: true, processed: 0 }), {
|
|
headers: { ...corsHeaders, "Content-Type": "application/json" },
|
|
});
|
|
}
|
|
|
|
// Filter out recently notified (within last 12 hours)
|
|
const twelveHoursAgo = new Date(now.getTime() - 12 * 60 * 60 * 1000);
|
|
const dueReminders = reminders.filter((r: any) => {
|
|
if (!r.last_notified_at) return true;
|
|
return new Date(r.last_notified_at) < twelveHoursAgo;
|
|
});
|
|
|
|
// Get active SMTP sender
|
|
const { data: senders } = await supabase
|
|
.from("email_senders")
|
|
.select("*")
|
|
.eq("is_active", true)
|
|
.eq("verified", true)
|
|
.limit(1);
|
|
|
|
const sender = senders?.[0];
|
|
|
|
let processed = 0;
|
|
|
|
for (const reminder of dueReminders) {
|
|
const userId = reminder.assigned_to || reminder.created_by;
|
|
if (!userId) continue;
|
|
|
|
// Create in-app notification
|
|
await supabase.rpc("insert_notification", {
|
|
p_user_id: userId,
|
|
p_type: "reminder_due",
|
|
p_title: "Reminder Due Soon",
|
|
p_message: `"${reminder.title}" is due ${new Date(reminder.due_date).toLocaleString()}.`,
|
|
p_related_item_type: "reminder",
|
|
p_link: "/dashboard/settings/reminders",
|
|
});
|
|
|
|
// Send email if SMTP is configured
|
|
if (sender) {
|
|
try {
|
|
const { data: userData } = await supabase.auth.admin.getUserById(userId);
|
|
if (userData?.user?.email) {
|
|
const senderFrom = sender.sender_name
|
|
? `${sender.sender_name} <${sender.email_address}>`
|
|
: sender.email_address;
|
|
|
|
await supabase.functions.invoke("send-smtp-email", {
|
|
body: {
|
|
sender: {
|
|
host: sender.smtp_host,
|
|
port: sender.smtp_port,
|
|
username: sender.smtp_username,
|
|
password: sender.smtp_password,
|
|
use_tls: sender.use_tls,
|
|
use_ssl: sender.use_ssl,
|
|
from: senderFrom,
|
|
},
|
|
recipient: [userData.user.email],
|
|
subject: `Reminder Due: ${reminder.title}`,
|
|
body: `<h3>Reminder Due Soon</h3><p>Your reminder "<strong>${reminder.title}</strong>" is due on ${new Date(reminder.due_date).toLocaleString()}.</p>${reminder.description ? `<p>${reminder.description}</p>` : ""}<p>Please log in to the portal to manage your reminders.</p>`,
|
|
html: `<h3>Reminder Due Soon</h3><p>Your reminder "<strong>${reminder.title}</strong>" is due on ${new Date(reminder.due_date).toLocaleString()}.</p>${reminder.description ? `<p>${reminder.description}</p>` : ""}<p>Please log in to the portal to manage your reminders.</p>`,
|
|
debug: false,
|
|
},
|
|
});
|
|
}
|
|
} catch (emailErr) {
|
|
console.error(`Failed to send email for reminder ${reminder.id}:`, emailErr);
|
|
}
|
|
}
|
|
|
|
// Update last_notified_at
|
|
await supabase
|
|
.from("reminders")
|
|
.update({ last_notified_at: now.toISOString() })
|
|
.eq("id", reminder.id);
|
|
|
|
processed++;
|
|
}
|
|
|
|
return new Response(JSON.stringify({ success: true, processed }), {
|
|
headers: { ...corsHeaders, "Content-Type": "application/json" },
|
|
});
|
|
} catch (error) {
|
|
console.error("check-reminder-emails error:", error);
|
|
return new Response(JSON.stringify({ success: false, error: (error as Error).message }), {
|
|
status: 500,
|
|
headers: { ...corsHeaders, "Content-Type": "application/json" },
|
|
});
|
|
}
|
|
});
|