Files
calendar/packages/features/ee/round-robin/handleRescheduleEventManager.ts
T

175 lines
5.8 KiB
TypeScript

import type { DestinationCalendar } from "@prisma/client";
import type { Prisma } from "@prisma/client";
import { metadata as GoogleMeetMetadata } from "@calcom/app-store/googlevideo/_metadata";
import { MeetLocationType } from "@calcom/app-store/locations";
import EventManager from "@calcom/core/EventManager";
import type { EventManagerInitParams } from "@calcom/core/EventManager";
import { getVideoCallDetails } from "@calcom/features/bookings/lib/handleNewBooking/getVideoCallDetails";
import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser";
import logger from "@calcom/lib/logger";
import { getTranslation } from "@calcom/lib/server/i18n";
import { BookingReferenceRepository } from "@calcom/lib/server/repository/bookingReference";
import { prisma } from "@calcom/prisma";
import type { CalendarEvent, AdditionalInformation } from "@calcom/types/Calendar";
export const handleRescheduleEventManager = async ({
evt,
rescheduleUid,
newBookingId,
changedOrganizer,
previousHostDestinationCalendar,
initParams,
bookingLocation,
bookingId,
bookingICalUID,
bookingMetadata,
}: {
evt: CalendarEvent;
rescheduleUid: string;
newBookingId?: number;
changedOrganizer?: boolean;
previousHostDestinationCalendar?: DestinationCalendar[] | null;
initParams: EventManagerInitParams;
bookingLocation: string | null;
bookingId: number;
bookingICalUID?: string | null;
bookingMetadata?: Prisma.JsonValue;
}) => {
const handleRescheduleEventManager = logger.getSubLogger({
prefix: ["handleRescheduleEventManager", `${bookingId}`],
});
const eventManager = new EventManager(initParams.user, initParams?.eventTypeAppMetadata);
const updateManager = await eventManager.reschedule(
evt,
rescheduleUid,
newBookingId,
changedOrganizer,
previousHostDestinationCalendar
);
const results = updateManager.results ?? [];
const { metadata: videoMetadata, videoCallUrl: _videoCallUrl } = getVideoCallDetails({
results: results,
});
let videoCallUrl = _videoCallUrl;
let metadata: AdditionalInformation = {};
metadata = videoMetadata;
if (results.length) {
// Handle Google Meet results
if (bookingLocation === MeetLocationType) {
const googleMeetResult = {
appName: GoogleMeetMetadata.name,
type: "conferencing",
uid: results[0].uid,
originalEvent: results[0].originalEvent,
};
// Find index of google_calendar inside createManager.referencesToCreate
const googleCalIndex = updateManager.referencesToCreate.findIndex(
(ref) => ref.type === "google_calendar"
);
const googleCalResult = results[googleCalIndex];
const t = await getTranslation("en", "common");
if (!googleCalResult) {
handleRescheduleEventManager.warn("Google Calendar not installed but using Google Meet as location");
results.push({
...googleMeetResult,
success: false,
calWarnings: [t("google_meet_warning")],
});
}
const googleHangoutLink = Array.isArray(googleCalResult?.updatedEvent)
? googleCalResult.updatedEvent[0]?.hangoutLink
: googleCalResult?.updatedEvent?.hangoutLink ?? googleCalResult?.createdEvent?.hangoutLink;
if (googleHangoutLink) {
results.push({
...googleMeetResult,
success: true,
});
// Add google_meet to referencesToCreate in the same index as google_calendar
updateManager.referencesToCreate[googleCalIndex] = {
...updateManager.referencesToCreate[googleCalIndex],
meetingUrl: googleHangoutLink,
};
// Also create a new referenceToCreate with type video for google_meet
updateManager.referencesToCreate.push({
type: "google_meet_video",
meetingUrl: googleHangoutLink,
uid: googleCalResult.uid,
credentialId: updateManager.referencesToCreate[googleCalIndex].credentialId,
});
} else if (googleCalResult && !googleHangoutLink) {
results.push({
...googleMeetResult,
success: false,
});
}
}
const createdOrUpdatedEvent = Array.isArray(results[0]?.updatedEvent)
? results[0]?.updatedEvent[0]
: results[0]?.updatedEvent ?? results[0]?.createdEvent;
metadata.hangoutLink = createdOrUpdatedEvent?.hangoutLink;
metadata.conferenceData = createdOrUpdatedEvent?.conferenceData;
metadata.entryPoints = createdOrUpdatedEvent?.entryPoints;
videoCallUrl =
metadata.hangoutLink || createdOrUpdatedEvent?.url || getVideoCallUrlFromCalEvent(evt) || videoCallUrl;
const calendarResult = results.find((result) => result.type.includes("_calendar"));
evt.iCalUID = Array.isArray(calendarResult?.updatedEvent)
? calendarResult?.updatedEvent[0]?.iCalUID
: calendarResult?.updatedEvent?.iCalUID || undefined;
}
const newReferencesToCreate = structuredClone(updateManager.referencesToCreate);
await BookingReferenceRepository.replaceBookingReferences({
bookingId,
newReferencesToCreate,
});
try {
if (bookingLocation?.startsWith("http")) {
videoCallUrl = bookingLocation;
}
const newBookingMetaData = videoCallUrl
? {
videoCallUrl: getVideoCallUrlFromCalEvent(evt) || videoCallUrl,
}
: undefined;
await prisma.booking.update({
where: {
id: bookingId,
},
data: {
location: bookingLocation,
iCalUID: evt.iCalUID !== bookingICalUID ? evt.iCalUID : bookingICalUID,
metadata: { ...(typeof bookingMetadata === "object" && bookingMetadata), ...newBookingMetaData },
},
});
} catch (error) {
handleRescheduleEventManager.error("Error while updating booking metadata", JSON.stringify({ error }));
}
const evtWithAdditionalInfo = {
...evt,
additionalInformation: metadata,
};
return { evtWithAdditionalInfo };
};