---
title: "Anti-link e anti-spam em grupo de WhatsApp: bot de moderação pela API"
description: "Bot anti-link e anti-spam para grupo de WhatsApp com a API não oficial: detectar links e convites, apagar a mensagem, advertir e remover no 3º strike."
url: "https://wame.api.br/blog/moderacao-anti-link-grupo-whatsapp-bot"
language: "pt-BR"
og:type: "article"
published_time: "2026-09-28"
modified_time: "2026-09-28"
author: "Raphael Serafim"
keywords: "api whatsapp não oficial, api não oficial whatsapp, gerenciar grupos whatsapp api, anti link grupo whatsapp, bot moderação grupo whatsapp, remover participante automaticamente whatsapp, anti spam grupo whatsapp"
reading_time: "9 min de leitura"
---

# Anti-link e anti-spam em grupo de WhatsApp: bot de moderação pela API

> Bot anti-link e anti-spam para grupo de WhatsApp com a API não oficial: detectar links e convites, apagar a mensagem, advertir e remover no 3º strike.

**Um bot anti-link e anti-spam para grupo de WhatsApp recebe cada mensagem pelo webhook, detecta links e convites de outros grupos, ignora admins e domínios permitidos, apaga a mensagem para todos com `DELETE /{key}/message/{id}`, adverte o autor e, na terceira infração, remove o participante com `DELETE /{key}/groups/{id}/participants`.** Somado ao modo anúncio e ao bloqueio de edição do grupo, isso segura a maior parte do lixo que aparece em grupo aberto.

Grupo com centenas de pessoas atrai sempre os mesmos visitantes: quem divulga outro grupo, quem vende curso, quem cola link encurtado suspeito às duas da manhã. Moderar isso na mão depende de um admin acordado. Este guia monta a moderação automática com a API não oficial da WAME.

> A camada não oficial da WAME é independente e não é afiliada, endossada ou suportada pelo WhatsApp ou pela Meta. O uso é de responsabilidade de quem envia.

## O que a API permite (e o que não)

Vale acertar a expectativa antes do código:

- **Receber toda mensagem do grupo:** sim, pelo webhook, com o autor e o grupo identificados.
- **Responder citando a mensagem:** sim, com `POST /{key}/message/{id}/text`.
- **Remover participante:** sim, com `DELETE /{key}/groups/{id}/participants`, se o número do bot for admin.
- **Mudar configurações do grupo:** sim, com `PATCH /{key}/groups/{id}?setting=...`.
- **Apagar a mensagem de outro membro:** sim, se o número do bot for admin. `DELETE /{key}/message/{id}`, com o id que chegou no webhook, apaga para todos — é o mesmo "apagar para todos" que um admin faz no app. Só funciona na instância não oficial; a Cloud API oficial não apaga mensagens.

Tudo que envolve ação sobre outro membro depende de uma condição: **o número conectado na instância precisa ser admin do grupo**. Promova o número antes de ligar o bot.

A estratégia combina três camadas: **prevenção** (configurações do grupo), **reação** (apagar, advertir e remover) e **registro** (log para os admins humanos).

## Camada 1: prevenção pelas configurações

Antes de escrever o bot, feche as portas mais óbvias:

```bash
# Impede membros de trocar nome, foto e descrição
curl -X PATCH "https://server.wame.api.br/SUA_KEY/groups/ID@g.us?setting=locked"

# Em grupo de avisos: só admins falam
curl -X PATCH "https://server.wame.api.br/SUA_KEY/groups/ID@g.us?setting=announcement"
```

Grupo de avisos com `announcement` praticamente dispensa anti-link. O bot faz sentido nos grupos de conversa aberta — comunidade de clientes, alunos, bairro, grupo de lançamento no dia do carrinho.

Controlar a entrada também ajuda: com aprovação de pedidos, você decide quem entra antes do problema existir. Veja o fluxo em [automatizar grupos pela API](/blog/automatizar-grupos-whatsapp-api).

## Camada 2: receber e identificar

No formato `meta`, a mensagem de grupo traz `from` (quem enviou), `group_id` (o grupo, terminado em `@g.us`) e `chat_type: "group"`:

```js
function extrair(body) {
  const msg = body?.entry?.[0]?.changes?.[0]?.value?.messages?.[0];
  if (!msg?.group_id || msg.from_me) return null;

  const texto =
    msg.text?.body ??
    msg.image?.caption ??
    msg.video?.caption ??
    '';

  return { grupo: msg.group_id, autor: msg.from, id: msg.id, texto };
}
```

Repare no `caption`: muito spam vem como imagem com link na legenda. Ler só `text.body` deixa passar metade do problema.

Em alguns grupos o autor pode chegar como LID (`...@lid`), um identificador que não é telefone. Para a moderação isso não muda nada: use o identificador que chegou nas listas e na remoção. Se precisar do telefone para o relatório, veja [LID no WhatsApp](/blog/lid-whatsapp-o-que-e-resolver-numero-api).

