ruby-baileys 0.0.0-stage → 1.5.17

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 (296) hide show
  1. package/EXPERIMENTAL.md +350 -0
  2. package/LICENSE +23 -0
  3. package/NOTICE.md +14 -0
  4. package/README.md +6265 -2
  5. package/WAProto/GenerateStatics.sh +3 -0
  6. package/WAProto/WAProto.proto +5479 -0
  7. package/WAProto/fix-imports.js +81 -0
  8. package/WAProto/index.d.ts +16877 -0
  9. package/WAProto/index.js +122159 -0
  10. package/assets/ruby_aspirant.jpg +0 -0
  11. package/assets/ruby_aspirant_4k.jpg +88 -0
  12. package/assets/ruby_aspirant_full.jpg +0 -0
  13. package/assets/ruby_aspirant_render.png +1 -0
  14. package/assets/ruby_aspirants_hd.jpg +0 -0
  15. package/assets/thumb.jpg +0 -0
  16. package/engine-requirements.js +14 -0
  17. package/index.cjs +29 -0
  18. package/index.d.ts +2 -0
  19. package/package.json +178 -4
  20. package/src/Defaults/index.d.ts +153 -0
  21. package/src/Defaults/index.js +165 -0
  22. package/src/MessageBuilder/bot-signature.d.ts +22 -0
  23. package/src/MessageBuilder/bot-signature.js +123 -0
  24. package/src/MessageBuilder/extras.d.ts +396 -0
  25. package/src/MessageBuilder/extras.js +1229 -0
  26. package/src/MessageBuilder/index.d.ts +210 -0
  27. package/src/MessageBuilder/index.js +3521 -0
  28. package/src/MessageBuilder/metaai.d.ts +438 -0
  29. package/src/MessageBuilder/metaai.js +891 -0
  30. package/src/Signal/Group/ciphertext-message.d.ts +10 -0
  31. package/src/Signal/Group/ciphertext-message.js +12 -0
  32. package/src/Signal/Group/group-session-builder.d.ts +8 -0
  33. package/src/Signal/Group/group-session-builder.js +28 -0
  34. package/src/Signal/Group/group_cipher.d.ts +11 -0
  35. package/src/Signal/Group/group_cipher.js +79 -0
  36. package/src/Signal/Group/index.d.ts +12 -0
  37. package/src/Signal/Group/index.js +12 -0
  38. package/src/Signal/Group/keyhelper.d.ts +7 -0
  39. package/src/Signal/Group/keyhelper.js +18 -0
  40. package/src/Signal/Group/sender-chain-key.d.ts +14 -0
  41. package/src/Signal/Group/sender-chain-key.js +26 -0
  42. package/src/Signal/Group/sender-key-distribution-message.d.ts +17 -0
  43. package/src/Signal/Group/sender-key-distribution-message.js +63 -0
  44. package/src/Signal/Group/sender-key-message.d.ts +19 -0
  45. package/src/Signal/Group/sender-key-message.js +66 -0
  46. package/src/Signal/Group/sender-key-name.d.ts +12 -0
  47. package/src/Signal/Group/sender-key-name.js +48 -0
  48. package/src/Signal/Group/sender-key-record.d.ts +13 -0
  49. package/src/Signal/Group/sender-key-record.js +41 -0
  50. package/src/Signal/Group/sender-key-state.d.ts +17 -0
  51. package/src/Signal/Group/sender-key-state.js +84 -0
  52. package/src/Signal/Group/sender-message-key.d.ts +12 -0
  53. package/src/Signal/Group/sender-message-key.js +26 -0
  54. package/src/Signal/libsignal.d.ts +55 -0
  55. package/src/Signal/libsignal.js +429 -0
  56. package/src/Signal/lid-mapping.d.ts +21 -0
  57. package/src/Signal/lid-mapping.js +275 -0
  58. package/src/Socket/Client/index.d.ts +3 -0
  59. package/src/Socket/Client/index.js +3 -0
  60. package/src/Socket/Client/types.d.ts +6 -0
  61. package/src/Socket/Client/types.js +10 -0
  62. package/src/Socket/Client/websocket.d.ts +13 -0
  63. package/src/Socket/Client/websocket.js +54 -0
  64. package/src/Socket/business.d.ts +432 -0
  65. package/src/Socket/business.js +380 -0
  66. package/src/Socket/chats.d.ts +248 -0
  67. package/src/Socket/chats.js +1485 -0
  68. package/src/Socket/communities.d.ts +599 -0
  69. package/src/Socket/communities.js +422 -0
  70. package/src/Socket/groups.d.ts +299 -0
  71. package/src/Socket/groups.js +340 -0
  72. package/src/Socket/index.d.ts +582 -0
  73. package/src/Socket/index.js +48 -0
  74. package/src/Socket/messages-recv.d.ts +371 -0
  75. package/src/Socket/messages-recv.js +1803 -0
  76. package/src/Socket/messages-send.d.ts +391 -0
  77. package/src/Socket/messages-send.js +1575 -0
  78. package/src/Socket/mex.d.ts +2 -0
  79. package/src/Socket/mex.js +45 -0
  80. package/src/Socket/newsletter.d.ts +469 -0
  81. package/src/Socket/newsletter.js +643 -0
  82. package/src/Socket/socket.d.ts +78 -0
  83. package/src/Socket/socket.js +1088 -0
  84. package/src/Store/index.d.ts +4 -0
  85. package/src/Store/index.js +4 -0
  86. package/src/Store/make-in-memory-store.d.ts +63 -0
  87. package/src/Store/make-in-memory-store.js +398 -0
  88. package/src/Store/make-ordered-dictionary.d.ts +13 -0
  89. package/src/Store/make-ordered-dictionary.js +79 -0
  90. package/src/Store/object-repository.d.ts +11 -0
  91. package/src/Store/object-repository.js +24 -0
  92. package/src/Types/Auth.d.ts +2 -0
  93. package/src/Types/Auth.js +2 -0
  94. package/src/Types/Bussines.d.ts +2 -0
  95. package/src/Types/Bussines.js +2 -0
  96. package/src/Types/Call.d.ts +2 -0
  97. package/src/Types/Call.js +2 -0
  98. package/src/Types/Chat.d.ts +3 -0
  99. package/src/Types/Chat.js +25 -0
  100. package/src/Types/Contact.d.ts +2 -0
  101. package/src/Types/Contact.js +2 -0
  102. package/src/Types/Events.d.ts +2 -0
  103. package/src/Types/Events.js +1 -0
  104. package/src/Types/GroupMetadata.d.ts +6 -0
  105. package/src/Types/GroupMetadata.js +7 -0
  106. package/src/Types/Label.d.ts +3 -0
  107. package/src/Types/Label.js +25 -0
  108. package/src/Types/LabelAssociation.d.ts +3 -0
  109. package/src/Types/LabelAssociation.js +7 -0
  110. package/src/Types/Message.d.ts +14 -0
  111. package/src/Types/Message.js +24 -0
  112. package/src/Types/Mex.d.ts +3 -0
  113. package/src/Types/Mex.js +96 -0
  114. package/src/Types/Product.d.ts +2 -0
  115. package/src/Types/Product.js +2 -0
  116. package/src/Types/Signal.d.ts +2 -0
  117. package/src/Types/Signal.js +1 -0
  118. package/src/Types/Socket.d.ts +2 -0
  119. package/src/Types/Socket.js +1 -0
  120. package/src/Types/State.d.ts +6 -0
  121. package/src/Types/State.js +55 -0
  122. package/src/Types/USync.d.ts +2 -0
  123. package/src/Types/USync.js +1 -0
  124. package/src/Types/index.d.ts +14 -0
  125. package/src/Types/index.js +26 -0
  126. package/src/Utils/auth-store.d.ts +30 -0
  127. package/src/Utils/auth-store.js +77 -0
  128. package/src/Utils/auth-utils.d.ts +59 -0
  129. package/src/Utils/auth-utils.js +274 -0
  130. package/src/Utils/browser-utils.d.ts +10 -0
  131. package/src/Utils/browser-utils.js +29 -0
  132. package/src/Utils/business.d.ts +50 -0
  133. package/src/Utils/business.js +227 -0
  134. package/src/Utils/chat-utils.d.ts +409 -0
  135. package/src/Utils/chat-utils.js +847 -0
  136. package/src/Utils/companion-reg-client-utils.d.ts +5 -0
  137. package/src/Utils/companion-reg-client-utils.js +40 -0
  138. package/src/Utils/crypto.d.ts +40 -0
  139. package/src/Utils/crypto.js +111 -0
  140. package/src/Utils/decode-wa-message.d.ts +100 -0
  141. package/src/Utils/decode-wa-message.js +374 -0
  142. package/src/Utils/event-buffer.d.ts +23 -0
  143. package/src/Utils/event-buffer.js +625 -0
  144. package/src/Utils/generics.d.ts +64 -0
  145. package/src/Utils/generics.js +376 -0
  146. package/src/Utils/group-metadata-cache.d.ts +5 -0
  147. package/src/Utils/group-metadata-cache.js +26 -0
  148. package/src/Utils/history.d.ts +76 -0
  149. package/src/Utils/history.js +132 -0
  150. package/src/Utils/html-app.d.ts +19 -0
  151. package/src/Utils/html-app.js +97 -0
  152. package/src/Utils/html-multiplayer.d.ts +10 -0
  153. package/src/Utils/html-multiplayer.js +95 -0
  154. package/src/Utils/identity-change-handler.d.ts +14 -0
  155. package/src/Utils/identity-change-handler.js +49 -0
  156. package/src/Utils/index.d.ts +45 -0
  157. package/src/Utils/index.js +45 -0
  158. package/src/Utils/link-preview-metadata.d.ts +47 -0
  159. package/src/Utils/link-preview-metadata.js +89 -0
  160. package/src/Utils/link-preview.d.ts +13 -0
  161. package/src/Utils/link-preview.js +80 -0
  162. package/src/Utils/logger.d.ts +3 -0
  163. package/src/Utils/logger.js +3 -0
  164. package/src/Utils/lt-hash.d.ts +7 -0
  165. package/src/Utils/lt-hash.js +4 -0
  166. package/src/Utils/make-mutex.d.ts +7 -0
  167. package/src/Utils/make-mutex.js +33 -0
  168. package/src/Utils/message-retry-manager.d.ts +80 -0
  169. package/src/Utils/message-retry-manager.js +256 -0
  170. package/src/Utils/messages-media.d.ts +137 -0
  171. package/src/Utils/messages-media.js +815 -0
  172. package/src/Utils/messages.d.ts +63 -0
  173. package/src/Utils/messages.js +2149 -0
  174. package/src/Utils/modern-messages.d.ts +150 -0
  175. package/src/Utils/modern-messages.js +496 -0
  176. package/src/Utils/native-flow.d.ts +11 -0
  177. package/src/Utils/native-flow.js +116 -0
  178. package/src/Utils/newsletter-status.d.ts +158 -0
  179. package/src/Utils/newsletter-status.js +651 -0
  180. package/src/Utils/noise-handler.d.ts +21 -0
  181. package/src/Utils/noise-handler.js +201 -0
  182. package/src/Utils/offline-node-processor.d.ts +10 -0
  183. package/src/Utils/offline-node-processor.js +34 -0
  184. package/src/Utils/optional-media.d.ts +3 -0
  185. package/src/Utils/optional-media.js +46 -0
  186. package/src/Utils/payment-messages.d.ts +66 -0
  187. package/src/Utils/payment-messages.js +161 -0
  188. package/src/Utils/pre-key-manager.d.ts +26 -0
  189. package/src/Utils/pre-key-manager.js +96 -0
  190. package/src/Utils/process-message.d.ts +61 -0
  191. package/src/Utils/process-message.js +689 -0
  192. package/src/Utils/reporting-utils.d.ts +13 -0
  193. package/src/Utils/reporting-utils.js +257 -0
  194. package/src/Utils/scheduled-message.d.ts +51 -0
  195. package/src/Utils/scheduled-message.js +113 -0
  196. package/src/Utils/sender-key-memory.d.ts +20 -0
  197. package/src/Utils/sender-key-memory.js +52 -0
  198. package/src/Utils/signal.d.ts +83 -0
  199. package/src/Utils/signal.js +194 -0
  200. package/src/Utils/stanza-ack.d.ts +17 -0
  201. package/src/Utils/stanza-ack.js +31 -0
  202. package/src/Utils/status-stickers.d.ts +127 -0
  203. package/src/Utils/status-stickers.js +261 -0
  204. package/src/Utils/sync-action-utils.d.ts +3 -0
  205. package/src/Utils/sync-action-utils.js +45 -0
  206. package/src/Utils/tc-token-utils.d.ts +30 -0
  207. package/src/Utils/tc-token-utils.js +156 -0
  208. package/src/Utils/ttl-cache.d.ts +29 -0
  209. package/src/Utils/ttl-cache.js +121 -0
  210. package/src/Utils/use-mongo-auth-state.d.ts +22 -0
  211. package/src/Utils/use-mongo-auth-state.js +68 -0
  212. package/src/Utils/use-multi-file-auth-state.d.ts +12 -0
  213. package/src/Utils/use-multi-file-auth-state.js +107 -0
  214. package/src/Utils/use-mysql-auth-state.d.ts +20 -0
  215. package/src/Utils/use-mysql-auth-state.js +80 -0
  216. package/src/Utils/use-postgres-auth-state.d.ts +20 -0
  217. package/src/Utils/use-postgres-auth-state.js +80 -0
  218. package/src/Utils/use-redis-auth-state.d.ts +20 -0
  219. package/src/Utils/use-redis-auth-state.js +90 -0
  220. package/src/Utils/use-single-file-auth-state.d.ts +11 -0
  221. package/src/Utils/use-single-file-auth-state.js +109 -0
  222. package/src/Utils/use-sqlite-auth-state.d.ts +13 -0
  223. package/src/Utils/use-sqlite-auth-state.js +121 -0
  224. package/src/Utils/useNekoDBAuth.d.ts +19 -0
  225. package/src/Utils/useNekoDBAuth.js +111 -0
  226. package/src/Utils/username.d.ts +12 -0
  227. package/src/Utils/username.js +59 -0
  228. package/src/Utils/validate-connection.d.ts +44 -0
  229. package/src/Utils/validate-connection.js +208 -0
  230. package/src/Utils/voice-recognition.d.ts +53 -0
  231. package/src/Utils/voice-recognition.js +219 -0
  232. package/src/Voip/audio-feeder.d.ts +25 -0
  233. package/src/Voip/audio-feeder.js +269 -0
  234. package/src/Voip/index.d.ts +89 -0
  235. package/src/Voip/index.js +937 -0
  236. package/src/Voip/relay-transport.d.ts +6 -0
  237. package/src/Voip/relay-transport.js +825 -0
  238. package/src/Voip/signaling.d.ts +12 -0
  239. package/src/Voip/signaling.js +1100 -0
  240. package/src/Voip/types.d.ts +3 -0
  241. package/src/Voip/types.js +13 -0
  242. package/src/Voip/video-feeder.d.ts +25 -0
  243. package/src/Voip/video-feeder.js +269 -0
  244. package/src/Voip/wasm-engine.d.ts +27 -0
  245. package/src/Voip/wasm-engine.js +1308 -0
  246. package/src/Voip/worker-bootstrap.js +1024 -0
  247. package/src/WABinary/constants.d.ts +23 -0
  248. package/src/WABinary/constants.js +1301 -0
  249. package/src/WABinary/decode.d.ts +10 -0
  250. package/src/WABinary/decode.js +262 -0
  251. package/src/WABinary/encode.d.ts +3 -0
  252. package/src/WABinary/encode.js +220 -0
  253. package/src/WABinary/generic-utils.d.ts +77 -0
  254. package/src/WABinary/generic-utils.js +214 -0
  255. package/src/WABinary/index.d.ts +6 -0
  256. package/src/WABinary/index.js +6 -0
  257. package/src/WABinary/jid-utils.d.ts +31 -0
  258. package/src/WABinary/jid-utils.js +98 -0
  259. package/src/WABinary/types.d.ts +2 -0
  260. package/src/WABinary/types.js +1 -0
  261. package/src/WAM/BinaryInfo.d.ts +8 -0
  262. package/src/WAM/BinaryInfo.js +10 -0
  263. package/src/WAM/constants.d.ts +34927 -0
  264. package/src/WAM/constants.js +22853 -0
  265. package/src/WAM/encode.d.ts +2 -0
  266. package/src/WAM/encode.js +149 -0
  267. package/src/WAM/index.d.ts +4 -0
  268. package/src/WAM/index.js +4 -0
  269. package/src/WAUSync/Protocols/USyncContactProtocol.d.ts +37 -0
  270. package/src/WAUSync/Protocols/USyncContactProtocol.js +51 -0
  271. package/src/WAUSync/Protocols/USyncDeviceProtocol.d.ts +23 -0
  272. package/src/WAUSync/Protocols/USyncDeviceProtocol.js +52 -0
  273. package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +13 -0
  274. package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
  275. package/src/WAUSync/Protocols/USyncStatusProtocol.d.ts +13 -0
  276. package/src/WAUSync/Protocols/USyncStatusProtocol.js +38 -0
  277. package/src/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
  278. package/src/WAUSync/Protocols/USyncUsernameProtocol.js +24 -0
  279. package/src/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +39 -0
  280. package/src/WAUSync/Protocols/UsyncBotProfileProtocol.js +50 -0
  281. package/src/WAUSync/Protocols/UsyncLIDProtocol.d.ts +15 -0
  282. package/src/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
  283. package/src/WAUSync/Protocols/index.d.ts +6 -0
  284. package/src/WAUSync/Protocols/index.js +6 -0
  285. package/src/WAUSync/USyncQuery.d.ts +21 -0
  286. package/src/WAUSync/USyncQuery.js +94 -0
  287. package/src/WAUSync/USyncUser.d.ts +17 -0
  288. package/src/WAUSync/USyncUser.js +31 -0
  289. package/src/WAUSync/index.d.ts +4 -0
  290. package/src/WAUSync/index.js +4 -0
  291. package/src/assets/wasm/README.md +76 -0
  292. package/src/assets/wasm/loader.js +5 -0
  293. package/src/assets/wasm/whatsapp.wasm +0 -0
  294. package/src/assets/wasm/worker-modules.js +273 -0
  295. package/src/index.d.ts +49 -0
  296. package/src/index.js +54 -0
