前面幾章完成了,當日任務和長期目標的基礎模塊,現在我將要完成定時任務模塊。就像我一開始介紹的那樣,我要對我每天沒有完成的任務,或者長期目標沒有達成的情況下,發送電子郵件來提醒我。
如果大家時間充裕的話,可以看下相關的文章使用Cron Jobs和NestJS實現任務自動化[1]和通過工作隊列發送郵件[2]。重點要看下Cron Jobs,里面有對時間設置的具體說明。
由于個人管理項目,沒有什么特別需要處理高并發的需求,所以我只寫了普通的郵件發送就足夠了,不需要通過工作隊列來處理。
NestJS 提供了一種非常方便的方式來創建定時任務,通常用于執行周期性的后臺任務,例如數據同步、數據清理、報告生成等等。
以下是如何在 NestJS 中創建和使用定時任務的步驟:
$ pnpm install --save @nestjs/schedule
// app.module.tsimport { Module } from '@nestjs/common';import { ScheduleModule } from '@nestjs/schedule';@Module({ imports: [ ScheduleModule.forRoot() ],})export class AppModule {}
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]。
在 NestJS 中發送郵件通常涉及使用郵件發送庫,如 Nodemailer。下面是如何在 NestJS 中發送郵件的一般步驟:
首先,你需要在你的 NestJS 項目中安裝 Nodemailer。可以使用以下命令安裝:
$ pnpm install nodemailer
在你的 NestJS 應用程序中,創建一個專門的郵件服務,該服務負責配置和發送郵件。你可以創建一個自定義的郵件服務類,也可以將郵件配置添加到現有的服務中。
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 方法,用于發送郵件。
將 EmailService 添加到你的 NestJS 模塊的 providers 數組中,以便在整個應用程序中使用它。
import { Module } from '@nestjs/common';import { EmailService } from './email.service';@Module({ providers: [EmailService], // ...})export class AppModule {}
現在,你可以在你的控制器或其他服務中使用 EmailService 來發送郵件。例如,在你的控制器中:
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 中發送郵件。你可以根據你的需求擴展和自定義郵件服務,以適應不同的郵件發送場景。確保你的配置信息正確,以及你的郵件服務提供了適當的錯誤處理來處理可能的發送失敗情況。
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 {}
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}`); } }); }}
@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); } }
@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(); }
本文鏈接:http://www.www897cc.com/showinfo-26-73796-0.htmlNest.js寫一個定時發郵件任務?太簡單了!
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
下一篇: 個掌握C++編程的關鍵要點