From 84fb4f68b2e405dfbb5d21b77c6106549b8f80a5 Mon Sep 17 00:00:00 2001 From: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:58:30 -0500 Subject: [PATCH] fix: wrong workflow notifications when enabling workflows (#18169) * only schedule workflow emails not send * fix if statement --------- Co-authored-by: CarinaWolli --- .../workflows/activateEventType.handler.ts | 288 +++++++++--------- 1 file changed, 146 insertions(+), 142 deletions(-) diff --git a/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts b/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts index 2191a80dc4..b27e26bff8 100644 --- a/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts +++ b/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts @@ -6,7 +6,7 @@ import { WorkflowRepository } from "@calcom/lib/server/repository/workflow"; import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat"; import { prisma } from "@calcom/prisma"; import { BookingStatus } from "@calcom/prisma/client"; -import { MembershipRole, SchedulingType, WorkflowActions } from "@calcom/prisma/enums"; +import { MembershipRole, SchedulingType, WorkflowActions, WorkflowTriggerEvents } from "@calcom/prisma/enums"; import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils"; import type { TrpcSessionUser } from "@calcom/trpc/server/trpc"; @@ -186,30 +186,34 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType } await removeSmsReminderFieldForEventTypes({ activeOnToRemove: activeOn, workflowId, isOrg }); } else { - // activate workflow and schedule reminders for existing bookings - - const bookingsForReminders = await prisma.booking.findMany({ - where: { - eventTypeId: eventTypeId, - status: BookingStatus.ACCEPTED, - startTime: { - gte: new Date(), + if ( + eventTypeWorkflow.trigger == WorkflowTriggerEvents.BEFORE_EVENT || + eventTypeWorkflow.trigger == WorkflowTriggerEvents.AFTER_EVENT + ) { + // activate workflow and schedule reminders for existing bookings + const bookingsForReminders = await prisma.booking.findMany({ + where: { + eventTypeId: eventTypeId, + status: BookingStatus.ACCEPTED, + startTime: { + gte: new Date(), + }, }, - }, - include: { - attendees: true, - eventType: { - select: { - schedulingType: true, - slug: true, - hosts: { - select: { - user: { - select: { - email: true, - destinationCalendar: { - select: { - primaryEmail: true, + include: { + attendees: true, + eventType: { + select: { + schedulingType: true, + slug: true, + hosts: { + select: { + user: { + select: { + email: true, + destinationCalendar: { + select: { + primaryEmail: true, + }, }, }, }, @@ -217,129 +221,129 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType }, }, }, + user: true, }, - user: true, - }, - }); + }); - const bookerUrl = await getBookerBaseUrl(ctx.user.organizationId ?? null); + const bookerUrl = await getBookerBaseUrl(ctx.user.organizationId ?? null); - for (const booking of bookingsForReminders) { - const defaultLocale = "en"; - const bookingInfo = { - uid: booking.uid, - bookerUrl, - attendees: booking.attendees.map((attendee) => { - return { - name: attendee.name, - email: attendee.email, - timeZone: attendee.timeZone, - language: { locale: attendee.locale || defaultLocale }, - }; - }), - organizer: booking.user - ? { - name: booking.user.name || "", - email: booking?.userPrimaryEmail ?? booking.user.email, - timeZone: booking.user.timeZone, - timeFormat: getTimeFormatStringFromUserTimeFormat(booking.user.timeFormat), - language: { locale: booking.user.locale || defaultLocale }, - } - : { name: "", email: "", timeZone: "", language: { locale: "" } }, - startTime: booking.startTime.toISOString(), - endTime: booking.endTime.toISOString(), - title: booking.title, - language: { locale: booking?.user?.locale || defaultLocale }, - eventType: { - slug: booking.eventType?.slug || "", - schedulingType: booking.eventType?.schedulingType, - hosts: booking.eventType?.hosts, - }, - metadata: booking.metadata, - }; - for (const step of eventTypeWorkflow.steps) { - if ( - step.action === WorkflowActions.EMAIL_ATTENDEE || - step.action === WorkflowActions.EMAIL_HOST || - step.action === WorkflowActions.EMAIL_ADDRESS - ) { - let sendTo: string[] = []; - - switch (step.action) { - case WorkflowActions.EMAIL_HOST: - sendTo = [bookingInfo.organizer?.email]; - const schedulingType = bookingInfo.eventType?.schedulingType; - const hosts = bookingInfo.eventType.hosts - ?.filter((host) => - bookingInfo.attendees.some((attendee) => host.user.email === attendee.email) - ) - .map(({ user }) => user.destinationCalendar?.primaryEmail ?? user.email); - if ( - (schedulingType === SchedulingType.ROUND_ROBIN || - schedulingType === SchedulingType.COLLECTIVE) && - hosts - ) { - sendTo = sendTo.concat(hosts); + for (const booking of bookingsForReminders) { + const defaultLocale = "en"; + const bookingInfo = { + uid: booking.uid, + bookerUrl, + attendees: booking.attendees.map((attendee) => { + return { + name: attendee.name, + email: attendee.email, + timeZone: attendee.timeZone, + language: { locale: attendee.locale || defaultLocale }, + }; + }), + organizer: booking.user + ? { + name: booking.user.name || "", + email: booking?.userPrimaryEmail ?? booking.user.email, + timeZone: booking.user.timeZone, + timeFormat: getTimeFormatStringFromUserTimeFormat(booking.user.timeFormat), + language: { locale: booking.user.locale || defaultLocale }, } - break; - case WorkflowActions.EMAIL_ATTENDEE: - sendTo = bookingInfo.attendees - .map((attendee) => attendee.email) - .filter((email): email is string => !!email); - break; - case WorkflowActions.EMAIL_ADDRESS: - sendTo = step.sendTo ? [step.sendTo] : []; - break; - } + : { name: "", email: "", timeZone: "", language: { locale: "" } }, + startTime: booking.startTime.toISOString(), + endTime: booking.endTime.toISOString(), + title: booking.title, + language: { locale: booking?.user?.locale || defaultLocale }, + eventType: { + slug: booking.eventType?.slug || "", + schedulingType: booking.eventType?.schedulingType, + hosts: booking.eventType?.hosts, + }, + metadata: booking.metadata, + }; + for (const step of eventTypeWorkflow.steps) { + if ( + step.action === WorkflowActions.EMAIL_ATTENDEE || + step.action === WorkflowActions.EMAIL_HOST || + step.action === WorkflowActions.EMAIL_ADDRESS + ) { + let sendTo: string[] = []; - await scheduleEmailReminder({ - evt: bookingInfo, - triggerEvent: eventTypeWorkflow.trigger, - action: step.action, - timeSpan: { - time: eventTypeWorkflow.time, - timeUnit: eventTypeWorkflow.timeUnit, - }, - sendTo, - emailSubject: step.emailSubject || "", - emailBody: step.reminderBody || "", - template: step.template, - sender: step.sender, - workflowStepId: step.id, - }); - } else if (step.action === WorkflowActions.SMS_NUMBER && step.sendTo) { - await scheduleSMSReminder({ - evt: bookingInfo, - reminderPhone: step.sendTo, - triggerEvent: eventTypeWorkflow.trigger, - action: step.action, - timeSpan: { - time: eventTypeWorkflow.time, - timeUnit: eventTypeWorkflow.timeUnit, - }, - message: step.reminderBody || "", - workflowStepId: step.id, - template: step.template, - sender: step.sender, - userId: booking.userId, - teamId: eventTypeWorkflow.teamId, - }); - } else if (step.action === WorkflowActions.WHATSAPP_NUMBER && step.sendTo) { - await scheduleWhatsappReminder({ - evt: bookingInfo, - reminderPhone: step.sendTo, - triggerEvent: eventTypeWorkflow.trigger, - action: step.action, - timeSpan: { - time: eventTypeWorkflow.time, - timeUnit: eventTypeWorkflow.timeUnit, - }, - message: step.reminderBody || "", - workflowStepId: step.id, - template: step.template, - userId: booking.userId, - teamId: eventTypeWorkflow.teamId, - }); + switch (step.action) { + case WorkflowActions.EMAIL_HOST: + sendTo = [bookingInfo.organizer?.email]; + const schedulingType = bookingInfo.eventType?.schedulingType; + const hosts = bookingInfo.eventType.hosts + ?.filter((host) => + bookingInfo.attendees.some((attendee) => host.user.email === attendee.email) + ) + .map(({ user }) => user.destinationCalendar?.primaryEmail ?? user.email); + if ( + (schedulingType === SchedulingType.ROUND_ROBIN || + schedulingType === SchedulingType.COLLECTIVE) && + hosts + ) { + sendTo = sendTo.concat(hosts); + } + break; + case WorkflowActions.EMAIL_ATTENDEE: + sendTo = bookingInfo.attendees + .map((attendee) => attendee.email) + .filter((email): email is string => !!email); + break; + case WorkflowActions.EMAIL_ADDRESS: + sendTo = step.sendTo ? [step.sendTo] : []; + break; + } + + await scheduleEmailReminder({ + evt: bookingInfo, + triggerEvent: eventTypeWorkflow.trigger, + action: step.action, + timeSpan: { + time: eventTypeWorkflow.time, + timeUnit: eventTypeWorkflow.timeUnit, + }, + sendTo, + emailSubject: step.emailSubject || "", + emailBody: step.reminderBody || "", + template: step.template, + sender: step.sender, + workflowStepId: step.id, + }); + } else if (step.action === WorkflowActions.SMS_NUMBER && step.sendTo) { + await scheduleSMSReminder({ + evt: bookingInfo, + reminderPhone: step.sendTo, + triggerEvent: eventTypeWorkflow.trigger, + action: step.action, + timeSpan: { + time: eventTypeWorkflow.time, + timeUnit: eventTypeWorkflow.timeUnit, + }, + message: step.reminderBody || "", + workflowStepId: step.id, + template: step.template, + sender: step.sender, + userId: booking.userId, + teamId: eventTypeWorkflow.teamId, + }); + } else if (step.action === WorkflowActions.WHATSAPP_NUMBER && step.sendTo) { + await scheduleWhatsappReminder({ + evt: bookingInfo, + reminderPhone: step.sendTo, + triggerEvent: eventTypeWorkflow.trigger, + action: step.action, + timeSpan: { + time: eventTypeWorkflow.time, + timeUnit: eventTypeWorkflow.timeUnit, + }, + message: step.reminderBody || "", + workflowStepId: step.id, + template: step.template, + userId: booking.userId, + teamId: eventTypeWorkflow.teamId, + }); + } } } }