diff --git a/packages/app-store/routing-forms/trpc/utils.ts b/packages/app-store/routing-forms/trpc/utils.ts index 948d2aeab6..0f1174c2dd 100644 --- a/packages/app-store/routing-forms/trpc/utils.ts +++ b/packages/app-store/routing-forms/trpc/utils.ts @@ -167,7 +167,8 @@ export async function onFormSubmission( }); const promisesFormSubmittedNoEvent = webhooksFormSubmittedNoEvent.map((webhook) => { - const scheduledAt = dayjs().add(10, "minute").toDate(); + const scheduledAt = dayjs().add(60, "minute").toDate(); + return tasker.create( "triggerFormSubmittedNoEventWebhook", { diff --git a/packages/features/tasker/tasks/triggerFormSubmittedNoEvent/triggerFormSubmittedNoEventWebhook.ts b/packages/features/tasker/tasks/triggerFormSubmittedNoEvent/triggerFormSubmittedNoEventWebhook.ts index 225bbe8115..56ef23dd0c 100644 --- a/packages/features/tasker/tasks/triggerFormSubmittedNoEvent/triggerFormSubmittedNoEventWebhook.ts +++ b/packages/features/tasker/tasks/triggerFormSubmittedNoEvent/triggerFormSubmittedNoEventWebhook.ts @@ -33,6 +33,10 @@ export const ZTriggerFormSubmittedNoEventWebhookPayloadSchema = z.object({ id: z.string(), name: z.string(), teamId: z.number().nullable(), + fields: z + .array(z.object({ id: z.string(), label: z.string() }).passthrough()) + .nullable() + .default([]), }), }); @@ -52,6 +56,49 @@ export async function triggerFormSubmittedNoEventWebhook(payload: string): Promi return; } + const sixtyMinutesAgo = new Date(Date.now() - 60 * 60 * 1000); + const recentResponses = + (await prisma.app_RoutingForms_FormResponse.findMany({ + where: { + formId: form.id, + createdAt: { + gte: sixtyMinutesAgo, + lt: new Date(), + }, + routedToBookingUid: { + not: null, + }, + NOT: { + id: responseId, + }, + }, + })) ?? []; + + const emailValue = Object.values(responses).find( + (response): response is { value: string; label: string } => { + const value = + typeof response === "object" && response && "value" in response ? response.value : response; + return typeof value === "string" && value.includes("@"); + } + )?.value; + + // Check for duplicate email in recent responses + const hasDuplicate = + emailValue && + recentResponses.some((response) => { + return Object.values(response.response as Record).some( + (field) => { + if (!response.response || typeof response.response !== "object") return false; + + return typeof field.value === "string" && field.value.toLowerCase() === emailValue.toLowerCase(); + } + ); + }); + + if (hasDuplicate) { + return; + } + await sendGenericWebhookPayload({ secretKey: webhook.secret, triggerEvent: "FORM_SUBMITTED_NO_EVENT",