diff --git a/packages/features/ee/round-robin/roundRobinManualReassignment.ts b/packages/features/ee/round-robin/roundRobinManualReassignment.ts index 1ed40527bc..b9ac0962de 100644 --- a/packages/features/ee/round-robin/roundRobinManualReassignment.ts +++ b/packages/features/ee/round-robin/roundRobinManualReassignment.ts @@ -502,8 +502,6 @@ export async function handleWorkflowsUpdate({ includeCalendarEvent: workflowStep.includeCalendarEvent, workflowStepId: workflowStep.id, verifiedAt: workflowStep.verifiedAt, - userId: workflow.userId, - teamId: workflow.teamId, }); } diff --git a/packages/features/ee/workflows/lib/reminders/emailReminderManager.ts b/packages/features/ee/workflows/lib/reminders/emailReminderManager.ts index 819f018ec9..5c039c1dfc 100644 --- a/packages/features/ee/workflows/lib/reminders/emailReminderManager.ts +++ b/packages/features/ee/workflows/lib/reminders/emailReminderManager.ts @@ -3,7 +3,6 @@ import { v4 as uuidv4 } from "uuid"; import dayjs from "@calcom/dayjs"; import generateIcsString from "@calcom/emails/lib/generateIcsString"; -import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { preprocessNameFieldDataWithVariant } from "@calcom/features/form-builder/utils"; import tasker from "@calcom/features/tasker"; import { SENDER_NAME, WEBSITE_URL } from "@calcom/lib/constants"; @@ -19,10 +18,8 @@ import { } from "@calcom/prisma/enums"; import { bookingMetadataSchema } from "@calcom/prisma/zod-utils"; -import { IMMEDIATE_WORKFLOW_TRIGGER_EVENTS } from "../constants"; import { getWorkflowRecipientEmail } from "../getWorkflowReminders"; import { sendOrScheduleWorkflowEmails } from "./providers/emailProvider"; -import { getBatchId, sendSendgridMail } from "./providers/sendgridProvider"; import type { AttendeeInBookingInfo, BookingInfo, timeUnitLowerCase } from "./smsReminderManager"; import type { VariablesType } from "./templates/customTemplate"; import customTemplate from "./templates/customTemplate"; @@ -53,13 +50,10 @@ interface scheduleEmailReminderArgs extends ScheduleReminderArgs { evt: BookingInfo; sendTo: string[]; action: ScheduleEmailReminderAction; - userId?: number | null; - teamId?: number | null; emailSubject?: string; emailBody?: string; hideBranding?: boolean; includeCalendarEvent?: boolean; - isMandatoryReminder?: boolean; verifiedAt: Date | null; } @@ -77,11 +71,8 @@ export const scheduleEmailReminder = async (args: scheduleEmailReminderArgs) => emailBody = "", hideBranding, includeCalendarEvent, - isMandatoryReminder, action, verifiedAt, - userId, - teamId, } = args; if (!verifiedAt) { @@ -91,7 +82,6 @@ export const scheduleEmailReminder = async (args: scheduleEmailReminderArgs) => const { startTime, endTime } = evt; const uid = evt.uid as string; - const currentDate = dayjs(); const timeUnit: timeUnitLowerCase | undefined = timeSpan.timeUnit?.toLocaleLowerCase() as timeUnitLowerCase; let scheduledDate = null; @@ -286,130 +276,26 @@ export const scheduleEmailReminder = async (args: scheduleEmailReminderArgs) => const mailData = await prepareEmailData(); - const isSendgridEnabled = !!(process.env.SENDGRID_API_KEY && process.env.SENDGRID_EMAIL); - - const featureRepo = new FeaturesRepository(prisma); - - const isWorkflowSmtpEmailsEnabled = teamId - ? await featureRepo.checkIfTeamHasFeature(teamId, "workflow-smtp-emails") - : userId - ? await featureRepo.checkIfUserHasFeature(userId, "workflow-smtp-emails") - : false; - - if (isWorkflowSmtpEmailsEnabled || !isSendgridEnabled) { - let reminderUid; - if (scheduledDate) { - const reminder = await prisma.workflowReminder.create({ - data: { - bookingUid: uid, - workflowStepId, - method: WorkflowMethods.EMAIL, - scheduledDate: scheduledDate.toDate(), - scheduled: true, - }, - }); - reminderUid = reminder.uuid; - } - - await sendOrScheduleWorkflowEmails({ - ...mailData, - to: sendTo, - sendAt: scheduledDate?.toDate(), - referenceUid: reminderUid ?? undefined, + let reminderUid = undefined; + if (scheduledDate) { + const reminder = await prisma.workflowReminder.create({ + data: { + bookingUid: uid, + workflowStepId, + method: WorkflowMethods.EMAIL, + scheduledDate: scheduledDate.toDate(), + scheduled: true, + }, }); - - return; + reminderUid = reminder.uuid; } - /** - * @deprecated only needed for SendGrid, use SMTP with tasker instead - */ - if (IMMEDIATE_WORKFLOW_TRIGGER_EVENTS.includes(triggerEvent)) { - try { - const promises = sendTo.map((email) => sendSendgridMail({ ...mailData, to: email })); - // TODO: Maybe don't await for this? - await Promise.all(promises); - } catch (error) { - log.error("Error sending Email"); - } - } else if ( - (triggerEvent === WorkflowTriggerEvents.BEFORE_EVENT || - triggerEvent === WorkflowTriggerEvents.AFTER_EVENT) && - scheduledDate - ) { - // Sendgrid to schedule emails - // Can only schedule at least 60 minutes and at most 72 hours in advance - // To limit the amount of canceled sends we schedule at most 2 hours in advance - if ( - currentDate.isBefore(scheduledDate.subtract(1, "hour")) && - !scheduledDate.isAfter(currentDate.add(2, "hour")) - ) { - try { - const sendgridBatchId = await getBatchId(); - - // If sendEmail failed then workflowReminer will not be created, failing E2E tests - await sendSendgridMail({ - ...mailData, - to: sendTo, - sendAt: scheduledDate.unix(), - batchId: sendgridBatchId, - }); - - if (!isMandatoryReminder) { - await prisma.workflowReminder.create({ - data: { - bookingUid: uid, - workflowStepId: workflowStepId, - method: WorkflowMethods.EMAIL, - scheduledDate: scheduledDate.toDate(), - scheduled: true, - referenceId: sendgridBatchId, - seatReferenceId: seatReferenceUid, - }, - }); - } else { - await prisma.workflowReminder.create({ - data: { - bookingUid: uid, - method: WorkflowMethods.EMAIL, - scheduledDate: scheduledDate.toDate(), - scheduled: true, - referenceId: sendgridBatchId, - seatReferenceId: seatReferenceUid, - isMandatoryReminder: true, - }, - }); - } - } catch (error) { - log.error(`Error scheduling email with error ${error}`); - } - } else if (scheduledDate.isAfter(currentDate.add(2, "hour"))) { - // Write to DB and send to CRON if scheduled reminder date is past 2 hours - if (!isMandatoryReminder) { - await prisma.workflowReminder.create({ - data: { - bookingUid: uid, - workflowStepId: workflowStepId, - method: WorkflowMethods.EMAIL, - scheduledDate: scheduledDate.toDate(), - scheduled: false, - seatReferenceId: seatReferenceUid, - }, - }); - } else { - await prisma.workflowReminder.create({ - data: { - bookingUid: uid, - method: WorkflowMethods.EMAIL, - scheduledDate: scheduledDate.toDate(), - scheduled: false, - seatReferenceId: seatReferenceUid, - isMandatoryReminder: true, - }, - }); - } - } - } + await sendOrScheduleWorkflowEmails({ + ...mailData, + to: sendTo, + sendAt: scheduledDate?.toDate(), + referenceUid: reminderUid ?? undefined, + }); }; export const deleteScheduledEmailReminder = async (reminderId: number) => { diff --git a/packages/features/ee/workflows/lib/reminders/reminderScheduler.ts b/packages/features/ee/workflows/lib/reminders/reminderScheduler.ts index aafec88f36..58e21674a2 100644 --- a/packages/features/ee/workflows/lib/reminders/reminderScheduler.ts +++ b/packages/features/ee/workflows/lib/reminders/reminderScheduler.ts @@ -156,8 +156,6 @@ const processWorkflowStep = async ( seatReferenceUid, includeCalendarEvent: step.includeCalendarEvent, verifiedAt: step.verifiedAt, - userId: workflow.userId, - teamId: workflow.teamId, }); } else if (isWhatsappAction(step.action)) { const sendTo = step.action === WorkflowActions.WHATSAPP_ATTENDEE ? smsReminderNumber : step.sendTo; diff --git a/packages/features/ee/workflows/lib/reminders/scheduleMandatoryReminder.ts b/packages/features/ee/workflows/lib/reminders/scheduleMandatoryReminder.ts index 76c80884e3..564e23653d 100644 --- a/packages/features/ee/workflows/lib/reminders/scheduleMandatoryReminder.ts +++ b/packages/features/ee/workflows/lib/reminders/scheduleMandatoryReminder.ts @@ -63,10 +63,8 @@ async function _scheduleMandatoryReminder({ hideBranding, seatReferenceUid, includeCalendarEvent: false, - isMandatoryReminder: true, // Template is fixed so we don't have to verify verifiedAt: new Date(), - userId: evt.organizer.id, }); } catch (error) { log.error("Error while scheduling mandatory reminders", JSON.stringify({ error })); diff --git a/packages/features/ee/workflows/lib/test/workflows.test.ts b/packages/features/ee/workflows/lib/test/workflows.test.ts index e5c9e992d9..6ac763c906 100644 --- a/packages/features/ee/workflows/lib/test/workflows.test.ts +++ b/packages/features/ee/workflows/lib/test/workflows.test.ts @@ -36,7 +36,6 @@ import { FeaturesRepository } from "../../../../flags/features.repository"; import { deleteWorkfowRemindersOfRemovedMember } from "../../../teams/lib/deleteWorkflowRemindersOfRemovedMember"; import { scheduleEmailReminder } from "../reminders/emailReminderManager"; import * as emailProvider from "../reminders/providers/emailProvider"; -import * as sendgridProvider from "../reminders/providers/sendgridProvider"; const workflowSelect = { id: true, @@ -709,7 +708,6 @@ describe("scheduleBookingReminders", () => { }, }); - const allVerified = await prismock.verifiedNumber.findMany(); await scheduleBookingReminders( bookings, workflow.steps, @@ -1061,7 +1059,6 @@ describe("deleteWorkfowRemindersOfRemovedMember", () => { }); describe("Workflow SMTP Emails Feature Flag", () => { - vi.spyOn(sendgridProvider, "sendSendgridMail"); vi.spyOn(emailProvider, "sendOrScheduleWorkflowEmails"); const mockEvt = { @@ -1097,72 +1094,10 @@ describe("Workflow SMTP Emails Feature Flag", () => { beforeEach(() => { vi.clearAllMocks(); - // Mock SendGrid environment variables - process.env.SENDGRID_API_KEY = "test-key"; - process.env.SENDGRID_EMAIL = "test@example.com"; }); - test("should use SMTP when team has workflow-smtp-emails feature", async () => { - vi.spyOn(FeaturesRepository.prototype, "checkIfTeamHasFeature").mockResolvedValue(true); - - await scheduleEmailReminder({ - ...baseArgs, - teamId: 123, - }); - expect(sendgridProvider.sendSendgridMail).not.toHaveBeenCalled(); - expect(emailProvider.sendOrScheduleWorkflowEmails).toHaveBeenCalled(); - }); - - test("should use SMTP when user has workflow-smtp-emails feature", async () => { - vi.spyOn(FeaturesRepository.prototype, "checkIfUserHasFeature").mockResolvedValue(true); - - await scheduleEmailReminder({ - ...baseArgs, - userId: 123, - }); - expect(sendgridProvider.sendSendgridMail).not.toHaveBeenCalled(); - expect(emailProvider.sendOrScheduleWorkflowEmails).toHaveBeenCalled(); - }); - - test("should use SendGrid when workflow-smtp-emails feature is not enabled for team", async () => { - vi.spyOn(FeaturesRepository.prototype, "checkIfTeamHasFeature").mockResolvedValue(false); - - await scheduleEmailReminder({ - ...baseArgs, - teamId: 123, - }); - - expect(sendgridProvider.sendSendgridMail).toHaveBeenCalled(); - expect(emailProvider.sendOrScheduleWorkflowEmails).not.toHaveBeenCalled(); - }); - - test("should use SendGrid when workflow-smtp-emails feature is not enabled for user", async () => { - vi.spyOn(FeaturesRepository.prototype, "checkIfUserHasFeature").mockResolvedValue(false); - - await scheduleEmailReminder({ - ...baseArgs, - userId: 123, - }); - - expect(sendgridProvider.sendSendgridMail).toHaveBeenCalled(); - expect(emailProvider.sendOrScheduleWorkflowEmails).not.toHaveBeenCalled(); - }); - - test("should use SMTP when SendGrid is not configured", async () => { - vi.spyOn(FeaturesRepository.prototype, "checkIfTeamHasFeature").mockResolvedValue(false); - - vi.spyOn(FeaturesRepository.prototype, "checkIfUserHasFeature").mockResolvedValue(false); - - delete process.env.SENDGRID_API_KEY; - delete process.env.SENDGRID_EMAIL; - - await scheduleEmailReminder({ - ...baseArgs, - teamId: 123, - userId: 456, - }); - - expect(sendgridProvider.sendSendgridMail).not.toHaveBeenCalled(); + test("should use SMTP", async () => { + await scheduleEmailReminder(baseArgs); expect(emailProvider.sendOrScheduleWorkflowEmails).toHaveBeenCalled(); }); }); diff --git a/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts b/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts index 6c73e5c2bd..20bac521c8 100644 --- a/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts +++ b/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts @@ -388,8 +388,6 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType sender: step.sender, workflowStepId: step.id, verifiedAt: step.verifiedAt, - userId: eventTypeWorkflow.userId, - teamId: eventTypeWorkflow.teamId, }); } else if (step.action === WorkflowActions.SMS_NUMBER && step.sendTo) { await scheduleSMSReminder({ diff --git a/packages/trpc/server/routers/viewer/workflows/util.ts b/packages/trpc/server/routers/viewer/workflows/util.ts index a041556c46..d07e38fc44 100644 --- a/packages/trpc/server/routers/viewer/workflows/util.ts +++ b/packages/trpc/server/routers/viewer/workflows/util.ts @@ -794,8 +794,6 @@ export async function scheduleBookingReminders( sender: step.sender, workflowStepId: step.id, verifiedAt: step?.verifiedAt ?? null, - userId, - teamId, }); } else if (step.action === WorkflowActions.SMS_NUMBER && step.sendTo) { await scheduleSMSReminder({