import { createClient } from "https://esm.sh/@supabase/supabase-js@2.45.0"; 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 { association_id, subject, from_name, reply_to, html, send_now } = await req.json(); if (!association_id || !subject || !from_name || !reply_to || !html) { return new Response(JSON.stringify({ success: false, error: "Missing required fields." }), { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" }, }); } const supabase = createClient( Deno.env.get("SUPABASE_URL")!, Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!, ); const { data: config, error: cfgErr } = await supabase .from("mailchimp_configs") .select("*") .eq("association_id", association_id) .maybeSingle(); if (cfgErr) throw cfgErr; if (!config?.api_key || !config?.server_prefix || !config?.audience_id) { return new Response(JSON.stringify({ success: false, error: "Mailchimp is not configured for this association." }), { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" }, }); } const baseUrl = `https://${config.server_prefix}.api.mailchimp.com/3.0`; const auth = "Basic " + btoa(`anystring:${config.api_key}`); // 1. Create the campaign const createRes = await fetch(`${baseUrl}/campaigns`, { method: "POST", headers: { Authorization: auth, "Content-Type": "application/json" }, body: JSON.stringify({ type: "regular", recipients: { list_id: config.audience_id }, settings: { subject_line: subject, title: `${subject} - ${new Date().toISOString()}`, from_name, reply_to, }, }), }); const campaign = await createRes.json(); if (!createRes.ok) { return new Response(JSON.stringify({ success: false, error: `Create failed: ${campaign.detail || campaign.title || "Unknown"}` }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" }, }); } // 2. Set the content const contentRes = await fetch(`${baseUrl}/campaigns/${campaign.id}/content`, { method: "PUT", headers: { Authorization: auth, "Content-Type": "application/json" }, body: JSON.stringify({ html }), }); if (!contentRes.ok) { const errBody = await contentRes.json().catch(() => ({})); return new Response(JSON.stringify({ success: false, error: `Content failed: ${errBody.detail || "Unknown"}`, campaign_id: campaign.id }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" }, }); } // 3. Optionally send immediately if (send_now) { const sendRes = await fetch(`${baseUrl}/campaigns/${campaign.id}/actions/send`, { method: "POST", headers: { Authorization: auth }, }); if (!sendRes.ok) { const errBody = await sendRes.json().catch(() => ({})); return new Response(JSON.stringify({ success: false, error: `Send failed: ${errBody.detail || errBody.title || "Unknown"}. Campaign saved as draft in Mailchimp.`, campaign_id: campaign.id, web_id: campaign.web_id, }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }); } } return new Response(JSON.stringify({ success: true, campaign_id: campaign.id, web_id: campaign.web_id, sent: !!send_now, recipient_count: campaign.recipients?.recipient_count ?? null, }), { headers: { ...corsHeaders, "Content-Type": "application/json" } }); } catch (e: any) { return new Response(JSON.stringify({ success: false, error: e.message || String(e) }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" }, }); } });