Wow! Redução de 65% no preço para clientes brasileiros! Registre-se agora
Moderação de entrada no grupo · caso de uso WhatsApp API

Gerencie pedidos de entrada em grupos de WhatsApp a partir do backend

Clubes pagos e comunidades privadas deixam de perder candidatos quando as filas ficam presas no telefone. Quando alguém pede acesso a um grupo só com aprovação, seu backend pode reagir a um webhook groups.put, listar pedidos pendentes e admitir ou rejeitar cada um via Whapi.Cloud. Este caso de uso mostra aos integradores como implementar esse fluxo com a WhatsApp API.

Webhook groups.put com action request GET pedidos pendentes, depois POST ou DELETE por id
Notebook com diagrama de integração ao lado de um telefone com visão de admin do grupo WhatsApp e uma fila curta de pedidos pendentes.
Cenário de uso

Quando usar este fluxo

O grupo exige aprovação antes de entrar

Use este fluxo quando o grupo de WhatsApp não é entrada livre: alguém toca no link de convite e cria um pedido que um admin aprovaria ou negaria no app.

As regras de moderação ficam no seu backend

Use este fluxo quando own_backend decide quem entra (lista paga, código de indicação, allowlist manual) e você precisa de um caminho HTTP estável em vez de copiar toques do telefone.

Você gerencia vários grupos só com aprovação

Use este fluxo quando pedidos se acumulam em vários grupos ou fora do horário e você quer um padrão único de listar, aprovar e rejeitar.

Tela de info do grupo WhatsApp no telefone com pedido resolvido: o membro aparece na lista ou o pedido pendente some após rejeição.
Experiência do cliente

Os candidatos sabem rápido se entraram ou não

Sem automação, um pedido pode ficar pendente até alguém abrir o WhatsApp no telefone e tocar em aprovar ou rejeitar.

Depois das suas regras, quem é aprovado pode entrar no grupo pelo mesmo convite, e um pedido rejeitado não bloqueia mais a fila. Integradores constroem esse resultado com a WhatsApp API.

Fluxo de trabalho

De pedido pendente a aprovar ou rejeitar

1

Alguém pede para entrar no grupo

A pessoa usa o link de convite enquanto o grupo está em modo só com aprovação. Com o webhook de canal groups.put ativo, a Whapi publica um payload onde groups_participants[].action é request, event.type é groups e event.event é put: o sinal para own_backend listar pedidos e decidir aprovar ou rejeitar.

2

Listar pedidos de entrada pendentes

GET /groups/{GroupID}/applications

GET /groups/{GroupID}/applications para o GroupID configurado. Leia cada id de pedido (e campos relacionados) da resposta para o próximo passo.

3

Aprovar um pedido

POST /groups/{GroupID}/applications

Se as regras de own_backend passarem, POST /groups/{GroupID}/applications com o id do pedido no corpo. OpenAPI indica um id por chamada: itere quando houver vários pedidos.

4

Rejeitar um pedido

DELETE /groups/{GroupID}/applications

Se as regras falharem, DELETE /groups/{GroupID}/applications com a mesma forma de id. Uma chamada por pedido rejeitado, separada de aprovar.

Precisa da forma completa do webhook? O callback de pedido de entrada está na seção de entrega abaixo — não são acks de mensagem. Ver o payload groups.put →

Pré-requisitos

Antes de executar o fluxo

Conecte a conta WhatsApp que administra o grupo à Whapi.Cloud, ative o webhook de canal groups.put e use o token API desse canal nos endpoints de pedidos do grupo. Guarde o GroupID alvo e suas regras de moderação em own_backend antes de processar pedidos.

Opcional — aprofundar neste fluxo

Implementação da API

Chamadas de pedidos do grupo em ordem

Três passos HTTP espelham a cadeia do catálogo: obter a fila, admitir candidatos permitidos, rejeitar o resto. A Whapi expõe listar, aprovar e rejeitar no mesmo path de pedidos do grupo para ligar moderação sem toques manuais de admin.

