Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: undefined in meeting url workflow variable #16771

Merged
merged 14 commits into from
Sep 30, 2024
13 changes: 13 additions & 0 deletions packages/features/bookings/lib/handleCancelBooking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { deleteWebhookScheduledTriggers } from "@calcom/features/webhooks/lib/sc
import sendPayload from "@calcom/features/webhooks/lib/sendOrSchedulePayload";
import type { EventTypeInfo } from "@calcom/features/webhooks/lib/sendPayload";
import { isPrismaObjOrUndefined, parseRecurringEvent } from "@calcom/lib";
import { getBookerBaseUrl } from "@calcom/lib/getBookerUrl/server";
import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId";
import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType";
import { HttpError } from "@calcom/lib/http-error";
Expand Down Expand Up @@ -276,7 +277,18 @@ async function handler(req: CustomRequest) {
const teamMembers = await Promise.all(teamMembersPromises);
const tOrganizer = await getTranslation(organizer.locale ?? "en", "common");

const ownerProfile = await prisma.profile.findFirst({
where: {
userId: bookingToDelete.userId,
},
});

const bookerUrl = await getBookerBaseUrl(
bookingToDelete.eventType?.team?.parentId ?? ownerProfile?.organizationId ?? null
);

const evt: CalendarEvent = {
bookerUrl,
title: bookingToDelete?.title,
length: bookingToDelete?.eventType?.length,
type: bookingToDelete?.eventType?.slug as string,
Expand Down Expand Up @@ -371,6 +383,7 @@ async function handler(req: CustomRequest) {
evt: {
...evt,
metadata: { videoCallUrl: bookingMetadataSchema.parse(bookingToDelete.metadata || {})?.videoCallUrl },
bookerUrl,
...{
eventType: {
slug: bookingToDelete.eventType?.slug,
Expand Down
30 changes: 17 additions & 13 deletions packages/features/bookings/lib/handleConfirmation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { scheduleTrigger } from "@calcom/features/webhooks/lib/scheduleTrigger";
import sendPayload from "@calcom/features/webhooks/lib/sendOrSchedulePayload";
import type { EventPayloadType, EventTypeInfo } from "@calcom/features/webhooks/lib/sendPayload";
import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser";
import { getBookerBaseUrl } from "@calcom/lib/getBookerUrl/server";
import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId";
import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType";
import logger from "@calcom/lib/logger";
Expand Down Expand Up @@ -283,6 +284,21 @@ export async function handleConfirmation(args: {
updatedBookings.push(updatedBooking);
}

const teamId = await getTeamIdFromEventType({
eventType: {
team: { id: eventType?.teamId ?? null },
parentId: eventType?.parentId ?? null,
},
});

const triggerForUser = !teamId || (teamId && eventType?.parentId);

const userId = triggerForUser ? booking.userId : null;

const orgId = await getOrgIdFromMemberOrTeamId({ memberId: userId, teamId });

const bookerUrl = await getBookerBaseUrl(orgId ?? null);

//Workflows - set reminders for confirmed events
try {
for (let index = 0; index < updatedBookings.length; index++) {
Expand All @@ -295,6 +311,7 @@ export async function handleConfirmation(args: {
schedulingType: updatedBookings[index].eventType?.schedulingType,
hosts: updatedBookings[index].eventType?.hosts,
},
bookerUrl,
};
evtOfBooking.startTime = updatedBookings[index].startTime.toISOString();
evtOfBooking.endTime = updatedBookings[index].endTime.toISOString();
Expand Down Expand Up @@ -325,19 +342,6 @@ export async function handleConfirmation(args: {
}

try {
const teamId = await getTeamIdFromEventType({
eventType: {
team: { id: eventType?.teamId ?? null },
parentId: eventType?.parentId ?? null,
},
});

const triggerForUser = !teamId || (teamId && eventType?.parentId);

const userId = triggerForUser ? booking.userId : null;

const orgId = await getOrgIdFromMemberOrTeamId({ memberId: userId, teamId });

const subscribersBookingCreated = await getWebhooks({
userId,
eventTypeId: booking.eventTypeId,
Expand Down
3 changes: 2 additions & 1 deletion packages/features/bookings/lib/handleNewBooking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,7 @@ async function handler(
rescheduleUid,
reqBookingUid: reqBody.bookingUid,
eventType,
evt,
evt: { ...evt, bookerUrl },
invitee,
allCredentials,
organizerUser,
Expand Down Expand Up @@ -1782,6 +1782,7 @@ async function handler(
...evt,
metadata,
eventType: { slug: eventType.slug, schedulingType: eventType.schedulingType, hosts: eventType.hosts },
bookerUrl,
};

if (!eventType.metadata?.disableStandardEmails?.all?.attendee) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ const attendeeRescheduleSeatedBooking = async (
}),
]);
}

// Add the new attendees to the new time slot booking attendees
for (const attendee of newTimeSlotBooking.attendees) {
const language = await getTranslation(attendee.locale ?? "en", "common");
const translate = await getTranslation(attendee.locale ?? "en", "common");
evt.attendees.push({
email: attendee.email,
name: attendee.name,
language,
timeZone: attendee.timeZone,
language: { translate, locale: attendee.locale ?? "en" },
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const combineTwoSeatedBookings = async (

evt.attendees = updatedBookingAttendees;

evt = addVideoCallDataToEvent(updatedNewBooking.references, evt);
evt = { ...addVideoCallDataToEvent(updatedNewBooking.references, evt), bookerUrl: evt.bookerUrl };

const copyEvent = cloneDeep(evt);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const moveSeatedBookingToNewTimeSlot = async (
},
});

evt = addVideoCallDataToEvent(newBooking.references, evt);
evt = { ...addVideoCallDataToEvent(newBooking.references, evt), bookerUrl: evt.bookerUrl };

const copyEvent = cloneDeep(evt);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ const ownerRescheduleSeatedBooking = async (
) => {
const { originalRescheduledBooking, tAttendees } = rescheduleSeatedBookingObject;
const { evt } = rescheduleSeatedBookingObject;
evt.attendees = originalRescheduledBooking?.attendees.map((attendee) => {
return {
name: attendee.name,
email: attendee.email,
timeZone: attendee.timeZone,
language: { translate: tAttendees, locale: attendee.locale ?? "en" },
};
});

evt.attendees =
originalRescheduledBooking?.attendees.map((attendee) => {
return {
name: attendee.name,
email: attendee.email,
timeZone: attendee.timeZone,
language: { translate: tAttendees, locale: attendee.locale ?? "en" },
};
}) ?? [];

// If there is no booking during the new time slot then update the current booking to the new date
if (!newTimeSlotBooking) {
Expand Down
6 changes: 4 additions & 2 deletions packages/features/bookings/lib/handleSeats/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Prisma } from "@prisma/client";
import type z from "zod";

import type { Workflow } from "@calcom/features/ee/workflows/lib/types";
import type { AppsStatus } from "@calcom/types/Calendar";
import type { AppsStatus, CalendarEvent } from "@calcom/types/Calendar";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CalendarEvent wasn't imported, so evt was treated as any instead. Importing it now caused some other type errors that needed to be fixed


import type { Booking, NewBookingEventType, OriginalRescheduledBooking } from "../handleNewBooking/types";

Expand All @@ -12,7 +12,9 @@ export type NewSeatedBookingObject = {
rescheduleUid: string | undefined;
reqBookingUid: string | undefined;
eventType: NewBookingEventType;
evt: CalendarEvent;
evt: Omit<CalendarEvent, "bookerUrl"> & {
bookerUrl: string;
};
invitee: Invitee;
allCredentials: Awaited<ReturnType<typeof getAllCredentials>>;
organizerUser: OrganizerUser;
Expand Down
19 changes: 17 additions & 2 deletions packages/features/ee/round-robin/roundRobinReassignment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { scheduleWorkflowReminders } from "@calcom/features/ee/workflows/lib/reminders/reminderScheduler";
import { isPrismaObjOrUndefined } from "@calcom/lib";
import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser";
import { getBookerBaseUrl } from "@calcom/lib/getBookerUrl/server";
import logger from "@calcom/lib/logger";
import { getLuckyUser } from "@calcom/lib/server";
import { getTranslation } from "@calcom/lib/server/i18n";
Expand Down Expand Up @@ -50,7 +51,13 @@ const bookingSelect = {
references: true,
};

export const roundRobinReassignment = async ({ bookingId }: { bookingId: number }) => {
export const roundRobinReassignment = async ({
bookingId,
orgId,
}: {
bookingId: number;
orgId: number | null;
}) => {
const roundRobinReassignLogger = logger.getSubLogger({
prefix: ["roundRobinReassign", `${bookingId}`],
});
Expand Down Expand Up @@ -465,6 +472,8 @@ export const roundRobinReassignment = async ({ bookingId }: { bookingId: number

const workflowEventMetadata = { videoCallUrl: getVideoCallUrlFromCalEvent(evt) };

const bookerUrl = await getBookerBaseUrl(orgId);

for (const workflowReminder of workflowReminders) {
const workflowStep = workflowReminder?.workflowStep;
const workflow = workflowStep?.workflow;
Expand All @@ -475,6 +484,7 @@ export const roundRobinReassignment = async ({ bookingId }: { bookingId: number
...evt,
metadata: workflowEventMetadata,
eventType,
bookerUrl,
},
action: WorkflowActions.EMAIL_HOST,
triggerEvent: workflow.trigger,
Expand Down Expand Up @@ -538,7 +548,12 @@ export const roundRobinReassignment = async ({ bookingId }: { bookingId: number
await scheduleWorkflowReminders({
workflows: newEventWorkflows,
smsReminderNumber: null,
calendarEvent: { ...evt, metadata: workflowEventMetadata, eventType: { slug: eventType.slug } },
calendarEvent: {
...evt,
metadata: workflowEventMetadata,
eventType: { slug: eventType.slug },
bookerUrl,
},
hideBranding: !!eventType?.owner?.hideBranding,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { v4 as uuidv4 } from "uuid";
import { guessEventLocationType } from "@calcom/app-store/locations";
import dayjs from "@calcom/dayjs";
import { preprocessNameFieldDataWithVariant } from "@calcom/features/form-builder/utils";
import { WEBSITE_URL } from "@calcom/lib/constants";
import logger from "@calcom/lib/logger";
import prisma from "@calcom/prisma";
import type { TimeUnit } from "@calcom/prisma/enums";
Expand Down Expand Up @@ -189,6 +190,8 @@ export const scheduleEmailReminder = async (args: scheduleEmailReminderArgs) =>
emailSubject,
emailBody: `<body style="white-space: pre-wrap;">${emailBody}</body>`,
};
const bookerUrl = evt.bookerUrl ?? WEBSITE_URL;

if (emailBody) {
const variables: VariablesType = {
eventName: evt.title || "",
Expand All @@ -204,10 +207,10 @@ export const scheduleEmailReminder = async (args: scheduleEmailReminderArgs) =>
additionalNotes: evt.additionalNotes,
responses: evt.responses,
meetingUrl: bookingMetadataSchema.parse(evt.metadata || {})?.videoCallUrl,
cancelLink: `${evt.bookerUrl}/booking/${evt.uid}?cancel=true`,
rescheduleLink: `${evt.bookerUrl}/reschedule/${evt.uid}`,
ratingUrl: `${evt.bookerUrl}/booking/${evt.uid}?rating`,
noShowUrl: `${evt.bookerUrl}/booking/${evt.uid}?noShow=true`,
cancelLink: `${bookerUrl}/booking/${evt.uid}?cancel=true`,
rescheduleLink: `${bookerUrl}/reschedule/${evt.uid}`,
ratingUrl: `${bookerUrl}/booking/${evt.uid}?rating`,
noShowUrl: `${bookerUrl}/booking/${evt.uid}?noShow=true`,
};

const locale =
Expand Down Expand Up @@ -247,8 +250,8 @@ export const scheduleEmailReminder = async (args: scheduleEmailReminderArgs) =>
timeZone,
organizer: evt.organizer.name,
name,
ratingUrl: `${evt.bookerUrl}/booking/${evt.uid}?rating`,
noShowUrl: `${evt.bookerUrl}/booking/${evt.uid}?noShow=true`,
ratingUrl: `${bookerUrl}/booking/${evt.uid}?rating`,
noShowUrl: `${bookerUrl}/booking/${evt.uid}?noShow=true`,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import type { ScheduleTextReminderAction } from "./smsReminderManager";
import { scheduleSMSReminder } from "./smsReminderManager";
import { scheduleWhatsappReminder } from "./whatsappReminderManager";

export type ExtendedCalendarEvent = CalendarEvent & {
export type ExtendedCalendarEvent = Omit<CalendarEvent, "bookerUrl"> & {
metadata?: { videoCallUrl: string | undefined };
eventType: {
slug?: string;
schedulingType?: SchedulingType | null;
hosts?: { user: { email: string; destinationCalendar?: { primaryEmail: string | null } | null } }[];
};
bookerUrl: string;
};

type ProcessWorkflowStepParams = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import dayjs from "@calcom/dayjs";
import { SENDER_ID } from "@calcom/lib/constants";
import { SENDER_ID, WEBSITE_URL } from "@calcom/lib/constants";
import logger from "@calcom/lib/logger";
import type { TimeFormat } from "@calcom/lib/timeFormat";
import type { PrismaClient } from "@calcom/prisma";
Expand Down Expand Up @@ -36,7 +36,7 @@ export type AttendeeInBookingInfo = {

export type BookingInfo = {
uid?: string | null;
bookerUrl?: string;
bookerUrl: string;
attendees: AttendeeInBookingInfo[];
organizer: {
language: { locale: string };
Expand Down Expand Up @@ -158,8 +158,8 @@ export const scheduleSMSReminder = async (args: ScheduleTextReminderArgs) => {
additionalNotes: evt.additionalNotes,
responses: evt.responses,
meetingUrl: bookingMetadataSchema.parse(evt.metadata || {})?.videoCallUrl,
cancelLink: `${evt.bookerUrl}/booking/${evt.uid}?cancel=true`,
rescheduleLink: `${evt.bookerUrl}/reschedule/${evt.uid}`,
cancelLink: `${evt.bookerUrl ?? WEBSITE_URL}/booking/${evt.uid}?cancel=true`,
rescheduleLink: `${evt.bookerUrl ?? WEBSITE_URL}/reschedule/${evt.uid}`,
};
const customMessage = customTemplate(smsMessage, variables, locale, evt.organizer.timeFormat);
smsMessage = customMessage.text;
Expand Down
2 changes: 1 addition & 1 deletion packages/prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// This is your Prisma Schema file
// This is your Prisma Schema file
// learn more about it in the docs: https://pris.ly/d/prisma-schema

datasource db {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const roundRobinReassignHandler = async ({ ctx, input }: RoundRobinReassi
throw new TRPCError({ code: "FORBIDDEN", message: "You do not have permission" });
}

await roundRobinReassignment({ bookingId });
await roundRobinReassignment({ bookingId, orgId: ctx.user.organizationId });
};

export default roundRobinReassignHandler;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { scheduleEmailReminder } from "@calcom/features/ee/workflows/lib/reminders/emailReminderManager";
import { scheduleSMSReminder } from "@calcom/features/ee/workflows/lib/reminders/smsReminderManager";
import { scheduleWhatsappReminder } from "@calcom/features/ee/workflows/lib/reminders/whatsappReminderManager";
import { getBookerBaseUrl } from "@calcom/lib/getBookerUrl/server";
import { WorkflowRepository } from "@calcom/lib/server/repository/workflow";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import { prisma } from "@calcom/prisma";
Expand Down Expand Up @@ -221,10 +222,13 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType
},
});

const bookerUrl = await getBookerBaseUrl(ctx.user.organizationId ?? null);

for (const booking of bookingsForReminders) {
const defaultLocale = "en";
const bookingInfo = {
uid: booking.uid,
bookerUrl,
attendees: booking.attendees.map((attendee) => {
return {
name: attendee.name,
Expand Down
Loading
Loading