import type { Host } from "@calcom/features/bookings/lib/getHostsAndGuests"; import { AttendeeRepository } from "@calcom/features/bookings/repositories/AttendeeRepository"; import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import { prisma } from "@calcom/prisma"; import { WebhookTriggerEvents } from "@calcom/prisma/enums"; import type { Booking } from "./common"; import { calculateMaxStartTime, log, prepareNoShowTrigger, sendWebhookPayload, } from "./common"; const markHostsAsNoShowInBooking = async (booking: Booking, hostsThatDidntJoinTheCall: Host[]) => { const bookingRepository = new BookingRepository(prisma); const attendeeRepository = new AttendeeRepository(prisma); try { if (hostsThatDidntJoinTheCall.length === 0) { return null; } const attendeesBefore = await attendeeRepository.findByBookingId(booking.id); const attendeesBeforeByEmail = new Map(attendeesBefore.map((a) => [a.email, a])); let noShowHost = booking.noShowHost; await Promise.allSettled( hostsThatDidntJoinTheCall.map(async (host) => { if (booking?.user?.id === host.id) { noShowHost = true; return bookingRepository.updateNoShowHost({ bookingUid: booking.uid, noShowHost: true }); } const attendeeBefore = attendeesBeforeByEmail.get(host.email); if (attendeeBefore) { await attendeeRepository.updateNoShow({ where: { attendeeId: attendeeBefore.id }, data: { noShow: true }, }); } return Promise.resolve(); }) ); const updatedAttendees = await attendeeRepository.findByBookingId(booking.id); return { noShowHost, attendees: updatedAttendees }; } catch (error) { log.error("Error marking hosts as no show in booking", error); return null; } }; export async function triggerHostNoShow(payload: string): Promise { const result = await prepareNoShowTrigger(payload); if (!result) return; const { booking, webhook, hostsThatDidntJoinTheCall, originalRescheduledBooking, participants } = result; const maxStartTime = calculateMaxStartTime(booking.startTime, webhook.time, webhook.timeUnit); const updatedData = await markHostsAsNoShowInBooking(booking, hostsThatDidntJoinTheCall); const bookingWithUpdatedData = updatedData ? { ...booking, noShowHost: updatedData.noShowHost, attendees: updatedData.attendees } : booking; const hostsNoShowPromises = hostsThatDidntJoinTheCall.map((host) => { return sendWebhookPayload( webhook, WebhookTriggerEvents.AFTER_HOSTS_CAL_VIDEO_NO_SHOW, bookingWithUpdatedData, maxStartTime, participants, originalRescheduledBooking, host.email ); }); await Promise.all(hostsNoShowPromises); }