128 lines
3.1 KiB
JavaScript

const nodemailer = require('nodemailer');
class EmailService {
constructor() {
this.transporter = null;
this.initializeTransporter();
}
initializeTransporter() {
try {
this.transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT) || 587,
secure: process.env.SMTP_PORT === '465', // true for 465, false for other ports
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS
},
tls: {
rejectUnauthorized: false
}
});
console.log('Email transporter initialized successfully');
} catch (error) {
console.error('Failed to initialize email transporter:', error);
}
}
async testConnection() {
try {
if (!this.transporter) {
throw new Error('Email transporter not initialized');
}
await this.transporter.verify();
return {
success: true,
message: 'SMTP connection verified successfully'
};
} catch (error) {
return {
success: false,
message: 'SMTP connection failed',
error: error.message
};
}
}
async sendEmail(emailOptions) {
try {
if (!this.transporter) {
throw new Error('Email transporter not initialized');
}
const mailOptions = {
from: `"${emailOptions.from.name}" <${emailOptions.from.email}>`,
to: emailOptions.to,
replyTo: emailOptions.replyTo,
subject: emailOptions.subject,
text: emailOptions.text,
html: emailOptions.html
};
const info = await this.transporter.sendMail(mailOptions);
console.log('Email sent successfully:', info.messageId);
return {
success: true,
messageId: info.messageId,
response: info.response
};
} catch (error) {
console.error('Email send error:', error);
return {
success: false,
error: error.message
};
}
}
async sendBulkEmails(emails) {
const results = [];
for (const email of emails) {
try {
const result = await this.sendEmail(email);
results.push({
to: email.to,
success: result.success,
messageId: result.messageId,
error: result.error
});
// Add a small delay between emails to avoid overwhelming the SMTP server
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
results.push({
to: email.to,
success: false,
error: error.message
});
}
}
return results;
}
formatEmailTemplate(template, data) {
let formattedTemplate = template;
// Replace placeholders with actual data
Object.keys(data).forEach(key => {
const placeholder = `{{${key}}}`;
formattedTemplate = formattedTemplate.replace(new RegExp(placeholder, 'g'), data[key]);
});
return formattedTemplate;
}
validateEmailAddress(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
}
module.exports = new EmailService();