ZAP-API
PreçosCasos de UsoBlogDocsLogin
Começar grátis
  1. Blog
  2. Multi-atendentes no WhatsApp via API: como implementar
Tutorial

Multi-atendentes no WhatsApp via API: como implementar

Implemente fila de atendimento, distribuição round-robin e transferência entre atendentes no WhatsApp com uma única instância. Código Node.js completo.

07 de março de 2026·10 min de leitura·Equipe Editorial ZAP API

Implementar multi-atendentes no WhatsApp via API é essencial quando sua empresa recebe mais mensagens do que uma pessoa consegue responder. Com a ZAP API, você constrói um sistema de fila de atendimento, distribuição round-robin e transferência entre atendentes — tudo usando uma única instância WhatsApp.

Arquitetura do sistema

A ideia é simples: todas as mensagens chegam via webhook no seu servidor. Seu sistema distribui cada conversa para um atendente disponível, mantém o estado da conversa e permite transferência entre atendentes.

  • Webhook: recebe todas as mensagens
  • Router: distribui para o atendente correto
  • Fila: quando todos estão ocupados, cliente entra na fila
  • Painel: atendentes veem suas conversas e respondem

Implementação: sistema de fila e distribuição

const axios = require('axios');
const express = require('express');
const app = express();
app.use(express.json());

const api = axios.create({
  baseURL: 'https://zap-api.tech/v1',
  headers: { Authorization: 'Bearer tk_seu_token_aqui' }
});
const INST = 'inst_seu_id_aqui';

// Estado dos atendentes
const atendentes = [
  { id: 1, nome: 'Ana', status: 'disponivel', conversas: [] },
  { id: 2, nome: 'Bruno', status: 'disponivel', conversas: [] },
  { id: 3, nome: 'Carol', status: 'disponivel', conversas: [] }
];

// Conversas ativas: phone → atendenteId
const conversasAtivas = new Map();
const fila = [];

// Distribuição round-robin
let ultimoAtendente = -1;

function proximoAtendente() {
  const disponiveis = atendentes.filter(a => a.status === 'disponivel' && a.conversas.length < 5);
  if (disponiveis.length === 0) return null;
  ultimoAtendente = (ultimoAtendente + 1) % disponiveis.length;
  return disponiveis[ultimoAtendente];
}

// Webhook: receber mensagens
app.post('/webhook', async (req, res) => {
  res.json({ ok: true });
  const { event, data } = req.body;
  if (event !== 'message.received' || data.fromMe) return;

  const phone = data.phone;
  const texto = data.body || '';

  // Verificar se já tem conversa ativa
  if (conversasAtivas.has(phone)) {
    const atendenteId = conversasAtivas.get(phone);
    // Encaminhar para o painel do atendente
    notificarAtendente(atendenteId, phone, texto);
    return;
  }

  // Distribuir para próximo atendente
  const atendente = proximoAtendente();
  if (atendente) {
    conversasAtivas.set(phone, atendente.id);
    atendente.conversas.push(phone);
    notificarAtendente(atendente.id, phone, texto);

    await api.post(`/instances/${INST}/send`, {
      phone, type: 'text',
      body: `Olá! Você está sendo atendido por ${atendente.nome}. Como posso ajudar?`
    });
  } else {
    fila.push({ phone, texto, timestamp: Date.now() });
    const posicao = fila.length;
    await api.post(`/instances/${INST}/send`, {
      phone, type: 'text',
      body: `Todos os atendentes estão ocupados. Posição na fila: ${posicao}.\nAguarde, responderemos em breve!`
    });
  }
});

// API para atendente responder
app.post('/api/responder', async (req, res) => {
  const { atendenteId, phone, mensagem } = req.body;
  if (conversasAtivas.get(phone) !== atendenteId) {
    return res.status(403).json({ error: 'Conversa não atribuída a este atendente' });
  }

  await api.post(`/instances/${INST}/send`, {
    phone, type: 'text', body: mensagem
  });
  res.json({ ok: true });
});

// API para transferir conversa
app.post('/api/transferir', async (req, res) => {
  const { phone, deAtendenteId, paraAtendenteId } = req.body;
  const de = atendentes.find(a => a.id === deAtendenteId);
  const para = atendentes.find(a => a.id === paraAtendenteId);

  de.conversas = de.conversas.filter(p => p !== phone);
  para.conversas.push(phone);
  conversasAtivas.set(phone, paraAtendenteId);

  await api.post(`/instances/${INST}/send`, {
    phone, type: 'text',
    body: `Você foi transferido para ${para.nome}. Como posso ajudar?`
  });
  res.json({ ok: true });
});

