Files
calendar/packages/features/tasker/tasks/sendWorkflowEmails.ts
T
98b6d63164 refactor: apply biome formatting to packages/features (#27844)
* refactor: apply biome formatting to packages/features (batch 1 - small subdirs)

Format small subdirectories in packages/features: di, flags, holidays, oauth,
settings, users, assignment-reason, selectedCalendar, hashedLink, host, form,
form-builder, availability, data-table, pbac, schedules, troubleshooter,
eventtypes, calendar-subscription, and root-level files.

Also includes straggler apps/web BookEventForm.tsx.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 2 - medium subdirs)

Format medium subdirectories in packages/features: auth, credentials,
calendars, routing-forms, routing-trace, attributes, watchlist, calAIPhone,
tasker, and webhooks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 3 - bookings + insights)

Format bookings and insights subdirectories in packages/features.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 4 - ee)

Format packages/features/ee subdirectory covering billing, workflows,
organizations, teams, managed-event-types, round-robin, dsync,
integration-attribute-sync, and payments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 5 - booking-audit part 1)

Format booking-audit di, actions, common, dto, repository, and types
subdirectories in packages/features/booking-audit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 6 - booking-audit part 2)

Format booking-audit service subdirectory in packages/features/booking-audit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 15:47:14 +01:00

94 lines
2.9 KiB
TypeScript

import { z } from "zod";
import { sendCustomWorkflowEmail } from "@calcom/emails/workflow-email-service";
import { CalendarEventBuilder } from "@calcom/features/CalendarEventBuilder";
import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository";
import { BookingSeatRepository } from "@calcom/features/bookings/repositories/BookingSeatRepository";
import { EmailWorkflowService } from "@calcom/features/ee/workflows/lib/service/EmailWorkflowService";
import { WorkflowReminderRepository } from "@calcom/features/ee/workflows/repositories/WorkflowReminderRepository";
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
import { prisma } from "@calcom/prisma";
export const ZSendWorkflowEmailsSchemaEager = z.object({
to: z.array(z.string()),
subject: z.string(),
html: z.string(),
replyTo: z.string().optional(),
sender: z.string().nullable().optional(),
attachments: z
.array(
z
.object({
content: z.string(),
filename: z.string(),
})
.passthrough()
)
.optional(),
});
const ZSendWorkflowEmailsSchemaLazy = z.object({
bookingUid: z.string(),
workflowReminderId: z.number(),
});
export const ZSendWorkflowEmailsSchema = z.union([
ZSendWorkflowEmailsSchemaEager,
ZSendWorkflowEmailsSchemaLazy,
]);
export async function sendWorkflowEmails(payload: string): Promise<void> {
const mailData = ZSendWorkflowEmailsSchema.parse(JSON.parse(payload));
// Generate workflow body to send
if ("bookingUid" in mailData && "workflowReminderId" in mailData) {
const bookingRepository = new BookingRepository(prisma);
const booking = await bookingRepository.getBookingForCalEventBuilderFromUid(mailData.bookingUid);
if (!booking) {
throw new Error("Booking not found");
}
const bookingMetadata = bookingMetadataSchema.parse(booking.metadata || {});
const calendarEvent = (
await CalendarEventBuilder.fromBooking(booking, {
platformClientId: bookingMetadata?.platformClientId,
})
).build();
if (!calendarEvent) {
throw new Error("Calendar event could not be built");
}
// Check if videoCallUrl exists in booking metadata and add it to evt.metadata
const metadata = bookingMetadata?.videoCallUrl
? {
videoCallUrl: bookingMetadata.videoCallUrl,
}
: undefined;
const evtWithMetadata = { ...calendarEvent, metadata };
const workflowReminderRepository = new WorkflowReminderRepository(prisma);
const bookingSeatRepository = new BookingSeatRepository(prisma);
const emailWorkflowService = new EmailWorkflowService(workflowReminderRepository, bookingSeatRepository);
await emailWorkflowService.handleSendEmailWorkflowTask({
evt: evtWithMetadata,
workflowReminderId: mailData.workflowReminderId,
});
return;
}
await Promise.all(
mailData.to.map((to) =>
sendCustomWorkflowEmail({
...mailData,
to,
})
)
);
}