WhatsApp API Multi Device Version

Un servidor de API de WhatsApp multidispositivo para agentes y herramientas de IA.

Documentación

GoWA Logo

Go WhatsApp — Diseñado para un uso eficiente de la memoria

Patreon

¡Si estás usando esta herramienta para generar ingresos, considera apoyar su desarrollo convirtiéndote en miembro de Patreon!

¡Tu apoyo ayuda a garantizar que el proyecto se mantenga actualizado y reciba actualizaciones periódicas!


release version Build Image Binary Release

Soporte para ARM, AMD64 y MCP

Descarga:

Nodo de la comunidad n8n

  • Paquete n8n
  • Ve a Configuración → Nodos de la comunidad, ingresa @aldinokemal2104/n8n-nodes-gowa y selecciona Instalar.

Cambios importantes

  • v6
    • El modo REST requiere <binary> rest en lugar de <binary>.
      • Ejemplo: ./whatsapp rest en lugar de ./whatsapp.
      • El modo MCP requería <binary> mcp.
      • Ejemplo: ./whatsapp mcp.
  • v7
    • A partir de la versión 7.x, los binarios se compilan con GoReleaser y se pueden descargar desde el último release.
  • v8
    • Soporte multi-dispositivo: Ahora puedes conectar y gestionar múltiples cuentas de WhatsApp simultáneamente en una única instancia del servidor.
      • Nueva API de gestión de dispositivos: Nuevos endpoints bajo /devices gestionan múltiples dispositivos.
      • Ámbito de dispositivo requerido: Todas las llamadas a la API REST con ámbito de dispositivo ahora requieren:
      • El encabezado X-Device-Id, o - El parámetro de consulta device_id. - Si solo hay un dispositivo registrado, se utiliza como predeterminado.
      • Ámbito de dispositivo WebSocket: Conéctate a /ws?device_id=<id> para limitar la conexión WebSocket a un dispositivo específico.
      • Soporte de UI remota: CORS permite los encabezados Authorization y X-Device-Id, por lo que una interfaz web independiente (por ejemplo, gowa-ui) alojada en otro origen puede llamar a la API directamente. GET /app/info expone la versión y los límites de tamaño de medios. Debido a que los navegadores no pueden establecer encabezados en conexiones WebSocket, pasa /ws?device_id=<id>&authorization=<base64(user:pass)> cuando la autenticación básica esté habilitada (usa TLS; la credencial es visible en la URL).
      • Cambios en los payloads de webhooks: Todos los payloads de webhooks ahora incluyen un campo de nivel superior device_id que identifica qué dispositivo recibió el evento:
      {
        "event": "message",
        "device_id": "628123456789@s.whatsapp.net",
        "payload": { ... }
      }
      
  • v9
    • MCP y API están unificados bajo rest: MCP ya no es un modo o proceso separado. Ejecuta ./whatsapp rest para servir tanto la API REST como MCP; MCP está disponible en /mcp (sin subcomando independiente mcp). Consulta Servidor MCP (Model Context Protocol) para detalles de migración.
      • La UI se movió a un repositorio separado: El panel web ya no está incluido en este repositorio. Ahora vive en aldinokemal/gowa-ui y se distribuye como un único gowa-ui.html autocontenido. El servidor descarga la última versión del panel al iniciar, verifica su digest SHA-256, lo almacena en caché bajo storages/ui/ y lo sirve en /. Consulta Panel web (gowa-ui) para la configuración de APP_UI_*, el anclaje de la cadena de suministro y la implementación en entornos aislados.

