""" Brevo (ex-Sendinblue) integration. - Send transactional confirmation emails - Sync confirmed contacts to a Brevo list """ import logging import httpx from app.config import settings logger = logging.getLogger(__name__) BREVO_API = "https://api.brevo.com/v3" def _headers() -> dict[str, str]: return { "api-key": settings.BREVO_API_KEY, "Content-Type": "application/json", "Accept": "application/json", } async def send_confirmation_email(email: str, confirm_url: str, unsubscribe_url: str = "") -> bool: """Send a double opt-in confirmation email. Returns True on success.""" if not settings.brevo_configured: logger.warning("Brevo not configured — skipping confirmation email for %s***", email[:3]) return False payload = { "sender": { "name": settings.BREVO_SENDER_NAME, "email": settings.BREVO_SENDER_EMAIL, }, "to": [{"email": email}], "subject": "Confirm your spot on the adiuvAI waitlist", "htmlContent": _confirmation_html(confirm_url, unsubscribe_url), } try: async with httpx.AsyncClient(timeout=10) as client: resp = await client.post(f"{BREVO_API}/smtp/email", headers=_headers(), json=payload) resp.raise_for_status() logger.info("Confirmation email sent to %s***", email[:3]) return True except httpx.HTTPError: logger.exception("Failed to send confirmation email to %s***", email[:3]) return False async def add_contact_to_list(email: str) -> bool: """Add a confirmed contact to the Brevo waitlist list. Returns True on success.""" if not settings.brevo_configured: logger.warning("Brevo not configured — skipping contact sync for %s***", email[:3]) return False if settings.BREVO_LIST_ID == 0: logger.warning("BREVO_LIST_ID not set — skipping contact sync") return False payload = { "email": email, "listIds": [settings.BREVO_LIST_ID], "updateEnabled": True, } try: async with httpx.AsyncClient(timeout=10) as client: resp = await client.post(f"{BREVO_API}/contacts", headers=_headers(), json=payload) resp.raise_for_status() logger.info("Contact synced to Brevo list %d: %s***", settings.BREVO_LIST_ID, email[:3]) return True except httpx.HTTPError: logger.exception("Failed to sync contact to Brevo: %s***", email[:3]) return False def _confirmation_html(confirm_url: str, unsubscribe_url: str = "") -> str: """Email template aligned with the adiuvAI landing page brand.""" return f"""\ Confirm your spot — adiuvAI
Confirm your email to secure your early access spot on the adiuvAI waitlist.
 
adiuvAI
● One more step

Confirm your spot on
the waitlist

Thanks for signing up! Please confirm your email address so we can keep you in the loop when adiuvAI launches.

Confirm my email

This link expires in {settings.CONFIRM_TOKEN_EXPIRY_HOURS} hours.

 

If you didn't sign up, simply ignore this email.

adiuvai.com {f' · Unsubscribe' if unsubscribe_url else ''}

"""