## Camada 3: a regra de detecção

Três padrões cobrem a maioria dos casos: convite de outro grupo, link qualquer fora da whitelist e encurtador.

```js
const CONVITE = /chat\.whatsapp\.com\/[A-Za-z0-9]+/i;
const LINK = /\b((https?:\/\/)?([a-z0-9-]+\.)+[a-z]{2,})(\/\S*)?/gi;
const ENCURTADORES = ['bit.ly', 'tinyurl.com', 'cutt.ly', 'encurtador.com.br'];

const DOMINIOS_OK = ['seusite.com.br', 'loja.seusite.com.br'];
const ISENTOS = new Set(['5511988887777', '5511977776666']); // admins e time

function dominioDe(url) {
  return url.replace(/^https?:\/\//, '').split(/[/?#]/)[0].toLowerCase();
}

function infracao({ autor, texto }) {
  if (ISENTOS.has(autor)) return null;
  if (CONVITE.test(texto)) return 'convite de outro grupo';

  const links = texto.match(LINK) ?? [];
  for (const l of links) {
    const d = dominioDe(l);
    if (ENCURTADORES.includes(d)) return 'link encurtado';
    if (!DOMINIOS_OK.some((ok) => d === ok || d.endsWith('.' + ok))) return 'link externo';
  }
  return null;
}
```

Comece permissivo e aperte com o tempo. Uma regex agressiva demais pune quem escreve "vi no site.com" sem má intenção, e um grupo que remove gente injustamente perde confiança rápido.

## Camada 4: apagar, advertir e três strikes

A mensagem com link sai do grupo na hora, em toda infração. Já a pessoa não precisa ser removida na primeira vez: remover direto é duro demais para grupo de clientes. O padrão que funciona é apagar e advertir, apagar e advertir, apagar e remover:

```js
const BASE = 'https://server.wame.api.br/SUA_KEY';
const strikes = new Map(); // em produção: Redis com expiração de alguns dias

async function apagar(msgId) {
  // Funciona com mensagem de outro membro porque o bot é admin do grupo.
  await fetch(`${BASE}/message/${msgId}`, { method: 'DELETE' });
}

async function avisar(grupo, texto) {
  await fetch(`${BASE}/message/text`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ to: grupo, text: texto }),
  });
}

async function remover(grupo, autor) {
  await fetch(`${BASE}/groups/${grupo}/participants`, {
    method: 'DELETE',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ participants: [autor] }),
  });
}

async function moderar(m, motivo) {
  const chave = `${m.grupo}:${m.autor}`;
  const n = (strikes.get(chave) ?? 0) + 1;
  strikes.set(chave, n);
  await registrar(m, motivo, n); // log para os admins (inclui o trecho apagado)
  await apagar(m.id);

  if (n >= 3) {
    await remover(m.grupo, m.autor);
    strikes.delete(chave);
    return;
  }
  await avisar(m.grupo, `Aviso ${n}/3: ${motivo} não é permitido aqui. Leia as regras fixadas.`);
}
```

Repare na ordem: primeiro o registro, depois apagar. Como a mensagem some para todos, o log é o único lugar em que o admin vai conseguir ver o que foi removido. E como ela não existe mais, a advertência sai como mensagem normal, não citada.

Se preferir um modo mais brando nas primeiras semanas — só advertir, sem apagar —, troque `apagar` por uma resposta citada com `POST /{key}/message/{id}/text` (o guia de [responder mensagem citada](/blog/tutorial-responder-mensagem-citada-whatsapp-api) mostra como) e deixe a remoção da mensagem para os admins humanos enquanto calibra a regra.

## Camada 5: flood

Nem todo spam tem link. Às vezes é a mesma mensagem colada cinco vezes, ou vinte mensagens em um minuto. Um contador por autor resolve:

```js
const janela = new Map(); // autor -> timestamps recentes

function flood(m, limite = 8, janelaMs = 60_000) {
  const agora = Date.now();
  const chave = `${m.grupo}:${m.autor}`;
  const lista = (janela.get(chave) ?? []).filter((t) => agora - t < janelaMs);
  lista.push(agora);
  janela.set(chave, lista);
  return lista.length > limite;
}
```

Flood entra no mesmo sistema de strikes, com o motivo "excesso de mensagens". Os números acima são ponto de partida; ajuste ao ritmo normal do seu grupo.

## Juntando tudo

```js
app.post('/webhook/grupos', async (req, res) => {
  res.sendStatus(200); // responda antes de processar

  const m = extrair(req.body);
  if (!m) return;

  const motivo = infracao(m) ?? (flood(m) ? 'excesso de mensagens' : null);
  if (motivo) await moderar(m, motivo);
});
```

