feat: show originally scheduled time in rescheduled meeting emails#28865
feat: show originally scheduled time in rescheduled meeting emails#28865SinghaAnirban005 wants to merge 1 commit intocalcom:mainfrom
Conversation
📝 WalkthroughWalkthroughThis change extends the system to track and display previous event times when a booking is rescheduled. The 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/features/bookings/lib/BookingEmailSmsHandler.ts (1)
117-143:⚠️ Potential issue | 🟠 MajorAdd error handling in rescheduled notification flow.
_handleRescheduledis the only notification path here without atry/catch; a mail/SMS failure can escape and disrupt the side-effect pipeline.Suggested fix
private async _handleRescheduled(data: RescheduleEmailAndSmsPayload) { @@ const { sendRescheduledEmailsAndSMS } = await import("@calcom/emails/email-manager"); - await sendRescheduledEmailsAndSMS( - { - ...evt, - previousStartTime: originalRescheduledBooking?.startTime - ? dayjs(originalRescheduledBooking.startTime).utc().format() - : undefined, - previousEndTime: originalRescheduledBooking?.endTime - ? dayjs(originalRescheduledBooking.endTime).utc().format() - : undefined, - additionalInformation, - additionalNotes, - cancellationReason: `$RCH$${rescheduleReason || ""}`, - }, - metadata - ); + try { + await sendRescheduledEmailsAndSMS( + { + ...evt, + previousStartTime: originalRescheduledBooking?.startTime + ? dayjs(originalRescheduledBooking.startTime).utc().format() + : undefined, + previousEndTime: originalRescheduledBooking?.endTime + ? dayjs(originalRescheduledBooking.endTime).utc().format() + : undefined, + additionalInformation, + additionalNotes, + cancellationReason: `$RCH$${rescheduleReason || ""}`, + }, + metadata + ); + } catch (err) { + this.log.error("Failed to send rescheduled event related emails and SMS", err); + } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/features/bookings/lib/BookingEmailSmsHandler.ts` around lines 117 - 143, _handleRescheduled currently calls sendRescheduledEmailsAndSMS without protection so any mail/SMS error can escape; wrap the await sendRescheduledEmailsAndSMS(...) call in a try/catch inside _handleRescheduled, catch any thrown error, log it (use this.logger.error if available, otherwise processLogger/console.error) including contextual data (evt, metadata, rescheduleReason), and swallow or handle the error so it does not propagate and break the side-effect pipeline.
🧹 Nitpick comments (1)
packages/features/bookings/lib/BookingEmailSmsHandler.ts (1)
131-136: Deduplicate previous-time UTC conversion logic.The same conversion block appears in both reschedule handlers; extracting one helper will prevent drift and keep behavior consistent.
Refactor sketch
export class BookingEmailSmsHandler { private readonly log: Pick<Logger<unknown>, "warn" | "debug" | "error">; + private toUtcIso(value?: string | Date | null) { + return value ? dayjs(value).utc().format() : undefined; + } @@ - previousStartTime: originalRescheduledBooking?.startTime - ? dayjs(originalRescheduledBooking.startTime).utc().format() - : undefined, - previousEndTime: originalRescheduledBooking?.endTime - ? dayjs(originalRescheduledBooking.endTime).utc().format() - : undefined, + previousStartTime: this.toUtcIso(originalRescheduledBooking?.startTime), + previousEndTime: this.toUtcIso(originalRescheduledBooking?.endTime), @@ - previousStartTime: originalRescheduledBooking?.startTime - ? dayjs(originalRescheduledBooking.startTime).utc().format() - : undefined, - previousEndTime: originalRescheduledBooking?.endTime - ? dayjs(originalRescheduledBooking.endTime).utc().format() - : undefined, + previousStartTime: this.toUtcIso(originalRescheduledBooking?.startTime), + previousEndTime: this.toUtcIso(originalRescheduledBooking?.endTime),Also applies to: 167-172
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/features/bookings/lib/BookingEmailSmsHandler.ts` around lines 131 - 136, Extract the repeated UTC conversion of originalRescheduledBooking start/end times into a single helper (e.g., a private method on BookingEmailSmsHandler such as formatBookingTimesToUtc(originalBooking) that returns { previousStartTime, previousEndTime } where each value is computed with dayjs(...).utc().format() or undefined) and replace the duplicated blocks in both reschedule handlers (the places referencing originalRescheduledBooking) to call that helper so behavior is centralized and consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/features/bookings/lib/BookingEmailSmsHandler.ts`:
- Around line 117-143: _handleRescheduled currently calls
sendRescheduledEmailsAndSMS without protection so any mail/SMS error can escape;
wrap the await sendRescheduledEmailsAndSMS(...) call in a try/catch inside
_handleRescheduled, catch any thrown error, log it (use this.logger.error if
available, otherwise processLogger/console.error) including contextual data
(evt, metadata, rescheduleReason), and swallow or handle the error so it does
not propagate and break the side-effect pipeline.
---
Nitpick comments:
In `@packages/features/bookings/lib/BookingEmailSmsHandler.ts`:
- Around line 131-136: Extract the repeated UTC conversion of
originalRescheduledBooking start/end times into a single helper (e.g., a private
method on BookingEmailSmsHandler such as
formatBookingTimesToUtc(originalBooking) that returns { previousStartTime,
previousEndTime } where each value is computed with dayjs(...).utc().format() or
undefined) and replace the duplicated blocks in both reschedule handlers (the
places referencing originalRescheduledBooking) to call that helper so behavior
is centralized and consistent.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: be17a3c7-ffe0-4c46-8e2e-fc59156f9019
📒 Files selected for processing (3)
packages/emails/src/components/WhenInfo.tsxpackages/features/bookings/lib/BookingEmailSmsHandler.tspackages/types/Calendar.d.ts
What does this PR do?
This PR ensures that when a booking is rescheduled email notifications show the original booking time (with line through) above the new time so recipients can immediately see when free time opened up and how far the meeting was moved.
Video Demo (if applicable):
Screencast.from.2026-04-13.13-32-55.webm
Mandatory Tasks (DO NOT REMOVE)