From 2b3af18db27fb33fdc3f73a41d697aedb9f6700a Mon Sep 17 00:00:00 2001 From: Alejandro Pirola Date: Sun, 12 May 2024 04:06:33 -0300 Subject: [PATCH 1/3] Fix Whatsapp message hook enpoint fixed a reference error in endpoint hook. ``` self.instance.xxxx ``` references. Improve error handling and logging --- whatsapp/__init__.py | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/whatsapp/__init__.py b/whatsapp/__init__.py index fb36e6b..37f8b1f 100644 --- a/whatsapp/__init__.py +++ b/whatsapp/__init__.py @@ -5,7 +5,7 @@ import requests import logging -from fastapi import FastAPI, Request +from fastapi import FastAPI, HTTPException, Request from uvicorn import run as _run from .constants import VERSION from . import ext @@ -16,7 +16,7 @@ from .ext._media import upload_media, query_media_url, download_media, delete_media from .ext._buttons import send_button, create_button, send_reply_button from .ext._static import is_message, get_mobile, get_author, get_name, get_message, get_message_id, get_message_type, get_message_timestamp, get_audio, get_delivery, get_document, get_image, get_interactive_response, get_location, get_video, changed_field - +import json class WhatsApp(object): def __init__(self, token: str = "", phone_number_id: str = "", logger: bool = True, update_check: bool = True): @@ -71,6 +71,7 @@ def __init__(self, token: str = "", phone_number_id: str = "", logger: bool = Tr self.phone_number_id = phone_number_id self.base_url = "https://graph.facebook.com/v18.0" self.url = f"{self.base_url}/{phone_number_id}/messages" + async def base(*args): pass @@ -104,19 +105,32 @@ async def verify_endpoint(r: Request): @self.app.post("/") async def hook(r: Request): - # Handle Webhook Subscriptions - data = await r.json() - if data is None: - return {"success": False} - logging.info("Received webhook data: %s", data) - changed_field = self.instance.changed_field(data) - if changed_field == "messages": - new_message = self.instance.is_message(data) - if new_message: - msg = Message(instance=self.instance, data=data) - await self.message_handler(msg) - await self.other_handler(msg) - return {"success": True} + try: + # Handle Webhook Subscriptions + data = await r.json() + if data is None: + return {"success": False} + logging.info("Received webhook data: %s", data) + data_str = json.dumps(data, indent=4) + logging.debug(f"Received webhook data: {data_str}") + + changed_field = self.changed_field(data) + if changed_field == "messages": + new_message = self.is_message(data) + if new_message: + msg = Message(instance=self, data=data) + await self.message_handler(msg) + await self.other_handler(msg) + return {"success": True} + except Exception as e: + logging.error(f"Error parsing message: {e}") + raise HTTPException(status_code=500, detail={ + "success": False, + "error": str(e) + }) + + + # all the files starting with _ are imported here, and should not be imported directly. From 3adc73191f4448768bec6affab433cd11c3149c7 Mon Sep 17 00:00:00 2001 From: Alejandro Pirola Date: Sun, 12 May 2024 04:09:18 -0300 Subject: [PATCH 2/3] fix verify_token in verify endpoint The method incorrectly compared the verification token with the WhatsApp token. To solve this, a new parameter was added to the WhatsApp constructor called verify_token. The endpoint was modified to compare with that token. --- whatsapp/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/whatsapp/__init__.py b/whatsapp/__init__.py index 37f8b1f..fd799e4 100644 --- a/whatsapp/__init__.py +++ b/whatsapp/__init__.py @@ -19,7 +19,7 @@ import json class WhatsApp(object): - def __init__(self, token: str = "", phone_number_id: str = "", logger: bool = True, update_check: bool = True): + def __init__(self, token: str = "", phone_number_id: str = "", logger: bool = True, update_check: bool = True, verify_token: str = ""): """ Initialize the WhatsApp Object @@ -71,6 +71,7 @@ def __init__(self, token: str = "", phone_number_id: str = "", logger: bool = Tr self.phone_number_id = phone_number_id self.base_url = "https://graph.facebook.com/v18.0" self.url = f"{self.base_url}/{phone_number_id}/messages" + self.verify_token = verify_token async def base(*args): @@ -92,7 +93,7 @@ async def base(*args): @self.app.get("/") async def verify_endpoint(r: Request): - if r.query_params.get("hub.verify_token") == self.token: + if r.query_params.get("hub.verify_token") == self.verify_token: logging.info("Verified webhook") challenge = r.query_params.get("hub.challenge") self.verification_handler(challenge) From b85004beff7693b3a2ce859ad6103415a0e179e7 Mon Sep 17 00:00:00 2001 From: Alejandro Pirola Date: Sun, 12 May 2024 04:16:01 -0300 Subject: [PATCH 3/3] add missing requirements Add requests and python-dotenv missing package requirements --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5e0ecdb..b3cb398 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ classifiers=[ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", ] -dependencies = ["fastapi", "unicorn","requests_toolbelt"] +dependencies = ["fastapi", "unicorn","requests_toolbelt", "requests", "python-dotenv"] [project.urls] "Homepage" = "https://github.com/filipporomani/whatsapp"