Merged PR 594: [TODO対処] メールの内容について編集しやすくする
## 概要 [Task2163: [TODO対処] メールの内容について編集しやすくする](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2163) - メール文面をハードコードしない構造を試作 ## レビューポイント - メールテンプレートの定義場所、定義形式、読み込み方法などは問題なさそうか ## 動作確認状況 - ローカルで確認
This commit is contained in:
parent
a0da277c05
commit
b1f169def5
@ -1,5 +1,9 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/nest-cli",
|
"$schema": "https://json.schemastore.org/nest-cli",
|
||||||
"collection": "@nestjs/schematics",
|
"collection": "@nestjs/schematics",
|
||||||
"sourceRoot": "src"
|
"sourceRoot": "src",
|
||||||
|
"compilerOptions": {
|
||||||
|
"assets": ["templates/**/*.html", "templates/**/*.txt"],
|
||||||
|
"watchAssets": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,12 +4,17 @@ import { sign } from '../../common/jwt';
|
|||||||
import sendgrid from '@sendgrid/mail';
|
import sendgrid from '@sendgrid/mail';
|
||||||
import { getPrivateKey } from '../../common/jwt/jwt';
|
import { getPrivateKey } from '../../common/jwt/jwt';
|
||||||
import { Context } from '../../common/log';
|
import { Context } from '../../common/log';
|
||||||
|
import { readFileSync } from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SendGridService {
|
export class SendGridService {
|
||||||
private readonly logger = new Logger(SendGridService.name);
|
private readonly logger = new Logger(SendGridService.name);
|
||||||
private readonly emailConfirmLifetime: number;
|
private readonly emailConfirmLifetime: number;
|
||||||
private readonly appDomain: string;
|
private readonly appDomain: string;
|
||||||
|
private readonly templateEmailVerifyHtml: string;
|
||||||
|
private readonly templateEmailVerifyText: string;
|
||||||
|
|
||||||
constructor(private readonly configService: ConfigService) {
|
constructor(private readonly configService: ConfigService) {
|
||||||
this.appDomain = this.configService.getOrThrow<string>('APP_DOMAIN');
|
this.appDomain = this.configService.getOrThrow<string>('APP_DOMAIN');
|
||||||
this.emailConfirmLifetime = this.configService.getOrThrow<number>(
|
this.emailConfirmLifetime = this.configService.getOrThrow<number>(
|
||||||
@ -17,6 +22,18 @@ export class SendGridService {
|
|||||||
);
|
);
|
||||||
const key = this.configService.getOrThrow<string>('SENDGRID_API_KEY');
|
const key = this.configService.getOrThrow<string>('SENDGRID_API_KEY');
|
||||||
sendgrid.setApiKey(key);
|
sendgrid.setApiKey(key);
|
||||||
|
|
||||||
|
// メールテンプレートを読み込む
|
||||||
|
{
|
||||||
|
this.templateEmailVerifyHtml = readFileSync(
|
||||||
|
path.resolve(__dirname, `../../templates/template_email_verify.html`),
|
||||||
|
'utf-8',
|
||||||
|
);
|
||||||
|
this.templateEmailVerifyText = readFileSync(
|
||||||
|
path.resolve(__dirname, `../../templates/template_email_verify.txt`),
|
||||||
|
'utf-8',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,29 +56,44 @@ export class SendGridService {
|
|||||||
`accountId: ${accountId},` +
|
`accountId: ${accountId},` +
|
||||||
`userId: ${userId} };`,
|
`userId: ${userId} };`,
|
||||||
);
|
);
|
||||||
|
try {
|
||||||
|
const privateKey = getPrivateKey(this.configService);
|
||||||
|
const token = sign<{ accountId: number; userId: number; email: string }>(
|
||||||
|
{
|
||||||
|
accountId,
|
||||||
|
userId,
|
||||||
|
email,
|
||||||
|
},
|
||||||
|
this.emailConfirmLifetime,
|
||||||
|
privateKey,
|
||||||
|
);
|
||||||
|
const path = 'mail-confirm/';
|
||||||
|
|
||||||
const privateKey = getPrivateKey(this.configService);
|
const html = this.templateEmailVerifyHtml
|
||||||
const token = sign<{ accountId: number; userId: number; email: string }>(
|
.replace('VERIFY_LINK', `${this.appDomain}${path}?verify=${token}`)
|
||||||
{
|
.replace(
|
||||||
accountId,
|
'VERIFY_LINK_TEXT',
|
||||||
userId,
|
`${this.appDomain}${path}?verify=${token}`,
|
||||||
email,
|
);
|
||||||
},
|
const text = this.templateEmailVerifyText
|
||||||
this.emailConfirmLifetime,
|
.replace('VERIFY_LINK', `${this.appDomain}${path}?verify=${token}`)
|
||||||
privateKey,
|
.replace(
|
||||||
);
|
'VERIFY_LINK_TEXT',
|
||||||
const path = 'mail-confirm/';
|
`${this.appDomain}${path}?verify=${token}`,
|
||||||
|
);
|
||||||
|
|
||||||
this.logger.log(
|
return {
|
||||||
`[OUT] [${context.getTrackingId()}] ${
|
subject: 'Verify your new account',
|
||||||
this.createMailContentFromEmailConfirm.name
|
text: text,
|
||||||
}`,
|
html: html,
|
||||||
);
|
};
|
||||||
return {
|
} finally {
|
||||||
subject: 'Verify your new account',
|
this.logger.log(
|
||||||
text: `The verification URL. ${this.appDomain}${path}?verify=${token}`,
|
`[OUT] [${context.getTrackingId()}] ${
|
||||||
html: `<p>The verification URL.<p><a href="${this.appDomain}${path}?verify=${token}">${this.appDomain}${path}?verify=${token}</a>`,
|
this.createMailContentFromEmailConfirm.name
|
||||||
};
|
}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>The verification URL.</p>
|
||||||
|
<a href="VERIFY_LINK">VERIFY_LINK_TEXT</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2
dictation_server/src/templates/template_email_verify.txt
Normal file
2
dictation_server/src/templates/template_email_verify.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
The verification URL.
|
||||||
|
VERIFY_LINK
|
||||||
Loading…
x
Reference in New Issue
Block a user