@xbibzlibrary/whatsbibz 1.3.2 → 1.4.3

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 (247) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/README.cn.md +604 -0
  3. package/README.id.md +237 -7
  4. package/README.md +237 -7
  5. package/WAProto/WAProto.proto +1 -0
  6. package/WAProto/index.d.ts +1 -0
  7. package/WAProto/index.js +1 -0
  8. package/assets/logo/README.md +11 -13
  9. package/assets/logo/preview.png +0 -0
  10. package/lib/BibzWhats/banner.d.ts +32 -0
  11. package/lib/BibzWhats/banner.js +121 -0
  12. package/lib/BibzWhats/client.d.ts +8 -1
  13. package/lib/BibzWhats/client.js +13 -0
  14. package/lib/BibzWhats/device-identity.d.ts +1 -0
  15. package/lib/BibzWhats/device-identity.js +1 -0
  16. package/lib/BibzWhats/extract.d.ts +1 -0
  17. package/lib/BibzWhats/extract.js +1 -0
  18. package/lib/BibzWhats/index.d.ts +2 -0
  19. package/lib/BibzWhats/index.js +2 -0
  20. package/lib/BibzWhats/jid.d.ts +1 -0
  21. package/lib/BibzWhats/jid.js +1 -0
  22. package/lib/BibzWhats/pairing.d.ts +1 -0
  23. package/lib/BibzWhats/pairing.js +1 -0
  24. package/lib/BibzWhats/send.d.ts +1 -0
  25. package/lib/BibzWhats/send.js +1 -0
  26. package/lib/BibzWhats/version.js +5 -4
  27. package/lib/Defaults/index.d.ts +3 -0
  28. package/lib/Defaults/index.js +4 -6
  29. package/lib/Modded/message_builder.d.ts +1 -0
  30. package/lib/Modded/message_builder.js +36 -43
  31. package/lib/Signal/Group/ciphertext-message.d.ts +1 -0
  32. package/lib/Signal/Group/ciphertext-message.js +1 -0
  33. package/lib/Signal/Group/group-session-builder.d.ts +1 -0
  34. package/lib/Signal/Group/group-session-builder.js +1 -0
  35. package/lib/Signal/Group/group_cipher.d.ts +1 -0
  36. package/lib/Signal/Group/group_cipher.js +1 -0
  37. package/lib/Signal/Group/index.d.ts +1 -0
  38. package/lib/Signal/Group/index.js +1 -0
  39. package/lib/Signal/Group/keyhelper.d.ts +1 -0
  40. package/lib/Signal/Group/keyhelper.js +1 -0
  41. package/lib/Signal/Group/sender-chain-key.d.ts +1 -0
  42. package/lib/Signal/Group/sender-chain-key.js +1 -0
  43. package/lib/Signal/Group/sender-key-distribution-message.d.ts +1 -0
  44. package/lib/Signal/Group/sender-key-distribution-message.js +1 -0
  45. package/lib/Signal/Group/sender-key-message.d.ts +1 -0
  46. package/lib/Signal/Group/sender-key-message.js +1 -0
  47. package/lib/Signal/Group/sender-key-name.d.ts +1 -0
  48. package/lib/Signal/Group/sender-key-name.js +1 -0
  49. package/lib/Signal/Group/sender-key-record.d.ts +1 -0
  50. package/lib/Signal/Group/sender-key-record.js +1 -0
  51. package/lib/Signal/Group/sender-key-state.d.ts +1 -0
  52. package/lib/Signal/Group/sender-key-state.js +1 -0
  53. package/lib/Signal/Group/sender-message-key.d.ts +1 -0
  54. package/lib/Signal/Group/sender-message-key.js +1 -0
  55. package/lib/Signal/libsignal.d.ts +1 -0
  56. package/lib/Signal/libsignal.js +1 -0
  57. package/lib/Signal/lid-mapping.d.ts +1 -0
  58. package/lib/Signal/lid-mapping.js +1 -0
  59. package/lib/Socket/Client/index.d.ts +1 -0
  60. package/lib/Socket/Client/index.js +1 -0
  61. package/lib/Socket/Client/types.d.ts +1 -0
  62. package/lib/Socket/Client/types.js +1 -0
  63. package/lib/Socket/Client/websocket.d.ts +1 -0
  64. package/lib/Socket/Client/websocket.js +1 -0
  65. package/lib/Socket/business.d.ts +1 -2
  66. package/lib/Socket/business.js +1 -0
  67. package/lib/Socket/chats.d.ts +1 -0
  68. package/lib/Socket/chats.js +1 -0
  69. package/lib/Socket/communities.d.ts +1 -2
  70. package/lib/Socket/communities.js +12 -2
  71. package/lib/Socket/engine.d.ts +1 -0
  72. package/lib/Socket/engine.js +1 -0
  73. package/lib/Socket/groups.d.ts +1 -0
  74. package/lib/Socket/groups.js +1 -0
  75. package/lib/Socket/index.d.ts +1 -2
  76. package/lib/Socket/index.js +12 -11
  77. package/lib/Socket/messages-recv.d.ts +1 -2
  78. package/lib/Socket/messages-recv.js +13 -4
  79. package/lib/Socket/messages-send.d.ts +7 -2
  80. package/lib/Socket/messages-send.js +59 -23
  81. package/lib/Socket/mex.d.ts +1 -0
  82. package/lib/Socket/mex.js +1 -0
  83. package/lib/Socket/newsletter.d.ts +1 -1
  84. package/lib/Socket/newsletter.js +255 -432
  85. package/lib/Socket/socket.d.ts +1 -0
  86. package/lib/Socket/socket.js +20 -1
  87. package/lib/Types/Auth.d.ts +2 -0
  88. package/lib/Types/Auth.js +1 -0
  89. package/lib/Types/Bussines.d.ts +1 -0
  90. package/lib/Types/Bussines.js +1 -0
  91. package/lib/Types/Call.d.ts +1 -0
  92. package/lib/Types/Call.js +1 -0
  93. package/lib/Types/Chat.d.ts +1 -0
  94. package/lib/Types/Chat.js +1 -0
  95. package/lib/Types/Contact.d.ts +1 -0
  96. package/lib/Types/Contact.js +1 -0
  97. package/lib/Types/Events.d.ts +1 -0
  98. package/lib/Types/Events.js +1 -0
  99. package/lib/Types/GroupMetadata.d.ts +1 -0
  100. package/lib/Types/GroupMetadata.js +1 -0
  101. package/lib/Types/Label.d.ts +1 -0
  102. package/lib/Types/Label.js +1 -0
  103. package/lib/Types/LabelAssociation.d.ts +1 -0
  104. package/lib/Types/LabelAssociation.js +1 -0
  105. package/lib/Types/Message.d.ts +1 -0
  106. package/lib/Types/Message.js +1 -0
  107. package/lib/Types/Newsletter.d.ts +1 -0
  108. package/lib/Types/Newsletter.js +1 -0
  109. package/lib/Types/Product.d.ts +1 -0
  110. package/lib/Types/Product.js +1 -0
  111. package/lib/Types/Signal.d.ts +1 -0
  112. package/lib/Types/Signal.js +1 -0
  113. package/lib/Types/Socket.d.ts +1 -6
  114. package/lib/Types/Socket.js +1 -0
  115. package/lib/Types/State.d.ts +1 -0
  116. package/lib/Types/State.js +1 -0
  117. package/lib/Types/USync.d.ts +1 -0
  118. package/lib/Types/USync.js +1 -0
  119. package/lib/Types/index.d.ts +1 -0
  120. package/lib/Types/index.js +1 -0
  121. package/lib/Utils/auth-utils.d.ts +1 -0
  122. package/lib/Utils/auth-utils.js +4 -0
  123. package/lib/Utils/browser-utils.d.ts +1 -0
  124. package/lib/Utils/browser-utils.js +3 -2
  125. package/lib/Utils/business.d.ts +1 -0
  126. package/lib/Utils/business.js +1 -0
  127. package/lib/Utils/chat-utils.d.ts +1 -0
  128. package/lib/Utils/chat-utils.js +1 -0
  129. package/lib/Utils/companion-reg-client-utils.d.ts +1 -0
  130. package/lib/Utils/companion-reg-client-utils.js +1 -0
  131. package/lib/Utils/crypto.d.ts +1 -0
  132. package/lib/Utils/crypto.js +1 -0
  133. package/lib/Utils/decode-wa-message.d.ts +1 -0
  134. package/lib/Utils/decode-wa-message.js +1 -0
  135. package/lib/Utils/event-buffer.d.ts +1 -0
  136. package/lib/Utils/event-buffer.js +9 -0
  137. package/lib/Utils/generics.d.ts +1 -0
  138. package/lib/Utils/generics.js +2 -1
  139. package/lib/Utils/history.d.ts +1 -0
  140. package/lib/Utils/history.js +1 -0
  141. package/lib/Utils/identity-change-handler.d.ts +1 -0
  142. package/lib/Utils/identity-change-handler.js +1 -0
  143. package/lib/Utils/index.d.ts +1 -0
  144. package/lib/Utils/index.js +1 -0
  145. package/lib/Utils/link-preview.d.ts +1 -0
  146. package/lib/Utils/link-preview.js +1 -0
  147. package/lib/Utils/logger.d.ts +1 -0
  148. package/lib/Utils/logger.js +1 -0
  149. package/lib/Utils/lt-hash.d.ts +1 -0
  150. package/lib/Utils/lt-hash.js +1 -0
  151. package/lib/Utils/make-mutex.d.ts +1 -0
  152. package/lib/Utils/make-mutex.js +1 -0
  153. package/lib/Utils/message-retry-manager.d.ts +1 -0
  154. package/lib/Utils/message-retry-manager.js +1 -0
  155. package/lib/Utils/messages-media.d.ts +1 -0
  156. package/lib/Utils/messages-media.js +28 -92
  157. package/lib/Utils/messages.d.ts +5 -0
  158. package/lib/Utils/messages.js +50 -5
  159. package/lib/Utils/noise-handler.d.ts +1 -0
  160. package/lib/Utils/noise-handler.js +1 -0
  161. package/lib/Utils/offline-node-processor.d.ts +2 -0
  162. package/lib/Utils/offline-node-processor.js +6 -0
  163. package/lib/Utils/platform-identity.d.ts +1 -0
  164. package/lib/Utils/platform-identity.js +1 -0
  165. package/lib/Utils/pre-key-manager.d.ts +1 -0
  166. package/lib/Utils/pre-key-manager.js +1 -0
  167. package/lib/Utils/process-message.d.ts +1 -0
  168. package/lib/Utils/process-message.js +1 -0
  169. package/lib/Utils/reporting-utils.d.ts +1 -0
  170. package/lib/Utils/reporting-utils.js +1 -0
  171. package/lib/Utils/rich-messages.d.ts +1 -0
  172. package/lib/Utils/rich-messages.js +11 -0
  173. package/lib/Utils/signal.d.ts +1 -0
  174. package/lib/Utils/signal.js +1 -0
  175. package/lib/Utils/stanza-ack.d.ts +1 -0
  176. package/lib/Utils/stanza-ack.js +1 -0
  177. package/lib/Utils/sticker-pack.d.ts +1 -0
  178. package/lib/Utils/sticker-pack.js +1 -0
  179. package/lib/Utils/sync-action-utils.d.ts +1 -0
  180. package/lib/Utils/sync-action-utils.js +1 -0
  181. package/lib/Utils/tc-token-utils.d.ts +1 -0
  182. package/lib/Utils/tc-token-utils.js +1 -0
  183. package/lib/Utils/use-multi-file-auth-state.d.ts +1 -0
  184. package/lib/Utils/use-multi-file-auth-state.js +1 -0
  185. package/lib/Utils/validate-connection.d.ts +1 -0
  186. package/lib/Utils/validate-connection.js +1 -0
  187. package/lib/VoIP/audio-feeder.d.ts +1 -0
  188. package/lib/VoIP/audio-feeder.js +1 -0
  189. package/lib/VoIP/index.d.ts +1 -0
  190. package/lib/VoIP/index.js +1 -0
  191. package/lib/VoIP/relay-transport.d.ts +1 -0
  192. package/lib/VoIP/relay-transport.js +1 -0
  193. package/lib/VoIP/signaling.js +1 -0
  194. package/lib/VoIP/types.d.ts +1 -0
  195. package/lib/VoIP/types.js +1 -0
  196. package/lib/VoIP/wasm-engine.d.ts +1 -0
  197. package/lib/VoIP/wasm-engine.js +1 -0
  198. package/lib/VoIP/worker-bootstrap.js +2 -1
  199. package/lib/WABinary/constants.d.ts +1 -0
  200. package/lib/WABinary/constants.js +1 -0
  201. package/lib/WABinary/decode.d.ts +1 -0
  202. package/lib/WABinary/decode.js +1 -0
  203. package/lib/WABinary/encode.d.ts +1 -0
  204. package/lib/WABinary/encode.js +1 -0
  205. package/lib/WABinary/generic-utils.d.ts +1 -0
  206. package/lib/WABinary/generic-utils.js +1 -0
  207. package/lib/WABinary/index.d.ts +1 -0
  208. package/lib/WABinary/index.js +1 -0
  209. package/lib/WABinary/jid-utils.d.ts +1 -0
  210. package/lib/WABinary/jid-utils.js +1 -0
  211. package/lib/WABinary/types.d.ts +1 -0
  212. package/lib/WABinary/types.js +1 -0
  213. package/lib/WAM/BinaryInfo.d.ts +1 -0
  214. package/lib/WAM/BinaryInfo.js +1 -0
  215. package/lib/WAM/constants.d.ts +1 -0
  216. package/lib/WAM/constants.js +1 -0
  217. package/lib/WAM/encode.d.ts +1 -0
  218. package/lib/WAM/encode.js +1 -0
  219. package/lib/WAM/index.d.ts +1 -0
  220. package/lib/WAM/index.js +1 -0
  221. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +1 -0
  222. package/lib/WAUSync/Protocols/USyncContactProtocol.js +1 -0
  223. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +1 -0
  224. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +1 -0
  225. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +1 -0
  226. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -0
  227. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +1 -0
  228. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +1 -0
  229. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +1 -0
  230. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +1 -0
  231. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +1 -0
  232. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +1 -0
  233. package/lib/WAUSync/Protocols/index.d.ts +1 -0
  234. package/lib/WAUSync/Protocols/index.js +1 -0
  235. package/lib/WAUSync/USyncQuery.d.ts +1 -0
  236. package/lib/WAUSync/USyncQuery.js +1 -0
  237. package/lib/WAUSync/USyncUser.d.ts +1 -0
  238. package/lib/WAUSync/USyncUser.js +1 -0
  239. package/lib/WAUSync/index.d.ts +1 -0
  240. package/lib/WAUSync/index.js +1 -0
  241. package/lib/assets/wasm/loader.js +1 -0
  242. package/lib/assets/wasm/worker-modules.js +1 -0
  243. package/lib/index.d.ts +1 -0
  244. package/lib/index.js +1 -1
  245. package/package.json +27 -9
  246. package/WAProto/GenerateStatics.sh +0 -3
  247. package/WAProto/fix-imports.js +0 -81
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/messages-media */
1
2
  import { Boom } from '@hapi/boom';