@@ -0,0 +1,23 @@
1
+ /* Elaina Baileys maintained distribution. Upstream notices and license are preserved in LICENSE and NOTICE.md. */
2
+ export const DEFAULT_MAX_EVENT_LISTENERS: number;
3
+ export function makeEventBuffer(logger: any, maxListeners?: number): {
4
+ process(handler: any): () => void;
5
+ emit(event: any, evData: any): any;
6
+ isBuffering(): boolean;
7
+ buffer: () => void;
8
+ flush: () => boolean;
9
+ createBufferedFunction(work: any): (...args: any[]) => Promise<any>;
10
+ on: (...args: any[]) => any;
11
+ off: (...args: any[]) => any;
12
+ removeAllListeners: (...args: any[]) => any;
13
+ once: (...args: any[]) => any;
14
+ addListener: (...args: any[]) => any;
15
+ removeListener: (...args: any[]) => any;
16
+ listeners: (...args: any[]) => Function[];
17
+ rawListeners: (...args: any[]) => Function[];
18
+ eventNames: () => (string | symbol)[];
19
+ setMaxListeners: (count: number) => any;
20
+ getMaxListeners: () => number;
21
+ listenerCount: (...args: any[]) => number;
22
+ destroy(): void;
23
+ };
@@ -0,0 +1,625 @@
1
+ /* Elaina Baileys maintained distribution. Upstream notices and license are preserved in LICENSE and NOTICE.md. */
2
+ import EventEmitter from 'events';
3
+ import { WAMessageStatus } from '../Types/index.js';
4
+ import { trimUndefined } from './generics.js';
5
+ import { updateMessageWithReaction, updateMessageWithReceipt } from './messages.js';
6
+ import { isRealMessage, shouldIncrementChatUnread } from './process-message.js';
7
+ const BUFFERABLE_EVENT = [
8
+ 'messaging-history.set',
9
+ 'chats.upsert',
10
+ 'chats.update',
11
+ 'chats.delete',
12
+ 'contacts.upsert',
13
+ 'contacts.update',
14
+ 'messages.upsert',
15
+ 'messages.update',
16
+ 'messages.delete',
17
+ 'messages.reaction',
18
+ 'message-receipt.update',
19
+ 'groups.update'
20
+ ];
21
+ const BUFFERABLE_EVENT_SET = new Set(BUFFERABLE_EVENT);
22
+
23
+ export const DEFAULT_MAX_EVENT_LISTENERS = 64;
24
+
25
+ export const makeEventBuffer = (logger, maxListeners = DEFAULT_MAX_EVENT_LISTENERS) => {
26
+ const ev = new EventEmitter();
27
+ ev.setMaxListeners(Number.isFinite(maxListeners) && maxListeners >= 0 ? maxListeners : DEFAULT_MAX_EVENT_LISTENERS);
28
+ const historyCache = new Set();
29
+ let data = makeBufferData();
30
+ let isBuffering = false;
31
+ let bufferTimeout = null;
32
+ let flushPendingTimeout = null;
33
+ let bufferCount = 0;
34
+ const MAX_HISTORY_CACHE_SIZE = 10000;
35
+ const BUFFER_TIMEOUT_MS = 30000;
36
+
37
+ ev.on('event', (map) => {
38
+ for (const event in map) {
39
+ ev.emit(event, map[event]);
40
+ }
41
+ });
42
+ function buffer() {
43
+ if (!isBuffering) {
44
+ logger.debug('Event buffer activated');
45
+ isBuffering = true;
46
+ bufferCount = 0;
47
+ if (bufferTimeout) {
48
+ clearTimeout(bufferTimeout);
49
+ }
50
+ bufferTimeout = setTimeout(() => {
51
+ if (isBuffering) {
52
+ logger.warn('Buffer timeout reached, auto-flushing');
53
+ flush();
54
+ }
55
+ }, BUFFER_TIMEOUT_MS);
56
+ }
57
+
58
+ bufferCount++;
59
+ }
60
+ function flush() {
61
+ if (!isBuffering) {
62
+ return false;
63
+ }
64
+ logger.debug({ bufferCount }, 'Flushing event buffer');
65
+ isBuffering = false;
66
+ bufferCount = 0;
67
+
68
+ if (bufferTimeout) {
69
+ clearTimeout(bufferTimeout);
70
+ bufferTimeout = null;
71
+ }
72
+ if (flushPendingTimeout) {
73
+ clearTimeout(flushPendingTimeout);
74
+ flushPendingTimeout = null;
75
+ }
76
+
77
+ if (historyCache.size > MAX_HISTORY_CACHE_SIZE) {
78
+ logger.debug({ cacheSize: historyCache.size }, 'Clearing history cache');
79
+ historyCache.clear();
80
+ }
81
+ const newData = makeBufferData();
82
+ const chatUpdates = Object.values(data.chatUpdates);
83
+ let conditionalChatUpdatesLeft = 0;
84
+ for (const update of chatUpdates) {
85
+ if (update.conditional) {
86
+ conditionalChatUpdatesLeft += 1;
87
+ newData.chatUpdates[update.id] = update;
88
+ delete data.chatUpdates[update.id];
89
+ }
90
+ }
91
+ const consolidatedData = consolidateEvents(data);
92
+ if (Object.keys(consolidatedData).length) {
93
+ ev.emit('event', consolidatedData);
94
+ }
95
+ data = newData;
96
+ logger.trace({ conditionalChatUpdatesLeft }, 'released buffered events');
97
+ return true;
98
+ }
99
+ return {
100
+ process(handler) {
101
+ const listener = async (map) => {
102
+ await handler(map);
103
+ };
104
+ ev.on('event', listener);
105
+ return () => {
106
+ ev.off('event', listener);
107
+ };
108
+ },
109
+ emit(event, evData) {
110
+
111
+ if (event === 'messages.upsert') {
112
+ const { type } = evData;
113
+ const existingUpserts = Object.values(data.messageUpserts);
114
+ if (existingUpserts.length > 0) {
115
+ const bufferedType = existingUpserts[0].type;
116
+ if (bufferedType !== type) {
117
+ logger.debug({ bufferedType, newType: type }, 'messages.upsert type mismatch, emitting buffered messages');
118
+
119
+ ev.emit('event', {
120
+ 'messages.upsert': {
121
+ messages: existingUpserts.map(m => m.message),
122
+ type: bufferedType
123
+ }
124
+ });
125
+
126
+ data.messageUpserts = {};
127
+ }
128
+ }
129
+ }
130
+ if (isBuffering && BUFFERABLE_EVENT_SET.has(event)) {
131
+ append(data, historyCache, event, evData, logger);
132
+ return true;
133
+ }
134
+ return ev.emit('event', { [event]: evData });
135
+ },
136
+ isBuffering() {
137
+ return isBuffering;
138
+ },
139
+ buffer,
140
+ flush,
141
+ createBufferedFunction(work) {
142
+ return async (...args) => {
143
+ buffer();
144
+ try {
145
+ const result = await work(...args);
146
+
147
+ if (bufferCount === 1) {
148
+ setTimeout(() => {
149
+ if (isBuffering && bufferCount === 1) {
150
+ flush();
151
+ }
152
+ }, 100);
153
+ }
154
+ return result;
155
+ }
156
+ catch (error) {
157
+ throw error;
158
+ }
159
+ finally {
160
+ bufferCount = Math.max(0, bufferCount - 1);
161
+ if (bufferCount === 0) {
162
+
163
+ if (!flushPendingTimeout) {
164
+ flushPendingTimeout = setTimeout(flush, 100);
165
+ }
166
+ }
167
+ }
168
+ };
169
+ },
170
+ on: (...args) => ev.on(...args),
171
+ off: (...args) => ev.off(...args),
172
+ once: (...args) => ev.once(...args),
173
+ addListener: (...args) => ev.addListener(...args),
174
+ removeListener: (...args) => ev.removeListener(...args),
175
+ removeAllListeners: (...args) => ev.removeAllListeners(...args),
176
+ setMaxListeners: (count) => ev.setMaxListeners(count),
177
+ getMaxListeners: () => ev.getMaxListeners(),
178
+ listenerCount: (...args) => ev.listenerCount(...args),
179
+ listeners: (...args) => ev.listeners(...args),
180
+ rawListeners: (...args) => ev.rawListeners(...args),
181
+ eventNames: () => ev.eventNames(),
182
+ destroy() {
183
+
184
+ if (bufferTimeout) {
185
+ clearTimeout(bufferTimeout);
186
+ bufferTimeout = null;
187
+ }
188
+ if (flushPendingTimeout) {
189
+ clearTimeout(flushPendingTimeout);
190
+ flushPendingTimeout = null;
191
+ }
192
+
193
+ historyCache.clear();
194
+
195
+ data = makeBufferData();
196
+ isBuffering = false;
197
+ bufferCount = 0;
198
+
199
+ ev.removeAllListeners();
200
+ logger.debug('Event buffer destroyed');
201
+ }
202
+ };
203
+ };
204
+ const makeBufferData = () => {
205
+ return {
206
+ historySets: {
207
+ chats: {},
208
+ messages: {},
209
+ contacts: {},
210
+ isLatest: false,
211
+ empty: true
212
+ },
213
+ chatUpserts: {},
214
+ chatUpdates: {},
215
+ chatDeletes: new Set(),
216
+ contactUpserts: {},
217
+ contactUpdates: {},
218
+ messageUpserts: {},
219
+ messageUpdates: {},
220
+ messageReactions: {},
221
+ messageDeletes: {},
222
+ messageReceipts: {},
223
+ groupUpdates: {}
224
+ };
225
+ };
226
+ function append(data, historyCache, event,
227
+
228
+ eventData, logger) {
229
+ switch (event) {
230
+ case 'messaging-history.set':
231
+ for (const chat of eventData.chats) {
232
+ const id = chat.id || '';
233
+ const existingChat = data.historySets.chats[id];
234
+ if (existingChat) {
235
+ existingChat.endOfHistoryTransferType = chat.endOfHistoryTransferType;
236
+ }
237
+ if (!existingChat && !historyCache.has(id)) {
238
+ data.historySets.chats[id] = chat;
239
+ historyCache.add(id);
240
+ absorbingChatUpdate(chat);
241
+ }
242
+ }
243
+ for (const contact of eventData.contacts) {
244
+ const existingContact = data.historySets.contacts[contact.id];
245
+ if (existingContact) {
246
+ Object.assign(existingContact, trimUndefined(contact));
247
+ }
248
+ else {
249
+ const historyContactId = `c:${contact.id}`;
250
+ const hasAnyName = contact.notify || contact.name || contact.verifiedName;
251
+ if (!historyCache.has(historyContactId) || hasAnyName) {
252
+ data.historySets.contacts[contact.id] = contact;
253
+ historyCache.add(historyContactId);
254
+ }
255
+ }
256
+ }
257
+ for (const message of eventData.messages) {
258
+ const key = stringifyMessageKey(message.key);
259
+ const existingMsg = data.historySets.messages[key];
260
+ if (!existingMsg && !historyCache.has(key)) {
261
+ data.historySets.messages[key] = message;
262
+ historyCache.add(key);
263
+ }
264
+ }
265
+ data.historySets.empty = false;
266
+ data.historySets.syncType = eventData.syncType;
267
+ if (eventData.pastParticipants?.length) {
268
+ const merged = new Map();
269
+ const sigOf = (p) => `${p.userJid || ''}:${p.leaveTs || ''}:${p.leaveReason || ''}`;
270
+ const ingest = (entry) => {
271
+ const key = entry.groupJid ?? JSON.stringify(entry);
272
+ const existing = merged.get(key);
273
+ if (!existing) {
274
+ merged.set(key, { ...entry, pastParticipants: [...(entry.pastParticipants || [])] });
275
+ return;
276
+ }
277
+ const seen = new Set((existing.pastParticipants || []).map(sigOf));
278
+ for (const p of entry.pastParticipants || []) {
279
+ const sig = sigOf(p);
280
+ if (!seen.has(sig)) {
281
+ existing.pastParticipants.push(p);
282
+ seen.add(sig);
283
+ }
284
+ }
285
+ };
286
+ for (const entry of data.historySets.pastParticipants || [])
287
+ ingest(entry);
288
+ for (const entry of eventData.pastParticipants)
289
+ ingest(entry);
290
+ data.historySets.pastParticipants = [...merged.values()];
291
+ }
292
+ data.historySets.progress = eventData.progress;
293
+ data.historySets.chunkOrder = eventData.chunkOrder;
294
+ data.historySets.peerDataRequestSessionId = eventData.peerDataRequestSessionId;
295
+ data.historySets.isLatest = eventData.isLatest || data.historySets.isLatest;
296
+ break;
297
+ case 'chats.upsert':
298
+ for (const chat of eventData) {
299
+ const id = chat.id || '';
300
+ let upsert = data.chatUpserts[id];
301
+ if (id && !upsert) {
302
+ upsert = data.historySets.chats[id];
303
+ if (upsert) {
304
+ logger.debug({ chatId: id }, 'absorbed chat upsert in chat set');
305
+ }
306
+ }
307
+ if (upsert) {
308
+ upsert = concatChats(upsert, chat);
309
+ }
310
+ else {
311
+ upsert = chat;
312
+ data.chatUpserts[id] = upsert;
313
+ }
314
+ absorbingChatUpdate(upsert);
315
+ if (data.chatDeletes.has(id)) {
316
+ data.chatDeletes.delete(id);
317
+ }
318
+ }
319
+ break;
320
+ case 'chats.update':
321
+ for (const update of eventData) {
322
+ const chatId = update.id;
323
+ const conditionMatches = update.conditional ? update.conditional(data) : true;
324
+ if (conditionMatches) {
325
+ delete update.conditional;
326
+
327
+ const upsert = data.historySets.chats[chatId] || data.chatUpserts[chatId];
328
+ if (upsert) {
329
+ concatChats(upsert, update);
330
+ }
331
+ else {
332
+
333
+ const chatUpdate = data.chatUpdates[chatId] || {};
334
+ data.chatUpdates[chatId] = concatChats(chatUpdate, update);
335
+ }
336
+ }
337
+ else if (conditionMatches === undefined) {
338
+
339
+ data.chatUpdates[chatId] = update;
340
+ }
341
+
342
+ if (data.chatDeletes.has(chatId)) {
343
+ data.chatDeletes.delete(chatId);
344
+ }
345
+ }
346
+ break;
347
+ case 'chats.delete':
348
+ for (const chatId of eventData) {
349
+ if (!data.chatDeletes.has(chatId)) {
350
+ data.chatDeletes.add(chatId);
351
+ }
352
+
353
+ if (data.chatUpdates[chatId]) {
354
+ delete data.chatUpdates[chatId];
355
+ }
356
+ if (data.chatUpserts[chatId]) {
357
+ delete data.chatUpserts[chatId];
358
+ }
359
+ if (data.historySets.chats[chatId]) {
360
+ delete data.historySets.chats[chatId];
361
+ }
362
+ }
363
+ break;
364
+ case 'contacts.upsert':
365
+ for (const contact of eventData) {
366
+ let upsert = data.contactUpserts[contact.id];
367
+ if (!upsert) {
368
+ upsert = data.historySets.contacts[contact.id];
369
+ if (upsert) {
370
+ logger.debug({ contactId: contact.id }, 'absorbed contact upsert in contact set');
371
+ }
372
+ }
373
+ if (upsert) {
374
+ upsert = Object.assign(upsert, trimUndefined(contact));
375
+ }
376
+ else {
377
+ upsert = contact;
378
+ data.contactUpserts[contact.id] = upsert;
379
+ }
380
+ if (data.contactUpdates[contact.id]) {
381
+ upsert = Object.assign(data.contactUpdates[contact.id], trimUndefined(contact));
382
+ delete data.contactUpdates[contact.id];
383
+ }
384
+ }
385
+ break;
386
+ case 'contacts.update':
387
+ const contactUpdates = eventData;
388
+ for (const update of contactUpdates) {
389
+ const id = update.id;
390
+
391
+ const upsert = data.historySets.contacts[id] || data.contactUpserts[id];
392
+ if (upsert) {
393
+ Object.assign(upsert, update);
394
+ }
395
+ else {
396
+
397
+ const contactUpdate = data.contactUpdates[id] || {};
398
+ data.contactUpdates[id] = Object.assign(contactUpdate, update);
399
+ }
400
+ }
401
+ break;
402
+ case 'messages.upsert':
403
+ const { messages, type } = eventData;
404
+ for (const message of messages) {
405
+ const key = stringifyMessageKey(message.key);
406
+ let existing = data.messageUpserts[key]?.message;
407
+ if (!existing) {
408
+ existing = data.historySets.messages[key];
409
+ if (existing) {
410
+ logger.debug({ messageId: key }, 'absorbed message upsert in message set');
411
+ }
412
+ }
413
+ if (existing) {
414
+ message.messageTimestamp = existing.messageTimestamp;
415
+ }
416
+ if (data.messageUpdates[key]) {
417
+ logger.debug('absorbed prior message update in message upsert');
418
+ Object.assign(message, data.messageUpdates[key].update);
419
+ delete data.messageUpdates[key];
420
+ }
421
+ if (data.historySets.messages[key]) {
422
+ data.historySets.messages[key] = message;
423
+ }
424
+ else {
425
+ data.messageUpserts[key] = {
426
+ message,
427
+ type: type === 'notify' || data.messageUpserts[key]?.type === 'notify' ? 'notify' : type
428
+ };
429
+ }
430
+ }
431
+ break;
432
+ case 'messages.update':
433
+ const msgUpdates = eventData;
434
+ for (const { key, update } of msgUpdates) {
435
+ const keyStr = stringifyMessageKey(key);
436
+ const existing = data.historySets.messages[keyStr] || data.messageUpserts[keyStr]?.message;
437
+ if (existing) {
438
+ Object.assign(existing, update);
439
+
440
+ if (update.status === WAMessageStatus.READ && !key.fromMe) {
441
+ decrementChatReadCounterIfMsgDidUnread(existing);
442
+ }
443
+ }
444
+ else {
445
+ const msgUpdate = data.messageUpdates[keyStr] || { key, update: {} };
446
+ Object.assign(msgUpdate.update, update);
447
+ data.messageUpdates[keyStr] = msgUpdate;
448
+ }
449
+ }
450
+ break;
451
+ case 'messages.delete':
452
+ const deleteData = eventData;
453
+ if ('keys' in deleteData) {
454
+ const { keys } = deleteData;
455
+ for (const key of keys) {
456
+ const keyStr = stringifyMessageKey(key);
457
+ if (!data.messageDeletes[keyStr]) {
458
+ data.messageDeletes[keyStr] = key;
459
+ }
460
+ if (data.messageUpserts[keyStr]) {
461
+ delete data.messageUpserts[keyStr];
462
+ }
463
+ if (data.messageUpdates[keyStr]) {
464
+ delete data.messageUpdates[keyStr];
465
+ }
466
+ }
467
+ }
468
+ else {
469
+
470
+ }
471
+ break;
472
+ case 'messages.reaction':
473
+ const reactions = eventData;
474
+ for (const { key, reaction } of reactions) {
475
+ const keyStr = stringifyMessageKey(key);
476
+ const existing = data.messageUpserts[keyStr];
477
+ if (existing) {
478
+ updateMessageWithReaction(existing.message, reaction);
479
+ }
480
+ else {
481
+ data.messageReactions[keyStr] = data.messageReactions[keyStr] || { key, reactions: [] };
482
+ updateMessageWithReaction(data.messageReactions[keyStr], reaction);
483
+ }
484
+ }
485
+ break;
486
+ case 'message-receipt.update':
487
+ const receipts = eventData;
488
+ for (const { key, receipt } of receipts) {
489
+ const keyStr = stringifyMessageKey(key);
490
+ const existing = data.messageUpserts[keyStr];
491
+ if (existing) {
492
+ updateMessageWithReceipt(existing.message, receipt);
493
+ }
494
+ else {
495
+ data.messageReceipts[keyStr] = data.messageReceipts[keyStr] || { key, userReceipt: [] };
496
+ updateMessageWithReceipt(data.messageReceipts[keyStr], receipt);
497
+ }
498
+ }
499
+ break;
500
+ case 'groups.update':
501
+ const groupUpdates = eventData;
502
+ for (const update of groupUpdates) {
503
+ const id = update.id;
504
+ const groupUpdate = data.groupUpdates[id] || {};
505
+ if (!data.groupUpdates[id]) {
506
+ data.groupUpdates[id] = Object.assign(groupUpdate, update);
507
+ }
508
+ }
509
+ break;
510
+ default:
511
+ throw new Error(`"${event}" cannot be buffered`);
512
+ }
513
+ function absorbingChatUpdate(existing) {
514
+ const chatId = existing.id || '';
515
+ const update = data.chatUpdates[chatId];
516
+ if (update) {
517
+ const conditionMatches = update.conditional ? update.conditional(data) : true;
518
+ if (conditionMatches) {
519
+ delete update.conditional;
520
+ logger.debug({ chatId }, 'absorbed chat update in existing chat');
521
+ Object.assign(existing, concatChats(update, existing));
522
+ delete data.chatUpdates[chatId];
523
+ }
524
+ else if (conditionMatches === false) {
525
+ logger.debug({ chatId }, 'chat update condition fail, removing');
526
+ delete data.chatUpdates[chatId];
527
+ }
528
+ }
529
+ }
530
+ function decrementChatReadCounterIfMsgDidUnread(message) {
531
+
532
+ const chatId = message.key.remoteJid;
533
+ const chat = data.chatUpdates[chatId] || data.chatUpserts[chatId];
534
+ if (isRealMessage(message) &&
535
+ shouldIncrementChatUnread(message) &&
536
+ typeof chat?.unreadCount === 'number' &&
537
+ chat.unreadCount > 0) {
538
+ logger.debug({ chatId: chat.id }, 'decrementing chat counter');
539
+ chat.unreadCount -= 1;
540
+ if (chat.unreadCount === 0) {
541
+ delete chat.unreadCount;
542
+ }
543
+ }
544
+ }
545
+ }
546
+ function consolidateEvents(data) {
547
+ const map = {};
548
+ if (!data.historySets.empty) {
549
+ map['messaging-history.set'] = {
550
+ chats: Object.values(data.historySets.chats),
551
+ messages: Object.values(data.historySets.messages),
552
+ contacts: Object.values(data.historySets.contacts),
553
+ pastParticipants: data.historySets.pastParticipants,
554
+ syncType: data.historySets.syncType,
555
+ progress: data.historySets.progress,
556
+ isLatest: data.historySets.isLatest,
557
+ chunkOrder: data.historySets.chunkOrder,
558
+ peerDataRequestSessionId: data.historySets.peerDataRequestSessionId
559
+ };
560
+ }
561
+ const chatUpsertList = Object.values(data.chatUpserts);
562
+ if (chatUpsertList.length) {
563
+ map['chats.upsert'] = chatUpsertList;
564
+ }
565
+ const chatUpdateList = Object.values(data.chatUpdates);
566
+ if (chatUpdateList.length) {
567
+ map['chats.update'] = chatUpdateList;
568
+ }
569
+ const chatDeleteList = Array.from(data.chatDeletes);
570
+ if (chatDeleteList.length) {
571
+ map['chats.delete'] = chatDeleteList;
572
+ }
573
+ const messageUpsertList = Object.values(data.messageUpserts);
574
+ if (messageUpsertList.length) {
575
+ const type = messageUpsertList[0].type;
576
+ map['messages.upsert'] = {
577
+ messages: messageUpsertList.map(m => m.message),
578
+ type
579
+ };
580
+ }
581
+ const messageUpdateList = Object.values(data.messageUpdates);
582
+ if (messageUpdateList.length) {
583
+ map['messages.update'] = messageUpdateList;
584
+ }
585
+ const messageDeleteList = Object.values(data.messageDeletes);
586
+ if (messageDeleteList.length) {
587
+ map['messages.delete'] = { keys: messageDeleteList };
588
+ }
589
+ const messageReactionList = Object.values(data.messageReactions).flatMap(({ key, reactions }) => reactions.flatMap(reaction => ({ key, reaction })));
590
+ if (messageReactionList.length) {
591
+ map['messages.reaction'] = messageReactionList;
592
+ }
593
+ const messageReceiptList = Object.values(data.messageReceipts).flatMap(({ key, userReceipt }) => userReceipt.flatMap(receipt => ({ key, receipt })));
594
+ if (messageReceiptList.length) {
595
+ map['message-receipt.update'] = messageReceiptList;
596
+ }
597
+ const contactUpsertList = Object.values(data.contactUpserts);
598
+ if (contactUpsertList.length) {
599
+ map['contacts.upsert'] = contactUpsertList;
600
+ }
601
+ const contactUpdateList = Object.values(data.contactUpdates);
602
+ if (contactUpdateList.length) {
603
+ map['contacts.update'] = contactUpdateList;
604
+ }
605
+ const groupUpdateList = Object.values(data.groupUpdates);
606
+ if (groupUpdateList.length) {
607
+ map['groups.update'] = groupUpdateList;
608
+ }
609
+ return map;
610
+ }
611
+ function concatChats(a, b) {
612
+ if (b.unreadCount === null &&
613
+ a.unreadCount < 0) {
614
+ a.unreadCount = undefined;
615
+ b.unreadCount = undefined;
616
+ }
617
+ if (typeof a.unreadCount === 'number' && typeof b.unreadCount === 'number') {
618
+ b = { ...b };
619
+ if (b.unreadCount >= 0) {
620
+ b.unreadCount = Math.max(b.unreadCount, 0) + Math.max(a.unreadCount, 0);
621
+ }
622
+ }
623
+ return Object.assign(a, b);
624
+ }
625
+ const stringifyMessageKey = (key) => `${key.remoteJid},${key.id},${key.fromMe ? '1' : '0'}`;