Compare commits
2 Commits
main
...
gh-readonl
Author | SHA1 | Date | |
---|---|---|---|
|
84fb1e2a64 | ||
|
d0030ce3a3 |
|
@ -1,5 +1,13 @@
|
||||||
export const slugify = (str: string) => {
|
export const slugify = (str: string) => {
|
||||||
return str.replace(/[^a-zA-Z0-9-]/g, "-").toLowerCase();
|
return str
|
||||||
|
.toLowerCase() // Convert to lowercase
|
||||||
|
.trim() // Remove whitespace from both sides
|
||||||
|
.normalize("NFD") // Normalize to decomposed form for handling accents
|
||||||
|
.replace(/\p{Diacritic}/gu, "") // Remove any diacritics (accents) from characters
|
||||||
|
.replace(/[^\p{L}\p{N}\p{Zs}\p{Emoji}]+/gu, "-") // Replace any non-alphanumeric characters (including Unicode) with a dash
|
||||||
|
.replace(/[\s_]+/g, "-") // Replace whitespace and underscores with a single dash
|
||||||
|
.replace(/^-+/, "") // Remove dashes from start
|
||||||
|
.replace(/-+$/, ""); // Remove dashes from end
|
||||||
};
|
};
|
||||||
|
|
||||||
export default slugify;
|
export default slugify;
|
||||||
|
|
|
@ -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 { 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 type { TrpcSessionUser } from "@calcom/trpc/server/trpc";
|
||||||
|
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
|
@ -17,7 +27,7 @@ type ActivateEventTypeOptions = {
|
||||||
export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventTypeOptions) => {
|
export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventTypeOptions) => {
|
||||||
const { eventTypeId, workflowId } = input;
|
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({
|
const userEventType = await prisma.eventType.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: eventTypeId,
|
id: eventTypeId,
|
||||||
|
@ -76,6 +86,35 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isActive) {
|
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({
|
await prisma.workflowsOnEventTypes.deleteMany({
|
||||||
where: {
|
where: {
|
||||||
workflowId,
|
workflowId,
|
||||||
|
@ -88,6 +127,99 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType
|
||||||
eventTypeId,
|
eventTypeId,
|
||||||
});
|
});
|
||||||
} else {
|
} 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({
|
await prisma.workflowsOnEventTypes.create({
|
||||||
data: {
|
data: {
|
||||||
workflowId,
|
workflowId,
|
||||||
|
|
|
@ -532,7 +532,7 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
|
||||||
user: true,
|
user: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
bookingsForReminders.forEach(async (booking) => {
|
for (const booking of bookingsForReminders) {
|
||||||
const bookingInfo = {
|
const bookingInfo = {
|
||||||
uid: booking.uid,
|
uid: booking.uid,
|
||||||
attendees: booking.attendees.map((attendee) => {
|
attendees: booking.attendees.map((attendee) => {
|
||||||
|
@ -611,7 +611,7 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
|
||||||
userWorkflow.teamId
|
userWorkflow.teamId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user