From a676d65f0ab75aa0ac627c7a9fbfc06a123742c2 Mon Sep 17 00:00:00 2001 From: "makabe.t" Date: Mon, 18 Dec 2023 04:54:53 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20633:=20HTML=E3=83=86=E3=83=B3?= =?UTF-8?q?=E3=83=97=E3=83=AC=E3=83=BC=E3=83=88=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=81=AE=E5=BD=A2=E5=BC=8F=E3=82=92=E6=B1=BA=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3320: HTMLテンプレートファイルの形式を決定](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3320) - HTMLテンプレートの形式を見ていただくにあたって、ライセンス注文キャンセルでテンプレートからメールを生成する処理を実装しました。 - ライセンス注文キャンセルメールのテンプレートを追加しています。 - メール送信時にTOとCCに複数人を設定できるように修正しました。 ## レビューポイント - テンプレート中で置き換える文字列を定数として定義していますが違和感はないでしょうか? - テンプレートの文言置き換え処理ですべてのパターンに引っかかるように正規表現で検索していますが問題ないでしょうか? - HTMLテンプレート、メール表示内容に違和感はないでしょうか? ## UIの変更 - [Task3320](https://ndstokyo.sharepoint.com/:f:/r/sites/Piranha/Shared%20Documents/General/OMDS/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88/Task3320?csf=1&web=1&e=yU9aDH) ## 動作確認状況 - ローカルで確認 --- .../src/features/accounts/accounts.service.ts | 6 +- .../src/features/users/users.service.ts | 8 ++- .../src/gateways/sendgrid/sendgrid.service.ts | 60 ++++++++++++++++-- dictation_server/src/templates/constants.ts | 4 ++ .../src/templates/template_U_106.html | 63 +++++++++++++++++++ .../src/templates/template_U_106.txt | 38 +++++++++++ 6 files changed, 169 insertions(+), 10 deletions(-) create mode 100644 dictation_server/src/templates/constants.ts create mode 100644 dictation_server/src/templates/template_U_106.html create mode 100644 dictation_server/src/templates/template_U_106.txt diff --git a/dictation_server/src/features/accounts/accounts.service.ts b/dictation_server/src/features/accounts/accounts.service.ts index ba76c63..bad087b 100644 --- a/dictation_server/src/features/accounts/accounts.service.ts +++ b/dictation_server/src/features/accounts/accounts.service.ts @@ -299,7 +299,8 @@ export class AccountsService { // メールを送信 await this.sendgridService.sendMail( context, - email, + [email], + [], this.mailFrom, subject, text, @@ -865,7 +866,8 @@ export class AccountsService { ); await this.sendgridService.sendMail( context, - email, + [email], + [], this.mailFrom, subject, text, diff --git a/dictation_server/src/features/users/users.service.ts b/dictation_server/src/features/users/users.service.ts index 9221ead..cb7606b 100644 --- a/dictation_server/src/features/users/users.service.ts +++ b/dictation_server/src/features/users/users.service.ts @@ -298,7 +298,8 @@ export class UsersService { //SendGridAPIを呼び出してメールを送信する await this.sendgridService.sendMail( context, - email, + [email], + [], this.mailFrom, subject, text, @@ -506,7 +507,8 @@ export class UsersService { // メールを送信 await this.sendgridService.sendMail( context, - email, + [email], + [], this.mailFrom, subject, text, @@ -574,7 +576,7 @@ export class UsersService { if (adb2cUser == null) { throw new Error('mail not found.'); // TODO: リファクタ時に挙動を変更しないようエラー文面をmail not foundのまま据え置き。影響がない事が確認できたらエラー文面を変更する。 } - + // メールアドレスを取得する const { emailAddress: mail } = getUserNameAndMailAddress(adb2cUser); diff --git a/dictation_server/src/gateways/sendgrid/sendgrid.service.ts b/dictation_server/src/gateways/sendgrid/sendgrid.service.ts index dbb7776..30bb16a 100644 --- a/dictation_server/src/gateways/sendgrid/sendgrid.service.ts +++ b/dictation_server/src/gateways/sendgrid/sendgrid.service.ts @@ -6,17 +6,27 @@ import { getPrivateKey } from '../../common/jwt/jwt'; import { Context } from '../../common/log'; import { readFileSync } from 'node:fs'; import path from 'node:path'; +import { + CUSTOMER_NAME, + DEALER_NAME, + LICENSE_QUANTITY, + PO_NUMBER, +} from '../../templates/constants'; @Injectable() export class SendGridService { private readonly logger = new Logger(SendGridService.name); private readonly emailConfirmLifetime: number; private readonly appDomain: string; + private readonly mailFrom: string; private readonly templateEmailVerifyHtml: string; private readonly templateEmailVerifyText: string; + private readonly templateU106Html: string; + private readonly templateU106Text: string; constructor(private readonly configService: ConfigService) { this.appDomain = this.configService.getOrThrow('APP_DOMAIN'); + this.mailFrom = this.configService.getOrThrow('MAIL_FROM'); this.emailConfirmLifetime = this.configService.getOrThrow( 'EMAIL_CONFIRM_LIFETIME', ); @@ -33,6 +43,15 @@ export class SendGridService { path.resolve(__dirname, `../../templates/template_email_verify.txt`), 'utf-8', ); + + this.templateU106Html = readFileSync( + path.resolve(__dirname, `../../templates/template_U_106.html`), + 'utf-8', + ); + this.templateU106Text = readFileSync( + path.resolve(__dirname, `../../templates/template_U_106.txt`), + 'utf-8', + ); } } @@ -161,7 +180,38 @@ export class SendGridService { `[IN] [${context.getTrackingId()}] ${this.sendMailWithU106.name}`, ); try { - // NOT IMPLEMENT + const subject = 'Cancelled License Order Notification [U-106]'; + + // メールの本文を作成する + const html = this.templateU106Html + .split(CUSTOMER_NAME) + .join(customerAccountName) + .split(DEALER_NAME) + .join(dealerAccountName) + .split(PO_NUMBER) + .join(poNumber) + .split(LICENSE_QUANTITY) + .join(`${lisenceCount}`); + const text = this.templateU106Text + .split(CUSTOMER_NAME) + .join(customerAccountName) + .split(DEALER_NAME) + .join(dealerAccountName) + .split(PO_NUMBER) + .join(poNumber) + .split(LICENSE_QUANTITY) + .join(`${lisenceCount}`); + + // メールを送信する + this.sendMail( + context, + customerMails, + dealerEmails, + this.mailFrom, + subject, + text, + html, + ); } finally { this.logger.log( `[OUT] [${context.getTrackingId()}] ${this.sendMailWithU106.name}`, @@ -181,7 +231,8 @@ export class SendGridService { */ async sendMail( context: Context, - to: string, + to: string[], + cc: string[], from: string, subject: string, text: string, @@ -194,9 +245,8 @@ export class SendGridService { from: { email: from, }, - to: { - email: to, - }, + to: to.map((v) => ({ email: v })), + cc: cc.map((v) => ({ email: v })), subject: subject, text: text, html: html, diff --git a/dictation_server/src/templates/constants.ts b/dictation_server/src/templates/constants.ts new file mode 100644 index 0000000..920b4f1 --- /dev/null +++ b/dictation_server/src/templates/constants.ts @@ -0,0 +1,4 @@ +export const CUSTOMER_NAME = '$CUSTOMER_NAME$'; +export const DEALER_NAME = '$DEALER_NAME$'; +export const LICENSE_QUANTITY = '$LICENSE_QUANTITY$'; +export const PO_NUMBER = '$PO_NUMBER$'; diff --git a/dictation_server/src/templates/template_U_106.html b/dictation_server/src/templates/template_U_106.html new file mode 100644 index 0000000..3854b11 --- /dev/null +++ b/dictation_server/src/templates/template_U_106.html @@ -0,0 +1,63 @@ + + + Cancelled License Order Notification [U-106] + + +
+

