97 lines
3.4 KiB
Python
97 lines
3.4 KiB
Python
import logging
|
|
from typing import Any
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from .models import WhatsAppWebhookEvent
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _extract_events(payload: dict[str, Any]) -> list[dict[str, Any]]:
|
|
events: list[dict[str, Any]] = []
|
|
if payload.get("object") != "whatsapp_business_account":
|
|
return events
|
|
|
|
for entry in payload.get("entry", []):
|
|
waba_id = entry.get("id")
|
|
for change in entry.get("changes", []):
|
|
field = change.get("field", "unknown")
|
|
value = change.get("value", {})
|
|
phone_number_id = (value.get("metadata") or {}).get("phone_number_id")
|
|
|
|
if field == "messages":
|
|
for message in value.get("messages", []):
|
|
events.append(
|
|
{
|
|
"waba_id": waba_id,
|
|
"phone_number_id": phone_number_id,
|
|
"field": field,
|
|
"event_type": "message",
|
|
"from_wa_id": message.get("from"),
|
|
"message_id": message.get("id"),
|
|
"status": message.get("type"),
|
|
"payload": change,
|
|
}
|
|
)
|
|
for status in value.get("statuses", []):
|
|
events.append(
|
|
{
|
|
"waba_id": waba_id,
|
|
"phone_number_id": phone_number_id,
|
|
"field": field,
|
|
"event_type": "status",
|
|
"from_wa_id": status.get("recipient_id"),
|
|
"message_id": status.get("id"),
|
|
"status": status.get("status"),
|
|
"payload": change,
|
|
}
|
|
)
|
|
else:
|
|
events.append(
|
|
{
|
|
"waba_id": waba_id,
|
|
"phone_number_id": phone_number_id,
|
|
"field": field,
|
|
"event_type": field,
|
|
"from_wa_id": None,
|
|
"message_id": None,
|
|
"status": None,
|
|
"payload": change,
|
|
}
|
|
)
|
|
return events
|
|
|
|
|
|
def persist_webhook_payload(db: Session, payload: dict[str, Any]) -> int:
|
|
events = _extract_events(payload)
|
|
if not events:
|
|
events = [
|
|
{
|
|
"waba_id": None,
|
|
"phone_number_id": None,
|
|
"field": "unknown",
|
|
"event_type": "raw",
|
|
"from_wa_id": None,
|
|
"message_id": None,
|
|
"status": None,
|
|
"payload": payload,
|
|
}
|
|
]
|
|
|
|
for event in events:
|
|
db.add(
|
|
WhatsAppWebhookEvent(
|
|
waba_id=event.get("waba_id"),
|
|
phone_number_id=event.get("phone_number_id"),
|
|
field=event["field"],
|
|
event_type=event["event_type"],
|
|
from_wa_id=event.get("from_wa_id"),
|
|
message_id=event.get("message_id"),
|
|
status=event.get("status"),
|
|
payload=event["payload"],
|
|
)
|
|
)
|
|
db.commit()
|
|
logger.info("Stored %s WhatsApp webhook event(s)", len(events))
|
|
return len(events)
|