import { NextResponse } from "next/server"; import * as nodemailer from "nodemailer"; import directus, { ensureAuthenticated } from "@/lib/directus"; import { createItem } from "@directus/sdk"; import { getServerAppServices } from "@/lib/services/create-services.server"; export async function POST(req: Request) { const services = getServerAppServices(); const logger = services.logger.child({ action: "contact_submission" }); try { const { name, email, company, message, website } = await req.json(); // Honeypot check if (website) { logger.info("Spam detected (honeypot)"); return NextResponse.json({ message: "Ok" }); } // Validation if (!name || name.length < 2 || name.length > 100) { return NextResponse.json({ error: "Ungültiger Name" }, { status: 400 }); } if (!email || !/^\S+@\S+\.\S+$/.test(email)) { return NextResponse.json({ error: "Ungültige E-Mail" }, { status: 400 }); } if (!message || message.length < 20) { return NextResponse.json({ error: "message_too_short" }, { status: 400 }); } if (message.length > 4000) { return NextResponse.json({ error: "message_too_long" }, { status: 400 }); } // 1. Directus save let directusSaved = false; try { await ensureAuthenticated(); await directus.request( createItem("contact_submissions", { name, email, company: company || "Nicht angegeben", message, }), ); logger.info("Contact submission saved to Directus"); directusSaved = true; } catch (directusError) { logger.error("Failed to save to Directus", { error: directusError }); services.errors.captureException(directusError, { phase: "directus_save", }); // We still try to send the email even if Directus fails } // 2. Email sending try { const transporter = nodemailer.createTransport({ host: process.env.SMTP_HOST, port: parseInt(process.env.SMTP_PORT || "587"), secure: process.env.SMTP_SECURE === "true", auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS, }, }); await transporter.sendMail({ from: process.env.SMTP_FROM, to: process.env.CONTACT_RECIPIENT || "info@mb-grid-solutions.com", replyTo: email, subject: `Kontaktanfrage von ${name}`, text: ` Name: ${name} Firma: ${company || "Nicht angegeben"} E-Mail: ${email} Zeitpunkt: ${new Date().toISOString()} Nachricht: ${message} `, }); logger.info("Email sent successfully"); // Notify success for important leads await services.notifications.notify({ title: "📩 Neue Kontaktanfrage", message: `Anfrage von ${name} (${email}) erhalten.\nFirma: ${company || "Nicht angegeben"}`, priority: 5, }); } catch (smtpError) { logger.error("SMTP Error", { error: smtpError }); services.errors.captureException(smtpError, { phase: "smtp_send" }); // If Directus failed AND SMTP failed, then we really have a problem if (!directusSaved) { return NextResponse.json( { error: "Systemfehler (Speicherung und Versand fehlgeschlagen)" }, { status: 500 }, ); } // If Directus was successful, we tell the user "Ok" but we know internally it was a partial failure await services.notifications.notify({ title: "🚨 SMTP Fehler (Kontaktformular)", message: `Anfrage von ${name} (${email}) in Directus gespeichert, aber E-Mail-Versand fehlgeschlagen: ${smtpError instanceof Error ? smtpError.message : String(smtpError)}`, priority: 8, }); } return NextResponse.json({ message: "Ok" }); } catch (error) { logger.error("Global API Error", { error }); services.errors.captureException(error, { phase: "api_global" }); return NextResponse.json( { error: "Interner Serverfehler" }, { status: 500 }, ); } }