feat: add auto-reply email to contact form submitter

- Add sendAutoReply() to email service with branded HTML template
- Auto-reply sends a professional thank-you with 1-business-day SLA
- Includes urgent contact info (phone + email) in a styled callout
- Wired into POST /api/contact alongside the internal notification
- Both emails are fire-and-forget (don't block API response)
This commit is contained in:
Z User 2026-05-05 22:25:44 +00:00
parent b9dbd59e7d
commit 78961331d1
2 changed files with 94 additions and 3 deletions

View File

@ -1,7 +1,7 @@
import express from 'express';
import { dbRun, dbAll, dbGet } from '../db/database.js';
import { generateId, ApiResponse, asyncHandler } from '../utils/helpers.js';
import { sendContactEmail } from '../services/email.js';
import { sendContactEmail, sendAutoReply } from '../services/email.js';
const router = express.Router();
@ -65,7 +65,7 @@ router.post('/', asyncHandler(async (req, res) => {
console.log(`New contact submission: ${submissionId} from ${email}`);
// Send email notification (fire-and-forget — don't block the response)
// Send email notification to you (fire-and-forget)
sendContactEmail({ name: name.trim(), email: email.trim().toLowerCase(), company: company?.trim(), message: message.trim() })
.then((result) => {
if (result.success) {
@ -78,6 +78,19 @@ router.post('/', asyncHandler(async (req, res) => {
console.error(`[Contact] Email error for submission ${submissionId}:`, err.message);
});
// Send auto-reply to the submitter (fire-and-forget)
sendAutoReply({ name: name.trim(), email: email.trim().toLowerCase() })
.then((result) => {
if (result.success) {
console.log(`[Contact] Auto-reply sent for submission ${submissionId}`);
} else {
console.warn(`[Contact] Auto-reply failed for submission ${submissionId}: ${result.error}`);
}
})
.catch((err) => {
console.error(`[Contact] Auto-reply error for submission ${submissionId}:`, err.message);
});
res.status(201).json(ApiResponse(true, {
id: submissionId,
message: 'Thank you for your message! We\'ll get back to you soon.'

View File

@ -132,6 +132,84 @@ export const sendContactEmail = async ({ name, email, company, message }) => {
}
};
/**
* Send an auto-reply thank-you email to the person who submitted the form.
*
* @param {Object} params
* @param {string} params.name - Submitter's name
* @param {string} params.email - Submitter's email
* @returns {Promise<{success: boolean, messageId?: string, error?: string}>}
*/
export const sendAutoReply = async ({ name, email }) => {
try {
const transporter = createTransport();
const from = getFromAddress();
const info = await transporter.sendMail({
from: `"Moxiegen" <${from}>`,
to: email,
subject: 'Thank you for contacting Moxiegen',
text: [
`Dear ${name},`,
'',
'Thank you for reaching out to Moxiegen. We have received your inquiry',
'and our team is currently reviewing your message.',
'',
'We understand the importance of your request and will make every effort',
'to respond to you as promptly as possible. In most cases, you can expect',
'to hear back from us within one business day.',
'',
'If your matter is urgent, please feel free to call us directly at',
'+1 (855) 246-6943 or email info@moxiegen.com.',
'',
'Thank you for your interest in Moxiegen. We look forward to speaking with you.',
'',
'Best regards,',
'The Moxiegen Team',
'https://moxiegen.com',
].join('\n'),
html: `
<div style="font-family: Arial, Helvetica, sans-serif; max-width: 600px; margin: 0 auto; padding: 0;">
<div style="background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); padding: 40px 40px 30px 40px; border-radius: 12px 12px 0 0;">
<h1 style="color: #00f0c8; font-size: 28px; margin: 0 0 4px 0; font-weight: 600;">Moxiegen</h1>
<p style="color: #94a3b8; font-size: 14px; margin: 0;">Algorithmic Enhancement for Enterprise AI</p>
</div>
<div style="background: #ffffff; padding: 40px; border-radius: 0 0 12px 12px; color: #334155;">
<p style="font-size: 18px; margin: 0 0 20px 0;">Dear ${escapeHtml(name)},</p>
<p style="font-size: 16px; line-height: 1.6; margin: 0 0 16px 0;">
Thank you for reaching out to <strong>Moxiegen</strong>. We have received your inquiry and our team is currently reviewing your message.
</p>
<p style="font-size: 16px; line-height: 1.6; margin: 0 0 16px 0;">
We understand the importance of your request and will make every effort to respond to you as promptly as possible. In most cases, you can expect to hear back from us within <strong>one business day</strong>.
</p>
<div style="background: #f0fdf4; border-left: 4px solid #00f0c8; padding: 16px 20px; border-radius: 0 8px 8px 0; margin: 24px 0;">
<p style="font-size: 15px; color: #334155; margin: 0 0 6px 0;"><strong>Need a faster response?</strong></p>
<p style="font-size: 15px; color: #334155; margin: 0;">
Call us at <a href="tel:+18552466943" style="color: #00f0c8; text-decoration: none;">+1 (855) 246-6943</a> or email
<a href="mailto:info@moxiegen.com" style="color: #00f0c8; text-decoration: none;">info@moxiegen.com</a>
</p>
</div>
<p style="font-size: 16px; line-height: 1.6; margin: 0 0 8px 0;">
Thank you for your interest in Moxiegen. We look forward to speaking with you.
</p>
<p style="font-size: 16px; margin: 32px 0 0 0; color: #334155;">Best regards,</p>
<p style="font-size: 16px; margin: 4px 0 0 0; color: #334155;"><strong>The Moxiegen Team</strong></p>
</div>
<div style="text-align: center; padding: 24px 0;">
<a href="https://moxiegen.com" style="color: #00f0c8; text-decoration: none; font-size: 14px;">moxiegen.com</a>
</div>
</div>
`,
});
console.log(`[Email] Auto-reply sent to ${email} (messageId: ${info.messageId})`);
return { success: true, messageId: info.messageId };
} catch (err) {
console.error('[Email] Failed to send auto-reply:', err.message);
return { success: false, error: err.message };
}
};
/**
* Minimal HTML entity escaping for user-submitted content.
* @param {string} str
@ -146,4 +224,4 @@ function escapeHtml(str) {
.replace(/'/g, '&#039;');
}
export default { verifyTransport, sendContactEmail };
export default { verifyTransport, sendContactEmail, sendAutoReply };