You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 19:24:05