feat: Replace mock WhatsApp with real Meta Graph API webhook

- POST /api/whatsapp/webhook handles Meta verification (hub.challenge)
- Inbound text messages create tickets via create_ticket()
- Auto-reply confirmation sent back via Meta Graph API
- WhatsApp messages logged with ticket linkage in whatsapp_log
- Added WHATSAPP_PHONE_NUMBER_ID, WHATSAPP_ACCESS_TOKEN, WHATSAPP_VERIFY_TOKEN config
- Kept /mock-log debug endpoint for backward compatibility
- Graceful degradation: logs message even if ticket/reply fails
This commit is contained in:
2026-07-24 20:07:30 -04:00
parent 3920cf14a1
commit 4afdc36765
4 changed files with 212 additions and 34 deletions
+6 -4
View File
@@ -1,4 +1,4 @@
"""WhatsApp log model for mock endpoint."""
"""WhatsApp log model for inbound webhook messages."""
from __future__ import annotations
@@ -14,10 +14,12 @@ class WhatsAppLog(Base):
__tablename__ = "whatsapp_log"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
command: Mapped[str] = mapped_column(Text, nullable=False)
from_number: Mapped[str | None] = mapped_column(String(50), nullable=True)
from_number: Mapped[str] = mapped_column(String(50), nullable=False)
message_text: Mapped[str] = mapped_column(Text, nullable=False)
wa_message_id: Mapped[str | None] = mapped_column(String(100), nullable=True)
ticket_id: Mapped[int | None] = mapped_column(Integer, nullable=True)
ticket_number: Mapped[str | None] = mapped_column(String(30), nullable=True)
received_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
def __repr__(self) -> str:
return f"<WhatsAppLog {self.id}: {self.command[:50]}>"
return f"<WhatsAppLog {self.id}: from={self.from_number} ticket={self.ticket_number}>"