From c4565da50a4ee2eab100af289c88a92b29a2b71e Mon Sep 17 00:00:00 2001
From: Dmytro Hryshyn
Date: Wed, 29 Nov 2023 15:18:00 +0200
Subject: [PATCH] chore: migrate trpc, ssgInit, ssrInit
---
apps/web/app/_trpc/createTRPCNextLayout.ts | 212 ++++++++++++++++++
apps/web/app/_trpc/serverClient.ts | 3 +
apps/web/app/_trpc/ssgInit.ts | 34 +++
apps/web/app/_trpc/ssrInit.ts | 50 +++++
apps/web/next.config.js | 5 +
apps/web/pages/api/email.ts | 2 +-
.../emails/templates/response-email.ts | 4 +-
packages/emails/README.md | 2 +-
packages/emails/email-manager.ts | 46 +---
packages/emails/src/renderEmail.ts | 5 +-
.../AdminOrganizationNotificationEmail.tsx | 2 +
.../src/templates/BrokenIntegrationEmail.tsx | 2 +
.../src/templates/SlugReplacementEmail.tsx | 2 +
.../emails/src/templates/TeamInviteEmail.tsx | 8 +-
packages/emails/templates/_base-email.ts | 19 +-
.../emails/templates/account-verify-email.ts | 4 +-
.../admin-organization-notification.ts | 4 +-
.../attendee-awaiting-payment-email.ts | 4 +-
.../templates/attendee-cancelled-email.ts | 4 +-
.../attendee-cancelled-seat-email.ts | 4 +-
...ee-daily-video-download-recording-email.ts | 4 +-
.../templates/attendee-declined-email.ts | 4 +-
.../attendee-location-change-email.ts | 4 +-
.../templates/attendee-request-email.ts | 4 +-
.../templates/attendee-rescheduled-email.ts | 4 +-
.../templates/attendee-scheduled-email.ts | 4 +-
.../emails/templates/attendee-verify-email.ts | 4 +-
...endee-was-requested-to-reschedule-email.ts | 4 +-
.../templates/broken-integration-email.ts | 4 +-
.../emails/templates/disabled-app-email.ts | 6 +-
packages/emails/templates/feedback-email.ts | 4 +-
.../emails/templates/forgot-password-email.ts | 4 +-
.../emails/templates/monthly-digest-email.ts | 4 +-
.../templates/no-show-fee-charged-email.ts | 4 +-
.../emails/templates/org-auto-join-invite.ts | 4 +-
.../organization-email-verification.ts | 4 +-
...organizer-attendee-cancelled-seat-email.ts | 4 +-
.../templates/organizer-cancelled-email.ts | 4 +-
...er-daily-video-download-recording-email.ts | 4 +-
.../organizer-location-change-email.ts | 4 +-
.../organizer-payment-refund-failed-email.ts | 4 +-
.../templates/organizer-request-email.ts | 4 +-
.../organizer-request-reminder-email.ts | 4 +-
...organizer-requested-to-reschedule-email.ts | 4 +-
.../templates/organizer-rescheduled-email.ts | 4 +-
.../templates/organizer-scheduled-email.ts | 4 +-
.../templates/slug-replacement-email.ts | 4 +-
.../emails/templates/team-invite-email.ts | 4 +-
48 files changed, 402 insertions(+), 128 deletions(-)
create mode 100644 apps/web/app/_trpc/createTRPCNextLayout.ts
create mode 100644 apps/web/app/_trpc/serverClient.ts
create mode 100644 apps/web/app/_trpc/ssgInit.ts
create mode 100644 apps/web/app/_trpc/ssrInit.ts
diff --git a/apps/web/app/_trpc/createTRPCNextLayout.ts b/apps/web/app/_trpc/createTRPCNextLayout.ts
new file mode 100644
index 00000000000000..646257bd132856
--- /dev/null
+++ b/apps/web/app/_trpc/createTRPCNextLayout.ts
@@ -0,0 +1,212 @@
+// originally from in the "experimental playground for tRPC + next.js 13" repo owned by trpc team
+// file link: https://github.com/trpc/next-13/blob/main/%40trpc/next-layout/createTRPCNextLayout.ts
+// repo link: https://github.com/trpc/next-13
+// code is / will continue to be adapted for our usage
+import { dehydrate, QueryClient } from "@tanstack/query-core";
+import type { DehydratedState, QueryKey } from "@tanstack/react-query";
+
+import type { Maybe, TRPCClientError, TRPCClientErrorLike } from "@calcom/trpc";
+import {
+ callProcedure,
+ type AnyProcedure,
+ type AnyQueryProcedure,
+ type AnyRouter,
+ type DataTransformer,
+ type inferProcedureInput,
+ type inferProcedureOutput,
+ type inferRouterContext,
+ type MaybePromise,
+ type ProcedureRouterRecord,
+} from "@calcom/trpc/server";
+
+import { createRecursiveProxy, createFlatProxy } from "@trpc/server/shared";
+
+export function getArrayQueryKey(
+ queryKey: string | [string] | [string, ...unknown[]] | unknown[],
+ type: string
+): QueryKey {
+ const queryKeyArrayed = Array.isArray(queryKey) ? queryKey : [queryKey];
+ const [arrayPath, input] = queryKeyArrayed;
+
+ if (!input && (!type || type === "any")) {
+ return arrayPath.length ? [arrayPath] : ([] as unknown as QueryKey);
+ }
+
+ return [
+ arrayPath,
+ {
+ ...(typeof input !== "undefined" && { input: input }),
+ ...(type && type !== "any" && { type: type }),
+ },
+ ];
+}
+
+// copy starts
+// copied from trpc/trpc repo
+// ref: https://github.com/trpc/trpc/blob/main/packages/next/src/withTRPC.tsx#L37-#L58
+function transformQueryOrMutationCacheErrors<
+ TState extends DehydratedState["queries"][0] | DehydratedState["mutations"][0]
+>(result: TState): TState {
+ const error = result.state.error as Maybe>;
+ if (error instanceof Error && error.name === "TRPCClientError") {
+ const newError: TRPCClientErrorLike = {
+ message: error.message,
+ data: error.data,
+ shape: error.shape,
+ };
+ return {
+ ...result,
+ state: {
+ ...result.state,
+ error: newError,
+ },
+ };
+ }
+ return result;
+}
+// copy ends
+
+interface CreateTRPCNextLayoutOptions {
+ router: TRouter;
+ createContext: () => MaybePromise>;
+ transformer?: DataTransformer;
+}
+
+/**
+ * @internal
+ */
+export type DecorateProcedure = TProcedure extends AnyQueryProcedure
+ ? {
+ fetch(input: inferProcedureInput): Promise>;
+ fetchInfinite(input: inferProcedureInput): Promise>;
+ prefetch(input: inferProcedureInput): Promise>;
+ prefetchInfinite(input: inferProcedureInput): Promise>;
+ }
+ : never;
+
+type OmitNever = Pick<
+ TType,
+ {
+ [K in keyof TType]: TType[K] extends never ? never : K;
+ }[keyof TType]
+>;
+/**
+ * @internal
+ */
+export type DecoratedProcedureRecord<
+ TProcedures extends ProcedureRouterRecord,
+ TPath extends string = ""
+> = OmitNever<{
+ [TKey in keyof TProcedures]: TProcedures[TKey] extends AnyRouter
+ ? DecoratedProcedureRecord
+ : TProcedures[TKey] extends AnyQueryProcedure
+ ? DecorateProcedure
+ : never;
+}>;
+
+type CreateTRPCNextLayout = DecoratedProcedureRecord & {
+ dehydrate(): Promise;
+ queryClient: QueryClient;
+};
+
+const getStateContainer = (opts: CreateTRPCNextLayoutOptions) => {
+ let _trpc: {
+ queryClient: QueryClient;
+ context: inferRouterContext;
+ } | null = null;
+
+ return () => {
+ if (_trpc === null) {
+ _trpc = {
+ context: opts.createContext(),
+ queryClient: new QueryClient(),
+ };
+ }
+
+ return _trpc;
+ };
+};
+
+export function createTRPCNextLayout(
+ opts: CreateTRPCNextLayoutOptions
+): CreateTRPCNextLayout {
+ const getState = getStateContainer(opts);
+
+ const transformer = opts.transformer ?? {
+ serialize: (v) => v,
+ deserialize: (v) => v,
+ };
+
+ return createFlatProxy((key) => {
+ const state = getState();
+ const { queryClient } = state;
+ if (key === "queryClient") {
+ return queryClient;
+ }
+
+ if (key === "dehydrate") {
+ // copy starts
+ // copied from trpc/trpc repo
+ // ref: https://github.com/trpc/trpc/blob/main/packages/next/src/withTRPC.tsx#L214-#L229
+ const dehydratedCache = dehydrate(queryClient, {
+ shouldDehydrateQuery() {
+ // makes sure errors are also dehydrated
+ return true;
+ },
+ });
+
+ // since error instances can't be serialized, let's make them into `TRPCClientErrorLike`-objects
+ const dehydratedCacheWithErrors = {
+ ...dehydratedCache,
+ queries: dehydratedCache.queries.map(transformQueryOrMutationCacheErrors),
+ mutations: dehydratedCache.mutations.map(transformQueryOrMutationCacheErrors),
+ };
+
+ return () => transformer.serialize(dehydratedCacheWithErrors);
+ }
+ // copy ends
+
+ return createRecursiveProxy(async (callOpts) => {
+ const path = [key, ...callOpts.path];
+ const utilName = path.pop();
+ const ctx = await state.context;
+
+ const caller = opts.router.createCaller(ctx);
+
+ const pathStr = path.join(".");
+ const input = callOpts.args[0];
+
+ if (utilName === "fetchInfinite") {
+ return queryClient.fetchInfiniteQuery(getArrayQueryKey([path, input], "infinite"), () =>
+ caller.query(pathStr, input)
+ );
+ }
+
+ if (utilName === "prefetch") {
+ return queryClient.prefetchQuery({
+ queryKey: getArrayQueryKey([path, input], "query"),
+ queryFn: async () => {
+ const res = await callProcedure({
+ procedures: opts.router._def.procedures,
+ path: pathStr,
+ rawInput: input,
+ ctx,
+ type: "query",
+ });
+ return res;
+ },
+ });
+ }
+
+ if (utilName === "prefetchInfinite") {
+ return queryClient.prefetchInfiniteQuery(getArrayQueryKey([path, input], "infinite"), () =>
+ caller.query(pathStr, input)
+ );
+ }
+
+ return queryClient.fetchQuery(getArrayQueryKey([path, input], "query"), () =>
+ caller.query(pathStr, input)
+ );
+ }) as CreateTRPCNextLayout;
+ });
+}
diff --git a/apps/web/app/_trpc/serverClient.ts b/apps/web/app/_trpc/serverClient.ts
new file mode 100644
index 00000000000000..bf453ccd2b4968
--- /dev/null
+++ b/apps/web/app/_trpc/serverClient.ts
@@ -0,0 +1,3 @@
+import { appRouter } from "@calcom/trpc/server/routers/_app";
+
+export const serverClient = appRouter.createCaller({});
diff --git a/apps/web/app/_trpc/ssgInit.ts b/apps/web/app/_trpc/ssgInit.ts
new file mode 100644
index 00000000000000..cd8929541b1bc4
--- /dev/null
+++ b/apps/web/app/_trpc/ssgInit.ts
@@ -0,0 +1,34 @@
+import { serverSideTranslations } from "next-i18next/serverSideTranslations";
+import { headers } from "next/headers";
+import superjson from "superjson";
+
+import { CALCOM_VERSION } from "@calcom/lib/constants";
+import prisma from "@calcom/prisma";
+import { appRouter } from "@calcom/trpc/server/routers/_app";
+
+import { createTRPCNextLayout } from "./createTRPCNextLayout";
+
+export async function ssgInit() {
+ const locale = headers().get("x-locale") ?? "en";
+
+ const i18n = (await serverSideTranslations(locale, ["common"])) || "en";
+
+ const ssg = createTRPCNextLayout({
+ router: appRouter,
+ transformer: superjson,
+ createContext() {
+ return { prisma, session: null, locale, i18n };
+ },
+ });
+
+ // i18n translations are already retrieved from serverSideTranslations call, there is no need to run a i18n.fetch
+ // we can set query data directly to the queryClient
+ const queryKey = [
+ ["viewer", "public", "i18n"],
+ { input: { locale, CalComVersion: CALCOM_VERSION }, type: "query" },
+ ];
+
+ ssg.queryClient.setQueryData(queryKey, { i18n });
+
+ return ssg;
+}
diff --git a/apps/web/app/_trpc/ssrInit.ts b/apps/web/app/_trpc/ssrInit.ts
new file mode 100644
index 00000000000000..ce6f89cd9a03db
--- /dev/null
+++ b/apps/web/app/_trpc/ssrInit.ts
@@ -0,0 +1,50 @@
+import { type GetServerSidePropsContext } from "next";
+import { serverSideTranslations } from "next-i18next/serverSideTranslations";
+import { headers, cookies } from "next/headers";
+import superjson from "superjson";
+
+import { getLocale } from "@calcom/features/auth/lib/getLocale";
+import { CALCOM_VERSION } from "@calcom/lib/constants";
+import prisma from "@calcom/prisma";
+import { appRouter } from "@calcom/trpc/server/routers/_app";
+
+import { createTRPCNextLayout } from "./createTRPCNextLayout";
+
+export async function ssrInit(options?: { noI18nPreload: boolean }) {
+ const req = {
+ headers: headers(),
+ cookies: cookies(),
+ };
+
+ const locale = await getLocale(req);
+
+ const i18n = (await serverSideTranslations(locale, ["common", "vital"])) || "en";
+
+ const ssr = createTRPCNextLayout({
+ router: appRouter,
+ transformer: superjson,
+ createContext() {
+ return { prisma, session: null, locale, i18n, req: req as unknown as GetServerSidePropsContext["req"] };
+ },
+ });
+
+ // i18n translations are already retrieved from serverSideTranslations call, there is no need to run a i18n.fetch
+ // we can set query data directly to the queryClient
+ const queryKey = [
+ ["viewer", "public", "i18n"],
+ { input: { locale, CalComVersion: CALCOM_VERSION }, type: "query" },
+ ];
+ if (!options?.noI18nPreload) {
+ ssr.queryClient.setQueryData(queryKey, { i18n });
+ }
+
+ await Promise.allSettled([
+ // So feature flags are available on first render
+ ssr.viewer.features.map.prefetch(),
+ // Provides a better UX to the users who have already upgraded.
+ ssr.viewer.teams.hasTeamPlan.prefetch(),
+ ssr.viewer.public.session.prefetch(),
+ ]);
+
+ return ssr;
+}
diff --git a/apps/web/next.config.js b/apps/web/next.config.js
index 24d6ceb2fcf091..f65204aa727257 100644
--- a/apps/web/next.config.js
+++ b/apps/web/next.config.js
@@ -154,6 +154,9 @@ const matcherConfigUserTypeEmbedRoute = {
/** @type {import("next").NextConfig} */
const nextConfig = {
+ experimental: {
+ serverComponentsExternalPackages: ["next-i18next"],
+ },
i18n: {
...i18n,
localeDetection: false,
@@ -231,6 +234,8 @@ const nextConfig = {
...config.resolve.fallback, // if you miss it, all the other options in fallback, specified
// by next.js will be dropped. Doesn't make much sense, but how it is
fs: false,
+ "pg-native": false,
+ "superagent-proxy": false,
};
/**
diff --git a/apps/web/pages/api/email.ts b/apps/web/pages/api/email.ts
index b855eccee2f1be..9ca6337d3217a4 100644
--- a/apps/web/pages/api/email.ts
+++ b/apps/web/pages/api/email.ts
@@ -13,7 +13,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
res.setHeader("Content-Type", "text/html");
res.setHeader("Cache-Control", "no-cache, no-store, private, must-revalidate");
res.write(
- renderEmail("MonthlyDigestEmail", {
+ await renderEmail("MonthlyDigestEmail", {
language: t,
Created: 12,
Completed: 13,
diff --git a/packages/app-store/routing-forms/emails/templates/response-email.ts b/packages/app-store/routing-forms/emails/templates/response-email.ts
index 0fa84b8ae63ba9..16e421184d56fe 100644
--- a/packages/app-store/routing-forms/emails/templates/response-email.ts
+++ b/packages/app-store/routing-forms/emails/templates/response-email.ts
@@ -25,14 +25,14 @@ export default class ResponseEmail extends BaseEmail {
this.toAddresses = toAddresses;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = this.toAddresses;
const subject = `${this.form.name} has a new response`;
return {
from: `Cal.com <${this.getMailerOptions().from}>`,
to: toAddresses.join(","),
subject,
- html: renderEmail("ResponseEmail", {
+ html: await renderEmail("ResponseEmail", {
form: this.form,
orderedResponses: this.orderedResponses,
subject,
diff --git a/packages/emails/README.md b/packages/emails/README.md
index 520b7e1ffd0bf2..ea27acba56541d 100644
--- a/packages/emails/README.md
+++ b/packages/emails/README.md
@@ -8,7 +8,7 @@
```ts
import { renderEmail } from "@calcom/emails";
-renderEmail("TeamInviteEmail", */{
+await renderEmail("TeamInviteEmail", */{
language: t,
from: "teampro@example.com",
to: "pro@example.com",
diff --git a/packages/emails/email-manager.ts b/packages/emails/email-manager.ts
index 8774278fa1fd53..8a8f5bd799b263 100644
--- a/packages/emails/email-manager.ts
+++ b/packages/emails/email-manager.ts
@@ -87,7 +87,6 @@ export const sendScheduledEmails = async (
new AttendeeScheduledEmail(
{
...calEvent,
- ...(calEvent.hideCalendarNotes && { additionalNotes: undefined }),
...(eventNameObject && {
title: getEventName({ ...eventNameObject, t: attendee.language.translate }),
}),
@@ -102,37 +101,6 @@ export const sendScheduledEmails = async (
await Promise.all(emailsToSend);
};
-// for rescheduled round robin booking that assigned new members
-export const sendRoundRobinScheduledEmails = async (calEvent: CalendarEvent, members: Person[]) => {
- const emailsToSend: Promise[] = [];
-
- for (const teamMember of members) {
- emailsToSend.push(sendEmail(() => new OrganizerScheduledEmail({ calEvent, teamMember })));
- }
-
- await Promise.all(emailsToSend);
-};
-
-export const sendRoundRobinRescheduledEmails = async (calEvent: CalendarEvent, members: Person[]) => {
- const emailsToSend: Promise[] = [];
-
- for (const teamMember of members) {
- emailsToSend.push(sendEmail(() => new OrganizerRescheduledEmail({ calEvent, teamMember })));
- }
-
- await Promise.all(emailsToSend);
-};
-
-export const sendRoundRobinCancelledEmails = async (calEvent: CalendarEvent, members: Person[]) => {
- const emailsToSend: Promise[] = [];
-
- for (const teamMember of members) {
- emailsToSend.push(sendEmail(() => new OrganizerCancelledEmail({ calEvent, teamMember })));
- }
-
- await Promise.all(emailsToSend);
-};
-
export const sendRescheduledEmails = async (calEvent: CalendarEvent) => {
const emailsToSend: Promise[] = [];
@@ -184,19 +152,7 @@ export const sendScheduledSeatsEmails = async (
}
if (!attendeeEmailDisabled) {
- emailsToSend.push(
- sendEmail(
- () =>
- new AttendeeScheduledEmail(
- {
- ...calEvent,
- ...(calEvent.hideCalendarNotes && { additionalNotes: undefined }),
- },
- invitee,
- showAttendees
- )
- )
- );
+ emailsToSend.push(sendEmail(() => new AttendeeScheduledEmail(calEvent, invitee, showAttendees)));
}
await Promise.all(emailsToSend);
};
diff --git a/packages/emails/src/renderEmail.ts b/packages/emails/src/renderEmail.ts
index 4404c94a472824..4ada467b557fd6 100644
--- a/packages/emails/src/renderEmail.ts
+++ b/packages/emails/src/renderEmail.ts
@@ -1,12 +1,11 @@
-import * as ReactDOMServer from "react-dom/server";
-
import * as templates from "./templates";
-function renderEmail(
+async function renderEmail(
template: K,
props: React.ComponentProps<(typeof templates)[K]>
) {
const Component = templates[template];
+ const ReactDOMServer = (await import("react-dom/server")).default;
return (
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
diff --git a/packages/emails/src/templates/AdminOrganizationNotificationEmail.tsx b/packages/emails/src/templates/AdminOrganizationNotificationEmail.tsx
index 1449a2ed98954e..b6e9198e56f08e 100644
--- a/packages/emails/src/templates/AdminOrganizationNotificationEmail.tsx
+++ b/packages/emails/src/templates/AdminOrganizationNotificationEmail.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { Trans, type TFunction } from "next-i18next";
import { APP_NAME, WEBAPP_URL } from "@calcom/lib/constants";
diff --git a/packages/emails/src/templates/BrokenIntegrationEmail.tsx b/packages/emails/src/templates/BrokenIntegrationEmail.tsx
index 4271d68c9108e6..d7ebe70026c383 100644
--- a/packages/emails/src/templates/BrokenIntegrationEmail.tsx
+++ b/packages/emails/src/templates/BrokenIntegrationEmail.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import type { TFunction } from "next-i18next";
import { Trans } from "react-i18next";
diff --git a/packages/emails/src/templates/SlugReplacementEmail.tsx b/packages/emails/src/templates/SlugReplacementEmail.tsx
index 8a889456ef3ce1..c40ebdb55815eb 100644
--- a/packages/emails/src/templates/SlugReplacementEmail.tsx
+++ b/packages/emails/src/templates/SlugReplacementEmail.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import type { TFunction } from "next-i18next";
import { Trans } from "next-i18next";
diff --git a/packages/emails/src/templates/TeamInviteEmail.tsx b/packages/emails/src/templates/TeamInviteEmail.tsx
index 4edc91c4e6603f..693acfa2e56c49 100644
--- a/packages/emails/src/templates/TeamInviteEmail.tsx
+++ b/packages/emails/src/templates/TeamInviteEmail.tsx
@@ -78,13 +78,13 @@ export const TeamInviteEmail = (
marginTop: "48px",
lineHeightStep: "24px",
}}>
- {/* <>
+ <>
{props.language("email_no_user_invite_steps_intro", {
entity: props.language(props.isOrg ? "organization" : "team").toLowerCase(),
})}
- > */}
+ >
- {/*
+
{!props.isCalcomMember && (
{
+ protected async getNodeMailerPayload(): Promise> {
return {};
}
public async sendEmail() {
@@ -38,17 +38,27 @@ export default class BaseEmail {
if (process.env.INTEGRATION_TEST_MODE === "true") {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-expect-error
- setTestEmail(this.getNodeMailerPayload());
+ setTestEmail(await this.getNodeMailerPayload());
console.log(
"Skipped Sending Email as process.env.NEXT_PUBLIC_UNIT_TESTS is set. Emails are available in globalThis.testEmails"
);
return new Promise((r) => r("Skipped sendEmail for Unit Tests"));
}
- const payload = this.getNodeMailerPayload();
+ const payload = await this.getNodeMailerPayload();
const parseSubject = z.string().safeParse(payload?.subject);
const payloadWithUnEscapedSubject = {
- headers: this.getMailerOptions().headers,
+ headers: {
+ "X-SMTPAPI": JSON.stringify({
+ filters: {
+ bypass_list_management: {
+ settings: {
+ enable: 1,
+ },
+ },
+ },
+ }),
+ },
...payload,
...(parseSubject.success && { subject: decodeHTML(parseSubject.data) }),
};
@@ -74,7 +84,6 @@ export default class BaseEmail {
return {
transport: serverConfig.transport,
from: serverConfig.from,
- headers: serverConfig.headers,
};
}
diff --git a/packages/emails/templates/account-verify-email.ts b/packages/emails/templates/account-verify-email.ts
index 74a651ac00ee99..6f692898aa167e 100644
--- a/packages/emails/templates/account-verify-email.ts
+++ b/packages/emails/templates/account-verify-email.ts
@@ -23,14 +23,14 @@ export default class AccountVerifyEmail extends BaseEmail {
this.verifyAccountInput = passwordEvent;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
to: `${this.verifyAccountInput.user.name} <${this.verifyAccountInput.user.email}>`,
from: `${APP_NAME} <${this.getMailerOptions().from}>`,
subject: this.verifyAccountInput.language("verify_email_subject", {
appName: APP_NAME,
}),
- html: renderEmail("VerifyAccountEmail", this.verifyAccountInput),
+ html: await renderEmail("VerifyAccountEmail", this.verifyAccountInput),
text: this.getTextBody(),
};
}
diff --git a/packages/emails/templates/admin-organization-notification.ts b/packages/emails/templates/admin-organization-notification.ts
index 680add21d09e60..01b6f469ab875e 100644
--- a/packages/emails/templates/admin-organization-notification.ts
+++ b/packages/emails/templates/admin-organization-notification.ts
@@ -22,12 +22,12 @@ export default class AdminOrganizationNotification extends BaseEmail {
this.input = input;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
from: `${APP_NAME} <${this.getMailerOptions().from}>`,
to: this.input.instanceAdmins.map((admin) => admin.email).join(","),
subject: `${this.input.t("admin_org_notification_email_subject")}`,
- html: renderEmail("AdminOrganizationNotificationEmail", {
+ html: await renderEmail("AdminOrganizationNotificationEmail", {
orgSlug: this.input.orgSlug,
webappIPAddress: this.input.webappIPAddress,
language: this.input.t,
diff --git a/packages/emails/templates/attendee-awaiting-payment-email.ts b/packages/emails/templates/attendee-awaiting-payment-email.ts
index 772b55c10b445c..24eef1262cceac 100644
--- a/packages/emails/templates/attendee-awaiting-payment-email.ts
+++ b/packages/emails/templates/attendee-awaiting-payment-email.ts
@@ -2,7 +2,7 @@ import { renderEmail } from "../";
import AttendeeScheduledEmail from "./attendee-scheduled-email";
export default class AttendeeAwaitingPaymentEmail extends AttendeeScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
to: `${this.attendee.name} <${this.attendee.email}>`,
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
@@ -11,7 +11,7 @@ export default class AttendeeAwaitingPaymentEmail extends AttendeeScheduledEmail
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("AttendeeAwaitingPaymentEmail", {
+ html: await renderEmail("AttendeeAwaitingPaymentEmail", {
calEvent: this.calEvent,
attendee: this.attendee,
}),
diff --git a/packages/emails/templates/attendee-cancelled-email.ts b/packages/emails/templates/attendee-cancelled-email.ts
index ecc128cadccc07..e3cb71b54add6b 100644
--- a/packages/emails/templates/attendee-cancelled-email.ts
+++ b/packages/emails/templates/attendee-cancelled-email.ts
@@ -2,7 +2,7 @@ import { renderEmail } from "../";
import AttendeeScheduledEmail from "./attendee-scheduled-email";
export default class AttendeeCancelledEmail extends AttendeeScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
to: `${this.attendee.name} <${this.attendee.email}>`,
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
@@ -11,7 +11,7 @@ export default class AttendeeCancelledEmail extends AttendeeScheduledEmail {
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("AttendeeCancelledEmail", {
+ html: await renderEmail("AttendeeCancelledEmail", {
calEvent: this.calEvent,
attendee: this.attendee,
}),
diff --git a/packages/emails/templates/attendee-cancelled-seat-email.ts b/packages/emails/templates/attendee-cancelled-seat-email.ts
index 396891800c5b1f..610274732e6dd7 100644
--- a/packages/emails/templates/attendee-cancelled-seat-email.ts
+++ b/packages/emails/templates/attendee-cancelled-seat-email.ts
@@ -2,7 +2,7 @@ import { renderEmail } from "../";
import AttendeeScheduledEmail from "./attendee-scheduled-email";
export default class AttendeeCancelledSeatEmail extends AttendeeScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
to: `${this.attendee.name} <${this.attendee.email}>`,
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
@@ -11,7 +11,7 @@ export default class AttendeeCancelledSeatEmail extends AttendeeScheduledEmail {
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("AttendeeCancelledSeatEmail", {
+ html: await renderEmail("AttendeeCancelledSeatEmail", {
calEvent: this.calEvent,
attendee: this.attendee,
}),
diff --git a/packages/emails/templates/attendee-daily-video-download-recording-email.ts b/packages/emails/templates/attendee-daily-video-download-recording-email.ts
index 7fc0a74d5231c9..76cfaff69017ca 100644
--- a/packages/emails/templates/attendee-daily-video-download-recording-email.ts
+++ b/packages/emails/templates/attendee-daily-video-download-recording-email.ts
@@ -21,7 +21,7 @@ export default class AttendeeDailyVideoDownloadRecordingEmail extends BaseEmail
this.downloadLink = downloadLink;
this.t = attendee.language.translate;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
to: `${this.attendee.name} <${this.attendee.email}>`,
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
@@ -30,7 +30,7 @@ export default class AttendeeDailyVideoDownloadRecordingEmail extends BaseEmail
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("DailyVideoDownloadRecordingEmail", {
+ html: await renderEmail("DailyVideoDownloadRecordingEmail", {
title: this.calEvent.title,
date: this.getFormattedDate(),
downloadLink: this.downloadLink,
diff --git a/packages/emails/templates/attendee-declined-email.ts b/packages/emails/templates/attendee-declined-email.ts
index 2d7fe6d33ba5c0..8ff713332cbabb 100644
--- a/packages/emails/templates/attendee-declined-email.ts
+++ b/packages/emails/templates/attendee-declined-email.ts
@@ -2,7 +2,7 @@ import { renderEmail } from "../";
import AttendeeScheduledEmail from "./attendee-scheduled-email";
export default class AttendeeDeclinedEmail extends AttendeeScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
to: `${this.attendee.name} <${this.attendee.email}>`,
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
@@ -11,7 +11,7 @@ export default class AttendeeDeclinedEmail extends AttendeeScheduledEmail {
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("AttendeeDeclinedEmail", {
+ html: await renderEmail("AttendeeDeclinedEmail", {
calEvent: this.calEvent,
attendee: this.attendee,
}),
diff --git a/packages/emails/templates/attendee-location-change-email.ts b/packages/emails/templates/attendee-location-change-email.ts
index 925ba0806df7c0..af15fec058bd30 100644
--- a/packages/emails/templates/attendee-location-change-email.ts
+++ b/packages/emails/templates/attendee-location-change-email.ts
@@ -2,7 +2,7 @@ import { renderEmail } from "../";
import AttendeeScheduledEmail from "./attendee-scheduled-email";
export default class AttendeeLocationChangeEmail extends AttendeeScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
icalEvent: {
filename: "event.ics",
@@ -16,7 +16,7 @@ export default class AttendeeLocationChangeEmail extends AttendeeScheduledEmail
name: this.calEvent.team?.name || this.calEvent.organizer.name,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("AttendeeLocationChangeEmail", {
+ html: await renderEmail("AttendeeLocationChangeEmail", {
calEvent: this.calEvent,
attendee: this.attendee,
}),
diff --git a/packages/emails/templates/attendee-request-email.ts b/packages/emails/templates/attendee-request-email.ts
index 22367aaa501dc8..3f5d555b7c6832 100644
--- a/packages/emails/templates/attendee-request-email.ts
+++ b/packages/emails/templates/attendee-request-email.ts
@@ -4,7 +4,7 @@ import { renderEmail } from "../";
import AttendeeScheduledEmail from "./attendee-scheduled-email";
export default class AttendeeRequestEmail extends AttendeeScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = this.calEvent.attendees.map((attendee) => attendee.email);
return {
@@ -15,7 +15,7 @@ export default class AttendeeRequestEmail extends AttendeeScheduledEmail {
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("AttendeeRequestEmail", {
+ html: await renderEmail("AttendeeRequestEmail", {
calEvent: this.calEvent,
attendee: this.attendee,
}),
diff --git a/packages/emails/templates/attendee-rescheduled-email.ts b/packages/emails/templates/attendee-rescheduled-email.ts
index 0c7e183335f88b..85bc7543caa207 100644
--- a/packages/emails/templates/attendee-rescheduled-email.ts
+++ b/packages/emails/templates/attendee-rescheduled-email.ts
@@ -2,7 +2,7 @@ import { renderEmail } from "../";
import AttendeeScheduledEmail from "./attendee-scheduled-email";
export default class AttendeeRescheduledEmail extends AttendeeScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
icalEvent: {
filename: "event.ics",
@@ -15,7 +15,7 @@ export default class AttendeeRescheduledEmail extends AttendeeScheduledEmail {
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("AttendeeRescheduledEmail", {
+ html: await renderEmail("AttendeeRescheduledEmail", {
calEvent: this.calEvent,
attendee: this.attendee,
}),
diff --git a/packages/emails/templates/attendee-scheduled-email.ts b/packages/emails/templates/attendee-scheduled-email.ts
index 0d228911183985..c2dba8dcc5c163 100644
--- a/packages/emails/templates/attendee-scheduled-email.ts
+++ b/packages/emails/templates/attendee-scheduled-email.ts
@@ -82,7 +82,7 @@ export default class AttendeeScheduledEmail extends BaseEmail {
return icsEvent.value;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const clonedCalEvent = cloneDeep(this.calEvent);
this.getiCalEventAsString();
@@ -97,7 +97,7 @@ export default class AttendeeScheduledEmail extends BaseEmail {
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
replyTo: [...this.calEvent.attendees.map(({ email }) => email), this.calEvent.organizer.email],
subject: `${this.calEvent.title}`,
- html: renderEmail("AttendeeScheduledEmail", {
+ html: await renderEmail("AttendeeScheduledEmail", {
calEvent: clonedCalEvent,
attendee: this.attendee,
}),
diff --git a/packages/emails/templates/attendee-verify-email.ts b/packages/emails/templates/attendee-verify-email.ts
index 99e9e3e31fb862..7919b8aa34de91 100644
--- a/packages/emails/templates/attendee-verify-email.ts
+++ b/packages/emails/templates/attendee-verify-email.ts
@@ -23,14 +23,14 @@ export default class AttendeeVerifyEmail extends BaseEmail {
this.verifyAccountInput = passwordEvent;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
to: `${this.verifyAccountInput.user.name} <${this.verifyAccountInput.user.email}>`,
from: `${APP_NAME} <${this.getMailerOptions().from}>`,
subject: this.verifyAccountInput.language("verify_email_subject", {
appName: APP_NAME,
}),
- html: renderEmail("VerifyEmailByCode", this.verifyAccountInput),
+ html: await renderEmail("VerifyEmailByCode", this.verifyAccountInput),
text: this.getTextBody(),
};
}
diff --git a/packages/emails/templates/attendee-was-requested-to-reschedule-email.ts b/packages/emails/templates/attendee-was-requested-to-reschedule-email.ts
index 184cbf4065d39b..e5f11807a9aa18 100644
--- a/packages/emails/templates/attendee-was-requested-to-reschedule-email.ts
+++ b/packages/emails/templates/attendee-was-requested-to-reschedule-email.ts
@@ -16,7 +16,7 @@ export default class AttendeeWasRequestedToRescheduleEmail extends OrganizerSche
this.metadata = metadata;
this.t = this.calEvent.attendees[0].language.translate;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = [this.calEvent.attendees[0].email];
return {
@@ -30,7 +30,7 @@ export default class AttendeeWasRequestedToRescheduleEmail extends OrganizerSche
eventType: this.calEvent.type,
name: this.calEvent.attendees[0].name,
})}`,
- html: renderEmail("AttendeeWasRequestedToRescheduleEmail", {
+ html: await renderEmail("AttendeeWasRequestedToRescheduleEmail", {
calEvent: this.calEvent,
attendee: this.calEvent.attendees[0],
metadata: this.metadata,
diff --git a/packages/emails/templates/broken-integration-email.ts b/packages/emails/templates/broken-integration-email.ts
index 12d7800a895628..1cbba4c6f168e5 100644
--- a/packages/emails/templates/broken-integration-email.ts
+++ b/packages/emails/templates/broken-integration-email.ts
@@ -21,7 +21,7 @@ export default class BrokenIntegrationEmail extends BaseEmail {
this.type = type;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = [this.calEvent.organizer.email];
return {
@@ -32,7 +32,7 @@ export default class BrokenIntegrationEmail extends BaseEmail {
name: this.calEvent.attendees[0].name,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("BrokenIntegrationEmail", {
+ html: await renderEmail("BrokenIntegrationEmail", {
calEvent: this.calEvent,
attendee: this.calEvent.organizer,
type: this.type,
diff --git a/packages/emails/templates/disabled-app-email.ts b/packages/emails/templates/disabled-app-email.ts
index 0a927a179c0a7f..724bed66e1fce2 100644
--- a/packages/emails/templates/disabled-app-email.ts
+++ b/packages/emails/templates/disabled-app-email.ts
@@ -1,4 +1,4 @@
-import { TFunction } from "next-i18next";
+import type { TFunction } from "next-i18next";
import { renderEmail } from "..";
import BaseEmail from "./_base-email";
@@ -28,7 +28,7 @@ export default class DisabledAppEmail extends BaseEmail {
this.eventTypeId = eventTypeId;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
from: `Cal.com <${this.getMailerOptions().from}>`,
to: this.email,
@@ -36,7 +36,7 @@ export default class DisabledAppEmail extends BaseEmail {
this.title && this.eventTypeId
? this.t("disabled_app_affects_event_type", { appName: this.appName, eventType: this.title })
: this.t("admin_has_disabled", { appName: this.appName }),
- html: renderEmail("DisabledAppEmail", {
+ html: await renderEmail("DisabledAppEmail", {
title: this.title,
appName: this.appName,
eventTypeId: this.eventTypeId,
diff --git a/packages/emails/templates/feedback-email.ts b/packages/emails/templates/feedback-email.ts
index e0dd9e5d0f733a..4eef2a9f34054c 100644
--- a/packages/emails/templates/feedback-email.ts
+++ b/packages/emails/templates/feedback-email.ts
@@ -18,12 +18,12 @@ export default class FeedbackEmail extends BaseEmail {
this.feedback = feedback;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
from: `${APP_NAME} <${this.getMailerOptions().from}>`,
to: process.env.SEND_FEEDBACK_EMAIL,
subject: `User Feedback`,
- html: renderEmail("FeedbackEmail", this.feedback),
+ html: await renderEmail("FeedbackEmail", this.feedback),
text: this.getTextBody(),
};
}
diff --git a/packages/emails/templates/forgot-password-email.ts b/packages/emails/templates/forgot-password-email.ts
index 6c21606cc69d3d..7f041693b71e62 100644
--- a/packages/emails/templates/forgot-password-email.ts
+++ b/packages/emails/templates/forgot-password-email.ts
@@ -23,14 +23,14 @@ export default class ForgotPasswordEmail extends BaseEmail {
this.passwordEvent = passwordEvent;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
to: `${this.passwordEvent.user.name} <${this.passwordEvent.user.email}>`,
from: `${APP_NAME} <${this.getMailerOptions().from}>`,
subject: this.passwordEvent.language("reset_password_subject", {
appName: APP_NAME,
}),
- html: renderEmail("ForgotPasswordEmail", this.passwordEvent),
+ html: await renderEmail("ForgotPasswordEmail", this.passwordEvent),
text: this.getTextBody(),
};
}
diff --git a/packages/emails/templates/monthly-digest-email.ts b/packages/emails/templates/monthly-digest-email.ts
index 5230732f3a175f..629b389329c668 100644
--- a/packages/emails/templates/monthly-digest-email.ts
+++ b/packages/emails/templates/monthly-digest-email.ts
@@ -12,12 +12,12 @@ export default class MonthlyDigestEmail extends BaseEmail {
this.eventData = eventData;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
from: `${APP_NAME} <${this.getMailerOptions().from}>`,
to: this.eventData.admin.email,
subject: `${APP_NAME}: Your monthly digest`,
- html: renderEmail("MonthlyDigestEmail", this.eventData),
+ html: await renderEmail("MonthlyDigestEmail", this.eventData),
text: "",
};
}
diff --git a/packages/emails/templates/no-show-fee-charged-email.ts b/packages/emails/templates/no-show-fee-charged-email.ts
index 500e4393eb233b..3ede12d7195ee0 100644
--- a/packages/emails/templates/no-show-fee-charged-email.ts
+++ b/packages/emails/templates/no-show-fee-charged-email.ts
@@ -2,7 +2,7 @@ import { renderEmail } from "../";
import AttendeeScheduledEmail from "./attendee-scheduled-email";
export default class NoShowFeeChargedEmail extends AttendeeScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
if (!this.calEvent.paymentInfo?.amount) throw new Error("No payment into");
return {
to: `${this.attendee.name} <${this.attendee.email}>`,
@@ -14,7 +14,7 @@ export default class NoShowFeeChargedEmail extends AttendeeScheduledEmail {
amount: this.calEvent.paymentInfo.amount / 100,
formatParams: { amount: { currency: this.calEvent.paymentInfo?.currency } },
})}`,
- html: renderEmail("NoShowFeeChargedEmail", {
+ html: await renderEmail("NoShowFeeChargedEmail", {
calEvent: this.calEvent,
attendee: this.attendee,
}),
diff --git a/packages/emails/templates/org-auto-join-invite.ts b/packages/emails/templates/org-auto-join-invite.ts
index 002ebf7482aa75..64a2811ec66681 100644
--- a/packages/emails/templates/org-auto-join-invite.ts
+++ b/packages/emails/templates/org-auto-join-invite.ts
@@ -22,7 +22,7 @@ export default class OrgAutoJoinEmail extends BaseEmail {
this.orgAutoInviteEvent = orgAutoInviteEvent;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
to: this.orgAutoInviteEvent.to,
from: `${APP_NAME} <${this.getMailerOptions().from}>`,
@@ -32,7 +32,7 @@ export default class OrgAutoJoinEmail extends BaseEmail {
appName: APP_NAME,
entity: this.orgAutoInviteEvent.language("organization").toLowerCase(),
}),
- html: renderEmail("OrgAutoInviteEmail", this.orgAutoInviteEvent),
+ html: await renderEmail("OrgAutoInviteEmail", this.orgAutoInviteEvent),
text: "",
};
}
diff --git a/packages/emails/templates/organization-email-verification.ts b/packages/emails/templates/organization-email-verification.ts
index cfbc591df6c38a..89cfec56f48ecf 100644
--- a/packages/emails/templates/organization-email-verification.ts
+++ b/packages/emails/templates/organization-email-verification.ts
@@ -22,12 +22,12 @@ export default class OrganizationEmailVerification extends BaseEmail {
this.orgVerifyInput = orgVerifyInput;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
from: `${APP_NAME} <${this.getMailerOptions().from}>`,
to: this.orgVerifyInput.user.email,
subject: this.orgVerifyInput.language("verify_email_organization"),
- html: renderEmail("OrganisationAccountVerifyEmail", this.orgVerifyInput),
+ html: await renderEmail("OrganisationAccountVerifyEmail", this.orgVerifyInput),
text: this.getTextBody(),
};
}
diff --git a/packages/emails/templates/organizer-attendee-cancelled-seat-email.ts b/packages/emails/templates/organizer-attendee-cancelled-seat-email.ts
index fe6ce757265844..5fa17765b1bb9b 100644
--- a/packages/emails/templates/organizer-attendee-cancelled-seat-email.ts
+++ b/packages/emails/templates/organizer-attendee-cancelled-seat-email.ts
@@ -4,7 +4,7 @@ import { renderEmail } from "../";
import OrganizerScheduledEmail from "./organizer-scheduled-email";
export default class OrganizerCancelledEmail extends OrganizerScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = [this.calEvent.organizer.email];
if (this.calEvent.team) {
this.calEvent.team.members.forEach((member) => {
@@ -22,7 +22,7 @@ export default class OrganizerCancelledEmail extends OrganizerScheduledEmail {
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("OrganizerAttendeeCancelledSeatEmail", {
+ html: await renderEmail("OrganizerAttendeeCancelledSeatEmail", {
attendee: this.calEvent.organizer,
calEvent: this.calEvent,
}),
diff --git a/packages/emails/templates/organizer-cancelled-email.ts b/packages/emails/templates/organizer-cancelled-email.ts
index d0e2fb315cc4d9..3c3792e2a35bd5 100644
--- a/packages/emails/templates/organizer-cancelled-email.ts
+++ b/packages/emails/templates/organizer-cancelled-email.ts
@@ -4,7 +4,7 @@ import { renderEmail } from "../";
import OrganizerScheduledEmail from "./organizer-scheduled-email";
export default class OrganizerCancelledEmail extends OrganizerScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = [this.teamMember?.email || this.calEvent.organizer.email];
return {
@@ -14,7 +14,7 @@ export default class OrganizerCancelledEmail extends OrganizerScheduledEmail {
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("OrganizerCancelledEmail", {
+ html: await renderEmail("OrganizerCancelledEmail", {
attendee: this.calEvent.organizer,
calEvent: this.calEvent,
}),
diff --git a/packages/emails/templates/organizer-daily-video-download-recording-email.ts b/packages/emails/templates/organizer-daily-video-download-recording-email.ts
index 714ba4f7e449af..34e1549132b60b 100644
--- a/packages/emails/templates/organizer-daily-video-download-recording-email.ts
+++ b/packages/emails/templates/organizer-daily-video-download-recording-email.ts
@@ -19,7 +19,7 @@ export default class OrganizerDailyVideoDownloadRecordingEmail extends BaseEmail
this.downloadLink = downloadLink;
this.t = this.calEvent.organizer.language.translate;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
to: `${this.calEvent.organizer.email}>`,
from: `${APP_NAME} <${this.getMailerOptions().from}>`,
@@ -28,7 +28,7 @@ export default class OrganizerDailyVideoDownloadRecordingEmail extends BaseEmail
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("DailyVideoDownloadRecordingEmail", {
+ html: await renderEmail("DailyVideoDownloadRecordingEmail", {
title: this.calEvent.title,
date: this.getFormattedDate(),
downloadLink: this.downloadLink,
diff --git a/packages/emails/templates/organizer-location-change-email.ts b/packages/emails/templates/organizer-location-change-email.ts
index a0ed9e79934211..8eb1110e52f73a 100644
--- a/packages/emails/templates/organizer-location-change-email.ts
+++ b/packages/emails/templates/organizer-location-change-email.ts
@@ -4,7 +4,7 @@ import { renderEmail } from "../";
import OrganizerScheduledEmail from "./organizer-scheduled-email";
export default class OrganizerLocationChangeEmail extends OrganizerScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = [this.teamMember?.email || this.calEvent.organizer.email];
return {
@@ -20,7 +20,7 @@ export default class OrganizerLocationChangeEmail extends OrganizerScheduledEmai
name: this.calEvent.attendees[0].name,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("OrganizerLocationChangeEmail", {
+ html: await renderEmail("OrganizerLocationChangeEmail", {
attendee: this.calEvent.organizer,
calEvent: this.calEvent,
}),
diff --git a/packages/emails/templates/organizer-payment-refund-failed-email.ts b/packages/emails/templates/organizer-payment-refund-failed-email.ts
index 26818b1fd7a897..fd907ba1b52623 100644
--- a/packages/emails/templates/organizer-payment-refund-failed-email.ts
+++ b/packages/emails/templates/organizer-payment-refund-failed-email.ts
@@ -4,7 +4,7 @@ import { renderEmail } from "../";
import OrganizerScheduledEmail from "./organizer-scheduled-email";
export default class OrganizerPaymentRefundFailedEmail extends OrganizerScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = [this.teamMember?.email || this.calEvent.organizer.email];
return {
@@ -15,7 +15,7 @@ export default class OrganizerPaymentRefundFailedEmail extends OrganizerSchedule
name: this.calEvent.attendees[0].name,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("OrganizerPaymentRefundFailedEmail", {
+ html: await renderEmail("OrganizerPaymentRefundFailedEmail", {
calEvent: this.calEvent,
attendee: this.calEvent.organizer,
}),
diff --git a/packages/emails/templates/organizer-request-email.ts b/packages/emails/templates/organizer-request-email.ts
index 0267df22612563..47b82627f5715c 100644
--- a/packages/emails/templates/organizer-request-email.ts
+++ b/packages/emails/templates/organizer-request-email.ts
@@ -4,7 +4,7 @@ import { renderEmail } from "../";
import OrganizerScheduledEmail from "./organizer-scheduled-email";
export default class OrganizerRequestEmail extends OrganizerScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = [this.teamMember?.email || this.calEvent.organizer.email];
return {
@@ -12,7 +12,7 @@ export default class OrganizerRequestEmail extends OrganizerScheduledEmail {
to: toAddresses.join(","),
replyTo: [this.calEvent.organizer.email, ...this.calEvent.attendees.map(({ email }) => email)],
subject: `${this.t("awaiting_approval")}: ${this.calEvent.title}`,
- html: renderEmail("OrganizerRequestEmail", {
+ html: await renderEmail("OrganizerRequestEmail", {
calEvent: this.calEvent,
attendee: this.calEvent.organizer,
}),
diff --git a/packages/emails/templates/organizer-request-reminder-email.ts b/packages/emails/templates/organizer-request-reminder-email.ts
index b9f2c1b53c4f94..b8d5130a7acba0 100644
--- a/packages/emails/templates/organizer-request-reminder-email.ts
+++ b/packages/emails/templates/organizer-request-reminder-email.ts
@@ -4,7 +4,7 @@ import { renderEmail } from "../";
import OrganizerRequestEmail from "./organizer-request-email";
export default class OrganizerRequestReminderEmail extends OrganizerRequestEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = [this.teamMember?.email || this.calEvent.organizer.email];
return {
@@ -15,7 +15,7 @@ export default class OrganizerRequestReminderEmail extends OrganizerRequestEmail
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("OrganizerRequestReminderEmail", {
+ html: await renderEmail("OrganizerRequestReminderEmail", {
calEvent: this.calEvent,
attendee: this.calEvent.organizer,
}),
diff --git a/packages/emails/templates/organizer-requested-to-reschedule-email.ts b/packages/emails/templates/organizer-requested-to-reschedule-email.ts
index 7a601af696876d..7f8bdfb2fb18f4 100644
--- a/packages/emails/templates/organizer-requested-to-reschedule-email.ts
+++ b/packages/emails/templates/organizer-requested-to-reschedule-email.ts
@@ -15,7 +15,7 @@ export default class OrganizerRequestedToRescheduleEmail extends OrganizerSchedu
super({ calEvent });
this.metadata = metadata;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = [this.calEvent.organizer.email];
return {
@@ -30,7 +30,7 @@ export default class OrganizerRequestedToRescheduleEmail extends OrganizerSchedu
name: this.calEvent.attendees[0].name,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("OrganizerRequestedToRescheduleEmail", {
+ html: await renderEmail("OrganizerRequestedToRescheduleEmail", {
calEvent: this.calEvent,
attendee: this.calEvent.organizer,
}),
diff --git a/packages/emails/templates/organizer-rescheduled-email.ts b/packages/emails/templates/organizer-rescheduled-email.ts
index 26da823a1ebd9d..9dfa5fe9ba675a 100644
--- a/packages/emails/templates/organizer-rescheduled-email.ts
+++ b/packages/emails/templates/organizer-rescheduled-email.ts
@@ -4,7 +4,7 @@ import { renderEmail } from "../";
import OrganizerScheduledEmail from "./organizer-scheduled-email";
export default class OrganizerRescheduledEmail extends OrganizerScheduledEmail {
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const toAddresses = [this.teamMember?.email || this.calEvent.organizer.email];
return {
@@ -19,7 +19,7 @@ export default class OrganizerRescheduledEmail extends OrganizerScheduledEmail {
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
- html: renderEmail("OrganizerRescheduledEmail", {
+ html: await renderEmail("OrganizerRescheduledEmail", {
calEvent: { ...this.calEvent, attendeeSeatId: undefined },
attendee: this.calEvent.organizer,
}),
diff --git a/packages/emails/templates/organizer-scheduled-email.ts b/packages/emails/templates/organizer-scheduled-email.ts
index 76b036252e02f2..bd1a490e399a5c 100644
--- a/packages/emails/templates/organizer-scheduled-email.ts
+++ b/packages/emails/templates/organizer-scheduled-email.ts
@@ -70,7 +70,7 @@ export default class OrganizerScheduledEmail extends BaseEmail {
return icsEvent.value;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
const clonedCalEvent = cloneDeep(this.calEvent);
const toAddresses = [this.teamMember?.email || this.calEvent.organizer.email];
@@ -83,7 +83,7 @@ export default class OrganizerScheduledEmail extends BaseEmail {
to: toAddresses.join(","),
replyTo: [this.calEvent.organizer.email, ...this.calEvent.attendees.map(({ email }) => email)],
subject: `${this.newSeat ? `${this.t("new_attendee")}: ` : ""}${this.calEvent.title}`,
- html: renderEmail("OrganizerScheduledEmail", {
+ html: await renderEmail("OrganizerScheduledEmail", {
calEvent: clonedCalEvent,
attendee: this.calEvent.organizer,
teamMember: this.teamMember,
diff --git a/packages/emails/templates/slug-replacement-email.ts b/packages/emails/templates/slug-replacement-email.ts
index c9316cb28dd6db..2a2655718d0064 100644
--- a/packages/emails/templates/slug-replacement-email.ts
+++ b/packages/emails/templates/slug-replacement-email.ts
@@ -19,12 +19,12 @@ export default class SlugReplacementEmail extends BaseEmail {
this.t = t;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
from: `Cal.com <${this.getMailerOptions().from}>`,
to: this.email,
subject: this.t("email_subject_slug_replacement", { slug: this.slug }),
- html: renderEmail("SlugReplacementEmail", {
+ html: await renderEmail("SlugReplacementEmail", {
slug: this.slug,
name: this.name,
teamName: this.teamName || "",
diff --git a/packages/emails/templates/team-invite-email.ts b/packages/emails/templates/team-invite-email.ts
index d583f7dc966841..6d272bd22521df 100644
--- a/packages/emails/templates/team-invite-email.ts
+++ b/packages/emails/templates/team-invite-email.ts
@@ -24,7 +24,7 @@ export default class TeamInviteEmail extends BaseEmail {
this.teamInviteEvent = teamInviteEvent;
}
- protected getNodeMailerPayload(): Record {
+ protected async getNodeMailerPayload(): Promise> {
return {
to: this.teamInviteEvent.to,
from: `${APP_NAME} <${this.getMailerOptions().from}>`,
@@ -36,7 +36,7 @@ export default class TeamInviteEmail extends BaseEmail {
.language(this.teamInviteEvent.isOrg ? "organization" : "team")
.toLowerCase(),
}),
- html: renderEmail("TeamInviteEmail", this.teamInviteEvent),
+ html: await renderEmail("TeamInviteEmail", this.teamInviteEvent),
text: "",
};
}