@fer2809fl/baileys 7.0.0 → 7.0.2
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 +259 -595
- package/WAProto/WAProto.proto +916 -360
- package/WAProto/fix-imports.js +18 -22
- package/WAProto/index.d.ts +15471 -8638
- package/WAProto/index.js +80576 -45941
- package/lib/Defaults/index.d.ts +14 -18
- package/lib/Defaults/index.d.ts.map +1 -1
- package/lib/Defaults/index.js +110 -115
- package/lib/Defaults/index.js.map +1 -1
- package/lib/Signal/Group/group_cipher.js.map +1 -1
- package/lib/Signal/Group/keyhelper.d.ts.map +1 -1
- package/lib/Signal/Group/keyhelper.js.map +1 -1
- package/lib/Signal/Group/sender-chain-key.js.map +1 -1
- package/lib/Signal/Group/sender-key-message.js.map +1 -1
- package/lib/Signal/Group/sender-message-key.js.map +1 -1
- package/lib/Signal/libsignal.d.ts.map +1 -1
- package/lib/Signal/libsignal.js +17 -45
- package/lib/Signal/libsignal.js.map +1 -1
- package/lib/Signal/lid-mapping.d.ts +0 -4
- package/lib/Signal/lid-mapping.d.ts.map +1 -1
- package/lib/Signal/lid-mapping.js +0 -6
- package/lib/Signal/lid-mapping.js.map +1 -1
- package/lib/Socket/business.d.ts +532 -280
- package/lib/Socket/business.d.ts.map +1 -1
- package/lib/Socket/business.js +401 -358
- package/lib/Socket/chats.d.ts +2 -22
- package/lib/Socket/chats.d.ts.map +1 -1
- package/lib/Socket/chats.js +43 -314
- package/lib/Socket/chats.js.map +1 -1
- package/lib/Socket/communities.d.ts +641 -336
- package/lib/Socket/communities.d.ts.map +1 -1
- package/lib/Socket/communities.js +3 -6
- package/lib/Socket/communities.js.map +1 -1
- package/lib/Socket/dugong.d.ts +130 -0
- package/lib/Socket/dugong.d.ts.map +1 -0
- package/lib/Socket/dugong.js +772 -0
- package/lib/Socket/dugong.js.map +1 -0
- package/lib/Socket/groups.d.ts +2 -23
- package/lib/Socket/groups.d.ts.map +1 -1
- package/lib/Socket/groups.js +8 -171
- package/lib/Socket/groups.js.map +1 -1
- package/lib/Socket/index.d.ts +631 -322
- package/lib/Socket/index.d.ts.map +1 -1
- package/lib/Socket/index.js +12 -9
- package/lib/Socket/index.js.map +1 -1
- package/lib/Socket/messages-recv.d.ts +52 -84
- package/lib/Socket/messages-recv.d.ts.map +1 -1
- package/lib/Socket/messages-recv.js +185 -686
- package/lib/Socket/messages-recv.js.map +1 -1
- package/lib/Socket/messages-send.d.ts +643 -262
- package/lib/Socket/messages-send.d.ts.map +1 -1
- package/lib/Socket/messages-send.js +1559 -1359
- package/lib/Socket/messages-send.js.map +1 -1
- package/lib/Socket/mex.d.ts +0 -1
- package/lib/Socket/mex.d.ts.map +1 -1
- package/lib/Socket/mex.js +8 -22
- package/lib/Socket/mex.js.map +1 -1
- package/lib/Socket/native-buttons.js +231 -0
- package/lib/Socket/newsletter.d.ts +27 -42
- package/lib/Socket/newsletter.d.ts.map +1 -1
- package/lib/Socket/newsletter.js +439 -402
- package/lib/Socket/newsletter.js.map +1 -1
- package/lib/Socket/socket.d.ts +2 -6
- package/lib/Socket/socket.d.ts.map +1 -1
- package/lib/Socket/socket.js +26 -62
- package/lib/Socket/socket.js.map +1 -1
- package/lib/Types/Auth.d.ts +0 -1
- package/lib/Types/Auth.d.ts.map +1 -1
- package/lib/Types/Bussines.d.ts +34 -22
- package/lib/Types/Call.d.ts +1 -1
- package/lib/Types/Call.d.ts.map +1 -1
- package/lib/Types/Chat.d.ts +0 -1
- package/lib/Types/Chat.d.ts.map +1 -1
- package/lib/Types/Contact.d.ts +0 -2
- package/lib/Types/Contact.d.ts.map +1 -1
- package/lib/Types/Events.d.ts +1 -20
- package/lib/Types/Events.d.ts.map +1 -1
- package/lib/Types/GroupMetadata.d.ts +1 -4
- package/lib/Types/GroupMetadata.d.ts.map +1 -1
- package/lib/Types/Message.d.ts +348 -354
- package/lib/Types/Message.d.ts.map +1 -1
- package/lib/Types/Message.js +0 -4
- package/lib/Types/Message.js.map +1 -1
- package/lib/Types/{Mex.d.ts → Newsletter.d.ts} +7 -26
- package/lib/Types/Newsletter.d.ts.map +1 -0
- package/lib/Types/{Mex.js → Newsletter.js} +3 -11
- package/lib/Types/Newsletter.js.map +1 -0
- package/lib/Types/Signal.d.ts +1 -12
- package/lib/Types/Signal.d.ts.map +1 -1
- package/lib/Types/Socket.d.ts +148 -135
- package/lib/Types/Socket.d.ts.map +1 -1
- package/lib/Types/Socket.js.map +1 -1
- package/lib/Types/State.d.ts +0 -65
- package/lib/Types/State.d.ts.map +1 -1
- package/lib/Types/State.js +0 -43
- package/lib/Types/State.js.map +1 -1
- package/lib/Types/index.d.ts +52 -52
- package/lib/Types/index.d.ts.map +1 -1
- package/lib/Types/index.js +30 -23
- package/lib/Types/index.js.map +1 -1
- package/lib/Utils/auth-utils.d.ts +0 -5
- package/lib/Utils/auth-utils.d.ts.map +1 -1
- package/lib/Utils/auth-utils.js +0 -12
- package/lib/Utils/auth-utils.js.map +1 -1
- package/lib/Utils/browser-utils.d.ts.map +1 -1
- package/lib/Utils/browser-utils.js +0 -1
- package/lib/Utils/browser-utils.js.map +1 -1
- package/lib/Utils/chat-utils.d.ts +4 -34
- package/lib/Utils/chat-utils.d.ts.map +1 -1
- package/lib/Utils/chat-utils.js +20 -80
- package/lib/Utils/chat-utils.js.map +1 -1
- package/lib/Utils/crypto.d.ts +12 -12
- package/lib/Utils/crypto.d.ts.map +1 -1
- package/lib/Utils/crypto.js.map +1 -1
- package/lib/Utils/decode-wa-message.d.ts +0 -18
- package/lib/Utils/decode-wa-message.d.ts.map +1 -1
- package/lib/Utils/decode-wa-message.js +0 -34
- package/lib/Utils/decode-wa-message.js.map +1 -1
- package/lib/Utils/event-buffer.d.ts +0 -2
- package/lib/Utils/event-buffer.d.ts.map +1 -1
- package/lib/Utils/event-buffer.js +1 -49
- package/lib/Utils/event-buffer.js.map +1 -1
- package/lib/Utils/generics.d.ts +2 -3
- package/lib/Utils/generics.d.ts.map +1 -1
- package/lib/Utils/generics.js +1 -10
- package/lib/Utils/generics.js.map +1 -1
- package/lib/Utils/history.d.ts +0 -2
- package/lib/Utils/history.d.ts.map +1 -1
- package/lib/Utils/history.js +9 -12
- package/lib/Utils/history.js.map +1 -1
- package/lib/Utils/identity-change-handler.d.ts +0 -7
- package/lib/Utils/identity-change-handler.d.ts.map +1 -1
- package/lib/Utils/identity-change-handler.js +0 -1
- package/lib/Utils/identity-change-handler.js.map +1 -1
- package/lib/Utils/index.d.ts +23 -30
- package/lib/Utils/index.d.ts.map +1 -1
- package/lib/Utils/index.js +2 -9
- package/lib/Utils/index.js.map +1 -1
- package/lib/Utils/link-preview.js +2 -2
- package/lib/Utils/link-preview.js.map +1 -1
- package/lib/Utils/message-retry-manager.d.ts +0 -5
- package/lib/Utils/message-retry-manager.d.ts.map +1 -1
- package/lib/Utils/message-retry-manager.js +0 -40
- package/lib/Utils/message-retry-manager.js.map +1 -1
- package/lib/Utils/messages-media.d.ts +13 -45
- package/lib/Utils/messages-media.d.ts.map +1 -1
- package/lib/Utils/messages-media.js +98 -293
- package/lib/Utils/messages-media.js.map +1 -1
- package/lib/Utils/messages.d.ts +3 -16
- package/lib/Utils/messages.d.ts.map +1 -1
- package/lib/Utils/messages.js +1123 -1219
- package/lib/Utils/messages.js.map +1 -1
- package/lib/Utils/noise-handler.d.ts +1 -1
- package/lib/Utils/process-message.d.ts.map +1 -1
- package/lib/Utils/process-message.js +1 -103
- package/lib/Utils/process-message.js.map +1 -1
- package/lib/Utils/rich-messages.d.ts +277 -0
- package/lib/Utils/rich-messages.d.ts.map +1 -0
- package/lib/Utils/rich-messages.js +1144 -0
- package/lib/Utils/rich-messages.js.map +1 -0
- package/lib/Utils/signal.d.ts +0 -13
- package/lib/Utils/signal.d.ts.map +1 -1
- package/lib/Utils/signal.js +0 -42
- package/lib/Utils/signal.js.map +1 -1
- package/lib/Utils/sticker-pack.d.ts +10 -0
- package/lib/Utils/sticker-pack.js +111 -0
- package/lib/Utils/sync-action-utils.d.ts.map +1 -1
- package/lib/Utils/sync-action-utils.js +0 -1
- package/lib/Utils/sync-action-utils.js.map +1 -1
- package/lib/Utils/tc-token-utils.d.ts +1 -26
- package/lib/Utils/tc-token-utils.d.ts.map +1 -1
- package/lib/Utils/tc-token-utils.js +5 -151
- package/lib/Utils/tc-token-utils.js.map +1 -1
- package/lib/Utils/validate-connection.d.ts +0 -1
- package/lib/Utils/validate-connection.d.ts.map +1 -1
- package/lib/Utils/validate-connection.js +3 -13
- package/lib/Utils/validate-connection.js.map +1 -1
- package/lib/WABinary/decode.d.ts +1 -1
- package/lib/WABinary/decode.d.ts.map +1 -1
- package/lib/WABinary/generic-utils.d.ts +3 -1
- package/lib/WABinary/generic-utils.d.ts.map +1 -1
- package/lib/WABinary/generic-utils.js +78 -0
- package/lib/WABinary/generic-utils.js.map +1 -1
- package/lib/WABinary/jid-utils.d.ts +0 -11
- package/lib/WABinary/jid-utils.d.ts.map +1 -1
- package/lib/WABinary/jid-utils.js +0 -33
- package/lib/WABinary/jid-utils.js.map +1 -1
- package/lib/WAM/encode.d.ts +1 -1
- package/lib/WAM/encode.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +3 -26
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -1
- package/lib/WAUSync/Protocols/index.d.ts +0 -1
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/index.js +0 -1
- package/lib/WAUSync/Protocols/index.js.map +1 -1
- package/lib/WAUSync/USyncQuery.d.ts +0 -1
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -1
- package/lib/WAUSync/USyncQuery.js +2 -6
- package/lib/WAUSync/USyncQuery.js.map +1 -1
- package/lib/WAUSync/USyncUser.d.ts +0 -4
- package/lib/WAUSync/USyncUser.d.ts.map +1 -1
- package/lib/WAUSync/USyncUser.js +0 -8
- package/lib/WAUSync/USyncUser.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -4
- package/lib/index.js.map +1 -1
- package/package.json +30 -34
- package/LICENSE +0 -21
- package/engine-requirements.js +0 -10
- package/lib/Socket/smgss.d.ts +0 -119
- package/lib/Socket/smgss.d.ts.map +0 -1
- package/lib/Socket/smgss.js +0 -453
- package/lib/Socket/smgss.js.map +0 -1
- package/lib/Store/index.d.ts +0 -4
- package/lib/Store/index.d.ts.map +0 -1
- package/lib/Store/index.js +0 -4
- package/lib/Store/index.js.map +0 -1
- package/lib/Store/make-in-memory-store.d.ts +0 -132
- package/lib/Store/make-in-memory-store.d.ts.map +0 -1
- package/lib/Store/make-in-memory-store.js +0 -450
- package/lib/Store/make-in-memory-store.js.map +0 -1
- package/lib/Store/make-ordered-dictionary.d.ts +0 -14
- package/lib/Store/make-ordered-dictionary.d.ts.map +0 -1
- package/lib/Store/make-ordered-dictionary.js +0 -80
- package/lib/Store/make-ordered-dictionary.js.map +0 -1
- package/lib/Store/object-repository.d.ts +0 -13
- package/lib/Store/object-repository.d.ts.map +0 -1
- package/lib/Store/object-repository.js +0 -24
- package/lib/Store/object-repository.js.map +0 -1
- package/lib/Types/Mex.d.ts.map +0 -1
- package/lib/Types/Mex.js.map +0 -1
- package/lib/Utils/button-handler.d.ts +0 -28
- package/lib/Utils/button-handler.d.ts.map +0 -1
- package/lib/Utils/button-handler.js +0 -140
- package/lib/Utils/button-handler.js.map +0 -1
- package/lib/Utils/companion-reg-client-utils.d.ts +0 -17
- package/lib/Utils/companion-reg-client-utils.d.ts.map +0 -1
- package/lib/Utils/companion-reg-client-utils.js +0 -35
- package/lib/Utils/companion-reg-client-utils.js.map +0 -1
- package/lib/Utils/interactive.d.ts +0 -60
- package/lib/Utils/interactive.d.ts.map +0 -1
- package/lib/Utils/interactive.js +0 -224
- package/lib/Utils/interactive.js.map +0 -1
- package/lib/Utils/message-composer.d.ts +0 -93
- package/lib/Utils/message-composer.d.ts.map +0 -1
- package/lib/Utils/message-composer.js +0 -311
- package/lib/Utils/message-composer.js.map +0 -1
- package/lib/Utils/messages-newsletter.d.ts +0 -74
- package/lib/Utils/messages-newsletter.d.ts.map +0 -1
- package/lib/Utils/messages-newsletter.js +0 -128
- package/lib/Utils/messages-newsletter.js.map +0 -1
- package/lib/Utils/shortcake-crypto.d.ts +0 -36
- package/lib/Utils/shortcake-crypto.d.ts.map +0 -1
- package/lib/Utils/shortcake-crypto.js +0 -71
- package/lib/Utils/shortcake-crypto.js.map +0 -1
- package/lib/Utils/shortcake.d.ts +0 -36
- package/lib/Utils/shortcake.d.ts.map +0 -1
- package/lib/Utils/shortcake.js +0 -162
- package/lib/Utils/shortcake.js.map +0 -1
- package/lib/Utils/use-single-file-auth-state.d.ts +0 -6
- package/lib/Utils/use-single-file-auth-state.d.ts.map +0 -1
- package/lib/Utils/use-single-file-auth-state.js +0 -111
- package/lib/Utils/use-single-file-auth-state.js.map +0 -1
- package/lib/Utils/use-sqlite-auth-state.d.ts +0 -14
- package/lib/Utils/use-sqlite-auth-state.d.ts.map +0 -1
- package/lib/Utils/use-sqlite-auth-state.js +0 -107
- package/lib/Utils/use-sqlite-auth-state.js.map +0 -1
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +0 -25
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,694 +1,358 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<img src="https://raw.githubusercontent.com/Fer2809fl/Baileys/refs/heads/main/lib/Baileys.jpeg" alt="Baileys" width="500" style="border-radius: 20px;"/>
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# @fer2809fl/baileys
|
|
6
|
+
### API de WhatsApp Web para Node.js
|
|
6
7
|
|
|
7
|
-