Obtenha seu token API grátis após se registrar em whapi.cloud e use-o no código em vez de Your_Token dos exemplos.

Listar pedidos de entrada pendentes

Retorna pedidos de entrada aguardando no grupo para own_backend combinar cada pedido com sua allowlist ou estado de pagamento.

curl --request GET \
     --url https://gate.whapi.cloud/groups/[email protected]/applications \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Your_Token'
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://gate.whapi.cloud/groups/[email protected]/applications",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "accept: application/json",
    "authorization: Bearer Your_Token"
  ],
]);

$response = curl_exec($curl);
curl_close($curl);
echo $response;
import requests

url = "https://gate.whapi.cloud/groups/[email protected]/applications"
headers = {
    "accept": "application/json",
    "authorization": "Bearer Your_Token",
}
response = requests.get(url, headers=headers)
print(response.text)
const response = await fetch('https://gate.whapi.cloud/groups/[email protected]/applications', {
  method: 'GET',
  headers: {
    accept: 'application/json',
    authorization: 'Bearer Your_Token',
  },
});
console.log(await response.text());
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
  .url("https://gate.whapi.cloud/groups/[email protected]/applications")
  .get()
  .addHeader("accept", "application/json")
  .addHeader("authorization", "Bearer Your_Token")
  .build();
Response response = client.newCall(request).execute();
using RestSharp;
var options = new RestClientOptions("https://gate.whapi.cloud/groups/[email protected]/applications");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("accept", "application/json");
request.AddHeader("Authorization", "Bearer Your_Token");
var response = await client.GetAsync(request);
Console.WriteLine("{0}", response.Content);
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://gate.whapi.cloud/groups/[email protected]/applications", nil)
	req.Header.Set("accept", "application/json")
	req.Header.Set("authorization", "Bearer Your_Token")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(string(out))
}

Aprovar um pedido

Aceita um pedido pendente para essa pessoa acessar o grupo pelo caminho normal de convite após aprovação bem-sucedida.

curl --request POST \
     --url https://gate.whapi.cloud/groups/[email protected]/applications \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Your_Token' \
     --header 'content-type: application/json' \
     --data '
{
  "application": "61371989850@..."
}
'
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://gate.whapi.cloud/groups/[email protected]/applications",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"application\": \"61371989850@...\"}",
  CURLOPT_HTTPHEADER => [
    "accept: application/json",
    "authorization: Bearer Your_Token",
    "content-type: application/json"
  ],
]);

$response = curl_exec($curl);
curl_close($curl);
echo $response;
import requests

url = "https://gate.whapi.cloud/groups/[email protected]/applications"
payload = {
    "application": "61371989850@..."
}
headers = {
    "accept": "application/json",
    "authorization": "Bearer Your_Token",
    "content-type": "application/json",
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
const response = await fetch('https://gate.whapi.cloud/groups/[email protected]/applications', {
  method: 'POST',
  headers: {
    accept: 'application/json',
    authorization: 'Bearer Your_Token',
    'content-type': 'application/json',
  },
  body: JSON.stringify({
  "application": "61371989850@..."
}),
});
console.log(await response.text());
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"application\": \"61371989850@...\"}");
Request request = new Request.Builder()
  .url("https://gate.whapi.cloud/groups/[email protected]/applications")
  .post(body)
  .addHeader("accept", "application/json")
  .addHeader("authorization", "Bearer Your_Token")
  .addHeader("content-type", "application/json")
  .build();
Response response = client.newCall(request).execute();
using RestSharp;
var options = new RestClientOptions("https://gate.whapi.cloud/groups/[email protected]/applications");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("accept", "application/json");
request.AddHeader("Authorization", "Bearer Your_Token");
request.AddJsonBody(new { application = "61371989850@..." });
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	body := []byte(`{"application": "61371989850@..."}`)
	req, _ := http.NewRequest("POST", "https://gate.whapi.cloud/groups/[email protected]/applications", bytes.NewReader(body))
	req.Header.Set("accept", "application/json")
	req.Header.Set("authorization", "Bearer Your_Token")
	req.Header.Set("content-type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(string(out))
}

