diff --git a/pywa/types/callback.py b/pywa/types/callback.py index 3eee0953..94bcf9d3 100644 --- a/pywa/types/callback.py +++ b/pywa/types/callback.py @@ -258,14 +258,14 @@ class CallbackButton(BaseUserUpdate, Generic[_CallbackDataT]): type: The message type (:class:`MessageType.INTERACTIVE` for :class:`~pywa.types.callback.Button` presses or :class:`MessageType.BUTTON` for :class:`~pywa.types.templates.QuickReplyButton` clicks). from_user: The user who sent the message. timestamp: The timestamp when the message was sent (in UTC). - reply_to_message: The message to which this callback button is a reply to. + reply_to_message: The message to which this callback button is a reply to. ``None`` when a template :class:`~pywa.types.templates.QuickReplyButton` is clicked (WhatsApp omits the ``context`` field for template ``button`` messages). data: The data of the button (the ``callback_data`` parameter you provided in :class:`~pywa.types.callback.Button` or :class:`~pywa.types.templates.QuickReplyButton`). title: The title of the button. shared_data: Shared data between handlers. """ type: MessageType - reply_to_message: ReplyToMessage + reply_to_message: ReplyToMessage | None data: _CallbackDataT title: str @@ -286,6 +286,7 @@ def from_update(cls, client: "WhatsApp", update: RawUpdate) -> "CallbackButton": data = msg["button"]["payload"] case _: raise ValueError(f"Invalid message type {msg_type}") + context = msg.get("context", {}) return cls( _client=client, raw=update, @@ -295,7 +296,9 @@ def from_update(cls, client: "WhatsApp", update: RawUpdate) -> "CallbackButton": type=MessageType(msg_type), from_user=client._usr_cls.from_contact(value["contacts"][0], client=client), timestamp=helpers.timestamp_to_datetime(msg["timestamp"]), - reply_to_message=ReplyToMessage.from_dict(msg["context"]), + reply_to_message=ReplyToMessage.from_dict(context) + if context.get("id") + else None, data=data, title=title, ) diff --git a/pywa_async/types/callback.py b/pywa_async/types/callback.py index bf5b3a74..cdfae938 100644 --- a/pywa_async/types/callback.py +++ b/pywa_async/types/callback.py @@ -46,7 +46,7 @@ class CallbackButton(BaseUserUpdateAsync, _CallbackButton[_CallbackDataT]): type: The message type (:class:`MessageType.INTERACTIVE` for :class:`~pywa.types.callback.Button` presses or :class:`MessageType.BUTTON` for :class:`~pywa.types.templates.QuickReplyButton` clicks). from_user: The user who sent the message. timestamp: The timestamp when the message was sent (in UTC). - reply_to_message: The message to which this callback button is a reply to. + reply_to_message: The message to which this callback button is a reply to. ``None`` when a template :class:`~pywa.types.templates.QuickReplyButton` is clicked (WhatsApp omits the ``context`` field for template ``button`` messages). data: The data of the button (the ``callback_data`` parameter you provided in :class:`~pywa.types.callback.Button` or :class:`~pywa.types.templates.QuickReplyButton`). title: The title of the button. shared_data: Shared data between handlers. diff --git a/tests/data/updates/callback_button.json b/tests/data/updates/callback_button.json index bc69fa45..6928a60c 100644 --- a/tests/data/updates/callback_button.json +++ b/tests/data/updates/callback_button.json @@ -93,5 +93,48 @@ ] } ] + }, + "quick_reply_without_context": { + "object": "whatsapp_business_account", + "entry": [ + { + "id": "5467539754836534", + "changes": [ + { + "value": { + "messaging_product": "whatsapp", + "metadata": { + "display_phone_number": "972123456789", + "phone_number_id": "1122334455667" + }, + "contacts": [ + { + "profile": { + "name": "Test Name" + }, + "wa_id": "972987654321", + "user_id": "US.13491208655302741918", + "parent_user_id": "US.ENT.11815799212886844830" + } + ], + "messages": [ + { + "from": "972987654321", + "from_user_id": "US.13491208655302741918", + "id": "wamid.xsidjx", + "timestamp": "1698269027", + "type": "button", + "button": { + "payload": "callback_data", + "text": "title" + } + } + ] + }, + "field": "messages" + } + ] + } + ] } } diff --git a/tests/test_updates.py b/tests/test_updates.py index 59edce54..f7f4f3fd 100644 --- a/tests/test_updates.py +++ b/tests/test_updates.py @@ -66,8 +66,18 @@ "media_with_url": [lambda m: m.media.url is not None], }, "callback_button": { - "button": [lambda b: b.type == MessageType.INTERACTIVE], - "quick_reply": [lambda b: b.type == MessageType.BUTTON], + "button": [ + lambda b: b.type == MessageType.INTERACTIVE, + lambda b: b.reply_to_message is not None, + ], + "quick_reply": [ + lambda b: b.type == MessageType.BUTTON, + lambda b: b.reply_to_message is not None, + ], + "quick_reply_without_context": [ + lambda b: b.type == MessageType.BUTTON, + lambda b: b.reply_to_message is None, + ], }, "callback_selection": { "callback": [lambda s: s.data is not None],