Skip to content

Interview Scheduler new ics email invites#1138

Open
ladriennel wants to merge 4 commits intomainfrom
al/new-gcal-ics-invite
Open

Interview Scheduler new ics email invites#1138
ladriennel wants to merge 4 commits intomainfrom
al/new-gcal-ics-invite

Conversation

@ladriennel
Copy link
Collaborator

@ladriennel ladriennel commented Feb 28, 2026

Summary

The previous gapi/Google OAuth approach required the https://www.googleapis.com/auth/calendar.events scope to solve an issue we came across where applicants were receiving errors from trying to add their time slot to gcal. The issue was that this scope is classified as sensitive by Google and when added, it requires an app verification before it can be used in production which is more overhead than needed for this feature.

This new approach uses .ics attachments sent via email that don't require OAuth and can work with any calendar app. When sign-ups and cancellations occur, an email is sent with the ics attachment that includes the time slots location, date/time, and a uid. This uid is the same across the invitation + cancellation, so the same event is modified each time. Previously calendar invites were only sent to applicants, now DTI members also receive them.

  • Removed calendar.ts and any previous, related gapi integration
  • Applicants and DTI members who sign up to interview receive confirmation emails with an ics calendar invite after signing up in an InterviewScheduler instance.
  • Applicants receive cancellation emails if time slot is deleted or admin removes them, DTI members receive this email for same reason as well as if they decide to cancel their own sign up
  • Leads currently receive no notifications
  • Applicant confirmation card now includes text saying that they received an email rather than a button with option to add to gcal

Test Plan

  • Create a test Interview Scheduler instance with an applicant of your personal (non Cornell) email (so that you can mimic an applicant). Add time slots (need to temporarily change role to lead).
  • Through personal email, access IDOL local host and sign up for a time slot. Check confirmation card that notes a success and email has been sent. In non-prod, the email won't actually be sent, but an stdout will appear in the backend terminal with the contents
  • Check that the email contents and ics content are correct and match sign up details.
  • Through Cornell email, sign up for a time slot as an IDOL member. Check email contents match.
  • Check that removing an applicant from time slot sends cancellation to applicant, deleting entire time slot sends cancellation to applicant and member, and cancelling sign up as member sends email.

Notion Link

notion

Notes

  • To test the actual email and ics calendar functionality, I ran a temporary script with the exact ics details + email content from stdout testing to confirm it works.
Screenshot 2026-02-28 at 5 03 51 PM

@ladriennel ladriennel requested a review from a team as a code owner February 28, 2026 23:34
@dti-github-bot
Copy link
Member

dti-github-bot commented Feb 28, 2026

[diff-counting] Significant lines: 324.

Comment on lines 381 to 387
const interviewerNames: string[] = [];
if (slot.lead) {
interviewerNames.push(`${slot.lead.firstName} ${slot.lead.lastName} (Lead)`);
}
slot.members.forEach((member, index) => {
if (member) {
interviewerNames.push(`${member.firstName} ${member.lastName}`);
}
slot.members.forEach((member) => {
if (member) interviewerNames.push(`${member.firstName} ${member.lastName}`);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at the email body after this code, interviewerNames is never used! We can either remove this, or add - Interviewers: ${interviewerNames.join(', ')}. The second option wuould be helpful for applicants to know who they'll be meeting with. I'm not sure what is the best option, but you can provide more input on such.

@@ -4,7 +4,12 @@ import InterviewSlotDao from '../dao/InterviewSlotDao';
import { BadRequestError, NotFoundError, PermissionError } from '../utils/errors';
Copy link
Contributor

Choose a reason for hiding this comment

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

Hi Adrienne. Everything looks really well done, and when tested, I did receive the email and got it added to my GCal. There was only really one comment really on what to change. However, I do wonder if you have tested out deleting an available time slot from like leads side. I know this isn't common so it's not that big of a worry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants