TL;DR: Tres endpoints de Whapi.Cloud cubren el ciclo completo de solicitudes de unión a grupos: GET para listar solicitudes pendientes, POST para aceptar una y DELETE para rechazar una. Configure un webhook groups.put, filtre por action: "request", y enrute a aceptar o rechazar según su regla. El manejador Python Flask tiene menos de 50 líneas. Para Make o n8n, es un disparador Webhook más un módulo HTTP. Comience con un sandbox gratuito para probar cada llamada antes de desplegar.
Por Qué la Moderación Manual de Grupos Falla a Escala
Todo grupo cerrado de WhatsApp falla eventualmente bajo la moderación manual. Con 20 solicitudes de unión por semana la tarea es una interrupción rutinaria; con 100, las solicitudes se acumulan sin respuesta y la integridad del grupo se deteriora.
Los cohortes de cursos en línea, las comunidades beta de SaaS y los canales de membresía de pago enfrentan el mismo límite: un administrador que debe abrir la aplicación, leer cada solicitud y aprobar o rechazar con un toque. El trabajo no escala.
Whapi.Cloud cubre el ciclo completo de moderación: detecta una solicitud de unión en el instante en que llega, recupera la lista completa de solicitudes pendientes bajo demanda, acepta a un solicitante específico y rechaza a otros, todo a través de tres endpoints REST. Esta guía muestra exactamente cómo conectarlos, tanto para desarrolladores de Python como para equipos que usan Make o n8n.
La referencia completa de la API de Grupos y la guía de automatización de grupos cubren toda la superficie de la API; este artículo se enfoca específicamente en la moderación de solicitudes de unión.
Requisitos Previos Antes de Comenzar
Antes de escribir cualquier código, confirme que tiene los cuatro elementos siguientes. Si falta alguno, las llamadas a la API fallarán silenciosamente o devolverán un 403.
-
Cuenta de Whapi.Cloud con un número conectado: regístrese en panel.whapi.cloud/register, escanee el código QR y copie su token de canal desde el panel de control.
-
Rol de administrador del grupo: el número conectado debe ser administrador del grupo objetivo. Las cuentas sin rol de administrador reciben un 403 en todos los endpoints de moderación.
-
Configuración de grupo cerrado/privado: las solicitudes de unión solo existen cuando el grupo está configurado como "Privado"; solo los administradores pueden aprobar nuevos miembros. Los grupos abiertos no tienen cola de solicitudes pendientes.
-
Python 3.8+ con
requestsyFlask(para la ruta del desarrollador), o una cuenta activa de Make o n8n (para la ruta de bajo código).
Cómo Funcionan las Solicitudes de Unión a Grupos de WhatsApp
Cuando un grupo de WhatsApp está configurado como privado, cualquier persona que intente unirse a través de un enlace de invitación entra en una cola pendiente en lugar de unirse de inmediato. GET /groups/{GroupID}/applications expone esa cola a través de la API.
Cada solicitante permanece en la cola hasta que se le acepta o rechaza explícitamente. No hay expiración automática. Para comunidades de alto volumen, la cola puede alcanzar cientos de entradas si no se gestiona. La moderación automatizada es la única forma confiable de mantener el ritmo.
Configuración del Disparador Webhook para Solicitudes de Unión
Un webhook de solicitud de unión se activa en el instante en que alguien solicita entrar a su grupo. No necesita sondear el endpoint de la lista; Whapi.Cloud envía el evento a su URL en tiempo real en el momento en que WhatsApp lo entrega.
Para habilitarlo, vaya a la configuración de su canal en Whapi.Cloud y active el evento de webhook groups.put. Configure la URL del webhook con el endpoint de su servidor (o la URL del Webhook de Make/n8n). Una vez habilitado, cada cambio de membresía del grupo — uniones, salidas, promociones y solicitudes de unión — enviará un POST a esa URL.
El payload de una solicitud de unión tiene este aspecto. Para descripciones completas de los campos, consulte la referencia del formato de webhooks entrantes:
{
"groups_participants": [
{
"group_id": "[email protected]",
"participants": [
"61371989850"
],
"action": "request"
}
],
"event": {
"type": "groups",
"event": "put"
},
"channel_id": "MANTIS-M72HC"
}
El discriminador es el campo action. El mismo webhook groups.put también se activa para uniones, salidas, promociones de administrador y eliminaciones. Su manejador debe verificar action === "request" antes de llamar a cualquier endpoint de moderación. De lo contrario, intentará aprobar a personas que ya se unieron.
Del payload, extraiga dos valores: group_id (p. ej., [email protected]) y cada entrada en participants (el número de teléfono o identificador @lid del solicitante). Ambos son parámetros obligatorios para cada llamada a la API de moderación.
Obtención de la Lista de Solicitudes de Unión Pendientes
El endpoint GET recupera la cola completa de pendientes bajo demanda, independientemente de los webhooks. Úselo para completar aprobaciones al inicio, auditar la cola actual o mostrar un panel de revisión.
| Parámetro | Tipo | Obligatorio | Descripción |
GroupID |
string | Sí | ID completo del grupo incluyendo el sufijo @g.us |
count |
number | No | Número máximo de resultados a devolver |
offset |
number | No | Desplazamiento de resultados para paginación |
count y offset para paginar cuando la cola supere las 50 entradas pendientes; cada llamada devuelve solo tantos registros como especifica count.
La llamada Python a continuación lista las solicitudes pendientes con su token de canal en el encabezado de autorización. Consulte la documentación de miembros de grupos de Whapi.Cloud para descripciones completas de los campos de respuesta.
import requests
WHAPI_TOKEN = "your_channel_token_here"
WHAPI_BASE = "https://gate.whapi.cloud"
def get_pending_applications(group_id):
"""Lists pending join requests for a group. Inputs: group_id (str). Returns: list of applicants."""
url = f"{WHAPI_BASE}/groups/{group_id}/applications"
headers = {"Authorization": f"Bearer {WHAPI_TOKEN}"}
resp = requests.get(url, headers=headers)
resp.raise_for_status()
return resp.json()
# Example usage
pending = get_pending_applications("[email protected]")
print(pending)
La respuesta incluye el número de teléfono o identificador @lid de cada solicitante. Use count y offset para paginar a través de colas con más de 50 entradas.
Aceptación de una Solicitud de Unión a través de la API
POST /groups/{GroupID}/applications acepta exactamente a un solicitante por llamada. Pase el número de teléfono o el identificador @lid del payload del webhook como parámetro application. Para aprobar a múltiples solicitantes, llame en un bucle.
| Parámetro | Ubicación | Obligatorio | Descripción |
GroupID |
path | Sí | ID completo del grupo (p. ej., [email protected]) |
application |
body (JSON) | Sí | Chat ID del solicitante (número de teléfono o @lid del payload del webhook) |
Authorization |
header | Sí | Bearer {channel_token} |
application acepta tanto un número de teléfono como un identificador @lid; ambos son Chat IDs válidos para los endpoints de aceptar y rechazar.
Ruta Python: Aceptar una Solicitud
La función siguiente acepta a un único solicitante. Llámela para cada entrada en el array participants del payload del webhook. Verifique el código de estado de la respuesta: 200 significa éxito, un 4xx significa que el ID del solicitante es incorrecto o que no tiene derechos de administrador.
def approve_application(group_id, participant):
"""Accepts one join request. Inputs: group_id (str), participant phone (str). Returns: response."""
url = f"{WHAPI_BASE}/groups/{group_id}/applications"
headers = {"Authorization": f"Bearer {WHAPI_TOKEN}"}
body = {"application": participant}
resp = requests.post(url, json=body, headers=headers)
if resp.status_code not in (200, 201):
print(f"Approve failed [{resp.status_code}]: {resp.text}")
return resp
Ruta de Bajo Código: Aceptar en Make
En Make: el módulo Webhook se activa, el módulo HTTP llama al endpoint de Whapi.Cloud. Configure el módulo HTTP después de que su disparador Webhook filtre el evento de solicitud de unión. Consulte la guía de integración con Make.com para la configuración completa del escenario:
-
URL:
https://gate.whapi.cloud/groups/{{groups_participants[].group_id}}/applications -
Método: POST
-
Encabezados: Agregue un encabezado con Nombre
Authorization, ValorBearer {{your_channel_token}} -
Tipo de cuerpo: Raw, Tipo de contenido: JSON
-
Contenido del cuerpo:
{"application": "{{groups_participants[].participants[]}}"}
Ruta de Bajo Código: Aceptar en n8n
En n8n: el nodo Webhook captura el evento, el nodo HTTP Request llama a aceptar o rechazar. Después del nodo Webhook y un nodo IF que filtre por body.groups_participants[0].action === "request", configure el nodo HTTP Request:
-
URL:
https://gate.whapi.cloud/groups/{{$json.body.groups_participants[0].group_id}}/applications -
Método: POST
-
Autenticación: Header Auth. Nombre:
Authorization, Valor:Bearer {{your_channel_token}} -
Parámetros del cuerpo: Enviar cuerpo como JSON. Clave:
application, Valor:{{$json.body.groups_participants[0].participants[0]}}
Rechazo de Solicitudes de Unión a través de la API
El endpoint DELETE rechaza a un solicitante por llamada, con los mismos parámetros que el endpoint de aceptación. Cambie el método HTTP a DELETE; todo lo demás permanece idéntico. Para rechazos masivos, itere sobre la lista de participantes.
application en el body; solo cambia el método HTTP de POST a DELETE.
Ruta Python: Rechazar una Solicitud
def reject_application(group_id, participant):
"""Rejects one join request. Inputs: group_id (str), participant phone (str). Returns: response."""
url = f"{WHAPI_BASE}/groups/{group_id}/applications"
headers = {"Authorization": f"Bearer {WHAPI_TOKEN}"}
body = {"application": participant}
resp = requests.delete(url, json=body, headers=headers)
if resp.status_code not in (200, 201):
print(f"Reject failed [{resp.status_code}]: {resp.text}")
return resp
Ruta de Bajo Código: Rechazar en Make
Misma configuración del módulo HTTP que en el flujo de aceptación anterior. Cambie solo un campo:
-
Método: DELETE (todos los demás campos — URL, encabezados, cuerpo — permanecen iguales al módulo de aceptación)
Ruta de Bajo Código: Rechazar en n8n
-
Método: DELETE (URL, autenticación y parámetros del cuerpo permanecen idénticos al nodo de aceptación)
-
En n8n, conecte las ramas "true" (aprobar) y "false" (rechazar) de su nodo IF a nodos HTTP Request separados con los métodos respectivos.
Construcción del Flujo Completo de Automatización de Moderación
El manejador Python completo es una única ruta Flask que filtra el webhook, aplica su regla y llama a POST o DELETE. Cabe en menos de 50 líneas y cubre los tres endpoints.
Reemplace la función should_approve() con su propia lógica: verificar contra una lista de permitidos, validar un dominio de correo electrónico, buscar el número de teléfono en su CRM o consultar su propia base de datos. El tutorial de bot de WhatsApp en Python cubre patrones Flask adicionales si desea extender este manejador.
import requests
from flask import Flask, request, jsonify
app = Flask(__name__)
WHAPI_TOKEN = "your_channel_token_here"
WHAPI_BASE = "https://gate.whapi.cloud"
def get_pending_applications(group_id):
"""Lists pending join requests. Inputs: group_id (str). Returns: API response JSON."""
url = f"{WHAPI_BASE}/groups/{group_id}/applications"
headers = {"Authorization": f"Bearer {WHAPI_TOKEN}"}
resp = requests.get(url, headers=headers)
resp.raise_for_status()
return resp.json()
def approve_application(group_id, participant):
"""Accepts one join request. Inputs: group_id (str), participant phone (str). Returns: response."""
url = f"{WHAPI_BASE}/groups/{group_id}/applications"
headers = {"Authorization": f"Bearer {WHAPI_TOKEN}"}
resp = requests.post(url, json={"application": participant}, headers=headers)
if resp.status_code not in (200, 201):
print(f"Approve failed [{resp.status_code}]: {resp.text}")
return resp
def reject_application(group_id, participant):
"""Rejects one join request. Inputs: group_id (str), participant phone (str). Returns: response."""
url = f"{WHAPI_BASE}/groups/{group_id}/applications"
headers = {"Authorization": f"Bearer {WHAPI_TOKEN}"}
resp = requests.delete(url, json={"application": participant}, headers=headers)
if resp.status_code not in (200, 201):
print(f"Reject failed [{resp.status_code}]: {resp.text}")
return resp
def should_approve(phone_number):
"""
Your custom approval rule. Return True to accept, False to reject.
Replace this with your own logic: allowlist check, CRM lookup, domain validation, etc.
"""
# Example: approve any number (replace with real condition)
return True
@app.route("/webhook", methods=["POST"])
def handle_webhook():
"""Receives Whapi.Cloud webhook events and routes join requests to approve or reject."""
data = request.get_json(force=True)
for group_event in data.get("groups_participants", []):
# Only process join request events — skip joins, leaves, and promotions
if group_event.get("action") != "request":
continue
group_id = group_event["group_id"]
for participant in group_event.get("participants", []):
if should_approve(participant):
approve_application(group_id, participant)
else:
reject_application(group_id, participant)
return jsonify({"status": "ok"})
if __name__ == "__main__":
app.run(port=5000)
Sobre el manejo de errores: una respuesta 403 significa que el número conectado no es administrador del grupo. Un 404 significa que el ID del grupo es incorrecto o que el solicitante ya abandonó la cola. Registre ambos: identifican errores de configuración, no fallos transitorios.
Para la ruta de bajo código, el flujo completo en Make o n8n sigue esta secuencia:
-
Disparador Webhook: el módulo Custom Webhook (Make) o el nodo Webhook (n8n) recibe el payload
groups.putde Whapi.Cloud. -
Filtro: el Router (Make) o el nodo IF (n8n) verifica que
groups_participants[].actionsea igual arequest. Los eventos que no coinciden se descartan. -
Decisión: agregue su propia condición: busque el número del participante en una lista de permitidos en Google Sheets, verifique una solicitud HTTP a una base de datos, o use un filtro de texto simple.
-
Módulo HTTP (ruta de aceptación): POST a
https://gate.whapi.cloud/groups/{group_id}/applicationscon{"application": "{participant}"}en el cuerpo JSON. -
Módulo HTTP (ruta de rechazo): misma URL, mismo cuerpo; el método cambia a DELETE.
Whapi.Cloud entrega un payload JSON limpio con un único campo discriminador. Make y n8n lo mapean directamente sin middleware ni transformador personalizado. La moderación automatizada elimina la cola de administración manual y aplica reglas de acceso consistentes en todos los grupos que administra el número conectado.
Nota sobre los Identificadores @lid en las Solicitudes de Unión
Algunos solicitantes aparecen como identificadores @lid, como 1524746986546@lid, en lugar de números de teléfono, debido a los cambios de privacidad de WhatsApp en 2025. Pase los valores @lid directamente como parámetro application; funcionan de manera idéntica a los números de teléfono en los endpoints de aceptar y rechazar.
Whapi.Cloud resuelve automáticamente los @lid a números de teléfono cuando WhatsApp proporciona el mapeo. Cuando la resolución no está disponible, el valor @lid se devuelve tal cual y aún puede pasarse directamente como parámetro application al endpoint de aceptar o rechazar. Para una explicación completa, consulte los artículos de la base de conocimiento de Whapi.Cloud sobre qué es @lid en los grupos de WhatsApp y las preguntas frecuentes sobre @lid.
Resumen de Endpoints: El Ciclo Completo de Moderación
Tres endpoints — GET para listar, POST para aceptar, DELETE para rechazar — cubren el ciclo completo de moderación. Aquí está la tabla de referencia completa antes de pasar a las pruebas:
| Operación | Método | Endpoint | Cuerpo requerido | Notas |
| Listar solicitudes pendientes | GET | /groups/{GroupID}/applications |
Ninguno | Devuelve la cola completa; admite paginación |
| Aceptar una solicitud | POST | /groups/{GroupID}/applications |
{"application": "phone_or_lid"} |
Un solicitante por llamada; use bucle para múltiples |
| Rechazar una solicitud | DELETE | /groups/{GroupID}/applications |
{"application": "phone_or_lid"} |
Un solicitante por llamada; use bucle para múltiples |
Las tres llamadas usan el mismo encabezado de autorización: Bearer {channel_token}. La URL base es https://gate.whapi.cloud. Cualquier limitación de velocidad que agregue es por detección de spam del lado de WhatsApp, no por restricciones de la API de Whapi.Cloud; los planes de producción no tienen límites de velocidad estrictos a nivel de API.
Comience a Probar en el Sandbox Gratuito
Inicie un sandbox gratuito de Whapi.Cloud para probar la API de solicitudes de unión sin pago. El sandbox es permanentemente gratuito: 5 conversaciones activas por mes, sin límite de tiempo. Escanee un código QR, conecte un número y ejecute cada endpoint de esta guía en un grupo real de WhatsApp antes de desplegarlo en producción.









