Nest.js写一个定时发邮件任务?太简单了!
2024-02-05 09:33:13 软件 190观看
摘要概要前面几章完成了,当日任务和长期目标的基础模块,现在我将要完成定时任务模块。就像我一开始介绍的那样,我要对我每天没有完成的任务,或者长期目标没有达成的情况下,发送电子邮件来提醒我。如果大家时间充裕的话,可以看下

概要

前面几章完成了,当日任务和长期目标的基础模块,现在我将要完成定时任务模块。就像我一开始介绍的那样,我要对我每天没有完成的任务,或者长期目标没有达成的情况下,发送电子邮件来提醒我。yXQ28资讯网——每日最新资讯28at.com

如果大家时间充裕的话,可以看下相关的文章使用Cron Jobs和NestJS实现任务自动化[1]和通过工作队列发送邮件[2]。重点要看下Cron Jobs,里面有对时间设置的具体说明。yXQ28资讯网——每日最新资讯28at.com

由于个人管理项目,没有什么特别需要处理高并发的需求,所以我只写了普通的邮件发送就足够了,不需要通过工作队列来处理。yXQ28资讯网——每日最新资讯28at.com

定时任务介绍

NestJS 提供了一种非常方便的方式来创建定时任务,通常用于执行周期性的后台任务,例如数据同步、数据清理、报告生成等等。yXQ28资讯网——每日最新资讯28at.com

以下是如何在 NestJS 中创建和使用定时任务的步骤:yXQ28资讯网——每日最新资讯28at.com

  1. 安装相关依赖:
$ pnpm install --save @nestjs/schedule
  1. 在app.module.ts中注册定时任务:
// app.module.tsimport { Module } from '@nestjs/common';import { ScheduleModule } from '@nestjs/schedule';@Module({  imports: [    ScheduleModule.forRoot()  ],})export class AppModule {}
  1. 创建定时任务服务
import { Injectable, Logger } from '@nestjs/common';import { Cron } from '@nestjs/schedule';@Injectable()export class TasksService {  private readonly logger = new Logger(TasksService.name);  @Cron('45 * * * * *')  handleCron() {    this.logger.debug('Called when the current second is 45');  }}

详细内容请参照官方文档[3]。yXQ28资讯网——每日最新资讯28at.com

邮件发送

在 NestJS 中发送邮件通常涉及使用邮件发送库,如 Nodemailer。下面是如何在 NestJS 中发送邮件的一般步骤:yXQ28资讯网——每日最新资讯28at.com

  1. 安装 Nodemailer:

首先,你需要在你的 NestJS 项目中安装 Nodemailer。可以使用以下命令安装:yXQ28资讯网——每日最新资讯28at.com

$ pnpm install nodemailer
  1. 创建一个邮件服务:

在你的 NestJS 应用程序中,创建一个专门的邮件服务,该服务负责配置和发送邮件。你可以创建一个自定义的邮件服务类,也可以将邮件配置添加到现有的服务中。yXQ28资讯网——每日最新资讯28at.com