Responder `200` na hora importa: webhook lento é reenviado, e o bot advertiria a mesma pessoa duas vezes. Para idempotência com o id da mensagem, veja [webhook em produção](/blog/webhook-producao-assinatura-retry-idempotencia).

## O bot também precisa de modos

Moderação boa não fala demais. Três cuidados que evitam o bot virar o problema:

- **Cooldown por grupo:** no máximo uma advertência a cada poucos segundos por grupo. Se dez pessoas colarem o mesmo link ao mesmo tempo, é ataque — feche o grupo com `announcement` e avise os admins.
- **Mensagens curtas e variadas:** advertência longa e sempre idêntica polui o grupo e tem cara de robô.
- **Remoções espaçadas:** se o bot precisar remover várias pessoas, uma por vez, com intervalo. Remoção em rajada parece ação automatizada em massa.
- **Advertência agrupada em ataque:** se muitas mensagens forem apagadas em sequência, apague todas, mas mande um único aviso ao final em vez de um por mensagem.

Esses cuidados também protegem o número. Ação de moderação é algo que admins fazem no app todos os dias; o que chama atenção é volume anormal. A WAME já envia com tempo humano e avisa no webhook de conexão se o número der sinal de restrição. O restante é o seu bot não exagerar. Para quem modera assim, a taxa de bloqueio é muito baixa.

## Log para os admins humanos

Todo evento de moderação vai para um registro: data, grupo, autor, motivo, strike e texto da mensagem. Como as mensagens infratoras são apagadas para todos, o log é a única cópia do que aconteceu. Um resumo diário para o grupo de admins ajuda a revisar se a regra está justa e a desfazer remoções injustas.

```js
async function registrar(m, motivo, strike) {
  await db.moderacao.inserir({
    quando: new Date(), grupo: m.grupo, autor: m.autor,
    motivo, strike, trecho: m.texto.slice(0, 200),
  });
}
```

Guarde só o necessário e por pouco tempo. É dado pessoal de quem está no grupo.

## Onde isso se encaixa

Se você já tem um [bot de comandos no grupo](/blog/bot-comandos-grupo-whatsapp-api), a moderação entra como mais uma etapa do mesmo webhook, antes do parser de comandos. Em grupos de lançamento, ligue o bot no dia em que a conversa abre — o roteiro está em [grupos de lançamento com rotação](/blog/grupos-lancamento-whatsapp-automacao-api). E se você administra dezenas de grupos, aplique a mesma política em todos a partir de um inventário central, como em [gerenciar centenas de grupos](/blog/gerenciar-centenas-grupos-whatsapp-api).

## Conclusão

Anti-link e anti-spam em grupo de WhatsApp se resolvem com três camadas: configurações preventivas (`locked`, `announcement`, aprovação de entrada), um bot admin que lê cada mensagem pelo webhook, apaga o que viola a regra, adverte e remove o reincidente, e um log que deixa os admins humanos no controle. Com a API não oficial da WAME, tudo isso é HTTP simples. O que separa um bom bot de moderação de um bot irritante é saber a hora de ficar quieto: whitelist, strikes, cooldown e remoções espaçadas. Os endpoints completos estão na [documentação](/docs).

## Perguntas frequentes

### Como funciona um bot anti-link em grupo de WhatsApp?

O webhook entrega cada mensagem do grupo ao seu servidor. O bot verifica se o texto tem link ou convite de outro grupo, confere se o autor está na lista de exceções e, se não estiver, apaga a mensagem para todos e manda uma advertência. Na reincidência, remove o participante com DELETE /{key}/groups/{id}/participants.

### O bot consegue apagar a mensagem de outra pessoa no grupo?

Sim, desde que o número do bot seja admin do grupo. Chame DELETE /{key}/message/{id} com o id que chegou no webhook e a mensagem é apagada para todos, como quando um admin apaga pelo app. Isso vale para a instância não oficial; na oficial (Cloud API) não é possível apagar mensagens.

### O número do bot precisa ser admin do grupo?

Sim. Remover participante, mudar configurações e aprovar pedidos de entrada exigem que o número conectado na instância seja administrador do grupo. Sem isso, o bot só consegue advertir: não apaga mensagem de ninguém nem remove participante.

### Como evitar que o bot puna admins ou links permitidos?

Mantenha duas listas: participantes isentos (admins, moderadores, o próprio time) e domínios permitidos (seu site, sua loja). A regra só age quando o link não está na lista de domínios e o autor não está na lista de isentos.

### Moderar grupo automaticamente pode bloquear o número do bot?

Moderação bem feita é ação de admin, algo que qualquer pessoa faz no app. O risco aparece quando o bot responde demais: advertência a cada mensagem, remoções em rajada, textos idênticos. Com cooldown, sistema de strikes e respostas curtas, a taxa de bloqueio para esse uso é muito baixa.