<English>

+

Dear $CUSTOMER_NAME$,

+

+ We have received the cancellation of your recent license order.
+ - Number of canceled licenses: $LICENSE_QUANTITY$
+ - PO Number: $PO_NUMBER$ +

+

+ If you need support regarding ODMS Cloud, please contact $DEALER_NAME$. +

+

+ If you have received this e-mail in error, please delete this e-mail + from your system.
+ This is an automatically generated e-mail and this mailbox is not + monitored. Please do not reply. +

+
+
+

<Deutsch>

+

Sehr geehrte(r) $CUSTOMER_NAME$,

+

+ Wir haben die Stornierung Ihrer letzten Lizenzbestellung erhalten.
+ - Anzahl der gekündigten Lizenzen: $LICENSE_QUANTITY$
+ - Bestellnummer: $PO_NUMBER$ +

+

+ Wenn Sie Unterstützung bezüglich ODMS Cloud benötigen, wenden Sie sich + bitte an $DEALER_NAME$. +

+

+ Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie + diese E-Mail bitte aus Ihrem System.
+ Dies ist eine automatisch generierte E-Mail und dieses Postfach wird + nicht überwacht. Bitte nicht antworten. +

+
+
+

<Français>

+

Chère/Cher $CUSTOMER_NAME$,

+

