Merged changes from o10aupva/main
Replit-Task-Id: 96838fc6-bf00-4a8d-ae18-84ba08feec56
This commit is contained in:
73
artifacts/api-server/src/routes/contact.ts
Normal file
73
artifacts/api-server/src/routes/contact.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { Router, type IRouter } from "express";
|
||||
import { BrevoClient } from "@getbrevo/brevo";
|
||||
import { SendContactMessageBody } from "@workspace/api-zod";
|
||||
|
||||
const router: IRouter = Router();
|
||||
|
||||
function getBrevoClient() {
|
||||
const apiKey = process.env.BREVO_API_KEY;
|
||||
if (!apiKey) throw new Error("BREVO_API_KEY is not set");
|
||||
return new BrevoClient({ apiKey });
|
||||
}
|
||||
|
||||
router.post("/contact", async (req, res) => {
|
||||
const parsed = SendContactMessageBody.safeParse(req.body);
|
||||
|
||||
if (!parsed.success) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
message: "Ungültige Eingabe. Bitte überprüfen Sie Ihre Angaben.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const { name, email, subject, message } = parsed.data;
|
||||
|
||||
try {
|
||||
const brevo = getBrevoClient();
|
||||
|
||||
await brevo.transactionalEmails.sendTransacEmail({
|
||||
sender: { name: "Kontaktformular Portfolio", email: "jh@unixweb.de" },
|
||||
to: [{ email: "jh@unixweb.de", name: "Joachim Hummel" }],
|
||||
replyTo: { email, name },
|
||||
subject: subject ? `[Portfolio] ${subject}` : `[Portfolio] Neue Anfrage von ${name}`,
|
||||
textContent: [
|
||||
`Name: ${name}`,
|
||||
`E-Mail: ${email}`,
|
||||
subject ? `Betreff: ${subject}` : "",
|
||||
"",
|
||||
message,
|
||||
]
|
||||
.filter((l) => l !== undefined)
|
||||
.join("\n"),
|
||||
htmlContent: `
|
||||
<p><strong>Name:</strong> ${escapeHtml(name)}</p>
|
||||
<p><strong>E-Mail:</strong> ${escapeHtml(email)}</p>
|
||||
${subject ? `<p><strong>Betreff:</strong> ${escapeHtml(subject)}</p>` : ""}
|
||||
<hr />
|
||||
<p style="white-space:pre-wrap">${escapeHtml(message)}</p>
|
||||
`,
|
||||
});
|
||||
|
||||
req.log.info({ to: "jh@unixweb.de", from: email }, "Contact message sent via Brevo");
|
||||
res.json({ success: true, message: "Ihre Nachricht wurde erfolgreich gesendet." });
|
||||
} catch (err) {
|
||||
req.log.error({ err }, "Failed to send contact email via Brevo");
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message:
|
||||
"Die Nachricht konnte nicht gesendet werden. Bitte versuchen Sie es später erneut.",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function escapeHtml(text: string): string {
|
||||
return text
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
export default router;
|
||||
@@ -1,8 +1,10 @@
|
||||
import { Router, type IRouter } from "express";
|
||||
import healthRouter from "./health";
|
||||
import contactRouter from "./contact";
|
||||
|
||||
const router: IRouter = Router();
|
||||
|
||||
router.use(healthRouter);
|
||||
router.use(contactRouter);
|
||||
|
||||
export default router;
|
||||
|
||||
Reference in New Issue
Block a user