Repository navigation
Business messages: answerable buttons (reply, interactive quick reply, list rows, template) in the Tab order - #569
Merged
gabrielhhaber merged 4 commits intoOct 21, 2026
Conversation
…o e dizer o número Os botões de resposta (mensagens simples, interativas e de modelo) são enviados como o WhatsApp Web envia, por um endpoint novo reply-button; link, copiar e ligar são resolvidos na janela. Strings e changelog nos 7 idiomas e guia de uso. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The buttons of a business's message become real buttons under the message list, in the order of Tab, and tapping a reply button answers the business the way WhatsApp Web does. Until now these messages were only text with "options: ..." (and
buttonsMessagewas stored empty), so a screen-reader user could read the options but not answer them.How it works
core/business_buttons.pyreads them off the message the server serialized, in four shapes:dynamicReplyButtons(reply buttons of a plain message, the kind most bots send today),interactivePayload.buttons(interactive / native flow:quick_reply,cta_url,cta_copy,cta_call),hydratedButtons(template) andlist(each row of a list message). They are kept with the message asbusinessButtons(websocket_client.py).ui/conversation_panel/business_buttons.py(a new mixin, not more lines inmessage_list.py) shows onewx.Buttonper entry in the existing buttons container. A reply is sent once per tap (a second tap while it is on its way does nothing, a failure is never retried by itself) and the result is spoken. A link opens, a code is copied, a phone number is spoken. Nothing is sent to the server for those three.POST /api/:session/reply-button/:messageId(api_patches/.../buttonReplyController.ts, added to the three file lists). It runs in the page and calls what WhatsApp Web itself calls when the button is tapped, read over CDP:WAWebSendButtonsMsgReplyChatAction(message, button, chat)(abuttons_response);quick_reply:sendTextMsgToChatwith the label, quoting the message and carryingselectedIndex/selectedId, thenmarkInteractiveButtonClicked;list_responsewith the row's title, description and id, quoting the list;replyToButtonMessage.The id is validated, the index is bounded, the native error is never returned (it can carry a chat id or text), and nothing is retried: a send that threw may have reached the business.
Tested
Live, on a real account, with the code from this branch (
setup_api.pybuild, the app's ownPOST /reply-buttonreturned 200):quick_reply(Mercado Pago, "Consultar dívida"): sent as a reply that quotes the message, the business answered and the button was marked as used.Automatic:
tests/test_business_buttons.py(reading of every shape, what is not offered, the request contract, the one-tap rule, the stored field) andbuttonReplyController.test.ts(12 tests; the in-page function with fake WhatsApp Web modules, the route's refusals). The translation, changelog, guide and API-patch sync tests pass.Not tested live
hydratedButtons): no message of that kind was available. They go through WA-JS'sreplyToButtonMessage, covered by the unit test only.Notes
tests/test_call_audio_*andtest_call_*echo*fail in my environment becauselivekitis not installed there; unrelated.🤖 Generated with Claude Code