name: comercialrs-meta-whatsapp-button-fix
description: Fix WhatsApp button clicks updating the wrong meeting in ComercialRS β encode task_id in button payload
ComercialRS β Meta WhatsApp Button Click Bug Fix
Problem
When a corretor clicks a button (Iniciada/ConcluΓda/Remarketing) on WhatsApp, the wrong meeting is updated. The confirmation shows a different meeting name than the one clicked.
Root Cause
WhatsApp button clicks do NOT send context.id β only payload (button text) and phone.
The old code searched find_tasks_by_phone_and_status() ordered by due_date ASC NULLS LAST, so it always picked the meeting with the OLDEST due date, not the one that was clicked.
Solution: Embed task_id in Button Payload
1. When sending messages with buttons, use payload format:
`
PAYLOAD_STATUS|TASK_ID
`
Example payloads sent to WhatsApp:
- -
in_progress|aa7ad6c3-6371-4ef8-ab22-993d97fae572 - -
completed|aa7ad6c3-6371-4ef8-ab22-993d97fae572 - -
remarketing|aa7ad6c3-6371-4ef8-ab22-993d97fae572 - - PID: 1121352, Port: 8083
- - Log:
/var/log/meta_webhook.log - - Syntax validated:
β Syntax OK - -
/var/www/comercialrs/data/β only receiver code found - -
/var/www/comercialrs/dist/assets/*.jsβ button UI code found, not sender API calls - -
task_alerts.pyβ sends reminder messages, NOT meeting button messages - -
/var/www/comercialrs/data/meta_webhook_vps.pyβ reference copy (patched) - -
/var/www/comercialrs/data/meta_webhook_vps_service.pyβ LIVE running service (patched, PID 1121352) - - Button clicks send ONLY:
payload(text) +phone+from - - NO
context.id(the original message ID is NOT forwarded) - - Workaround: encode
task_iddirectly in the payload string
2. In meta_webhook_vps.py, parse the payload:
`python
if msg_type == 'button' and button_payload:
parts = button_payload.split('|')
if len(parts) == 2:
button_status, task_id = parts
# Direct update β no need to search by phone+status
if button_status in BUTTON_STATUSES:
update_task_status(task_id, status_map[button_status])
...
return
# Fallback: old payload without task_id (for legacy buttons)
# Use find_tasks_by_phone_and_status with ORDER BY created_at DESC
`
3. Also fix the fallback ordering:
When legacy payload (no task_id) is detected, order by created_at DESC instead of due_date ASC:
`sql
ORDER BY created_at DESC
`
This picks the most recently created task, which is more likely the one that was clicked.
Receiver Implementation (DONE)
Both files have been patched with:
1. parse_button_payload(payload) β splits status|TASK_ID, validates UUID format
2. get_task_by_id_direct(task_id) β direct task lookup by UUID
3. Button handler updated to route based on payload format
`python
In meta_webhook_vps_service.py:
def parse_button_payload(payload):
"""Returns (status, task_id) or (None, None)"""
if not payload or '|' not in payload:
return None, None
parts = payload.split('|', 1)
if len(parts) != 2:
return None, None
button_status, task_id = parts
if button_status not in BUTTON_STATUSES:
return None, None
# task_id must be β₯32 chars and UUID-like
if len(task_id) < 32:
return None, None
return button_status, task_id
`
Live service status:
Sender Code β NOT FOUND (BLOCKED)
Critical gap: The code that SENDS messages with buttons to WhatsApp was not found on the VPS.
Searched in:
Possible sender locations (not confirmed):
1. Supabase Edge Function (e.g., dispatch-automation) β sends via graph.facebook.com
2. n8n workflow β separate automation system
3. Frontend Nuxt app β sends via Supabase Edge Function or API
4. External service β not on this VPS
The receiver fix alone does NOT fix the problem. Existing buttons in the wild still have plain payloads (no task_id). New buttons must be sent with |TASK_ID appended to each button payload.
Fallback Fix (DONE)
When legacy payload (no task_id) is detected, the code now orders by created_at DESC instead of due_date ASC β picks the most recently created task, more likely the one clicked.
Files
Key Discovery
WhatsApp Meta API Button Payload limitations:
Verification
`bash
Check service is running
ps aux | grep meta_webhook | grep -v grep
Check port binding
ss -tlnp | grep 8083
Check recent button clicks
grep -a "button\|parse_button\|find_task\|Task.*->" /var/log/meta_webhook.log | tail -30
Syntax check a file before deploying
/usr/bin/python3 -m py_compile /var/www/comercialrs/data/meta_webhook_vps_service.py
Reload service after changes
kill -HUP
If hung on port: fuser 8083/tcp to find PID, then kill -9
`
Root Cause (Updated β June 2026)
Two separate bugs can cause wrong meeting updates:
Bug 1: task_id always NULL in message_log (THIS SESSION)
When dispatch-automation sends WhatsApp, logMessageSent is called with taskId = null (line ~273):
`typescript
logMessageSent(serviceKey, result.messageId, null, member.id, templateName, member.phone)
// ^^^^ NULL!
`
Result: ALL message_log records have task_id = null. When webhook receives reply and calls get_task_by_meta_message_id, it returns nothing β no update happens. The confirmation "β
ReuniΓ£o atualizada" is sent but the task never changes.
Bug 2: Legacy button payloads (no task_id) β prior session
WhatsApp button clicks send only payload + phone, not context.id. Old payload format in_progress has no task_id β fallback find_tasks_by_phone_and_status picks oldest task by due_date ASC.
Both bugs can coexist. Fix both:
1. Fix task_id null in dispatch-automation (this session β line 276)
2. Fix button payload format to embed task_id (prior skill)
3. Fix fallback ordering to created_at DESC (prior skill)
Critical discovery
The RPC get_task_by_meta_message_id relies on message_log.task_id being populated. If it is NULL, the lookup succeeds but returns task_status=NULL and the update fails silently. Check message_log.task_id before assuming the RPC is working.
Verification
`bash
Check if task_id is NULL in recent message_log records
curl -s -X POST "https://api.supabase.com/v1/projects/dauftiqcvgaydddoxqhh/database/query" \
-H "Authorization: Bearer sbp_REDACTED" \
-H "Content-Type: application/json" \
--data-raw '{"query": "SELECT task_id IS NULL as is_null, count(*) FROM message_log GROUP BY is_null ORDER BY is_null;"}'
If all recent records have task_id=null β Bug 1 confirmed
Fix: dispatch-automation/index.ts line ~276, change null -> taskId variable
`
Next Steps
1. Find where meeting button messages are SENT (Supabase Edge Function or n8n)
2. Update sender to append |TASK_ID to each button payload
3. Test: send a meeting reminder with new format buttons, click a button, verify correct meeting name in confirmation