From b1f169def5d65d3746dce0025f232d26474665bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B9=AF=E6=9C=AC=20=E9=96=8B?= Date: Fri, 8 Dec 2023 05:06:02 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20594:=20[TODO=E5=AF=BE=E5=87=A6]?= =?UTF-8?q?=20=E3=83=A1=E3=83=BC=E3=83=AB=E3=81=AE=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E3=81=AB=E3=81=A4=E3=81=84=E3=81=A6=E7=B7=A8=E9=9B=86=E3=81=97?= =?UTF-8?q?=E3=82=84=E3=81=99=E3=81=8F=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task2163: [TODO対処] メールの内容について編集しやすくする](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2163) - メール文面をハードコードしない構造を試作 ## レビューポイント - メールテンプレートの定義場所、定義形式、読み込み方法などは問題なさそうか ## 動作確認状況 - ローカルで確認 --- dictation_server/nest-cli.json | 6 +- .../src/gateways/sendgrid/sendgrid.service.ts | 74 +++++++++++++------ .../src/templates/template_email_verify.html | 8 ++ .../src/templates/template_email_verify.txt | 2 + 4 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 dictation_server/src/templates/template_email_verify.html create mode 100644 dictation_server/src/templates/template_email_verify.txt diff --git a/dictation_server/nest-cli.json b/dictation_server/nest-cli.json index 2566481..8791e11 100644 --- a/dictation_server/nest-cli.json +++ b/dictation_server/nest-cli.json @@ -1,5 +1,9 @@ { "$schema": "https://json.schemastore.org/nest-cli", "collection": "@nestjs/schematics", - "sourceRoot": "src" + "sourceRoot": "src", + "compilerOptions": { + "assets": ["templates/**/*.html", "templates/**/*.txt"], + "watchAssets": true + } } diff --git a/dictation_server/src/gateways/sendgrid/sendgrid.service.ts b/dictation_server/src/gateways/sendgrid/sendgrid.service.ts index f611e65..9b1edfd 100644 --- a/dictation_server/src/gateways/sendgrid/sendgrid.service.ts +++ b/dictation_server/src/gateways/sendgrid/sendgrid.service.ts @@ -4,12 +4,17 @@ import { sign } from '../../common/jwt'; import sendgrid from '@sendgrid/mail'; import { getPrivateKey } from '../../common/jwt/jwt'; import { Context } from '../../common/log'; +import { readFileSync } from 'node:fs'; +import path from 'node:path'; @Injectable() export class SendGridService { private readonly logger = new Logger(SendGridService.name); private readonly emailConfirmLifetime: number; private readonly appDomain: string; + private readonly templateEmailVerifyHtml: string; + private readonly templateEmailVerifyText: string; + constructor(private readonly configService: ConfigService) { this.appDomain = this.configService.getOrThrow('APP_DOMAIN'); this.emailConfirmLifetime = this.configService.getOrThrow( @@ -17,6 +22,18 @@ export class SendGridService { ); const key = this.configService.getOrThrow('SENDGRID_API_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},` + `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 token = sign<{ accountId: number; userId: number; email: string }>( - { - accountId, - userId, - email, - }, - this.emailConfirmLifetime, - privateKey, - ); - const path = 'mail-confirm/'; + const html = this.templateEmailVerifyHtml + .replace('VERIFY_LINK', `${this.appDomain}${path}?verify=${token}`) + .replace( + 'VERIFY_LINK_TEXT', + `${this.appDomain}${path}?verify=${token}`, + ); + const text = this.templateEmailVerifyText + .replace('VERIFY_LINK', `${this.appDomain}${path}?verify=${token}`) + .replace( + 'VERIFY_LINK_TEXT', + `${this.appDomain}${path}?verify=${token}`, + ); - this.logger.log( - `[OUT] [${context.getTrackingId()}] ${ - this.createMailContentFromEmailConfirm.name - }`, - ); - return { - subject: 'Verify your new account', - text: `The verification URL. ${this.appDomain}${path}?verify=${token}`, - html: `

The verification URL.

${this.appDomain}${path}?verify=${token}`, - }; + return { + subject: 'Verify your new account', + text: text, + html: html, + }; + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${ + this.createMailContentFromEmailConfirm.name + }`, + ); + } } /** diff --git a/dictation_server/src/templates/template_email_verify.html b/dictation_server/src/templates/template_email_verify.html new file mode 100644 index 0000000..cefecea --- /dev/null +++ b/dictation_server/src/templates/template_email_verify.html @@ -0,0 +1,8 @@ + + + + +

The verification URL.

+ VERIFY_LINK_TEXT + + \ No newline at end of file diff --git a/dictation_server/src/templates/template_email_verify.txt b/dictation_server/src/templates/template_email_verify.txt new file mode 100644 index 0000000..73a316d --- /dev/null +++ b/dictation_server/src/templates/template_email_verify.txt @@ -0,0 +1,2 @@ +The verification URL. +VERIFY_LINK \ No newline at end of file