Sending Emails
Send transactional emails with Nodemailer.
Installation
bash
npm install nodemailernpm install -D @types/nodemailerConfiguration
typescript
// src/config/mail.tsimport nodemailer from 'nodemailer'; const transporter = nodemailer.createTransport({ host: process.env.MAIL_HOST, port: Number(process.env.MAIL_PORT), secure: process.env.MAIL_SECURE === 'true', auth: { user: process.env.MAIL_USER, pass: process.env.MAIL_PASS, },}); export default transporter;Mail Service
typescript
// src/services/mail.service.tsimport transporter from '../config/mail'; interface SendMailOptions { to: string; subject: string; html: string;} export class MailService { private from = `"E-commerce" <${process.env.MAIL_FROM}>`; async send({ to, subject, html }: SendMailOptions): Promise<void> { await transporter.sendMail({ from: this.from, to, subject, html }); } async sendWelcome(user: { name: string; email: string }): Promise<void> { await this.send({ to: user.email, subject: 'Welcome to E-commerce!', html: ` <h1>Hello, ${user.name}!</h1> <p>Your account was created successfully.</p> `, }); } async sendPasswordReset(user: { email: string }, token: string): Promise<void> { const resetUrl = `${process.env.FRONTEND_URL}/reset-password?token=${token}`; await this.send({ to: user.email, subject: 'Password Reset', html: ` <h1>Password Reset</h1> <p>Click the link below to reset your password:</p> <a href="${resetUrl}">Reset Password</a> <p>Link expires in 1 hour.</p> `, }); } async sendOrderConfirmation(user: { name: string; email: string }, order: any): Promise<void> { await this.send({ to: user.email, subject: `Order #${order.id} Confirmed`, html: ` <h1>Order Confirmed!</h1> <p>Thank you for your purchase, ${user.name}!</p> <p><strong>Total: $${order.total}</strong></p> `, }); }}Queue with Bull
bash
npm install bullnpm install -D @types/bulltypescript
// src/jobs/mail.job.tsimport Bull from 'bull';import { MailService } from '../services/mail.service'; const mailQueue = new Bull('mail', { redis: process.env.REDIS_URL });const mailService = new MailService(); mailQueue.process(async (job) => { await mailService.send(job.data);}); export const addMailJob = (data: SendMailOptions) => { return mailQueue.add(data, { attempts: 3, backoff: { type: 'exponential', delay: 2000 }, });};Summary
- ✅ Nodemailer configuration
- ✅ Transactional emails
- ✅ Async queues with Bull
Next lesson: Redis Cache! 🚀