import { Injectable } from '@nestjs/common'; import fs from 'node:fs/promises'; import { ConfigService } from '@nestjs/config'; import nodemailer from 'nodemailer'; import Handlebars from 'handlebars'; import { AllConfigType } from 'src/config/config.type'; @Injectable() export class MailerService { private readonly transporter: nodemailer.Transporter; constructor(private readonly configService: ConfigService) { this.transporter = nodemailer.createTransport({ host: configService.get('mail.host', { infer: true }), port: configService.get('mail.port', { infer: true }), ignoreTLS: configService.get('mail.ignoreTLS', { infer: true }), secure: configService.get('mail.secure', { infer: true }), requireTLS: configService.get('mail.requireTLS', { infer: true }), auth: { user: configService.get('mail.user', { infer: true }), pass: configService.get('mail.password', { infer: true }), }, }); } async sendMail({ templatePath, context, ...mailOptions }: nodemailer.SendMailOptions & { templatePath: string; context: Record; }): Promise { let html: string | undefined; if (templatePath) { const template = await fs.readFile(templatePath, 'utf-8'); html = Handlebars.compile(template, { strict: true, })(context); } await this.transporter.sendMail({ ...mailOptions, from: mailOptions.from ? mailOptions.from : `"${this.configService.get('mail.defaultName', { infer: true, })}" <${this.configService.get('mail.defaultEmail', { infer: true, })}>`, html: mailOptions.html ? mailOptions.html : html, }); } }