@areumtecnologia/wasockets 1.1.6 → 2.0.0
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 +742 -34
- package/WAProto/index.d.ts +17 -0
- package/lib/Defaults/connection.js +34 -2
- package/lib/Defaults/index.d.ts +6 -0
- package/lib/Plugins/index.d.ts +33 -0
- package/lib/Plugins/index.js +125 -0
- package/lib/Socket/business.js +33 -0
- package/lib/Socket/chats.js +103 -2
- package/lib/Socket/community.js +126 -69
- package/lib/Socket/groups.js +103 -26
- package/lib/Socket/index.js +27 -3
- package/lib/Socket/messages-send.js +111 -0
- package/lib/Socket/newsletter.js +125 -3
- package/lib/Store/index.d.ts +4 -0
- package/lib/Store/make-in-memory-store.js +294 -25
- package/lib/Types/index.d.ts +199 -0
- package/lib/Utils/index.d.ts +33 -0
- package/lib/Utils/index.js +2 -1
- package/lib/Utils/messages.js +14 -3
- package/lib/Utils/reconnect.js +136 -0
- package/lib/Utils/validate-connection.js +5 -5
- package/lib/WABinary/index.d.ts +17 -0
- package/lib/index.d.ts +274 -0
- package/lib/index.js +1 -0
- package/package.json +19 -5
package/README.md
CHANGED
|
@@ -36,6 +36,10 @@ O **WaSockets** foi criado para resolver problemas crônicos de estabilidade e a
|
|
|
36
36
|
| **Recursos Web (v1.1.6)** | Favoritos & Notas de Contato | Sincronização via App State de chats favoritos (`updateFavorite`) e anotações internas de contatos (`updateChatNote`). |
|
|
37
37
|
| **Recursos Web (v1.1.6)** | Chamadas Web (Web Calling) | Sinalização completa de chamadas no navegador (`offerCall`, `acceptCall`, `terminateCall`, `rejectCall`). |
|
|
38
38
|
| **Recursos Web (v1.1.6)** | Resolução Reversa de LID | Consulta reversa USync para obter o número de telefone a partir de um identificador `@lid` (`getPnUser`). |
|
|
39
|
+
| **Transição LID (Pilar 2)** | Store Unificado (LID & PN) | `store.getContact(jid)` e `store.getChat(jid)` com indexação cruzada e resolução automática de apelidos LID/PN. |
|
|
40
|
+
| **Transição LID (Pilar 2)** | Roteamento & Resolução JID | Métodos `sock.toPn()`, `sock.toLid()`, `sock.resolveJid()` e auto-aprendizado de chaves no cache do Signal. |
|
|
41
|
+
| **Multimídia & Canais (Pilar 3)** | Álbum Nativo & Waveforms | Envio de álbuns (`sendAlbumMessage`), ordenação indexada e suporte a waveforms PTT customizadas. |
|
|
42
|
+
| **Multimídia & Canais (Pilar 3)** | Newsletters (Canais) v2 | Consulta de reações (`newsletterFetchReactions`), mensagens individuais (`newsletterFetchMessage`) e lista parseada. |
|
|
39
43
|
|
|
40
44
|
---
|
|
41
45
|
|
|
@@ -49,25 +53,45 @@ O **WaSockets** foi criado para resolver problemas crônicos de estabilidade e a
|
|
|
49
53
|
- [Salvando e Restaurando Sessões](#-salvando-e-restaurando-sessões)
|
|
50
54
|
- [Configurações Importantes do Socket](#-configurações-importantes-do-socket)
|
|
51
55
|
- [Exemplo Prático Inicial (Bootstrap)](#-exemplo-prático-inicial-bootstrap)
|
|
52
|
-
- [Tratamento de Eventos](#-tratamento-de-eventos)
|
|
56
|
+
- [Tratamento de Eventos e Mídia](#-tratamento-de-eventos-e-mídia)
|
|
57
|
+
- [Download de Mídias Recebidas](#download-de-mídias-recebidas)
|
|
53
58
|
- [Decifrar Votos de Enquetes](#decifrar-votos-de-enquetes)
|
|
54
59
|
- [Decifrar Respostas de Eventos](#decifrar-respostas-de-eventos)
|
|
60
|
+
- [Verificação de Contatos e Presença](#-verificação-de-contatos-e-presença)
|
|
61
|
+
- [Verificação de Números no WhatsApp (onWhatsApp)](#verificação-de-números-no-whatsapp-onwhatsapp)
|
|
62
|
+
- [Presença e Digitando / Gravando Áudio](#presença-e-digitando--gravando-áudio)
|
|
55
63
|
- [Enviando Mensagens](#-enviando-mensagens)
|
|
56
|
-
- [Mensagens de Texto e
|
|
64
|
+
- [Mensagens de Texto, Menções e Links](#mensagens-de-texto-e-menções)
|
|
57
65
|
- [Mensagens de Mídia](#mensagens-de-mídia)
|
|
66
|
+
- [Documentos e Arquivos](#documentos-e-arquivos)
|
|
67
|
+
- [Figurinhas (Stickers)](#figurinhas-stickers)
|
|
68
|
+
- [Localização Fixa e Tempo Real](#localização-fixa-e-em-tempo-real)
|
|
69
|
+
- [Contatos e Cartões vCard](#contatos-e-cartões-vcard)
|
|
70
|
+
- [Reações a Mensagens](#reações-a-mensagens)
|
|
71
|
+
- [Criação de Enquetes](#criação-de-enquetes)
|
|
72
|
+
- [Listas Interativas de Opções](#listas-interativas-de-opções-sections)
|
|
58
73
|
- [Botões Interativos](#botões-interativos)
|
|
59
74
|
- [Botão de Pagamento PIX](#botão-de-pagamento-pix)
|
|
60
75
|
- [Fluxos de Checkout (PAY)](#fluxos-de-checkout-pay)
|
|
61
|
-
- [
|
|
76
|
+
- [Encaminhamento de Mensagens](#encaminhamento-de-mensagens)
|
|
77
|
+
- [Menção em Status e Reações](#menção-em-status)
|
|
62
78
|
- [Comentários em Canais e Comunidades](#comentários-em-canais-e-comunidades)
|
|
63
79
|
- [Modificando Mensagens e Chats](#-modificando-mensagens-e-chats)
|
|
80
|
+
- [Confirmação de Leitura (readMessages)](#confirmação-de-leitura-readmessages)
|
|
81
|
+
- [Mensagens com Estrela (star)](#mensagens-com-estrela-star)
|
|
64
82
|
- [Fixação de Mensagens com Duração](#fixação-de-mensagens-com-duração)
|
|
65
83
|
- [Favoritos e Anotações de Contato](#favoritos-e-anotações-de-contato)
|
|
84
|
+
- [Perfil do Usuário e Foto](#-perfil-do-usuário-e-foto)
|
|
66
85
|
- [Eventos em Grupos e RSVP](#-eventos-em-grupos-e-rsvp)
|
|
67
86
|
- [Chamadas Web (Web Calling)](#-chamadas-web-web-calling)
|
|
68
|
-
- [Resolução de Usuários (LID e Telefone)](#-resolução-de-usuários-lid-
|
|
87
|
+
- [Resolução de Usuários (LID e Telefone)](#-resolução-de-usuários--transição-lid-pilar-2)
|
|
88
|
+
- [Etiquetas e Respostas Rápidas (WhatsApp Business)](#-etiquetas-de-negócio-labels---whatsapp-business)
|
|
69
89
|
- [Gerenciamento de Grupos](#-gerenciamento-de-grupos)
|
|
70
|
-
- [Newsletters (Canais)](#-newsletters-
|
|
90
|
+
- [Newsletters (Canais)](#-newsletters--canais-v2-pilar-3)
|
|
91
|
+
- [WhatsApp Business (Catálogo e Produtos)](#-whatsapp-business-catálogo-produtos-e-perfil-comercial)
|
|
92
|
+
- [Grupos e Comunidades v2](#-grupos-comunidades-v2-e-moderação-avançada)
|
|
93
|
+
- [Arquitetura de Plugins e Middlewares](#-arquitetura-de-plugins-e-middlewares)
|
|
94
|
+
- [Alta Performance, Cache e Memória](#-alta-performance-cache-e-controle-de-memória)
|
|
71
95
|
- [Configurações de Privacidade](#-configurações-de-privacidade)
|
|
72
96
|
- [Logs e Protocolo](#-logs-e-protocolo)
|
|
73
97
|
|
|
@@ -200,6 +224,24 @@ const sock = makeWASocket({
|
|
|
200
224
|
})
|
|
201
225
|
```
|
|
202
226
|
|
|
227
|
+
### 3. Fila Inteligente de Mensagens Durante Quedas Transitórias
|
|
228
|
+
Quando a conexão com o WhatsApp cai momentaneamente, o **WaSockets** armazena mensagens em buffer de espera e as envia automaticamente assim que a conexão se restabelece:
|
|
229
|
+
|
|
230
|
+
```javascript
|
|
231
|
+
const sock = makeWASocket({
|
|
232
|
+
enableMessageQueue: true, // Ativado por padrão (evita perda de mensagens durante reconexão)
|
|
233
|
+
messageQueueTtlMs: 5 * 60 * 1000 // TTL de expiração na fila (padrão: 5 minutos)
|
|
234
|
+
})
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 4. Auto-Reparo de Sessão E2E / Signal (`repairSession`)
|
|
238
|
+
Se uma conversa específica apresentar erros de chave ou falhas de descriptografia (`Bad MAC` ou `Session Corrupted`), não é mais necessário deletar a pasta inteira de autenticação. Use o método `repairSession`:
|
|
239
|
+
|
|
240
|
+
```javascript
|
|
241
|
+
// Remove a sessão danificada e força a renegociação de chaves E2E com o contato
|
|
242
|
+
await sock.repairSession('5511999999999@s.whatsapp.net')
|
|
243
|
+
```
|
|
244
|
+
|
|
203
245
|
---
|
|
204
246
|
|
|
205
247
|
## 🚀 Exemplo Prático Inicial (Bootstrap)
|
|
@@ -207,34 +249,36 @@ const sock = makeWASocket({
|
|
|
207
249
|
Aqui está um arquivo funcional completo em JavaScript (CommonJS) para iniciar a sua integração:
|
|
208
250
|
|
|
209
251
|
```javascript
|
|
210
|
-
const { default: makeWASocket, DisconnectReason, useMultiFileAuthState } = require('@areumtecnologia/wasockets')
|
|
252
|
+
const { default: makeWASocket, DisconnectReason, useMultiFileAuthState, makeReconnectManager, shouldReconnect } = require('@areumtecnologia/wasockets')
|
|
211
253
|
const { Boom } = require('@hapi/boom')
|
|
212
254
|
|
|
213
255
|
async function connectToWhatsApp() {
|
|
214
256
|
// 1. Inicializa o estado de autenticação baseado em arquivos
|
|
215
257
|
const { state, saveCreds } = await useMultiFileAuthState('./auth_info_baileys')
|
|
216
258
|
|
|
217
|
-
// 2. Cria o Socket de Conexão
|
|
259
|
+
// 2. Cria o Socket de Conexão com fila de mensagens inteligente ativada por padrão
|
|
218
260
|
const sock = makeWASocket({
|
|
219
261
|
auth: state,
|
|
220
|
-
printQRInTerminal: true
|
|
262
|
+
printQRInTerminal: true,
|
|
263
|
+
enableMessageQueue: true // Fila de envio automático durante reconexões transitórias
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
// Gerenciador de reconexão adaptativa com Backoff Exponencial e Full Jitter (evita banimentos)
|
|
267
|
+
const reconnectManager = makeReconnectManager({
|
|
268
|
+
onReconnect: async (attempt) => {
|
|
269
|
+
console.log(`Reconectando ao WhatsApp (tentativa #${attempt})...`)
|
|
270
|
+
await connectToWhatsApp()
|
|
271
|
+
}
|
|
221
272
|
})
|
|
222
273
|
|
|
223
274
|
// 3. Monitora o status da conexão
|
|
224
|
-
sock.ev.on('connection.update', (update) => {
|
|
275
|
+
sock.ev.on('connection.update', async (update) => {
|
|
225
276
|
const { connection, lastDisconnect } = update
|
|
226
277
|
|
|
227
278
|
if (connection === 'close') {
|
|
228
|
-
|
|
229
|
-
? lastDisconnect.error.output.statusCode !== DisconnectReason.loggedOut
|
|
230
|
-
: true
|
|
231
|
-
|
|
232
|
-
console.log('Conexão fechada devido a:', lastDisconnect.error, '. Reconectando:', shouldReconnect)
|
|
233
|
-
|
|
234
|
-
if (shouldReconnect) {
|
|
235
|
-
connectToWhatsApp() // Reconexão automática se não tiver feito logout
|
|
236
|
-
}
|
|
279
|
+
await reconnectManager.handleDisconnect(lastDisconnect?.error)
|
|
237
280
|
} else if (connection === 'open') {
|
|
281
|
+
reconnectManager.reset()
|
|
238
282
|
console.log('Conexão com o WhatsApp estabelecida com sucesso!')
|
|
239
283
|
}
|
|
240
284
|
})
|
|
@@ -263,14 +307,48 @@ connectToWhatsApp()
|
|
|
263
307
|
|
|
264
308
|
---
|
|
265
309
|
|
|
266
|
-
## 📡 Tratamento de Eventos
|
|
310
|
+
## 📡 Tratamento de Eventos e Mídia
|
|
267
311
|
|
|
268
312
|
O **WaSockets** utiliza um sistema de eventos tipado baseado no `EventEmitter`.
|
|
269
313
|
|
|
270
314
|
```javascript
|
|
271
315
|
sock.ev.on('messages.upsert', ({ messages, type }) => {
|
|
272
316
|
// type pode ser 'notify' (nova notificação) ou 'append' (carregamento histórico)
|
|
273
|
-
console.log('Novas mensagens:', messages)
|
|
317
|
+
console.log('Novas mensagens recebidas:', messages)
|
|
318
|
+
})
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Download de Mídias Recebidas
|
|
322
|
+
|
|
323
|
+
Para baixar mídias (fotos, vídeos, áudios, documentos ou stickers) recebidas no evento `messages.upsert`, utilize a função utilitária `downloadMediaMessage`:
|
|
324
|
+
|
|
325
|
+
```javascript
|
|
326
|
+
const { downloadMediaMessage } = require('@areumtecnologia/wasockets')
|
|
327
|
+
const fs = require('fs')
|
|
328
|
+
|
|
329
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
330
|
+
for (const msg of messages) {
|
|
331
|
+
if (!msg.message || msg.key.fromMe) continue
|
|
332
|
+
|
|
333
|
+
const isMedia = msg.message.imageMessage ||
|
|
334
|
+
msg.message.videoMessage ||
|
|
335
|
+
msg.message.audioMessage ||
|
|
336
|
+
msg.message.documentMessage ||
|
|
337
|
+
msg.message.stickerMessage
|
|
338
|
+
|
|
339
|
+
if (isMedia) {
|
|
340
|
+
// Baixa o arquivo diretamente em formato Buffer
|
|
341
|
+
const buffer = await downloadMediaMessage(msg, 'buffer', {})
|
|
342
|
+
|
|
343
|
+
// Exemplo: Salvar no disco
|
|
344
|
+
const ext = msg.message.imageMessage ? 'jpg' : msg.message.audioMessage ? 'ogg' : 'bin'
|
|
345
|
+
fs.writeFileSync(`./download_${msg.key.id}.${ext}`, buffer)
|
|
346
|
+
console.log(`Mídia baixada com sucesso (${buffer.length} bytes)!`)
|
|
347
|
+
|
|
348
|
+
// Ou baixar como stream de leitura para processamento em tempo real:
|
|
349
|
+
// const stream = await downloadMediaMessage(msg, 'stream', {})
|
|
350
|
+
}
|
|
351
|
+
}
|
|
274
352
|
})
|
|
275
353
|
```
|
|
276
354
|
|
|
@@ -326,6 +404,53 @@ sock.ev.on('messages.update', async (updates) => {
|
|
|
326
404
|
|
|
327
405
|
---
|
|
328
406
|
|
|
407
|
+
## 🔍 Verificação de Contatos e Presença
|
|
408
|
+
|
|
409
|
+
### Verificação de Números no WhatsApp (onWhatsApp)
|
|
410
|
+
|
|
411
|
+
Valide se um ou vários números de telefone possuem contas ativas registradas no WhatsApp antes de disparar mensagens:
|
|
412
|
+
|
|
413
|
+
```javascript
|
|
414
|
+
// Aceita um ou vários números (com DDI e DDD)
|
|
415
|
+
const resultados = await sock.onWhatsApp('5511999999999', '5511888888888', '5521977777777')
|
|
416
|
+
|
|
417
|
+
for (const { jid, exists } of resultados) {
|
|
418
|
+
if (exists) {
|
|
419
|
+
console.log(`O número ${jid} está ativo no WhatsApp!`)
|
|
420
|
+
} else {
|
|
421
|
+
console.log(`O número ${jid} NÃO possui conta no WhatsApp.`)
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Presença e Digitando / Gravando Áudio
|
|
427
|
+
|
|
428
|
+
Simule atividade humana enviando estados de presença ou monitore o status de contatos:
|
|
429
|
+
|
|
430
|
+
```javascript
|
|
431
|
+
// 1. Indicar que está digitando...
|
|
432
|
+
await sock.sendPresenceUpdate('composing', jid)
|
|
433
|
+
|
|
434
|
+
// 2. Indicar que está gravando áudio...
|
|
435
|
+
await sock.sendPresenceUpdate('recording', jid)
|
|
436
|
+
|
|
437
|
+
// 3. Pausar status de digitação/gravação
|
|
438
|
+
await sock.sendPresenceUpdate('paused', jid)
|
|
439
|
+
|
|
440
|
+
// 4. Alterar presença geral da conta ('available' = Online, 'unavailable' = Offline)
|
|
441
|
+
await sock.sendPresenceUpdate('available')
|
|
442
|
+
|
|
443
|
+
// 5. Inscrever-se para escutar presença de um contato específico
|
|
444
|
+
await sock.presenceSubscribe(jid)
|
|
445
|
+
|
|
446
|
+
// 6. Monitorar atualizações de presença recebidas
|
|
447
|
+
sock.ev.on('presence.update', ({ id, presences }) => {
|
|
448
|
+
console.log(`Atualização de presença de ${id}:`, presences)
|
|
449
|
+
})
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
329
454
|
## ✉️ Enviando Mensagens
|
|
330
455
|
|
|
331
456
|
### Mensagens de Texto e Menções
|
|
@@ -394,6 +519,145 @@ await sock.sendMessage(jid, {
|
|
|
394
519
|
|
|
395
520
|
---
|
|
396
521
|
|
|
522
|
+
### Documentos e Arquivos
|
|
523
|
+
|
|
524
|
+
Envie qualquer formato de arquivo (PDF, planilhas, arquivos compactados) informando o `mimetype` e o `fileName` para exibição correta no aplicativo:
|
|
525
|
+
|
|
526
|
+
```javascript
|
|
527
|
+
await sock.sendMessage(jid, {
|
|
528
|
+
document: { url: './fatura_setembro.pdf' }, // ou Buffer ou { url: 'https://exemplo.com/doc.pdf' }
|
|
529
|
+
mimetype: 'application/pdf',
|
|
530
|
+
fileName: 'Fatura_Setembro_2026.pdf'
|
|
531
|
+
})
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Figurinhas (Stickers)
|
|
535
|
+
|
|
536
|
+
Envie figurinhas estáticas ou animadas no formato WebP:
|
|
537
|
+
|
|
538
|
+
```javascript
|
|
539
|
+
await sock.sendMessage(jid, {
|
|
540
|
+
sticker: fs.readFileSync('./minha_figurinha.webp') // aceita Buffer ou { url: './figurinha.webp' }
|
|
541
|
+
})
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
### Localização Fixa e em Tempo Real
|
|
545
|
+
|
|
546
|
+
Envie pontos no mapa ou compartilhe localização em tempo real com latitude e longitude:
|
|
547
|
+
|
|
548
|
+
```javascript
|
|
549
|
+
// Localização Fixa
|
|
550
|
+
await sock.sendMessage(jid, {
|
|
551
|
+
location: {
|
|
552
|
+
degreesLatitude: -23.55052,
|
|
553
|
+
degreesLongitude: -46.633308,
|
|
554
|
+
name: 'Sede da Áreum Tecnologia',
|
|
555
|
+
address: 'Av. Paulista, 1000 - Bela Vista, São Paulo - SP'
|
|
556
|
+
}
|
|
557
|
+
})
|
|
558
|
+
|
|
559
|
+
// Localização em Tempo Real (Live Location)
|
|
560
|
+
await sock.sendMessage(jid, {
|
|
561
|
+
location: {
|
|
562
|
+
degreesLatitude: -23.55052,
|
|
563
|
+
degreesLongitude: -46.633308
|
|
564
|
+
},
|
|
565
|
+
live: true
|
|
566
|
+
})
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### Contatos e Cartões vCard
|
|
570
|
+
|
|
571
|
+
Envie um ou múltiplos contatos com cartão vCard formatado:
|
|
572
|
+
|
|
573
|
+
```javascript
|
|
574
|
+
const vcard = 'BEGIN:VCARD\n'
|
|
575
|
+
+ 'VERSION:3.0\n'
|
|
576
|
+
+ 'FN:Suporte Técnico Áreum\n'
|
|
577
|
+
+ 'ORG:Áreum Tecnologia;\n'
|
|
578
|
+
+ 'TEL;type=CELL;type=VOICE;waid=5511999999999:+55 11 99999-9999\n'
|
|
579
|
+
+ 'END:VCARD'
|
|
580
|
+
|
|
581
|
+
await sock.sendMessage(jid, {
|
|
582
|
+
contacts: {
|
|
583
|
+
displayName: 'Suporte Técnico Áreum',
|
|
584
|
+
contacts: [{ vcard }]
|
|
585
|
+
}
|
|
586
|
+
})
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
### Reações a Mensagens
|
|
590
|
+
|
|
591
|
+
Reaja com emojis a qualquer mensagem enviada ou recebida (ou remova a reação enviando string vazia `''`):
|
|
592
|
+
|
|
593
|
+
```javascript
|
|
594
|
+
// Reagir à mensagem com um emoji
|
|
595
|
+
await sock.sendMessage(jid, {
|
|
596
|
+
react: {
|
|
597
|
+
text: '🔥', // Emoji da reação
|
|
598
|
+
key: msg.key // Chave da mensagem original que receberá a reação
|
|
599
|
+
}
|
|
600
|
+
})
|
|
601
|
+
|
|
602
|
+
// Remover reação anterior
|
|
603
|
+
await sock.sendMessage(jid, {
|
|
604
|
+
react: {
|
|
605
|
+
text: '',
|
|
606
|
+
key: msg.key
|
|
607
|
+
}
|
|
608
|
+
})
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### Criação de Enquetes
|
|
612
|
+
|
|
613
|
+
Crie enquetes interativas com contagem configurável de seleção (voto único ou múltiplo):
|
|
614
|
+
|
|
615
|
+
```javascript
|
|
616
|
+
await sock.sendMessage(jid, {
|
|
617
|
+
poll: {
|
|
618
|
+
name: 'Qual o melhor diferencial do WaSockets?',
|
|
619
|
+
values: [
|
|
620
|
+
'Resolução Transparente de LID',
|
|
621
|
+
'Envio Nativo de Álbuns',
|
|
622
|
+
'Newsletters v2 e Canais',
|
|
623
|
+
'Fila Inteligente de Reconexão'
|
|
624
|
+
],
|
|
625
|
+
selectableCount: 1 // 1 para escolha única; > 1 para permitir múltiplas escolhas
|
|
626
|
+
}
|
|
627
|
+
})
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### Listas Interativas de Opções (Sections)
|
|
631
|
+
|
|
632
|
+
Envie menus organizados por categorias e linhas para navegação intuitiva:
|
|
633
|
+
|
|
634
|
+
```javascript
|
|
635
|
+
await sock.sendMessage(jid, {
|
|
636
|
+
text: 'Selecione o setor desejado para atendimento:',
|
|
637
|
+
footer: 'Áreum Tecnologia • Atendimento Automatizado',
|
|
638
|
+
title: 'Central de Relacionamento',
|
|
639
|
+
buttonText: 'Ver Departamentos',
|
|
640
|
+
sections: [
|
|
641
|
+
{
|
|
642
|
+
title: 'Atendimento Comercial',
|
|
643
|
+
rows: [
|
|
644
|
+
{ title: 'Novas Contratações', rowId: 'row_vendas', description: 'Conheça nossos planos e soluções' },
|
|
645
|
+
{ title: 'Upgrade de Plano', rowId: 'row_upgrade', description: 'Amplie os limites da sua conta' }
|
|
646
|
+
]
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
title: 'Suporte & Operações',
|
|
650
|
+
rows: [
|
|
651
|
+
{ title: 'Suporte Técnico', rowId: 'row_suporte', description: 'Dúvidas de integração e bugs' },
|
|
652
|
+
{ title: 'Financeiro', rowId: 'row_financeiro', description: '2ª via de boleto e notas fiscais' }
|
|
653
|
+
]
|
|
654
|
+
}
|
|
655
|
+
]
|
|
656
|
+
})
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
397
661
|
### Botões Interativos
|
|
398
662
|
|
|
399
663
|
Os botões nativos do WhatsApp são suportados através da propriedade `interactiveButtons`.
|
|
@@ -538,6 +802,60 @@ await sock.sendMessage(jid, {
|
|
|
538
802
|
})
|
|
539
803
|
```
|
|
540
804
|
|
|
805
|
+
### Envio Nativo de Álbuns de Fotos e Vídeos (Pilar 3)
|
|
806
|
+
|
|
807
|
+
Envie múltiplos arquivos de imagem e vídeo agrupados nativamente em um container de álbum (layout de grade no WhatsApp Web e Celular) com ordenação indexada e suporte a legendas:
|
|
808
|
+
|
|
809
|
+
```javascript
|
|
810
|
+
// Método direto e simplificado
|
|
811
|
+
await sock.sendAlbumMessage(jid, [
|
|
812
|
+
{ image: { url: 'https://exemplo.com/foto1.jpg' }, caption: 'Foto 1 do produto' },
|
|
813
|
+
{ image: { url: 'https://exemplo.com/foto2.jpg' }, caption: 'Foto 2 em outro ângulo' },
|
|
814
|
+
{ video: { url: 'https://exemplo.com/demonstracao.mp4' }, caption: 'Vídeo explicativo' }
|
|
815
|
+
])
|
|
816
|
+
|
|
817
|
+
// Ou através de sendMessage com a propriedade album:
|
|
818
|
+
await sock.sendMessage(jid, {
|
|
819
|
+
album: [
|
|
820
|
+
{ image: { url: './local/foto1.jpg' } },
|
|
821
|
+
{ image: { url: './local/foto2.jpg' } }
|
|
822
|
+
]
|
|
823
|
+
})
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
### Mensagens de Áudio PTT com Waveform Customizada (Pilar 3)
|
|
827
|
+
|
|
828
|
+
Você pode enviar notas de voz (Push-To-Talk) com geração automática de ondas sonoras ou fornecer uma forma de onda predefinida (array ou Buffer):
|
|
829
|
+
|
|
830
|
+
```javascript
|
|
831
|
+
// Áudio PTT com waveform automática gerada a partir do arquivo
|
|
832
|
+
await sock.sendMessage(jid, {
|
|
833
|
+
audio: { url: './audio.mp3' },
|
|
834
|
+
mimetype: 'audio/ogg; codecs=opus',
|
|
835
|
+
ptt: true
|
|
836
|
+
})
|
|
837
|
+
|
|
838
|
+
// Áudio PTT com waveform predefinida (evita decodificação intensiva de CPU)
|
|
839
|
+
await sock.sendMessage(jid, {
|
|
840
|
+
audio: { url: './audio.mp3' },
|
|
841
|
+
mimetype: 'audio/ogg; codecs=opus',
|
|
842
|
+
ptt: true,
|
|
843
|
+
waveform: [0, 15, 30, 75, 100, 80, 45, 20, 10, 0] // 64 barras de amplitude
|
|
844
|
+
})
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
### Encaminhamento de Mensagens
|
|
848
|
+
|
|
849
|
+
Encaminhe mensagens para outros chats preservando ou forçando o status de encaminhado:
|
|
850
|
+
|
|
851
|
+
```javascript
|
|
852
|
+
// Encaminhar uma mensagem recebida para outro destinatário
|
|
853
|
+
await sock.sendMessage(outroJid, {
|
|
854
|
+
forward: mensagemOriginal,
|
|
855
|
+
force: true // Exibe o selo de mensagem encaminhada
|
|
856
|
+
})
|
|
857
|
+
```
|
|
858
|
+
|
|
541
859
|
---
|
|
542
860
|
|
|
543
861
|
## 📝 Modificando Mensagens e Chats
|
|
@@ -569,6 +887,27 @@ await sock.chatModify({ markRead: false, lastMessages: [msg] }, jid)
|
|
|
569
887
|
await sock.chatModify({ pin: true }, jid)
|
|
570
888
|
```
|
|
571
889
|
|
|
890
|
+
### Confirmação de Leitura (readMessages)
|
|
891
|
+
|
|
892
|
+
Envie confirmações de leitura explícitas para exibir os ticks azuis ao remetente:
|
|
893
|
+
|
|
894
|
+
```javascript
|
|
895
|
+
// Marca uma ou mais mensagens recebidas como lidas
|
|
896
|
+
await sock.readMessages([msg.key])
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
### Mensagens com Estrela (star)
|
|
900
|
+
|
|
901
|
+
Marque mensagens importantes com estrela (favoritas) na conversa:
|
|
902
|
+
|
|
903
|
+
```javascript
|
|
904
|
+
// Adicionar estrela à mensagem
|
|
905
|
+
await sock.star(jid, [{ id: msg.key.id, fromMe: msg.key.fromMe }], true)
|
|
906
|
+
|
|
907
|
+
// Remover estrela da mensagem
|
|
908
|
+
await sock.star(jid, [{ id: msg.key.id, fromMe: msg.key.fromMe }], false)
|
|
909
|
+
```
|
|
910
|
+
|
|
572
911
|
### Fixação de Mensagens com Duração
|
|
573
912
|
|
|
574
913
|
Fixe mensagens em conversas individuais ou grupos escolhendo a duração desejada:
|
|
@@ -613,6 +952,34 @@ await sock.removeChatNote(jid)
|
|
|
613
952
|
|
|
614
953
|
---
|
|
615
954
|
|
|
955
|
+
## 👤 Perfil do Usuário e Foto
|
|
956
|
+
|
|
957
|
+
Gerencie fotos de perfil, recados e nome de exibição (PushName) diretamente pelo socket:
|
|
958
|
+
|
|
959
|
+
```javascript
|
|
960
|
+
// 1. Obter a URL da foto de perfil de um contato ou grupo
|
|
961
|
+
const pfpUrl = await sock.profilePictureUrl(jid, 'image') // ou 'preview' para miniatura
|
|
962
|
+
console.log('Foto de Perfil:', pfpUrl)
|
|
963
|
+
|
|
964
|
+
// 2. Atualizar a sua própria foto de perfil (ou a foto de um grupo do qual você é admin)
|
|
965
|
+
await sock.updateProfilePicture(jid, { url: './nova_foto.jpg' }) // Aceita caminho, URL ou Buffer
|
|
966
|
+
|
|
967
|
+
// 3. Remover a foto de perfil
|
|
968
|
+
await sock.removeProfilePicture(jid)
|
|
969
|
+
|
|
970
|
+
// 4. Consultar o recado / About (Status) de um contato
|
|
971
|
+
const statusInfo = await sock.fetchStatus(jid)
|
|
972
|
+
console.log(`Recado de ${jid}: ${statusInfo?.status} (Definido em: ${statusInfo?.setAt})`)
|
|
973
|
+
|
|
974
|
+
// 5. Atualizar o seu próprio recado / About
|
|
975
|
+
await sock.updateProfileStatus('Disponível apenas para atendimentos prioritários 🚀')
|
|
976
|
+
|
|
977
|
+
// 6. Atualizar o seu nome público de exibição (PushName)
|
|
978
|
+
await sock.updateProfileName('Áreum Tecnologia - Suporte Oficial')
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
---
|
|
982
|
+
|
|
616
983
|
## 📅 Eventos em Grupos e RSVP
|
|
617
984
|
|
|
618
985
|
Crie eventos colaborativos, responda confirmações de presença e cancele eventos:
|
|
@@ -659,18 +1026,55 @@ await sock.rejectCall(callId, callerJid)
|
|
|
659
1026
|
|
|
660
1027
|
---
|
|
661
1028
|
|
|
662
|
-
## 🔍 Resolução de Usuários
|
|
1029
|
+
## 🔍 Resolução de Usuários & Transição LID (Pilar 2)
|
|
1030
|
+
|
|
1031
|
+
Com a evolução da privacidade no WhatsApp, participantes de grupos e canais frequentemente utilizam identificadores `@lid`. O **WaSockets** oferece um conjunto completo de ferramentas de alto desempenho com cache automático em memória e no banco de chaves Signal:
|
|
663
1032
|
|
|
664
|
-
|
|
1033
|
+
### Métodos de Resolução Transparente no Socket
|
|
665
1034
|
|
|
666
1035
|
```javascript
|
|
667
|
-
//
|
|
668
|
-
const
|
|
669
|
-
console.log('
|
|
1036
|
+
// 1. Converter LID para número de telefone (PN) com busca em cache/DB
|
|
1037
|
+
const pnJid = await sock.toPn('12345678901234@lid')
|
|
1038
|
+
console.log('JID com número real:', pnJid) // '5511999999999@s.whatsapp.net'
|
|
1039
|
+
|
|
1040
|
+
// Caso não esteja em cache local, pode passar true para consultar o servidor via USync:
|
|
1041
|
+
const pnJidFromNetwork = await sock.toPn('12345678901234@lid', true)
|
|
670
1042
|
|
|
671
|
-
//
|
|
1043
|
+
// 2. Converter número de telefone (PN) para LID
|
|
1044
|
+
const lidJid = await sock.toLid('5511999999999@s.whatsapp.net')
|
|
1045
|
+
console.log('LID correspondente:', lidJid) // '12345678901234@lid'
|
|
1046
|
+
|
|
1047
|
+
// 3. Resolução completa e unificada (retorna ambos)
|
|
1048
|
+
const resolved = await sock.resolveJid(authorJid)
|
|
1049
|
+
console.log(resolved) // { pn: '5511999999999@s.whatsapp.net', lid: '12345678901234@lid', jid: ... }
|
|
1050
|
+
|
|
1051
|
+
// 4. Registrar manualmente um mapeamento conhecido
|
|
1052
|
+
await sock.storeLidPnMapping('5511999999999@s.whatsapp.net', '12345678901234@lid')
|
|
1053
|
+
|
|
1054
|
+
// 5. Consultas diretas via protocolo USync (baixo nível)
|
|
1055
|
+
const [lidUser] = await sock.getLidUser('5511999999999@s.whatsapp.net')
|
|
672
1056
|
const [pnUser] = await sock.getPnUser('12345678901234@lid')
|
|
673
|
-
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
### Store Unificado de Contatos e Conversas (`makeInMemoryStore`)
|
|
1060
|
+
|
|
1061
|
+
Tradicionalmente, quando o WhatsApp chaveia as mensagens para `@lid`, chamadas como `store.contacts[jid]` ou `store.messages[jid]` falhavam por incompatibilidade de identificadores. O **WaSockets** resolve isso unificando o catálogo em tempo de execução:
|
|
1062
|
+
|
|
1063
|
+
```javascript
|
|
1064
|
+
import { makeInMemoryStore } from '@areumtecnologia/wasockets'
|
|
1065
|
+
|
|
1066
|
+
const store = makeInMemoryStore({})
|
|
1067
|
+
store.bind(sock.ev)
|
|
1068
|
+
|
|
1069
|
+
// Busca unificada: localiza o contato quer você passe o número (@s.whatsapp.net), o @lid ou apenas os dígitos
|
|
1070
|
+
const contact = store.getContact('12345678901234@lid')
|
|
1071
|
+
// Retorna o contato completo contendo .id, .lid, .phoneNumber, .name, etc.
|
|
1072
|
+
|
|
1073
|
+
// Busca unificada de chat: localiza a conversa mesmo se foi iniciada com PN ou com LID
|
|
1074
|
+
const chat = store.getChat('12345678901234@lid')
|
|
1075
|
+
|
|
1076
|
+
// Carregamento de mensagens com fallback cruzado automático entre LID e PN
|
|
1077
|
+
const messages = await store.loadMessages('12345678901234@lid', 25)
|
|
674
1078
|
```
|
|
675
1079
|
|
|
676
1080
|
---
|
|
@@ -713,6 +1117,23 @@ await sock.addMessageLabel(jid, 'mensagem_id_456', 'label_id_123')
|
|
|
713
1117
|
await sock.removeMessageLabel(jid, 'mensagem_id_456', 'label_id_123')
|
|
714
1118
|
```
|
|
715
1119
|
|
|
1120
|
+
### Respostas Rápidas (Quick Replies)
|
|
1121
|
+
|
|
1122
|
+
Para contas WhatsApp Business, gerencie respostas rápidas acessíveis via atalhos:
|
|
1123
|
+
|
|
1124
|
+
```javascript
|
|
1125
|
+
// Criar ou atualizar resposta rápida
|
|
1126
|
+
await sock.addOrEditQuickReply({
|
|
1127
|
+
id: 'qr_ola',
|
|
1128
|
+
shortcut: '/ola',
|
|
1129
|
+
message: 'Olá! Seja muito bem-vindo à Áreum Tecnologia. Como podemos te ajudar hoje?',
|
|
1130
|
+
keywords: ['ola', 'ajuda', 'suporte', 'inicio']
|
|
1131
|
+
})
|
|
1132
|
+
|
|
1133
|
+
// Remover resposta rápida pelo ID
|
|
1134
|
+
await sock.removeQuickReply('qr_ola')
|
|
1135
|
+
```
|
|
1136
|
+
|
|
716
1137
|
---
|
|
717
1138
|
|
|
718
1139
|
## 👥 Gerenciamento de Grupos
|
|
@@ -728,6 +1149,10 @@ console.log('Grupo criado com ID:', grupo.id)
|
|
|
728
1149
|
// Parâmetros de ação: 'add' | 'remove' | 'promote' | 'demote'
|
|
729
1150
|
await sock.groupParticipantsUpdate(grupo.id, ['5511888888888@s.whatsapp.net'], 'add')
|
|
730
1151
|
|
|
1152
|
+
// Obter dados/metadados de um grupo ANTES de entrar usando o código de convite
|
|
1153
|
+
const infoConvite = await sock.groupGetInviteInfo('ABcdEFghIJklMnOpQrStUv')
|
|
1154
|
+
console.log(`Nome do grupo no convite: ${infoConvite.subject}`)
|
|
1155
|
+
|
|
731
1156
|
// Obter o código/link de convite do grupo
|
|
732
1157
|
const codigoConvite = await sock.groupInviteCode(grupo.id)
|
|
733
1158
|
console.log(`Link: https://chat.whatsapp.com/${codigoConvite}`)
|
|
@@ -738,6 +1163,15 @@ const novoCodigo = await sock.groupRevokeInvite(grupo.id)
|
|
|
738
1163
|
// Entrar em um grupo usando um código de convite (apenas o código, sem o domínio completo)
|
|
739
1164
|
const resposta = await sock.groupAcceptInvite('ABcdEFghIJklMnOpQrStUv')
|
|
740
1165
|
|
|
1166
|
+
// Alterar o assunto (título) do grupo
|
|
1167
|
+
await sock.groupUpdateSubject(grupo.id, 'Novo Nome do Grupo')
|
|
1168
|
+
|
|
1169
|
+
// Alterar a descrição do grupo
|
|
1170
|
+
await sock.groupUpdateDescription(grupo.id, 'Regras do grupo e links importantes.')
|
|
1171
|
+
|
|
1172
|
+
// Sair do grupo
|
|
1173
|
+
await sock.groupLeave(grupo.id)
|
|
1174
|
+
|
|
741
1175
|
// Obter a lista de pessoas aguardando aprovação para entrar no grupo
|
|
742
1176
|
const solicitacoes = await sock.groupRequestParticipantsList(grupo.id)
|
|
743
1177
|
console.log(solicitacoes)
|
|
@@ -776,30 +1210,63 @@ sock.ev.on('group.member-tag.update', (update) => {
|
|
|
776
1210
|
|
|
777
1211
|
---
|
|
778
1212
|
|
|
779
|
-
## 📢 Newsletters (
|
|
1213
|
+
## 📢 Newsletters / Canais v2 (Pilar 3)
|
|
780
1214
|
|
|
781
|
-
O **WaSockets** traz suporte avançado para a criação e
|
|
1215
|
+
O **WaSockets** traz suporte avançado para a criação, monitoramento, consumo e interação em Newsletters (Canais de Transmissão públicos do WhatsApp):
|
|
782
1216
|
|
|
783
1217
|
```javascript
|
|
784
|
-
// Criar uma Newsletter (Canal)
|
|
1218
|
+
// 1. Criar uma Newsletter (Canal)
|
|
785
1219
|
const canal = await sock.newsletterCreate('Notícias Tecnológicas Áreum', 'Canal oficial de novidades')
|
|
786
1220
|
console.log('Canal criado com ID:', canal.id)
|
|
787
1221
|
|
|
788
|
-
// Obter metadados de um Canal público pelo ID
|
|
1222
|
+
// 2. Obter metadados de um Canal público pelo ID ou Invite Code
|
|
789
1223
|
const metadadosCanal = await sock.newsletterMetadata('JID', canal.id)
|
|
790
1224
|
console.log('Nome do Canal:', metadadosCanal.name)
|
|
791
1225
|
|
|
792
|
-
// Listar
|
|
1226
|
+
// 3. Listar todos os Canais inscritos
|
|
793
1227
|
const canaisInscritos = await sock.newsletterSubscribed()
|
|
794
1228
|
console.log('Canais que eu sigo:', canaisInscritos)
|
|
795
1229
|
|
|
796
|
-
//
|
|
1230
|
+
// 4. Buscar e decodificar mensagens do Canal (com contagem de visualizações e reações)
|
|
1231
|
+
const { messages } = await sock.newsletterFetchMessages(canal.id, 20)
|
|
1232
|
+
for (const msg of messages) {
|
|
1233
|
+
console.log(`[ID: ${msg.server_id}] Visualizações: ${msg.views}`)
|
|
1234
|
+
console.log('Conteúdo:', msg.message?.conversation || msg.message?.extendedTextMessage?.text)
|
|
1235
|
+
console.log('Reações:', msg.reactions) // [{ code: '👍', count: 12 }, { code: '❤️', count: 5 }]
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
// 5. Buscar mensagem individual do Canal
|
|
1239
|
+
const singleMsg = await sock.newsletterFetchMessage(canal.id, '12345')
|
|
1240
|
+
|
|
1241
|
+
// 6. Consultar contadores de reações de uma postagem
|
|
1242
|
+
const reacoes = await sock.newsletterFetchReactions(canal.id, '12345')
|
|
1243
|
+
console.log('Reações do post:', reacoes)
|
|
1244
|
+
|
|
1245
|
+
// 7. Reagir a uma postagem do Canal (suporta server_id, id ou chave da mensagem)
|
|
1246
|
+
await sock.newsletterReactMessage(canal.id, '12345', '🔥')
|
|
1247
|
+
|
|
1248
|
+
// 8. Seguir / Deixar de Seguir
|
|
797
1249
|
await sock.newsletterFollow(canal.id)
|
|
798
1250
|
await sock.newsletterUnfollow(canal.id)
|
|
799
1251
|
|
|
800
|
-
// Silenciar / Ativar notificações
|
|
1252
|
+
// 9. Silenciar / Ativar notificações
|
|
801
1253
|
await sock.newsletterMute(canal.id)
|
|
802
1254
|
await sock.newsletterUnmute(canal.id)
|
|
1255
|
+
await sock.newsletterToggleMute(canal.id, true) // ou false para desativar
|
|
1256
|
+
|
|
1257
|
+
// 10. Atualizar nome, descrição ou foto do Canal (Admins)
|
|
1258
|
+
await sock.newsletterUpdateName(canal.id, 'Novo Nome do Canal')
|
|
1259
|
+
await sock.newsletterUpdateDescription(canal.id, 'Nova descrição detalhada do canal')
|
|
1260
|
+
await sock.newsletterUpdatePicture(canal.id, './novo_avatar_canal.jpg')
|
|
1261
|
+
await sock.newsletterRemovePicture(canal.id)
|
|
1262
|
+
|
|
1263
|
+
// 11. Consultar inscritos e administradores
|
|
1264
|
+
const inscritos = await sock.newsletterSubscribers(canal.id)
|
|
1265
|
+
const totalAdmins = await sock.newsletterAdminCount(canal.id)
|
|
1266
|
+
|
|
1267
|
+
// 12. Transferir propriedade ou excluir o Canal
|
|
1268
|
+
await sock.newsletterChangeOwner(canal.id, '5511888888888@s.whatsapp.net')
|
|
1269
|
+
await sock.newsletterDelete(canal.id)
|
|
803
1270
|
```
|
|
804
1271
|
|
|
805
1272
|
---
|
|
@@ -878,12 +1345,233 @@ await sock.productUpdate(novoProduto.id, {
|
|
|
878
1345
|
price: 5990
|
|
879
1346
|
})
|
|
880
1347
|
|
|
1348
|
+
// Obter detalhes de um único produto
|
|
1349
|
+
const produto = await sock.getProduct(sock.user.id, novoProduto.id)
|
|
1350
|
+
console.log('Detalhes do Produto:', produto)
|
|
1351
|
+
|
|
881
1352
|
// Remover produtos do catálogo (aceita um array de IDs de produtos)
|
|
882
1353
|
await sock.productDelete([novoProduto.id])
|
|
883
1354
|
```
|
|
884
1355
|
|
|
885
1356
|
---
|
|
886
1357
|
|
|
1358
|
+
## 👥 Grupos, Comunidades v2 e Moderação Avançada
|
|
1359
|
+
|
|
1360
|
+
O **WaSockets** oferece um conjunto completo e modernizado para gerenciamento profissional de Grupos e Comunidades no WhatsApp.
|
|
1361
|
+
|
|
1362
|
+
### Gestão e Moderação de Entrada (Approval Mode)
|
|
1363
|
+
|
|
1364
|
+
Controle quem pode entrar no grupo através do fluxo oficial de aprovação de membros:
|
|
1365
|
+
|
|
1366
|
+
```javascript
|
|
1367
|
+
const groupJid = '1234567890-987654@g.us'
|
|
1368
|
+
|
|
1369
|
+
// Ativar modo de aprovação obrigatória de novos membros
|
|
1370
|
+
await sock.groupMembershipApprovalMode(groupJid, 'on') // ou true / 'off'
|
|
1371
|
+
|
|
1372
|
+
// Listar participantes aguardando aprovação
|
|
1373
|
+
const pendentes = await sock.groupRequestParticipantsList(groupJid)
|
|
1374
|
+
console.log('Solicitações pendentes:', pendentes)
|
|
1375
|
+
|
|
1376
|
+
// Aprovar participantes pendentes (aceita string única ou array)
|
|
1377
|
+
await sock.groupApprovePendingParticipants(groupJid, ['5511999999999@s.whatsapp.net'])
|
|
1378
|
+
|
|
1379
|
+
// Rejeitar participantes pendentes
|
|
1380
|
+
await sock.groupRejectPendingParticipants(groupJid, ['5511888888888@s.whatsapp.net'])
|
|
1381
|
+
```
|
|
1382
|
+
|
|
1383
|
+
### Configuração Unificada de Políticas do Grupo
|
|
1384
|
+
|
|
1385
|
+
Altere facilmente todas as diretrizes de segurança e permissões do grupo em uma única chamada:
|
|
1386
|
+
|
|
1387
|
+
```javascript
|
|
1388
|
+
await sock.groupUpdatePermissions(groupJid, {
|
|
1389
|
+
announce: true, // true: apenas admins enviam mensagens; false: todos
|
|
1390
|
+
restrict: true, // true: apenas admins editam dados do grupo; false: todos
|
|
1391
|
+
memberAddMode: 'admin_add', // 'admin_add' ou 'all_member_add'
|
|
1392
|
+
approvalMode: true, // Exigir aprovação de admin para novos participantes
|
|
1393
|
+
ephemeral: 86400 // Mensagens temporárias (24h = 86400s, 7 dias = 604800s, false = desativar)
|
|
1394
|
+
})
|
|
1395
|
+
```
|
|
1396
|
+
|
|
1397
|
+
### Menção a Todos os Membros (@everyone / Mention All)
|
|
1398
|
+
|
|
1399
|
+
Notifique ou mencione todos os participantes de um grupo de forma prática e sem boilerplate:
|
|
1400
|
+
|
|
1401
|
+
```javascript
|
|
1402
|
+
// Método direto
|
|
1403
|
+
await sock.groupSendMentionAll(groupJid, '📢 Atenção a todos os membros: reunião às 15h!')
|
|
1404
|
+
|
|
1405
|
+
// Ou apenas para administradores, excluindo a si próprio:
|
|
1406
|
+
await sock.groupSendMentionAll(groupJid, 'Aviso importante aos administradores', {
|
|
1407
|
+
adminsOnly: true,
|
|
1408
|
+
excludeMe: true
|
|
1409
|
+
})
|
|
1410
|
+
|
|
1411
|
+
// Ou diretamente através do sendMessage usando o parâmetro mentionAll:
|
|
1412
|
+
await sock.sendMessage(groupJid, {
|
|
1413
|
+
text: 'Olá a todos!',
|
|
1414
|
+
mentionAll: true
|
|
1415
|
+
})
|
|
1416
|
+
```
|
|
1417
|
+
|
|
1418
|
+
### Extração Rápida de Administradores e Membros
|
|
1419
|
+
|
|
1420
|
+
```javascript
|
|
1421
|
+
// Retorna array de JIDs apenas de administradores e criador
|
|
1422
|
+
const adminJids = await sock.groupGetAdminJids(groupJid)
|
|
1423
|
+
|
|
1424
|
+
// Retorna lista completa normalizada de participantes com status de admin e LID
|
|
1425
|
+
const participantes = await sock.groupGetParticipants(groupJid)
|
|
1426
|
+
```
|
|
1427
|
+
|
|
1428
|
+
### Comunidades v2 (Subgrupos e Anúncios)
|
|
1429
|
+
|
|
1430
|
+
Gerencie Comunidades do WhatsApp com suporte a separação de subgrupos e grupo de avisos geral:
|
|
1431
|
+
|
|
1432
|
+
```javascript
|
|
1433
|
+
// Criar uma comunidade
|
|
1434
|
+
const comunidade = await sock.communityCreate('Minha Comunidade', 'Descrição da comunidade')
|
|
1435
|
+
|
|
1436
|
+
// Vincular um grupo existente como subgrupo da comunidade
|
|
1437
|
+
await sock.communityLinkGroup(groupJid, comunidade.id)
|
|
1438
|
+
|
|
1439
|
+
// Desvincular um subgrupo da comunidade
|
|
1440
|
+
await sock.communityUnlinkGroup(groupJid, comunidade.id)
|
|
1441
|
+
|
|
1442
|
+
// Obter subgrupos organizados (grupo padrão de anúncios vs subgrupos comuns)
|
|
1443
|
+
const { defaultSubGroup, subGroups, allGroups } = await sock.communityFetchSubGroups(comunidade.id)
|
|
1444
|
+
console.log('Grupo Geral de Anúncios:', defaultSubGroup)
|
|
1445
|
+
console.log('Subgrupos de discussão:', subGroups)
|
|
1446
|
+
|
|
1447
|
+
// Gerenciar aprovações de entrada na Comunidade
|
|
1448
|
+
await sock.communityMembershipApprovalMode(comunidade.id, 'on')
|
|
1449
|
+
await sock.communityApprovePendingParticipants(comunidade.id, ['5511999999999@s.whatsapp.net'])
|
|
1450
|
+
```
|
|
1451
|
+
|
|
1452
|
+
### Mensagens de Visualização Única (View Once)
|
|
1453
|
+
|
|
1454
|
+
Envie imagens, vídeos ou mídias efêmeras com a flag `viewOnce: true`:
|
|
1455
|
+
|
|
1456
|
+
```javascript
|
|
1457
|
+
await sock.sendMessage(jid, {
|
|
1458
|
+
image: { url: './comprovante.jpg' },
|
|
1459
|
+
caption: 'Comprovante confidencial',
|
|
1460
|
+
viewOnce: true
|
|
1461
|
+
})
|
|
1462
|
+
```
|
|
1463
|
+
|
|
1464
|
+
---
|
|
1465
|
+
|
|
1466
|
+
## 🧩 Arquitetura de Plugins e Middlewares
|
|
1467
|
+
|
|
1468
|
+
O **WaSockets** introduz uma arquitetura modular de plugins e ciclo de vida de middlewares que permite estender o socket de maneira limpa, sem monkey-patching.
|
|
1469
|
+
|
|
1470
|
+
### Criando e Instalando Plugins
|
|
1471
|
+
|
|
1472
|
+
Um plugin pode ser uma função simples ou um objeto estruturado:
|
|
1473
|
+
|
|
1474
|
+
```javascript
|
|
1475
|
+
// Exemplo de Plugin de Boas-Vindas ou Auto-Resposta
|
|
1476
|
+
const meuPluginBot = {
|
|
1477
|
+
name: 'auto-reply-plugin',
|
|
1478
|
+
version: '1.0.0',
|
|
1479
|
+
description: 'Responde automaticamente a palavras-chave',
|
|
1480
|
+
install(sock, options, manager) {
|
|
1481
|
+
console.log('Plugin instalado com opções:', options)
|
|
1482
|
+
|
|
1483
|
+
// Escuta eventos normais da conexão
|
|
1484
|
+
sock.ev.on('messages.upsert', async ({ messages, type }) => {
|
|
1485
|
+
if (type !== 'notify') return
|
|
1486
|
+
for (const msg of messages) {
|
|
1487
|
+
if (!msg.key.fromMe && msg.message?.conversation === '!ping') {
|
|
1488
|
+
await sock.sendMessage(msg.key.remoteJid, { text: '🏓 Pong via Plugin!' })
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
})
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
// Instalação do plugin no socket
|
|
1496
|
+
sock.use(meuPluginBot, { prefix: '!' })
|
|
1497
|
+
|
|
1498
|
+
// Listar plugins ativos
|
|
1499
|
+
console.log('Plugins ativos:', sock.listPlugins())
|
|
1500
|
+
```
|
|
1501
|
+
|
|
1502
|
+
### Middlewares de Interceptação de Mensagens
|
|
1503
|
+
|
|
1504
|
+
Intercepte ou cancele envios e recebimentos antes que cheguem à rede:
|
|
1505
|
+
|
|
1506
|
+
```javascript
|
|
1507
|
+
// Intercepta qualquer mensagem antes do envio (retornar false cancela o envio)
|
|
1508
|
+
sock.registerMiddleware('beforeSendMessage', async ({ jid, content, options }, socket) => {
|
|
1509
|
+
console.log(`Enviando mensagem para ${jid}...`)
|
|
1510
|
+
|
|
1511
|
+
// Bloquear envio se contiver palavras proibidas
|
|
1512
|
+
if (typeof content?.text === 'string' && content.text.includes('palavra_bloqueada')) {
|
|
1513
|
+
console.warn('Mensagem bloqueada por política de segurança.')
|
|
1514
|
+
return false // Cancela o disparo
|
|
1515
|
+
}
|
|
1516
|
+
})
|
|
1517
|
+
|
|
1518
|
+
// Executa após a mensagem ser enviada com sucesso
|
|
1519
|
+
sock.registerMiddleware('afterSendMessage', async ({ jid, content, fullMsg }, socket) => {
|
|
1520
|
+
console.log(`Mensagem ${fullMsg.key.id} entregue ao servidor com sucesso!`)
|
|
1521
|
+
})
|
|
1522
|
+
```
|
|
1523
|
+
|
|
1524
|
+
---
|
|
1525
|
+
|
|
1526
|
+
## ⚡ Alta Performance, Cache e Controle de Memória
|
|
1527
|
+
|
|
1528
|
+
### Cache Integrado de Metadados de Grupo (TTL LRU)
|
|
1529
|
+
|
|
1530
|
+
Por padrão, o **WaSockets** ativa um cache inteligente com expiração por tempo (TTL de 5 minutos e limite de grupos em memória). Ao enviar mensagens para grupos ou listar participantes, as requisições repetidas ao WhatsApp são evitadas, acelerando disparos em massa em até 10x:
|
|
1531
|
+
|
|
1532
|
+
```javascript
|
|
1533
|
+
const sock = makeWASocket({
|
|
1534
|
+
enableGroupCache: true // Ativado por padrão com TTL de 5 minutos
|
|
1535
|
+
})
|
|
1536
|
+
```
|
|
1537
|
+
|
|
1538
|
+
### Proteção de Memória na Store (`makeInMemoryStore`)
|
|
1539
|
+
|
|
1540
|
+
Evite vazamento de memória em bots de alta demanda com limpeza automática e limite configurável de mensagens por chat:
|
|
1541
|
+
|
|
1542
|
+
```javascript
|
|
1543
|
+
const store = makeInMemoryStore({
|
|
1544
|
+
maxMessagesPerChat: 200 // Limita o histórico a 200 mensagens por chat em RAM (padrão: 500)
|
|
1545
|
+
})
|
|
1546
|
+
|
|
1547
|
+
// Limpeza manual sob demanda
|
|
1548
|
+
store.pruneMessages(groupJid, 50) // Mantém apenas as últimas 50 mensagens do chat especificado
|
|
1549
|
+
store.pruneMessages(undefined, 100) // Trunca todos os chats para no máximo 100 mensagens
|
|
1550
|
+
|
|
1551
|
+
// Obter contagem de mensagens armazenadas
|
|
1552
|
+
const qtdTotal = store.getMessageCount()
|
|
1553
|
+
const qtdChat = store.getMessageCount(groupJid)
|
|
1554
|
+
|
|
1555
|
+
// Limpar mensagens de um chat ou resetar toda a memória
|
|
1556
|
+
store.clear(groupJid)
|
|
1557
|
+
```
|
|
1558
|
+
|
|
1559
|
+
---
|
|
1560
|
+
|
|
1561
|
+
## 🔷 Suporte Completo a TypeScript
|
|
1562
|
+
|
|
1563
|
+
O **WaSockets** inclui definições de tipo completas em `lib/index.d.ts` e exporta a tipagem de todos os métodos dos 5 pilares, interfaces de mensagens, eventos e plugins:
|
|
1564
|
+
|
|
1565
|
+
```typescript
|
|
1566
|
+
import makeWASocket, { WASocket, AnyMessageContent, DisconnectReason, GroupMetadata } from '@areumtecnologia/wasockets'
|
|
1567
|
+
|
|
1568
|
+
const sock: WASocket = makeWASocket({
|
|
1569
|
+
printQRInTerminal: true
|
|
1570
|
+
})
|
|
1571
|
+
```
|
|
1572
|
+
|
|
1573
|
+
---
|
|
1574
|
+
|
|
887
1575
|
## 🔒 Configurações de Privacidade
|
|
888
1576
|
|
|
889
1577
|
```javascript
|
|
@@ -904,6 +1592,26 @@ await sock.updateOnlinePrivacy('match_last_seen')
|
|
|
904
1592
|
// Atualizar privacidade das confirmações de leitura (ticks azuis)
|
|
905
1593
|
// Valores aceitos: 'all' | 'none'
|
|
906
1594
|
await sock.updateReadReceiptsPrivacy('none')
|
|
1595
|
+
|
|
1596
|
+
// Atualizar privacidade da Foto de Perfil
|
|
1597
|
+
// Valores aceitos: 'all' | 'contacts' | 'contact_blacklist' | 'none'
|
|
1598
|
+
await sock.updateProfilePicturePrivacy('contacts')
|
|
1599
|
+
|
|
1600
|
+
// Atualizar privacidade do Recado/Status (About)
|
|
1601
|
+
// Valores aceitos: 'all' | 'contacts' | 'contact_blacklist' | 'none'
|
|
1602
|
+
await sock.updateStatusPrivacy('contacts')
|
|
1603
|
+
|
|
1604
|
+
// Atualizar quem pode adicionar você a grupos
|
|
1605
|
+
// Valores aceitos: 'all' | 'contacts' | 'contact_blacklist'
|
|
1606
|
+
await sock.updateGroupsAddPrivacy('contacts')
|
|
1607
|
+
|
|
1608
|
+
// Silenciar chamadas de números desconhecidos
|
|
1609
|
+
// Valores aceitos: 'all' (permite todos) | 'known' (apenas contatos conhecidos)
|
|
1610
|
+
await sock.updateCallPrivacy('known')
|
|
1611
|
+
|
|
1612
|
+
// Consultar todas as configurações de privacidade ativas da conta
|
|
1613
|
+
const privacySettings = await sock.fetchPrivacySettings()
|
|
1614
|
+
console.log('Configurações de privacidade atuais:', privacySettings)
|
|
907
1615
|
```
|
|
908
1616
|
|
|
909
1617
|
---
|