import { serve } from "https://deno.land/std@0.190.0/http/server.ts"; 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", }; serve(async (req: Request): Promise => { if (req.method === "OPTIONS") { return new Response(null, { headers: corsHeaders }); } try { const supabaseUrl = Deno.env.get("SUPABASE_URL")!; const supabaseServiceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!; const supabase = createClient(supabaseUrl, supabaseServiceKey); // Get current date/time in Jakarta timezone const now = new Date(); const jakartaOffset = 7 * 60; // UTC+7 const jakartaTime = new Date(now.getTime() + jakartaOffset * 60 * 1000); const today = jakartaTime.toISOString().split('T')[0]; // Find consultations happening in the next 24 hours that haven't been reminded const tomorrow = new Date(jakartaTime); tomorrow.setDate(tomorrow.getDate() + 1); const tomorrowStr = tomorrow.toISOString().split('T')[0]; console.log("Checking consultations for dates:", today, "to", tomorrowStr); // Get confirmed slots for today and tomorrow const { data: upcomingSlots, error: slotsError } = await supabase .from("consulting_slots") .select(` *, profiles:user_id (full_name, email) `) .eq("status", "confirmed") .gte("date", today) .lte("date", tomorrowStr) .order("date") .order("start_time"); if (slotsError) { console.error("Error fetching slots:", slotsError); throw slotsError; } console.log("Found upcoming slots:", upcomingSlots?.length || 0); if (!upcomingSlots || upcomingSlots.length === 0) { return new Response( JSON.stringify({ success: true, message: "No upcoming consultations to remind" }), { headers: { ...corsHeaders, "Content-Type": "application/json" } } ); } // Get notification template for consultation reminder const { data: template } = await supabase .from("notification_templates") .select("*") .eq("key", "consulting_scheduled") .single(); // Get SMTP settings const { data: smtpSettings } = await supabase .from("notification_settings") .select("*") .single(); // Get platform settings const { data: platformSettings } = await supabase .from("platform_settings") .select("brand_name, brand_email_from_name, integration_whatsapp_number") .single(); const results: any[] = []; for (const slot of upcomingSlots) { const profile = slot.profiles as any; // Build payload for notification const payload = { nama: profile?.full_name || "Pelanggan", email: profile?.email || "", tanggal_konsultasi: new Date(slot.date).toLocaleDateString("id-ID", { weekday: "long", year: "numeric", month: "long", day: "numeric", }), jam_konsultasi: `${slot.start_time.substring(0, 5)} - ${slot.end_time.substring(0, 5)} WIB`, link_meet: slot.meet_link || "Akan diinformasikan", topik: slot.topic_category, catatan: slot.notes || "-", brand_name: platformSettings?.brand_name || "LearnHub", whatsapp: platformSettings?.integration_whatsapp_number || "", }; // Log the reminder payload console.log("Reminder payload for slot:", slot.id, payload); // Update last_payload_example in template if (template) { await supabase .from("notification_templates") .update({ last_payload_example: payload }) .eq("id", template.id); } // Send webhook if configured if (template?.webhook_url) { try { await fetch(template.webhook_url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ event: "consulting_reminder", slot_id: slot.id, ...payload, }), }); console.log("Webhook sent for slot:", slot.id); } catch (webhookError) { console.error("Webhook error:", webhookError); } } // Send email if template is active and Mailketing is configured if (template?.is_active && smtpSettings?.api_token && profile?.email) { try { // Replace shortcodes in email body using master template system let emailBody = template.email_body_html || ""; let emailSubject = template.email_subject || "Reminder Konsultasi"; Object.entries(payload).forEach(([key, value]) => { const regex = new RegExp(`\\{${key}\\}`, "g"); emailBody = emailBody.replace(regex, String(value)); emailSubject = emailSubject.replace(regex, String(value)); }); // Send via send-email-v2 (Mailketing API) const { error: emailError } = await supabase.functions.invoke("send-email-v2", { body: { to: profile.email, api_token: smtpSettings.api_token, from_name: smtpSettings.from_name || platformSettings?.brand_name || "Access Hub", from_email: smtpSettings.from_email || "noreply@with.dwindi.com", subject: emailSubject, html_body: emailBody, }, }); if (emailError) { console.error("Failed to send reminder email:", emailError); } else { console.log("Reminder email sent to:", profile.email); } } catch (emailError) { console.error("Error sending reminder email:", emailError); } } results.push({ slot_id: slot.id, client: profile?.full_name, date: slot.date, time: slot.start_time, reminded: true, }); } return new Response( JSON.stringify({ success: true, message: `Processed ${results.length} consultation reminders`, results }), { headers: { ...corsHeaders, "Content-Type": "application/json" } } ); } catch (error: any) { console.error("Error sending reminders:", error); return new Response( JSON.stringify({ success: false, message: error.message }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } } ); } });