定时任务
NestJS 定时任务可通过miaowing/nest-schedule实现。
定时任务的实现
- 按照 miaowing/nest-schedule 的说明文档,将 nest-schedule 模块导入到项目中:
import { Module } from '@nestjs/common';
import { ScheduleModule } from 'nest-schedule';
@Module({
imports: [
ScheduleModule.register(),
]
})
export class AppModule {
}
2. 需要支持定时任务的服务继承 NestSchedule 类:
import { Injectable } from '@nestjs/common';
import { Cron, Interval, Timeout, NestSchedule } from 'nest-schedule';
@Injectable() // Only support SINGLETON scope
export class ScheduleService extends NestSchedule {
@Cron('15 16 * * *')
async cronJob() {
console.log('executing cron job');
}
3. 执行定时任务的方法添加@Cron('15 16 * * *')
注解。这条注解的意思是“每天16:15” 执行一次定时任务。这里似乎与常见的 Cron 表达式不一样:第一个数据段代表的不是秒而是分,由此可见,miaowing/nest-schedule 不支持秒级的定时任务。
以上三步就能实现定时任务的功能了。
需要留意的问题
- 不知何故,开启服务后,定时任务并没有执行,必须手动访问过任意一个 controller 之后,定时任务才会开启。开始猜测是在子模块导入的原因,尝试在根模块注入之后,问题依旧,难道与
Only support SINGLETON scope
有关系? @Cron('15 16 * * *')
中的表达式并非常见的 Cron 表达式,第一个数据段代表的是分而不是秒,且不支持如:“0/15 * * * *
每15分钟执行一次”这样的配置,逗号分隔符是支持的,因此每15分钟执行一次可以配置成“0,15,30,45”。
发送 Exchange 邮件
Exchange 邮件的支持借助gautamsi/ews-javascript-api来实现。
Exchange 邮件发送实现
- 导入相关方法
import {
ExchangeService, ExchangeVersion,
Uri as ExchangeUri,
WebCredentials, EmailMessage, MessageBody, ConfigurationApi
} from 'ews-javascript-api';
2. 新建ExchangeService 服务
const exch = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
3. 配置登录凭据以及服务地址
exch.Credentials = new WebCredentials(ewsConfig.username, ewsConfig.password);
exch.Url = new ExchangeUri(ewsConfig.host);
4. 构建要发送的邮件实体,Subject 为邮件的标题,Body 为邮件的内容,收件人地址可以通过msgattach.ToRecipients.Add(address)
方法实现:
const msgattach = new EmailMessage(exch);
msgattach.Subject = mailContent.Subject;
msgattach.Body = new MessageBody(mailContent.Body);
msgattach.ToRecipients.Add(address);
5. 发送邮件
msgattach.SendAndSaveCopy() // 此方法返回 Promise
按照上述步骤实现,可能会出现鉴权不通过的问题,可能是 NTLM 认证的问题,NTLM 是 telnet 的一种验证身份的方式,是 Windows NT 早期版本的标准安全协议。可以安装另外一个库@ewsjs/xhr, 尝试以下配置:
...
import { XhrApi } from '@ewsjs/xhr';
...
const exch = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
const xhr = new XhrApi({ rejectUnauthorized: false }).useNtlmAuthentication(username, password);
ConfigurationApi.ConfigureXHR(xhr);
完整代码如下:
import {
ExchangeService, ExchangeVersion,
Uri as ExchangeUri,
WebCredentials, EmailMessage, MessageBody, ConfigurationApi
} from 'ews-javascript-api';
/**
* 发邮件
*/
mailToSomeOne(address: string, mailContent: {
Subject: string,
Body: string
}): void {
const exch = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
const xhr = new XhrApi({ rejectUnauthorized: false }).useNtlmAuthentication(ewsConfig.username, ewsConfig.password);
ConfigurationApi.ConfigureXHR(xhr);
exch.Credentials = new WebCredentials(ewsConfig.username, ewsConfig.password);
exch.Url = new ExchangeUri(ewsConfig.host);
const msgattach = new EmailMessage(exch);
msgattach.Subject = mailContent.Subject;
msgattach.Body = new MessageBody(mailContent.Body);
msgattach.ToRecipients.Add(address);
msgattach.SendAndSaveCopy().then(res => {
console.log(res);
}, (err) => {
console.error(err);
});
}
需要留意的问题
- 权限部分可能并非使用 NTLM 方式,@ewsjs/xhr还支持 Cookies Auth,可查阅文档。
发表回复