shimoda.m b3845187f6 Merged PR 1009: Revert "Merged PR 1006: 2025/1/27 PH1エンハンス 本番リリース"
Revert "Merged PR 1006: 2025/1/27 PH1エンハンス 本番リリース"

Reverted commit `b5293888`.

デプロイミスによる切り戻し
2025-01-21 04:47:21 +00:00

1664 lines
59 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,
TEMPORARY_PASSWORD,
EMAIL_DUPLICATION_EN,
AUTHOR_ID_DUPLICATION_EN,
UNEXPECTED_ERROR_EN,
EMAIL_DUPLICATION_DE,
AUTHOR_ID_DUPLICATION_DE,
UNEXPECTED_ERROR_DE,
EMAIL_DUPLICATION_FR,
AUTHOR_ID_DUPLICATION_FR,
UNEXPECTED_ERROR_FR,
REQUEST_TIME,
NO_ERROR_MESSAGE_EN,
NO_ERROR_MESSAGE_DE,
NO_ERROR_MESSAGE_FR,
} from '../../templates/constants';
import { URL } from 'node:url';
@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 templateU101Html: string;
private readonly templateU101Text: string;
private readonly templateU102Html: string;
private readonly templateU102Text: 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;
// U-108のテンプレート差分親アカウントがない場合
private readonly templateU108NoParentHtml: string;
private readonly templateU108NoParentText: 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 templateU113Html: string;
private readonly templateU113Text: string;
private readonly templateU114Html: string;
private readonly templateU114Text: string;
private readonly templateU115Html: string;
private readonly templateU115Text: string;
private readonly templateU116Html: string;
private readonly templateU116Text: string;
private readonly templateU117Html: string;
private readonly templateU117Text: string;
private readonly templateU118Html: string;
private readonly templateU118Text: string;
private readonly templateU118NoParentHtml: string;
private readonly templateU118NoParentText: string;
private readonly templateU119Html: string;
private readonly templateU119Text: string;
private readonly templateU119NoParentHtml: string;
private readonly templateU119NoParentText: string;
private readonly templateU120Html: string;
private readonly templateU120Text: string;
private readonly templateU120NoParentHtml: string;
private readonly templateU120NoParentText: string;
private readonly templateU121Html: string;
private readonly templateU121Text: string;
private readonly templateU121NoParentHtml: string;
private readonly templateU121NoParentText: string;
private readonly templateU122Html: string;
private readonly templateU122Text: string;
private readonly templateU122NoParentHtml: string;
private readonly templateU122NoParentText: string;
private readonly templateU123Html: string;
private readonly templateU123Text: string;
private readonly templateU124Html: string;
private readonly templateU124Text: 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.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.templateU102Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_102.html`),
'utf-8',
);
this.templateU102Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_102.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.templateU108NoParentHtml = readFileSync(
path.resolve(
__dirname,
`../../templates/template_U_108_no_parent.html`,
),
'utf-8',
);
this.templateU108NoParentText = readFileSync(
path.resolve(__dirname, `../../templates/template_U_108_no_parent.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.templateU113Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_113.html`),
'utf-8',
);
this.templateU113Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_113.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.templateU115Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_115.html`),
'utf-8',
);
this.templateU115Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_115.txt`),
'utf-8',
);
this.templateU116Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_116.html`),
'utf-8',
);
this.templateU116Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_116.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',
);
this.templateU118Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_118.html`),
'utf-8',
);
this.templateU118Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_118.txt`),
'utf-8',
);
this.templateU118NoParentHtml = readFileSync(
path.resolve(
__dirname,
`../../templates/template_U_118_no_parent.html`,
),
'utf-8',
);
this.templateU118NoParentText = readFileSync(
path.resolve(__dirname, `../../templates/template_U_118_no_parent.txt`),
'utf-8',
);
this.templateU119Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_119.html`),
'utf-8',
);
this.templateU119Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_119.txt`),
'utf-8',
);
this.templateU119NoParentHtml = readFileSync(
path.resolve(
__dirname,
`../../templates/template_U_119_no_parent.html`,
),
'utf-8',
);
this.templateU119NoParentText = readFileSync(
path.resolve(__dirname, `../../templates/template_U_119_no_parent.txt`),
'utf-8',
);
this.templateU120Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_120.html`),
'utf-8',
);
this.templateU120Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_120.txt`),
'utf-8',
);
this.templateU120NoParentHtml = readFileSync(
path.resolve(
__dirname,
`../../templates/template_U_120_no_parent.html`,
),
'utf-8',
);
this.templateU120NoParentText = readFileSync(
path.resolve(__dirname, `../../templates/template_U_120_no_parent.txt`),
'utf-8',
);
this.templateU121Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_121.html`),
'utf-8',
);
this.templateU121Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_121.txt`),
'utf-8',
);
this.templateU121NoParentHtml = readFileSync(
path.resolve(
__dirname,
`../../templates/template_U_121_no_parent.html`,
),
'utf-8',
);
this.templateU121NoParentText = readFileSync(
path.resolve(__dirname, `../../templates/template_U_121_no_parent.txt`),
'utf-8',
);
this.templateU122Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_122.html`),
'utf-8',
);
this.templateU122Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_122.txt`),
'utf-8',
);
this.templateU122NoParentHtml = readFileSync(
path.resolve(
__dirname,
`../../templates/template_U_122_no_parent.html`,
),
'utf-8',
);
this.templateU122NoParentText = readFileSync(
path.resolve(__dirname, `../../templates/template_U_122_no_parent.txt`),
'utf-8',
);
this.templateU123Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_123.html`),
'utf-8',
);
this.templateU123Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_123.txt`),
'utf-8',
);
this.templateU124Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_124.html`),
'utf-8',
);
this.templateU124Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_124.txt`),
'utf-8',
);
}
}
/**
* 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 url = new URL(this.appDomain).href;
const html = this.templateU101Html
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(TOP_URL, escapeDollar(url));
const text = this.templateU101Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(TOP_URL, escapeDollar(url));
await this.sendMail(
context,
[customerMail],
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU101.name}`,
);
}
}
/**
* U-102のテンプレートを使用したメールを送信する
* @param context
* @param adminEmail 登録したアカウントの管理者(primary)のメールアドレス
* @param accountId 登録したアカウントのID
* @param userId 登録したユーザーのID
* @returns mail with u102
*/
async sendMailWithU102(
context: Context,
adminEmail: string,
accountId: number,
userId: number,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU102.name}`,
);
try {
const privateKey = getPrivateKey(this.configService);
const token = sign<{ accountId: number; userId: number; email: string }>(
{
accountId,
userId,
email: adminEmail,
},
this.emailConfirmLifetime,
privateKey,
);
const paths = path.join('mail-confirm');
const url = new URL(paths, this.appDomain).href;
const verifyUrl = `${url}?verify=${token}`;
const subject = 'User Registration Notification [U-102]';
const html = this.templateU102Html.replaceAll(VERIFY_LINK, escapeDollar(verifyUrl));
const text = this.templateU102Text.replaceAll(VERIFY_LINK, escapeDollar(verifyUrl));
await this.sendMail(
context,
[adminEmail],
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU102.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, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
const text = this.templateU105Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
// メールを送信する
await 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, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
const text = this.templateU106Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
// メールを送信する
await 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, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY,escapeDollar(`${lisenceCount}`));
const text = this.templateU107Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY,escapeDollar(`${lisenceCount}`));
// メールを送信する
await this.sendMail(
context,
customerMails,
dealerEmails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU107.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 | null,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU108.name}`,
);
try {
const subject = 'License Assigned Notification [U-108]';
const url = new URL(this.appDomain).href;
let html: string;
let text: string;
if (dealerAccountName === null) {
html = this.templateU108NoParentHtml
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
text = this.templateU108NoParentText
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
} else {
html = this.templateU108Html
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
text = this.templateU108Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
}
const ccAddress = customerAdminMails.includes(userMail) ? [] : [userMail];
// メールを送信する
await this.sendMail(
context,
customerAdminMails,
ccAddress,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU108.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, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
const text = this.templateU109Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
// メールを送信する
await this.sendMail(
context,
dealerEmails,
customerMails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU109.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 url = new URL(this.appDomain).href;
// メールの本文を作成する
const html = this.templateU111Html
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
const text = this.templateU111Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
// メールを送信する
await 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;
const url = new URL(this.appDomain).href;
// 親アカウントがない場合は別のテンプレートを使用する
if (dealerAccountName === null) {
// メールの本文を作成する
html = this.templateU112NoParentHtml
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
text = this.templateU112NoParentText
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
} else {
html = this.templateU112Html
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
text = this.templateU112Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
}
// メールを送信する
await this.sendMail(
context,
[primaryAdminMail],
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU112.name}`,
);
}
}
/**
* U-113のテンプレートを使用したメールを送信する
* @param context
* @param userMail 認証済みユーザーのメールアドレス
* @param primaryAdminName 認証済みユーザーが所属するアカウントの管理者(primary)の名前
* @param temporaryPassword 認証済みユーザーの一時パスワード
* @returns mail with u113
*/
async sendMailWithU113(
context: Context,
userMail: string,
primaryAdminName: string,
temporaryPassword: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU113.name}`,
);
try {
const subject = 'Temporary password [U-113]';
// メールの本文を作成する
const html = this.templateU113Html
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TEMPORARY_PASSWORD, escapeDollar(temporaryPassword));
const text = this.templateU113Text
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TEMPORARY_PASSWORD, escapeDollar(temporaryPassword));
// メールを送信する
await this.sendMail(
context,
[userMail],
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU113.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 paths = path.join('mail-confirm', '/user');
const url = new URL(paths, this.appDomain);
const verifyUrl = `${url}?verify=${token}`;
const subject = 'User Registration Notification [U-114]';
// メールの本文を作成する
const html = this.templateU114Html
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(VERIFY_LINK, escapeDollar(verifyUrl));
const text = this.templateU114Text
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(VERIFY_LINK, escapeDollar(verifyUrl));
// メールを送信する
await this.sendMail(
context,
[userMail],
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU114.name}`,
);
}
}
/**
* U-115のテンプレートを使用したメールを送信する
* @param context
* @param userName 情報更新が行われたユーザーの名前
* @param userMail 情報更新が行われたユーザーのメールアドレス
* @param primaryAdminName 情報更新が行われたユーザーの所属するアカウントの管理者(primary)の名前
* @param adminMails 情報更新が行われたユーザーの所属するアカウントの管理者(primary/secondary)のメールアドレス
* @returns mail with u115
*/
async sendMailWithU115(
context: Context,
userName: string,
userMail: string,
primaryAdminName: string,
adminMails: string[],
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU115.name}`,
);
try {
const subject = 'Edit User Notification [U-115]';
// メールの本文を作成する
const html = this.templateU115Html
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName));
const text = this.templateU115Text
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName));
// 管理者ユーザーの情報を変更した場合にはTOに管理者のメールアドレスを設定するので、CCには管理者のメールアドレスを設定しない
const ccAdminMails = adminMails.filter((x) => x !== userMail);
// メールを送信する
await this.sendMail(
context,
[userMail],
ccAdminMails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU115.name}`,
);
}
}
/**
* U-116のテンプレートを使用したメールを送信する
* @param context
* @param userName 削除されたユーザーの名前
* @param userMail 削除されたユーザーのメールアドレス
* @param primaryAdminName 削除されたユーザーの所属するアカウントの管理者(primary)の名前
* @param adminMails 削除されたユーザーの所属するアカウントの管理者(primary/secondary)のメールアドレス
* @returns mail with u116
*/
async sendMailWithU116(
context: Context,
userName: string,
userMail: string,
primaryAdminName: string,
adminMails: string[],
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU116.name}`,
);
try {
const subject = 'User Deleted Notification [U-116]';
// メールの本文を作成する
const html = this.templateU116Html
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName));
const text = this.templateU116Text
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName));
// メールを送信する
await this.sendMail(
context,
[userMail],
adminMails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU116.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 | null,
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, escapeDollar(authorName))
.replaceAll(FILE_NAME, escapeDollar(fileName))
.replaceAll(TYPIST_NAME, escapeDollar(typistName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(adminName));
const text = this.templateU117Text
.replaceAll(AUTHOR_NAME, escapeDollar(authorName))
.replaceAll(FILE_NAME, escapeDollar(fileName))
.replaceAll(TYPIST_NAME, escapeDollar(typistName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(adminName));
// OMDS_IS-380 Dictation Workflow完了通知 [U-117]  をTypistには送信しないようにしたいの対応のため送信先からtypistEmailを削除 2024年8月7日
const to = [authorEmail].filter((x): x is string => x !== null);
if (to.length === 0) {
this.logger.log('There is no email recipient.');
return;
}
// メールを送信する
await this.sendMail(context, to, [], this.mailFrom, subject, text, html);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU117.name}`,
);
}
}
/**
* U-118のテンプレートを使用したメールを送信する
* @param context
* @param customerAdminMails アカウントの管理者(primary/secondary)のメールアドレス
* @param customerAccountName アカウントの名前
* @param dealerAccountName 問題発生時に問い合わせする先の上位のディーラー名(会社名)
* @returns mail with u118
*/
async sendMailWithU118(
context: Context,
customerAdminMails: string[],
customerAccountName: string,
dealerAccountName: string | null,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU118.name}`,
);
try {
const subject = 'Storage Usage Worning Notification [U-118]';
let html: string;
let text: string;
if (!dealerAccountName) {
html = this.templateU118NoParentHtml.replaceAll(
CUSTOMER_NAME,escapeDollar( customerAccountName),
);
text = this.templateU118NoParentText.replaceAll(
CUSTOMER_NAME,
escapeDollar(customerAccountName),
);
} else {
html = this.templateU118Html
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
text = this.templateU118Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
}
// メールを送信する
await this.sendMail(
context,
customerAdminMails,
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU118.name}`,
);
}
}
/**
* U-119のテンプレートを使用したメールを送信する
* @param context
* @param customerAdminMails アカウントの管理者(primary/secondary)のメールアドレス
* @param customerAccountName アカウントの名前
* @param dealerAccountName 問題発生時に問い合わせする先の上位のディーラー名(会社名)
* @param tire1AdminMails 第一階層の管理者(primary/secondary)のメールアドレス
* @returns mail with u119
*/
async sendMailWithU119(
context: Context,
customerAdminMails: string[],
customerAccountName: string,
dealerAccountName: string | null,
tire1AdminMails: string[],
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU119.name}`,
);
try {
const subject = 'Storage Usage Exceeded Notification [U-119]';
let html: string;
let text: string;
if (!dealerAccountName) {
html = this.templateU119NoParentHtml.replaceAll(
CUSTOMER_NAME,
escapeDollar(customerAccountName),
);
text = this.templateU119NoParentText.replaceAll(
CUSTOMER_NAME,
escapeDollar(customerAccountName),
);
} else {
html = this.templateU119Html
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
text = this.templateU119Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
}
// メールを送信する
await this.sendMail(
context,
customerAdminMails,
tire1AdminMails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU119.name}`,
);
}
}
/**
* U-120のテンプレートを使用したメールを送信する
* @param context
* @param customerAdminMails アカウントの管理者(primary/secondary)のメールアドレス
* @param customerAccountName アカウントの名前
* @param dealerAccountName 問題発生時に問い合わせする先の上位のディーラー名(会社名)
* @param tire1AdminMails 第一階層の管理者(primary/secondary)のメールアドレス
* @returns mail with u119
*/
async sendMailWithU120(
context: Context,
customerAdminMails: string[],
customerAccountName: string,
dealerAccountName: string | null,
requestTime: string,
fileName: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU120.name}`,
);
try {
const subject = 'User Bulk Registration Received Notification [U-120]';
let html: string;
let text: string;
console.log(dealerAccountName);
if (!dealerAccountName) {
html = this.templateU120NoParentHtml
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
text = this.templateU120NoParentText
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
} else {
html = this.templateU120Html
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
text = this.templateU120Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
}
// メールを送信する
await this.sendMail(
context,
customerAdminMails,
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU120.name}`,
);
}
}
/**
* U-121のテンプレートを使用したメールを送信する
* @param context
* @param customerAdminMails アカウントの管理者(primary/secondary)のメールアドレス
* @param customerAccountName アカウントの名前
* @param dealerAccountName 問題発生時に問い合わせする先の上位のディーラー名(会社名)
* @param requestTime ユーザー一括登録のリクエストを受け付けた日時
* @param fileName ユーザー一括登録で使用されたファイル名
* @returns mail with u121
*/
async sendMailWithU121(
context: Context,
customerAdminMails: string[],
customerAccountName: string,
dealerAccountName: string | null,
requestTime: string,
fileName: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU121.name}`,
);
try {
const subject = 'User Bulk Registration Completed Notification [U-121]';
let html: string;
let text: string;
if (!dealerAccountName) {
html = this.templateU121NoParentHtml
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
text = this.templateU121NoParentText
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
} else {
html = this.templateU121Html
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
text = this.templateU121Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
}
// メールを送信する
await this.sendMail(
context,
customerAdminMails,
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU121.name}`,
);
}
}
/**
* U-122のテンプレートを使用したメールを送信する
* @param context
* @param customerAdminMails アカウントの管理者(primary/secondary)のメールアドレス
* @param customerAccountName アカウントの名前
* @param dealerAccountName 問題発生時に問い合わせする先の上位のディーラー名(会社名)
* @param duplicateEmails メールアドレスの重複エラーのある行番号
* @param duplicateAuthorIds AuthorIdの重複エラーのある行番号
* @param otherErrors その他のエラーのある行番号
* @returns mail with u122
*/
async sendMailWithU122(
context: Context,
customerAdminMails: string[],
customerAccountName: string,
dealerAccountName: string | null,
duplicateEmails: number[],
duplicateAuthorIds: number[],
otherErrors: number[],
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU122.name}`,
);
try {
let duplicateEmailsMsgEn = NO_ERROR_MESSAGE_EN;
let duplicateAuthorIdsMsgEn = NO_ERROR_MESSAGE_EN;
let otherErrorsMsgEn = NO_ERROR_MESSAGE_EN;
let duplicateEmailsMsgDe = NO_ERROR_MESSAGE_DE;
let duplicateAuthorIdsMsgDe = NO_ERROR_MESSAGE_DE;
let otherErrorsMsgDe = NO_ERROR_MESSAGE_DE;
let duplicateEmailsMsgFr = NO_ERROR_MESSAGE_FR;
let duplicateAuthorIdsMsgFr = NO_ERROR_MESSAGE_FR;
let otherErrorsMsgFr = NO_ERROR_MESSAGE_FR;
if (duplicateEmails.length !== 0) {
duplicateEmailsMsgEn = duplicateEmails.map((x) => `L${x}`).join(', ');
duplicateEmailsMsgDe = duplicateEmails.map((x) => `L${x}`).join(', ');
duplicateEmailsMsgFr = duplicateEmails.map((x) => `L${x}`).join(', ');
}
if (duplicateAuthorIds.length !== 0) {
duplicateAuthorIdsMsgEn = duplicateAuthorIds
.map((x) => `L${x}`)
.join(', ');
duplicateAuthorIdsMsgDe = duplicateAuthorIds
.map((x) => `L${x}`)
.join(', ');
duplicateAuthorIdsMsgFr = duplicateAuthorIds
.map((x) => `L${x}`)
.join(', ');
}
if (otherErrors.length !== 0) {
otherErrorsMsgEn = otherErrors.map((x) => `L${x}`).join(', ');
otherErrorsMsgDe = otherErrors.map((x) => `L${x}`).join(', ');
otherErrorsMsgFr = otherErrors.map((x) => `L${x}`).join(', ');
}
const subject = 'User Bulk Registration Failed Notification [U-122]';
let html: string;
let text: string;
if (!dealerAccountName) {
html = this.templateU122NoParentHtml
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(EMAIL_DUPLICATION_EN, escapeDollar(duplicateEmailsMsgEn))
.replaceAll(EMAIL_DUPLICATION_DE, escapeDollar(duplicateEmailsMsgDe))
.replaceAll(EMAIL_DUPLICATION_FR, escapeDollar(duplicateEmailsMsgFr))
.replaceAll(AUTHOR_ID_DUPLICATION_EN, escapeDollar(duplicateAuthorIdsMsgEn))
.replaceAll(AUTHOR_ID_DUPLICATION_DE, escapeDollar(duplicateAuthorIdsMsgDe))
.replaceAll(AUTHOR_ID_DUPLICATION_FR, escapeDollar(duplicateAuthorIdsMsgFr))
.replaceAll(UNEXPECTED_ERROR_EN, escapeDollar(otherErrorsMsgEn))
.replaceAll(UNEXPECTED_ERROR_DE, escapeDollar(otherErrorsMsgDe))
.replaceAll(UNEXPECTED_ERROR_FR, escapeDollar(otherErrorsMsgFr));
text = this.templateU122NoParentText
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(EMAIL_DUPLICATION_EN, escapeDollar(duplicateEmailsMsgEn))
.replaceAll(EMAIL_DUPLICATION_DE, escapeDollar(duplicateEmailsMsgDe))
.replaceAll(EMAIL_DUPLICATION_FR, escapeDollar(duplicateEmailsMsgFr))
.replaceAll(AUTHOR_ID_DUPLICATION_EN, escapeDollar(duplicateAuthorIdsMsgEn))
.replaceAll(AUTHOR_ID_DUPLICATION_DE, escapeDollar(duplicateAuthorIdsMsgDe))
.replaceAll(AUTHOR_ID_DUPLICATION_FR, escapeDollar(duplicateAuthorIdsMsgFr))
.replaceAll(UNEXPECTED_ERROR_EN, escapeDollar(otherErrorsMsgEn))
.replaceAll(UNEXPECTED_ERROR_DE, escapeDollar(otherErrorsMsgDe))
.replaceAll(UNEXPECTED_ERROR_FR, escapeDollar(otherErrorsMsgFr));
} else {
html = this.templateU122Html
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(EMAIL_DUPLICATION_EN, escapeDollar(duplicateEmailsMsgEn))
.replaceAll(EMAIL_DUPLICATION_DE, escapeDollar(duplicateEmailsMsgDe))
.replaceAll(EMAIL_DUPLICATION_FR, escapeDollar(duplicateEmailsMsgFr))
.replaceAll(AUTHOR_ID_DUPLICATION_EN, escapeDollar(duplicateAuthorIdsMsgEn))
.replaceAll(AUTHOR_ID_DUPLICATION_DE, escapeDollar(duplicateAuthorIdsMsgDe))
.replaceAll(AUTHOR_ID_DUPLICATION_FR, escapeDollar(duplicateAuthorIdsMsgFr))
.replaceAll(UNEXPECTED_ERROR_EN, escapeDollar(otherErrorsMsgEn))
.replaceAll(UNEXPECTED_ERROR_DE, escapeDollar(otherErrorsMsgDe))
.replaceAll(UNEXPECTED_ERROR_FR, escapeDollar(otherErrorsMsgFr));
text = this.templateU122Text
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(EMAIL_DUPLICATION_EN, escapeDollar(duplicateEmailsMsgEn))
.replaceAll(EMAIL_DUPLICATION_DE, escapeDollar(duplicateEmailsMsgDe))
.replaceAll(EMAIL_DUPLICATION_FR, escapeDollar(duplicateEmailsMsgFr))
.replaceAll(AUTHOR_ID_DUPLICATION_EN, escapeDollar(duplicateAuthorIdsMsgEn))
.replaceAll(AUTHOR_ID_DUPLICATION_DE, escapeDollar(duplicateAuthorIdsMsgDe))
.replaceAll(AUTHOR_ID_DUPLICATION_FR, escapeDollar(duplicateAuthorIdsMsgFr))
.replaceAll(UNEXPECTED_ERROR_EN, escapeDollar(otherErrorsMsgEn))
.replaceAll(UNEXPECTED_ERROR_DE, escapeDollar(otherErrorsMsgDe))
.replaceAll(UNEXPECTED_ERROR_FR, escapeDollar(otherErrorsMsgFr));
}
// メールを送信する
await this.sendMail(
context,
customerAdminMails,
[],
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU122.name}`,
);
}
}
/**
* U-123のテンプレートを使用したメールを送信する
* @param context
* @param partnerAccountName
* @param partnerPrimaryName
* @param partnerPrimaryMail
* @param dealerAccountName
* @param dealerEmails
* @returns mail with u123
*/
async sendMailWithU123(
context: Context,
partnerAccountName: string,
partnerPrimaryName: string,
partnerPrimaryMail: string,
dealerAccountName: string,
dealerEmails: string[],
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU123.name}`,
);
try {
const subject = 'Partner Account Deleted Notification [U-123]';
const html = this.templateU123Html
.replaceAll(CUSTOMER_NAME, escapeDollar(partnerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(partnerPrimaryName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
const text = this.templateU123Text
.replaceAll(CUSTOMER_NAME, escapeDollar(partnerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(partnerPrimaryName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
// メールを送信する
await this.sendMail(
context,
[partnerPrimaryMail],
dealerEmails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU123.name}`,
);
}
}
/**
* U-124のテンプレートを使用したメールを送信する
* @param context
* @param partnerAccountName
* @param partnerPrimaryName
* @param partnerPrimaryMail
* @param dealerAccountName
* @param dealerEmails
* @returns mail with u124
*/
async sendMailWithU124(
context: Context,
partnerAccountName: string,
partnerPrimaryName: string,
partnerPrimaryMail: string,
dealerAccountName: string,
dealerEmails: string[],
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU124.name}`,
);
try {
const subject = 'Partner Account Edit Notification [U-124]';
const url = new URL(this.appDomain).href;
const html = this.templateU124Html
.replaceAll(CUSTOMER_NAME, escapeDollar(partnerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(partnerPrimaryName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(TOP_URL, escapeDollar(url));
const text = this.templateU124Text
.replaceAll(CUSTOMER_NAME, escapeDollar(partnerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(partnerPrimaryName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(TOP_URL, escapeDollar(url));
// メールを送信する
await this.sendMail(
context,
[partnerPrimaryMail],
dealerEmails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU124.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 {
// toの重複を削除
const uniqueTo = [...new Set(to)];
// ccの重複を削除
let uniqueCc = [...new Set(cc)];
// toとccの重複を削除cc側から削除
uniqueCc = uniqueCc.filter((email) => !uniqueTo.includes(email));
const res = await sendgrid
.send({
from: {
email: from,
},
to: uniqueTo.map((v) => ({ email: v })),
cc: uniqueCc.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}`,
);
}
}
}
/**
* 与えられた文字列内の $ を $$ にエスケープする
* @param str - エスケープする対象の文字列
* @returns エスケープ後の文字列
*/
export const escapeDollar = (str: string): string => str.replace(/\$/g, "$$$$");