Only send single mail when booking zoom

pull/375/head
nicolas 2021-07-20 20:07:59 +02:00
parent a40a5c04fe
commit 7aff32fb50
3 changed files with 79 additions and 43 deletions

View File

@ -509,7 +509,11 @@ const listCalendars = (withCredentials) =>
results.reduce((acc, calendars) => acc.concat(calendars), []) results.reduce((acc, calendars) => acc.concat(calendars), [])
); );
const createEvent = async (credential: Credential, calEvent: CalendarEvent): Promise<EventResult> => { const createEvent = async (
credential: Credential,
calEvent: CalendarEvent,
noMail = false
): Promise<EventResult> => {
const parser: CalEventParser = new CalEventParser(calEvent); const parser: CalEventParser = new CalEventParser(calEvent);
const uid: string = parser.getUid(); const uid: string = parser.getUid();
const richEvent: CalendarEvent = parser.asRichEvent(); const richEvent: CalendarEvent = parser.asRichEvent();
@ -529,29 +533,31 @@ const createEvent = async (credential: Credential, calEvent: CalendarEvent): Pro
const maybeEntryPoints = creationResult?.entryPoints; const maybeEntryPoints = creationResult?.entryPoints;
const maybeConferenceData = creationResult?.conferenceData; const maybeConferenceData = creationResult?.conferenceData;
const organizerMail = new EventOrganizerMail(calEvent, uid, { if (!noMail) {
hangoutLink: maybeHangoutLink, const organizerMail = new EventOrganizerMail(calEvent, uid, {
conferenceData: maybeConferenceData, hangoutLink: maybeHangoutLink,
entryPoints: maybeEntryPoints, conferenceData: maybeConferenceData,
}); entryPoints: maybeEntryPoints,
});
const attendeeMail = new EventAttendeeMail(calEvent, uid, { const attendeeMail = new EventAttendeeMail(calEvent, uid, {
hangoutLink: maybeHangoutLink, hangoutLink: maybeHangoutLink,
conferenceData: maybeConferenceData, conferenceData: maybeConferenceData,
entryPoints: maybeEntryPoints, entryPoints: maybeEntryPoints,
}); });
try {
await organizerMail.sendEmail();
} catch (e) {
console.error("organizerMail.sendEmail failed", e);
}
if (!creationResult || !creationResult.disableConfirmationEmail) {
try { try {
await attendeeMail.sendEmail(); await organizerMail.sendEmail();
} catch (e) { } catch (e) {
console.error("attendeeMail.sendEmail failed", e); console.error("organizerMail.sendEmail failed", e);
}
if (!creationResult || !creationResult.disableConfirmationEmail) {
try {
await attendeeMail.sendEmail();
} catch (e) {
console.error("attendeeMail.sendEmail failed", e);
}
} }
} }
@ -567,7 +573,8 @@ const createEvent = async (credential: Credential, calEvent: CalendarEvent): Pro
const updateEvent = async ( const updateEvent = async (
credential: Credential, credential: Credential,
uidToUpdate: string, uidToUpdate: string,
calEvent: CalendarEvent calEvent: CalendarEvent,
noMail: false
): Promise<EventResult> => { ): Promise<EventResult> => {
const parser: CalEventParser = new CalEventParser(calEvent); const parser: CalEventParser = new CalEventParser(calEvent);
const newUid: string = parser.getUid(); const newUid: string = parser.getUid();
@ -584,19 +591,21 @@ const updateEvent = async (
}) })
: null; : null;
const organizerMail = new EventOrganizerRescheduledMail(calEvent, newUid); if (!noMail) {
const attendeeMail = new EventAttendeeRescheduledMail(calEvent, newUid); const organizerMail = new EventOrganizerRescheduledMail(calEvent, newUid);
try { const attendeeMail = new EventAttendeeRescheduledMail(calEvent, newUid);
await organizerMail.sendEmail();
} catch (e) {
console.error("organizerMail.sendEmail failed", e);
}
if (!updateResult || !updateResult.disableConfirmationEmail) {
try { try {
await attendeeMail.sendEmail(); await organizerMail.sendEmail();
} catch (e) { } catch (e) {
console.error("attendeeMail.sendEmail failed", e); console.error("organizerMail.sendEmail failed", e);
}
if (!updateResult || !updateResult.disableConfirmationEmail) {
try {
await attendeeMail.sendEmail();
} catch (e) {
console.error("attendeeMail.sendEmail failed", e);
}
} }
} }

View File

@ -33,11 +33,13 @@ export default class EventManager {
} }
public async create(event: CalendarEvent): Promise<Array<EventResult>> { public async create(event: CalendarEvent): Promise<Array<EventResult>> {
// First, create all calendar events. const isVideo = EventManager.isIntegration(event.location);
const results: Array<EventResult> = await this.createAllCalendarEvents(event);
// First, create all calendar events. If this is a video event, don't send a mail right here.
const results: Array<EventResult> = await this.createAllCalendarEvents(event, isVideo);
// If and only if event type is a video meeting, create a video meeting as well. // If and only if event type is a video meeting, create a video meeting as well.
if (EventManager.isIntegration(event.location)) { if (isVideo) {
results.push(await this.createVideoEvent(event)); results.push(await this.createVideoEvent(event));
} }
@ -45,11 +47,13 @@ export default class EventManager {
} }
public async update(event: CalendarEvent, booking: PartialBooking): Promise<Array<EventResult>> { public async update(event: CalendarEvent, booking: PartialBooking): Promise<Array<EventResult>> {
// First, update all calendar events. const isVideo = EventManager.isIntegration(event.location);
const results: Array<EventResult> = await this.updateAllCalendarEvents(event, booking);
// First, update all calendar events. If this is a video event, don't send a mail right here.
const results: Array<EventResult> = await this.updateAllCalendarEvents(event, booking, isVideo);
// If and only if event type is a video meeting, update the video meeting as well. // If and only if event type is a video meeting, update the video meeting as well.
if (EventManager.isIntegration(event.location)) { if (isVideo) {
results.push(await this.updateVideoEvent(event, booking)); results.push(await this.updateVideoEvent(event, booking));
} }
@ -58,13 +62,17 @@ export default class EventManager {
/** /**
* Creates event entries for all calendar integrations given in the credentials. * Creates event entries for all calendar integrations given in the credentials.
* When noMail is true, no mails will be sent. This is used when the event is
* a video meeting because then the mail containing the video credentials will be
* more important than the mails created for these bare calendar events.
* *
* @param event * @param event
* @param noMail
* @private * @private
*/ */
private createAllCalendarEvents(event: CalendarEvent): Promise<Array<EventResult>> { private createAllCalendarEvents(event: CalendarEvent, noMail: boolean): Promise<Array<EventResult>> {
return async.mapLimit(this.calendarCredentials, 5, async (credential: Credential) => { return async.mapLimit(this.calendarCredentials, 5, async (credential: Credential) => {
return createEvent(credential, event); return createEvent(credential, event, noMail);
}); });
} }
@ -89,16 +97,35 @@ export default class EventManager {
} }
} }
/**
* Updates the event entries for all calendar integrations given in the credentials.
* When noMail is true, no mails will be sent. This is used when the event is
* a video meeting because then the mail containing the video credentials will be
* more important than the mails created for these bare calendar events.
*
* @param event
* @param booking
* @param noMail
* @private
*/
private updateAllCalendarEvents( private updateAllCalendarEvents(
event: CalendarEvent, event: CalendarEvent,
booking: PartialBooking booking: PartialBooking,
noMail: boolean
): Promise<Array<EventResult>> { ): Promise<Array<EventResult>> {
return async.mapLimit(this.calendarCredentials, 5, async (credential) => { return async.mapLimit(this.calendarCredentials, 5, async (credential) => {
const bookingRefUid = booking.references.filter((ref) => ref.type === credential.type)[0]?.uid; const bookingRefUid = booking.references.filter((ref) => ref.type === credential.type)[0]?.uid;
return updateEvent(credential, bookingRefUid, event); return updateEvent(credential, bookingRefUid, event, noMail);
}); });
} }
/**
* Updates a single video event.
*
* @param event
* @param booking
* @private
*/
private updateVideoEvent(event: CalendarEvent, booking: PartialBooking) { private updateVideoEvent(event: CalendarEvent, booking: PartialBooking) {
const credential = this.getVideoCredential(event); const credential = this.getVideoCredential(event);

View File

@ -356,7 +356,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
await Promise.all([bookingReferenceDeletes, attendeeDeletes, bookingDeletes]); await Promise.all([bookingReferenceDeletes, attendeeDeletes, bookingDeletes]);
} else { } else {
// Use EventManager to conditionally use all needed integrations. // Use EventManager to conditionally use all needed integrations.
const results: Array<EventResult> = await eventManager.create(evt); results = await eventManager.create(evt);
if (results.length > 0 && results.every((res) => !res.success)) { if (results.length > 0 && results.every((res) => !res.success)) {
const error = { const error = {