@systemzero/baileys 1.0.4 → 1.0.6

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