cancel and schedule reminders when workflow activated/deactivated on event type (#8757)
* add switches to advanced even type settings * only show switches when workflow is enabled * check in event type update handler if user is allowed to disable standard emails * don't send emails if disabled * remove reminders when workflow is deactivated on event type * make sure emails can't be disabled if no workflow exist * send workflow emails to all attendees * code clean up * add translations * always send to all attendees when scheduling reminders * schedule reminders if event type gets activated on workflow * schedule reminders (commented code) * change text * schedule reminders for all attendees not just first one --------- Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>8868-cal-1667-bottomnav-only-border-top
parent
492b4d3e97
commit
82d3c4370d
|
@ -1,5 +1,15 @@
|
|||
import {
|
||||
deleteScheduledEmailReminder,
|
||||
scheduleEmailReminder,
|
||||
} from "@calcom/features/ee/workflows/lib/reminders/emailReminderManager";
|
||||
import {
|
||||
deleteScheduledSMSReminder,
|
||||
scheduleSMSReminder,
|
||||
} from "@calcom/features/ee/workflows/lib/reminders/smsReminderManager";
|
||||
import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import { MembershipRole, WorkflowActions } from "@calcom/prisma/enums";
|
||||
import { BookingStatus } from "@calcom/prisma/client";
|
||||
import { MembershipRole, WorkflowActions, WorkflowMethods } from "@calcom/prisma/enums";
|
||||
import type { TrpcSessionUser } from "@calcom/trpc/server/trpc";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
@ -17,7 +27,7 @@ type ActivateEventTypeOptions = {
|
|||
export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventTypeOptions) => {
|
||||
const { eventTypeId, workflowId } = input;
|
||||
|
||||
// Check that vent type belong to the user or team
|
||||
// Check that event type belong to the user or team
|
||||
const userEventType = await prisma.eventType.findFirst({
|
||||
where: {
|
||||
id: eventTypeId,
|
||||
|
@ -76,6 +86,35 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType
|
|||
});
|
||||
|
||||
if (isActive) {
|
||||
// disable workflow for this event type & delete all reminders
|
||||
const remindersToDelete = await prisma.workflowReminder.findMany({
|
||||
where: {
|
||||
booking: {
|
||||
eventTypeId: eventTypeId,
|
||||
userId: ctx.user.id,
|
||||
},
|
||||
workflowStepId: {
|
||||
in: eventTypeWorkflow.steps.map((step) => {
|
||||
return step.id;
|
||||
}),
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
referenceId: true,
|
||||
method: true,
|
||||
scheduled: true,
|
||||
},
|
||||
});
|
||||
|
||||
remindersToDelete.forEach((reminder) => {
|
||||
if (reminder.method === WorkflowMethods.EMAIL) {
|
||||
deleteScheduledEmailReminder(reminder.id, reminder.referenceId);
|
||||
} else if (reminder.method === WorkflowMethods.SMS) {
|
||||
deleteScheduledSMSReminder(reminder.id, reminder.referenceId);
|
||||
}
|
||||
});
|
||||
|
||||
await prisma.workflowsOnEventTypes.deleteMany({
|
||||
where: {
|
||||
workflowId,
|
||||
|
@ -88,6 +127,99 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType
|
|||
eventTypeId,
|
||||
});
|
||||
} 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(),
|
||||
},
|
||||
},
|
||||
include: {
|
||||
attendees: true,
|
||||
eventType: true,
|
||||
user: true,
|
||||
},
|
||||
});
|
||||
|
||||
for (const booking of bookingsForReminders) {
|
||||
const bookingInfo = {
|
||||
uid: booking.uid,
|
||||
attendees: booking.attendees.map((attendee) => {
|
||||
return {
|
||||
name: attendee.name,
|
||||
email: attendee.email,
|
||||
timeZone: attendee.timeZone,
|
||||
language: { locale: attendee.locale || "" },
|
||||
};
|
||||
}),
|
||||
organizer: booking.user
|
||||
? {
|
||||
name: booking.user.name || "",
|
||||
email: booking.user.email,
|
||||
timeZone: booking.user.timeZone,
|
||||
language: { locale: booking.user.locale || "" },
|
||||
}
|
||||
: { name: "", email: "", timeZone: "", language: { locale: "" } },
|
||||
startTime: booking.startTime.toISOString(),
|
||||
endTime: booking.endTime.toISOString(),
|
||||
title: booking.title,
|
||||
language: { locale: booking?.user?.locale || "" },
|
||||
eventType: {
|
||||
slug: booking.eventType?.slug,
|
||||
},
|
||||
};
|
||||
for (const step of eventTypeWorkflow.steps) {
|
||||
if (step.action === WorkflowActions.EMAIL_ATTENDEE || step.action === WorkflowActions.EMAIL_HOST) {
|
||||
let sendTo: string[] = [];
|
||||
|
||||
switch (step.action) {
|
||||
case WorkflowActions.EMAIL_HOST:
|
||||
sendTo = [bookingInfo.organizer?.email];
|
||||
break;
|
||||
case WorkflowActions.EMAIL_ATTENDEE:
|
||||
sendTo = bookingInfo.attendees.map((attendee) => attendee.email);
|
||||
break;
|
||||
}
|
||||
|
||||
await scheduleEmailReminder(
|
||||
bookingInfo,
|
||||
eventTypeWorkflow.trigger,
|
||||
step.action,
|
||||
{
|
||||
time: eventTypeWorkflow.time,
|
||||
timeUnit: eventTypeWorkflow.timeUnit,
|
||||
},
|
||||
sendTo,
|
||||
step.emailSubject || "",
|
||||
step.reminderBody || "",
|
||||
step.id,
|
||||
step.template,
|
||||
step.sender || SENDER_NAME
|
||||
);
|
||||
} else if (step.action === WorkflowActions.SMS_NUMBER && step.sendTo) {
|
||||
await scheduleSMSReminder(
|
||||
bookingInfo,
|
||||
step.sendTo,
|
||||
eventTypeWorkflow.trigger,
|
||||
step.action,
|
||||
{
|
||||
time: eventTypeWorkflow.time,
|
||||
timeUnit: eventTypeWorkflow.timeUnit,
|
||||
},
|
||||
step.reminderBody || "",
|
||||
step.id,
|
||||
step.template,
|
||||
step.sender || SENDER_ID,
|
||||
booking.userId,
|
||||
eventTypeWorkflow.teamId
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await prisma.workflowsOnEventTypes.create({
|
||||
data: {
|
||||
workflowId,
|
||||
|
|
|
@ -532,7 +532,7 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
|
|||
user: true,
|
||||
},
|
||||
});
|
||||
bookingsForReminders.forEach(async (booking) => {
|
||||
for (const booking of bookingsForReminders) {
|
||||
const bookingInfo = {
|
||||
uid: booking.uid,
|
||||
attendees: booking.attendees.map((attendee) => {
|
||||
|
@ -611,7 +611,7 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
|
|||
userWorkflow.teamId
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue