From 8d675fd8b62c5ae7819d6b571593f38ccbe20cb9 Mon Sep 17 00:00:00 2001 From: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Date: Wed, 14 May 2025 19:33:25 -0400 Subject: [PATCH] feat: Add `AssignmentReason` to `BOOKING_CREATED` webhook (#21315) * AssignmentREasonRecorder methods return the reason generated * Add assignmentReason to `EventPayloadType` * Pass `assignmentReason` to webhook payload data * Undo constants commit --- .../features/bookings/lib/handleNewBooking.ts | 8 +++- .../AssignmentReasonRecorder.ts | 38 +++++++++++++++---- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts index 8c3c5cd733..3b34b83c25 100644 --- a/packages/features/bookings/lib/handleNewBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking.ts @@ -68,6 +68,7 @@ import { getTranslation } from "@calcom/lib/server/i18n"; import { WorkflowRepository } from "@calcom/lib/server/repository/workflow"; import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat"; import prisma from "@calcom/prisma"; +import type { AssignmentReasonEnum } from "@calcom/prisma/enums"; import { BookingStatus, SchedulingType, WebhookTriggerEvents } from "@calcom/prisma/enums"; import { CreationSource } from "@calcom/prisma/enums"; import { @@ -1301,6 +1302,8 @@ async function handler( }) ); + let assignmentReason: { reasonEnum: AssignmentReasonEnum; reasonString: string } | undefined; + try { if (!isDryRun) { booking = await createBooking({ @@ -1341,7 +1344,7 @@ async function handler( // If it's a round robin event, record the reason for the host assignment if (eventType.schedulingType === SchedulingType.ROUND_ROBIN) { if (reqBody.crmOwnerRecordType && reqBody.crmAppSlug && contactOwnerEmail && routingFormResponseId) { - await AssignmentReasonRecorder.CRMOwnership({ + assignmentReason = await AssignmentReasonRecorder.CRMOwnership({ bookingId: booking.id, crmAppSlug: reqBody.crmAppSlug, teamMemberEmail: contactOwnerEmail, @@ -1349,7 +1352,7 @@ async function handler( routingFormResponseId, }); } else if (routingFormResponseId && teamId) { - await AssignmentReasonRecorder.routingFormRoute({ + assignmentReason = await AssignmentReasonRecorder.routingFormRoute({ bookingId: booking.id, routingFormResponseId, organizerId: organizerUser.id, @@ -1885,6 +1888,7 @@ async function handler( status: "ACCEPTED", smsReminderNumber: booking?.smsReminderNumber || undefined, rescheduledBy: reqBody.rescheduledBy, + ...(assignmentReason ? { assignmentReason: [assignmentReason] } : {}), }; if (bookingRequiresPayment) { diff --git a/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts b/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts index ba1da99b81..bb675b3577 100644 --- a/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts +++ b/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts @@ -113,13 +113,21 @@ export default class AssignmentReasonRecorder { } } + const reasonEnum = AssignmentReasonEnum.ROUTING_FORM_ROUTING; + const reasonString = attributeValues.join(", "); + await prisma.assignmentReason.create({ data: { bookingId: bookingId, - reasonEnum: AssignmentReasonEnum.ROUTING_FORM_ROUTING, - reasonString: attributeValues.join(", "), + reasonEnum, + reasonString, }, }); + + return { + reasonEnum, + reasonString, + }; } // Separate method to handle rerouting @@ -148,13 +156,20 @@ export default class AssignmentReasonRecorder { if (!crmRoutingReason || !crmRoutingReason.assignmentReason) return; + const { reasonEnum, assignmentReason } = crmRoutingReason; + await prisma.assignmentReason.create({ data: { bookingId, - reasonEnum: crmRoutingReason.reasonEnum, - reasonString: crmRoutingReason.assignmentReason, + reasonEnum, + reasonString: assignmentReason, }, }); + + return { + reasonEnum, + reasonString: assignmentReason, + }; } static roundRobinReassignment = withReporting( AssignmentReasonRecorder._roundRobinReassignment, @@ -180,6 +195,11 @@ export default class AssignmentReasonRecorder { }, }); + const reasonEnum = + reassignmentType === RRReassignmentType.MANUAL + ? AssignmentReasonEnum.REASSIGNED + : AssignmentReasonEnum.RR_REASSIGNED; + const reasonString = `Reassigned by: ${reassignedBy?.username || "team member"}. ${ reassignReason ? `Reason: ${reassignReason}` : "" }`; @@ -187,12 +207,14 @@ export default class AssignmentReasonRecorder { await prisma.assignmentReason.create({ data: { bookingId: bookingId, - reasonEnum: - reassignmentType === RRReassignmentType.MANUAL - ? AssignmentReasonEnum.REASSIGNED - : AssignmentReasonEnum.RR_REASSIGNED, + reasonEnum, reasonString, }, }); + + return { + reasonEnum, + reasonString, + }; } }