feat(workflows): add localization support for date variables in reminders#24281
feat(workflows): add localization support for date variables in reminders#24281Bhavyabhardwaj wants to merge 4 commits intocalcom:mainfrom
Conversation
Updated locale handling to use recipient's locale for WhatsApp reminders.
Updated SMS reminder localization to use recipient's locale for date/time formatting.
Updated locale determination to use recipient's language for date/time localization.
|
|
|
@Bhavyabhardwaj is attempting to deploy a commit to the cal Team on Vercel. A member of the Team first needs to authorize it. |
|
Hey there and thank you for opening this pull request! 👋🏼 We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted. Details: |
WalkthroughAdds recipient-aware locale selection to reminder workflows. For WhatsApp (scheduler API and manager), SMS, and Email REMINDER flows, the locale now switches to the attendee’s locale for attendee-targeted actions (WHATSAPP_ATTENDEE, SMS_ATTENDEE, EMAIL_ATTENDEE), otherwise it uses the organizer/user locale. The computed locale is applied to template rendering, translation lookups, and date/time localization (e.g., via dayjs.locale). Emitted/constructed messages now pass the computed per-recipient locale instead of always using the organizer/user locale. No exported/public API signatures were changed. Possibly related PRs
Pre-merge checks and finishing touches❌ 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
🧹 Nitpick comments (4)
packages/features/ee/workflows/lib/reminders/smsReminderManager.ts (2)
189-192: Use the computed locale for opt-out message.The opt-out message uses
evt.organizer.language.localeinstead of the computedlocalevariable, creating an inconsistency where the main message and opt-out message could be in different languages.Apply this diff to use the recipient's locale:
if (process.env.TWILIO_OPT_OUT_ENABLED === "true") { smsMessage = await WorkflowOptOutService.addOptOutMessage( smsMessage, - evt.organizer.language.locale + locale || "en" ); }
165-174: Consider adding a fallback for undefined locale.The locale selection logic correctly chooses the recipient's locale for SMS_ATTENDEE actions. However, if
attendeeToBeUsedInSMS.language?.localeis undefined, the template will receiveundefinedas the locale parameter.Apply this diff to add a fallback to "en":
- const locale = - action === WorkflowActions.SMS_ATTENDEE - ? attendeeToBeUsedInSMS.language?.locale - : evt.organizer.language.locale; + const locale = + action === WorkflowActions.SMS_ATTENDEE + ? attendeeToBeUsedInSMS.language?.locale || "en" + : evt.organizer.language.locale || "en";Note: This matches the defensive pattern used in
scheduleWhatsappReminders.ts(lines 78-81) where explicit fallbacks to "en" are provided.packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1)
193-202: Consider adding a fallback for undefined locale.The locale selection logic correctly chooses the recipient's locale for EMAIL_ATTENDEE actions. While Line 202 provides a fallback (
reminderLocale || "en") ingetTranslation, Line 201 passesreminderLocaledirectly to the template'slocaleparameter without a fallback.Apply this diff to ensure consistent fallback handling:
const reminderLocale = isEmailAttendeeAction ? attendeeToBeUsedInMail.language?.locale - : evt.organizer.language.locale; + : evt.organizer.language.locale || "en"; emailContent = emailReminderTemplate({ isEditingMode: false, - locale: reminderLocale, + locale: reminderLocale || "en", t: await getTranslation(reminderLocale || "en", "common"),This matches the defensive pattern used in
scheduleWhatsappReminders.ts(lines 78-81).packages/features/ee/workflows/lib/reminders/whatsappReminderManager.ts (1)
83-88: Consider adding a fallback for undefined locale.The locale selection logic correctly chooses the recipient's locale for WHATSAPP_ATTENDEE actions. However, if
evt.attendees[0].language?.localeis undefined, downstream usages (e.g.,dayjs.locale(locale)on lines 96, 99) will receiveundefined.Apply this diff to add a fallback to "en":
- const locale = - action === WorkflowActions.WHATSAPP_ATTENDEE - ? evt.attendees[0].language?.locale - : evt.organizer.language.locale; + const locale = + action === WorkflowActions.WHATSAPP_ATTENDEE + ? evt.attendees[0].language?.locale || "en" + : evt.organizer.language.locale || "en";This matches the defensive pattern used in
scheduleWhatsappReminders.ts(lines 78-81).
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
packages/features/ee/workflows/api/scheduleWhatsappReminders.ts(2 hunks)packages/features/ee/workflows/lib/reminders/emailReminderManager.ts(1 hunks)packages/features/ee/workflows/lib/reminders/smsReminderManager.ts(1 hunks)packages/features/ee/workflows/lib/reminders/whatsappReminderManager.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/features/ee/workflows/lib/reminders/smsReminderManager.tspackages/features/ee/workflows/lib/reminders/whatsappReminderManager.tspackages/features/ee/workflows/lib/reminders/emailReminderManager.tspackages/features/ee/workflows/api/scheduleWhatsappReminders.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/features/ee/workflows/lib/reminders/smsReminderManager.tspackages/features/ee/workflows/lib/reminders/whatsappReminderManager.tspackages/features/ee/workflows/lib/reminders/emailReminderManager.tspackages/features/ee/workflows/api/scheduleWhatsappReminders.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/features/ee/workflows/lib/reminders/smsReminderManager.tspackages/features/ee/workflows/lib/reminders/whatsappReminderManager.tspackages/features/ee/workflows/lib/reminders/emailReminderManager.tspackages/features/ee/workflows/api/scheduleWhatsappReminders.ts
🧬 Code graph analysis (2)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1)
packages/platform/libraries/index.ts (2)
WorkflowActions(38-38)getTranslation(82-82)
packages/features/ee/workflows/api/scheduleWhatsappReminders.ts (1)
packages/platform/libraries/index.ts (1)
WorkflowActions(38-38)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Install dependencies / Yarn install & cache
- GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (2)
packages/features/ee/workflows/api/scheduleWhatsappReminders.ts (2)
76-81: LGTM! Good fallback handling.The locale selection properly handles undefined values with
|| "en"fallback, ensuring safe defaults for both date/time formatting and template rendering. This pattern should be applied to the other reminder manager files for consistency.
76-99: LGTM! Excellent defensive coding.The locale selection logic correctly chooses the recipient's locale for WHATSAPP_ATTENDEE actions and includes explicit fallbacks to "en" to prevent undefined values. This defensive approach ensures that downstream usages (e.g.,
dayjs.locale(locale)on lines 90, 93) always receive a valid locale string.This pattern could serve as a reference for the other reminder managers in this PR.
| const reminderLocale = isEmailAttendeeAction | ||
| ? attendeeToBeUsedInMail.language?.locale | ||
| : evt.organizer.language.locale; |
There was a problem hiding this comment.
Add fallback locale to handle undefined values.
The reminderLocale doesn't provide a fallback when attendeeToBeUsedInMail.language?.locale is undefined. While getTranslation at line 202 has a fallback (|| "en"), the locale passed to emailReminderTemplate at line 201 could still be undefined, potentially causing issues with date/time formatting.
Apply this diff to add a fallback:
const reminderLocale = isEmailAttendeeAction
? attendeeToBeUsedInMail.language?.locale
: evt.organizer.language.locale;
+ const safeLocale = reminderLocale || "en";
emailContent = emailReminderTemplate({
isEditingMode: false,
- locale: reminderLocale,
- t: await getTranslation(reminderLocale || "en", "common"),
+ locale: safeLocale,
+ t: await getTranslation(safeLocale, "common"),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const reminderLocale = isEmailAttendeeAction | |
| ? attendeeToBeUsedInMail.language?.locale | |
| : evt.organizer.language.locale; | |
| const reminderLocale = isEmailAttendeeAction | |
| ? attendeeToBeUsedInMail.language?.locale | |
| : evt.organizer.language.locale; | |
| const safeLocale = reminderLocale || "en"; | |
| emailContent = emailReminderTemplate({ | |
| isEditingMode: false, | |
| locale: safeLocale, | |
| t: await getTranslation(safeLocale, "common"), | |
| // …other template props | |
| }); |
🤖 Prompt for AI Agents
In packages/features/ee/workflows/lib/reminders/emailReminderManager.ts around
lines 196 to 198, the reminderLocale assignment can be undefined when
attendeeToBeUsedInMail.language?.locale or evt.organizer.language.locale is
missing; change the expression to provide a fallback (e.g., append || "en" to
the chosen value) so reminderLocale is always a defined locale string before
passing it to emailReminderTemplate and date/time formatting.
| // Use the recipient's locale for proper date/time localization | ||
| // This ensures variables like {EVENT_DATE_ddd} are localized to the recipient's language | ||
| const locale = | ||
| action === WorkflowActions.SMS_ATTENDEE | ||
| ? attendeeToBeUsedInSMS.language?.locale | ||
| : evt.organizer.language.locale; | ||
| smsMessage = | ||
| smsReminderTemplate( | ||
| false, | ||
| evt.organizer.language.locale, | ||
| locale, |
There was a problem hiding this comment.
Add fallback locale to handle undefined values.
The locale selection doesn't provide a fallback when attendeeToBeUsedInSMS.language?.locale is undefined, potentially passing undefined to smsReminderTemplate. This could cause issues with date/time formatting and template rendering.
Apply this diff to add a fallback:
- const locale =
- action === WorkflowActions.SMS_ATTENDEE
- ? attendeeToBeUsedInSMS.language?.locale
- : evt.organizer.language.locale;
+ const locale =
+ action === WorkflowActions.SMS_ATTENDEE
+ ? attendeeToBeUsedInSMS.language?.locale || "en"
+ : evt.organizer.language.locale || "en";This matches the pattern used in scheduleWhatsappReminders.ts at lines 78-81.
🤖 Prompt for AI Agents
In packages/features/ee/workflows/lib/reminders/smsReminderManager.ts around
lines 165 to 174, the locale selection can be undefined when
attendeeToBeUsedInSMS.language?.locale is missing; update the assignment to
provide a fallback (use the organizer's locale and then a global default like
'en' as final fallback) so smsReminderTemplate never receives undefined;
implement the same fallback chain used in scheduleWhatsappReminders (e.g.,
attendee locale || organizer locale || 'en').
| const locale = | ||
| action === WorkflowActions.WHATSAPP_ATTENDEE | ||
| ? evt.attendees[0].language?.locale | ||
| : evt.organizer.language.locale; |
There was a problem hiding this comment.
Add fallback locale to handle undefined values.
The locale selection doesn't provide a fallback when evt.attendees[0].language?.locale is undefined. This locale is used extensively for date/time formatting via dayjs.locale() (lines 96, 99) and in multiple template function calls, where undefined values could cause formatting issues.
Apply this diff to add a fallback:
const locale =
action === WorkflowActions.WHATSAPP_ATTENDEE
- ? evt.attendees[0].language?.locale
- : evt.organizer.language.locale;
+ ? evt.attendees[0].language?.locale || "en"
+ : evt.organizer.language.locale || "en";This matches the pattern used in scheduleWhatsappReminders.ts at lines 78-81.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const locale = | |
| action === WorkflowActions.WHATSAPP_ATTENDEE | |
| ? evt.attendees[0].language?.locale | |
| : evt.organizer.language.locale; | |
| const locale = | |
| action === WorkflowActions.WHATSAPP_ATTENDEE | |
| ? evt.attendees[0].language?.locale || "en" | |
| : evt.organizer.language.locale || "en"; |
🤖 Prompt for AI Agents
In packages/features/ee/workflows/lib/reminders/whatsappReminderManager.ts
around lines 85 to 88, the locale selection can end up undefined when
evt.attendees[0].language?.locale is missing; change the assignment so that when
action === WorkflowActions.WHATSAPP_ATTENDEE you use
attendees[0].language?.locale with a fallback to evt.organizer.language.locale
(i.e., use the attendee locale if present, otherwise fall back to the organizer
locale), matching the pattern used in scheduleWhatsappReminders.ts lines 78–81
so dayjs.locale() and template calls never receive undefined.
|
hey @Bhavyabhardwaj thanks for the Pr. But this issue still needs approval. It is advised not to start working on an issue which has a "needs approval" tag. Closing the pr for now. Happy to reopen the if the issue got approval. |
|
@Devanshusharma2005 Thanks for the clarification! I wasn't aware of the "needs approval" workflow. Will avoid working on such issues in the future and wait for proper approval. Appreciate the guidance! |
|
Hi @Devanshusharma2005 |
Fixes #24280
What does this PR do?
Enhances localization for workflow reminders across all notification channels (Email, SMS, WhatsApp) to properly support date/time variables in the recipient's locale.
Description of Changes
This ensures that date variables like
EVENT_DATE_ddddisplay correctly in the recipient's language (e.g., "Mar" for Tuesday in French instead of "Tue").Files Changed
emailReminderManager.ts- Added locale support for email reminderssmsReminderManager.ts- Added locale support for SMS reminderswhatsappReminderManager.ts- Added locale support for WhatsApp remindersscheduleWhatsappReminders.ts- Enhanced locale handling for schedulingType of Change
Testing
Related Issue
Fixes #24280