Rejeitar um pedido

Recusa um pedido pendente para sair da fila sem admitir essa pessoa.

curl --request DELETE \
     --url https://gate.whapi.cloud/groups/[email protected]/applications \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Your_Token' \
     --header 'content-type: application/json' \
     --data '
{
  "application": "61371989850@..."
}
'
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://gate.whapi.cloud/groups/[email protected]/applications",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_POSTFIELDS => "{\"application\": \"61371989850@...\"}",
  CURLOPT_HTTPHEADER => [
    "accept: application/json",
    "authorization: Bearer Your_Token",
    "content-type: application/json"
  ],
]);

$response = curl_exec($curl);
curl_close($curl);
echo $response;
import requests

url = "https://gate.whapi.cloud/groups/[email protected]/applications"
payload = {
    "application": "61371989850@..."
}
headers = {
    "accept": "application/json",
    "authorization": "Bearer Your_Token",
    "content-type": "application/json",
}
response = requests.delete(url, json=payload, headers=headers)
print(response.text)
const response = await fetch('https://gate.whapi.cloud/groups/[email protected]/applications', {
  method: 'DELETE',
  headers: {
    accept: 'application/json',
    authorization: 'Bearer Your_Token',
    'content-type': 'application/json',
  },
  body: JSON.stringify({
  "application": "61371989850@..."
}),
});
console.log(await response.text());
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"application\": \"61371989850@...\"}");
Request request = new Request.Builder()
  .url("https://gate.whapi.cloud/groups/[email protected]/applications")
  .delete(body)
  .addHeader("accept", "application/json")
  .addHeader("authorization", "Bearer Your_Token")
  .addHeader("content-type", "application/json")
  .build();
Response response = client.newCall(request).execute();
using RestSharp;
var options = new RestClientOptions("https://gate.whapi.cloud/groups/[email protected]/applications");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("accept", "application/json");
request.AddHeader("Authorization", "Bearer Your_Token");
request.AddJsonBody(new { application = "61371989850@..." });
var response = await client.DeleteAsync(request);
Console.WriteLine("{0}", response.Content);
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	body := []byte(`{"application": "61371989850@..."}`)
	req, _ := http.NewRequest("DELETE", "https://gate.whapi.cloud/groups/[email protected]/applications", bytes.NewReader(body))
	req.Header.Set("accept", "application/json")
	req.Header.Set("authorization", "Bearer Your_Token")
	req.Header.Set("content-type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(string(out))
}
Evento recebido

Pedidos de entrada em groups.put

Use a configuração de webhook de canal para groups.put para receber eventos de pedido de entrada. A Whapi envia JSON com groups_participants (cada item tem group_id, participants e action), mais event.type groups, event.event put e channel_id. Quando action é request, alguém pediu para entrar: chame getGroupApplicationsList para o group_id correspondente e depois aprove ou rejeite. Isso é distinto do rastreamento de entrega de mensagens statuses.post.

  • Forma de exemplo confirmada pelo operador: groups_participants com action request, event groups/put e channel_id no mesmo payload que a Whapi publica na sua URL.

  • Mapeie groups_participants[].group_id ao GroupID em GET /groups/{GroupID}/applications antes de aprovar ou rejeitar.

  • Ids de participantes no webhook identificam quem pediu acesso; combine com a resposta da listagem ao preencher ApplicationRequest.

  • Polling de getGroupApplicationsList por agenda ainda funciona se você não usar webhook; só muda o gatilho.

O que ler sobre entrega e webhooks

Fale com nosso suporte se algo deu errado
Quando algo falha

Trate falhas em cada passo

