如何优雅的使用nestjs实现邮件发送

前言

邮箱发送是我们常见的一个服务,本篇文章带大家用nestjs来实现一下

前置准备

首先我们需要开通邮箱服务,这里我以qq邮箱为例子演示一下

我这里已经开通好了,我们第一次开通时会给你一个密钥,这个需要记下来,后面会用到。这里开通很简单,就问你用途,无脑填即可。

当我们开通之后,我们在nestjs中创建好一个邮箱服务

这里我们需要用到一个包 nodemailer 这个包的生态很成熟,帮我们做好了那些协议,我们直接用即可

我的习惯是,对于单独的服务例如邮箱服务,prisma查询构造生成器等,我会放到services目录下,其他模块想使用直接依赖注入就可

下面我们进入实操

这个是nodemailer这个包需要配置的配置项,我们来解释一下

  • host:服务器邮箱地址,这里qq的是 smtp.qq.com,其他邮箱例如网易的,可以百度搜索的到
  • port: 服务器端口号, qq的是465, 一般都是465
  • secure:表示安全连接
  • auth: 账户信息,第一个user就填写你开通服务的邮箱账号, 第二个pass就是刚刚生成的密钥
mail.service.ts 复制代码
import { Injectable } from '@nestjs/common';
import * as nodemailer from 'nodemailer';
interface MailInfo {
    // 接收方邮箱
    to: string;
    // 标题
    subject: string;
    // 文本
    text?: string;
    // 富文本,如果文本和富文本同时设置,富文本生效。
    html?: string;
  }
@Injectable()
export class EmailService {
  private transporter: nodemailer.Transporter;
  private mailConfig =  {
    host: 'smtp.qq.com',
    port: 465,
    secure: true,
    auth: {
    user: '你开通的邮箱账号',
    pass: '生成的密钥'
  }
  }
  constructor() {
    this.transporter = nodemailer.createTransport(this.mailConfig);
  }

  async sendEmail(mailInfo: MailInfo) {
     const info = await this.transporter.sendMail({
        from: this.mailConfig.auth.user, //发送方邮箱
        ...mailInfo
     })
     return info
  }
}

对于mailConfig最好抽离成一个单独的模块,可以用命名空间存放,然后用configService读取出来,这里为了演示就简单操作了。

上面的代码就是配置项,主要就是为了利用它的sendMail服务实现邮箱发送,这里需要的参数,我这里也写得很清楚了。接下来让我们实战演练,以邮箱验证码为例

实战演练

我们在开通账号时,我需要邮箱的验证码,只有验证码正确了才能开通,我的逻辑是,前端在点击验证码发送时,将邮箱账号传递到后端,此时后端生成一个验证码,并且存到redis中,设置有效期,然后通过邮箱服务将验证码发送给这个邮箱账号,在邮箱中获取到验证码后再在表单中输入,然后提交时,再和redis中的验证码进行比对。

前端代码我就不展示了,就一个点击发送后设置一个倒计时,主要还是展示后端

js 复制代码
 @Post('/send/emailCaptcha')
  async sendEmailCaptcha(@Body() emailInfo: {email: string}){
      if(!emailInfo) {
         throw new HttpException('邮箱不能为空', HttpStatus.BAD_REQUEST)
      }
      //生成随机四位数
      const emailCaptcha = Math.floor(Math.random() * 9000) + 1000
      //生成的数据存在redis中,后面添加用户做验证
      await this.redisClient
      .multi()
      .set(
        `emailCaptcha:${emailInfo.email}`,
         emailCaptcha,
      )
      .expire( `emailCaptcha:${emailInfo.email}`, 60 * 30) //30min
      .exec()
      
      this.emailService.sendEmail({
            to: emailInfo.email,
            html: `<div>
            您本次的验证码是<span style="color:#FFB6C1; font-weight:700; font-size:24px">${emailCaptcha}</span>, 验证码有效期是30分钟 </div>`,
            subject: 'xxx平台邮箱检验提醒'
      })
  }

这样当我们前端点击验证码发送后,调用这个接口,然后我们就可以在邮箱中收到验证码了

差不多就是这样一个效果,具体样式可以自己调整,核心逻辑就是这里了,后面的逻辑就很简单了,不做演示了。

写在最后

希望这样一个简单的邮件服务能够让大家学到新的知识,最后假期余额快不足了,祝大家节日快乐!

相关推荐
火星思想6 分钟前
都2025年了,还在问构建工具是干嘛的?
前端·前端框架·设计
杨进军9 分钟前
MutationObserver 实现 iframe 自适应高度
前端
火星思想10 分钟前
Promise 核心知识点(非基础)
前端·javascript·面试
前端大白话11 分钟前
炸裂!10个 React 实战技巧,让你的代码从“青铜”秒变“王者”
前端·javascript·react.js
Paramita12 分钟前
Koa源码解读
前端
用户614722537720312 分钟前
JavaScript 性能优化实战:从理论到落地的全面指南
前端
专业掘金12 分钟前
0426 手打基础丸
前端
WEI_Gaot17 分钟前
React 19 Props 和 react-icons 和 事件处理函数
前端·react.js
10年前端老司机17 分钟前
微信小程序模板语法和事件
前端·javascript·微信小程序
龙在天18 分钟前
Promise.withResolvers() vs 传统 Promise:谁更胜一筹?
前端