mirror of
https://github.com/idrainformatica/PecFlow.git
synced 2026-06-16 20:55:41 +02:00
74 lines
2.3 KiB
Python
74 lines
2.3 KiB
Python
"""
|
||
WhatsApp sender (worker) – Meta Cloud API v18.
|
||
|
||
Copia del sender backend: i due container sono separati.
|
||
"""
|
||
|
||
import httpx
|
||
|
||
META_GRAPH_API_URL = "https://graph.facebook.com/v18.0"
|
||
DEFAULT_TIMEOUT = 10.0
|
||
|
||
|
||
class WhatsAppError(Exception):
|
||
def __init__(self, message: str, http_status: int | None = None, api_code: int | None = None):
|
||
super().__init__(message)
|
||
self.http_status = http_status
|
||
self.api_code = api_code
|
||
|
||
|
||
async def send_whatsapp_message(
|
||
phone_number_id: str,
|
||
to_phone: str,
|
||
text: str,
|
||
access_token: str,
|
||
timeout: float = DEFAULT_TIMEOUT,
|
||
) -> dict:
|
||
"""
|
||
Invia un messaggio di testo WhatsApp via Meta Cloud API.
|
||
|
||
Raises:
|
||
WhatsAppError: in caso di errore HTTP o risposta API non-ok
|
||
"""
|
||
url = f"{META_GRAPH_API_URL}/{phone_number_id}/messages"
|
||
payload = {
|
||
"messaging_product": "whatsapp",
|
||
"to": to_phone.replace(" ", "").replace("-", ""),
|
||
"type": "text",
|
||
"text": {"body": text},
|
||
}
|
||
headers = {
|
||
"Authorization": f"Bearer {access_token}",
|
||
"Content-Type": "application/json",
|
||
}
|
||
|
||
async with httpx.AsyncClient(timeout=timeout) as client:
|
||
try:
|
||
response = await client.post(url, json=payload, headers=headers)
|
||
except httpx.TimeoutException as exc:
|
||
raise WhatsAppError(f"Timeout WhatsApp API dopo {timeout}s") from exc
|
||
except httpx.RequestError as exc:
|
||
raise WhatsAppError(f"Errore di rete WhatsApp: {exc}") from exc
|
||
|
||
if response.status_code == 401:
|
||
raise WhatsAppError("Token Meta non valido o scaduto", http_status=401)
|
||
|
||
if response.status_code >= 400:
|
||
try:
|
||
err_data = response.json()
|
||
err_msg = err_data.get("error", {}).get("message", response.text[:200])
|
||
err_code = err_data.get("error", {}).get("code")
|
||
except Exception:
|
||
err_msg = response.text[:200]
|
||
err_code = None
|
||
raise WhatsAppError(
|
||
f"Meta API errore HTTP {response.status_code}: {err_msg}",
|
||
http_status=response.status_code,
|
||
api_code=err_code,
|
||
)
|
||
|
||
data = response.json()
|
||
messages = data.get("messages", [])
|
||
message_id = messages[0].get("id") if messages else None
|
||
return {"message_id": message_id, "http_status": response.status_code}
|