// API para encerrar conversa
app.post('/api/encerrar', async (req, res) => {
  const { atendenteId, phone } = req.body;
  const atendente = atendentes.find(a => a.id === atendenteId);
  atendente.conversas = atendente.conversas.filter(p => p !== phone);
  conversasAtivas.delete(phone);

  await api.post(`/instances/${INST}/send`, {
    phone, type: 'text',
    body: 'Atendimento encerrado. Obrigado pelo contato! Se precisar, mande mensagem novamente.'
  });

  // Atender próximo da fila
  if (fila.length > 0) {
    const proximo = fila.shift();
    conversasAtivas.set(proximo.phone, atendente.id);
    atendente.conversas.push(proximo.phone);
    notificarAtendente(atendente.id, proximo.phone, proximo.texto);
  }
  res.json({ ok: true });
});

function notificarAtendente(atendenteId, phone, texto) {
  // Em produção: WebSocket, SSE ou push notification para o painel
  console.log(`[Atendente ${atendenteId}] ${phone}: ${texto}`);
}

app.listen(3000);

Distribuição por departamento

// Roteamento por palavra-chave para departamento
function detectarDepartamento(texto) {
  const t = texto.toLowerCase();
  if (t.match(/comprar|preco|orcamento|produto/)) return 'vendas';
  if (t.match(/problema|erro|defeito|trocar|devolver/)) return 'suporte';
  if (t.match(/boleto|pagamento|nota|fatura/)) return 'financeiro';
  return 'geral';
}

// No webhook, distribuir para atendente do departamento correto
const depto = detectarDepartamento(texto);
const atendente = atendentes.find(a =>
  a.departamento === depto && a.status === 'disponivel' && a.conversas.length < 5
);

Métricas de atendimento

  • Tempo médio de espera: quanto tempo o cliente ficou na fila
  • Tempo de primeira resposta: do recebimento à primeira resposta do atendente
  • Tempo de resolução: do início ao encerramento da conversa
  • Conversas por atendente: distribuição de carga
  • CSAT: pesquisa de satisfação automática ao encerrar

FAQ

  • Preciso de uma instância por atendente?
    Não. Todos os atendentes usam a mesma instância. O roteamento é feito no seu backend.
  • Quantos atendentes simultâneos?
    Sem limite. O gargalo é o volume de mensagens por minuto, não o número de atendentes.
  • Como o atendente vê as mensagens?
    Crie um painel web que consome os webhooks e usa a API /send para responder. Pode ser React, Vue ou qualquer framework.
  • Posso integrar com Zendesk/Freshdesk?
    Sim. Use o webhook da ZAP API para criar tickets automaticamente no seu help desk.

Criar instância grátis e montar seu multi-atendimento

Experimente a ZAP API gratuitamente

7 dias de trial sem precisar de cartão. A partir de R$29/mês*.

Criar instância grátis
EE
Equipe Editorial ZAP APIRevisão técnica

Desenvolvedores e especialistas em integrações WhatsApp. Todo conteúdo passa por revisão técnica para garantir precisão e aplicabilidade.

Ver perfil completoDocumentaçãoTrial grátis

Leia também

Tutorial · 06 de jun. de 2026 · 12 min

WhatsApp API para Atendimento Automático: guia completo 2026

Respostas fora do horário, triagem de leads por palavra-chave, fluxos condicionais e transferência para humano: como montar atendimento automático no WhatsApp em menos de 30 minutos.

Tutorial · 12 de jun. de 2026 · 12 min

Tipos de mensagem do WhatsApp via API: enquete, localização, contato, evento e mais

Catálogo completo dos tipos de mensagem da API de WhatsApp com o corpo JSON exato e exemplos prontos: texto, mídia, enquete (poll), localização, contato, evento, link e figurinha.

Tutorial · 13 de jun. de 2026 · 10 min

Reagir, editar, apagar, fixar e encaminhar mensagens do WhatsApp via API

Vá além do envio: as ações de mensagem da API de WhatsApp com endpoint exato — reação com emoji, edição, apagar para todos, fixar no topo, encaminhar e marcar como lida.

Tutorial · 14 de jun. de 2026 · 11 min

Autenticação 2FA e OTP por WhatsApp via API: mais barato e confiável que SMS

Como enviar códigos de verificação (OTP/2FA) por WhatsApp via API REST: fluxo completo, código de geração e validação, cuidados de segurança e por que verificar o número antes.

Tópicos:Chatbots com IAE-commerceAPI WhatsApp

Explore também

Casos de usoWhatsApp API por segmentoComparativoZAP API vs alternativasPreçosPlanos e o que está inclusoGlossárioTermos técnicos de WhatsApp API
ZAP-API

API REST para WhatsApp com webhooks assinados, Meta Pixel/CAPI e compliance LGPD. Sem aprovação da Meta.

Status operacional🇧🇷 Feito no Brasil

Produto

  • Preços
  • Casos de uso
  • Comparativo
  • Trial grátis
  • Dashboard

Recursos

  • Documentação
  • Blog
  • Glossário
  • RSS Feed

Empresa

  • Sobre
  • Imprensa
  • Termos de uso
  • Privacidade
  • Criar conta
  • Login

Contato

  • [email protected]
  • [email protected]
  • Resposta em até 24h úteis
© 2026 ZAP-API — Todos os direitos reservados·CNPJ 42.130.949/0001-56·Termos·Privacidade

Desenvolvido por PreviusIA