fix: workflow email is not sending on form submission (#25722)

* fix: email not sending on form submission

* Remove handleCheckoutSessionExpired function

Removed the handleCheckoutSessionExpired function and its registration in webhookHandlers.
This commit is contained in:
Anik Dhabal Babu
2025-12-09 13:24:41 +00:00
committed by GitHub
parent 476460dad8
commit 6ae2ce8ed9
2 changed files with 126 additions and 3 deletions
@@ -381,4 +381,122 @@ describe("EmailWorkflowService", () => {
expect(result.sendTo.length).toBe(1);
});
});
describe("generateParametersToBuildEmailWorkflowContent - Form Data", () => {
const mockCommonScheduleFunctionParams = {
triggerEvent: WorkflowTriggerEvents.FORM_SUBMITTED,
timeSpan: {
time: null,
timeUnit: null,
},
workflowStepId: 1,
template: WorkflowTemplates.REMINDER,
userId: 1,
teamId: null,
seatReferenceUid: undefined,
verifiedAt: new Date(),
creditCheckFn: vi.fn().mockResolvedValue(true),
};
const mockFormData = {
responses: {
"contact person": {
value: "Jane Smith",
response: "Jane Smith",
},
email: {
value: "jane@example.com",
response: "jane@example.com",
},
},
routedEventTypeId: null,
user: {
email: "user@test.com",
timeFormat: 12,
locale: "en",
},
};
test("should work with EMAIL_ADDRESS action and formData (no evt)", async () => {
const mockWorkflowStep = {
id: 1,
action: WorkflowActions.EMAIL_ADDRESS,
verifiedAt: new Date(),
sendTo: "recipient@example.com",
template: WorkflowTemplates.REMINDER,
reminderBody: null,
emailSubject: null,
sender: null,
includeCalendarEvent: false,
numberVerificationPending: false,
numberRequired: false,
};
const result = await emailWorkflowService.generateParametersToBuildEmailWorkflowContent({
formData: mockFormData,
workflowStep: mockWorkflowStep,
workflow: { userId: 1 },
commonScheduleFunctionParams: mockCommonScheduleFunctionParams,
hideBranding: false,
});
expect(result.sendTo).toEqual(["recipient@example.com"]);
expect(result.formData).toEqual(mockFormData);
expect(result.evt).toBeUndefined();
});
test("should work with EMAIL_ATTENDEE action and formData (no evt)", async () => {
const mockWorkflowStep = {
id: 1,
action: WorkflowActions.EMAIL_ATTENDEE,
verifiedAt: new Date(),
sendTo: null,
template: WorkflowTemplates.REMINDER,
reminderBody: null,
emailSubject: null,
sender: null,
includeCalendarEvent: false,
numberVerificationPending: false,
numberRequired: false,
};
const result = await emailWorkflowService.generateParametersToBuildEmailWorkflowContent({
formData: mockFormData,
workflowStep: mockWorkflowStep,
workflow: { userId: 1 },
commonScheduleFunctionParams: mockCommonScheduleFunctionParams,
hideBranding: false,
});
// Should extract email from formData responses
expect(result.sendTo).toEqual(["jane@example.com"]);
expect(result.formData).toEqual(mockFormData);
expect(result.evt).toBeUndefined();
});
test("should throw error if neither evt nor formData is provided", async () => {
const mockWorkflowStep = {
id: 1,
action: WorkflowActions.EMAIL_ADDRESS,
verifiedAt: new Date(),
sendTo: "recipient@example.com",
template: WorkflowTemplates.REMINDER,
reminderBody: null,
emailSubject: null,
sender: null,
includeCalendarEvent: false,
numberVerificationPending: false,
numberRequired: false,
};
await expect(
emailWorkflowService.generateParametersToBuildEmailWorkflowContent({
workflowStep: mockWorkflowStep,
workflow: { userId: 1 },
commonScheduleFunctionParams: mockCommonScheduleFunctionParams,
hideBranding: false,
})
).rejects.toThrow("Either evt or formData must be provided");
});
});
});
@@ -208,11 +208,15 @@ export class EmailWorkflowService {
}
}
// The evt builder already validates the bookerUrl exists
if (!evt || typeof evt.bookerUrl !== "string") {
// Only check for bookerUrl when evt is provided (not for form submissions)
if (evt && typeof evt.bookerUrl !== "string") {
throw new Error("bookerUrl not a part of the evt");
}
if (!evt && !formData) {
throw new Error("Either evt or formData must be provided");
}
const contextData: WorkflowContextData = evt
? { evt: evt as BookingInfo }
: { formData: formData as FormSubmissionData };
@@ -311,7 +315,8 @@ export class EmailWorkflowService {
organizerEmail: evt.organizer.email,
sendToEmail: sendTo[0],
});
const meetingUrl = getVideoCallUrlFromCalEvent(evt) || bookingMetadataSchema.parse(evt.metadata || {})?.videoCallUrl;
const meetingUrl =
getVideoCallUrlFromCalEvent(evt) || bookingMetadataSchema.parse(evt.metadata || {})?.videoCallUrl;
const variables: VariablesType = {
eventName: evt.title || "",
organizerName: evt.organizer.name,