Initial commit: CI Agent competitive-intelligence monitoring app
FastAPI + Celery + Next.js + Postgres/Redis app with company monitoring, source collection, LLM-based change analysis, enrichment, and account security (Turnstile, escalating lockout, email verification).
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
"""Resend HTTP API email provider - a separate transport from SmtpEmailProvider
|
||||
(which also happens to point at Resend's SMTP relay for alert notifications
|
||||
in this deployment, but that's a different concern/sender identity; see
|
||||
app/services/security_email_service.py). Fixed, trusted first-party vendor
|
||||
endpoint - no SSRF guard needed, same reasoning as the NinjaPear/USPTO calls
|
||||
elsewhere in this app.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import httpx
|
||||
|
||||
from app.core.config import Settings
|
||||
from app.core.logging import get_logger
|
||||
from app.notifications.base import DeliveryResult, NotificationMessage
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
_RESEND_API_URL = "https://api.resend.com/emails"
|
||||
|
||||
|
||||
class ResendEmailProvider:
|
||||
provider_name = "resend"
|
||||
|
||||
def __init__(self, settings: Settings) -> None:
|
||||
self._settings = settings
|
||||
|
||||
async def send(self, message: NotificationMessage) -> DeliveryResult:
|
||||
payload = {
|
||||
"from": self._settings.resend_security_from_email,
|
||||
"to": [message.destination_value],
|
||||
"subject": message.subject,
|
||||
"text": message.body_text,
|
||||
}
|
||||
if message.body_html:
|
||||
payload["html"] = message.body_html
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=10) as client:
|
||||
response = await client.post(
|
||||
_RESEND_API_URL,
|
||||
headers={"Authorization": f"Bearer {self._settings.resend_api_key}"},
|
||||
json=payload,
|
||||
)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return DeliveryResult(success=True, external_message_id=data.get("id"))
|
||||
except Exception as exc: # noqa: BLE001 - network/API failure path
|
||||
logger.error("resend_send_failed", error=str(exc))
|
||||
return DeliveryResult(success=False, error=str(exc))
|
||||
Reference in New Issue
Block a user