@systemzero/baileys 1.0.5 → 1.0.7
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 +629 -658
- package/lib/Defaults/index.js +2 -2
- package/lib/Socket/chats.js +12 -1
- package/lib/Socket/groups.js +13 -4
- package/lib/Socket/messages-recv.js +45 -6
- package/lib/Socket/messages-recv.js.bak +1273 -0
- package/lib/Socket/messages-send.js +1 -0
- package/lib/Socket/socket.js +4 -4
- package/lib/Utils/bad-mac-handler.js +158 -0
- package/lib/Utils/generics.js +2 -1
- 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 +8 -0
- package/lib/Utils/logger.js +4 -1
- package/lib/Utils/messages-media.js +38 -0
- package/lib/Utils/messages.js +113 -7
- 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/Utils/scheduling.js +138 -0
- package/lib/Utils/validate-connection.js +11 -5
- package/lib/WABinary/jid-utils.js +245 -1
- package/package.json +1 -1
- 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
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
# @systemzero/baileys
|
|
6
6
|
|
|
7
|
-
**v1.0.
|
|
7
|
+
**v1.0.7** · Fork avançado do Baileys com suporte nativo a todos os tipos de mensagens do WhatsApp
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/@systemzero/baileys)
|
|
10
10
|
[](LICENSE)
|
|
11
11
|
[](https://t.me/blackhzx)
|
|
12
|
+
[](https://nodejs.org)
|
|
12
13
|
|
|
13
14
|
</div>
|
|
14
15
|
|
|
@@ -20,13 +21,14 @@
|
|
|
20
21
|
npm i @systemzero/baileys
|
|
21
22
|
```
|
|
22
23
|
|
|
23
|
-
Dependências opcionais
|
|
24
|
+
Dependências opcionais:
|
|
24
25
|
```bash
|
|
25
|
-
npm i sharp
|
|
26
|
-
#
|
|
27
|
-
npm i @napi-rs/image
|
|
26
|
+
npm i sharp # conversão de imagem para sticker pack
|
|
27
|
+
npm i @napi-rs/image # alternativa ao sharp
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
Requer `ffmpeg` instalado no sistema (com suporte a `libopus`) para conversão automática de áudio PTT. Confirme com `ffmpeg -encoders | grep opus`.
|
|
31
|
+
|
|
30
32
|
---
|
|
31
33
|
|
|
32
34
|
## Índice
|
|
@@ -39,28 +41,40 @@ npm i @napi-rs/image
|
|
|
39
41
|
6. [Canais Newsletter](#6-canais-newsletter)
|
|
40
42
|
7. [Enquetes com decrypt](#7-enquetes-com-decrypt)
|
|
41
43
|
8. [AI Rich](#8-ai-rich)
|
|
42
|
-
9. [
|
|
43
|
-
10. [
|
|
44
|
-
11. [
|
|
45
|
-
12. [
|
|
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](#12-botões-estendidos)
|
|
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](#19-ptt-real-com-qualquer-formato)
|
|
55
|
+
20. [Guard de pagamento stealth](#20-guard-de-pagamento-stealth-anti-fraude)
|
|
56
|
+
21. [Bad MAC Handler](#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](#24-whatsapp-flows--formulários-interativos)
|
|
60
|
+
25. [Mensagens agendadas](#25-mensagens-agendadas)
|
|
61
|
+
26. [Status em grupo (GroupStatusMessageV2)](#26-status-em-grupo-groupstatusmessagev2)
|
|
46
62
|
|
|
47
63
|
---
|
|
48
64
|
|
|
49
65
|
## 1. Conexão
|
|
50
66
|
|
|
51
|
-
### Setup básico
|
|
52
|
-
|
|
53
67
|
```js
|
|
54
68
|
const {
|
|
55
69
|
default: makeWASocket,
|
|
56
70
|
useMultiFileAuthState,
|
|
57
71
|
DisconnectReason,
|
|
58
72
|
Browsers,
|
|
59
|
-
|
|
73
|
+
getBestWaVersion
|
|
60
74
|
} = require('@systemzero/baileys')
|
|
61
75
|
|
|
62
76
|
const { state, saveCreds } = await useMultiFileAuthState('./session')
|
|
63
|
-
const { version } = await
|
|
77
|
+
const { version, isLatest, source } = await getBestWaVersion()
|
|
64
78
|
|
|
65
79
|
const sock = makeWASocket({
|
|
66
80
|
version,
|
|
@@ -79,19 +93,25 @@ sock.ev.on('creds.update', saveCreds)
|
|
|
79
93
|
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
|
|
80
94
|
if (connection === 'close') {
|
|
81
95
|
const code = lastDisconnect?.error?.output?.statusCode
|
|
82
|
-
if (code
|
|
96
|
+
if (code === DisconnectReason.loggedOut) {
|
|
97
|
+
process.exit()
|
|
98
|
+
} else if (code === DisconnectReason.forbidden) {
|
|
99
|
+
console.log('Sessão revogada pelo WhatsApp (403). Apague a sessão e re-pareie.')
|
|
100
|
+
process.exit()
|
|
101
|
+
} else {
|
|
102
|
+
startBot()
|
|
103
|
+
}
|
|
83
104
|
}
|
|
84
105
|
})
|
|
85
106
|
```
|
|
86
107
|
|
|
108
|
+
> Use `getBestWaVersion()` em vez de `fetchLatestWaWebVersion()` — ela tenta as duas fontes e só aceita resultado se buscou fresco de verdade, sem cair silenciosamente num fallback desatualizado que pode causar erros 403.
|
|
109
|
+
|
|
87
110
|
### Pairing Code
|
|
88
111
|
|
|
89
112
|
```js
|
|
90
|
-
// Código gerado automaticamente (ex: ABCD-EFGH)
|
|
91
113
|
const code = await sock.requestPairingCode('5511999999999')
|
|
92
|
-
|
|
93
|
-
// Código personalizado — exatamente 8 caracteres
|
|
94
|
-
const code = await sock.requestPairingCode('5511999999999', 'MYBOT001')
|
|
114
|
+
const code = await sock.requestPairingCode('5511999999999', 'MYBOT001') // personalizado — 8 chars
|
|
95
115
|
```
|
|
96
116
|
|
|
97
117
|
### Store em memória
|
|
@@ -110,7 +130,6 @@ const store = {
|
|
|
110
130
|
},
|
|
111
131
|
loadMessage: async (jid, id) => store.messages[jid]?.[id] || null
|
|
112
132
|
}
|
|
113
|
-
|
|
114
133
|
store.bind(sock.ev)
|
|
115
134
|
```
|
|
116
135
|
|
|
@@ -118,111 +137,28 @@ store.bind(sock.ev)
|
|
|
118
137
|
|
|
119
138
|
## 2. Mensagens de mídia
|
|
120
139
|
|
|
121
|
-
Todos os campos de mídia aceitam `Buffer`, `{ url: 'https://...' }` ou `{ stream
|
|
122
|
-
|
|
123
|
-
### Texto
|
|
140
|
+
Todos os campos de mídia aceitam `Buffer`, `{ url: 'https://...' }` ou `{ stream }`.
|
|
124
141
|
|
|
125
142
|
```js
|
|
126
143
|
await sock.sendMessage(jid, { text: 'Olá!' })
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
await sock.sendMessage(jid, {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
})
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Imagem
|
|
136
|
-
|
|
137
|
-
```js
|
|
138
|
-
await sock.sendMessage(jid, {
|
|
139
|
-
image: { url: 'https://exemplo.com/foto.jpg' },
|
|
140
|
-
caption: 'Legenda'
|
|
141
|
-
})
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### Vídeo
|
|
145
|
-
|
|
146
|
-
```js
|
|
147
|
-
await sock.sendMessage(jid, {
|
|
148
|
-
video: { url: 'https://exemplo.com/video.mp4' },
|
|
149
|
-
caption: 'Legenda',
|
|
150
|
-
gifPlayback: false // true envia como GIF silencioso
|
|
151
|
-
})
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### Áudio
|
|
155
|
-
|
|
156
|
-
```js
|
|
157
|
-
// Música
|
|
158
|
-
await sock.sendMessage(jid, {
|
|
159
|
-
audio: buffer,
|
|
160
|
-
mimetype: 'audio/mpeg',
|
|
161
|
-
ptt: false
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
// Nota de voz (PTT)
|
|
165
|
-
await sock.sendMessage(jid, {
|
|
166
|
-
audio: buffer,
|
|
167
|
-
mimetype: 'audio/ogg; codecs=opus',
|
|
168
|
-
ptt: true
|
|
169
|
-
})
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### Documento
|
|
173
|
-
|
|
174
|
-
```js
|
|
175
|
-
await sock.sendMessage(jid, {
|
|
176
|
-
document: buffer,
|
|
177
|
-
mimetype: 'application/pdf',
|
|
178
|
-
fileName: 'relatorio.pdf',
|
|
179
|
-
caption: 'Segue o relatório'
|
|
180
|
-
})
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Figurinha
|
|
184
|
-
|
|
185
|
-
```js
|
|
144
|
+
await sock.sendMessage(jid, { text: '@5511...!', mentions: ['5511999999999@s.whatsapp.net'] })
|
|
145
|
+
await sock.sendMessage(jid, { image: { url: 'https://...' }, caption: 'Legenda' })
|
|
146
|
+
await sock.sendMessage(jid, { video: buffer, caption: 'Legenda', gifPlayback: false })
|
|
147
|
+
await sock.sendMessage(jid, { audio: buffer, mimetype: 'audio/mpeg', ptt: false })
|
|
148
|
+
await sock.sendMessage(jid, { audio: buffer, ptt: true }) // PTT — converte automaticamente
|
|
149
|
+
await sock.sendMessage(jid, { document: buffer, mimetype: 'application/pdf', fileName: 'doc.pdf' })
|
|
186
150
|
await sock.sendMessage(jid, { sticker: buffer })
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### Album (múltiplas mídias agrupadas)
|
|
190
|
-
|
|
191
|
-
Mínimo 2 itens.
|
|
192
|
-
|
|
193
|
-
```js
|
|
194
151
|
await sock.sendMessage(jid, {
|
|
195
|
-
album: [
|
|
196
|
-
{ image: buffer1 },
|
|
197
|
-
{ image: buffer2, caption: 'Segunda foto' },
|
|
198
|
-
{ video: bufferVideo },
|
|
199
|
-
]
|
|
152
|
+
album: [{ image: buffer1 }, { image: buffer2 }, { video: bufferVideo }]
|
|
200
153
|
})
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### Contato
|
|
204
|
-
|
|
205
|
-
```js
|
|
206
154
|
await sock.sendMessage(jid, {
|
|
207
155
|
contacts: {
|
|
208
156
|
displayName: 'João',
|
|
209
|
-
contacts: [{
|
|
210
|
-
vcard: `BEGIN:VCARD\nVERSION:3.0\nFN:João Silva\nTEL:+5511999999999\nEND:VCARD`
|
|
211
|
-
}]
|
|
157
|
+
contacts: [{ vcard: 'BEGIN:VCARD\nVERSION:3.0\nFN:João\nTEL:+5511999999999\nEND:VCARD' }]
|
|
212
158
|
}
|
|
213
159
|
})
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
### Localização
|
|
217
|
-
|
|
218
|
-
```js
|
|
219
160
|
await sock.sendMessage(jid, {
|
|
220
|
-
location: {
|
|
221
|
-
degreesLatitude: -23.550520,
|
|
222
|
-
degreesLongitude: -46.633308,
|
|
223
|
-
name: 'São Paulo',
|
|
224
|
-
address: 'SP, Brasil'
|
|
225
|
-
}
|
|
161
|
+
location: { degreesLatitude: -23.55, degreesLongitude: -46.63, name: 'São Paulo' }
|
|
226
162
|
})
|
|
227
163
|
```
|
|
228
164
|
|
|
@@ -230,790 +166,825 @@ await sock.sendMessage(jid, {
|
|
|
230
166
|
|
|
231
167
|
## 3. Mensagens especiais
|
|
232
168
|
|
|
233
|
-
### Reação
|
|
234
|
-
|
|
235
|
-
```js
|
|
236
|
-
await sock.sendMessage(jid, {
|
|
237
|
-
react: { text: '❤️', key: message.key }
|
|
238
|
-
// text: '' remove a reação
|
|
239
|
-
})
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
### Deletar mensagem
|
|
243
|
-
|
|
244
169
|
```js
|
|
170
|
+
await sock.sendMessage(jid, { react: { text: '❤️', key: message.key } })
|
|
245
171
|
await sock.sendMessage(jid, { delete: message.key })
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
172
|
+
await sock.sendMessage(jid, { edit: message.key, text: 'Texto editado' })
|
|
173
|
+
await sock.sendMessage(jid, { image: buffer, viewOnce: true })
|
|
174
|
+
await sock.sendMessage(jid, { image: buffer, viewOnceV2: true })
|
|
175
|
+
await sock.sendMessage(jid, { image: buffer, caption: '!', spoiler: true })
|
|
176
|
+
await sock.sendMessage(jid, { image: buffer, groupStatus: true })
|
|
177
|
+
await sock.sendMessage(jid, { image: buffer, ephemeral: true })
|
|
178
|
+
await sock.sendMessage(jid, { sticker: buffer, isLottie: true })
|
|
179
|
+
await sock.sendMessage(jid, { text: '@all', mentionAll: true })
|
|
251
180
|
await sock.sendMessage(jid, {
|
|
252
|
-
|
|
253
|
-
|
|
181
|
+
text: 'Confira!',
|
|
182
|
+
externalAdReply: {
|
|
183
|
+
title: 'Título', body: 'Descrição',
|
|
184
|
+
thumbnail: bufferImg, mediaType: 1,
|
|
185
|
+
sourceUrl: 'https://systemzone.store',
|
|
186
|
+
renderLargerThumbnail: true
|
|
187
|
+
}
|
|
254
188
|
})
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### Fixar mensagem
|
|
258
|
-
|
|
259
|
-
```js
|
|
260
189
|
await sock.sendMessage(jid, {
|
|
261
|
-
|
|
262
|
-
type: 1, // 1 = fixar, 2 = desfixar
|
|
263
|
-
time: 86400, // duração em segundos
|
|
264
|
-
messageKey: message.key
|
|
265
|
-
}
|
|
190
|
+
poll: { name: 'Pergunta?', values: ['A', 'B', 'C'], selectableCount: 1 }
|
|
266
191
|
})
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
### Encaminhar
|
|
270
|
-
|
|
271
|
-
```js
|
|
272
192
|
const { generateForwardMessageContent, generateWAMessageFromContent } = require('@systemzero/baileys')
|
|
273
|
-
|
|
274
|
-
const
|
|
275
|
-
const msg = generateWAMessageFromContent(jid, content, { quoted: m })
|
|
193
|
+
const fwd = generateForwardMessageContent(message, false)
|
|
194
|
+
const msg = generateWAMessageFromContent(jid, fwd, { quoted: m })
|
|
276
195
|
await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
|
|
277
196
|
```
|
|
278
197
|
|
|
279
|
-
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 4. Botões e interativos
|
|
280
201
|
|
|
281
202
|
```js
|
|
282
|
-
|
|
203
|
+
const { generateWAMessageFromContent, proto } = require('@systemzero/baileys')
|
|
283
204
|
|
|
284
|
-
|
|
285
|
-
|
|
205
|
+
const msg = generateWAMessageFromContent(jid, {
|
|
206
|
+
viewOnceMessage: {
|
|
207
|
+
message: {
|
|
208
|
+
interactiveMessage: proto.Message.InteractiveMessage.create({
|
|
209
|
+
header: { title: 'Título', hasMediaAttachment: false },
|
|
210
|
+
body: { text: 'Texto' },
|
|
211
|
+
footer: { text: 'Rodapé' },
|
|
212
|
+
nativeFlowMessage: { buttons: [ /* tipos abaixo */ ] }
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}, { quoted: m })
|
|
286
217
|
|
|
287
|
-
|
|
288
|
-
await sock.sendMessage(jid, { image: buffer, viewOnceV2Extension: true })
|
|
218
|
+
await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
|
|
289
219
|
```
|
|
290
220
|
|
|
291
|
-
### Spoiler
|
|
292
|
-
|
|
293
221
|
```js
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
222
|
+
{ name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: 'OK', id: 'ok' }) }
|
|
223
|
+
{ name: 'cta_url', buttonParamsJson: JSON.stringify({ display_text: 'Abrir', url: 'https://systemzone.store' }) }
|
|
224
|
+
{ name: 'cta_copy', buttonParamsJson: JSON.stringify({ display_text: 'Copiar', copy_code: 'CODIGO' }) }
|
|
225
|
+
{ name: 'cta_call', buttonParamsJson: JSON.stringify({ display_text: 'Ligar', phone_number: '5511999999999' }) }
|
|
226
|
+
{
|
|
227
|
+
name: 'single_select',
|
|
228
|
+
buttonParamsJson: JSON.stringify({
|
|
229
|
+
title: 'Escolher',
|
|
230
|
+
sections: [{ title: 'Cat', rows: [{ header: 'Op1', title: 'Opção 1', description: 'Desc', id: 'op1' }] }]
|
|
231
|
+
})
|
|
232
|
+
}
|
|
299
233
|
```
|
|
300
234
|
|
|
301
|
-
###
|
|
235
|
+
### Header com imagem + nativeFlow
|
|
302
236
|
|
|
303
237
|
```js
|
|
238
|
+
// Use `caption`, não `text` — `text` faz a lib pular o bloco do header
|
|
304
239
|
await sock.sendMessage(jid, {
|
|
305
|
-
image:
|
|
306
|
-
caption:
|
|
307
|
-
|
|
240
|
+
image: { url: 'https://...' },
|
|
241
|
+
caption: 'Texto do card',
|
|
242
|
+
nativeFlow: [{ text: 'Botão', id: 'btn1' }]
|
|
308
243
|
})
|
|
309
244
|
```
|
|
310
245
|
|
|
311
|
-
###
|
|
246
|
+
### Carousel
|
|
312
247
|
|
|
313
248
|
```js
|
|
314
249
|
await sock.sendMessage(jid, {
|
|
315
|
-
|
|
316
|
-
|
|
250
|
+
cards: [
|
|
251
|
+
{ image: buffer1, caption: 'Card 1', nativeFlow: [{ text: 'Ver', id: 'c1' }] },
|
|
252
|
+
{ image: buffer2, caption: 'Card 2', nativeFlow: [{ text: 'Ver', id: 'c2' }] },
|
|
253
|
+
],
|
|
254
|
+
footer: 'Rodapé'
|
|
317
255
|
})
|
|
318
256
|
```
|
|
319
257
|
|
|
320
|
-
###
|
|
258
|
+
### Template Buttons / Sections
|
|
321
259
|
|
|
322
260
|
```js
|
|
323
261
|
await sock.sendMessage(jid, {
|
|
324
|
-
|
|
325
|
-
|
|
262
|
+
text: 'Escolha:',
|
|
263
|
+
templateButtons: [
|
|
264
|
+
{ text: 'Resposta', id: 'r1' },
|
|
265
|
+
{ text: 'Site', url: 'https://systemzone.store' },
|
|
266
|
+
{ text: 'Ligar', call: '5511999999999' },
|
|
267
|
+
]
|
|
326
268
|
})
|
|
327
|
-
```
|
|
328
269
|
|
|
329
|
-
### Keep (salvar mensagem)
|
|
330
|
-
|
|
331
|
-
```js
|
|
332
270
|
await sock.sendMessage(jid, {
|
|
333
|
-
|
|
334
|
-
|
|
271
|
+
text: 'Selecione', buttonText: 'Ver opções',
|
|
272
|
+
sections: [{ title: 'Cat', rows: [{ title: 'Item 1', description: 'Desc', id: 'i1' }] }]
|
|
335
273
|
})
|
|
336
274
|
```
|
|
337
275
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
```js
|
|
341
|
-
await sock.sendMessage(jid, {
|
|
342
|
-
event: {
|
|
343
|
-
isCanceled: false,
|
|
344
|
-
name: 'Reunião',
|
|
345
|
-
description: 'Alinhamento',
|
|
346
|
-
location: { name: 'Sala 3', address: 'Rua X, 100' },
|
|
347
|
-
startTime: Math.floor(Date.now() / 1000) + 3600,
|
|
348
|
-
endTime: Math.floor(Date.now() / 1000) + 7200,
|
|
349
|
-
}
|
|
350
|
-
})
|
|
351
|
-
```
|
|
276
|
+
---
|
|
352
277
|
|
|
353
|
-
|
|
278
|
+
## 5. Sticker Pack nativo
|
|
354
279
|
|
|
355
280
|
```js
|
|
356
281
|
await sock.sendMessage(jid, {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
282
|
+
cover: bufferWebP,
|
|
283
|
+
stickers: [
|
|
284
|
+
{ data: bufferWebP, emojis: ['😂'] },
|
|
285
|
+
{ data: bufferAnima, emojis: ['🔥'] },
|
|
286
|
+
{ data: bufferPng, emojis: ['✨'] },
|
|
287
|
+
],
|
|
288
|
+
name: 'Nome do Pack',
|
|
289
|
+
publisher: 'Autor',
|
|
362
290
|
})
|
|
363
291
|
```
|
|
364
292
|
|
|
365
|
-
|
|
293
|
+
`cover` e cada `stickers[].data` esperam **Buffer**. Máximo 60 figurinhas, até 1MB cada. Requer `sharp` ou `@napi-rs/image` para PNG.
|
|
366
294
|
|
|
367
|
-
|
|
368
|
-
await sock.sendMessage(jid, {
|
|
369
|
-
image: buffer,
|
|
370
|
-
invoiceNote: 'Pagamento pedido #1234'
|
|
371
|
-
})
|
|
372
|
-
```
|
|
295
|
+
---
|
|
373
296
|
|
|
374
|
-
|
|
297
|
+
## 6. Canais Newsletter
|
|
375
298
|
|
|
376
299
|
```js
|
|
377
|
-
await sock.sendMessage(
|
|
378
|
-
text: 'Confira!',
|
|
379
|
-
externalAdReply: {
|
|
380
|
-
title: 'System Zero',
|
|
381
|
-
body: 'Descrição do produto',
|
|
382
|
-
thumbnail: bufferImagem,
|
|
383
|
-
mediaType: 1,
|
|
384
|
-
sourceUrl: 'https://systemzone.store',
|
|
385
|
-
renderLargerThumbnail: true
|
|
386
|
-
}
|
|
387
|
-
})
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
### Mention All
|
|
300
|
+
await sock.sendMessage('120363...@newsletter', { text: 'Novidade!' })
|
|
391
301
|
|
|
392
|
-
|
|
393
|
-
await
|
|
394
|
-
|
|
395
|
-
|
|
302
|
+
const { generateWAMessage, generateMessageIDV2 } = require('@systemzero/baileys')
|
|
303
|
+
const fullMsg = await generateWAMessage(canalJid, { image: buffer, caption: 'Legenda' }, {
|
|
304
|
+
upload: sock.waUploadToServer, userJid: sock.user.id,
|
|
305
|
+
messageId: generateMessageIDV2(sock.user.id),
|
|
396
306
|
})
|
|
307
|
+
await sock.relayMessage(canalJid, fullMsg.message, { messageId: fullMsg.key.id })
|
|
308
|
+
|
|
309
|
+
const canal = await sock.newsletterCreate('Nome', 'Descrição')
|
|
310
|
+
await sock.newsletterFollow(jid)
|
|
311
|
+
await sock.newsletterUnfollow(jid)
|
|
312
|
+
await sock.newsletterMute(jid)
|
|
313
|
+
await sock.newsletterUnmute(jid)
|
|
314
|
+
const meta = await sock.newsletterMetadata('jid', jid)
|
|
315
|
+
await sock.newsletterUpdateName(jid, 'Novo Nome')
|
|
316
|
+
await sock.newsletterUpdateDescription(jid, 'Nova descrição')
|
|
317
|
+
await sock.newsletterUpdatePicture(jid, buffer)
|
|
318
|
+
await sock.newsletterRemovePicture(jid)
|
|
319
|
+
await sock.newsletterReactMessage(jid, serverId, '❤️')
|
|
320
|
+
const msgs = await sock.newsletterFetchMessages(jid, 30, 0, 0)
|
|
321
|
+
await sock.newsletterDelete(jid)
|
|
322
|
+
const { subscribers } = await sock.newsletterSubscribers(jid)
|
|
397
323
|
```
|
|
398
324
|
|
|
399
|
-
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## 7. Enquetes com decrypt
|
|
400
328
|
|
|
401
329
|
```js
|
|
402
330
|
await sock.sendMessage(jid, {
|
|
403
|
-
|
|
331
|
+
poll: { name: 'Pergunta?', values: ['A', 'B', 'C'], selectableCount: 1 }
|
|
404
332
|
})
|
|
405
|
-
```
|
|
406
333
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
]
|
|
334
|
+
const { getAggregateVotesInPollMessage } = require('@systemzero/baileys/lib/Utils/messages.js')
|
|
335
|
+
sock.ev.on('messages.update', async (updates) => {
|
|
336
|
+
for (const { key, update } of updates) {
|
|
337
|
+
if (!update.pollUpdates) continue
|
|
338
|
+
const pollMsg = await store.loadMessage(key.remoteJid, key.id)
|
|
339
|
+
if (!pollMsg?.message) continue
|
|
340
|
+
const result = getAggregateVotesInPollMessage({
|
|
341
|
+
message: pollMsg.message, pollUpdates: update.pollUpdates
|
|
342
|
+
})
|
|
343
|
+
// [{ name: 'A', voters: ['5511...@s.whatsapp.net'] }]
|
|
418
344
|
}
|
|
419
345
|
})
|
|
420
346
|
```
|
|
421
347
|
|
|
422
348
|
---
|
|
423
349
|
|
|
424
|
-
##
|
|
425
|
-
|
|
426
|
-
### Estrutura base
|
|
350
|
+
## 8. AI Rich
|
|
427
351
|
|
|
428
352
|
```js
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
header: { title: 'Título', hasMediaAttachment: false },
|
|
436
|
-
body: { text: 'Texto do corpo' },
|
|
437
|
-
footer: { text: 'Rodapé' },
|
|
438
|
-
nativeFlowMessage: {
|
|
439
|
-
buttons: [ /* tipos abaixo */ ]
|
|
440
|
-
}
|
|
441
|
-
})
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}, { quoted: m })
|
|
353
|
+
await sock.sendRich(jid, [
|
|
354
|
+
sock.makeText('Acesse [nosso site](https://systemzone.store).'),
|
|
355
|
+
sock.makeCode('bash', 'npm i @systemzero/baileys'),
|
|
356
|
+
sock.makeTable([['Nome', 'Status'], ['Botões', '✅']]),
|
|
357
|
+
sock.makeList(['Item 1', 'Item 2']),
|
|
358
|
+
], quotedMsg, ['RICH_RESPONSE_CODE', 'RICH_RESPONSE_TABLE'])
|
|
445
359
|
|
|
446
|
-
await sock.
|
|
360
|
+
await sock.sendRichText(jid, 'Texto com [link](https://systemzone.store)', quotedMsg)
|
|
361
|
+
await sock.sendRichCode(jid, 'Título', 'javascript', 'const x = 1', quotedMsg)
|
|
362
|
+
await sock.sendRichList(jid, 'Lista', ['A', 'B'], quotedMsg)
|
|
447
363
|
```
|
|
448
364
|
|
|
449
|
-
|
|
365
|
+
---
|
|
450
366
|
|
|
451
|
-
|
|
452
|
-
// Resposta rápida
|
|
453
|
-
{ name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: 'Confirmar', id: 'confirmar' }) }
|
|
367
|
+
## 9. LID / JID — Sistema avançado
|
|
454
368
|
|
|
455
|
-
|
|
456
|
-
|
|
369
|
+
O WhatsApp usa dois tipos de identificador:
|
|
370
|
+
- **JID** (`@s.whatsapp.net`) — baseado em número de telefone
|
|
371
|
+
- **LID** (`@lid`) — identificador opaco sem número
|
|
457
372
|
|
|
458
|
-
|
|
459
|
-
{ name: 'cta_copy', buttonParamsJson: JSON.stringify({ display_text: 'Copiar código', copy_code: 'PROMO2025' }) }
|
|
373
|
+
A partir da v1.0.6, a lib resolve automaticamente LID↔JID via `sharedLidPhoneCache`, inclusive ao buscar metadata de grupo (`groupMetadata`).
|
|
460
374
|
|
|
461
|
-
|
|
462
|
-
|
|
375
|
+
```js
|
|
376
|
+
const {
|
|
377
|
+
lidToJid, resolveJid, resolveAll, normalizeJid, validateJid,
|
|
378
|
+
getSenderInfo, sharedLidPhoneCache, isLidUser, isPnUser,
|
|
379
|
+
getBotJid, setBotMap
|
|
380
|
+
} = require('@systemzero/baileys')
|
|
463
381
|
|
|
464
|
-
|
|
465
|
-
{
|
|
382
|
+
const jid = lidToJid('123456@lid')
|
|
383
|
+
const { jid, lid } = resolveAll('5511999999999@s.whatsapp.net')
|
|
384
|
+
const { jid, lid, isGroup } = getSenderInfo(message)
|
|
466
385
|
|
|
467
|
-
//
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
rows: [
|
|
475
|
-
{ header: 'Op 1', title: 'Opção 1', description: 'Desc', id: 'op1' },
|
|
476
|
-
{ header: 'Op 2', title: 'Opção 2', description: 'Desc', id: 'op2' },
|
|
477
|
-
]
|
|
478
|
-
}]
|
|
479
|
-
})
|
|
480
|
-
}
|
|
386
|
+
normalizeJid('5511999999999') // → '5511999999999@s.whatsapp.net'
|
|
387
|
+
normalizeJid('123456@lid') // → resolve via cache
|
|
388
|
+
|
|
389
|
+
sharedLidPhoneCache.set('123456@lid', '5511999999999@s.whatsapp.net')
|
|
390
|
+
const jid = sharedLidPhoneCache.getPhoneForLid('123456@lid')
|
|
391
|
+
const lid = sharedLidPhoneCache.getLidForPhone('5511999999999@s.whatsapp.net')
|
|
392
|
+
console.log('Cache size:', sharedLidPhoneCache.size)
|
|
481
393
|
```
|
|
482
394
|
|
|
483
|
-
|
|
395
|
+
> ⚠️ Identidades do próprio bot (`sock.user.id`/`.lid`) vêm com sufixo de dispositivo (`numero:N@dominio`). Pra comparar com `participants`, remova só o `:N` preservando o domínio: `jid.replace(/:\d+(?=@)/, '')` — **não use** `split(':')[0]`.
|
|
396
|
+
|
|
397
|
+
---
|
|
484
398
|
|
|
485
|
-
|
|
399
|
+
## 10. Username (@usuario)
|
|
486
400
|
|
|
487
401
|
```js
|
|
488
|
-
const {
|
|
402
|
+
const { resolveUsername, isUsername } = require('@systemzero/baileys')
|
|
489
403
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
messageId: generateMessageIDV2(sock.user.id),
|
|
494
|
-
})
|
|
495
|
-
const img = uploaded.message?.imageMessage
|
|
496
|
-
|
|
497
|
-
// No header:
|
|
498
|
-
header: {
|
|
499
|
-
title: '',
|
|
500
|
-
hasMediaAttachment: true,
|
|
501
|
-
imageMessage: {
|
|
502
|
-
url: img.url,
|
|
503
|
-
mimetype: img.mimetype,
|
|
504
|
-
fileSha256: img.fileSha256,
|
|
505
|
-
fileLength: img.fileLength,
|
|
506
|
-
mediaKey: img.mediaKey,
|
|
507
|
-
fileEncSha256: img.fileEncSha256,
|
|
508
|
-
directPath: img.directPath,
|
|
509
|
-
mediaKeyTimestamp: img.mediaKeyTimestamp,
|
|
510
|
-
jpegThumbnail: img.jpegThumbnail,
|
|
511
|
-
}
|
|
512
|
-
}
|
|
404
|
+
isUsername('@josue') // true
|
|
405
|
+
const jid = await resolveUsername('@josue', sock.onWhatsApp.bind(sock))
|
|
406
|
+
if (jid) await sock.sendMessage(jid, { text: 'Olá!' })
|
|
513
407
|
```
|
|
514
408
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
```js
|
|
518
|
-
header: {
|
|
519
|
-
title: 'Produto',
|
|
520
|
-
hasMediaAttachment: true,
|
|
521
|
-
productMessage: proto.Message.ProductMessage.create({
|
|
522
|
-
product: proto.Message.ProductMessage.ProductSnapshot.create({
|
|
523
|
-
productImage: proto.Message.ImageMessage.create({ ...img }),
|
|
524
|
-
productId: 'ID-001',
|
|
525
|
-
title: 'Nome do Produto',
|
|
526
|
-
description: 'Descrição completa',
|
|
527
|
-
currencyCode: 'BRL',
|
|
528
|
-
priceAmount1000: 29990, // R$ 29,99
|
|
529
|
-
retailerId: 'minha-loja',
|
|
530
|
-
url: 'https://loja.com/produto',
|
|
531
|
-
productImageCount: 1,
|
|
532
|
-
}),
|
|
533
|
-
businessOwnerJid: sock.user.id
|
|
534
|
-
})
|
|
535
|
-
}
|
|
536
|
-
```
|
|
409
|
+
---
|
|
537
410
|
|
|
538
|
-
|
|
411
|
+
## 11. MessageBuilder — Button, ButtonV2, Carousel, AIRich
|
|
539
412
|
|
|
540
413
|
```js
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
{
|
|
544
|
-
image: buffer1,
|
|
545
|
-
caption: 'Texto do card 1',
|
|
546
|
-
title: 'Card 1',
|
|
547
|
-
nativeFlow: [
|
|
548
|
-
{ text: 'Ver mais', id: 'card1' },
|
|
549
|
-
{ text: 'Site', url: 'https://systemzone.store' }
|
|
550
|
-
]
|
|
551
|
-
},
|
|
552
|
-
{
|
|
553
|
-
image: buffer2,
|
|
554
|
-
caption: 'Texto do card 2',
|
|
555
|
-
nativeFlow: [{ text: 'Clique', id: 'card2' }]
|
|
556
|
-
}
|
|
557
|
-
],
|
|
558
|
-
footer: 'Rodapé'
|
|
559
|
-
})
|
|
414
|
+
const { Button, ButtonV2, Carousel, AIRich } = require('@systemzero/baileys/lib/MB.cjs')
|
|
415
|
+
// O socket vai sempre no construtor: new ButtonV2(sock)
|
|
560
416
|
```
|
|
561
417
|
|
|
562
|
-
###
|
|
418
|
+
### ButtonV2
|
|
563
419
|
|
|
564
420
|
```js
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
})
|
|
421
|
+
const msg = new ButtonV2(sock)
|
|
422
|
+
msg.setTitle('Título'); msg.setBody('Corpo'); msg.setFooter('Rodapé')
|
|
423
|
+
msg.setThumbnail('https://exemplo.com/imagem.jpg')
|
|
424
|
+
msg.addButton('✅ Opção 1', 'opcao_1')
|
|
425
|
+
msg.addButton('❌ Opção 2', 'opcao_2')
|
|
426
|
+
await msg.send(jid, { quoted: m })
|
|
427
|
+
// clique chega como m.body === 'opcao_1'
|
|
573
428
|
```
|
|
574
429
|
|
|
575
|
-
###
|
|
430
|
+
### Button (native flow)
|
|
576
431
|
|
|
577
432
|
```js
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
{ title: 'Item 1', description: 'Desc', id: 'item1' },
|
|
585
|
-
{ title: 'Item 2', description: 'Desc', id: 'item2' },
|
|
586
|
-
]
|
|
587
|
-
}]
|
|
588
|
-
})
|
|
433
|
+
const msg = new Button(sock)
|
|
434
|
+
msg.addReply('✅ Confirmar', 'confirmar')
|
|
435
|
+
msg.addUrl('🔗 Abrir', 'https://systemzone.store')
|
|
436
|
+
msg.addCopy('📋 Copiar', 'PROMO2025')
|
|
437
|
+
msg.addCall('📞 Ligar', '5511999999999')
|
|
438
|
+
await msg.send(jid, { quoted: m })
|
|
589
439
|
```
|
|
590
440
|
|
|
591
|
-
###
|
|
441
|
+
### Carousel
|
|
592
442
|
|
|
593
443
|
```js
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
})
|
|
444
|
+
const msg = new Carousel(sock)
|
|
445
|
+
msg.setBody('Escolha:')
|
|
446
|
+
msg.card(c => c.image('https://...').title('Card 1').text('Desc').button('Ver', 'c1'))
|
|
447
|
+
msg.card(c => c.image('https://...').title('Card 2').text('Desc').button('Ver', 'c2'))
|
|
448
|
+
await msg.send(jid, { quoted: m })
|
|
599
449
|
```
|
|
600
450
|
|
|
601
|
-
###
|
|
451
|
+
### AIRich
|
|
602
452
|
|
|
603
453
|
```js
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
{ text: 'Link', url: 'https://systemzone.store' },
|
|
610
|
-
]
|
|
611
|
-
})
|
|
454
|
+
const msg = new AIRich(sock)
|
|
455
|
+
msg.addText('Acesse [System Zero](https://systemzone.store).')
|
|
456
|
+
msg.addCode('javascript', `require('@systemzero/baileys')`)
|
|
457
|
+
msg.addTable([['Comando', 'Desc'], ['!menu', 'Menu principal']])
|
|
458
|
+
await msg.send(jid, { quoted: m })
|
|
612
459
|
```
|
|
613
460
|
|
|
614
|
-
|
|
461
|
+
---
|
|
615
462
|
|
|
616
|
-
|
|
617
|
-
await sock.sendMessage(jid, {
|
|
618
|
-
text: 'Ouça e escolha:',
|
|
619
|
-
nativeFlow: [{ text: 'Opção', id: 'op' }],
|
|
620
|
-
audioFooter: bufferAudio
|
|
621
|
-
})
|
|
622
|
-
```
|
|
463
|
+
## 12. Botões estendidos
|
|
623
464
|
|
|
624
|
-
|
|
465
|
+
```js
|
|
466
|
+
await sock.sendMessage(jid, { text: 'Mensagem', nativeFlow: [ /* botões */ ] })
|
|
625
467
|
|
|
626
|
-
|
|
468
|
+
{ text: '⏰ Me lembre', reminder: 'lembrete_id' }
|
|
469
|
+
{ text: '🔕 Cancelar', cancelReminder: 'lembrete_id' }
|
|
470
|
+
{ text: '📍 Endereço', address: true }
|
|
471
|
+
{ text: '📡 Localização', location: true }
|
|
472
|
+
{ text: '🛍️ Catálogo', catalog: '5511999999999@s.whatsapp.net' }
|
|
473
|
+
{ text: 'Copiar código', otp: '123456' }
|
|
474
|
+
{ text: '📞 Ligar', phoneNumber: '5511999999999' }
|
|
475
|
+
{ text: '🗑️ Limpar chat', clearChat: true }
|
|
476
|
+
{ text: '🔗 Abrir', urlBtn: 'https://systemzone.store' }
|
|
477
|
+
```
|
|
627
478
|
|
|
628
|
-
|
|
479
|
+
### isSystemNotification
|
|
629
480
|
|
|
630
481
|
```js
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
{ data: buffer1, emojis: ['😂'] },
|
|
635
|
-
{ data: bufferAnimado, emojis: ['🔥', '💀'] },
|
|
636
|
-
{ data: bufferPng, emojis: ['🐱'] }, // PNG converte automaticamente
|
|
637
|
-
],
|
|
638
|
-
name: 'Nome do Pack',
|
|
639
|
-
publisher: 'Autor',
|
|
640
|
-
description: 'Descrição opcional'
|
|
482
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
483
|
+
const msg = messages[0]
|
|
484
|
+
if (msg.isSystemNotification) return
|
|
641
485
|
})
|
|
642
486
|
```
|
|
643
487
|
|
|
644
|
-
`cover` aceita `Buffer`, `{ url }` ou `{ stream }`. O mesmo vale para cada `sticker.data`.
|
|
645
|
-
|
|
646
|
-
Limites: máximo **60 figurinhas** por pack, cada uma com até **1MB**.
|
|
647
|
-
|
|
648
|
-
Requer `sharp` ou `@napi-rs/image` para conversão de PNG e geração de thumbnail. Sem eles, apenas WebP é aceito.
|
|
649
|
-
|
|
650
488
|
---
|
|
651
489
|
|
|
652
|
-
##
|
|
653
|
-
|
|
654
|
-
### Enviar texto
|
|
490
|
+
## 13. Grupos
|
|
655
491
|
|
|
656
492
|
```js
|
|
657
|
-
await sock.
|
|
493
|
+
const meta = await sock.groupMetadata(jid)
|
|
494
|
+
const grupo = await sock.groupCreate('Nome', ['5511...@s.whatsapp.net'])
|
|
495
|
+
await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'add')
|
|
496
|
+
await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'remove')
|
|
497
|
+
await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'promote')
|
|
498
|
+
await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'demote')
|
|
499
|
+
await sock.groupLeave(jid)
|
|
500
|
+
await sock.groupUpdateSubject(jid, 'Novo Nome')
|
|
501
|
+
await sock.groupUpdateDescription(jid, 'Nova descrição')
|
|
502
|
+
const code = await sock.groupInviteCode(jid)
|
|
503
|
+
await sock.groupRevokeInvite(jid)
|
|
504
|
+
await sock.groupAcceptInvite('CODIGO')
|
|
505
|
+
await sock.groupToggleEphemeral(jid, 86400)
|
|
506
|
+
const grupos = await sock.groupFetchAllParticipating()
|
|
658
507
|
```
|
|
659
508
|
|
|
660
|
-
|
|
509
|
+
---
|
|
661
510
|
|
|
662
|
-
|
|
511
|
+
## 14. Perfil e privacidade
|
|
663
512
|
|
|
664
513
|
```js
|
|
665
|
-
const
|
|
514
|
+
const url = await sock.profilePictureUrl(jid, 'image')
|
|
515
|
+
await sock.updateProfilePicture(jid, buffer)
|
|
516
|
+
await sock.updateProfileStatus('🤖 Bot ativo')
|
|
517
|
+
const [result] = await sock.onWhatsApp('5511999999999')
|
|
518
|
+
await sock.updateBlockStatus(jid, 'block')
|
|
519
|
+
await sock.updateBlockStatus(jid, 'unblock')
|
|
520
|
+
await sock.sendPresenceUpdate('composing', jid)
|
|
521
|
+
await sock.sendPresenceUpdate('available', jid)
|
|
522
|
+
await sock.presenceSubscribe(jid)
|
|
523
|
+
await sock.readMessages([message.key])
|
|
524
|
+
await sock.chatModify({ archive: true }, jid)
|
|
525
|
+
await sock.chatModify({ pin: true }, jid)
|
|
526
|
+
await sock.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid)
|
|
527
|
+
await sock.logout()
|
|
528
|
+
```
|
|
666
529
|
|
|
667
|
-
|
|
530
|
+
---
|
|
668
531
|
|
|
669
|
-
|
|
670
|
-
image: buffer,
|
|
671
|
-
caption: 'Legenda'
|
|
672
|
-
}, {
|
|
673
|
-
upload: sock.waUploadToServer,
|
|
674
|
-
userJid: sock.user.id,
|
|
675
|
-
messageId: generateMessageIDV2(sock.user.id),
|
|
676
|
-
})
|
|
532
|
+
## 15. Eventos do socket
|
|
677
533
|
|
|
678
|
-
|
|
679
|
-
|
|
534
|
+
```js
|
|
535
|
+
sock.ev.on('messages.upsert', ({ messages, type }) => {})
|
|
536
|
+
sock.ev.on('messages.update', (updates) => {})
|
|
537
|
+
sock.ev.on('messages.delete', (item) => {})
|
|
538
|
+
sock.ev.on('messages.reaction', (reactions) => {})
|
|
539
|
+
sock.ev.on('messages.decrypt-failed', (failInfo) => {}) // ver seção 20
|
|
540
|
+
sock.ev.on('presence.update', ({ id, presences }) => {})
|
|
541
|
+
sock.ev.on('groups.update', (updates) => {})
|
|
542
|
+
sock.ev.on('group-participants.update', ({ id, participants, action }) => {})
|
|
543
|
+
sock.ev.on('contacts.update', (contacts) => {})
|
|
544
|
+
sock.ev.on('connection.update', ({ connection, lastDisconnect, qr }) => {})
|
|
545
|
+
sock.ev.on('creds.update', saveCreds)
|
|
546
|
+
sock.ev.on('call', (calls) => {
|
|
547
|
+
for (const call of calls) {
|
|
548
|
+
if (call.status === 'offer') sock.rejectCall(call.id, call.from)
|
|
549
|
+
}
|
|
680
550
|
})
|
|
681
551
|
```
|
|
682
552
|
|
|
683
|
-
|
|
553
|
+
---
|
|
684
554
|
|
|
685
|
-
|
|
555
|
+
## 16. Utilitários
|
|
686
556
|
|
|
687
557
|
```js
|
|
688
|
-
|
|
689
|
-
const
|
|
690
|
-
|
|
691
|
-
// Seguir / deixar
|
|
692
|
-
await sock.newsletterFollow(jid)
|
|
693
|
-
await sock.newsletterUnfollow(jid)
|
|
694
|
-
|
|
695
|
-
// Silenciar
|
|
696
|
-
await sock.newsletterMute(jid)
|
|
697
|
-
await sock.newsletterUnmute(jid)
|
|
698
|
-
|
|
699
|
-
// Metadata
|
|
700
|
-
const meta = await sock.newsletterMetadata('jid', jid)
|
|
701
|
-
const meta = await sock.newsletterMetadata('invite', 'CODIGO')
|
|
558
|
+
const { downloadMediaMessage } = require('@systemzero/baileys')
|
|
559
|
+
const buffer = await downloadMediaMessage(message, 'buffer', {})
|
|
702
560
|
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
await sock.newsletterUpdateDescription(jid, 'Nova descrição')
|
|
706
|
-
await sock.newsletterUpdatePicture(jid, buffer)
|
|
707
|
-
await sock.newsletterRemovePicture(jid)
|
|
561
|
+
const { generateWAMessage, generateWAMessageFromContent, generateMessageIDV2 } = require('@systemzero/baileys')
|
|
562
|
+
const { jidNormalizedUser, isJidGroup, isJidNewsletter, isLidUser, isPnUser } = require('@systemzero/baileys')
|
|
708
563
|
|
|
709
|
-
//
|
|
710
|
-
|
|
564
|
+
// Detectar dispositivo — analisa o ID DA MENSAGEM, não o JID
|
|
565
|
+
const { getDevice } = require('@systemzero/baileys')
|
|
566
|
+
const device = getDevice(message.key.id) // 'android' | 'ios' | 'web' | 'unknown'
|
|
567
|
+
```
|
|
711
568
|
|
|
712
|
-
|
|
713
|
-
const msgs = await sock.newsletterFetchMessages(jid, 30, 0, 0)
|
|
569
|
+
---
|
|
714
570
|
|
|
715
|
-
|
|
716
|
-
const count = await sock.newsletterAdminCount(jid)
|
|
717
|
-
await sock.newsletterChangeOwner(jid, novoDonoJid)
|
|
718
|
-
await sock.newsletterDemote(jid, usuarioJid)
|
|
719
|
-
await sock.newsletterDelete(jid)
|
|
571
|
+
## 17. Fixar / Desfixar mensagens
|
|
720
572
|
|
|
721
|
-
|
|
722
|
-
|
|
573
|
+
```js
|
|
574
|
+
await sock.sendMessage(jid, { pin: quotedMsg.key, type: 1 }) // PIN_FOR_ALL
|
|
575
|
+
await sock.sendMessage(jid, { pin: quotedMsg.key, type: 2 }) // UNPIN_FOR_ALL
|
|
723
576
|
```
|
|
724
577
|
|
|
725
578
|
---
|
|
726
579
|
|
|
727
|
-
##
|
|
728
|
-
|
|
729
|
-
### Criar enquete
|
|
580
|
+
## 18. Resolução de nomes (getName)
|
|
730
581
|
|
|
731
582
|
```js
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
values: ['A', 'B', 'C'],
|
|
736
|
-
selectableCount: 1 // 0 = múltipla escolha
|
|
737
|
-
}
|
|
738
|
-
})
|
|
583
|
+
const { getName } = require('@systemzero/baileys')
|
|
584
|
+
const nome = getName(msg, contactStore)
|
|
585
|
+
// Prioridade: contato salvo → verifiedName → pushName → @lid → telefone → "Usuário desconhecido"
|
|
739
586
|
```
|
|
740
587
|
|
|
741
|
-
|
|
588
|
+
---
|
|
742
589
|
|
|
743
|
-
|
|
590
|
+
## 19. PTT real com qualquer formato
|
|
744
591
|
|
|
745
592
|
```js
|
|
746
|
-
|
|
593
|
+
// Qualquer formato de entrada — a lib converte via ffmpeg automaticamente
|
|
594
|
+
await sock.sendMessage(jid, { audio: { url: 'https://musica.mp3' }, ptt: true })
|
|
595
|
+
```
|
|
747
596
|
|
|
748
|
-
|
|
749
|
-
for (const { key, update } of updates) {
|
|
750
|
-
if (!update.pollUpdates) continue
|
|
597
|
+
A lib detecta a extensão real da fonte (não o `mimetype` declarado) e converte pra mono/16kHz opus quando necessário. Requer `ffmpeg` com `libopus`.
|
|
751
598
|
|
|
752
|
-
|
|
753
|
-
if (!pollMsg?.message) continue
|
|
599
|
+
---
|
|
754
600
|
|
|
755
|
-
|
|
756
|
-
message: pollMsg.message,
|
|
757
|
-
pollUpdates: update.pollUpdates,
|
|
758
|
-
})
|
|
601
|
+
## 20. Guard de pagamento stealth (anti-fraude)
|
|
759
602
|
|
|
760
|
-
|
|
761
|
-
|
|
603
|
+
```js
|
|
604
|
+
const { bindPaymentGuard } = require('@systemzero/baileys')
|
|
762
605
|
|
|
763
|
-
|
|
764
|
-
|
|
606
|
+
bindPaymentGuard(sock, {
|
|
607
|
+
isPaymentMessage: (webMessage) => { /* sua lógica */ },
|
|
608
|
+
recordEnvelope: (webMessage, isPayment) => { /* seu registro */ },
|
|
609
|
+
treatDecryptFailureAsSuspicious: true,
|
|
610
|
+
onDetect: (detection) => {
|
|
611
|
+
// detection.type: 'direct' | 'edited' | 'undecryptable'
|
|
765
612
|
}
|
|
766
613
|
})
|
|
767
614
|
```
|
|
768
615
|
|
|
769
|
-
|
|
616
|
+
| Caminho | Evento | Garantia |
|
|
617
|
+
|---|---|---|
|
|
618
|
+
| Mensagem direta | `messages.upsert` | Roda detector no conteúdo |
|
|
619
|
+
| Mensagem editada | `messages.update` | Extrai `editedMessage` e roda detector |
|
|
620
|
+
| Falha de decrypt | `messages.decrypt-failed` | Nunca ignora silenciosamente |
|
|
770
621
|
|
|
771
622
|
---
|
|
772
623
|
|
|
773
|
-
##
|
|
774
|
-
|
|
775
|
-
Mensagens com formatação avançada: markdown, código, tabelas, hyperlinks clicáveis no texto.
|
|
776
|
-
|
|
777
|
-
### Direto pelo socket
|
|
624
|
+
## 21. Bad MAC Handler — sessões Signal
|
|
778
625
|
|
|
779
626
|
```js
|
|
780
|
-
|
|
781
|
-
await sock.sendRich(jid, [
|
|
782
|
-
sock.makeText('Acesse [nosso site](https://systemzone.store).')
|
|
783
|
-
], quotedMsg)
|
|
784
|
-
|
|
785
|
-
// Código
|
|
786
|
-
await sock.sendRich(jid, [
|
|
787
|
-
sock.makeCode('bash', 'npm i @systemzero/baileys')
|
|
788
|
-
], null, ['RICH_RESPONSE_CODE'])
|
|
627
|
+
const { badMacHandler } = require('@systemzero/baileys')
|
|
789
628
|
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
['Botões', '✅'],
|
|
795
|
-
['Canais', '✅'],
|
|
796
|
-
])
|
|
797
|
-
], null, ['RICH_RESPONSE_TABLE'])
|
|
798
|
-
|
|
799
|
-
// Lista
|
|
800
|
-
await sock.sendRich(jid, [
|
|
801
|
-
sock.makeList(['Item 1', 'Item 2', 'Item 3'])
|
|
802
|
-
])
|
|
803
|
-
|
|
804
|
-
// Tudo junto
|
|
805
|
-
await sock.sendRich(jid, [
|
|
806
|
-
sock.makeText('# Título\nConteúdo com [link](https://systemzone.store)'),
|
|
807
|
-
sock.makeCode('javascript', 'const x = require("@systemzero/baileys")'),
|
|
808
|
-
sock.makeTable([['Col A', 'Col B'], ['val1', 'val2']]),
|
|
809
|
-
], quotedMsg, ['RICH_RESPONSE_CODE', 'RICH_RESPONSE_TABLE'])
|
|
629
|
+
if (badMacHandler.isBadMacError(error)) {
|
|
630
|
+
badMacHandler.handleError(error, 'contexto')
|
|
631
|
+
}
|
|
632
|
+
badMacHandler.clearProblematicSessionFiles() // preserva creds.json
|
|
810
633
|
```
|
|
811
634
|
|
|
812
|
-
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
## 22. Resolução LID → telefone via grupo
|
|
813
638
|
|
|
814
639
|
```js
|
|
815
|
-
|
|
816
|
-
await sock
|
|
817
|
-
await sock.sendRichList(jid, 'Lista', ['A', 'B', 'C'], quotedMsg)
|
|
640
|
+
const { resolveLidPhoneFromGroup } = require('@systemzero/baileys')
|
|
641
|
+
const telefone = await resolveLidPhoneFromGroup(sock, groupJid, lid)
|
|
818
642
|
```
|
|
819
643
|
|
|
820
|
-
|
|
644
|
+
Força resolução de `@lid` → telefone via `groupMetadata` — útil quando o cache ainda não tem aquele par.
|
|
821
645
|
|
|
822
|
-
|
|
823
|
-
const { AIRich } = require('@systemzero/baileys/lib/MB.cjs')
|
|
646
|
+
---
|
|
824
647
|
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
648
|
+
## 23. Versão do WhatsApp sempre atualizada
|
|
649
|
+
|
|
650
|
+
```js
|
|
651
|
+
const { getBestWaVersion } = require('@systemzero/baileys')
|
|
652
|
+
const { version, isLatest, source } = await getBestWaVersion()
|
|
653
|
+
// tenta web.whatsapp.com → GitHub → fallback fixo (avisando explicitamente)
|
|
830
654
|
```
|
|
831
655
|
|
|
832
656
|
---
|
|
833
657
|
|
|
834
|
-
##
|
|
658
|
+
## 24. WhatsApp Flows — Formulários interativos
|
|
659
|
+
|
|
660
|
+
> Requer `flow_id` aprovado no Meta Business Manager.
|
|
835
661
|
|
|
836
662
|
```js
|
|
837
|
-
|
|
838
|
-
const grupo = await sock.groupCreate('Nome', ['5511...@s.whatsapp.net'])
|
|
663
|
+
const { generateWAMessageFromContent } = require('@systemzero/baileys')
|
|
839
664
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
665
|
+
const formMsg = generateWAMessageFromContent(jid, {
|
|
666
|
+
viewOnceMessage: {
|
|
667
|
+
message: {
|
|
668
|
+
messageContextInfo: { deviceListMetadata: {}, deviceListMetadataVersion: 2 },
|
|
669
|
+
interactiveMessage: {
|
|
670
|
+
body: { text: 'Preencha seus dados.' },
|
|
671
|
+
nativeFlowMessage: {
|
|
672
|
+
buttons: [{
|
|
673
|
+
name: 'galaxy_message',
|
|
674
|
+
buttonParamsJson: JSON.stringify({
|
|
675
|
+
flow_message_version: '4',
|
|
676
|
+
flow_id: 'SEU_FLOW_ID',
|
|
677
|
+
flow_action_payload: {
|
|
678
|
+
screen: 'contact_details',
|
|
679
|
+
data: { full_name_visible: true, email_visible: true }
|
|
680
|
+
},
|
|
681
|
+
flow_cta: '__localize:FLOWS_SIGN_UP_BUTTON_TITLE',
|
|
682
|
+
flow_action: 'navigate',
|
|
683
|
+
flow_token: 'T0ZGRVJfU0lHTlVQ'
|
|
684
|
+
})
|
|
685
|
+
}],
|
|
686
|
+
messageParamsJson: '{}'
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}, { userJid: sock.user.id })
|
|
845
692
|
|
|
846
|
-
|
|
847
|
-
|
|
693
|
+
await sock.relayMessage(jid, formMsg.message, { messageId: formMsg.key.id })
|
|
694
|
+
```
|
|
848
695
|
|
|
849
|
-
|
|
850
|
-
await sock.groupUpdateSubject(jid, 'Novo Nome')
|
|
851
|
-
await sock.groupUpdateDescription(jid, 'Nova descrição')
|
|
696
|
+
### Recebendo a resposta
|
|
852
697
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
698
|
+
```js
|
|
699
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
700
|
+
const m = messages[0]
|
|
701
|
+
const nfr = m.message?.interactiveResponseMessage?.nativeFlowResponseMessage
|
|
702
|
+
if (nfr?.name !== 'galaxy_message' || !nfr?.paramsJson) return
|
|
857
703
|
|
|
858
|
-
|
|
859
|
-
|
|
704
|
+
const parsed = JSON.parse(nfr.paramsJson)
|
|
705
|
+
if (!parsed.wa_flow_response_params) return
|
|
860
706
|
|
|
861
|
-
|
|
862
|
-
const
|
|
863
|
-
|
|
707
|
+
const flowId = parsed.wa_flow_response_params.flow_id
|
|
708
|
+
const screens = JSON.parse(parsed.wa_flow_response_params.response_message).screens || []
|
|
709
|
+
|
|
710
|
+
const campos = {}
|
|
711
|
+
for (const screen of screens) {
|
|
712
|
+
for (const comp of (screen.components || [])) {
|
|
713
|
+
if (comp.name && comp.value !== undefined && comp.value !== '')
|
|
714
|
+
campos[comp.name] = comp.value
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
if (flowId === 'SEU_FLOW_ID') {
|
|
719
|
+
let resposta = 'Formulário recebido!\n\n'
|
|
720
|
+
if (campos.full_name) resposta += `Nome: ${campos.full_name}\n`
|
|
721
|
+
if (campos.email) resposta += `Email: ${campos.email}\n`
|
|
722
|
+
await sock.sendMessage(m.key.remoteJid, { text: resposta }, { quoted: m })
|
|
723
|
+
}
|
|
724
|
+
})
|
|
864
725
|
```
|
|
865
726
|
|
|
866
727
|
---
|
|
867
728
|
|
|
868
|
-
##
|
|
729
|
+
## 25. Mensagens agendadas
|
|
730
|
+
|
|
731
|
+
Sistema de agendamento em memória. Auto-inicia o timer quando há mensagens na fila, auto-para quando a fila esvazia.
|
|
869
732
|
|
|
870
733
|
```js
|
|
871
|
-
|
|
872
|
-
const url = await sock.profilePictureUrl(jid, 'image')
|
|
873
|
-
await sock.updateProfilePicture(jid, buffer)
|
|
734
|
+
const { createMessageScheduler } = require('@systemzero/baileys')
|
|
874
735
|
|
|
875
|
-
|
|
876
|
-
|
|
736
|
+
const scheduler = createMessageScheduler(
|
|
737
|
+
(jid, content) => sock.sendMessage(jid, content),
|
|
738
|
+
{
|
|
739
|
+
onSent: (s, msg) => console.log(`Enviado pra ${s.jid} — ID: ${s.id}`),
|
|
740
|
+
onFailed: (s, err) => console.error(`Falhou: ${err.message}`)
|
|
741
|
+
}
|
|
742
|
+
)
|
|
877
743
|
|
|
878
|
-
//
|
|
879
|
-
const
|
|
880
|
-
|
|
744
|
+
// Agendar para data/hora específica
|
|
745
|
+
const entry = scheduler.schedule(
|
|
746
|
+
'5511999999999@s.whatsapp.net',
|
|
747
|
+
{ text: 'Feliz Aniversário! 🎂' },
|
|
748
|
+
new Date('2026-12-25T09:00:00')
|
|
749
|
+
)
|
|
750
|
+
console.log('Agendado com ID:', entry.id)
|
|
881
751
|
|
|
882
|
-
//
|
|
883
|
-
|
|
884
|
-
await sock.updateBlockStatus(jid, 'unblock')
|
|
752
|
+
// Agendar com delay (30 minutos)
|
|
753
|
+
scheduler.scheduleDelay(jid, { text: 'Lembrete!' }, 30 * 60 * 1000)
|
|
885
754
|
|
|
886
|
-
//
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
await sock.presenceSubscribe(jid) // receber presence de contato
|
|
755
|
+
// Agendar qualquer tipo de mensagem
|
|
756
|
+
scheduler.schedule(groupJid, {
|
|
757
|
+
image: { url: './promo.jpg' },
|
|
758
|
+
caption: 'Promoção de fim de semana!'
|
|
759
|
+
}, new Date('2026-12-20T08:00:00'))
|
|
892
760
|
|
|
893
|
-
//
|
|
894
|
-
|
|
761
|
+
// Cancelar um agendamento
|
|
762
|
+
scheduler.cancel(entry.id)
|
|
895
763
|
|
|
896
|
-
//
|
|
897
|
-
|
|
764
|
+
// Cancelar todos de um JID
|
|
765
|
+
scheduler.cancelForJid(jid)
|
|
898
766
|
|
|
899
|
-
//
|
|
900
|
-
|
|
901
|
-
await sock.chatModify({ pin: true }, jid)
|
|
902
|
-
await sock.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid)
|
|
903
|
-
await sock.chatModify({ star: { messages: [{ id, fromMe }], star: true } }, jid)
|
|
904
|
-
await sock.chatModify({ clear: { messages: [{ id, fromMe, timestamp }] } }, jid)
|
|
767
|
+
// Ver pendentes
|
|
768
|
+
const pendentes = scheduler.getPending()
|
|
905
769
|
|
|
906
|
-
//
|
|
907
|
-
|
|
770
|
+
// Parar/retomar
|
|
771
|
+
scheduler.stop()
|
|
772
|
+
scheduler.start()
|
|
773
|
+
|
|
774
|
+
// Limpar tudo
|
|
775
|
+
scheduler.clearAll()
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
**Objeto retornado:**
|
|
779
|
+
```js
|
|
780
|
+
{
|
|
781
|
+
id: 'sched_1782000000000_a3f2b1',
|
|
782
|
+
jid: '5511...@s.whatsapp.net',
|
|
783
|
+
content: { text: '...' },
|
|
784
|
+
scheduledTime: Date,
|
|
785
|
+
createdAt: Date,
|
|
786
|
+
status: 'pending' | 'sent' | 'failed' | 'cancelled',
|
|
787
|
+
messageId: '...', // preenchido após envio
|
|
788
|
+
error: '...' // preenchido em caso de falha
|
|
789
|
+
}
|
|
908
790
|
```
|
|
909
791
|
|
|
910
792
|
---
|
|
911
793
|
|
|
912
|
-
##
|
|
794
|
+
## 26. Status em grupo (GroupStatusMessageV2)
|
|
795
|
+
|
|
796
|
+
Posta conteúdo como status dentro de um grupo — texto, imagem, vídeo ou áudio. Suporta modo **Close Friends** (apenas amigos próximos), usando o mesmo mecanismo do status nativo do WhatsApp.
|
|
913
797
|
|
|
914
798
|
```js
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
sock.ev.on('messages.delete', (item) => {})
|
|
918
|
-
sock.ev.on('messages.reaction', (reactions) => {})
|
|
919
|
-
sock.ev.on('presence.update', ({ id, presences }) => {})
|
|
920
|
-
sock.ev.on('groups.update', (updates) => {})
|
|
921
|
-
sock.ev.on('group-participants.update', ({ id, participants, action }) => {})
|
|
922
|
-
sock.ev.on('contacts.update', (contacts) => {})
|
|
923
|
-
sock.ev.on('chats.update', (chats) => {})
|
|
924
|
-
sock.ev.on('connection.update', ({ connection, lastDisconnect, qr }) => {})
|
|
925
|
-
sock.ev.on('creds.update', saveCreds)
|
|
799
|
+
const { generateWAMessageFromContent, prepareWAMessageMedia, downloadMediaMessage } = require('@systemzero/baileys')
|
|
800
|
+
const crypto = require('crypto')
|
|
926
801
|
|
|
927
|
-
//
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
802
|
+
// ── Texto para todos do grupo ────────────────────────────────────────────────
|
|
803
|
+
const messageSecret = crypto.randomBytes(32)
|
|
804
|
+
|
|
805
|
+
const msg = generateWAMessageFromContent(jid, {
|
|
806
|
+
messageContextInfo: { messageSecret },
|
|
807
|
+
groupStatusMessageV2: {
|
|
808
|
+
message: {
|
|
809
|
+
extendedTextMessage: {
|
|
810
|
+
text: 'Olá, grupo! 👋',
|
|
811
|
+
contextInfo: { isGroupStatus: true }
|
|
812
|
+
},
|
|
813
|
+
messageContextInfo: { messageSecret }
|
|
932
814
|
}
|
|
933
815
|
}
|
|
934
|
-
})
|
|
816
|
+
}, {})
|
|
817
|
+
|
|
818
|
+
await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
|
|
935
819
|
```
|
|
936
820
|
|
|
937
|
-
|
|
821
|
+
```js
|
|
822
|
+
// ── Texto apenas para Amigos Próximos (Close Friends) ────────────────────────
|
|
823
|
+
const messageSecret = crypto.randomBytes(32)
|
|
938
824
|
|
|
939
|
-
|
|
825
|
+
const msg = generateWAMessageFromContent(jid, {
|
|
826
|
+
messageContextInfo: { messageSecret },
|
|
827
|
+
groupStatusMessageV2: {
|
|
828
|
+
message: {
|
|
829
|
+
extendedTextMessage: {
|
|
830
|
+
text: 'Só pra você que é chegado 🤫',
|
|
831
|
+
contextInfo: {
|
|
832
|
+
isGroupStatus: true,
|
|
833
|
+
statusAudienceMetadata: { audienceType: 1 } // 1 = Close Friends
|
|
834
|
+
}
|
|
835
|
+
},
|
|
836
|
+
messageContextInfo: { messageSecret }
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}, {})
|
|
940
840
|
|
|
941
|
-
|
|
841
|
+
await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
|
|
842
|
+
```
|
|
942
843
|
|
|
943
844
|
```js
|
|
944
|
-
|
|
845
|
+
// ── Imagem para todos do grupo ───────────────────────────────────────────────
|
|
846
|
+
const messageSecret = crypto.randomBytes(32)
|
|
945
847
|
|
|
946
|
-
const
|
|
947
|
-
|
|
948
|
-
|
|
848
|
+
const prep = await prepareWAMessageMedia(
|
|
849
|
+
{ image: buffer },
|
|
850
|
+
{ upload: sock.waUploadToServer }
|
|
851
|
+
)
|
|
949
852
|
|
|
950
|
-
|
|
853
|
+
const msg = generateWAMessageFromContent(jid, {
|
|
854
|
+
messageContextInfo: { messageSecret },
|
|
855
|
+
groupStatusMessageV2: {
|
|
856
|
+
message: {
|
|
857
|
+
imageMessage: {
|
|
858
|
+
...prep.imageMessage,
|
|
859
|
+
caption: 'Legenda da imagem',
|
|
860
|
+
contextInfo: { isGroupStatus: true }
|
|
861
|
+
},
|
|
862
|
+
messageContextInfo: { messageSecret }
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}, {})
|
|
866
|
+
|
|
867
|
+
await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
|
|
868
|
+
```
|
|
951
869
|
|
|
952
870
|
```js
|
|
953
|
-
|
|
871
|
+
// ── Imagem apenas para Amigos Próximos ───────────────────────────────────────
|
|
872
|
+
const messageSecret = crypto.randomBytes(32)
|
|
954
873
|
|
|
955
|
-
const
|
|
956
|
-
{
|
|
957
|
-
|
|
874
|
+
const prep = await prepareWAMessageMedia(
|
|
875
|
+
{ image: buffer },
|
|
876
|
+
{ upload: sock.waUploadToServer }
|
|
958
877
|
)
|
|
959
|
-
const chunks = []
|
|
960
|
-
for await (const chunk of stream) chunks.push(chunk)
|
|
961
|
-
const buffer = Buffer.concat(chunks)
|
|
962
|
-
```
|
|
963
878
|
|
|
964
|
-
|
|
879
|
+
const msg = generateWAMessageFromContent(jid, {
|
|
880
|
+
messageContextInfo: { messageSecret },
|
|
881
|
+
groupStatusMessageV2: {
|
|
882
|
+
message: {
|
|
883
|
+
imageMessage: {
|
|
884
|
+
...prep.imageMessage,
|
|
885
|
+
caption: 'Só pra chegados 🤫',
|
|
886
|
+
contextInfo: {
|
|
887
|
+
isGroupStatus: true,
|
|
888
|
+
statusAudienceMetadata: { audienceType: 1 }
|
|
889
|
+
}
|
|
890
|
+
},
|
|
891
|
+
messageContextInfo: { messageSecret }
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}, {})
|
|
895
|
+
|
|
896
|
+
await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
|
|
897
|
+
```
|
|
965
898
|
|
|
966
899
|
```js
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
generateWAMessageFromContent,
|
|
970
|
-
generateMessageIDV2,
|
|
971
|
-
generateForwardMessageContent
|
|
972
|
-
} = require('@systemzero/baileys')
|
|
900
|
+
// ── Vídeo ─────────────────────────────────────────────────────────────────────
|
|
901
|
+
const messageSecret = crypto.randomBytes(32)
|
|
973
902
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
upload:
|
|
977
|
-
|
|
978
|
-
messageId: generateMessageIDV2(sock.user.id),
|
|
979
|
-
})
|
|
903
|
+
const prep = await prepareWAMessageMedia(
|
|
904
|
+
{ video: buffer },
|
|
905
|
+
{ upload: sock.waUploadToServer }
|
|
906
|
+
)
|
|
980
907
|
|
|
981
|
-
|
|
982
|
-
|
|
908
|
+
const msg = generateWAMessageFromContent(jid, {
|
|
909
|
+
messageContextInfo: { messageSecret },
|
|
910
|
+
groupStatusMessageV2: {
|
|
911
|
+
message: {
|
|
912
|
+
videoMessage: {
|
|
913
|
+
...prep.videoMessage,
|
|
914
|
+
caption: 'Legenda do vídeo',
|
|
915
|
+
contextInfo: { isGroupStatus: true }
|
|
916
|
+
},
|
|
917
|
+
messageContextInfo: { messageSecret }
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
}, {})
|
|
983
921
|
|
|
984
|
-
// Enviar o proto
|
|
985
922
|
await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
|
|
986
923
|
```
|
|
987
924
|
|
|
988
|
-
### Detectar dispositivo
|
|
989
|
-
|
|
990
925
|
```js
|
|
991
|
-
|
|
992
|
-
const
|
|
993
|
-
// 'android' | 'ios' | 'web' | 'unknown'
|
|
994
|
-
```
|
|
926
|
+
// ── Áudio ─────────────────────────────────────────────────────────────────────
|
|
927
|
+
const messageSecret = crypto.randomBytes(32)
|
|
995
928
|
|
|
996
|
-
|
|
929
|
+
const prep = await prepareWAMessageMedia(
|
|
930
|
+
{ audio: buffer, mimetype: 'audio/mp4' },
|
|
931
|
+
{ upload: sock.waUploadToServer }
|
|
932
|
+
)
|
|
997
933
|
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
}
|
|
934
|
+
const msg = generateWAMessageFromContent(jid, {
|
|
935
|
+
messageContextInfo: { messageSecret },
|
|
936
|
+
groupStatusMessageV2: {
|
|
937
|
+
message: {
|
|
938
|
+
audioMessage: {
|
|
939
|
+
...prep.audioMessage,
|
|
940
|
+
contextInfo: { isGroupStatus: true }
|
|
941
|
+
},
|
|
942
|
+
messageContextInfo: { messageSecret }
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}, {})
|
|
1006
946
|
|
|
1007
|
-
|
|
1008
|
-
isJidGroup('120363...@g.us') // true
|
|
1009
|
-
isJidNewsletter('120363...@newsletter') // true
|
|
947
|
+
await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
|
|
1010
948
|
```
|
|
1011
949
|
|
|
950
|
+
**Pontos importantes:**
|
|
951
|
+
- `messageSecret` deve ser um `Buffer` de 32 bytes gerado com `crypto.randomBytes(32)` — cada postagem precisa de um novo secret
|
|
952
|
+
- `audienceType: 1` ativa o modo Close Friends; omitir `statusAudienceMetadata` posta para todos do grupo
|
|
953
|
+
- Para repostar uma mensagem citada (quoted), baixe a mídia com `downloadMediaMessage` antes de fazer o `prepareWAMessageMedia`
|
|
954
|
+
- O `groupStatus: true` no `sendMessage` simples (seção 3) existe como atalho, mas para controle de Close Friends e repost de mídias, use o `groupStatusMessageV2` direto como mostrado acima
|
|
955
|
+
|
|
956
|
+
---
|
|
957
|
+
|
|
958
|
+
## Changelog
|
|
959
|
+
|
|
960
|
+
### v1.0.7
|
|
961
|
+
- **Fix PTT real** — `ptt: true` converte via `ffmpeg` antes do upload; corrigido bug `Cannot use 'in' operator to search for 'stream'` (caminho do arquivo transcrito era passado como string crua em vez de `{ url }`)
|
|
962
|
+
- **Fix 403 / conexão** — `lidDbMigrated` no login agora reflete o estado real das credenciais; companion version usa a versão real do WA; `"forbidden"` mapeado corretamente pra `DisconnectReason.forbidden`
|
|
963
|
+
- **Mensagens agendadas** — `MessageScheduler` / `createMessageScheduler` portado de innovatorssoft/baileys
|
|
964
|
+
- **PreKey recovery melhorado** — upload de 30 chaves (era 5), delay de 2500ms (era 1000ms), parâmetro `force` pra ignorar `MIN_UPLOAD_INTERVAL` em recuperação de erro
|
|
965
|
+
- **Fix groupMetadata → sharedLidPhoneCache** — pares LID↔telefone agora registrados automaticamente ao buscar metadata de grupo
|
|
966
|
+
- Guard de pagamento stealth, Bad MAC Handler, getName, getBestWaVersion, resolveLidPhoneFromGroup, WhatsApp Flows
|
|
967
|
+
|
|
968
|
+
### v1.0.6
|
|
969
|
+
- Sistema LID/JID avançado com cache bidirecional (`sharedLidPhoneCache`)
|
|
970
|
+
- `lidToJid`, `resolveJid`, `resolveAll`, `normalizeJid`, `validateJid`, `getSenderInfo`
|
|
971
|
+
- Suporte a `@username` — `isUsername`, `resolveUsername`
|
|
972
|
+
- Botões estendidos (20+ tipos via `nativeFlow`)
|
|
973
|
+
- Fix canal newsletter, fix groupStatus audio, `isSystemNotification`
|
|
974
|
+
|
|
975
|
+
### v1.0.5
|
|
976
|
+
- Sticker Pack nativo com animadas e PNG
|
|
977
|
+
- Album, Spoiler, ViewOnce V2, Ephemeral, Lottie, Evento
|
|
978
|
+
- Native Flow, Carousel, Template Buttons
|
|
979
|
+
- AI Rich (makeText, makeCode, makeTable, makeList, sendRich)
|
|
980
|
+
- Poll decrypt com `getAggregateVotesInPollMessage`
|
|
981
|
+
- MessageBuilder (`Button`, `ButtonV2`, `Carousel`, `AIRich`)
|
|
982
|
+
|
|
1012
983
|
---
|
|
1013
984
|
|
|
1014
985
|
<div align="center">
|
|
1015
986
|
|
|
1016
|
-
**@systemzero/baileys v1.0.
|
|
987
|
+
**@systemzero/baileys v1.0.7**
|
|
1017
988
|
|
|
1018
989
|
Desenvolvido por [Josué </>](https://t.me/blackhzx) · [Canal WhatsApp](https://whatsapp.com/channel/0029VaqUb9aGk1FxqeKKOd2i) · [systemzone.store](https://systemzone.store)
|
|
1019
990
|
|