From f29328e6a29699fb27475b34e2f115df6c3230ce Mon Sep 17 00:00:00 2001 From: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com> Date: Mon, 13 Nov 2023 09:28:15 -0500 Subject: [PATCH] fix: meeting url variable in workflow notifitcations (#12308) Co-authored-by: CarinaWolli --- .../bookings/lib/handleConfirmation.ts | 55 +++++++++++++++++-- .../features/bookings/lib/handleNewBooking.ts | 2 +- packages/lib/payment/getBooking.ts | 1 + .../viewer/bookings/confirm.handler.ts | 1 + 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/packages/features/bookings/lib/handleConfirmation.ts b/packages/features/bookings/lib/handleConfirmation.ts index 90c4e63bca..0db3b9c000 100644 --- a/packages/features/bookings/lib/handleConfirmation.ts +++ b/packages/features/bookings/lib/handleConfirmation.ts @@ -12,9 +12,14 @@ import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType"; import logger from "@calcom/lib/logger"; import type { PrismaClient } from "@calcom/prisma"; import { BookingStatus, WebhookTriggerEvents } from "@calcom/prisma/enums"; -import { bookingMetadataSchema } from "@calcom/prisma/zod-utils"; +import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils"; import type { AdditionalInformation, CalendarEvent } from "@calcom/types/Calendar"; +import { + allowDisablingAttendeeConfirmationEmails, + allowDisablingHostConfirmationEmails, +} from "../../ee/workflows/lib/allowDisablingStandardEmails"; + const log = logger.getSubLogger({ prefix: ["[handleConfirmation] book:user"] }); export async function handleConfirmation(args: { @@ -31,10 +36,17 @@ export async function handleConfirmation(args: { length: number; price: number; requiresConfirmation: boolean; + metadata?: Prisma.JsonValue; title: string; teamId?: number | null; parentId?: number | null; + workflows?: { + workflow: Workflow & { + steps: WorkflowStep[]; + }; + }[]; } | null; + metadata?: Prisma.JsonValue; eventTypeId: number | null; smsReminderNumber: string | null; userId: number | null; @@ -45,6 +57,7 @@ export async function handleConfirmation(args: { const eventManager = new EventManager(user); const scheduleResult = await eventManager.create(evt); const results = scheduleResult.results; + const metadata: AdditionalInformation = {}; if (results.length > 0 && results.every((res) => !res.success)) { const error = { @@ -54,8 +67,6 @@ export async function handleConfirmation(args: { log.error(`Booking ${user.username} failed`, JSON.stringify({ error, results })); } else { - const metadata: AdditionalInformation = {}; - if (results.length) { // TODO: Handle created event metadata more elegantly metadata.hangoutLink = results[0].createdEvent?.hangoutLink; @@ -63,7 +74,34 @@ export async function handleConfirmation(args: { metadata.entryPoints = results[0].createdEvent?.entryPoints; } try { - await sendScheduledEmails({ ...evt, additionalInformation: metadata }); + const eventType = booking.eventType; + const eventTypeMetadata = EventTypeMetaDataSchema.parse(eventType?.metadata || {}); + let isHostConfirmationEmailsDisabled = false; + let isAttendeeConfirmationEmailDisabled = false; + + const workflows = eventType?.workflows?.map((workflow) => workflow.workflow); + + if (workflows) { + isHostConfirmationEmailsDisabled = + eventTypeMetadata?.disableStandardEmails?.confirmation?.host || false; + isAttendeeConfirmationEmailDisabled = + eventTypeMetadata?.disableStandardEmails?.confirmation?.attendee || false; + + if (isHostConfirmationEmailsDisabled) { + isHostConfirmationEmailsDisabled = allowDisablingHostConfirmationEmails(workflows); + } + + if (isAttendeeConfirmationEmailDisabled) { + isAttendeeConfirmationEmailDisabled = allowDisablingAttendeeConfirmationEmails(workflows); + } + } + + await sendScheduledEmails( + { ...evt, additionalInformation: metadata }, + undefined, + isHostConfirmationEmailsDisabled, + isAttendeeConfirmationEmailDisabled + ); } catch (error) { log.error(error); } @@ -97,6 +135,8 @@ export async function handleConfirmation(args: { } | null; }[] = []; + const videoCallUrl = metadata.hangoutLink ? metadata.hangoutLink : evt.videoCallData?.url || ""; + if (recurringEventId) { // The booking to confirm is a recurring event and comes from /booking/recurring, proceeding to mark all related // bookings as confirmed. Prisma updateMany does not support relations, so doing this in two steps for now. @@ -118,6 +158,10 @@ export async function handleConfirmation(args: { create: scheduleResult.referencesToCreate, }, paid, + metadata: { + ...(typeof recurringBooking.metadata === "object" ? recurringBooking.metadata : {}), + videoCallUrl, + }, }, select: { eventType: { @@ -169,6 +213,7 @@ export async function handleConfirmation(args: { references: { create: scheduleResult.referencesToCreate, }, + metadata: { ...(typeof booking.metadata === "object" ? booking.metadata : {}), videoCallUrl }, }, select: { eventType: { @@ -218,8 +263,6 @@ export async function handleConfirmation(args: { const eventTypeSlug = updatedBookings[index].eventType?.slug || ""; const isFirstBooking = index === 0; - const videoCallUrl = - bookingMetadataSchema.parse(updatedBookings[index].metadata || {})?.videoCallUrl || ""; await scheduleWorkflowReminders({ workflows: updatedBookings[index]?.eventType?.workflows || [], diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts index 1513acd4f7..f91d3811c5 100644 --- a/packages/features/bookings/lib/handleNewBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking.ts @@ -2516,7 +2516,7 @@ async function handler( ...evt, ...{ metadata: metadataFromEvent, eventType: { slug: eventType.slug } }, }, - isNotConfirmed: evt.requiresConfirmation || false, + isNotConfirmed: !isConfirmedByDefault, isRescheduleEvent: !!rescheduleUid, isFirstRecurringEvent: true, hideBranding: !!eventType.owner?.hideBranding, diff --git a/packages/lib/payment/getBooking.ts b/packages/lib/payment/getBooking.ts index 16846a6ce8..cf11a6c491 100644 --- a/packages/lib/payment/getBooking.ts +++ b/packages/lib/payment/getBooking.ts @@ -30,6 +30,7 @@ export async function getBooking(bookingId: number) { ...bookingMinimalSelect, responses: true, eventType: true, + metadata: true, smsReminderNumber: true, location: true, eventTypeId: true, diff --git a/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts b/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts index 05c2f2790d..39cd84e443 100644 --- a/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts +++ b/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts @@ -48,6 +48,7 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => { attendees: true, eventTypeId: true, responses: true, + metadata: true, eventType: { select: { id: true,