# 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): ```bash claude mcp add --transport http whatsapp https://whatsapp.nucleoriofrio.com/api/mcp --header "Authorization: Bearer " ``` --- ## Setup ```bash npm install ``` ## Development ```bash npm run dev ``` ## Production ```bash npm run build node .output/server/index.mjs ``` --- ## API REST ### Autenticación Todos los endpoints requieren autenticación mediante API Key: ``` Authorization: Bearer ``` ### 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:** ```bash curl -X GET "https://whatsapp.nucleoriofrio.com/api/instances" \ -H "Authorization: Bearer " ``` **Ejemplo - Crear instancia:** ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/instances" \ -H "Authorization: Bearer " \ -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:** ```bash curl -X GET "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/chats" \ -H "Authorization: Bearer " ``` **Respuesta:** ```json [ { "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:** ```bash curl -X GET "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}" \ -H "Authorization: Bearer " ``` **Ejemplo - Paginación con limit/offset:** ```bash curl -X GET "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}?limit=20&offset=40" \ -H "Authorization: Bearer " ``` **Ejemplo - Scroll infinito (mensajes antes de fecha):** ```bash curl -X GET "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}?limit=20&before=2025-01-15T10:00:00Z" \ -H "Authorization: Bearer " ``` **Respuesta:** ```json [ { "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 ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "content": "Hola! Este es un mensaje de texto" }' ``` **Con mensaje citado:** ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "content": "Esta es mi respuesta", "quotedMessageId": "3EB0A1B2C3D4E5F6" }' ``` #### Imagen ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -F "file=@foto.jpg" \ -F "caption=Descripción de la imagen" ``` #### Video ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -F "file=@video.mp4" \ -F "caption=Mi video" ``` #### Audio / Nota de Voz ```bash # Audio normal curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -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 " \ -F "file=@nota.ogg" \ -F "isPtt=true" ``` #### Documento ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -F "file=@reporte.pdf" \ -F "caption=Reporte mensual de ventas" ``` #### Sticker ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -F "file=@imagen.png" \ -F 'asSticker=["true"]' ``` > Se convierte automáticamente a WebP. Formatos soportados: JPG, PNG, WebP. #### Contacto ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "type": "contact", "contacts": [ { "displayName": "Juan Pérez", "phoneNumber": "+5491155551234", "organization": "Empresa SA" } ] }' ``` **Múltiples contactos:** ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "type": "contact", "contacts": [ {"displayName": "Juan", "phoneNumber": "+5491155551234"}, {"displayName": "María", "phoneNumber": "+5491166662345"} ] }' ``` #### Encuesta (Poll) ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -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` | Sí | Pregunta de la encuesta | | `options` | Sí | Array de opciones (mín: 2, máx: 12) | | `selectableCount` | No | Cuántas opciones se pueden elegir (default: 1) | #### Evento ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -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` | Sí | Nombre del evento | | `startDate` | Sí | 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):** ```json { "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:** ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "content": "Totalmente de acuerdo!", "quotedMessageId": "3EB0A1B2C3D4E5F6" }' ``` **Imagen citando otro mensaje:** ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -F "file=@imagen.jpg" \ -F "caption=Mira esto!" \ -F "quotedMessageId=3EB0A1B2C3D4E5F6" ``` **Encuesta citando otro mensaje:** ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/{chatId}/send" \ -H "Authorization: Bearer " \ -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:** ```json { "messageId": "3EB0A1B2C3D4E5F6", "emoji": "👍" } ``` **Ejemplo - Agregar reacción:** ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/react" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"messageId": "3EB0A1B2C3D4E5F6", "emoji": "👍"}' ``` **Ejemplo - Quitar reacción:** ```bash curl -X POST "https://whatsapp.nucleoriofrio.com/api/messages/{instanceId}/react" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"messageId": "3EB0A1B2C3D4E5F6", "emoji": ""}' ``` **Emojis comunes:** | Emoji | Significado | |-------|-------------| | 👍 | Me gusta | | ❤️ | Amor | | 😂 | Risa | | 😮 | Sorpresa | | 😢 | Tristeza | | 🙏 | Gracias | **Respuesta:** ```json { "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