josedario87 a848adf4f8
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m9s
Fix: Preservar alias al recargar lista de chats
El endpoint chats.get no retornaba el campo alias, lo que causaba
que al recargar los chats (cuando llega un mensaje nuevo) el alias
se perdiera.

Cambios:
- Agregar alias a la query de chats.get
- Priorizar alias sobre name en la respuesta
- Incluir originalName para referencia en el modal
2025-12-04 16:04:47 -06:00

WhatsApp Nucleo

Sistema de gestión centralizada de múltiples instancias de WhatsApp para Nucleo V3.

MCP Server para Claude Code

Agregar el MCP a tu proyecto (usa tu NUXT_MASTER_API_KEY):

claude mcp add --transport http whatsapp https://whatsapp.nucleoriofrio.com/api/mcp --header "Authorization: Bearer <NUXT_MASTER_API_KEY>"

Setup

npm install

Development

npm run dev

Production

npm run build
node .output/server/index.mjs

API REST

Autenticación

Todos los endpoints requieren autenticación mediante API Key:

Authorization: Bearer <NUXT_MASTER_API_KEY>

Instancias

Método Endpoint Descripción
GET /api/instances Listar todas las instancias
POST /api/instances Crear nueva instancia
GET /api/instances/:id Obtener detalles de instancia
GET /api/instances/:id/qr Obtener código QR
POST /api/instances/:id/connect Conectar instancia
POST /api/instances/:id/disconnect Desconectar instancia
DELETE /api/instances/:id Eliminar instancia

Ejemplo - Listar instancias:

curl -X GET "https://whatsapp.nucleoriofrio.com/api/instances" \
  -H "Authorization: Bearer <API_KEY>"

Ejemplo - Crear instancia:

curl -X POST "https://whatsapp.nucleoriofrio.com/api/instances" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"name": "Mi WhatsApp"}'

Obtener Lista de Chats/Contactos

GET /api/messages/:instanceId/chats

Retorna todos los chats (contactos individuales y grupos) de una instancia, ordenados por última actividad.

Ejemplo:

curl -X GET "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/chats" \
  -H "Authorization: Bearer <API_KEY>"

Respuesta:

[
  {
    "id": "chat_abc123",
    "jid": "5491155551234@s.whatsapp.net",
    "name": "Juan Pérez",
    "isGroup": false,
    "unreadCount": 2,
    "lastMessageAt": "2025-01-15T10:30:00Z",
    "lastMessage": "Hola, ¿cómo estás?",
    "lastMessageType": "text"
  },
  {
    "id": "chat_xyz789",
    "jid": "120363123456789012@g.us",
    "name": "Grupo de Trabajo",
    "isGroup": true,
    "unreadCount": 0,
    "lastMessageAt": "2025-01-15T09:00:00Z",
    "lastMessage": "Reunión a las 3pm",
    "lastMessageType": "text"
  }
]

Campos de respuesta:

Campo Tipo Descripción
id string ID interno del chat (usar en otros endpoints)
jid string JID de WhatsApp del contacto/grupo
name string Nombre del contacto o grupo
isGroup boolean true si es un grupo
unreadCount number Cantidad de mensajes no leídos
lastMessageAt string Fecha ISO del último mensaje
lastMessage string Contenido del último mensaje
lastMessageType string Tipo del último mensaje

Obtener Mensajes de un Chat

GET /api/messages/:instanceId/:chatId

Obtiene los mensajes de un chat con soporte para paginación.

Parámetros de Query:

Parámetro Tipo Default Descripción
limit number 50 Cantidad de mensajes (máx: 100)
offset number 0 Saltar N mensajes
before string - Timestamp ISO para scroll infinito

Ejemplo - Obtener últimos 50 mensajes:

curl -X GET "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}" \
  -H "Authorization: Bearer <API_KEY>"

Ejemplo - Paginación con limit/offset:

