|
9 | 9 | from auth.authorization import require_role
|
10 | 10 | from auth.user_identity import User, utc_now
|
11 | 11 | from models.ApplicationData import Decision, Review
|
12 |
| -from services import mongodb_handler |
| 12 | +from services import mongodb_handler, sendgrid_handler |
13 | 13 | from services.mongodb_handler import BaseRecord, Collection
|
| 14 | +from services.sendgrid_handler import ApplicationUpdatePersonalization, Template |
14 | 15 | from utils import email_handler
|
15 | 16 | from utils.batched import batched
|
| 17 | +from utils.email_handler import IH_SENDER, REPLY_TO_HACK_AT_UCI |
16 | 18 | from utils.user_record import Applicant, Role, Status
|
17 | 19 |
|
18 | 20 | log = getLogger(__name__)
|
@@ -131,6 +133,33 @@ async def release_decisions() -> None:
|
131 | 133 | )
|
132 | 134 |
|
133 | 135 |
|
| 136 | +@router.post("/rsvp-reminder", dependencies=[Depends(require_role([Role.DIRECTOR]))]) |
| 137 | +async def rsvp_reminder() -> None: |
| 138 | + """Send email to applicants who have a status of ACCEPTED or WAIVER_SIGNED |
| 139 | + reminding them to RSVP.""" |
| 140 | + # TODO: Consider using Pydantic model validation instead of type annotations |
| 141 | + not_yet_rsvpd: list[dict[str, Any]] = await mongodb_handler.retrieve( |
| 142 | + Collection.USERS, |
| 143 | + {"status": {"$in": [Decision.ACCEPTED, Status.WAIVER_SIGNED]}}, |
| 144 | + ["_id", "application_data.first_name"], |
| 145 | + ) |
| 146 | + log.info(f"Sending RSVP reminder emails to {len(not_yet_rsvpd)} applicants") |
| 147 | + personalizations = [ |
| 148 | + ApplicationUpdatePersonalization( |
| 149 | + email=_recover_email_from_uid(record["_id"]), |
| 150 | + first_name=record["application_data"]["first_name"], |
| 151 | + ) |
| 152 | + for record in not_yet_rsvpd |
| 153 | + ] |
| 154 | + await sendgrid_handler.send_email( |
| 155 | + Template.RSVP_REMINDER, |
| 156 | + IH_SENDER, |
| 157 | + personalizations, |
| 158 | + True, |
| 159 | + reply_to=REPLY_TO_HACK_AT_UCI, |
| 160 | + ) |
| 161 | + |
| 162 | + |
134 | 163 | async def _process_batch(batch: tuple[dict[str, Any], ...], decision: Decision) -> None:
|
135 | 164 | uids: list[str] = [record["_id"] for record in batch]
|
136 | 165 | log.info(f"Setting {','.join(uids)} as {decision}")
|
|
0 commit comments