2023-03-13 22:03:06 +00:00
|
|
|
import { decodeHTML } from "entities";
|
2023-05-02 12:58:47 +00:00
|
|
|
import { createTransport } from "nodemailer";
|
2023-03-03 16:35:11 +00:00
|
|
|
import { z } from "zod";
|
2022-05-13 12:34:54 +00:00
|
|
|
|
2023-02-27 20:45:40 +00:00
|
|
|
import dayjs from "@calcom/dayjs";
|
2023-03-25 00:59:04 +00:00
|
|
|
import { getFeatureFlagMap } from "@calcom/features/flags/server/utils";
|
2022-05-13 12:34:54 +00:00
|
|
|
import { getErrorFromUnknown } from "@calcom/lib/errors";
|
|
|
|
import { serverConfig } from "@calcom/lib/serverConfig";
|
2023-03-25 00:59:04 +00:00
|
|
|
import prisma from "@calcom/prisma";
|
2022-05-13 12:34:54 +00:00
|
|
|
|
|
|
|
export default class BaseEmail {
|
2022-05-17 20:43:27 +00:00
|
|
|
name = "";
|
2022-05-13 12:34:54 +00:00
|
|
|
|
2022-06-06 17:49:56 +00:00
|
|
|
protected getTimezone() {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2023-07-28 14:22:19 +00:00
|
|
|
protected getLocale(): string {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
protected getFormattedRecipientTime({ time, format }: { time: string; format: string }) {
|
|
|
|
return dayjs(time).tz(this.getTimezone()).locale(this.getLocale()).format(format);
|
2022-06-06 17:49:56 +00:00
|
|
|
}
|
|
|
|
|
2022-05-13 12:34:54 +00:00
|
|
|
protected getNodeMailerPayload(): Record<string, unknown> {
|
|
|
|
return {};
|
|
|
|
}
|
2023-03-25 00:59:04 +00:00
|
|
|
public async sendEmail() {
|
|
|
|
const featureFlags = await getFeatureFlagMap(prisma);
|
|
|
|
/** If email kill switch exists and is active, we prevent emails being sent. */
|
|
|
|
if (featureFlags.emails) {
|
|
|
|
console.warn("Skipped Sending Email due to active Kill Switch");
|
|
|
|
return new Promise((r) => r("Skipped Sending Email due to active Kill Switch"));
|
|
|
|
}
|
2023-03-03 16:35:11 +00:00
|
|
|
|
|
|
|
const payload = this.getNodeMailerPayload();
|
|
|
|
const parseSubject = z.string().safeParse(payload?.subject);
|
|
|
|
const payloadWithUnEscapedSubject = {
|
|
|
|
...payload,
|
2023-03-13 22:03:06 +00:00
|
|
|
...(parseSubject.success && { subject: decodeHTML(parseSubject.data) }),
|
2023-03-03 16:35:11 +00:00
|
|
|
};
|
|
|
|
|
2023-08-08 19:07:09 +00:00
|
|
|
await new Promise((resolve, reject) =>
|
2023-05-09 17:08:14 +00:00
|
|
|
createTransport(this.getMailerOptions().transport).sendMail(
|
|
|
|
payloadWithUnEscapedSubject,
|
|
|
|
(_err, info) => {
|
2022-05-13 12:34:54 +00:00
|
|
|
if (_err) {
|
|
|
|
const err = getErrorFromUnknown(_err);
|
|
|
|
this.printNodeMailerError(err);
|
|
|
|
reject(err);
|
|
|
|
} else {
|
|
|
|
resolve(info);
|
|
|
|
}
|
2023-05-09 17:08:14 +00:00
|
|
|
}
|
|
|
|
)
|
2022-05-13 12:34:54 +00:00
|
|
|
).catch((e) => console.error("sendEmail", e));
|
|
|
|
return new Promise((resolve) => resolve("send mail async"));
|
|
|
|
}
|
|
|
|
|
|
|
|
protected getMailerOptions() {
|
|
|
|
return {
|
|
|
|
transport: serverConfig.transport,
|
|
|
|
from: serverConfig.from,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
protected printNodeMailerError(error: Error): void {
|
|
|
|
/** Don't clog the logs with unsent emails in E2E */
|
|
|
|
if (process.env.NEXT_PUBLIC_IS_E2E) return;
|
|
|
|
console.error(`${this.name}_ERROR`, error);
|
|
|
|
}
|
|
|
|
}
|