import { Injectable } from '@nestjs/common';import * as nodemailer from 'nodemailer';import { ConfigService } from '@nestjs/config';import { ConfigEnum } from './enum/config.enum';@Injectable()export class EmailService {  private transporter;  constructor(private readonly configService: ConfigService) {    const mailConfig = this.configService.get(ConfigEnum.MAIL_CONFIG);    this.transporter = nodemailer.createTransport({      host: mailConfig.host,      port: mailConfig.port,      secure: true, // 如果是 SMTPS 连接,设置为 true      auth: {        user: mailConfig.authUser,        pass: mailConfig.authPass,      },    });  }  async sendMail(to: string, subject: string, text: string): Promise<void> {    const mailOptions = {      from: this.configService.get(ConfigEnum.MAIL_CONFIG).authUser,      to,      subject,      text,    };    await this.transporter.sendMail(mailOptions);  }}

在这个示例中,我们创建了一个 EmailService,它接收邮件配置信息并初始化 Nodemailer 的传输器。然后,它提供了一个 sendMail 方法,用于发送邮件。yXQ28资讯网——每日最新资讯28at.com

  1. 注册邮件服务:

将 EmailService 添加到你的 NestJS 模块的 providers 数组中,以便在整个应用程序中使用它。yXQ28资讯网——每日最新资讯28at.com

import { Module } from '@nestjs/common';import { EmailService } from './email.service';@Module({  providers: [EmailService],  // ...})export class AppModule {}
  1. 使用邮件服务:

现在,你可以在你的控制器或其他服务中使用 EmailService 来发送邮件。例如,在你的控制器中:yXQ28资讯网——每日最新资讯28at.com

import { Controller, Get } from '@nestjs/common';import { EmailService } from './email.service';@Controller('email')export class EmailController {  constructor(private readonly emailService: EmailService) {}  @Get('send')  async sendEmail() {    try {      await this.emailService.sendMail('recipient@example.com', 'Hello', 'This is the email body.');      return 'Email sent successfully!';    } catch (error) {      return 'Email sending failed: ' + error;    }  }}

这是一个简单的示例,说明如何在 NestJS 中发送邮件。你可以根据你的需求扩展和自定义邮件服务,以适应不同的邮件发送场景。确保你的配置信息正确,以及你的邮件服务提供了适当的错误处理来处理可能的发送失败情况。yXQ28资讯网——每日最新资讯28at.com

定时任务做成

  • 首先,因为需要用到当日任务的长期目标模块里面的方法。先导入这2个模块
import { Module } from '@nestjs/common';import { TasksCronService } from './tasks-cron.service';import { TasksModule } from '../tasks/tasks.module';import { LongTeamGoalsModule } from '../long-team-goals/long-team-goals.module';@Module({  imports: [TasksModule, LongTeamGoalsModule],  providers: [TasksCronService],})export class TasksCronModule {}
  • 然后都要用到邮件发送,所以要在构造函数中初期化transporter。并且发送成功或者失败,希望能在log日志中能看到,所以loggerError个loggerNomal2个函数。
import * as nodemailer from 'nodemailer';import { TasksService } from '../tasks/tasks.service';import { LongTeamGoalsService } from '../long-team-goals/long-team-goals.service';import { ConfigService } from '@nestjs/config';import { ConfigEnum } from '../enum/config.enum';import { Injectable, Logger } from '@nestjs/common';@Injectable()export class TasksCronService {  private transporter;  private readonly logger = new Logger(TasksCronService.name);  constructor(    private readonly configService: ConfigService,    private readonly tasksService: TasksService,    private readonly longsService: LongTeamGoalsService,  ) {    const MAIL_CONFIG = this.configService.get(ConfigEnum.MAIL_CONFIG);    this.transporter = nodemailer.createTransport({      host: MAIL_CONFIG.host,      port: MAIL_CONFIG.port,      secure: true,      auth: {        user: MAIL_CONFIG.authUser,        pass: MAIL_CONFIG.authPass,      },    });  }    loggerError(message: string, error?: any) {    this.logger.error(message, error);  }  loggerNomal(message: string, info?: any) {    this.logger.log(message, info);  }    // 发送邮件  async sendReminderEmail(taskTitles: string) {    const MAIL_CONFIG = this.configService.get(ConfigEnum.MAIL_CONFIG);    const mailOptions = {      from: MAIL_CONFIG.authUser,      to: MAIL_CONFIG.destUser,      subject: '您有未完成的任务',      text: `以下是您今天尚未完成的任务:/n/n${taskTitles}`,    };    this.transporter.sendMail(mailOptions, (error, info) => {      if (error) {        this.loggerError(`邮件发送失败: ${error}`);      } else {        this.loggerNomal(`邮件已发送: ${info.response}`);      }    });  }}
  • 简单的介绍下,项目中定时任务的内容。
  1. 每天下午17:30点,检查当日任务里面有没有没完成的任务。如果有就发送电子邮件
@Cron('30 17 * * *') // 每天下午7点30分执行  async handleCron() {    this.loggerNomal('开始检查未完成的任务');    const currentDate = dayjs().format('YYYY-MM-DD');    const startDate = currentDate;    const endDate = currentDate;    const tasks = await this.tasksService.search({      startDate,      endDate,    });    // 过滤当日任务中已完成的任务。    const incompleteTasks = tasks.data.filter((task) => !task.isCompleted);    if (incompleteTasks.length) {      const titles = incompleteTasks.map((task) => task.title).join('/n');      await this.sendReminderEmail(titles);    }  }
  1. 每天晚上22:00点,检查长期目标里面有没有临近的任务还没有完成。如果有就发送电子邮件
@Cron('0 22 * * *')  async handleLongCron() {    const nearlyExpiredGoals = await this.longsService.findNearlyExpiredGoals(      3,    );    if (nearlyExpiredGoals.length) {      const titles = nearlyExpiredGoals.map((long) => long.title).join('/n');      await this.sendReminderEmail(titles);      await this.longsService.setWarned(nearlyExpiredGoals);    }  }
  • 长期目标模块中的方法
// 在你的目标服务中  async findNearlyExpiredGoals(days: number): Promise<any[]> {    const deadlineDate = new Date(Date.now() + days * 24 * 60 * 60 * 1000);    return this.longTermGoalModel      .find({        deadline: { $lte: deadlineDate },        isWarned: false,      })      .exec();  }

yXQ28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-73796-0.htmlNest.js写一个定时发邮件任务?太简单了!

声明:本网页内容旨在传播知识,不代表本站观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。

显示全文

上一篇:Vue 10 岁了!你知道它最初的名字吗?

下一篇:个掌握C++编程的关键要点

最新热点