Sistemas e Integrações

Como construímos um CRM jurídico com WhatsApp como canal principal

Um escritório de advocacia com 15 advogados, cada um com o próprio celular, cada um atendendo clientes pelo WhatsApp pessoal. Contratos em pasta compartilhada no Drive. Status de processos em planilha que ninguém atualizava. Esse era o estado da Adele antes de começarmos.

Por: Lixum LabsPublicado em 04/11/2025•3 min de leitura
Rede de pontos de luz conectados por linhas, representando as conversas de WhatsApp ligadas ao CRM

O problema real

O cliente ligava para o escritório perguntando sobre o processo. Ninguém sabia responder sem ligar para o advogado responsável. O advogado responsável estava em audiência. O cliente ficava sem resposta por horas.

O problema não era tecnologia. Era que cada advogado operava como uma ilha. O CRM ia ter que mudar esse comportamento sem exigir que ninguém mudasse de ferramenta — porque ninguém ia mudar de ferramenta.

A decisão central

WhatsApp Cloud API não como integração — como canal principal. Isso muda tudo.

Integração significa que você tem um sistema e o WhatsApp é uma saída. Canal principal significa que o WhatsApp é onde o atendimento acontece de verdade, e o sistema é o que organiza o que está chegando lá.

Escolhemos FastAPI + SQLModel no backend porque precisávamos de validação de schema rigorosa nos dados de processo. Cada mensagem recebida passa por um parser que tenta classificá-la: é sobre qual processo? É de qual cliente? É uma dúvida ou uma atualização?

O frontend em React ficou para o escritório — painel de casos, histórico de conversa por cliente, atribuição de responsável. O advogado continua respondendo pelo WhatsApp. O sistema apenas organiza o que está acontecendo.

# Classifier simplificado — versão de produção tem 3x mais regras
async def classify_message(msg: IncomingMessage) -> Classification:
    client = await db.get_client_by_phone(msg.from_number)
    if not client:
        return Classification(type="unknown_sender")

    open_cases = await db.get_open_cases(client.id)
    if len(open_cases) == 1:
        return Classification(
            type="case_update",
            case_id=open_cases[0].id,
            confidence=0.91
        )

    # múltiplos casos abertos — precisa de contexto adicional
    return Classification(type="ambiguous", client_id=client.id)

Classificação de mensagem — determina qual processo a mensagem pertence

O que ninguém documenta

Webhook reliability. A documentação do WhatsApp Cloud API é clara sobre o formato. O que ela não conta é que o mesmo webhook pode chegar duas vezes. Ou não chegar.

Implementamos idempotency por message ID antes de qualquer outra coisa. Cada mensagem processada é registrada. Duplicata descartada silenciosamente. Sem isso, um cliente receberia duas respostas automáticas e um caso seria registrado em duplicidade.

O segundo problema: múltiplos advogados no mesmo caso. Se dois advogados respondem ao cliente com 30 segundos de diferença, qual resposta o cliente vê primeiro? Qual a ordem no histórico? Adicionamos timestamp de envio real (não de recebimento pelo nosso server) e ordenação explícita na query.

  • 15 · advogados ativos
  • < 2h · tempo médio de resposta
  • 0 · treinamentos formais
  • 2 sem · para adoção completa

A lição central: quando o canal de comunicação já é o WhatsApp, o sistema precisa ir até lá — não o contrário. Qualquer CRM que exige que o advogado mude de ferramenta vai falhar na adoção. O que funciona é o sistema que se adapta ao comportamento existente.

Continue lendo

plugins premium WordPress