fix: send attendee email with event updates of reassignment (#17836)

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
This commit is contained in:
Carina Wollendorfer
2024-11-26 10:33:00 -05:00
committed by GitHub
co-authored by CarinaWolli
parent 2df553b58b
commit ae70786b2b
8 changed files with 90 additions and 2 deletions
@@ -130,7 +130,9 @@
"download_your_transcripts": "Download your Transcripts",
"your_meeting_has_been_booked": "Your meeting has been booked",
"event_type_has_been_rescheduled_on_time_date": "Your {{title}} has been rescheduled to {{date}}.",
"event_type_has_been_updated": "Your {{title}} has been updated.",
"event_has_been_rescheduled": "Updated - Your event has been rescheduled",
"event_has_been_updated": "Event has been updated",
"your_event_has_been_rescheduled": "Your event has been rescheduled",
"request_reschedule_subtitle": "{{organizer}} has canceled the booking and requested you to pick another time.",
"request_reschedule_title_organizer": "You have requested {{attendee}} to reschedule",
+17
View File
@@ -38,6 +38,7 @@ import AttendeeLocationChangeEmail from "./templates/attendee-location-change-em
import AttendeeRequestEmail from "./templates/attendee-request-email";
import AttendeeRescheduledEmail from "./templates/attendee-rescheduled-email";
import AttendeeScheduledEmail from "./templates/attendee-scheduled-email";
import AttendeeUpdatedEmail from "./templates/attendee-updated-email";
import type { EmailVerifyCode } from "./templates/attendee-verify-email";
import AttendeeVerifyEmail from "./templates/attendee-verify-email";
import AttendeeWasRequestedToRescheduleEmail from "./templates/attendee-was-requested-to-reschedule-email";
@@ -195,6 +196,22 @@ export const sendRoundRobinRescheduledEmailsAndSMS = async (
await Promise.all(emailsAndSMSToSend);
};
export const sendRoundRobinUpdatedEmailsAndSMS = async ({
calEvent,
eventTypeMetadata,
}: {
calEvent: CalendarEvent;
eventTypeMetadata?: EventTypeMetadata;
}) => {
if (eventTypeDisableAttendeeEmail(eventTypeMetadata)) return;
const emailsToSend = calEvent.attendees.map((attendee) =>
sendEmail(() => new AttendeeUpdatedEmail(calEvent, attendee))
);
await Promise.all(emailsToSend);
};
export const sendRoundRobinCancelledEmailsAndSMS = async (
calEvent: CalendarEvent,
members: Person[],
@@ -0,0 +1,10 @@
import { AttendeeScheduledEmail } from "./AttendeeScheduledEmail";
export const AttendeeUpdatedEmail = (props: React.ComponentProps<typeof AttendeeScheduledEmail>) => (
<AttendeeScheduledEmail
title="event_has_been_updated"
headerType="calendarCircle"
subject="event_type_has_been_updated"
{...props}
/>
);
+1
View File
@@ -6,6 +6,7 @@ export { AttendeeLocationChangeEmail } from "./AttendeeLocationChangeEmail";
export { AttendeeRequestEmail } from "./AttendeeRequestEmail";
export { AttendeeWasRequestedToRescheduleEmail } from "./AttendeeWasRequestedToRescheduleEmail";
export { AttendeeRescheduledEmail } from "./AttendeeRescheduledEmail";
export { AttendeeUpdatedEmail } from "./AttendeeUpdatedEmail";
export { AttendeeScheduledEmail } from "./AttendeeScheduledEmail";
export { DisabledAppEmail } from "./DisabledAppEmail";
export { SlugReplacementEmail } from "./SlugReplacementEmail";
@@ -0,0 +1,33 @@
import type { CalendarEvent, Person } from "@calcom/types/Calendar";
import { renderEmail } from "../";
import generateIcsFile, { GenerateIcsRole } from "../lib/generateIcsFile";
import AttendeeScheduledEmail from "./attendee-scheduled-email";
export default class AttendeeUpdatedEmail extends AttendeeScheduledEmail {
protected async getNodeMailerPayload(): Promise<Record<string, unknown>> {
return {
icalEvent: generateIcsFile({
calEvent: this.calEvent,
role: GenerateIcsRole.ATTENDEE,
status: "CONFIRMED",
}),
to: `${this.attendee.name} <${this.attendee.email}>`,
from: `${this.calEvent.organizer.name} <${this.getMailerOptions().from}>`,
replyTo: [...this.calEvent.attendees.map(({ email }) => email), this.calEvent.organizer.email],
subject: `${this.attendee.language.translate("event_type_has_been_updated", {
title: this.calEvent.title,
date: this.getFormattedDate(),
})}`,
html: await this.getHtml(this.calEvent, this.attendee),
text: this.getTextBody("event_has_been_updated", "emailed_you_and_any_other_attendees"),
};
}
async getHtml(calEvent: CalendarEvent, attendee: Person) {
return await renderEmail("AttendeeUpdatedEmail", {
calEvent,
attendee,
});
}
}
@@ -4,7 +4,11 @@ import { cloneDeep } from "lodash";
import { OrganizerDefaultConferencingAppType, getLocationValueForDB } from "@calcom/app-store/locations";
import { getEventName } from "@calcom/core/event";
import dayjs from "@calcom/dayjs";
import { sendRoundRobinCancelledEmailsAndSMS, sendRoundRobinScheduledEmailsAndSMS } from "@calcom/emails";
import {
sendRoundRobinCancelledEmailsAndSMS,
sendRoundRobinScheduledEmailsAndSMS,
sendRoundRobinUpdatedEmailsAndSMS,
} from "@calcom/emails";
import getBookingResponsesSchema from "@calcom/features/bookings/lib/getBookingResponsesSchema";
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
import { getEventTypesFromDB } from "@calcom/features/bookings/lib/handleNewBooking/getEventTypesFromDB";
@@ -339,6 +343,13 @@ export const roundRobinManualReassignment = async ({
}
if (hasOrganizerChanged) {
if (emailsEnabled) {
// send email with event updates to attendees
await sendRoundRobinUpdatedEmailsAndSMS({
calEvent: evtWithoutCancellationReason,
});
}
// Handle changing workflows with organizer
await handleWorkflowsUpdate({
booking,
@@ -4,7 +4,11 @@ import { cloneDeep } from "lodash";
import { OrganizerDefaultConferencingAppType, getLocationValueForDB } from "@calcom/app-store/locations";
import { getEventName } from "@calcom/core/event";
import dayjs from "@calcom/dayjs";
import { sendRoundRobinCancelledEmailsAndSMS, sendRoundRobinScheduledEmailsAndSMS } from "@calcom/emails";
import {
sendRoundRobinCancelledEmailsAndSMS,
sendRoundRobinScheduledEmailsAndSMS,
sendRoundRobinUpdatedEmailsAndSMS,
} from "@calcom/emails";
import getBookingResponsesSchema from "@calcom/features/bookings/lib/getBookingResponsesSchema";
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
import { ensureAvailableUsers } from "@calcom/features/bookings/lib/handleNewBooking/ensureAvailableUsers";
@@ -389,6 +393,13 @@ export const roundRobinReassignment = async ({
// Handle changing workflows with organizer
if (hasOrganizerChanged) {
if (emailsEnabled) {
// send email with event updates to attendees
await sendRoundRobinUpdatedEmailsAndSMS({
calEvent: evtWithoutCancellationReason,
});
}
const scheduledWorkflowReminders = await prisma.workflowReminder.findMany({
where: {
bookingUid: booking.uid,
+3
View File
@@ -10,6 +10,7 @@ import AttendeeDeclinedEmail from "@calcom/emails/templates/attendee-declined-em
import AttendeeRequestEmail from "@calcom/emails/templates/attendee-request-email";
import AttendeeRescheduledEmail from "@calcom/emails/templates/attendee-rescheduled-email";
import AttendeeScheduledEmail from "@calcom/emails/templates/attendee-scheduled-email";
import AttendeeUpdatedEmail from "@calcom/emails/templates/attendee-updated-email";
import OrganizerCancelledEmail from "@calcom/emails/templates/organizer-cancelled-email";
import OrganizerReassignedEmail from "@calcom/emails/templates/organizer-reassigned-email";
import OrganizerRequestEmail from "@calcom/emails/templates/organizer-request-email";
@@ -212,6 +213,8 @@ export { OrganizerRescheduledEmail };
export { AttendeeRescheduledEmail };
export { AttendeeUpdatedEmail };
export { OrganizerRequestEmail };
export { AttendeeRequestEmail };