@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.
Files changed (206) hide show
  1. package/README.md +629 -658
  2. package/lib/Defaults/index.js +2 -2
  3. package/lib/Socket/chats.js +12 -1
  4. package/lib/Socket/groups.js +13 -4
  5. package/lib/Socket/messages-recv.js +45 -6
  6. package/lib/Socket/messages-recv.js.bak +1273 -0
  7. package/lib/Socket/messages-send.js +1 -0
  8. package/lib/Socket/socket.js +4 -4
  9. package/lib/Utils/bad-mac-handler.js +158 -0
  10. package/lib/Utils/generics.js +2 -1
  11. package/lib/Utils/get-best-version.js +41 -0
  12. package/lib/Utils/get-name.d.ts +1 -0
  13. package/lib/Utils/get-name.js +54 -0
  14. package/lib/Utils/group-status-detection.js +113 -0
  15. package/lib/Utils/index.js +8 -0
  16. package/lib/Utils/logger.js +4 -1
  17. package/lib/Utils/messages-media.js +38 -0
  18. package/lib/Utils/messages.js +113 -7
  19. package/lib/Utils/payment-detection.js +212 -0
  20. package/lib/Utils/payment-guard.d.ts +15 -0
  21. package/lib/Utils/payment-guard.js +142 -0
  22. package/lib/Utils/resolve-lid-phone.js +30 -0
  23. package/lib/Utils/scheduling.js +138 -0
  24. package/lib/Utils/validate-connection.js +11 -5
  25. package/lib/WABinary/jid-utils.js +245 -1
  26. package/package.json +1 -1
  27. package/lib/Defaults/index.d.ts.map +0 -1
  28. package/lib/Defaults/index.js.map +0 -1
  29. package/lib/Signal/Group/ciphertext-message.d.ts.map +0 -1
  30. package/lib/Signal/Group/ciphertext-message.js.map +0 -1
  31. package/lib/Signal/Group/group-session-builder.d.ts.map +0 -1
  32. package/lib/Signal/Group/group-session-builder.js.map +0 -1
  33. package/lib/Signal/Group/group_cipher.d.ts.map +0 -1
  34. package/lib/Signal/Group/group_cipher.js.map +0 -1
  35. package/lib/Signal/Group/index.d.ts.map +0 -1
  36. package/lib/Signal/Group/index.js.map +0 -1
  37. package/lib/Signal/Group/keyhelper.d.ts.map +0 -1
  38. package/lib/Signal/Group/keyhelper.js.map +0 -1
  39. package/lib/Signal/Group/sender-chain-key.d.ts.map +0 -1
  40. package/lib/Signal/Group/sender-chain-key.js.map +0 -1
  41. package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +0 -1
  42. package/lib/Signal/Group/sender-key-distribution-message.js.map +0 -1
  43. package/lib/Signal/Group/sender-key-message.d.ts.map +0 -1
  44. package/lib/Signal/Group/sender-key-message.js.map +0 -1
  45. package/lib/Signal/Group/sender-key-name.d.ts.map +0 -1
  46. package/lib/Signal/Group/sender-key-name.js.map +0 -1
  47. package/lib/Signal/Group/sender-key-record.d.ts.map +0 -1
  48. package/lib/Signal/Group/sender-key-record.js.map +0 -1
  49. package/lib/Signal/Group/sender-key-state.d.ts.map +0 -1
  50. package/lib/Signal/Group/sender-key-state.js.map +0 -1
  51. package/lib/Signal/Group/sender-message-key.d.ts.map +0 -1
  52. package/lib/Signal/Group/sender-message-key.js.map +0 -1
  53. package/lib/Signal/libsignal.d.ts.map +0 -1
  54. package/lib/Signal/libsignal.js.map +0 -1
  55. package/lib/Signal/lid-mapping.d.ts.map +0 -1
  56. package/lib/Signal/lid-mapping.js.map +0 -1
  57. package/lib/Socket/Client/index.d.ts.map +0 -1
  58. package/lib/Socket/Client/index.js.map +0 -1
  59. package/lib/Socket/Client/types.d.ts.map +0 -1
  60. package/lib/Socket/Client/types.js.map +0 -1
  61. package/lib/Socket/Client/websocket.d.ts.map +0 -1
  62. package/lib/Socket/Client/websocket.js.map +0 -1
  63. package/lib/Socket/business.d.ts.map +0 -1
  64. package/lib/Socket/business.js.map +0 -1
  65. package/lib/Socket/chats.d.ts.map +0 -1
  66. package/lib/Socket/chats.js.map +0 -1
  67. package/lib/Socket/communities.d.ts.map +0 -1
  68. package/lib/Socket/communities.js.map +0 -1
  69. package/lib/Socket/groups.d.ts.map +0 -1
  70. package/lib/Socket/groups.js.map +0 -1
  71. package/lib/Socket/index.d.ts.map +0 -1
  72. package/lib/Socket/index.js.map +0 -1
  73. package/lib/Socket/messages-recv.d.ts.map +0 -1
  74. package/lib/Socket/messages-recv.js.map +0 -1
  75. package/lib/Socket/messages-send.d.ts.map +0 -1
  76. package/lib/Socket/messages-send.js.map +0 -1
  77. package/lib/Socket/mex.d.ts.map +0 -1
  78. package/lib/Socket/mex.js.map +0 -1
  79. package/lib/Socket/newsletter.d.ts.map +0 -1
  80. package/lib/Socket/newsletter.js.map +0 -1
  81. package/lib/Socket/socket.d.ts.map +0 -1
  82. package/lib/Socket/socket.js.map +0 -1
  83. package/lib/Types/Auth.d.ts.map +0 -1
  84. package/lib/Types/Auth.js.map +0 -1
  85. package/lib/Types/Bussines.d.ts.map +0 -1
  86. package/lib/Types/Bussines.js.map +0 -1
  87. package/lib/Types/Call.d.ts.map +0 -1
  88. package/lib/Types/Call.js.map +0 -1
  89. package/lib/Types/Chat.d.ts.map +0 -1
  90. package/lib/Types/Chat.js.map +0 -1
  91. package/lib/Types/Contact.d.ts.map +0 -1
  92. package/lib/Types/Contact.js.map +0 -1
  93. package/lib/Types/Events.d.ts.map +0 -1
  94. package/lib/Types/Events.js.map +0 -1
  95. package/lib/Types/GroupMetadata.d.ts.map +0 -1
  96. package/lib/Types/GroupMetadata.js.map +0 -1
  97. package/lib/Types/Label.d.ts.map +0 -1
  98. package/lib/Types/Label.js.map +0 -1
  99. package/lib/Types/LabelAssociation.d.ts.map +0 -1
  100. package/lib/Types/LabelAssociation.js.map +0 -1
  101. package/lib/Types/Message.d.ts.map +0 -1
  102. package/lib/Types/Message.js.map +0 -1
  103. package/lib/Types/Newsletter.d.ts.map +0 -1
  104. package/lib/Types/Newsletter.js.map +0 -1
  105. package/lib/Types/Product.d.ts.map +0 -1
  106. package/lib/Types/Product.js.map +0 -1
  107. package/lib/Types/Signal.d.ts.map +0 -1
  108. package/lib/Types/Signal.js.map +0 -1
  109. package/lib/Types/Socket.d.ts.map +0 -1
  110. package/lib/Types/Socket.js.map +0 -1
  111. package/lib/Types/State.d.ts.map +0 -1
  112. package/lib/Types/State.js.map +0 -1
  113. package/lib/Types/USync.d.ts.map +0 -1
  114. package/lib/Types/USync.js.map +0 -1
  115. package/lib/Types/index.d.ts.map +0 -1
  116. package/lib/Types/index.js.map +0 -1
  117. package/lib/Utils/auth-utils.d.ts.map +0 -1
  118. package/lib/Utils/auth-utils.js.map +0 -1
  119. package/lib/Utils/browser-utils.d.ts.map +0 -1
  120. package/lib/Utils/browser-utils.js.map +0 -1
  121. package/lib/Utils/business.d.ts.map +0 -1
  122. package/lib/Utils/business.js.map +0 -1
  123. package/lib/Utils/chat-utils.d.ts.map +0 -1
  124. package/lib/Utils/chat-utils.js.map +0 -1
  125. package/lib/Utils/crypto.d.ts.map +0 -1
  126. package/lib/Utils/crypto.js.map +0 -1
  127. package/lib/Utils/decode-wa-message.d.ts.map +0 -1
  128. package/lib/Utils/decode-wa-message.js.map +0 -1
  129. package/lib/Utils/event-buffer.d.ts.map +0 -1
  130. package/lib/Utils/event-buffer.js.map +0 -1
  131. package/lib/Utils/generics.d.ts.map +0 -1
  132. package/lib/Utils/generics.js.map +0 -1
  133. package/lib/Utils/history.d.ts.map +0 -1
  134. package/lib/Utils/history.js.map +0 -1
  135. package/lib/Utils/index.d.ts.map +0 -1
  136. package/lib/Utils/index.js.map +0 -1
  137. package/lib/Utils/link-preview.d.ts.map +0 -1
  138. package/lib/Utils/link-preview.js.map +0 -1
  139. package/lib/Utils/logger.d.ts.map +0 -1
  140. package/lib/Utils/logger.js.map +0 -1
  141. package/lib/Utils/lt-hash.d.ts.map +0 -1
  142. package/lib/Utils/lt-hash.js.map +0 -1
  143. package/lib/Utils/make-mutex.d.ts.map +0 -1
  144. package/lib/Utils/make-mutex.js.map +0 -1
  145. package/lib/Utils/message-retry-manager.d.ts.map +0 -1
  146. package/lib/Utils/message-retry-manager.js.map +0 -1
  147. package/lib/Utils/messages-media.d.ts.map +0 -1
  148. package/lib/Utils/messages-media.js.map +0 -1
  149. package/lib/Utils/messages.d.ts.map +0 -1
  150. package/lib/Utils/messages.js.map +0 -1
  151. package/lib/Utils/noise-handler.d.ts.map +0 -1
  152. package/lib/Utils/noise-handler.js.map +0 -1
  153. package/lib/Utils/pre-key-manager.d.ts.map +0 -1
  154. package/lib/Utils/pre-key-manager.js.map +0 -1
  155. package/lib/Utils/process-message.d.ts.map +0 -1
  156. package/lib/Utils/process-message.js.map +0 -1
  157. package/lib/Utils/signal.d.ts.map +0 -1
  158. package/lib/Utils/signal.js.map +0 -1
  159. package/lib/Utils/use-multi-file-auth-state.d.ts.map +0 -1
  160. package/lib/Utils/use-multi-file-auth-state.js.map +0 -1
  161. package/lib/Utils/validate-connection.d.ts.map +0 -1
  162. package/lib/Utils/validate-connection.js.map +0 -1
  163. package/lib/WABinary/constants.d.ts.map +0 -1
  164. package/lib/WABinary/constants.js.map +0 -1
  165. package/lib/WABinary/decode.d.ts.map +0 -1
  166. package/lib/WABinary/decode.js.map +0 -1
  167. package/lib/WABinary/encode.d.ts.map +0 -1
  168. package/lib/WABinary/encode.js.map +0 -1
  169. package/lib/WABinary/generic-utils.d.ts.map +0 -1
  170. package/lib/WABinary/generic-utils.js.map +0 -1
  171. package/lib/WABinary/index.d.ts.map +0 -1
  172. package/lib/WABinary/index.js.map +0 -1
  173. package/lib/WABinary/jid-utils.d.ts.map +0 -1
  174. package/lib/WABinary/jid-utils.js.map +0 -1
  175. package/lib/WABinary/types.d.ts.map +0 -1
  176. package/lib/WABinary/types.js.map +0 -1
  177. package/lib/WAM/BinaryInfo.d.ts.map +0 -1
  178. package/lib/WAM/BinaryInfo.js.map +0 -1
  179. package/lib/WAM/constants.d.ts.map +0 -1
  180. package/lib/WAM/constants.js.map +0 -1
  181. package/lib/WAM/encode.d.ts.map +0 -1
  182. package/lib/WAM/encode.js.map +0 -1
  183. package/lib/WAM/index.d.ts.map +0 -1
  184. package/lib/WAM/index.js.map +0 -1
  185. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +0 -1
  186. package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +0 -1
  187. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +0 -1
  188. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +0 -1
  189. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +0 -1
  190. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +0 -1
  191. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +0 -1
  192. package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +0 -1
  193. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +0 -1
  194. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +0 -1
  195. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +0 -1
  196. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +0 -1
  197. package/lib/WAUSync/Protocols/index.d.ts.map +0 -1
  198. package/lib/WAUSync/Protocols/index.js.map +0 -1
  199. package/lib/WAUSync/USyncQuery.d.ts.map +0 -1
  200. package/lib/WAUSync/USyncQuery.js.map +0 -1
  201. package/lib/WAUSync/USyncUser.d.ts.map +0 -1
  202. package/lib/WAUSync/USyncUser.js.map +0 -1
  203. package/lib/WAUSync/index.d.ts.map +0 -1
  204. package/lib/WAUSync/index.js.map +0 -1
  205. package/lib/index.d.ts.map +0 -1
  206. 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.5** · Fork avançado do Baileys com suporte nativo a todos os tipos de mensagens do WhatsApp