Se a listagem de pedidos ou as chamadas de aprovar e rejeitar falharem, os pedidos ficam pendentes — tente de novo, pule ids obsoletos ou alerte ops em vez de assumir que alguém entrou.

Quando pedidos nunca somem

GroupID errado, grupo inexistente ou respostas 400 repetidas deixam candidatos presos em pendente. Corrija o parâmetro de rota, confirme que o canal ainda administra esse grupo e tente aprovar ou rejeitar só o id de pedido atual; não assuma que um id anterior ainda vale. Se erros persistirem após nova tentativa, contate o suporte Whapi com GroupID e corpo da requisição que falhou.

Fale com nosso suporte se algo deu errado

Diagnóstico por passo da API

Situação O que significa O que fazer
400 Wrong request parameters Corrija parâmetros de consulta como count ou offset conforme OpenAPI antes de repetir a listagem.
404 Specified group not found Confirme que GroupID corresponde a um grupo que este canal pode gerenciar; atualize a configuração de own_backend.
Situação O que significa O que fazer
400 Wrong request parameters Envie um id de pedido válido no corpo; aprove um id por chamada como descreve OpenAPI.
404 Specified group not found Liste pedidos de novo — o id pode já estar aprovado, rejeitado ou retirado.
Situação O que significa O que fazer
400 Wrong request parameters Igual o corpo DELETE ao OpenAPI e passe o id de pedido que quer rejeitar.
404 Specified group not found Busque a fila de novo; o pedido pode não existir mais no servidor.
Perguntas frequentes

Pedidos de entrada e ids de pedido

Ative groups.put no webhook do canal. A Whapi publica event.type groups e event.event put com groups_participants onde action é request, group_id é o JID do grupo e participants lista o id do solicitante; depois seu worker chama getGroupApplicationsList e approveGroupApplicationsList ou rejectGroupApplicationsList.
OpenAPI descreve um id de pedido por chamada approveGroupApplicationsList e um por rejectGroupApplicationsList. Itere em own_backend quando várias pessoas esperam.
Use o identificador de pedido da resposta getGroupApplicationsList (campo application esperado por ApplicationRequest). Se a chamada retornar 404, liste de novo antes de repetir — a fila pode ter mudado.
Trate como seu failure_mode do catálogo: confirme que o grupo ainda é só com aprovação, que o link de convite é válido e que você não rejeitou o mesmo id em outro lugar. Alerte ops em vez de deixar tentativas duplicadas de aprovar rodando para sempre.
Recursos compatíveis do WhatsApp

Tudo o que você precisa para criar automações no WhatsApp

O Whapi.Cloud oferece acesso a um conjunto completo de recursos do WhatsApp — mensagens, mídia, grupos, canais, webhooks e muito mais. Crie bots, automações e integrações sem limitações de funcionalidades.

Escolhido por desenvolvedores

Confiado por mais de 3.300 desenvolvedores e equipes SaaS

Desenvolvedores no mundo inteiro utilizam o Whapi.Cloud para criar automações, bots, integrações com CRM, ferramentas de envio em massa e fluxos avançados de WhatsApp. Nossa infraestrutura processa milhões de requisições API com alta estabilidade — e esse número cresce a cada mês.

Ícone de recurso

5,5K+

canais de API ativos

Ícone de recurso

21M+

requisições API por mês

“Tudo é simples, intuitivo e fácil de navegar. A documentação é clara e todas as informações estão bem à mão. Trabalho excelente.”

Roberto K. / Desenvolvedor Web

“Conectamos o WhatsApp aos nossos fluxos usando o n8n em apenas alguns minutos. Sem código, sem complicações — funcionou de primeira.”

Martin P. / Desenvolvedor

“O Whapi.Cloud se tornou uma parte essencial da nossa comunicação com clientes. Automatizamos atualizações de produtos, notificações de pedidos e mensagens de suporte — tudo sem templates nem aprovações da Meta.”

Oscar T. / CTO

Balão decorativo