Wrong language in emails (#1541)
* test --wip * --wip * --wip * --wip * split language into organizer-attendees * name fix for tAttendees * --WIP * added attendee locale migration, --WIP * --wip * fixed check types --wip * updated person language type * test snapshot updated * --wip * --WIP * --WIP * --WIP * test changes revert * cleanup * removed extra space from test Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>pull/1633/head^2
parent
1119d7f558
commit
af89de8004
|
@ -10,7 +10,6 @@ import { getErrorFromUnknown } from "@lib/errors";
|
|||
import EventManager from "@lib/events/EventManager";
|
||||
import { CalendarEvent } from "@lib/integrations/calendar/interfaces/Calendar";
|
||||
import prisma from "@lib/prisma";
|
||||
import { Ensure } from "@lib/types/utils";
|
||||
|
||||
import { getTranslation } from "@server/lib/i18n";
|
||||
|
||||
|
@ -78,18 +77,35 @@ async function handlePaymentSuccess(event: Stripe.Event) {
|
|||
if (!user) throw new Error("No user found");
|
||||
|
||||
const t = await getTranslation(user.locale ?? "en", "common");
|
||||
const attendeesListPromises = booking.attendees.map(async (attendee) => {
|
||||
return {
|
||||
name: attendee.name,
|
||||
email: attendee.email,
|
||||
timeZone: attendee.timeZone,
|
||||
language: {
|
||||
translate: await getTranslation(attendee.locale ?? "en", "common"),
|
||||
locale: attendee.locale ?? "en",
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const evt: Ensure<CalendarEvent, "language"> = {
|
||||
const attendeesList = await Promise.all(attendeesListPromises);
|
||||
|
||||
const evt: CalendarEvent = {
|
||||
type: booking.title,
|
||||
title: booking.title,
|
||||
description: booking.description || undefined,
|
||||
startTime: booking.startTime.toISOString(),
|
||||
endTime: booking.endTime.toISOString(),
|
||||
organizer: { email: user.email!, name: user.name!, timeZone: user.timeZone },
|
||||
attendees: booking.attendees,
|
||||
organizer: {
|
||||
email: user.email!,
|
||||
name: user.name!,
|
||||
timeZone: user.timeZone,
|
||||
language: { translate: t, locale: user.locale ?? "en" },
|
||||
},
|
||||
attendees: attendeesList,
|
||||
uid: booking.uid,
|
||||
destinationCalendar: booking.destinationCalendar || user.destinationCalendar,
|
||||
language: t,
|
||||
};
|
||||
|
||||
if (booking.location) evt.location = booking.location;
|
||||
|
|
|
@ -13,14 +13,14 @@ const translator = short();
|
|||
|
||||
export const getWhat = (calEvent: CalendarEvent) => {
|
||||
return `
|
||||
${calEvent.language("what")}:
|
||||
${calEvent.organizer.language.translate("what")}:
|
||||
${calEvent.type}
|
||||
`;
|
||||
};
|
||||
|
||||
export const getWhen = (calEvent: CalendarEvent) => {
|
||||
return `
|
||||
${calEvent.language("invitee_timezone")}:
|
||||
${calEvent.organizer.language.translate("invitee_timezone")}:
|
||||
${calEvent.attendees[0].timeZone}
|
||||
`;
|
||||
};
|
||||
|
@ -29,26 +29,26 @@ export const getWho = (calEvent: CalendarEvent) => {
|
|||
const attendees = calEvent.attendees
|
||||
.map((attendee) => {
|
||||
return `
|
||||
${attendee?.name || calEvent.language("guest")}
|
||||
${attendee?.name || calEvent.organizer.language.translate("guest")}
|
||||
${attendee.email}
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
const organizer = `
|
||||
${calEvent.organizer.name} - ${calEvent.language("organizer")}
|
||||
${calEvent.organizer.name} - ${calEvent.organizer.language.translate("organizer")}
|
||||
${calEvent.organizer.email}
|
||||
`;
|
||||
|
||||
return `
|
||||
${calEvent.language("who")}:
|
||||
${calEvent.organizer.language.translate("who")}:
|
||||
${organizer + attendees}
|
||||
`;
|
||||
};
|
||||
|
||||
export const getAdditionalNotes = (calEvent: CalendarEvent) => {
|
||||
return `
|
||||
${calEvent.language("additional_notes")}:
|
||||
${calEvent.organizer.language.translate("additional_notes")}:
|
||||
${calEvent.description}
|
||||
`;
|
||||
};
|
||||
|
@ -74,7 +74,7 @@ export const getLocation = (calEvent: CalendarEvent) => {
|
|||
|
||||
export const getManageLink = (calEvent: CalendarEvent) => {
|
||||
return `
|
||||
${calEvent.language("need_to_reschedule_or_cancel")}
|
||||
${calEvent.organizer.language.translate("need_to_reschedule_or_cancel")}
|
||||
${getCancelLink(calEvent)}
|
||||
`;
|
||||
};
|
||||
|
@ -96,7 +96,7 @@ export const getRichDescription = (calEvent: CalendarEvent, attendee?: Person) =
|
|||
${getWhat(calEvent)}
|
||||
${getWhen(calEvent)}
|
||||
${getWho(calEvent)}
|
||||
${calEvent.language("where")}:
|
||||
${calEvent.organizer.language.translate("where")}:
|
||||
${getLocation(calEvent)}
|
||||
${getAdditionalNotes(calEvent)}
|
||||
`.trim();
|
||||
|
@ -106,7 +106,7 @@ ${getAdditionalNotes(calEvent)}
|
|||
${getWhat(calEvent)}
|
||||
${getWhen(calEvent)}
|
||||
${getWho(calEvent)}
|
||||
${calEvent.language("where")}:
|
||||
${calEvent.organizer.language.translate("where")}:
|
||||
${getLocation(calEvent)}
|
||||
${getAdditionalNotes(calEvent)}
|
||||
${getManageLink(calEvent)}
|
||||
|
|
|
@ -25,14 +25,14 @@ export default class AttendeeAwaitingPaymentEmail extends AttendeeScheduledEmail
|
|||
to: `${this.attendee.name} <${this.attendee.email}>`,
|
||||
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
|
||||
replyTo: this.calEvent.organizer.email,
|
||||
subject: `${this.calEvent.language("awaiting_payment_subject", {
|
||||
subject: `${this.calEvent.attendees[0].language.translate("awaiting_payment_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.team?.name || this.calEvent.organizer.name,
|
||||
date: `${this.getInviteeStart().format("h:mma")} - ${this.getInviteeEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getInviteeStart().format("D")}, ${this.getInviteeStart().format("YYYY")}`,
|
||||
})}`,
|
||||
|
@ -43,8 +43,8 @@ export default class AttendeeAwaitingPaymentEmail extends AttendeeScheduledEmail
|
|||
|
||||
protected getTextBody(): string {
|
||||
return `
|
||||
${this.calEvent.language("meeting_awaiting_payment")}
|
||||
${this.calEvent.language("emailed_you_and_any_other_attendees")}
|
||||
${this.calEvent.attendees[0].language.translate("meeting_awaiting_payment")}
|
||||
${this.calEvent.attendees[0].language.translate("emailed_you_and_any_other_attendees")}
|
||||
${this.getWhat()}
|
||||
${this.getWhen()}
|
||||
${this.getLocation()}
|
||||
|
@ -53,14 +53,14 @@ ${this.getAdditionalNotes()}
|
|||
}
|
||||
|
||||
protected getHtmlBody(): string {
|
||||
const headerContent = this.calEvent.language("awaiting_payment_subject", {
|
||||
const headerContent = this.calEvent.attendees[0].language.translate("awaiting_payment_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.team?.name || this.calEvent.organizer.name,
|
||||
date: `${this.getInviteeStart().format("h:mma")} - ${this.getInviteeEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getInviteeStart().format("D")}, ${this.getInviteeStart().format("YYYY")}`,
|
||||
});
|
||||
|
@ -73,8 +73,8 @@ ${this.getAdditionalNotes()}
|
|||
<div style="background-color:#F5F5F5;">
|
||||
${emailSchedulingBodyHeader("calendarCircle")}
|
||||
${emailScheduledBodyHeaderContent(
|
||||
this.calEvent.language("meeting_awaiting_payment"),
|
||||
this.calEvent.language("emailed_you_and_any_other_attendees")
|
||||
this.calEvent.attendees[0].language.translate("meeting_awaiting_payment"),
|
||||
this.calEvent.attendees[0].language.translate("emailed_you_and_any_other_attendees")
|
||||
)}
|
||||
${emailSchedulingBodyDivider()}
|
||||
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
@ -148,7 +148,7 @@ ${this.getAdditionalNotes()}
|
|||
}
|
||||
|
||||
protected getManageLink(): string {
|
||||
const manageText = this.calEvent.language("pay_now");
|
||||
const manageText = this.calEvent.attendees[0].language.translate("pay_now");
|
||||
|
||||
if (this.calEvent.paymentInfo) {
|
||||
return `
|
||||
|
|
|
@ -24,14 +24,14 @@ export default class AttendeeCancelledEmail extends AttendeeScheduledEmail {
|
|||
to: `${this.attendee.name} <${this.attendee.email}>`,
|
||||
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
|
||||
replyTo: this.calEvent.organizer.email,
|
||||
subject: `${this.calEvent.language("event_cancelled_subject", {
|
||||
subject: `${this.calEvent.attendees[0].language.translate("event_cancelled_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.team?.name || this.calEvent.organizer.name,
|
||||
date: `${this.getInviteeStart().format("h:mma")} - ${this.getInviteeEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getInviteeStart().format("D")}, ${this.getInviteeStart().format("YYYY")}`,
|
||||
})}`,
|
||||
|
@ -42,8 +42,8 @@ export default class AttendeeCancelledEmail extends AttendeeScheduledEmail {
|
|||
|
||||
protected getTextBody(): string {
|
||||
return `
|
||||
${this.calEvent.language("event_request_cancelled")}
|
||||
${this.calEvent.language("emailed_you_and_any_other_attendees")}
|
||||
${this.calEvent.attendees[0].language.translate("event_request_cancelled")}
|
||||
${this.calEvent.attendees[0].language.translate("emailed_you_and_any_other_attendees")}
|
||||
${this.getWhat()}
|
||||
${this.getWhen()}
|
||||
${this.getLocation()}
|
||||
|
@ -52,14 +52,14 @@ ${this.getAdditionalNotes()}
|
|||
}
|
||||
|
||||
protected getHtmlBody(): string {
|
||||
const headerContent = this.calEvent.language("event_cancelled_subject", {
|
||||
const headerContent = this.calEvent.attendees[0].language.translate("event_cancelled_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.team?.name || this.calEvent.organizer.name,
|
||||
date: `${this.getInviteeStart().format("h:mma")} - ${this.getInviteeEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getInviteeStart().format("D")}, ${this.getInviteeStart().format("YYYY")}`,
|
||||
});
|
||||
|
@ -73,8 +73,8 @@ ${this.getAdditionalNotes()}
|
|||
<div style="background-color:#F5F5F5;">
|
||||
${emailSchedulingBodyHeader("xCircle")}
|
||||
${emailScheduledBodyHeaderContent(
|
||||
this.calEvent.language("event_request_cancelled"),
|
||||
this.calEvent.language("emailed_you_and_any_other_attendees")
|
||||
this.calEvent.attendees[0].language.translate("event_request_cancelled"),
|
||||
this.calEvent.attendees[0].language.translate("emailed_you_and_any_other_attendees")
|
||||
)}
|
||||
${emailSchedulingBodyDivider()}
|
||||
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
|
|
@ -24,14 +24,14 @@ export default class AttendeeDeclinedEmail extends AttendeeScheduledEmail {
|
|||
to: `${this.attendee.name} <${this.attendee.email}>`,
|
||||
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
|
||||
replyTo: this.calEvent.organizer.email,
|
||||
subject: `${this.calEvent.language("event_declined_subject", {
|
||||
subject: `${this.calEvent.attendees[0].language.translate("event_declined_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.team?.name || this.calEvent.organizer.name,
|
||||
date: `${this.getInviteeStart().format("h:mma")} - ${this.getInviteeEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getInviteeStart().format("D")}, ${this.getInviteeStart().format("YYYY")}`,
|
||||
})}`,
|
||||
|
@ -42,8 +42,8 @@ export default class AttendeeDeclinedEmail extends AttendeeScheduledEmail {
|
|||
|
||||
protected getTextBody(): string {
|
||||
return `
|
||||
${this.calEvent.language("event_request_declined")}
|
||||
${this.calEvent.language("emailed_you_and_any_other_attendees")}
|
||||
${this.calEvent.attendees[0].language.translate("event_request_declined")}
|
||||
${this.calEvent.attendees[0].language.translate("emailed_you_and_any_other_attendees")}
|
||||
${this.getWhat()}
|
||||
${this.getWhen()}
|
||||
${this.getLocation()}
|
||||
|
@ -52,14 +52,14 @@ ${this.getAdditionalNotes()}
|
|||
}
|
||||
|
||||
protected getHtmlBody(): string {
|
||||
const headerContent = this.calEvent.language("event_declined_subject", {
|
||||
const headerContent = this.calEvent.attendees[0].language.translate("event_declined_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.team?.name || this.calEvent.organizer.name,
|
||||
date: `${this.getInviteeStart().format("h:mma")} - ${this.getInviteeEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getInviteeStart().format("D")}, ${this.getInviteeStart().format("YYYY")}`,
|
||||
});
|
||||
|
@ -73,8 +73,8 @@ ${this.getAdditionalNotes()}
|
|||
<div style="background-color:#F5F5F5;">
|
||||
${emailSchedulingBodyHeader("xCircle")}
|
||||
${emailScheduledBodyHeaderContent(
|
||||
this.calEvent.language("event_request_declined"),
|
||||
this.calEvent.language("emailed_you_and_any_other_attendees")
|
||||
this.calEvent.attendees[0].language.translate("event_request_declined"),
|
||||
this.calEvent.attendees[0].language.translate("emailed_you_and_any_other_attendees")
|
||||
)}
|
||||
${emailSchedulingBodyDivider()}
|
||||
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
|
|
@ -30,14 +30,14 @@ export default class AttendeeRescheduledEmail extends AttendeeScheduledEmail {
|
|||
to: `${this.attendee.name} <${this.attendee.email}>`,
|
||||
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
|
||||
replyTo: this.calEvent.organizer.email,
|
||||
subject: `${this.calEvent.language("rescheduled_event_type_subject", {
|
||||
subject: `${this.calEvent.attendees[0].language.translate("rescheduled_event_type_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.team?.name || this.calEvent.organizer.name,
|
||||
date: `${this.getInviteeStart().format("h:mma")} - ${this.getInviteeEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getInviteeStart().format("D")}, ${this.getInviteeStart().format("YYYY")}`,
|
||||
})}`,
|
||||
|
@ -51,20 +51,20 @@ export default class AttendeeRescheduledEmail extends AttendeeScheduledEmail {
|
|||
// Guests cannot
|
||||
if (this.attendee === this.calEvent.attendees[0]) {
|
||||
return `
|
||||
${this.calEvent.language("event_has_been_rescheduled")}
|
||||
${this.calEvent.language("emailed_you_and_any_other_attendees")}
|
||||
${this.calEvent.attendees[0].language.translate("event_has_been_rescheduled")}
|
||||
${this.calEvent.attendees[0].language.translate("emailed_you_and_any_other_attendees")}
|
||||
${this.getWhat()}
|
||||
${this.getWhen()}
|
||||
${this.getLocation()}
|
||||
${this.getAdditionalNotes()}
|
||||
${this.calEvent.language("need_to_reschedule_or_cancel")}
|
||||
${this.calEvent.attendees[0].language.translate("need_to_reschedule_or_cancel")}
|
||||
${getCancelLink(this.calEvent)}
|
||||
`.replace(/(<([^>]+)>)/gi, "");
|
||||
}
|
||||
|
||||
return `
|
||||
${this.calEvent.language("event_has_been_rescheduled")}
|
||||
${this.calEvent.language("emailed_you_and_any_other_attendees")}
|
||||
${this.calEvent.attendees[0].language.translate("event_has_been_rescheduled")}
|
||||
${this.calEvent.attendees[0].language.translate("emailed_you_and_any_other_attendees")}
|
||||
${this.getWhat()}
|
||||
${this.getWhen()}
|
||||
${this.getLocation()}
|
||||
|
@ -73,14 +73,14 @@ ${this.getAdditionalNotes()}
|
|||
}
|
||||
|
||||
protected getHtmlBody(): string {
|
||||
const headerContent = this.calEvent.language("rescheduled_event_type_subject", {
|
||||
const headerContent = this.calEvent.attendees[0].language.translate("rescheduled_event_type_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.team?.name || this.calEvent.organizer.name,
|
||||
date: `${this.getInviteeStart().format("h:mma")} - ${this.getInviteeEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getInviteeStart().format("D")}, ${this.getInviteeStart().format("YYYY")}`,
|
||||
});
|
||||
|
@ -93,8 +93,8 @@ ${this.getAdditionalNotes()}
|
|||
<div style="background-color:#F5F5F5;">
|
||||
${emailSchedulingBodyHeader("calendarCircle")}
|
||||
${emailScheduledBodyHeaderContent(
|
||||
this.calEvent.language("event_has_been_rescheduled"),
|
||||
this.calEvent.language("emailed_you_and_any_other_attendees")
|
||||
this.calEvent.attendees[0].language.translate("event_has_been_rescheduled"),
|
||||
this.calEvent.attendees[0].language.translate("emailed_you_and_any_other_attendees")
|
||||
)}
|
||||
${emailSchedulingBodyDivider()}
|
||||
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
|
|
@ -61,7 +61,7 @@ export default class AttendeeScheduledEmail {
|
|||
.map((v, i) => (i === 1 ? v + 1 : v)) as DateArray,
|
||||
startInputType: "utc",
|
||||
productId: "calendso/ics",
|
||||
title: this.calEvent.language("ics_event_title", {
|
||||
title: this.calEvent.attendees[0].language.translate("ics_event_title", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
}),
|
||||
|
@ -89,14 +89,14 @@ export default class AttendeeScheduledEmail {
|
|||
to: `${this.attendee.name} <${this.attendee.email}>`,
|
||||
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
|
||||
replyTo: this.calEvent.organizer.email,
|
||||
subject: `${this.calEvent.language("confirmed_event_type_subject", {
|
||||
subject: `${this.calEvent.attendees[0].language.translate("confirmed_event_type_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.team?.name || this.calEvent.organizer.name,
|
||||
date: `${this.getInviteeStart().format("h:mma")} - ${this.getInviteeEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getInviteeStart().format("D")}, ${this.getInviteeStart().format("YYYY")}`,
|
||||
})}`,
|
||||
|
@ -114,8 +114,8 @@ export default class AttendeeScheduledEmail {
|
|||
|
||||
protected getTextBody(): string {
|
||||
return `
|
||||
${this.calEvent.language("your_event_has_been_scheduled")}
|
||||
${this.calEvent.language("emailed_you_and_any_other_attendees")}
|
||||
${this.calEvent.attendees[0].language.translate("your_event_has_been_scheduled")}
|
||||
${this.calEvent.attendees[0].language.translate("emailed_you_and_any_other_attendees")}
|
||||
|
||||
${getRichDescription(this.calEvent)}
|
||||
`.trim();
|
||||
|
@ -126,14 +126,14 @@ ${getRichDescription(this.calEvent)}
|
|||
}
|
||||
|
||||
protected getHtmlBody(): string {
|
||||
const headerContent = this.calEvent.language("confirmed_event_type_subject", {
|
||||
const headerContent = this.calEvent.attendees[0].language.translate("confirmed_event_type_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.team?.name || this.calEvent.organizer.name,
|
||||
date: `${this.getInviteeStart().format("h:mma")} - ${this.getInviteeEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getInviteeStart().format("D")}, ${this.getInviteeStart().format("YYYY")}`,
|
||||
});
|
||||
|
@ -146,8 +146,8 @@ ${getRichDescription(this.calEvent)}
|
|||
<div style="background-color:#F5F5F5;">
|
||||
${emailSchedulingBodyHeader("checkCircle")}
|
||||
${emailScheduledBodyHeaderContent(
|
||||
this.calEvent.language("your_event_has_been_scheduled"),
|
||||
this.calEvent.language("emailed_you_and_any_other_attendees")
|
||||
this.calEvent.attendees[0].language.translate("your_event_has_been_scheduled"),
|
||||
this.calEvent.attendees[0].language.translate("emailed_you_and_any_other_attendees")
|
||||
)}
|
||||
${emailSchedulingBodyDivider()}
|
||||
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
@ -219,8 +219,8 @@ ${getRichDescription(this.calEvent)}
|
|||
// Only the original attendee can make changes to the event
|
||||
// Guests cannot
|
||||
if (this.attendee === this.calEvent.attendees[0]) {
|
||||
const manageText = this.calEvent.language("manage_this_event");
|
||||
return `<p>${this.calEvent.language(
|
||||
const manageText = this.calEvent.attendees[0].language.translate("manage_this_event");
|
||||
return `<p>${this.calEvent.attendees[0].language.translate(
|
||||
"need_to_reschedule_or_cancel"
|
||||
)}</p><p style="font-weight: 400; line-height: 24px;"><a href="${getCancelLink(
|
||||
this.calEvent
|
||||
|
@ -233,7 +233,7 @@ ${getRichDescription(this.calEvent)}
|
|||
protected getWhat(): string {
|
||||
return `
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("what")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.attendees[0].language.translate("what")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.type}</p>
|
||||
</div>`;
|
||||
}
|
||||
|
@ -242,11 +242,11 @@ ${getRichDescription(this.calEvent)}
|
|||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("when")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.attendees[0].language.translate("when")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">
|
||||
${this.calEvent.language(
|
||||
${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.attendees[0].language.translate(
|
||||
this.getInviteeStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getInviteeStart().format("D")}, ${this.getInviteeStart().format(
|
||||
"YYYY"
|
||||
|
@ -261,7 +261,7 @@ ${getRichDescription(this.calEvent)}
|
|||
const attendees = this.calEvent.attendees
|
||||
.map((attendee) => {
|
||||
return `<div style="color: #494949; font-weight: 400; line-height: 24px;">${
|
||||
attendee?.name || `${this.calEvent.language("guest")}`
|
||||
attendee?.name || `${this.calEvent.attendees[0].language.translate("guest")}`
|
||||
} <span style="color: #888888"><a href="mailto:${attendee.email}" style="color: #888888;">${
|
||||
attendee.email
|
||||
}</a></span></div>`;
|
||||
|
@ -270,14 +270,16 @@ ${getRichDescription(this.calEvent)}
|
|||
|
||||
const organizer = `<div style="color: #494949; font-weight: 400; line-height: 24px;">${
|
||||
this.calEvent.organizer.name
|
||||
} - ${this.calEvent.language("organizer")} <span style="color: #888888"><a href="mailto:${
|
||||
} - ${this.calEvent.attendees[0].language.translate(
|
||||
"organizer"
|
||||
)} <span style="color: #888888"><a href="mailto:${
|
||||
this.calEvent.organizer.email
|
||||
}" style="color: #888888;">${this.calEvent.organizer.email}</a></span></div>`;
|
||||
|
||||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("who")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.attendees[0].language.translate("who")}</p>
|
||||
${organizer + attendees}
|
||||
</div>`;
|
||||
}
|
||||
|
@ -286,7 +288,7 @@ ${getRichDescription(this.calEvent)}
|
|||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("additional_notes")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.attendees[0].language.translate("additional_notes")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.description}</p>
|
||||
</div>
|
||||
`;
|
||||
|
@ -308,30 +310,30 @@ ${getRichDescription(this.calEvent)}
|
|||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("where")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.attendees[0].language.translate("where")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">${providerName} ${
|
||||
meetingUrl &&
|
||||
`<a href="${meetingUrl}" target="_blank" alt="${this.calEvent.language(
|
||||
`<a href="${meetingUrl}" target="_blank" alt="${this.calEvent.attendees[0].language.translate(
|
||||
"meeting_url"
|
||||
)}"><img src="${linkIcon()}" width="12px"></img></a>`
|
||||
}</p>
|
||||
${
|
||||
meetingId &&
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.language(
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.attendees[0].language.translate(
|
||||
"meeting_id"
|
||||
)}: <span>${meetingId}</span></div>`
|
||||
}
|
||||
${
|
||||
meetingPassword &&
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.language(
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.attendees[0].language.translate(
|
||||
"meeting_password"
|
||||
)}: <span>${meetingPassword}</span></div>`
|
||||
}
|
||||
${
|
||||
meetingUrl &&
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.language(
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.attendees[0].language.translate(
|
||||
"meeting_url"
|
||||
)}: <a href="${meetingUrl}" alt="${this.calEvent.language(
|
||||
)}: <a href="${meetingUrl}" alt="${this.calEvent.attendees[0].language.translate(
|
||||
"meeting_url"
|
||||
)}" style="color: #3E3E3E" target="_blank">${meetingUrl}</a></div>`
|
||||
}
|
||||
|
@ -345,14 +347,14 @@ ${getRichDescription(this.calEvent)}
|
|||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("where")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.attendees[0].language.translate("where")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">${providerName} ${
|
||||
hangoutLink &&
|
||||
`<a href="${hangoutLink}" target="_blank" alt="${this.calEvent.language(
|
||||
`<a href="${hangoutLink}" target="_blank" alt="${this.calEvent.attendees[0].language.translate(
|
||||
"meeting_url"
|
||||
)}"><img src="${linkIcon()}" width="12px"></img></a>`
|
||||
}</p>
|
||||
<div style="color: #494949; font-weight: 400; line-height: 24px;"><a href="${hangoutLink}" alt="${this.calEvent.language(
|
||||
<div style="color: #494949; font-weight: 400; line-height: 24px;"><a href="${hangoutLink}" alt="${this.calEvent.attendees[0].language.translate(
|
||||
"meeting_url"
|
||||
)}" style="color: #3E3E3E" target="_blank">${hangoutLink}</a></div>
|
||||
</div>
|
||||
|
@ -362,7 +364,7 @@ ${getRichDescription(this.calEvent)}
|
|||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("where")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.attendees[0].language.translate("where")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">${
|
||||
providerName || this.calEvent.location
|
||||
}</p>
|
||||
|
|
|
@ -33,14 +33,14 @@ export default class OrganizerCancelledEmail extends OrganizerScheduledEmail {
|
|||
return {
|
||||
from: `Cal.com <${this.getMailerOptions().from}>`,
|
||||
to: toAddresses.join(","),
|
||||
subject: `${this.calEvent.language("event_cancelled_subject", {
|
||||
subject: `${this.calEvent.organizer.language.translate("event_cancelled_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
})}`,
|
||||
|
@ -51,8 +51,8 @@ export default class OrganizerCancelledEmail extends OrganizerScheduledEmail {
|
|||
|
||||
protected getTextBody(): string {
|
||||
return `
|
||||
${this.calEvent.language("event_request_cancelled")}
|
||||
${this.calEvent.language("emailed_you_and_any_other_attendees")}
|
||||
${this.calEvent.organizer.language.translate("event_request_cancelled")}
|
||||
${this.calEvent.organizer.language.translate("emailed_you_and_any_other_attendees")}
|
||||
${this.getWhat()}
|
||||
${this.getWhen()}
|
||||
${this.getLocation()}
|
||||
|
@ -61,14 +61,14 @@ ${this.getAdditionalNotes()}
|
|||
}
|
||||
|
||||
protected getHtmlBody(): string {
|
||||
const headerContent = this.calEvent.language("event_cancelled_subject", {
|
||||
const headerContent = this.calEvent.organizer.language.translate("event_cancelled_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
});
|
||||
|
@ -81,8 +81,8 @@ ${this.getAdditionalNotes()}
|
|||
<div style="background-color:#F5F5F5;">
|
||||
${emailSchedulingBodyHeader("xCircle")}
|
||||
${emailScheduledBodyHeaderContent(
|
||||
this.calEvent.language("event_request_cancelled"),
|
||||
this.calEvent.language("emailed_you_and_any_other_attendees")
|
||||
this.calEvent.organizer.language.translate("event_request_cancelled"),
|
||||
this.calEvent.organizer.language.translate("emailed_you_and_any_other_attendees")
|
||||
)}
|
||||
${emailSchedulingBodyDivider()}
|
||||
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
|
|
@ -27,14 +27,14 @@ export default class OrganizerPaymentRefundFailedEmail extends OrganizerSchedule
|
|||
return {
|
||||
from: `Cal.com <${this.getMailerOptions().from}>`,
|
||||
to: toAddresses.join(","),
|
||||
subject: `${this.calEvent.language("refund_failed_subject", {
|
||||
subject: `${this.calEvent.organizer.language.translate("refund_failed_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
})}`,
|
||||
|
@ -45,11 +45,15 @@ export default class OrganizerPaymentRefundFailedEmail extends OrganizerSchedule
|
|||
|
||||
protected getTextBody(): string {
|
||||
return `
|
||||
${this.calEvent.language("a_refund_failed")}
|
||||
${this.calEvent.language("check_with_provider_and_user", { user: this.calEvent.attendees[0].name })}
|
||||
${this.calEvent.organizer.language.translate("a_refund_failed")}
|
||||
${this.calEvent.organizer.language.translate("check_with_provider_and_user", {
|
||||
user: this.calEvent.attendees[0].name,
|
||||
})}
|
||||
${
|
||||
this.calEvent.paymentInfo &&
|
||||
this.calEvent.language("error_message", { errorMessage: this.calEvent.paymentInfo.reason })
|
||||
this.calEvent.organizer.language.translate("error_message", {
|
||||
errorMessage: this.calEvent.paymentInfo.reason,
|
||||
})
|
||||
}
|
||||
${this.getWhat()}
|
||||
${this.getWhen()}
|
||||
|
@ -59,14 +63,14 @@ ${this.getAdditionalNotes()}
|
|||
}
|
||||
|
||||
protected getHtmlBody(): string {
|
||||
const headerContent = this.calEvent.language("refund_failed_subject", {
|
||||
const headerContent = this.calEvent.organizer.language.translate("refund_failed_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
});
|
||||
|
@ -91,14 +95,14 @@ ${this.getAdditionalNotes()}
|
|||
<tbody>
|
||||
<tr>
|
||||
<td align="center" style="font-size:0px;padding:10px 25px;padding-top:24px;padding-bottom:0px;word-break:break-word;">
|
||||
<div style="font-family:Roboto, Helvetica, sans-serif;font-size:24px;font-weight:700;line-height:24px;text-align:center;color:#292929;">${this.calEvent.language(
|
||||
<div style="font-family:Roboto, Helvetica, sans-serif;font-size:24px;font-weight:700;line-height:24px;text-align:center;color:#292929;">${this.calEvent.organizer.language.translate(
|
||||
"a_refund_failed"
|
||||
)}</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
<div style="font-family:Roboto, Helvetica, sans-serif;font-size:16px;font-weight:400;line-height:24px;text-align:center;color:#494949;">${this.calEvent.language(
|
||||
<div style="font-family:Roboto, Helvetica, sans-serif;font-size:16px;font-weight:400;line-height:24px;text-align:center;color:#494949;">${this.calEvent.organizer.language.translate(
|
||||
"check_with_provider_and_user",
|
||||
{ user: this.calEvent.attendees[0].name }
|
||||
)}</div>
|
||||
|
@ -174,7 +178,7 @@ ${this.getAdditionalNotes()}
|
|||
refundInformation = `
|
||||
<tr>
|
||||
<td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
||||
<div style="font-family:Roboto, Helvetica, sans-serif;font-size:16px;font-weight:400;line-height:24px;text-align:center;color:#494949;">${this.calEvent.language(
|
||||
<div style="font-family:Roboto, Helvetica, sans-serif;font-size:16px;font-weight:400;line-height:24px;text-align:center;color:#494949;">${this.calEvent.organizer.language.translate(
|
||||
"error_message",
|
||||
{ errorMessage: paymentInfo.reason }
|
||||
)}</div>
|
||||
|
|
|
@ -34,14 +34,14 @@ export default class OrganizerRequestEmail extends OrganizerScheduledEmail {
|
|||
return {
|
||||
from: `Cal.com <${this.getMailerOptions().from}>`,
|
||||
to: toAddresses.join(","),
|
||||
subject: `${this.calEvent.language("event_awaiting_approval_subject", {
|
||||
subject: `${this.calEvent.organizer.language.translate("event_awaiting_approval_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
})}`,
|
||||
|
@ -52,26 +52,26 @@ export default class OrganizerRequestEmail extends OrganizerScheduledEmail {
|
|||
|
||||
protected getTextBody(): string {
|
||||
return `
|
||||
${this.calEvent.language("event_awaiting_approval")}
|
||||
${this.calEvent.language("someone_requested_an_event")}
|
||||
${this.calEvent.organizer.language.translate("event_awaiting_approval")}
|
||||
${this.calEvent.organizer.language.translate("someone_requested_an_event")}
|
||||
${this.getWhat()}
|
||||
${this.getWhen()}
|
||||
${this.getLocation()}
|
||||
${this.getAdditionalNotes()}
|
||||
${this.calEvent.language("confirm_or_reject_request")}
|
||||
${this.calEvent.organizer.language.translate("confirm_or_reject_request")}
|
||||
${process.env.BASE_URL} + "/bookings/upcoming"
|
||||
`.replace(/(<([^>]+)>)/gi, "");
|
||||
}
|
||||
|
||||
protected getHtmlBody(): string {
|
||||
const headerContent = this.calEvent.language("event_awaiting_approval_subject", {
|
||||
const headerContent = this.calEvent.organizer.language.translate("event_awaiting_approval_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
});
|
||||
|
@ -85,8 +85,8 @@ ${process.env.BASE_URL} + "/bookings/upcoming"
|
|||
<div style="background-color:#F5F5F5;">
|
||||
${emailSchedulingBodyHeader("calendarCircle")}
|
||||
${emailScheduledBodyHeaderContent(
|
||||
this.calEvent.language("event_awaiting_approval"),
|
||||
this.calEvent.language("someone_requested_an_event")
|
||||
this.calEvent.organizer.language.translate("event_awaiting_approval"),
|
||||
this.calEvent.organizer.language.translate("someone_requested_an_event")
|
||||
)}
|
||||
${emailSchedulingBodyDivider()}
|
||||
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
@ -166,7 +166,7 @@ ${process.env.BASE_URL} + "/bookings/upcoming"
|
|||
}
|
||||
|
||||
protected getManageLink(): string {
|
||||
const manageText = this.calEvent.language("confirm_or_reject_request");
|
||||
const manageText = this.calEvent.organizer.language.translate("confirm_or_reject_request");
|
||||
const manageLink = process.env.BASE_URL + "/bookings/upcoming";
|
||||
return `<a style="color: #FFFFFF; text-decoration: none;" href="${manageLink}" target="_blank">${manageText} <img src="${linkIcon()}" width="12px"></img></a>`;
|
||||
}
|
||||
|
|
|
@ -34,14 +34,14 @@ export default class OrganizerRequestReminderEmail extends OrganizerScheduledEma
|
|||
return {
|
||||
from: `Cal.com <${this.getMailerOptions().from}>`,
|
||||
to: toAddresses.join(","),
|
||||
subject: `${this.calEvent.language("event_awaiting_approval_subject", {
|
||||
subject: `${this.calEvent.organizer.language.translate("event_awaiting_approval_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
})}`,
|
||||
|
@ -52,26 +52,26 @@ export default class OrganizerRequestReminderEmail extends OrganizerScheduledEma
|
|||
|
||||
protected getTextBody(): string {
|
||||
return `
|
||||
${this.calEvent.language("event_still_awaiting_approval")}
|
||||
${this.calEvent.language("someone_requested_an_event")}
|
||||
${this.calEvent.organizer.language.translate("event_still_awaiting_approval")}
|
||||
${this.calEvent.organizer.language.translate("someone_requested_an_event")}
|
||||
${this.getWhat()}
|
||||
${this.getWhen()}
|
||||
${this.getLocation()}
|
||||
${this.getAdditionalNotes()}
|
||||
${this.calEvent.language("confirm_or_reject_request")}
|
||||
${this.calEvent.organizer.language.translate("confirm_or_reject_request")}
|
||||
${process.env.BASE_URL} + "/bookings/upcoming"
|
||||
`.replace(/(<([^>]+)>)/gi, "");
|
||||
}
|
||||
|
||||
protected getHtmlBody(): string {
|
||||
const headerContent = this.calEvent.language("event_awaiting_approval_subject", {
|
||||
const headerContent = this.calEvent.organizer.language.translate("event_awaiting_approval_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
});
|
||||
|
@ -84,8 +84,8 @@ ${process.env.BASE_URL} + "/bookings/upcoming"
|
|||
<div style="background-color:#F5F5F5;">
|
||||
${emailSchedulingBodyHeader("calendarCircle")}
|
||||
${emailScheduledBodyHeaderContent(
|
||||
this.calEvent.language("event_still_awaiting_approval"),
|
||||
this.calEvent.language("someone_requested_an_event")
|
||||
this.calEvent.organizer.language.translate("event_still_awaiting_approval"),
|
||||
this.calEvent.organizer.language.translate("someone_requested_an_event")
|
||||
)}
|
||||
${emailSchedulingBodyDivider()}
|
||||
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
@ -165,7 +165,7 @@ ${process.env.BASE_URL} + "/bookings/upcoming"
|
|||
}
|
||||
|
||||
protected getManageLink(): string {
|
||||
const manageText = this.calEvent.language("confirm_or_reject_request");
|
||||
const manageText = this.calEvent.organizer.language.translate("confirm_or_reject_request");
|
||||
const manageLink = process.env.BASE_URL + "/bookings/upcoming";
|
||||
return `<a style="color: #FFFFFF; text-decoration: none;" href="${manageLink}" target="_blank">${manageText} <img src="${linkIcon()}" width="12px"></img></a>`;
|
||||
}
|
||||
|
|
|
@ -39,14 +39,14 @@ export default class OrganizerRescheduledEmail extends OrganizerScheduledEmail {
|
|||
},
|
||||
from: `Cal.com <${this.getMailerOptions().from}>`,
|
||||
to: toAddresses.join(","),
|
||||
subject: `${this.calEvent.language("rescheduled_event_type_subject", {
|
||||
subject: `${this.calEvent.organizer.language.translate("rescheduled_event_type_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
})}`,
|
||||
|
@ -57,26 +57,26 @@ export default class OrganizerRescheduledEmail extends OrganizerScheduledEmail {
|
|||
|
||||
protected getTextBody(): string {
|
||||
return `
|
||||
${this.calEvent.language("event_has_been_rescheduled")}
|
||||
${this.calEvent.language("emailed_you_and_any_other_attendees")}
|
||||
${this.calEvent.organizer.language.translate("event_has_been_rescheduled")}
|
||||
${this.calEvent.organizer.language.translate("emailed_you_and_any_other_attendees")}
|
||||
${this.getWhat()}
|
||||
${this.getWhen()}
|
||||
${this.getLocation()}
|
||||
${this.getAdditionalNotes()}
|
||||
${this.calEvent.language("need_to_reschedule_or_cancel")}
|
||||
${this.calEvent.organizer.language.translate("need_to_reschedule_or_cancel")}
|
||||
${getCancelLink(this.calEvent)}
|
||||
`.replace(/(<([^>]+)>)/gi, "");
|
||||
}
|
||||
|
||||
protected getHtmlBody(): string {
|
||||
const headerContent = this.calEvent.language("rescheduled_event_type_subject", {
|
||||
const headerContent = this.calEvent.organizer.language.translate("rescheduled_event_type_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
});
|
||||
|
@ -89,8 +89,8 @@ ${getCancelLink(this.calEvent)}
|
|||
<div style="background-color:#F5F5F5;">
|
||||
${emailSchedulingBodyHeader("calendarCircle")}
|
||||
${emailScheduledBodyHeaderContent(
|
||||
this.calEvent.language("event_has_been_rescheduled"),
|
||||
this.calEvent.language("emailed_you_and_any_other_attendees")
|
||||
this.calEvent.organizer.language.translate("event_has_been_rescheduled"),
|
||||
this.calEvent.organizer.language.translate("emailed_you_and_any_other_attendees")
|
||||
)}
|
||||
${emailSchedulingBodyDivider()}
|
||||
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
|
|
@ -59,7 +59,7 @@ export default class OrganizerScheduledEmail {
|
|||
.map((v, i) => (i === 1 ? v + 1 : v)) as DateArray,
|
||||
startInputType: "utc",
|
||||
productId: "calendso/ics",
|
||||
title: this.calEvent.language("ics_event_title", {
|
||||
title: this.calEvent.organizer.language.translate("ics_event_title", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
}),
|
||||
|
@ -96,14 +96,14 @@ export default class OrganizerScheduledEmail {
|
|||
},
|
||||
from: `Cal.com <${this.getMailerOptions().from}>`,
|
||||
to: toAddresses.join(","),
|
||||
subject: `${this.calEvent.language("confirmed_event_type_subject", {
|
||||
subject: `${this.calEvent.organizer.language.translate("confirmed_event_type_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
})}`,
|
||||
|
@ -121,8 +121,8 @@ export default class OrganizerScheduledEmail {
|
|||
|
||||
protected getTextBody(): string {
|
||||
return `
|
||||
${this.calEvent.language("new_event_scheduled")}
|
||||
${this.calEvent.language("emailed_you_and_any_other_attendees")}
|
||||
${this.calEvent.organizer.language.translate("new_event_scheduled")}
|
||||
${this.calEvent.organizer.language.translate("emailed_you_and_any_other_attendees")}
|
||||
|
||||
${getRichDescription(this.calEvent)}
|
||||
`.trim();
|
||||
|
@ -133,14 +133,14 @@ ${getRichDescription(this.calEvent)}
|
|||
}
|
||||
|
||||
protected getHtmlBody(): string {
|
||||
const headerContent = this.calEvent.language("confirmed_event_type_subject", {
|
||||
const headerContent = this.calEvent.organizer.language.translate("confirmed_event_type_subject", {
|
||||
eventType: this.calEvent.type,
|
||||
name: this.calEvent.attendees[0].name,
|
||||
date: `${this.getOrganizerStart().format("h:mma")} - ${this.getOrganizerEnd().format(
|
||||
"h:mma"
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format("YYYY")}`,
|
||||
});
|
||||
|
@ -153,8 +153,8 @@ ${getRichDescription(this.calEvent)}
|
|||
<div style="background-color:#F5F5F5;">
|
||||
${emailSchedulingBodyHeader("checkCircle")}
|
||||
${emailScheduledBodyHeaderContent(
|
||||
this.calEvent.language("new_event_scheduled"),
|
||||
this.calEvent.language("emailed_you_and_any_other_attendees")
|
||||
this.calEvent.organizer.language.translate("new_event_scheduled"),
|
||||
this.calEvent.organizer.language.translate("emailed_you_and_any_other_attendees")
|
||||
)}
|
||||
${emailSchedulingBodyDivider()}
|
||||
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
|
||||
|
@ -223,8 +223,8 @@ ${getRichDescription(this.calEvent)}
|
|||
}
|
||||
|
||||
protected getManageLink(): string {
|
||||
const manageText = this.calEvent.language("manage_this_event");
|
||||
return `<p>${this.calEvent.language(
|
||||
const manageText = this.calEvent.organizer.language.translate("manage_this_event");
|
||||
return `<p>${this.calEvent.organizer.language.translate(
|
||||
"need_to_reschedule_or_cancel"
|
||||
)}</p><p style="font-weight: 400; line-height: 24px;"><a href="${getCancelLink(
|
||||
this.calEvent
|
||||
|
@ -234,7 +234,7 @@ ${getRichDescription(this.calEvent)}
|
|||
protected getWhat(): string {
|
||||
return `
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("what")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.organizer.language.translate("what")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.type}</p>
|
||||
</div>`;
|
||||
}
|
||||
|
@ -243,11 +243,11 @@ ${getRichDescription(this.calEvent)}
|
|||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("when")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.organizer.language.translate("when")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">
|
||||
${this.calEvent.language(
|
||||
${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("dddd").toLowerCase()
|
||||
)}, ${this.calEvent.language(
|
||||
)}, ${this.calEvent.organizer.language.translate(
|
||||
this.getOrganizerStart().format("MMMM").toLowerCase()
|
||||
)} ${this.getOrganizerStart().format("D")}, ${this.getOrganizerStart().format(
|
||||
"YYYY"
|
||||
|
@ -262,7 +262,7 @@ ${getRichDescription(this.calEvent)}
|
|||
const attendees = this.calEvent.attendees
|
||||
.map((attendee) => {
|
||||
return `<div style="color: #494949; font-weight: 400; line-height: 24px;">${
|
||||
attendee?.name || `${this.calEvent.language("guest")}`
|
||||
attendee?.name || `${this.calEvent.organizer.language.translate("guest")}`
|
||||
} <span style="color: #888888"><a href="mailto:${attendee.email}" style="color: #888888;">${
|
||||
attendee.email
|
||||
}</a></span></div>`;
|
||||
|
@ -271,14 +271,16 @@ ${getRichDescription(this.calEvent)}
|
|||
|
||||
const organizer = `<div style="color: #494949; font-weight: 400; line-height: 24px;">${
|
||||
this.calEvent.organizer.name
|
||||
} - ${this.calEvent.language("organizer")} <span style="color: #888888"><a href="mailto:${
|
||||
} - ${this.calEvent.organizer.language.translate(
|
||||
"organizer"
|
||||
)} <span style="color: #888888"><a href="mailto:${
|
||||
this.calEvent.organizer.email
|
||||
}" style="color: #888888;">${this.calEvent.organizer.email}</a></span></div>`;
|
||||
|
||||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("who")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.organizer.language.translate("who")}</p>
|
||||
${organizer + attendees}
|
||||
</div>`;
|
||||
}
|
||||
|
@ -287,7 +289,7 @@ ${getRichDescription(this.calEvent)}
|
|||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("additional_notes")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.organizer.language.translate("additional_notes")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.description}</p>
|
||||
</div>
|
||||
`;
|
||||
|
@ -309,30 +311,30 @@ ${getRichDescription(this.calEvent)}
|
|||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("where")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.organizer.language.translate("where")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">${providerName} ${
|
||||
meetingUrl &&
|
||||
`<a href="${meetingUrl}" target="_blank" alt="${this.calEvent.language(
|
||||
`<a href="${meetingUrl}" target="_blank" alt="${this.calEvent.organizer.language.translate(
|
||||
"meeting_url"
|
||||
)}"><img src="${linkIcon()}" width="12px"></img></a>`
|
||||
}</p>
|
||||
${
|
||||
meetingId &&
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.language(
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.organizer.language.translate(
|
||||
"meeting_id"
|
||||
)}: <span>${meetingId}</span></div>`
|
||||
}
|
||||
${
|
||||
meetingPassword &&
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.language(
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.organizer.language.translate(
|
||||
"meeting_password"
|
||||
)}: <span>${meetingPassword}</span></div>`
|
||||
}
|
||||
${
|
||||
meetingUrl &&
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.language(
|
||||
`<div style="color: #494949; font-weight: 400; line-height: 24px;">${this.calEvent.organizer.language.translate(
|
||||
"meeting_url"
|
||||
)}: <a href="${meetingUrl}" alt="${this.calEvent.language(
|
||||
)}: <a href="${meetingUrl}" alt="${this.calEvent.organizer.language.translate(
|
||||
"meeting_url"
|
||||
)}" style="color: #3E3E3E" target="_blank">${meetingUrl}</a></div>`
|
||||
}
|
||||
|
@ -346,14 +348,14 @@ ${getRichDescription(this.calEvent)}
|
|||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("where")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.organizer.language.translate("where")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">${providerName} ${
|
||||
hangoutLink &&
|
||||
`<a href="${hangoutLink}" target="_blank" alt="${this.calEvent.language(
|
||||
`<a href="${hangoutLink}" target="_blank" alt="${this.calEvent.organizer.language.translate(
|
||||
"meeting_url"
|
||||
)}"><img src="${linkIcon()}" width="12px"></img></a>`
|
||||
}</p>
|
||||
<div style="color: #494949; font-weight: 400; line-height: 24px;"><a href="${hangoutLink}" alt="${this.calEvent.language(
|
||||
<div style="color: #494949; font-weight: 400; line-height: 24px;"><a href="${hangoutLink}" alt="${this.calEvent.organizer.language.translate(
|
||||
"meeting_url"
|
||||
)}" style="color: #3E3E3E" target="_blank">${hangoutLink}</a></div>
|
||||
</div>
|
||||
|
@ -363,7 +365,7 @@ ${getRichDescription(this.calEvent)}
|
|||
return `
|
||||
<p style="height: 6px"></p>
|
||||
<div style="line-height: 6px;">
|
||||
<p style="color: #494949;">${this.calEvent.language("where")}</p>
|
||||
<p style="color: #494949;">${this.calEvent.organizer.language.translate("where")}</p>
|
||||
<p style="color: #494949; font-weight: 400; line-height: 24px;">${
|
||||
providerName || this.calEvent.location
|
||||
}</p>
|
||||
|
|
|
@ -8,7 +8,6 @@ import { createEvent, updateEvent } from "@lib/integrations/calendar/CalendarMan
|
|||
import { AdditionInformation, CalendarEvent } from "@lib/integrations/calendar/interfaces/Calendar";
|
||||
import { LocationType } from "@lib/location";
|
||||
import prisma from "@lib/prisma";
|
||||
import { Ensure } from "@lib/types/utils";
|
||||
import { createMeeting, updateMeeting, VideoCallData } from "@lib/videoClient";
|
||||
|
||||
export type Event = AdditionInformation & VideoCallData;
|
||||
|
@ -118,7 +117,7 @@ export default class EventManager {
|
|||
*
|
||||
* @param event
|
||||
*/
|
||||
public async create(event: Ensure<CalendarEvent, "language">): Promise<CreateUpdateResult> {
|
||||
public async create(event: CalendarEvent): Promise<CreateUpdateResult> {
|
||||
const evt = processLocation(event);
|
||||
const isDedicated = evt.location ? isDedicatedIntegration(evt.location) : null;
|
||||
|
||||
|
@ -158,10 +157,7 @@ export default class EventManager {
|
|||
*
|
||||
* @param event
|
||||
*/
|
||||
public async update(
|
||||
event: Ensure<CalendarEvent, "language">,
|
||||
rescheduleUid: string
|
||||
): Promise<CreateUpdateResult> {
|
||||
public async update(event: CalendarEvent, rescheduleUid: string): Promise<CreateUpdateResult> {
|
||||
const evt = processLocation(event);
|
||||
|
||||
if (!rescheduleUid) {
|
||||
|
@ -293,7 +289,7 @@ export default class EventManager {
|
|||
* @param event
|
||||
* @private
|
||||
*/
|
||||
private createVideoEvent(event: Ensure<CalendarEvent, "language">): Promise<EventResult> {
|
||||
private createVideoEvent(event: CalendarEvent): Promise<EventResult> {
|
||||
const credential = this.getVideoCredential(event);
|
||||
|
||||
if (credential) {
|
||||
|
|
|
@ -13,6 +13,7 @@ export type Person = {
|
|||
name: string;
|
||||
email: string;
|
||||
timeZone: string;
|
||||
language: { translate: TFunction; locale: string };
|
||||
};
|
||||
|
||||
export interface EntryPoint {
|
||||
|
@ -46,7 +47,6 @@ export interface CalendarEvent {
|
|||
organizer: Person;
|
||||
attendees: Person[];
|
||||
conferenceData?: ConferenceData;
|
||||
language: TFunction;
|
||||
additionInformation?: AdditionInformation;
|
||||
uid?: string | null;
|
||||
videoCallData?: VideoCallData;
|
||||
|
|
|
@ -10,7 +10,6 @@ import logger from "@lib/logger";
|
|||
import DailyVideoApiAdapter from "./integrations/Daily/DailyVideoApiAdapter";
|
||||
import ZoomVideoApiAdapter from "./integrations/Zoom/ZoomVideoApiAdapter";
|
||||
import { CalendarEvent } from "./integrations/calendar/interfaces/Calendar";
|
||||
import { Ensure } from "./types/utils";
|
||||
|
||||
const log = logger.getChildLogger({ prefix: ["[lib] videoClient"] });
|
||||
|
||||
|
@ -56,10 +55,7 @@ const getBusyVideoTimes = (withCredentials: Credential[]) =>
|
|||
results.reduce((acc, availability) => acc.concat(availability), [])
|
||||
);
|
||||
|
||||
const createMeeting = async (
|
||||
credential: Credential,
|
||||
calEvent: Ensure<CalendarEvent, "language">
|
||||
): Promise<EventResult> => {
|
||||
const createMeeting = async (credential: Credential, calEvent: CalendarEvent): Promise<EventResult> => {
|
||||
const uid: string = getUid(calEvent);
|
||||
|
||||
if (!credential) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { CalendarEvent } from "@lib/integrations/calendar/interfaces/Calendar";
|
|||
|
||||
type ContentType = "application/json" | "application/x-www-form-urlencoded";
|
||||
|
||||
function applyTemplate(template: string, data: Omit<CalendarEvent, "language">, contentType: ContentType) {
|
||||
function applyTemplate(template: string, data: CalendarEvent, contentType: ContentType) {
|
||||
const compiled = compile(template)(data);
|
||||
if (contentType === "application/json") {
|
||||
return jsonParse(compiled);
|
||||
|
@ -25,7 +25,9 @@ const sendPayload = async (
|
|||
triggerEvent: string,
|
||||
createdAt: string,
|
||||
subscriberUrl: string,
|
||||
data: Omit<CalendarEvent, "language"> & { metadata?: { [key: string]: string } },
|
||||
data: CalendarEvent & {
|
||||
metadata?: { [key: string]: string };
|
||||
},
|
||||
template?: string | null
|
||||
) => {
|
||||
if (!subscriberUrl || !data) {
|
||||
|
|
|
@ -43,8 +43,6 @@ const authorized = async (
|
|||
const log = logger.getChildLogger({ prefix: ["[api] book:user"] });
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse): Promise<void> {
|
||||
const t = await getTranslation(req.body.language ?? "en", "common");
|
||||
|
||||
const session = await getSession({ req: req });
|
||||
if (!session?.user?.id) {
|
||||
return res.status(401).json({ message: "Not authenticated" });
|
||||
|
@ -71,6 +69,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
name: true,
|
||||
username: true,
|
||||
destinationCalendar: true,
|
||||
locale: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -78,6 +77,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
return res.status(404).json({ message: "User not found" });
|
||||
}
|
||||
|
||||
const tOrganizer = await getTranslation(currentUser.locale ?? "en", "common");
|
||||
|
||||
if (req.method === "PATCH") {
|
||||
const booking = await prisma.booking.findFirst({
|
||||
where: {
|
||||
|
@ -112,6 +113,20 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
return res.status(400).json({ message: "booking already confirmed" });
|
||||
}
|
||||
|
||||
const attendeesListPromises = booking.attendees.map(async (attendee) => {
|
||||
return {
|
||||
name: attendee.name,
|
||||
email: attendee.email,
|
||||
timeZone: attendee.timeZone,
|
||||
language: {
|
||||
translate: await getTranslation(attendee.locale ?? "en", "common"),
|
||||
locale: attendee.locale ?? "en",
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const attendeesList = await Promise.all(attendeesListPromises);
|
||||
|
||||
const evt: CalendarEvent = {
|
||||
type: booking.title,
|
||||
title: booking.title,
|
||||
|
@ -122,11 +137,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
email: currentUser.email,
|
||||
name: currentUser.name || "Unnamed",
|
||||
timeZone: currentUser.timeZone,
|
||||
language: { translate: tOrganizer, locale: currentUser.locale ?? "en" },
|
||||
},
|
||||
attendees: booking.attendees,
|
||||
attendees: attendeesList,
|
||||
location: booking.location ?? "",
|
||||
uid: booking.uid,
|
||||
language: t,
|
||||
destinationCalendar: booking?.destinationCalendar || currentUser.destinationCalendar,
|
||||
};
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ const userSelect = Prisma.validator<Prisma.UserArgs>()({
|
|||
credentials: true,
|
||||
bufferTime: true,
|
||||
destinationCalendar: true,
|
||||
locale: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -152,6 +153,7 @@ const getUserNameWithBookingCounts = async (eventTypeId: number, selectedUserNam
|
|||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
locale: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -180,8 +182,8 @@ type User = Prisma.UserGetPayload<typeof userSelect>;
|
|||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
const reqBody = req.body as BookingCreateBody;
|
||||
const eventTypeId = reqBody.eventTypeId;
|
||||
const t = await getTranslation(reqBody.language ?? "en", "common");
|
||||
|
||||
const tAttendees = await getTranslation(reqBody.language ?? "en", "common");
|
||||
const tGuests = await getTranslation("en", "common");
|
||||
log.debug(`Booking eventType ${eventTypeId} started`);
|
||||
|
||||
const isTimeInPast = (time: string): boolean => {
|
||||
|
@ -244,6 +246,17 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
users.push(eventTypeUser);
|
||||
}
|
||||
|
||||
const organizer = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: users[0].id,
|
||||
},
|
||||
select: {
|
||||
locale: true,
|
||||
},
|
||||
});
|
||||
|
||||
const tOrganizer = await getTranslation(organizer?.locale ?? "en", "common");
|
||||
|
||||
if (eventType.schedulingType === SchedulingType.ROUND_ROBIN) {
|
||||
const bookingCounts = await getUserNameWithBookingCounts(
|
||||
eventTypeId,
|
||||
|
@ -253,25 +266,41 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
users = getLuckyUsers(users, bookingCounts);
|
||||
}
|
||||
|
||||
const invitee = [{ email: reqBody.email, name: reqBody.name, timeZone: reqBody.timeZone }];
|
||||
const invitee = [
|
||||
{
|
||||
email: reqBody.email,
|
||||
name: reqBody.name,
|
||||
timeZone: reqBody.timeZone,
|
||||
language: { translate: tAttendees, locale: reqBody.language ?? "en" },
|
||||
},
|
||||
];
|
||||
const guests = (reqBody.guests || []).map((guest) => {
|
||||
const g = {
|
||||
email: guest,
|
||||
name: "",
|
||||
timeZone: reqBody.timeZone,
|
||||
language: { translate: tGuests, locale: "en" },
|
||||
};
|
||||
return g;
|
||||
});
|
||||
|
||||
const teamMembers =
|
||||
const teamMemberPromises =
|
||||
eventType.schedulingType === SchedulingType.COLLECTIVE
|
||||
? users.slice(1).map((user) => ({
|
||||
email: user.email || "",
|
||||
name: user.name || "",
|
||||
timeZone: user.timeZone,
|
||||
}))
|
||||
? users.slice(1).map(async function (user) {
|
||||
return {
|
||||
email: user.email || "",
|
||||
name: user.name || "",
|
||||
timeZone: user.timeZone,
|
||||
language: {
|
||||
translate: await getTranslation(user.locale ?? "en", "common"),
|
||||
locale: user.locale ?? "en",
|
||||
},
|
||||
};
|
||||
})
|
||||
: [];
|
||||
|
||||
const teamMembers = await Promise.all(teamMemberPromises);
|
||||
|
||||
const attendeesList = [...invitee, ...guests, ...teamMembers];
|
||||
|
||||
const seed = `${users[0].username}:${dayjs(req.body.start).utc().format()}:${new Date().getTime()}`;
|
||||
|
@ -282,7 +311,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
eventType: eventType.title,
|
||||
eventName: eventType.eventName,
|
||||
host: users[0].name || "Nameless",
|
||||
t,
|
||||
t: tOrganizer,
|
||||
};
|
||||
|
||||
const description =
|
||||
|
@ -294,7 +323,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
|
||||
const evt: CalendarEvent = {
|
||||
type: eventType.title,
|
||||
title: getEventName(eventNameObject),
|
||||
title: getEventName(eventNameObject), //this needs to be either forced in english, or fetched for each attendee and organizer separately
|
||||
description,
|
||||
startTime: reqBody.start,
|
||||
endTime: reqBody.end,
|
||||
|
@ -302,10 +331,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
name: users[0].name || "Nameless",
|
||||
email: users[0].email || "Email-less",
|
||||
timeZone: users[0].timeZone,
|
||||
language: { translate: tOrganizer, locale: organizer?.locale ?? "en" },
|
||||
},
|
||||
attendees: attendeesList,
|
||||
location: reqBody.location, // Will be processed by the EventManager later.
|
||||
language: t,
|
||||
/** For team events, we will need to handle each member destinationCalendar eventually */
|
||||
destinationCalendar: eventType.destinationCalendar || users[0].destinationCalendar,
|
||||
};
|
||||
|
@ -343,7 +372,17 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
},
|
||||
attendees: {
|
||||
createMany: {
|
||||
data: evt.attendees,
|
||||
data: evt.attendees.map((attendee) => {
|
||||
//if attendee is team member, it should fetch their locale not booker's locale
|
||||
//perhaps make email fetch request to see if his locale is stored, else
|
||||
const retObj = {
|
||||
name: attendee.name,
|
||||
email: attendee.email,
|
||||
timeZone: attendee.timeZone,
|
||||
locale: attendee.language.locale,
|
||||
};
|
||||
return retObj;
|
||||
}),
|
||||
},
|
||||
},
|
||||
user: {
|
||||
|
|
|
@ -89,11 +89,25 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
name: true,
|
||||
email: true,
|
||||
timeZone: true,
|
||||
locale: true,
|
||||
},
|
||||
rejectOnNotFound: true,
|
||||
});
|
||||
|
||||
const t = await getTranslation(req.body.language ?? "en", "common");
|
||||
const attendeesListPromises = bookingToDelete.attendees.map(async (attendee) => {
|
||||
return {
|
||||
name: attendee.name,
|
||||
email: attendee.email,
|
||||
timeZone: attendee.timeZone,
|
||||
language: {
|
||||
translate: await getTranslation(attendee.locale ?? "en", "common"),
|
||||
locale: attendee.locale ?? "en",
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const attendeesList = await Promise.all(attendeesListPromises);
|
||||
const tOrganizer = await getTranslation(organizer.locale ?? "en", "common");
|
||||
|
||||
const evt: CalendarEvent = {
|
||||
title: bookingToDelete?.title,
|
||||
|
@ -105,14 +119,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
email: organizer.email,
|
||||
name: organizer.name ?? "Nameless",
|
||||
timeZone: organizer.timeZone,
|
||||
language: { translate: tOrganizer, locale: organizer.locale ?? "en" },
|
||||
},
|
||||
attendees: bookingToDelete?.attendees.map((attendee) => {
|
||||
const retObj = { name: attendee.name, email: attendee.email, timeZone: attendee.timeZone };
|
||||
return retObj;
|
||||
}),
|
||||
attendees: attendeesList,
|
||||
uid: bookingToDelete?.uid,
|
||||
location: bookingToDelete?.location,
|
||||
language: t,
|
||||
destinationCalendar: bookingToDelete?.destinationCalendar || bookingToDelete?.user.destinationCalendar,
|
||||
};
|
||||
|
||||
|
@ -168,11 +179,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
email: bookingToDelete.user?.email ?? "dev@calendso.com",
|
||||
name: bookingToDelete.user?.name ?? "no user",
|
||||
timeZone: bookingToDelete.user?.timeZone ?? "",
|
||||
language: { translate: tOrganizer, locale: organizer.locale ?? "en" },
|
||||
},
|
||||
attendees: bookingToDelete.attendees,
|
||||
attendees: attendeesList,
|
||||
location: bookingToDelete.location ?? "",
|
||||
uid: bookingToDelete.uid ?? "",
|
||||
language: t,
|
||||
destinationCalendar: bookingToDelete?.destinationCalendar || bookingToDelete?.user.destinationCalendar,
|
||||
};
|
||||
await refund(bookingToDelete, evt);
|
||||
|
|
|
@ -73,7 +73,21 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
continue;
|
||||
}
|
||||
|
||||
const t = await getTranslation(user.locale ?? "en", "common");
|
||||
const tOrganizer = await getTranslation(user.locale ?? "en", "common");
|
||||
|
||||
const attendeesListPromises = booking.attendees.map(async (attendee) => {
|
||||
return {
|
||||
name: attendee.name,
|
||||
email: attendee.email,
|
||||
timeZone: attendee.timeZone,
|
||||
language: {
|
||||
translate: await getTranslation(attendee.locale ?? "en", "common"),
|
||||
locale: attendee.locale ?? "en",
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const attendeesList = await Promise.all(attendeesListPromises);
|
||||
|
||||
const evt: CalendarEvent = {
|
||||
type: booking.title,
|
||||
|
@ -86,10 +100,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
email: user.email,
|
||||
name,
|
||||
timeZone: user.timeZone,
|
||||
language: { translate: tOrganizer, locale: user.locale ?? "en" },
|
||||
},
|
||||
attendees: booking.attendees,
|
||||
attendees: attendeesList,
|
||||
uid: booking.uid,
|
||||
language: t,
|
||||
destinationCalendar: booking.destinationCalendar || user.destinationCalendar,
|
||||
};
|
||||
|
||||
|
|
|
@ -63,8 +63,10 @@ test.describe("integrations", () => {
|
|||
body.payload.location = dynamic;
|
||||
for (const attendee of body.payload.attendees) {
|
||||
attendee.timeZone = dynamic;
|
||||
attendee.language = dynamic;
|
||||
}
|
||||
body.payload.organizer.timeZone = dynamic;
|
||||
body.payload.organizer.language = dynamic;
|
||||
body.payload.uid = dynamic;
|
||||
body.payload.additionInformation = dynamic;
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"triggerEvent":"BOOKING_CREATED","createdAt":"[redacted/dynamic]","payload":{"type":"30min","title":"30min between Pro Example and Test Testson","description":"","startTime":"[redacted/dynamic]","endTime":"[redacted/dynamic]","organizer":{"name":"Pro Example","email":"pro@example.com","timeZone":"[redacted/dynamic]"},"attendees":[{"email":"test@example.com","name":"Test Testson","timeZone":"[redacted/dynamic]"}],"location":"[redacted/dynamic]","destinationCalendar":null,"uid":"[redacted/dynamic]","metadata":{},"additionInformation":"[redacted/dynamic]"}}
|
||||
{"triggerEvent":"BOOKING_CREATED","createdAt":"[redacted/dynamic]","payload":{"type":"30min","title":"30min between Pro Example and Test Testson","description":"","startTime":"[redacted/dynamic]","endTime":"[redacted/dynamic]","organizer":{"name":"Pro Example","email":"pro@example.com","timeZone":"[redacted/dynamic]","language":"[redacted/dynamic]"},"attendees":[{"email":"test@example.com","name":"Test Testson","timeZone":"[redacted/dynamic]","language":"[redacted/dynamic]"}],"location":"[redacted/dynamic]","destinationCalendar":null,"uid":"[redacted/dynamic]","metadata":{},"additionInformation":"[redacted/dynamic]"}}
|
|
@ -0,0 +1,2 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "Attendee" ADD COLUMN "locale" TEXT DEFAULT E'en';
|
|
@ -199,6 +199,7 @@ model Attendee {
|
|||
email String
|
||||
name String
|
||||
timeZone String
|
||||
locale String? @default("en")
|
||||
booking Booking? @relation(fields: [bookingId], references: [id])
|
||||
bookingId Int?
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ export const _AttendeeModel = z.object({
|
|||
email: z.string(),
|
||||
name: z.string(),
|
||||
timeZone: z.string(),
|
||||
locale: z.string().nullish(),
|
||||
bookingId: z.number().int().nullish(),
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue