diff --git a/lib/events/EventManager.ts b/lib/events/EventManager.ts index 28a7876a..050f870d 100644 --- a/lib/events/EventManager.ts +++ b/lib/events/EventManager.ts @@ -3,6 +3,9 @@ import { Credential } from "@prisma/client"; import async from "async"; import { createMeeting, updateMeeting } from "@lib/videoClient"; import prisma from "@lib/prisma"; +import { LocationType } from "@lib/location"; +import { v5 as uuidv5 } from "uuid"; +import merge from "lodash.merge"; export interface EventResult { type: string; @@ -29,6 +32,10 @@ export interface PartialReference { uid: string; } +interface GetLocationRequestFromIntegrationRequest { + location: string; +} + export default class EventManager { calendarCredentials: Array; videoCredentials: Array; @@ -51,6 +58,7 @@ export default class EventManager { * @param event */ public async create(event: CalendarEvent): Promise { + event = EventManager.processLocation(event); const isVideo = EventManager.isIntegration(event.location); // First, create all calendar events. If this is a video event, don't send a mail right here. @@ -82,6 +90,8 @@ export default class EventManager { * @param rescheduleUid */ public async update(event: CalendarEvent, rescheduleUid: string): Promise { + event = EventManager.processLocation(event); + // Get details of existing booking. const booking = await prisma.booking.findFirst({ where: { @@ -227,4 +237,52 @@ export default class EventManager { private static isIntegration(location: string): boolean { return location.includes("integrations:"); } + + /** + * Helper function for processLocation: Returns the conferenceData object to be merged + * with the CalendarEvent. + * + * @param locationObj + * @private + */ + private static getLocationRequestFromIntegration(locationObj: GetLocationRequestFromIntegrationRequest) { + const location = locationObj.location; + + if (location === LocationType.GoogleMeet.valueOf() || location === LocationType.Zoom.valueOf()) { + const requestId = uuidv5(location, uuidv5.URL); + + return { + conferenceData: { + createRequest: { + requestId: requestId, + }, + }, + location, + }; + } + + return null; + } + + /** + * Takes a CalendarEvent and adds a ConferenceData object to the event + * if the event has an integration-related location. + * + * @param event + * @private + */ + private static processLocation(event: CalendarEvent): CalendarEvent { + // If location is set to an integration location + // Build proper transforms for evt object + // Extend evt object with those transformations + if (event.location?.includes("integration")) { + const maybeLocationRequestObject = EventManager.getLocationRequestFromIntegration({ + location: event.location, + }); + + event = merge(event, maybeLocationRequestObject); + } + + return event; + } } diff --git a/pages/api/book/[user].ts b/pages/api/book/[user].ts index f086bf3f..df756da3 100644 --- a/pages/api/book/[user].ts +++ b/pages/api/book/[user].ts @@ -6,8 +6,6 @@ import short from "short-uuid"; import { getBusyVideoTimes } from "@lib/videoClient"; import EventAttendeeMail from "../../../lib/emails/EventAttendeeMail"; import { getEventName } from "@lib/event"; -import { LocationType } from "@lib/location"; -import merge from "lodash.merge"; import dayjs from "dayjs"; import logger from "../../../lib/logger"; import EventManager, { CreateUpdateResult, EventResult } from "@lib/events/EventManager"; @@ -86,38 +84,6 @@ function isOutOfBounds( } } -interface GetLocationRequestFromIntegrationRequest { - location: string; -} - -const getLocationRequestFromIntegration = ({ location }: GetLocationRequestFromIntegrationRequest) => { - if (location === LocationType.GoogleMeet.valueOf()) { - const requestId = uuidv5(location, uuidv5.URL); - - return { - conferenceData: { - createRequest: { - requestId: requestId, - }, - }, - location, - }; - } else if (location === LocationType.Zoom.valueOf()) { - const requestId = uuidv5(location, uuidv5.URL); - - return { - conferenceData: { - createRequest: { - requestId: requestId, - }, - }, - location, - }; - } - - return null; -}; - export async function handleLegacyConfirmationMail( results: Array, selectedEventType: { requiresConfirmation: boolean }, @@ -235,9 +201,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) }, }); - const rawLocation = req.body.location; - - let evt: CalendarEvent = { + const evt: CalendarEvent = { type: selectedEventType.title, title: getEventName(req.body.name, selectedEventType.title, selectedEventType.eventName), description: req.body.notes, @@ -245,25 +209,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) endTime: req.body.end, organizer: { email: currentUser.email, name: currentUser.name, timeZone: currentUser.timeZone }, attendees: [{ email: req.body.email, name: req.body.name, timeZone: req.body.timeZone }], + location: req.body.location, // Will be processed by the EventManager later. }; - // If phone or inPerson use raw location - // set evt.location to req.body.location - if (!rawLocation?.includes("integration")) { - evt.location = rawLocation; - } - - // If location is set to an integration location - // Build proper transforms for evt object - // Extend evt object with those transformations - if (rawLocation?.includes("integration")) { - const maybeLocationRequestObject = getLocationRequestFromIntegration({ - location: rawLocation, - }); - - evt = merge(evt, maybeLocationRequestObject); - } - const eventType = await prisma.eventType.findFirst({ where: { userId: currentUser.id,