@arcaelas/whatsapp 1.0.21 → 1.2.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.
Files changed (50) hide show
  1. package/API.md +776 -0
  2. package/DOC.md +532 -0
  3. package/build/Chat.d.ts +335 -0
  4. package/build/Chat.js +396 -0
  5. package/build/Chat.js.map +1 -0
  6. package/build/Contact.d.ts +828 -0
  7. package/build/Contact.js +188 -0
  8. package/build/Contact.js.map +1 -0
  9. package/build/Message.d.ts +525 -0
  10. package/build/Message.js +445 -0
  11. package/build/Message.js.map +1 -0
  12. package/build/WhatsApp.d.ts +68 -0
  13. package/build/WhatsApp.js +399 -0
  14. package/build/WhatsApp.js.map +1 -0
  15. package/build/index.d.ts +11 -107
  16. package/build/index.js +1 -1
  17. package/build/index.js.map +3 -3
  18. package/build/store/driver/FileEngine.d.ts +23 -0
  19. package/build/store/driver/FileEngine.js +90 -0
  20. package/build/store/driver/FileEngine.js.map +1 -0
  21. package/build/store/driver/RedisEngine.d.ts +38 -0
  22. package/build/store/driver/RedisEngine.js +69 -0
  23. package/build/store/driver/RedisEngine.js.map +1 -0
  24. package/build/store/engine.d.ts +54 -0
  25. package/build/store/engine.js +7 -0
  26. package/build/store/engine.js.map +1 -0
  27. package/build/store/index.d.ts +8 -0
  28. package/build/store/index.js +12 -0
  29. package/build/store/index.js.map +1 -0
  30. package/context7.json +4 -0
  31. package/package.json +59 -52
  32. package/tsconfig.json +25 -25
  33. package/build/model/base.d.ts +0 -28
  34. package/build/model/base.js +0 -65
  35. package/build/model/base.js.map +0 -1
  36. package/build/model/chat.d.ts +0 -112
  37. package/build/model/chat.js +0 -105
  38. package/build/model/chat.js.map +0 -1
  39. package/build/model/contact.d.ts +0 -16
  40. package/build/model/contact.js +0 -22
  41. package/build/model/contact.js.map +0 -1
  42. package/build/model/message.d.ts +0 -159
  43. package/build/model/message.js +0 -206
  44. package/build/model/message.js.map +0 -1
  45. package/build/static/Store.d.ts +0 -137
  46. package/build/static/Store.js +0 -238
  47. package/build/static/Store.js.map +0 -1
  48. package/build/static/useCache.d.ts +0 -12
  49. package/build/static/useCache.js +0 -43
  50. package/build/static/useCache.js.map +0 -1
