@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
@@ -782,6 +782,7 @@ export const makeMessagesSocket = (config) => {
782
782
  else if (message.contactsArrayMessage) return 'contact_array';
783
783
  else if (message.liveLocationMessage) return 'livelocation';
784
784
  else if (message.stickerMessage) return 'sticker';
785
+ else if (message.lottieStickerMessage) return 'sticker';
785
786
  else if (message.listMessage) return 'list';
786
787
  else if (message.listResponseMessage) return 'list_response';
787
788
  else if (message.buttonsResponseMessage) return 'buttons_response';
@@ -311,7 +311,7 @@ export const makeSocket = (config) => {
311
311
  logger.info({ node }, 'not logged in, attempting registration...');
312
312
  }
313
313
  else {
314
- node = generateLoginNode(creds.me.id, config);
314
+ node = generateLoginNode(creds.me.id, { ...config, auth: { creds } });
315
315
  logger.info({ node }, 'logging in...');
316
316
  }
317
317
  const payloadEnc = noise.encrypt(proto.ClientPayload.encode(node).finish());
@@ -342,9 +342,9 @@ export const makeSocket = (config) => {
342
342
  let uploadPreKeysPromise = null;
343
343
  let lastUploadTime = 0;
344
344
  /** generates and uploads a set of pre-keys to the server */
345
- const uploadPreKeys = async (count = MIN_PREKEY_COUNT, retryCount = 0) => {
346
- // Check minimum interval (except for retries)
347
- if (retryCount === 0) {
345
+ const uploadPreKeys = async (count = MIN_PREKEY_COUNT, retryCount = 0, force = false) => {
346
+ // Check minimum interval (except for retries ou uploads forçados por erro de PreKey)
347
+ if (retryCount === 0 && !force) {
348
348
  const timeSinceLastUpload = Date.now() - lastUploadTime;
349
349
  if (timeSinceLastUpload < MIN_UPLOAD_INTERVAL) {
350
350
  logger.debug(`Skipping upload, only ${timeSinceLastUpload}ms since last upload`);
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Utilitário para lidar com erros "Bad MAC", comuns em bots WhatsApp usando
3
+ * Baileys quando a sessão Signal de um par fica desincronizada (ex: o
4
+ * outro lado reinstalou o WhatsApp, trocou de aparelho, ou houve perda de
5
+ * mensagens na troca de chaves). Não é uma falha do bot — é esperado que
6
+ * aconteça ocasionalmente em qualquer cliente Signal Protocol.
7
+ *
8
+ * Este módulo fornece funções para detectar, contar e lidar graciosamente
9
+ * com esses erros, sem derrubar o processo do bot.
10
+ *
11
+ * @author Dev Gui (original), integrado na lib para System Zero. By Josué </>
12
+ */
13
+
14
+ import fs from 'node:fs';
15
+ import path from 'node:path';
16
+ import { errorLog, warningLog } from './logger.js';
17
+
18
+ export class BadMacHandler {
19
+ constructor(options = {}) {
20
+ this.errorCount = 0;
21
+ this.maxRetries = options.maxRetries ?? 5;
22
+ this.resetInterval = options.resetInterval ?? 300000; // 5 min
23
+ this.lastReset = Date.now();
24
+ // pasta de auth configurável — por padrão segue o padrão Baileys comum
25
+ this.authFolder = options.authFolder ?? path.resolve(process.cwd(), 'assets', 'auth', 'baileys');
26
+ }
27
+
28
+ isBadMacError(error) {
29
+ const errorMessage = error?.message || error?.toString() || '';
30
+ return (
31
+ errorMessage.includes('Bad MAC') ||
32
+ errorMessage.includes('MAC verification failed') ||
33
+ errorMessage.includes('decryption failed')
34
+ );
35
+ }
36
+
37
+ isSessionError(error) {
38
+ const errorMessage = error?.message || error?.toString() || '';
39
+ return (
40
+ errorMessage.includes('Session') ||
41
+ errorMessage.includes('signal protocol') ||
42
+ errorMessage.includes('decrypt') ||
43
+ this.isBadMacError(error)
44
+ );
45
+ }
46
+
47
+ /**
48
+ * Remove arquivos de sessão Signal problemáticos, preservando SEMPRE as
49
+ * credenciais principais (creds.json, app-state-sync-key/version) — só
50
+ * descarta arquivos de sessão por par (que serão renegociados
51
+ * automaticamente na próxima troca de chaves).
52
+ */
53
+ clearProblematicSessionFiles() {
54
+ try {
55
+ if (!fs.existsSync(this.authFolder)) {
56
+ return false;
57
+ }
58
+
59
+ const PRESERVE_PATTERNS = ['app-state-sync-key', 'creds.json', 'app-state-sync-version'];
60
+ const files = fs.readdirSync(this.authFolder);
61
+ let removedCount = 0;
62
+
63
+ for (const file of files) {
64
+ const filePath = path.join(this.authFolder, file);
65
+ if (!fs.statSync(filePath).isFile()) continue;
66
+
67
+ const mustPreserve = PRESERVE_PATTERNS.some((pattern) => file.includes(pattern));
68
+ if (mustPreserve) continue;
69
+
70
+ // só remove arquivos de sessão por par (ex: session-*.json)
71
+ if (file.startsWith('session-') || file.includes('sender-key')) {
72
+ fs.unlinkSync(filePath);
73
+ removedCount++;
74
+ }
75
+ }
76
+
77
+ if (removedCount > 0) {
78
+ warningLog(`${removedCount} arquivo(s) de sessão problemáticos removidos. Credenciais principais preservadas.`);
79
+ return true;
80
+ }
81
+
82
+ return false;
83
+ } catch (error) {
84
+ errorLog(`Erro ao limpar arquivos de sessão: ${error.message}`);
85
+ return false;
86
+ }
87
+ }
88
+
89
+ incrementErrorCount() {
90
+ this.errorCount++;
91
+ errorLog(`Bad MAC error count: ${this.errorCount}/${this.maxRetries}`);
92
+
93
+ const now = Date.now();
94
+ if (now - this.lastReset > this.resetInterval) {
95
+ this.resetErrorCount();
96
+ }
97
+ }
98
+
99
+ resetErrorCount() {
100
+ const previousCount = this.errorCount;
101
+ this.errorCount = 0;
102
+ this.lastReset = Date.now();
103
+
104
+ if (previousCount > 0) {
105
+ warningLog(`Reset do contador de Bad MAC errors. Contador anterior: ${previousCount}`);
106
+ }
107
+ }
108
+
109
+ hasReachedLimit() {
110
+ return this.errorCount >= this.maxRetries;
111
+ }
112
+
113
+ /**
114
+ * @returns {boolean} true se o erro foi tratado (Bad MAC engolido),
115
+ * false se NÃO era Bad MAC (deve ser relançado pelo caller)
116
+ */
117
+ handleError(error, context = 'unknown') {
118
+ if (!this.isBadMacError(error)) {
119
+ return false;
120
+ }
121
+
122
+ errorLog(`Bad MAC error detectado em ${context}: ${error.message}`);
123
+ this.incrementErrorCount();
124
+
125
+ if (this.hasReachedLimit()) {
126
+ warningLog(`Limite de Bad MAC errors atingido (${this.maxRetries}). Considere reiniciar o bot ou limpar sessões com clearProblematicSessionFiles().`);
127
+ return true;
128
+ }
129
+
130
+ warningLog(`Ignorando Bad MAC error e continuando operação... (${this.errorCount}/${this.maxRetries})`);
131
+ return true;
132
+ }
133
+
134
+ /** Envolve uma função async — engole Bad MAC, relança qualquer outro erro. */
135
+ createSafeWrapper(fn, context) {
136
+ return async (...args) => {
137
+ try {
138
+ return await fn(...args);
139
+ } catch (error) {
140
+ if (this.handleError(error, context)) {
141
+ return null;
142
+ }
143
+ throw error;
144
+ }
145
+ };
146
+ }
147
+
148
+ getStats() {
149
+ return {
150
+ errorCount: this.errorCount,
151
+ maxRetries: this.maxRetries,
152
+ lastReset: new Date(this.lastReset).toISOString(),
153
+ timeUntilReset: Math.max(0, this.resetInterval - (Date.now() - this.lastReset)),
154
+ };
155
+ }
156
+ }
157
+
158
+ export const badMacHandler = new BadMacHandler();
@@ -277,7 +277,8 @@ export const getStatusFromReceiptType = (type) => {
277
277
  return status;
278
278
  };
279
279
  const CODE_MAP = {
280
- conflict: DisconnectReason.connectionReplaced
280
+ conflict: DisconnectReason.connectionReplaced,
281
+ forbidden: DisconnectReason.forbidden
281
282
  };
282
283
  /**
283
284
  * Stream errors generally provide a reason, map that to a baileys DisconnectReason
@@ -0,0 +1,41 @@
1
+ // lib/Utils/get-best-version.js
2
+ //
3
+ // fetchLatestWaWebVersion() e fetchLatestBaileysVersion() SEMPRE retornam um
4
+ // objeto com `version` preenchido, mesmo quando a busca falha — nesse caso
5
+ // devolvem isLatest:false e um valor antigo fixo embutido na lib. Checar só
6
+ // `if (result.version)` nunca detecta a falha, porque version sempre existe.
7
+ //
8
+ // Este helper tenta as duas fontes, na ordem, e só aceita um resultado se
9
+ // `isLatest === true` (ou seja, se realmente buscou fresco da rede). Só cai
10
+ // no valor fixo antigo se AMBAS as fontes falharem de verdade.
11
+
12
+ import { fetchLatestWaWebVersion } from './generics.js';
13
+ import { fetchLatestBaileysVersion } from './generics.js';
14
+
15
+ /**
16
+ * @param {object} [options] - passado direto pras duas funções de fetch
17
+ * @returns {Promise<{ version: number[], isLatest: boolean, source: string }>}
18
+ */
19
+ export const getBestWaVersion = async (options = {}) => {
20
+ try {
21
+ const web = await fetchLatestWaWebVersion(options);
22
+ if (web?.isLatest && web?.version) {
23
+ return { version: web.version, isLatest: true, source: 'web.whatsapp.com' };
24
+ }
25
+ } catch {
26
+ // segue pra próxima fonte
27
+ }
28
+
29
+ try {
30
+ const github = await fetchLatestBaileysVersion(options);
31
+ if (github?.isLatest && github?.version) {
32
+ return { version: github.version, isLatest: true, source: 'github' };
33
+ }
34
+ } catch {
35
+ // segue pro fallback fixo
36
+ }
37
+
38
+ // as duas fontes falharam de verdade — usa o valor fixo embutido,
39
+ // mas avisa explicitamente que NÃO é a versão mais atual
40
+ return { version: [2, 3000, 1027934701], isLatest: false, source: 'fallback-fixo' };
41
+ };
@@ -0,0 +1 @@
1
+ export declare const getName: (msg: any, contactStore?: Record<string, { name?: string; notify?: string; verifiedName?: string }>) => string;
@@ -0,0 +1,54 @@
1
+ // lib/Utils/get-name.js
2
+ // Resolve o nome do remetente com cobertura total (nunca retorna vazio).
3
+ // Ordem de prioridade:
4
+ // 1) Nome salvo localmente (store/contatos) — mais confiável
5
+ // 2) verifiedName (conta business confirmada pela Meta)
6
+ // 3) notify / pushName da própria mensagem
7
+ // 4) Nome resolvido via cache LID -> JID (se sender for @lid)
8
+ // 5) Número de telefone formatado (fallback final, nunca undefined)
9
+
10
+ import { jidDecode, isLidUser, sharedLidPhoneCache, lidToJid } from '../WABinary/jid-utils.js';
11
+
12
+ /**
13
+ * @param {object} msg - mensagem completa do Baileys (proto.IWebMessageInfo)
14
+ * @param {object} [contactStore] - opcional: { [jid]: { name, notify, verifiedName } }
15
+ * @returns {string} nome final, garantido não-vazio
16
+ */
17
+ export const getName = (msg, contactStore) => {
18
+ try {
19
+ const key = msg?.key || {};
20
+ let sender = key.participant || key.remoteJid || '';
21
+
22
+ // se vier @lid, tenta resolver pro JID real (telefone) primeiro,
23
+ // pois o contactStore normalmente é indexado por @s.whatsapp.net
24
+ let resolvedSender = sender;
25
+ if (isLidUser(sender)) {
26
+ const phone = sharedLidPhoneCache.getPhoneForLid(sender) || lidToJid(sender);
27
+ if (phone && phone !== sender) resolvedSender = phone;
28
+ }
29
+
30
+ // 1) contato salvo localmente
31
+ const contact = contactStore?.[resolvedSender] || contactStore?.[sender];
32
+ if (contact?.name && contact.name.trim()) return contact.name.trim();
33
+
34
+ // 2) verifiedName (conta business)
35
+ if (contact?.verifiedName && contact.verifiedName.trim()) return contact.verifiedName.trim();
36
+
37
+ // 3) pushName / notify da mensagem em si
38
+ const pushName = msg?.pushName || contact?.notify;
39
+ if (pushName && pushName.trim() && pushName.trim() !== 'WhatsApp User') {
40
+ return pushName.trim();
41
+ }
42
+
43
+ // 4) fallback: número de telefone formatado a partir do JID resolvido
44
+ const decoded = jidDecode(resolvedSender);
45
+ if (decoded?.user) {
46
+ return `+${decoded.user}`;
47
+ }
48
+
49
+ // 5) último recurso absoluto — nunca undefined/empty
50
+ return 'Usuário desconhecido';
51
+ } catch {
52
+ return 'Usuário desconhecido';
53
+ }
54
+ };
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Detecção robusta de mensagens de status-em-grupo (marcação de status no grupo).
3
+ *
4
+ * Cobre:
5
+ * - groupStatusMentionMessage / groupStatusMessage / groupStatusMessageV2
6
+ * - isGroupStatus: true | 1 em qualquer nível
7
+ * - statusAttributions com type GROUP_STATUS / type 5 / groupStatus: true
8
+ * - mensagens aninhadas em wrappers (ephemeral, viewOnce, etc)
9
+ *
10
+ * @author Dev Gui (original), integrado na lib para System Zero. By Josué </>
11
+ */
12
+
13
+ const MAX_MESSAGE_UNWRAP_DEPTH = 5;
14
+ const MAX_FLAG_SCAN_DEPTH = 8;
15
+
16
+ const STRONG_GROUP_STATUS_MESSAGE_KEYS = new Set([
17
+ 'groupStatusMentionMessage',
18
+ 'groupStatusMessage',
19
+ 'groupStatusMessageV2',
20
+ ]);
21
+
22
+ const WRAPPED_MESSAGE_KEYS = [
23
+ 'ephemeralMessage',
24
+ 'viewOnceMessage',
25
+ 'viewOnceMessageV2',
26
+ 'viewOnceMessageV2Extension',
27
+ 'documentWithCaptionMessage',
28
+ 'statusMentionMessage',
29
+ 'groupStatusMentionMessage',
30
+ 'groupStatusMessage',
31
+ 'groupStatusMessageV2',
32
+ ];
33
+
34
+ export function isGroupStatusValue(value) {
35
+ return value === true || value === 1;
36
+ }
37
+
38
+ function canScanObject(value) {
39
+ return value && typeof value === 'object' && !(value instanceof ArrayBuffer) && !ArrayBuffer.isView(value);
40
+ }
41
+
42
+ function hasGroupStatusAttribution(statusAttributions) {
43
+ if (!Array.isArray(statusAttributions)) return false;
44
+
45
+ return statusAttributions.some(
46
+ (sa) =>
47
+ canScanObject(sa) &&
48
+ (Boolean(sa.groupStatus) || sa.attributionData === 'groupStatus' || sa.type === 'GROUP_STATUS' || sa.type === 5)
49
+ );
50
+ }
51
+
52
+ function hasGroupStatusContextInfo(contextInfo) {
53
+ return (
54
+ canScanObject(contextInfo) &&
55
+ (isGroupStatusValue(contextInfo.isGroupStatus) || hasGroupStatusAttribution(contextInfo.statusAttributions))
56
+ );
57
+ }
58
+
59
+ export function hasGroupStatusFlag(value, depth = 0, seenObjects = new WeakSet()) {
60
+ if (!canScanObject(value) || depth > MAX_FLAG_SCAN_DEPTH || seenObjects.has(value)) {
61
+ return false;
62
+ }
63
+
64
+ seenObjects.add(value);
65
+
66
+ for (const [key, childValue] of Object.entries(value)) {
67
+ if (key === 'quotedMessage') continue;
68
+
69
+ if (STRONG_GROUP_STATUS_MESSAGE_KEYS.has(key) && canScanObject(childValue)) {
70
+ return true;
71
+ }
72
+
73
+ if (key === 'isGroupStatus' && isGroupStatusValue(childValue)) {
74
+ return true;
75
+ }
76
+
77
+ if (key === 'statusAttributions' && hasGroupStatusAttribution(childValue)) {
78
+ return true;
79
+ }
80
+
81
+ if (key === 'contextInfo' && hasGroupStatusContextInfo(childValue)) {
82
+ return true;
83
+ }
84
+
85
+ if (hasGroupStatusFlag(childValue, depth + 1, seenObjects)) {
86
+ return true;
87
+ }
88
+ }
89
+
90
+ return false;
91
+ }
92
+
93
+ export function getCurrentMessageContentVariants(message, depth = 0, seenObjects = new WeakSet()) {
94
+ if (!canScanObject(message) || depth > MAX_MESSAGE_UNWRAP_DEPTH || seenObjects.has(message)) {
95
+ return [];
96
+ }
97
+
98
+ seenObjects.add(message);
99
+
100
+ const variants = [message];
101
+
102
+ for (const key of WRAPPED_MESSAGE_KEYS) {
103
+ const wrappedMessage = message[key]?.message;
104
+ variants.push(...getCurrentMessageContentVariants(wrappedMessage, depth + 1, seenObjects));
105
+ }
106
+
107
+ return variants;
108
+ }
109
+
110
+ /** Verifica se a webMessage é uma marcação de status em grupo, inclusive em wrappers ou níveis profundos. */
111
+ export function hasGroupStatusMessage(webMessage) {
112
+ return getCurrentMessageContentVariants(webMessage?.message).some((message) => hasGroupStatusFlag(message));
113
+ }
@@ -16,4 +16,12 @@ export * from './event-buffer.js';
16
16
  export * from './process-message.js';
17
17
  export * from './message-retry-manager.js';
18
18
  export * from './browser-utils.js';
19
+ export * from './get-name.js';
20
+ export * from './payment-guard.js';
21
+ export * from './payment-detection.js';
22
+ export * from './group-status-detection.js';
23
+ export * from './bad-mac-handler.js';
24
+ export * from './resolve-lid-phone.js';
25
+ export * from './get-best-version.js';
26
+ export * from './scheduling.js';
19
27
  //# sourceMappingURL=index.js.map
@@ -1,3 +1,6 @@
1
1
  import P from 'pino';
2
- export default P({ timestamp: () => `,"time":"${new Date().toJSON()}"` });
2
+ const logger = P({ timestamp: () => `,"time":"${new Date().toJSON()}"` });
3
+ export const errorLog = (msg) => logger.error(msg);
4
+ export const warningLog = (msg) => logger.warn(msg);
5
+ export default logger;
3
6
  //# sourceMappingURL=logger.js.map
@@ -7,12 +7,50 @@ import { tmpdir } from 'os';
7
7
  import { join } from 'path';
8
8
  import { Readable, Transform } from 'stream';
9
9
  import { URL } from 'url';
10
+ import { promisify } from 'util';
10
11
  import { proto } from '../../WAProto/index.js';
11
12
  import { DEFAULT_ORIGIN, MEDIA_HKDF_KEY_MAPPING, MEDIA_PATH_MAP } from '../Defaults/index.js';
12
13
  import { getBinaryNodeChild, getBinaryNodeChildBuffer, jidNormalizedUser } from '../WABinary/index.js';
13
14
  import { aesDecryptGCM, aesEncryptGCM, hkdf } from './crypto.js';
14
15
  import { generateMessageIDV2 } from './generics.js';
15
16
  const getTmpFilesDirectory = () => tmpdir();
17
+ const execAsync = promisify(exec);
18
+
19
+ /**
20
+ * Converte QUALQUER áudio de entrada pra opus/ogg mono 16kHz — o formato
21
+ * exato que o player de PTT do WhatsApp espera. Sem isso, marcar `ptt: true`
22
+ * num mp3/m4a só troca o RÓTULO do mimetype sem mudar os bytes reais, e o
23
+ * WhatsApp mostra "algo errado com o arquivo de áudio" ao tentar decodificar.
24
+ *
25
+ * @param {string | Buffer} input - caminho de arquivo local, URL http(s), ou Buffer já em memória
26
+ * @returns {Promise<string>} caminho do arquivo .ogg convertido (temporário — chame fs.unlink depois de usar)
27
+ */
28
+ export async function transcodeAudioToOpus(input) {
29
+ const outputPath = join(getTmpFilesDirectory(), 'ptt-' + generateMessageIDV2() + '.ogg');
30
+ let inputPath = input;
31
+ let tempInputPath;
32
+
33
+ try {
34
+ if (Buffer.isBuffer(input)) {
35
+ tempInputPath = join(getTmpFilesDirectory(), 'ptt-src-' + generateMessageIDV2());
36
+ await fs.writeFile(tempInputPath, input);
37
+ inputPath = tempInputPath;
38
+ }
39
+
40
+ // -vn: ignora qualquer vídeo/capa embutida (mp3 com artwork, por exemplo)
41
+ // -ac 1 -ar 16000: mono 16kHz — espec exata do PTT nativo do WhatsApp
42
+ // -c:a libopus -b:a 32k: codec real opus, não só o rótulo
43
+ const cmd = `ffmpeg -i "${inputPath}" -y -vn -ac 1 -ar 16000 -c:a libopus -b:a 32k -f ogg "${outputPath}"`;
44
+ await execAsync(cmd);
45
+
46
+ return outputPath;
47
+ } finally {
48
+ if (tempInputPath) {
49
+ await fs.unlink(tempInputPath).catch(() => {});
50
+ }
51
+ }
52
+ }
53
+
16
54
  export const getImageProcessingLibrary = async () => {
17
55
  //@ts-ignore
18
56
  const [jimp, sharp] = await Promise.all([import('jimp').catch(() => { }), import('sharp').catch(() => { })]);