--- name: WhatsApp Chat - Contatos sumindo apos encerramento description: Filtro da sidebar esconde contatos que o atendente atendeu apos encerrar. Corrigido mantendo historico via last_attended_by. type: project originSessionId: 717f106c-cb9a-4b0e-bbff-97d35eddf122 --- # WhatsApp Chat - Contatos sumindo da sidebar do atendente (CORRIGIDO 2026-04-24) ## Sintoma Erick (e demais atendentes nao-admin) reclamaram que contatos "sumiam" da sidebar apos algum tempo, mesmo os que foram criados ou atendidos por ele. ## Causa raiz Tres problemas no fluxo: 1. **`salvarContato()`** nao setava `ultimo_contato` nem `last_attended_by` na criacao. 2. **Cron `autoEncerrar()`** (a cada 15min) zera `assigned_to`, move atendente para `last_attended_by`, e insere mensagem outgoing `[Atendimento encerrado automaticamente]`. 3. **Filtro PHP em `listarContatos()`** so mostrava sem_dono se `last_direction === 'incoming'`. Como o encerramento insere mensagem outgoing, contatos encerrados viravam invisiveis para quem os atendeu. ## Fix aplicado - `app/Controllers/WhatsAppChat.php`: - `salvarContato()` agora seta `last_attended_by` e `ultimo_contato` no insert - `listarContatos()` marca flag `atendi_por_ultimo` quando `last_attended_by == userId` - Nova regra no filtro: se `atendi_por_ultimo && sem_dono` → mostra (historico meu) - `app/Models/WhatsappContactModel.php`: - `getContactsWithLastMessage()` ja retornava via SQL (`orWhere('last_attended_by', $assignedTo)`) - Agora `atendente_nome` usa `last_attended_by` como fallback quando `assigned_to` e NULL, para renderizar "Encerrado - NOME" corretamente ## Regra atual (não-admin) Contato visivel se: - `assigned_to = eu` (meu atendimento ativo) - `created_by = eu` (eu criei) - `last_attended_by = eu AND assigned_to IS NULL` (historico meu apos encerramento) - `assigned_to IS NULL AND last_direction = incoming` (aguardando + tem permissao wa_ver_sem_dono) **Some apenas** quando outro atendente puxa/transfere (assigned_to vai para outro usuario). ## Arquivos - `app/Controllers/WhatsAppChat.php:300-327` — salvarContato - `app/Controllers/WhatsAppChat.php:354-400` — listarContatos (filtro) - `app/Models/WhatsappContactModel.php:74-87` — atendente_nome com fallback ## Extra (mesma sessao): Mensagens `[messageContextInfo]` no chat Baileys enviava tipos puramente de metadados (`messageContextInfo`, `senderKeyDistributionMessage`, `protocolMessage`, `stickerSyncRmrMessage`, `keepInChatMessage`, `encReactionMessage`) que caiam no `extractTextFromUnknownMessage()` e eram salvas como `[messageContextInfo]` etc, poluindo o chat. **Fix**: em `WhatsApp.php` (`processarMensagemIndividual` linha ~968 e `processarMensagemGrupo` linha ~1390), logo apos ler `$messageType`, faz `return` se estiver em `$metadataOnlyTypes`. Limpeza: DELETE de 68 mensagens-lixo ja salvas no banco (18 messageContextInfo + 50 protocolMessage). ## Extra 2 (2026-04-24): Auto-atribuicao ao enviar Atendente podia responder em um contato `sem_dono` (ex: apos auto-encerramento) sem "puxar" explicitamente. Resultado: ao cliente responder, o contato aparecia como "Aguardando" mesmo com atendente conversando. **Fix**: helper privado `autoAtribuirContato($sessionId, $phone)` aplicado em `enviarMensagem`, `enviarArquivo`, `enviarAudio`, `responderMensagem`. Se `assigned_to` estiver vazio, seta para `session('id_usuario')` + `last_attended_by = mesmo id`. Tambem atualiza `ultimo_contato` (centralizado). Caso real: SS Qualitá (id 488) — Valeria transferida → encerrou 14:10 → voltou a digitar 14:20 sem puxar → cliente respondeu 14:22 → ficou "aguardando". Agora atribui automaticamente.