2
3
  import { exec } from 'child_process';
3
4
  import * as Crypto from 'crypto';
@@ -491,6 +492,7 @@ export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, {
491
492
  }
492
493
  }
493
494
  });
495
+ fetched.on('error', error => output.destroy(error));
494
496
  return fetched.pipe(output, { end: true });
495
497
  };
496
498
  export function extensionForMediaMessage(message) {
@@ -512,65 +514,6 @@ const isNodeRuntime = () => {
512
514
  typeof process.versions.bun === 'undefined' &&
513
515
  typeof globalThis.Deno === 'undefined');
514
516
  };
515
- export const uploadWithNodeHttp = async ({ url, filePath, headers, timeoutMs, agent }, redirectCount = 0) => {
516
- if (redirectCount > 5) {
517
- throw new Error('Too many redirects');
518
- }
519
- const parsedUrl = new URL(url);
520
- const httpModule = parsedUrl.protocol === 'https:' ? await import('https') : await import('http');
521
- // Get file size for Content-Length header (required for Node.js streaming)
522
- const fileStats = await fs.stat(filePath);
523
- const fileSize = fileStats.size;
524
- return new Promise((resolve, reject) => {
525
- const req = httpModule.request({
526
- hostname: parsedUrl.hostname,
527
- port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80),
528
- path: parsedUrl.pathname + parsedUrl.search,
529
- method: 'POST',
530
- headers: {
531
- ...headers,
532
- 'Content-Length': fileSize
533
- },
534
- agent,
535
- timeout: timeoutMs
536
- }, res => {
537
- // Handle redirects (3xx)
538
- if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
539
- res.resume(); // Consume response to free resources
540
- const newUrl = new URL(res.headers.location, url).toString();
541
- resolve(uploadWithNodeHttp({
542
- url: newUrl,
543
- filePath,
544
- headers,
545
- timeoutMs,
546
- agent
547
- }, redirectCount + 1));
548
- return;
549
- }
550
- let body = '';
551
- res.on('data', chunk => (body += chunk));
552
- res.on('end', () => {
553
- try {
554
- resolve(JSON.parse(body));
555
- }
556
- catch {
557
- resolve(undefined);
558
- }
559
- });
560
- });
561
- req.on('error', reject);
562
- req.on('timeout', () => {
563
- req.destroy();
564
- reject(new Error('Upload timeout'));
565
- });
566
- const stream = createReadStream(filePath);
567
- stream.pipe(req);
568
- stream.on('error', err => {
569
- req.destroy();
570
- reject(err);
571
- });
572
- });
573
- };
574
517
  const uploadWithFetch = async ({ url, filePath, headers, timeoutMs, agent }) => {
575
518
  // Convert Node.js Readable to Web ReadableStream
576
519
  const nodeStream = createReadStream(filePath);
@@ -592,32 +535,15 @@ const uploadWithFetch = async ({ url, filePath, headers, timeoutMs, agent }) =>
592
535
  return undefined;
593
536
  }
