Delay workflow email cancellation in sendgrid for all case (#7647)

* don't use immediate email cancellation in any case

* use continue

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
This commit is contained in:
Carina Wollendorfer
2023-03-10 14:28:42 +00:00
committed by GitHub
co-authored by CarinaWolli
parent 4e8653cf4e
commit d50473468a
7 changed files with 62 additions and 59 deletions
@@ -1147,7 +1147,7 @@ async function handler(
// cancel workflow reminders from previous rescheduled booking
originalRescheduledBooking.workflowReminders.forEach((reminder) => {
if (reminder.method === WorkflowMethods.EMAIL) {
deleteScheduledEmailReminder(reminder.id, reminder.referenceId, true);
deleteScheduledEmailReminder(reminder.id, reminder.referenceId);
} else if (reminder.method === WorkflowMethods.SMS) {
deleteScheduledSMSReminder(reminder.id, reminder.referenceId);
}
@@ -7,10 +7,11 @@ import type { NextApiRequest, NextApiResponse } from "next";
import dayjs from "@calcom/dayjs";
import { defaultHandler } from "@calcom/lib/server";
import prisma from "@calcom/prisma";
import { Prisma, WorkflowReminder } from "@calcom/prisma/client";
import type { Prisma, WorkflowReminder } from "@calcom/prisma/client";
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
import customTemplate, { VariablesType } from "../lib/reminders/templates/customTemplate";
import type { VariablesType } from "../lib/reminders/templates/customTemplate";
import customTemplate from "../lib/reminders/templates/customTemplate";
import emailReminderTemplate from "../lib/reminders/templates/emailReminderTemplate";
const sendgridAPIKey = process.env.SENDGRID_API_KEY as string;
@@ -103,15 +104,18 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
}
for (const reminder of unscheduledReminders) {
if (!reminder.workflowStep || !reminder.booking) {
continue;
}
try {
let sendTo;
switch (reminder.workflowStep.action) {
case WorkflowActions.EMAIL_HOST:
sendTo = reminder.booking?.user?.email;
sendTo = reminder.booking.user?.email;
break;
case WorkflowActions.EMAIL_ATTENDEE:
sendTo = reminder.booking?.attendees[0].email;
sendTo = reminder.booking.attendees[0].email;
break;
case WorkflowActions.EMAIL_ADDRESS:
sendTo = reminder.workflowStep.sendTo;
@@ -119,24 +123,24 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
const name =
reminder.workflowStep.action === WorkflowActions.EMAIL_ATTENDEE
? reminder.booking?.attendees[0].name
: reminder.booking?.user?.name;
? reminder.booking.attendees[0].name
: reminder.booking.user?.name;
const attendeeName =
reminder.workflowStep.action === WorkflowActions.EMAIL_ATTENDEE
? reminder.booking?.user?.name
: reminder.booking?.attendees[0].name;
? reminder.booking.user?.name
: reminder.booking.attendees[0].name;
const timeZone =
reminder.workflowStep.action === WorkflowActions.EMAIL_ATTENDEE
? reminder.booking?.attendees[0].timeZone
: reminder.booking?.user?.timeZone;
? reminder.booking.attendees[0].timeZone
: reminder.booking.user?.timeZone;
const locale =
reminder.workflowStep.action === WorkflowActions.EMAIL_ATTENDEE ||
reminder.workflowStep.action === WorkflowActions.SMS_ATTENDEE
? reminder.booking?.attendees[0].locale
: reminder.booking?.user?.locale;
? reminder.booking.attendees[0].locale
: reminder.booking.user?.locale;
let emailContent = {
emailSubject: reminder.workflowStep.emailSubject || "",
@@ -149,9 +153,9 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
switch (reminder.workflowStep.template) {
case WorkflowTemplates.REMINDER:
emailContent = emailReminderTemplate(
reminder.booking?.startTime.toISOString() || "",
reminder.booking?.endTime.toISOString() || "",
reminder.booking?.eventType?.title || "",
reminder.booking.startTime.toISOString() || "",
reminder.booking.endTime.toISOString() || "",
reminder.booking.eventType?.title || "",
timeZone || "",
attendeeName || "",
name || ""
@@ -160,16 +164,16 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
case WorkflowTemplates.CUSTOM:
const variables: VariablesType = {
eventName: reminder.booking?.eventType?.title || "",
organizerName: reminder.booking?.user?.name || "",
attendeeName: reminder.booking?.attendees[0].name,
attendeeEmail: reminder.booking?.attendees[0].email,
eventDate: dayjs(reminder.booking?.startTime).tz(timeZone),
eventTime: dayjs(reminder.booking?.startTime).tz(timeZone),
organizerName: reminder.booking.user?.name || "",
attendeeName: reminder.booking.attendees[0].name,
attendeeEmail: reminder.booking.attendees[0].email,
eventDate: dayjs(reminder.booking.startTime).tz(timeZone),
eventTime: dayjs(reminder.booking.startTime).tz(timeZone),
timeZone: timeZone,
location: reminder.booking?.location || "",
additionalNotes: reminder.booking?.description,
customInputs: reminder.booking?.customInputs,
meetingUrl: bookingMetadataSchema.parse(reminder.booking?.metadata || {})?.videoCallUrl,
location: reminder.booking.location || "",
additionalNotes: reminder.booking.description,
customInputs: reminder.booking.customInputs,
meetingUrl: bookingMetadataSchema.parse(reminder.booking.metadata || {})?.videoCallUrl,
};
const emailSubject = await customTemplate(
reminder.workflowStep.emailSubject || "",
@@ -204,7 +208,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
html: emailContent.emailBody.html,
batchId: batchId,
sendAt: dayjs(reminder.scheduledDate).unix(),
replyTo: reminder.booking?.user?.email || senderEmail,
replyTo: reminder.booking.user?.email || senderEmail,
});
}
@@ -9,7 +9,8 @@ import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
import { getSenderId } from "../lib/alphanumericSenderIdSupport";
import * as twilio from "../lib/reminders/smsProviders/twilioProvider";
import customTemplate, { VariablesType } from "../lib/reminders/templates/customTemplate";
import type { VariablesType } from "../lib/reminders/templates/customTemplate";
import customTemplate from "../lib/reminders/templates/customTemplate";
import smsReminderTemplate from "../lib/reminders/templates/smsReminderTemplate";
async function handler(req: NextApiRequest, res: NextApiResponse) {
@@ -53,6 +54,9 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
if (!unscheduledReminders.length) res.json({ ok: true });
for (const reminder of unscheduledReminders) {
if (!reminder.workflowStep || !reminder.booking) {
continue;
}
try {
const sendTo =
reminder.workflowStep.action === WorkflowActions.SMS_NUMBER
@@ -1,10 +1,5 @@
import {
TimeUnit,
WorkflowTriggerEvents,
WorkflowTemplates,
WorkflowActions,
WorkflowMethods,
} from "@prisma/client";
import type { TimeUnit } from "@prisma/client";
import { WorkflowTriggerEvents, WorkflowTemplates, WorkflowActions, WorkflowMethods } from "@prisma/client";
import client from "@sendgrid/client";
import sgMail from "@sendgrid/mail";
@@ -12,8 +7,9 @@ import dayjs from "@calcom/dayjs";
import prisma from "@calcom/prisma";
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
import { BookingInfo, timeUnitLowerCase } from "./smsReminderManager";
import customTemplate, { VariablesType } from "./templates/customTemplate";
import type { BookingInfo, timeUnitLowerCase } from "./smsReminderManager";
import type { VariablesType } from "./templates/customTemplate";
import customTemplate from "./templates/customTemplate";
import emailReminderTemplate from "./templates/emailReminderTemplate";
let sendgridAPIKey, senderEmail: string;
@@ -194,11 +190,7 @@ export const scheduleEmailReminder = async (
}
};
export const deleteScheduledEmailReminder = async (
reminderId: number,
referenceId: string | null,
immediateDelete?: boolean
) => {
export const deleteScheduledEmailReminder = async (reminderId: number, referenceId: string | null) => {
try {
if (!referenceId) {
await prisma.workflowReminder.delete({
@@ -210,18 +202,6 @@ export const deleteScheduledEmailReminder = async (
return;
}
if (immediateDelete) {
await client.request({
url: "/v3/user/scheduled_sends",
method: "POST",
body: {
batch_id: referenceId,
status: "cancel",
},
});
return;
}
await prisma.workflowReminder.update({
where: {
id: reminderId,
@@ -0,0 +1,15 @@
-- DropForeignKey
ALTER TABLE "WorkflowReminder" DROP CONSTRAINT "WorkflowReminder_bookingUid_fkey";
-- DropForeignKey
ALTER TABLE "WorkflowReminder" DROP CONSTRAINT "WorkflowReminder_workflowStepId_fkey";
-- AlterTable
ALTER TABLE "WorkflowReminder" ALTER COLUMN "bookingUid" DROP NOT NULL,
ALTER COLUMN "workflowStepId" DROP NOT NULL;
-- AddForeignKey
ALTER TABLE "WorkflowReminder" ADD CONSTRAINT "WorkflowReminder_bookingUid_fkey" FOREIGN KEY ("bookingUid") REFERENCES "Booking"("uid") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "WorkflowReminder" ADD CONSTRAINT "WorkflowReminder_workflowStepId_fkey" FOREIGN KEY ("workflowStepId") REFERENCES "WorkflowStep"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+4 -4
View File
@@ -642,14 +642,14 @@ enum TimeUnit {
model WorkflowReminder {
id Int @id @default(autoincrement())
bookingUid String
booking Booking? @relation(fields: [bookingUid], references: [uid], onDelete: Cascade)
bookingUid String?
booking Booking? @relation(fields: [bookingUid], references: [uid])
method WorkflowMethods
scheduledDate DateTime
referenceId String? @unique
scheduled Boolean
workflowStepId Int
workflowStep WorkflowStep @relation(fields: [workflowStepId], references: [id], onDelete: Cascade)
workflowStepId Int?
workflowStep WorkflowStep? @relation(fields: [workflowStepId], references: [id])
cancelled Boolean?
}
@@ -410,7 +410,7 @@ export const workflowsRouter = router({
//cancel workflow reminders of deleted workflow
scheduledReminders.forEach((reminder) => {
if (reminder.method === WorkflowMethods.EMAIL) {
deleteScheduledEmailReminder(reminder.id, reminder.referenceId, true);
deleteScheduledEmailReminder(reminder.id, reminder.referenceId);
} else if (reminder.method === WorkflowMethods.SMS) {
deleteScheduledSMSReminder(reminder.id, reminder.referenceId);
}
@@ -736,7 +736,7 @@ export const workflowsRouter = router({
if (remindersFromStep.length > 0) {
remindersFromStep.forEach((reminder) => {
if (reminder.method === WorkflowMethods.EMAIL) {
deleteScheduledEmailReminder(reminder.id, reminder.referenceId, true);
deleteScheduledEmailReminder(reminder.id, reminder.referenceId);
} else if (reminder.method === WorkflowMethods.SMS) {
deleteScheduledSMSReminder(reminder.id, reminder.referenceId);
}