Como funciona o processo de autenticação via QR Code no Evolution GO.
- Visão Geral
- Fluxo de Conexão
- Geração do QR Code
- Leitura do QR Code
- Pareamento por Código
- Estados da Conexão
- Reconexão Automática
- Troubleshooting
- Boas Práticas
O Evolution GO utiliza o protocolo Multi-Device do WhatsApp para autenticar instâncias. O processo é baseado em QR Code, similar ao WhatsApp Web.
- Gerar QR Code: O Evolution GO cria um código único
- Escanear: Você escaneia o código com o WhatsApp no celular
- Pareamento: WhatsApp e Evolution GO trocam chaves de criptografia
- Sessão Ativa: Conexão estabelecida e salva no banco de dados
Vantagens:
- ✅ Seguro: chaves criptográficas trocadas de forma protegida
- ✅ Não requer senha ou número de telefone
- ✅ Suporta múltiplos dispositivos conectados simultaneamente
- ✅ Processo simples e rápido
Importante: O WhatsApp não oferece login com usuário e senha para APIs. A autenticação é exclusivamente via QR Code ou código de pareamento.
┌──────────────┐ ┌──────────────┐
│ Evolution GO │ │ WhatsApp │
│ Client │ │ Servers │
└──────┬───────┘ └──────┬───────┘
│ │
│ 1. POST /instance/connect │
│────────────────────────┐ │
│ │ │
│ 2. StartClient() │ │
│<───────────────────────┘ │
│ │
│ 3. Connect WebSocket │
│──────────────────────────────────────────────────────>│
│ │
│ 4. Request QR Code │
│──────────────────────────────────────────────────────>│
│ │
│ 5. QR Code Data (ref + public key) │
│<──────────────────────────────────────────────────────│
│ │
│ 6. Generate PNG QR Code │
│────────────┐ │
│ │ │
│<───────────┘ │
│ │
│ 7. Save QR to Database (base64|text) │
│────────────┐ │
│ │ │
│<───────────┘ │
│ │
│ 8. Emit QR_CODE Event │
│────────────┐ │
│ │ (Webhook/WebSocket) │
│<───────────┘ │
│ │
┌──────▼───────┐ │
│ User │ │
│ (Smartphone) │ │
└──────┬───────┘ │
│ │
│ 9. Open WhatsApp App │
│ → Linked Devices │
│ → Scan QR Code │
│ │
│ 10. Send Pairing Data (encrypted) │
│──────────────────────────────────────────────────────>│
│ │
│ 11. Pairing Success │
│<──────────────────────────────────────────────────────│
│ │
┌──────▼───────┐ │
│ Evolution GO │ │
└──────┬───────┘ │
│ │
│ 12. Receive Pairing Success Event │
│<──────────────────────────────────────────────────────│
│ │
│ 13. Generate Identity & Pre-Keys │
│────────────┐ │
│ │ │
│<───────────┘ │
│ │
│ 14. Save Session to Database │
│────────────┐ │
│ │ (JID, Keys, Device Info) │
│<───────────┘ │
│ │
│ 15. Update Instance (connected=true, jid=...) │
│────────────┐ │
│ │ │
│<───────────┘ │
│ │
│ 16. Emit CONNECTED Event │
│────────────┐ │
│ │ │
│<───────────┘ │
│ │
│ 17. Start Message Sync │
│<─────────────────────────────────────────────────────>│
│ (bidirectional) │
│ │
API Call:
POST /instance/connect
{
"instanceName": "vendas"
}Ações:
- Verifica se instância existe no banco
- Inicia goroutine com whatsmeow client
- Estabelece WebSocket com servidores WhatsApp
O Evolution GO solicita ao WhatsApp um código QR único, que contém:
- Ref: Referência única que identifica esta tentativa de conexão
- Public Key: Chave pública para iniciar o pareamento criptografado
Formato do texto no QR Code:
versão@ref,chave_pública,segredo,dados_adicionais
Exemplo:
2@ABC123DEF456,GHI789JKL012MNO345,PQR678STU901VWX234,YZA567
Armazenamento: O QR Code é convertido em uma imagem PNG, codificada em base64 e salva no banco de dados junto com o texto original.
Via navegador:
GET /instance/qr?instanceName=vendas
Resposta HTML:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." />Via API JSON:
GET /instance/qr?instanceName=vendas{
"qrcode": "iVBORw0KGgoAAAANSUhEUgAA...",
"code": "2@ABC123,DEF456,GHI789,JKL012"
}No smartphone:
- Abre WhatsApp
- Menu → Aparelhos conectados
- Conectar um aparelho
- Escaneia QR Code
WhatsApp envia:
- Chaves públicas do device
- JID (WhatsApp ID) do número
- Device info (modelo, OS)
Após o usuário escanear o QR Code:
- Evolution GO recebe confirmação do WhatsApp
- Sessão é salva no banco de dados com:
- Chaves de identidade
- Chaves pré-geradas
- JID (identificador do WhatsApp)
- Informações do dispositivo
- Instância marcada como conectada
- Evento CONNECTED é publicado
Quando um QR Code é gerado:
- Texto do QR Code é recebido do WhatsApp
- Imagem PNG é criada a partir do texto
- Salvo no banco de dados em formato base64
- Evento QR_CODE é publicado para webhooks/websockets configurados
Estrutura:
version@ref,pub_key,secret,adv
Componentes:
version: Versão do protocolo (geralmente2)ref: Referência única (identifica esta tentativa de pareamento)pub_key: Chave pública do servidorsecret: Segredo compartilhadoadv: Dados de advertising (device info)
Exemplo real:
2@12345abcdef,67890ghijk,lmnop12345,qrstu67890
Tempo de vida: ~40 segundos
Após expiração:
- Whatsmeow emite novo evento QR
- Novo QR Code é gerado
- Repete até
max_attempts(padrão: 5 tentativas)
Evento de timeout:
case *events.QRTimeout:
logger.Warn("QR Code expired, generating new one...")Obter QR Code via API:
GET /instance/qr?instanceName=vendasResponse (JSON):
{
"qrcode": "iVBORw0KGgoAAAANSUhEUgAABAA...",
"code": "2@12345abcdef,67890ghijk,lmnop12345,qrstu67890"
}Response (HTML) - Se aceitar text/html:
<!DOCTYPE html>
<html>
<head><title>QR Code - vendas</title></head>
<body>
<h1>QR Code - Instância: vendas</h1>
<img src="data:image/png;base64,iVBORw0KG..." />
<p>Escaneie com WhatsApp</p>
</body>
</html>Conectar:
const ws = new WebSocket('ws://localhost:4000/ws?token=TOKEN&instanceId=vendas');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.queue === 'qrcode') {
const payload = JSON.parse(data.payload);
const qrBase64 = payload.qrcode;
// Exibir QR Code
document.getElementById('qr-img').src =
`data:image/png;base64,${qrBase64}`;
}
};Configurar webhook:
POST /instance/connect
{
"instanceName": "vendas",
"webhookUrl": "https://meu-servidor.com/webhook",
"subscribe": ["QRCODE"]
}Evento recebido:
{
"event": "QRCODE",
"instance": "vendas",
"data": {
"qrcode": "iVBORw0KGgoAAAANSUhEUgA...",
"code": "2@12345abcdef,67890ghijk,lmnop12345,qrstu67890"
}
}Além de QR Code, é possível parear via código de 8 dígitos.
Endpoint:
POST /instance/pair
{
"instanceName": "vendas",
"phone": "5511999999999"
}Response:
{
"pairingCode": "ABCD-1234"
}No smartphone:
- Abre WhatsApp
- Menu → Aparelhos conectados
- Conectar um aparelho
- Link com código de aparelho
- Digita
ABCD-1234
Vantagens:
- ✅ Não precisa de camera/QR scanner
- ✅ Mais fácil para compartilhar remotamente
Desvantagens:
- ❌ Requer digitação manual
- ❌ Menos visual que QR Code
O Evolution GO gera um código de 8 dígitos único e o retorna na API. Esse código é válido por tempo limitado e pode ser usado uma única vez.
┌─────────────┐
│ CREATED │ Instância criada, nunca conectada
└──────┬──────┘
│ POST /instance/connect
▼
┌─────────────┐
│ CONNECTING │ WebSocket iniciando
└──────┬──────┘
│
▼
┌─────────────┐
│ WAITING_QR │ Aguardando usuário escanear
└──────┬──────┘
│ Usuário escaneia QR
▼
┌─────────────┐
│ PAIRING │ Trocando chaves criptográficas
└──────┬──────┘
│
▼
┌─────────────┐
│ OPEN │ Conectado e autenticado
└──────┬──────┘
│
│ Erro de conexão ou logout
▼
┌─────────────┐
│ DISCONNECTED│
└─────────────┘
{
"event": "QRCODE",
"data": {
"qrcode": "base64...",
"code": "2@..."
}
}{
"event": "QR_TIMEOUT",
"data": {
"attempts": 1,
"maxAttempts": 5
}
}{
"event": "QR_SUCCESS",
"data": {
"jid": "5511999999999@s.whatsapp.net"
}
}{
"event": "CONNECTED",
"data": {
"jid": "5511999999999@s.whatsapp.net",
"name": "João Silva",
"timestamp": "2025-11-11T10:30:00Z"
}
}Depois do primeiro pareamento bem-sucedido via QR Code:
- Sessão é salva no banco de dados PostgreSQL
- Próxima inicialização: Sessão é carregada automaticamente
- Conecta diretamente sem necessidade de novo QR Code
O Evolution GO mantém várias tabelas para armazenar as informações de sessão e chaves criptográficas necessárias para reconexão.
Se uma conexão cair, o Evolution GO tenta reconectar automaticamente usando estratégia de intervalo crescente:
- Tentativa 1: 2 segundos
- Tentativa 2: 4 segundos
- Tentativa 3: 8 segundos
- Tentativa 4: 16 segundos
- Tentativa 5: 32 segundos
Em alguns cenários, é necessário gerar um novo QR Code:
- ❌ Após logout explícito via API
- ❌ Dispositivo removido manualmente no app WhatsApp
- ❌ Sessão expirada (mais de 14 dias offline)
- ❌ Conta temporariamente ou permanentemente bloqueada
Diagnóstico:
GET /instance/logs/:instanceId?level=ERRORCausas comuns:
- Cliente não conectado ao WebSocket
- Firewall bloqueando conexão com WhatsApp servers
- Instância já conectada (não precisa de QR)
Solução:
# Forçar reconexão
POST /instance/reconnect
{
"instanceName": "vendas"
}Causa: Delay entre geração e exibição.
Solução: Use WebSocket para receber QR em tempo real.
const ws = new WebSocket('ws://localhost:4000/ws?token=TOKEN&instanceId=vendas');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.queue === 'qrcode') {
// Exibir imediatamente
showQRCode(data.payload.qrcode);
}
};Diagnóstico:
GET /instance/status?instanceName=vendasResposta esperada após scan:
{
"connected": true,
"loggedIn": true,
"jid": "5511999999999@s.whatsapp.net"
}Se continuar connected: false:
- Verificar logs de erro
- Tentar logout e novo QR
- Verificar se WhatsApp está atualizado
Causa: QR Code expirou 5 vezes.
Solução:
# Desconectar
POST /instance/disconnect
# Aguardar 30 segundos
# Reconectar
POST /instance/connectUse WebSocket em vez de polling:
❌ Ruim (polling):
setInterval(() => {
fetch('/instance/qr?instanceName=vendas')
.then(res => res.json())
.then(data => showQR(data.qrcode));
}, 5000); // A cada 5 segundos✅ Bom (WebSocket):
const ws = new WebSocket('ws://localhost:4000/ws?token=TOKEN&instanceId=vendas');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.queue === 'qrcode') showQR(data.payload.qrcode);
};Mostre estado da conexão para o usuário:
ws.onmessage = (event) => {
const { queue } = JSON.parse(event.data);
switch(queue) {
case 'qrcode':
showStatus('Escaneie o QR Code');
break;
case 'qr_success':
showStatus('QR Code escaneado! Conectando...');
break;
case 'connected':
showStatus('Conectado com sucesso!');
break;
}
};Desconecte se QR não for escaneado em tempo razoável:
let qrTimeout;
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.queue === 'qrcode') {
// Cancela timeout anterior
clearTimeout(qrTimeout);
// Timeout de 2 minutos
qrTimeout = setTimeout(() => {
alert('QR Code expirou. Por favor, tente novamente.');
ws.close();
}, 120000);
}
if (data.queue === 'connected') {
clearTimeout(qrTimeout);
}
};# Verificar status primeiro
GET /instance/status?instanceName=vendas
# Se já conectado, não precisa de QR
# Se desconectado mas tem sessão, tentar reconnect
# Só gerar QR se não tem sessão- Multi-Dispositivo - Entender protocolo Multi-Device
- Instâncias WhatsApp - Ciclo de vida completo
- Sistema de Eventos - Receber eventos de conexão
- API de Instâncias - Todos os endpoints
Documentação gerada para Evolution GO v1.0