feat: dynamic time format rendering in workflows based on user settings (#10229)
This commit is contained in:
parent
1ad4f7247e
commit
26e458be6d
|
@ -22,6 +22,7 @@ import { HttpError } from "@calcom/lib/http-error";
|
||||||
import logger from "@calcom/lib/logger";
|
import logger from "@calcom/lib/logger";
|
||||||
import { handleRefundError } from "@calcom/lib/payment/handleRefundError";
|
import { handleRefundError } from "@calcom/lib/payment/handleRefundError";
|
||||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||||
|
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import prisma, { bookingMinimalSelect } from "@calcom/prisma";
|
import prisma, { bookingMinimalSelect } from "@calcom/prisma";
|
||||||
import { BookingStatus, MembershipRole, WorkflowMethods, WebhookTriggerEvents } from "@calcom/prisma/enums";
|
import { BookingStatus, MembershipRole, WorkflowMethods, WebhookTriggerEvents } from "@calcom/prisma/enums";
|
||||||
import { schemaBookingCancelParams } from "@calcom/prisma/zod-utils";
|
import { schemaBookingCancelParams } from "@calcom/prisma/zod-utils";
|
||||||
|
@ -44,6 +45,7 @@ async function getBookingToDelete(id: number | undefined, uid: string | undefine
|
||||||
credentials: true, // Not leaking at the moment, be careful with
|
credentials: true, // Not leaking at the moment, be careful with
|
||||||
email: true,
|
email: true,
|
||||||
timeZone: true,
|
timeZone: true,
|
||||||
|
timeFormat: true,
|
||||||
name: true,
|
name: true,
|
||||||
destinationCalendar: true,
|
destinationCalendar: true,
|
||||||
},
|
},
|
||||||
|
@ -154,6 +156,7 @@ async function handler(req: CustomRequest) {
|
||||||
name: true,
|
name: true,
|
||||||
email: true,
|
email: true,
|
||||||
timeZone: true,
|
timeZone: true,
|
||||||
|
timeFormat: true,
|
||||||
locale: true,
|
locale: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -207,6 +210,7 @@ async function handler(req: CustomRequest) {
|
||||||
email: organizer.email,
|
email: organizer.email,
|
||||||
name: organizer.name ?? "Nameless",
|
name: organizer.name ?? "Nameless",
|
||||||
timeZone: organizer.timeZone,
|
timeZone: organizer.timeZone,
|
||||||
|
timeFormat: getTimeFormatStringFromUserTimeFormat(organizer.timeFormat),
|
||||||
language: { translate: tOrganizer, locale: organizer.locale ?? "en" },
|
language: { translate: tOrganizer, locale: organizer.locale ?? "en" },
|
||||||
},
|
},
|
||||||
attendees: attendeesList,
|
attendees: attendeesList,
|
||||||
|
@ -540,6 +544,7 @@ async function handler(req: CustomRequest) {
|
||||||
email: bookingToDelete.user?.email ?? "dev@calendso.com",
|
email: bookingToDelete.user?.email ?? "dev@calendso.com",
|
||||||
name: bookingToDelete.user?.name ?? "no user",
|
name: bookingToDelete.user?.name ?? "no user",
|
||||||
timeZone: bookingToDelete.user?.timeZone ?? "",
|
timeZone: bookingToDelete.user?.timeZone ?? "",
|
||||||
|
timeFormat: getTimeFormatStringFromUserTimeFormat(organizer.timeFormat),
|
||||||
language: { translate: tOrganizer, locale: organizer.locale ?? "en" },
|
language: { translate: tOrganizer, locale: organizer.locale ?? "en" },
|
||||||
},
|
},
|
||||||
attendees: attendeesList,
|
attendees: attendeesList,
|
||||||
|
|
|
@ -60,7 +60,7 @@ import { getBookerUrl } from "@calcom/lib/server/getBookerUrl";
|
||||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||||
import { slugify } from "@calcom/lib/slugify";
|
import { slugify } from "@calcom/lib/slugify";
|
||||||
import { updateWebUser as syncServicesUpdateWebUser } from "@calcom/lib/sync/SyncServiceManager";
|
import { updateWebUser as syncServicesUpdateWebUser } from "@calcom/lib/sync/SyncServiceManager";
|
||||||
import { TimeFormat } from "@calcom/lib/timeFormat";
|
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import prisma, { userSelect } from "@calcom/prisma";
|
import prisma, { userSelect } from "@calcom/prisma";
|
||||||
import type { BookingReference } from "@calcom/prisma/client";
|
import type { BookingReference } from "@calcom/prisma/client";
|
||||||
import { BookingStatus, SchedulingType, WebhookTriggerEvents, WorkflowMethods } from "@calcom/prisma/enums";
|
import { BookingStatus, SchedulingType, WebhookTriggerEvents, WorkflowMethods } from "@calcom/prisma/enums";
|
||||||
|
@ -1027,7 +1027,7 @@ async function handler(
|
||||||
username: organizerUser.username || undefined,
|
username: organizerUser.username || undefined,
|
||||||
timeZone: organizerUser.timeZone,
|
timeZone: organizerUser.timeZone,
|
||||||
language: { translate: tOrganizer, locale: organizerUser.locale ?? "en" },
|
language: { translate: tOrganizer, locale: organizerUser.locale ?? "en" },
|
||||||
timeFormat: organizerUser.timeFormat === 24 ? TimeFormat.TWENTY_FOUR_HOUR : TimeFormat.TWELVE_HOUR,
|
timeFormat: getTimeFormatStringFromUserTimeFormat(organizerUser.timeFormat),
|
||||||
},
|
},
|
||||||
responses: "calEventResponses" in reqBody ? reqBody.calEventResponses : null,
|
responses: "calEventResponses" in reqBody ? reqBody.calEventResponses : null,
|
||||||
userFieldsResponses: calEventUserFieldsResponses,
|
userFieldsResponses: calEventUserFieldsResponses,
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { IS_PRODUCTION } from "@calcom/lib/constants";
|
||||||
import { getErrorFromUnknown } from "@calcom/lib/errors";
|
import { getErrorFromUnknown } from "@calcom/lib/errors";
|
||||||
import { HttpError as HttpCode } from "@calcom/lib/http-error";
|
import { HttpError as HttpCode } from "@calcom/lib/http-error";
|
||||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||||
|
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import { prisma, bookingMinimalSelect } from "@calcom/prisma";
|
import { prisma, bookingMinimalSelect } from "@calcom/prisma";
|
||||||
import { BookingStatus } from "@calcom/prisma/enums";
|
import { BookingStatus } from "@calcom/prisma/enums";
|
||||||
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
||||||
|
@ -59,6 +60,7 @@ async function getBooking(bookingId: number) {
|
||||||
id: true,
|
id: true,
|
||||||
username: true,
|
username: true,
|
||||||
timeZone: true,
|
timeZone: true,
|
||||||
|
timeFormat: true,
|
||||||
email: true,
|
email: true,
|
||||||
name: true,
|
name: true,
|
||||||
locale: true,
|
locale: true,
|
||||||
|
@ -108,6 +110,7 @@ async function getBooking(bookingId: number) {
|
||||||
email: user.email,
|
email: user.email,
|
||||||
name: user.name!,
|
name: user.name!,
|
||||||
timeZone: user.timeZone,
|
timeZone: user.timeZone,
|
||||||
|
timeFormat: getTimeFormatStringFromUserTimeFormat(user.timeFormat),
|
||||||
language: { translate: t, locale: user.locale ?? "en" },
|
language: { translate: t, locale: user.locale ?? "en" },
|
||||||
id: user.id,
|
id: user.id,
|
||||||
},
|
},
|
||||||
|
@ -163,6 +166,7 @@ async function handlePaymentSuccess(event: Stripe.Event) {
|
||||||
username: true,
|
username: true,
|
||||||
credentials: true,
|
credentials: true,
|
||||||
timeZone: true,
|
timeZone: true,
|
||||||
|
timeFormat: true,
|
||||||
email: true,
|
email: true,
|
||||||
name: true,
|
name: true,
|
||||||
locale: true,
|
locale: true,
|
||||||
|
@ -216,6 +220,7 @@ async function handlePaymentSuccess(event: Stripe.Event) {
|
||||||
email: user.email,
|
email: user.email,
|
||||||
name: user.name!,
|
name: user.name!,
|
||||||
timeZone: user.timeZone,
|
timeZone: user.timeZone,
|
||||||
|
timeFormat: getTimeFormatStringFromUserTimeFormat(user.timeFormat),
|
||||||
language: { translate: t, locale: user.locale ?? "en" },
|
language: { translate: t, locale: user.locale ?? "en" },
|
||||||
},
|
},
|
||||||
attendees: attendeesList,
|
attendees: attendeesList,
|
||||||
|
|
|
@ -6,6 +6,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||||
import { defaultHandler } from "@calcom/lib/server";
|
import { defaultHandler } from "@calcom/lib/server";
|
||||||
|
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
import { WorkflowActions, WorkflowMethods, WorkflowTemplates } from "@calcom/prisma/enums";
|
import { WorkflowActions, WorkflowMethods, WorkflowTemplates } from "@calcom/prisma/enums";
|
||||||
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
|
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
|
||||||
|
@ -196,6 +197,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
reminder.workflowStep.emailSubject || "",
|
reminder.workflowStep.emailSubject || "",
|
||||||
variables,
|
variables,
|
||||||
emailLocale,
|
emailLocale,
|
||||||
|
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
|
||||||
!!reminder.booking.user?.hideBranding
|
!!reminder.booking.user?.hideBranding
|
||||||
).text;
|
).text;
|
||||||
emailContent.emailSubject = emailSubject;
|
emailContent.emailSubject = emailSubject;
|
||||||
|
@ -203,15 +205,22 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
reminder.workflowStep.reminderBody || "",
|
reminder.workflowStep.reminderBody || "",
|
||||||
variables,
|
variables,
|
||||||
emailLocale,
|
emailLocale,
|
||||||
|
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
|
||||||
!!reminder.booking.user?.hideBranding
|
!!reminder.booking.user?.hideBranding
|
||||||
).html;
|
).html;
|
||||||
|
|
||||||
emailBodyEmpty =
|
emailBodyEmpty =
|
||||||
customTemplate(reminder.workflowStep.reminderBody || "", variables, emailLocale).text.length === 0;
|
customTemplate(
|
||||||
|
reminder.workflowStep.reminderBody || "",
|
||||||
|
variables,
|
||||||
|
emailLocale,
|
||||||
|
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat)
|
||||||
|
).text.length === 0;
|
||||||
} else if (reminder.workflowStep.template === WorkflowTemplates.REMINDER) {
|
} else if (reminder.workflowStep.template === WorkflowTemplates.REMINDER) {
|
||||||
emailContent = emailReminderTemplate(
|
emailContent = emailReminderTemplate(
|
||||||
false,
|
false,
|
||||||
reminder.workflowStep.action,
|
reminder.workflowStep.action,
|
||||||
|
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
|
||||||
reminder.booking.startTime.toISOString() || "",
|
reminder.booking.startTime.toISOString() || "",
|
||||||
reminder.booking.endTime.toISOString() || "",
|
reminder.booking.endTime.toISOString() || "",
|
||||||
reminder.booking.eventType?.title || "",
|
reminder.booking.eventType?.title || "",
|
||||||
|
|
|
@ -4,6 +4,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
|
||||||
import { defaultHandler } from "@calcom/lib/server";
|
import { defaultHandler } from "@calcom/lib/server";
|
||||||
|
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
import { WorkflowActions, WorkflowMethods, WorkflowTemplates } from "@calcom/prisma/enums";
|
import { WorkflowActions, WorkflowMethods, WorkflowTemplates } from "@calcom/prisma/enums";
|
||||||
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
|
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
|
||||||
|
@ -116,13 +117,15 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
const customMessage = customTemplate(
|
const customMessage = customTemplate(
|
||||||
reminder.workflowStep.reminderBody || "",
|
reminder.workflowStep.reminderBody || "",
|
||||||
variables,
|
variables,
|
||||||
locale || "en"
|
locale || "en",
|
||||||
|
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat)
|
||||||
);
|
);
|
||||||
message = customMessage.text;
|
message = customMessage.text;
|
||||||
} else if (reminder.workflowStep.template === WorkflowTemplates.REMINDER) {
|
} else if (reminder.workflowStep.template === WorkflowTemplates.REMINDER) {
|
||||||
message = smsReminderTemplate(
|
message = smsReminderTemplate(
|
||||||
false,
|
false,
|
||||||
reminder.workflowStep.action,
|
reminder.workflowStep.action,
|
||||||
|
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
|
||||||
reminder.booking?.startTime.toISOString() || "",
|
reminder.booking?.startTime.toISOString() || "",
|
||||||
reminder.booking?.eventType?.title || "",
|
reminder.booking?.eventType?.title || "",
|
||||||
timeZone || "",
|
timeZone || "",
|
||||||
|
|
|
@ -4,6 +4,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
import { defaultHandler } from "@calcom/lib/server";
|
import { defaultHandler } from "@calcom/lib/server";
|
||||||
|
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
|
|
||||||
import { getWhatsappTemplateFunction } from "../lib/actionHelperFunctions";
|
import { getWhatsappTemplateFunction } from "../lib/actionHelperFunctions";
|
||||||
|
@ -81,6 +82,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
const message = templateFunction(
|
const message = templateFunction(
|
||||||
false,
|
false,
|
||||||
reminder.workflowStep.action,
|
reminder.workflowStep.action,
|
||||||
|
getTimeFormatStringFromUserTimeFormat(reminder.booking.user?.timeFormat),
|
||||||
reminder.booking?.startTime.toISOString() || "",
|
reminder.booking?.startTime.toISOString() || "",
|
||||||
reminder.booking?.eventType?.title || "",
|
reminder.booking?.eventType?.title || "",
|
||||||
timeZone || "",
|
timeZone || "",
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import { WorkflowTemplates } from "@calcom/prisma/enums";
|
import { WorkflowTemplates } from "@calcom/prisma/enums";
|
||||||
import type { WorkflowActions } from "@calcom/prisma/enums";
|
import type { WorkflowActions } from "@calcom/prisma/enums";
|
||||||
import { trpc } from "@calcom/trpc/react";
|
import { trpc } from "@calcom/trpc/react";
|
||||||
|
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||||
import type { MultiSelectCheckboxesOptionType as Option } from "@calcom/ui";
|
import type { MultiSelectCheckboxesOptionType as Option } from "@calcom/ui";
|
||||||
import { Button, Label, MultiSelectCheckboxes, TextField } from "@calcom/ui";
|
import { Button, Label, MultiSelectCheckboxes, TextField } from "@calcom/ui";
|
||||||
import { ArrowDown, Trash2 } from "@calcom/ui/components/icon";
|
import { ArrowDown, Trash2 } from "@calcom/ui/components/icon";
|
||||||
|
@ -19,12 +20,15 @@ import { AddActionDialog } from "./AddActionDialog";
|
||||||
import { DeleteDialog } from "./DeleteDialog";
|
import { DeleteDialog } from "./DeleteDialog";
|
||||||
import WorkflowStepContainer from "./WorkflowStepContainer";
|
import WorkflowStepContainer from "./WorkflowStepContainer";
|
||||||
|
|
||||||
|
type User = RouterOutputs["viewer"]["me"];
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
form: UseFormReturn<FormValues>;
|
form: UseFormReturn<FormValues>;
|
||||||
workflowId: number;
|
workflowId: number;
|
||||||
selectedEventTypes: Option[];
|
selectedEventTypes: Option[];
|
||||||
setSelectedEventTypes: Dispatch<SetStateAction<Option[]>>;
|
setSelectedEventTypes: Dispatch<SetStateAction<Option[]>>;
|
||||||
teamId?: number;
|
teamId?: number;
|
||||||
|
user: User;
|
||||||
isMixedEventType: boolean;
|
isMixedEventType: boolean;
|
||||||
readOnly: boolean;
|
readOnly: boolean;
|
||||||
}
|
}
|
||||||
|
@ -158,7 +162,7 @@ export default function WorkflowDetailsPage(props: Props) {
|
||||||
<div className="bg-muted border-subtle w-full rounded-md border p-3 py-5 md:ml-3 md:p-8">
|
<div className="bg-muted border-subtle w-full rounded-md border p-3 py-5 md:ml-3 md:p-8">
|
||||||
{form.getValues("trigger") && (
|
{form.getValues("trigger") && (
|
||||||
<div>
|
<div>
|
||||||
<WorkflowStepContainer form={form} teamId={teamId} readOnly={props.readOnly} />
|
<WorkflowStepContainer form={form} user={props.user} teamId={teamId} readOnly={props.readOnly} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{form.getValues("steps") && (
|
{form.getValues("steps") && (
|
||||||
|
@ -168,6 +172,7 @@ export default function WorkflowDetailsPage(props: Props) {
|
||||||
<WorkflowStepContainer
|
<WorkflowStepContainer
|
||||||
key={step.id}
|
key={step.id}
|
||||||
form={form}
|
form={form}
|
||||||
|
user={props.user}
|
||||||
step={step}
|
step={step}
|
||||||
reload={reload}
|
reload={reload}
|
||||||
setReload={setReload}
|
setReload={setReload}
|
||||||
|
|
|
@ -9,9 +9,11 @@ import { classNames } from "@calcom/lib";
|
||||||
import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
|
import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import { HttpError } from "@calcom/lib/http-error";
|
import { HttpError } from "@calcom/lib/http-error";
|
||||||
|
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import { WorkflowTemplates, TimeUnit, WorkflowActions } from "@calcom/prisma/enums";
|
import { WorkflowTemplates, TimeUnit, WorkflowActions } from "@calcom/prisma/enums";
|
||||||
import { WorkflowTriggerEvents } from "@calcom/prisma/enums";
|
import { WorkflowTriggerEvents } from "@calcom/prisma/enums";
|
||||||
import { trpc } from "@calcom/trpc/react";
|
import { trpc } from "@calcom/trpc/react";
|
||||||
|
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||||
import {
|
import {
|
||||||
Badge,
|
Badge,
|
||||||
Button,
|
Button,
|
||||||
|
@ -54,9 +56,12 @@ import { whatsappReminderTemplate } from "../lib/reminders/templates/whatsapp";
|
||||||
import type { FormValues } from "../pages/workflow";
|
import type { FormValues } from "../pages/workflow";
|
||||||
import { TimeTimeUnitInput } from "./TimeTimeUnitInput";
|
import { TimeTimeUnitInput } from "./TimeTimeUnitInput";
|
||||||
|
|
||||||
|
type User = RouterOutputs["viewer"]["me"];
|
||||||
|
|
||||||
type WorkflowStepProps = {
|
type WorkflowStepProps = {
|
||||||
step?: WorkflowStep;
|
step?: WorkflowStep;
|
||||||
form: UseFormReturn<FormValues>;
|
form: UseFormReturn<FormValues>;
|
||||||
|
user: User;
|
||||||
reload?: boolean;
|
reload?: boolean;
|
||||||
setReload?: Dispatch<SetStateAction<boolean>>;
|
setReload?: Dispatch<SetStateAction<boolean>>;
|
||||||
teamId?: number;
|
teamId?: number;
|
||||||
|
@ -72,6 +77,9 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||||
{ teamId },
|
{ teamId },
|
||||||
{ enabled: !!teamId }
|
{ enabled: !!teamId }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const timeFormat = getTimeFormatStringFromUserTimeFormat(props.user.timeFormat);
|
||||||
|
|
||||||
const verifiedNumbers = _verifiedNumbers?.map((number) => number.phoneNumber) || [];
|
const verifiedNumbers = _verifiedNumbers?.map((number) => number.phoneNumber) || [];
|
||||||
const [isAdditionalInputsDialogOpen, setIsAdditionalInputsDialogOpen] = useState(false);
|
const [isAdditionalInputsDialogOpen, setIsAdditionalInputsDialogOpen] = useState(false);
|
||||||
|
|
||||||
|
@ -118,23 +126,30 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||||
if (!form.getValues(`steps.${step.stepNumber - 1}.reminderBody`)) {
|
if (!form.getValues(`steps.${step.stepNumber - 1}.reminderBody`)) {
|
||||||
const action = form.getValues(`steps.${step.stepNumber - 1}.action`);
|
const action = form.getValues(`steps.${step.stepNumber - 1}.action`);
|
||||||
if (isSMSAction(action)) {
|
if (isSMSAction(action)) {
|
||||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, smsReminderTemplate(true, action));
|
form.setValue(
|
||||||
|
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||||
|
smsReminderTemplate(true, action, timeFormat)
|
||||||
|
);
|
||||||
} else if (isWhatsappAction(action)) {
|
} else if (isWhatsappAction(action)) {
|
||||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, whatsappReminderTemplate(true, action));
|
form.setValue(
|
||||||
|
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||||
|
whatsappReminderTemplate(true, action, timeFormat)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
const reminderBodyTemplate = emailReminderTemplate(true, action).emailBody;
|
const reminderBodyTemplate = emailReminderTemplate(true, action, timeFormat).emailBody;
|
||||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, reminderBodyTemplate);
|
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, reminderBodyTemplate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!form.getValues(`steps.${step.stepNumber - 1}.emailSubject`)) {
|
if (!form.getValues(`steps.${step.stepNumber - 1}.emailSubject`)) {
|
||||||
const subjectTemplate = emailReminderTemplate(
|
const subjectTemplate = emailReminderTemplate(
|
||||||
true,
|
true,
|
||||||
form.getValues(`steps.${step.stepNumber - 1}.action`)
|
form.getValues(`steps.${step.stepNumber - 1}.action`),
|
||||||
|
timeFormat
|
||||||
).emailSubject;
|
).emailSubject;
|
||||||
form.setValue(`steps.${step.stepNumber - 1}.emailSubject`, subjectTemplate);
|
form.setValue(`steps.${step.stepNumber - 1}.emailSubject`, subjectTemplate);
|
||||||
}
|
}
|
||||||
} else if (step && isWhatsappAction(step.action)) {
|
} else if (step && isWhatsappAction(step.action)) {
|
||||||
const templateBody = getWhatsappTemplateForAction(step.action, step.template);
|
const templateBody = getWhatsappTemplateForAction(step.action, step.template, timeFormat);
|
||||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, templateBody);
|
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, templateBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,15 +478,19 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||||
if (isSMSAction(val.value)) {
|
if (isSMSAction(val.value)) {
|
||||||
form.setValue(
|
form.setValue(
|
||||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||||
smsReminderTemplate(true, val.value)
|
smsReminderTemplate(true, val.value, timeFormat)
|
||||||
);
|
);
|
||||||
} else if (isWhatsappAction(val.value)) {
|
} else if (isWhatsappAction(val.value)) {
|
||||||
form.setValue(
|
form.setValue(
|
||||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||||
whatsappReminderTemplate(true, val.value)
|
whatsappReminderTemplate(true, val.value, timeFormat)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const emailReminderBody = emailReminderTemplate(true, val.value);
|
const emailReminderBody = emailReminderTemplate(
|
||||||
|
true,
|
||||||
|
val.value,
|
||||||
|
timeFormat
|
||||||
|
);
|
||||||
form.setValue(
|
form.setValue(
|
||||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||||
emailReminderBody.emailBody
|
emailReminderBody.emailBody
|
||||||
|
@ -680,28 +699,28 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||||
if (isWhatsappAction(action)) {
|
if (isWhatsappAction(action)) {
|
||||||
form.setValue(
|
form.setValue(
|
||||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||||
whatsappReminderTemplate(true, action)
|
whatsappReminderTemplate(true, action, timeFormat)
|
||||||
);
|
);
|
||||||
} else if (isSMSAction(action)) {
|
} else if (isSMSAction(action)) {
|
||||||
form.setValue(
|
form.setValue(
|
||||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||||
smsReminderTemplate(true, action)
|
smsReminderTemplate(true, action, timeFormat)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
form.setValue(
|
form.setValue(
|
||||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||||
emailReminderTemplate(true, action).emailBody
|
emailReminderTemplate(true, action, timeFormat).emailBody
|
||||||
);
|
);
|
||||||
form.setValue(
|
form.setValue(
|
||||||
`steps.${step.stepNumber - 1}.emailSubject`,
|
`steps.${step.stepNumber - 1}.emailSubject`,
|
||||||
emailReminderTemplate(true, action).emailSubject
|
emailReminderTemplate(true, action, timeFormat).emailSubject
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isWhatsappAction(action)) {
|
if (isWhatsappAction(action)) {
|
||||||
form.setValue(
|
form.setValue(
|
||||||
`steps.${step.stepNumber - 1}.reminderBody`,
|
`steps.${step.stepNumber - 1}.reminderBody`,
|
||||||
getWhatsappTemplateForAction(action, val.value)
|
getWhatsappTemplateForAction(action, val.value, timeFormat)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, "");
|
form.setValue(`steps.${step.stepNumber - 1}.reminderBody`, "");
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import { WorkflowActions, WorkflowTemplates, WorkflowTriggerEvents } from "@prisma/client";
|
import type { WorkflowTriggerEvents } from "@prisma/client";
|
||||||
|
import { WorkflowActions, WorkflowTemplates } from "@prisma/client";
|
||||||
|
|
||||||
|
import type { TimeFormat } from "@calcom/lib/timeFormat";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
whatsappEventCancelledTemplate,
|
whatsappEventCancelledTemplate,
|
||||||
|
@ -61,8 +64,9 @@ export function getWhatsappTemplateFunction(template: WorkflowTemplates): typeof
|
||||||
|
|
||||||
export function getWhatsappTemplateForAction(
|
export function getWhatsappTemplateForAction(
|
||||||
action: WorkflowActions,
|
action: WorkflowActions,
|
||||||
template: WorkflowTemplates
|
template: WorkflowTemplates,
|
||||||
|
timeFormat: TimeFormat
|
||||||
): string | null {
|
): string | null {
|
||||||
const templateFunction = getWhatsappTemplateFunction(template);
|
const templateFunction = getWhatsappTemplateFunction(template);
|
||||||
return templateFunction(true, action);
|
return templateFunction(true, action, timeFormat);
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,13 +104,20 @@ export const scheduleEmailReminder = async (
|
||||||
? evt.attendees[0].language?.locale
|
? evt.attendees[0].language?.locale
|
||||||
: evt.organizer.language.locale;
|
: evt.organizer.language.locale;
|
||||||
|
|
||||||
const emailSubjectTemplate = customTemplate(emailSubject, variables, locale);
|
const emailSubjectTemplate = customTemplate(emailSubject, variables, locale, evt.organizer.timeFormat);
|
||||||
emailContent.emailSubject = emailSubjectTemplate.text;
|
emailContent.emailSubject = emailSubjectTemplate.text;
|
||||||
emailContent.emailBody = customTemplate(emailBody, variables, locale, hideBranding).html;
|
emailContent.emailBody = customTemplate(
|
||||||
|
emailBody,
|
||||||
|
variables,
|
||||||
|
locale,
|
||||||
|
evt.organizer.timeFormat,
|
||||||
|
hideBranding
|
||||||
|
).html;
|
||||||
} else if (template === WorkflowTemplates.REMINDER) {
|
} else if (template === WorkflowTemplates.REMINDER) {
|
||||||
emailContent = emailReminderTemplate(
|
emailContent = emailReminderTemplate(
|
||||||
false,
|
false,
|
||||||
action,
|
action,
|
||||||
|
evt.organizer.timeFormat,
|
||||||
startTime,
|
startTime,
|
||||||
endTime,
|
endTime,
|
||||||
evt.title,
|
evt.title,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
import logger from "@calcom/lib/logger";
|
import logger from "@calcom/lib/logger";
|
||||||
|
import type { TimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
import type { Prisma } from "@calcom/prisma/client";
|
import type { Prisma } from "@calcom/prisma/client";
|
||||||
import type { TimeUnit } from "@calcom/prisma/enums";
|
import type { TimeUnit } from "@calcom/prisma/enums";
|
||||||
|
@ -29,6 +30,7 @@ export type BookingInfo = {
|
||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
timeZone: string;
|
timeZone: string;
|
||||||
|
timeFormat?: TimeFormat;
|
||||||
username?: string;
|
username?: string;
|
||||||
};
|
};
|
||||||
eventType: {
|
eventType: {
|
||||||
|
@ -115,11 +117,20 @@ export const scheduleSMSReminder = async (
|
||||||
cancelLink: `/booking/${evt.uid}?cancel=true`,
|
cancelLink: `/booking/${evt.uid}?cancel=true`,
|
||||||
rescheduleLink: `/${evt.organizer.username}/${evt.eventType.slug}?rescheduleUid=${evt.uid}`,
|
rescheduleLink: `/${evt.organizer.username}/${evt.eventType.slug}?rescheduleUid=${evt.uid}`,
|
||||||
};
|
};
|
||||||
const customMessage = customTemplate(message, variables, locale);
|
const customMessage = customTemplate(message, variables, locale, evt.organizer.timeFormat);
|
||||||
message = customMessage.text;
|
message = customMessage.text;
|
||||||
} else if (template === WorkflowTemplates.REMINDER) {
|
} else if (template === WorkflowTemplates.REMINDER) {
|
||||||
message =
|
message =
|
||||||
smsReminderTemplate(false, action, evt.startTime, evt.title, timeZone, attendeeName, name) || message;
|
smsReminderTemplate(
|
||||||
|
false,
|
||||||
|
action,
|
||||||
|
evt.organizer.timeFormat,
|
||||||
|
evt.startTime,
|
||||||
|
evt.title,
|
||||||
|
timeZone,
|
||||||
|
attendeeName,
|
||||||
|
name
|
||||||
|
) || message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allows debugging generated email content without waiting for sendgrid to send emails
|
// Allows debugging generated email content without waiting for sendgrid to send emails
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { guessEventLocationType } from "@calcom/app-store/locations";
|
||||||
import type { Dayjs } from "@calcom/dayjs";
|
import type { Dayjs } from "@calcom/dayjs";
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
import { APP_NAME, WEBAPP_URL } from "@calcom/lib/constants";
|
import { APP_NAME, WEBAPP_URL } from "@calcom/lib/constants";
|
||||||
|
import { TimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import type { CalEventResponses } from "@calcom/types/Calendar";
|
import type { CalEventResponses } from "@calcom/types/Calendar";
|
||||||
|
|
||||||
export type VariablesType = {
|
export type VariablesType = {
|
||||||
|
@ -24,6 +25,7 @@ const customTemplate = (
|
||||||
text: string,
|
text: string,
|
||||||
variables: VariablesType,
|
variables: VariablesType,
|
||||||
locale: string,
|
locale: string,
|
||||||
|
timeFormat?: TimeFormat,
|
||||||
isBrandingDisabled?: boolean
|
isBrandingDisabled?: boolean
|
||||||
) => {
|
) => {
|
||||||
const translatedDate = new Intl.DateTimeFormat(locale, {
|
const translatedDate = new Intl.DateTimeFormat(locale, {
|
||||||
|
@ -42,6 +44,8 @@ const customTemplate = (
|
||||||
const cancelLink = variables.cancelLink ? `${WEBAPP_URL}${variables.cancelLink}` : "";
|
const cancelLink = variables.cancelLink ? `${WEBAPP_URL}${variables.cancelLink}` : "";
|
||||||
const rescheduleLink = variables.rescheduleLink ? `${WEBAPP_URL}${variables.rescheduleLink}` : "";
|
const rescheduleLink = variables.rescheduleLink ? `${WEBAPP_URL}${variables.rescheduleLink}` : "";
|
||||||
|
|
||||||
|
const currentTimeFormat = timeFormat || TimeFormat.TWELVE_HOUR;
|
||||||
|
|
||||||
let dynamicText = text
|
let dynamicText = text
|
||||||
.replaceAll("{EVENT_NAME}", variables.eventName || "")
|
.replaceAll("{EVENT_NAME}", variables.eventName || "")
|
||||||
.replaceAll("{ORGANIZER}", variables.organizerName || "")
|
.replaceAll("{ORGANIZER}", variables.organizerName || "")
|
||||||
|
@ -49,9 +53,9 @@ const customTemplate = (
|
||||||
.replaceAll("{ORGANIZER_NAME}", variables.organizerName || "") //old variable names
|
.replaceAll("{ORGANIZER_NAME}", variables.organizerName || "") //old variable names
|
||||||
.replaceAll("{ATTENDEE_NAME}", variables.attendeeName || "") //old variable names
|
.replaceAll("{ATTENDEE_NAME}", variables.attendeeName || "") //old variable names
|
||||||
.replaceAll("{EVENT_DATE}", translatedDate)
|
.replaceAll("{EVENT_DATE}", translatedDate)
|
||||||
.replaceAll("{EVENT_TIME}", variables.eventDate?.format("H:mmA") || "")
|
.replaceAll("{EVENT_TIME}", variables.eventDate?.format(currentTimeFormat) || "")
|
||||||
.replaceAll("{START_TIME}", variables.eventDate?.format("H:mmA") || "")
|
.replaceAll("{START_TIME}", variables.eventDate?.format(currentTimeFormat) || "")
|
||||||
.replaceAll("{EVENT_END_TIME}", variables.eventEndTime?.format("H:mmA") || "")
|
.replaceAll("{EVENT_END_TIME}", variables.eventEndTime?.format(currentTimeFormat) || "")
|
||||||
.replaceAll("{LOCATION}", locationString)
|
.replaceAll("{LOCATION}", locationString)
|
||||||
.replaceAll("{ADDITIONAL_NOTES}", variables.additionalNotes || "")
|
.replaceAll("{ADDITIONAL_NOTES}", variables.additionalNotes || "")
|
||||||
.replaceAll("{ATTENDEE_EMAIL}", variables.attendeeEmail || "")
|
.replaceAll("{ATTENDEE_EMAIL}", variables.attendeeEmail || "")
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
import { APP_NAME } from "@calcom/lib/constants";
|
import { APP_NAME } from "@calcom/lib/constants";
|
||||||
|
import { TimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import { WorkflowActions } from "@calcom/prisma/enums";
|
import { WorkflowActions } from "@calcom/prisma/enums";
|
||||||
|
|
||||||
const emailReminderTemplate = (
|
const emailReminderTemplate = (
|
||||||
isEditingMode: boolean,
|
isEditingMode: boolean,
|
||||||
action?: WorkflowActions,
|
action?: WorkflowActions,
|
||||||
|
timeFormat?: TimeFormat,
|
||||||
startTime?: string,
|
startTime?: string,
|
||||||
endTime?: string,
|
endTime?: string,
|
||||||
eventName?: string,
|
eventName?: string,
|
||||||
|
@ -13,6 +15,9 @@ const emailReminderTemplate = (
|
||||||
name?: string,
|
name?: string,
|
||||||
isBrandingDisabled?: boolean
|
isBrandingDisabled?: boolean
|
||||||
) => {
|
) => {
|
||||||
|
const currentTimeFormat = timeFormat || TimeFormat.TWELVE_HOUR;
|
||||||
|
const dateTimeFormat = `ddd, MMM D, YYYY ${currentTimeFormat}`;
|
||||||
|
|
||||||
let eventDate = "";
|
let eventDate = "";
|
||||||
|
|
||||||
if (isEditingMode) {
|
if (isEditingMode) {
|
||||||
|
@ -21,23 +26,24 @@ const emailReminderTemplate = (
|
||||||
timeZone = "{TIMEZONE}";
|
timeZone = "{TIMEZONE}";
|
||||||
otherPerson = action === WorkflowActions.EMAIL_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
otherPerson = action === WorkflowActions.EMAIL_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
||||||
name = action === WorkflowActions.EMAIL_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
name = action === WorkflowActions.EMAIL_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
||||||
eventDate = "{EVENT_DATE_ddd, MMM D, YYYY H:mmA}";
|
eventDate = `{EVENT_DATE_${dateTimeFormat}}`;
|
||||||
} else {
|
} else {
|
||||||
eventDate = dayjs(startTime).tz(timeZone).format("ddd, MMM D, YYYY H:mmA");
|
eventDate = dayjs(startTime).tz(timeZone).format(dateTimeFormat);
|
||||||
|
|
||||||
endTime = dayjs(endTime).tz(timeZone).format("H:mmA");
|
endTime = dayjs(endTime).tz(timeZone).format(currentTimeFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
const emailSubject = `Reminder: ${eventName} - ${eventDate}`;
|
const emailSubject = `Reminder: ${eventName} - ${eventDate}`;
|
||||||
|
|
||||||
const introHtml = `<body>Hi${
|
const introHtml = `<body>Hi${
|
||||||
name ? " " + name : ""
|
name ? " " + name : ""
|
||||||
},<br><br>This is a reminder about your upcoming event.<br><br>`;
|
},<br><br>This is a reminder about your upcoming event.<br><br>`;
|
||||||
|
|
||||||
const eventHtml = `<div><strong class="editor-text-bold">Event:</strong></div>${eventName}<br><br>`;
|
const eventHtml = `<div><strong class="editor-text-bold">Event: </strong></div>${eventName}<br><br>`;
|
||||||
|
|
||||||
const dateTimeHtml = `<div><strong class="editor-text-bold">Date & Time:</strong></div>${eventDate} - ${endTime} (${timeZone})<br><br>`;
|
const dateTimeHtml = `<div><strong class="editor-text-bold">Date & Time: </strong></div>${eventDate} - ${endTime} (${timeZone})<br><br>`;
|
||||||
|
|
||||||
const attendeeHtml = `<div><strong class="editor-text-bold">Attendees:</strong></div>You & ${otherPerson}<br><br>`;
|
const attendeeHtml = `<div><strong class="editor-text-bold">Attendees: </strong></div>You & ${otherPerson}<br><br>`;
|
||||||
|
|
||||||
const branding = !isBrandingDisabled && !isEditingMode ? `<br><br>_<br><br>Scheduling by ${APP_NAME}` : "";
|
const branding = !isBrandingDisabled && !isEditingMode ? `<br><br>_<br><br>Scheduling by ${APP_NAME}` : "";
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,31 @@
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
|
import { TimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import { WorkflowActions } from "@calcom/prisma/enums";
|
import { WorkflowActions } from "@calcom/prisma/enums";
|
||||||
|
|
||||||
const smsReminderTemplate = (
|
const smsReminderTemplate = (
|
||||||
isEditingMode: boolean,
|
isEditingMode: boolean,
|
||||||
action?: WorkflowActions,
|
action?: WorkflowActions,
|
||||||
|
timeFormat?: TimeFormat,
|
||||||
startTime?: string,
|
startTime?: string,
|
||||||
eventName?: string,
|
eventName?: string,
|
||||||
timeZone?: string,
|
timeZone?: string,
|
||||||
attendee?: string,
|
attendee?: string,
|
||||||
name?: string
|
name?: string
|
||||||
) => {
|
) => {
|
||||||
|
const currentTimeFormat = timeFormat || TimeFormat.TWELVE_HOUR;
|
||||||
|
|
||||||
let eventDate;
|
let eventDate;
|
||||||
if (isEditingMode) {
|
if (isEditingMode) {
|
||||||
eventName = "{EVENT_NAME}";
|
eventName = "{EVENT_NAME}";
|
||||||
timeZone = "{TIMEZONE}";
|
timeZone = "{TIMEZONE}";
|
||||||
startTime = "{EVENT_TIME_h:mmA}";
|
startTime = `{EVENT_TIME_${currentTimeFormat}}`;
|
||||||
|
|
||||||
eventDate = "{EVENT_DATE_YYYY MMM D}";
|
eventDate = "{EVENT_DATE_YYYY MMM D}";
|
||||||
attendee = action === WorkflowActions.SMS_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
attendee = action === WorkflowActions.SMS_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
||||||
name = action === WorkflowActions.SMS_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
name = action === WorkflowActions.SMS_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
||||||
} else {
|
} else {
|
||||||
eventDate = dayjs(startTime).tz(timeZone).format("YYYY MMM D");
|
eventDate = dayjs(startTime).tz(timeZone).format("YYYY MMM D");
|
||||||
startTime = dayjs(startTime).tz(timeZone).format("h:mmA");
|
startTime = dayjs(startTime).tz(timeZone).format(currentTimeFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateOne = `Hi${
|
const templateOne = `Hi${
|
||||||
|
|
|
@ -1,28 +1,33 @@
|
||||||
import { WorkflowActions } from "@prisma/client";
|
import { WorkflowActions } from "@prisma/client";
|
||||||
|
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
|
import { TimeFormat } from "@calcom/lib/timeFormat";
|
||||||
|
|
||||||
export const whatsappEventCancelledTemplate = (
|
export const whatsappEventCancelledTemplate = (
|
||||||
isEditingMode: boolean,
|
isEditingMode: boolean,
|
||||||
action?: WorkflowActions,
|
action?: WorkflowActions,
|
||||||
|
timeFormat?: TimeFormat,
|
||||||
startTime?: string,
|
startTime?: string,
|
||||||
eventName?: string,
|
eventName?: string,
|
||||||
timeZone?: string,
|
timeZone?: string,
|
||||||
attendee?: string,
|
attendee?: string,
|
||||||
name?: string
|
name?: string
|
||||||
) => {
|
) => {
|
||||||
|
const currentTimeFormat = timeFormat || TimeFormat.TWELVE_HOUR;
|
||||||
|
const dateTimeFormat = `ddd, MMM D, YYYY ${currentTimeFormat}`;
|
||||||
|
|
||||||
let eventDate;
|
let eventDate;
|
||||||
if (isEditingMode) {
|
if (isEditingMode) {
|
||||||
eventName = "{EVENT_NAME}";
|
eventName = "{EVENT_NAME}";
|
||||||
timeZone = "{TIMEZONE}";
|
timeZone = "{TIMEZONE}";
|
||||||
startTime = "{START_TIME_h:mmA}";
|
startTime = `{START_TIME_${currentTimeFormat}}`;
|
||||||
|
|
||||||
eventDate = "{EVENT_DATE_YYYY MMM D}";
|
eventDate = `{EVENT_DATE_${dateTimeFormat}}`;
|
||||||
attendee = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
attendee = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
||||||
name = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
name = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
||||||
} else {
|
} else {
|
||||||
eventDate = dayjs(startTime).tz(timeZone).format("YYYY MMM D");
|
eventDate = dayjs(startTime).tz(timeZone).format("YYYY MMM D");
|
||||||
startTime = dayjs(startTime).tz(timeZone).format("h:mmA");
|
startTime = dayjs(startTime).tz(timeZone).format(currentTimeFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateOne = `Hi${
|
const templateOne = `Hi${
|
||||||
|
|
|
@ -1,28 +1,33 @@
|
||||||
import { WorkflowActions } from "@prisma/client";
|
import { WorkflowActions } from "@prisma/client";
|
||||||
|
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
|
import { TimeFormat } from "@calcom/lib/timeFormat";
|
||||||
|
|
||||||
export const whatsappEventCompletedTemplate = (
|
export const whatsappEventCompletedTemplate = (
|
||||||
isEditingMode: boolean,
|
isEditingMode: boolean,
|
||||||
action?: WorkflowActions,
|
action?: WorkflowActions,
|
||||||
|
timeFormat?: TimeFormat,
|
||||||
startTime?: string,
|
startTime?: string,
|
||||||
eventName?: string,
|
eventName?: string,
|
||||||
timeZone?: string,
|
timeZone?: string,
|
||||||
attendee?: string,
|
attendee?: string,
|
||||||
name?: string
|
name?: string
|
||||||
) => {
|
) => {
|
||||||
|
const currentTimeFormat = timeFormat || TimeFormat.TWELVE_HOUR;
|
||||||
|
const dateTimeFormat = `ddd, MMM D, YYYY ${currentTimeFormat}`;
|
||||||
|
|
||||||
let eventDate;
|
let eventDate;
|
||||||
if (isEditingMode) {
|
if (isEditingMode) {
|
||||||
eventName = "{EVENT_NAME}";
|
eventName = "{EVENT_NAME}";
|
||||||
timeZone = "{TIMEZONE}";
|
timeZone = "{TIMEZONE}";
|
||||||
startTime = "{START_TIME_h:mmA}";
|
startTime = `{START_TIME_${currentTimeFormat}}`;
|
||||||
|
|
||||||
eventDate = "{EVENT_DATE_YYYY MMM D}";
|
eventDate = `{EVENT_DATE_${dateTimeFormat}}`;
|
||||||
attendee = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
attendee = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
||||||
name = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
name = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
||||||
} else {
|
} else {
|
||||||
eventDate = dayjs(startTime).tz(timeZone).format("YYYY MMM D");
|
eventDate = dayjs(startTime).tz(timeZone).format("YYYY MMM D");
|
||||||
startTime = dayjs(startTime).tz(timeZone).format("h:mmA");
|
startTime = dayjs(startTime).tz(timeZone).format(currentTimeFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateOne = `Hi${
|
const templateOne = `Hi${
|
||||||
|
|
|
@ -1,28 +1,33 @@
|
||||||
import { WorkflowActions } from "@prisma/client";
|
import { WorkflowActions } from "@prisma/client";
|
||||||
|
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
|
import { TimeFormat } from "@calcom/lib/timeFormat";
|
||||||
|
|
||||||
export const whatsappReminderTemplate = (
|
export const whatsappReminderTemplate = (
|
||||||
isEditingMode: boolean,
|
isEditingMode: boolean,
|
||||||
action?: WorkflowActions,
|
action?: WorkflowActions,
|
||||||
|
timeFormat?: TimeFormat,
|
||||||
startTime?: string,
|
startTime?: string,
|
||||||
eventName?: string,
|
eventName?: string,
|
||||||
timeZone?: string,
|
timeZone?: string,
|
||||||
attendee?: string,
|
attendee?: string,
|
||||||
name?: string
|
name?: string
|
||||||
) => {
|
) => {
|
||||||
|
const currentTimeFormat = timeFormat || TimeFormat.TWELVE_HOUR;
|
||||||
|
const dateTimeFormat = `ddd, MMM D, YYYY ${currentTimeFormat}`;
|
||||||
|
|
||||||
let eventDate;
|
let eventDate;
|
||||||
if (isEditingMode) {
|
if (isEditingMode) {
|
||||||
eventName = "{EVENT_NAME}";
|
eventName = "{EVENT_NAME}";
|
||||||
timeZone = "{TIMEZONE}";
|
timeZone = "{TIMEZONE}";
|
||||||
startTime = "{START_TIME_h:mmA}";
|
startTime = `{START_TIME_${currentTimeFormat}}`;
|
||||||
|
|
||||||
eventDate = "{EVENT_DATE_YYYY MMM D}";
|
eventDate = `{EVENT_DATE_${dateTimeFormat}}`;
|
||||||
attendee = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
attendee = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
||||||
name = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
name = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
||||||
} else {
|
} else {
|
||||||
eventDate = dayjs(startTime).tz(timeZone).format("YYYY MMM D");
|
eventDate = dayjs(startTime).tz(timeZone).format("YYYY MMM D");
|
||||||
startTime = dayjs(startTime).tz(timeZone).format("h:mmA");
|
startTime = dayjs(startTime).tz(timeZone).format(currentTimeFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateOne = `Hi${
|
const templateOne = `Hi${
|
||||||
|
|
|
@ -1,28 +1,33 @@
|
||||||
import { WorkflowActions } from "@prisma/client";
|
import { WorkflowActions } from "@prisma/client";
|
||||||
|
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
|
import { TimeFormat } from "@calcom/lib/timeFormat";
|
||||||
|
|
||||||
export const whatsappEventRescheduledTemplate = (
|
export const whatsappEventRescheduledTemplate = (
|
||||||
isEditingMode: boolean,
|
isEditingMode: boolean,
|
||||||
action?: WorkflowActions,
|
action?: WorkflowActions,
|
||||||
|
timeFormat?: TimeFormat,
|
||||||
startTime?: string,
|
startTime?: string,
|
||||||
eventName?: string,
|
eventName?: string,
|
||||||
timeZone?: string,
|
timeZone?: string,
|
||||||
attendee?: string,
|
attendee?: string,
|
||||||
name?: string
|
name?: string
|
||||||
) => {
|
) => {
|
||||||
|
const currentTimeFormat = timeFormat || TimeFormat.TWELVE_HOUR;
|
||||||
|
const dateTimeFormat = `ddd, MMM D, YYYY ${currentTimeFormat}`;
|
||||||
|
|
||||||
let eventDate;
|
let eventDate;
|
||||||
if (isEditingMode) {
|
if (isEditingMode) {
|
||||||
eventName = "{EVENT_NAME}";
|
eventName = "{EVENT_NAME}";
|
||||||
timeZone = "{TIMEZONE}";
|
timeZone = "{TIMEZONE}";
|
||||||
startTime = "{START_TIME_h:mmA}";
|
startTime = `{START_TIME_${currentTimeFormat}}`;
|
||||||
|
|
||||||
eventDate = "{EVENT_DATE_YYYY MMM D}";
|
eventDate = `{EVENT_DATE_${dateTimeFormat}}`;
|
||||||
attendee = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
attendee = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ORGANIZER}" : "{ATTENDEE}";
|
||||||
name = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
name = action === WorkflowActions.WHATSAPP_ATTENDEE ? "{ATTENDEE}" : "{ORGANIZER}";
|
||||||
} else {
|
} else {
|
||||||
eventDate = dayjs(startTime).tz(timeZone).format("YYYY MMM D");
|
eventDate = dayjs(startTime).tz(timeZone).format("YYYY MMM D");
|
||||||
startTime = dayjs(startTime).tz(timeZone).format("h:mmA");
|
startTime = dayjs(startTime).tz(timeZone).format(currentTimeFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateOne = `Hi${
|
const templateOne = `Hi${
|
||||||
|
|
|
@ -6,7 +6,8 @@ import logger from "@calcom/lib/logger";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
|
|
||||||
import * as twilio from "./smsProviders/twilioProvider";
|
import * as twilio from "./smsProviders/twilioProvider";
|
||||||
import { BookingInfo, deleteScheduledSMSReminder, timeUnitLowerCase } from "./smsReminderManager";
|
import type { BookingInfo, timeUnitLowerCase } from "./smsReminderManager";
|
||||||
|
import { deleteScheduledSMSReminder } from "./smsReminderManager";
|
||||||
import {
|
import {
|
||||||
whatsappEventCancelledTemplate,
|
whatsappEventCancelledTemplate,
|
||||||
whatsappEventCompletedTemplate,
|
whatsappEventCompletedTemplate,
|
||||||
|
@ -68,14 +69,23 @@ export const scheduleWhatsappReminder = async (
|
||||||
switch (template) {
|
switch (template) {
|
||||||
case WorkflowTemplates.REMINDER:
|
case WorkflowTemplates.REMINDER:
|
||||||
message =
|
message =
|
||||||
whatsappReminderTemplate(false, action, evt.startTime, evt.title, timeZone, attendeeName, name) ||
|
whatsappReminderTemplate(
|
||||||
message;
|
false,
|
||||||
|
action,
|
||||||
|
evt.organizer.timeFormat,
|
||||||
|
evt.startTime,
|
||||||
|
evt.title,
|
||||||
|
timeZone,
|
||||||
|
attendeeName,
|
||||||
|
name
|
||||||
|
) || message;
|
||||||
break;
|
break;
|
||||||
case WorkflowTemplates.CANCELLED:
|
case WorkflowTemplates.CANCELLED:
|
||||||
message =
|
message =
|
||||||
whatsappEventCancelledTemplate(
|
whatsappEventCancelledTemplate(
|
||||||
false,
|
false,
|
||||||
action,
|
action,
|
||||||
|
evt.organizer.timeFormat,
|
||||||
evt.startTime,
|
evt.startTime,
|
||||||
evt.title,
|
evt.title,
|
||||||
timeZone,
|
timeZone,
|
||||||
|
@ -88,6 +98,7 @@ export const scheduleWhatsappReminder = async (
|
||||||
whatsappEventRescheduledTemplate(
|
whatsappEventRescheduledTemplate(
|
||||||
false,
|
false,
|
||||||
action,
|
action,
|
||||||
|
evt.organizer.timeFormat,
|
||||||
evt.startTime,
|
evt.startTime,
|
||||||
evt.title,
|
evt.title,
|
||||||
timeZone,
|
timeZone,
|
||||||
|
@ -100,6 +111,7 @@ export const scheduleWhatsappReminder = async (
|
||||||
whatsappEventCompletedTemplate(
|
whatsappEventCompletedTemplate(
|
||||||
false,
|
false,
|
||||||
action,
|
action,
|
||||||
|
evt.organizer.timeFormat,
|
||||||
evt.startTime,
|
evt.startTime,
|
||||||
evt.title,
|
evt.title,
|
||||||
timeZone,
|
timeZone,
|
||||||
|
@ -109,8 +121,16 @@ export const scheduleWhatsappReminder = async (
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
message =
|
message =
|
||||||
whatsappReminderTemplate(false, action, evt.startTime, evt.title, timeZone, attendeeName, name) ||
|
whatsappReminderTemplate(
|
||||||
message;
|
false,
|
||||||
|
action,
|
||||||
|
evt.organizer.timeFormat,
|
||||||
|
evt.startTime,
|
||||||
|
evt.title,
|
||||||
|
timeZone,
|
||||||
|
attendeeName,
|
||||||
|
name
|
||||||
|
) || message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allows debugging generated whatsapp content without waiting for twilio to send whatsapp messages
|
// Allows debugging generated whatsapp content without waiting for twilio to send whatsapp messages
|
||||||
|
|
|
@ -19,6 +19,8 @@ import { trpc } from "@calcom/trpc/react";
|
||||||
import type { MultiSelectCheckboxesOptionType as Option } from "@calcom/ui";
|
import type { MultiSelectCheckboxesOptionType as Option } from "@calcom/ui";
|
||||||
import { Alert, Button, Form, showToast, Badge } from "@calcom/ui";
|
import { Alert, Button, Form, showToast, Badge } from "@calcom/ui";
|
||||||
|
|
||||||
|
import useMeQuery from "@lib/hooks/useMeQuery";
|
||||||
|
|
||||||
import LicenseRequired from "../../common/components/LicenseRequired";
|
import LicenseRequired from "../../common/components/LicenseRequired";
|
||||||
import SkeletonLoader from "../components/SkeletonLoaderEdit";
|
import SkeletonLoader from "../components/SkeletonLoaderEdit";
|
||||||
import WorkflowDetailsPage from "../components/WorkflowDetailsPage";
|
import WorkflowDetailsPage from "../components/WorkflowDetailsPage";
|
||||||
|
@ -93,6 +95,9 @@ function WorkflowPage() {
|
||||||
const { workflow: workflowId } = router.isReady ? querySchema.parse(router.query) : { workflow: -1 };
|
const { workflow: workflowId } = router.isReady ? querySchema.parse(router.query) : { workflow: -1 };
|
||||||
const utils = trpc.useContext();
|
const utils = trpc.useContext();
|
||||||
|
|
||||||
|
const userQuery = useMeQuery();
|
||||||
|
const user = userQuery.data;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: workflow,
|
data: workflow,
|
||||||
isError,
|
isError,
|
||||||
|
@ -285,11 +290,12 @@ function WorkflowPage() {
|
||||||
<LicenseRequired>
|
<LicenseRequired>
|
||||||
{!isError ? (
|
{!isError ? (
|
||||||
<>
|
<>
|
||||||
{isAllDataLoaded ? (
|
{isAllDataLoaded && user ? (
|
||||||
<>
|
<>
|
||||||
<WorkflowDetailsPage
|
<WorkflowDetailsPage
|
||||||
form={form}
|
form={form}
|
||||||
workflowId={+workflowId}
|
workflowId={+workflowId}
|
||||||
|
user={user}
|
||||||
selectedEventTypes={selectedEventTypes}
|
selectedEventTypes={selectedEventTypes}
|
||||||
setSelectedEventTypes={setSelectedEventTypes}
|
setSelectedEventTypes={setSelectedEventTypes}
|
||||||
teamId={workflow ? workflow.teamId || undefined : undefined}
|
teamId={workflow ? workflow.teamId || undefined : undefined}
|
||||||
|
|
|
@ -24,6 +24,10 @@ export const getIs24hClockFromLocalStorage = () => {
|
||||||
return is24hFromLocalstorage === "true";
|
return is24hFromLocalstorage === "true";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getTimeFormatStringFromUserTimeFormat = (timeFormat: number | null | undefined) => {
|
||||||
|
return timeFormat === 24 ? TimeFormat.TWENTY_FOUR_HOUR : TimeFormat.TWELVE_HOUR;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the browsers time format preference, checking local storage first
|
* Retrieves the browsers time format preference, checking local storage first
|
||||||
* for a user set preference. If no preference is found, it will use the browser
|
* for a user set preference. If no preference is found, it will use the browser
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { handleWebhookTrigger } from "@calcom/features/bookings/lib/handleWebhoo
|
||||||
import type { EventTypeInfo } from "@calcom/features/webhooks/lib/sendPayload";
|
import type { EventTypeInfo } from "@calcom/features/webhooks/lib/sendPayload";
|
||||||
import { isPrismaObjOrUndefined, parseRecurringEvent } from "@calcom/lib";
|
import { isPrismaObjOrUndefined, parseRecurringEvent } from "@calcom/lib";
|
||||||
import { getTranslation } from "@calcom/lib/server";
|
import { getTranslation } from "@calcom/lib/server";
|
||||||
|
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import { prisma } from "@calcom/prisma";
|
import { prisma } from "@calcom/prisma";
|
||||||
import { BookingStatus, MembershipRole, SchedulingType, WebhookTriggerEvents } from "@calcom/prisma/enums";
|
import { BookingStatus, MembershipRole, SchedulingType, WebhookTriggerEvents } from "@calcom/prisma/enums";
|
||||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||||
|
@ -162,6 +163,7 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => {
|
||||||
name: user.name || "Unnamed",
|
name: user.name || "Unnamed",
|
||||||
username: user.username || undefined,
|
username: user.username || undefined,
|
||||||
timeZone: user.timeZone,
|
timeZone: user.timeZone,
|
||||||
|
timeFormat: getTimeFormatStringFromUserTimeFormat(user.timeFormat),
|
||||||
language: { translate: tOrganizer, locale: user.locale ?? "en" },
|
language: { translate: tOrganizer, locale: user.locale ?? "en" },
|
||||||
},
|
},
|
||||||
attendees: attendeesList,
|
attendees: attendeesList,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
scheduleWhatsappReminder,
|
scheduleWhatsappReminder,
|
||||||
} from "@calcom/features/ee/workflows/lib/reminders/whatsappReminderManager";
|
} from "@calcom/features/ee/workflows/lib/reminders/whatsappReminderManager";
|
||||||
import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
|
import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
|
||||||
|
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import { prisma } from "@calcom/prisma";
|
import { prisma } from "@calcom/prisma";
|
||||||
import { BookingStatus } from "@calcom/prisma/client";
|
import { BookingStatus } from "@calcom/prisma/client";
|
||||||
import { MembershipRole, WorkflowActions, WorkflowMethods } from "@calcom/prisma/enums";
|
import { MembershipRole, WorkflowActions, WorkflowMethods } from "@calcom/prisma/enums";
|
||||||
|
@ -171,6 +172,7 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType
|
||||||
name: booking.user.name || "",
|
name: booking.user.name || "",
|
||||||
email: booking.user.email,
|
email: booking.user.email,
|
||||||
timeZone: booking.user.timeZone,
|
timeZone: booking.user.timeZone,
|
||||||
|
timeFormat: getTimeFormatStringFromUserTimeFormat(booking.user.timeFormat),
|
||||||
language: { locale: booking.user.locale || defaultLocale },
|
language: { locale: booking.user.locale || defaultLocale },
|
||||||
}
|
}
|
||||||
: { name: "", email: "", timeZone: "", language: { locale: "" } },
|
: { name: "", email: "", timeZone: "", language: { locale: "" } },
|
||||||
|
|
|
@ -2,6 +2,7 @@ import type { Workflow } from "@prisma/client";
|
||||||
|
|
||||||
import emailReminderTemplate from "@calcom/ee/workflows/lib/reminders/templates/emailReminderTemplate";
|
import emailReminderTemplate from "@calcom/ee/workflows/lib/reminders/templates/emailReminderTemplate";
|
||||||
import { SENDER_NAME } from "@calcom/lib/constants";
|
import { SENDER_NAME } from "@calcom/lib/constants";
|
||||||
|
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import { prisma } from "@calcom/prisma";
|
import { prisma } from "@calcom/prisma";
|
||||||
import type { PrismaClient } from "@calcom/prisma/client";
|
import type { PrismaClient } from "@calcom/prisma/client";
|
||||||
import {
|
import {
|
||||||
|
@ -65,13 +66,19 @@ export const createHandler = async ({ ctx, input }: CreateOptions) => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const renderedEmailTemplate = emailReminderTemplate(
|
||||||
|
true,
|
||||||
|
WorkflowActions.EMAIL_ATTENDEE,
|
||||||
|
getTimeFormatStringFromUserTimeFormat(ctx.user.timeFormat)
|
||||||
|
);
|
||||||
|
|
||||||
await ctx.prisma.workflowStep.create({
|
await ctx.prisma.workflowStep.create({
|
||||||
data: {
|
data: {
|
||||||
stepNumber: 1,
|
stepNumber: 1,
|
||||||
action: WorkflowActions.EMAIL_ATTENDEE,
|
action: WorkflowActions.EMAIL_ATTENDEE,
|
||||||
template: WorkflowTemplates.REMINDER,
|
template: WorkflowTemplates.REMINDER,
|
||||||
reminderBody: emailReminderTemplate(true, WorkflowActions.EMAIL_ATTENDEE).emailBody,
|
reminderBody: renderedEmailTemplate.emailBody,
|
||||||
emailSubject: emailReminderTemplate(true, WorkflowActions.EMAIL_ATTENDEE).emailSubject,
|
emailSubject: renderedEmailTemplate.emailSubject,
|
||||||
workflowId: workflow.id,
|
workflowId: workflow.id,
|
||||||
sender: SENDER_NAME,
|
sender: SENDER_NAME,
|
||||||
numberVerificationPending: false,
|
numberVerificationPending: false,
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
} from "@calcom/features/ee/workflows/lib/reminders/whatsappReminderManager";
|
} from "@calcom/features/ee/workflows/lib/reminders/whatsappReminderManager";
|
||||||
import { IS_SELF_HOSTED, SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
|
import { IS_SELF_HOSTED, SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
|
||||||
import hasKeyInMetadata from "@calcom/lib/hasKeyInMetadata";
|
import hasKeyInMetadata from "@calcom/lib/hasKeyInMetadata";
|
||||||
|
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||||
import type { PrismaClient } from "@calcom/prisma/client";
|
import type { PrismaClient } from "@calcom/prisma/client";
|
||||||
import { BookingStatus, WorkflowActions, WorkflowMethods, WorkflowTriggerEvents } from "@calcom/prisma/enums";
|
import { BookingStatus, WorkflowActions, WorkflowMethods, WorkflowTriggerEvents } from "@calcom/prisma/enums";
|
||||||
import type { TrpcSessionUser } from "@calcom/trpc/server/trpc";
|
import type { TrpcSessionUser } from "@calcom/trpc/server/trpc";
|
||||||
|
@ -280,6 +281,7 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
|
||||||
name: booking.user.name || "",
|
name: booking.user.name || "",
|
||||||
email: booking.user.email,
|
email: booking.user.email,
|
||||||
timeZone: booking.user.timeZone,
|
timeZone: booking.user.timeZone,
|
||||||
|
timeFormat: getTimeFormatStringFromUserTimeFormat(booking.user.timeFormat),
|
||||||
}
|
}
|
||||||
: { name: "", email: "", timeZone: "", language: { locale: "" } },
|
: { name: "", email: "", timeZone: "", language: { locale: "" } },
|
||||||
startTime: booking.startTime.toISOString(),
|
startTime: booking.startTime.toISOString(),
|
||||||
|
@ -503,6 +505,7 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
|
||||||
name: booking.user.name || "",
|
name: booking.user.name || "",
|
||||||
email: booking.user.email,
|
email: booking.user.email,
|
||||||
timeZone: booking.user.timeZone,
|
timeZone: booking.user.timeZone,
|
||||||
|
timeFormat: getTimeFormatStringFromUserTimeFormat(booking.user.timeFormat),
|
||||||
}
|
}
|
||||||
: { name: "", email: "", timeZone: "", language: { locale: "" } },
|
: { name: "", email: "", timeZone: "", language: { locale: "" } },
|
||||||
startTime: booking.startTime.toISOString(),
|
startTime: booking.startTime.toISOString(),
|
||||||
|
@ -649,6 +652,7 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
|
||||||
name: booking.user.name || "",
|
name: booking.user.name || "",
|
||||||
email: booking.user.email,
|
email: booking.user.email,
|
||||||
timeZone: booking.user.timeZone,
|
timeZone: booking.user.timeZone,
|
||||||
|
timeFormat: getTimeFormatStringFromUserTimeFormat(booking.user.timeFormat),
|
||||||
language: { locale: booking.user.locale || defaultLocale },
|
language: { locale: booking.user.locale || defaultLocale },
|
||||||
}
|
}
|
||||||
: { name: "", email: "", timeZone: "", language: { locale: "" } },
|
: { name: "", email: "", timeZone: "", language: { locale: "" } },
|
||||||
|
|
Loading…
Reference in New Issue
Block a user