Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions apps/web/pages/api/book/recurring-event.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ describe("handleNewBooking", () => {
organizer,
location: "integrations:daily",
subscriberUrl: "http://my-webhook.example.com",
//FIXME: All recurring bookings seem to have the same URL. https://github.com/calcom/cal.diy/issues/11955
videoCallUrl: `${WEBAPP_URL}/video/${createdBookings[0].uid}`,
});
}
Expand Down Expand Up @@ -549,7 +548,6 @@ describe("handleNewBooking", () => {
organizer,
location: "integrations:daily",
subscriberUrl: "http://my-webhook.example.com",
//FIXME: File a bug - All recurring bookings seem to have the same URL. They should have same CalVideo URL which could mean that future recurring meetings would have already expired by the time they are needed.
videoCallUrl: `${WEBAPP_URL}/video/${createdBookings[0].uid}`,
});
}
Expand Down Expand Up @@ -765,7 +763,6 @@ describe("handleNewBooking", () => {
organizer,
location: "integrations:daily",
subscriberUrl: "http://my-webhook.example.com",
//FIXME: File a bug - All recurring bookings seem to have the same URL. They should have same CalVideo URL which could mean that future recurring meetings would have already expired by the time they are needed.
videoCallUrl: `${WEBAPP_URL}/video/${createdBookings[0].uid}`,
});
}
Expand Down
20 changes: 14 additions & 6 deletions packages/features/bookings/lib/handleConfirmation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks";
import { scheduleTrigger } from "@calcom/features/webhooks/lib/scheduleTrigger";
import sendPayload from "@calcom/features/webhooks/lib/sendOrSchedulePayload";
import type { EventPayloadType, EventTypeInfo } from "@calcom/features/webhooks/lib/sendPayload";
import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser";
import { getVideoCallUrlFromCalEvent, getPublicVideoCallUrl, isDailyVideoCall } from "@calcom/lib/CalEventParser";
import { safeStringify } from "@calcom/lib/safeStringify";
import type { TraceContext } from "@calcom/lib/tracing";
import { distributedTracing } from "@calcom/lib/tracing/factory";
Expand Down Expand Up @@ -176,8 +176,13 @@ export async function handleConfirmation(args: {
uid: booking.uid,
}));

const updateBookingsPromise = unconfirmedRecurringBookings.map((recurringBooking) =>
prisma.booking.update({
const updateBookingsPromise = unconfirmedRecurringBookings.map((recurringBooking) => {
// For Cal Video (daily_video), each occurrence has its own room URL derived from its uid.
// For other providers, reuse the shared meetingUrl since they create one meeting per series.
const occurrenceVideoCallUrl = isDailyVideoCall(evt.videoCallData)
? getPublicVideoCallUrl(recurringBooking.uid)
: meetingUrl;
return prisma.booking.update({
where: {
id: recurringBooking.id,
},
Expand All @@ -189,7 +194,7 @@ export async function handleConfirmation(args: {
paid,
metadata: {
...(typeof recurringBooking.metadata === "object" ? recurringBooking.metadata : {}),
videoCallUrl: meetingUrl,
videoCallUrl: occurrenceVideoCallUrl,
},
},
select: {
Expand Down Expand Up @@ -234,8 +239,8 @@ export async function handleConfirmation(args: {
customInputs: true,
id: true,
},
})
);
});
});

const updatedBookingsResult = await Promise.all(updateBookingsPromise);
updatedBookings = updatedBookings.concat(updatedBookingsResult);
Expand Down Expand Up @@ -407,6 +412,9 @@ export async function handleConfirmation(args: {
eventTypeId: eventType?.id,
status: "ACCEPTED",
smsReminderNumber: booking.smsReminderNumber || undefined,
// This is a single series-level webhook fired once on confirmation.
// It uses the first occurrence's URL. Webhook consumers needing per-occurrence
// URLs should query each booking's metadata.videoCallUrl from the database.
metadata: meetingUrl ? { videoCallUrl: meetingUrl } : {},
...(platformClientParams ? platformClientParams : {}),
};
Expand Down
Loading