makabe.t 2f2e401ae5 Merged PR 647: ユーザー認証完了のお願い [U-114] の実装
## 概要
[Task3310: ユーザー認証完了のお願い [U-114] の実装](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3310)

- ユーザー追加後の認証メール送信について正規のメール文面を出すようにしました。

## レビューポイント
- メールに渡す情報の取得内容で不自然な点はないでしょうか?
- メール送信処理に失敗した場合には仮登録したユーザーを削除する処理をそのままにしていますが問題ないでしょうか?

## UIの変更
- なし

## 動作確認状況
- ローカルで確認
2023-12-22 08:23:01 +00:00

873 lines
29 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
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';
import {
PRIMARY_ADMIN_NAME,
AUTHOR_NAME,
CUSTOMER_NAME,
DEALER_NAME,
FILE_NAME,
LICENSE_QUANTITY,
PO_NUMBER,
TOP_URL,
USER_EMAIL,
USER_NAME,
TYPIST_NAME,
VERIFY_LINK,
} 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 templateU101Html: string;
private readonly templateU101Text: string;
private readonly templateU105Html: string;
private readonly templateU105Text: string;
private readonly templateU106Html: string;
private readonly templateU106Text: string;
private readonly templateU107Html: string;
private readonly templateU107Text: string;
private readonly templateU108Html: string;
private readonly templateU108Text: string;
private readonly templateU109Html: string;
private readonly templateU109Text: string;
private readonly templateU111Html: string;
private readonly templateU111Text: string;
private readonly templateU112Html: string;
private readonly templateU112Text: string;
// U-112のテンプレート差分親アカウントがない場合
private readonly templateU112NoParentHtml: string;
private readonly templateU112NoParentText: string;
private readonly templateU114Html: string;
private readonly templateU114Text: string;
private readonly templateU117Html: string;
private readonly templateU117Text: string;
constructor(private readonly configService: ConfigService) {
this.appDomain = this.configService.getOrThrow<string>('APP_DOMAIN');
this.mailFrom = this.configService.getOrThrow<string>('MAIL_FROM');
this.emailConfirmLifetime = this.configService.getOrThrow<number>(
'EMAIL_CONFIRM_LIFETIME',
);
const key = this.configService.getOrThrow<string>('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',
);
this.templateU101Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_101.html`),
'utf-8',
);
this.templateU101Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_101.txt`),
'utf-8',
);
this.templateU105Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_105.html`),
'utf-8',
);
this.templateU105Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_105.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',
);
this.templateU107Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_107.html`),
'utf-8',
);
this.templateU107Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_107.txt`),
'utf-8',
);
this.templateU108Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_108.html`),
'utf-8',
);
this.templateU108Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_108.txt`),
'utf-8',
);
this.templateU109Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_109.html`),
'utf-8',
);
this.templateU109Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_109.txt`),
'utf-8',
);
this.templateU111Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_111.html`),
'utf-8',
);
this.templateU111Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_111.txt`),
'utf-8',
);
this.templateU112Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_112.html`),
'utf-8',
);
this.templateU112Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_112.txt`),
'utf-8',
);
this.templateU112NoParentHtml = readFileSync(
path.resolve(
__dirname,
`../../templates/template_U_112_no_parent.html`,
),
'utf-8',
);
this.templateU112NoParentText = readFileSync(
path.resolve(__dirname, `../../templates/template_U_112_no_parent.txt`),
'utf-8',
);
this.templateU114Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_114.html`),
'utf-8',
);
this.templateU114Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_114.txt`),
'utf-8',
);
this.templateU117Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_117.html`),
'utf-8',
);
this.templateU117Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_117.txt`),
'utf-8',
);
}
}
/**
* Email認証用のメールコンテンツを作成する
* @param accountId 認証対象のユーザーが所属するアカウントのID
* @param userId 認証対象のユーザーのID
* @param email 認証対象のユーザーのメールアドレス
* @returns メールのサブジェクトとコンテンツ
*/
async createMailContentFromEmailConfirm(
context: Context,
accountId: number,
userId: number,
email: string,
): Promise<{ subject: string; text: string; html: string }> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.createMailContentFromEmailConfirm.name
} | params: { ` +
`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 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}`,
);
return {
subject: 'Verify your new account',
text: text,
html: html,
};
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${
this.createMailContentFromEmailConfirm.name
}`,
);
}
}
/**
* Email認証用のメールコンテンツを作成する(一般ユーザ向け)
* @param accountId 認証対象のユーザーが所属するアカウントのID
* @param userId 認証対象のユーザーのID
* @param email 認証対象のユーザーのメールアドレス
* @returns メールのサブジェクトとコンテンツ
*/
//TODO [Task2163] 中身が管理ユーザ向けのままなので、修正の必要あり
async createMailContentFromEmailConfirmForNormalUser(
context: Context,
accountId: number,
userId: number,
email: string,
): Promise<{ subject: string; text: string; html: string }> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.createMailContentFromEmailConfirmForNormalUser.name
} | params: { ` +
`accountId: ${accountId},` +
`userId: ${userId} };`,
);
const privateKey = getPrivateKey(this.configService);
const token = sign<{ accountId: number; userId: number; email: string }>(
{
accountId,
userId,
email,
},
this.emailConfirmLifetime,
privateKey,
);
const path = 'mail-confirm/user/';
return {
subject: 'Verify your new account',
text: `The verification URL. ${this.appDomain}${path}?verify=${token}`,
html: `<p>The verification URL.<p><a href="${this.appDomain}${path}?verify=${token}">${this.appDomain}${path}?verify=${token}</a>`,
};
}
/**
* U-101のテンプレートを使用したメールを送信する
* @param context
* @param customerMail アカウント登録を行った管理者ユーザーのメールアドレス
* @param customerAccountName アカウント登録した会社名
* @returns mail with u101
*/
async sendMailWithU101(
context: Context,
customerMail: string,
customerAccountName: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU101.name}`,
);
try {
const subject = 'Account Registered Notification [U-101]';
const html = this.templateU101Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(TOP_URL, this.appDomain);
const text = this.templateU101Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(TOP_URL, this.appDomain);
await this.sendMail(
context,
[customerMail],
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU101.name}`,
);
}
}
/**
* U-105のテンプレートを使用したメールを送信する
* @param context
* @param customerMails 注文を行ったアカウントの管理者(primary/secondary)のメールアドレス
* @param customerAccountName 送信対象の企業名
* @param lisenceCount 注文を行った対象の注文の内容(ライセンス数)
* @param poNumber 注文を行った対象の注文の内容PO番号
* @param dealerEmails 問題発生時に問い合わせする先の上位のディーラーの管理者(primary/secondary)のメールアドレス
* @param dealerAccountName 問題発生時に問い合わせする先の上位のディーラー名(会社名)
* @returns mail with u105
*/
async sendMailWithU105(
context: Context,
customerMails: string[],
customerAccountName: string,
lisenceCount: number,
poNumber: string,
dealerEmails: string[],
dealerAccountName: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU105.name}`,
);
try {
const subject = 'License Requested Notification [U-105]';
// メールの本文を作成する
const html = this.templateU105Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
const text = this.templateU105Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
// メールを送信する
this.sendMail(
context,
customerMails,
dealerEmails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU105.name}`,
);
}
}
/**
* U-106のテンプレートを使用したメールを送信する
* @param context
* @param cancelUserEmailAddress 注文キャンセルを行ったアカウントの管理者(primary/secondary)のメールアドレス
* @param customerAccountName 送信対象の企業名
* @param lisenceCount 注文キャンセルを行った対象の注文の内容(ライセンス数)
* @param poNumber 注文キャンセルを行った対象の注文の内容PO番号
* @param dealerEmails 問題発生時に問い合わせする先の上位のディーラーの管理者(primary/secondary)のメールアドレス
* @param dealerAccountName 問題発生時に問い合わせする先の上位のディーラー名(会社名)
* @returns mail with u106
*/
async sendMailWithU106(
context: Context,
customerMails: string[],
customerAccountName: string,
lisenceCount: number,
poNumber: string,
dealerEmails: string[],
dealerAccountName: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU106.name}`,
);
try {
const subject = 'Cancelled License Order Notification [U-106]';
// メールの本文を作成する
const html = this.templateU106Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
const text = this.templateU106Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
// メールを送信する
this.sendMail(
context,
customerMails,
dealerEmails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU106.name}`,
);
}
}
/**
* U-107のテンプレートを使用したメールを送信する
* @param context
* @param cancelUserEmailAddress ライセンス発行をされたアカウントの管理者(primary/secondary)のメールアドレス
* @param customerAccountName 送信対象の企業名
* @param lisenceCount ライセンス発行を行った対象の注文の内容(ライセンス数)
* @param poNumber ライセンス発行を行った対象の注文の内容PO番号
* @param dealerEmails 問題発生時に問い合わせする先の上位のディーラーの管理者(primary/secondary)のメールアドレス
* @param dealerAccountName 問題発生時に問い合わせする先の上位のディーラー名(会社名)
* @returns mail with u107
*/
async sendMailWithU107(
context: Context,
customerMails: string[],
customerAccountName: string,
lisenceCount: number,
poNumber: string,
dealerEmails: string[],
dealerAccountName: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU107.name}`,
);
try {
const subject = 'License Issued Notification [U-107]';
// メールの本文を作成する
const html = this.templateU107Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
const text = this.templateU107Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
// メールを送信する
this.sendMail(
context,
customerMails,
dealerEmails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU107.name}`,
);
}
}
/**
* U-109のテンプレートを使用したメールを送信する
* @param context context
* @param dealerEmails ライセンス発行をキャンセルした上位アカウントの管理者(primary/secondary)のメールアドレス
* @param dealerAccountName ライセンス発行をキャンセルした上位アカウントの会社名
* @param lisenceCount ライセンス発行をキャンセルした対象の注文の内容(ライセンス数)
* @param poNumber ライセンス発行をキャンセルした対象の注文の内容PO番号
* @param customerMails ライセンス発行をキャンセルされたアカウントの管理者(primary/secondary)のメールアドレス
* @param customerAccountName ライセンス発行をキャンセルされたアカウントの会社名
* @returns
*/
async sendMailWithU109(
context: Context,
dealerEmails: string[],
dealerAccountName: string,
lisenceCount: number,
poNumber: string,
customerMails: string[],
customerAccountName: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU109.name}`,
);
try {
const subject = 'License Returned Notification [U-109]';
// メールの本文を作成する
const html = this.templateU109Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
const text = this.templateU109Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
// メールを送信する
this.sendMail(
context,
dealerEmails,
customerMails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU109.name}`,
);
}
}
/**
* U-108のテンプレートを使用したメールを送信する
* @param context
* @param userName ライセンス割り当てされたユーザーの名前
* @param userMail ライセンス割り当てされたユーザーのメールアドレス
* @param customerAdminMails ライセンス割り当てされたユーザーの所属するアカウントの管理者(primary/secondary)のメールアドレス
* @param customerAccountName ライセンス割り当てされたユーザーの所属するアカウントの名前
* @param dealerAccountName 問題発生時に問い合わせする先の上位のディーラー名(会社名)
* @returns mail with u108
*/
async sendMailWithU108(
context: Context,
userName: string,
userMail: string,
customerAdminMails: string[],
customerAccountName: string,
dealerAccountName: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU108.name}`,
);
try {
const subject = 'License Assigned Notification [U-108]';
// メールの本文を作成する
const html = this.templateU108Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(USER_NAME, userName)
.replaceAll(USER_EMAIL, userMail)
.replaceAll(TOP_URL, this.appDomain);
const text = this.templateU108Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(USER_NAME, userName)
.replaceAll(USER_EMAIL, userMail)
.replaceAll(TOP_URL, this.appDomain);
// メールを送信する
this.sendMail(
context,
[userMail],
customerAdminMails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU108.name}`,
);
}
}
/**
* U-111のテンプレートを使用したメールを送信する
* @param context
* @param primaryAdminName 削除されたアカウントの管理者(primary)の名前
* @param primaryAdminMail 削除されたアカウントの管理者(primary)のメールアドレス
* @param customerAccountName 削除されたアカウントの会社名
* @returns mail with u111
*/
async sendMailWithU111(
context: Context,
primaryAdminName: string,
primaryAdminMail: string,
customerAccountName: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU111.name}`,
);
try {
const subject = 'Account Deleted Notification [U-111]';
// メールの本文を作成する
const html = this.templateU111Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, this.appDomain);
const text = this.templateU111Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, this.appDomain);
// メールを送信する
this.sendMail(
context,
[primaryAdminMail],
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU111.name}`,
);
}
}
/**
* U-112のテンプレートを使用したメールを送信する
* @param context
* @param primaryAdminName 情報変更を行ったアカウントの管理者(primary)の名前
* @param primaryAdminMail 情報変更を行ったアカウントの管理者(primary)のメールアドレス
* @param customerAccountName 情報変更を行ったアカウントの名前
* @param dealerAccountName 問題発生時に問い合わせする先の上位のディーラー名(会社名)
* @returns mail with u112
*/
async sendMailWithU112(
context: Context,
primaryAdminName: string,
primaryAdminMail: string,
customerAccountName: string,
dealerAccountName: string | null,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU112.name}`,
);
try {
const subject = 'Account Edit Notification [U-112]';
let html: string;
let text: string;
// 親アカウントがない場合は別のテンプレートを使用する
if (dealerAccountName === null) {
// メールの本文を作成する
html = this.templateU112NoParentHtml
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, this.appDomain);
text = this.templateU112NoParentText
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, this.appDomain);
} else {
html = this.templateU112Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, this.appDomain);
text = this.templateU112Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, this.appDomain);
}
// メールを送信する
this.sendMail(
context,
[primaryAdminMail],
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU112.name}`,
);
}
}
/**
* U-114のテンプレートを使用したメールを送信する
* @param context
* @param accountId 認証対象のユーザーが所属するアカウントのID
* @param userId 認証対象のユーザーのID
* @param userMail 認証対象のユーザーのメールアドレス
* @param primaryAdminName 認証対象のユーザーが所属するアカウントの管理者(primary)の名前
* @returns mail with u114
*/
async sendMailWithU114(
context: Context,
accountId: number,
userId: number,
userMail: string,
primaryAdminName: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU114.name}`,
);
try {
// ユーザー認証用のトークンを作成する
const privateKey = getPrivateKey(this.configService);
const token = sign<{ accountId: number; userId: number; email: string }>(
{
accountId,
userId,
email: userMail,
},
this.emailConfirmLifetime,
privateKey,
);
const path = 'mail-confirm/user/';
const verifyLink = `${this.appDomain}${path}?verify=${token}`;
const subject = 'User Registration Notification [U-114]';
// メールの本文を作成する
const html = this.templateU114Html
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(VERIFY_LINK, verifyLink);
const text = this.templateU114Text
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(VERIFY_LINK, verifyLink);
// メールを送信する
this.sendMail(
context,
[userMail],
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU114.name}`,
);
}
}
/**
* U-117のテンプレートを使用したメールを送信する
* @param context
* @param authorEmail 文字起こしファイルのAuthorのメールアドレス
* @param typistEmail 文字起こしを行ったTypistのメールアドレス
* @param authorName 文字起こしファイルのAuthorの名前
* @param fileName 文字起こしファイルのファイル名
* @param typistName 文字起こしを行ったTypistの名前
* @param adminName アカウント管理者の名前(プライマリ)
* @returns mail with u117
*/
async sendMailWithU117(
context: Context,
authorEmail: string,
typistEmail: string,
authorName: string,
fileName: string,
typistName: string,
adminName: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU117.name}`,
);
try {
const subject = 'Transcription Completion Notification [U-117]';
// メールの本文を作成する
const html = this.templateU117Html
.replaceAll(AUTHOR_NAME, authorName)
.replaceAll(FILE_NAME, fileName)
.replaceAll(TYPIST_NAME, typistName)
.replaceAll(PRIMARY_ADMIN_NAME, adminName);
const text = this.templateU117Text
.replaceAll(AUTHOR_NAME, authorName)
.replaceAll(FILE_NAME, fileName)
.replaceAll(TYPIST_NAME, typistName)
.replaceAll(PRIMARY_ADMIN_NAME, adminName);
// メールを送信する
this.sendMail(
context,
[authorEmail, typistEmail],
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU117.name}`,
);
}
}
/**
* メールを送信する
* @param context
* @param to
* @param cc
* @param from
* @param subject
* @param text
* @param html
* @returns mail
*/
async sendMail(
context: Context,
to: string[],
cc: string[],
from: string,
subject: string,
text: string,
html: string,
): Promise<void> {
this.logger.log(`[IN] [${context.getTrackingId()}] ${this.sendMail.name}`);
try {
const res = await sendgrid
.send({
from: {
email: from,
},
to: to.map((v) => ({ email: v })),
cc: cc.map((v) => ({ email: v })),
subject: subject,
text: text,
html: html,
})
.then((v) => v[0]);
this.logger.log(
`[${context.getTrackingId()}] status code: ${
res.statusCode
} body: ${JSON.stringify(res.body)}`,
);
} catch (e) {
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e;
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMail.name}`,
);
}
}
}