| from __future__ import annotations |
| import logging |
| import os |
| import httpx |
|
|
| logger = logging.getLogger(__name__) |
|
|
| RESEND_API_KEY = os.environ.get("RESEND_API_KEY", "") |
| FROM_EMAIL = "MERLx Aperture <noreply@aperture.merlx.org>" |
|
|
| async def send_completion_email(to_email: str, job_id: str, aoi_name: str) -> bool: |
| if not RESEND_API_KEY: |
| logger.warning(f"No RESEND_API_KEY — skipping email to {to_email} for job {job_id}") |
| return False |
|
|
| html = f""" |
| <div style="font-family: Inter, sans-serif; max-width: 500px; margin: 0 auto; padding: 24px; background: #F5F3EE;"> |
| <div style="font-size: 14px; font-weight: 700; margin-bottom: 8px;">MERL<span style="color: #8071BC;">x</span></div> |
| <h2 style="font-size: 18px; color: #111; margin-bottom: 12px;">Your analysis is ready</h2> |
| <p style="font-size: 13px; color: #2A2A2A; line-height: 1.6;"> |
| The satellite analysis for <strong>{aoi_name}</strong> is complete. |
| </p> |
| <p style="font-size: 11px; color: #6B6B6B; margin-top: 20px;"> |
| Generated by MERLx Aperture using open satellite data. |
| </p> |
| </div> |
| """ |
|
|
| async with httpx.AsyncClient() as client: |
| resp = await client.post( |
| "https://api.resend.com/emails", |
| headers={"Authorization": f"Bearer {RESEND_API_KEY}"}, |
| json={"from": FROM_EMAIL, "to": [to_email], "subject": f"MERLx Aperture: Analysis ready — {aoi_name}", "html": html}, |
| ) |
| return resp.status_code == 200 |
|
|