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 TestEmailRequest {
to: string;
smtp_host: string;
smtp_port: number;
smtp_username: string;
smtp_password: string;
smtp_from_name: string;
smtp_from_email: string;
smtp_use_tls: boolean;
}
async function sendEmail(config: TestEmailRequest): Promise<{ success: boolean; message: string }> {
const { to, smtp_host, smtp_port, smtp_username, smtp_password, smtp_from_name, smtp_from_email, smtp_use_tls } = config;
// Build email content
const boundary = "----=_Part_" + Math.random().toString(36).substr(2, 9);
const emailContent = [
`From: "${smtp_from_name}" <${smtp_from_email}>`,
`To: ${to}`,
`Subject: =?UTF-8?B?${btoa("Email Uji Coba - Konfigurasi SMTP Berhasil")}?=`,
`MIME-Version: 1.0`,
`Content-Type: multipart/alternative; boundary="${boundary}"`,
``,
`--${boundary}`,
`Content-Type: text/plain; charset=UTF-8`,
``,
`Ini adalah email uji coba dari sistem notifikasi Anda.`,
`Jika Anda menerima email ini, konfigurasi SMTP Anda sudah benar.`,
``,
`--${boundary}`,
`Content-Type: text/html; charset=UTF-8`,
``,
`
Email Uji Coba Berhasil! ✓
Ini adalah email uji coba dari sistem notifikasi Anda.
Jika Anda menerima email ini, konfigurasi SMTP Anda sudah benar.
Dikirim dari: ${smtp_from_email}
Server: ${smtp_host}:${smtp_port}
`,
`--${boundary}--`,
].join("\r\n");
// Connect to SMTP server
const conn = smtp_use_tls
? await Deno.connectTls({ hostname: smtp_host, port: smtp_port })
: await Deno.connect({ hostname: smtp_host, port: smtp_port });
const encoder = new TextEncoder();
const decoder = new TextDecoder();
async function readResponse(): Promise {
const buffer = new Uint8Array(1024);
const n = await conn.read(buffer);
if (n === null) return "";
return decoder.decode(buffer.subarray(0, n));
}
async function sendCommand(cmd: string): Promise {
await conn.write(encoder.encode(cmd + "\r\n"));
return await readResponse();
}
try {
// Read greeting
await readResponse();
// EHLO
let response = await sendCommand(`EHLO localhost`);
console.log("EHLO response:", response);
// For non-TLS connection on port 587, we may need STARTTLS
if (!smtp_use_tls && response.includes("STARTTLS")) {
await sendCommand("STARTTLS");
// Upgrade to TLS - not supported in basic Deno.connect
// For now, recommend using TLS directly
}
// AUTH LOGIN
response = await sendCommand("AUTH LOGIN");
console.log("AUTH response:", response);
// Username (base64)
response = await sendCommand(btoa(smtp_username));
console.log("Username response:", response);
// Password (base64)
response = await sendCommand(btoa(smtp_password));
console.log("Password response:", response);
if (!response.includes("235") && !response.includes("Authentication successful")) {
throw new Error("Authentication failed: " + response);
}
// MAIL FROM
response = await sendCommand(`MAIL FROM:<${smtp_from_email}>`);
if (!response.includes("250")) {
throw new Error("MAIL FROM failed: " + response);
}
// RCPT TO
response = await sendCommand(`RCPT TO:<${to}>`);
if (!response.includes("250")) {
throw new Error("RCPT TO failed: " + response);
}
// DATA
response = await sendCommand("DATA");
if (!response.includes("354")) {
throw new Error("DATA failed: " + response);
}
// Send email content
await conn.write(encoder.encode(emailContent + "\r\n.\r\n"));
response = await readResponse();
if (!response.includes("250")) {
throw new Error("Email send failed: " + response);
}
// QUIT
await sendCommand("QUIT");
conn.close();
return { success: true, message: "Email uji coba berhasil dikirim ke " + to };
} catch (error) {
conn.close();
throw error;
}
}
serve(async (req: Request): Promise => {
// Handle CORS preflight
if (req.method === "OPTIONS") {
return new Response(null, { headers: corsHeaders });
}
try {
const body: TestEmailRequest = await req.json();
// Validate required fields
if (!body.to || !body.smtp_host || !body.smtp_username || !body.smtp_password) {
return new Response(
JSON.stringify({ success: false, message: "Missing required fields" }),
{ status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
);
}
console.log("Attempting to send test email to:", body.to);
console.log("SMTP config:", { host: body.smtp_host, port: body.smtp_port, user: body.smtp_username });
const result = await sendEmail(body);
return new Response(
JSON.stringify(result),
{ status: 200, headers: { ...corsHeaders, "Content-Type": "application/json" } }
);
} catch (error: any) {
console.error("Error sending test email:", error);
return new Response(
JSON.stringify({ success: false, message: error.message || "Failed to send email" }),
{ status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
);
}
});