@fer2809fl/baileys 7.0.4 → 7.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +347 -50
- package/lib/Defaults/index.js +1 -1
- package/lib/Modded/message_builder.js +2356 -0
- package/lib/Socket/chats.d.ts +14 -0
- package/lib/Socket/chats.js +48 -0
- package/lib/Socket/index.d.ts +17 -0
- package/lib/Socket/messages-send.d.ts +18 -0
- package/lib/Socket/messages-send.js +50 -2
- package/lib/Utils/anti-ban.d.ts +41 -0
- package/lib/Utils/anti-ban.js +182 -0
- package/lib/Utils/banner.d.ts +8 -0
- package/lib/Utils/banner.js +76 -0
- package/lib/Utils/bot-utils.d.ts +57 -0
- package/lib/Utils/bot-utils.js +241 -0
- package/lib/Utils/enhanced-cache.d.ts +40 -0
- package/lib/Utils/enhanced-cache.js +242 -0
- package/lib/Utils/enhanced-logger.d.ts +41 -0
- package/lib/Utils/enhanced-logger.js +185 -0
- package/lib/Utils/index.d.ts +14 -0
- package/lib/Utils/index.js +13 -0
- package/lib/Utils/lid-utils.d.ts +139 -0
- package/lib/Utils/lid-utils.js +503 -0
- package/lib/Utils/message-queue.d.ts +47 -0
- package/lib/Utils/message-queue.js +226 -0
- package/lib/Utils/rich-message-utils.d.ts +21 -0
- package/lib/Utils/rich-message-utils.js +229 -0
- package/lib/Utils/rich-messages.d.ts +52 -0
- package/lib/Utils/rich-messages.js +185 -0
- package/lib/Utils/scheduled-messages.d.ts +122 -0
- package/lib/Utils/scheduled-messages.js +289 -0
- package/lib/Utils/smart-reconnect.d.ts +48 -0
- package/lib/Utils/smart-reconnect.js +207 -0
- package/lib/Utils/use-sqlite-auth-state.d.ts +11 -0
- package/lib/Utils/use-sqlite-auth-state.js +95 -0
- package/lib/VoIP/audio-feeder.d.ts +15 -0
- package/lib/VoIP/audio-feeder.js +132 -0
- package/lib/VoIP/index.js +277 -0
- package/lib/VoIP/relay-transport.d.ts +43 -0
- package/lib/VoIP/relay-transport.js +559 -0
- package/lib/VoIP/signaling.js +594 -0
- package/lib/VoIP/types.d.ts +69 -0
- package/lib/VoIP/types.js +17 -0
- package/lib/VoIP/wasm-engine.d.ts +103 -0
- package/lib/VoIP/wasm-engine.js +1214 -0
- package/lib/VoIP/worker-bootstrap.js +1042 -0
- package/lib/assets/wasm/loader.js +5 -0
- package/lib/assets/wasm/whatsapp.wasm +0 -0
- package/lib/assets/wasm/worker-modules.js +273 -0
- package/lib/index.d.ts +41 -0
- package/lib/index.js +3 -0
- package/package.json +10 -2
package/README.md
CHANGED
|
@@ -16,68 +16,117 @@
|
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
## 🆕 Novedades — v7.0.
|
|
19
|
+
## 🆕 Novedades — v7.0.5
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
**La actualización más completa hasta ahora.** Se revisó el fork "beta" del proyecto en busca de utilidades que este repo todavía no tenía, se portaron una por una (evitando duplicar nombres ya existentes) y se hizo una auditoría de código de punta a punta — no solo del README.
|
|
22
22
|
|
|
23
|
-
###
|
|
24
|
-
- **`
|
|
23
|
+
### 🔧 Mantenimiento y correcciones
|
|
24
|
+
- **`messages-send.js`** — se corrigió un caso donde el nodo `biz` (usado por los botones nativos) podía duplicarse dentro del stanza si ya venía agregado por otra parte del mensaje; ahora se verifica que no exista antes de agregarlo.
|
|
25
|
+
- **Auditoría completa de `lib/`**, archivo por archivo contra el fork beta: no faltaba ninguna función real, solo faltaban algunos exports y tipos, ya corregidos.
|
|
26
|
+
- **Exports arreglados** — `Utils/reporting-utils.js` y `Utils/companion-reg-client-utils.js` existían en el código pero no se exportaban bien desde el paquete; quien instalaba `@fer2809fl/baileys` no podía importar sus funciones. Ya se puede.
|
|
27
|
+
- **Tipos de TypeScript agregados** para los 9 módulos que solo venían en JavaScript — `anti-ban`, `smart-reconnect`, `message-queue`, `enhanced-cache`, `enhanced-logger`, `bot-utils`, `banner`, `rich-message-utils` y `use-sqlite-auth-state` — verificados con `tsc`. Ahora tienen autocompletado y chequeo de tipos.
|
|
28
|
+
- **Limpieza de marca** en `banner.js` y `enhanced-logger.js` (traían branding del proyecto original de donde se portó el código).
|
|
29
|
+
- En general: se optimizó y se prolijaron varios detalles sueltos de código y documentación que quedaron de fusiones anteriores.
|
|
30
|
+
|
|
31
|
+
Se documentaron además funciones que ya existían en el código pero no tenían ejemplo de uso: tablas, bloques de código, carruseles, álbumes y canales/newsletters (ver secciones nuevas más abajo).
|
|
32
|
+
|
|
33
|
+
Próximas tandas (se irán agregando poco a poco): documentación de Grupos avanzados, Comunidades, Negocios, Perfil/Privacidad, Estados (stories) y Eventos.
|
|
34
|
+
|
|
35
|
+
### 🆕 Protocolo actualizado + funciones nuevas de chat
|
|
36
|
+
- **Versión de WhatsApp Web actualizada** a `2.3000.1047406223` (la más reciente confirmada al momento de esta actualización), reduciendo el riesgo de rechazo de conexión por versión vieja.
|
|
37
|
+
- **Nuevas funciones de chat** (no existían ni en este fork ni en el beta — son de cosecha propia esta vez): atajos simples para las operaciones de chat más comunes, en vez de tener que armar el objeto de `chatModify` a mano:
|
|
25
38
|
```javascript
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
)
|
|
39
|
+
await sock.pinChat(jid) // fijar chat
|
|
40
|
+
await sock.pinChat(jid, false) // desfijar
|
|
41
|
+
await sock.archiveChat(jid) // archivar
|
|
42
|
+
await sock.archiveChat(jid, false) // desarchivar
|
|
43
|
+
await sock.muteChat(jid, Date.now() + 8 * 60 * 60 * 1000) // silenciar 8 horas
|
|
44
|
+
await sock.muteChat(jid) // quitar silencio
|
|
45
|
+
await sock.markChatRead(jid) // marcar como leído
|
|
46
|
+
await sock.markChatUnread(jid) // marcar como no leído
|
|
47
|
+
await sock.clearChat(jid) // vaciar el historial del chat
|
|
48
|
+
await sock.deleteChat(jid) // eliminar el chat de la lista
|
|
49
|
+
```
|
|
50
|
+
Todas usan por debajo el mismo `chatModify` de siempre (mismo protocolo, mismos parches de estado), solo que ahora no hay que recordar la forma exacta del objeto `mod`.
|
|
51
|
+
- **Fijar un mensaje dentro del chat** (`pinInChatMessage`) — esta ya existía en el código pero no estaba documentada:
|
|
52
|
+
```javascript
|
|
53
|
+
// Fijar el mensaje citado por 24 horas (86400 segundos)
|
|
54
|
+
await sock.sendMessage(jid, { pin: quotedMsg.key, type: 1, time: 86400 })
|
|
55
|
+
// Desfijar
|
|
56
|
+
await sock.sendMessage(jid, { pin: quotedMsg.key, type: 2 })
|
|
29
57
|
```
|
|
30
|
-
- **`sock.fetchAccountReachoutTimelock()`** — consulta si tu cuenta tiene alguna restricción activa para iniciar chats nuevos, y hasta cuándo dura.
|
|
31
|
-
- **`sock.fetchNewChatMessageCap()`** — consulta el límite de mensajes que puedes enviar a chats/números nuevos (cupo anti-spam de WhatsApp).
|
|
32
|
-
- **`sock.registerSocketEndHandler(handler)`** — registra una función que se ejecuta automáticamente cada vez que la conexión se cierra (útil para limpieza de recursos propios sin tener que escuchar `connection.update` a mano).
|
|
33
|
-
- **Nuevo formato de código QR de emparejamiento** — el QR ahora incluye el identificador de plataforma del companion, igual que el WhatsApp Web oficial (mejora la tasa de éxito al vincular).
|
|
34
|
-
|
|
35
|
-
### 🐛 Correcciones de estabilidad y memoria
|
|
36
|
-
- **Fuga de memoria en el buffer de eventos** — se agregó limpieza real de timers, cachés y listeners al cerrar una conexión (`ev.destroy()`), evitando que la memoria crezca con reconexiones frecuentes.
|
|
37
|
-
- **Loop de reintentos por fallas de descifrado (MAC)** — se agregó detección de colisión de "base key" en reintentos de mensajes: si WhatsApp reenvía el mismo mensaje repetidamente por un fallo de sesión, la librería ahora detecta el patrón y fuerza una sesión nueva en vez de reintentar indefinidamente.
|
|
38
|
-
- **Duplicados al sincronizar historial de grupos** — se corrigió el merge de "participantes que salieron" (`pastParticipants`) para no duplicar entradas cuando WhatsApp envía el historial en varios paquetes.
|
|
39
|
-
- **IDs de consulta de canales (newsletters) desactualizados** — los IDs internos de `FOLLOW`/`UNFOLLOW` de canales estaban vencidos y podían empezar a fallar silenciosamente; se actualizaron a los vigentes.
|
|
40
|
-
- **Versión de protocolo de WhatsApp Web actualizada** — reduce el riesgo de desconexiones forzadas por versión obsoleta.
|
|
41
|
-
- **Dependencias actualizadas**: `libsignal` ahora se instala desde npm (antes requería `git` instalado en el servidor), `whatsapp-rust-bridge`, `protobufjs` y otras al día.
|
|
42
|
-
|
|
43
|
-
> Nota: las funciones de auto-follow de canales, el motor de envío de mensajes (`sendMessage` y helpers internos) y el manejo avanzado de negocios (`business.js`) son personalizaciones propias de este fork — se mantuvieron intactas durante esta actualización.
|
|
44
|
-
|
|
45
|
-
### 🔧 Fusión profunda adicional
|
|
46
|
-
- **`chats.js` reconstruido sobre la base oficial**: recuperación automática de sincronización de estado cuando falta una clave (antes fallaba silenciosamente), resolución correcta de bloqueo de contactos por LID/PN, y tracking de finalización de sincronización de historial.
|
|
47
|
-
- **`groups.js` reconstruido**: mejor resolución de LID/PN en metadata de grupos + tus funciones `isGroupAdmin`, `getGroupAdmins`, `resolveParticipantJid`, `groupMetadataCached` intactas.
|
|
48
|
-
- **`business.js` alineado al oficial** (era funcionalmente idéntico, solo cambiaba el estilo del código).
|
|
49
|
-
- **Endpoint de canales actualizado**: WhatsApp movió `newsletterFollow`/`newsletterUnfollow` a un endpoint nuevo (`_v2`); se actualizó, incluyendo tu sistema de auto-follow interno, para que siga funcionando.
|
|
50
58
|
|
|
51
|
-
|
|
59
|
+
### ✅ Nuevas funciones añadidas
|
|
52
60
|
|
|
61
|
+
**Anti-Ban** (`Utils/anti-ban.js`)
|
|
62
|
+
- `randomDelay`, `messageDelay`, `typingDelay` — retrasos aleatorios "humanizados" antes de enviar.
|
|
63
|
+
- `RateLimiter`, `globalRateLimiter`, `groupRateLimiter`, `broadcastRateLimiter` — limitadores de tasa listos para usar por chat/grupo/difusión.
|
|
64
|
+
- `PresenceManager`, `generateSessionFingerprint`, `isValidJid`, `sanitizeMessage` — utilidades de apoyo para reducir el riesgo de baneo por comportamiento de bot.
|
|
53
65
|
|
|
66
|
+
**Reconexión inteligente** (`Utils/smart-reconnect.js`)
|
|
67
|
+
- `SmartReconnect`, `createConnectionHandler`, `withRetry` — backoff exponencial con jitter y detección de causas de desconexión recuperables vs definitivas.
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
- `isGroupAdmin(chatId, jid)` — `true`/`false` si ese participante (venga como número o como `@lid`) es admin o superadmin del grupo.
|
|
58
|
-
- `getGroupAdmins(chatId)` — lista de admins del grupo, ya resueltos a su jid de número de teléfono real (nunca `@lid`).
|
|
59
|
-
- `resolveParticipantJid(chatIdOrParticipants, jid)` — convierte cualquier `@lid` a su número real. Primero busca en los participantes del grupo; si no encuentra coincidencia, usa el mapeo LID↔PN nativo de WhatsApp (`signalRepository.lidMapping`) en vez de adivinar.
|
|
60
|
-
- `groupMetadataCached(chatId)` — igual que `groupMetadata`, pero con cache de 30s que se invalida solo apenas hay un alta, baja, ascenso o descenso real de participantes (via `group-participants.update`), para no golpear a WhatsApp en cada mensaje.
|
|
69
|
+
**Cola de mensajes** (`Utils/message-queue.js`)
|
|
70
|
+
- `MessageQueue`, `createMessageQueue` — colas con prioridad (`PRIORITY.CRITICAL` a `PRIORITY.BACKGROUND`) y control de tasa por tipo de contenido.
|
|
61
71
|
|
|
62
|
-
|
|
72
|
+
**Caché mejorada** (`Utils/enhanced-cache.js`)
|
|
73
|
+
- `EnhancedCache`, `CacheManager` — caché en memoria con TTL/stale-TTL basada en `lru-cache`, con snapshot a disco.
|
|
63
74
|
|
|
64
|
-
|
|
75
|
+
**Logger mejorado** (`Utils/enhanced-logger.js`)
|
|
76
|
+
- `createLogger`, `RyzeLogger` — logger con niveles, colores en consola e iconos por categoría (no reemplaza tu logger `pino` existente, es una alternativa opcional).
|
|
65
77
|
|
|
66
|
-
|
|
78
|
+
**Mensajes programados** (`Utils/scheduled-messages.js`)
|
|
79
|
+
```javascript
|
|
80
|
+
import { startScheduler, scheduleMessage, recurringMessage } from '@fer2809fl/baileys'
|
|
67
81
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
startScheduler(sock) // arranca el scheduler una vez tengas el sock conectado
|
|
83
|
+
|
|
84
|
+
// una sola vez, en una fecha exacta
|
|
85
|
+
scheduleMessage('123@s.whatsapp.net', { text: 'Recordatorio' }, Date.now() + 60_000)
|
|
86
|
+
|
|
87
|
+
// recurrente con cron simple: "MIN HOUR DOM MON DOW"
|
|
88
|
+
recurringMessage('123@s.whatsapp.net', { text: 'Buenos días' }, '0 9 * * *')
|
|
89
|
+
```
|
|
90
|
+
También: `cancelScheduledMessage`, `deleteScheduledMessage`, `listScheduledMessages`, `getScheduledMessage`, `updateScheduledMessage`, `getSchedulerStats`. Persiste en `database/scheduled-messages.json`.
|
|
91
|
+
|
|
92
|
+
**Utilidades de LID** (`Utils/lid-utils.js`)
|
|
93
|
+
- `isLid`, `lidToJid`, `resolveAnyLidToJid`, `resolveParticipant`, `getParticipantJid(s)`, `cacheParticipantLids`, `findParticipantByNumber`, entre otras — resolución y cacheo de `@lid` ↔ número real con persistencia en `database/lid-cache.json`. Complementa (no reemplaza) la resolución de admins/JID-LID nativa que ya tenía este fork desde v1.10.0.
|
|
94
|
+
|
|
95
|
+
**Utilidades para bots** (`Utils/bot-utils.js`)
|
|
96
|
+
- `parseCommand(text, prefix)` — parseo de comandos con flags (`--flag=valor`) y argumentos.
|
|
97
|
+
- `CooldownManager`, `PermissionManager` (owners/admins/baneados/premium).
|
|
98
|
+
- `extractMentions`, `extractQuotedMessage`, `isGroupAdmin`, `isBotAdmin`, `formatPhoneNumber`, `parseTime('10m')`, `formatDuration(ms)`, `sendFast(sock, jid, contenido)`.
|
|
99
|
+
|
|
100
|
+
**Auth state en SQLite** (`Utils/use-sqlite-auth-state.js`)
|
|
101
|
+
```javascript
|
|
102
|
+
import { useSqliteAuthState } from '@fer2809fl/baileys'
|
|
103
|
+
const { state, saveCreds } = await useSqliteAuthState({ dbPath: './auth.db' })
|
|
104
|
+
```
|
|
105
|
+
Requiere `better-sqlite3` (peer dependency opcional: `npm i better-sqlite3`).
|
|
106
|
+
|
|
107
|
+
**Banner de inicio** (`Utils/banner.js`) — `printBanner()` opcional para mostrar un logo ASCII al arrancar el bot.
|
|
108
|
+
|
|
109
|
+
**AI Rich Response — helpers de bajo nivel** (`Utils/rich-message-utils.js`)
|
|
110
|
+
- `prepareRichResponseMessage(contenido)` — arma un `AIRichResponseMessage` completo (texto + código + tabla + links) en un solo llamado, incluyendo la firma/certificado de `botMetadata`.
|
|
111
|
+
- `toUnified`, `wrapToBotForwardedMessage`, `botMetadataSignature`, `botMetadataCertificate` — piezas internas reutilizables si armas tus propios mensajes enriquecidos.
|
|
112
|
+
- Se ampliaron los lenguajes soportados para resaltado de código en `LANGUAGE_KEYWORDS` (`Utils/rich-messages.js`): ahora incluye `rust`, `c`, `cpp`/`c++`, `csharp`/`c#`, `html` y `css`, además de los que ya tenías.
|
|
113
|
+
|
|
114
|
+
**Builder "Modded"** (`Modded/message_builder.js`) — clases con API encadenable para armar botones, carruseles y respuestas AI-Rich sin construir el objeto a mano: `Button`, `ButtonV2`, `Carousel`, `AIRich`, `ORich`, `Toolkit`. *(Este archivo trae una nota de autoría de su creador original — se mantuvo intacta tal cual, junto con los términos: uso libre para proyectos propios, pero no puede revenderse ni redistribuirse como librería independiente.)*
|
|
115
|
+
|
|
116
|
+
**VoIP — llamadas de voz** (`VoIP/`) — cliente experimental de llamadas de voz de WhatsApp sobre el motor WASM oficial:
|
|
117
|
+
```javascript
|
|
118
|
+
import { VoipClient, CallState } from '@fer2809fl/baileys'
|
|
119
|
+
|
|
120
|
+
const voip = new VoipClient(sock)
|
|
121
|
+
const call = await voip.call('123@s.whatsapp.net')
|
|
122
|
+
call.on('stateChange', (state) => console.log(CallState[state]))
|
|
123
|
+
```
|
|
124
|
+
Incluye `ActiveCall`, manejo de señalización, y el binario WASM necesario (`lib/assets/wasm/`). Es una función pesada y experimental: úsala solo si tu bot realmente necesita hacer/recibir llamadas.
|
|
125
|
+
|
|
126
|
+
### 📌 Notas finales
|
|
127
|
+
- Se revisó cuidadosamente cada función nueva contra el código ya existente para no pisar ni duplicar exports (por ejemplo, `BufferJSON` y los tipos de resaltado de código se reutilizan de los archivos que ya tenías, en vez de crear una segunda copia).
|
|
128
|
+
- Las funciones marcadas arriba con ejemplo de código ya están 100% cableadas y listas para usar; el resto se documentará con más ejemplos en la próxima revisión.
|
|
129
|
+
- Los archivos `anti-ban.js`, `smart-reconnect.js`, `message-queue.js`, `enhanced-cache.js`, `enhanced-logger.js`, `bot-utils.js`, `banner.js`, `rich-message-utils.js` y `use-sqlite-auth-state.js` se distribuyen por ahora solo en JavaScript (igual que en el fork de origen); los tipos de TypeScript para estos módulos llegarán en una futura actualización.
|
|
81
130
|
|
|
82
131
|
---
|
|
83
132
|
|
|
@@ -412,6 +461,253 @@ export default handler
|
|
|
412
461
|
|
|
413
462
|
---
|
|
414
463
|
|
|
464
|
+
## 🌐 HTML embebido en WhatsApp *(nuevo en v7.1.0)*
|
|
465
|
+
|
|
466
|
+
WhatsApp expone un renderer HTML interno (diseñado originalmente para Meta AI)
|
|
467
|
+
accesible vía el campo opaco `unifiedResponse.data` de `AIRichResponseMessage`.
|
|
468
|
+
Cuando el JSON embebido contiene un `__typename: "GenAIaeacdsnwHtmlPrimitive"`,
|
|
469
|
+
el cliente levanta un **WebView sandboxed dentro del bocadillo del mensaje** y
|
|
470
|
+
renderiza el HTML+JS indicado en `payload`, con permiso de red limitado a los
|
|
471
|
+
dominios listados en `trusted_sources`.
|
|
472
|
+
|
|
473
|
+
Este fork expone esa capacidad como API de primer nivel:
|
|
474
|
+
|
|
475
|
+
### `sock.sendHtml` — envía un WebView dentro del chat
|
|
476
|
+
|
|
477
|
+
```javascript
|
|
478
|
+
await sock.sendHtml(
|
|
479
|
+
jid,
|
|
480
|
+
html, // string con <style>, <body>, <script>
|
|
481
|
+
trustedSources, // ["api.tuyo.com"] ← dominios permitidos para fetch
|
|
482
|
+
quoted, // mensaje a responder (opcional)
|
|
483
|
+
{ headerText, footer } // opciones (opcional)
|
|
484
|
+
)
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
O construí el mensaje por tu cuenta con `generateHtmlContent` (exportado desde
|
|
488
|
+
`@nyxthor-dev/baileys`) y mandalo con `relayMessage` si querés más control.
|
|
489
|
+
|
|
490
|
+
### Ejemplo mínimo
|
|
491
|
+
|
|
492
|
+
```javascript
|
|
493
|
+
const html = `
|
|
494
|
+
<body style="margin:0;font-family:sans-serif">
|
|
495
|
+
<h1 style="color:#a3e635">¡Hola desde el WebView!</h1>
|
|
496
|
+
<p>Esto se renderiza dentro del bocadillo de WhatsApp.</p>
|
|
497
|
+
</body>
|
|
498
|
+
`;
|
|
499
|
+
await sock.sendHtml(jid, html, [], msg);
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### ⚠️ Limitaciones estructurales (importante)
|
|
503
|
+
|
|
504
|
+
El WebView tiene 4 restricciones que **no se pueden evitar desde el lado del
|
|
505
|
+
HTML**. El patrón recomendado para resolverlas es mover la lógica a un backend
|
|
506
|
+
HTTP (ver `examples/html-dynamic/` para un demo completo):
|
|
507
|
+
|
|
508
|
+
| Limitación | Qué NO hacer | Patrón recomendado |
|
|
509
|
+
|---|---|---|
|
|
510
|
+
| El WebView es efímero: `localStorage` a menudo se borra al cerrar el chat | Confiar en `localStorage` como única persistencia | Mover la persistencia a un backend HTTP en `trusted_sources` |
|
|
511
|
+
| No existe puente HTML → bot (`window.WhatsApp.postMessage` no existe) | Esperar callbacks automáticos al bot | El HTML hace `fetch` a tu API, y tu API llama `sock.sendMessage(...)` |
|
|
512
|
+
| `fetch()` solo anda hacia dominios listados en `trusted_sources` | Hacer `fetch` a dominios arbitrarios | Listar todos los dominios necesarios al llamar `sendHtml` |
|
|
513
|
+
| El HTML no recibe identidad del usuario automáticamente | Generar el mismo HTML para todos los usuarios | Inyectar `window.__INITIAL__ = { jid, token, ... }` al renderizar |
|
|
514
|
+
|
|
515
|
+
### Patrón dinámico con estado persistente
|
|
516
|
+
|
|
517
|
+
```javascript
|
|
518
|
+
// En tu comando del bot:
|
|
519
|
+
const best = await db.scores.get(senderJid); // 1. leer estado
|
|
520
|
+
const token = issueJwt(senderJid, { expiresIn: '5m' }); // 2. firmar identidad
|
|
521
|
+
|
|
522
|
+
let html = readFileSync('game.html', 'utf8');
|
|
523
|
+
const init = JSON.stringify({ jid: senderJid, best, token, apiBase });
|
|
524
|
+
html = html.replace('</body>',
|
|
525
|
+
`<script>window.__INITIAL__ = ${init};</script></body>`);
|
|
526
|
+
|
|
527
|
+
await sock.sendHtml(jid, html, ['api.tuyo.com'], msg, {
|
|
528
|
+
headerText: '🎮 Mini-juego con estado persistente',
|
|
529
|
+
});
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
```javascript
|
|
533
|
+
// Dentro del HTML (game.html):
|
|
534
|
+
async function saveScore(score) {
|
|
535
|
+
await fetch(INIT.apiBase + '/score', {
|
|
536
|
+
method: 'POST',
|
|
537
|
+
headers: { 'Authorization': 'Bearer ' + INIT.token,
|
|
538
|
+
'Content-Type': 'application/json' },
|
|
539
|
+
body: JSON.stringify({ score })
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
```javascript
|
|
545
|
+
// En tu backend (Express):
|
|
546
|
+
app.post('/score', authMiddleware, async (req, res) => {
|
|
547
|
+
const { jid } = verifyJwt(req.headers.authorization); // <- identidad del JWT
|
|
548
|
+
const { score } = req.body;
|
|
549
|
+
await db.query('INSERT INTO scores ... ON CONFLICT ...', [jid, score]);
|
|
550
|
+
res.json({ ok: true });
|
|
551
|
+
});
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
Ver **`examples/html-dynamic/`** para un demo completo y funcional con SQLite.
|
|
555
|
+
|
|
556
|
+
### Anti-patrones (qué NO hacer)
|
|
557
|
+
|
|
558
|
+
- ❌ Usar `forwardOrigin = META_AI` para broadcast masivo — riesgo de ban.
|
|
559
|
+
- ❌ Enviar HTML > 50KB — puede truncarse.
|
|
560
|
+
- ❌ Confiar en `localStorage` para persistencia entre sesiones.
|
|
561
|
+
- ❌ Hacer `fetch` a dominios fuera de `trusted_sources`.
|
|
562
|
+
- ❌ Generar HTML sin identidad de usuario (no sabrás quién interactúa).
|
|
563
|
+
- ❌ Exponer tokens en texto plano dentro del HTML sin expiración corta.
|
|
564
|
+
|
|
565
|
+
### ⚠️ Advertencias
|
|
566
|
+
|
|
567
|
+
- Esta capacidad **no es oficial** y **no está documentada** por Meta. Puede
|
|
568
|
+
romperse en cualquier update del cliente de WhatsApp.
|
|
569
|
+
- El renderer depende de `forwardOrigin = META_AI` + `forwardedAiBotMessageInfo`,
|
|
570
|
+
que es una **impersonación** de un mensaje de Meta AI. Usalo en chats propios
|
|
571
|
+
o privados, no en broadcast.
|
|
572
|
+
- Probá siempre en Android, iOS y WhatsApp Web — los tres WebViews tienen
|
|
573
|
+
comportamientos distintos.
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
## 📊 Mensajes Enriquecidos (Tablas, Código, Links, LaTeX)
|
|
578
|
+
|
|
579
|
+
Estas funciones ya vienen integradas en el fork (heredadas de la fusión con el fork beta) — aquí quedan documentadas con ejemplos reales.
|
|
580
|
+
|
|
581
|
+
```javascript
|
|
582
|
+
// Tabla (formato clásico)
|
|
583
|
+
await sock.sendTable(
|
|
584
|
+
jid,
|
|
585
|
+
'Precios',
|
|
586
|
+
['Producto', 'Precio'],
|
|
587
|
+
[['Plan A', '$10'], ['Plan B', '$20']],
|
|
588
|
+
quotedMsg,
|
|
589
|
+
{ headerText: 'Nuestros planes', footer: 'Precios en USD' }
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
// Tabla V2 (respuesta unificada tipo "AI Rich")
|
|
593
|
+
await sock.sendTableV2(jid, tablaObjeto, quotedMsg, { title: 'Precios' })
|
|
594
|
+
|
|
595
|
+
// Lista simple
|
|
596
|
+
await sock.sendList(jid, 'Tareas', ['Comprar pan', 'Pagar luz'], quotedMsg)
|
|
597
|
+
|
|
598
|
+
// Bloque de código
|
|
599
|
+
await sock.sendCodeBlock(jid, 'console.log("hola")', quotedMsg, {
|
|
600
|
+
language: 'javascript',
|
|
601
|
+
title: 'Ejemplo'
|
|
602
|
+
})
|
|
603
|
+
|
|
604
|
+
// Bloque de código V2 (unified response)
|
|
605
|
+
await sock.sendCodeBlockV2(jid, 'SELECT * FROM users;', quotedMsg, { language: 'sql' })
|
|
606
|
+
|
|
607
|
+
// Texto con links enriquecidos (embeds inline)
|
|
608
|
+
await sock.sendLink(jid, 'Mira esto: ', [
|
|
609
|
+
{ url: 'https://github.com/Fer2809fl/Bail', displayName: 'Repo en GitHub' }
|
|
610
|
+
], quotedMsg)
|
|
611
|
+
|
|
612
|
+
// LaTeX (fórmulas)
|
|
613
|
+
await sock.sendLatex(quotedMsg, { formula: 'E = mc^2' })
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
## 🎠 Carruseles y 🖼️ Álbumes
|
|
617
|
+
|
|
618
|
+
**Carrusel** — se envía como un `interactiveMessage` con `carouselMessage`, cada tarjeta puede llevar imagen/video y sus propios botones nativos:
|
|
619
|
+
|
|
620
|
+
```javascript
|
|
621
|
+
await sock.sendMessage(jid, {
|
|
622
|
+
interactiveMessage: {
|
|
623
|
+
body: { text: 'Elegí un producto' },
|
|
624
|
+
footer: { text: 'Catálogo 2026' },
|
|
625
|
+
carouselMessage: {
|
|
626
|
+
cards: [
|
|
627
|
+
{
|
|
628
|
+
header: { title: 'Producto 1', imageMessage: 'https://.../foto1.jpg' },
|
|
629
|
+
body: { text: 'Descripción del producto 1' },
|
|
630
|
+
nativeFlowMessage: { buttons: [/* botones nativos, ver sección de Botones */] }
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
header: { title: 'Producto 2', videoMessage: 'https://.../video2.mp4' },
|
|
634
|
+
body: { text: 'Descripción del producto 2' }
|
|
635
|
+
}
|
|
636
|
+
]
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
})
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
**Álbum** — varias imágenes/videos agrupados en un mismo "paquete" visual (como el álbum nativo de WhatsApp):
|
|
643
|
+
|
|
644
|
+
```javascript
|
|
645
|
+
await sock.sendMessage(jid, {
|
|
646
|
+
album: [
|
|
647
|
+
{ image: { url: './foto1.jpg' }, caption: 'Foto 1' },
|
|
648
|
+
{ image: { url: './foto2.jpg' } },
|
|
649
|
+
{ video: { url: './video1.mp4' } }
|
|
650
|
+
]
|
|
651
|
+
})
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
> Ambas funciones viven en `Socket/dugong.js` (el despachador interno que detecta el tipo de contenido especial que le mandás a `sock.sendMessage`) y ya estaban portadas desde la fusión con el fork beta — lo que faltaba era este ejemplo en el README.
|
|
655
|
+
|
|
656
|
+
---
|
|
657
|
+
|
|
658
|
+
## 📰 Newsletters / Canales
|
|
659
|
+
|
|
660
|
+
Todo el manejo de canales (newsletters) de WhatsApp ya está integrado en `Socket/newsletter.js`. Resumen de las funciones disponibles en `sock`:
|
|
661
|
+
|
|
662
|
+
```javascript
|
|
663
|
+
// Crear un canal
|
|
664
|
+
const canal = await sock.newsletterCreate('Mi Canal', 'Descripción del canal')
|
|
665
|
+
|
|
666
|
+
// Seguir / dejar de seguir / silenciar / activar notificaciones
|
|
667
|
+
await sock.newsletterAction(jid, 'follow') // seguir
|
|
668
|
+
await sock.newsletterAction(jid, 'unfollow') // dejar de seguir
|
|
669
|
+
await sock.newsletterAction(jid, 'mute') // silenciar
|
|
670
|
+
await sock.newsletterAction(jid, 'unmute') // reactivar notificaciones
|
|
671
|
+
|
|
672
|
+
// Seguir varios canales de una (separados por espacio en un solo string)
|
|
673
|
+
await sock.newsletterMultipleFollow('120363...@newsletter 120363...@newsletter')
|
|
674
|
+
|
|
675
|
+
// Ver todos los canales a los que estás suscrito
|
|
676
|
+
const misCanales = await sock.newsletterFetchAllSubscribe()
|
|
677
|
+
|
|
678
|
+
// Obtener metadata de un canal por su JID o por su código de invitación
|
|
679
|
+
const meta = await sock.newsletterMetadata('invite', 'codigoDeInvitacion')
|
|
680
|
+
// o, a partir de un link https://whatsapp.com/channel/xxxx o wa.me/channel/xxxx:
|
|
681
|
+
const metaPorLink = await sock.cekIDSaluran('https://whatsapp.com/channel/xxxxxxxx')
|
|
682
|
+
|
|
683
|
+
// Editar (nombre, descripción, foto)
|
|
684
|
+
await sock.newsletterUpdateName(jid, 'Nuevo nombre')
|
|
685
|
+
await sock.newsletterUpdateDescription(jid, 'Nueva descripción')
|
|
686
|
+
await sock.newsletterUpdatePicture(jid, fotoBuffer)
|
|
687
|
+
await sock.newsletterRemovePicture(jid)
|
|
688
|
+
|
|
689
|
+
// Administración
|
|
690
|
+
await sock.newsletterSubscribers(jid) // cantidad/lista de suscriptores
|
|
691
|
+
await sock.newsletterAdminCount(jid) // cantidad de admins
|
|
692
|
+
await sock.newsletterChangeOwner(jid, nuevoOwnerJid)
|
|
693
|
+
await sock.newsletterDemote(jid, userJid)
|
|
694
|
+
await sock.newsletterDelete(jid)
|
|
695
|
+
|
|
696
|
+
// Mensajes del canal
|
|
697
|
+
await sock.newsletterFetchMessages(jid, 20) // últimos 20 mensajes
|
|
698
|
+
await sock.newsletterReactMessage(jid, serverId, '❤️')
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
**Enviar un mensaje a un canal** es igual que a cualquier chat, usando el JID del canal (termina en `@newsletter`):
|
|
702
|
+
|
|
703
|
+
```javascript
|
|
704
|
+
await sock.sendMessage(canalJid, { text: 'Novedades de hoy 🎉' })
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
> Nota de mantenimiento (heredada de v7.0.4): WhatsApp movió los endpoints internos de `follow`/`unfollow` a una versión `_v2`; este fork ya usa los IDs de consulta vigentes, así que el seguimiento de canales no debería fallar por IDs vencidos.
|
|
708
|
+
|
|
709
|
+
---
|
|
710
|
+
|
|
415
711
|
## ✨ Características
|
|
416
712
|
|
|
417
713
|
### General
|
|
@@ -419,6 +715,7 @@ export default handler
|
|
|
419
715
|
- 📸 Mensajes multimedia (imágenes, video, audio, documentos)
|
|
420
716
|
- 🔘 **Botones nativos reales, sin imports sueltos** *(v1.9.0)*
|
|
421
717
|
- 🖼️ **Previsualización automática de links en botones y mensajes** *(v1.9.0)*
|
|
718
|
+
- 🌐 **HTML embebido en WhatsApp con `sock.sendHtml`** *(v7.1.0)* — WebView sandboxed dentro del bocadillo, con patrón documentado para sitios dinámicos + BD
|
|
422
719
|
- 👥 Soporte para grupos y chats privados
|
|
423
720
|
|
|
424
721
|
### Técnicas
|
package/lib/Defaults/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { proto } from "../../WAProto/index.js";
|
|
|
2
2
|
import { makeLibSignalRepository } from "../Signal/libsignal.js";
|
|
3
3
|
import { Browsers } from "../Utils/browser-utils.js";
|
|
4
4
|
import logger from "../Utils/logger.js";
|
|
5
|
-
const version = [2, 3000,
|
|
5
|
+
const version = [2, 3000, 1047406223];
|
|
6
6
|
export const UNAUTHORIZED_CODES = [401, 403, 419];
|
|
7
7
|
export const DEFAULT_ORIGIN = "https://web.whatsapp.com";
|
|
8
8
|
export const CALL_VIDEO_PREFIX = "https://call.whatsapp.com/video/";
|