import nodemailer from 'nodemailer';
// ============================================
// Configuration
// ============================================
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST || 'smtp.example.com',
port: parseInt(process.env.SMTP_PORT || '587'),
secure: process.env.SMTP_SECURE === 'true', // true for 465, false for other ports
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
// ============================================
// Templates (Simple)
// ============================================
const templates = {
welcome: (name: string) => ({
subject: 'Welcome to MyApp!',
html: `
<h1>Welcome, ${name}!</h1>
<p>We're excited to have you on board.</p>
<p>Click <a href="${process.env.DOMAIN}/dashboard">here</a> to get started.</p>
`,
text: `Welcome, ${name}!\nWe're excited to have you on board.\nGo to ${process.env.DOMAIN}/dashboard to get started.`,
}),
resetPassword: (token: string) => ({
subject: 'Reset your password',
html: `
<h1>Reset Password</h1>
<p>Click the link below to reset your password:</p>
<p><a href="${process.env.DOMAIN}/reset-password?token=${token}">Reset Password</a></p>
<p>If you didn't request this, please ignore this email.</p>
`,
text: `Reset Password\nClick the link: ${process.env.DOMAIN}/reset-password?token=${token}\nIf you didn't request this, ignore this email.`,
}),
};
// ============================================
// Service
// ============================================
export const emailService = {
async sendEmail(to: string, subject: string, html: string, text?: string) {
try {
const info = await transporter.sendMail({
from: `"${process.env.FROM_NAME}" <${process.env.FROM_EMAIL}>`,
to,
subject,
html,
text: text || html.replace(/<[^>]*>?/gm, ''), // fallback strip tags
});
console.log(`Email sent: ${info.messageId}`);
return { success: true, messageId: info.messageId };
} catch (error) {
console.error('Error sending email:', error);
throw error;
}
},
async sendWelcome(to: string, name: string) {
const { subject, html, text } = templates.welcome(name);
return this.sendEmail(to, subject, html, text);
},
async sendPasswordReset(to: string, token: string) {
const { subject, html, text } = templates.resetPassword(token);
return this.sendEmail(to, subject, html, text);
},
// Validates connection at startup
async verifyConnection() {
try {
await transporter.verify();
console.log('✅ SMTP connection established');
return true;
} catch (error) {
console.error('❌ SMTP connection failed:', error);
return false;
}
}
};
/*
// For dev env (using Ethereal Email):
if (process.env.NODE_ENV !== 'production') {
nodemailer.createTestAccount().then((account) => {
// ... update config using account.user/pass
});
}
*/