diff --git a/lib/CalEventParser.ts b/lib/CalEventParser.ts
index 143322cbe4..ded6fb12b4 100644
--- a/lib/CalEventParser.ts
+++ b/lib/CalEventParser.ts
@@ -1,15 +1,104 @@
+import dayjs from "dayjs";
import short from "short-uuid";
import { v5 as uuidv5 } from "uuid";
+import { getIntegrationName } from "@lib/integrations";
+
import { CalendarEvent } from "./calendarClient";
import { BASE_URL } from "./config/constants";
const translator = short();
-export const getUid = (calEvent: CalendarEvent) => {
+export const getWhat = (calEvent: CalendarEvent) => {
+ return `
+${calEvent.language("what")}
+${calEvent.type}
+ `;
+};
+
+export const getWhen = (calEvent: CalendarEvent) => {
+ const inviteeStart = dayjs(calEvent.startTime).tz(calEvent.attendees[0].timeZone);
+ const inviteeEnd = dayjs(calEvent.endTime).tz(calEvent.attendees[0].timeZone);
+
+ return `
+${calEvent.language("when")}
+${calEvent.language(inviteeStart.format("dddd").toLowerCase())}, ${calEvent.language(
+ inviteeStart.format("MMMM").toLowerCase()
+ )} ${inviteeStart.format("D")}, ${inviteeStart.format("YYYY")} | ${inviteeStart.format(
+ "h:mma"
+ )} - ${inviteeEnd.format("h:mma")} (${calEvent.attendees[0].timeZone})
+ `;
+};
+
+export const getWho = (calEvent: CalendarEvent) => {
+ const attendees = calEvent.attendees
+ .map((attendee) => {
+ return `
+${attendee?.name || calEvent.language("guest")}
+${attendee.email}
+ `;
+ })
+ .join("");
+
+ const organizer = `
+${calEvent.organizer.name} - ${calEvent.language("organizer")}
+${calEvent.organizer.email}
+ `;
+
+ return `
+${calEvent.language("who")}
+${organizer + attendees}
+ `;
+};
+
+export const getAdditionalNotes = (calEvent: CalendarEvent) => {
+ return `
+${calEvent.language("additional_notes")}
+${calEvent.description}
+ `;
+};
+
+export const getLocation = (calEvent: CalendarEvent) => {
+ let providerName = calEvent.location ? getIntegrationName(calEvent.location) : "";
+
+ if (calEvent.location && calEvent.location.includes("integrations:")) {
+ const location = calEvent.location.split(":")[1];
+ providerName = location[0].toUpperCase() + location.slice(1);
+ }
+
+ if (calEvent.videoCallData) {
+ return calEvent.videoCallData.url;
+ }
+
+ if (calEvent.additionInformation?.hangoutLink) {
+ return calEvent.additionInformation.hangoutLink;
+ }
+
+ return providerName || calEvent.location;
+};
+
+export const getManageLink = (calEvent: CalendarEvent) => {
+ return `
+${calEvent.language("need_to_reschedule_or_cancel")}
+${getCancelLink(calEvent)}
+ `;
+};
+
+export const getUid = (calEvent: CalendarEvent): string => {
return calEvent.uid ?? translator.fromUUID(uuidv5(JSON.stringify(calEvent), uuidv5.URL));
};
-export const getCancelLink = (calEvent: CalendarEvent) => {
+export const getCancelLink = (calEvent: CalendarEvent): string => {
return BASE_URL + "/cancel/" + getUid(calEvent);
};
+
+export const getRichDescription = (calEvent: CalendarEvent) => {
+ return `
+ ${getWhat(calEvent)}
+ ${getWhen(calEvent)}
+ ${getWho(calEvent)}
+ ${getLocation(calEvent)}
+ ${getAdditionalNotes(calEvent)}
+ ${getManageLink(calEvent)}
+ `;
+};
diff --git a/lib/calendarClient.ts b/lib/calendarClient.ts
index 5f5f66a7e9..999b208784 100644
--- a/lib/calendarClient.ts
+++ b/lib/calendarClient.ts
@@ -181,7 +181,7 @@ const updateEvent = async (
const uid = getUid(calEvent);
let success = true;
- const updationResult =
+ const updatedResult =
credential && bookingRefUid
? await calendars([credential])[0]
.updateEvent(bookingRefUid, calEvent)
@@ -192,7 +192,7 @@ const updateEvent = async (
})
: undefined;
- if (!updationResult) {
+ if (!updatedResult) {
return {
type: credential.type,
success,
@@ -205,7 +205,7 @@ const updateEvent = async (
type: credential.type,
success,
uid,
- updatedEvent: updationResult,
+ updatedEvent: updatedResult,
originalEvent: calEvent,
};
};
diff --git a/lib/emails/templates/attendee-scheduled-email.ts b/lib/emails/templates/attendee-scheduled-email.ts
index eabe008f9d..0e4fea8b6d 100644
--- a/lib/emails/templates/attendee-scheduled-email.ts
+++ b/lib/emails/templates/attendee-scheduled-email.ts
@@ -121,6 +121,7 @@ export default class AttendeeScheduledEmail {
${this.calEvent.language("emailed_you_and_any_other_attendees")}
${this.getWhat()}
${this.getWhen()}
+ ${this.getWho()}
${this.getLocation()}
${this.getAdditionalNotes()}
${this.calEvent.language("need_to_reschedule_or_cancel")}
@@ -380,7 +381,9 @@ ${this.getAdditionalNotes()}
${this.calEvent.language("where")}
-
${providerName}
+
${
+ providerName || this.calEvent.location
+ }
`;
}
diff --git a/lib/emails/templates/organizer-scheduled-email.ts b/lib/emails/templates/organizer-scheduled-email.ts
index 8b03dcf33c..3dd206352c 100644
--- a/lib/emails/templates/organizer-scheduled-email.ts
+++ b/lib/emails/templates/organizer-scheduled-email.ts
@@ -125,6 +125,7 @@ ${this.calEvent.language("new_event_scheduled")}
${this.calEvent.language("emailed_you_and_any_other_attendees")}
${this.getWhat()}
${this.getWhen()}
+${this.getWho()}
${this.getLocation()}
${this.getAdditionalNotes()}
${this.calEvent.language("need_to_reschedule_or_cancel")}
@@ -368,7 +369,9 @@ ${getCancelLink(this.calEvent)}
${this.calEvent.language("where")}
-
${providerName}
+
${
+ providerName || this.calEvent.location
+ }
`;
}
diff --git a/lib/events/EventManager.ts b/lib/events/EventManager.ts
index c819162911..790e6e2e59 100644
--- a/lib/events/EventManager.ts
+++ b/lib/events/EventManager.ts
@@ -123,7 +123,6 @@ export default class EventManager {
const result = await this.createVideoEvent(evt);
if (result.createdEvent) {
evt.videoCallData = result.createdEvent;
- evt.location = result.createdEvent.url;
}
results.push(result);
@@ -195,7 +194,6 @@ export default class EventManager {
const result = await this.updateVideoEvent(evt, booking);
if (result.updatedEvent) {
evt.videoCallData = result.updatedEvent;
- evt.location = result.updatedEvent.url;
}
results.push(result);
}
diff --git a/lib/integrations/Apple/AppleCalendarAdapter.ts b/lib/integrations/Apple/AppleCalendarAdapter.ts
index e5cf684702..a2c3244755 100644
--- a/lib/integrations/Apple/AppleCalendarAdapter.ts
+++ b/lib/integrations/Apple/AppleCalendarAdapter.ts
@@ -14,6 +14,7 @@ import {
} from "tsdav";
import { v4 as uuidv4 } from "uuid";
+import { getLocation, getRichDescription } from "@lib/CalEventParser";
import { symmetricDecrypt } from "@lib/crypto";
import logger from "@lib/logger";
@@ -79,8 +80,8 @@ export class AppleCalendar implements CalendarApiAdapter {
start: this.convertDate(event.startTime),
duration: this.getDuration(event.startTime, event.endTime),
title: event.title,
- description: event.description ?? "",
- location: event.location,
+ description: getRichDescription(event),
+ location: getLocation(event),
organizer: { email: event.organizer.email, name: event.organizer.name },
attendees: this.getAttendees(event.attendees),
});
@@ -137,8 +138,8 @@ export class AppleCalendar implements CalendarApiAdapter {
start: this.convertDate(event.startTime),
duration: this.getDuration(event.startTime, event.endTime),
title: event.title,
- description: event.description ?? "",
- location: event.location,
+ description: getRichDescription(event),
+ location: getLocation(event),
organizer: { email: event.organizer.email, name: event.organizer.name },
attendees: this.getAttendees(event.attendees),
});
diff --git a/lib/integrations/CalDav/CalDavCalendarAdapter.ts b/lib/integrations/CalDav/CalDavCalendarAdapter.ts
index 69b27f0779..511c9cb0dc 100644
--- a/lib/integrations/CalDav/CalDavCalendarAdapter.ts
+++ b/lib/integrations/CalDav/CalDavCalendarAdapter.ts
@@ -14,6 +14,7 @@ import {
} from "tsdav";
import { v4 as uuidv4 } from "uuid";
+import { getLocation, getRichDescription } from "@lib/CalEventParser";
import { symmetricDecrypt } from "@lib/crypto";
import logger from "@lib/logger";
@@ -82,8 +83,8 @@ export class CalDavCalendar implements CalendarApiAdapter {
start: this.convertDate(event.startTime),
duration: this.getDuration(event.startTime, event.endTime),
title: event.title,
- description: event.description ?? "",
- location: event.location,
+ description: getRichDescription(event),
+ location: getLocation(event),
organizer: { email: event.organizer.email, name: event.organizer.name },
attendees: this.getAttendees(event.attendees),
});
@@ -141,8 +142,8 @@ export class CalDavCalendar implements CalendarApiAdapter {
start: this.convertDate(event.startTime),
duration: this.getDuration(event.startTime, event.endTime),
title: event.title,
- description: event.description ?? "",
- location: event.location,
+ description: getRichDescription(event),
+ location: getLocation(event),
organizer: { email: event.organizer.email, name: event.organizer.name },
attendees: this.getAttendees(event.attendees),
});
diff --git a/lib/integrations/GoogleCalendar/GoogleCalendarApiAdapter.ts b/lib/integrations/GoogleCalendar/GoogleCalendarApiAdapter.ts
index 047e72f6f7..306b595a7f 100644
--- a/lib/integrations/GoogleCalendar/GoogleCalendarApiAdapter.ts
+++ b/lib/integrations/GoogleCalendar/GoogleCalendarApiAdapter.ts
@@ -2,6 +2,7 @@ import { Credential, Prisma } from "@prisma/client";
import { GetTokenResponse } from "google-auth-library/build/src/auth/oauth2client";
import { Auth, calendar_v3, google } from "googleapis";
+import { getLocation, getRichDescription } from "@lib/CalEventParser";
import { CalendarApiAdapter, CalendarEvent, IntegrationCalendar } from "@lib/calendarClient";
import prisma from "@lib/prisma";
@@ -105,7 +106,7 @@ export const GoogleCalendarApiAdapter = (credential: Credential): CalendarApiAda
auth.getToken().then((myGoogleAuth) => {
const payload: calendar_v3.Schema$Event = {
summary: event.title,
- description: event.description,
+ description: getRichDescription(event),
start: {
dateTime: event.startTime,
timeZone: event.organizer.timeZone,
@@ -122,7 +123,7 @@ export const GoogleCalendarApiAdapter = (credential: Credential): CalendarApiAda
};
if (event.location) {
- payload["location"] = event.location;
+ payload["location"] = getLocation(event);
}
if (event.conferenceData && event.location === "integrations:google:meet") {
@@ -155,7 +156,7 @@ export const GoogleCalendarApiAdapter = (credential: Credential): CalendarApiAda
auth.getToken().then((myGoogleAuth) => {
const payload: calendar_v3.Schema$Event = {
summary: event.title,
- description: event.description,
+ description: getRichDescription(event),
start: {
dateTime: event.startTime,
timeZone: event.organizer.timeZone,
@@ -171,7 +172,7 @@ export const GoogleCalendarApiAdapter = (credential: Credential): CalendarApiAda
};
if (event.location) {
- payload["location"] = event.location;
+ payload["location"] = getLocation(event);
}
const calendar = google.calendar({
diff --git a/lib/integrations/Office365Calendar/Office365CalendarApiAdapter.ts b/lib/integrations/Office365Calendar/Office365CalendarApiAdapter.ts
index 1166079b72..e0843a8063 100644
--- a/lib/integrations/Office365Calendar/Office365CalendarApiAdapter.ts
+++ b/lib/integrations/Office365Calendar/Office365CalendarApiAdapter.ts
@@ -1,6 +1,7 @@
import { Calendar as OfficeCalendar } from "@microsoft/microsoft-graph-types-beta";
import { Credential } from "@prisma/client";
+import { getLocation, getRichDescription } from "@lib/CalEventParser";
import { CalendarApiAdapter, CalendarEvent, IntegrationCalendar } from "@lib/calendarClient";
import { handleErrorsJson, handleErrorsRaw } from "@lib/errors";
import prisma from "@lib/prisma";
@@ -65,7 +66,7 @@ export const Office365CalendarApiAdapter = (credential: Credential): CalendarApi
subject: event.title,
body: {
contentType: "HTML",
- content: event.description,
+ content: getRichDescription(event),
},
start: {
dateTime: event.startTime,
@@ -82,7 +83,7 @@ export const Office365CalendarApiAdapter = (credential: Credential): CalendarApi
},
type: "required",
})),
- location: event.location ? { displayName: event.location } : undefined,
+ location: event.location ? { displayName: getLocation(event) } : undefined,
};
};