From c93e238e1521a61ce1f1bd2a0317c979175532a4 Mon Sep 17 00:00:00 2001 From: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com> Date: Thu, 21 Jul 2022 14:56:20 -0400 Subject: [PATCH] Fixes bug that new line is not working in workflow reminder emails (#3452) * add html format to email template * remove workflow reminder email * fix that text was used instead of html * fixes that email subject was used instead of body * remove \n\n from text template Co-authored-by: CarinaWolli Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../reminders/emailReminderManager.ts | 32 ++++++++++------- .../templates/emailReminderTemplate.ts | 16 ++++++--- .../cron/workflows/scheduleEmailReminders.ts | 27 +++++++-------- packages/emails/email-manager.ts | 13 ------- .../templates/workflow-reminder-email.ts | 34 ------------------- packages/prisma/schema.prisma | 32 ++++++++--------- 6 files changed, 60 insertions(+), 94 deletions(-) delete mode 100644 packages/emails/templates/workflow-reminder-email.ts diff --git a/apps/web/ee/lib/workflows/reminders/emailReminderManager.ts b/apps/web/ee/lib/workflows/reminders/emailReminderManager.ts index 76bbb0a809..18b434e443 100644 --- a/apps/web/ee/lib/workflows/reminders/emailReminderManager.ts +++ b/apps/web/ee/lib/workflows/reminders/emailReminderManager.ts @@ -9,7 +9,6 @@ import client from "@sendgrid/client"; import sgMail from "@sendgrid/mail"; import dayjs from "@calcom/dayjs"; -import { sendWorkflowReminderEmail } from "@calcom/emails"; import prisma from "@calcom/prisma"; import { BookingInfo, timeUnitLowerCase } from "@ee/lib/workflows/reminders/smsReminderManager"; import emailReminderTemplate from "@ee/lib/workflows/reminders/templates/emailReminderTemplate"; @@ -60,11 +59,17 @@ export const scheduleEmailReminder = async ( const attendeeName = action === WorkflowActions.EMAIL_HOST ? evt.attendees[0].name : evt.organizer.name; const timeZone = action === WorkflowActions.EMAIL_HOST ? evt.organizer.timeZone : evt.attendees[0].timeZone; + let emailContent = { + emailSubject, + emailBody: { + text: emailBody, + html: `${emailBody}`, + }, + }; + switch (template) { case WorkflowTemplates.REMINDER: - const emailTemplate = emailReminderTemplate(startTime, evt.title, timeZone, attendeeName, name); - emailSubject = emailTemplate.subject; - emailBody = emailTemplate.body; + emailContent = emailReminderTemplate(startTime, evt.title, timeZone, attendeeName, name); break; } @@ -73,7 +78,14 @@ export const scheduleEmailReminder = async ( triggerEvent === WorkflowTriggerEvents.EVENT_CANCELLED ) { try { - await sendWorkflowReminderEmail(evt, sendTo, emailSubject, emailBody); + await sgMail.send({ + to: sendTo, + from: senderEmail, + subject: emailContent.emailSubject, + text: emailContent.emailBody.text, + html: emailContent.emailBody.html, + batchId: batchIdResponse[1].batch_id, + }); } catch (error) { console.log("Error sending Email"); } @@ -88,13 +100,9 @@ export const scheduleEmailReminder = async ( await sgMail.send({ to: sendTo, from: senderEmail, - subject: emailSubject, - content: [ - { - type: "text/html", - value: emailBody, - }, - ], + subject: emailContent.emailSubject, + text: emailContent.emailBody.text, + html: emailContent.emailBody.html, batchId: batchIdResponse[1].batch_id, sendAt: scheduledDate.unix(), }); diff --git a/apps/web/ee/lib/workflows/reminders/templates/emailReminderTemplate.ts b/apps/web/ee/lib/workflows/reminders/templates/emailReminderTemplate.ts index 60368f797a..f3c18b6d3b 100644 --- a/apps/web/ee/lib/workflows/reminders/templates/emailReminderTemplate.ts +++ b/apps/web/ee/lib/workflows/reminders/templates/emailReminderTemplate.ts @@ -7,19 +7,25 @@ const emailReminderTemplate = ( attendee: string, name: string ) => { - const templateSubject = `Reminder: ${eventName} at ${dayjs(startTime) + const emailSubject = `Reminder: ${eventName} on ${dayjs(startTime) .tz(timeZone) - .format("YYYY MMM D h:mmA")}`; + .format("YYYY MMM D")} at ${dayjs(startTime).tz(timeZone).format("h:mmA")} ${timeZone}.`; - const templateBody = `Hi ${name},\n\nThis is a reminder that your meeting (${eventName}) with ${attendee} is on ${dayjs( + const templateBodyText = `Hi ${name}, this is a reminder that your meeting (${eventName}) with ${attendee} is on ${dayjs( startTime ) .tz(timeZone) .format("YYYY MMM D")} at ${dayjs(startTime).tz(timeZone).format("h:mmA")} ${timeZone}.`; - const emailContent = { subject: templateSubject, body: templateBody }; + const templateBodyHtml = `Hi ${name},

This is a reminder that your meeting (${eventName}) with ${attendee} is on ${dayjs( + startTime + ) + .tz(timeZone) + .format("YYYY MMM D")} at ${dayjs(startTime).tz(timeZone).format("h:mmA")} ${timeZone}.`; - return emailContent; + const emailBody = { text: templateBodyText, html: templateBodyHtml }; + + return { emailSubject, emailBody }; }; export default emailReminderTemplate; diff --git a/apps/web/ee/pages/api/cron/workflows/scheduleEmailReminders.ts b/apps/web/ee/pages/api/cron/workflows/scheduleEmailReminders.ts index 4dabde6756..fbdafb64e2 100644 --- a/apps/web/ee/pages/api/cron/workflows/scheduleEmailReminders.ts +++ b/apps/web/ee/pages/api/cron/workflows/scheduleEmailReminders.ts @@ -72,11 +72,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { ? reminder.booking?.user?.email : reminder.booking?.attendees[0].email; - let emailTemplate = { - subject: reminder.workflowStep.emailSubject || "", - body: reminder.workflowStep.reminderBody || "", - }; - const name = reminder.workflowStep.action === WorkflowActions.EMAIL_ATTENDEE ? reminder.booking?.attendees[0].name @@ -92,9 +87,17 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { ? reminder.booking?.attendees[0].timeZone : reminder.booking?.user?.timeZone; + let emailContent = { + emailSubject: reminder.workflowStep.emailSubject || "", + emailBody: { + text: reminder.workflowStep.reminderBody || "", + html: `${reminder.workflowStep.reminderBody || ""}`, + }, + }; + switch (reminder.workflowStep.template) { case WorkflowTemplates.REMINDER: - emailTemplate = emailReminderTemplate( + emailContent = emailReminderTemplate( reminder.booking?.startTime.toISOString() || "", reminder.booking?.eventType?.title || "", timeZone || "", @@ -103,17 +106,13 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { ); break; } - if (emailTemplate.subject.length > 0 && emailTemplate.body.length > 0 && sendTo) { + if (emailContent.emailSubject.length > 0 && emailContent.emailBody.text.length > 0 && sendTo) { await sgMail.send({ to: sendTo, from: senderEmail, - subject: emailTemplate.subject, - content: [ - { - type: "text/html", - value: emailTemplate.body, - }, - ], + subject: emailContent.emailSubject, + text: emailContent.emailBody.text, + html: emailContent.emailBody.html, batchId: batchIdResponse[1].batch_id, sendAt: dayjs(reminder.scheduledDate).unix(), }); diff --git a/packages/emails/email-manager.ts b/packages/emails/email-manager.ts index 2247e26919..db1f8c7c9e 100644 --- a/packages/emails/email-manager.ts +++ b/packages/emails/email-manager.ts @@ -10,7 +10,6 @@ import AttendeeRescheduledEmail from "./templates/attendee-rescheduled-email"; import AttendeeScheduledEmail from "./templates/attendee-scheduled-email"; import BrokenIntegrationEmail from "./templates/broken-integration-email"; import FeedbackEmail, { Feedback } from "./templates/feedback-email"; -import WorkflowReminderEmail from "./templates/workflow-reminder-email"; import ForgotPasswordEmail, { PasswordReset } from "./templates/forgot-password-email"; import OrganizerCancelledEmail from "./templates/organizer-cancelled-email"; import OrganizerLocationChangeEmail from "./templates/organizer-location-change-email"; @@ -21,7 +20,6 @@ import OrganizerRequestRescheduleEmail from "./templates/organizer-request-resch import OrganizerRescheduledEmail from "./templates/organizer-rescheduled-email"; import OrganizerScheduledEmail from "./templates/organizer-scheduled-email"; import TeamInviteEmail, { TeamInvite } from "./templates/team-invite-email"; -import { BookingInfo } from "@calcom/web/ee/lib/workflows/reminders/smsReminderManager"; export const sendScheduledEmails = async (calEvent: CalendarEvent) => { const emailsToSend: Promise[] = []; @@ -329,14 +327,3 @@ export const sendBrokenIntegrationEmail = async (evt: CalendarEvent, type: "vide } }); }; - -export const sendWorkflowReminderEmail = async (evt: BookingInfo, sendTo: string, emailSubject: string, emailBody: string) => { - await new Promise((resolve, reject) => { - try { - const workflowReminderEmail = new WorkflowReminderEmail(evt, sendTo, emailSubject, emailBody); - resolve(workflowReminderEmail.sendEmail()); - } catch (e) { - reject(console.error("WorkflowReminderEmail.sendEmail failed", e)); - } - }); -} diff --git a/packages/emails/templates/workflow-reminder-email.ts b/packages/emails/templates/workflow-reminder-email.ts deleted file mode 100644 index e9faa079a0..0000000000 --- a/packages/emails/templates/workflow-reminder-email.ts +++ /dev/null @@ -1,34 +0,0 @@ -import BaseEmail from "./_base-email"; -import { BookingInfo } from "@calcom/web/ee/lib/workflows/reminders/smsReminderManager"; -export default class WorkflowReminderEmail extends BaseEmail { - sendTo: string; - body: string; - emailSubject: string; - evt: BookingInfo; - - constructor(evt: BookingInfo, sendTo: string, emailSubject: string, body: string) { - super(); - this.sendTo = sendTo; - this.body = body; - this.evt = evt; - this.emailSubject = emailSubject; - } - - protected getNodeMailerPayload(): Record { - let from =""; - let replyTo =""; - - if(this.evt.organizer) { - from = this.evt.organizer.name || ""; - replyTo = this.evt.organizer.email; - } - return { - to: `<${this.sendTo}>`, - from: `${from} <${this.getMailerOptions().from}>`, - replyTo: replyTo, - subject: this.emailSubject, - text: this.body, - }; - } - -} diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 752857ef33..b6a84f337c 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -19,14 +19,14 @@ generator zod { } enum SchedulingType { - ROUND_ROBIN @map("roundRobin") - COLLECTIVE @map("collective") + ROUND_ROBIN @map("roundRobin") + COLLECTIVE @map("collective") } enum PeriodType { - UNLIMITED @map("unlimited") - ROLLING @map("rolling") - RANGE @map("range") + UNLIMITED @map("unlimited") + ROLLING @map("rolling") + RANGE @map("range") } model EventType { @@ -253,10 +253,10 @@ model Attendee { } enum BookingStatus { - CANCELLED @map("cancelled") - ACCEPTED @map("accepted") - REJECTED @map("rejected") - PENDING @map("pending") + CANCELLED @map("cancelled") + ACCEPTED @map("accepted") + REJECTED @map("rejected") + PENDING @map("pending") } model DailyEventReference { @@ -335,10 +335,10 @@ model SelectedCalendar { } enum EventTypeCustomInputType { - TEXT @map("text") - TEXTLONG @map("textLong") - NUMBER @map("number") - BOOL @map("bool") + TEXT @map("text") + TEXTLONG @map("textLong") + NUMBER @map("number") + BOOL @map("bool") } model EventTypeCustomInput { @@ -575,9 +575,9 @@ model WorkflowsOnEventTypes { } enum TimeUnit { - DAY @map("day") - HOUR @map("hour") - MINUTE @map("minute") + DAY @map("day") + HOUR @map("hour") + MINUTE @map("minute") } model WorkflowReminder {