|
|
9
|
-
](https://www.npmjs.com/package/@fer2809fl/baileys)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://nodejs.org)
|
|
11
|
+
[](https://www.typescriptlang.org)
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<br/>
|
|
15
|
-
|
|
16
|
-
> [!NOTE]
|
|
17
|
-
> ASTA-BOTS no requiere Selenium, Puppeteer ni ningún navegador para funcionar. Se conecta directamente a WhatsApp Web mediante un **WebSocket**, lo que la hace mucho más liviana en consumo de RAM y CPU en comparación con soluciones basadas en navegador.
|
|
18
|
-
|
|
19
|
-
## Índice
|
|
20
|
-
|
|
21
|
-
- [¿Qué es ASTA-BOTS?](#qué-es-asta-bots)
|
|
22
|
-
- [Características](#características)
|
|
23
|
-
- [Instalación](#instalación)
|
|
24
|
-
- [Inicio rápido](#inicio-rápido)
|
|
25
|
-
- [Vinculación de la cuenta](#vinculación-de-la-cuenta)
|
|
26
|
-
- [Guardado de credenciales](#guardado-de-credenciales)
|
|
27
|
-
- [Métodos de mensajería](#métodos-de-mensajería)
|
|
28
|
-
- [`sendMessage`](#sendmessage-el-método-principal)
|
|
29
|
-
- [Mensajes de texto](#mensajes-de-texto)
|
|
30
|
-
- [Mensajes multimedia](#mensajes-multimedia)
|
|
31
|
-
- [Procesar medios sin enviarlos](#procesar-medios-sin-enviarlos)
|
|
32
|
-
- [Ubicación y contactos](#ubicación-y-contactos)
|
|
33
|
-
- [Encuestas, reacciones y respuestas a botones](#encuestas-reacciones-y-respuestas-a-botones)
|
|
34
|
-
- [Botones, listas, templates y carousel](#botones-listas-templates-y-carousel)
|
|
35
|
-
- [Mensajes crudos (smgss): pagos, productos, álbumes, eventos y más](#mensajes-crudos-smgss-pagos-productos-álbumes-eventos-y-más)
|
|
36
|
-
- [Mensajes "raw" (proto armado a mano)](#mensajes-raw-proto-armado-a-mano)
|
|
37
|
-
- [Editar, eliminar, reenviar y fijar](#editar-eliminar-reenviar-y-fijar)
|
|
38
|
-
- [Mensajes enriquecidos](#mensajes-enriquecidos)
|
|
39
|
-
- [Marcar un mensaje como generado por IA](#marcar-un-mensaje-como-generado-por-ia)
|
|
40
|
-
- [Estados (historias)](#estados-historias)
|
|
41
|
-
- [Recibos, lectura y presencia](#recibos-lectura-y-presencia)
|
|
42
|
-
- [Grupos, comunidades y canales](#grupos-comunidades-y-canales)
|
|
43
|
-
- [Perfil, privacidad y negocios](#perfil-privacidad-y-negocios)
|
|
44
|
-
- [Store (caché en memoria)](#store-caché-en-memoria)
|
|
45
|
-
- [Utilidades ASTA-BOTS](#utilidades-asta-bots)
|
|
46
|
-
- [`resolveJid`: resolución automática de JID](#resolvejid-resolución-automática-de-jid)
|
|
47
|
-
- [Sistema de botones de conveniencia](#sistema-de-botones-de-conveniencia)
|
|
48
|
-
- [Código de vinculación de marca](#código-de-vinculación-de-marca)
|
|
49
|
-
- [Aviso legal](#aviso-legal)
|
|
50
|
-
- [Créditos](#créditos)
|
|
51
|
-
|
|
52
|
-
## ¿Qué es ASTA-BOTS?
|
|
53
|
-
|
|
54
|
-
**ASTA-BOTS** es una librería para conectarse a WhatsApp Web de forma directa, sin depender de un navegador ni de librerías de automatización como Selenium o Puppeteer. Toda la comunicación con WhatsApp ocurre a través de un **WebSocket**, tal como lo hace la propia versión web de WhatsApp, lo que se traduce en una librería rápida y liviana en recursos.
|
|
55
|
-
|
|
56
|
-
Es un fork de **Baileys**, y conserva casi toda su base: el protocolo, el cifrado, la arquitectura del socket y el manejo de credenciales. Además, incorpora algunos métodos para enviar mensajes con contenido enriquecido (tablas, listas, código y LaTeX), botones/listas/carousel nativos de WhatsApp, un dispatcher para contenido avanzado (pagos, productos, álbumes, eventos), y utilidades propias de **ASTA-BOTS** para resolución automática de JID y botones de conveniencia — más detalle en las secciones correspondientes.
|
|
57
|
-
|
|
58
|
-
Este README está enfocado principalmente en explicar **cómo enviar cada tipo de mensaje**, ya que es lo que más se necesita a la hora de integrar la librería en un proyecto real.
|
|
59
|
-
|
|
60
|
-
## Características
|
|
61
|
-
|
|
62
|
-
- 🔌 Conexión directa por WebSocket, sin navegador de por medio.
|
|
63
|
-
- 💬 Envío de todo tipo de mensajes: texto, imágenes, video, audio, notas de voz, documentos, stickers, ubicación, contactos, encuestas y más.
|
|
64
|
-
- 🔘 Botones, listas de selección, templates y carousel (interactive/native_flow), con el nodo `biz` necesario para que WhatsApp los acepte y renderice.
|
|
65
|
-
- ⚡ **Resolución automática de JID** (`resolveJid`): detecta el destinatario de un comando por citado, mención o argumento, sin pasar el número a mano.
|
|
66
|
-
- ⚡ **Helpers de botones listos para usar** (`sendQuickReplyButtons`, `sendUrlButton`, `sendListMenu`, etc.) y un detector de respuestas de botón (`setupButtonHandler`) para enrutarlas directo a tus comandos.
|
|
67
|
-
- 💳 Contenido avanzado vía `smgss`: pedidos de pago, cards de producto, álbumes, eventos, resultados de encuesta e historias por grupo.
|
|
68
|
-
- 🖼️ Procesamiento de medios (`resize`, `convert`, `toSticker`, `compress`, `metadata`) sobre cualquier `Buffer`, sin necesidad de enviarlo.
|
|
69
|
-
- 🛠️ Salida de emergencia `raw: true` para mandar un mensaje armado a mano cuando ningún builder alcanza.
|
|
70
|
-
- 🧩 Métodos para enviar mensajes enriquecidos: tablas, listas, código y LaTeX.
|
|
71
|
-
- 🤖 Marca de "generado por IA" en mensajes de chats individuales.
|
|
72
|
-
- 📸 Publicación de estados (historias) con notificación por menciones, tanto a contactos individuales como a grupos.
|
|
73
|
-
- 👥 Administración completa de grupos, comunidades y canales de difusión.
|
|
74
|
-
- 🔐 2 métodos de vinculación: código QR o código de emparejamiento (con código de marca **`ASTABOTS`** por defecto).
|
|
75
|
-
- 🗂️ 3 formas de guardar credenciales: por archivos múltiples, un solo archivo o SQLite.
|
|
76
|
-
|
|
77
|
-
## Instalación
|
|
78
|
-
|
|
79
|
-
Instalación directa desde GitHub:
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
npm install github:TU-USUARIO/asta-bots
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
> Cambia `TU-USUARIO/asta-bots` por la ruta de tu propio repositorio de ASTA-BOTS en GitHub.
|
|
86
|
-
>
|
|
87
|
-
> **Requisito:** Node.js **20** o superior.
|
|
88
|
-
|
|
89
|
-
Una vez instalada, importala en tu proyecto:
|
|
90
|
-
|
|
91
|
-
```ts
|
|
92
|
-
import makeWASocket from 'baileys'
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
## Inicio rápido
|
|
96
|
-
|
|
97
|
-
Para conectar una cuenta de WhatsApp a ASTA-BOTS hacen falta dos cosas: **cómo se guardan las credenciales de la sesión** y **cómo se vincula el dispositivo** (que puede ser con código QR o con código de emparejamiento).
|
|
98
|
-
|
|
99
|
-
### Vinculación de la cuenta
|
|
100
|
-
|
|
101
|
-
ASTA-BOTS soporta los **2 métodos de vinculación** que ofrece WhatsApp:
|
|
102
|
-
|
|
103
|
-
#### 1. Con código QR
|
|
104
|
-
|
|
105
|
-
```ts
|
|
106
|
-
import makeWASocket, { useMultiFileAuthState } from 'baileys'
|
|
107
|
-
|
|
108
|
-
async function iniciar() {
|
|
109
|
-
const { state, saveCreds } = await useMultiFileAuthState('sesion')
|
|
110
|
-
|
|
111
|
-
const sock = makeWASocket({
|
|
112
|
-
auth: state,
|
|
113
|
-
printQRInTerminal: true
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
sock.ev.on('creds.update', saveCreds)
|
|
117
|
-
|
|
118
|
-
sock.ev.on('connection.update', (update) => {
|
|
119
|
-
console.log(update)
|
|
120
|
-
})
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
iniciar()
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Al iniciar, se imprime un código QR en la terminal que hay que escanear desde WhatsApp (Dispositivos vinculados → Vincular un dispositivo).
|
|
127
|
-
|
|
128
|
-
#### 2. Con código de emparejamiento
|
|
129
|
-
|
|
130
|
-
```ts
|
|
131
|
-
const sock = makeWASocket({
|
|
132
|
-
auth: state,
|
|
133
|
-
printQRInTerminal: false
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
if (!sock.authState?.creds?.registered) {
|
|
137
|
-
const codigo = await sock.requestPairingCode('5215512345678') // número con código de país, sin +
|
|
138
|
-
console.log('Tu código de emparejamiento es:', codigo)
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
En este caso, en vez de escanear un QR, WhatsApp te muestra en el celular un código de 8 caracteres que hay que ingresar desde la opción "Vincular con número de teléfono".
|
|
143
|
-
|
|
144
|
-
### Guardado de credenciales
|
|
145
|
-
|
|
146
|
-
Una vez vinculada la cuenta, ASTA-BOTS necesita persistir las credenciales para no tener que volver a escanear el QR o pedir el código cada vez. Hay **3 formas** de hacerlo, todas exportadas por la librería:
|
|
147
|
-
|
|
148
|
-
| Método | Cómo guarda los datos | Cuándo conviene |
|
|
149
|
-
|---|---|---|
|
|
150
|
-
| `useMultiFileAuthState('carpeta')` | Un archivo por cada clave, dentro de una carpeta | Uso por defecto, ideal para desarrollo y bots simples |
|
|
151
|
-
| `useSingleFileAuthState('archivo.json')` | Todo en un único archivo JSON | Cuando querés portar la sesión fácilmente como un solo archivo |
|
|
152
|
-
| `useSqliteAuthState({ dbPath: 'sesion.db' })` | En una base de datos SQLite (requiere `better-sqlite3`) | Bots con mucho volumen de claves o que necesitan acceso concurrente |
|
|
153
|
-
|
|
154
|
-
Ejemplo con SQLite:
|
|
155
|
-
|
|
156
|
-
```ts
|
|
157
|
-
import makeWASocket, { useSqliteAuthState } from 'baileys'
|
|
158
|
-
|
|
159
|
-
const { state, saveCreds } = await useSqliteAuthState({ dbPath: 'sesion.db' })
|
|
160
|
-
|
|
161
|
-
const sock = makeWASocket({ auth: state })
|
|
162
|
-
sock.ev.on('creds.update', saveCreds)
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## Métodos de mensajería
|
|
13
|
+
*Conéctate a WhatsApp Web directamente desde Node.js sin navegadores ni Selenium*
|
|
166
14
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
Formatos de JID más comunes:
|
|
170
|
-
|
|
171
|
-
| Tipo de chat | Formato de JID |
|
|
172
|
-
|---|---|
|
|
173
|
-
| Contacto individual | `5215512345678@s.whatsapp.net` |
|
|
174
|
-
| Grupo | `1234567890@g.us` |
|
|
175
|
-
| Canal de difusión (newsletter) | `1234567890@newsletter` |
|
|
176
|
-
| Estado (historia) | `status@broadcast` |
|
|
177
|
-
| Identificador LID | `123456789@lid` |
|
|
178
|
-
|
|
179
|
-
> **¿Qué es un LID?** Es un identificador que WhatsApp usa como capa de privacidad: en ciertos contextos (por ejemplo, dentro de comunidades) un contacto no se identifica con su número de teléfono (`@s.whatsapp.net`) sino con un `@lid`, un ID que no revela el número real. ASTA-BOTS mantiene internamente una tabla de equivalencias entre el LID y el número de teléfono real (`LIDMappingStore`) para poder cifrar y enviar los mensajes correctamente sin que tengas que hacer nada manualmente. Si necesitás revisarlo, `isLidUser(jid)` te dice si un JID es de tipo LID.
|
|
180
|
-
|
|
181
|
-
### `sendMessage` — el método principal
|
|
15
|
+
</div>
|
|
182
16
|
|
|
183
|
-
|
|
184
|
-
await sock.sendMessage(jid, contenido, opciones)
|
|
185
|
-
```
|
|
17
|
+
---
|
|
186
18
|
|
|
187
|
-
|
|
188
|
-
- **`contenido`** *(`AnyMessageContent`)*: define qué tipo de mensaje se envía (texto, imagen, video, encuesta, botones, etc. — ver detalle abajo).
|
|
189
|
-
- **`opciones`** *(`MiscMessageGenerationOptions`, opcional)*: permite, entre otras cosas:
|
|
190
|
-
- `quoted`: el mensaje al que se responde (citar).
|
|
191
|
-
- `messageId`: forzar un ID de mensaje propio.
|
|
192
|
-
- `ephemeralExpiration`: duración de los mensajes efímeros.
|
|
193
|
-
- `mediaUploadTimeoutMs`: tiempo máximo para subir archivos.
|
|
19
|
+
## 🆕 Novedades — v1.9.0
|
|
194
20
|
|
|
195
|
-
|
|
21
|
+
### ✅ Nuevas funciones añadidas
|
|
22
|
+
- **Botones nativos reales** — Se agregaron métodos directos en el socket para enviar botones interactivos de WhatsApp (native flow), reemplazando el viejo formato `buttons: [{text, id}]` que ya no renderiza en WhatsApp:
|
|
23
|
+
- `sendQuickReplyButtons` — Botones de respuesta rápida
|
|
24
|
+
- `sendUrlButton` — Botón que abre un enlace
|
|
25
|
+
- `sendCallButton` — Botón para iniciar una llamada
|
|
26
|
+
- `sendCopyButton` — Botón que copia texto al portapapeles
|
|
27
|
+
- `sendReminderButton` — Botón de recordatorio
|
|
28
|
+
- `sendListButton` — Menú desplegable con secciones y filas
|
|
29
|
+
- `sendMixedButtons` — Combinación libre de varios tipos en un solo mensaje
|
|
30
|
+
- **Previsualización automática de links** — `sendLinkPreview` y todos los botones de arriba arman solos la tarjeta grande (imagen + título + descripción) de cualquier URL que detecten en el texto, con el mismo motor que usa WhatsApp para los links normales.
|
|
196
31
|
|
|
197
|
-
|
|
32
|
+
### 🐛 Correcciones
|
|
33
|
+
- **Error en macOS** — Se reparó un bug crítico que impedía iniciar sesión correctamente en dispositivos Mac. El proceso de pairing/QR ahora funciona de forma estable en macOS.
|
|
198
34
|
|
|
199
|
-
|
|
35
|
+
---
|
|
200
36
|
|
|
201
|
-
|
|
37
|
+
## ⚠️ Nota Importante
|
|
202
38
|
|
|
203
|
-
|
|
204
|
-
await sock.sendMessage(jid, { text: 'Hola, esto es ASTA-BOTS 👋' })
|
|
205
|
-
```
|
|
39
|
+
ꕤ Esta librería está basada en Baileys. No está afiliada ni aprobada oficialmente por WhatsApp.
|
|
206
40
|
|
|
207
|
-
|
|
41
|
+
> **@fer2809fl/baileys** y su desarrollador no se hacen responsables por el mal uso de esta librería.
|
|
42
|
+
> Úsala de forma responsable — nada de spam ni actividades maliciosas.
|
|
208
43
|
|
|
209
|
-
|
|
210
|
-
await sock.sendMessage(jid, { text: 'Mirá esto: https://ejemplo.com', linkPreview: null })
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
Citando un mensaje:
|
|
44
|
+
---
|
|
214
45
|
|
|
215
|
-
|
|
216
|
-
await sock.sendMessage(jid, { text: 'Respondiendo a tu mensaje' }, { quoted: mensajeOriginal })
|
|
217
|
-
```
|
|
46
|
+
## 📦 Instalación
|
|
218
47
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
| Imagen | `image` | `{ image: { url: './foto.jpg' }, caption: 'Mirá esto' }` |
|
|
224
|
-
| Video | `video` | `{ video: { url: './video.mp4' }, caption: 'Un video', gifPlayback: false }` |
|
|
225
|
-
| Nota de voz | `audio` + `ptt: true` | `{ audio: { url: './audio.mp3' }, ptt: true }` |
|
|
226
|
-
| Audio normal | `audio` | `{ audio: { url: './cancion.mp3' }, mimetype: 'audio/mp4' }` |
|
|
227
|
-
| Video nota (círculo) | `video` + `ptv: true` | `{ video: { url: './nota.mp4' }, ptv: true }` |
|
|
228
|
-
| Sticker | `sticker` | `{ sticker: { url: './sticker.webp' } }` |
|
|
229
|
-
| Documento | `document` | `{ document: { url: './archivo.pdf' }, mimetype: 'application/pdf', fileName: 'informe.pdf' }` |
|
|
230
|
-
| Paquete de stickers | `stickerPack` | `{ stickerPack: { name: 'Mi pack', cover: {...}, stickers: [...] } }` |
|
|
231
|
-
| Álbum (varias fotos/videos) | `album` | `{ album: { images: [...], videos: [...] } }` |
|
|
232
|
-
|
|
233
|
-
Ejemplo completo:
|
|
234
|
-
|
|
235
|
-
```ts
|
|
236
|
-
await sock.sendMessage(jid, {
|
|
237
|
-
image: { url: './foto.jpg' },
|
|
238
|
-
caption: 'Foto enviada desde ASTA-BOTS'
|
|
239
|
-
})
|
|
48
|
+
**Opción 1 — Desde npm (recomendado)**
|
|
49
|
+
```bash
|
|
50
|
+
npm install @fer2809fl/baileys
|
|
51
|
+
yarn add @fer2809fl/baileys
|
|
240
52
|
```
|
|
241
53
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
Además de enviar, el socket expone helpers para procesar imágenes y video directamente sobre un `Buffer`, sin que eso implique mandar ningún mensaje:
|
|
247
|
-
|
|
248
|
-
```ts
|
|
249
|
-
const redimensionada = await sock.resize(buffer, 512, 512, { quality: 80 })
|
|
250
|
-
const convertida = await sock.convert(buffer, { to: 'webp' })
|
|
251
|
-
const sticker = await sock.toSticker(buffer, { quality: 80 })
|
|
252
|
-
const comprimida = await sock.compress(buffer, { quality: 50 })
|
|
253
|
-
const info = await sock.metadata(buffer) // { size, mimetype, width, height, duration, ... }
|
|
54
|
+
**Opción 2 — Desde GitHub directamente**
|
|
55
|
+
```bash
|
|
56
|
+
npm install github:Fer2809fl/Baileys
|
|
57
|
+
yarn add github:Fer2809fl/Baileys
|
|
254
58
|
```
|
|
255
59
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
// Ubicación
|
|
262
|
-
await sock.sendMessage(jid, {
|
|
263
|
-
location: { degreesLatitude: 19.4326, degreesLongitude: -99.1332, name: 'CDMX' }
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
// Contacto (vCard)
|
|
267
|
-
await sock.sendMessage(jid, {
|
|
268
|
-
contacts: {
|
|
269
|
-
displayName: 'Soporte',
|
|
270
|
-
contacts: [{ vcard: 'BEGIN:VCARD\nVERSION:3.0\nFN:Soporte\nTEL:+521234567890\nEND:VCARD' }]
|
|
60
|
+
**En tu package.json**
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@fer2809fl/baileys": "^1.9.0"
|
|
271
65
|
}
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### Encuestas, reacciones y respuestas a botones
|
|
276
|
-
|
|
277
|
-
```ts
|
|
278
|
-
// Encuesta
|
|
279
|
-
await sock.sendMessage(jid, {
|
|
280
|
-
poll: { name: '¿Cuál prefieres?', values: ['Opción A', 'Opción B'], selectableCount: 1 }
|
|
281
|
-
})
|
|
282
|
-
|
|
283
|
-
// Reacción a un mensaje
|
|
284
|
-
await sock.sendMessage(jid, { react: { text: '🔥', key: mensaje.key } })
|
|
285
|
-
|
|
286
|
-
// Respuesta a un botón / lista (uso interno al procesar interacciones)
|
|
287
|
-
await sock.sendMessage(jid, { buttonReply: { displayText: 'Sí', id: 'btn_si', index: 0 }, type: 'plain' })
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
### Botones, listas, templates y carousel
|
|
291
|
-
|
|
292
|
-
ASTA-BOTS puede armar botones nativos (`native_flow`), listas de selección, templates legados y carousel directamente desde `sock.sendMessage`, sin tener que construir el protobuf a mano. En todos los casos se agrega automáticamente el nodo `biz` necesario para que WhatsApp los acepte.
|
|
293
|
-
|
|
294
|
-
**Botones** — soporta respuesta rápida (`id`), enlace (`url`), llamada (`call`), copiar texto (`copy`), una mini-lista embebida (`sections`), un flow crudo (`name` + `paramsJson`), o un botón ya armado con `nativeFlowInfo` (por ejemplo, reenviado de otro lado) — en ese caso se respeta tal cual viene:
|
|
295
|
-
|
|
296
|
-
```ts
|
|
297
|
-
await sock.sendMessage(jid, {
|
|
298
|
-
text: 'Elegí una opción',
|
|
299
|
-
footer: 'Powered by ASTA-BOTS',
|
|
300
|
-
buttons: [
|
|
301
|
-
{ text: 'Visitar sitio', url: 'https://ejemplo.com' },
|
|
302
|
-
{ text: 'Llamar', call: '+50488888888' },
|
|
303
|
-
{ text: 'Copiar código', copy: 'ABC123' },
|
|
304
|
-
{ text: 'Responder', id: 'opt_1' }
|
|
305
|
-
]
|
|
306
|
-
})
|
|
66
|
+
}
|
|
307
67
|
```
|
|
308
68
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
**Lista de selección única:**
|
|
312
|
-
|
|
313
|
-
```ts
|
|
314
|
-
await sock.sendMessage(jid, {
|
|
315
|
-
description: 'Elegí un producto del catálogo',
|
|
316
|
-
title: 'Catálogo',
|
|
317
|
-
buttonText: 'Ver opciones',
|
|
318
|
-
footer: 'ASTA-BOTS',
|
|
319
|
-
sections: [
|
|
320
|
-
{
|
|
321
|
-
title: 'Sección 1',
|
|
322
|
-
rows: [
|
|
323
|
-
{ title: 'Producto A', rowId: 'a' },
|
|
324
|
-
{ title: 'Producto B', rowId: 'b' }
|
|
325
|
-
]
|
|
326
|
-
}
|
|
327
|
-
]
|
|
328
|
-
})
|
|
329
|
-
```
|
|
69
|
+
Repositorio: [github.com/Fer2809fl/Baileys](https://github.com/Fer2809fl/Baileys)
|
|
70
|
+
Paquete npm: [npmjs.com/package/@fer2809fl/baileys](https://www.npmjs.com/package/@fer2809fl/baileys)
|
|
330
71
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
```ts
|
|
334
|
-
await sock.sendMessage(jid, {
|
|
335
|
-
text: 'Confirmá tu pedido',
|
|
336
|
-
templateButtons: [
|
|
337
|
-
{ text: 'Sí', id: 'yes' },
|
|
338
|
-
{ text: 'Visitar', url: 'https://ejemplo.com' },
|
|
339
|
-
{ text: 'Llamar', call: '+50488888888' }
|
|
340
|
-
]
|
|
341
|
-
})
|
|
342
|
-
```
|
|
72
|
+
---
|
|
343
73
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
```ts
|
|
347
|
-
await sock.sendMessage(jid, {
|
|
348
|
-
image: { url: 'https://ejemplo.com/foto.jpg' },
|
|
349
|
-
caption: 'Mirá esto',
|
|
350
|
-
title: 'Título',
|
|
351
|
-
subtitle: 'Subtítulo',
|
|
352
|
-
footer: 'ASTA-BOTS',
|
|
353
|
-
nativeFlow: [
|
|
354
|
-
{ text: 'Ver más', url: 'https://ejemplo.com' }
|
|
355
|
-
]
|
|
356
|
-
})
|
|
357
|
-
```
|
|
74
|
+
## ⚡ Inicio Rápido
|
|
358
75
|
|
|
359
|
-
|
|
76
|
+
```javascript
|
|
77
|
+
const { makeWASocket, useMultiFileAuthState } = require('@fer2809fl/baileys')
|
|
360
78
|
|
|
361
|
-
|
|
362
|
-
await
|
|
363
|
-
cards: [
|
|
364
|
-
{ image: { url: 'https://ejemplo.com/1.jpg' }, caption: 'Carta 1', nativeFlow: [{ text: 'Comprar', id: 'buy_1' }] },
|
|
365
|
-
{ image: { url: 'https://ejemplo.com/2.jpg' }, caption: 'Carta 2', nativeFlow: [{ text: 'Comprar', id: 'buy_2' }] }
|
|
366
|
-
]
|
|
367
|
-
})
|
|
368
|
-
```
|
|
79
|
+
async function startBot() {
|
|
80
|
+
const { state, saveCreds } = await useMultiFileAuthState('session-mymelody')
|
|
369
81
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|---|---|
|
|
376
|
-
| `{ requestPaymentMessage: {...} }` | Pedido de pago, con nota de texto o sticker adjunto opcional. |
|
|
377
|
-
| `{ productMessage: {...} }` | Card de un producto individual (imagen, precio, descripción). |
|
|
378
|
-
| `{ interactiveButtons: [...] }` | Botones declarativos con header de imagen/video/documento/ubicación/producto. |
|
|
379
|
-
| `{ interactiveMessage: {...} }` | Interactive message armado a mano (media header + botones nativos propios). |
|
|
380
|
-
| `{ interactiveMessage: { carouselMessage: {...} } }` | Carousel armado a mano, con cards en formato de proto crudo. |
|
|
381
|
-
| `{ albumMessage: [...] }` o `{ album: [...] }` | Álbum: manda el contenedor y después cada foto/video asociado. |
|
|
382
|
-
| `{ eventMessage: {...} }` | Evento de WhatsApp (nombre, descripción, fecha, ubicación, link para unirse). |
|
|
383
|
-
| `{ pollResultMessage: {...} }` | Snapshot de resultados de una encuesta. |
|
|
384
|
-
| `{ groupStatusMessage: {...} }` | Historia visible solo para un grupo puntual (distinto al estado normal). |
|
|
385
|
-
|
|
386
|
-
Ejemplo de pedido de pago:
|
|
387
|
-
|
|
388
|
-
```ts
|
|
389
|
-
await sock.sendMessage(jid, {
|
|
390
|
-
requestPaymentMessage: {
|
|
391
|
-
amount: 50000, // en la unidad mínima de la moneda (ej. centavos)
|
|
392
|
-
currency: 'USD',
|
|
393
|
-
from: '0@s.whatsapp.net',
|
|
394
|
-
note: 'Pago por el servicio de este mes'
|
|
395
|
-
}
|
|
396
|
-
})
|
|
397
|
-
```
|
|
82
|
+
const melody = makeWASocket({
|
|
83
|
+
auth: state,
|
|
84
|
+
printQRInTerminal: true,
|
|
85
|
+
generateHighQualityLinkPreview: true // recomendado para que las previews se vean mejor
|
|
86
|
+
})
|
|
398
87
|
|
|
399
|
-
|
|
88
|
+
melody.ev.on('connection.update', ({ connection }) => {
|
|
89
|
+
if (connection === 'open') console.log('✅ ¡Conectado con éxito!')
|
|
90
|
+
if (connection === 'close') console.log('❌ Conexión cerrada, reconectando...')
|
|
91
|
+
})
|
|
400
92
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
{ image: { url: './foto1.jpg' } },
|
|
405
|
-
{ image: { url: './foto2.jpg' } },
|
|
406
|
-
{ video: { url: './video1.mp4' } }
|
|
407
|
-
]
|
|
408
|
-
})
|
|
409
|
-
```
|
|
93
|
+
melody.ev.on('messages.upsert', async ({ messages }) => {
|
|
94
|
+
const m = messages[0]
|
|
95
|
+
if (!m.message) return
|
|
410
96
|
|
|
411
|
-
|
|
97
|
+
await melody.sendMessage(m.key.remoteJid, {
|
|
98
|
+
text: '¡Hola! Soy un bot de Delta!'
|
|
99
|
+
})
|
|
100
|
+
})
|
|
412
101
|
|
|
413
|
-
|
|
102
|
+
melody.ev.on('creds.update', saveCreds)
|
|
103
|
+
}
|
|
414
104
|
|
|
415
|
-
|
|
416
|
-
await sock.sendMessage(jid, {
|
|
417
|
-
raw: true,
|
|
418
|
-
extendedTextMessage: { text: 'Mensaje armado a mano' }
|
|
419
|
-
})
|
|
105
|
+
startBot()
|
|
420
106
|
```
|
|
421
107
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
### Editar, eliminar, reenviar y fijar
|
|
425
|
-
|
|
426
|
-
```ts
|
|
427
|
-
// Editar un mensaje ya enviado
|
|
428
|
-
await sock.sendMessage(jid, { text: 'Texto corregido', edit: mensajeAnterior.key })
|
|
429
|
-
|
|
430
|
-
// Eliminar (para todos)
|
|
431
|
-
await sock.sendMessage(jid, { delete: mensaje.key })
|
|
108
|
+
---
|
|
432
109
|
|
|
433
|
-
|
|
434
|
-
await sock.sendMessage(jid, { forward: mensajeOriginal })
|
|
110
|
+
## 🔘 Botones Interactivos *(actualizado en v1.9.0)*
|
|
435
111
|
|
|
436
|
-
|
|
437
|
-
await sock.sendMessage(jid, { pin: mensaje.key, type: 1, time: 86400 })
|
|
438
|
-
```
|
|
112
|
+
A diferencia de otras librerías, acá **no se importan funciones sueltas**: los botones son métodos que ya están directamente en el socket que devuelve `makeWASocket`. Solo llamalos desde `sock` (o como hayas nombrado tu conexión, `melody` en los ejemplos).
|
|
439
113
|
|
|
440
|
-
|
|
114
|
+
Todos aceptan al final un objeto `extra` opcional (`footer`, `image`, `video`, `document`, `quoted`) y uno de `options` para lo que ya soporta `sendMessage` normalmente.
|
|
441
115
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
**`sendTable`** — envía una tabla con encabezados y filas:
|
|
116
|
+
---
|
|
445
117
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
118
|
+
### ⚡ `sendQuickReplyButtons` — Botones de Respuesta Rápida
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
await melody.sendQuickReplyButtons(
|
|
122
|
+
jid,
|
|
123
|
+
'🎮 *MENÚ DE OPCIONES*\n\n¿Qué deseas hacer?',
|
|
124
|
+
[
|
|
125
|
+
{ id: 'menu', text: '📋 Ver Menú' },
|
|
126
|
+
{ id: 'info', text: 'ℹ️ Información' },
|
|
127
|
+
{ id: 'owner', text: '👑 Owner' }
|
|
128
|
+
]
|
|
454
129
|
)
|
|
455
130
|
```
|
|
456
131
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
```ts
|
|
460
|
-
await sock.sendList(jid, 'Tareas pendientes', ['Comprar pan', 'Enviar reporte', 'Llamar al cliente'])
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
> No confundir con la lista de selección de WhatsApp (`sections`) explicada en [Botones, listas, templates y carousel](#botones-listas-templates-y-carousel) — `sendList` arma un mensaje enriquecido de solo lectura, no una lista interactiva con opciones seleccionables.
|
|
464
|
-
|
|
465
|
-
**`sendCodeBlock`** — envía código con resaltado de sintaxis (soporta `javascript`, `typescript`, `python`, entre otros):
|
|
466
|
-
|
|
467
|
-
```ts
|
|
468
|
-
await sock.sendCodeBlock(jid, 'console.log("Hola mundo")', undefined, { language: 'javascript', title: 'Ejemplo' })
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
**`sendLatex`** — envía una o más expresiones matemáticas en formato LaTeX:
|
|
132
|
+
---
|
|
472
133
|
|
|
473
|
-
|
|
474
|
-
await sock.sendLatex(jid, undefined, {
|
|
475
|
-
text: 'La fórmula cuadrática es:',
|
|
476
|
-
expressions: [{ latexExpression: 'x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}' }]
|
|
477
|
-
})
|
|
478
|
-
```
|
|
134
|
+
### 🔗 `sendUrlButton` — Botón URL (con previsualización automática)
|
|
479
135
|
|
|
480
|
-
|
|
136
|
+
Genera solo la tarjeta de previsualización (imagen, título, descripción) del link del botón.
|
|
481
137
|
|
|
482
|
-
```
|
|
483
|
-
await
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
138
|
+
```javascript
|
|
139
|
+
await melody.sendUrlButton(
|
|
140
|
+
jid,
|
|
141
|
+
'🔗 *ENLACES IMPORTANTES*\n\nVisita nuestro repositorio oficial:',
|
|
142
|
+
'🌐 Ver GitHub', // etiqueta del botón
|
|
143
|
+
'https://github.com/Fer2809fl/Baileys' // URL de destino
|
|
144
|
+
)
|
|
487
145
|
```
|
|
488
146
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
```ts
|
|
492
|
-
const capturado = sock.captureUnifiedResponse(mensajeRecibido.message)
|
|
493
|
-
if (capturado) {
|
|
494
|
-
await sock.sendUnifiedResponse(otroJid, undefined, capturado)
|
|
495
|
-
}
|
|
496
|
-
```
|
|
147
|
+
---
|
|
497
148
|
|
|
498
|
-
|
|
149
|
+
### 📞 `sendCallButton` — Botón de Llamada
|
|
499
150
|
|
|
500
|
-
```
|
|
501
|
-
await
|
|
151
|
+
```javascript
|
|
152
|
+
await melody.sendCallButton(
|
|
153
|
+
jid,
|
|
154
|
+
'📞 *SOPORTE TÉCNICO*\n\n¿Necesitas ayuda? Llámanos:',
|
|
155
|
+
'📞 Llamar Ahora', // etiqueta del botón
|
|
156
|
+
'+5214183357841' // número de teléfono
|
|
157
|
+
)
|
|
502
158
|
```
|
|
503
159
|
|
|
504
|
-
|
|
160
|
+
---
|
|
505
161
|
|
|
506
|
-
|
|
162
|
+
### 📋 `sendCopyButton` — Botón Copiar
|
|
507
163
|
|
|
508
|
-
```
|
|
509
|
-
await
|
|
164
|
+
```javascript
|
|
165
|
+
await melody.sendCopyButton(
|
|
166
|
+
jid,
|
|
167
|
+
'📋 *CÓDIGO DE INSTALACIÓN*\n\nEjecuta este comando en tu terminal:',
|
|
168
|
+
'📋 Copiar Comando', // etiqueta del botón
|
|
169
|
+
'npm install asta-bot' // texto que se copiará
|
|
170
|
+
)
|
|
510
171
|
```
|
|
511
172
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
### Estados (historias)
|
|
173
|
+
---
|
|
515
174
|
|
|
516
|
-
|
|
175
|
+
### ⏰ `sendReminderButton` — Botón de Recordatorio
|
|
517
176
|
|
|
518
|
-
```
|
|
519
|
-
await
|
|
520
|
-
|
|
521
|
-
|
|
177
|
+
```javascript
|
|
178
|
+
await melody.sendReminderButton(
|
|
179
|
+
jid,
|
|
180
|
+
'⏰ *RECORDATORIO*\n\nActiva un aviso para no olvidarlo:',
|
|
181
|
+
'⏰ Recordarme'
|
|
522
182
|
)
|
|
523
183
|
```
|
|
524
184
|
|
|
525
|
-
|
|
526
|
-
- Si se pasa un JID de **grupo**, el grupo entero recibe una única notificación de mención de estado a nivel de grupo (no se le manda una notificación repetida a cada miembro por separado).
|
|
527
|
-
- Si no se pasa ningún JID, el estado no se publica ya que requiere pasar las menciones necesarias.
|
|
528
|
-
- Para contenido multimedia (imagen, video, audio) en el estado, se pueden combinar los mismos campos que en `sendMessage` (`image`, `video`, `audio`), y ASTA-BOTS ajusta automáticamente el color de fondo y la fuente cuando corresponde.
|
|
529
|
-
|
|
530
|
-
### Recibos, lectura y presencia
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
```ts
|
|
534
|
-
// Marcar mensajes como leídos (doble check azul)
|
|
535
|
-
await sock.readMessages([mensaje.key])
|
|
536
|
-
|
|
537
|
-
// Enviar un recibo manualmente
|
|
538
|
-
await sock.sendReceipt(jid, participante, [id], 'read')
|
|
539
|
-
|
|
540
|
-
// Actualizar presencia (escribiendo, grabando audio, en línea)
|
|
541
|
-
await sock.sendPresenceUpdate('composing', jid) // 'available' | 'unavailable' | 'composing' | 'recording' | 'paused'
|
|
185
|
+
---
|
|
542
186
|
|
|
543
|
-
|
|
544
|
-
|
|
187
|
+
### 📋 `sendListButton` — Menú Desplegable (Lista)
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
await melody.sendListButton(
|
|
191
|
+
jid,
|
|
192
|
+
'📋 *SELECCIONA UNA OPCIÓN*',
|
|
193
|
+
'Menú Principal', // título del botón que abre la lista
|
|
194
|
+
[
|
|
195
|
+
{
|
|
196
|
+
title: '📱 COMANDOS BÁSICOS',
|
|
197
|
+
rows: [
|
|
198
|
+
{ id: '#menu', title: '📋 Menú', description: 'Ver todos los comandos' },
|
|
199
|
+
{ id: '#ping', title: '🏓 Ping', description: 'Ver latencia del bot' },
|
|
200
|
+
{ id: '#owner', title: '👑 Owner', description: 'Info del creador' }
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
title: '🎮 COMANDOS DE GRUPO',
|
|
205
|
+
rows: [
|
|
206
|
+
{ id: '#add', title: '➕ Agregar', description: 'Agregar usuario al grupo' },
|
|
207
|
+
{ id: '#kick', title: '👢 Expulsar', description: 'Expulsar usuario del grupo' },
|
|
208
|
+
{ id: '#promote', title: '⭐ Promover', description: 'Dar admin a un usuario' }
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
)
|
|
545
213
|
```
|
|
546
214
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
ASTA-BOTS conserva toda la funcionalidad estándar de Baileys para administrar grupos, comunidades (grupos con subgrupos) y canales de difusión (newsletters):
|
|
215
|
+
---
|
|
550
216
|
|
|
551
|
-
|
|
552
|
-
await sock.groupCreate('Mi grupo', [jid1, jid2])
|
|
553
|
-
await sock.groupParticipantsUpdate(jid, [participante], 'add') // 'add' | 'remove' | 'promote' | 'demote'
|
|
554
|
-
await sock.groupInviteCode(jid)
|
|
217
|
+
### 🎯 `sendMixedButtons` — Múltiples Botones Combinados
|
|
555
218
|
|
|
556
|
-
|
|
219
|
+
Para armar cualquier combinación libre de tipos (o alguno que no tenga método propio) en un solo mensaje.
|
|
557
220
|
|
|
558
|
-
|
|
221
|
+
```javascript
|
|
222
|
+
await melody.sendMixedButtons(
|
|
223
|
+
jid,
|
|
224
|
+
'🎯 *PANEL DE CONTROL*\n\nSelecciona una acción rápida:',
|
|
225
|
+
[
|
|
226
|
+
{ name: 'cta_url', params: { display_text: '🌐 GitHub', url: 'https://github.com/Fer2809fl/Baileys', merchant_url: 'https://github.com/Fer2809fl/Baileys' } },
|
|
227
|
+
{ name: 'cta_copy', params: { display_text: '📋 Comando Inicio', copy_code: 'npm start' } },
|
|
228
|
+
{ name: 'quick_reply', params: { display_text: '📋 Ver Menú', id: 'menu' } }
|
|
229
|
+
]
|
|
230
|
+
)
|
|
559
231
|
```
|
|
560
232
|
|
|
561
|
-
|
|
233
|
+
---
|
|
562
234
|
|
|
563
|
-
|
|
564
|
-
await sock.updateProfileName('Mi Bot')
|
|
565
|
-
await sock.updateProfileStatus('Disponible 24/7')
|
|
566
|
-
await sock.updateProfilePicture(jid, { url: './avatar.jpg' })
|
|
235
|
+
## 🖼️ Previsualización de Links *(nuevo en v1.9.0)*
|
|
567
236
|
|
|
568
|
-
|
|
237
|
+
`sendLinkPreview` manda solo texto + una tarjeta grande y prolija con la imagen, título y descripción de cualquier URL — igual que un mensaje normal de WhatsApp con link, pero forzando `renderLargerThumbnail` para que se vea mejor. Sirve para links a fotos, artículos, redes sociales, lo que sea.
|
|
569
238
|
|
|
570
|
-
|
|
571
|
-
await
|
|
572
|
-
|
|
239
|
+
```javascript
|
|
240
|
+
await melody.sendLinkPreview(
|
|
241
|
+
jid,
|
|
242
|
+
'¡Mirá esto! 👀',
|
|
243
|
+
'https://github.com/Fer2809fl/Baileys'
|
|
244
|
+
)
|
|
573
245
|
```
|
|
574
246
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
El **Store** es un caché en memoria de chats, contactos, mensajes y metadata de grupos, que se va llenando solo a medida que van llegando eventos (`sock.ev`). El Baileys oficial más reciente **eliminó este módulo** de la librería; en ASTA-BOTS se mantiene disponible porque resuelve un problema muy común al hacer un bot: no depender de volver a pedirle todo a WhatsApp (mensaje anterior, foto de perfil, metadata de un grupo) cada vez que se necesita.
|
|
578
|
-
|
|
579
|
-
### ¿Cuándo conviene usarlo?
|
|
580
|
-
|
|
581
|
-
- Si tu bot necesita **buscar mensajes anteriores** (por ejemplo, para citar o reenviar algo que no tenés a mano).
|
|
582
|
-
- Si querés **listar los chats o contactos** sin tener que reconstruirlos manualmente desde los eventos.
|
|
583
|
-
- Si hacés muchas consultas de `groupMetadata` o `profilePictureUrl` y no querés golpear la API de WhatsApp cada vez.
|
|
584
|
-
|
|
585
|
-
Si tu bot es simple y solo responde a mensajes entrantes sin necesitar historial, podés omitirlo sin problema; el store consume RAM porque guarda todo en memoria.
|
|
586
|
-
|
|
587
|
-
### Uso
|
|
247
|
+
Si el texto ya trae el link adentro, no hace falta pasarlo aparte:
|
|
588
248
|
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
const { state, saveCreds } = await useMultiFileAuthState('sesion')
|
|
596
|
-
const sock = makeWASocket({ auth: state })
|
|
597
|
-
|
|
598
|
-
store.bind(sock.ev) // conecta el store a todos los eventos del socket
|
|
599
|
-
|
|
600
|
-
sock.ev.on('creds.update', saveCreds)
|
|
601
|
-
|
|
602
|
-
// Guardar el store a disco cada cierto tiempo
|
|
603
|
-
setInterval(() => {
|
|
604
|
-
store.writeToFile('./store.json')
|
|
605
|
-
}, 10_000)
|
|
606
|
-
|
|
607
|
-
// Ejemplos de consulta
|
|
608
|
-
const chats = store.chats.all()
|
|
609
|
-
const contacto = store.contacts['5215512345678@s.whatsapp.net']
|
|
610
|
-
const mensaje = await store.loadMessage(jid, mensajeId)
|
|
249
|
+
```javascript
|
|
250
|
+
await melody.sendLinkPreview(
|
|
251
|
+
jid,
|
|
252
|
+
'Repo oficial: https://github.com/Fer2809fl/Baileys'
|
|
253
|
+
)
|
|
611
254
|
```
|
|
612
255
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
Estas utilidades son propias de **ASTA-BOTS** y no existen en el Baileys original: nacieron para resolver lo más repetitivo al armar un bot de comandos.
|
|
616
|
-
|
|
617
|
-
### `resolveJid`: resolución automática de JID
|
|
256
|
+
Esta misma previsualización se activa automáticamente en `sendUrlButton` y en cualquier otro botón si el texto trae un link. Para desactivarla en un envío puntual:
|
|
618
257
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
```ts
|
|
622
|
-
import { resolveJid } from 'baileys'
|
|
623
|
-
|
|
624
|
-
// .ban (respondiendo a alguien) → toma el citado
|
|
625
|
-
// .ban @usuario → toma la mención
|
|
626
|
-
// .ban 5216141234567 → toma el argumento
|
|
627
|
-
// .ban → cae al remitente
|
|
628
|
-
const targetJid = resolveJid(m, args[0])
|
|
258
|
+
```javascript
|
|
259
|
+
await melody.sendUrlButton(jid, texto, '🌐 Ver más', url, { preview: false })
|
|
629
260
|
```
|
|
630
261
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
Además del soporte nativo de `sock.sendMessage` (ver [Botones, listas, templates y carousel](#botones-listas-templates-y-carousel)), ASTA-BOTS trae funciones listas para usar cuando querés algo rápido sin armar el objeto del mensaje:
|
|
262
|
+
---
|
|
634
263
|
|
|
635
|
-
|
|
636
|
-
import { sendQuickReplyButtons, setupButtonHandler } from 'baileys'
|
|
264
|
+
### Plugin de ejemplo completo
|
|
637
265
|
|
|
638
|
-
|
|
639
|
-
|
|
266
|
+
```javascript
|
|
267
|
+
// plugins/botones.js
|
|
268
|
+
let handler = async (m, { conn, usedPrefix }) => {
|
|
640
269
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
270
|
+
if (m.text === `${usedPrefix}boton1`) {
|
|
271
|
+
await conn.sendCopyButton(m.chat,
|
|
272
|
+
'📋 *CÓDIGO DE INSTALACIÓN*\n\nEjecuta este comando en tu terminal:',
|
|
273
|
+
'📋 Copiar Comando',
|
|
274
|
+
'npm install asta-bot'
|
|
275
|
+
)
|
|
276
|
+
}
|
|
646
277
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
| `sendInteractiveMessage` | Combinación de varios tipos de botón |
|
|
655
|
-
| `handleButtonResponse` | Detecta y ejecuta el comando de un botón presionado |
|
|
656
|
-
| `setupButtonHandler` | Engancha el detector de botones al socket sin pisar tu handler de mensajes |
|
|
278
|
+
else if (m.text === `${usedPrefix}boton2`) {
|
|
279
|
+
await conn.sendUrlButton(m.chat,
|
|
280
|
+
'🔗 *ENLACES IMPORTANTES*\n\nVisita nuestro repositorio oficial:',
|
|
281
|
+
'🌐 Ver GitHub',
|
|
282
|
+
'https://github.com/Fer2809fl/Baileys'
|
|
283
|
+
)
|
|
284
|
+
}
|
|
657
285
|
|
|
658
|
-
|
|
286
|
+
else if (m.text === `${usedPrefix}boton3`) {
|
|
287
|
+
await conn.sendQuickReplyButtons(m.chat,
|
|
288
|
+
'🎮 *MENÚ DE OPCIONES*\n\n¿Qué deseas hacer?',
|
|
289
|
+
[
|
|
290
|
+
{ id: 'menu', text: '📋 Ver Menú' },
|
|
291
|
+
{ id: 'info', text: 'ℹ️ Información' },
|
|
292
|
+
{ id: 'owner', text: '👑 Owner' }
|
|
293
|
+
]
|
|
294
|
+
)
|
|
295
|
+
}
|
|
659
296
|
|
|
660
|
-
|
|
297
|
+
else if (m.text === `${usedPrefix}boton4`) {
|
|
298
|
+
await conn.sendCallButton(m.chat,
|
|
299
|
+
'📞 *SOPORTE TÉCNICO*\n\n¿Necesitas ayuda? Llámanos:',
|
|
300
|
+
'📞 Llamar Ahora',
|
|
301
|
+
'+5214183357841'
|
|
302
|
+
)
|
|
303
|
+
}
|
|
661
304
|
|
|
662
|
-
|
|
305
|
+
else if (m.text === `${usedPrefix}boton5`) {
|
|
306
|
+
await conn.sendListButton(m.chat,
|
|
307
|
+
'📋 *SELECCIONA UNA OPCIÓN*',
|
|
308
|
+
'Menú Principal',
|
|
309
|
+
[
|
|
310
|
+
{
|
|
311
|
+
title: '📱 COMANDOS BÁSICOS',
|
|
312
|
+
rows: [
|
|
313
|
+
{ id: '#menu', title: '📋 Menú', description: 'Ver todos los comandos' },
|
|
314
|
+
{ id: '#ping', title: '🏓 Ping', description: 'Ver latencia del bot' }
|
|
315
|
+
]
|
|
316
|
+
}
|
|
317
|
+
]
|
|
318
|
+
)
|
|
319
|
+
}
|
|
663
320
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
321
|
+
else if (m.text === `${usedPrefix}boton6`) {
|
|
322
|
+
await conn.sendLinkPreview(m.chat,
|
|
323
|
+
'¡Mirá el repo! 👀',
|
|
324
|
+
'https://github.com/Fer2809fl/Baileys'
|
|
325
|
+
)
|
|
326
|
+
}
|
|
327
|
+
}
|
|
667
328
|
|
|
668
|
-
|
|
669
|
-
|
|
329
|
+
handler.command = ['boton1', 'boton2', 'boton3', 'boton4', 'boton5', 'boton6']
|
|
330
|
+
export default handler
|
|
670
331
|
```
|
|
671
332
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
Este proyecto no está afiliado, asociado, autorizado ni respaldado de ninguna forma por WhatsApp Inc. ni por Meta. "WhatsApp" y las marcas relacionadas son propiedad de sus respectivos dueños.
|
|
675
|
-
|
|
676
|
-
El uso de esta librería es responsabilidad exclusiva de quien la implementa. Se recomienda no usarla para spam, mensajería masiva no solicitada ni cualquier práctica que viole los Términos de Servicio de WhatsApp.
|
|
677
|
-
|
|
678
|
-
## Créditos
|
|
333
|
+
---
|
|
679
334
|
|
|
680
|
-
|
|
335
|
+
## ✨ Características
|
|
681
336
|
|
|
682
|
-
|
|
683
|
-
-
|
|
337
|
+
### General
|
|
338
|
+
- 🚀 Optimizado para mayor velocidad y estabilidad
|
|
339
|
+
- 📸 Mensajes multimedia (imágenes, video, audio, documentos)
|
|
340
|
+
- 🔘 **Botones nativos reales, sin imports sueltos** *(v1.9.0)*
|
|
341
|
+
- 🖼️ **Previsualización automática de links en botones y mensajes** *(v1.9.0)*
|
|
342
|
+
- 👥 Soporte para grupos y chats privados
|
|
684
343
|
|
|
685
|
-
|
|
344
|
+
### Técnicas
|
|
345
|
+
- ⚡ Sin Selenium — Conexión directa vía WebSocket
|
|
346
|
+
- 💾 Super eficiente — Bajo consumo de RAM
|
|
347
|
+
- 📱 Soporte multi-dispositivo — Compatible con WhatsApp Web
|
|
348
|
+
- 🔷 Totalmente tipado — TypeScript y JavaScript
|
|
349
|
+
- 🔄 Reconexión automática ante desconexiones
|
|
350
|
+
- 🔐 Sesiones persistentes guardadas localmente
|
|
351
|
+
- 🍎 Compatible con macOS
|
|
686
352
|
|
|
687
353
|
---
|
|
688
354
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
## créditos
|
|
692
|
-
|
|
693
|
-
this-xys/bails
|
|
355
|
+
## 📖 Enlaces
|
|
694
356
|
|
|
357
|
+
- Repositorio: [https://github.com/Fer2809fl/Baileys](https://github.com/Fer2809fl/Baileys)
|
|
358
|
+
- Paquete npm: [https://www.npmjs.com/package/@fer2809fl/baileys](https://www.npmjs.com/package/@fer2809fl/baileys)
|