* wip * update layoutHOC * wip * remove app router related code no longer used * remove more * await cookies, headers, params, serachparams * update yarn.lock * await cookies, headers, params, serachparams more * update yarn lock again * downgrade next-auth to 4.22.1 * update yarn lock * fix * update yarn lock * fix type checks * update yarn lock * await headers and cookies * restore pages folder * restore yarn.lock * update yarn.lock * await headers and cookies * remove * await params in API routes * updates * restore next.config.js * remove i18n from next.config.js * Fixed tests * Fixed types * Removed duplicate favicon.ico * Fixing more types * ImageResponse moved to next/og * Fixed prisma import issues * dynamic import for @ewsjs/xhr * remove deasync dep * dynamic import for @tryvital/vital-node * fix type checks * add back turbopack command * Type fix * Removed unneeded file * fix turbopack relative path errors * add comments * remove unneeded code * Fixed build errors * await apis * use Promise<Params> type in defaultResponderForAppDir util * refactor scim api route * fix type checks * separate app-routing.config into client-config and server-config * wip * refactor routing forms components * revert unneeded changes for easier review * fix * fix * use CustomTrans * fix type * fix unit tests * fix type error * fix build error * fix build error * fix build error * fix warnings * fix warnings * upgrade @tremor/react and tailwindcss * numCols -> numItems * fix forgot-password e2e test * fix 1 more e2e test * fix login e2e test * fix e2e tests * fix e2e tests * clean up * remove error * use tremor/react 2.11.0 * fix * rename CustomTrans to ServerTrans * address comment * fix test * fix ServerTrans * fix * fix type * fix ServerTrans usages 1 * fix translations * fix type checks * fix type checks * link styling * fix --------- Co-authored-by: Keith Williams <keithwillcode@gmail.com> Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
import type { TFunction } from "i18next";
|
|
|
|
import { getRichDescription } from "@calcom/lib/CalEventParser";
|
|
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
|
|
import { TimeFormat } from "@calcom/lib/timeFormat";
|
|
import type { CalendarEvent } from "@calcom/types/Calendar";
|
|
|
|
import { renderEmail } from "..";
|
|
import BaseEmail from "./_base-email";
|
|
|
|
export default class BrokenIntegrationEmail extends BaseEmail {
|
|
type: "calendar" | "video";
|
|
calEvent: CalendarEvent;
|
|
t: TFunction;
|
|
|
|
constructor(calEvent: CalendarEvent, type: "calendar" | "video") {
|
|
super();
|
|
this.name = "SEND_BROKEN_INTEGRATION";
|
|
this.calEvent = calEvent;
|
|
this.t = this.calEvent.organizer.language.translate;
|
|
this.type = type;
|
|
}
|
|
|
|
protected async getNodeMailerPayload(): Promise<Record<string, unknown>> {
|
|
const toAddresses = [this.calEvent.organizer.email];
|
|
|
|
return {
|
|
from: `${EMAIL_FROM_NAME} <${this.getMailerOptions().from}>`,
|
|
to: toAddresses.join(","),
|
|
subject: `[Action Required] ${this.t("confirmed_event_type_subject", {
|
|
eventType: this.calEvent.type,
|
|
name: this.calEvent.attendees[0].name,
|
|
date: this.getFormattedDate(),
|
|
})}`,
|
|
html: await renderEmail("BrokenIntegrationEmail", {
|
|
calEvent: this.calEvent,
|
|
attendee: this.calEvent.organizer,
|
|
type: this.type,
|
|
}),
|
|
text: this.getTextBody(),
|
|
};
|
|
}
|
|
|
|
protected getTextBody(
|
|
title = "",
|
|
subtitle = "emailed_you_and_any_other_attendees",
|
|
extraInfo = "",
|
|
callToAction = ""
|
|
): string {
|
|
return `
|
|
${this.t(
|
|
title || this.calEvent.recurringEvent?.count ? "new_event_scheduled_recurring" : "new_event_scheduled"
|
|
)}
|
|
${this.t(subtitle)}
|
|
${extraInfo}
|
|
${getRichDescription(this.calEvent, this.t, true)}
|
|
${callToAction}
|
|
`.trim();
|
|
}
|
|
|
|
protected getTimezone(): string {
|
|
return this.calEvent.organizer.timeZone;
|
|
}
|
|
|
|
protected getLocale(): string {
|
|
return this.calEvent.organizer.language.locale;
|
|
}
|
|
|
|
protected getOrganizerStart(format: string) {
|
|
return this.getFormattedRecipientTime({
|
|
time: this.calEvent.startTime,
|
|
format,
|
|
});
|
|
}
|
|
|
|
protected getOrganizerEnd(format: string) {
|
|
return this.getFormattedRecipientTime({
|
|
time: this.calEvent.endTime,
|
|
format,
|
|
});
|
|
}
|
|
|
|
protected getFormattedDate() {
|
|
const organizerTimeFormat = this.calEvent.organizer.timeFormat || TimeFormat.TWELVE_HOUR;
|
|
return `${this.getOrganizerStart(organizerTimeFormat)} - ${this.getOrganizerEnd(
|
|
organizerTimeFormat
|
|
)}, ${this.t(this.getOrganizerStart("dddd").toLowerCase())}, ${this.t(
|
|
this.getOrganizerStart("MMMM").toLowerCase()
|
|
)} ${this.getOrganizerStart("D, YYYY")}`;
|
|
}
|
|
}
|