package/DOC.md ADDED
@@ -0,0 +1,532 @@
1
+ # @arcaelas/whatsapp
2
+
3
+ Libreria para crear clientes de WhatsApp utilizando Baileys como proveedor WebSocket.
4
+
5
+ ---
6
+
7
+ ## Flujo de Uso
8
+
9
+ El ciclo de vida de una conexion WhatsApp sigue 4 pasos bien definidos:
10
+
11
+ ### 1. Inicializacion
12
+
13
+ ```typescript
14
+ const wa = new WhatsApp({ phone: "56962816490" })
15
+ ```
16
+
17
+ El constructor prepara toda la configuracion interna: el store, los factories de entidades (Contact, Chat, Message) y se suscribe a sus propios eventos (`this.on(...)`) para persistir automaticamente. **En este punto no hay conexion a WhatsApp ni contacto con Baileys.**
18
+
19
+ ### 2. Conexion
20
+
21
+ ```typescript
22
+ await wa.pair(code => console.log("Ingresa el codigo: %s", code))
23
+ ```
24
+
25
+ El metodo `pair()` establece la conexion con WhatsApp. Si es primera vez, ejecuta el callback con el codigo de emparejamiento que el usuario debe ingresar en su telefono. Si ya existe una sesion valida, el callback nunca se ejecuta. **La promesa se resuelve cuando la conexion esta establecida.**
26
+
27
+ ### 3. Listo para usar
28
+
29
+ ```typescript
30
+ console.log("Conectado!")
31
+ // Ya puedes usar wa.on("message"), wa.Chat.text(), etc.
32
+ ```
33
+
34
+ Una vez que `pair()` resuelve, la instancia esta operativa. Puedes enviar mensajes, recibir eventos, y acceder a datos. Los mensajes entrantes comienzan a llegar inmediatamente.
35
+
36
+ ### 4. Sincronizacion (opcional)
37
+
38
+ ```typescript
39
+ await wa.sync(percent => console.log("Sincronizacion al %s%", percent))
40
+ ```
41
+
42
+ Internamente, WhatsApp **siempre** sincroniza el historial y emite eventos `progress`. El metodo `sync()` simplemente espera hasta que esa sincronizacion termine (100%). Es util si necesitas garantizar que todos los contactos, chats y mensajes historicos esten disponibles antes de continuar.
43
+
44
+ ### Resumen
45
+
46
+ | Metodo | Proposito | Obligatorio |
47
+ |--------|-----------|-------------|
48
+ | `new WhatsApp()` | Configurar la instancia | Si |
49
+ | `pair()` | Conectar a WhatsApp | Si |
50
+ | `sync()` | Esperar historial completo | No |
51
+
52
+ La separacion entre `pair()` y `sync()` permite que puedas empezar a recibir mensajes en tiempo real inmediatamente despues de conectar, sin esperar a que se descargue todo el historial.
53
+
54
+ ---
55
+
56
+ ## Eventos
57
+
58
+ La clase `WhatsApp` extiende `EventEmitter<EventMap>`, por lo que los eventos se manejan directamente en la instancia. Puedes suscribirte **antes o despues** de `pair()`, es indiferente porque usa un EventEmitter propio, no el socket de Baileys.
59
+
60
+ ### Eventos disponibles
61
+
62
+ | Evento | Payload | Descripcion |
63
+ |--------|---------|-------------|
64
+ | `open` | `void` | Conexion establecida. Usado internamente por `pair()` |
65
+ | `close` | `void` | Desconexion. Util para metricas o reintentos |
66
+ | `progress` | `number` | Progreso de sincronizacion (0-100). Usado internamente por `sync()` |
67
+ | `error` | `Error` | Error de conexion o autenticacion |
68
+ | | | |
69
+ | `contact:upsert` | `Contact` | Contacto nuevo o actualizado |
70
+ | | | |
71
+ | `chat:upsert` | `Chat` | Chat nuevo o actualizado |
72
+ | `chat:deleted` | `string` | ID del chat eliminado |
73
+ | | | |
74
+ | `message:created` | `Message` | Mensaje nuevo |
75
+ | `message:status` | `Message` | Cambio de estado (pending→sent→delivered→read) |
76
+ | `message:updated` | `Message` | Mensaje editado |
77
+ | `message:deleted` | `{ cid: string, mid: string }` | Mensaje eliminado |
78
+ | `message:reaction` | `Message` | Reaccion emoji al mensaje |
79
+
80
+ ### Uso de eventos
81
+
82
+ ```typescript
83
+ const wa = new WhatsApp({ phone: "56962816490" })
84
+
85
+ // Mensajes nuevos
86
+ wa.on("message:created", async (message) => {
87
+ const buffer = await message.content() // Siempre retorna Buffer
88
+
89
+ if (message.mime === "text/plain") {
90
+ const text = buffer.toString("utf-8")
91
+ console.log("Texto:", text)
92
+ } else if (message.mime === "application/json") {
93
+ const data = JSON.parse(buffer.toString())
94
+ console.log("JSON:", data) // location: {lat, lng}, poll: {content, items}
95
+ } else {
96
+ console.log("Media:", buffer.length, "bytes") // image/*, video/*, audio/*
97
+ }
98
+ })
99
+
100
+ // Cambios de estado del mensaje
101
+ wa.on("message:status", (message) => {
102
+ console.log(`Mensaje ${message.id}: ${message.status}`) // pending, sent, delivered, read
103
+ })
104
+
105
+ // Mensaje editado
106
+ wa.on("message:updated", async (message) => {
107
+ const text = (await message.content()).toString()
108
+ console.log("Editado:", text)
109
+ })
110
+
111
+ // Mensaje eliminado
112
+ wa.on("message:deleted", ({ cid, mid }) => {
113
+ console.log(`Eliminado: ${mid} en chat ${cid}`)
114
+ })
115
+
116
+ // Reaccion a mensaje
117
+ wa.on("message:reaction", (message) => {
118
+ console.log("Reaccion en mensaje:", message.id)
119
+ })
120
+
121
+ // Contactos y chats
122
+ wa.on("contact:upsert", (contact) => console.log("Contacto:", contact.name))
123
+ wa.on("chat:upsert", (chat) => console.log("Chat:", chat.name))
124
+ wa.on("chat:deleted", (cid) => console.log("Chat eliminado:", cid))
125
+
126
+ // Progreso de sincronizacion
127
+ wa.on("progress", (percent) => {
128
+ console.log("Sincronizacion:", percent + "%")
129
+ })
130
+
131
+ // Conexion y desconexion
132
+ wa.on("open", () => console.log("Conectado"))
133
+ wa.on("close", () => console.log("Desconectado"))
134
+
135
+ await wa.pair()
136
+ ```
137
+
138
+ ### Arquitectura interna
139
+
140
+ ```
141
+ BAILEYS (socket.ev.on)
142
+
143
+
144
+ pair() ← Unico punto de contacto con Baileys
145
+ │ Recibe eventos Baileys
146
+ │ Transforma → new Contact/Chat/Message(data)
147
+ │ Reemplaza content() con buffer en memoria
148
+ │ Emite → this.emit("event:type", instance)
149
+
150
+ EventEmitter (this)
151
+
152
+ ├── Constructor (listener interno)
153
+ │ this.on("message:created", m => store.message.set(...))
154
+ │ this.on("contact:upsert", c => store.contact.set(...))
155
+ │ this.on("chat:upsert", ch => store.chat.set(...))
156
+
157
+ └── Usuario (listener externo)
158
+ wa.on("message:created", m => console.log(m))
159
+ ```
160
+
161
+ **Flujo de datos:**
162
+ 1. `pair()` recibe eventos de Baileys (`messages.upsert`, `contacts.upsert`, etc.)
163
+ 2. `pair()` transforma los datos a instancias propias (Contact, Chat, Message)
164
+ 3. `pair()` emite con `this.emit()` el evento correspondiente (`:created`, `:upsert`, etc.)
165
+ 4. El constructor (listener interno) persiste automaticamente en el store
166
+ 5. El usuario (listener externo) procesa segun su logica
167
+
168
+ **Ventajas:**
169
+ - `pair()` es el unico metodo que interactua con Baileys
170
+ - El resto de la libreria usa instancias propias, eventos propios
171
+ - El store se actualiza automaticamente via eventos internos
172
+ - El usuario tiene acceso a los mismos eventos sin conocer Baileys
173
+
174
+ **Virtualizacion de content():**
175
+ El metodo `content()` de cada mensaje se reemplaza en runtime con una funcion que retorna el buffer directamente desde memoria. Esto evita ir al store cuando el contenido ya fue descargado por `pair()`.
176
+
177
+ ---
178
+
179
+ ## Class WhatsApp
180
+
181
+ Clase principal para gestionar la conexion y comunicacion con WhatsApp.
182
+
183
+ ##### Opciones de Configuracion
184
+
185
+ | Propiedad | Tipo | Default | Descripcion |
186
+ |-----------|------|---------|-------------|
187
+ | `phone` | `string` | - | Numero con prefijo de pais, ej: `5491155555555` (requerido para auth por codigo) |
188
+ | `engine` | `Engine` | `FileStore` | Engine de persistencia para credenciales. Por defecto usa FileStore en `.baileys/{phone}/` |
189
+
190
+ **Modo de autenticacion:** Si `phone` esta presente -> codigo. Si no -> QR.
191
+
192
+ ##### Retorno del Constructor
193
+
194
+ | Propiedad | Tipo | Default | Descripcion |
195
+ |-----------|------|---------|-------------|
196
+ | `Contact` | `typeof Contact` | - | Clase Contact vinculada a esta instancia |
197
+ | `Chat` | `typeof Chat` | - | Clase Chat vinculada a esta instancia |
198
+ | `Message` | `typeof Message` | - | Clase Message vinculada a esta instancia |
199
+ | `pair` | `(cb?) => Promise<void>` | - | Funcion para completar autenticacion |
200
+ | `sync` | `(cb?) => Promise<void>` | - | Funcion para esperar sincronizacion completa |
201
+ | `on` | `(event, handler) => void` | - | Suscribirse a eventos |
202
+ | `off` | `(event, handler) => void` | - | Desuscribirse de eventos |
203
+
204
+ ##### Funcion pair(callback)
205
+
206
+ | Escenario | Callback param | Ejecucion | Comportamiento |
207
+ |-----------|----------------|-----------|----------------|
208
+ | Sin `phone` (QR) | `Buffer` | Multiples veces | Imagen QR lista para mostrar, se renueva cada ~20s |
209
+ | Con `phone` (Code) | `string` | Una vez | Codigo de 8 caracteres para ingresar en WhatsApp |
210
+ | Sesion existente | - | No se ejecuta | Resuelve inmediatamente sin llamar callback |
211
+
212
+ **Notas:**
213
+ - En modo QR, el Buffer es una imagen PNG del codigo QR.
214
+ - En modo Code, el usuario debe ingresar el codigo en WhatsApp > Dispositivos vinculados > Vincular con numero.
215
+ - Si la autenticacion falla, `pair()` lanza una excepcion.
216
+
217
+ ##### Funcion sync(callback)
218
+
219
+ Bloquea hasta que WhatsApp termine de sincronizar contactos, chats y mensajes.
220
+
221
+ | Escenario | Callback param | Ejecucion | Comportamiento |
222
+ |-----------|----------------|-----------|----------------|
223
+ | Sincronizando | `number` (0-100) | Multiples veces | Progreso de sincronizacion |
224
+ | Sincronizacion completa | `100` | Una vez final | Resuelve la promesa |
225
+
226
+ **Notas:**
227
+ - Llamar despues de `pair()` para esperar sincronizacion completa.
228
+ - El callback es opcional - sin callback solo bloquea hasta completar.
229
+
230
+ ##### Eventos
231
+
232
+ Ver seccion [Eventos](#eventos) para detalles completos.
233
+
234
+ ```typescript
235
+ // Modo QR
236
+ const wa = new WhatsApp()
237
+
238
+ wa.on('open', () => console.log('Conectado'))
239
+ wa.on('contact:upsert', (c) => console.log('Contacto:', c.name))
240
+ wa.on('chat:upsert', (ch) => console.log('Chat:', ch.name))
241
+ wa.on('message:created', (msg) => console.log('Mensaje:', msg.id))
242
+
243
+ await wa.pair((qr: Buffer) => {
244
+ fs.writeFileSync('qr.png', qr)
245
+ })
246
+
247
+ await wa.sync((progress) => {
248
+ console.log(`Sincronizando: ${progress}%`)
249
+ })
250
+ console.log('Sincronizacion completa')
251
+
252
+ // Modo Code
253
+ const wa = new WhatsApp({ phone: '5491155555555' })
254
+
255
+ await wa.pair((code: string) => {
256
+ console.log('Ingresa en WhatsApp:', code)
257
+ })
258
+
259
+ await wa.sync() // Esperar sin callback
260
+ ```
261
+
262
+ ---
263
+
264
+ ## Interface Engine
265
+
266
+ Contrato minimo que cualquier proveedor de persistencia debe implementar.
267
+
268
+ ##### Metodos
269
+
270
+ | Metodo | Argumentos | Retorno | Descripcion |
271
+ |--------|------------|---------|-------------|
272
+ | `get` | `(key, offset?, limit?)` | `Promise<string[]>` | Obtiene documentos por clave o namespace |
273
+ | `set` | `(key, value)` | `Promise<boolean>` | Guarda string, `null` elimina |
274
+
275
+ ##### Comportamiento de get()
276
+
277
+ | Llamada | Resultado |
278
+ |---------|-----------|
279
+ | `get('contact/123')` | Array con 1 item (o vacio) |
280
+ | `get('contact/123', 0, 100)` | Igual - offset/limit no afectan clave exacta |
281
+ | `get('contact', 0, 50)` | Array con contactos paginados |
282
+ | `get('chat/abc/message', 0, 20)` | Array con mensajes del chat |
283
+
284
+ La firma es uniforme. El Engine detecta internamente si es clave exacta o namespace y aplica offset/limit solo cuando corresponde.
285
+
286
+ ##### Ejemplo
287
+
288
+ ```typescript
289
+ class MemoryEngine implements Engine {
290
+ private data = new Map<string, string>()
291
+
292
+ async get(key: string, offset = 0, limit = 50): Promise<string[]> {
293
+ if (this.data.has(key)) return [this.data.get(key)!]
294
+ const items: string[] = []
295
+ for (const [k, v] of this.data) {
296
+ if (k.startsWith(`${key}/`)) items.push(v)
297
+ }
298
+ return items.slice(offset, offset + limit)
299
+ }
300
+
301
+ async set(key: string, value: string | null): Promise<boolean> {
302
+ if (value === null) return this.data.delete(key)
303
+ this.data.set(key, value)
304
+ return true
305
+ }
306
+ }
307
+ ```
308
+
309
+ ---
310
+
311
+ ## Class Store
312
+
313
+ Clase interna que envuelve el Engine y expone metodos tipados para cada entidad.
314
+
315
+ ##### Namespaces
316
+
317
+ Cada namespace almacena strings JSON con las propiedades de la entidad correspondiente.
318
+
319
+ | Namespace | Ruta | Propiedades JSON |
320
+ |-----------|------|------------------|
321
+ | `session` | `session/creds`, `session/signal/{type}/{id}` | Credenciales y claves de sesion Baileys |
322
+ | `contact` | `contact/:id` | `{ id, name, phone, photo, custom_name }` |
323
+ | `chat` | `chat/:id` | `{ id, name, photo, phone, type }` |
324
+ | `message` | `chat/:cid/message/:mid` | `{ id, cid, uid, mid, type, mime, caption, me, status, created_at, edited }` |
325
+ | `content` | `chat/:cid/message/:mid/content` | `Buffer` serializado con BufferJSON |
326
+
327
+ ##### Metodos document
328
+
329
+ | Metodo | Argumentos | Retorno | Descripcion |
330
+ |--------|------------|---------|-------------|
331
+ | `document.get` | `(pathname, offset?, limit?)` | `Promise<T[]>` | Obtiene documentos parseados con BufferJSON |
332
+ | `document.set` | `(pathname, value)` | `Promise<boolean>` | Guarda documento serializado con BufferJSON |
333
+
334
+ ##### Metodos de Entidades
335
+
336
+ | Metodo | Argumentos | Retorno | Descripcion |
337
+ |--------|------------|---------|-------------|
338
+ | `contact.get` | `(id)` | `Promise<IContact \| null>` | Obtiene contacto parseado |
339
+ | `contact.find` | `(offset, limit)` | `Promise<IContact[]>` | Pagina contactos parseados |
340
+ | `contact.set` | `(data)` | `Promise<boolean>` | Guarda contacto |
341
+ | `chat.get` | `(id)` | `Promise<IChat \| null>` | Obtiene chat parseado |
342
+ | `chat.find` | `(offset, limit)` | `Promise<IChat[]>` | Pagina chats parseados |
343
+ | `chat.set` | `(data)` | `Promise<boolean>` | Guarda chat |
344
+ | `message.get` | `(cid, mid)` | `Promise<IMessage \| null>` | Obtiene mensaje parseado |
345
+ | `message.find` | `(cid, offset, limit)` | `Promise<IMessage[]>` | Pagina mensajes parseados |
346
+ | `message.set` | `(data)` | `Promise<boolean>` | Guarda mensaje |
347
+ | `content.get` | `(cid, mid)` | `Promise<Buffer \| null>` | Obtiene contenido multimedia |
348
+ | `content.set` | `(cid, mid, buffer)` | `Promise<boolean>` | Guarda contenido multimedia |
349
+
350
+ ```typescript
351
+ // document: parsea JSON con BufferJSON, retorna objetos
352
+ await store.document.get('contact/123') // object[]
353
+ await store.document.set('contact/123', obj) // boolean
354
+
355
+ // entidades: retornan datos crudos (IContact, IChat, IMessage)
356
+ await store.contact.get('123') // IContact | null
357
+ await store.contact.find(0, 50) // IContact[]
358
+ await store.chat.get('cid') // IChat | null
359
+ await store.chat.find(0, 50) // IChat[]
360
+ await store.message.get('cid', 'mid') // IMessage | null
361
+ await store.message.find('cid', 0, 20) // IMessage[]
362
+ await store.content.get('cid', 'mid') // Buffer | null
363
+ ```
364
+
365
+ ---
366
+
367
+ ## Class Contact
368
+
369
+ Representa un contacto de WhatsApp.
370
+
371
+ ##### Propiedades
372
+
373
+ | Propiedad | Tipo | Default | Descripcion |
374
+ |-----------|------|---------|-------------|
375
+ | `id` | `string` | - | JID del contacto (`@s.whatsapp.net`) |
376
+ | `name` | `string` | - | Nombre publico del usuario |
377
+ | `phone` | `string` | - | Numero con prefijo de pais (sin +) |
378
+ | `photo` | `string \| null` | `null` | URL de foto de perfil |
379
+ | `custom_name` | `string` | `name` | Nombre en agenda local |
380
+
381
+ ##### Metodos Estaticos
382
+
383
+ | Metodo | Argumentos | Retorno | Descripcion |
384
+ |--------|------------|---------|-------------|
385
+ | `me` | `()` | `Promise<Contact>` | Obtiene el contacto propio |
386
+ | `get` | `(uid)` | `Promise<Contact \| null>` | Obtiene contacto por UID |
387
+ | `find` | `(offset, limit)` | `Promise<Contact[]>` | Obtiene contactos paginados |
388
+
389
+ ##### Metodos de Instancia
390
+
391
+ | Metodo | Argumentos | Retorno | Descripcion |
392
+ |--------|------------|---------|-------------|
393
+ | `chat` | `()` | `Promise<Chat>` | Obtiene o crea el chat 1-1 |
394
+ | `rename` | `(name)` | `Promise<boolean>` | Cambia custom_name localmente |
395
+
396
+ ```typescript
397
+ const yo = await wa.Contact.me()
398
+ const contact = await wa.Contact.get('5491155555555@s.whatsapp.net')
399
+ const todos = await wa.Contact.find(0, 50)
400
+ const chat = await contact.chat()
401
+ await contact.rename('Mi amigo')
402
+ ```
403
+
404
+ ---
405
+
406
+ ## Class Chat
407
+
408
+ Representa un chat de WhatsApp (grupo o contacto directo).
409
+
410
+ ##### Propiedades
411
+
412
+ | Propiedad | Tipo | Default | Descripcion |
413
+ |-----------|------|---------|-------------|
414
+ | `id` | `string` | - | ID del chat (remoteJid) |
415
+ | `name` | `string` | - | Nombre del grupo o contacto |
416
+ | `photo` | `string \| null` | `null` | URL de foto de perfil |
417
+ | `phone` | `string \| null` | `null` | Numero (null en grupos) |
418
+ | `type` | `'group' \| 'contact'` | - | Tipo de chat |
419
+
420
+ ##### Metodos Estaticos
421
+
422
+ | Metodo | Argumentos | Retorno | Descripcion |
423
+ |--------|------------|---------|-------------|
424
+ | `get` | `(cid)` | `Promise<Chat \| null>` | Obtiene chat por CID |
425
+ | `find` | `(offset, limit)` | `Promise<Chat[]>` | Obtiene chats paginados |
426
+ | `seen` | `(cid, mid?)` | `Promise<boolean>` | Marca mensaje como leido. Sin mid usa el ultimo |
427
+ | `members` | `(cid, offset, limit)` | `Promise<Contact[]>` | Participantes (incluye `me`) |
428
+ | `messages` | `(cid, offset, limit)` | `Promise<Message[]>` | Obtiene mensajes paginados |
429
+ | `text` | `(cid, content, mid?)` | `Promise<boolean>` | Envia texto |
430
+ | `image` | `(cid, buffer, mid?)` | `Promise<boolean>` | Envia imagen |
431
+ | `video` | `(cid, buffer, mid?)` | `Promise<boolean>` | Envia video |
432
+ | `audio` | `(cid, buffer, mid?)` | `Promise<boolean>` | Envia audio |
433
+ | `location` | `(cid, {lat, lng, caption?})` | `Promise<boolean>` | Envia ubicacion |
434
+ | `poll` | `(cid, text, options[])` | `Promise<boolean>` | Crea encuesta |
435
+ | `typing` | `(cid, bool)` | `Promise<boolean>` | Activa/desactiva "escribiendo..." |
436
+ | `recording` | `(cid, bool)` | `Promise<boolean>` | Activa/desactiva "grabando..." |
437
+
438
+ ##### Metodos de Instancia
439
+
440
+ | Metodo | Argumentos | Retorno | Descripcion |
441
+ |--------|------------|---------|-------------|
442
+ | `seen` | `(mid?)` | `Promise<boolean>` | `Chat.seen(this.id, mid)` |
443
+ | `members` | `(offset, limit)` | `Promise<Contact[]>` | `Chat.members(this.id, ...)` |
444
+ | `messages` | `(offset, limit)` | `Promise<Message[]>` | `Chat.messages(this.id, ...)` |
445
+ | `text` | `(content, mid?)` | `Promise<boolean>` | `Chat.text(this.id, ...)` |
446
+ | `image` | `(buffer, mid?)` | `Promise<boolean>` | `Chat.image(this.id, ...)` |
447
+ | `video` | `(buffer, mid?)` | `Promise<boolean>` | `Chat.video(this.id, ...)` |
448
+ | `audio` | `(buffer, mid?)` | `Promise<boolean>` | `Chat.audio(this.id, ...)` |
449
+ | `location` | `({lat, lng, caption?})` | `Promise<boolean>` | `Chat.location(this.id, ...)` |
450
+ | `poll` | `(text, options[])` | `Promise<boolean>` | `Chat.poll(this.id, ...)` |
451
+ | `typing` | `(bool)` | `Promise<boolean>` | `Chat.typing(this.id, ...)` |
452
+ | `recording` | `(bool)` | `Promise<boolean>` | `Chat.recording(this.id, ...)` |
453
+
454
+ ```typescript
455
+ const chat = await wa.Chat.get('5491155555555@s.whatsapp.net')
456
+ const chats = await wa.Chat.find(0, 50)
457
+ const msgs = await chat.messages(0, 10)
458
+ const members = await chat.members(0, 50)
459
+ await chat.text('Hola!', msgs[0].id)
460
+ await chat.poll('Donde cenamos?', ['Pizza', 'Sushi', 'Tacos'])
461
+ await chat.location({ lat: -34.603, lng: -58.381 })
462
+ await chat.seen() // Marca ultimo mensaje como leido
463
+ ```
464
+
465
+ ---
466
+
467
+ ## Class Message
468
+
469
+ Representa un mensaje de WhatsApp.
470
+
471
+ ##### Propiedades
472
+
473
+ | Propiedad | Tipo | Default | Descripcion |
474
+ |-----------|------|---------|-------------|
475
+ | `id` | `string` | - | ID unico del mensaje |
476
+ | `cid` | `string` | - | ID del chat |
477
+ | `uid` | `string` | - | ID del usuario que envio |
478
+ | `mid` | `string \| null` | `null` | ID del mensaje citado |
479
+ | `type` | `'text' \| 'image' \| 'video' \| 'audio' \| 'location' \| 'poll' \| 'unknown'` | - | Tipo de contenido |
480
+ | `mime` | `string` | `'text/plain'` | Formato: `text/plain`, `image/*`, `video/*`, `audio/*`, `application/json` |
481
+ | `caption` | `string` | `''` | Texto en imagen/video/location |
482
+ | `me` | `boolean` | - | `true` si soy el autor |
483
+ | `status` | `'pending' \| 'sent' \| 'delivered' \| 'read'` | - | Estado del mensaje |
484
+ | `created_at` | `string` | - | Fecha en UTC (ISO string) |
485
+ | `edited` | `boolean` | `false` | `true` si fue editado |
486
+
487
+ ##### Metodos Estaticos
488
+
489
+ | Metodo | Argumentos | Retorno | Descripcion |
490
+ |--------|------------|---------|-------------|
491
+ | `get` | `(cid, mid)` | `Promise<Message \| null>` | Obtiene mensaje por CID y MID |
492
+ | `delete` | `(cid, mid, all?)` | `Promise<boolean>` | Elimina mensaje (`all` = para todos) |
493
+ | ~~`forward`~~ | ~~`(cid, mid, target_cid)`~~ | ~~`Promise<boolean>`~~ | ~~Deprecated: usar envio manual~~ |
494
+ | `edit` | `(cid, mid, content)` | `Promise<boolean>` | Edita mensaje de texto propio |
495
+ | `votes` | `(cid, mid)` | `Promise<{name, count}[]>` | Obtiene votos de encuesta |
496
+ | `seen` | `(cid, mid)` | `Promise<boolean>` | Marca mensaje como leido |
497
+
498
+ ##### Metodos de Instancia
499
+
500
+ | Metodo | Argumentos | Retorno | Descripcion |
501
+ |--------|------------|---------|-------------|
502
+ | `content` | `()` | `Promise<Buffer>` | Contenido segun tipo y mime |
503
+ | `chat` | `()` | `Promise<Chat \| null>` | Obtiene el chat donde se envio |
504
+ | `author` | `()` | `Promise<Contact \| null>` | Obtiene el contacto autor |
505
+ | `delete` | `(all?)` | `Promise<boolean>` | `Message.delete(this.cid, this.id, ...)` |
506
+ | `edit` | `(content)` | `Promise<boolean>` | `Message.edit(this.cid, this.id, ...)` |
507
+ | `votes` | `()` | `Promise<{name, count}[]>` | `Message.votes(this.cid, this.id)` |
508
+ | `seen` | `()` | `Promise<boolean>` | `Message.seen(this.cid, this.id)` |
509
+
510
+ ```typescript
511
+ const msg = await wa.Message.get('5491155555555@s.whatsapp.net', 'ABC123')
512
+
513
+ // Texto: mime = 'text/plain'
514
+ const text = (await msg.content()).toString()
515
+
516
+ // Media: mime = 'image/jpeg', 'video/mp4', 'audio/ogg', etc.
517
+ const media = await msg.content()
518
+
519
+ // Location/Poll: mime = 'application/json'
520
+ const location = JSON.parse((await msg.content()).toString()) // {lat, lng}
521
+ const poll = JSON.parse((await msg.content()).toString()) // {content, items[]}
522
+
523
+ // Navegacion
524
+ const chat = await msg.chat()
525
+ const author = await msg.author()
526
+
527
+ await msg.edit('Texto corregido')
528
+ await msg.delete(true)
529
+ await msg.seen()
530
+ ```
531
+
532
+ ---