curl -X GET "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}?limit=20&offset=40" \
  -H "Authorization: Bearer <API_KEY>"

Ejemplo - Scroll infinito (mensajes antes de fecha):

curl -X GET "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}?limit=20&before=2025-01-15T10:00:00Z" \
  -H "Authorization: Bearer <API_KEY>"

Respuesta:

[
  {
    "id": "msg_123",
    "messageId": "3EB0A1B2C3D4E5F6",
    "chatId": "chat_abc123",
    "fromJid": "5491155551234@s.whatsapp.net",
    "fromMe": false,
    "type": "text",
    "content": "Hola, ¿cómo estás?",
    "caption": null,
    "media": null,
    "timestamp": "2025-01-15T10:30:00Z",
    "status": "read",
    "pushName": "Juan",
    "isGroup": false
  },
  {
    "id": "msg_124",
    "messageId": "3EB0A1B2C3D4E5F7",
    "chatId": "chat_abc123",
    "fromJid": "me",
    "fromMe": true,
    "type": "image",
    "content": null,
    "caption": "Mira esta foto",
    "media": {
      "mimetype": "image/jpeg",
      "filesize": 245000,
      "width": 1920,
      "height": 1080,
      "thumbnail": "base64..."
    },
    "timestamp": "2025-01-15T10:31:00Z",
    "status": "delivered",
    "isGroup": false
  }
]

Campos de respuesta por tipo:

Campo Descripción
messageId ID de WhatsApp (usar para reaccionar o citar)
fromMe true si lo envié yo
type text, image, video, audio, document, sticker, contact, location, poll, event
content Texto del mensaje
caption Caption de media
media Info de archivo (mimetype, filesize, thumbnail, etc.)
poll Datos de encuesta (name, options, selectableCount)
event Datos de evento (name, startDate, location)
quoted Mensaje citado (id, content, type)
pushName Nombre del remitente
participant JID del participante (en grupos)

Enviar Mensajes

POST /api/messages/:instanceId/:chatId/send

Endpoint unificado para enviar todos los tipos de mensaje. El tipo se detecta automáticamente según el Content-Type y body.

Mensaje de Texto

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Hola! Este es un mensaje de texto"
  }'

Con mensaje citado:

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Esta es mi respuesta",
    "quotedMessageId": "3EB0A1B2C3D4E5F6"
  }'

Imagen

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -F "file=@foto.jpg" \
  -F "caption=Descripción de la imagen"

Video

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -F "file=@video.mp4" \
  -F "caption=Mi video"

Audio / Nota de Voz

# Audio normal
curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -F "file=@audio.mp3"

# Nota de voz (PTT - Push To Talk)
curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -F "file=@nota.ogg" \
  -F "isPtt=true"

Documento

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -F "file=@reporte.pdf" \
  -F "caption=Reporte mensual de ventas"

Sticker

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -F "file=@imagen.png" \
  -F 'asSticker=["true"]'

Se convierte automáticamente a WebP. Formatos soportados: JPG, PNG, WebP.

Contacto

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "contact",
    "contacts": [
      {
        "displayName": "Juan Pérez",
        "phoneNumber": "+5491155551234",
        "organization": "Empresa SA"
      }
    ]
  }'

Múltiples contactos:

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "contact",
    "contacts": [
      {"displayName": "Juan", "phoneNumber": "+5491155551234"},
      {"displayName": "María", "phoneNumber": "+5491166662345"}
    ]
  }'

Encuesta (Poll)

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "poll",
    "name": "¿Qué día prefieres para la reunión?",
    "options": ["Lunes", "Martes", "Miércoles", "Jueves", "Viernes"],
    "selectableCount": 1
  }'

Parámetros de Poll:

Campo Requerido Descripción
name Pregunta de la encuesta
options Array de opciones (mín: 2, máx: 12)
selectableCount No Cuántas opciones se pueden elegir (default: 1)

