From b731dfd421bf1d1a6a2cfee0aa1a71c72db25093 Mon Sep 17 00:00:00 2001 From: Hariom Balhara Date: Fri, 23 Jun 2023 22:34:34 +0530 Subject: [PATCH] fix: Error during booking when default app is a Static Link Video App and Event has Organizer default location selected. (#9734) --- packages/app-store/locations.ts | 15 ++++++++---- packages/core/videoClient.ts | 12 ++++++++-- .../features/bookings/lib/handleNewBooking.ts | 23 ++++++++++++++----- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/packages/app-store/locations.ts b/packages/app-store/locations.ts index eee45daf3f..95055bfaba 100644 --- a/packages/app-store/locations.ts +++ b/packages/app-store/locations.ts @@ -50,6 +50,11 @@ export const DailyLocationType = "integrations:daily"; export const MeetLocationType = "integrations:google:meet"; +/** + * This isn't an actual location app type. It is a special value that informs to use the Organizer's default conferencing app during booking + */ +export const OrganizerDefaultConferencingAppType = "conferencing"; + export enum DefaultEventLocationTypeEnum { /** * Booker Address @@ -68,6 +73,7 @@ export enum DefaultEventLocationTypeEnum { */ UserPhone = "userPhone", Link = "link", + // Same as `OrganizerDefaultConferencingAppType` Conferencing = "conferencing", } @@ -324,10 +330,11 @@ export const getEventLocationWithType = ( return location; }; -// FIXME: It assumes that type would be sent mostly now. If just in case a value and not type is sent(when old frontend sends requests to new backend), below forEach won't be able to find a match and thus bookingLocation would still be correct equal to reqBody.location -// We must handle the situation where frontend doesn't send us the value because it doesn't have it(displayLocationPublicly not set) -// But we want to store the actual location(except dynamic URL based location type) so that Emails, Calendars pick the value only. -// TODO: We must store both type as well as value so that we know the type of data that we are having. Is it an address or a phone number? This is to be done post v2.0 +/** + * It converts a static link based video location type(e.g. integrations:campfire_video) to it's value (e.g. https://campfire.to/my_link) set in the eventType. + * If the type provided is already a value(when displayLocationPublicly is on), it would just return that. + * For, dynamic link based video location apps, it doesn't do anything. + */ export const getLocationValueForDB = ( bookingLocationTypeOrValue: EventLocationType["type"], eventLocations: LocationObject[] diff --git a/packages/core/videoClient.ts b/packages/core/videoClient.ts index 244354967d..2a11116055 100644 --- a/packages/core/videoClient.ts +++ b/packages/core/videoClient.ts @@ -23,9 +23,17 @@ const getVideoAdapters = async (withCredentials: CredentialPayload[]): Promise 1) { users = users.sort((a, b) => { @@ -771,7 +774,8 @@ async function handler( }); const firstUsersMetadata = userMetadataSchema.parse(users[0].metadata); locationBodyString = firstUsersMetadata?.defaultConferencingApp?.appLink || locationBodyString; - defaultLocationUrl = firstUsersMetadata?.defaultConferencingApp?.appLink; + organizerOrFirstDynamicGroupMemberDefaultLocationUrl = + firstUsersMetadata?.defaultConferencingApp?.appLink; } if ( @@ -838,14 +842,16 @@ async function handler( const [organizerUser] = users; const tOrganizer = await getTranslation(organizerUser?.locale ?? "en", "common"); + // use host default - if (isTeamEventType && locationBodyString === "conferencing") { + if (isTeamEventType && locationBodyString === OrganizerDefaultConferencingAppType) { const metadataParseResult = userMetadataSchema.safeParse(organizerUser.metadata); const organizerMetadata = metadataParseResult.success ? metadataParseResult.data : undefined; if (organizerMetadata) { const app = getAppFromSlug(organizerMetadata?.defaultConferencingApp?.appSlug); locationBodyString = app?.appData?.location?.type || locationBodyString; - defaultLocationUrl = organizerMetadata?.defaultConferencingApp?.appLink; + organizerOrFirstDynamicGroupMemberDefaultLocationUrl = + organizerMetadata?.defaultConferencingApp?.appLink; } else { locationBodyString = ""; } @@ -877,7 +883,11 @@ async function handler( const seed = `${organizerUser.username}:${dayjs(reqBody.start).utc().format()}:${new Date().getTime()}`; const uid = translator.fromUUID(uuidv5(seed, uuidv5.URL)); - const bookingLocation = getLocationValueForDB(locationBodyString, eventType.locations); + // For static link based video apps, it would have the static URL value instead of it's type(e.g. integrations:campfire_video) + // This ensures that createMeeting isn't called for static video apps as bookingLocation becomes just a regular value for them. + const bookingLocation = organizerOrFirstDynamicGroupMemberDefaultLocationUrl + ? organizerOrFirstDynamicGroupMemberDefaultLocationUrl + : getLocationValueForDB(locationBodyString, eventType.locations); const customInputs = getCustomInputsResponses(reqBody, eventType.customInputs); const teamMemberPromises = @@ -2026,7 +2036,8 @@ async function handler( metadata.conferenceData = results[0].createdEvent?.conferenceData; metadata.entryPoints = results[0].createdEvent?.entryPoints; handleAppsStatus(results, booking); - videoCallUrl = metadata.hangoutLink || defaultLocationUrl || videoCallUrl; + videoCallUrl = + metadata.hangoutLink || organizerOrFirstDynamicGroupMemberDefaultLocationUrl || videoCallUrl; } if (noEmail !== true) { let isHostConfirmationEmailsDisabled = false;