feat: support custom email subject with booking field placeholders in…#29662
feat: support custom email subject with booking field placeholders in…#29662sciencebanda09 wants to merge 4 commits into
Conversation
… confirmation email
- Add confirmationEmailSubject to EventTypeMetaDataSchema
- Add customEmailSubject field to CalendarEvent type
- Pass customEmailSubject from event type metadata through CalendarEventBuilder
- Interpolate {fieldIdentifier} placeholders in AttendeeScheduledEmail using booking responses
- Add UI input field in EventAdvancedTab for setting custom confirmation email subject
Fixes calcom#29658
|
Welcome to Cal.diy, @sciencebanda09! Thanks for opening this pull request. A few things to keep in mind:
A maintainer will review your PR soon. Thanks for contributing! |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughA new optional 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ 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.
Actionable comments posted: 3
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/service/RegularBookingService.ts (1)
1382-1397: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winPass
metadatathrough here instead ofcustomEmailSubject.CalendarEventBuilder.withEventType()only readsconfirmationEmailSubjectfrommetadata, so this value is dropped and the booking-created email keeps the default subject.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/features/bookings/lib/service/RegularBookingService.ts` around lines 1382 - 1397, Pass the event type metadata through RegularBookingService’s withEventType call instead of mapping only customEmailSubject, because CalendarEventBuilder.withEventType reads confirmationEmailSubject from metadata and the subject is currently being dropped. Update the eventType object passed from RegularBookingService so it includes metadata (with confirmationEmailSubject) and keep the existing fields like customReplyToEmail unchanged.
🧹 Nitpick comments (1)
packages/emails/templates/attendee-scheduled-email.ts (1)
114-117: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDrop the what-comment above
getInterpolatedSubject.The method name already explains this. As per coding guidelines, “Only add code comments that explain why, not what” and “Never add comments that simply restate what the code does.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/emails/templates/attendee-scheduled-email.ts` around lines 114 - 117, Remove the redundant what-comment above getInterpolatedSubject in attendee-scheduled-email.ts. The method name already conveys the behavior, so delete the JSDoc block and keep the implementation self-explanatory; if any comment remains, make sure it explains intent or rationale rather than restating what getInterpolatedSubject does.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/modules/event-types/components/tabs/advanced/EventAdvancedTab.tsx`:
- Around line 1346-1352: The confirmation email subject field in
EventAdvancedTab adds a visible Label and helper text but does not
programmatically associate them with the TextField. Update the TextField/Label
wiring so the input has an accessible name and description, using the existing
confirmation_email_subject elements and the form field registration for
metadata.confirmationEmailSubject; the helper text paragraph should also be
linked as the field’s description.
In `@packages/emails/templates/attendee-scheduled-email.ts`:
- Around line 122-124: The placeholder replacement in
attendee-scheduled-email.ts should preserve missing tokens instead of dropping
them. Update the replace callback in the template handling logic so that when
responses[key] is absent in the relevant formatter function, it returns the
original matched placeholder from template.replace rather than an empty string.
This keeps unresolved placeholders visible for saved templates and avoids
silently stripping missing or renamed response keys.
In `@packages/i18n/locales/en/common.json`:
- Line 3314: Update the example string for
confirmation_email_subject_placeholder in the common locale so it demonstrates a
booking-field placeholder that matches the booking response field identifier
resolution used by the first attendee email. Replace the current {eventName} and
{organizer} example with a booking-field token such as {company}, keeping the
wording aligned with the placeholder behavior exposed by the interpolation path.
---
Outside diff comments:
In `@packages/features/bookings/lib/service/RegularBookingService.ts`:
- Around line 1382-1397: Pass the event type metadata through
RegularBookingService’s withEventType call instead of mapping only
customEmailSubject, because CalendarEventBuilder.withEventType reads
confirmationEmailSubject from metadata and the subject is currently being
dropped. Update the eventType object passed from RegularBookingService so it
includes metadata (with confirmationEmailSubject) and keep the existing fields
like customReplyToEmail unchanged.
---
Nitpick comments:
In `@packages/emails/templates/attendee-scheduled-email.ts`:
- Around line 114-117: Remove the redundant what-comment above
getInterpolatedSubject in attendee-scheduled-email.ts. The method name already
conveys the behavior, so delete the JSDoc block and keep the implementation
self-explanatory; if any comment remains, make sure it explains intent or
rationale rather than restating what getInterpolatedSubject does.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: edfd26dd-3ce7-442b-95bc-cd5118ec6d05
📒 Files selected for processing (7)
apps/web/modules/event-types/components/tabs/advanced/EventAdvancedTab.tsxpackages/emails/templates/attendee-scheduled-email.tspackages/features/CalendarEventBuilder.tspackages/features/bookings/lib/service/RegularBookingService.tspackages/i18n/locales/en/common.jsonpackages/prisma/zod-utils.tspackages/types/Calendar.d.ts
- Remove duplicate customEmailSubject field in RegularBookingService
- Preserve unresolved placeholders as {key} instead of empty string
- Remove what-comment above getInterpolatedSubject
…listic placeholder example
|
@bandhan-majumder Ready for review. All CodeRabbit comments addressed. Happy to make any changes the maintainers suggest. also could a maintainer please add the run-ci label to trigger CI? Happy to address any feedback. Thanks! |
|
This bug was encountered on the Cal.com free plan (cal.eu), so I assume it also exists in the calcom/cal.com repository. Will this fix be merged there as well? |
bandhan-majumder
left a comment
There was a problem hiding this comment.
changes looks good. Can u add a video demo?
|
Hi @bandhan-majumder a live demo isn't possible right now as the feature requires a running local instance with a database. Here's the full data flow instead: Data Flow
ExampleOrganizer sets: Happy to set up a local instance for a full end-to-end demo if that's a hard requirement! |
|
@sciencebanda09 please don't make change if u are not reviewing it locally yourself |
What does this PR do?
Fixes #29658
Implements custom confirmation email subject with
{placeholder}support for booking fields. When an organizer sets a custom subject likeMeeting with {company}, the attendee receives the email with the actual submitted value (e.g.Meeting with Acme Corp).Changes
packages/prisma/zod-utils.ts— addedconfirmationEmailSubjectfield toEventTypeMetaDataSchemapackages/types/Calendar.d.ts— addedcustomEmailSubjecttoCalendarEventinterfacepackages/features/CalendarEventBuilder.ts— passcustomEmailSubjectthroughwithEventType()packages/features/bookings/lib/service/RegularBookingService.ts— readconfirmationEmailSubjectfrom event type metadata and pass it to the calendar eventpackages/emails/templates/attendee-scheduled-email.ts— interpolate{fieldIdentifier}placeholders using attendee's booking responsesapps/web/modules/event-types/components/tabs/advanced/EventAdvancedTab.tsx— UI input field for organizers to set custom confirmation email subjectHow was this tested?
zod schema→FormValues→UI→RegularBookingService→CalendarEventBuilder→CalendarEvent→AttendeeScheduledEmailcalEvent.titlewhen no custom subject is set (no breaking change)