feat: add SMS_ATTENDEE action to activateEventType.handler.ts (#21201)

This commit is contained in:
devin-ai-integration[bot] authored and GitHub committed 2025-05-09 18:08:21 +02:00
1 parent 47d941676e
commit 93bad282d7
4 files changed
+119 -29

No files matched your search

@@ -216,7 +216,9 @@ describe("scanWorkflowBody", () => {
passthrough: true,
}),
});
expect(prismaMock.workflowStep.update).not.toHaveBeenCalled();
expect(prismaMock.workflowStep.update).toHaveBeenCalled();
expect(scheduleWorkflowNotifications).toHaveBeenCalled();
expect(lockUser).not.toHaveBeenCalled();
});
});
@@ -17,13 +17,23 @@ export const scanWorkflowBodySchema = z.object({
const log = logger.getSubLogger({ prefix: ["[tasker] scanWorkflowBody"] });
export async function scanWorkflowBody(payload: string) {
const { workflowStepIds, userId } = scanWorkflowBodySchema.parse(JSON.parse(payload));
if (!process.env.IFFY_API_KEY) {
log.info("IFFY_API_KEY not set, skipping scan");
await prisma.workflowStep.updateMany({
where: {
id: {
in: workflowStepIds,
},
},
data: {
verifiedAt: new Date(),
},
});
return;
}
const { workflowStepIds, userId } = scanWorkflowBodySchema.parse(JSON.parse(payload));
const workflowSteps = await prisma.workflowStep.findMany({
where: {
id: {
@@ -91,29 +101,27 @@ export async function scanWorkflowBody(payload: string) {
const isSpam = await iffyScanBody(workflowStep.reminderBody, workflowStep.id);
if (isSpam) {
if (workflowStep.workflow.user?.whitelistWorkflows) {
log.warn(
`For whitelisted user, workflow step ${workflowStep.id} is spam with body ${workflowStep.reminderBody}`
);
if (!workflowStep.workflow.user?.whitelistWorkflows) {
// We won't delete the workflow step incase it is flagged as a false positive
log.warn(`Workflow step ${workflowStep.id} is spam with body ${workflowStep.reminderBody}`);
await lockUser("userId", userId.toString(), LockReason.SPAM_WORKFLOW_BODY);
// Return early if spam is detected
return;
}
// We won't delete the workflow step incase it is flagged as a false positive
log.warn(`Workflow step ${workflowStep.id} is spam with body ${workflowStep.reminderBody}`);
await lockUser("userId", userId.toString(), LockReason.SPAM_WORKFLOW_BODY);
// Return early if spam is detected
return;
} else {
await prisma.workflowStep.update({
where: {
id: workflowStep.id,
},
data: {
verifiedAt: new Date(),
},
});
log.warn(
`For whitelisted user, workflow step ${workflowStep.id} is spam with body ${workflowStep.reminderBody}`
);
}
await prisma.workflowStep.update({
where: {
id: workflowStep.id,
},
data: {
verifiedAt: new Date(),
},
});
}
const workflow = await prisma.workflow.findFirst({
@@ -139,7 +139,7 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType
let allEventTypes = [];
//get all event types of of team or user
//get all event types of team or user
if (eventTypeWorkflow.teamId) {
allEventTypes = await prisma.eventType.findMany({
where: {
@@ -193,7 +193,14 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType
// activate workflow and schedule reminders for existing bookings
const bookingsForReminders = await prisma.booking.findMany({
where: {
eventTypeId: eventTypeId,
OR: [
{ eventTypeId },
{
eventType: {
parentId: eventTypeId,
},
},
],
status: BookingStatus.ACCEPTED,
startTime: {
gte: new Date(),
@@ -352,6 +359,44 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType
teamId: eventTypeWorkflow.teamId,
verifiedAt: step.verifiedAt,
});
} else if (booking.smsReminderNumber) {
if (step.action === WorkflowActions.SMS_ATTENDEE) {
await scheduleSMSReminder({
evt: bookingInfo,
reminderPhone: booking.smsReminderNumber,
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,
verifiedAt: step.verifiedAt,
});
} else if (step.action === WorkflowActions.WHATSAPP_ATTENDEE) {
await scheduleWhatsappReminder({
evt: bookingInfo,
reminderPhone: booking.smsReminderNumber,
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,
verifiedAt: step.verifiedAt,
});
}
}
}
}
@@ -44,6 +44,7 @@ export const bookingSelect = {
title: true,
uid: true,
metadata: true,
smsReminderNumber: true,
attendees: {
select: {
name: true,
@@ -620,10 +621,6 @@ export async function scheduleBookingReminders(
//create reminders for all bookings for each workflow step
const promiseSteps = workflowSteps.map(async (step) => {
// we do not have attendees phone number (user is notified about that when setting this action)
if (step.action == WorkflowActions.SMS_ATTENDEE || step.action == WorkflowActions.WHATSAPP_ATTENDEE)
return;
const promiseScheduleReminders = bookings.map(async (booking) => {
const defaultLocale = "en";
const bookingInfo = {
@@ -742,6 +739,44 @@ export async function scheduleBookingReminders(
teamId: teamId,
verifiedAt: step?.verifiedAt ?? null,
});
} else if (booking.smsReminderNumber) {
if (step.action === WorkflowActions.SMS_ATTENDEE) {
await scheduleSMSReminder({
evt: bookingInfo,
reminderPhone: booking.smsReminderNumber,
triggerEvent: trigger,
action: step.action,
timeSpan: {
time,
timeUnit,
},
message: step.reminderBody || "",
workflowStepId: step.id,
template: step.template,
sender: step.sender,
userId: userId,
teamId: teamId,
verifiedAt: step?.verifiedAt ?? null,
});
} else if (step.action === WorkflowActions.WHATSAPP_ATTENDEE) {
await scheduleWhatsappReminder({
evt: bookingInfo,
reminderPhone: booking.smsReminderNumber,
triggerEvent: trigger,
action: step.action,
timeSpan: {
time,
timeUnit,
},
message: step.reminderBody || "",
workflowStepId: step.id,
template: step.template,
sender: step.sender,
userId: userId,
teamId: teamId,
verifiedAt: step?.verifiedAt ?? null,
});
}
}
});
await Promise.all(promiseScheduleReminders);