feat: add SMS_ATTENDEE action to activateEventType.handler.ts (#21201)
This commit is contained in:
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);
|
||||
|
||||
Reference in new issue
Block a user