@systemzero/baileys 1.0.4 → 1.0.6
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 +595 -762
- package/lib/Defaults/index.js +9 -3
- package/lib/MB.cjs +8 -0
- package/lib/MessageBuilder.cjs +2509 -0
- package/lib/Socket/chats.js +12 -1
- package/lib/Socket/groups.js +13 -4
- package/lib/Socket/messages-recv.js +36 -2
- package/lib/Socket/messages-recv.js.bak +1273 -0
- package/lib/Socket/messages-send.js +2 -1
- package/lib/Types/Message.js +7 -0
- package/lib/Utils/bad-mac-handler.js +158 -0
- package/lib/Utils/get-best-version.js +41 -0
- package/lib/Utils/get-name.d.ts +1 -0
- package/lib/Utils/get-name.js +54 -0
- package/lib/Utils/group-status-detection.js +113 -0
- package/lib/Utils/index.js +7 -0
- package/lib/Utils/logger.js +4 -1
- package/lib/Utils/messages-media.js +42 -3
- package/lib/Utils/messages.js +641 -10
- package/lib/Utils/payment-detection.js +212 -0
- package/lib/Utils/payment-guard.d.ts +15 -0
- package/lib/Utils/payment-guard.js +142 -0
- package/lib/Utils/resolve-lid-phone.js +30 -0
- package/lib/WABinary/jid-utils.js +245 -1
- package/package.json +4 -3
- package/lib/Defaults/index.d.ts.map +0 -1
- package/lib/Defaults/index.js.map +0 -1
- package/lib/Signal/Group/ciphertext-message.d.ts.map +0 -1
- package/lib/Signal/Group/ciphertext-message.js.map +0 -1
- package/lib/Signal/Group/group-session-builder.d.ts.map +0 -1
- package/lib/Signal/Group/group-session-builder.js.map +0 -1
- package/lib/Signal/Group/group_cipher.d.ts.map +0 -1
- package/lib/Signal/Group/group_cipher.js.map +0 -1
- package/lib/Signal/Group/index.d.ts.map +0 -1
- package/lib/Signal/Group/index.js.map +0 -1
- package/lib/Signal/Group/keyhelper.d.ts.map +0 -1
- package/lib/Signal/Group/keyhelper.js.map +0 -1
- package/lib/Signal/Group/sender-chain-key.d.ts.map +0 -1
- package/lib/Signal/Group/sender-chain-key.js.map +0 -1
- package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +0 -1
- package/lib/Signal/Group/sender-key-distribution-message.js.map +0 -1
- package/lib/Signal/Group/sender-key-message.d.ts.map +0 -1
- package/lib/Signal/Group/sender-key-message.js.map +0 -1
- package/lib/Signal/Group/sender-key-name.d.ts.map +0 -1
- package/lib/Signal/Group/sender-key-name.js.map +0 -1
- package/lib/Signal/Group/sender-key-record.d.ts.map +0 -1
- package/lib/Signal/Group/sender-key-record.js.map +0 -1
- package/lib/Signal/Group/sender-key-state.d.ts.map +0 -1
- package/lib/Signal/Group/sender-key-state.js.map +0 -1
- package/lib/Signal/Group/sender-message-key.d.ts.map +0 -1
- package/lib/Signal/Group/sender-message-key.js.map +0 -1
- package/lib/Signal/libsignal.d.ts.map +0 -1
- package/lib/Signal/libsignal.js.map +0 -1
- package/lib/Signal/lid-mapping.d.ts.map +0 -1
- package/lib/Signal/lid-mapping.js.map +0 -1
- package/lib/Socket/Client/index.d.ts.map +0 -1
- package/lib/Socket/Client/index.js.map +0 -1
- package/lib/Socket/Client/types.d.ts.map +0 -1
- package/lib/Socket/Client/types.js.map +0 -1
- package/lib/Socket/Client/websocket.d.ts.map +0 -1
- package/lib/Socket/Client/websocket.js.map +0 -1
- package/lib/Socket/business.d.ts.map +0 -1
- package/lib/Socket/business.js.map +0 -1
- package/lib/Socket/chats.d.ts.map +0 -1
- package/lib/Socket/chats.js.map +0 -1
- package/lib/Socket/communities.d.ts.map +0 -1
- package/lib/Socket/communities.js.map +0 -1
- package/lib/Socket/groups.d.ts.map +0 -1
- package/lib/Socket/groups.js.map +0 -1
- package/lib/Socket/index.d.ts.map +0 -1
- package/lib/Socket/index.js.map +0 -1
- package/lib/Socket/messages-recv.d.ts.map +0 -1
- package/lib/Socket/messages-recv.js.map +0 -1
- package/lib/Socket/messages-send.d.ts.map +0 -1
- package/lib/Socket/messages-send.js.map +0 -1
- package/lib/Socket/mex.d.ts.map +0 -1
- package/lib/Socket/mex.js.map +0 -1
- package/lib/Socket/newsletter.d.ts.map +0 -1
- package/lib/Socket/newsletter.js.map +0 -1
- package/lib/Socket/socket.d.ts.map +0 -1
- package/lib/Socket/socket.js.map +0 -1
- package/lib/Types/Auth.d.ts.map +0 -1
- package/lib/Types/Auth.js.map +0 -1
- package/lib/Types/Bussines.d.ts.map +0 -1
- package/lib/Types/Bussines.js.map +0 -1
- package/lib/Types/Call.d.ts.map +0 -1
- package/lib/Types/Call.js.map +0 -1
- package/lib/Types/Chat.d.ts.map +0 -1
- package/lib/Types/Chat.js.map +0 -1
- package/lib/Types/Contact.d.ts.map +0 -1
- package/lib/Types/Contact.js.map +0 -1
- package/lib/Types/Events.d.ts.map +0 -1
- package/lib/Types/Events.js.map +0 -1
- package/lib/Types/GroupMetadata.d.ts.map +0 -1
- package/lib/Types/GroupMetadata.js.map +0 -1
- package/lib/Types/Label.d.ts.map +0 -1
- package/lib/Types/Label.js.map +0 -1
- package/lib/Types/LabelAssociation.d.ts.map +0 -1
- package/lib/Types/LabelAssociation.js.map +0 -1
- package/lib/Types/Message.d.ts.map +0 -1
- package/lib/Types/Message.js.map +0 -1
- package/lib/Types/Newsletter.d.ts.map +0 -1
- package/lib/Types/Newsletter.js.map +0 -1
- package/lib/Types/Product.d.ts.map +0 -1
- package/lib/Types/Product.js.map +0 -1
- package/lib/Types/Signal.d.ts.map +0 -1
- package/lib/Types/Signal.js.map +0 -1
- package/lib/Types/Socket.d.ts.map +0 -1
- package/lib/Types/Socket.js.map +0 -1
- package/lib/Types/State.d.ts.map +0 -1
- package/lib/Types/State.js.map +0 -1
- package/lib/Types/USync.d.ts.map +0 -1
- package/lib/Types/USync.js.map +0 -1
- package/lib/Types/index.d.ts.map +0 -1
- package/lib/Types/index.js.map +0 -1
- package/lib/Utils/auth-utils.d.ts.map +0 -1
- package/lib/Utils/auth-utils.js.map +0 -1
- package/lib/Utils/browser-utils.d.ts.map +0 -1
- package/lib/Utils/browser-utils.js.map +0 -1
- package/lib/Utils/business.d.ts.map +0 -1
- package/lib/Utils/business.js.map +0 -1
- package/lib/Utils/chat-utils.d.ts.map +0 -1
- package/lib/Utils/chat-utils.js.map +0 -1
- package/lib/Utils/crypto.d.ts.map +0 -1
- package/lib/Utils/crypto.js.map +0 -1
- package/lib/Utils/decode-wa-message.d.ts.map +0 -1
- package/lib/Utils/decode-wa-message.js.map +0 -1
- package/lib/Utils/event-buffer.d.ts.map +0 -1
- package/lib/Utils/event-buffer.js.map +0 -1
- package/lib/Utils/generics.d.ts.map +0 -1
- package/lib/Utils/generics.js.map +0 -1
- package/lib/Utils/history.d.ts.map +0 -1
- package/lib/Utils/history.js.map +0 -1
- package/lib/Utils/index.d.ts.map +0 -1
- package/lib/Utils/index.js.map +0 -1
- package/lib/Utils/link-preview.d.ts.map +0 -1
- package/lib/Utils/link-preview.js.map +0 -1
- package/lib/Utils/logger.d.ts.map +0 -1
- package/lib/Utils/logger.js.map +0 -1
- package/lib/Utils/lt-hash.d.ts.map +0 -1
- package/lib/Utils/lt-hash.js.map +0 -1
- package/lib/Utils/make-mutex.d.ts.map +0 -1
- package/lib/Utils/make-mutex.js.map +0 -1
- package/lib/Utils/message-retry-manager.d.ts.map +0 -1
- package/lib/Utils/message-retry-manager.js.map +0 -1
- package/lib/Utils/messages-media.d.ts.map +0 -1
- package/lib/Utils/messages-media.js.map +0 -1
- package/lib/Utils/messages.d.ts.map +0 -1
- package/lib/Utils/messages.js.map +0 -1
- package/lib/Utils/noise-handler.d.ts.map +0 -1
- package/lib/Utils/noise-handler.js.map +0 -1
- package/lib/Utils/pre-key-manager.d.ts.map +0 -1
- package/lib/Utils/pre-key-manager.js.map +0 -1
- package/lib/Utils/process-message.d.ts.map +0 -1
- package/lib/Utils/process-message.js.map +0 -1
- package/lib/Utils/signal.d.ts.map +0 -1
- package/lib/Utils/signal.js.map +0 -1
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +0 -1
- package/lib/Utils/use-multi-file-auth-state.js.map +0 -1
- package/lib/Utils/validate-connection.d.ts.map +0 -1
- package/lib/Utils/validate-connection.js.map +0 -1
- package/lib/WABinary/constants.d.ts.map +0 -1
- package/lib/WABinary/constants.js.map +0 -1
- package/lib/WABinary/decode.d.ts.map +0 -1
- package/lib/WABinary/decode.js.map +0 -1
- package/lib/WABinary/encode.d.ts.map +0 -1
- package/lib/WABinary/encode.js.map +0 -1
- package/lib/WABinary/generic-utils.d.ts.map +0 -1
- package/lib/WABinary/generic-utils.js.map +0 -1
- package/lib/WABinary/index.d.ts.map +0 -1
- package/lib/WABinary/index.js.map +0 -1
- package/lib/WABinary/jid-utils.d.ts.map +0 -1
- package/lib/WABinary/jid-utils.js.map +0 -1
- package/lib/WABinary/types.d.ts.map +0 -1
- package/lib/WABinary/types.js.map +0 -1
- package/lib/WAM/BinaryInfo.d.ts.map +0 -1
- package/lib/WAM/BinaryInfo.js.map +0 -1
- package/lib/WAM/constants.d.ts.map +0 -1
- package/lib/WAM/constants.js.map +0 -1
- package/lib/WAM/encode.d.ts.map +0 -1
- package/lib/WAM/encode.js.map +0 -1
- package/lib/WAM/index.d.ts.map +0 -1
- package/lib/WAM/index.js.map +0 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +0 -1
- package/lib/WAUSync/Protocols/index.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/index.js.map +0 -1
- package/lib/WAUSync/USyncQuery.d.ts.map +0 -1
- package/lib/WAUSync/USyncQuery.js.map +0 -1
- package/lib/WAUSync/USyncUser.d.ts.map +0 -1
- package/lib/WAUSync/USyncUser.js.map +0 -1
- package/lib/WAUSync/index.d.ts.map +0 -1
- package/lib/WAUSync/index.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,1092 +1,925 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<img src="https://files.catbox.moe/w1m2q4.jpg" width="120" style="border-radius:16px" />
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# @systemzero/baileys
|
|
6
|
+
|
|
7
|
+
**v1.0.6** · Fork avançado do Baileys com suporte nativo a todos os tipos de mensagens do WhatsApp
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- [Imagem](#imagem)
|
|
14
|
-
- [Vídeo](#vídeo)
|
|
15
|
-
- [Áudio](#áudio)
|
|
16
|
-
- [Documento](#documento)
|
|
17
|
-
- [Sticker](#sticker)
|
|
18
|
-
- [Localização](#localização)
|
|
19
|
-
- [Contato](#contato)
|
|
20
|
-
- [Enquete (Poll)](#enquete-poll)
|
|
21
|
-
- [Reação](#reação)
|
|
22
|
-
- [Menção](#menção)
|
|
23
|
-
- [Link com Preview](#link-com-preview)
|
|
24
|
-
- [Resposta (Quoted)](#resposta-quoted)
|
|
25
|
-
- [Mensagem Editada](#mensagem-editada)
|
|
26
|
-
- [Mensagem Deletada](#mensagem-deletada)
|
|
27
|
-
- [Fixar Mensagem](#fixar-mensagem)
|
|
28
|
-
- [View Once](#view-once)
|
|
29
|
-
- [Modo Efêmero (Desaparecimento)](#modo-efêmero-desaparecimento)
|
|
30
|
-
- [🎨 Mensagens Interativas (Botões)](#-mensagens-interativas-botões)
|
|
31
|
-
- [Botões Rápidos (Quick Reply)](#botões-rápidos-quick-reply)
|
|
32
|
-
- [Lista](#lista)
|
|
33
|
-
- [Botões Nativos (interactiveButtons)](#botões-nativos-interactivebuttons)
|
|
34
|
-
- [Pagamento Nativo](#pagamento-nativo)
|
|
35
|
-
- [Produto](#produto)
|
|
36
|
-
- [🤖 Funções Rich (Meta AI Style)](#-funções-rich-meta-ai-style)
|
|
37
|
-
- [Texto Rico](#texto-rico)
|
|
38
|
-
- [Código Rico](#código-rico)
|
|
39
|
-
- [Lista Rica](#lista-rica)
|
|
40
|
-
- [Tabela Rica](#tabela-rica)
|
|
41
|
-
- [Rich Completo](#rich-completo)
|
|
42
|
-
- [Reels Ricos](#reels-ricos)
|
|
43
|
-
- [Perplexity IA](#perplexity-ia)
|
|
44
|
-
- [📁 Tipos Especiais de Mensagem](#-tipos-especiais-de-mensagem)
|
|
45
|
-
- [Álbum de Fotos/Vídeos](#álbum-de-fotosvídeos)
|
|
46
|
-
- [Evento](#evento)
|
|
47
|
-
- [Resultado de Enquete](#resultado-de-enquete)
|
|
48
|
-
- [Story de Grupo](#story-de-grupo)
|
|
49
|
-
- [Pagamento (requestPayment)](#pagamento-requestpayment)
|
|
50
|
-
- [👥 Funções de Grupo](#-funções-de-grupo)
|
|
51
|
-
- [💬 Funções de Chat](#-funções-de-chat)
|
|
52
|
-
- [🔒 Privacidade](#-privacidade)
|
|
53
|
-
- [🏷️ Labels](#️-labels)
|
|
54
|
-
- [📡 Presença](#-presença)
|
|
9
|
+
[](https://www.npmjs.com/package/@systemzero/baileys)
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
[](https://t.me/blackhzx)
|
|
12
|
+
[](https://nodejs.org)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
55
15
|
|
|
56
16
|
---
|
|
57
17
|
|
|
58
18
|
## Instalação
|
|
59
19
|
|
|
60
20
|
```bash
|
|
61
|
-
npm
|
|
62
|
-
|
|
63
|
-
|
|
21
|
+
npm i @systemzero/baileys
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Dependências opcionais:
|
|
25
|
+
```bash
|
|
26
|
+
npm i sharp # conversão de imagem para sticker pack
|
|
27
|
+
npm i @napi-rs/image # alternativa ao sharp
|
|
64
28
|
```
|
|
65
29
|
|
|
66
|
-
|
|
30
|
+
Requer `ffmpeg` instalado no sistema (com suporte a `libopus`) para conversão automática de áudio PTT e para o sistema anti-fraude de pagamento processar mídia. Confirme com `ffmpeg -encoders | grep opus`.
|
|
67
31
|
|
|
68
32
|
---
|
|
69
33
|
|
|
70
|
-
##
|
|
34
|
+
## Índice
|
|
35
|
+
|
|
36
|
+
1. [Conexão](#1-conexão)
|
|
37
|
+
2. [Mensagens de mídia](#2-mensagens-de-mídia)
|
|
38
|
+
3. [Mensagens especiais](#3-mensagens-especiais)
|
|
39
|
+
4. [Botões e interativos](#4-botões-e-interativos)
|
|
40
|
+
5. [Sticker Pack nativo](#5-sticker-pack-nativo)
|
|
41
|
+
6. [Canais Newsletter](#6-canais-newsletter)
|
|
42
|
+
7. [Enquetes com decrypt](#7-enquetes-com-decrypt)
|
|
43
|
+
8. [AI Rich](#8-ai-rich)
|
|
44
|
+
9. [LID / JID — Sistema avançado](#9-lid--jid--sistema-avançado)
|
|
45
|
+
10. [Username (@usuario)](#10-username-usuario)
|
|
46
|
+
11. [MessageBuilder — Button, ButtonV2, Carousel, AIRich](#11-messagebuilder--button-buttonv2-carousel-airich)
|
|
47
|
+
12. [Botões estendidos (v1.0.6)](#12-botões-estendidos-v106)
|
|
48
|
+
13. [Grupos](#13-grupos)
|
|
49
|
+
14. [Perfil e privacidade](#14-perfil-e-privacidade)
|
|
50
|
+
15. [Eventos do socket](#15-eventos-do-socket)
|
|
51
|
+
16. [Utilitários](#16-utilitários)
|
|
52
|
+
17. [Fixar / Desfixar mensagens](#17-fixar--desfixar-mensagens)
|
|
53
|
+
18. [Resolução de nomes (getName)](#18-resolução-de-nomes-getname)
|
|
54
|
+
19. [PTT real com qualquer formato de entrada](#19-ptt-real-com-qualquer-formato-de-entrada)
|
|
55
|
+
20. [Guard de pagamento stealth (anti-fraude)](#20-guard-de-pagamento-stealth-anti-fraude)
|
|
56
|
+
21. [Bad MAC Handler — sessões Signal](#21-bad-mac-handler--sessões-signal)
|
|
57
|
+
22. [Resolução LID → telefone via grupo](#22-resolução-lid--telefone-via-grupo)
|
|
58
|
+
23. [Versão do WhatsApp sempre atualizada](#23-versão-do-whatsapp-sempre-atualizada)
|
|
59
|
+
24. [WhatsApp Flows — Formulários interativos](#24-whatsapp-flows--formulários-interativos)
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 1. Conexão
|
|
71
64
|
|
|
72
65
|
```js
|
|
73
|
-
|
|
66
|
+
const {
|
|
67
|
+
default: makeWASocket,
|
|
68
|
+
useMultiFileAuthState,
|
|
69
|
+
DisconnectReason,
|
|
70
|
+
Browsers,
|
|
71
|
+
fetchLatestWaWebVersion
|
|
72
|
+
} = require('@systemzero/baileys')
|
|
74
73
|
|
|
75
|
-
const { state, saveCreds } = await useMultiFileAuthState('./
|
|
74
|
+
const { state, saveCreds } = await useMultiFileAuthState('./session')
|
|
75
|
+
const { version } = await fetchLatestWaWebVersion()
|
|
76
76
|
|
|
77
77
|
const sock = makeWASocket({
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
version,
|
|
79
|
+
auth: state,
|
|
80
|
+
browser: Browsers.ubuntu('Chrome'),
|
|
81
|
+
printQRInTerminal: false,
|
|
82
|
+
logger: require('pino')({ level: 'silent' }),
|
|
83
|
+
getMessage: async (key) => {
|
|
84
|
+
const msg = await store.loadMessage(key.remoteJid, key.id)
|
|
85
|
+
return msg?.message || undefined
|
|
86
|
+
}
|
|
80
87
|
})
|
|
81
88
|
|
|
82
89
|
sock.ev.on('creds.update', saveCreds)
|
|
83
90
|
|
|
84
91
|
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
|
|
85
92
|
if (connection === 'close') {
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
88
|
-
} else if (connection === 'open') {
|
|
89
|
-
console.log('✅ Conectado ao WhatsApp!')
|
|
93
|
+
const code = lastDisconnect?.error?.output?.statusCode
|
|
94
|
+
if (code !== DisconnectReason.loggedOut) startBot()
|
|
90
95
|
}
|
|
91
96
|
})
|
|
92
97
|
```
|
|
93
98
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
## 📨 Envio de Mensagens
|
|
97
|
-
|
|
98
|
-
Todas as funções de envio usam `sock.sendMessage(jid, conteúdo, opções?)`.
|
|
99
|
-
|
|
100
|
-
O `jid` é o identificador do destinatário:
|
|
101
|
-
- **Privado:** `'5511999999999@s.whatsapp.net'`
|
|
102
|
-
- **Grupo:** `'120363xxxxxxxx@g.us'`
|
|
103
|
-
- **Status:** `'status@broadcast'`
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
### Texto
|
|
99
|
+
> Veja a seção [23](#23-versão-do-whatsapp-sempre-atualizada) para um jeito mais robusto de buscar a versão, que não falha silenciosamente.
|
|
108
100
|
|
|
109
|
-
|
|
101
|
+
### Pairing Code
|
|
110
102
|
|
|
111
103
|
```js
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
})
|
|
115
|
-
```
|
|
104
|
+
// Automático
|
|
105
|
+
const code = await sock.requestPairingCode('5511999999999')
|
|
116
106
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
await sock.sendMessage(jid, {
|
|
120
|
-
text: '*negrito* _itálico_ ~tachado~ `monoespaçado`'
|
|
121
|
-
})
|
|
107
|
+
// Personalizado — exatamente 8 caracteres
|
|
108
|
+
const code = await sock.requestPairingCode('5511999999999', 'MYBOT001')
|
|
122
109
|
```
|
|
123
110
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
### Imagem
|
|
127
|
-
|
|
128
|
-
Envia uma imagem com legenda opcional. Aceita **Buffer**, **URL** ou **caminho local**.
|
|
111
|
+
### Store em memória
|
|
129
112
|
|
|
130
113
|
```js
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
114
|
+
const store = {
|
|
115
|
+
messages: {},
|
|
116
|
+
bind: (ev) => {
|
|
117
|
+
ev.on('messages.upsert', ({ messages }) => {
|
|
118
|
+
for (const msg of messages) {
|
|
119
|
+
if (!msg.key?.remoteJid) continue
|
|
120
|
+
store.messages[msg.key.remoteJid] ??= {}
|
|
121
|
+
store.messages[msg.key.remoteJid][msg.key.id] = msg
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
},
|
|
125
|
+
loadMessage: async (jid, id) => store.messages[jid]?.[id] || null
|
|
126
|
+
}
|
|
127
|
+
store.bind(sock.ev)
|
|
143
128
|
```
|
|
144
129
|
|
|
145
130
|
---
|
|
146
131
|
|
|
147
|
-
|
|
132
|
+
## 2. Mensagens de mídia
|
|
148
133
|
|
|
149
|
-
|
|
134
|
+
Todos os campos de mídia aceitam `Buffer`, `{ url: 'https://...' }` ou `{ stream }`.
|
|
150
135
|
|
|
151
136
|
```js
|
|
152
|
-
//
|
|
153
|
-
await sock.sendMessage(jid, {
|
|
154
|
-
video: { url: 'https://exemplo.com/video.mp4' },
|
|
155
|
-
caption: 'Assista esse vídeo! 🎬',
|
|
156
|
-
mimetype: 'video/mp4'
|
|
157
|
-
})
|
|
137
|
+
// Texto
|
|
138
|
+
await sock.sendMessage(jid, { text: 'Olá!' })
|
|
158
139
|
|
|
159
|
-
//
|
|
140
|
+
// Texto com menção
|
|
160
141
|
await sock.sendMessage(jid, {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
caption: 'Olha esse gif!'
|
|
142
|
+
text: '@5511...!',
|
|
143
|
+
mentions: ['5511999999999@s.whatsapp.net']
|
|
164
144
|
})
|
|
165
|
-
```
|
|
166
145
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
### Áudio
|
|
170
|
-
|
|
171
|
-
Envia um áudio. Use `ptt: true` para enviar como mensagem de voz (PTT).
|
|
146
|
+
// Imagem
|
|
147
|
+
await sock.sendMessage(jid, { image: { url: 'https://...' }, caption: 'Legenda' })
|
|
172
148
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
await sock.sendMessage(jid, {
|
|
176
|
-
audio: { url: 'https://exemplo.com/musica.mp3' },
|
|
177
|
-
mimetype: 'audio/mp4'
|
|
178
|
-
})
|
|
149
|
+
// Vídeo
|
|
150
|
+
await sock.sendMessage(jid, { video: buffer, caption: 'Legenda', gifPlayback: false })
|
|
179
151
|
|
|
180
|
-
//
|
|
181
|
-
await sock.sendMessage(jid, {
|
|
182
|
-
audio: readFileSync('./audio.ogg'),
|
|
183
|
-
mimetype: 'audio/ogg; codecs=opus',
|
|
184
|
-
ptt: true // Aparece como áudio de voz
|
|
185
|
-
})
|
|
186
|
-
```
|
|
152
|
+
// Áudio normal (música)
|
|
153
|
+
await sock.sendMessage(jid, { audio: buffer, mimetype: 'audio/mpeg', ptt: false })
|
|
187
154
|
|
|
188
|
-
|
|
155
|
+
// Nota de voz (PTT) — ver seção 19 para conversão automática de qualquer formato
|
|
156
|
+
await sock.sendMessage(jid, { audio: buffer, ptt: true })
|
|
189
157
|
|
|
190
|
-
|
|
158
|
+
// Documento
|
|
159
|
+
await sock.sendMessage(jid, { document: buffer, mimetype: 'application/pdf', fileName: 'doc.pdf' })
|
|
191
160
|
|
|
192
|
-
|
|
161
|
+
// Figurinha
|
|
162
|
+
await sock.sendMessage(jid, { sticker: buffer })
|
|
193
163
|
|
|
194
|
-
|
|
164
|
+
// Album (mínimo 2 itens)
|
|
195
165
|
await sock.sendMessage(jid, {
|
|
196
|
-
|
|
197
|
-
mimetype: 'application/pdf',
|
|
198
|
-
fileName: 'Relatório Mensal.pdf',
|
|
199
|
-
caption: 'Segue o relatório em anexo 📄'
|
|
166
|
+
album: [{ image: buffer1 }, { image: buffer2 }, { video: bufferVideo }]
|
|
200
167
|
})
|
|
201
168
|
|
|
202
|
-
//
|
|
169
|
+
// Contato
|
|
203
170
|
await sock.sendMessage(jid, {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
---
|
|
211
|
-
|
|
212
|
-
### Sticker
|
|
213
|
-
|
|
214
|
-
Envia um sticker (figurinha). Deve ser WebP ou convertido previamente.
|
|
215
|
-
|
|
216
|
-
```js
|
|
217
|
-
await sock.sendMessage(jid, {
|
|
218
|
-
sticker: readFileSync('./figurinha.webp')
|
|
171
|
+
contacts: {
|
|
172
|
+
displayName: 'João',
|
|
173
|
+
contacts: [{ vcard: 'BEGIN:VCARD\nVERSION:3.0\nFN:João\nTEL:+5511999999999\nEND:VCARD' }]
|
|
174
|
+
}
|
|
219
175
|
})
|
|
220
176
|
|
|
221
|
-
//
|
|
177
|
+
// Localização
|
|
222
178
|
await sock.sendMessage(jid, {
|
|
223
|
-
|
|
179
|
+
location: { degreesLatitude: -23.55, degreesLongitude: -46.63, name: 'São Paulo' }
|
|
224
180
|
})
|
|
225
181
|
```
|
|
226
182
|
|
|
227
183
|
---
|
|
228
184
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
Envia uma localização no mapa.
|
|
185
|
+
## 3. Mensagens especiais
|
|
232
186
|
|
|
233
187
|
```js
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
degreesLatitude: -23.5505,
|
|
237
|
-
degreesLongitude: -46.6333,
|
|
238
|
-
name: 'São Paulo, SP',
|
|
239
|
-
address: 'Av. Paulista, 1000'
|
|
240
|
-
}
|
|
241
|
-
})
|
|
242
|
-
```
|
|
188
|
+
// Reação
|
|
189
|
+
await sock.sendMessage(jid, { react: { text: '❤️', key: message.key } })
|
|
243
190
|
|
|
244
|
-
|
|
191
|
+
// Deletar
|
|
192
|
+
await sock.sendMessage(jid, { delete: message.key })
|
|
245
193
|
|
|
246
|
-
|
|
194
|
+
// Editar
|
|
195
|
+
await sock.sendMessage(jid, { edit: message.key, text: 'Texto editado' })
|
|
247
196
|
|
|
248
|
-
|
|
197
|
+
// Fixar — ver seção 17 para a versão completa
|
|
198
|
+
await sock.sendMessage(jid, { pin: message.key, type: 1 })
|
|
249
199
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
FN:João Silva
|
|
254
|
-
ORG:Empresa LTDA;
|
|
255
|
-
TEL;type=CELL;type=VOICE;waid=5511999999999:+55 11 99999-9999
|
|
256
|
-
END:VCARD`
|
|
200
|
+
// View Once
|
|
201
|
+
await sock.sendMessage(jid, { image: buffer, viewOnce: true })
|
|
202
|
+
await sock.sendMessage(jid, { image: buffer, viewOnceV2: true })
|
|
257
203
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
displayName: 'João Silva',
|
|
261
|
-
contacts: [{ vcard }]
|
|
262
|
-
}
|
|
263
|
-
})
|
|
264
|
-
```
|
|
204
|
+
// Spoiler
|
|
205
|
+
await sock.sendMessage(jid, { image: buffer, caption: '!', spoiler: true })
|
|
265
206
|
|
|
266
|
-
|
|
207
|
+
// Status de grupo
|
|
208
|
+
await sock.sendMessage(jid, { image: buffer, groupStatus: true })
|
|
267
209
|
|
|
268
|
-
|
|
210
|
+
// Efêmera
|
|
211
|
+
await sock.sendMessage(jid, { image: buffer, ephemeral: true })
|
|
269
212
|
|
|
270
|
-
|
|
213
|
+
// Lottie sticker
|
|
214
|
+
await sock.sendMessage(jid, { sticker: buffer, isLottie: true })
|
|
271
215
|
|
|
272
|
-
|
|
273
|
-
await sock.sendMessage(jid, {
|
|
274
|
-
poll: {
|
|
275
|
-
name: 'Qual sua linguagem favorita?',
|
|
276
|
-
values: ['JavaScript', 'Python', 'TypeScript', 'Go'],
|
|
277
|
-
selectableCount: 1 // Quantas opções o usuário pode escolher
|
|
278
|
-
}
|
|
279
|
-
})
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
---
|
|
216
|
+
// Mention All
|
|
217
|
+
await sock.sendMessage(jid, { text: '@all', mentionAll: true })
|
|
283
218
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
Reage a uma mensagem com um emoji.
|
|
287
|
-
|
|
288
|
-
```js
|
|
219
|
+
// External Ad Reply
|
|
289
220
|
await sock.sendMessage(jid, {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
221
|
+
text: 'Confira!',
|
|
222
|
+
externalAdReply: {
|
|
223
|
+
title: 'Título', body: 'Descrição',
|
|
224
|
+
thumbnail: bufferImg, mediaType: 1,
|
|
225
|
+
sourceUrl: 'https://systemzone.store',
|
|
226
|
+
renderLargerThumbnail: true
|
|
293
227
|
}
|
|
294
228
|
})
|
|
295
|
-
```
|
|
296
229
|
|
|
297
|
-
|
|
298
|
-
```js
|
|
230
|
+
// Enquete
|
|
299
231
|
await sock.sendMessage(jid, {
|
|
300
|
-
|
|
232
|
+
poll: { name: 'Pergunta?', values: ['A', 'B', 'C'], selectableCount: 1 }
|
|
301
233
|
})
|
|
234
|
+
|
|
235
|
+
// Encaminhar
|
|
236
|
+
const { generateForwardMessageContent, generateWAMessageFromContent } = require('@systemzero/baileys')
|
|
237
|
+
const fwd = generateForwardMessageContent(message, false)
|
|
238
|
+
const msg = generateWAMessageFromContent(jid, fwd, { quoted: m })
|
|
239
|
+
await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
|
|
302
240
|
```
|
|
303
241
|
|
|
304
|
-
|
|
242
|
+
> ⚠️ **Removido desta versão do README:** preview de link customizado (`linkPreview` manual) e áudio embutido em rodapé de card interativo (`audioFooter`). Os dois existem no proto do WhatsApp, mas em testes reais (Android e iOS) **não renderizaram corretamente** — o `audioFooter` não mostrou o player de áudio, e o `linkPreview` manual caiu num formato de card genérico em vez do esperado. Não são recursos confiáveis hoje.
|
|
305
243
|
|
|
306
|
-
|
|
244
|
+
---
|
|
307
245
|
|
|
308
|
-
|
|
246
|
+
## 4. Botões e interativos
|
|
309
247
|
|
|
310
248
|
```js
|
|
311
|
-
|
|
312
|
-
text: 'Oi @5511999999999, tudo bem?',
|
|
313
|
-
mentions: ['5511999999999@s.whatsapp.net']
|
|
314
|
-
})
|
|
315
|
-
```
|
|
249
|
+
const { generateWAMessageFromContent, proto } = require('@systemzero/baileys')
|
|
316
250
|
|
|
317
|
-
|
|
251
|
+
const msg = generateWAMessageFromContent(jid, {
|
|
252
|
+
viewOnceMessage: {
|
|
253
|
+
message: {
|
|
254
|
+
interactiveMessage: proto.Message.InteractiveMessage.create({
|
|
255
|
+
header: { title: 'Título', hasMediaAttachment: false },
|
|
256
|
+
body: { text: 'Texto' },
|
|
257
|
+
footer: { text: 'Rodapé' },
|
|
258
|
+
nativeFlowMessage: { buttons: [ /* tipos abaixo */ ] }
|
|
259
|
+
})
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}, { quoted: m })
|
|
318
263
|
|
|
319
|
-
|
|
264
|
+
await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
|
|
265
|
+
```
|
|
320
266
|
|
|
321
|
-
|
|
267
|
+
### Tipos de botão (testados e funcionais)
|
|
322
268
|
|
|
323
269
|
```js
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
})
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
---
|
|
270
|
+
// Resposta rápida
|
|
271
|
+
{ name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: 'OK', id: 'ok' }) }
|
|
330
272
|
|
|
331
|
-
|
|
273
|
+
// Link
|
|
274
|
+
{ name: 'cta_url', buttonParamsJson: JSON.stringify({ display_text: 'Abrir', url: 'https://systemzone.store' }) }
|
|
332
275
|
|
|
333
|
-
|
|
276
|
+
// Copiar
|
|
277
|
+
{ name: 'cta_copy', buttonParamsJson: JSON.stringify({ display_text: 'Copiar', copy_code: 'CODIGO' }) }
|
|
334
278
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
338
|
-
const msg = messages[0]
|
|
279
|
+
// Ligar
|
|
280
|
+
{ name: 'cta_call', buttonParamsJson: JSON.stringify({ display_text: 'Ligar', phone_number: '5511999999999' }) }
|
|
339
281
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
282
|
+
// Lista dropdown
|
|
283
|
+
{
|
|
284
|
+
name: 'single_select',
|
|
285
|
+
buttonParamsJson: JSON.stringify({
|
|
286
|
+
title: 'Escolher',
|
|
287
|
+
sections: [{ title: 'Cat', rows: [
|
|
288
|
+
{ header: 'Op1', title: 'Opção 1', description: 'Desc', id: 'op1' }
|
|
289
|
+
]}]
|
|
344
290
|
})
|
|
345
|
-
}
|
|
291
|
+
}
|
|
346
292
|
```
|
|
347
293
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
### Mensagem Editada
|
|
351
|
-
|
|
352
|
-
Edita o conteúdo de uma mensagem já enviada.
|
|
294
|
+
### Header com imagem (funciona — confirmado em teste real)
|
|
353
295
|
|
|
354
296
|
```js
|
|
297
|
+
const { generateWAMessage, generateMessageIDV2 } = require('@systemzero/baileys')
|
|
298
|
+
|
|
299
|
+
// Forma simplificada e já testada: usar `image` + `caption` direto no sendMessage,
|
|
300
|
+
// junto com nativeFlow — a lib monta o header automaticamente.
|
|
355
301
|
await sock.sendMessage(jid, {
|
|
356
|
-
|
|
357
|
-
|
|
302
|
+
image: { url: 'https://...' },
|
|
303
|
+
caption: 'Texto do card',
|
|
304
|
+
nativeFlow: [{ text: 'Botão', id: 'btn1' }]
|
|
358
305
|
})
|
|
359
306
|
```
|
|
360
307
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
### Mensagem Deletada
|
|
308
|
+
> Use `caption`, não `text`, quando quiser header com imagem junto de `nativeFlow` — usar `text` faz a lib pular inteiro o bloco que monta o header.
|
|
364
309
|
|
|
365
|
-
|
|
310
|
+
### Template Buttons
|
|
366
311
|
|
|
367
312
|
```js
|
|
368
313
|
await sock.sendMessage(jid, {
|
|
369
|
-
|
|
314
|
+
text: 'Escolha:',
|
|
315
|
+
templateButtons: [
|
|
316
|
+
{ text: 'Resposta', id: 'r1' },
|
|
317
|
+
{ text: 'Site', url: 'https://systemzone.store' },
|
|
318
|
+
{ text: 'Ligar', call: '5511999999999' },
|
|
319
|
+
]
|
|
370
320
|
})
|
|
371
321
|
```
|
|
372
322
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
### Fixar Mensagem
|
|
376
|
-
|
|
377
|
-
Fixa uma mensagem no chat ou grupo.
|
|
323
|
+
### Sections
|
|
378
324
|
|
|
379
325
|
```js
|
|
380
326
|
await sock.sendMessage(jid, {
|
|
381
|
-
|
|
382
|
-
|
|
327
|
+
text: 'Selecione', buttonText: 'Ver opções',
|
|
328
|
+
sections: [{ title: 'Cat', rows: [
|
|
329
|
+
{ title: 'Item 1', description: 'Desc', id: 'i1' }
|
|
330
|
+
]}]
|
|
383
331
|
})
|
|
384
332
|
```
|
|
385
333
|
|
|
386
334
|
---
|
|
387
335
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
Envia mídia que some após ser visualizada uma vez.
|
|
336
|
+
## 5. Sticker Pack nativo
|
|
391
337
|
|
|
392
338
|
```js
|
|
393
339
|
await sock.sendMessage(jid, {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
340
|
+
cover: bufferWebP,
|
|
341
|
+
stickers: [
|
|
342
|
+
{ data: bufferWebP, emojis: ['😂'] },
|
|
343
|
+
{ data: bufferAnima, emojis: ['🔥'] }, // animada
|
|
344
|
+
{ data: bufferPng, emojis: ['✨'] }, // PNG converte auto
|
|
345
|
+
],
|
|
346
|
+
name: 'Nome do Pack',
|
|
347
|
+
publisher: 'Autor',
|
|
348
|
+
description: 'Descrição'
|
|
397
349
|
})
|
|
398
350
|
```
|
|
399
351
|
|
|
400
|
-
|
|
352
|
+
> Tanto `cover` quanto cada item de `stickers[].data` esperam **Buffer**, não `{ url }`. Se você baixou as figurinhas de uma API, baixe o buffer primeiro (`axios.get(url, { responseType: 'arraybuffer' })`) antes de montar o objeto.
|
|
401
353
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
Ativa ou desativa mensagens temporárias em grupos.
|
|
405
|
-
|
|
406
|
-
```js
|
|
407
|
-
// Ativar (86400 = 24h, 604800 = 7 dias, 7776000 = 90 dias)
|
|
408
|
-
await sock.sendMessage(jid, {
|
|
409
|
-
disappearingMessagesInChat: 604800 // 7 dias em segundos
|
|
410
|
-
})
|
|
411
|
-
|
|
412
|
-
// Desativar
|
|
413
|
-
await sock.sendMessage(jid, {
|
|
414
|
-
disappearingMessagesInChat: false
|
|
415
|
-
})
|
|
416
|
-
```
|
|
354
|
+
Máximo 60 figurinhas, cada uma até 1MB. Requer `sharp` ou `@napi-rs/image` para PNG.
|
|
417
355
|
|
|
418
356
|
---
|
|
419
357
|
|
|
420
|
-
##
|
|
358
|
+
## 6. Canais Newsletter
|
|
421
359
|
|
|
422
|
-
|
|
360
|
+
```js
|
|
361
|
+
// Texto
|
|
362
|
+
await sock.sendMessage('120363...@newsletter', { text: 'Novidade!' })
|
|
423
363
|
|
|
424
|
-
|
|
364
|
+
// Mídia — sempre via generateWAMessage + relayMessage
|
|
365
|
+
const { generateWAMessage, generateMessageIDV2 } = require('@systemzero/baileys')
|
|
425
366
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
footer: 'Sistema de Atendimento',
|
|
430
|
-
buttons: [
|
|
431
|
-
{ buttonText: { displayText: '✅ Sim' }, buttonId: 'sim' },
|
|
432
|
-
{ buttonText: { displayText: '❌ Não' }, buttonId: 'nao' },
|
|
433
|
-
{ buttonText: { displayText: '❓ Talvez' }, buttonId: 'talvez' }
|
|
434
|
-
]
|
|
367
|
+
const fullMsg = await generateWAMessage(canalJid, { image: buffer, caption: 'Legenda' }, {
|
|
368
|
+
upload: sock.waUploadToServer, userJid: sock.user.id,
|
|
369
|
+
messageId: generateMessageIDV2(sock.user.id),
|
|
435
370
|
})
|
|
371
|
+
await sock.relayMessage(canalJid, fullMsg.message, { messageId: fullMsg.key.id })
|
|
372
|
+
|
|
373
|
+
// Gerenciar
|
|
374
|
+
const canal = await sock.newsletterCreate('Nome', 'Descrição')
|
|
375
|
+
await sock.newsletterFollow(jid)
|
|
376
|
+
await sock.newsletterUnfollow(jid)
|
|
377
|
+
await sock.newsletterMute(jid)
|
|
378
|
+
await sock.newsletterUnmute(jid)
|
|
379
|
+
const meta = await sock.newsletterMetadata('jid', jid)
|
|
380
|
+
await sock.newsletterUpdateName(jid, 'Novo Nome')
|
|
381
|
+
await sock.newsletterUpdateDescription(jid, 'Nova descrição')
|
|
382
|
+
await sock.newsletterUpdatePicture(jid, buffer)
|
|
383
|
+
await sock.newsletterRemovePicture(jid)
|
|
384
|
+
await sock.newsletterReactMessage(jid, serverId, '❤️')
|
|
385
|
+
const msgs = await sock.newsletterFetchMessages(jid, 30, 0, 0)
|
|
386
|
+
await sock.newsletterDelete(jid)
|
|
387
|
+
const { subscribers } = await sock.newsletterSubscribers(jid)
|
|
436
388
|
```
|
|
437
389
|
|
|
438
390
|
---
|
|
439
391
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
Envia uma lista interativa de opções (menu).
|
|
392
|
+
## 7. Enquetes com decrypt
|
|
443
393
|
|
|
444
394
|
```js
|
|
395
|
+
// Criar
|
|
445
396
|
await sock.sendMessage(jid, {
|
|
446
|
-
|
|
447
|
-
title: 'Menu Principal',
|
|
448
|
-
text: 'Selecione uma opção abaixo:',
|
|
449
|
-
footer: 'Powered by SystemZero',
|
|
450
|
-
buttonText: 'Ver Opções',
|
|
451
|
-
sections: [
|
|
452
|
-
{
|
|
453
|
-
title: 'Serviços',
|
|
454
|
-
rows: [
|
|
455
|
-
{ title: 'Suporte', description: 'Falar com atendente', rowId: 'suporte' },
|
|
456
|
-
{ title: 'Financeiro', description: 'Ver cobranças', rowId: 'financeiro' }
|
|
457
|
-
]
|
|
458
|
-
}
|
|
459
|
-
]
|
|
460
|
-
}
|
|
397
|
+
poll: { name: 'Pergunta?', values: ['A', 'B', 'C'], selectableCount: 1 }
|
|
461
398
|
})
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
---
|
|
465
399
|
|
|
466
|
-
|
|
400
|
+
// Receber votos — no connect.js após saveCreds:
|
|
401
|
+
const { getAggregateVotesInPollMessage } = require('@systemzero/baileys/lib/Utils/messages.js')
|
|
467
402
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
await
|
|
472
|
-
|
|
473
|
-
{
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
})
|
|
479
|
-
},
|
|
480
|
-
{
|
|
481
|
-
name: 'cta_url',
|
|
482
|
-
buttonParamsJson: JSON.stringify({
|
|
483
|
-
display_text: '🌐 Acessar Site',
|
|
484
|
-
url: 'https://meusite.com',
|
|
485
|
-
merchant_url: 'https://meusite.com'
|
|
486
|
-
})
|
|
487
|
-
},
|
|
488
|
-
{
|
|
489
|
-
name: 'cta_call',
|
|
490
|
-
buttonParamsJson: JSON.stringify({
|
|
491
|
-
display_text: '📞 Ligar',
|
|
492
|
-
phone_number: '+5511999999999'
|
|
493
|
-
})
|
|
494
|
-
}
|
|
495
|
-
],
|
|
496
|
-
text: 'Olá! Como posso te ajudar?',
|
|
497
|
-
footer: 'Atendimento 24h'
|
|
403
|
+
sock.ev.on('messages.update', async (updates) => {
|
|
404
|
+
for (const { key, update } of updates) {
|
|
405
|
+
if (!update.pollUpdates) continue
|
|
406
|
+
const pollMsg = await store.loadMessage(key.remoteJid, key.id)
|
|
407
|
+
if (!pollMsg?.message) continue
|
|
408
|
+
const result = getAggregateVotesInPollMessage({
|
|
409
|
+
message: pollMsg.message, pollUpdates: update.pollUpdates
|
|
410
|
+
})
|
|
411
|
+
// [{ name: 'A', voters: ['5511...@s.whatsapp.net'] }]
|
|
412
|
+
}
|
|
498
413
|
})
|
|
499
414
|
```
|
|
500
415
|
|
|
501
416
|
---
|
|
502
417
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
Solicita um pagamento pelo WhatsApp Pay.
|
|
418
|
+
## 8. AI Rich
|
|
506
419
|
|
|
507
420
|
```js
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
buttonParamsJson: JSON.stringify({
|
|
513
|
-
currency: 'BRL',
|
|
514
|
-
total_amount: { value: 5000, offset: 100 }, // R$ 50,00
|
|
515
|
-
reference_id: 'PEDIDO-001',
|
|
516
|
-
type: 'physical-goods',
|
|
517
|
-
order: {
|
|
518
|
-
status: 'pending',
|
|
519
|
-
subtotal: { value: 5000, offset: 100 },
|
|
520
|
-
order_type: 'ORDER',
|
|
521
|
-
items: [{
|
|
522
|
-
name: 'Produto X',
|
|
523
|
-
amount: { value: 5000, offset: 100 },
|
|
524
|
-
quantity: 1,
|
|
525
|
-
sale_amount: { value: 5000, offset: 100 }
|
|
526
|
-
}]
|
|
527
|
-
}
|
|
528
|
-
})
|
|
529
|
-
}
|
|
530
|
-
],
|
|
531
|
-
text: 'Seu pedido está pronto para pagamento!'
|
|
532
|
-
})
|
|
533
|
-
```
|
|
421
|
+
// Texto com hyperlink
|
|
422
|
+
await sock.sendRich(jid, [
|
|
423
|
+
sock.makeText('Acesse [nosso site](https://systemzone.store).')
|
|
424
|
+
], quotedMsg)
|
|
534
425
|
|
|
535
|
-
|
|
426
|
+
// Código
|
|
427
|
+
await sock.sendRich(jid, [
|
|
428
|
+
sock.makeCode('bash', 'npm i @systemzero/baileys')
|
|
429
|
+
], null, ['RICH_RESPONSE_CODE'])
|
|
536
430
|
|
|
537
|
-
|
|
431
|
+
// Tabela
|
|
432
|
+
await sock.sendRich(jid, [
|
|
433
|
+
sock.makeTable([['Nome', 'Status'], ['Botões', '✅'], ['Canais', '✅']])
|
|
434
|
+
], null, ['RICH_RESPONSE_TABLE'])
|
|
538
435
|
|
|
539
|
-
|
|
436
|
+
// Lista
|
|
437
|
+
await sock.sendRich(jid, [sock.makeList(['Item 1', 'Item 2'])])
|
|
540
438
|
|
|
541
|
-
|
|
542
|
-
await sock.
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
description: 'Conforto e estilo para o dia a dia.',
|
|
546
|
-
thumbnail: { url: 'https://exemplo.com/tenis.jpg' },
|
|
547
|
-
productId: 'PRODUTO-001',
|
|
548
|
-
retailerId: 'LOJA-BR',
|
|
549
|
-
priceAmount1000: 39900, // R$ 399,00
|
|
550
|
-
currencyCode: 'BRL',
|
|
551
|
-
url: 'https://minhaloja.com/produto',
|
|
552
|
-
body: 'Aproveite a oferta!',
|
|
553
|
-
footer: 'Frete grátis acima de R$ 200',
|
|
554
|
-
buttons: [
|
|
555
|
-
{
|
|
556
|
-
name: 'quick_reply',
|
|
557
|
-
buttonParamsJson: JSON.stringify({ display_text: '🛒 Comprar', id: 'comprar' })
|
|
558
|
-
}
|
|
559
|
-
]
|
|
560
|
-
}
|
|
561
|
-
})
|
|
439
|
+
// Atalhos
|
|
440
|
+
await sock.sendRichText(jid, 'Texto com [link](https://systemzone.store)', quotedMsg)
|
|
441
|
+
await sock.sendRichCode(jid, 'Título', 'javascript', 'const x = 1', quotedMsg)
|
|
442
|
+
await sock.sendRichList(jid, 'Lista', ['A', 'B'], quotedMsg)
|
|
562
443
|
```
|
|
563
444
|
|
|
564
445
|
---
|
|
565
446
|
|
|
566
|
-
##
|
|
447
|
+
## 9. LID / JID — Sistema avançado
|
|
567
448
|
|
|
568
|
-
|
|
449
|
+
O WhatsApp usa dois tipos de identificador:
|
|
450
|
+
- **JID** (`@s.whatsapp.net`) — formato baseado em número de telefone
|
|
451
|
+
- **LID** (`@lid`) — identificador opaco, não contém o número de telefone
|
|
569
452
|
|
|
570
|
-
|
|
453
|
+
A partir da v1.0.6, a baileys resolve automaticamente LID↔JID em mensagens recebidas e na metadata de grupo (ver seção 22), via `sharedLidPhoneCache`.
|
|
571
454
|
|
|
572
455
|
```js
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
456
|
+
const {
|
|
457
|
+
lidToJid, resolveJid, resolveAll, normalizeJid, validateJid,
|
|
458
|
+
getSenderInfo, sharedLidPhoneCache, isLidUser, isPnUser,
|
|
459
|
+
getBotJid, setBotMap
|
|
460
|
+
} = require('@systemzero/baileys')
|
|
577
461
|
```
|
|
578
462
|
|
|
579
|
-
---
|
|
580
|
-
|
|
581
|
-
### Código Rico
|
|
582
|
-
|
|
583
|
-
Exibe um bloco de código com syntax highlighting.
|
|
584
|
-
|
|
585
463
|
```js
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
}
|
|
593
|
-
console.log(soma(2, 3));`
|
|
594
|
-
)
|
|
464
|
+
const jid = lidToJid('123456@lid')
|
|
465
|
+
const { jid, lid } = resolveAll('5511999999999@s.whatsapp.net')
|
|
466
|
+
normalizeJid('5511999999999') // → '5511999999999@s.whatsapp.net'
|
|
467
|
+
normalizeJid('123456@lid') // → resolve via cache
|
|
468
|
+
const { isValid, error } = validateJid('5511999999999@s.whatsapp.net')
|
|
469
|
+
const { jid, lid, isGroup, isValid } = getSenderInfo(message)
|
|
595
470
|
```
|
|
596
471
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
### Lista Rica
|
|
472
|
+
### Cache bidirecional
|
|
600
473
|
|
|
601
|
-
|
|
474
|
+
O cache é populado automaticamente ao processar mensagens **e** ao buscar metadata de grupo (`groupMetadata`) — esse segundo ponto foi corrigido na v1.0.6, antes o par LID↔telefone que vem pronto na lista de participantes do grupo era descartado.
|
|
602
475
|
|
|
603
476
|
```js
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
)
|
|
477
|
+
sharedLidPhoneCache.set('123456@lid', '5511999999999@s.whatsapp.net') // manual, raro
|
|
478
|
+
const jid = sharedLidPhoneCache.getPhoneForLid('123456@lid')
|
|
479
|
+
const lid = sharedLidPhoneCache.getLidForPhone('5511999999999@s.whatsapp.net')
|
|
480
|
+
console.log('Entradas no cache:', sharedLidPhoneCache.size)
|
|
609
481
|
```
|
|
610
482
|
|
|
611
|
-
|
|
483
|
+
> ⚠️ Atenção com sufixo de dispositivo: identidades do **próprio bot** (`sock.user.id` / `sock.user.lid`) costumam vir como `numero:N@dominio` (ex: `558892659041:10@s.whatsapp.net`). Pra comparar com a lista de `participants` (que não tem sufixo), remova só o `:N`, preservando o domínio: `jid.replace(/:\d+(?=@)/, '')` — **não use** `jid.split(':')[0]`, isso corta o domínio inteiro junto.
|
|
612
484
|
|
|
613
|
-
|
|
485
|
+
---
|
|
614
486
|
|
|
615
|
-
|
|
487
|
+
## 10. Username (@usuario)
|
|
616
488
|
|
|
617
489
|
```js
|
|
618
|
-
|
|
619
|
-
jid,
|
|
620
|
-
'📊 Relatório de Vendas', // Título
|
|
621
|
-
[
|
|
622
|
-
['Produto', 'Qtd', 'Valor'], // Cabeçalho
|
|
623
|
-
['Camiseta', '10', 'R$ 300'],
|
|
624
|
-
['Calça', '5', 'R$ 500'],
|
|
625
|
-
['Tênis', '3', 'R$ 900']
|
|
626
|
-
],
|
|
627
|
-
'Total: R$ 1.700' // Rodapé (opcional)
|
|
628
|
-
)
|
|
629
|
-
```
|
|
630
|
-
|
|
631
|
-
---
|
|
490
|
+
const { resolveUsername, isUsername } = require('@systemzero/baileys')
|
|
632
491
|
|
|
633
|
-
|
|
492
|
+
isUsername('@josue') // true
|
|
493
|
+
isUsername('josue') // false
|
|
634
494
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
```js
|
|
638
|
-
await sock.sendRichFull(jid, {
|
|
639
|
-
title: '🚀 Relatório Completo',
|
|
640
|
-
code: `const resultado = calcular()`,
|
|
641
|
-
language: 'javascript',
|
|
642
|
-
items: ['Item A', 'Item B', 'Item C'],
|
|
643
|
-
table: [
|
|
644
|
-
['Campo', 'Valor'],
|
|
645
|
-
['Status', 'Ativo'],
|
|
646
|
-
['Versão', '1.0.3']
|
|
647
|
-
],
|
|
648
|
-
footer: '© SystemZero Baileys'
|
|
649
|
-
})
|
|
495
|
+
const jid = await resolveUsername('@josue', sock.onWhatsApp.bind(sock))
|
|
496
|
+
if (jid) await sock.sendMessage(jid, { text: 'Olá!' })
|
|
650
497
|
```
|
|
651
498
|
|
|
652
499
|
---
|
|
653
500
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
Envia uma mensagem no estilo de resultado de busca com reels/vídeos.
|
|
501
|
+
## 11. MessageBuilder — Button, ButtonV2, Carousel, AIRich
|
|
657
502
|
|
|
658
503
|
```js
|
|
659
|
-
|
|
660
|
-
jid,
|
|
661
|
-
'Resultado da Busca', // Título
|
|
662
|
-
'Vídeos encontrados', // Header
|
|
663
|
-
'gatos fofinhos', // Query de busca
|
|
664
|
-
[
|
|
665
|
-
{
|
|
666
|
-
title: 'Gato dançando',
|
|
667
|
-
url: 'https://video1.com',
|
|
668
|
-
thumbnail: 'https://thumb1.com/img.jpg'
|
|
669
|
-
}
|
|
670
|
-
]
|
|
671
|
-
)
|
|
504
|
+
const { Button, ButtonV2, Carousel, AIRich } = require('@systemzero/baileys/lib/MB.cjs')
|
|
672
505
|
```
|
|
673
506
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
### Perplexity IA
|
|
507
|
+
> O socket vai sempre no construtor: `new ButtonV2(sock)`
|
|
677
508
|
|
|
678
|
-
|
|
509
|
+
### ButtonV2 — botões clássicos
|
|
679
510
|
|
|
680
511
|
```js
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
)
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
'Explique inteligência artificial',
|
|
690
|
-
{ quoted: mensagemOriginal }
|
|
691
|
-
)
|
|
512
|
+
const msg = new ButtonV2(sock)
|
|
513
|
+
msg.setTitle('Título')
|
|
514
|
+
msg.setBody('Corpo')
|
|
515
|
+
msg.setFooter('Rodapé')
|
|
516
|
+
msg.setThumbnail('https://exemplo.com/imagem.jpg')
|
|
517
|
+
msg.addButton('✅ Opção 1', 'opcao_1')
|
|
518
|
+
msg.addButton('❌ Opção 2', 'opcao_2')
|
|
519
|
+
await msg.send(jid, { quoted: m })
|
|
692
520
|
```
|
|
693
521
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
## 📁 Tipos Especiais de Mensagem
|
|
697
|
-
|
|
698
|
-
### Álbum de Fotos/Vídeos
|
|
522
|
+
Capturar clique: `m.body` chega com o id do botão.
|
|
699
523
|
|
|
700
|
-
|
|
524
|
+
### Button — native flow avançado
|
|
701
525
|
|
|
702
526
|
```js
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
527
|
+
const msg = new Button(sock)
|
|
528
|
+
msg.setTitle('Título')
|
|
529
|
+
msg.setBody('Corpo')
|
|
530
|
+
msg.addReply('✅ Confirmar', 'confirmar')
|
|
531
|
+
msg.addUrl('🔗 Abrir site', 'https://systemzone.store')
|
|
532
|
+
msg.addCopy('📋 Copiar código', 'PROMO2025')
|
|
533
|
+
msg.addCall('📞 Ligar', '5511999999999')
|
|
534
|
+
await msg.send(jid, { quoted: m })
|
|
710
535
|
```
|
|
711
536
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
### Evento
|
|
715
|
-
|
|
716
|
-
Cria um evento no grupo ou conversa.
|
|
537
|
+
### Carousel
|
|
717
538
|
|
|
718
539
|
```js
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
degreesLatitude: -23.5505,
|
|
725
|
-
degreesLongitude: -46.6333,
|
|
726
|
-
name: 'Escritório Central, São Paulo'
|
|
727
|
-
},
|
|
728
|
-
joinLink: 'https://meet.google.com/abc-xyz',
|
|
729
|
-
startTime: Date.now() + 86400000, // Amanhã
|
|
730
|
-
endTime: Date.now() + 86400000 + 3600000, // +1 hora
|
|
731
|
-
extraGuestsAllowed: true,
|
|
732
|
-
isCanceled: false
|
|
733
|
-
}
|
|
734
|
-
})
|
|
540
|
+
const msg = new Carousel(sock)
|
|
541
|
+
msg.setBody('Escolha um item:')
|
|
542
|
+
msg.card(c => c.image('https://...').title('Card 1').text('Descrição').button('Ver', 'c1'))
|
|
543
|
+
msg.card(c => c.image('https://...').title('Card 2').text('Descrição').button('Ver', 'c2'))
|
|
544
|
+
await msg.send(jid, { quoted: m })
|
|
735
545
|
```
|
|
736
546
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
### Resultado de Enquete
|
|
740
|
-
|
|
741
|
-
Envia um snapshot de resultado de votação.
|
|
547
|
+
### AIRich
|
|
742
548
|
|
|
743
549
|
```js
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
{ optionName: 'Python', optionVoteCount: 35 },
|
|
750
|
-
{ optionName: 'TypeScript', optionVoteCount: 28 }
|
|
751
|
-
]
|
|
752
|
-
}
|
|
753
|
-
})
|
|
550
|
+
const msg = new AIRich(sock)
|
|
551
|
+
msg.addText('Acesse [System Zero](https://systemzone.store).')
|
|
552
|
+
msg.addCode('javascript', `const baileys = require('@systemzero/baileys')`)
|
|
553
|
+
msg.addTable([['Comando', 'Descrição'], ['!menu', 'Abre o menu']])
|
|
554
|
+
await msg.send(jid, { quoted: m })
|
|
754
555
|
```
|
|
755
556
|
|
|
756
557
|
---
|
|
757
558
|
|
|
758
|
-
|
|
559
|
+
## 12. Botões estendidos (v1.0.6)
|
|
759
560
|
|
|
760
|
-
|
|
561
|
+
> ⚠️ **Não verificado nesta versão do README.** Os tipos abaixo (`catalog`, `products`, `otp`, `orderDetails`, `flow`, etc) exigem conta **WhatsApp Business API verificada** com catálogo/pagamentos configurados — nenhum deles foi testado numa conta pessoal real. Os tipos mais simples (`reminder`, `address`, `location`, `phoneNumber`, `urlBtn`, `clearChat`) têm chance maior de funcionar em qualquer conta, mas também não foram confirmados em teste real. Trate como documentação do proto, não como garantia de funcionamento. Para formulários reais e testados, veja a seção 24.
|
|
761
562
|
|
|
762
563
|
```js
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
caption: 'Evento da semana'
|
|
775
|
-
}
|
|
776
|
-
})
|
|
564
|
+
{ text: '⏰ Me lembre', reminder: 'lembrete_id' }
|
|
565
|
+
{ text: '🔕 Cancelar', cancelReminder: 'lembrete_id' }
|
|
566
|
+
{ text: '📍 Enviar endereço', address: true }
|
|
567
|
+
{ text: '📡 Localização', location: true }
|
|
568
|
+
{ text: '🛍️ Ver catálogo', catalog: '5511999999999@s.whatsapp.net' }
|
|
569
|
+
{ text: '📦 Produtos', products: ['prod_id_1'], bizJid: '5511...@s.whatsapp.net' }
|
|
570
|
+
{ text: 'Copiar código', otp: '123456' }
|
|
571
|
+
{ text: '📞 Ligar', phoneNumber: '5511999999999' }
|
|
572
|
+
{ text: '📋 Ver pedido', orderDetails: { order_id: '123', token: 'abc' } }
|
|
573
|
+
{ text: '🗑️ Limpar chat', clearChat: true }
|
|
574
|
+
{ text: '🔗 Abrir', urlBtn: 'https://systemzone.store' }
|
|
777
575
|
```
|
|
778
576
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
### Pagamento (requestPayment)
|
|
782
|
-
|
|
783
|
-
Solicita um pagamento com nota ou sticker.
|
|
577
|
+
### isSystemNotification
|
|
784
578
|
|
|
785
579
|
```js
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
currency: 'BRL',
|
|
790
|
-
from: '5511999999999@s.whatsapp.net',
|
|
791
|
-
expiry: Math.floor(Date.now() / 1000) + 86400, // 24h
|
|
792
|
-
note: 'Pagamento do serviço de bot 🤖'
|
|
793
|
-
}
|
|
580
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
581
|
+
const msg = messages[0]
|
|
582
|
+
if (msg.isSystemNotification) return // ignora notificação de sistema
|
|
794
583
|
})
|
|
795
584
|
```
|
|
796
585
|
|
|
797
586
|
---
|
|
798
587
|
|
|
799
|
-
##
|
|
800
|
-
|
|
801
|
-
### Criar Grupo
|
|
588
|
+
## 13. Grupos
|
|
802
589
|
|
|
803
590
|
```js
|
|
804
|
-
const grupo = await sock.groupCreate('Nome
|
|
805
|
-
|
|
806
|
-
'5521888888888@s.whatsapp.net'
|
|
807
|
-
])
|
|
808
|
-
console.log('Grupo criado:', grupo.id)
|
|
809
|
-
```
|
|
591
|
+
const grupo = await sock.groupCreate('Nome', ['5511...@s.whatsapp.net'])
|
|
592
|
+
const meta = await sock.groupMetadata(jid)
|
|
810
593
|
|
|
811
|
-
|
|
594
|
+
await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'add')
|
|
595
|
+
await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'remove')
|
|
596
|
+
await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'promote')
|
|
597
|
+
await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'demote')
|
|
598
|
+
await sock.groupLeave(jid)
|
|
599
|
+
await sock.groupUpdateSubject(jid, 'Novo Nome')
|
|
600
|
+
await sock.groupUpdateDescription(jid, 'Nova descrição')
|
|
812
601
|
|
|
813
|
-
|
|
602
|
+
const code = await sock.groupInviteCode(jid)
|
|
603
|
+
await sock.groupRevokeInvite(jid)
|
|
604
|
+
await sock.groupAcceptInvite('CODIGO')
|
|
605
|
+
await sock.groupToggleEphemeral(jid, 86400)
|
|
814
606
|
|
|
815
|
-
|
|
816
|
-
const info = await sock.groupMetadata('120363xxxxxxxx@g.us')
|
|
817
|
-
console.log(info.subject) // Nome do grupo
|
|
818
|
-
console.log(info.participants) // Lista de participantes
|
|
819
|
-
console.log(info.desc) // Descrição
|
|
607
|
+
const grupos = await sock.groupFetchAllParticipating()
|
|
820
608
|
```
|
|
821
609
|
|
|
822
610
|
---
|
|
823
611
|
|
|
824
|
-
|
|
612
|
+
## 14. Perfil e privacidade
|
|
825
613
|
|
|
826
614
|
```js
|
|
827
|
-
|
|
828
|
-
await sock.
|
|
615
|
+
const url = await sock.profilePictureUrl(jid, 'image')
|
|
616
|
+
await sock.updateProfilePicture(jid, buffer)
|
|
617
|
+
await sock.updateProfileStatus('🤖 Bot ativo')
|
|
829
618
|
|
|
830
|
-
|
|
831
|
-
await sock.groupParticipantsUpdate(jid, ['5511999999999@s.whatsapp.net'], 'remove')
|
|
619
|
+
const [result] = await sock.onWhatsApp('5511999999999')
|
|
832
620
|
|
|
833
|
-
|
|
834
|
-
await sock.
|
|
621
|
+
await sock.updateBlockStatus(jid, 'block')
|
|
622
|
+
await sock.updateBlockStatus(jid, 'unblock')
|
|
835
623
|
|
|
836
|
-
|
|
837
|
-
await sock.
|
|
838
|
-
|
|
624
|
+
await sock.sendPresenceUpdate('composing', jid)
|
|
625
|
+
await sock.sendPresenceUpdate('available', jid)
|
|
626
|
+
await sock.presenceSubscribe(jid)
|
|
839
627
|
|
|
840
|
-
|
|
628
|
+
await sock.readMessages([message.key])
|
|
841
629
|
|
|
842
|
-
|
|
630
|
+
await sock.chatModify({ archive: true }, jid)
|
|
631
|
+
await sock.chatModify({ pin: true }, jid)
|
|
632
|
+
await sock.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid)
|
|
843
633
|
|
|
844
|
-
|
|
845
|
-
await sock.groupUpdateSubject(jid, 'Novo Nome do Grupo ✨')
|
|
846
|
-
await sock.groupUpdateDescription(jid, 'Nova descrição incrível do grupo!')
|
|
634
|
+
await sock.logout()
|
|
847
635
|
```
|
|
848
636
|
|
|
849
637
|
---
|
|
850
638
|
|
|
851
|
-
|
|
639
|
+
## 15. Eventos do socket
|
|
852
640
|
|
|
853
641
|
```js
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
642
|
+
sock.ev.on('messages.upsert', ({ messages, type }) => {})
|
|
643
|
+
sock.ev.on('messages.update', (updates) => {})
|
|
644
|
+
sock.ev.on('messages.delete', (item) => {})
|
|
645
|
+
sock.ev.on('messages.reaction', (reactions) => {})
|
|
646
|
+
sock.ev.on('messages.decrypt-failed', (failInfo) => {}) // ver seção 20
|
|
647
|
+
sock.ev.on('presence.update', ({ id, presences }) => {})
|
|
648
|
+
sock.ev.on('groups.update', (updates) => {})
|
|
649
|
+
sock.ev.on('group-participants.update', ({ id, participants, action }) => {})
|
|
650
|
+
sock.ev.on('contacts.update', (contacts) => {})
|
|
651
|
+
sock.ev.on('connection.update', ({ connection, lastDisconnect, qr }) => {})
|
|
652
|
+
sock.ev.on('creds.update', saveCreds)
|
|
857
653
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
// Info do grupo pelo link
|
|
865
|
-
const info = await sock.groupGetInviteInfo('CodigoAqui')
|
|
654
|
+
sock.ev.on('call', (calls) => {
|
|
655
|
+
for (const call of calls) {
|
|
656
|
+
if (call.status === 'offer') sock.rejectCall(call.id, call.from)
|
|
657
|
+
}
|
|
658
|
+
})
|
|
866
659
|
```
|
|
867
660
|
|
|
868
661
|
---
|
|
869
662
|
|
|
870
|
-
|
|
663
|
+
## 16. Utilitários
|
|
871
664
|
|
|
872
665
|
```js
|
|
873
|
-
|
|
874
|
-
await
|
|
875
|
-
|
|
876
|
-
// Todos podem enviar
|
|
877
|
-
await sock.groupSettingUpdate(jid, 'not_announcement')
|
|
666
|
+
const { downloadMediaMessage, downloadContentFromMessage } = require('@systemzero/baileys')
|
|
667
|
+
const buffer = await downloadMediaMessage(message, 'buffer', {})
|
|
878
668
|
|
|
879
|
-
|
|
880
|
-
await sock.groupSettingUpdate(jid, 'locked')
|
|
669
|
+
const { generateWAMessage, generateWAMessageFromContent, generateMessageIDV2 } = require('@systemzero/baileys')
|
|
881
670
|
|
|
882
|
-
|
|
883
|
-
|
|
671
|
+
const {
|
|
672
|
+
jidNormalizedUser, isJidGroup, isJidNewsletter,
|
|
673
|
+
isLidUser, isPnUser, isUsername,
|
|
674
|
+
normalizeJid, resolveAll, getSenderInfo,
|
|
675
|
+
jidEncode, jidDecode
|
|
676
|
+
} = require('@systemzero/baileys')
|
|
884
677
|
|
|
885
|
-
//
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
// Aprovação para entrar
|
|
890
|
-
await sock.groupJoinApprovalMode(jid, 'on') // Ativar aprovação
|
|
891
|
-
await sock.groupJoinApprovalMode(jid, 'off') // Desativar
|
|
678
|
+
// Detectar dispositivo — analisa o FORMATO DO ID DA MENSAGEM, não o JID
|
|
679
|
+
const { getDevice } = require('@systemzero/baileys')
|
|
680
|
+
const device = getDevice(message.key.id) // 'android' | 'ios' | 'web' | 'unknown'
|
|
892
681
|
```
|
|
893
682
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
### Sair do Grupo
|
|
897
|
-
|
|
898
|
-
```js
|
|
899
|
-
await sock.groupLeave(jid)
|
|
900
|
-
```
|
|
683
|
+
> `getDevice` só funciona em cima de um `message.key.id` real — não dá pra usar pra "descobrir o dispositivo" de alguém sem ter uma mensagem recente dela pra inspecionar.
|
|
901
684
|
|
|
902
685
|
---
|
|
903
686
|
|
|
904
|
-
|
|
687
|
+
## 17. Fixar / Desfixar mensagens
|
|
905
688
|
|
|
906
689
|
```js
|
|
907
|
-
//
|
|
908
|
-
|
|
690
|
+
// Fixar (type: 1 = PIN_FOR_ALL)
|
|
691
|
+
await sock.sendMessage(jid, { pin: quotedMsg.key, type: 1 })
|
|
909
692
|
|
|
910
|
-
//
|
|
911
|
-
await sock.
|
|
912
|
-
await sock.groupRequestParticipantsUpdate(jid, ['5511999999999@s.whatsapp.net'], 'reject')
|
|
693
|
+
// Desfixar (type: 2 = UNPIN_FOR_ALL)
|
|
694
|
+
await sock.sendMessage(jid, { pin: quotedMsg.key, type: 2 })
|
|
913
695
|
```
|
|
914
696
|
|
|
915
|
-
|
|
697
|
+
`quotedMsg.key` precisa conter `remoteJid`, `fromMe`, `id` e (em grupos) `participant`.
|
|
916
698
|
|
|
917
|
-
|
|
699
|
+
---
|
|
918
700
|
|
|
919
|
-
|
|
701
|
+
## 18. Resolução de nomes (getName)
|
|
920
702
|
|
|
921
703
|
```js
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
// Marcar como não lida
|
|
926
|
-
await sock.chatModify({ markRead: false, lastMessages: [mensagem] }, jid)
|
|
704
|
+
const { getName } = require('@systemzero/baileys')
|
|
705
|
+
const nome = getName(msg, contactStore) // contactStore opcional: { [jid]: { name, notify, verifiedName } }
|
|
706
|
+
```
|
|
927
707
|
|
|
928
|
-
|
|
929
|
-
await sock.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid)
|
|
708
|
+
Ordem de prioridade: contato salvo localmente → `verifiedName` → `pushName`/`notify` → resolução `@lid` via cache → número formatado → `"Usuário desconhecido"`. Nunca retorna vazio.
|
|
930
709
|
|
|
931
|
-
|
|
932
|
-
await sock.chatModify({ mute: null }, jid)
|
|
710
|
+
---
|
|
933
711
|
|
|
934
|
-
|
|
935
|
-
await sock.chatModify({ pin: true }, jid)
|
|
712
|
+
## 19. PTT real com qualquer formato de entrada
|
|
936
713
|
|
|
937
|
-
|
|
938
|
-
await sock.chatModify({ clear: { messages: [{ id: 'ID_MSG', fromMe: true }] } }, jid)
|
|
714
|
+
Antes da correção, `ptt: true` só **etiquetava** o mimetype como opus sem converter os bytes de verdade — qualquer entrada que não já fosse opus puro dava "algo errado com o arquivo de áudio" no WhatsApp. Agora a lib transcodifica de verdade via `ffmpeg` quando necessário.
|
|
939
715
|
|
|
940
|
-
|
|
941
|
-
await sock.
|
|
716
|
+
```js
|
|
717
|
+
await sock.sendMessage(jid, {
|
|
718
|
+
audio: { url: 'https://qualquer-formato.mp3' }, // mp3, m4a, wav, o que for
|
|
719
|
+
ptt: true
|
|
720
|
+
})
|
|
942
721
|
```
|
|
943
722
|
|
|
944
|
-
|
|
723
|
+
A lib detecta se a fonte já é `.opus`/`.ogg` (pela extensão real, não pelo que você declarar em `mimetype`) e só converte quando necessário, pra mono/16kHz — a especificação que o player de voz do WhatsApp espera.
|
|
945
724
|
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
```js
|
|
949
|
-
const key = { remoteJid: jid, id: mensagem.key.id, participant: mensagem.key.participant }
|
|
950
|
-
await sock.readMessages([key])
|
|
951
|
-
```
|
|
725
|
+
> Requer `ffmpeg` com `libopus` no `PATH` do servidor.
|
|
952
726
|
|
|
953
727
|
---
|
|
954
728
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
```js
|
|
958
|
-
// Ver foto de perfil
|
|
959
|
-
const url = await sock.profilePictureUrl('5511999999999@s.whatsapp.net', 'image')
|
|
729
|
+
## 20. Guard de pagamento stealth (anti-fraude)
|
|
960
730
|
|
|
961
|
-
|
|
962
|
-
await sock.updateProfilePicture(jid, readFileSync('./nova_foto.jpg'))
|
|
731
|
+
A lib emite o evento `messages.decrypt-failed` sempre que uma mensagem de grupo falha na descriptografia (PreKey/CIPHERTEXT) — cobre o golpe de cobrança "invisível": mensagem normal enviada, depois **editada** pra conteúdo de pagamento.
|
|
963
732
|
|
|
964
|
-
|
|
965
|
-
|
|
733
|
+
```js
|
|
734
|
+
const { bindPaymentGuard } = require('@systemzero/baileys')
|
|
966
735
|
|
|
967
|
-
|
|
968
|
-
|
|
736
|
+
bindPaymentGuard(sock, {
|
|
737
|
+
isPaymentMessage: (webMessage) => { /* sua lógica de detecção */ },
|
|
738
|
+
recordEnvelope: (webMessage, isPayment) => { /* seu registro de corroboração */ },
|
|
739
|
+
treatDecryptFailureAsSuspicious: true,
|
|
740
|
+
onDetect: (detection) => {
|
|
741
|
+
// detection.type: 'direct' | 'edited' | 'undecryptable'
|
|
742
|
+
}
|
|
743
|
+
})
|
|
744
|
+
```
|
|
969
745
|
|
|
970
|
-
|
|
971
|
-
|
|
746
|
+
| Caminho | Evento | Garantia |
|
|
747
|
+
|---|---|---|
|
|
748
|
+
| Mensagem direta | `messages.upsert` | Roda seu detector no conteúdo normal |
|
|
749
|
+
| Mensagem editada | `messages.update` | Extrai `editedMessage` e roda o mesmo detector |
|
|
750
|
+
| Falha de decrypt | `messages.decrypt-failed` | Nunca ignora em silêncio, mesmo sem conteúdo |
|
|
972
751
|
|
|
973
|
-
|
|
974
|
-
const status = await sock.fetchStatus('5511999999999@s.whatsapp.net')
|
|
975
|
-
```
|
|
752
|
+
> Falha de decrypt nunca foi lida pelo bot — não existe forma de confirmar que era pagamento. O guard garante que isso nunca passe sem nenhum aviso, não que vai "adivinhar" o conteúdo.
|
|
976
753
|
|
|
977
754
|
---
|
|
978
755
|
|
|
979
|
-
|
|
756
|
+
## 21. Bad MAC Handler — sessões Signal
|
|
980
757
|
|
|
981
758
|
```js
|
|
982
|
-
|
|
983
|
-
|
|
759
|
+
const { BadMacHandler, badMacHandler } = require('@systemzero/baileys')
|
|
760
|
+
|
|
761
|
+
if (badMacHandler.isBadMacError(error)) {
|
|
762
|
+
badMacHandler.handleError(error, 'algum-contexto')
|
|
763
|
+
}
|
|
984
764
|
|
|
985
|
-
//
|
|
986
|
-
|
|
765
|
+
// limpa sessões Signal problemáticas, preservando creds.json
|
|
766
|
+
badMacHandler.clearProblematicSessionFiles()
|
|
987
767
|
```
|
|
988
768
|
|
|
769
|
+
Erros "Bad MAC" são esperados ocasionalmente em qualquer cliente Signal Protocol (sessão desincronizada do outro lado) — esse handler conta, dá reset automático após um intervalo, e remove só arquivos de sessão por par, nunca as credenciais principais.
|
|
770
|
+
|
|
989
771
|
---
|
|
990
772
|
|
|
991
|
-
|
|
773
|
+
## 22. Resolução LID → telefone via grupo
|
|
992
774
|
|
|
993
775
|
```js
|
|
994
|
-
|
|
995
|
-
await sock
|
|
996
|
-
jid: '5511999999999@s.whatsapp.net',
|
|
997
|
-
notify: 'João Silva'
|
|
998
|
-
})
|
|
999
|
-
|
|
1000
|
-
// Remover contato
|
|
1001
|
-
await sock.removeContact('5511999999999@s.whatsapp.net')
|
|
776
|
+
const { resolveLidPhoneFromGroup } = require('@systemzero/baileys')
|
|
777
|
+
const telefone = await resolveLidPhoneFromGroup(sock, groupJid, lid)
|
|
1002
778
|
```
|
|
1003
779
|
|
|
780
|
+
Força a resolução de um `@lid` pro telefone real buscando a metadata do grupo (que já entrega o par pronto por participante) — útil quando o cache ainda não tem aquele par.
|
|
781
|
+
|
|
1004
782
|
---
|
|
1005
783
|
|
|
1006
|
-
##
|
|
784
|
+
## 23. Versão do WhatsApp sempre atualizada
|
|
1007
785
|
|
|
1008
786
|
```js
|
|
1009
|
-
|
|
1010
|
-
await
|
|
1011
|
-
|
|
1012
|
-
// Online: 'all' | 'match_last_seen'
|
|
1013
|
-
await sock.updateOnlinePrivacy('all')
|
|
1014
|
-
|
|
1015
|
-
// Foto de perfil: 'all' | 'contacts' | 'contact_blacklist' | 'none'
|
|
1016
|
-
await sock.updateProfilePicturePrivacy('contacts')
|
|
1017
|
-
|
|
1018
|
-
// Status: 'all' | 'contacts' | 'contact_blacklist' | 'none'
|
|
1019
|
-
await sock.updateStatusPrivacy('contacts')
|
|
787
|
+
const { getBestWaVersion } = require('@systemzero/baileys')
|
|
788
|
+
const { version, isLatest, source } = await getBestWaVersion()
|
|
789
|
+
```
|
|
1020
790
|
|
|
1021
|
-
|
|
1022
|
-
await sock.updateReadReceiptsPrivacy('all')
|
|
791
|
+
Tenta `web.whatsapp.com`, depois GitHub, e só aceita um resultado se `isLatest === true` de verdade. Diferente de `fetchLatestWaWebVersion()`/`fetchLatestBaileysVersion()` isoladas, que sempre retornam algo (mesmo em falha, caindo num valor fixo antigo) sem deixar isso óbvio.
|
|
1023
792
|
|
|
1024
|
-
|
|
1025
|
-
await sock.updateGroupsAddPrivacy('contacts')
|
|
793
|
+
---
|
|
1026
794
|
|
|
1027
|
-
|
|
1028
|
-
await sock.updateCallPrivacy('contacts')
|
|
795
|
+
## 24. WhatsApp Flows — Formulários interativos
|
|
1029
796
|
|
|
1030
|
-
|
|
1031
|
-
await sock.updateDisableLinkPreviewsPrivacy('none')
|
|
797
|
+
> ⚠️ WhatsApp Flows é um recurso de **WhatsApp Business API**, normalmente exigindo um `flow_id` aprovado pela Meta pra sua conta/app específico. O exemplo abaixo é o que está em uso real no System Zero — funciona pro `flow_id` configurado nessa conta, mas **não é garantido que o mesmo `flow_id` funcione pra qualquer outra conta**. Pra criar seu próprio Flow, você precisa cadastrar e aprovar ele no Meta Business Manager.
|
|
1032
798
|
|
|
1033
|
-
|
|
1034
|
-
await sock.updateDefaultDisappearingMode(604800) // 7 dias
|
|
1035
|
-
```
|
|
1036
|
-
|
|
1037
|
-
---
|
|
1038
|
-
|
|
1039
|
-
## 🏷️ Labels
|
|
799
|
+
### Enviando o formulário
|
|
1040
800
|
|
|
1041
801
|
```js
|
|
1042
|
-
|
|
1043
|
-
await sock.addLabel({ id: '1', name: 'Cliente VIP', color: 1 })
|
|
1044
|
-
|
|
1045
|
-
// Label em chat
|
|
1046
|
-
await sock.addChatLabel(jid, '1')
|
|
1047
|
-
await sock.removeChatLabel(jid, '1')
|
|
802
|
+
const { generateWAMessageFromContent } = require('@systemzero/baileys')
|
|
1048
803
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
804
|
+
const formMsg = generateWAMessageFromContent(jid, {
|
|
805
|
+
viewOnceMessage: {
|
|
806
|
+
message: {
|
|
807
|
+
messageContextInfo: {
|
|
808
|
+
deviceListMetadata: {},
|
|
809
|
+
deviceListMetadataVersion: 2
|
|
810
|
+
},
|
|
811
|
+
interactiveMessage: {
|
|
812
|
+
body: { text: 'Formulário de teste\n\nPreencha seus dados.' },
|
|
813
|
+
nativeFlowMessage: {
|
|
814
|
+
buttons: [{
|
|
815
|
+
name: 'galaxy_message',
|
|
816
|
+
buttonParamsJson: JSON.stringify({
|
|
817
|
+
flow_message_version: '4',
|
|
818
|
+
flow_id: 'SEU_FLOW_ID_AQUI',
|
|
819
|
+
flow_action_payload: {
|
|
820
|
+
screen: 'contact_details',
|
|
821
|
+
data: {
|
|
822
|
+
full_name_visible: true,
|
|
823
|
+
phone_number_visible: true,
|
|
824
|
+
email_visible: true,
|
|
825
|
+
offer_name: 'Olá, seja bem-vindo',
|
|
826
|
+
offer_description: 'Sistema de teste'
|
|
827
|
+
}
|
|
828
|
+
},
|
|
829
|
+
well_version: 'V700',
|
|
830
|
+
flow_cta: '__localize:FLOWS_SIGN_UP_BUTTON_TITLE',
|
|
831
|
+
flow_action: 'navigate',
|
|
832
|
+
flow_token: 'T0ZGRVJfU0lHTlVQ'
|
|
833
|
+
})
|
|
834
|
+
}],
|
|
835
|
+
messageParamsJson: '{}'
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}, { userJid: sock.user.id })
|
|
1052
841
|
|
|
1053
|
-
|
|
1054
|
-
await sock.star(jid, [{ id: msgId, fromMe: true }], true)
|
|
842
|
+
await sock.relayMessage(jid, formMsg.message, { messageId: formMsg.key.id })
|
|
1055
843
|
```
|
|
1056
844
|
|
|
1057
|
-
|
|
845
|
+
### Recebendo a resposta
|
|
1058
846
|
|
|
1059
|
-
|
|
847
|
+
A resposta do formulário chega como `interactiveResponseMessage`. O `nativeFlowResponseMessage.paramsJson` traz os dados preenchidos dentro de `wa_flow_response_params.response_message` (uma string JSON aninhada — precisa de `JSON.parse` duplo).
|
|
1060
848
|
|
|
1061
849
|
```js
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
850
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
851
|
+
const m = messages[0]
|
|
852
|
+
if (m.message?.interactiveResponseMessage) {
|
|
853
|
+
const nfr = m.message.interactiveResponseMessage.nativeFlowResponseMessage
|
|
854
|
+
|
|
855
|
+
if (nfr?.name === 'galaxy_message' && nfr?.paramsJson) {
|
|
856
|
+
const parsed = JSON.parse(nfr.paramsJson)
|
|
857
|
+
if (!parsed.wa_flow_response_params) return
|
|
858
|
+
|
|
859
|
+
const flowParams = parsed.wa_flow_response_params
|
|
860
|
+
const flowId = flowParams.flow_id || ''
|
|
861
|
+
const rawResponse = flowParams.response_message || ''
|
|
862
|
+
|
|
863
|
+
let screens = []
|
|
864
|
+
try { screens = JSON.parse(rawResponse).screens || [] } catch {}
|
|
865
|
+
|
|
866
|
+
// extrai só os campos preenchidos
|
|
867
|
+
const campos = {}
|
|
868
|
+
for (const screen of screens) {
|
|
869
|
+
for (const comp of (screen.components || [])) {
|
|
870
|
+
if (comp.name && comp.value !== undefined && comp.value !== '') {
|
|
871
|
+
campos[comp.name] = comp.value
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
1070
875
|
|
|
1071
|
-
//
|
|
1072
|
-
|
|
1073
|
-
|
|
876
|
+
// roteia por flow_id — adicione mais formulários aqui
|
|
877
|
+
if (flowId === 'SEU_FLOW_ID_AQUI') {
|
|
878
|
+
let resposta = 'Formulário recebido!\n\n'
|
|
879
|
+
if (campos.full_name) resposta += `Nome: ${campos.full_name}\n`
|
|
880
|
+
if (campos.phone_number) resposta += `Telefone: +${campos.phone_number}\n`
|
|
881
|
+
if (campos.email) resposta += `Email: ${campos.email}\n`
|
|
882
|
+
await sock.sendMessage(m.key.remoteJid, { text: resposta }, { quoted: m })
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
}
|
|
1074
886
|
})
|
|
1075
887
|
```
|
|
1076
888
|
|
|
1077
889
|
---
|
|
1078
890
|
|
|
1079
|
-
##
|
|
891
|
+
## Changelog
|
|
1080
892
|
|
|
1081
|
-
|
|
1082
|
-
-
|
|
1083
|
-
-
|
|
1084
|
-
-
|
|
893
|
+
### v1.0.6
|
|
894
|
+
- **Fix PTT real** — `ptt: true` agora transcodifica via `ffmpeg` quando necessário, em vez de só etiquetar o mimetype
|
|
895
|
+
- **Fix groupMetadata → sharedLidPhoneCache** — pares LID↔telefone da lista de participantes de grupo agora são registrados no cache (antes eram descartados)
|
|
896
|
+
- **Fix cleanId de identidade própria** — comparação de `sock.user.id`/`sock.user.lid` com sufixo de dispositivo (`:N`) agora preserva o domínio
|
|
897
|
+
- **Guard de pagamento stealth** — `bindPaymentGuard`, evento `messages.decrypt-failed`
|
|
898
|
+
- **Bad MAC Handler** — `BadMacHandler`, `badMacHandler`
|
|
899
|
+
- **getName** — resolução de nome em cascata, nunca vazia
|
|
900
|
+
- **getBestWaVersion** — busca de versão que não falha em silêncio
|
|
901
|
+
- **resolveLidPhoneFromGroup** — força resolução via metadata de grupo
|
|
902
|
+
- **WhatsApp Flows** — suporte documentado a formulários interativos (`nativeFlowResponseMessage`)
|
|
903
|
+
- **isSystemNotification** — flag em mensagens de notificação de sistema
|
|
904
|
+
- Sistema LID/JID avançado com cache bidirecional (`sharedLidPhoneCache`)
|
|
905
|
+
- `lidToJid`, `resolveJid`, `resolveAll`, `normalizeJid`, `validateJid`, `getSenderInfo`
|
|
906
|
+
- Suporte a `@username` — `isUsername`, `resolveUsername`
|
|
907
|
+
|
|
908
|
+
### v1.0.5
|
|
909
|
+
- Sticker Pack nativo com suporte a animadas e PNG
|
|
910
|
+
- Fix canal newsletter (`extraAttrs` no `plaintext`)
|
|
911
|
+
- Album, Spoiler, ViewOnce V2, Ephemeral, Lottie, Evento
|
|
912
|
+
- Native Flow, Carousel, Template Buttons
|
|
913
|
+
- AI Rich (makeText, makeCode, makeTable, makeList, sendRich)
|
|
914
|
+
- Poll decrypt com `getAggregateVotesInPollMessage`
|
|
915
|
+
- MessageBuilder (`Button`, `ButtonV2`, `Carousel`, `AIRich`)
|
|
1085
916
|
|
|
1086
917
|
---
|
|
1087
918
|
|
|
1088
919
|
<div align="center">
|
|
1089
920
|
|
|
1090
|
-
**@systemzero/baileys v1.0.
|
|
921
|
+
**@systemzero/baileys v1.0.6**
|
|
922
|
+
|
|
923
|
+
Desenvolvido por [Josué </>](https://t.me/blackhzx) · [Canal WhatsApp](https://whatsapp.com/channel/0029VaqUb9aGk1FxqeKKOd2i) · [systemzone.store](https://systemzone.store)
|
|
1091
924
|
|
|
1092
|
-
</div>
|
|
925
|
+
</div>
|