hotfix: zoom location on emails (#1153)

* fix: zoom location on emails

* test: fix

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
Mihai C 2021-11-09 18:27:33 +02:00 committed by GitHub
parent 43fa4f6497
commit 559ccb8ca7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 58 deletions

View File

@ -642,6 +642,15 @@ const createEvent = async (
})
: undefined;
if (!creationResult) {
return {
type: credential.type,
success,
uid,
originalEvent: calEvent,
};
}
const metadata: AdditionInformation = {};
if (creationResult) {
// TODO: Handle created event metadata more elegantly
@ -650,10 +659,10 @@ const createEvent = async (
metadata.entryPoints = creationResult.entryPoints;
}
const emailEvent = { ...calEvent, additionInformation: metadata };
calEvent.additionInformation = metadata;
if (!noMail) {
const organizerMail = new EventOrganizerMail(emailEvent);
const organizerMail = new EventOrganizerMail(calEvent);
try {
await organizerMail.sendEmail();
@ -674,27 +683,37 @@ const createEvent = async (
const updateEvent = async (
credential: Credential,
calEvent: CalendarEvent,
noMail: boolean | null = false
noMail: boolean | null = false,
bookingRefUid: string | null
): Promise<EventResult> => {
const parser: CalEventParser = new CalEventParser(calEvent);
const newUid: string = parser.getUid();
const uid = parser.getUid();
const richEvent: CalendarEvent = parser.asRichEventPlain();
let success = true;
const updateResult =
credential && calEvent.uid
const updatedResult =
credential && bookingRefUid
? await calendars([credential])[0]
.updateEvent(calEvent.uid, richEvent)
.updateEvent(bookingRefUid, richEvent)
.catch((e) => {
log.error("updateEvent failed", e, calEvent);
success = false;
return undefined;
})
: null;
if (!updatedResult) {
return {
type: credential.type,
success,
uid,
originalEvent: calEvent,
};
}
if (!noMail) {
const emailEvent = { ...calEvent, uid: newUid };
const organizerMail = new EventOrganizerRescheduledMail(emailEvent);
const organizerMail = new EventOrganizerRescheduledMail(calEvent);
try {
await organizerMail.sendEmail();
} catch (e) {
@ -705,8 +724,8 @@ const updateEvent = async (
return {
type: credential.type,
success,
uid: newUid,
updatedEvent: updateResult,
uid,
updatedEvent: updatedResult,
originalEvent: calEvent,
};
};

View File

@ -79,7 +79,7 @@ export default class EventManager {
* @param event
*/
public async create(event: Ensure<CalendarEvent, "language">): Promise<CreateUpdateResult> {
let evt = EventManager.processLocation(event);
const evt = EventManager.processLocation(event);
const isDedicated = evt.location ? EventManager.isDedicatedIntegration(evt.location) : null;
// First, create all calendar events. If this is a dedicated integration event, don't send a mail right here.
@ -88,7 +88,7 @@ export default class EventManager {
if (isDedicated) {
const result = await this.createVideoEvent(evt);
if (result.videoCallData) {
evt = { ...evt, videoCallData: result.videoCallData };
evt.videoCallData = result.videoCallData;
}
results.push(result);
} else {
@ -126,17 +126,20 @@ export default class EventManager {
*
* @param event
*/
public async update(event: Ensure<CalendarEvent, "uid">): Promise<CreateUpdateResult> {
let evt = EventManager.processLocation(event);
public async update(
event: Ensure<CalendarEvent, "language">,
rescheduleUid: string
): Promise<CreateUpdateResult> {
const evt = EventManager.processLocation(event);
if (!evt.uid) {
throw new Error("You called eventManager.update without an `uid`. This should never happen.");
if (!rescheduleUid) {
throw new Error("You called eventManager.update without an `rescheduleUid`. This should never happen.");
}
// Get details of existing booking.
const booking = await prisma.booking.findFirst({
where: {
uid: evt.uid,
uid: rescheduleUid,
},
select: {
id: true,
@ -164,7 +167,7 @@ export default class EventManager {
if (isDedicated) {
const result = await this.updateVideoEvent(evt, booking);
if (result.videoCallData) {
evt = { ...evt, videoCallData: result.videoCallData };
evt.videoCallData = result.videoCallData;
}
results.push(result);
} else {
@ -182,15 +185,11 @@ export default class EventManager {
},
});
let bookingDeletes = null;
if (evt.uid) {
bookingDeletes = prisma.booking.delete({
where: {
uid: evt.uid,
},
});
}
const bookingDeletes = prisma.booking.delete({
where: {
id: booking.id,
},
});
// Wait for all deletions to be applied.
await Promise.all([bookingReferenceDeletes, attendeeDeletes, bookingDeletes]);
@ -275,8 +274,7 @@ export default class EventManager {
const bookingRefUid = booking
? booking.references.filter((ref) => ref.type === credential.type)[0]?.uid
: null;
const evt = { ...event, uid: bookingRefUid };
return updateEvent(credential, evt, noMail);
return updateEvent(credential, event, noMail, bookingRefUid);
});
}
@ -292,10 +290,10 @@ export default class EventManager {
if (credential) {
const bookingRef = booking ? booking.references.filter((ref) => ref.type === credential.type)[0] : null;
const evt = { ...event, uid: bookingRef?.uid };
return updateMeeting(credential, evt).then((returnVal: EventResult) => {
const bookingRefUid = bookingRef ? bookingRef.uid : null;
return updateMeeting(credential, event, bookingRefUid).then((returnVal: EventResult) => {
// Some video integrations, such as Zoom, don't return any data about the booking when updating it.
if (returnVal.videoCallData == undefined) {
if (returnVal.videoCallData === undefined) {
returnVal.videoCallData = EventManager.bookingReferenceToVideoCallData(bookingRef);
}
return returnVal;
@ -441,15 +439,16 @@ export default class EventManager {
metadata.conferenceData = results[0].createdEvent?.conferenceData;
metadata.entryPoints = results[0].createdEvent?.entryPoints;
}
const emailEvent = { ...event, additionInformation: metadata };
event.additionInformation = metadata;
let attendeeMail;
switch (type) {
case "reschedule":
attendeeMail = new EventAttendeeRescheduledMail(emailEvent);
attendeeMail = new EventAttendeeRescheduledMail(event);
break;
case "new":
attendeeMail = new EventAttendeeMail(emailEvent);
attendeeMail = new EventAttendeeMail(event);
break;
}
try {

View File

@ -116,10 +116,11 @@ const createMeeting = async (
entryPoints: [entryPoint],
};
const emailEvent = { ...calEvent, uid, additionInformation, videoCallData };
calEvent.additionInformation = additionInformation;
calEvent.videoCallData = videoCallData;
try {
const organizerMail = new VideoEventOrganizerMail(emailEvent);
const organizerMail = new VideoEventOrganizerMail(calEvent);
await organizerMail.sendEmail();
} catch (e) {
console.error("organizerMail.sendEmail failed", e);
@ -127,7 +128,7 @@ const createMeeting = async (
if (!createdMeeting || !createdMeeting.disableConfirmationEmail) {
try {
const attendeeMail = new VideoEventAttendeeMail(emailEvent);
const attendeeMail = new VideoEventAttendeeMail(calEvent);
await attendeeMail.sendEmail();
} catch (e) {
console.error("attendeeMail.sendEmail failed", e);
@ -144,8 +145,12 @@ const createMeeting = async (
};
};
const updateMeeting = async (credential: Credential, calEvent: CalendarEvent): Promise<EventResult> => {
const newUid: string = translator.fromUUID(uuidv5(JSON.stringify(calEvent), uuidv5.URL));
const updateMeeting = async (
credential: Credential,
calEvent: CalendarEvent,
bookingRefUid: string | null
): Promise<EventResult> => {
const uid: string = translator.fromUUID(uuidv5(JSON.stringify(calEvent), uuidv5.URL));
if (!credential) {
throw new Error(
@ -153,31 +158,29 @@ const updateMeeting = async (credential: Credential, calEvent: CalendarEvent): P
);
}
if (!calEvent.uid) {
throw new Error("You can't update an meeting without it's UID.");
}
let success = true;
const [firstVideoAdapter] = getVideoAdapters([credential]);
const updatedMeeting = await firstVideoAdapter.updateMeeting(calEvent.uid, calEvent).catch((e) => {
log.error("updateMeeting failed", e, calEvent);
success = false;
});
const updatedMeeting =
credential && bookingRefUid
? await firstVideoAdapter.updateMeeting(bookingRefUid, calEvent).catch((e) => {
log.error("updateMeeting failed", e, calEvent);
success = false;
return undefined;
})
: undefined;
if (!updatedMeeting) {
return {
type: credential.type,
success,
uid: calEvent.uid,
uid,
originalEvent: calEvent,
};
}
const emailEvent = { ...calEvent, uid: newUid };
try {
const organizerMail = new EventOrganizerRescheduledMail(emailEvent);
const organizerMail = new EventOrganizerRescheduledMail(calEvent);
await organizerMail.sendEmail();
} catch (e) {
console.error("organizerMail.sendEmail failed", e);
@ -185,7 +188,7 @@ const updateMeeting = async (credential: Credential, calEvent: CalendarEvent): P
if (!updatedMeeting.disableConfirmationEmail) {
try {
const attendeeMail = new EventAttendeeRescheduledMail(emailEvent);
const attendeeMail = new EventAttendeeRescheduledMail(calEvent);
await attendeeMail.sendEmail();
} catch (e) {
console.error("attendeeMail.sendEmail failed", e);
@ -195,7 +198,7 @@ const updateMeeting = async (credential: Credential, calEvent: CalendarEvent): P
return {
type: credential.type,
success,
uid: newUid,
uid,
updatedEvent: updatedMeeting,
originalEvent: calEvent,
};

View File

@ -439,8 +439,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
if (rescheduleUid) {
// Use EventManager to conditionally use all needed integrations.
const eventManagerCalendarEvent = { ...evt, uid: rescheduleUid };
const updateResults = await eventManager.update(eventManagerCalendarEvent);
const updateResults = await eventManager.update(evt, rescheduleUid);
results = updateResults.results;
referencesToCreate = updateResults.referencesToCreate;
@ -473,7 +472,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
if (eventType.requiresConfirmation && !rescheduleUid) {
await new EventOrganizerRequestMail({ ...evt, uid }).sendEmail();
await new EventOrganizerRequestMail(evt).sendEmail();
}
if (typeof eventType.price === "number" && eventType.price > 0) {

View File

@ -67,6 +67,7 @@ describe("webhooks", () => {
}
body.payload.organizer.timeZone = dynamic;
body.payload.uid = dynamic;
body.payload.additionInformation = dynamic;
// if we change the shape of our webhooks, we can simply update this by clicking `u`
// console.log("BODY", body);
@ -74,6 +75,7 @@ describe("webhooks", () => {
Object {
"createdAt": "[redacted/dynamic]",
"payload": Object {
"additionInformation": "[redacted/dynamic]",
"attendees": Array [
Object {
"email": "test@example.com",