feat: add email ejs template route
This commit is contained in:
@@ -1,13 +1,16 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
apps: [
|
apps: [
|
||||||
{
|
{
|
||||||
name: 'mx-server',
|
name: 'mx-space-server@next',
|
||||||
script: 'index.js',
|
script: 'dist/src/main.js',
|
||||||
autorestart: true,
|
autorestart: true,
|
||||||
exec_mode: 'cluster',
|
exec_mode: 'cluster',
|
||||||
watch: false,
|
watch: false,
|
||||||
instances: 2,
|
instances: 2,
|
||||||
max_memory_restart: '230M',
|
max_memory_restart: '230M',
|
||||||
|
env: {
|
||||||
|
NODE_ENV: 'production',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,7 @@
|
|||||||
"@nestjs/testing": "8.0.6",
|
"@nestjs/testing": "8.0.6",
|
||||||
"@types/bcrypt": "5.0.0",
|
"@types/bcrypt": "5.0.0",
|
||||||
"@types/cache-manager": "3.4.2",
|
"@types/cache-manager": "3.4.2",
|
||||||
|
"@types/ejs": "^3.1.0",
|
||||||
"@types/ioredis": "4.27.2",
|
"@types/ioredis": "4.27.2",
|
||||||
"@types/jest": "27.0.1",
|
"@types/jest": "27.0.1",
|
||||||
"@types/lodash": "4.14.172",
|
"@types/lodash": "4.14.172",
|
||||||
|
|||||||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
@@ -25,6 +25,7 @@ specifiers:
|
|||||||
'@typegoose/typegoose': 8.2.0
|
'@typegoose/typegoose': 8.2.0
|
||||||
'@types/bcrypt': 5.0.0
|
'@types/bcrypt': 5.0.0
|
||||||
'@types/cache-manager': 3.4.2
|
'@types/cache-manager': 3.4.2
|
||||||
|
'@types/ejs': ^3.1.0
|
||||||
'@types/ioredis': 4.27.2
|
'@types/ioredis': 4.27.2
|
||||||
'@types/jest': 27.0.1
|
'@types/jest': 27.0.1
|
||||||
'@types/lodash': 4.14.172
|
'@types/lodash': 4.14.172
|
||||||
@@ -162,6 +163,7 @@ devDependencies:
|
|||||||
'@nestjs/testing': 8.0.6_67f7e5db8827badcb202b1d38f6b1aea
|
'@nestjs/testing': 8.0.6_67f7e5db8827badcb202b1d38f6b1aea
|
||||||
'@types/bcrypt': 5.0.0
|
'@types/bcrypt': 5.0.0
|
||||||
'@types/cache-manager': 3.4.2
|
'@types/cache-manager': 3.4.2
|
||||||
|
'@types/ejs': 3.1.0
|
||||||
'@types/ioredis': 4.27.2
|
'@types/ioredis': 4.27.2
|
||||||
'@types/jest': 27.0.1
|
'@types/jest': 27.0.1
|
||||||
'@types/lodash': 4.14.172
|
'@types/lodash': 4.14.172
|
||||||
@@ -1771,6 +1773,10 @@ packages:
|
|||||||
/@types/cors/2.8.12:
|
/@types/cors/2.8.12:
|
||||||
resolution: {integrity: sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==}
|
resolution: {integrity: sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==}
|
||||||
|
|
||||||
|
/@types/ejs/3.1.0:
|
||||||
|
resolution: {integrity: sha512-DCg+Ka+uDQ31lJ/UtEXVlaeV3d6t81gifaVWKJy4MYVVgvJttyX/viREy+If7fz+tK/gVxTGMtyrFPnm4gjrVA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/eslint-scope/3.7.1:
|
/@types/eslint-scope/3.7.1:
|
||||||
resolution: {integrity: sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==}
|
resolution: {integrity: sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ async function main() {
|
|||||||
await $`unzip /tmp/${tmpName}.zip -d ./run`
|
await $`unzip /tmp/${tmpName}.zip -d ./run`
|
||||||
await $`rm /tmp/${tmpName}.zip`
|
await $`rm /tmp/${tmpName}.zip`
|
||||||
cd('./run')
|
cd('./run')
|
||||||
|
process.env.NODE_ENV = 'production'
|
||||||
|
await $`export NODE_ENV=production`
|
||||||
await nothrow($`pm2 reload ecosystem.config.js -- ${argv}`)
|
await nothrow($`pm2 reload ecosystem.config.js -- ${argv}`)
|
||||||
console.log('等待 15 秒')
|
console.log('等待 15 秒')
|
||||||
await sleep(15000)
|
await sleep(15000)
|
||||||
|
|||||||
12
src/modules/option/dtos/email.dto.ts
Normal file
12
src/modules/option/dtos/email.dto.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { IsEnum, IsString } from 'class-validator'
|
||||||
|
import { ReplyMailType } from '~/processors/helper/helper.email.service'
|
||||||
|
|
||||||
|
export class ReplyEmailTypeDto {
|
||||||
|
@IsEnum(ReplyMailType)
|
||||||
|
type: ReplyMailType
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ReplyEmailBodyDto {
|
||||||
|
@IsString()
|
||||||
|
source: string
|
||||||
|
}
|
||||||
@@ -5,13 +5,20 @@ import {
|
|||||||
Get,
|
Get,
|
||||||
Param,
|
Param,
|
||||||
Patch,
|
Patch,
|
||||||
|
Put,
|
||||||
|
Query,
|
||||||
UnprocessableEntityException,
|
UnprocessableEntityException,
|
||||||
} from '@nestjs/common'
|
} from '@nestjs/common'
|
||||||
import { ApiTags } from '@nestjs/swagger'
|
import { ApiTags } from '@nestjs/swagger'
|
||||||
import { IsNotEmpty, IsString } from 'class-validator'
|
import { IsNotEmpty, IsString } from 'class-validator'
|
||||||
import { Auth } from '~/common/decorator/auth.decorator'
|
import { Auth } from '~/common/decorator/auth.decorator'
|
||||||
|
import {
|
||||||
|
EmailService,
|
||||||
|
ReplyMailType,
|
||||||
|
} from '~/processors/helper/helper.email.service'
|
||||||
import { IConfig } from '../configs/configs.interface'
|
import { IConfig } from '../configs/configs.interface'
|
||||||
import { ConfigsService } from '../configs/configs.service'
|
import { ConfigsService } from '../configs/configs.service'
|
||||||
|
import { ReplyEmailBodyDto, ReplyEmailTypeDto } from './dtos/email.dto'
|
||||||
import { OptionService } from './option.service'
|
import { OptionService } from './option.service'
|
||||||
|
|
||||||
class ConfigKeyDto {
|
class ConfigKeyDto {
|
||||||
@@ -27,6 +34,7 @@ export class OptionController {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly optionService: OptionService,
|
private readonly optionService: OptionService,
|
||||||
private readonly configs: ConfigsService,
|
private readonly configs: ConfigsService,
|
||||||
|
private readonly emailService: EmailService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Get('/')
|
@Get('/')
|
||||||
@@ -55,4 +63,26 @@ export class OptionController {
|
|||||||
}
|
}
|
||||||
return this.optionService.patchAndValid(params.key, body)
|
return this.optionService.patchAndValid(params.key, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('/email/template/reply')
|
||||||
|
getEmailReplyTemplate(@Query() { type }: ReplyEmailTypeDto) {
|
||||||
|
const template = this.emailService.readTemplate(
|
||||||
|
type === 'guest' ? ReplyMailType.Guest : ReplyMailType.Owner,
|
||||||
|
)
|
||||||
|
return template
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('/email/template/reply')
|
||||||
|
writeEmailReplyTemplate(
|
||||||
|
@Query() { type }: ReplyEmailTypeDto,
|
||||||
|
@Body() body: ReplyEmailBodyDto,
|
||||||
|
) {
|
||||||
|
this.emailService.writeTemplate(
|
||||||
|
type === 'guest' ? ReplyMailType.Guest : ReplyMailType.Owner,
|
||||||
|
body.source,
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
source: body.source,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { Injectable, Logger } from '@nestjs/common'
|
import { Injectable, Logger } from '@nestjs/common'
|
||||||
import { render } from 'ejs'
|
import { render } from 'ejs'
|
||||||
import { readFileSync } from 'fs'
|
import { readFileSync, writeFileSync } from 'fs'
|
||||||
import { createTransport } from 'nodemailer'
|
import { createTransport } from 'nodemailer'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { ConfigsService } from '~/modules/configs/configs.service'
|
import { ConfigsService } from '~/modules/configs/configs.service'
|
||||||
import { LinkModel } from '~/modules/link/link.model'
|
import { LinkModel } from '~/modules/link/link.model'
|
||||||
|
|
||||||
export enum ReplyMailType {
|
export enum ReplyMailType {
|
||||||
Owner,
|
Owner = 'owner',
|
||||||
Guest,
|
Guest = 'guest',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum LinkApplyEmailType {
|
export enum LinkApplyEmailType {
|
||||||
@@ -46,6 +46,29 @@ export class EmailService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeTemplate(type: ReplyMailType, source: string) {
|
||||||
|
switch (type) {
|
||||||
|
case ReplyMailType.Guest:
|
||||||
|
return writeFileSync(
|
||||||
|
path.resolve(
|
||||||
|
process.cwd(),
|
||||||
|
'assets/email-template/guest.template.ejs',
|
||||||
|
),
|
||||||
|
source,
|
||||||
|
{ encoding: 'utf-8' },
|
||||||
|
)
|
||||||
|
case ReplyMailType.Owner:
|
||||||
|
return writeFileSync(
|
||||||
|
path.resolve(
|
||||||
|
process.cwd(),
|
||||||
|
'assets/email-template/owner.template.ejs',
|
||||||
|
),
|
||||||
|
source,
|
||||||
|
{ encoding: 'utf-8' },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.getConfigFromConfigService().then((config) => {
|
this.getConfigFromConfigService().then((config) => {
|
||||||
this.instance = createTransport({
|
this.instance = createTransport({
|
||||||
|
|||||||
Reference in New Issue
Block a user