From 67ce78ae3b39d5d105c4ceffde29e91f83249b1c Mon Sep 17 00:00:00 2001 From: sebastjanartic <45803536-sebastjanartic@users.noreply.replit.com> Date: Fri, 6 Mar 2026 14:11:34 +0000 Subject: [PATCH] Add email notification system for contact form submissions Implement a new mailer module to send email notifications upon contact form submission, integrating with SMTP settings and formatting the email content. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 23852c00-4779-460a-9e0c-d09fee4b6c92 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 3a6f3b4b-2588-4a9e-9f58-fbe9c763e594 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/23852c00-4779-460a-9e0c-d09fee4b6c92/koutl3W Replit-Helium-Checkpoint-Created: true --- server/contact-messages.json | 12 +----- server/mailer.ts | 75 ++++++++++++++++++++++++++++++++++++ server/routes.ts | 10 +++-- 3 files changed, 83 insertions(+), 14 deletions(-) create mode 100644 server/mailer.ts diff --git a/server/contact-messages.json b/server/contact-messages.json index b55dd4d..fe51488 100644 --- a/server/contact-messages.json +++ b/server/contact-messages.json @@ -1,11 +1 @@ -[ - { - "id": 1772805974560, - "name": "sebastjan", - "email": "sebastjan.artic@folx.tv", - "subject": "Allgemeine Anfrage", - "message": "hallo ", - "createdAt": "2026-03-06T14:06:14.560Z", - "read": false - } -] \ No newline at end of file +[] diff --git a/server/mailer.ts b/server/mailer.ts new file mode 100644 index 0000000..ddd7f39 --- /dev/null +++ b/server/mailer.ts @@ -0,0 +1,75 @@ +import nodemailer from "nodemailer"; + +const transporter = nodemailer.createTransport({ + host: process.env.SMTP_HOST || "mail.folx.tv", + port: parseInt(process.env.SMTP_PORT || "465"), + secure: true, + auth: { + user: process.env.SMTP_USER || "web@folx.tv", + pass: process.env.SMTP_PASSWORD || "", + }, +}); + +interface ContactMessage { + name: string; + email: string; + subject: string; + message: string; +} + +export async function sendContactEmail(data: ContactMessage): Promise { + const subjectLine = data.subject + ? `[FOLX TV Kontakt] ${data.subject} – von ${data.name}` + : `[FOLX TV Kontakt] Nachricht von ${data.name}`; + + const htmlBody = ` +
+
+

Neue Kontaktanfrage

+
+
+ + + + + + + + + + + + + +
Name:${escapeHtml(data.name)}
E-Mail:${escapeHtml(data.email)}
Betreff:${escapeHtml(data.subject || "Keine Angabe")}
+
+
${escapeHtml(data.message)}
+
+

Gesendet über das Kontaktformular auf folx.tv

+
+ `; + + try { + await transporter.sendMail({ + from: `"FOLX TV Website" <${process.env.SMTP_FROM || "web@folx.tv"}>`, + to: process.env.CONTACT_TO || "office@folx.tv", + replyTo: data.email, + subject: subjectLine, + html: htmlBody, + text: `Neue Kontaktanfrage\n\nName: ${data.name}\nE-Mail: ${data.email}\nBetreff: ${data.subject || "Keine Angabe"}\n\nNachricht:\n${data.message}`, + }); + console.log(`[mailer] Contact email sent successfully (from: ${data.email})`); + return true; + } catch (err: any) { + console.error(`[mailer] Failed to send email:`, err.message); + return false; + } +} + +function escapeHtml(str: string): string { + return str + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """); +} diff --git a/server/routes.ts b/server/routes.ts index 8ffdfc5..dac91ea 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -8,6 +8,7 @@ import { analyzeAllArticleImages, getCachedFocalPoints } from "./focal-point"; import { optimizeImage } from "./image-optimizer"; import { getAuthUrl, exchangeCodeForTokens, isConnected, fetchGalleryFromDropbox, getValidAccessToken, migrateGalleryToCloudinary } from "./dropbox"; import { listCloudinaryGalleryDetailed, deleteFromCloudinary } from "./cloudinary"; +import { sendContactEmail } from "./mailer"; import multer from "multer"; import path from "path"; import fs from "fs"; @@ -473,7 +474,7 @@ export async function registerRoutes( if (fs.existsSync(contactPath)) { messages = JSON.parse(fs.readFileSync(contactPath, "utf-8")); } - messages.push({ + const entry = { id: Date.now(), name, email, @@ -481,9 +482,12 @@ export async function registerRoutes( message, createdAt: new Date().toISOString(), read: false, - }); + }; + messages.push(entry); fs.writeFileSync(contactPath, JSON.stringify(messages, null, 2)); - console.log(`[contact] New message from ${name} <${email}>: ${subject || "No subject"}`); + + const emailSent = await sendContactEmail({ name, email, subject: subject || "", message }); + console.log(`[contact] New message from ${name} <${email}>: ${subject || "No subject"} (email ${emailSent ? "sent" : "failed"})`); res.json({ ok: true }); } catch (err: any) { res.status(500).json({ message: err.message });