mirror of
https://github.com/idrainformatica/PecFlow.git
synced 2026-06-16 12:45:42 +02:00
Fix notification System
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
"""
|
||||
WhatsApp sender – Meta Cloud API v18.
|
||||
|
||||
Config non sensibile (config):
|
||||
{
|
||||
"phone_number_id": "123456789", # ID numero mittente Meta Business
|
||||
"to_phone": "+393331234567" # numero destinatario con prefisso
|
||||
}
|
||||
|
||||
Config sensibile (config_enc → config_secret):
|
||||
{ "access_token": "EAABs..." } # Meta Graph API token
|
||||
|
||||
API endpoint:
|
||||
POST https://graph.facebook.com/v18.0/{phone_number_id}/messages
|
||||
|
||||
Nota: richiede un account Meta Business verificato con WhatsApp Business API.
|
||||
"""
|
||||
|
||||
import httpx
|
||||
|
||||
META_GRAPH_API_URL = "https://graph.facebook.com/v18.0"
|
||||
DEFAULT_TIMEOUT = 10.0
|
||||
|
||||
|
||||
class WhatsAppError(Exception):
|
||||
"""Errore durante l'invio di un messaggio WhatsApp."""
|
||||
|
||||
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.
|
||||
|
||||
Args:
|
||||
phone_number_id: ID del numero WhatsApp Business mittente
|
||||
to_phone: numero destinatario (formato E.164, es. +393331234567)
|
||||
text: testo del messaggio
|
||||
access_token: Meta Graph API Bearer token
|
||||
timeout: timeout HTTP in secondi
|
||||
|
||||
Returns:
|
||||
dict con message_id dalla risposta 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}
|
||||
|
||||
|
||||
async def send_test_whatsapp(
|
||||
phone_number_id: str,
|
||||
to_phone: str,
|
||||
access_token: str,
|
||||
channel_name: str = "PEChub",
|
||||
) -> dict:
|
||||
"""Invia un messaggio WhatsApp di test per verificare la configurazione."""
|
||||
from datetime import datetime
|
||||
|
||||
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
text = (
|
||||
f"*PEChub – Test canale WhatsApp*\n\n"
|
||||
f"Il canale _{channel_name}_ e' configurato correttamente.\n\n"
|
||||
f"Data/ora: {ts}"
|
||||
)
|
||||
return await send_whatsapp_message(
|
||||
phone_number_id=phone_number_id,
|
||||
to_phone=to_phone,
|
||||
text=text,
|
||||
access_token=access_token,
|
||||
)
|
||||
Reference in New Issue
Block a user