Evento

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "event",
    "name": "Reunión de equipo",
    "startDate": "2025-01-20T14:00:00Z",
    "endDate": "2025-01-20T15:00:00Z",
    "description": "Revisión semanal del proyecto",
    "location": {
      "name": "Oficina Central",
      "address": "Av. Corrientes 1234, CABA",
      "latitude": -34.6037,
      "longitude": -58.3816
    }
  }'

Parámetros de Event:

Campo Requerido Descripción
name Nombre del evento
startDate Fecha/hora inicio (ISO 8601)
endDate No Fecha/hora fin
description No Descripción del evento
location.name No Nombre del lugar
location.address No Dirección
location.latitude No Latitud
location.longitude No Longitud

Respuesta de envío (todos los tipos):

{
  "success": true,
  "messages": [
    {
      "messageId": "3EB0A1B2C3D4E5F6",
      "type": "text"
    }
  ]
}

Responder/Citar Mensajes (quotedMessageId)

Todos los tipos de mensaje soportan citar otro mensaje usando quotedMessageId. El mensaje citado aparece como "respuesta a" en WhatsApp.

Texto citando otro mensaje:

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Totalmente de acuerdo!",
    "quotedMessageId": "3EB0A1B2C3D4E5F6"
  }'

Imagen citando otro mensaje:

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -F "file=@imagen.jpg" \
  -F "caption=Mira esto!" \
  -F "quotedMessageId=3EB0A1B2C3D4E5F6"

Encuesta citando otro mensaje:

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "poll",
    "name": "¿Qué opinan sobre esto?",
    "options": ["De acuerdo", "En desacuerdo", "Neutral"],
    "quotedMessageId": "3EB0A1B2C3D4E5F6"
  }'

Nota: El quotedMessageId se obtiene del campo messageId al listar mensajes con GET /api/messages/:instanceId/:chatId


Reaccionar a Mensajes

POST /api/messages/:instanceId/react

Envía una reacción (emoji) a un mensaje existente.

Body:

{
  "messageId": "3EB0A1B2C3D4E5F6",
  "emoji": "👍"
}

Ejemplo - Agregar reacción:

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/react" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"messageId": "3EB0A1B2C3D4E5F6", "emoji": "👍"}'

Ejemplo - Quitar reacción:

curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/react" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"messageId": "3EB0A1B2C3D4E5F6", "emoji": ""}'

Emojis comunes:

Emoji Significado
👍 Me gusta
❤️ Amor
😂 Risa
😮 Sorpresa
😢 Tristeza
🙏 Gracias

Respuesta:

{
  "success": true,
  "messageId": "3EB0A1B2C3D4E5F6",
  "emoji": "👍"
}

Nota: El messageId se obtiene de la respuesta al obtener mensajes (GET /api/messages/:instanceId/:chatId)

Formato de Destinatarios (JID)

  • Contacto individual: 5491155551234@s.whatsapp.net (código país sin +)
  • Grupo: 123456789012345678@g.us

Tipos de Mensaje Soportados

Tipo Descripción
text Mensaje de texto
image Imagen con caption opcional
video Video con caption opcional
audio Audio o nota de voz
document Documento/archivo
sticker Sticker
contact Tarjeta de contacto
poll Encuesta (2-12 opciones)
event Evento con fecha/ubicación

Límites de Archivos

Tipo Tamaño Máximo
Imagen 16 MB
Video 64 MB
Audio 16 MB
Documento 100 MB
Sticker 500 KB

Stack

  • Frontend: Nuxt 3, Vue 3, Nuxt UI, TailwindCSS
  • Backend: Nitro, PostgreSQL
  • WhatsApp: Baileys v6.7.9
  • Auth: Authentik + Traefik
Description
No description provided
Readme 1.1 MiB
Languages
TypeScript 51.5%
Vue 45.3%
PLpgSQL 1.5%
Shell 1.2%
CSS 0.4%
Other 0.1%