Add BCC functionality to email service

- Added optional bcc parameter to EmailOptions interface
- Updated sendEmail method to support BCC recipients
- Modified notifySubscribersOfNewEntry to use single BCC email instead of individual emails
- Improved logging to show BCC recipient count
- More efficient email delivery for multiple subscribers
This commit is contained in:
TheMaddax 2025-09-10 18:44:44 -06:00
parent 9023d35090
commit cd835cf31b

View file

@ -3,6 +3,7 @@ import nodemailer from 'nodemailer';
interface EmailOptions { interface EmailOptions {
to: string; to: string;
bcc?: string[];
subject: string; subject: string;
html: string; html: string;
} }
@ -45,7 +46,7 @@ export class EmailService {
async sendEmail(options: EmailOptions): Promise<boolean> { async sendEmail(options: EmailOptions): Promise<boolean> {
try { try {
const mailOptions = { const mailOptions: any = {
from: { from: {
name: 'Court Docket System', name: 'Court Docket System',
address: process.env['GOOGLE_EMAIL'] || 'system@deafgain.org', address: process.env['GOOGLE_EMAIL'] || 'system@deafgain.org',
@ -55,10 +56,16 @@ export class EmailService {
html: options.html, html: options.html,
}; };
// Add BCC if provided
if (options.bcc && options.bcc.length > 0) {
mailOptions.bcc = options.bcc;
}
const result = await this.transporter.sendMail(mailOptions); const result = await this.transporter.sendMail(mailOptions);
logger.info('Email sent successfully:', { logger.info('Email sent successfully:', {
to: options.to, to: options.to,
bcc: options.bcc ? `${options.bcc.length} recipients` : 'none',
subject: options.subject, subject: options.subject,
messageId: result.messageId, messageId: result.messageId,
}); });
@ -85,21 +92,21 @@ export class EmailService {
const subject = `New Court Filing: ${entryTitle}`; const subject = `New Court Filing: ${entryTitle}`;
const html = this.generateNotificationEmail(entryTitle, entryDate, entrySummary); const html = this.generateNotificationEmail(entryTitle, entryDate, entrySummary);
const subscriberEmails = subscribers.map((subscriber: any) => subscriber.email);
// Send emails to all subscribers // Send single email with all subscribers as BCC
const emailPromises = subscribers.map((subscriber: any) => const success = await this.sendEmail({
this.sendEmail({ to: process.env['GOOGLE_EMAIL'] || 'system@deafgain.org',
to: subscriber.email, bcc: subscriberEmails,
subject, subject,
html, html,
}) });
);
const results = await Promise.allSettled(emailPromises); if (success) {
const successful = results.filter((result: any) => result.status === 'fulfilled').length; logger.info(`Email notification sent successfully to ${subscriberEmails.length} subscribers via BCC`);
const failed = results.filter((result: any) => result.status === 'rejected').length; } else {
logger.error(`Failed to send BCC email notification to ${subscriberEmails.length} subscribers`);
logger.info(`Email notifications sent: ${successful} successful, ${failed} failed`); }
} catch (error) { } catch (error) {
logger.error('Failed to notify subscribers:', error); logger.error('Failed to notify subscribers:', error);
} }