Skip to content
Merged
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
1 change: 1 addition & 0 deletions apps/web/public/static/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,7 @@
"add_input": "Add an input",
"disable_notes": "Hide notes in calendar",
"disable_notes_description": "For privacy reasons, additional inputs and notes will be hidden in the calendar entry. They will still be sent to your email. <0>Learn more</0>",
"notes_hidden_by_organizer": "Notes have been hidden by the organizer",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not being anywhere right now, its for later

"requires_confirmation_description": "The booking needs to be manually confirmed before it is pushed to your calendar and a confirmation is sent. <0>Learn more</0>",
"requires_confirmation_will_block_slot_description": "Unconfirmed bookings still block calendar slots.",
"recurring_event": "Recurring event",
Expand Down
37 changes: 34 additions & 3 deletions packages/emails/email-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,18 @@ export const sendRoundRobinRescheduledEmailsAndSMS = async (
if (
!shouldSkipAttendeeEmailWithSettings(eventTypeMetadata, organizationSettings, EmailType.RESCHEDULED)
) {
emailsAndSMSToSend.push(sendEmail(() => new AttendeeRescheduledEmail(calendarEvent, person)));
emailsAndSMSToSend.push(
Copy link
Contributor Author

@Ryukemeister Ryukemeister Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not a breaking change or change in logic, it was simply missing for the rescheduling logic. if you checkout line 395 of email manager here we were already implementing this when create a new booking, it was simply missing when rescheduling

sendEmail(
() =>
new AttendeeRescheduledEmail(
{
...calendarEvent,
...(calendarEvent.hideCalendarNotes && { additionalNotes: undefined }),
},
person
)
)
);
if (person.phoneNumber) {
emailsAndSMSToSend.push(successfullyReScheduledSMS.sendSMSToAttendee(person));
}
Expand Down Expand Up @@ -322,7 +333,16 @@ const _sendRescheduledEmailsAndSMS = async (
if (!shouldSkipAttendeeEmailWithSettings(eventTypeMetadata, organizationSettings, EmailType.RESCHEDULED)) {
emailsToSend.push(
...calendarEvent.attendees.map((attendee) => {
return sendEmail(() => new AttendeeRescheduledEmail(calendarEvent, attendee));
return sendEmail(
() =>
new AttendeeRescheduledEmail(
{
...calendarEvent,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above, missing logic

...(calendarEvent.hideCalendarNotes && { additionalNotes: undefined }),
},
attendee
)
);
})
);
}
Expand Down Expand Up @@ -350,7 +370,18 @@ export const sendRescheduledSeatEmailAndSMS = async (
if (!eventTypeDisableHostEmail(eventTypeMetadata))
emailsToSend.push(sendEmail(() => new OrganizerRescheduledEmail({ calEvent: calendarEvent })));
if (!shouldSkipAttendeeEmailWithSettings(eventTypeMetadata, organizationSettings, EmailType.RESCHEDULED))
emailsToSend.push(sendEmail(() => new AttendeeRescheduledEmail(clonedCalEvent, attendee)));
emailsToSend.push(
sendEmail(
() =>
new AttendeeRescheduledEmail(
{
...clonedCalEvent,
...(clonedCalEvent.hideCalendarNotes && { additionalNotes: undefined }),
},
attendee
)
)
);

const successfullyReScheduledSMS = new EventSuccessfullyReScheduledSMS(calEvent);
await successfullyReScheduledSMS.sendSMSToAttendee(attendee);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2094,6 +2094,10 @@ async function handler(
});
}
}
// This gets overridden when updating the event - to check if notes have been hidden or not. We just reset this back
// to the default description when we are sending the emails.
evt.description = eventType.description;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not eventType.description ?? evt.description like before?

Copy link
Contributor Author

@Ryukemeister Ryukemeister Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because evt.description comes the description property in the Booking table and that is where we store the additional notes (even tho the name of the field is description). so say if there's an event type with no description in that eventType.description will be undefined and hence it will fallback to evt.description which is the additional notes. as a result we will end up having additional notes twice.


const updateManager = !skipCalendarSyncTaskCreation
? await eventManager.reschedule(
evt,
Expand All @@ -2105,9 +2109,6 @@ async function handler(
skipDeleteEventsAndMeetings
)
: placeholderCreatedEvent;
// This gets overridden when updating the event - to check if notes have been hidden or not. We just reset this back
// to the default description when we are sending the emails.
evt.description = eventType.description ?? evt.description;

results = updateManager.results;
referencesToCreate = updateManager.referencesToCreate;
Expand Down
7 changes: 6 additions & 1 deletion packages/features/calendars/lib/CalendarManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,11 @@ export const updateEvent = async (
externalCalendarId: string | null
): Promise<EventResult<NewCalendarEventType>> => {
const formattedEvent = formatCalEvent(rawCalEvent);

if (formattedEvent.hideCalendarNotes) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is again not a logic change or breaking change, it was simply missing for rescheduling logic. if you checkout line 308 of the same function here its already present for create booking, it was simply missing for rescheduling

formattedEvent.additionalNotes = "Notes have been hidden by the organizer"; // TODO: i18n this string?
}

const calEvent = processEvent(formattedEvent);
const uid = getUid(calEvent);
const calendar = await getCalendar(credential, "booking");
Expand Down Expand Up @@ -500,7 +505,7 @@ export const deleteEvent = async ({
* Process the calendar event by generating description and removing attendees if needed
*/
const processEvent = (calEvent: CalendarEvent): CalendarServiceEvent => {
if (calEvent.seatsPerTimeSlot){
if (calEvent.seatsPerTimeSlot) {
calEvent.responses = null;
calEvent.userFieldsResponses = null;
calEvent.additionalNotes = null;
Expand Down
Loading