import { type NextRequest, NextResponse } from "next/server";
import nodemailer from "nodemailer";
import SMTPTransport from "nodemailer/lib/smtp-transport";
import Mail from "nodemailer/lib/mailer";
const BRAND = {
siteUrl: "https://dk0.dev",
email: "contact@dk0.dev",
bg: "#FDFCF8",
sand: "#F3F1E7",
border: "#E7E5E4",
text: "#292524",
muted: "#78716C",
mint: "#A7F3D0",
red: "#EF4444",
};
function escapeHtml(input: string): string {
return input
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
function nl2br(input: string): string {
return input.replace(/\r\n|\r|\n/g, "
");
}
function baseEmail(opts: { title: string; subtitle: string; bodyHtml: string }) {
const sentAt = new Date().toLocaleString("de-DE", {
year: "numeric",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
});
return `
${escapeHtml(opts.title)}
${escapeHtml(opts.title)}
${escapeHtml(opts.subtitle)} • ${sentAt}
${opts.bodyHtml}
`.trim();
}
const emailTemplates = {
welcome: {
subject: "Vielen Dank für deine Nachricht! 👋",
template: (name: string, originalMessage: string) => {
const safeName = escapeHtml(name);
const safeMsg = nl2br(escapeHtml(originalMessage));
return baseEmail({
title: `Danke, ${safeName}!`,
subtitle: "Nachricht erhalten",
bodyHtml: `
Hey ${safeName},
danke für deine Nachricht — ich habe sie erhalten und melde mich so schnell wie möglich bei dir zurück.
`.trim(),
});
},
},
project: {
subject: "Projekt-Anfrage erhalten! 🚀",
template: (name: string, originalMessage: string) => {
const safeName = escapeHtml(name);
const safeMsg = nl2br(escapeHtml(originalMessage));
return baseEmail({
title: `Projekt-Anfrage: danke, ${safeName}!`,
subtitle: "Ich melde mich zeitnah",
bodyHtml: `
Hey ${safeName},
mega — danke für die Projekt-Anfrage. Ich schaue mir deine Nachricht an und komme mit Rückfragen/Ideen auf dich zu.
`.trim(),
});
},
},
quick: {
subject: "Danke für deine Nachricht! ⚡",
template: (name: string, originalMessage: string) => {
const safeName = escapeHtml(name);
const safeMsg = nl2br(escapeHtml(originalMessage));
return baseEmail({
title: `Danke, ${safeName}!`,
subtitle: "Kurze Bestätigung",
bodyHtml: `
Hey ${safeName},
kurze Bestätigung: deine Nachricht ist angekommen. Ich melde mich bald zurück.
`.trim(),
});
},
},
reply: {
subject: "Antwort auf deine Nachricht 📧",
template: (name: string, originalMessage: string) => {
const safeName = escapeHtml(name);
const safeMsg = nl2br(escapeHtml(originalMessage));
return baseEmail({
title: `Antwort für ${safeName}`,
subtitle: "Neue Nachricht",
bodyHtml: `
Hey ${safeName},
hier ist meine Antwort:
`.trim(),
});
},
},
};
export async function POST(request: NextRequest) {
try {
const body = (await request.json()) as {
to: string;
name: string;
template: 'welcome' | 'project' | 'quick' | 'reply';
originalMessage: string;
};
const { to, name, template, originalMessage } = body;
console.log('📧 Email response request:', { to, name, template, messageLength: originalMessage.length });
// Validate input
if (!to || !name || !template || !originalMessage) {
console.error('❌ Validation failed: Missing required fields');
return NextResponse.json(
{ error: "Alle Felder sind erforderlich" },
{ status: 400 },
);
}
// Validate email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(to)) {
console.error('❌ Validation failed: Invalid email format');
return NextResponse.json(
{ error: "Ungültige E-Mail-Adresse" },
{ status: 400 },
);
}
// Check if template exists
if (!emailTemplates[template]) {
console.error('❌ Validation failed: Invalid template');
return NextResponse.json(
{ error: "Ungültiges Template" },
{ status: 400 },
);
}
const user = process.env.MY_EMAIL ?? "";
const pass = process.env.MY_PASSWORD ?? "";
if (!user || !pass) {
console.error("❌ Missing email/password environment variables");
return NextResponse.json(
{ error: "E-Mail-Server nicht konfiguriert" },
{ status: 500 },
);
}
const transportOptions: SMTPTransport.Options = {
host: "mail.dk0.dev",
port: 587,
secure: false,
requireTLS: true,
auth: {
type: "login",
user,
pass,
},
connectionTimeout: 30000,
greetingTimeout: 30000,
socketTimeout: 60000,
tls: {
rejectUnauthorized: false,
ciphers: 'SSLv3'
}
};
const transport = nodemailer.createTransport(transportOptions);
// Verify transport configuration
try {
await transport.verify();
console.log('✅ SMTP connection verified successfully');
} catch (verifyError) {
console.error('❌ SMTP verification failed:', verifyError);
return NextResponse.json(
{ error: "E-Mail-Server-Verbindung fehlgeschlagen" },
{ status: 500 },
);
}
const selectedTemplate = emailTemplates[template];
const mailOptions: Mail.Options = {
from: `"Dennis Konkol" <${user}>`,
to: to,
replyTo: "contact@dk0.dev",
subject: selectedTemplate.subject,
html: selectedTemplate.template(name, originalMessage),
text: `
Hallo ${name}!
Vielen Dank für deine Nachricht:
${originalMessage}
Ich werde mich so schnell wie möglich bei dir melden.
Beste Grüße,
Dennis Konkol
Software Engineer & Student
https://dki.one
contact@dk0.dev
`,
};
console.log('📤 Sending templated email...');
const sendMailPromise = () =>
new Promise((resolve, reject) => {
transport.sendMail(mailOptions, function (err, info) {
if (!err) {
console.log('✅ Templated email sent successfully:', info.response);
resolve(info.response);
} else {
console.error("❌ Error sending templated email:", err);
reject(err.message);
}
});
});
const result = await sendMailPromise();
console.log('🎉 Templated email process completed successfully');
return NextResponse.json({
message: "Template-E-Mail erfolgreich gesendet",
template: template,
messageId: result
});
} catch (err) {
console.error("❌ Unexpected error in templated email API:", err);
return NextResponse.json({
error: "Fehler beim Senden der Template-E-Mail",
details: err instanceof Error ? err.message : 'Unbekannter Fehler'
}, { status: 500 });
}
}