594
537
  };
538
+ export const uploadWithNodeHttp = async (params) => {
539
+ return uploadWithFetch(params);
540
+ };
595
541
  /**
596
- * Uploads media to WhatsApp servers.
597
- *
598
- * ## Why we have two upload implementations:
599
- *
600
- * Node.js's native `fetch` (powered by undici) has a known bug where it buffers
601
- * the entire request body in memory before sending, even when using streams.
602
- * This causes memory issues with large files (e.g., 1GB file = 1GB+ memory usage).
603
- * See: https://github.com/nodejs/undici/issues/4058
604
- *
605
- * Other runtimes (Bun, Deno, browsers) correctly stream the request body without
606
- * buffering, so we can use the web-standard Fetch API there.
607
- *
608
- * ## Future considerations:
609
- * Once the undici bug is fixed, we can simplify this to use only the Fetch API
610
- * across all runtimes. Monitor the GitHub issue for updates.
542
+ * Uploads media to WhatsApp servers using Web-standard Fetch API.
611
543
  */
612
544
  const uploadMedia = async (params, logger) => {
613
- if (isNodeRuntime()) {
614
- logger?.debug('Using Node.js https module for upload (avoids undici buffering bug)');
615
- return uploadWithNodeHttp(params);
616
- }
617
- else {
618
- logger?.debug('Using web-standard Fetch API for upload');
619
- return uploadWithFetch(params);
620
- }
545
+ logger?.debug('Using web-standard Fetch API for upload');
546
+ return uploadWithFetch(params);
621
547
  };