+ Nous avons reçu l'annulation de votre récente commande de licence.
+ - Nombre de licences annulées: $LICENSE_QUANTITY$
+ - Numéro de bon de commande: $PO_NUMBER$ +

+

+ Si vous avez besoin d'assistance concernant ODMS Cloud, veuillez + contacter $DEALER_NAME$. +

+

+ Si vous avez reçu cet e-mail par erreur, veuillez supprimer cet e-mail + de votre système.
+ Il s'agit d'un e-mail généré automatiquement et cette boîte aux lettres + n'est pas surveillée. Merci de ne pas répondre. +

+
+ + diff --git a/dictation_server/src/templates/template_U_106.txt b/dictation_server/src/templates/template_U_106.txt new file mode 100644 index 0000000..accfe09 --- /dev/null +++ b/dictation_server/src/templates/template_U_106.txt @@ -0,0 +1,38 @@ + + +Dear $CUSTOMER_NAME$, + +We have received the cancellation of your recent license order. + - Number of canceled licenses: $LICENSE_QUANTITY$ + - PO Number: $PO_NUMBER$ + +If you need support regarding ODMS Cloud, please contact $DEALER_NAME$. + +If you have received this e-mail in error, please delete this e-mail from your system. +This is an automatically generated e-mail and this mailbox is not monitored. Please do not reply. + + + +Sehr geehrte(r) $CUSTOMER_NAME$, + +Wir haben die Stornierung Ihrer letzten Lizenzbestellung erhalten. + - Anzahl der gekündigten Lizenzen: $LICENSE_QUANTITY$ + - Bestellnummer: $PO_NUMBER$ + +Wenn Sie Unterstützung bezüglich ODMS Cloud benötigen, wenden Sie sich bitte an $DEALER_NAME$. + +Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System. +Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten. + + + +Chère/Cher $CUSTOMER_NAME$, + +Nous avons reçu l'annulation de votre récente commande de licence. + - Nombre de licences annulées: $LICENSE_QUANTITY$ + - Numéro de bon de commande: $PO_NUMBER$ + +Si vous avez besoin d'assistance concernant ODMS Cloud, veuillez contacter $DEALER_NAME$. + +Si vous avez reçu cet e-mail par erreur, veuillez supprimer cet e-mail de votre système. +Il s'agit d'un e-mail généré automatiquement et cette boîte aux lettres n'est pas surveillée. Merci de ne pas répondre.