Características

  • Envía mensajes de WhatsApp a través de la API HTTP. Consulta docs/openapi.yaml para más detalles.
  • Soporte de servidor MCP (Model Context Protocol) — Integra agentes y herramientas de IA usando un protocolo estandarizado.
  • OAuth 2.1 MCP opcional — Conecta clientes MCP remotos que no pueden proporcionar un encabezado de autenticación básica. Consulta MCP OAuth.
  • Menciona usuarios en el texto del mensaje y en los subtítulos de imágenes, videos o archivos:
    • @phoneNumber
      • Ejemplo: Hello @628974812XXXX, @628974812XXXX
  • Menciones fantasma (mencionar a todos) — Menciona a los participantes del grupo sin mostrar @phone en el texto del mensaje.
    • Pasa números de teléfono en el campo mentions para mencionar usuarios sin un @ visible en el mensaje.
      • Usa la palabra clave especial @everyone para mencionar automáticamente a todos los participantes del grupo.
  • Publica actualizaciones de estado de WhatsApp.
  • Marca los mensajes de audio entrantes y las notas de voz como reproducidos.
  • Envíos programados — Envía cualquier mensaje más tarde, una vez o con repetición diaria, semanal o mensual.
    • Agrega scheduled_at (RFC3339) y timezone (IANA) a una solicitud de envío; recurrence, weekdays, day_of_month, end_at y occurrence_limit controlan las repeticiones.
      • Los horarios sobreviven a los reinicios y esperan a un dispositivo sin conexión; lista, pausa, reanuda o cancélalos en /send/schedules.
  • Envía stickers — Convierte automáticamente imágenes al formato de sticker WebP.
    • Soporta formatos JPG, JPEG, PNG, WebP y GIF.
      • Redimensiona automáticamente las imágenes a 512×512 píxeles.
      • Preserva la transparencia en imágenes PNG.
      • Los stickers WebP animados son compatibles pero deben cumplir los requisitos de WhatsApp:
      • Exactamente 512×512 píxeles. - Menos de 500 KB. - No más de 10 segundos de duración. - Si un sticker animado no cumple estos requisitos, rediménsionalo antes de subirlo con una herramienta como ezgif.com.
  • Comprime imágenes antes de enviarlas.
  • Comprime videos antes de enviarlos.
  • Personaliza el nombre del sistema operativo que se muestra como nombre del dispositivo vinculado en WhatsApp:
    • --os=Chrome o --os=MyApplication
  • Autenticación básica con múltiples credenciales:
    • --basic-auth=kemal:secret,toni:password,userName:secretPassword
      • Forma corta: -b=kemal:secret,toni:password,userName:secretPassword
  • Soporte de implementación en subruta:
    • --base-path="/gowa" permite la implementación bajo una ruta como /gowa.
  • Puerto personalizable y modo de depuración:
    • --port 8000
      • --debug true
  • Respuestas automáticas a mensajes entrantes:
    • --autoreply="Don't reply to this message"
  • Marca automáticamente los mensajes entrantes como leídos:
    • --auto-mark-read=true
  • Descarga automáticamente medios de mensajes entrantes:
    • --auto-download-media=false desactiva la descarga automática de medios (predeterminado: true).
  • Ignora la descarga de medios de estado:
    • --ignore-status-media=true desactiva la descarga de medios de estado (predeterminado: false).
  • Rechaza automáticamente llamadas entrantes:
    • --auto-reject-call=true o WHATSAPP_AUTO_REJECT_CALL=true (consulta Webhook Payload para eventos de llamadas).
  • Presencia configurable al conectar:
    • --presence-on-connect=unavailable o WHATSAPP_PRESENCE_ON_CONNECT=unavailable
      • available — Marca la cuenta como en línea (suprime las notificaciones del teléfono).
      • unavailable — Registra el nombre de push sin conectarse (predeterminado; preserva las notificaciones del teléfono).
      • none — Omite la presencia por completo (el nombre de push no se registra, por lo que los contactos pueden ver - como nombre).
  • Pulso de presencia diario:
    • --presence-pulse-enabled=true o WHATSAPP_PRESENCE_PULSE_ENABLED=true (predeterminado: true).
      • --presence-pulse-interval=24h controla con qué frecuencia se pulsa cada dispositivo conectado.
      • --presence-pulse-duration=5m controla cuánto tiempo permanece la cuenta en available antes de volver a unavailable.
  • Webhooks para mensajes recibidos y otros eventos:
  • Webhooks por dispositivo — Cada dispositivo puede tener su propia URL de webhook y filtros de eventos.
    • Configura vía API: PATCH /devices/:device_id/webhook con {"webhook_url": "https://device-webhook.site/handler"}.
      • Obtén vía API: GET /devices/:device_id/webhook.
      • Cuando un dispositivo tiene un webhook personalizado, los eventos de ese dispositivo se envían a la URL específica del dispositivo.
      • Cuando no se establece un webhook de dispositivo, los eventos recurren al webhook global (--webhook).
      • Establece webhook_url a una cadena vacía con PATCH para limpiarlo y usar el webhook global.
      • Establece WHATSAPP_WEBHOOK_DEVICE_MERGE_GLOBAL=true (o --webhook-device-merge-global=true) para que un webhook de dispositivo sea una adición en lugar de un reemplazo: las URLs globales de --webhook aún reciben los eventos del dispositivo (firmados con el secreto global, filtrados por WHATSAPP_WEBHOOK_EVENTS) mientras que la URL del dispositivo mantiene su propio secreto y filtro de eventos.
  • Firmas de webhook — Las solicitudes de webhook incluyen una firma HMAC-SHA-256 en el encabezado X-Hub-Signature-256, generada con la clave predeterminada secret. Cambia la clave con:
    • --webhook-secret="secret"
  • Documentación de payloads de webhook — Para esquemas detallados, implementación de seguridad y ejemplos de integración, consulta Documentación de payloads de webhook.
  • Filtrado de eventos de webhook — Filtra qué eventos se reenvían a tu webhook con:
    • --webhook-events="message,message.ack" (una lista separada por comas), o
      • WHATSAPP_WEBHOOK_EVENTS=message,message.ack. Eventos de webhook disponibles: | Evento | Descripción | | --- | --- | | message | Mensajes de texto, medios, contactos, ubicación | | message.reaction | Reacciones de emoji a mensajes | | message.revoked | Mensajes eliminados/revocados | | message.edited | Mensajes editados | | message.ack | Confirmaciones de entrega y lectura | | message.deleted | Mensajes eliminados para el usuario | | chat_presence | Indicadores de escritura y grabación de contactos | | group.participants | Eventos de unirse/salir/promover/degradar miembros del grupo | | group.joined | Fuiste agregado a un grupo | | label.edit | Los metadatos de etiquetas de WhatsApp cambiaron | | label.association | Etiqueta aplicada o eliminada de un chat | | newsletter.joined | Te suscribiste a un boletín/canal | | newsletter.left | Te desuscribiste de un boletín | | newsletter.message | Nuevo(s) mensaje(s) publicado(s) en un boletín | | newsletter.mute | La configuración de silencio del boletín cambió | | call.offer | Llamada entrante recibida | Si esta configuración está vacía, todos los eventos se reenvían.
  • Filtrado de JID de webhook Puedes omitir eventos para chats o remitentes específicos (por ejemplo, silenciar todos los grupos) antes de que se reenvíen:
    • --webhook-ignore-jids="@g.us,628123456789@s.whatsapp.net" (una lista separada por comas), o
      • WHATSAPP_WEBHOOK_IGNORE_JIDS=@g.us.
      • Soporta los comodines @g.us / @s.whatsapp.net / @lid (coinciden con un espacio de direcciones completo) y JIDs exactos.
      • Esto filtra por conversación o remitente y es independiente de --webhook-events, que filtra por tipo de evento. La integración con Chatwoot tiene una configuración separada de CHATWOOT_IGNORE_JIDS.
  • Configuración TLS de webhook Si encuentras errores de verificación de certificados TLS al usar webhooks (por ejemplo, con túneles de Cloudflare o certificados autofirmados):
    tls: failed to verify certificate: x509: certificate signed by unknown authority
    
    Puedes desactivar la verificación de certificados TLS con:
    • --webhook-insecure-skip-verify=true, o
      • WHATSAPP_WEBHOOK_INSECURE_SKIP_VERIFY=true. Advertencia de seguridad: Esta opción desactiva la verificación de certificados TLS y solo debe usarse en:
    • Entornos de desarrollo o pruebas.
      • Túneles de Cloudflare, que proporcionan su propia capa de seguridad.
      • Redes internas con certificados autofirmados. Para entornos de producción, usa un certificado TLS válido (por ejemplo, de Let's Encrypt) en lugar de desactivar la verificación.

Configuración

La configuración se carga en este orden de prioridad:

  1. Banderas de línea de comandos (mayor prioridad)
  2. Variables de entorno
  3. Archivo .env (menor prioridad)

Variables de entorno

Para usar variables de entorno:

  1. Desde la raíz del repositorio, copia el archivo de ejemplo: cp src/.env.example src/.env.
  2. Actualiza los valores en src/.env según sea necesario.
  3. Alternativamente, establece las mismas variables en el entorno del proceso.

Variables de entorno disponibles

VariableDescripciónPredeterminadoEjemplo
APP_PORTPuerto de la aplicación3000APP_PORT=8080
APP_HOSTDirección del host para vincular el servidor0.0.0.0APP_HOST=127.0.0.1
APP_DEBUGHabilitar registro de depuraciónfalseAPP_DEBUG=true
APP_OSNombre del sistema operativo (nombre del dispositivo en WhatsApp)GOWAAPP_OS=MyApp
APP_BASIC_AUTHCredenciales de autenticación básica-APP_BASIC_AUTH=user1:pass1,user2:pass2
APP_BASE_PATHRuta base para implementación en subruta-APP_BASE_PATH=/gowa
APP_TRUSTED_PROXIESRangos de IP de proxy de confianza para proxy inverso-APP_TRUSTED_PROXIES=0.0.0.0/0
APP_CORS_ALLOWED_ORIGINSOrígenes CORS permitidos (cualquier origen cuando está vacío)-APP_CORS_ALLOWED_ORIGINS=https://ui.example.com
APP_UI_ENABLEDServir el panel gowa-ui descargadotrueAPP_UI_ENABLED=false
APP_UI_AUTO_UPDATEDescargar y actualizar periódicamente el panel más recientetrueAPP_UI_AUTO_UPDATE=false
APP_UI_REPORepositorio de GitHub que contiene las versiones de gowa-uialdinokemal/gowa-uiAPP_UI_REPO=my-org/gowa-ui
APP_UI_ASSET_NAMENombre del archivo del recurso de la versión del panelgowa-ui.htmlAPP_UI_ASSET_NAME=gowa-ui.html
APP_UI_UPDATE_INTERVALIntervalo entre comprobaciones de actualización del panel3hAPP_UI_UPDATE_INTERVAL=6h
APP_UI_GITHUB_TOKENToken de GitHub opcional para un límite de API más alto-APP_UI_GITHUB_TOKEN=github_pat_xxx
APP_UI_ASSET_SHA256Pin SHA-256 opcional para el recurso del panel-APP_UI_ASSET_SHA256=<hex-digest>
MCP_ENABLEDServir el endpoint MCP HTTP transmisible en /mcptrueMCP_ENABLED=false
MCP_OAUTH_ENABLEDHabilitar autenticación OAuth 2.1 para MCPfalseMCP_OAUTH_ENABLED=true
MCP_OAUTH_ISSUER_URLURL pública del emisor HTTPS de OAuth-MCP_OAUTH_ISSUER_URL=https://gowa.example.com
MCP_OAUTH_RESOURCE_URLURL pública canónica opcional de MCPDerivado del emisor y la ruta baseMCP_OAUTH_RESOURCE_URL=https://gowa.example.com/mcp
MCP_OAUTH_DB_URIURI SQLite para clientes OAuth, códigos y hashes de tokensfile:storages/oauth.dbMCP_OAUTH_DB_URI=file:storages/oauth.db
DB_URIURI de conexión a la base de datosfile:storages/whatsapp.dbDB_URI=postgres://user:pass@host/db
DB_KEYS_URIURI de base de datos opcional para caché de claves de cifrado/sesión. Déjelo en blanco para usar DB_URI; evite almacenamiento en memoria en producción porque los reinicios pueden perder el estado de la sesión de WhatsApp.-DB_KEYS_URI=file:storages/whatsapp-keys.db?_foreign_keys=on
CHAT_STORAGE_MAX_OPEN_CONNSConexiones SQLite concurrentes máximas para almacenamiento de chats5CHAT_STORAGE_MAX_OPEN_CONNS=10
WHATSAPP_AUTO_REPLYMensaje de respuesta automática-WHATSAPP_AUTO_REPLY="Auto reply message"
WHATSAPP_AUTO_MARK_READMarcar automáticamente los mensajes entrantes como leídosfalseWHATSAPP_AUTO_MARK_READ=true
WHATSAPP_AUTO_DOWNLOAD_MEDIADescargar automáticamente medios de mensajes entrantestrueWHATSAPP_AUTO_DOWNLOAD_MEDIA=false
WHATSAPP_IGNORE_STATUS_MEDIAIgnorar descarga de medios de estado (status@broadcast)falseWHATSAPP_IGNORE_STATUS_MEDIA=true
WHATSAPP_AUTO_REJECT_CALLRechazar automáticamente llamadas entrantes de WhatsAppfalseWHATSAPP_AUTO_REJECT_CALL=true
WHATSAPP_WEBHOOKURL(s) de webhook para eventos (separadas por comas)-WHATSAPP_WEBHOOK=https://webhook.site/xxx
WHATSAPP_WEBHOOK_SECRETSecreto de webhook para validaciónsecretWHATSAPP_WEBHOOK_SECRET=super-secret-key
WHATSAPP_WEBHOOK_INSECURE_SKIP_VERIFYOmitir verificación TLS para webhooks (inseguro)falseWHATSAPP_WEBHOOK_INSECURE_SKIP_VERIFY=true
WHATSAPP_WEBHOOK_EVENTSLista blanca de eventos a reenviar (separados por comas, vacío = todos)-WHATSAPP_WEBHOOK_EVENTS=message,message.ack
WHATSAPP_WEBHOOK_IGNORE_JIDSJIDs/comodines a omitir al reenviar (separados por comas)-WHATSAPP_WEBHOOK_IGNORE_JIDS=@g.us
WHATSAPP_WEBHOOK_DEVICE_MERGE_GLOBALLos webhooks por dispositivo se agregan a las URL globales en lugar de reemplazarlasfalseWHATSAPP_WEBHOOK_DEVICE_MERGE_GLOBAL=true
WHATSAPP_ACCOUNT_VALIDATIONHabilitar validación de cuentatrueWHATSAPP_ACCOUNT_VALIDATION=false
WHATSAPP_PRESENCE_ON_CONNECTPresencia al conectar: available, unavailable, o noneunavailableWHATSAPP_PRESENCE_ON_CONNECT=unavailable
WHATSAPP_PROXYProxy de salida para el WebSocket de WhatsApp (SOCKS5/HTTP/HTTPS)-WHATSAPP_PROXY=socks5://user:pass@host:1080
WHATSAPP_PRESENCE_PULSE_ENABLEDHabilitar pulso diario de presencia disponible/no disponibletrueWHATSAPP_PRESENCE_PULSE_ENABLED=false
WHATSAPP_PRESENCE_PULSE_INTERVALIntervalo entre pulsos de presencia24hWHATSAPP_PRESENCE_PULSE_INTERVAL=24h
WHATSAPP_PRESENCE_PULSE_DURATIONDuración para permanecer disponible durante cada pulso5mWHATSAPP_PRESENCE_PULSE_DURATION=5m
CHATWOOT_ENABLEDHabilitar integración con ChatwootfalseCHATWOOT_ENABLED=true
CHATWOOT_URLURL de la instancia de Chatwoot-CHATWOOT_URL=https://app.chatwoot.com
CHATWOOT_API_TOKENToken de acceso a la API de Chatwoot-CHATWOOT_API_TOKEN=your-api-token
CHATWOOT_ACCOUNT_IDID de cuenta de Chatwoot-CHATWOOT_ACCOUNT_ID=12345
CHATWOOT_INBOX_IDID de bandeja de entrada de Chatwoot-CHATWOOT_INBOX_ID=67890
CHATWOOT_DEVICE_IDID de dispositivo de WhatsApp para Chatwoot (respaldo de dispositivo único/entorno)-CHATWOOT_DEVICE_ID=628xxx@s.whatsapp.net
CHATWOOT_ALLOWED_HOSTSLista permitida de hosts de Chatwoot para configuraciones por dispositivo (protección SSRF)-CHATWOOT_ALLOWED_HOSTS=app.chatwoot.com,chat.example.com
CHATWOOT_IMPORT_MESSAGESHabilitar sincronización del historial de mensajes con ChatwootfalseCHATWOOT_IMPORT_MESSAGES=true
CHATWOOT_DAYS_LIMIT_IMPORT_MESSAGESDías de historial a importar3CHATWOOT_DAYS_LIMIT_IMPORT_MESSAGES=7
CHATWOOT_IMPORT_DB_URIURI PostgreSQL directo de Chatwoot para sincronización de historial-CHATWOOT_IMPORT_DB_URI=postgresql://user:pass@host:5432/chatwoot_production?sslmode=disable
CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGEInsertar marcadores de posición de texto para filas de medios durante importación directa a BDtrueCHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=true
CHATWOOT_IMPORT_MEDIA_WITH_RESTSubir filas de medios de importación directa a BD mediante REST de ChatwootfalseCHATWOOT_IMPORT_MEDIA_WITH_REST=true
CHATWOOT_AUTO_CREATEAuto-crear o reutilizar la bandeja de entrada de API de Chatwoot al iniciofalseCHATWOOT_AUTO_CREATE=true
CHATWOOT_INBOX_NAMENombre de bandeja de entrada usado cuando la auto-creación está habilitadaWhatsAppCHATWOOT_INBOX_NAME=WhatsApp Support
CHATWOOT_WEBHOOK_URLURL pública del webhook de respuesta de Chatwoot de GOWA-CHATWOOT_WEBHOOK_URL=https://api.example.com/chatwoot/webhook?secret=shared
CHATWOOT_WEBHOOK_SECRETSecreto compartido requerido para webhooks entrantes de Chatwoot-CHATWOOT_WEBHOOK_SECRET=shared
CHATWOOT_REOPEN_CONVERSATIONReabrir conversaciones resueltas de Chatwoot para contactos que regresantrueCHATWOOT_REOPEN_CONVERSATION=false
CHATWOOT_CONVERSATION_PENDINGCrear nuevas conversaciones de Chatwoot como pendientesfalseCHATWOOT_CONVERSATION_PENDING=true
CHATWOOT_IGNORE_JIDSJIDs o comodines a excluir del reenvío de Chatwoot-CHATWOOT_IGNORE_JIDS=@g.us,628123@s.whatsapp.net
CHATWOOT_SIGN_MSGPrefijar respuestas de agentes de Chatwoot con el nombre del agentefalseCHATWOOT_SIGN_MSG=true
CHATWOOT_SIGN_DELIMITERDelimitador entre la firma del agente de Chatwoot y el cuerpo del mensaje\n\nCHATWOOT_SIGN_DELIMITER=" - "
CHATWOOT_FORWARD_EDITSReflejar ediciones de WhatsApp en notas enhebradas de ChatwoottrueCHATWOOT_FORWARD_EDITS=false
CHATWOOT_FORWARD_DELETESReflejar eventos de eliminación para todos de WhatsApp en notas de ChatwoottrueCHATWOOT_FORWARD_DELETES=false
CHATWOOT_MESSAGE_READSincronizar estado de lectura para mensajes vinculados de WhatsApp/ChatwootfalseCHATWOOT_MESSAGE_READ=true
CHATWOOT_MESSAGE_DELETEEliminar mensajes vinculados del lado opuesto cuando se reporta eliminaciónfalseCHATWOOT_MESSAGE_DELETE=true

Documentación:

Ejecute ./whatsapp --help para ver todas las banderas de línea de comandos.

Requisitos

Requisitos del sistema

  • Go 1.26.0 o posterior (al compilar desde el código fuente)
  • FFmpeg (para procesamiento de medios)

Plataformas compatibles

  • Linux (x86_64, ARM64)
  • macOS (Intel, Apple Silicon)
  • Windows (x86_64; se recomienda WSL)

Dependencias (sin Docker)

  • macOS:
    • brew install ffmpeg webp
      • export CGO_CFLAGS_ALLOW="-Xpreprocessor"
  • Linux:
    • sudo apt update
      • sudo apt install ffmpeg webp
  • Windows (se recomienda WSL; consulte Instalar WSL):
    • Instale FFmpeg.
      • Instale libwebp, luego extráigalo y agregue su directorio bin a PATH.

Nota: El paquete webp proporciona las herramientas cwebp (codificador), dwebp (decodificador) y webpmux (extractor de fotogramas). FFmpeg es necesario para el procesamiento de medios. Las herramientas de libwebp (webpmux + dwebp) se usan para soporte de stickers WebP animados.

Cómo usar

Básico

  1. Clone el repositorio: git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice.
  2. Abra el directorio clonado en una terminal.
  3. Ejecute cd src.
  4. Ejecute go run . rest.
  5. Abra http://localhost:3000.

Docker

Docker evita la necesidad de instalar Go, FFmpeg y libwebp directamente en el host.

  1. Clone el repositorio: git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice.
  2. Abra el directorio clonado en una terminal.
  3. Copie el archivo de entorno: cp src/.env.example src/.env.
  4. Ejecute docker compose up -d --build.
  5. Abra http://localhost:3000.

Compile su propio binario

  1. Clone el repositorio: git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice.
  2. Abra el directorio clonado en una terminal.
  3. Ejecute cd src.
  4. Compile el binario:
    • Linux y macOS: go build -o whatsapp
      • Windows (Símbolo del sistema o PowerShell): go build -o whatsapp.exe
  5. Inicie el servidor:
    • Linux y macOS: ./whatsapp rest
      • Windows: .\whatsapp.exe rest
  6. Abra http://localhost:3000 en un navegador.

Ejecute ./whatsapp --help (o .\whatsapp.exe --help en Windows) para ver todas las banderas.

Compilación cruzada para Raspberry Pi (ARM)

Para compilar para una Raspberry Pi u otro dispositivo ARM sin un conjunto de herramientas C (CGO), use la etiqueta de compilación purego. Esto selecciona una implementación de SQLite puramente en Go.

  1. Clone el repositorio: git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice.
  2. Abra el directorio clonado en una terminal.
  3. Ejecute cd src.
  4. Compile para Raspberry Pi Zero / 1 (ARMv6):
    CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=6 go build -tags purego -o whatsapp-armv6
    
  5. Compile para Raspberry Pi 2 / 3 / 4 (ARMv7 de 32 bits):
    CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build -tags purego -o whatsapp-armv7
    
  6. Transfiera el binario a su Pi, otórguele permiso de ejecución (chmod +x) y ejecútelo:
    • Si compiló ARMv6: ./whatsapp-armv6 rest
      • Si compiló ARMv7: ./whatsapp-armv7 rest

Servidor MCP (Protocolo de Contexto de Modelo)

MCP no es un modo o proceso separado: lo sirve el propio servidor REST. Siempre que ./whatsapp rest esté en ejecución, el endpoint de MCP está disponible en http://<host>:<port><base-path>/mcp (predeterminado http://localhost:3000/mcp) usando el transporte HTTP transmisible. Desactívelo con MCP_ENABLED=false o --mcp-enabled=false (predeterminado: habilitado).

Herramientas MCP disponibles

Hay seis herramientas consolidadas; los agentes eligen el comportamiento mediante un argumento type / action en lugar de una herramienta por operación:

HerramientaValores de type / action
whatsapp_sendtext, image, video, audio, document, sticker, location, contact, poll, link, forward
whatsapp_schedulelist, get, pause, resume, cancel
whatsapp_messagereact, edit, revoke, delete, mark_read, mark_played, star, unstar, download_media
whatsapp_chatlist_chats, list_contacts, get_messages, archive
whatsapp_groupcreate, join_with_link, leave, info, participants, add_participants, remove_participants, promote, demote, invite_link, set_name, set_topic, set_settings, join_requests, manage_join_requests
whatsapp_appstatus, login_qr, login_code, logout, reconnect

whatsapp_send también acepta scheduled_at, timezone, recurrence, weekdays, day_of_month, end_at y occurrence_limit para programar el mensaje en lugar de enviarlo ahora; administre el resultado con whatsapp_schedule.

Selección de dispositivo

Para implementaciones multi-dispositivo, el encabezado X-Device-Id en la conexión del cliente MCP selecciona el dispositivo utilizado por cada llamada de herramienta en esa conexión. Si se omite, se recurre al dispositivo predeterminado, igual que con REST. Cualquier llamada individual puede anularlo con un argumento opcional device_id.

Configuración de MCP

Apunte su cliente MCP al endpoint /mcp. Hereda la autenticación Basic Auth del servidor REST, así que incluya el mismo encabezado Authorization que usan sus llamadas REST:

{
  "mcpServers": {
    "whatsapp": {
      "url": "http://localhost:3000/mcp",
      "headers": {
        "Authorization": "Basic dXNlcjpzZWNyZXQ=",
        "X-Device-Id": "628123456789"
      }
    }
  }
}

headers es opcional: incluya Authorization solo cuando Basic Auth esté configurado, y X-Device-Id solo para configuraciones multi-dispositivo.

OAuth para clientes MCP remotos

OAuth 2.1 está disponible para clientes remotos que no pueden adjuntar un encabezado Basic Auth. Está deshabilitado por defecto. Una configuración mínima es:

APP_BASIC_AUTH=admin:replace-with-a-strong-password
MCP_ENABLED=true
MCP_OAUTH_ENABLED=true
MCP_OAUTH_ISSUER_URL=https://gowa.example.com

Cuando OAuth está habilitado, /mcp acepta un token Bearer o las credenciales Basic Auth configuradas. OAuth no autentica rutas REST ni de interfaz de usuario. Consulte MCP OAuth para la configuración del cliente, requisitos de proxy inverso, comportamiento de subrutas y el modelo de seguridad.

Migración desde el modo MCP independiente

  • ./whatsapp mcp → ./whatsapp rest (MCP ahora se incluye automáticamente).
  • http://localhost:8080/sse → http://localhost:3000/mcp.
  • 40 herramientas granulares → 5 herramientas consolidadas (los agentes eligen acciones a través del campo type / action).

Servidor REST de Producción (Docker)

Usando Docker Hub:

docker volume create whatsapp-storages
docker volume create whatsapp-statics
docker run --detach \
  --publish 3000:3000 \
  --name whatsapp \
  --restart always \
  --volume whatsapp-storages:/app/storages \
  --volume whatsapp-statics:/app/statics \
  aldinokemal2104/go-whatsapp-web-multidevice \
  rest --autoreply="Don't reply to this message, please"

Usando GitHub Container Registry:

docker volume create whatsapp-storages
docker volume create whatsapp-statics
docker run --detach \
  --publish 3000:3000 \
  --name whatsapp \
  --restart always \
  --volume whatsapp-storages:/app/storages \
  --volume whatsapp-statics:/app/statics \
  ghcr.io/aldinokemal/go-whatsapp-web-multidevice \
  rest --autoreply="Don't reply to this message, please"

Servidor REST de Producción (Docker Compose)

Cree un archivo docker-compose.yml con una de las siguientes configuraciones.

Usando Docker Hub:

services:
  whatsapp:
    image: aldinokemal2104/go-whatsapp-web-multidevice
    container_name: whatsapp
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - whatsapp_storages:/app/storages
      - whatsapp_statics:/app/statics
    command:
      - rest
      - --basic-auth=admin:admin
      - --port=3000
      - --debug=true
      - --os=Chrome
      - --account-validation=false

volumes:
  whatsapp_storages:
  whatsapp_statics:

Usando GitHub Container Registry:

services:
  whatsapp:
    image: ghcr.io/aldinokemal/go-whatsapp-web-multidevice
    container_name: whatsapp
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - whatsapp_storages:/app/storages
      - whatsapp_statics:/app/statics
    command:
      - rest
      - --basic-auth=admin:admin
      - --port=3000
      - --debug=true
      - --os=Chrome
      - --account-validation=false

volumes:
  whatsapp_storages:
  whatsapp_statics:

Usando variables de entorno con Docker Hub:

services:
  whatsapp:
    image: aldinokemal2104/go-whatsapp-web-multidevice
    container_name: whatsapp
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - whatsapp_storages:/app/storages
      - whatsapp_statics:/app/statics
    environment:
      - APP_BASIC_AUTH=admin:admin
      - APP_PORT=3000
      - APP_DEBUG=true
      - APP_OS=Chrome
      - WHATSAPP_ACCOUNT_VALIDATION=false

volumes:
  whatsapp_storages:
  whatsapp_statics:

Usando variables de entorno con GitHub Container Registry:

services:
  whatsapp:
    image: ghcr.io/aldinokemal/go-whatsapp-web-multidevice
    container_name: whatsapp
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - whatsapp_storages:/app/storages
      - whatsapp_statics:/app/statics
    environment:
      - APP_BASIC_AUTH=admin:admin
      - APP_PORT=3000
      - APP_DEBUG=true
      - APP_OS=Chrome
      - WHATSAPP_ACCOUNT_VALIDATION=false

volumes:
  whatsapp_storages:
  whatsapp_statics:

Inicie la pila seleccionada con docker compose up -d.

Servidor de Producción (Binario)

Descargue un binario desde la página de versiones y luego ejecútelo con el subcomando rest.

También puede bifurcar o modificar el código fuente.

API Actual

API MCP (Model Context Protocol)

  • Se sirve en /mcp por el servidor REST usando HTTP transmisible siempre que MCP_ENABLED sea verdadero. Con APP_BASE_PATH configurado, la ruta es <base-path>/mcp.
  • Las herramientas disponibles se enumeran en la sección "Herramientas MCP Disponibles" anterior.
  • Compatible con herramientas y agentes de IA habilitados para MCP.

API REST HTTP

EstadoOperaciónMétodoURL
✅Verificación de SaludGET/health
✅Listar DispositivosGET/devices
✅Agregar DispositivoPOST/devices
✅Obtener Información del DispositivoGET/devices/:device_id
✅Eliminar DispositivoDELETE/devices/:device_id
✅Iniciar Sesión en Dispositivo (QR)GET/devices/:device_id/login
✅Iniciar Sesión en Dispositivo (Código)POST/devices/:device_id/login/code
✅Cerrar Sesión del DispositivoPOST/devices/:device_id/logout
✅Reconectar DispositivoPOST/devices/:device_id/reconnect
✅Obtener Estado del DispositivoGET/devices/:device_id/status
✅Obtener Webhook del DispositivoGET/devices/:device_id/webhook
✅Configurar Webhook del DispositivoPATCH/devices/:device_id/webhook
✅Iniciar Sesión con Código QRGET/app/login
✅Iniciar Sesión con Código de VinculaciónGET/app/login-with-code
✅Estado de Vinculación PasskeyGET/app/passkey
✅Respuesta de Vinculación PasskeyPOST/app/passkey/response
✅Confirmar Vinculación PasskeyPOST/app/passkey/confirm
✅Cerrar SesiónGET/app/logout
✅ReconectarGET/app/reconnect
✅DispositivosGET/app/devices
✅Estado de ConexiónGET/app/status
✅Información de la App (versión, límites)GET/app/info
✅Información del UsuarioGET/user/info
✅Avatar del UsuarioGET/user/avatar
✅Cambiar Avatar del UsuarioPOST/user/avatar
✅Cambiar Nombre de UsuarioPOST/user/pushname
✅Listar Mis Grupos*GET/user/my/groups
✅Listar Mis BoletinesGET/user/my/newsletters
✅Obtener Mis Configuraciones de PrivacidadGET/user/my/privacy
✅Listar Mis ContactosGET/user/my/contacts
✅Verificar Usuario de WhatsAppGET/user/check
✅Obtener Perfil de NegocioGET/user/business-profile
✅Enviar MensajePOST/send/message
✅Enviar ImagenPOST/send/image
✅Enviar AudioPOST/send/audio
✅Enviar ArchivoPOST/send/file
✅Enviar VideoPOST/send/video
✅Enviar StickerPOST/send/sticker
✅Enviar ContactoPOST/send/contact
✅Enviar EnlacePOST/send/link
✅Enviar UbicaciónPOST/send/location
✅Enviar Encuesta / VotoPOST/send/poll
✅Enviar PresenciaPOST/send/presence
✅Enviar Presencia de Chat (Indicador de Escritura)POST/send/chat-presence
✅Listar Envíos ProgramadosGET/send/schedules
✅Obtener Envío ProgramadoGET/send/schedules/:schedule_id
✅Pausar Envío ProgramadoPOST/send/schedules/:schedule_id/pause
✅Reanudar Envío ProgramadoPOST/send/schedules/:schedule_id/resume
✅Cancelar Envío ProgramadoPOST/send/schedules/:schedule_id/cancel
✅Revocar MensajePOST/message/:message_id/revoke
✅Reaccionar a MensajePOST/message/:message_id/reaction
✅Eliminar MensajePOST/message/:message_id/delete
✅Editar MensajePOST/message/:message_id/update
✅Marcar Mensaje como LeídoPOST/message/:message_id/read
✅Marcar Mensaje de Audio como ReproducidoPOST/message/:message_id/played
✅Destacar MensajePOST/message/:message_id/star
✅Quitar Destacado de MensajePOST/message/:message_id/unstar
✅Reenviar MensajePOST/message/:message_id/forward
✅Descargar Multimedia de MensajeGET/message/:message_id/download
✅Rechazar LlamadaPOST/call/reject
✅Unirse a Grupo con EnlacePOST/group/join-with-link
✅Obtener Información de Grupo desde EnlaceGET/group/info-from-link
✅Obtener Información de GrupoGET/group/info
✅Salir de GrupoPOST/group/leave
✅Crear GrupoPOST/group
✅Listar Participantes de GrupoGET/group/participants
✅Agregar Participantes de GrupoPOST/group/participants
✅Eliminar Participantes de GrupoPOST/group/participants/remove
✅Ascender Participantes de GrupoPOST/group/participants/promote
✅Descender Participantes de GrupoPOST/group/participants/demote
✅Exportar Participantes de Grupo (CSV)GET/group/participants/export
✅Listar Solicitudes de Unión a GrupoGET/group/participant-requests
✅Aprobar Solicitudes de Unión a GrupoPOST/group/participant-requests/approve
✅Rechazar Solicitudes de Unión a GrupoPOST/group/participant-requests/reject
✅Configurar Foto de GrupoPOST/group/photo
✅Configurar Nombre de GrupoPOST/group/name
✅Bloquear o Desbloquear Configuraciones de GrupoPOST/group/locked
✅Configurar Modo de Anuncio de GrupoPOST/group/announce
✅Configurar Tema de GrupoPOST/group/topic
✅Obtener Enlace de Invitación de GrupoGET/group/invite-link
✅Dejar de Seguir BoletínPOST/newsletter/unfollow
✅Obtener Mensajes de BoletínGET/newsletter/messages
✅Descargar Multimedia de Mensaje de BoletínGET/newsletter/messages/{server_id}/download
✅Obtener Lista de ChatsGET/chats
✅Obtener Mensajes de ChatGET/chat/:chat_jid/messages
✅Fijar ChatPOST/chat/:chat_jid/pin
✅Archivar ChatPOST/chat/:chat_jid/archive
✅Configurar Mensajes EfímerosPOST/chat/:chat_jid/disappearing
✅Solicitar Historial de Chat (Cargar Mensajes Antiguos)POST/chat/:chat_jid/history
✅Sincronizar Historial de ChatwootPOST/chatwoot/sync
✅Estado de Sincronización de ChatwootGET/chatwoot/sync/status
✅Listar Configuraciones de ChatwootGET/chatwoot/configs
✅Obtener Configuración de Chatwoot del DispositivoGET/devices/:device_id/chatwoot/config
✅Configurar Chatwoot del DispositivoPUT/devices/:device_id/chatwoot/config
✅Eliminar Configuración de Chatwoot del DispositivoDELETE/devices/:device_id/chatwoot/config
✅Webhook de Respuesta de ChatwootPOST/chatwoot/webhook
✅Webhook de Respuesta de Chatwoot del DispositivoPOST/chatwoot/webhook/:device_id

✅ = disponible. * = tiene limitaciones conocidas; consulte las notas a continuación.

Notas:

  • *List My Groups: Devuelve un máximo de 500 grupos debido a una limitación del protocolo de WhatsApp. Los servidores de WhatsApp, no esta API, imponen el límite. Consulte la fuente de whatsmeow para más detalles.
  • /health es público y siempre se registra en la ruta raíz, incluso cuando APP_BASE_PATH está configurado.
  • Las rutas de Chatwoot se registran solo cuando CHATWOOT_ENABLED=true.

Interfaz de Usuario

Interfaz MCP

  • Configurar MCP (probado en Cursor) Setup MCP
  • Probar MCP Test MCP
  • Configuración MCP exitosa Success MCP

Panel web (gowa-ui)

El panel vive en su propio repositorio: aldinokemal/gowa-ui. Cada versión de gowa-ui publica un único gowa-ui.html autocontenido; el servidor descarga la última versión al inicio (y cada APP_UI_UPDATE_INTERVAL, que por defecto es 3h), verifica su digest SHA-256, lo almacena en caché bajo storages/ui/, y lo sirve en / detrás de Basic Auth.

ConfiguraciónPredeterminadoPropósito
APP_UI_ENABLEDtrueServir el panel en /; false devuelve un banner JSON (solo API)
APP_UI_AUTO_UPDATEtrueDescargar/actualizar desde GitHub; deshabilitar para implementaciones aisladas
APP_UI_REPOaldinokemal/gowa-uiRepositorio que sigue el actualizador—siempre su última versión, no un pin de versión
APP_UI_ASSET_NAMEgowa-ui.htmlNombre del archivo de versión a descargar
APP_UI_UPDATE_INTERVAL3hCon qué frecuencia verificar releases/latest
APP_UI_GITHUB_TOKEN(vacío)Token opcional para aumentar el límite de tasa de la API de GitHub
APP_UI_ASSET_SHA256(vacío)Pin de cadena de suministro: rechazar cualquier panel cuyo SHA-256 difiera

Modelo de confianza: el digest de la versión prueba que la descarga coincide con lo que GitHub anuncia, no quién la publicó. Los operadores que auditan una compilación específica pueden fijarla con APP_UI_ASSET_SHA256 (cada versión incluye un activo .sha256—esta es la única configuración que fija una compilación exacta), apuntar APP_UI_REPO a una bifurcación que controlen (el actualizador aún sigue la última versión de ese repositorio), o pre-cargar la caché y deshabilitar la actualización automática por completo.

Servidores aislados: coloque un gowa-ui.html descargado en storages/ui/index.html y configure APP_UI_AUTO_UPDATE=false. El panel también puede auto-alojarse en cualquier lugar estático y apuntarse a la URL de este servidor (consulte el README de gowa-ui).

Nota para macOS

Si ve invalid flag in pkg-config --cflags: -Xpreprocessor, ejecute:

export CGO_CFLAGS_ALLOW="-Xpreprocessor"

Importante

  • Este proyecto no es oficial y no está afiliado con WhatsApp.
  • Use la Plataforma Oficial de Negocios de WhatsApp cuando necesite una integración compatible y de grado de producción.