- Add test/production toggle for n8n webhook URLs in IntegrasiTab - Update create-meet-link function to use database test_mode setting - Add send-email-v2 edge function for Mailketing API integration - Update daily-reminders and send-consultation-reminder to use send-email-v2 - Remove deprecated branding field from BrandingTab - Update domain references from hub.dwindi.com to with.dwindi.com - Add environment variables for Coolify deployment - Add comprehensive edge function test script - Update payment flow redirect to order detail page 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
99 lines
3.1 KiB
TypeScript
99 lines
3.1 KiB
TypeScript
import { serve } from "https://deno.land/std@0.190.0/http/server.ts";
|
|
|
|
const corsHeaders = {
|
|
"Access-Control-Allow-Origin": "*",
|
|
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
|
|
};
|
|
|
|
interface EmailRequest {
|
|
to: string;
|
|
api_token: string;
|
|
from_name: string;
|
|
from_email: string;
|
|
subject: string;
|
|
html_body: string;
|
|
}
|
|
|
|
// Send via Mailketing API
|
|
async function sendViaMailketing(request: EmailRequest): Promise<{ success: boolean; message: string }> {
|
|
const { to, api_token, from_name, from_email, subject, html_body } = request;
|
|
|
|
const formData = new FormData();
|
|
formData.append('to', to);
|
|
formData.append('from_name', from_name);
|
|
formData.append('from_email', from_email);
|
|
formData.append('subject', subject);
|
|
formData.append('html_body', html_body);
|
|
|
|
console.log(`Sending email via Mailketing to ${to}`);
|
|
|
|
const response = await fetch('https://api.mailketing.co/v1/send', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': `Bearer ${api_token}`,
|
|
},
|
|
body: formData,
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const errorText = await response.text();
|
|
console.error('Mailketing API error:', response.status, errorText);
|
|
throw new Error(`Mailketing API error: ${response.status} ${errorText}`);
|
|
}
|
|
|
|
const result = await response.json();
|
|
console.log('Mailketing API response:', result);
|
|
|
|
return {
|
|
success: true,
|
|
message: result.message || 'Email sent successfully via Mailketing'
|
|
};
|
|
}
|
|
|
|
serve(async (req: Request): Promise<Response> => {
|
|
if (req.method === "OPTIONS") {
|
|
return new Response(null, { headers: corsHeaders });
|
|
}
|
|
|
|
try {
|
|
const body: EmailRequest = await req.json();
|
|
|
|
// Validate required fields
|
|
if (!body.to || !body.api_token || !body.from_name || !body.from_email || !body.subject || !body.html_body) {
|
|
return new Response(
|
|
JSON.stringify({ success: false, message: "Missing required fields: to, api_token, from_name, from_email, subject, html_body" }),
|
|
{ status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
);
|
|
}
|
|
|
|
// Basic email validation
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailRegex.test(body.to) || !emailRegex.test(body.from_email)) {
|
|
return new Response(
|
|
JSON.stringify({ success: false, message: "Invalid email format" }),
|
|
{ status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
);
|
|
}
|
|
|
|
console.log(`Attempting to send email to: ${body.to}`);
|
|
console.log(`From: ${body.from_name} <${body.from_email}>`);
|
|
console.log(`Subject: ${body.subject}`);
|
|
|
|
const result = await sendViaMailketing(body);
|
|
|
|
return new Response(
|
|
JSON.stringify(result),
|
|
{ status: 200, headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
);
|
|
|
|
} catch (error: any) {
|
|
console.error("Error sending email:", error);
|
|
return new Response(
|
|
JSON.stringify({
|
|
success: false,
|
|
message: error.message || "Failed to send email"
|
|
}),
|
|
{ status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
);
|
|
}
|
|
}); |