如何优雅的使用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平台邮箱检验提醒'
      })
  }

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

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

写在最后

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

相关推荐
酷酷的阿云7 分钟前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
微信:137971205879 分钟前
web端手机录音
前端
齐 飞14 分钟前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
暮毅20 分钟前
10.Node.js连接MongoDb
数据库·mongodb·node.js
LunarCod31 分钟前
WorkFlow源码剖析——Communicator之TCPServer(中)
后端·workflow·c/c++·网络框架·源码剖析·高性能高并发
神仙别闹31 分钟前
基于tensorflow和flask的本地图片库web图片搜索引擎
前端·flask·tensorflow
码农派大星。1 小时前
Spring Boot 配置文件
java·spring boot·后端
GIS程序媛—椰子1 小时前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_0011 小时前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端2 小时前
Content Security Policy (CSP)
前端·javascript·面试