feat: send RSVP confirmation emails using environment-based SMTP config; split EMAIL_FROM into EMAIL_FROM_NAME and EMAIL_FROM_ADDRESS

This commit is contained in:
Ryderjj89
2025-05-05 08:26:27 -04:00
parent 1d8be55ed7
commit c2b4217601
4 changed files with 96 additions and 1 deletions

63
backend/src/email.ts Normal file
View File

@@ -0,0 +1,63 @@
import nodemailer from 'nodemailer';
const transporter = nodemailer.createTransport({
host: process.env.EMAIL_HOST,
port: Number(process.env.EMAIL_PORT),
secure: process.env.EMAIL_SECURE === 'true', // true for 465, false for other ports
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
},
});
export interface RSVPEmailData {
eventTitle: string;
name: string;
attending: string;
bringingGuests: string;
guestCount: number;
guestNames: string[];
itemsBringing: string[];
otherItems: string;
to: string;
}
export async function sendRSVPEmail(data: RSVPEmailData) {
const {
eventTitle,
name,
attending,
bringingGuests,
guestCount,
guestNames,
itemsBringing,
otherItems,
to,
} = data;
const subject = `RSVP Confirmation for ${eventTitle}`;
const guestList = guestNames.length ? guestNames.join(', ') : 'None';
const itemsList = itemsBringing.length ? itemsBringing.join(', ') : 'None';
const otherItemsList = otherItems ? otherItems : 'None';
const html = `
<h2>RSVP Confirmation</h2>
<p><strong>Event:</strong> ${eventTitle}</p>
<p><strong>Name:</strong> ${name}</p>
<p><strong>Attending:</strong> ${attending}</p>
<p><strong>Bringing Guests:</strong> ${bringingGuests} (${guestCount})</p>
<p><strong>Guest Names:</strong> ${guestList}</p>
<p><strong>Items Bringing (from needed list):</strong> ${itemsList}</p>
<p><strong>Other Items:</strong> ${otherItemsList}</p>
`;
await transporter.sendMail({
from: {
name: process.env.EMAIL_FROM_NAME || '',
address: process.env.EMAIL_FROM_ADDRESS || process.env.EMAIL_USER || '',
},
to,
subject,
html,
});
}

View File

@@ -6,6 +6,7 @@ import dotenv from 'dotenv';
import path from 'path';
import multer from 'multer';
import fs from 'fs';
import { sendRSVPEmail } from './email';
dotenv.config();
@@ -294,6 +295,29 @@ app.post('/api/events/:slug/rsvp', async (req: Request, res: Response) => {
[eventId, name, attending, bringing_guests, guest_count, JSON.stringify(parsedGuestNames), JSON.stringify(parsedItemsBringing), other_items || '']
);
// Fetch event title for the email
const eventInfo = await db.get('SELECT title FROM events WHERE id = ?', [eventId]);
const eventTitle = eventInfo ? eventInfo.title : slug;
// Send RSVP confirmation email (if email provided)
if (req.body.email) {
try {
await sendRSVPEmail({
eventTitle,
name,
attending,
bringingGuests: bringing_guests,
guestCount: guest_count,
guestNames: parsedGuestNames,
itemsBringing: parsedItemsBringing,
otherItems: other_items || '',
to: req.body.email,
});
} catch (emailErr) {
console.error('Error sending RSVP email:', emailErr);
}
}
// Return the complete RSVP data including the parsed arrays
res.status(201).json({
id: result.lastID,