You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.7 KiB
Python
85 lines
2.7 KiB
Python
import httpx
|
|
|
|
from app.core.settings import settings
|
|
|
|
|
|
class IntegrationProviderError(RuntimeError):
|
|
"""Erro de transporte ou configuracao em providers externos."""
|
|
|
|
|
|
class BrevoEmailProvider:
|
|
provider_name = "brevo_email"
|
|
|
|
def __init__(self) -> None:
|
|
self.base_url = str(settings.brevo_base_url or "https://api.brevo.com/v3").rstrip("/")
|
|
self.api_key = str(settings.brevo_api_key or "").strip()
|
|
self.sender_email = str(settings.brevo_sender_email or "").strip()
|
|
self.sender_name = str(settings.brevo_sender_name or "Orquestrador").strip() or "Orquestrador"
|
|
self.timeout_seconds = max(1, int(settings.brevo_request_timeout_seconds or 10))
|
|
|
|
def is_configured(self) -> bool:
|
|
return bool(self.api_key and self.sender_email)
|
|
|
|
async def send_email(
|
|
self,
|
|
*,
|
|
to_email: str,
|
|
to_name: str | None,
|
|
subject: str,
|
|
body: str,
|
|
tags: list[str] | None = None,
|
|
) -> dict:
|
|
if not self.is_configured():
|
|
raise IntegrationProviderError(
|
|
"Brevo nao configurado. Defina BREVO_API_KEY e BREVO_SENDER_EMAIL para enviar emails."
|
|
)
|
|
|
|
payload = {
|
|
"sender": {
|
|
"email": self.sender_email,
|
|
"name": self.sender_name,
|
|
},
|
|
"to": [
|
|
{
|
|
"email": str(to_email or "").strip(),
|
|
**({"name": str(to_name).strip()} if str(to_name or "").strip() else {}),
|
|
}
|
|
],
|
|
"subject": str(subject or "").strip(),
|
|
"textContent": str(body or "").strip(),
|
|
}
|
|
if tags:
|
|
payload["tags"] = [str(tag).strip() for tag in tags if str(tag).strip()]
|
|
|
|
headers = {
|
|
"accept": "application/json",
|
|
"content-type": "application/json",
|
|
"api-key": self.api_key,
|
|
}
|
|
|
|
try:
|
|
async with httpx.AsyncClient(timeout=self.timeout_seconds) as client:
|
|
response = await client.post(
|
|
f"{self.base_url}/smtp/email",
|
|
headers=headers,
|
|
json=payload,
|
|
)
|
|
except httpx.HTTPError as exc:
|
|
raise IntegrationProviderError(f"Falha ao enviar email via Brevo: {exc}") from exc
|
|
|
|
if response.status_code >= 400:
|
|
raise IntegrationProviderError(
|
|
f"Brevo retornou erro {response.status_code}: {response.text[:300]}"
|
|
)
|
|
|
|
try:
|
|
data = response.json()
|
|
except ValueError:
|
|
data = {}
|
|
|
|
return {
|
|
"provider": self.provider_name,
|
|
"message_id": data.get("messageId"),
|
|
"response": data,
|
|
}
|