如何为@nestjs-modules/mailer设置动态transport切换SMTP与AWS SES
实现方案
1. 调整邮件模块配置
删除email.module.ts中固定写死的transport配置,仅保留全局通用的模板渲染规则、默认发件人等公共配置即可,修改后代码如下:
import { MailerModule } from '@nestjs-modules/mailer'; import { Global, Module } from '@nestjs/common'; import { join } from 'path'; import { EmailService } from './email.service'; import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter'; import { ConfigService } from '@nestjs/config'; @Global() @Module({ imports: [ MailerModule.forRootAsync({ useFactory: async (config: ConfigService) => ({ // 移除固定的transport配置 defaults: { from: `"No Reply" <${config.get('SMTP_MAIL_FROM')}>`, }, template: { dir: join(__dirname, 'templates'), adapter: new HandlebarsAdapter(), options: { strict: true, }, }, }), inject: [ConfigService], }), ], providers: [EmailService], exports: [EmailService], }) export class EmailModule {}
2. 服务层动态配置传输实例
在email.service.ts中分别初始化SMTP和SES两种传输实例,调用sendMail方法时传入transport参数即可覆盖全局配置,实现动态切换发送方案,修改后代码如下:
import { MailerService } from '@nestjs-modules/mailer'; import { Injectable } from '@nestjs/common'; import { createTransport, Transporter } from "nodemailer"; import { ConfigService } from '@nestjs/config'; import { SES } from 'aws-sdk'; @Injectable() export class EmailService { private readonly sesTransport: SES; private readonly smtpTransport: Transporter; constructor( private readonly mailerService: MailerService, private readonly configService: ConfigService ) { // 初始化SES传输实例 this.sesTransport = new SES({ accessKeyId: this.configService.get('S3_ACCESS_KEY_ID'), secretAccessKey: this.configService.get('S3_SECRET_ACCESS_KEY'), region: this.configService.get('S3_REGION') }); // 初始化SMTP传输实例,可根据实际业务调整配置字段 this.smtpTransport = createTransport({ host: this.configService.get('SMTP_HOST'), port: this.configService.get('SMTP_PORT'), secure: this.configService.get('SMTP_SECURE'), auth: { user: this.configService.get('SMTP_USER'), pass: this.configService.get('SMTP_PASS') } }) } // SES方式发送邮件 async sendSESEmail(context: any): Promise<void> { return await this.mailerService.sendMail({ transport: { SES: this.sesTransport }, to: context.toEmail, subject: `Gentle Reminder ${context.taskName}`, template: './welcome', context: { context }, }); } // SMTP方式发送邮件 async sendSmtpEmail(context: any): Promise<void> { return await this.mailerService.sendMail({ transport: this.smtpTransport, to: context.toEmail, subject: `Gentle Reminder ${context.taskName}`, template: './welcome', context: { context }, }); } }
实现说明
@nestjs-modules/mailer的sendMail方法原生兼容nodemailer的参数规则,支持传入transport字段临时替换全局传输器,该配置仅对当前单次调用生效,不会影响其他请求的发送规则。如果需要更高的灵活性,也可以封装一个通用方法,通过传入类型参数动态选择使用哪种传输方案。
内容的提问来源于stack exchange,提问作者Nishad Ceroen
相关产品推荐
相关产品推荐

