import { Injectable, type OnModuleInit } from '@nestjs/common'; import { LoggerService } from '@modules/shared/infrastructure/logger.service'; import * as nodemailer from 'nodemailer'; export interface SendEmailDto { to: string; subject: string; html: string; } @Injectable() export class EmailService implements OnModuleInit { private transporter!: nodemailer.Transporter; constructor(private readonly logger: LoggerService) {} onModuleInit(): void { const host = process.env['SMTP_HOST'] ?? 'localhost'; const port = Number(process.env['SMTP_PORT'] ?? '1025'); const user = process.env['SMTP_USER']; const pass = process.env['SMTP_PASS']; this.transporter = nodemailer.createTransport({ host, port, secure: port === 465, ...(user && pass ? { auth: { user, pass } } : {}), }); this.logger.log(`Email transport configured: ${host}:${port}`, 'EmailService'); } async send(dto: SendEmailDto): Promise<{ messageId: string }> { const from = process.env['SMTP_FROM'] ?? 'noreply@goodgo.vn'; try { const info = await this.transporter.sendMail({ from, to: dto.to, subject: dto.subject, html: dto.html, }); this.logger.log(`Email sent to ${dto.to}: ${info.messageId}`, 'EmailService'); return { messageId: info.messageId }; } catch (error) { this.logger.error( `Failed to send email to ${dto.to}: ${error instanceof Error ? error.message : String(error)}`, 'EmailService', ); throw error; } } async verify(): Promise { try { await this.transporter.verify(); return true; } catch { return false; } } }