i messed up, lmao
Browse files
routes/api/whatsapp_webhook.py
CHANGED
@@ -24,9 +24,68 @@ router = APIRouter()
|
|
24 |
classifier = ZeroShotClassifier()
|
25 |
|
26 |
def _extract_from_number_and_text(payload: dict) -> Tuple[Optional[str], Optional[str]]:
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
@router.post("/message-received")
|
32 |
async def whatsapp_webhook_receiver(request: Request):
|
|
|
24 |
classifier = ZeroShotClassifier()
|
25 |
|
26 |
def _extract_from_number_and_text(payload: dict) -> Tuple[Optional[str], Optional[str]]:
|
27 |
+
"""
|
28 |
+
Extracts (from_number, message_text) from a WhatsApp webhook payload.
|
29 |
+
Returns (None, None) if not a user message (e.g., statuses, billing-event).
|
30 |
+
"""
|
31 |
+
try:
|
32 |
+
entries = payload.get("entry", [])
|
33 |
+
for entry in entries:
|
34 |
+
changes = entry.get("changes", [])
|
35 |
+
for change in changes:
|
36 |
+
field = change.get("field")
|
37 |
+
# Only process message-type changes
|
38 |
+
if field != "messages":
|
39 |
+
continue
|
40 |
+
|
41 |
+
value = change.get("value", {}) or {}
|
42 |
+
# Ignore pure status/billing updates that don't have 'messages'
|
43 |
+
messages_list = value.get("messages", [])
|
44 |
+
if not messages_list:
|
45 |
+
# Helpful debug so you can see why it was ignored
|
46 |
+
statuses = value.get("statuses", [])
|
47 |
+
if statuses:
|
48 |
+
# it's a status webhook, not a user message
|
49 |
+
pass
|
50 |
+
continue
|
51 |
+
|
52 |
+
# Only look at the first message in the list
|
53 |
+
msg = messages_list[0]
|
54 |
+
from_number = msg.get("from")
|
55 |
+
mtype = msg.get("type")
|
56 |
+
|
57 |
+
# 1) Plain text
|
58 |
+
if mtype == "text":
|
59 |
+
text_body = (msg.get("text", {}) or {}).get("body")
|
60 |
+
if from_number and text_body:
|
61 |
+
return from_number, text_body
|
62 |
+
|
63 |
+
# 2) Template reply button (older/simple schema)
|
64 |
+
if mtype == "button":
|
65 |
+
b = msg.get("button", {}) or {}
|
66 |
+
intent = b.get("payload") or b.get("text")
|
67 |
+
if from_number and intent:
|
68 |
+
return from_number, intent
|
69 |
+
|
70 |
+
# 3) Newer interactive replies (buttons or list)
|
71 |
+
if mtype == "interactive":
|
72 |
+
i = msg.get("interactive", {}) or {}
|
73 |
+
if "button_reply" in i:
|
74 |
+
intent = i["button_reply"].get("id") or i["button_reply"].get("title")
|
75 |
+
if from_number and intent:
|
76 |
+
return from_number, intent
|
77 |
+
if "list_reply" in i:
|
78 |
+
intent = i["list_reply"].get("id") or i["list_reply"].get("title")
|
79 |
+
if from_number and intent:
|
80 |
+
return from_number, intent
|
81 |
+
|
82 |
+
# No usable user message found
|
83 |
+
return None, None
|
84 |
+
|
85 |
+
except Exception as e:
|
86 |
+
# Always return a tuple on error
|
87 |
+
logging.exception(f"_extract_from_number_and_text error: {e}")
|
88 |
+
return None, None
|
89 |
|
90 |
@router.post("/message-received")
|
91 |
async def whatsapp_webhook_receiver(request: Request):
|