diff --git a/apps/web/playwright/webhook.e2e.ts b/apps/web/playwright/webhook.e2e.ts
index 3ed89f3a7d..23ba60e2a1 100644
--- a/apps/web/playwright/webhook.e2e.ts
+++ b/apps/web/playwright/webhook.e2e.ts
@@ -90,7 +90,16 @@ test("add webhook & test that creating an event triggers a webhook call", async
timeZone: "[redacted/dynamic]",
language: "[redacted/dynamic]",
},
- responses: { email: "test@example.com", name: "Test Testson" },
+ responses: {
+ email: {
+ value: "test@example.com",
+ label: "email_address",
+ },
+ name: {
+ value: "Test Testson",
+ label: "your_name",
+ },
+ },
userFieldsResponses: {},
attendees: [
{
diff --git a/packages/emails/src/components/UserFieldsResponses.tsx b/packages/emails/src/components/UserFieldsResponses.tsx
index fed4c41971..4df5a4bb81 100644
--- a/packages/emails/src/components/UserFieldsResponses.tsx
+++ b/packages/emails/src/components/UserFieldsResponses.tsx
@@ -1,16 +1,17 @@
+import getLabelValueMapFromResponses from "@calcom/lib/getLabelValueMapFromResponses";
import type { CalendarEvent } from "@calcom/types/Calendar";
import { Info } from "./Info";
export function UserFieldsResponses(props: { calEvent: CalendarEvent }) {
- const { customInputs, userFieldsResponses } = props.calEvent;
- const responses = userFieldsResponses || customInputs;
- if (!responses) return null;
+ const labelValueMap = getLabelValueMapFromResponses(props.calEvent);
+
+ if (!labelValueMap) return null;
return (
<>
- {Object.keys(responses).map((key) =>
- responses[key] !== "" ? (
-
+ {Object.keys(labelValueMap).map((key) =>
+ labelValueMap[key] !== "" ? (
+
) : null
)}
>
diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts
index db41714499..85254195ca 100644
--- a/packages/features/bookings/lib/handleNewBooking.ts
+++ b/packages/features/bookings/lib/handleNewBooking.ts
@@ -363,11 +363,23 @@ function getBookingData({
const reqBody = bookingDataSchema.parse(req.body);
if ("responses" in reqBody) {
const responses = reqBody.responses;
- const userFieldsResponses = {} as typeof responses;
+ const calEventResponses = {} as NonNullable;
+ const calEventUserFieldsResponses = {} as NonNullable;
eventType.bookingFields.forEach((field) => {
- if (field.editable === "user" || field.editable === "user-readonly") {
- userFieldsResponses[field.name] = responses[field.name];
+ const label = field.label || field.defaultLabel;
+ if (!label) {
+ throw new Error('Missing label for booking field "' + field.name + '"');
}
+ if (field.editable === "user" || field.editable === "user-readonly") {
+ calEventUserFieldsResponses[field.name] = {
+ label,
+ value: responses[field.name],
+ };
+ }
+ calEventResponses[field.name] = {
+ label,
+ value: responses[field.name],
+ };
});
return {
...reqBody,
@@ -377,8 +389,9 @@ function getBookingData({
location: responses.location?.optionValue || responses.location?.value || "",
smsReminderNumber: responses.smsReminderNumber,
notes: responses.notes || "",
- userFieldsResponses,
+ calEventUserFieldsResponses,
rescheduleReason: responses.rescheduleReason,
+ calEventResponses,
};
} else {
// Check if required custom inputs exist
@@ -721,7 +734,8 @@ async function handler(
}
const responses = "responses" in reqBody ? reqBody.responses : null;
- const userFieldsResponses = "userFieldsResponses" in reqBody ? reqBody.userFieldsResponses : null;
+ const calEventUserFieldsResponses =
+ "calEventUserFieldsResponses" in reqBody ? reqBody.calEventUserFieldsResponses : null;
let evt: CalendarEvent = {
type: eventType.title,
title: getEventName(eventNameObject), //this needs to be either forced in english, or fetched for each attendee and organizer separately
@@ -737,8 +751,8 @@ async function handler(
timeZone: organizerUser.timeZone,
language: { translate: tOrganizer, locale: organizerUser.locale ?? "en" },
},
- responses,
- userFieldsResponses,
+ responses: "calEventResponses" in reqBody ? reqBody.calEventResponses : null,
+ userFieldsResponses: calEventUserFieldsResponses,
attendees: attendeesList,
location: bookingLocation, // Will be processed by the EventManager later.
/** For team events & dynamic collective events, we will need to handle each member destinationCalendar eventually */
diff --git a/packages/lib/CalEventParser.ts b/packages/lib/CalEventParser.ts
index 1413f77b8a..2a8f95f710 100644
--- a/packages/lib/CalEventParser.ts
+++ b/packages/lib/CalEventParser.ts
@@ -4,6 +4,7 @@ import { v5 as uuidv5 } from "uuid";
import type { CalendarEvent } from "@calcom/types/Calendar";
import { WEBAPP_URL } from "./constants";
+import getLabelValueMapFromResponses from "./getLabelValueMapFromResponses";
const translator = short();
@@ -72,17 +73,18 @@ ${calEvent.additionalNotes}
};
export const getUserFieldsResponses = (calEvent: CalendarEvent) => {
- const responses = calEvent.userFieldsResponses || calEvent.customInputs;
- if (!responses) {
+ const labelValueMap = getLabelValueMapFromResponses(calEvent);
+
+ if (!labelValueMap) {
return "";
}
- const responsesString = Object.keys(responses)
+ const responsesString = Object.keys(labelValueMap)
.map((key) => {
- if (!responses) return "";
- if (responses[key] !== "") {
+ if (!labelValueMap) return "";
+ if (labelValueMap[key] !== "") {
return `
${key}:
-${responses[key]}
+${labelValueMap[key]}
`;
}
})
diff --git a/packages/lib/getLabelValueMapFromResponses.ts b/packages/lib/getLabelValueMapFromResponses.ts
new file mode 100644
index 0000000000..124c8af35c
--- /dev/null
+++ b/packages/lib/getLabelValueMapFromResponses.ts
@@ -0,0 +1,15 @@
+import type { CalendarEvent } from "@calcom/types/Calendar";
+
+export default function getLabelValueMapFromResponses(calEvent: CalendarEvent) {
+ const { customInputs, userFieldsResponses } = calEvent;
+
+ let labelValueMap: Record = {};
+ if (userFieldsResponses) {
+ for (const [, value] of Object.entries(userFieldsResponses)) {
+ labelValueMap[value.label] = value.value;
+ }
+ } else {
+ labelValueMap = customInputs as Record;
+ }
+ return labelValueMap;
+}
diff --git a/packages/types/Calendar.d.ts b/packages/types/Calendar.d.ts
index d4db84dcc7..46e94dc7dd 100644
--- a/packages/types/Calendar.d.ts
+++ b/packages/types/Calendar.d.ts
@@ -165,10 +165,22 @@ export interface CalendarEvent {
seatsPerTimeSlot?: number | null;
// It has responses to all the fields(system + user)
- responses?: Prisma.JsonObject | null;
+ responses?: Record<
+ string,
+ {
+ value: string | string[];
+ label: string;
+ }
+ > | null;
// It just has responses to only the user fields. It allows to easily iterate over to show only user fields
- userFieldsResponses?: Prisma.JsonObject | null;
+ userFieldsResponses?: Record<
+ string,
+ {
+ value: string | string[];
+ label: string;
+ }
+ > | null;
}
export interface EntryPoint {