622
548
  export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
623
549
  return async (streamOrPath, { mediaType, fileEncSha256B64, newsletter, timeoutMs }) => {
@@ -651,22 +577,29 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, opt
651
577
  if (newsletter && mediaPath) {
652
578
  mediaPath = mediaPath.replace('/mms/', '/newsletter/newsletter-');
653
579
  }
580
+ const dispatcher = typeof fetchAgent?.dispatch === 'function' ? fetchAgent : undefined;
654
581
  for (const { hostname } of hosts) {
655
582
  logger.debug(`uploading to "${hostname}"`);
656
583
  const auth = encodeURIComponent(uploadInfo.auth);
657
584
  const url = `https://${hostname}${mediaPath}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
658
585
  let result;
659
586
  try {
660
- const axios = (await import('axios')).default;
661
- const body = await axios.post(url, reqBuffer, {
662
- headers,
663
- httpsAgent: fetchAgent,
664
- timeout: timeoutMs,
665
- responseType: 'json',
666
- maxBodyLength: Infinity,
667
- maxContentLength: Infinity
587
+ const response = await fetch(url, {
588
+ ...(dispatcher ? { dispatcher } : {}),
589
+ method: 'POST',
590
+ body: reqBuffer,
591
+ headers: {
592
+ ...headers,
593
+ 'Content-Length': String(reqBuffer.length)
594
+ },
595
+ signal: timeoutMs ? AbortSignal.timeout(timeoutMs) : undefined
668
596
  });
669
- result = body.data;
597
+ try {
598
+ result = await response.json();
599
+ }
600
+ catch {
601
+ result = undefined;
602
+ }
670
603
  if (result?.url || result?.direct_path) {
671
604
  urls = {
672
605
  mediaUrl: result.url,
@@ -696,7 +629,10 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, opt
696
629
  };
697
630
 
698
631
  const getMediaRetryKey = (mediaKey) => {
699
- return hkdf(mediaKey, 32, { info: 'WhatsApp Media Retry Notification' });
632
+ const keyBuf = typeof mediaKey === 'string'
633
+ ? Buffer.from(mediaKey.replace('data:;base64,', ''), 'base64')
634
+ : mediaKey;
635
+ return hkdf(keyBuf, 32, { info: 'WhatsApp Media Retry Notification' });
700
636
  };
701
637
  /**
702
638
  * Generate a binary node that will request the phone to re-upload the media & return the newly uploaded URL
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/messages */
1
2
  import { type Transform } from 'stream';
2
3
  import { proto } from '../../WAProto/index.js';
3
4
  import type { AnyMediaMessageContent, AnyMessageContent, MessageContentGenerationOptions, MessageGenerationOptions, MessageGenerationOptionsFromContent, MessageUserReceipt, WAMessage, WAMessageContent, WAMessageKey } from '../Types/index.js';
@@ -32,6 +33,10 @@ export declare const getContentType: (content: proto.IMessage | undefined) => ke
32
33
  * @returns
33
34
  */
34
35
  export declare const normalizeMessageContent: (content: WAMessageContent | null | undefined) => WAMessageContent | undefined;
36
+ /**
37
+ * Checks whether a message content (or any of its wrappers) is a view-once message
38
+ */
39
+ export declare const isViewOnceMessage: (content: WAMessageContent | null | undefined) => boolean;
35
40
  /**
36
41
  * Extract the true message content from a message
37
42
  * Eg. extracts the inner message from a disappearing message/view once message
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/messages */
1
2
  import { Boom } from "@hapi/boom";
2
3
  import { randomBytes } from "crypto";
3
4
  import { promises as fs } from "fs";
@@ -974,6 +975,43 @@ export const normalizeMessageContent = (content) => {
974
975
  );
975
976
  }
976
977
  };
978
+ /**
979
+ * Checks whether a message content (or any of its wrappers) is a view-once message
980
+ */
981
+ export const isViewOnceMessage = (content) => {
982
+ if (!content) {
983
+ return false;
984
+ }
985
+ const hasViewOnceFlag = (msg) =>
986
+ Boolean(
987
+ msg?.imageMessage?.viewOnce ||
988
+ msg?.videoMessage?.viewOnce ||
989
+ msg?.audioMessage?.viewOnce,
990
+ );
991
+ for (let i = 0; i < 5 && content; i++) {
992
+ if (
993
+ content.viewOnceMessage ||
994
+ content.viewOnceMessageV2 ||
995
+ content.viewOnceMessageV2Extension ||
996
+ content.viewOnceMessageV3 ||
997
+ hasViewOnceFlag(content)
998
+ ) {
999
+ return true;
1000
+ }
1001
+ const inner =
1002
+ content.ephemeralMessage ||
1003
+ content.documentWithCaptionMessage ||
1004
+ content.editedMessage ||
1005
+ content.associatedChildMessage ||
1006
+ content.groupStatusMessage ||
1007
+ content.groupStatusMessageV2;
1008
+ if (!inner) {
1009
+ break;
1010
+ }
1011
+ content = inner.message;
1012
+ }
1013
+ return false;
1014
+ };
977
1015
  /**
978
1016
  * Extract the true message content from a message
979
1017
  * Eg. extracts the inner message from a disappearing message/view once message
@@ -1158,16 +1196,17 @@ export const aggregateMessageKeysNotFromMe = (keys) => {
1158
1196
  }
1159
1197
  return Object.values(keyMap);
1160
1198
  };
1161
- const REUPLOAD_REQUIRED_STATUS = [410, 404];
1199
+ const REUPLOAD_REQUIRED_STATUS = [403, 404, 410];
1162
1200
  /**
1163
1201
  * Downloads the given message. Throws an error if it's not a media message
1164
1202
  */
1165
1203
  export const downloadMediaMessage = async (message, type, options, ctx) => {
1166
1204
  const result = await downloadMsg().catch(async (error) => {
1205
+ const status = error?.output?.statusCode ?? error?.status;
1167
1206
  if (
1168
1207
  ctx &&
1169
- typeof error?.status === "number" && // treat errors with status as HTTP failures requiring reupload
1170
- REUPLOAD_REQUIRED_STATUS.includes(error.status)
1208
+ typeof status === "number" && // treat errors with status as HTTP failures requiring reupload
1209
+ REUPLOAD_REQUIRED_STATUS.includes(status)
1171
1210
  ) {
1172
1211
  ctx.logger.info(
1173
1212
  { key: message.key },
@@ -1192,12 +1231,18 @@ export const downloadMediaMessage = async (message, type, options, ctx) => {
1192
1231
  if (
1193
1232
  !media ||
1194
1233
  typeof media !== "object" ||
1195
- (!("url" in media) && !("thumbnailDirectPath" in media))
1234
+ (!("url" in media) &&
1235
+ !("directPath" in media) &&
1236
+ !("thumbnailDirectPath" in media))
1196
1237
  ) {
1197
1238
  throw new Boom(`"${contentType}" message is not a media message`);
1198
1239
  }
1199
1240
  let download;
1200
- if ("thumbnailDirectPath" in media && !("url" in media)) {
1241
+ if (
1242
+ "thumbnailDirectPath" in media &&
1243
+ !("url" in media) &&
1244
+ !("directPath" in media)
1245
+ ) {
1201
1246
  download = {
1202
1247
  directPath: media.thumbnailDirectPath,
1203
1248
  mediaKey: media.mediaKey,
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/noise-handler */
1
2
  import { proto } from '../../WAProto/index.js';
2
3
  import type { KeyPair } from '../Types/index.js';
3
4
  import type { BinaryNode } from '../WABinary/index.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/noise-handler */
1
2
  import { Boom } from '@hapi/boom';
2
3
  import { proto } from '../../WAProto/index.js';
3
4
  import { NOISE_MODE, WA_CERT_DETAILS } from '../Defaults/index.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/offline-node-processor */
1
2
  import type { BinaryNode } from '../WABinary/index.js';
2
3
  export type MessageType = 'message' | 'call' | 'receipt' | 'notification';
3
4
  export type OfflineNodeProcessorDeps = {
@@ -5,6 +6,7 @@ export type OfflineNodeProcessorDeps = {
5
6
  onUnexpectedError: (error: Error, msg: string) => void;
6
7
  yieldToEventLoop: () => Promise<void>;
7
8
  };
9
+ export declare const isOfflineNode: (node: BinaryNode) => boolean;
8
10
  /**
9
11
  * Creates a processor for offline stanza nodes that:
10
12
  * - Queues nodes for sequential processing
@@ -1,3 +1,9 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/offline-node-processor */
2
+ /**
3
+ * Determines whether a binary stanza was queued on the server while the client was offline.
4
+ * WhatsApp sets `offline="1"` for queued stanzas and `offline="0"` for live stanzas.
5
+ */
6
+ export const isOfflineNode = (node) => node?.attrs?.offline === '1';
1
7
  /**
2
8
  * Creates a processor for offline stanza nodes that:
3
9
  * - Queues nodes for sequential processing
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/platform-identity */
1
2
  import type { WABrowserDescription } from '../Types/index.js';
2
3
  export declare const PAIRING_ACCEPTED_OS: readonly string[];
3
4
  export declare const PAIRING_OS_FALLBACK: Readonly<Record<string, string>>;
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/platform-identity */
1
2
  // BibzWhats — identitas platform companion (apa yang WhatsApp "lihat" dari library ini)
2
3
  //
3
4
  // Tiga tempat identitas dipakai, dan ketiganya berbeda aturannya:
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/pre-key-manager */
1
2
  import type { SignalDataSet, SignalDataTypeMap, SignalKeyStore } from '../Types/index.js';
2
3
  import type { ILogger } from './logger.js';
3
4
  /**
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/pre-key-manager */
1
2
  import PQueue from 'p-queue';
2
3
  /**
3
4
  * Manages pre-key operations with proper concurrency control
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/process-message */
1
2
  import { proto } from '../../WAProto/index.js';
2
3
  import type { AuthenticationCreds, BaileysEventEmitter, CacheStore, SignalKeyStoreWithTransaction, SignalRepositoryWithLIDStore, SocketConfig, WAMessage, WAMessageKey } from '../Types/index.js';
3
4
  import type { ILogger } from './logger.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/process-message */
1
2
  import { proto } from '../../WAProto/index.js';
2
3
  import { WAMessageStubType } from '../Types/index.js';
3
4
  import { getContentType, normalizeMessageContent } from '../Utils/messages.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/reporting-utils */
1
2
  import { proto } from '../../WAProto/index.js';
2
3
  import type { WAMessageContent, WAMessageKey } from '../Types/index.js';
3
4
  import type { BinaryNode } from '../WABinary/index.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/reporting-utils */
1
2
  import { createHmac } from 'crypto';
2
3
  import { proto } from '../../WAProto/index.js';
3
4
  import { hkdf } from './crypto.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/rich-messages */
1
2
  import { proto } from "../../WAProto/index.js";
2
3
  export declare const JS_KEYWORDS: Set<string>;
3
4
  export declare const PYTHON_KEYWORDS: Set<string>;
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/rich-messages */
1
2
  import { proto } from "../../WAProto/index.js";
2
3
  import { generateMessageIDV2 } from "./generics.js";
3
4
  import { randomBytes, randomUUID } from "crypto";
@@ -544,6 +545,16 @@ export const captureUnifiedResponse = (msg) => {
544
545
  };
545
546
  };
546
547
  export const generateUnifiedResponseContent = (quoted, captured) => {
548
+ if (
549
+ !captured ||
550
+ !Array.isArray(captured.submessages) ||
551
+ !captured.unifiedResponse?.data
552
+ ) {
553
+ throw new TypeError(
554
+ 'captured wajib berupa hasil captureUnifiedResponse(msg) yang berisi ' +
555
+ 'unifiedResponse.data — contoh: sock.sendUnifiedResponse(jid, quoted, captureUnifiedResponse(m.message))',
556
+ );
557
+ }
547
558
  const ctxInfo = buildRichContextInfo(quoted);
548
559
  return {
549
560
  message: buildBotForwardedMessage(
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/signal */
1
2
  import type { SignalRepositoryWithLIDStore } from '../Types/index.js';
2
3
  import type { AuthenticationCreds, AuthenticationState, KeyPair, SignalIdentity, SignalKeyStore, SignedKeyPair } from '../Types/Auth.js';
3
4
  import { type BinaryNode, type FullJid } from '../WABinary/index.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/signal */
1
2
  import { KEY_BUNDLE_TYPE } from '../Defaults/index.js';
2
3
  import { assertNodeErrorFree, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildren, getBinaryNodeChildUInt, getServerFromDomainType, jidDecode, S_WHATSAPP_NET, WAJIDDomains } from '../WABinary/index.js';
3
4
  import { Curve, generateSignalPubKey } from './crypto.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/stanza-ack */
1
2
  import type { BinaryNode } from '../WABinary/index.js';
2
3
  /**
3
4
  * Builds an ACK stanza for a received node.
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/stanza-ack */
1
2
  /**
2
3
  * Builds an ACK stanza for a received node.
3
4
  * Pure function -- no I/O, no side effects.
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/sticker-pack */
1
2
  import type { StickerPackContent } from '../Types/Message.js';
2
3
  export type MakeStickerPackOptions = StickerPackContent & {
3
4
  contextInfo?: any;
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/sticker-pack */
1
2
  /**
2
3
  * Default emojis assigned to stickers when none are provided.
3
4
  * Rotates through this list by sticker index.
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/sync-action-utils */
1
2
  import { proto } from '../../WAProto/index.js';
2
3
  import type { BaileysEventEmitter, BaileysEventMap, Contact } from '../Types/index.js';
3
4
  import type { ILogger } from './logger.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/sync-action-utils */
1
2
  import { proto } from '../../WAProto/index.js';
2
3
  import { isLidUser, isPnUser } from '../WABinary/index.js';
3
4
  /**
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/tc-token-utils */
1
2
  import type { AuthenticationState } from '../Types/index.js';
2
3
  import type { BinaryNode } from '../WABinary/index.js';
3
4
  export declare function isTcTokenExpired(timestamp: number | string | null | undefined): boolean;
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/tc-token-utils */
1
2
  const TC_TOKEN_BUCKET_DURATION = 604800; // 7 hari
2
3
  const TC_TOKEN_NUM_BUCKETS = 4; // jendela bergulir ~28 hari
3
4
  /** true bila timestamp (detik unix) token sudah di luar jendela ~28 hari WA Web */
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/use-multi-file-auth-state */
1
2
  import type { AuthenticationState } from '../Types/index.js';
2
3
  /**
3
4
  * stores the full authentication state in a single folder.
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/use-multi-file-auth-state */
1
2
  import { Mutex } from 'async-mutex';
2
3
  import { mkdir, readFile, stat, unlink, writeFile } from 'fs/promises';
3
4
  import { join } from 'path';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/validate-connection */
1
2
  import { proto } from '../../WAProto/index.js';
2
3
  import type { AuthenticationCreds, SignalCreds, SocketConfig } from '../Types/index.js';
3
4
  import { type BinaryNode } from '../WABinary/index.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/Utils/validate-connection */
1
2
  import { Boom } from '@hapi/boom';
2
3
  import { createHash } from 'crypto';
3
4
  import { proto } from '../../WAProto/index.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/audio-feeder */
1
2
  export declare class AudioFeeder {
2
3
  #private;
3
4
  private readonly sampleRate;
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/audio-feeder */
1
2
  /**
2
3
  * Audio feeder.
3
4
  *
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/index */
1
2
  // Deklarasi minimal (upstream tidak menyertakan tipe untuk modul ini).
2
3
  import { EventEmitter } from 'events';
3
4
  export { CallState } from './types.js';
package/lib/VoIP/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/index */
1
2
  import { EventEmitter } from "node:events";
2
3
  import { randomBytes, createHmac } from "node:crypto";
3
4
 
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/relay-transport */
1
2
  type RelayAddress = {
2
3
  protocol: number;
3
4
  ipv4?: string;
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/relay-transport */
1
2
  /**
2
3
  * Relay transport.
3
4
  *
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/signaling */
1
2
  import { decodeBinaryNode } from '../WABinary/decode.js';
2
3
  import { encodeBinaryNode } from '../WABinary/encode.js';
3
4
  import { getBinaryNodeChild, getAllBinaryNodeChildren } from '../WABinary/generic-utils.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/types */
1
2
  /**
2
3
  * Shared type definitions for BibzWhats VoIP.
3
4
  *
package/lib/VoIP/types.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/types */
1
2
  /**
2
3
  * Shared type definitions for BibzWhats VoIP.
3
4
  *
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/wasm-engine */
1
2
  export type WasmAudioConfig = {
2
3
  sampleRate: number;
3
4
  channels: number;
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/wasm-engine */
1
2
  var _a;
2
3
  /**
3
4
  * WhatsApp VoIP WASM engine.
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/VoIP/worker-bootstrap */
1
2
  /**
2
3
  * Worker-thread bootstrap for the WhatsApp WASM VoIP engine.
3
4
  *
@@ -344,7 +345,7 @@ global.importScripts = function (...urls) {
344
345
  for (const url of urls) {
345
346
  try {
346
347
  const code = fs.readFileSync(url, "utf8");
347
- eval(code);
348
+ vm.runInThisContext(code);
348
349
  }
349
350
  catch (e) { }
350
351
  }
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/WABinary/constants */
1
2
  export declare const TAGS: {
2
3
  LIST_EMPTY: number;
3
4
  DICTIONARY_0: number;
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/WABinary/constants */
1
2
  export const TAGS = {
2
3
  LIST_EMPTY: 0,
3
4
  DICTIONARY_0: 236,
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/WABinary/decode */
1
2
  import type { BinaryNode, BinaryNodeCodingOptions } from './types.js';
2
3
  export declare const decompressingIfRequired: (buffer: Buffer) => Promise<Buffer>;
3
4
  export declare const decodeDecompressedBinaryNode: (buffer: Buffer, opts: Pick<BinaryNodeCodingOptions, "DOUBLE_BYTE_TOKENS" | "SINGLE_BYTE_TOKENS" | "TAGS">, indexRef?: {
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/WABinary/decode */
1
2
  import { promisify } from 'util';
2
3
  import { inflate } from 'zlib';
3
4
  import * as constants from './constants.js';
@@ -1,2 +1,3 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/WABinary/encode */
1
2
  import type { BinaryNode, BinaryNodeCodingOptions } from './types.js';
2
3
  export declare const encodeBinaryNode: (node: BinaryNode, opts?: Pick<BinaryNodeCodingOptions, "TAGS" | "TOKEN_MAP">, buffer?: number[]) => Buffer;
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/WABinary/encode */
1
2
  import * as constants from './constants.js';
2
3
  import { jidDecode } from './jid-utils.js';
3
4
  export const encodeBinaryNode = (node, opts = constants, buffer = [0]) => {
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/WABinary/generic-utils */
1
2
  import { proto } from '../../WAProto/index.js';
2
3
  import { type BinaryNode } from './types.js';
3
4
  export declare const getBinaryNodeChildren: (node: BinaryNode | undefined, childTag: string) => BinaryNode[];
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/WABinary/generic-utils */
1
2
  import { Boom } from '@hapi/boom';
2
3
  import { proto } from '../../WAProto/index.js';
3
4
  import { unixTimestampSeconds } from '../Utils/generics.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/WABinary/index */
1
2
  export * from './encode.js';
2
3
  export * from './decode.js';
3
4
  export * from './generic-utils.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/WABinary/index */
1
2
  export * from './encode.js';
2
3
  export * from './decode.js';
3
4
  export * from './generic-utils.js';
@@ -1,3 +1,4 @@
1
+ /** @module @xbibzlibrary/whatsbibz/lib/WABinary/jid-utils */
1
2
  export declare const S_WHATSAPP_NET = "@s.whatsapp.net";
2
3
  export declare const OFFICIAL_BIZ_JID = "16505361212@c.us";
3
4
  export declare const SERVER_JID = "server@c.us";