7
+ **v1.0.7** · Fork avançado do Baileys com suporte nativo a todos os tipos de mensagens do WhatsApp
8
8
 
9
9
  [![NPM](https://img.shields.io/npm/v/@systemzero/baileys?color=7c3aed&style=flat-square&label=npm)](https://www.npmjs.com/package/@systemzero/baileys)
10
10
  [![License](https://img.shields.io/badge/license-MIT-6366f1?style=flat-square)](LICENSE)
11
11
  [![Author](https://img.shields.io/badge/by-Josué%20%3C%2F%3E-ec4899?style=flat-square)](https://t.me/blackhzx)
12
+ [![Node](https://img.shields.io/badge/node-%3E%3D18-7c3aed?style=flat-square)](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 para sticker pack e thumbnail:
24
+ Dependências opcionais:
24
25
  ```bash
25
- npm i sharp
26
- # ou
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. [Grupos](#9-grupos)
43
- 10. [Perfil e privacidade](#10-perfil-e-privacidade)
44
- 11. [Eventos do socket](#11-eventos-do-socket)
45
- 12. [Utilitários](#12-utilitários)
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
- fetchLatestWaWebVersion
73
+ getBestWaVersion
60
74
  } = require('@systemzero/baileys')
61
75
 
62
76
  const { state, saveCreds } = await useMultiFileAuthState('./session')
63
- const { version } = await fetchLatestWaWebVersion()
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 !== DisconnectReason.loggedOut) startBot()
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: ReadableStream }`.
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
- // Com menção
129
- await sock.sendMessage(jid, {
130
- text: '@55119...!',
131
- mentions: ['5511999999999@s.whatsapp.net']
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
- ### Editar mensagem
249
-
250
- ```js
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
- edit: message.key,
253
- text: 'Texto editado'
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
- pin: {
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 content = generateForwardMessageContent(message, false)
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
- ### View Once
198
+ ---
199
+
200
+ ## 4. Botões e interativos
280
201
 
281
202
  ```js
282
- await sock.sendMessage(jid, { image: buffer, viewOnce: true })
203
+ const { generateWAMessageFromContent, proto } = require('@systemzero/baileys')
283
204
 
284
- // V2
285
- await sock.sendMessage(jid, { image: buffer, viewOnceV2: true })
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
- // V2 Extension
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
- await sock.sendMessage(jid, {
295
- image: buffer,
296
- caption: 'Spoiler!',
297
- spoiler: true
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
- ### Status de grupo
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: buffer,
306
- caption: 'Status do grupo',
307
- groupStatus: true
240
+ image: { url: 'https://...' },
241
+ caption: 'Texto do card',
242
+ nativeFlow: [{ text: 'Botão', id: 'btn1' }]
308
243
  })
309
244
  ```
310
245
 
311
- ### Mensagem efêmera
246
+ ### Carousel
312
247
 
313
248
  ```js
314
249
  await sock.sendMessage(jid, {
315
- image: buffer,
316
- ephemeral: true
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
- ### Lottie (sticker animado especial)
258
+ ### Template Buttons / Sections
321
259
 
322
260
  ```js
323
261
  await sock.sendMessage(jid, {
324
- sticker: buffer,
325
- isLottie: true
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
- keep: message.key,
334
- type: 1 // 1 = salvar, 2 = remover
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
- ### Evento
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
- ### Enquete
278
+ ## 5. Sticker Pack nativo
354
279
 
355
280
  ```js
356
281
  await sock.sendMessage(jid, {
357
- poll: {
358
- name: 'Qual seu time?',
359
- values: ['Flamengo', 'Corinthians', 'Palmeiras'],
360
- selectableCount: 1 // 0 = múltipla escolha
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
- ### Invoice (nota fiscal)
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
- ```js
368
- await sock.sendMessage(jid, {
369
- image: buffer,
370
- invoiceNote: 'Pagamento pedido #1234'
371
- })
372
- ```
295
+ ---
373
296
 
374
- ### External Ad Reply
297
+ ## 6. Canais Newsletter
375
298
 
376
299
  ```js
377
- await sock.sendMessage(jid, {
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
- ```js
393
- await sock.sendMessage(jid, {
394
- text: '👋 @all',
395
- mentionAll: true
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
- ### Convite de pagamento
325
+ ---
326
+
327
+ ## 7. Enquetes com decrypt
400
328
 
401
329
  ```js
402
330
  await sock.sendMessage(jid, {
403
- paymentInviteServiceType: 3
331
+ poll: { name: 'Pergunta?', values: ['A', 'B', 'C'], selectableCount: 1 }
404
332
  })
405
- ```
406
333
 
407
- ### Resultado de enquete (snapshot)
408
-
409
- ```js
410
- await sock.sendMessage(jid, {
411
- pollResult: {
412
- name: 'Pergunta?',
413
- pollType: 0, // 0 = poll, 1 = quiz
414
- votes: [
415
- { name: 'Opção A', voteCount: 12 },
416
- { name: 'Opção B', voteCount: 7 },
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
- ## 4. Botões e interativos
425
-
426
- ### Estrutura base
350
+ ## 8. AI Rich
427
351
 
428
352
  ```js
429
- const { generateWAMessageFromContent, proto } = require('@systemzero/baileys')
430
-
431
- const msg = generateWAMessageFromContent(jid, {
432
- viewOnceMessage: {
433
- message: {
434
- interactiveMessage: proto.Message.InteractiveMessage.create({
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.relayMessage(jid, msg.message, { messageId: msg.key.id })
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
- ### Tipos de botão
365
+ ---
450
366
 
451
- ```js
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
- // Link externo
456
- { name: 'cta_url', buttonParamsJson: JSON.stringify({ display_text: 'Abrir', url: 'https://systemzone.store' }) }
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
- // Copiar texto
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
- // Ligar
462
- { name: 'cta_call', buttonParamsJson: JSON.stringify({ display_text: 'Ligar', phone_number: '5511999999999' }) }
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
- // Webview interno
465
- { name: 'cta_webview', buttonParamsJson: JSON.stringify({ title: 'Painel', url: 'https://systemzone.store' }) }
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
- // Lista dropdown com seções
468
- {
469
- name: 'single_select',
470
- buttonParamsJson: JSON.stringify({
471
- title: 'Escolher',
472
- sections: [{
473
- title: 'Categoria',
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
- ### Header com imagem
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
- Upload da imagem antes de usar no header:
399
+ ## 10. Username (@usuario)
486
400
 
487
401
  ```js
488
- const { generateWAMessage, generateMessageIDV2 } = require('@systemzero/baileys')
402
+ const { resolveUsername, isUsername } = require('@systemzero/baileys')
489
403
 
490
- const uploaded = await generateWAMessage(jid, { image: buffer }, {
491
- upload: sock.waUploadToServer,
492
- userJid: sock.user.id,
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
- ### Catálogo (product no header)
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
- ### Carousel
411
+ ## 11. MessageBuilder — Button, ButtonV2, Carousel, AIRich
539
412
 
540
413
  ```js
541
- await sock.sendMessage(jid, {
542
- cards: [
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
- ### Template Buttons
418
+ ### ButtonV2
563
419
 
564
420
  ```js
565
- await sock.sendMessage(jid, {
566
- text: 'Escolha:',
567
- templateButtons: [
568
- { text: 'Resposta', id: 'res1' },
569
- { text: 'Site', url: 'https://systemzone.store' },
570
- { text: 'Ligar', call: '5511999999999' },
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
- ### Sections (lista clássica)
430
+ ### Button (native flow)
576
431
 
577
432
  ```js
578
- await sock.sendMessage(jid, {
579
- text: 'Selecione',
580
- buttonText: 'Ver opções',
581
- sections: [{
582
- title: 'Categoria',
583
- rows: [
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
- ### Interactive como Template
441
+ ### Carousel
592
442
 
593
443
  ```js
594
- await sock.sendMessage(jid, {
595
- nativeFlow: [{ text: 'Clique', id: 'btn' }],
596
- text: 'Mensagem',
597
- interactiveAsTemplate: true
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
- ### Botões com imagem no corpo (não no header)
451
+ ### AIRich
602
452
 
603
453
  ```js
604
- await sock.sendMessage(jid, {
605
- image: buffer,
606
- caption: 'Escolha:',
607
- buttons: [
608
- { text: 'Opção 1', id: 'op1' },
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
- ### Áudio no rodapé de interativo
461
+ ---
615
462
 
616
- ```js
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
- ## 5. Sticker Pack nativo
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
- Envia um pack de figurinhas que aparece na aba de stickers do WhatsApp, igual a um pack real.
479
+ ### isSystemNotification
629
480
 
630
481
  ```js
631
- await sock.sendMessage(jid, {
632
- cover: { url: 'https://exemplo.com/capa.webp' },
633
- stickers: [
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
- ## 6. Canais Newsletter
653
-
654
- ### Enviar texto
490
+ ## 13. Grupos
655
491
 
656
492
  ```js
657
- await sock.sendMessage('120363...@newsletter', { text: 'Novidade!' })
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
- ### Enviar mídia
509
+ ---
661
510
 
662
- `sendMessage` não passa pelo `encodeNewsletterMessage` corretamente para mídia. Use sempre `generateWAMessage` + `relayMessage`:
511
+ ## 14. Perfil e privacidade
663
512
 
664
513
  ```js
665
- const { generateWAMessage, generateMessageIDV2 } = require('@systemzero/baileys')
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
- const canalJid = '120363...@newsletter'
530
+ ---
668
531
 
669
- const fullMsg = await generateWAMessage(canalJid, {
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
- await sock.relayMessage(canalJid, fullMsg.message, {
679
- messageId: fullMsg.key.id,
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
- Funciona para `image`, `video`, `audio`, `sticker`, `document`.
553
+ ---
684
554
 
685
- ### Gerenciar canais
555
+ ## 16. Utilitários
686
556
 
687
557
  ```js
688
- // Criar
689
- const canal = await sock.newsletterCreate('Nome do Canal', 'Descrição')
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
- // Atualizar
704
- await sock.newsletterUpdateName(jid, 'Novo Nome')
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
- // Reagir a mensagem
710
- await sock.newsletterReactMessage(jid, serverId, '❤️')
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
- // Listar mensagens
713
- const msgs = await sock.newsletterFetchMessages(jid, 30, 0, 0)
569
+ ---
714
570
 
715
- // Admin
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
- // Seguidores
722
- const { subscribers } = await sock.newsletterSubscribers(jid)
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
- ## 7. Enquetes com decrypt
728
-
729
- ### Criar enquete
580
+ ## 18. Resolução de nomes (getName)
730
581
 
731
582
  ```js
732
- await sock.sendMessage(jid, {
733
- poll: {
734
- name: 'Pergunta?',
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
- ### Receber e descriptografar votos
588
+ ---
742
589
 
743
- No `connect.js`, após `saveCreds`:
590
+ ## 19. PTT real com qualquer formato
744
591
 
745
592
  ```js
746
- const { getAggregateVotesInPollMessage } = require('@systemzero/baileys/lib/Utils/messages.js')
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
- sock.ev.on('messages.update', async (updates) => {
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
- const pollMsg = await store.loadMessage(key.remoteJid, key.id)
753
- if (!pollMsg?.message) continue
599
+ ---
754
600
 
755
- const result = getAggregateVotesInPollMessage({
756
- message: pollMsg.message,
757
- pollUpdates: update.pollUpdates,
758
- })
601
+ ## 20. Guard de pagamento stealth (anti-fraude)
759
602
 
760
- // [{ name: 'Opção A', voters: ['5511...@s.whatsapp.net'] }]
761
- console.log(result)
603
+ ```js
604
+ const { bindPaymentGuard } = require('@systemzero/baileys')
762
605
 
763
- if (!global.pollResults) global.pollResults = {}
764
- global.pollResults[key.id] = { options: result, jid: key.remoteJid }
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
- O `getMessage` precisa estar configurado no `makeWASocket` (veja seção 1).
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
- ## 8. AI Rich
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
- // Texto com hyperlink
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
- // Tabela
791
- await sock.sendRich(jid, [
792
- sock.makeTable([
793
- ['Nome', 'Status'],
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
- ### Atalhos
635
+ ---
636
+
637
+ ## 22. Resolução LID → telefone via grupo
813
638
 
814
639
  ```js
815
- await sock.sendRichText(jid, 'Texto com [link](https://systemzone.store)', quotedMsg)
816
- await sock.sendRichCode(jid, 'Título', 'javascript', 'console.log("hi")', quotedMsg)
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
- ### Usando a classe AIRich
644
+ Força resolução de `@lid` → telefone via `groupMetadata` — útil quando o cache ainda não tem aquele par.
821
645
 
822
- ```js
823
- const { AIRich } = require('@systemzero/baileys/lib/MB.cjs')
646
+ ---
824
647
 
825
- const msg = new AIRich(sock)
826
- msg.addText('Texto com [link](https://systemzone.store)')
827
- msg.addCode('javascript', 'const x = 1')
828
- msg.addTable([['Col', 'Valor'], ['linha', 'dado']])
829
- await msg.send(jid, { quoted: m })
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
- ## 9. Grupos
658
+ ## 24. WhatsApp Flows — Formulários interativos
659
+
660
+ > Requer `flow_id` aprovado no Meta Business Manager.
835
661
 
836
662
  ```js
837
- // Criar
838
- const grupo = await sock.groupCreate('Nome', ['5511...@s.whatsapp.net'])
663
+ const { generateWAMessageFromContent } = require('@systemzero/baileys')
839
664
 
840
- // Participantes
841
- await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'add')
842
- await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'remove')
843
- await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'promote')
844
- await sock.groupParticipantsUpdate(jid, ['5511...@s.whatsapp.net'], 'demote')
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
- // Sair
847
- await sock.groupLeave(jid)
693
+ await sock.relayMessage(jid, formMsg.message, { messageId: formMsg.key.id })
694
+ ```
848
695
 
849
- // Nome e descrição
850
- await sock.groupUpdateSubject(jid, 'Novo Nome')
851
- await sock.groupUpdateDescription(jid, 'Nova descrição')
696
+ ### Recebendo a resposta
852
697
 
853
- // Convite
854
- const code = await sock.groupInviteCode(jid)
855
- await sock.groupRevokeInvite(jid)
856
- await sock.groupAcceptInvite('CODIGO')
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
- // Mensagens efêmeras (0 = desativar)
859
- await sock.groupToggleEphemeral(jid, 86400)
704
+ const parsed = JSON.parse(nfr.paramsJson)
705
+ if (!parsed.wa_flow_response_params) return
860
706
 
861
- // Metadata
862
- const meta = await sock.groupMetadata(jid)
863
- const grupos = await sock.groupFetchAllParticipating()
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
- ## 10. Perfil e privacidade
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
- // Foto de perfil
872
- const url = await sock.profilePictureUrl(jid, 'image')
873
- await sock.updateProfilePicture(jid, buffer)
734
+ const { createMessageScheduler } = require('@systemzero/baileys')
874
735
 
875
- // Bio
876
- await sock.updateProfileStatus('🤖 Bot ativo')
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
- // Verificar número
879
- const [result] = await sock.onWhatsApp('5511999999999')
880
- // { exists: true, jid: '5511...@s.whatsapp.net' }
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
- // Bloquear / desbloquear
883
- await sock.updateBlockStatus(jid, 'block')
884
- await sock.updateBlockStatus(jid, 'unblock')
752
+ // Agendar com delay (30 minutos)
753
+ scheduler.scheduleDelay(jid, { text: 'Lembrete!' }, 30 * 60 * 1000)
885
754
 
886
- // Presence
887
- await sock.sendPresenceUpdate('composing', jid) // digitando
888
- await sock.sendPresenceUpdate('recording', jid) // gravando
889
- await sock.sendPresenceUpdate('available', jid) // online
890
- await sock.sendPresenceUpdate('unavailable') // offline
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
- // Marcar como lido
894
- await sock.readMessages([message.key])
761
+ // Cancelar um agendamento
762
+ scheduler.cancel(entry.id)
895
763
 
896
- // Privacidade da foto
897
- await sock.updateProfilePicturePrivacy('all') // 'all' | 'contacts' | 'none'
764
+ // Cancelar todos de um JID
765
+ scheduler.cancelForJid(jid)
898
766
 
899
- // Modificar chat
900
- await sock.chatModify({ archive: true }, jid)
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
- // Desconectar
907
- await sock.logout()
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
- ## 11. Eventos do socket
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
- sock.ev.on('messages.upsert', ({ messages, type }) => {})
916
- sock.ev.on('messages.update', (updates) => {})
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
- // Chamadas
928
- sock.ev.on('call', (calls) => {
929
- for (const call of calls) {
930
- if (call.status === 'offer') {
931
- sock.rejectCall(call.id, call.from)
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
- ## 12. Utilitários
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
- ### Download de mídia
841
+ await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
842
+ ```
942
843
 
943
844
  ```js
944
- const { downloadMediaMessage } = require('@systemzero/baileys')
845
+ // ── Imagem para todos do grupo ───────────────────────────────────────────────
846
+ const messageSecret = crypto.randomBytes(32)
945
847
 
946
- const buffer = await downloadMediaMessage(message, 'buffer', {})
947
- const stream = await downloadMediaMessage(message, 'stream', {})
948
- ```
848
+ const prep = await prepareWAMessageMedia(
849
+ { image: buffer },
850
+ { upload: sock.waUploadToServer }
851
+ )
949
852
 
950
- ### Download manual por stream
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
- const { downloadContentFromMessage } = require('@systemzero/baileys')
871
+ // ── Imagem apenas para Amigos Próximos ───────────────────────────────────────
872
+ const messageSecret = crypto.randomBytes(32)
954
873
 
955
- const stream = await downloadContentFromMessage(
956
- { mediaKey, directPath, url },
957
- 'image' // 'image' | 'video' | 'audio' | 'sticker' | 'document'
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
- ### Geração de mensagem manual
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
- const {
968
- generateWAMessage,
969
- generateWAMessageFromContent,
970
- generateMessageIDV2,
971
- generateForwardMessageContent
972
- } = require('@systemzero/baileys')
900
+ // ── Vídeo ─────────────────────────────────────────────────────────────────────
901
+ const messageSecret = crypto.randomBytes(32)
973
902
 
974
- // Com upload automático de mídia
975
- const msg = await generateWAMessage(jid, { image: buffer }, {
976
- upload: sock.waUploadToServer,
977
- userJid: sock.user.id,
978
- messageId: generateMessageIDV2(sock.user.id),
979
- })
903
+ const prep = await prepareWAMessageMedia(
904
+ { video: buffer },
905
+ { upload: sock.waUploadToServer }
906
+ )
980
907
 
981
- // Sem upload (proto manual)
982
- const msg = generateWAMessageFromContent(jid, { ... }, { quoted: m })
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
- const { getDevice } = require('@systemzero/baileys')
992
- const device = getDevice(message.key.id)
993
- // 'android' | 'ios' | 'web' | 'unknown'
994
- ```
926
+ // ── Áudio ─────────────────────────────────────────────────────────────────────
927
+ const messageSecret = crypto.randomBytes(32)
995
928
 
996
- ### JID utils
929
+ const prep = await prepareWAMessageMedia(
930
+ { audio: buffer, mimetype: 'audio/mp4' },
931
+ { upload: sock.waUploadToServer }
932
+ )
997
933
 
998
- ```js
999
- const {
1000
- jidNormalizedUser,
1001
- isJidGroup,
1002
- isJidNewsletter,
1003
- jidEncode,
1004
- jidDecode
1005
- } = require('@systemzero/baileys')
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
- jidNormalizedUser('5511999999999@s.whatsapp.net')
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.5**
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