refactor: Split EmailManager into focused service files (#24997)
* refactor: Split EmailManager into focused service files - Created separate service files for different email categories: - auth-email-service.ts: Authentication and verification emails - organization-email-service.ts: Organization and team emails - billing-email-service.ts: Payment and credit-related emails - integration-email-service.ts: Integration and app-related emails - workflow-email-service.ts: Workflow and custom emails - recording-email-service.ts: Recording and transcript emails - Refactored email-manager.ts to keep only core booking lifecycle functions - Removed unused imports from email-manager.ts - Updated index.ts to export from all new service files - Updated all imports across the codebase to use package root (@calcom/emails) - Fixed lint warnings in handleChildrenEventTypes.ts This reduces the import cost of EmailManager by allowing consumers to import only the specific email services they need. Co-Authored-By: morgan@cal.com <morgan@cal.com> * refactor: Update all imports to use direct service file paths - Update 49 files to import directly from service files instead of barrel file - Update packages/emails/index.ts to keep only email-manager and renderEmail exports - Fix dynamic import in passwordResetRequest.ts - Update renderEmail imports to use direct path - Update test file to import from specific service module - Fix ESLint warnings in modified files (unused variables, unused expressions) This ensures consumers only import the specific email services they need, reducing import cost by avoiding the barrel file pattern for service files. Co-Authored-By: morgan@cal.com <morgan@cal.com> * fix: Use default import for renderEmail renderEmail is exported as a default export, not a named export. Changed from 'import { renderEmail }' to 'import renderEmail'. Co-Authored-By: morgan@cal.com <morgan@cal.com> * fix: Update test mocks to use direct service file imports - Update handleNoShowFee.test.ts to mock @calcom/emails/billing-email-service - Update credit-service.test.ts to mock @calcom/emails/billing-email-service - These tests were failing because they were mocking the barrel file @calcom/emails which no longer exports service functions after the refactoring Co-Authored-By: morgan@cal.com <morgan@cal.com> * fix: unit test spy * fix: unit test mock * address cubic comments * fix: type error sendMonthlyDigestEmail * remove barrel file and sendEmail unused task * fixup! remove barrel file and sendEmail unused task * fixup! fixup! remove barrel file and sendEmail unused task * fix: integration test mock emails --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: hbjORbj <sldisek783@gmail.com>
This commit is contained in:
co-authored by
morgan@cal.com
Devin AI
hbjORbj
parent
4407a1952c
commit
a73b804d48
@@ -3,7 +3,7 @@ import type { NextRequest } from "next/server";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { sendOrganizerRequestReminderEmail } from "@calcom/emails";
|
||||
import { sendOrganizerRequestReminderEmail } from "@calcom/emails/email-manager";
|
||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||
import { isPrismaObjOrUndefined } from "@calcom/lib/isPrismaObj";
|
||||
import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent";
|
||||
|
||||
@@ -4,7 +4,7 @@ import { NextResponse } from "next/server";
|
||||
import { z } from "zod";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { sendMonthlyDigestEmails } from "@calcom/emails/email-manager";
|
||||
import { sendMonthlyDigestEmail } from "@calcom/emails/workflow-email-service";
|
||||
import { EventsInsights } from "@calcom/features/insights/server/events";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import prisma from "@calcom/prisma";
|
||||
@@ -295,7 +295,7 @@ async function postHandler(request: NextRequest) {
|
||||
|
||||
// Only send email if user has allowed to receive monthly digest emails
|
||||
if (owner.receiveMonthlyDigestEmail) {
|
||||
await sendMonthlyDigestEmails({
|
||||
await sendMonthlyDigestEmail({
|
||||
...EventData,
|
||||
admin: { email: owner?.email ?? "", name: owner?.name ?? "" },
|
||||
language: t,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { defaultResponderForAppDir } from "app/api/defaultResponderForAppDir";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
import { renderEmail } from "@calcom/emails";
|
||||
import renderEmail from "@calcom/emails/src/renderEmail";
|
||||
import { IS_PRODUCTION } from "@calcom/lib/constants";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ const mockFindFirstEventType = (
|
||||
return eventType;
|
||||
};
|
||||
|
||||
vi.mock("@calcom/emails/email-manager", () => {
|
||||
vi.mock("@calcom/emails/integration-email-service", () => {
|
||||
return {
|
||||
sendSlugReplacementEmail: () => ({}),
|
||||
};
|
||||
@@ -419,7 +419,7 @@ describe("handleChildrenEventTypes", () => {
|
||||
timeZone: _timeZone,
|
||||
parentId: _parentId,
|
||||
userId: _userId,
|
||||
|
||||
|
||||
requiresBookerEmailVerification,
|
||||
lockTimeZoneToggleOnBookingPage,
|
||||
useEventTypeDestinationCalendarEmail,
|
||||
|
||||
@@ -2,7 +2,7 @@ import prismaMock from "../../../../../tests/libs/__mocks__/prisma";
|
||||
|
||||
import "vitest-fetch-mock";
|
||||
|
||||
import { sendAwaitingPaymentEmailAndSMS } from "@calcom/emails";
|
||||
import { sendAwaitingPaymentEmailAndSMS } from "@calcom/emails/email-manager";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import type { Payment, Prisma, PaymentOption, Booking } from "@calcom/prisma/client";
|
||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { eventTypeAppMetadataOptionalSchema } from "@calcom/app-store/zod-utils";
|
||||
import { sendScheduledEmailsAndSMS } from "@calcom/emails";
|
||||
import { sendScheduledEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import EventManager, { placeholderCreatedEvent } from "@calcom/features/bookings/lib/EventManager";
|
||||
import { doesBookingRequireConfirmation } from "@calcom/features/bookings/lib/doesBookingRequireConfirmation";
|
||||
import { getAllCredentialsIncludeServiceAccountKey } from "@calcom/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials";
|
||||
import { handleBookingRequested } from "@calcom/features/bookings/lib/handleBookingRequested";
|
||||
@@ -7,7 +8,6 @@ import { handleConfirmation } from "@calcom/features/bookings/lib/handleConfirma
|
||||
import { getBooking } from "@calcom/features/bookings/lib/payment/getBooking";
|
||||
import { getPlatformParams } from "@calcom/features/platform-oauth-client/get-platform-params";
|
||||
import { PlatformOAuthClientRepository } from "@calcom/features/platform-oauth-client/platform-oauth-client.repository";
|
||||
import EventManager, { placeholderCreatedEvent } from "@calcom/features/bookings/lib/EventManager";
|
||||
import { HttpError as HttpCode } from "@calcom/lib/http-error";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { renderEmail } from "@calcom/emails";
|
||||
import renderEmail from "@calcom/emails/src/renderEmail";
|
||||
import BaseEmail from "@calcom/emails/templates/_base-email";
|
||||
import type { App_RoutingForms_Form } from "@calcom/prisma/client";
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import Stripe from "stripe";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import z from "zod";
|
||||
|
||||
import { sendAwaitingPaymentEmailAndSMS } from "@calcom/emails";
|
||||
import { sendAwaitingPaymentEmailAndSMS } from "@calcom/emails/email-manager";
|
||||
import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository";
|
||||
import { ErrorCode } from "@calcom/lib/errorCodes";
|
||||
import { getErrorFromUnknown } from "@calcom/lib/errors";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { TFunction } from "i18next";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails";
|
||||
import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails/email-manager";
|
||||
import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient";
|
||||
import { CalendarEventBuilder } from "@calcom/lib/builders/CalendarEvent/builder";
|
||||
import { CalendarEventDirector } from "@calcom/lib/builders/CalendarEvent/director";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { TFunction } from "i18next";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails";
|
||||
import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails/email-manager";
|
||||
import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient";
|
||||
import { CalendarEventBuilder } from "@calcom/lib/builders/CalendarEvent/builder";
|
||||
import { CalendarEventDirector } from "@calcom/lib/builders/CalendarEvent/director";
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { renderEmail } from "@calcom/emails";
|
||||
import renderEmail from "@calcom/emails/renderEmail";
|
||||
|
||||
await renderEmail("TeamInviteEmail", {
|
||||
language: t,
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import type BaseEmail from "@calcom/emails/templates/_base-email";
|
||||
|
||||
import type { PasswordReset } from "./templates/forgot-password-email";
|
||||
import ForgotPasswordEmail from "./templates/forgot-password-email";
|
||||
import type { EmailVerifyLink } from "./templates/account-verify-email";
|
||||
import AccountVerifyEmail from "./templates/account-verify-email";
|
||||
import type { EmailVerifyCode } from "./templates/attendee-verify-email";
|
||||
import AttendeeVerifyEmail from "./templates/attendee-verify-email";
|
||||
import type { ChangeOfEmailVerifyLink } from "./templates/change-account-email-verify";
|
||||
import ChangeOfEmailVerifyEmail from "./templates/change-account-email-verify";
|
||||
|
||||
const sendEmail = (prepare: () => BaseEmail) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const email = prepare();
|
||||
resolve(email.sendEmail());
|
||||
} catch (e) {
|
||||
reject(console.error(`${prepare.constructor.name}.sendEmail failed`, e));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const sendPasswordResetEmail = async (passwordResetEvent: PasswordReset) => {
|
||||
await sendEmail(() => new ForgotPasswordEmail(passwordResetEvent));
|
||||
};
|
||||
|
||||
export const sendEmailVerificationLink = async (verificationInput: EmailVerifyLink) => {
|
||||
await sendEmail(() => new AccountVerifyEmail(verificationInput));
|
||||
};
|
||||
|
||||
export const sendEmailVerificationCode = async (verificationInput: EmailVerifyCode) => {
|
||||
await sendEmail(() => new AttendeeVerifyEmail(verificationInput));
|
||||
};
|
||||
|
||||
export const sendChangeOfEmailVerificationLink = async (verificationInput: ChangeOfEmailVerifyLink) => {
|
||||
await sendEmail(() => new ChangeOfEmailVerifyEmail(verificationInput));
|
||||
};
|
||||
@@ -0,0 +1,129 @@
|
||||
import type { TFunction } from "i18next";
|
||||
|
||||
import type BaseEmail from "@calcom/emails/templates/_base-email";
|
||||
import type { CalendarEvent, Person } from "@calcom/types/Calendar";
|
||||
import type { CreditUsageType } from "@calcom/prisma/enums";
|
||||
import type { EventTypeMetadata } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import OrganizerPaymentRefundFailedEmail from "./templates/organizer-payment-refund-failed-email";
|
||||
import NoShowFeeChargedEmail from "./templates/no-show-fee-charged-email";
|
||||
import CreditBalanceLowWarningEmail from "./templates/credit-balance-low-warning-email";
|
||||
import CreditBalanceLimitReachedEmail from "./templates/credit-balance-limit-reached-email";
|
||||
|
||||
const sendEmail = (prepare: () => BaseEmail) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const email = prepare();
|
||||
resolve(email.sendEmail());
|
||||
} catch (e) {
|
||||
reject(console.error(`${prepare.constructor.name}.sendEmail failed`, e));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const eventTypeDisableAttendeeEmail = (metadata?: EventTypeMetadata) => {
|
||||
return !!metadata?.disableStandardEmails?.all?.attendee;
|
||||
};
|
||||
|
||||
export const sendOrganizerPaymentRefundFailedEmail = async (calEvent: CalendarEvent) => {
|
||||
const emailsToSend: Promise<unknown>[] = [];
|
||||
emailsToSend.push(sendEmail(() => new OrganizerPaymentRefundFailedEmail({ calEvent })));
|
||||
|
||||
if (calEvent.team?.members) {
|
||||
for (const teamMember of calEvent.team.members) {
|
||||
emailsToSend.push(sendEmail(() => new OrganizerPaymentRefundFailedEmail({ calEvent, teamMember })));
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all(emailsToSend);
|
||||
};
|
||||
|
||||
export const sendNoShowFeeChargedEmail = async (
|
||||
attendee: Person,
|
||||
evt: CalendarEvent,
|
||||
eventTypeMetadata?: EventTypeMetadata
|
||||
) => {
|
||||
if (eventTypeDisableAttendeeEmail(eventTypeMetadata)) return;
|
||||
await sendEmail(() => new NoShowFeeChargedEmail(evt, attendee));
|
||||
};
|
||||
|
||||
export const sendCreditBalanceLowWarningEmails = async (input: {
|
||||
team?: {
|
||||
name: string | null;
|
||||
id: number;
|
||||
adminAndOwners: {
|
||||
id: number;
|
||||
name: string | null;
|
||||
email: string;
|
||||
t: TFunction;
|
||||
}[];
|
||||
};
|
||||
user?: {
|
||||
id: number;
|
||||
name: string | null;
|
||||
email: string;
|
||||
t: TFunction;
|
||||
};
|
||||
balance: number;
|
||||
creditFor?: CreditUsageType;
|
||||
}) => {
|
||||
const { team, balance, user, creditFor } = input;
|
||||
if ((!team || !team.adminAndOwners.length) && !user) return;
|
||||
|
||||
if (team) {
|
||||
const emailsToSend: Promise<unknown>[] = [];
|
||||
|
||||
for (const admin of team.adminAndOwners) {
|
||||
emailsToSend.push(
|
||||
sendEmail(() => new CreditBalanceLowWarningEmail({ user: admin, balance, team, creditFor }))
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(emailsToSend);
|
||||
}
|
||||
|
||||
if (user) {
|
||||
await sendEmail(() => new CreditBalanceLowWarningEmail({ user, balance, creditFor }));
|
||||
}
|
||||
};
|
||||
|
||||
export const sendCreditBalanceLimitReachedEmails = async ({
|
||||
team,
|
||||
user,
|
||||
creditFor,
|
||||
}: {
|
||||
team?: {
|
||||
name: string;
|
||||
id: number;
|
||||
adminAndOwners: {
|
||||
id: number;
|
||||
name: string | null;
|
||||
email: string;
|
||||
t: TFunction;
|
||||
}[];
|
||||
};
|
||||
user?: {
|
||||
id: number;
|
||||
name: string | null;
|
||||
email: string;
|
||||
t: TFunction;
|
||||
};
|
||||
creditFor?: CreditUsageType;
|
||||
}) => {
|
||||
if ((!team || !team.adminAndOwners.length) && !user) return;
|
||||
|
||||
if (team) {
|
||||
const emailsToSend: Promise<unknown>[] = [];
|
||||
|
||||
for (const admin of team.adminAndOwners) {
|
||||
emailsToSend.push(
|
||||
sendEmail(() => new CreditBalanceLimitReachedEmail({ user: admin, team, creditFor }))
|
||||
);
|
||||
}
|
||||
await Promise.all(emailsToSend);
|
||||
}
|
||||
|
||||
if (user) {
|
||||
await sendEmail(() => new CreditBalanceLimitReachedEmail({ user, creditFor }));
|
||||
}
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { TFunction } from "i18next";
|
||||
import { default as cloneDeep } from "lodash/cloneDeep";
|
||||
import type { z } from "zod";
|
||||
|
||||
@@ -10,7 +9,6 @@ import { formatCalEvent } from "@calcom/lib/formatCalendarEvent";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import { withReporting } from "@calcom/lib/sentryWrapper";
|
||||
import type { CreditUsageType } from "@calcom/prisma/enums";
|
||||
import type { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
||||
import type { CalendarEvent, Person } from "@calcom/types/Calendar";
|
||||
|
||||
@@ -23,65 +21,27 @@ import EventRequestSMS from "../sms/attendee/event-request-sms";
|
||||
import EventRequestToRescheduleSMS from "../sms/attendee/event-request-to-reschedule-sms";
|
||||
import EventSuccessfullyReScheduledSMS from "../sms/attendee/event-rescheduled-sms";
|
||||
import EventSuccessfullyScheduledSMS from "../sms/attendee/event-scheduled-sms";
|
||||
import type { MonthlyDigestEmailData } from "./src/templates/MonthlyDigestEmail";
|
||||
import type { OrganizationAdminNoSlotsEmailInput } from "./src/templates/OrganizationAdminNoSlots";
|
||||
import type { EmailVerifyLink } from "./templates/account-verify-email";
|
||||
import AccountVerifyEmail from "./templates/account-verify-email";
|
||||
import type { OrganizationNotification } from "./templates/admin-organization-notification";
|
||||
import AdminOrganizationNotification from "./templates/admin-organization-notification";
|
||||
import AttendeeAddGuestsEmail from "./templates/attendee-add-guests-email";
|
||||
import AttendeeAwaitingPaymentEmail from "./templates/attendee-awaiting-payment-email";
|
||||
import AttendeeCancelledEmail from "./templates/attendee-cancelled-email";
|
||||
import AttendeeCancelledSeatEmail from "./templates/attendee-cancelled-seat-email";
|
||||
import AttendeeDailyVideoDownloadRecordingEmail from "./templates/attendee-daily-video-download-recording-email";
|
||||
import AttendeeDailyVideoDownloadTranscriptEmail from "./templates/attendee-daily-video-download-transcript-email";
|
||||
import AttendeeDeclinedEmail from "./templates/attendee-declined-email";
|
||||
import AttendeeLocationChangeEmail from "./templates/attendee-location-change-email";
|
||||
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";
|
||||
import BookingRedirectEmailNotification from "./templates/booking-redirect-notification";
|
||||
import type { IBookingRedirect } from "./templates/booking-redirect-notification";
|
||||
import BrokenIntegrationEmail from "./templates/broken-integration-email";
|
||||
import type { ChangeOfEmailVerifyLink } from "./templates/change-account-email-verify";
|
||||
import ChangeOfEmailVerifyEmail from "./templates/change-account-email-verify";
|
||||
import CreditBalanceLimitReachedEmail from "./templates/credit-balance-limit-reached-email";
|
||||
import CreditBalanceLowWarningEmail from "./templates/credit-balance-low-warning-email";
|
||||
import DelegationCredentialDisabledEmail from "./templates/delegation-credential-disabled-email";
|
||||
import DisabledAppEmail from "./templates/disabled-app-email";
|
||||
import type { Feedback } from "./templates/feedback-email";
|
||||
import FeedbackEmail from "./templates/feedback-email";
|
||||
import type { PasswordReset } from "./templates/forgot-password-email";
|
||||
import ForgotPasswordEmail from "./templates/forgot-password-email";
|
||||
import MonthlyDigestEmail from "./templates/monthly-digest-email";
|
||||
import NoShowFeeChargedEmail from "./templates/no-show-fee-charged-email";
|
||||
import OrganizationAdminNoSlotsEmail from "./templates/organization-admin-no-slots-email";
|
||||
import type { OrganizationCreation } from "./templates/organization-creation-email";
|
||||
import OrganizationCreationEmail from "./templates/organization-creation-email";
|
||||
import type { OrganizationEmailVerify } from "./templates/organization-email-verification";
|
||||
import OrganizationEmailVerification from "./templates/organization-email-verification";
|
||||
import OrganizerAddGuestsEmail from "./templates/organizer-add-guests-email";
|
||||
import OrganizerAttendeeCancelledSeatEmail from "./templates/organizer-attendee-cancelled-seat-email";
|
||||
import OrganizerCancelledEmail from "./templates/organizer-cancelled-email";
|
||||
import OrganizerDailyVideoDownloadRecordingEmail from "./templates/organizer-daily-video-download-recording-email";
|
||||
import OrganizerDailyVideoDownloadTranscriptEmail from "./templates/organizer-daily-video-download-transcript-email";
|
||||
import OrganizerLocationChangeEmail from "./templates/organizer-location-change-email";
|
||||
import OrganizerPaymentRefundFailedEmail from "./templates/organizer-payment-refund-failed-email";
|
||||
import OrganizerReassignedEmail from "./templates/organizer-reassigned-email";
|
||||
import OrganizerRequestEmail from "./templates/organizer-request-email";
|
||||
import OrganizerRequestReminderEmail from "./templates/organizer-request-reminder-email";
|
||||
import OrganizerRequestedToRescheduleEmail from "./templates/organizer-requested-to-reschedule-email";
|
||||
import OrganizerRescheduledEmail from "./templates/organizer-rescheduled-email";
|
||||
import OrganizerScheduledEmail from "./templates/organizer-scheduled-email";
|
||||
import SlugReplacementEmail from "./templates/slug-replacement-email";
|
||||
import type { TeamInvite } from "./templates/team-invite-email";
|
||||
import TeamInviteEmail from "./templates/team-invite-email";
|
||||
import type { WorkflowEmailData } from "./templates/workflow-email";
|
||||
import WorkflowEmail from "./templates/workflow-email";
|
||||
|
||||
type EventTypeMetadata = z.infer<typeof EventTypeMetaDataSchema>;
|
||||
|
||||
@@ -571,52 +531,6 @@ export const sendAwaitingPaymentEmailAndSMS = async (
|
||||
await awaitingPaymentSMS.sendSMSToAttendees();
|
||||
};
|
||||
|
||||
export const sendOrganizerPaymentRefundFailedEmail = async (calEvent: CalendarEvent) => {
|
||||
const emailsToSend: Promise<unknown>[] = [];
|
||||
emailsToSend.push(sendEmail(() => new OrganizerPaymentRefundFailedEmail({ calEvent })));
|
||||
|
||||
if (calEvent.team?.members) {
|
||||
for (const teamMember of calEvent.team.members) {
|
||||
emailsToSend.push(sendEmail(() => new OrganizerPaymentRefundFailedEmail({ calEvent, teamMember })));
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all(emailsToSend);
|
||||
};
|
||||
|
||||
export const sendPasswordResetEmail = async (passwordResetEvent: PasswordReset) => {
|
||||
await sendEmail(() => new ForgotPasswordEmail(passwordResetEvent));
|
||||
};
|
||||
|
||||
export const sendTeamInviteEmail = async (teamInviteEvent: TeamInvite) => {
|
||||
await sendEmail(() => new TeamInviteEmail(teamInviteEvent));
|
||||
};
|
||||
|
||||
export const sendCustomWorkflowEmail = async (emailData: WorkflowEmailData) => {
|
||||
await sendEmail(() => new WorkflowEmail(emailData));
|
||||
};
|
||||
|
||||
export const sendOrganizationCreationEmail = async (organizationCreationEvent: OrganizationCreation) => {
|
||||
await sendEmail(() => new OrganizationCreationEmail(organizationCreationEvent));
|
||||
};
|
||||
|
||||
export const sendOrganizationAdminNoSlotsNotification = async (
|
||||
orgInviteEvent: OrganizationAdminNoSlotsEmailInput
|
||||
) => {
|
||||
await sendEmail(() => new OrganizationAdminNoSlotsEmail(orgInviteEvent));
|
||||
};
|
||||
|
||||
export const sendEmailVerificationLink = async (verificationInput: EmailVerifyLink) => {
|
||||
await sendEmail(() => new AccountVerifyEmail(verificationInput));
|
||||
};
|
||||
|
||||
export const sendEmailVerificationCode = async (verificationInput: EmailVerifyCode) => {
|
||||
await sendEmail(() => new AttendeeVerifyEmail(verificationInput));
|
||||
};
|
||||
|
||||
export const sendChangeOfEmailVerificationLink = async (verificationInput: ChangeOfEmailVerifyLink) => {
|
||||
await sendEmail(() => new ChangeOfEmailVerifyEmail(verificationInput));
|
||||
};
|
||||
|
||||
export const sendRequestRescheduleEmailAndSMS = async (
|
||||
calEvent: CalendarEvent,
|
||||
@@ -737,203 +651,3 @@ export const sendAddGuestsEmailsAndSMS = async (args: {
|
||||
|
||||
await Promise.all(emailsAndSMSToSend);
|
||||
};
|
||||
|
||||
export const sendFeedbackEmail = async (feedback: Feedback) => {
|
||||
await sendEmail(() => new FeedbackEmail(feedback));
|
||||
};
|
||||
|
||||
export const sendBrokenIntegrationEmail = async (evt: CalendarEvent, type: "video" | "calendar") => {
|
||||
const calendarEvent = formatCalEvent(evt);
|
||||
await sendEmail(() => new BrokenIntegrationEmail(calendarEvent, type));
|
||||
};
|
||||
|
||||
export const sendDisabledAppEmail = async ({
|
||||
email,
|
||||
appName,
|
||||
appType,
|
||||
t,
|
||||
title = undefined,
|
||||
eventTypeId = undefined,
|
||||
}: {
|
||||
email: string;
|
||||
appName: string;
|
||||
appType: string[];
|
||||
t: TFunction;
|
||||
title?: string;
|
||||
eventTypeId?: number;
|
||||
}) => {
|
||||
await sendEmail(() => new DisabledAppEmail(email, appName, appType, t, title, eventTypeId));
|
||||
};
|
||||
|
||||
export const sendSlugReplacementEmail = async ({
|
||||
email,
|
||||
name,
|
||||
teamName,
|
||||
t,
|
||||
slug,
|
||||
}: {
|
||||
email: string;
|
||||
name: string;
|
||||
teamName: string | null;
|
||||
t: TFunction;
|
||||
slug: string;
|
||||
}) => {
|
||||
await sendEmail(() => new SlugReplacementEmail(email, name, teamName, slug, t));
|
||||
};
|
||||
|
||||
export const sendNoShowFeeChargedEmail = async (
|
||||
attendee: Person,
|
||||
evt: CalendarEvent,
|
||||
eventTypeMetadata?: EventTypeMetadata
|
||||
) => {
|
||||
if (eventTypeDisableAttendeeEmail(eventTypeMetadata)) return;
|
||||
await sendEmail(() => new NoShowFeeChargedEmail(evt, attendee));
|
||||
};
|
||||
|
||||
export const sendDailyVideoRecordingEmails = async (calEvent: CalendarEvent, downloadLink: string) => {
|
||||
const calendarEvent = formatCalEvent(calEvent);
|
||||
const emailsToSend: Promise<unknown>[] = [];
|
||||
|
||||
emailsToSend.push(
|
||||
sendEmail(() => new OrganizerDailyVideoDownloadRecordingEmail(calendarEvent, downloadLink))
|
||||
);
|
||||
|
||||
for (const attendee of calendarEvent.attendees) {
|
||||
emailsToSend.push(
|
||||
sendEmail(() => new AttendeeDailyVideoDownloadRecordingEmail(calendarEvent, attendee, downloadLink))
|
||||
);
|
||||
}
|
||||
await Promise.all(emailsToSend);
|
||||
};
|
||||
|
||||
export const sendDailyVideoTranscriptEmails = async (calEvent: CalendarEvent, transcripts: string[]) => {
|
||||
const emailsToSend: Promise<unknown>[] = [];
|
||||
|
||||
emailsToSend.push(sendEmail(() => new OrganizerDailyVideoDownloadTranscriptEmail(calEvent, transcripts)));
|
||||
|
||||
for (const attendee of calEvent.attendees) {
|
||||
emailsToSend.push(
|
||||
sendEmail(() => new AttendeeDailyVideoDownloadTranscriptEmail(calEvent, attendee, transcripts))
|
||||
);
|
||||
}
|
||||
await Promise.all(emailsToSend);
|
||||
};
|
||||
|
||||
export const sendOrganizationEmailVerification = async (sendOrgInput: OrganizationEmailVerify) => {
|
||||
await sendEmail(() => new OrganizationEmailVerification(sendOrgInput));
|
||||
};
|
||||
|
||||
export const sendMonthlyDigestEmails = async (eventData: MonthlyDigestEmailData) => {
|
||||
await sendEmail(() => new MonthlyDigestEmail(eventData));
|
||||
};
|
||||
|
||||
export const sendAdminOrganizationNotification = async (input: OrganizationNotification) => {
|
||||
await sendEmail(() => new AdminOrganizationNotification(input));
|
||||
};
|
||||
|
||||
export const sendBookingRedirectNotification = async (bookingRedirect: IBookingRedirect) => {
|
||||
await sendEmail(() => new BookingRedirectEmailNotification(bookingRedirect));
|
||||
};
|
||||
|
||||
export const sendCreditBalanceLowWarningEmails = async (input: {
|
||||
team?: {
|
||||
name: string | null;
|
||||
id: number;
|
||||
adminAndOwners: {
|
||||
id: number;
|
||||
name: string | null;
|
||||
email: string;
|
||||
t: TFunction;
|
||||
}[];
|
||||
};
|
||||
user?: {
|
||||
id: number;
|
||||
name: string | null;
|
||||
email: string;
|
||||
t: TFunction;
|
||||
};
|
||||
balance: number;
|
||||
creditFor?: CreditUsageType;
|
||||
}) => {
|
||||
const { team, balance, user, creditFor } = input;
|
||||
if ((!team || !team.adminAndOwners.length) && !user) return;
|
||||
|
||||
if (team) {
|
||||
const emailsToSend: Promise<unknown>[] = [];
|
||||
|
||||
for (const admin of team.adminAndOwners) {
|
||||
emailsToSend.push(
|
||||
sendEmail(() => new CreditBalanceLowWarningEmail({ user: admin, balance, team, creditFor }))
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(emailsToSend);
|
||||
}
|
||||
|
||||
if (user) {
|
||||
await sendEmail(() => new CreditBalanceLowWarningEmail({ user, balance, creditFor }));
|
||||
}
|
||||
};
|
||||
|
||||
export const sendCreditBalanceLimitReachedEmails = async ({
|
||||
team,
|
||||
user,
|
||||
creditFor,
|
||||
}: {
|
||||
team?: {
|
||||
name: string;
|
||||
id: number;
|
||||
adminAndOwners: {
|
||||
id: number;
|
||||
name: string | null;
|
||||
email: string;
|
||||
t: TFunction;
|
||||
}[];
|
||||
};
|
||||
user?: {
|
||||
id: number;
|
||||
name: string | null;
|
||||
email: string;
|
||||
t: TFunction;
|
||||
};
|
||||
creditFor?: CreditUsageType;
|
||||
}) => {
|
||||
if ((!team || !team.adminAndOwners.length) && !user) return;
|
||||
|
||||
if (team) {
|
||||
const emailsToSend: Promise<unknown>[] = [];
|
||||
|
||||
for (const admin of team.adminAndOwners) {
|
||||
emailsToSend.push(
|
||||
sendEmail(() => new CreditBalanceLimitReachedEmail({ user: admin, team, creditFor }))
|
||||
);
|
||||
}
|
||||
await Promise.all(emailsToSend);
|
||||
}
|
||||
|
||||
if (user) {
|
||||
await sendEmail(() => new CreditBalanceLimitReachedEmail({ user, creditFor }));
|
||||
}
|
||||
};
|
||||
|
||||
export const sendDelegationCredentialDisabledEmail = async ({
|
||||
recipientEmail,
|
||||
recipientName,
|
||||
calendarAppName,
|
||||
conferencingAppName,
|
||||
}: {
|
||||
recipientEmail: string;
|
||||
recipientName?: string;
|
||||
calendarAppName: string;
|
||||
conferencingAppName: string;
|
||||
}) => {
|
||||
await sendEmail(
|
||||
() =>
|
||||
new DelegationCredentialDisabledEmail({
|
||||
recipientEmail,
|
||||
recipientName,
|
||||
calendarAppName,
|
||||
conferencingAppName,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from "./email-manager";
|
||||
export { default as renderEmail } from "./src/renderEmail";
|
||||
@@ -0,0 +1,82 @@
|
||||
import type { TFunction } from "i18next";
|
||||
|
||||
import type BaseEmail from "@calcom/emails/templates/_base-email";
|
||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||
import { formatCalEvent } from "@calcom/lib/formatCalendarEvent";
|
||||
|
||||
import BrokenIntegrationEmail from "./templates/broken-integration-email";
|
||||
import DisabledAppEmail from "./templates/disabled-app-email";
|
||||
import SlugReplacementEmail from "./templates/slug-replacement-email";
|
||||
import DelegationCredentialDisabledEmail from "./templates/delegation-credential-disabled-email";
|
||||
|
||||
const sendEmail = (prepare: () => BaseEmail) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const email = prepare();
|
||||
resolve(email.sendEmail());
|
||||
} catch (e) {
|
||||
reject(console.error(`${prepare.constructor.name}.sendEmail failed`, e));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const sendBrokenIntegrationEmail = async (evt: CalendarEvent, type: "video" | "calendar") => {
|
||||
const calendarEvent = formatCalEvent(evt);
|
||||
await sendEmail(() => new BrokenIntegrationEmail(calendarEvent, type));
|
||||
};
|
||||
|
||||
export const sendDisabledAppEmail = async ({
|
||||
email,
|
||||
appName,
|
||||
appType,
|
||||
t,
|
||||
title = undefined,
|
||||
eventTypeId = undefined,
|
||||
}: {
|
||||
email: string;
|
||||
appName: string;
|
||||
appType: string[];
|
||||
t: TFunction;
|
||||
title?: string;
|
||||
eventTypeId?: number;
|
||||
}) => {
|
||||
await sendEmail(() => new DisabledAppEmail(email, appName, appType, t, title, eventTypeId));
|
||||
};
|
||||
|
||||
export const sendSlugReplacementEmail = async ({
|
||||
email,
|
||||
name,
|
||||
teamName,
|
||||
t,
|
||||
slug,
|
||||
}: {
|
||||
email: string;
|
||||
name: string;
|
||||
teamName: string | null;
|
||||
t: TFunction;
|
||||
slug: string;
|
||||
}) => {
|
||||
await sendEmail(() => new SlugReplacementEmail(email, name, teamName, slug, t));
|
||||
};
|
||||
|
||||
export const sendDelegationCredentialDisabledEmail = async ({
|
||||
recipientEmail,
|
||||
recipientName,
|
||||
calendarAppName,
|
||||
conferencingAppName,
|
||||
}: {
|
||||
recipientEmail: string;
|
||||
recipientName?: string;
|
||||
calendarAppName: string;
|
||||
conferencingAppName: string;
|
||||
}) => {
|
||||
await sendEmail(
|
||||
() =>
|
||||
new DelegationCredentialDisabledEmail({
|
||||
recipientEmail,
|
||||
recipientName,
|
||||
calendarAppName,
|
||||
conferencingAppName,
|
||||
})
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
import type BaseEmail from "@calcom/emails/templates/_base-email";
|
||||
|
||||
import type { TeamInvite } from "./templates/team-invite-email";
|
||||
import TeamInviteEmail from "./templates/team-invite-email";
|
||||
import type { OrganizationCreation } from "./templates/organization-creation-email";
|
||||
import OrganizationCreationEmail from "./templates/organization-creation-email";
|
||||
import type { OrganizationAdminNoSlotsEmailInput } from "./src/templates/OrganizationAdminNoSlots";
|
||||
import OrganizationAdminNoSlotsEmail from "./templates/organization-admin-no-slots-email";
|
||||
import type { OrganizationEmailVerify } from "./templates/organization-email-verification";
|
||||
import OrganizationEmailVerification from "./templates/organization-email-verification";
|
||||
import type { OrganizationNotification } from "./templates/admin-organization-notification";
|
||||
import AdminOrganizationNotification from "./templates/admin-organization-notification";
|
||||
|
||||
const sendEmail = (prepare: () => BaseEmail) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const email = prepare();
|
||||
resolve(email.sendEmail());
|
||||
} catch (e) {
|
||||
reject(console.error(`${prepare.constructor.name}.sendEmail failed`, e));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const sendTeamInviteEmail = async (teamInviteEvent: TeamInvite) => {
|
||||
await sendEmail(() => new TeamInviteEmail(teamInviteEvent));
|
||||
};
|
||||
|
||||
export const sendOrganizationCreationEmail = async (organizationCreationEvent: OrganizationCreation) => {
|
||||
await sendEmail(() => new OrganizationCreationEmail(organizationCreationEvent));
|
||||
};
|
||||
|
||||
export const sendOrganizationAdminNoSlotsNotification = async (
|
||||
orgInviteEvent: OrganizationAdminNoSlotsEmailInput
|
||||
) => {
|
||||
await sendEmail(() => new OrganizationAdminNoSlotsEmail(orgInviteEvent));
|
||||
};
|
||||
|
||||
export const sendOrganizationEmailVerification = async (sendOrgInput: OrganizationEmailVerify) => {
|
||||
await sendEmail(() => new OrganizationEmailVerification(sendOrgInput));
|
||||
};
|
||||
|
||||
export const sendAdminOrganizationNotification = async (input: OrganizationNotification) => {
|
||||
await sendEmail(() => new AdminOrganizationNotification(input));
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
import type BaseEmail from "@calcom/emails/templates/_base-email";
|
||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||
import { formatCalEvent } from "@calcom/lib/formatCalendarEvent";
|
||||
|
||||
import OrganizerDailyVideoDownloadRecordingEmail from "./templates/organizer-daily-video-download-recording-email";
|
||||
import AttendeeDailyVideoDownloadRecordingEmail from "./templates/attendee-daily-video-download-recording-email";
|
||||
import OrganizerDailyVideoDownloadTranscriptEmail from "./templates/organizer-daily-video-download-transcript-email";
|
||||
import AttendeeDailyVideoDownloadTranscriptEmail from "./templates/attendee-daily-video-download-transcript-email";
|
||||
|
||||
const sendEmail = (prepare: () => BaseEmail) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const email = prepare();
|
||||
resolve(email.sendEmail());
|
||||
} catch (e) {
|
||||
reject(console.error(`${prepare.constructor.name}.sendEmail failed`, e));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const sendDailyVideoRecordingEmails = async (calEvent: CalendarEvent, downloadLink: string) => {
|
||||
const calendarEvent = formatCalEvent(calEvent);
|
||||
const emailsToSend: Promise<unknown>[] = [];
|
||||
|
||||
emailsToSend.push(
|
||||
sendEmail(() => new OrganizerDailyVideoDownloadRecordingEmail(calendarEvent, downloadLink))
|
||||
);
|
||||
|
||||
for (const attendee of calendarEvent.attendees) {
|
||||
emailsToSend.push(
|
||||
sendEmail(() => new AttendeeDailyVideoDownloadRecordingEmail(calendarEvent, attendee, downloadLink))
|
||||
);
|
||||
}
|
||||
await Promise.all(emailsToSend);
|
||||
};
|
||||
|
||||
export const sendDailyVideoTranscriptEmails = async (calEvent: CalendarEvent, transcripts: string[]) => {
|
||||
const emailsToSend: Promise<unknown>[] = [];
|
||||
|
||||
emailsToSend.push(sendEmail(() => new OrganizerDailyVideoDownloadTranscriptEmail(calEvent, transcripts)));
|
||||
|
||||
for (const attendee of calEvent.attendees) {
|
||||
emailsToSend.push(
|
||||
sendEmail(() => new AttendeeDailyVideoDownloadTranscriptEmail(calEvent, attendee, transcripts))
|
||||
);
|
||||
}
|
||||
await Promise.all(emailsToSend);
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
import type BaseEmail from "@calcom/emails/templates/_base-email";
|
||||
|
||||
import type { MonthlyDigestEmailData } from "./src/templates/MonthlyDigestEmail";
|
||||
import type { IBookingRedirect } from "./templates/booking-redirect-notification";
|
||||
import BookingRedirectEmailNotification from "./templates/booking-redirect-notification";
|
||||
import type { Feedback } from "./templates/feedback-email";
|
||||
import FeedbackEmail from "./templates/feedback-email";
|
||||
import MonthlyDigestEmail from "./templates/monthly-digest-email";
|
||||
import type { WorkflowEmailData } from "./templates/workflow-email";
|
||||
import WorkflowEmail from "./templates/workflow-email";
|
||||
|
||||
const sendEmail = (prepare: () => BaseEmail) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const email = prepare();
|
||||
resolve(email.sendEmail());
|
||||
} catch (e) {
|
||||
reject(console.error(`${prepare.constructor.name}.sendEmail failed`, e));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const sendFeedbackEmail = async (feedback: Feedback) => {
|
||||
await sendEmail(() => new FeedbackEmail(feedback));
|
||||
};
|
||||
|
||||
export const sendCustomWorkflowEmail = async (emailData: WorkflowEmailData) => {
|
||||
await sendEmail(() => new WorkflowEmail(emailData));
|
||||
};
|
||||
|
||||
export const sendMonthlyDigestEmail = async (eventData: MonthlyDigestEmailData) => {
|
||||
await sendEmail(() => new MonthlyDigestEmail(eventData));
|
||||
};
|
||||
|
||||
export const sendBookingRedirectNotification = async (bookingRedirect: IBookingRedirect) => {
|
||||
await sendEmail(() => new BookingRedirectEmailNotification(bookingRedirect));
|
||||
};
|
||||
@@ -51,7 +51,7 @@ const passwordResetRequest = async (user: Pick<User, "email" | "name" | "locale"
|
||||
const t = await getTranslation(user.locale ?? "en", "common");
|
||||
await guardAgainstTooManyPasswordResets(email);
|
||||
const resetLink = await createPasswordReset(email);
|
||||
const { sendPasswordResetEmail } = await import("@calcom/emails");
|
||||
const { sendPasswordResetEmail } = await import("@calcom/emails/auth-email-service");
|
||||
|
||||
// send email in user language
|
||||
await sendPasswordResetEmail({
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
sendEmailVerificationCode,
|
||||
sendEmailVerificationLink,
|
||||
sendChangeOfEmailVerificationLink,
|
||||
} from "@calcom/emails/email-manager";
|
||||
} from "@calcom/emails/auth-email-service";
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { sentrySpan } from "@calcom/features/watchlist/lib/telemetry";
|
||||
import { checkIfEmailIsBlockedInWatchlistController } from "@calcom/features/watchlist/operations/check-if-email-in-watchlist.controller";
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
sendOrganizerRequestEmail,
|
||||
sendAttendeeRequestEmailAndSMS,
|
||||
sendAddGuestsEmailsAndSMS,
|
||||
} from "@calcom/emails";
|
||||
} from "@calcom/emails/email-manager";
|
||||
import type { BookingType } from "@calcom/features/bookings/lib/handleNewBooking/originalRescheduledBookingUtils";
|
||||
import type { EventNameObjectType } from "@calcom/features/eventtypes/lib/eventNaming";
|
||||
import { getPiiFreeCalendarEvent } from "@calcom/lib/piiFreeData";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { sendAttendeeRequestEmailAndSMS, sendOrganizerRequestEmail } from "@calcom/emails";
|
||||
import { sendAttendeeRequestEmailAndSMS, sendOrganizerRequestEmail } from "@calcom/emails/email-manager";
|
||||
import { getWebhookPayloadForBooking } from "@calcom/features/bookings/lib/getWebhookPayloadForBooking";
|
||||
import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService";
|
||||
import type { Workflow } from "@calcom/features/ee/workflows/lib/types";
|
||||
|
||||
@@ -4,7 +4,7 @@ import { DailyLocationType } from "@calcom/app-store/constants";
|
||||
import { FAKE_DAILY_CREDENTIAL } from "@calcom/app-store/dailyvideo/lib/VideoApiAdapter";
|
||||
import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { sendCancelledEmailsAndSMS } from "@calcom/emails";
|
||||
import { sendCancelledEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import EventManager from "@calcom/features/bookings/lib/EventManager";
|
||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||
import { processNoShowFeeOnCancellation } from "@calcom/features/bookings/lib/payment/processNoShowFeeOnCancellation";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { eventTypeAppMetadataOptionalSchema } from "@calcom/app-store/zod-utils";
|
||||
import { scheduleMandatoryReminder } from "@calcom/ee/workflows/lib/reminders/scheduleMandatoryReminder";
|
||||
import { sendScheduledEmailsAndSMS } from "@calcom/emails";
|
||||
import { sendScheduledEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import type { EventManagerUser } from "@calcom/features/bookings/lib/EventManager";
|
||||
import EventManager, { placeholderCreatedEvent } from "@calcom/features/bookings/lib/EventManager";
|
||||
import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer";
|
||||
@@ -110,8 +110,6 @@ export async function handleConfirmation(args: {
|
||||
metadata.entryPoints = results[0].createdEvent?.entryPoints;
|
||||
}
|
||||
try {
|
||||
const eventType = booking.eventType;
|
||||
|
||||
let isHostConfirmationEmailsDisabled = false;
|
||||
let isAttendeeConfirmationEmailDisabled = false;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getCalendar } from "@calcom/app-store/_utils/getCalendar";
|
||||
import { getAllDelegationCredentialsForUserIncludeServiceAccountKey } from "@calcom/app-store/delegationCredential";
|
||||
import { getDelegationCredentialOrFindRegularCredential } from "@calcom/app-store/delegationCredential";
|
||||
import { sendCancelledSeatEmailsAndSMS } from "@calcom/emails";
|
||||
import { sendCancelledSeatEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import { updateMeeting } from "@calcom/features/conferencing/lib/videoClient";
|
||||
import { WorkflowRepository } from "@calcom/features/ee/workflows/repositories/WorkflowRepository";
|
||||
import sendPayload from "@calcom/features/webhooks/lib/sendOrSchedulePayload";
|
||||
@@ -116,7 +116,7 @@ async function cancelAttendeeSeat(
|
||||
|
||||
try {
|
||||
await Promise.all(integrationsToUpdate);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Shouldn't stop code execution if integrations fail
|
||||
// as integrations was already updated
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
|
||||
import { cloneDeep } from "lodash";
|
||||
import { uuid } from "short-uuid";
|
||||
|
||||
import { eventTypeAppMetadataOptionalSchema } from "@calcom/app-store/zod-utils";
|
||||
import { sendScheduledSeatsEmailsAndSMS } from "@calcom/emails";
|
||||
import { sendScheduledSeatsEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import { refreshCredentials } from "@calcom/features/bookings/lib/getAllCredentialsForUsersOnEvent/refreshCredentials";
|
||||
import { handlePayment } from "@calcom/features/bookings/lib/handlePayment";
|
||||
import {
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
|
||||
import { cloneDeep } from "lodash";
|
||||
|
||||
import { sendRescheduledSeatEmailAndSMS } from "@calcom/emails";
|
||||
import { sendRescheduledSeatEmailAndSMS } from "@calcom/emails/email-manager";
|
||||
import type EventManager from "@calcom/features/bookings/lib/EventManager";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
|
||||
import { cloneDeep } from "lodash";
|
||||
import { uuid } from "short-uuid";
|
||||
|
||||
import { sendRescheduledEmailsAndSMS } from "@calcom/emails";
|
||||
import { sendRescheduledEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import type EventManager from "@calcom/features/bookings/lib/EventManager";
|
||||
import { ErrorCode } from "@calcom/lib/errorCodes";
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
|
||||
import { cloneDeep } from "lodash";
|
||||
|
||||
import { sendRescheduledEmailsAndSMS } from "@calcom/emails";
|
||||
import { sendRescheduledEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import type EventManager from "@calcom/features/bookings/lib/EventManager";
|
||||
import prisma from "@calcom/prisma";
|
||||
import type { AdditionalInformation, AppsStatus } from "@calcom/types/Calendar";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, it, vi, beforeEach } from "vitest";
|
||||
|
||||
import { PaymentServiceMap } from "@calcom/app-store/payment.services.generated";
|
||||
import { sendNoShowFeeChargedEmail } from "@calcom/emails";
|
||||
import { sendNoShowFeeChargedEmail } from "@calcom/emails/billing-email-service";
|
||||
import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository";
|
||||
import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository";
|
||||
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
|
||||
@@ -21,7 +21,7 @@ vi.mock("@calcom/app-store/payment.services.generated", () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("@calcom/emails", () => ({
|
||||
vi.mock("@calcom/emails/billing-email-service", () => ({
|
||||
sendNoShowFeeChargedEmail: vi.fn(),
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { PaymentServiceMap } from "@calcom/app-store/payment.services.generated";
|
||||
import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { sendNoShowFeeChargedEmail } from "@calcom/emails";
|
||||
import { sendNoShowFeeChargedEmail } from "@calcom/emails/billing-email-service";
|
||||
import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository";
|
||||
import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository";
|
||||
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { sendOrganizerPaymentRefundFailedEmail } from "@calcom/emails";
|
||||
import { sendOrganizerPaymentRefundFailedEmail } from "@calcom/emails/billing-email-service";
|
||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||
|
||||
const handleRefundError = async (opts: { event: CalendarEvent; reason: string; paymentId: string }) => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { v5 as uuidv5 } from "uuid";
|
||||
import { DailyLocationType } from "@calcom/app-store/constants";
|
||||
import { getDailyAppKeys } from "@calcom/app-store/dailyvideo/lib/getDailyAppKeys";
|
||||
import { getVideoAdapters } from "@calcom/app-store/getVideoAdapters";
|
||||
import { sendBrokenIntegrationEmail } from "@calcom/emails";
|
||||
import { sendBrokenIntegrationEmail } from "@calcom/emails/integration-email-service";
|
||||
import { getUid } from "@calcom/lib/CalEventParser";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { getPiiFreeCalendarEvent, getPiiFreeCredential } from "@calcom/lib/piiFreeData";
|
||||
@@ -161,7 +161,7 @@ const createMeetingWithCalVideo = async (calEvent: CalendarEvent) => {
|
||||
let dailyAppKeys: Awaited<ReturnType<typeof getDailyAppKeys>>;
|
||||
try {
|
||||
dailyAppKeys = await getDailyAppKeys();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
const [videoAdapter] = await getVideoAdapters([
|
||||
@@ -184,7 +184,7 @@ export const createInstantMeetingWithCalVideo = async (endTime: string) => {
|
||||
let dailyAppKeys: Awaited<ReturnType<typeof getDailyAppKeys>>;
|
||||
try {
|
||||
dailyAppKeys = await getDailyAppKeys();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
const [videoAdapter] = await getVideoAdapters([
|
||||
@@ -209,7 +209,7 @@ const getRecordingsOfCalVideoByRoomName = async (
|
||||
let dailyAppKeys: Awaited<ReturnType<typeof getDailyAppKeys>>;
|
||||
try {
|
||||
dailyAppKeys = await getDailyAppKeys();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
console.error("Error: Cal video provider is not installed.");
|
||||
return;
|
||||
}
|
||||
@@ -235,7 +235,7 @@ const getDownloadLinkOfCalVideoByRecordingId = async (
|
||||
let dailyAppKeys: Awaited<ReturnType<typeof getDailyAppKeys>>;
|
||||
try {
|
||||
dailyAppKeys = await getDailyAppKeys();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
console.error("Error: Cal video provider is not installed.");
|
||||
return;
|
||||
}
|
||||
@@ -259,7 +259,7 @@ const getAllTranscriptsAccessLinkFromRoomName = async (roomName: string) => {
|
||||
let dailyAppKeys: Awaited<ReturnType<typeof getDailyAppKeys>>;
|
||||
try {
|
||||
dailyAppKeys = await getDailyAppKeys();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
console.error("Error: Cal video provider is not installed.");
|
||||
return;
|
||||
}
|
||||
@@ -283,7 +283,7 @@ const getAllTranscriptsAccessLinkFromMeetingId = async (meetingId: string) => {
|
||||
let dailyAppKeys: Awaited<ReturnType<typeof getDailyAppKeys>>;
|
||||
try {
|
||||
dailyAppKeys = await getDailyAppKeys();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
console.error("Error: Cal video provider is not installed.");
|
||||
return;
|
||||
}
|
||||
@@ -307,7 +307,7 @@ const submitBatchProcessorTranscriptionJob = async (recordingId: string) => {
|
||||
let dailyAppKeys: Awaited<ReturnType<typeof getDailyAppKeys>>;
|
||||
try {
|
||||
dailyAppKeys = await getDailyAppKeys();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
console.error("Error: Cal video provider is not installed.");
|
||||
return;
|
||||
}
|
||||
@@ -343,7 +343,7 @@ const getTranscriptsAccessLinkFromRecordingId = async (recordingId: string) => {
|
||||
let dailyAppKeys: Awaited<ReturnType<typeof getDailyAppKeys>>;
|
||||
try {
|
||||
dailyAppKeys = await getDailyAppKeys();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
console.error("Error: Cal video provider is not installed.");
|
||||
return;
|
||||
}
|
||||
@@ -368,7 +368,7 @@ const checkIfRoomNameMatchesInRecording = async (roomName: string, recordingId:
|
||||
let dailyAppKeys: Awaited<ReturnType<typeof getDailyAppKeys>>;
|
||||
try {
|
||||
dailyAppKeys = await getDailyAppKeys();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
console.error("Error: Cal video provider is not installed.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
eventTypeAppMetadataOptionalSchema,
|
||||
} from "@calcom/app-store/zod-utils";
|
||||
import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils";
|
||||
import { sendCancelledEmailsAndSMS } from "@calcom/emails";
|
||||
import { sendCancelledEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||
import { deletePayment } from "@calcom/features/bookings/lib/payment/deletePayment";
|
||||
import { deleteWebhookScheduledTriggers } from "@calcom/features/webhooks/lib/scheduleTrigger";
|
||||
|
||||
@@ -2,7 +2,7 @@ import Stripe from "stripe";
|
||||
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import * as EmailManager from "@calcom/emails/email-manager";
|
||||
import * as EmailManager from "@calcom/emails/billing-email-service";
|
||||
import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId";
|
||||
import { CreditsRepository } from "@calcom/lib/server/repository/credits";
|
||||
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
|
||||
@@ -70,7 +70,7 @@ vi.mock("@calcom/prisma/enums", async (importOriginal) => {
|
||||
vi.mock("@calcom/lib/server/repository/credits");
|
||||
vi.mock("@calcom/features/membership/repositories/MembershipRepository");
|
||||
vi.mock("@calcom/features/ee/teams/repositories/TeamRepository");
|
||||
vi.mock("@calcom/emails/email-manager", () => ({
|
||||
vi.mock("@calcom/emails/billing-email-service", () => ({
|
||||
sendCreditBalanceLimitReachedEmails: vi.fn().mockResolvedValue(undefined),
|
||||
sendCreditBalanceLowWarningEmails: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
@@ -4,7 +4,7 @@ import dayjs from "@calcom/dayjs";
|
||||
import {
|
||||
sendCreditBalanceLimitReachedEmails,
|
||||
sendCreditBalanceLowWarningEmails,
|
||||
} from "@calcom/emails/email-manager";
|
||||
} from "@calcom/emails/billing-email-service";
|
||||
import { StripeBillingService } from "@calcom/features/ee/billing/stripe-billing-service";
|
||||
import { InternalTeamBilling } from "@calcom/features/ee/billing/teams/internal-team-billing";
|
||||
import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { sendCreditBalanceLimitReachedEmails } from "@calcom/emails/email-manager";
|
||||
import { sendCreditBalanceLimitReachedEmails } from "@calcom/emails/billing-email-service";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import type { CreditUsageType } from "@calcom/prisma/enums";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
|
||||
import type { DeepMockProxy } from "vitest-mock-extended";
|
||||
|
||||
import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils";
|
||||
import { sendSlugReplacementEmail } from "@calcom/emails/email-manager";
|
||||
import { sendSlugReplacementEmail } from "@calcom/emails/integration-email-service";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
@@ -93,7 +93,7 @@ export default async function handleChildrenEventTypes({
|
||||
children,
|
||||
prisma,
|
||||
profileId,
|
||||
updatedValues,
|
||||
updatedValues: _updatedValues,
|
||||
}: handleChildrenEventTypesProps) {
|
||||
// Check we are dealing with a managed event type
|
||||
if (updatedEventType?.schedulingType !== SchedulingType.MANAGED)
|
||||
@@ -222,7 +222,7 @@ export default async function handleChildrenEventTypes({
|
||||
teamName: oldEventType.team?.name || null,
|
||||
});
|
||||
|
||||
const { unlockedFields } = managedEventTypeValues.metadata?.managedEventConfig;
|
||||
const { unlockedFields } = managedEventTypeValues.metadata?.managedEventConfig ?? {};
|
||||
const unlockedFieldProps = !unlockedFields
|
||||
? {}
|
||||
: Object.keys(unlockedFields).reduce((acc, key) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { lookup } from "dns";
|
||||
import { type TFunction } from "i18next";
|
||||
|
||||
import { sendAdminOrganizationNotification } from "@calcom/emails";
|
||||
import { sendAdminOrganizationNotification } from "@calcom/emails/organization-email-service";
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { UserRepository } from "@calcom/features/users/repositories/UserRepository";
|
||||
import {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { TFunction } from "i18next";
|
||||
|
||||
import { sendOrganizationCreationEmail } from "@calcom/emails/email-manager";
|
||||
import { sendOrganizationCreationEmail } from "@calcom/emails/organization-email-service";
|
||||
import { sendEmailVerification } from "@calcom/features/auth/lib/verifyEmail";
|
||||
import { getOrgFullOrigin } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
import {
|
||||
|
||||
@@ -4,7 +4,8 @@ import type Stripe from "stripe";
|
||||
|
||||
import { handlePaymentSuccess } from "@calcom/app-store/_utils/payments/handlePaymentSuccess";
|
||||
import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils";
|
||||
import { sendAttendeeRequestEmailAndSMS, sendOrganizerRequestEmail } from "@calcom/emails";
|
||||
import { sendAttendeeRequestEmailAndSMS, sendOrganizerRequestEmail } from "@calcom/emails/email-manager";
|
||||
import EventManager, { placeholderCreatedEvent } from "@calcom/features/bookings/lib/EventManager";
|
||||
import { doesBookingRequireConfirmation } from "@calcom/features/bookings/lib/doesBookingRequireConfirmation";
|
||||
import { getAllCredentialsIncludeServiceAccountKey } from "@calcom/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials";
|
||||
import { handleConfirmation } from "@calcom/features/bookings/lib/handleConfirmation";
|
||||
@@ -12,7 +13,6 @@ import { getBooking } from "@calcom/features/bookings/lib/payment/getBooking";
|
||||
import stripe from "@calcom/features/ee/payments/server/stripe";
|
||||
import { getPlatformParams } from "@calcom/features/platform-oauth-client/get-platform-params";
|
||||
import { PlatformOAuthClientRepository } from "@calcom/features/platform-oauth-client/platform-oauth-client.repository";
|
||||
import EventManager, { placeholderCreatedEvent } from "@calcom/features/bookings/lib/EventManager";
|
||||
import { IS_PRODUCTION } from "@calcom/lib/constants";
|
||||
import { getErrorFromUnknown } from "@calcom/lib/errors";
|
||||
import { HttpError as HttpCode } from "@calcom/lib/http-error";
|
||||
|
||||
@@ -466,7 +466,7 @@ describe("roundRobinManualReassignment test", () => {
|
||||
await mockEventManagerReschedule();
|
||||
|
||||
const sendRoundRobinReassignedEmailsAndSMSSpy = vi.spyOn(
|
||||
await import("@calcom/emails"),
|
||||
await import("@calcom/emails/email-manager"),
|
||||
"sendRoundRobinReassignedEmailsAndSMS"
|
||||
);
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { cloneDeep } from "lodash";
|
||||
|
||||
|
||||
|
||||
import { enrichUserWithDelegationCredentialsIncludeServiceAccountKey } from "@calcom/app-store/delegationCredential";
|
||||
import { eventTypeAppMetadataOptionalSchema } from "@calcom/app-store/zod-utils";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
@@ -9,16 +7,21 @@ import {
|
||||
sendRoundRobinReassignedEmailsAndSMS,
|
||||
sendRoundRobinScheduledEmailsAndSMS,
|
||||
sendRoundRobinUpdatedEmailsAndSMS,
|
||||
} from "@calcom/emails";
|
||||
} from "@calcom/emails/email-manager";
|
||||
import EventManager from "@calcom/features/bookings/lib/EventManager";
|
||||
import { getAllCredentialsIncludeServiceAccountKey } from "@calcom/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials";
|
||||
import { getBookingResponsesPartialSchema } from "@calcom/features/bookings/lib/getBookingResponsesSchema";
|
||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||
import { getEventTypesFromDB } from "@calcom/features/bookings/lib/handleNewBooking/getEventTypesFromDB";
|
||||
import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer";
|
||||
import AssignmentReasonRecorder, { RRReassignmentType } from "@calcom/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder";
|
||||
import AssignmentReasonRecorder, {
|
||||
RRReassignmentType,
|
||||
} from "@calcom/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder";
|
||||
import { BookingLocationService } from "@calcom/features/ee/round-robin/lib/bookingLocationService";
|
||||
import { scheduleEmailReminder, deleteScheduledEmailReminder } from "@calcom/features/ee/workflows/lib/reminders/emailReminderManager";
|
||||
import {
|
||||
scheduleEmailReminder,
|
||||
deleteScheduledEmailReminder,
|
||||
} from "@calcom/features/ee/workflows/lib/reminders/emailReminderManager";
|
||||
import { scheduleWorkflowReminders } from "@calcom/features/ee/workflows/lib/reminders/reminderScheduler";
|
||||
import { getEventName } from "@calcom/features/eventtypes/lib/eventNaming";
|
||||
import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser";
|
||||
@@ -33,15 +36,12 @@ import { WorkflowActions, WorkflowMethods, WorkflowTriggerEvents } from "@calcom
|
||||
import type { EventTypeMetadata, PlatformClientParams } from "@calcom/prisma/zod-utils";
|
||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||
|
||||
|
||||
|
||||
import { handleRescheduleEventManager } from "./handleRescheduleEventManager";
|
||||
import type { BookingSelectResult } from "./utils/bookingSelect";
|
||||
import { bookingSelect } from "./utils/bookingSelect";
|
||||
import { getDestinationCalendar } from "./utils/getDestinationCalendar";
|
||||
import { getTeamMembers } from "./utils/getTeamMembers";
|
||||
|
||||
|
||||
enum ErrorCode {
|
||||
InvalidRoundRobinHost = "invalid_round_robin_host",
|
||||
UserIsFixed = "user_is_round_robin_fixed",
|
||||
@@ -615,4 +615,4 @@ export async function handleWorkflowsUpdate({
|
||||
});
|
||||
}
|
||||
|
||||
export default roundRobinManualReassignment;
|
||||
export default roundRobinManualReassignment;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { cloneDeep } from "lodash";
|
||||
|
||||
|
||||
|
||||
import {
|
||||
enrichHostsWithDelegationCredentials,
|
||||
enrichUserWithDelegationCredentialsIncludeServiceAccountKey,
|
||||
@@ -13,7 +11,7 @@ import {
|
||||
sendRoundRobinReassignedEmailsAndSMS,
|
||||
sendRoundRobinScheduledEmailsAndSMS,
|
||||
sendRoundRobinUpdatedEmailsAndSMS,
|
||||
} from "@calcom/emails";
|
||||
} from "@calcom/emails/email-manager";
|
||||
import EventManager from "@calcom/features/bookings/lib/EventManager";
|
||||
import { getAllCredentialsIncludeServiceAccountKey } from "@calcom/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials";
|
||||
import { getBookingResponsesPartialSchema } from "@calcom/features/bookings/lib/getBookingResponsesSchema";
|
||||
@@ -519,4 +517,4 @@ export const roundRobinReassignment = async ({
|
||||
};
|
||||
};
|
||||
|
||||
export default roundRobinReassignment;
|
||||
export default roundRobinReassignment;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { sendCustomWorkflowEmail } from "@calcom/emails";
|
||||
import { sendCustomWorkflowEmail } from "@calcom/emails/workflow-email-service";
|
||||
import type { WorkflowEmailData } from "@calcom/emails/templates/workflow-email";
|
||||
import tasker from "@calcom/features/tasker";
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { z } from "zod";
|
||||
|
||||
export type TaskerTypes = "internal" | "redis";
|
||||
type TaskPayloads = {
|
||||
sendEmail: string;
|
||||
sendWebhook: string;
|
||||
sendSms: string;
|
||||
triggerHostNoShowWebhook: z.infer<
|
||||
|
||||
@@ -8,7 +8,6 @@ import type { TaskHandler, TaskTypes } from "../tasker";
|
||||
* The task handlers are imported dynamically to avoid circular dependencies.
|
||||
*/
|
||||
const tasks: Record<TaskTypes, () => Promise<TaskHandler>> = {
|
||||
sendEmail: () => import("./sendEmail").then((module) => module.sendEmail),
|
||||
sendWebhook: () => import("./sendWebook").then((module) => module.sendWebhook),
|
||||
triggerHostNoShowWebhook: () =>
|
||||
import("./triggerNoShow/triggerHostNoShow").then((module) => module.triggerHostNoShow),
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import { z } from "zod";
|
||||
|
||||
const sendEmailPayloadSchema = z.object({
|
||||
/** */
|
||||
to: z.string(),
|
||||
/** The email template to send */
|
||||
template: z.string(),
|
||||
payload: z.string(),
|
||||
});
|
||||
|
||||
export async function sendEmail(payload: string): Promise<void> {
|
||||
try {
|
||||
const parsedPayload = sendEmailPayloadSchema.parse(JSON.parse(payload));
|
||||
console.log(parsedPayload);
|
||||
const emails = await import("@calcom/emails");
|
||||
const email = emails[parsedPayload.template as keyof typeof emails];
|
||||
if (!email) throw new Error("Invalid email template");
|
||||
// @ts-expect-error - TODO bring back email type safety
|
||||
await email(parsedPayload.to);
|
||||
} catch (error) {
|
||||
// ... handle error
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { sendCustomWorkflowEmail } from "@calcom/emails";
|
||||
import { sendCustomWorkflowEmail } from "@calcom/emails/workflow-email-service";
|
||||
|
||||
export const ZSendWorkflowEmailsSchema = z.object({
|
||||
to: z.array(z.string()),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { sendScheduledEmailsAndSMS } from "@calcom/emails";
|
||||
import { sendScheduledEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||
import { scheduleNoShowTriggers } from "@calcom/features/bookings/lib/handleNewBooking/scheduleNoShowTriggers";
|
||||
import { isPrismaObjOrUndefined } from "@calcom/lib/isPrismaObj";
|
||||
@@ -213,7 +213,7 @@ export const Handler = async ({ ctx, input }: Options) => {
|
||||
eventTypeId: eventType?.id,
|
||||
videoCallData,
|
||||
customReplyToEmail: eventType?.customReplyToEmail,
|
||||
team: !!updatedBooking.eventType?.team
|
||||
team: updatedBooking.eventType?.team
|
||||
? {
|
||||
name: updatedBooking.eventType.team.name,
|
||||
id: updatedBooking.eventType.team.id,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { sendPasswordResetEmail } from "@calcom/emails";
|
||||
import { sendPasswordResetEmail } from "@calcom/emails/auth-email-service";
|
||||
import { PASSWORD_RESET_EXPIRY_HOURS } from "@calcom/features/auth/lib/passwordResetRequest";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getLocalAppMetadata } from "@calcom/app-store/utils";
|
||||
import { sendDisabledAppEmail } from "@calcom/emails";
|
||||
import { sendDisabledAppEmail } from "@calcom/emails/integration-email-service";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import { AppCategories } from "@calcom/prisma/enums";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getUsersCredentialsIncludeServiceAccountKey } from "@calcom/app-store/delegationCredential";
|
||||
import type { LocationObject } from "@calcom/app-store/locations";
|
||||
import { getLocationValueForDB } from "@calcom/app-store/locations";
|
||||
import { sendDeclinedEmailsAndSMS } from "@calcom/emails";
|
||||
import { sendDeclinedEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import { getAllCredentialsIncludeServiceAccountKey } from "@calcom/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials";
|
||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||
import { handleConfirmation } from "@calcom/features/bookings/lib/handleConfirmation";
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { z } from "zod";
|
||||
import { getUsersCredentialsIncludeServiceAccountKey } from "@calcom/app-store/delegationCredential";
|
||||
import { getEventLocationType, OrganizerDefaultConferencingAppType } from "@calcom/app-store/locations";
|
||||
import { getAppFromSlug } from "@calcom/app-store/utils";
|
||||
import { sendLocationChangeEmailsAndSMS } from "@calcom/emails";
|
||||
import { sendLocationChangeEmailsAndSMS } from "@calcom/emails/email-manager";
|
||||
import EventManager from "@calcom/features/bookings/lib/EventManager";
|
||||
import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository";
|
||||
import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository";
|
||||
|
||||
@@ -4,7 +4,7 @@ import { getCalendar } from "@calcom/app-store/_utils/getCalendar";
|
||||
import { getDelegationCredentialOrRegularCredential } from "@calcom/app-store/delegationCredential";
|
||||
import { getUsersCredentialsIncludeServiceAccountKey } from "@calcom/app-store/delegationCredential";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails";
|
||||
import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails/email-manager";
|
||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||
import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient";
|
||||
import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer";
|
||||
@@ -220,7 +220,9 @@ export const requestRescheduleHandler = async ({ ctx, input }: RequestReschedule
|
||||
const director = new CalendarEventDirector();
|
||||
director.setBuilder(builder);
|
||||
director.setExistingBooking(bookingToReschedule);
|
||||
cancellationReason && director.setCancellationReason(cancellationReason);
|
||||
if (cancellationReason) {
|
||||
director.setCancellationReason(cancellationReason);
|
||||
}
|
||||
if (Object.keys(event).length) {
|
||||
// Request Reschedule flow first cancels the booking and then reschedule email is sent. So, we need to allow reschedule for cancelled booking
|
||||
await director.buildForRescheduleEmail({ allowRescheduleForCancelledBooking: true });
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { z } from "zod";
|
||||
|
||||
import { checkIfSuccessfullyConfiguredInWorkspace } from "@calcom/app-store/delegationCredential";
|
||||
import { sendDelegationCredentialDisabledEmail } from "@calcom/emails/email-manager";
|
||||
import { sendDelegationCredentialDisabledEmail } from "@calcom/emails/integration-email-service";
|
||||
import { DelegationCredentialRepository } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository";
|
||||
import type { ServiceAccountKey } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository";
|
||||
import logger from "@calcom/lib/logger";
|
||||
|
||||
@@ -2,7 +2,7 @@ import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
import { selectOOOEntries } from "@calcom/app-store/zapier/api/subscriptions/listOOOEntries";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { sendBookingRedirectNotification } from "@calcom/emails";
|
||||
import { sendBookingRedirectNotification } from "@calcom/emails/workflow-email-service";
|
||||
import type { GetSubscriberOptions } from "@calcom/features/webhooks/lib/getWebhooks";
|
||||
import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks";
|
||||
import type { OOOEntryPayloadType } from "@calcom/features/webhooks/lib/sendPayload";
|
||||
@@ -47,7 +47,7 @@ export const outOfOfficeCreateOrUpdate = async ({ ctx, input }: TBookingRedirect
|
||||
let oooUserFullName = ctx.user.name;
|
||||
|
||||
let isAdmin;
|
||||
if (!!input.forUserId) {
|
||||
if (input.forUserId) {
|
||||
isAdmin = await isAdminForUser(ctx.user.id, input.forUserId);
|
||||
if (!isAdmin) {
|
||||
throw new TRPCError({ code: "NOT_FOUND", message: "only_admin_can_create_ooo" });
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { sendBookingRedirectNotification } from "@calcom/emails";
|
||||
import { sendBookingRedirectNotification } from "@calcom/emails/workflow-email-service";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import prisma from "@calcom/prisma";
|
||||
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
|
||||
|
||||
@@ -2,7 +2,7 @@ import { lookup } from "dns";
|
||||
|
||||
import { getOrgFullOrigin } from "@calcom/ee/organizations/lib/orgDomains";
|
||||
import { isNotACompanyEmail } from "@calcom/ee/organizations/lib/server/orgCreationUtils";
|
||||
import { sendAdminOrganizationNotification, sendOrganizationCreationEmail } from "@calcom/emails";
|
||||
import { sendAdminOrganizationNotification, sendOrganizationCreationEmail } from "@calcom/emails/organization-email-service";
|
||||
import { sendEmailVerification } from "@calcom/features/auth/lib/verifyEmail";
|
||||
import { getOrganizationRepository } from "@calcom/features/ee/organizations/di/OrganizationRepository.container";
|
||||
import { UserRepository } from "@calcom/features/users/repositories/UserRepository";
|
||||
|
||||
@@ -4,7 +4,7 @@ import prismaMock from "../../../../../../tests/libs/__mocks__/prismaMock";
|
||||
import { vi, describe, it, beforeAll, afterAll, expect, beforeEach, afterEach } from "vitest";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import * as CalcomEmails from "@calcom/emails";
|
||||
import * as CalcomEmails from "@calcom/emails/organization-email-service";
|
||||
import { getNoSlotsNotificationService } from "@calcom/features/di/containers/NoSlotsNotification";
|
||||
import { RedisService } from "@calcom/features/redis/RedisService";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Dayjs } from "@calcom/dayjs";
|
||||
import { sendOrganizationAdminNoSlotsNotification } from "@calcom/emails";
|
||||
import { sendOrganizationAdminNoSlotsNotification } from "@calcom/emails/organization-email-service";
|
||||
import type { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository";
|
||||
import type { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
|
||||
import type { IRedisService } from "@calcom/features/redis/IRedisService";
|
||||
|
||||
+3
-8
@@ -30,8 +30,6 @@ async function verifyMembershipExists(userId: number, teamId: number): Promise<M
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Test data creation helpers with unique identifiers
|
||||
function generateUniqueId() {
|
||||
return `${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
||||
@@ -120,7 +118,7 @@ vi.mock("node-fetch", () => ({
|
||||
}));
|
||||
|
||||
// Mock email sending
|
||||
vi.mock("@calcom/emails", () => ({
|
||||
vi.mock("@calcom/emails/organization-email-service", () => ({
|
||||
sendTeamInviteEmail: vi.fn(() => Promise.resolve()),
|
||||
sendOrganizationAutoJoinEmail: vi.fn(() => Promise.resolve()),
|
||||
}));
|
||||
@@ -401,10 +399,7 @@ describe("inviteMember.handler Integration Tests", () => {
|
||||
],
|
||||
});
|
||||
|
||||
await verifyMembershipExists(
|
||||
unverifiedUserWithUnacceptedMembership.id,
|
||||
organization.id
|
||||
);
|
||||
await verifyMembershipExists(unverifiedUserWithUnacceptedMembership.id, organization.id);
|
||||
const profile = await verifyProfileExists(unverifiedUserWithUnacceptedMembership.id, organization.id);
|
||||
|
||||
expect(profile?.userId).toBe(unverifiedUserWithUnacceptedMembership.id);
|
||||
@@ -503,7 +498,7 @@ describe("inviteMember.handler Integration Tests", () => {
|
||||
where: { email: newUserEmail },
|
||||
});
|
||||
expect(createdUser).toBeTruthy();
|
||||
|
||||
|
||||
if (createdUser) {
|
||||
trackUser(createdUser);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { randomBytes } from "crypto";
|
||||
import type { TFunction } from "i18next";
|
||||
|
||||
import { getOrgFullOrigin } from "@calcom/ee/organizations/lib/orgDomains";
|
||||
import { sendTeamInviteEmail } from "@calcom/emails";
|
||||
import { sendTeamInviteEmail } from "@calcom/emails/organization-email-service";
|
||||
import { checkAdminOrOwner } from "@calcom/features/auth/lib/checkAdminOrOwner";
|
||||
import { updateNewTeamMemberEventTypes } from "@calcom/features/ee/teams/lib/queries";
|
||||
import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { sendTeamInviteEmail } from "@calcom/emails";
|
||||
import { sendTeamInviteEmail } from "@calcom/emails/organization-email-service";
|
||||
import { UserRepository } from "@calcom/features/users/repositories/UserRepository";
|
||||
import { OnboardingPathService } from "@calcom/features/onboarding/lib/onboarding-path.service";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
|
||||
+6
-5
@@ -2,6 +2,7 @@ import matchers from "@testing-library/jest-dom/matchers";
|
||||
import ResizeObserver from "resize-observer-polyfill";
|
||||
import { vi, expect } from "vitest";
|
||||
import createFetchMock from "vitest-fetch-mock";
|
||||
|
||||
import type { CalendarService } from "@calcom/types/Calendar";
|
||||
|
||||
global.ResizeObserver = ResizeObserver;
|
||||
@@ -61,9 +62,9 @@ class MockPaymentService {
|
||||
constructor(credentials?: any) {
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
|
||||
private credentials: any;
|
||||
|
||||
|
||||
async create(
|
||||
payment: any,
|
||||
bookingId: number,
|
||||
@@ -78,7 +79,7 @@ class MockPaymentService {
|
||||
) {
|
||||
const { default: prismaMock } = await import("./tests/libs/__mocks__/prisma");
|
||||
const externalId = "mock_payment_external_id";
|
||||
|
||||
|
||||
const paymentCreateData = {
|
||||
uid: MOCK_PAYMENT_UID,
|
||||
appId: null,
|
||||
@@ -96,7 +97,7 @@ class MockPaymentService {
|
||||
const createdPayment = await prismaMock.payment.create({
|
||||
data: paymentCreateData,
|
||||
});
|
||||
|
||||
|
||||
return createdPayment;
|
||||
}
|
||||
async collectCard() {
|
||||
@@ -112,7 +113,7 @@ class MockPaymentService {
|
||||
return { success: true };
|
||||
}
|
||||
async afterPayment(event: any, booking: any, paymentData: any) {
|
||||
const { sendAwaitingPaymentEmailAndSMS } = await import("@calcom/emails");
|
||||
const { sendAwaitingPaymentEmailAndSMS } = await import("@calcom/emails/email-manager");
|
||||
await sendAwaitingPaymentEmailAndSMS({
|
||||
...event,
|
||||
paymentInfo: {
|
||||
|
||||
Reference in New Issue
Block a user