Add team members to iCal, Apple Cal, Outlook, and Lark calendar events (#7846)

* Outlook add team members

* iCal & Apple add team members

* Exchange add team members

* iCal & App cal update include attendees

* Exchange reschedule

* GCal add team members on reschedule

* Lark cal loop through team members
This commit is contained in:
Joe Au-Yeung 2023-03-20 23:15:59 -04:00 committed by GitHub
parent f1ac45ee19
commit 2ef4a05750
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 78 additions and 13 deletions

View File

@ -74,6 +74,12 @@ export default class ExchangeCalendarService implements Calendar {
appointment.RequiredAttendees.Add(new Attendee(event.attendees[i].email)); appointment.RequiredAttendees.Add(new Attendee(event.attendees[i].email));
} }
if (event.team?.members) {
event.team.members.forEach((member) => {
appointment.RequiredAttendees.Add(new Attendee(member.email));
});
}
await appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy); await appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy);
return { return {
@ -106,6 +112,11 @@ export default class ExchangeCalendarService implements Calendar {
for (let i = 0; i < event.attendees.length; i++) { for (let i = 0; i < event.attendees.length; i++) {
appointment.RequiredAttendees.Add(new Attendee(event.attendees[i].email)); appointment.RequiredAttendees.Add(new Attendee(event.attendees[i].email));
} }
if (event.team?.members) {
event.team.members.forEach((member) => {
appointment.RequiredAttendees.Add(new Attendee(member.email));
});
}
appointment.Update( appointment.Update(
ConflictResolutionMode.AlwaysOverwrite, ConflictResolutionMode.AlwaysOverwrite,
SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy

View File

@ -75,6 +75,12 @@ export default class ExchangeCalendarService implements Calendar {
appointment.RequiredAttendees.Add(new Attendee(event.attendees[i].email)); appointment.RequiredAttendees.Add(new Attendee(event.attendees[i].email));
} }
if (event.team?.members) {
event.team.members.forEach((member) => {
appointment.RequiredAttendees.Add(new Attendee(member.email));
});
}
await appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy); await appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy);
return { return {
@ -106,6 +112,11 @@ export default class ExchangeCalendarService implements Calendar {
for (let i = 0; i < event.attendees.length; i++) { for (let i = 0; i < event.attendees.length; i++) {
appointment.RequiredAttendees.Add(new Attendee(event.attendees[i].email)); appointment.RequiredAttendees.Add(new Attendee(event.attendees[i].email));
} }
if (event.team?.members) {
event.team.members.forEach((member) => {
appointment.RequiredAttendees.Add(new Attendee(member.email));
});
}
appointment.Update( appointment.Update(
ConflictResolutionMode.AlwaysOverwrite, ConflictResolutionMode.AlwaysOverwrite,
SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy

View File

@ -64,6 +64,11 @@ export default class ExchangeCalendarService implements Calendar {
event.attendees.forEach((attendee: Person) => { event.attendees.forEach((attendee: Person) => {
appointment.RequiredAttendees.Add(new Attendee(attendee.email)); appointment.RequiredAttendees.Add(new Attendee(attendee.email));
}); });
if (event.team?.members) {
event.team.members.forEach((member: Person) => {
appointment.RequiredAttendees.Add(new Attendee(member.email));
});
}
return appointment return appointment
.Save(SendInvitationsMode.SendToAllAndSaveCopy) .Save(SendInvitationsMode.SendToAllAndSaveCopy)
.then(() => { .then(() => {
@ -95,6 +100,11 @@ export default class ExchangeCalendarService implements Calendar {
event.attendees.forEach((attendee: Person) => { event.attendees.forEach((attendee: Person) => {
appointment.RequiredAttendees.Add(new Attendee(attendee.email)); appointment.RequiredAttendees.Add(new Attendee(attendee.email));
}); });
if (event.team?.members) {
event.team.members.forEach((member) => {
appointment.RequiredAttendees.Add(new Attendee(member.email));
});
}
return appointment return appointment
.Update( .Update(
ConflictResolutionMode.AlwaysOverwrite, ConflictResolutionMode.AlwaysOverwrite,

View File

@ -177,6 +177,12 @@ export default class GoogleCalendarService implements Calendar {
...rest, ...rest,
responseStatus: "accepted", responseStatus: "accepted",
})); }));
const teamMembers =
event.team?.members.map((m) => ({
email: m.email,
displayName: m.name,
responseStatus: "accepted",
})) || [];
const payload: calendar_v3.Schema$Event = { const payload: calendar_v3.Schema$Event = {
summary: event.title, summary: event.title,
description: getRichDescription(event), description: getRichDescription(event),
@ -197,6 +203,7 @@ export default class GoogleCalendarService implements Calendar {
}, },
// eslint-disable-next-line // eslint-disable-next-line
...eventAttendees, ...eventAttendees,
...teamMembers,
], ],
reminders: { reminders: {
useDefault: true, useDefault: true,

View File

@ -377,16 +377,25 @@ export default class LarkCalendarService implements Calendar {
}; };
private translateAttendees = (event: CalendarEvent): LarkEventAttendee[] => { private translateAttendees = (event: CalendarEvent): LarkEventAttendee[] => {
const attendees: LarkEventAttendee[] = event.attendees const attendeeArray: LarkEventAttendee[] = [];
event.attendees
.filter((att) => att.email) .filter((att) => att.email)
.map((att) => { .forEach((att) => {
const attendee: LarkEventAttendee = { const attendee: LarkEventAttendee = {
type: "third_party", type: "third_party",
is_optional: false, is_optional: false,
third_party_email: att.email, third_party_email: att.email,
}; };
return attendee; attendeeArray.push(attendee);
}); });
return attendees; event.team?.members.forEach((member) => {
const attendee: LarkEventAttendee = {
type: "third_party",
is_optional: false,
third_party_email: member.email,
};
attendeeArray.push(attendee);
});
return attendeeArray;
}; };
} }

View File

@ -267,13 +267,24 @@ export default class Office365CalendarService implements Calendar {
dateTime: dayjs(event.endTime).tz(event.organizer.timeZone).format("YYYY-MM-DDTHH:mm:ss"), dateTime: dayjs(event.endTime).tz(event.organizer.timeZone).format("YYYY-MM-DDTHH:mm:ss"),
timeZone: event.organizer.timeZone, timeZone: event.organizer.timeZone,
}, },
attendees: event.attendees.map((attendee) => ({ attendees: [
emailAddress: { ...event.attendees.map((attendee) => ({
address: attendee.email, emailAddress: {
name: attendee.name, address: attendee.email,
}, name: attendee.name,
type: "required", },
})), type: "required",
})),
...(event.team?.members
? event.team?.members.map((member) => ({
emailAddress: {
address: member.email,
name: member.name,
},
type: "required",
}))
: []),
],
location: event.location ? { displayName: getLocation(event) } : undefined, location: event.location ? { displayName: getLocation(event) } : undefined,
}; };
}; };

View File

@ -118,7 +118,10 @@ export default abstract class BaseCalendarService implements Calendar {
description: getRichDescription(event), description: getRichDescription(event),
location: getLocation(event), location: getLocation(event),
organizer: { email: event.organizer.email, name: event.organizer.name }, organizer: { email: event.organizer.email, name: event.organizer.name },
attendees: getAttendees(event.attendees), attendees: [
...getAttendees(event.attendees),
...(event.team?.members ? getAttendees(event.team.members) : []),
],
/** according to https://datatracker.ietf.org/doc/html/rfc2446#section-3.2.1, in a published iCalendar component. /** according to https://datatracker.ietf.org/doc/html/rfc2446#section-3.2.1, in a published iCalendar component.
* "Attendees" MUST NOT be present * "Attendees" MUST NOT be present
* `attendees: this.getAttendees(event.attendees),` * `attendees: this.getAttendees(event.attendees),`
@ -189,7 +192,10 @@ export default abstract class BaseCalendarService implements Calendar {
description: getRichDescription(event), description: getRichDescription(event),
location: getLocation(event), location: getLocation(event),
organizer: { email: event.organizer.email, name: event.organizer.name }, organizer: { email: event.organizer.email, name: event.organizer.name },
attendees: getAttendees(event.attendees), attendees: [
...getAttendees(event.attendees),
...(event.team?.members ? getAttendees(event.team.members) : []),
],
}); });
if (error) { if (error) {