Revert "Merged PR 1006: 2025/1/27 PH1エンハンス 本番リリース" Reverted commit `b5293888`. デプロイミスによる切り戻し
1664 lines
59 KiB
TypeScript
1664 lines
59 KiB
TypeScript
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, "$$$$"); |