@fer2809fl/baileys 1.4.9 → 7.0.0

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 (481) hide show
  1. package/LICENSE +21 -674
  2. package/README.md +556 -523
  3. package/WAProto/GenerateStatics.sh +3 -4
  4. package/WAProto/WAProto.proto +1215 -511
  5. package/WAProto/fix-imports.js +85 -0
  6. package/WAProto/index.d.ts +4347 -45387
  7. package/WAProto/index.js +65475 -137445
  8. package/engine-requirements.js +10 -0
  9. package/lib/Defaults/index.d.ts +34 -18
  10. package/lib/Defaults/index.d.ts.map +1 -0
  11. package/lib/Defaults/index.js +95 -67
  12. package/lib/Defaults/index.js.map +1 -0
  13. package/lib/Signal/Group/ciphertext-message.d.ts +1 -0
  14. package/lib/Signal/Group/ciphertext-message.d.ts.map +1 -0
  15. package/lib/Signal/Group/ciphertext-message.js +2 -5
  16. package/lib/Signal/Group/ciphertext-message.js.map +1 -0
  17. package/lib/Signal/Group/group-session-builder.d.ts +4 -3
  18. package/lib/Signal/Group/group-session-builder.d.ts.map +1 -0
  19. package/lib/Signal/Group/group-session-builder.js +7 -41
  20. package/lib/Signal/Group/group-session-builder.js.map +1 -0
  21. package/lib/Signal/Group/group_cipher.d.ts +4 -4
  22. package/lib/Signal/Group/group_cipher.d.ts.map +1 -0
  23. package/lib/Signal/Group/group_cipher.js +37 -60
  24. package/lib/Signal/Group/group_cipher.js.map +1 -0
  25. package/lib/Signal/Group/index.d.ts +12 -11
  26. package/lib/Signal/Group/index.d.ts.map +1 -0
  27. package/lib/Signal/Group/index.js +12 -57
  28. package/lib/Signal/Group/index.js.map +1 -0
  29. package/lib/Signal/Group/keyhelper.d.ts +2 -1
  30. package/lib/Signal/Group/keyhelper.d.ts.map +1 -0
  31. package/lib/Signal/Group/keyhelper.js +7 -44
  32. package/lib/Signal/Group/keyhelper.js.map +1 -0
  33. package/lib/Signal/Group/sender-chain-key.d.ts +3 -2
  34. package/lib/Signal/Group/sender-chain-key.d.ts.map +1 -0
  35. package/lib/Signal/Group/sender-chain-key.js +7 -15
  36. package/lib/Signal/Group/sender-chain-key.js.map +1 -0
  37. package/lib/Signal/Group/sender-key-distribution-message.d.ts +2 -1
  38. package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -0
  39. package/lib/Signal/Group/sender-key-distribution-message.js +8 -11
  40. package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -0
  41. package/lib/Signal/Group/sender-key-message.d.ts +2 -1
  42. package/lib/Signal/Group/sender-key-message.d.ts.map +1 -0
  43. package/lib/Signal/Group/sender-key-message.js +9 -12
  44. package/lib/Signal/Group/sender-key-message.js.map +1 -0
  45. package/lib/Signal/Group/sender-key-name.d.ts +1 -0
  46. package/lib/Signal/Group/sender-key-name.d.ts.map +1 -0
  47. package/lib/Signal/Group/sender-key-name.js +2 -5
  48. package/lib/Signal/Group/sender-key-name.js.map +1 -0
  49. package/lib/Signal/Group/sender-key-record.d.ts +3 -2
  50. package/lib/Signal/Group/sender-key-record.d.ts.map +1 -0
  51. package/lib/Signal/Group/sender-key-record.js +12 -37
  52. package/lib/Signal/Group/sender-key-record.js.map +1 -0
  53. package/lib/Signal/Group/sender-key-state.d.ts +7 -6
  54. package/lib/Signal/Group/sender-key-state.d.ts.map +1 -0
  55. package/lib/Signal/Group/sender-key-state.js +27 -42
  56. package/lib/Signal/Group/sender-key-state.js.map +1 -0
  57. package/lib/Signal/Group/sender-message-key.d.ts +1 -0
  58. package/lib/Signal/Group/sender-message-key.d.ts.map +1 -0
  59. package/lib/Signal/Group/sender-message-key.js +4 -7
  60. package/lib/Signal/Group/sender-message-key.js.map +1 -0
  61. package/lib/Signal/libsignal.d.ts +5 -3
  62. package/lib/Signal/libsignal.d.ts.map +1 -0
  63. package/lib/Signal/libsignal.js +347 -90
  64. package/lib/Signal/libsignal.js.map +1 -0
  65. package/lib/Signal/lid-mapping.d.ts +23 -0
  66. package/lib/Signal/lid-mapping.d.ts.map +1 -0
  67. package/lib/Signal/lid-mapping.js +277 -0
  68. package/lib/Signal/lid-mapping.js.map +1 -0
  69. package/lib/Socket/Client/index.d.ts +3 -2
  70. package/lib/Socket/Client/index.d.ts.map +1 -0
  71. package/lib/Socket/Client/index.js +3 -18
  72. package/lib/Socket/Client/index.js.map +1 -0
  73. package/lib/Socket/Client/types.d.ts +4 -4
  74. package/lib/Socket/Client/types.d.ts.map +1 -0
  75. package/lib/Socket/Client/types.js +4 -6
  76. package/lib/Socket/Client/types.js.map +1 -0
  77. package/lib/Socket/Client/websocket.d.ts +3 -3
  78. package/lib/Socket/Client/websocket.d.ts.map +1 -0
  79. package/lib/Socket/Client/websocket.js +21 -78
  80. package/lib/Socket/Client/websocket.js.map +1 -0
  81. package/lib/Socket/business.d.ts +205 -93
  82. package/lib/Socket/business.d.ts.map +1 -0
  83. package/lib/Socket/business.js +162 -43
  84. package/lib/Socket/business.js.map +1 -0
  85. package/lib/Socket/chats.d.ts +77 -28
  86. package/lib/Socket/chats.d.ts.map +1 -0
  87. package/lib/Socket/chats.js +639 -248
  88. package/lib/Socket/chats.js.map +1 -0
  89. package/lib/Socket/communities.d.ts +340 -0
  90. package/lib/Socket/communities.d.ts.map +1 -0
  91. package/lib/Socket/communities.js +434 -0
  92. package/lib/Socket/communities.js.map +1 -0
  93. package/lib/Socket/groups.d.ts +93 -46
  94. package/lib/Socket/groups.d.ts.map +1 -0
  95. package/lib/Socket/groups.js +260 -102
  96. package/lib/Socket/groups.js.map +1 -0
  97. package/lib/Socket/index.d.ts +253 -98
  98. package/lib/Socket/index.d.ts.map +1 -0
  99. package/lib/Socket/index.js +11 -9
  100. package/lib/Socket/index.js.map +1 -0
  101. package/lib/Socket/messages-recv.d.ts +192 -83
  102. package/lib/Socket/messages-recv.d.ts.map +1 -0
  103. package/lib/Socket/messages-recv.js +1314 -559
  104. package/lib/Socket/messages-recv.js.map +1 -0
  105. package/lib/Socket/messages-send.d.ts +190 -75
  106. package/lib/Socket/messages-send.d.ts.map +1 -0
  107. package/lib/Socket/messages-send.js +937 -581
  108. package/lib/Socket/messages-send.js.map +1 -0
  109. package/lib/Socket/mex.d.ts +4 -0
  110. package/lib/Socket/mex.d.ts.map +1 -0
  111. package/lib/Socket/mex.js +62 -0
  112. package/lib/Socket/mex.js.map +1 -0
  113. package/lib/Socket/newsletter.d.ts +129 -73
  114. package/lib/Socket/newsletter.d.ts.map +1 -0
  115. package/lib/Socket/newsletter.js +373 -222
  116. package/lib/Socket/newsletter.js.map +1 -0
  117. package/lib/Socket/smgss.d.ts +119 -0
  118. package/lib/Socket/smgss.d.ts.map +1 -0
  119. package/lib/Socket/smgss.js +453 -0
  120. package/lib/Socket/smgss.js.map +1 -0
  121. package/lib/Socket/socket.d.ts +59 -270
  122. package/lib/Socket/socket.d.ts.map +1 -0
  123. package/lib/Socket/socket.js +738 -326
  124. package/lib/Socket/socket.js.map +1 -0
  125. package/lib/Store/index.d.ts +4 -2
  126. package/lib/Store/index.d.ts.map +1 -0
  127. package/lib/Store/index.js +4 -8
  128. package/lib/Store/index.js.map +1 -0
  129. package/lib/Store/make-in-memory-store.d.ts +74 -60
  130. package/lib/Store/make-in-memory-store.d.ts.map +1 -0
  131. package/lib/Store/make-in-memory-store.js +130 -119
  132. package/lib/Store/make-in-memory-store.js.map +1 -0
  133. package/lib/Store/make-ordered-dictionary.d.ts +4 -3
  134. package/lib/Store/make-ordered-dictionary.d.ts.map +1 -0
  135. package/lib/Store/make-ordered-dictionary.js +5 -6
  136. package/lib/Store/make-ordered-dictionary.js.map +1 -0
  137. package/lib/Store/object-repository.d.ts +6 -3
  138. package/lib/Store/object-repository.d.ts.map +1 -0
  139. package/lib/Store/object-repository.js +2 -5
  140. package/lib/Store/object-repository.js.map +1 -0
  141. package/lib/Types/Auth.d.ts +19 -5
  142. package/lib/Types/Auth.d.ts.map +1 -0
  143. package/lib/Types/Auth.js +2 -2
  144. package/lib/Types/Auth.js.map +1 -0
  145. package/lib/Types/Bussines.d.ts +25 -0
  146. package/lib/Types/Bussines.d.ts.map +1 -0
  147. package/lib/Types/Bussines.js +2 -0
  148. package/lib/Types/Bussines.js.map +1 -0
  149. package/lib/Types/Call.d.ts +3 -1
  150. package/lib/Types/Call.d.ts.map +1 -0
  151. package/lib/Types/Call.js +2 -2
  152. package/lib/Types/Call.js.map +1 -0
  153. package/lib/Types/Chat.d.ts +24 -9
  154. package/lib/Types/Chat.d.ts.map +1 -0
  155. package/lib/Types/Chat.js +8 -4
  156. package/lib/Types/Chat.js.map +1 -0
  157. package/lib/Types/Contact.d.ts +7 -4
  158. package/lib/Types/Contact.d.ts.map +1 -0
  159. package/lib/Types/Contact.js +2 -2
  160. package/lib/Types/Contact.js.map +1 -0
  161. package/lib/Types/Events.d.ts +90 -33
  162. package/lib/Types/Events.d.ts.map +1 -0
  163. package/lib/Types/Events.js +2 -2
  164. package/lib/Types/Events.js.map +1 -0
  165. package/lib/Types/GroupMetadata.d.ts +16 -9
  166. package/lib/Types/GroupMetadata.d.ts.map +1 -0
  167. package/lib/Types/GroupMetadata.js +2 -2
  168. package/lib/Types/GroupMetadata.js.map +1 -0
  169. package/lib/Types/Label.d.ts +12 -0
  170. package/lib/Types/Label.d.ts.map +1 -0
  171. package/lib/Types/Label.js +3 -5
  172. package/lib/Types/Label.js.map +1 -0
  173. package/lib/Types/LabelAssociation.d.ts +1 -0
  174. package/lib/Types/LabelAssociation.d.ts.map +1 -0
  175. package/lib/Types/LabelAssociation.js +3 -5
  176. package/lib/Types/LabelAssociation.js.map +1 -0
  177. package/lib/Types/Message.d.ts +176 -148
  178. package/lib/Types/Message.d.ts.map +1 -0
  179. package/lib/Types/Message.js +15 -7
  180. package/lib/Types/Message.js.map +1 -0
  181. package/lib/Types/Mex.d.ts +154 -0
  182. package/lib/Types/Mex.d.ts.map +1 -0
  183. package/lib/Types/Mex.js +39 -0
  184. package/lib/Types/Mex.js.map +1 -0
  185. package/lib/Types/Product.d.ts +2 -1
  186. package/lib/Types/Product.d.ts.map +1 -0
  187. package/lib/Types/Product.js +2 -2
  188. package/lib/Types/Product.js.map +1 -0
  189. package/lib/Types/Signal.d.ts +32 -2
  190. package/lib/Types/Signal.d.ts.map +1 -0
  191. package/lib/Types/Signal.js +2 -2
  192. package/lib/Types/Signal.js.map +1 -0
  193. package/lib/Types/Socket.d.ts +46 -20
  194. package/lib/Types/Socket.d.ts.map +1 -0
  195. package/lib/Types/Socket.js +3 -2
  196. package/lib/Types/Socket.js.map +1 -0
  197. package/lib/Types/State.d.ts +79 -2
  198. package/lib/Types/State.d.ts.map +1 -0
  199. package/lib/Types/State.js +56 -2
  200. package/lib/Types/State.js.map +1 -0
  201. package/lib/Types/USync.d.ts +3 -2
  202. package/lib/Types/USync.d.ts.map +1 -0
  203. package/lib/Types/USync.js +2 -2
  204. package/lib/Types/USync.js.map +1 -0
  205. package/lib/Types/index.d.ts +16 -14
  206. package/lib/Types/index.d.ts.map +1 -0
  207. package/lib/Types/index.js +15 -31
  208. package/lib/Types/index.js.map +1 -0
  209. package/lib/Utils/auth-utils.d.ts +10 -4
  210. package/lib/Utils/auth-utils.d.ts.map +1 -0
  211. package/lib/Utils/auth-utils.js +242 -151
  212. package/lib/Utils/auth-utils.js.map +1 -0
  213. package/lib/Utils/browser-utils.d.ts +4 -0
  214. package/lib/Utils/browser-utils.d.ts.map +1 -0
  215. package/lib/Utils/browser-utils.js +29 -0
  216. package/lib/Utils/browser-utils.js.map +1 -0
  217. package/lib/Utils/business.d.ts +3 -2
  218. package/lib/Utils/business.d.ts.map +1 -0
  219. package/lib/Utils/business.js +66 -69
  220. package/lib/Utils/business.js.map +1 -0
  221. package/lib/Utils/button-handler.d.ts +28 -0
  222. package/lib/Utils/button-handler.d.ts.map +1 -0
  223. package/lib/Utils/button-handler.js +79 -90
  224. package/lib/Utils/button-handler.js.map +1 -0
  225. package/lib/Utils/chat-utils.d.ts +42 -12
  226. package/lib/Utils/chat-utils.d.ts.map +1 -0
  227. package/lib/Utils/chat-utils.js +380 -238
  228. package/lib/Utils/chat-utils.js.map +1 -0
  229. package/lib/Utils/companion-reg-client-utils.d.ts +17 -0
  230. package/lib/Utils/companion-reg-client-utils.d.ts.map +1 -0
  231. package/lib/Utils/companion-reg-client-utils.js +35 -0
  232. package/lib/Utils/companion-reg-client-utils.js.map +1 -0
  233. package/lib/Utils/crypto.d.ts +11 -14
  234. package/lib/Utils/crypto.d.ts.map +1 -0
  235. package/lib/Utils/crypto.js +41 -116
  236. package/lib/Utils/crypto.js.map +1 -0
  237. package/lib/Utils/decode-wa-message.d.ts +36 -5
  238. package/lib/Utils/decode-wa-message.d.ts.map +1 -0
  239. package/lib/Utils/decode-wa-message.js +173 -63
  240. package/lib/Utils/decode-wa-message.js.map +1 -0
  241. package/lib/Utils/event-buffer.d.ts +8 -7
  242. package/lib/Utils/event-buffer.d.ts.map +1 -0
  243. package/lib/Utils/event-buffer.js +174 -70
  244. package/lib/Utils/event-buffer.js.map +1 -0
  245. package/lib/Utils/generics.d.ts +20 -17
  246. package/lib/Utils/generics.d.ts.map +1 -0
  247. package/lib/Utils/generics.js +159 -207
  248. package/lib/Utils/generics.js.map +1 -0
  249. package/lib/Utils/history.d.ts +16 -11
  250. package/lib/Utils/history.d.ts.map +1 -0
  251. package/lib/Utils/history.js +93 -53
  252. package/lib/Utils/history.js.map +1 -0
  253. package/lib/Utils/identity-change-handler.d.ts +44 -0
  254. package/lib/Utils/identity-change-handler.d.ts.map +1 -0
  255. package/lib/Utils/identity-change-handler.js +50 -0
  256. package/lib/Utils/identity-change-handler.js.map +1 -0
  257. package/lib/Utils/index.d.ts +30 -18
  258. package/lib/Utils/index.d.ts.map +1 -0
  259. package/lib/Utils/index.js +30 -34
  260. package/lib/Utils/index.js.map +1 -0
  261. package/lib/Utils/interactive.d.ts +60 -0
  262. package/lib/Utils/interactive.d.ts.map +1 -0
  263. package/lib/Utils/interactive.js +87 -117
  264. package/lib/Utils/interactive.js.map +1 -0
  265. package/lib/Utils/link-preview.d.ts +4 -4
  266. package/lib/Utils/link-preview.d.ts.map +1 -0
  267. package/lib/Utils/link-preview.js +17 -58
  268. package/lib/Utils/link-preview.js.map +1 -0
  269. package/lib/Utils/logger.d.ts +8 -6
  270. package/lib/Utils/logger.d.ts.map +1 -0
  271. package/lib/Utils/logger.js +3 -10
  272. package/lib/Utils/logger.js.map +1 -0
  273. package/lib/Utils/lt-hash.d.ts +8 -12
  274. package/lib/Utils/lt-hash.d.ts.map +1 -0
  275. package/lib/Utils/lt-hash.js +3 -46
  276. package/lib/Utils/lt-hash.js.map +1 -0
  277. package/lib/Utils/make-mutex.d.ts +2 -0
  278. package/lib/Utils/make-mutex.d.ts.map +1 -0
  279. package/lib/Utils/make-mutex.js +24 -34
  280. package/lib/Utils/make-mutex.js.map +1 -0
  281. package/lib/Utils/message-composer.d.ts +93 -0
  282. package/lib/Utils/message-composer.d.ts.map +1 -0
  283. package/lib/Utils/message-composer.js +311 -0
  284. package/lib/Utils/message-composer.js.map +1 -0
  285. package/lib/Utils/message-retry-manager.d.ts +115 -0
  286. package/lib/Utils/message-retry-manager.d.ts.map +1 -0
  287. package/lib/Utils/message-retry-manager.js +265 -0
  288. package/lib/Utils/message-retry-manager.js.map +1 -0
  289. package/lib/Utils/messages-media.d.ts +82 -40
  290. package/lib/Utils/messages-media.d.ts.map +1 -0
  291. package/lib/Utils/messages-media.js +674 -677
  292. package/lib/Utils/messages-media.js.map +1 -0
  293. package/lib/Utils/messages-newsletter.d.ts +74 -0
  294. package/lib/Utils/messages-newsletter.d.ts.map +1 -0
  295. package/lib/Utils/messages-newsletter.js +128 -0
  296. package/lib/Utils/messages-newsletter.js.map +1 -0
  297. package/lib/Utils/messages.d.ts +38 -14
  298. package/lib/Utils/messages.d.ts.map +1 -0
  299. package/lib/Utils/messages.js +835 -602
  300. package/lib/Utils/messages.js.map +1 -0
  301. package/lib/Utils/noise-handler.d.ts +9 -8
  302. package/lib/Utils/noise-handler.d.ts.map +1 -0
  303. package/lib/Utils/noise-handler.js +149 -98
  304. package/lib/Utils/noise-handler.js.map +1 -0
  305. package/lib/Utils/offline-node-processor.d.ts +17 -0
  306. package/lib/Utils/offline-node-processor.d.ts.map +1 -0
  307. package/lib/Utils/offline-node-processor.js +40 -0
  308. package/lib/Utils/offline-node-processor.js.map +1 -0
  309. package/lib/Utils/pre-key-manager.d.ts +28 -0
  310. package/lib/Utils/pre-key-manager.d.ts.map +1 -0
  311. package/lib/Utils/pre-key-manager.js +106 -0
  312. package/lib/Utils/pre-key-manager.js.map +1 -0
  313. package/lib/Utils/process-message.d.ts +30 -12
  314. package/lib/Utils/process-message.d.ts.map +1 -0
  315. package/lib/Utils/process-message.js +438 -230
  316. package/lib/Utils/process-message.js.map +1 -0
  317. package/lib/Utils/reporting-utils.d.ts +11 -0
  318. package/lib/Utils/reporting-utils.d.ts.map +1 -0
  319. package/lib/Utils/reporting-utils.js +258 -0
  320. package/lib/Utils/reporting-utils.js.map +1 -0
  321. package/lib/Utils/shortcake-crypto.d.ts +36 -0
  322. package/lib/Utils/shortcake-crypto.d.ts.map +1 -0
  323. package/lib/Utils/shortcake-crypto.js +71 -0
  324. package/lib/Utils/shortcake-crypto.js.map +1 -0
  325. package/lib/Utils/shortcake.d.ts +36 -0
  326. package/lib/Utils/shortcake.d.ts.map +1 -0
  327. package/lib/Utils/shortcake.js +162 -0
  328. package/lib/Utils/shortcake.js.map +1 -0
  329. package/lib/Utils/signal.d.ts +20 -6
  330. package/lib/Utils/signal.d.ts.map +1 -0
  331. package/lib/Utils/signal.js +112 -64
  332. package/lib/Utils/signal.js.map +1 -0
  333. package/lib/Utils/stanza-ack.d.ts +11 -0
  334. package/lib/Utils/stanza-ack.d.ts.map +1 -0
  335. package/lib/Utils/stanza-ack.js +38 -0
  336. package/lib/Utils/stanza-ack.js.map +1 -0
  337. package/lib/Utils/sync-action-utils.d.ts +19 -0
  338. package/lib/Utils/sync-action-utils.d.ts.map +1 -0
  339. package/lib/Utils/sync-action-utils.js +49 -0
  340. package/lib/Utils/sync-action-utils.js.map +1 -0
  341. package/lib/Utils/tc-token-utils.d.ts +37 -0
  342. package/lib/Utils/tc-token-utils.d.ts.map +1 -0
  343. package/lib/Utils/tc-token-utils.js +164 -0
  344. package/lib/Utils/tc-token-utils.js.map +1 -0
  345. package/lib/Utils/use-multi-file-auth-state.d.ts +2 -1
  346. package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
  347. package/lib/Utils/use-multi-file-auth-state.js +40 -64
  348. package/lib/Utils/use-multi-file-auth-state.js.map +1 -0
  349. package/lib/Utils/use-single-file-auth-state.d.ts +6 -0
  350. package/lib/Utils/use-single-file-auth-state.d.ts.map +1 -0
  351. package/lib/Utils/use-single-file-auth-state.js +111 -0
  352. package/lib/Utils/use-single-file-auth-state.js.map +1 -0
  353. package/lib/Utils/use-sqlite-auth-state.d.ts +14 -0
  354. package/lib/Utils/use-sqlite-auth-state.d.ts.map +1 -0
  355. package/lib/Utils/use-sqlite-auth-state.js +107 -0
  356. package/lib/Utils/use-sqlite-auth-state.js.map +1 -0
  357. package/lib/Utils/validate-connection.d.ts +5 -3
  358. package/lib/Utils/validate-connection.d.ts.map +1 -0
  359. package/lib/Utils/validate-connection.js +82 -101
  360. package/lib/Utils/validate-connection.js.map +1 -0
  361. package/lib/WABinary/constants.d.ts +1 -0
  362. package/lib/WABinary/constants.d.ts.map +1 -0
  363. package/lib/WABinary/constants.js +10 -12
  364. package/lib/WABinary/constants.js.map +1 -0
  365. package/lib/WABinary/decode.d.ts +2 -1
  366. package/lib/WABinary/decode.d.ts.map +1 -0
  367. package/lib/WABinary/decode.js +49 -52
  368. package/lib/WABinary/decode.js.map +1 -0
  369. package/lib/WABinary/encode.d.ts +2 -1
  370. package/lib/WABinary/encode.d.ts.map +1 -0
  371. package/lib/WABinary/encode.js +19 -49
  372. package/lib/WABinary/encode.js.map +1 -0
  373. package/lib/WABinary/generic-utils.d.ts +5 -4
  374. package/lib/WABinary/generic-utils.d.ts.map +1 -0
  375. package/lib/WABinary/generic-utils.js +46 -43
  376. package/lib/WABinary/generic-utils.js.map +1 -0
  377. package/lib/WABinary/index.d.ts +6 -5
  378. package/lib/WABinary/index.d.ts.map +1 -0
  379. package/lib/WABinary/index.js +6 -21
  380. package/lib/WABinary/index.js.map +1 -0
  381. package/lib/WABinary/jid-utils.d.ts +32 -10
  382. package/lib/WABinary/jid-utils.d.ts.map +1 -0
  383. package/lib/WABinary/jid-utils.js +103 -59
  384. package/lib/WABinary/jid-utils.js.map +1 -0
  385. package/lib/WABinary/types.d.ts +2 -1
  386. package/lib/WABinary/types.d.ts.map +1 -0
  387. package/lib/WABinary/types.js +2 -2
  388. package/lib/WABinary/types.js.map +1 -0
  389. package/lib/WAM/BinaryInfo.d.ts +2 -1
  390. package/lib/WAM/BinaryInfo.d.ts.map +1 -0
  391. package/lib/WAM/BinaryInfo.js +2 -5
  392. package/lib/WAM/BinaryInfo.js.map +1 -0
  393. package/lib/WAM/constants.d.ts +5 -3
  394. package/lib/WAM/constants.d.ts.map +1 -0
  395. package/lib/WAM/constants.js +19071 -11568
  396. package/lib/WAM/constants.js.map +1 -0
  397. package/lib/WAM/encode.d.ts +2 -1
  398. package/lib/WAM/encode.d.ts.map +1 -0
  399. package/lib/WAM/encode.js +17 -22
  400. package/lib/WAM/encode.js.map +1 -0
  401. package/lib/WAM/index.d.ts +4 -3
  402. package/lib/WAM/index.d.ts.map +1 -0
  403. package/lib/WAM/index.js +4 -19
  404. package/lib/WAM/index.js.map +1 -0
  405. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +4 -3
  406. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -0
  407. package/lib/WAUSync/Protocols/USyncContactProtocol.js +33 -13
  408. package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -0
  409. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +3 -2
  410. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +1 -0
  411. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +11 -14
  412. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +1 -0
  413. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +3 -2
  414. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +1 -0
  415. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +8 -11
  416. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +1 -0
  417. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +3 -2
  418. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +1 -0
  419. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +9 -13
  420. package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +1 -0
  421. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
  422. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +1 -0
  423. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
  424. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +1 -0
  425. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +4 -3
  426. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +1 -0
  427. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +20 -22
  428. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +1 -0
  429. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +5 -3
  430. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +1 -0
  431. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +13 -8
  432. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +1 -0
  433. package/lib/WAUSync/Protocols/index.d.ts +6 -4
  434. package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
  435. package/lib/WAUSync/Protocols/index.js +6 -20
  436. package/lib/WAUSync/Protocols/index.js.map +1 -0
  437. package/lib/WAUSync/USyncQuery.d.ts +6 -4
  438. package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
  439. package/lib/WAUSync/USyncQuery.js +44 -35
  440. package/lib/WAUSync/USyncQuery.js.map +1 -0
  441. package/lib/WAUSync/USyncUser.d.ts +10 -5
  442. package/lib/WAUSync/USyncUser.d.ts.map +1 -0
  443. package/lib/WAUSync/USyncUser.js +10 -5
  444. package/lib/WAUSync/USyncUser.js.map +1 -0
  445. package/lib/WAUSync/index.d.ts +4 -3
  446. package/lib/WAUSync/index.d.ts.map +1 -0
  447. package/lib/WAUSync/index.js +4 -19
  448. package/lib/WAUSync/index.js.map +1 -0
  449. package/lib/index.d.ts +12 -15
  450. package/lib/index.d.ts.map +1 -0
  451. package/lib/index.js +15 -48
  452. package/lib/index.js.map +1 -0
  453. package/package.json +44 -64
  454. package/WAProto/index.ts.ts +0 -53473
  455. package/WAProto/n +0 -1
  456. package/lib/Baileys.jpeg +0 -0
  457. package/lib/Defaults/baileys-version.json +0 -3
  458. package/lib/Defaults/n +0 -1
  459. package/lib/Signal/Group/queue-job.d.ts +0 -1
  460. package/lib/Signal/Group/queue-job.js +0 -57
  461. package/lib/Signal/n +0 -1
  462. package/lib/Socket/Client/n +0 -1
  463. package/lib/Socket/n +0 -1
  464. package/lib/Socket/setup.js +0 -480
  465. package/lib/Socket/setup.ts +0 -622
  466. package/lib/Socket/usync.d.ts +0 -36
  467. package/lib/Socket/usync.js +0 -70
  468. package/lib/Store/n +0 -1
  469. package/lib/Types/Newsletter.d.ts +0 -79
  470. package/lib/Types/Newsletter.js +0 -18
  471. package/lib/Types/n +0 -1
  472. package/lib/Utils/baileys-event-stream.d.ts +0 -16
  473. package/lib/Utils/baileys-event-stream.js +0 -63
  474. package/lib/Utils/error-handler.js +0 -37
  475. package/lib/Utils/n +0 -1
  476. package/lib/WABinary/jid-utils.js.bak +0 -83
  477. package/lib/WABinary/n +0 -1
  478. package/lib/WAM/n +0 -1
  479. package/lib/WAUSync/Protocols/n +0 -1
  480. package/lib/WAUSync/n +0 -1
  481. package/lib/n +0 -1
@@ -1,56 +1,70 @@
1
- /* baileys by alip
2
- mau ngapain lu memekkkkkkk*/
3
-
4
- "use strict";
5
- var __importDefault = (this && this.__importDefault) || function (mod) {
6
- return (mod && mod.__esModule) ? mod : { "default": mod };
7
- };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.makeMessagesSocket = void 0;
10
- const boom_1 = require("@hapi/boom");
11
- const node_cache_1 = __importDefault(require("@cacheable/node-cache"));
12
- const crypto_1 = require("crypto");
13
- const WAProto_1 = require("../../WAProto");
14
- const Defaults_1 = require("../Defaults");
15
- const Utils_1 = require("../Utils");
16
- const link_preview_1 = require("../Utils/link-preview");
17
- const WABinary_1 = require("../WABinary");
18
- const WAUSync_1 = require("../WAUSync");
19
- const newsletter_1 = require("./newsletter");
20
- const NotForrAll = require("./setup");
21
- const makeMessagesSocket = (config) => {
22
- const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: axiosOptions, patchMessageBeforeSending, cachedGroupMetadata, } = config;
23
- const sock = (0, newsletter_1.makeNewsletterSocket)(config);
24
- const { ev, authState, processingMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral, } = sock;
25
- const userDevicesCache = config.userDevicesCache || new node_cache_1.default({
26
- stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
27
- useClones: false
28
- });
1
+ import NodeCache from '@cacheable/node-cache';
2
+ import { Boom } from '@hapi/boom';
3
+ import { randomBytes } from 'crypto';
4
+ import { proto } from '../../WAProto/index.js';
5
+ import { BIZ_BOT_SUPPORT_PAYLOAD, DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
6
+ import { aggregateMessageKeysNotFromMe, assertMediaContent, assertMeId, bindWaitForEvent, compressMedia, convertMedia, captureUnifiedResponse, decryptMediaRetryData, DEF_MEDIA_HOST, delay, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateCodeBlockContent, generateLatexContent, generateListContent, generateMessageIDV2, generateParticipantHashV2, generateRichMessageContent, generateTableContent, generateUnifiedResponseContent, generateWAMessage, generateWAMessageFromContent, getMediaMetadata, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, imageToWebpSticker, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, resizeImage, unixTimestampSeconds } from '../Utils/index.js';
7
+ import { getUrlInfo } from '../Utils/link-preview.js';
8
+ import { makeKeyedMutex, makeMutex } from '../Utils/make-mutex.js';
9
+ import { getMessageReportingToken, shouldIncludeReportingToken } from '../Utils/reporting-utils.js';
10
+ import { buildMergedTcTokenIndexWrite, isTcTokenExpired, resolveIssuanceJid, resolveTcTokenJid, shouldSendNewTcToken, storeTcTokensFromIqResult } from '../Utils/tc-token-utils.js';
11
+ import { areJidsSameUser, getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isJidBot, isJidGroup, isJidMetaAI, isLidUser, isPnUser, jidDecode, jidEncode, jidNormalizedUser, PSA_WID, S_WHATSAPP_NET, STORIES_JID } from '../WABinary/index.js';
12
+ import { USyncQuery, USyncUser } from '../WAUSync/index.js';
13
+ import { makeNewsletterSocket } from './newsletter.js';
14
+ import { Smgss } from './smgss.js';
15
+ export const makeMessagesSocket = (config) => {
16
+ const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: httpRequestOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache, maxMsgRetryCount } = config;
17
+ const sock = makeNewsletterSocket(config);
18
+ const { ev, authState, messageMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral, registerSocketEndHandler } = sock;
19
+ const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping);
20
+ /**
21
+ * Set of tctoken storage JIDs with a fire-and-forget `issuePrivacyTokens` IQ in flight.
22
+ * Prevents duplicate IQs from rapid back-to-back sends before `senderTimestamp` persists.
23
+ * Entries are always removed in `.finally()`, so the set is bounded by concurrency.
24
+ */
25
+ const inFlightTcTokenIssuance = new Set();
26
+ const userDevicesCache = config.userDevicesCache ||
27
+ new NodeCache({
28
+ stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
29
+ useClones: false
30
+ });
31
+ /** Serializes writes to userDevicesCache across USync refresh and device-notification handling. */
32
+ const devicesMutex = makeMutex();
33
+ // Initialize message retry manager if enabled
34
+ const messageRetryManager = enableRecentMessageCache ? new MessageRetryManager(logger, maxMsgRetryCount) : null;
35
+ // Prevent race conditions in Signal session encryption by user
36
+ const encryptionMutex = makeKeyedMutex();
29
37
  let mediaConn;
38
+ /** Per-socket media host; updated whenever media_conn is fetched. Defaults to the public WhatsApp host. */
39
+ let mediaHost = DEF_MEDIA_HOST;
30
40
  const refreshMediaConn = async (forceGet = false) => {
31
41
  const media = await mediaConn;
32
- if (!media || forceGet || (new Date().getTime() - media.fetchDate.getTime()) > media.ttl * 1000) {
42
+ if (!media || forceGet || new Date().getTime() - media.fetchDate.getTime() > media.ttl * 1000) {
33
43
  mediaConn = (async () => {
34
44
  const result = await query({
35
45
  tag: 'iq',
36
46
  attrs: {
37
47
  type: 'set',
38
48
  xmlns: 'w:m',
39
- to: WABinary_1.S_WHATSAPP_NET,
49
+ to: S_WHATSAPP_NET
40
50
  },
41
51
  content: [{ tag: 'media_conn', attrs: {} }]
42
52
  });
43
- const mediaConnNode = (0, WABinary_1.getBinaryNodeChild)(result, 'media_conn');
53
+ const mediaConnNode = getBinaryNodeChild(result, 'media_conn');
54
+ // TODO: explore full length of data that whatsapp provides
44
55
  const node = {
45
- hosts: (0, WABinary_1.getBinaryNodeChildren)(mediaConnNode, 'host').map(({ attrs }) => ({
56
+ hosts: getBinaryNodeChildren(mediaConnNode, 'host').map(({ attrs }) => ({
46
57
  hostname: attrs.hostname,
47
- maxContentLengthBytes: +attrs.maxContentLengthBytes,
58
+ maxContentLengthBytes: +attrs.maxContentLengthBytes
48
59
  })),
49
60
  auth: mediaConnNode.attrs.auth,
50
61
  ttl: +mediaConnNode.attrs.ttl,
51
62
  fetchDate: new Date()
52
63
  };
53
64
  logger.debug('fetched media conn');
65
+ if (node.hosts[0]) {
66
+ mediaHost = node.hosts[0].hostname;
67
+ }
54
68
  return node;
55
69
  })();
56
70
  }
@@ -61,17 +75,20 @@ const makeMessagesSocket = (config) => {
61
75
  * used for receipts of phone call, read, delivery etc.
62
76
  * */
63
77
  const sendReceipt = async (jid, participant, messageIds, type) => {
78
+ if (!messageIds || messageIds.length === 0) {
79
+ throw new Boom('missing ids in receipt');
80
+ }
64
81
  const node = {
65
82
  tag: 'receipt',
66
83
  attrs: {
67
- id: messageIds[0],
68
- },
84
+ id: messageIds[0]
85
+ }
69
86
  };
70
87
  const isReadReceipt = type === 'read' || type === 'read-self';
71
88
  if (isReadReceipt) {
72
- node.attrs.t = (0, Utils_1.unixTimestampSeconds)().toString();
89
+ node.attrs.t = unixTimestampSeconds().toString();
73
90
  }
74
- if (type === 'sender' && (0, WABinary_1.isJidUser)(jid)) {
91
+ if (type === 'sender' && (isPnUser(jid) || isLidUser(jid))) {
75
92
  node.attrs.recipient = jid;
76
93
  node.attrs.to = participant;
77
94
  }
@@ -82,7 +99,7 @@ const makeMessagesSocket = (config) => {
82
99
  }
83
100
  }
84
101
  if (type) {
85
- node.attrs.type = (0, WABinary_1.isJidNewsletter)(jid) ? 'read-self' : type;
102
+ node.attrs.type = type;
86
103
  }
87
104
  const remainingMessageIds = messageIds.slice(1);
88
105
  if (remainingMessageIds.length) {
@@ -102,7 +119,7 @@ const makeMessagesSocket = (config) => {
102
119
  };
103
120
  /** Correctly bulk send receipts to multiple chats, participants */
104
121
  const sendReceipts = async (keys, type) => {
105
- const recps = (0, Utils_1.aggregateMessageKeysNotFromMe)(keys);
122
+ const recps = aggregateMessageKeysNotFromMe(keys);
106
123
  for (const { jid, participant, messageIds } of recps) {
107
124
  await sendReceipt(jid, participant, messageIds, type);
108
125
  }
@@ -116,20 +133,44 @@ const makeMessagesSocket = (config) => {
116
133
  };
117
134
  /** Fetch all the devices we've to send a message to */
118
135
  const getUSyncDevices = async (jids, useCache, ignoreZeroDevices) => {
119
- var _a;
120
136
  const deviceResults = [];
121
137
  if (!useCache) {
122
138
  logger.debug('not using cache for devices');
123
139
  }
124
140
  const toFetch = [];
125
- jids = Array.from(new Set(jids));
126
- for (let jid of jids) {
127
- const user = (_a = (0, WABinary_1.jidDecode)(jid)) === null || _a === void 0 ? void 0 : _a.user;
128
- jid = (0, WABinary_1.jidNormalizedUser)(jid);
141
+ const jidsWithUser = jids
142
+ .map(jid => {
143
+ const decoded = jidDecode(jid);
144
+ const user = decoded?.user;
145
+ const device = decoded?.device;
146
+ const isExplicitDevice = typeof device === 'number' && device >= 0;
147
+ if (isExplicitDevice && user) {
148
+ deviceResults.push({
149
+ user,
150
+ device,
151
+ jid
152
+ });
153
+ return null;
154
+ }
155
+ jid = jidNormalizedUser(jid);
156
+ return { jid, user };
157
+ })
158
+ .filter(jid => jid !== null);
159
+ let mgetDevices;
160
+ if (useCache && userDevicesCache.mget) {
161
+ const usersToFetch = jidsWithUser.map(j => j?.user).filter(Boolean);
162
+ mgetDevices = await userDevicesCache.mget(usersToFetch);
163
+ }
164
+ for (const { jid, user } of jidsWithUser) {
129
165
  if (useCache) {
130
- const devices = userDevicesCache.get(user);
166
+ const devices = mgetDevices?.[user] ||
167
+ (userDevicesCache.mget ? undefined : (await userDevicesCache.get(user)));
131
168
  if (devices) {
132
- deviceResults.push(...devices);
169
+ const devicesWithJid = devices.map(d => ({
170
+ ...d,
171
+ jid: jidEncode(d.user, d.server, d.device)
172
+ }));
173
+ deviceResults.push(...devicesWithJid);
133
174
  logger.trace({ user }, 'using cache for devices');
134
175
  }
135
176
  else {
@@ -143,146 +184,270 @@ const makeMessagesSocket = (config) => {
143
184
  if (!toFetch.length) {
144
185
  return deviceResults;
145
186
  }
146
- const query = new WAUSync_1.USyncQuery()
147
- .withContext('message')
148
- .withDeviceProtocol();
187
+ const requestedLidUsers = new Set();
188
+ for (const jid of toFetch) {
189
+ if (isLidUser(jid) || isHostedLidUser(jid)) {
190
+ const user = jidDecode(jid)?.user;
191
+ if (user)
192
+ requestedLidUsers.add(user);
193
+ }
194
+ }
195
+ const query = new USyncQuery().withContext('message').withDeviceProtocol().withLIDProtocol();
149
196
  for (const jid of toFetch) {
150
- query.withUser(new WAUSync_1.USyncUser().withId(jid));
197
+ query.withUser(new USyncUser().withId(jid)); // todo: investigate - the idea here is that <user> should have an inline lid field with the lid being the pn equivalent
151
198
  }
152
199
  const result = await sock.executeUSyncQuery(query);
153
200
  if (result) {
154
- const extracted = (0, Utils_1.extractDeviceJids)(result === null || result === void 0 ? void 0 : result.list, authState.creds.me.id, ignoreZeroDevices);
201
+ // TODO: LID MAP this stuff (lid protocol will now return lid with devices)
202
+ const lidResults = result.list.filter(a => !!a.lid);
203
+ if (lidResults.length > 0) {
204
+ logger.trace('Storing LID maps from device call');
205
+ await signalRepository.lidMapping.storeLIDPNMappings(lidResults.map(a => ({ lid: a.lid, pn: a.id })));
206
+ // Force-refresh sessions for newly mapped LIDs to align identity addressing
207
+ try {
208
+ const lids = lidResults.map(a => a.lid);
209
+ if (lids.length) {
210
+ await assertSessions(lids, true);
211
+ }
212
+ }
213
+ catch (e) {
214
+ logger.warn({ e, count: lidResults.length }, 'failed to assert sessions for newly mapped LIDs');
215
+ }
216
+ }
217
+ const extracted = extractDeviceJids(result?.list, authState.creds.me.id, authState.creds.me.lid, ignoreZeroDevices);
155
218
  const deviceMap = {};
156
219
  for (const item of extracted) {
157
220
  deviceMap[item.user] = deviceMap[item.user] || [];
158
- deviceMap[item.user].push(item);
159
- deviceResults.push(item);
221
+ deviceMap[item.user]?.push(item);
222
+ }
223
+ // Process each user's devices as a group for bulk LID migration
224
+ for (const [user, userDevices] of Object.entries(deviceMap)) {
225
+ const isLidUser = requestedLidUsers.has(user);
226
+ // Process all devices for this user
227
+ for (const item of userDevices) {
228
+ const finalJid = isLidUser
229
+ ? jidEncode(user, item.server, item.device)
230
+ : jidEncode(item.user, item.server, item.device);
231
+ deviceResults.push({
232
+ ...item,
233
+ jid: finalJid
234
+ });
235
+ logger.debug({
236
+ user: item.user,
237
+ device: item.device,
238
+ finalJid,
239
+ usedLid: isLidUser
240
+ }, 'Processed device with LID priority');
241
+ }
242
+ }
243
+ await devicesMutex.mutex(async () => {
244
+ if (userDevicesCache.mset) {
245
+ // if the cache supports mset, we can set all devices in one go
246
+ await userDevicesCache.mset(Object.entries(deviceMap).map(([key, value]) => ({ key, value })));
247
+ }
248
+ else {
249
+ for (const key in deviceMap) {
250
+ if (deviceMap[key])
251
+ await userDevicesCache.set(key, deviceMap[key]);
252
+ }
253
+ }
254
+ });
255
+ const userDeviceUpdates = {};
256
+ for (const [userId, devices] of Object.entries(deviceMap)) {
257
+ if (devices && devices.length > 0) {
258
+ userDeviceUpdates[userId] = devices.map(d => d.device?.toString() || '0');
259
+ }
160
260
  }
161
- for (const key in deviceMap) {
162
- userDevicesCache.set(key, deviceMap[key]);
261
+ if (Object.keys(userDeviceUpdates).length > 0) {
262
+ try {
263
+ await authState.keys.set({ 'device-list': userDeviceUpdates });
264
+ logger.debug({ userCount: Object.keys(userDeviceUpdates).length }, 'stored user device lists for bulk migration');
265
+ }
266
+ catch (error) {
267
+ logger.warn({ error }, 'failed to store user device lists');
268
+ }
163
269
  }
164
270
  }
165
271
  return deviceResults;
166
272
  };
273
+ /**
274
+ * Update Member Label
275
+ */
276
+ const updateMemberLabel = (jid, memberLabel) => {
277
+ return relayMessage(jid, {
278
+ protocolMessage: {
279
+ type: proto.Message.ProtocolMessage.Type.GROUP_MEMBER_LABEL_CHANGE,
280
+ memberLabel: {
281
+ label: memberLabel?.slice(0, 30),
282
+ labelTimestamp: unixTimestampSeconds()
283
+ }
284
+ }
285
+ }, {
286
+ additionalNodes: [
287
+ {
288
+ tag: 'meta',
289
+ attrs: {
290
+ tag_reason: 'user_update',
291
+ appdata: 'member_tag'
292
+ },
293
+ content: undefined
294
+ }
295
+ ]
296
+ });
297
+ };
167
298
  const assertSessions = async (jids, force) => {
168
299
  let didFetchNewSession = false;
169
- let jidsRequiringFetch = [];
170
- if (force) {
171
- jidsRequiringFetch = jids;
172
- }
173
- else {
174
- const addrs = jids.map(jid => (signalRepository
175
- .jidToSignalProtocolAddress(jid)));
176
- const sessions = await authState.keys.get('session', addrs);
177
- for (const jid of jids) {
178
- const signalId = signalRepository
179
- .jidToSignalProtocolAddress(jid);
180
- if (!sessions[signalId]) {
181
- jidsRequiringFetch.push(jid);
300
+ const uniqueJids = [...new Set(jids)];
301
+ const jidsRequiringFetch = [];
302
+ logger.debug({ jids }, 'assertSessions call with jids');
303
+ for (const jid of uniqueJids) {
304
+ if (!force) {
305
+ const sessionValidation = await signalRepository.validateSession(jid);
306
+ if (sessionValidation.exists) {
307
+ continue;
182
308
  }
183
309
  }
310
+ jidsRequiringFetch.push(jid);
184
311
  }
185
312
  if (jidsRequiringFetch.length) {
186
- logger.debug({ jidsRequiringFetch }, 'fetching sessions');
313
+ // LID if mapped, otherwise original
314
+ const wireJids = [
315
+ ...jidsRequiringFetch.filter(jid => !!isLidUser(jid) || !!isHostedLidUser(jid)),
316
+ ...((await signalRepository.lidMapping.getLIDsForPNs(jidsRequiringFetch.filter(jid => !!isPnUser(jid) || !!isHostedPnUser(jid)))) || []).map(a => a.lid)
317
+ ];
318
+ logger.debug({ jidsRequiringFetch, wireJids }, 'fetching sessions');
187
319
  const result = await query({
188
320
  tag: 'iq',
189
321
  attrs: {
190
322
  xmlns: 'encrypt',
191
323
  type: 'get',
192
- to: WABinary_1.S_WHATSAPP_NET,
324
+ to: S_WHATSAPP_NET
193
325
  },
194
326
  content: [
195
327
  {
196
328
  tag: 'key',
197
329
  attrs: {},
198
- content: jidsRequiringFetch.map(jid => ({
199
- tag: 'user',
200
- attrs: { jid },
201
- }))
330
+ content: wireJids.map(jid => {
331
+ const attrs = { jid };
332
+ if (force)
333
+ attrs.reason = 'identity';
334
+ return { tag: 'user', attrs };
335
+ })
202
336
  }
203
337
  ]
204
338
  });
205
- await (0, Utils_1.parseAndInjectE2ESessions)(result, signalRepository);
339
+ await parseAndInjectE2ESessions(result, signalRepository);
206
340
  didFetchNewSession = true;
207
341
  }
208
342
  return didFetchNewSession;
209
343
  };
210
344
  const sendPeerDataOperationMessage = async (pdoMessage) => {
211
- var _a;
212
345
  //TODO: for later, abstract the logic to send a Peer Message instead of just PDO - useful for App State Key Resync with phone
213
- if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
214
- throw new boom_1.Boom('Not authenticated');
346
+ if (!authState.creds.me?.id) {
347
+ throw new Boom('Not authenticated');
215
348
  }
216
349
  const protocolMessage = {
217
350
  protocolMessage: {
218
351
  peerDataOperationRequestMessage: pdoMessage,
219
- type: WAProto_1.proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE
352
+ type: proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE
220
353
  }
221
354
  };
222
- const meJid = (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id);
355
+ const meJid = jidNormalizedUser(authState.creds.me.id);
223
356
  const msgId = await relayMessage(meJid, protocolMessage, {
224
357
  additionalAttributes: {
225
358
  category: 'peer',
226
- // eslint-disable-next-line camelcase
227
- push_priority: 'high_force',
359
+ push_priority: 'high_force'
228
360
  },
361
+ additionalNodes: [
362
+ {
363
+ tag: 'meta',
364
+ attrs: { appdata: 'default' }
365
+ }
366
+ ]
229
367
  });
230
368
  return msgId;
231
369
  };
232
- const createParticipantNodes = async (jids, message, extraAttrs) => {
233
- let patched = await patchMessageBeforeSending(message, jids);
234
- if (!Array.isArray(patched)) {
235
- patched = jids ? jids.map(jid => ({ recipientJid: jid, ...patched })) : [patched];
370
+ const createParticipantNodes = async (recipientJids, message, extraAttrs, dsmMessage) => {
371
+ if (!recipientJids.length) {
372
+ return { nodes: [], shouldIncludeDeviceIdentity: false };
236
373
  }
374
+ const patched = await patchMessageBeforeSending(message, recipientJids);
375
+ const patchedMessages = Array.isArray(patched)
376
+ ? patched
377
+ : recipientJids.map(jid => ({ recipientJid: jid, message: patched }));
237
378
  let shouldIncludeDeviceIdentity = false;
238
- const nodes = await Promise.all(patched.map(async (patchedMessageWithJid) => {
239
- const { recipientJid: jid, ...patchedMessage } = patchedMessageWithJid;
240
- if (!jid) {
241
- return {};
379
+ const meId = authState.creds.me.id;
380
+ const meLid = authState.creds.me?.lid;
381
+ const meLidUser = meLid ? jidDecode(meLid)?.user : null;
382
+ const encryptionPromises = patchedMessages.map(async ({ recipientJid: jid, message: patchedMessage }) => {
383
+ try {
384
+ if (!jid)
385
+ return null;
386
+ let msgToEncrypt = patchedMessage;
387
+ if (dsmMessage) {
388
+ const { user: targetUser } = jidDecode(jid);
389
+ const { user: ownPnUser } = jidDecode(meId);
390
+ const ownLidUser = meLidUser;
391
+ const isOwnUser = targetUser === ownPnUser || (ownLidUser && targetUser === ownLidUser);
392
+ const isExactSenderDevice = jid === meId || (meLid && jid === meLid);
393
+ if (isOwnUser && !isExactSenderDevice) {
394
+ msgToEncrypt = dsmMessage;
395
+ logger.debug({ jid, targetUser }, 'Using DSM for own device');
396
+ }
397
+ }
398
+ const bytes = encodeWAMessage(msgToEncrypt);
399
+ const mutexKey = jid;
400
+ const node = await encryptionMutex.mutex(mutexKey, async () => {
401
+ const { type, ciphertext } = await signalRepository.encryptMessage({ jid, data: bytes });
402
+ if (type === 'pkmsg') {
403
+ shouldIncludeDeviceIdentity = true;
404
+ }
405
+ return {
406
+ tag: 'to',
407
+ attrs: { jid },
408
+ content: [
409
+ {
410
+ tag: 'enc',
411
+ attrs: { v: '2', type, ...(extraAttrs || {}) },
412
+ content: ciphertext
413
+ }
414
+ ]
415
+ };
416
+ });
417
+ return node;
242
418
  }
243
- const bytes = (0, Utils_1.encodeWAMessage)(patchedMessage);
244
- const { type, ciphertext } = await signalRepository
245
- .encryptMessage({ jid, data: bytes });
246
- if (type === 'pkmsg') {
247
- shouldIncludeDeviceIdentity = true;
419
+ catch (err) {
420
+ logger.error({ jid, err }, 'Failed to encrypt for recipient');
421
+ return null;
248
422
  }
249
- const node = {
250
- tag: 'to',
251
- attrs: { jid },
252
- content: [{
253
- tag: 'enc',
254
- attrs: {
255
- v: '2',
256
- type,
257
- ...extraAttrs || {}
258
- },
259
- content: ciphertext
260
- }]
261
- };
262
- return node;
263
- }));
423
+ });
424
+ const nodes = (await Promise.all(encryptionPromises)).filter(node => node !== null);
425
+ if (recipientJids.length > 0 && nodes.length === 0) {
426
+ throw new Boom('All encryptions failed', { statusCode: 500 });
427
+ }
264
428
  return { nodes, shouldIncludeDeviceIdentity };
265
429
  };
266
- const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList, AI = true }) => {
267
- var _a;
268
- const meId = authState.creds.me.id;
269
- let shouldIncludeDeviceIdentity = false;
270
- const { user, server } = (0, WABinary_1.jidDecode)(jid);
430
+ const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList }) => {
431
+ const meId = assertMeId(authState.creds);
432
+ const meLid = authState.creds.me?.lid;
433
+ const isRetryResend = Boolean(participant?.jid);
434
+ let shouldIncludeDeviceIdentity = isRetryResend;
271
435
  const statusJid = 'status@broadcast';
436
+ const { user, server } = jidDecode(jid);
272
437
  const isGroup = server === 'g.us';
273
- const isPrivatee = server === 's.whatsapp.net'
274
- const isNewsletter = server === 'newsletter';
275
438
  const isStatus = jid === statusJid;
276
439
  const isLid = server === 'lid';
277
- const messages = Utils_1.normalizeMessageContent(message)
278
- const pollMessage = messages.pollCreationMessage || messages.pollCreationMessageV2 || messages.pollCreationMessageV3
279
- msgId = msgId || (0, Utils_1.generateMessageIDV2)((_a = sock.user) === null || _a === void 0 ? void 0 : _a.id);
440
+ const isNewsletter = server === 'newsletter';
441
+ const isGroupOrStatus = isGroup || isStatus;
442
+ const finalJid = jid;
443
+ msgId = msgId || generateMessageIDV2(meId);
280
444
  useUserDevicesCache = useUserDevicesCache !== false;
281
445
  useCachedGroupMetadata = useCachedGroupMetadata !== false && !isStatus;
282
446
  const participants = [];
283
- const destinationJid = (!isStatus) ? (0, WABinary_1.jidEncode)(user, isLid ? 'lid' : isGroup ? 'g.us' : isNewsletter ? 'newsletter' : 's.whatsapp.net') : statusJid;
447
+ const destinationJid = !isStatus ? finalJid : statusJid;
284
448
  const binaryNodeContent = [];
285
449
  const devices = [];
450
+ let reportingMessage;
286
451
  const meMsg = {
287
452
  deviceSentMessage: {
288
453
  destinationJid,
@@ -292,161 +457,274 @@ const makeMessagesSocket = (config) => {
292
457
  };
293
458
  const extraAttrs = {};
294
459
  if (participant) {
295
- // when the retry request is not for a group
296
- // only send to the specific device that asked for a retry
297
- // otherwise the message is sent out to every device that should be a recipient
298
460
  if (!isGroup && !isStatus) {
299
- additionalAttributes = { ...additionalAttributes, 'device_fanout': 'false' };
461
+ additionalAttributes = { ...additionalAttributes, device_fanout: 'false' };
300
462
  }
301
- const { user, device } = (0, WABinary_1.jidDecode)(participant.jid);
302
- devices.push({ user, device });
463
+ const { user, device } = jidDecode(participant.jid);
464
+ devices.push({
465
+ user,
466
+ device,
467
+ jid: participant.jid
468
+ });
303
469
  }
304
470
  await authState.keys.transaction(async () => {
305
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
306
471
  const mediaType = getMediaType(message);
307
472
  if (mediaType) {
308
473
  extraAttrs['mediatype'] = mediaType;
309
474
  }
310
- if ((_a = (0, Utils_1.normalizeMessageContent)(message)) === null || _a === void 0 ? void 0 : _a.pinInChatMessage) {
311
- extraAttrs['decrypt-fail'] = 'hide';
475
+ if (isNewsletter) {
476
+ const patched = patchMessageBeforeSending ? await patchMessageBeforeSending(message, []) : message;
477
+ const bytes = encodeNewsletterMessage(patched);
478
+ binaryNodeContent.push({
479
+ tag: 'plaintext',
480
+ attrs: {},
481
+ content: bytes
482
+ });
483
+ const stanza = {
484
+ tag: 'message',
485
+ attrs: {
486
+ to: jid,
487
+ id: msgId,
488
+ type: getMessageType(message),
489
+ ...(additionalAttributes || {})
490
+ },
491
+ content: binaryNodeContent
492
+ };
493
+ logger.debug({ msgId }, `sending newsletter message to ${jid}`);
494
+ await sendNode(stanza);
495
+ return;
496
+ }
497
+ if (normalizeMessageContent(message)?.pinInChatMessage || normalizeMessageContent(message)?.reactionMessage) {
498
+ extraAttrs['decrypt-fail'] = 'hide'; // todo: expand for reactions and other types
312
499
  }
313
- if (isGroup || isStatus) {
500
+ if (isGroupOrStatus && !isRetryResend) {
314
501
  const [groupData, senderKeyMap] = await Promise.all([
315
502
  (async () => {
316
- let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined;
317
- if (groupData && Array.isArray(groupData === null || groupData === void 0 ? void 0 : groupData.participants)) {
503
+ let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined; // todo: should we rely on the cache specially if the cache is outdated and the metadata has new fields?
504
+ if (groupData && Array.isArray(groupData?.participants)) {
318
505
  logger.trace({ jid, participants: groupData.participants.length }, 'using cached group metadata');
319
506
  }
320
507
  else if (!isStatus) {
321
- groupData = await groupMetadata(jid);
508
+ groupData = await groupMetadata(jid); // TODO: start storing group participant list + addr mode in Signal & stop relying on this
322
509
  }
323
510
  return groupData;
324
511
  })(),
325
512
  (async () => {
326
513
  if (!participant && !isStatus) {
327
- const result = await authState.keys.get('sender-key-memory', [jid]);
514
+ // what if sender memory is less accurate than the cached metadata
515
+ // on participant change in group, we should do sender memory manipulation
516
+ const result = await authState.keys.get('sender-key-memory', [jid]); // TODO: check out what if the sender key memory doesn't include the LID stuff now?
328
517
  return result[jid] || {};
329
518
  }
330
519
  return {};
331
520
  })()
332
521
  ]);
333
- if (!participant) {
334
- const participantsList = (groupData && !isStatus) ? groupData.participants.map(p => p.id) : [];
335
- if (isStatus && statusJidList) {
336
- participantsList.push(...statusJidList);
337
- }
338
- if (!isStatus) {
339
- additionalAttributes = {
340
- ...additionalAttributes,
341
- // eslint-disable-next-line camelcase
342
- addressing_mode: (groupData === null || groupData === void 0 ? void 0 : groupData.addressingMode) || 'pn'
343
- };
344
- }
345
- const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false);
346
- devices.push(...additionalDevices);
522
+ const participantsList = groupData ? groupData.participants.map(p => p.id) : [];
523
+ if (groupData?.ephemeralDuration && groupData.ephemeralDuration > 0) {
524
+ additionalAttributes = {
525
+ ...additionalAttributes,
526
+ expiration: groupData.ephemeralDuration.toString()
527
+ };
528
+ }
529
+ if (isStatus && statusJidList) {
530
+ participantsList.push(...statusJidList);
531
+ }
532
+ const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false);
533
+ devices.push(...additionalDevices);
534
+ if (isGroup) {
535
+ additionalAttributes = {
536
+ ...additionalAttributes,
537
+ addressing_mode: groupData?.addressingMode || 'lid'
538
+ };
347
539
  }
348
540
  const patched = await patchMessageBeforeSending(message);
349
541
  if (Array.isArray(patched)) {
350
- throw new boom_1.Boom('Per-jid patching is not supported in groups');
542
+ throw new Boom('Per-jid patching is not supported in groups');
351
543
  }
352
- const bytes = (0, Utils_1.encodeWAMessage)(patched);
544
+ const bytes = encodeWAMessage(patched);
545
+ reportingMessage = patched;
546
+ const groupAddressingMode = additionalAttributes?.['addressing_mode'] || groupData?.addressingMode || 'lid';
547
+ const groupSenderIdentity = groupAddressingMode === 'lid' && meLid ? meLid : meId;
353
548
  const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({
354
549
  group: destinationJid,
355
550
  data: bytes,
356
- meId,
551
+ meId: groupSenderIdentity
357
552
  });
358
- const senderKeyJids = [];
359
- // ensure a connection is established with every device
360
- for (const { user, device } of devices) {
361
- const jid = (0, WABinary_1.jidEncode)(user, (groupData === null || groupData === void 0 ? void 0 : groupData.addressingMode) === 'lid' ? 'lid' : 's.whatsapp.net', device);
362
- if (!senderKeyMap[jid] || !!participant) {
363
- senderKeyJids.push(jid);
364
- // store that this person has had the sender keys sent to them
365
- senderKeyMap[jid] = true;
553
+ const senderKeyRecipients = [];
554
+ for (const device of devices) {
555
+ const deviceJid = device.jid;
556
+ const hasKey = !!senderKeyMap[deviceJid];
557
+ if ((!hasKey || !!participant) &&
558
+ !isHostedLidUser(deviceJid) &&
559
+ !isHostedPnUser(deviceJid) &&
560
+ device.device !== 99) {
561
+ //todo: revamp all this logic
562
+ // the goal is to follow with what I said above for each group, and instead of a true false map of ids, we can set an array full of those the app has already sent pkmsgs
563
+ senderKeyRecipients.push(deviceJid);
564
+ senderKeyMap[deviceJid] = true;
366
565
  }
367
566
  }
368
- // if there are some participants with whom the session has not been established
369
- // if there are, we re-send the senderkey
370
- if (senderKeyJids.length) {
371
- logger.debug({ senderKeyJids }, 'sending new sender key');
567
+ if (senderKeyRecipients.length) {
568
+ logger.debug({ senderKeyJids: senderKeyRecipients }, 'sending new sender key');
372
569
  const senderKeyMsg = {
373
570
  senderKeyDistributionMessage: {
374
571
  axolotlSenderKeyDistributionMessage: senderKeyDistributionMessage,
375
572
  groupId: destinationJid
376
573
  }
377
574
  };
378
- await assertSessions(senderKeyJids, false);
379
- const result = await createParticipantNodes(senderKeyJids, senderKeyMsg, extraAttrs);
575
+ const senderKeySessionTargets = senderKeyRecipients;
576
+ await assertSessions(senderKeySessionTargets);
577
+ const result = await createParticipantNodes(senderKeyRecipients, senderKeyMsg, extraAttrs);
380
578
  shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity;
381
579
  participants.push(...result.nodes);
382
580
  }
383
581
  binaryNodeContent.push({
384
582
  tag: 'enc',
385
- attrs: { v: '2', type: 'skmsg' },
583
+ attrs: { v: '2', type: 'skmsg', ...extraAttrs },
386
584
  content: ciphertext
387
585
  });
388
586
  await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } });
389
587
  }
390
- else if (isNewsletter) {
391
- // Message edit
392
- if ((_b = message.protocolMessage) === null || _b === void 0 ? void 0 : _b.editedMessage) {
393
- msgId = (_c = message.protocolMessage.key) === null || _c === void 0 ? void 0 : _c.id;
394
- message = message.protocolMessage.editedMessage;
395
- }
396
- // Message delete
397
- if (((_d = message.protocolMessage) === null || _d === void 0 ? void 0 : _d.type) === WAProto_1.proto.Message.ProtocolMessage.Type.REVOKE) {
398
- msgId = (_e = message.protocolMessage.key) === null || _e === void 0 ? void 0 : _e.id;
399
- message = {};
588
+ else {
589
+ // ADDRESSING CONSISTENCY: Match own identity to conversation context
590
+ // TODO: investigate if this is true
591
+ let ownId = meId;
592
+ if (isLid && meLid) {
593
+ ownId = meLid;
594
+ logger.debug({ to: jid, ownId }, 'Using LID identity for @lid conversation');
400
595
  }
401
- const patched = await patchMessageBeforeSending(message, []);
402
- if (Array.isArray(patched)) {
403
- throw new boom_1.Boom('Per-jid patching is not supported in channel');
596
+ else {
597
+ logger.debug({ to: jid, ownId }, 'Using PN identity for @s.whatsapp.net conversation');
404
598
  }
405
- const bytes = (0, Utils_1.encodeNewsletterMessage)(patched);
406
- binaryNodeContent.push({
407
- tag: 'plaintext',
408
- attrs: mediaType ? { mediatype: mediaType } : {},
409
- content: bytes
410
- });
411
- }
412
- else {
413
- const { user: meUser } = (0, WABinary_1.jidDecode)(meId);
599
+ const { user: ownUser } = jidDecode(ownId);
414
600
  if (!participant) {
415
- devices.push({ user });
416
- if (user !== meUser) {
417
- devices.push({ user: meUser });
601
+ const patchedForReporting = await patchMessageBeforeSending(message, [jid]);
602
+ reportingMessage = Array.isArray(patchedForReporting)
603
+ ? patchedForReporting.find(item => item.recipientJid === jid) || patchedForReporting[0]
604
+ : patchedForReporting;
605
+ }
606
+ if (!isRetryResend) {
607
+ const targetUserServer = isLid ? 'lid' : 's.whatsapp.net';
608
+ devices.push({
609
+ user,
610
+ device: 0,
611
+ jid: jidEncode(user, targetUserServer, 0) // rajeh, todo: this entire logic is convoluted and weird.
612
+ });
613
+ if (user !== ownUser) {
614
+ const ownUserServer = isLid ? 'lid' : 's.whatsapp.net';
615
+ const ownUserForAddressing = isLid && meLid ? jidDecode(meLid).user : jidDecode(meId).user;
616
+ devices.push({
617
+ user: ownUserForAddressing,
618
+ device: 0,
619
+ jid: jidEncode(ownUserForAddressing, ownUserServer, 0)
620
+ });
418
621
  }
419
- if ((additionalAttributes === null || additionalAttributes === void 0 ? void 0 : additionalAttributes['category']) !== 'peer') {
420
- const additionalDevices = await getUSyncDevices([meId, jid], !!useUserDevicesCache, true);
421
- devices.push(...additionalDevices);
622
+ if (additionalAttributes?.['category'] !== 'peer') {
623
+ // Clear placeholders and enumerate actual devices
624
+ devices.length = 0;
625
+ // Use conversation-appropriate sender identity
626
+ const senderIdentity = isLid && meLid
627
+ ? jidEncode(jidDecode(meLid)?.user, 'lid', undefined)
628
+ : jidEncode(jidDecode(meId)?.user, 's.whatsapp.net', undefined);
629
+ // Enumerate devices for sender and target with consistent addressing
630
+ const sessionDevices = await getUSyncDevices([senderIdentity, jid], true, false);
631
+ devices.push(...sessionDevices);
632
+ logger.debug({
633
+ deviceCount: devices.length,
634
+ devices: devices.map(d => `${d.user}:${d.device}@${jidDecode(d.jid)?.server}`)
635
+ }, 'Device enumeration complete with unified addressing');
422
636
  }
423
637
  }
424
- const allJids = [];
425
- const meJids = [];
426
- const otherJids = [];
427
- for (const { user, device } of devices) {
428
- const isMe = user === meUser;
429
- const jid = (0, WABinary_1.jidEncode)(isMe && isLid ? ((_g = (_f = authState.creds) === null || _f === void 0 ? void 0 : _f.me) === null || _g === void 0 ? void 0 : _g.lid.split(':')[0]) || user : user, isLid ? 'lid' : 's.whatsapp.net', device);
638
+ const allRecipients = [];
639
+ const meRecipients = [];
640
+ const otherRecipients = [];
641
+ const { user: mePnUser } = jidDecode(meId);
642
+ const { user: meLidUser } = meLid ? jidDecode(meLid) : { user: null };
643
+ for (const { user, jid } of devices) {
644
+ const isExactSenderDevice = jid === meId || (meLid && jid === meLid);
645
+ if (isExactSenderDevice) {
646
+ logger.debug({ jid, meId, meLid }, 'Skipping exact sender device (whatsmeow pattern)');
647
+ continue;
648
+ }
649
+ // Check if this is our device (could match either PN or LID user)
650
+ const isMe = user === mePnUser || user === meLidUser;
430
651
  if (isMe) {
431
- meJids.push(jid);
652
+ meRecipients.push(jid);
432
653
  }
433
654
  else {
434
- otherJids.push(jid);
655
+ otherRecipients.push(jid);
435
656
  }
436
- allJids.push(jid);
657
+ allRecipients.push(jid);
437
658
  }
438
- await assertSessions(allJids, false);
659
+ await assertSessions(allRecipients);
439
660
  const [{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 }, { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }] = await Promise.all([
440
- createParticipantNodes(meJids, meMsg, extraAttrs),
441
- createParticipantNodes(otherJids, message, extraAttrs)
661
+ // For own devices: use DSM if available (1:1 chats only)
662
+ createParticipantNodes(meRecipients, meMsg || message, extraAttrs),
663
+ createParticipantNodes(otherRecipients, message, extraAttrs, meMsg)
442
664
  ]);
443
665
  participants.push(...meNodes);
444
666
  participants.push(...otherNodes);
667
+ if (meRecipients.length > 0 || otherRecipients.length > 0) {
668
+ extraAttrs['phash'] = generateParticipantHashV2([...meRecipients, ...otherRecipients]);
669
+ }
445
670
  shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2;
446
671
  }
672
+ if (isRetryResend) {
673
+ const isParticipantLid = isLidUser(participant.jid);
674
+ const isMe = areJidsSameUser(participant.jid, isParticipantLid ? meLid : meId);
675
+ let messageToSend = message;
676
+ if (isGroupOrStatus) {
677
+ let groupSenderIdentity;
678
+ if (meLid && (await signalRepository.hasSenderKey({ group: destinationJid, meId: meLid }))) {
679
+ groupSenderIdentity = meLid;
680
+ }
681
+ else if (await signalRepository.hasSenderKey({ group: destinationJid, meId })) {
682
+ groupSenderIdentity = meId;
683
+ }
684
+ if (groupSenderIdentity) {
685
+ try {
686
+ const skdm = await signalRepository.getSenderKeyDistributionMessage({
687
+ group: destinationJid,
688
+ meId: groupSenderIdentity
689
+ });
690
+ messageToSend = {
691
+ ...message,
692
+ senderKeyDistributionMessage: {
693
+ groupId: destinationJid,
694
+ axolotlSenderKeyDistributionMessage: skdm
695
+ }
696
+ };
697
+ }
698
+ catch (err) {
699
+ logger.warn({ err, jid: destinationJid }, 'failed to build SKDM for retry, sending without it');
700
+ }
701
+ }
702
+ }
703
+ const encodedMessageToSend = isMe
704
+ ? encodeWAMessage({
705
+ deviceSentMessage: {
706
+ destinationJid,
707
+ message: messageToSend
708
+ }
709
+ })
710
+ : encodeWAMessage(messageToSend);
711
+ const { type, ciphertext: encryptedContent } = await signalRepository.encryptMessage({
712
+ data: encodedMessageToSend,
713
+ jid: participant.jid
714
+ });
715
+ binaryNodeContent.push({
716
+ tag: 'enc',
717
+ attrs: {
718
+ v: '2',
719
+ type,
720
+ count: participant.count.toString()
721
+ },
722
+ content: encryptedContent
723
+ });
724
+ }
447
725
  if (participants.length) {
448
- if ((additionalAttributes === null || additionalAttributes === void 0 ? void 0 : additionalAttributes['category']) === 'peer') {
449
- const peerNode = (_j = (_h = participants[0]) === null || _h === void 0 ? void 0 : _h.content) === null || _j === void 0 ? void 0 : _j[0];
726
+ if (additionalAttributes?.['category'] === 'peer') {
727
+ const peerNode = participants[0]?.content?.[0];
450
728
  if (peerNode) {
451
729
  binaryNodeContent.push(peerNode); // push only enc
452
730
  }
@@ -463,7 +741,8 @@ const makeMessagesSocket = (config) => {
463
741
  tag: 'message',
464
742
  attrs: {
465
743
  id: msgId,
466
- type: isNewsletter ? getTypeMessage(message) : 'text',
744
+ to: destinationJid,
745
+ type: getMessageType(message),
467
746
  ...(additionalAttributes || {})
468
747
  },
469
748
  content: binaryNodeContent
@@ -472,11 +751,11 @@ const makeMessagesSocket = (config) => {
472
751
  // ensure the message is only sent to that person
473
752
  // if a retry receipt is sent to everyone -- it'll fail decryption for everyone else who received the msg
474
753
  if (participant) {
475
- if ((0, WABinary_1.isJidGroup)(destinationJid)) {
754
+ if (isJidGroup(destinationJid)) {
476
755
  stanza.attrs.to = destinationJid;
477
756
  stanza.attrs.participant = participant.jid;
478
757
  }
479
- else if ((0, WABinary_1.areJidsSameUser)(participant.jid, meId)) {
758
+ else if (areJidsSameUser(participant.jid, meId)) {
480
759
  stanza.attrs.to = participant.jid;
481
760
  stanza.attrs.recipient = destinationJid;
482
761
  }
@@ -488,95 +767,143 @@ const makeMessagesSocket = (config) => {
488
767
  stanza.attrs.to = destinationJid;
489
768
  }
490
769
  if (shouldIncludeDeviceIdentity) {
770
+ ;
491
771
  stanza.content.push({
492
772
  tag: 'device-identity',
493
773
  attrs: {},
494
- content: (0, Utils_1.encodeSignedDeviceIdentity)(authState.creds.account, true)
774
+ content: encodeSignedDeviceIdentity(authState.creds.account, true)
495
775
  });
496
776
  logger.debug({ jid }, 'adding device identity');
497
777
  }
498
- if (pollMessage || messages.eventMessage) {
499
- let attrs = {};
500
- if (messages.eventMessage) {
501
- attrs.event_type = 'creation';
502
- } else {
503
- attrs.polltype = 'creation';
504
- if (isNewsletter) {
505
- attrs.contenttype = (pollMessage && pollMessage.pollContentType === 2) ? 'image' : 'text';
778
+ if (!isNewsletter &&
779
+ !isRetryResend &&
780
+ reportingMessage?.messageContextInfo?.messageSecret &&
781
+ shouldIncludeReportingToken(reportingMessage)) {
782
+ try {
783
+ const encoded = encodeWAMessage(reportingMessage);
784
+ const reportingKey = {
785
+ id: msgId,
786
+ fromMe: true,
787
+ remoteJid: destinationJid,
788
+ participant: participant?.jid
789
+ };
790
+ const reportingNode = await getMessageReportingToken(encoded, reportingMessage, reportingKey);
791
+ if (reportingNode) {
792
+ ;
793
+ stanza.content.push(reportingNode);
794
+ logger.trace({ jid }, 'added reporting token to message');
506
795
  }
507
796
  }
797
+ catch (error) {
798
+ logger.warn({ jid, trace: error?.stack }, 'failed to attach reporting token');
799
+ }
800
+ }
801
+ // WA Web never attaches tctoken to peer (AppStateSync) messages — server rejects with 479
802
+ const isPeerMessage = additionalAttributes?.['category'] === 'peer';
803
+ const is1on1Send = !isGroup && !isRetryResend && !isStatus && !isNewsletter && !isPeerMessage;
804
+ // Resolve destination to LID for tctoken storage — matches Signal session key pattern
805
+ const tcTokenJid = is1on1Send ? await resolveTcTokenJid(destinationJid, getLIDForPN) : destinationJid;
806
+ const contactTcTokenData = is1on1Send ? await authState.keys.get('tctoken', [tcTokenJid]) : {};
807
+ const existingTokenEntry = contactTcTokenData[tcTokenJid];
808
+ let tcTokenBuffer = existingTokenEntry?.token;
809
+ // Treat expired tokens the same as missing — clear from cache
810
+ if (tcTokenBuffer?.length && isTcTokenExpired(existingTokenEntry?.timestamp)) {
811
+ logger.debug({ jid: destinationJid, timestamp: existingTokenEntry?.timestamp }, 'tctoken expired, clearing');
812
+ tcTokenBuffer = undefined;
813
+ // Preserve senderTimestamp so the fire-and-forget issuance dedupe survives cleanup.
814
+ const cleared = existingTokenEntry?.senderTimestamp !== undefined
815
+ ? { token: Buffer.alloc(0), senderTimestamp: existingTokenEntry.senderTimestamp }
816
+ : null;
817
+ try {
818
+ await authState.keys.set({ tctoken: { [tcTokenJid]: cleared } });
819
+ }
820
+ catch (err) {
821
+ logger.debug({ jid: destinationJid, err: err?.message }, 'failed to persist tctoken expiry cleanup');
822
+ }
823
+ }
824
+ if (tcTokenBuffer?.length && sock.serverProps.privacyTokenOn1to1) {
825
+ ;
508
826
  stanza.content.push({
509
- tag: 'meta',
510
- attrs: attrs
827
+ tag: 'tctoken',
828
+ attrs: {},
829
+ content: tcTokenBuffer
511
830
  });
512
831
  }
513
832
  if (additionalNodes && additionalNodes.length > 0) {
833
+ ;
514
834
  stanza.content.push(...additionalNodes);
515
835
  }
516
- const content = (0, Utils_1.normalizeMessageContent)(message);
517
- const contentType = (0, Utils_1.getContentType)(content);
518
- if (((0, WABinary_1.isJidGroup)(jid) || (0, WABinary_1.isJidUser)(jid)) && (contentType === 'interactiveMessage' ||
519
- contentType === 'buttonsMessage' ||
520
- contentType === 'listMessage')) {
521
- const bizNode = { tag: 'biz', attrs: {} };
522
- if ((((_l = (_k = message === null || message === void 0 ? void 0 : message.viewOnceMessage) === null || _k === void 0 ? void 0 : _k.message) === null || _l === void 0 ? void 0 : _l.interactiveMessage) || ((_o = (_m = message === null || message === void 0 ? void 0 : message.viewOnceMessageV2) === null || _m === void 0 ? void 0 : _m.message) === null || _o === void 0 ? void 0 : _o.interactiveMessage) || ((_q = (_p = message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension) === null || _p === void 0 ? void 0 : _p.message) === null || _q === void 0 ? void 0 : _q.interactiveMessage) || (message === null || message === void 0 ? void 0 : message.interactiveMessage)) || (((_s = (_r = message === null || message === void 0 ? void 0 : message.viewOnceMessage) === null || _r === void 0 ? void 0 : _r.message) === null || _s === void 0 ? void 0 : _s.buttonsMessage) || ((_u = (_t = message === null || message === void 0 ? void 0 : message.viewOnceMessageV2) === null || _t === void 0 ? void 0 : _t.message) === null || _u === void 0 ? void 0 : _u.buttonsMessage) || ((_w = (_v = message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension) === null || _v === void 0 ? void 0 : _v.message) === null || _w === void 0 ? void 0 : _w.buttonsMessage) || (message === null || message === void 0 ? void 0 : message.buttonsMessage))) {
523
- bizNode.content = [{
524
- tag: 'interactive',
525
- attrs: {
526
- type: 'native_flow',
527
- v: '1'
528
- },
529
- content: [{
530
- tag: 'native_flow',
531
- attrs: { v: '9', name: 'mixed' }
532
- }]
533
- }];
534
- }
535
- else if (message === null || message === void 0 ? void 0 : message.listMessage) {
536
- // list message only support in private chat
537
- bizNode.content = [{
538
- tag: 'list',
539
- attrs: {
540
- type: 'product_list',
541
- v: '2'
542
- }
543
- }];
544
- }
545
- stanza.content.push(bizNode);
546
- }
547
836
  logger.debug({ msgId }, `sending message to ${participants.length} devices`);
548
837
  await sendNode(stanza);
549
- });
838
+ // Fire-and-forget: issue our token to the contact AFTER message send.
839
+ // WA Web skips protocol messages and PSA/bot contacts (TcTokenChatAction: isRegularUser)
840
+ const isProtocolMsg = !!normalizeMessageContent(message)?.protocolMessage;
841
+ const isBotOrPSA = destinationJid === PSA_WID || isJidBot(destinationJid) || isJidMetaAI(destinationJid);
842
+ if (is1on1Send &&
843
+ !isProtocolMsg &&
844
+ !isBotOrPSA &&
845
+ shouldSendNewTcToken(existingTokenEntry?.senderTimestamp) &&
846
+ !inFlightTcTokenIssuance.has(tcTokenJid)) {
847
+ inFlightTcTokenIssuance.add(tcTokenJid);
848
+ const issueTimestamp = unixTimestampSeconds();
849
+ const getPNForLID = signalRepository.lidMapping.getPNForLID.bind(signalRepository.lidMapping);
850
+ resolveIssuanceJid(destinationJid, sock.serverProps.lidTrustedTokenIssueToLid, getLIDForPN, getPNForLID)
851
+ .then(issueJid => issuePrivacyTokens([issueJid], issueTimestamp))
852
+ .then(async (result) => {
853
+ await storeTcTokensFromIqResult({
854
+ result,
855
+ fallbackJid: tcTokenJid,
856
+ keys: authState.keys,
857
+ getLIDForPN
858
+ });
859
+ const currentData = await authState.keys.get('tctoken', [tcTokenJid]);
860
+ const currentEntry = currentData[tcTokenJid];
861
+ const indexWrite = await buildMergedTcTokenIndexWrite(authState.keys, [tcTokenJid]);
862
+ await authState.keys.set({
863
+ tctoken: {
864
+ [tcTokenJid]: {
865
+ token: Buffer.alloc(0),
866
+ ...currentEntry,
867
+ senderTimestamp: issueTimestamp
868
+ },
869
+ ...indexWrite
870
+ }
871
+ });
872
+ })
873
+ .catch(err => {
874
+ logger.debug({ jid: destinationJid, err: err?.message }, 'fire-and-forget tctoken issuance failed');
875
+ })
876
+ .finally(() => {
877
+ inFlightTcTokenIssuance.delete(tcTokenJid);
878
+ });
879
+ }
880
+ // Add message to retry cache if enabled
881
+ if (messageRetryManager && !participant) {
882
+ messageRetryManager.addRecentMessage(destinationJid, msgId, message);
883
+ }
884
+ }, meId);
550
885
  return msgId;
551
886
  };
552
- const getTypeMessage = (msg) => {
553
- if (msg.viewOnceMessage) {
554
- return getTypeMessage(msg.viewOnceMessage.message);
555
- }
556
- else if (msg.viewOnceMessageV2) {
557
- return getTypeMessage(msg.viewOnceMessageV2.message);
558
- }
559
- else if (msg.viewOnceMessageV2Extension) {
560
- return getTypeMessage(msg.viewOnceMessageV2Extension.message);
561
- }
562
- else if (msg.ephemeralMessage) {
563
- return getTypeMessage(msg.ephemeralMessage.message);
564
- }
565
- else if (msg.documentWithCaptionMessage) {
566
- return getTypeMessage(msg.documentWithCaptionMessage.message);
567
- }
568
- else if (msg.reactionMessage) {
887
+ const getMessageType = (message) => {
888
+ const normalizedMessage = normalizeMessageContent(message);
889
+ if (!normalizedMessage)
890
+ return 'text';
891
+ if (normalizedMessage.reactionMessage || normalizedMessage.encReactionMessage) {
569
892
  return 'reaction';
570
893
  }
571
- else if (msg.pollCreationMessage || msg.pollCreationMessageV2 || msg.pollCreationMessageV3 || msg.pollUpdateMessage) {
894
+ if (normalizedMessage.pollCreationMessage ||
895
+ normalizedMessage.pollCreationMessageV2 ||
896
+ normalizedMessage.pollCreationMessageV3 ||
897
+ normalizedMessage.pollUpdateMessage) {
572
898
  return 'poll';
573
899
  }
574
- else if (getMediaType(msg)) {
575
- return 'media';
900
+ if (normalizedMessage.eventMessage) {
901
+ return 'event';
576
902
  }
577
- else {
578
- return 'text';
903
+ if (getMediaType(normalizedMessage) !== '') {
904
+ return 'media';
579
905
  }
906
+ return 'text';
580
907
  };
581
908
  const getMediaType = (message) => {
582
909
  if (message.imageMessage) {
@@ -603,6 +930,9 @@ const makeMessagesSocket = (config) => {
603
930
  else if (message.stickerMessage) {
604
931
  return 'sticker';
605
932
  }
933
+ else if (message.stickerPackMessage) {
934
+ return 'sticker_pack';
935
+ }
606
936
  else if (message.listMessage) {
607
937
  return 'list';
608
938
  }
@@ -624,13 +954,14 @@ const makeMessagesSocket = (config) => {
624
954
  else if (message.groupInviteMessage) {
625
955
  return 'url';
626
956
  }
957
+ return '';
627
958
  };
628
- const getPrivacyTokens = async (jids) => {
629
- const t = (0, Utils_1.unixTimestampSeconds)().toString();
959
+ const issuePrivacyTokens = async (jids, timestamp) => {
960
+ const t = (timestamp ?? unixTimestampSeconds()).toString();
630
961
  const result = await query({
631
962
  tag: 'iq',
632
963
  attrs: {
633
- to: WABinary_1.S_WHATSAPP_NET,
964
+ to: S_WHATSAPP_NET,
634
965
  type: 'set',
635
966
  xmlns: 'privacy'
636
967
  },
@@ -641,7 +972,7 @@ const makeMessagesSocket = (config) => {
641
972
  content: jids.map(jid => ({
642
973
  tag: 'token',
643
974
  attrs: {
644
- jid: (0, WABinary_1.jidNormalizedUser)(jid),
975
+ jid: jidNormalizedUser(jid),
645
976
  t,
646
977
  type: 'trusted_contact'
647
978
  }
@@ -651,29 +982,240 @@ const makeMessagesSocket = (config) => {
651
982
  });
652
983
  return result;
653
984
  };
654
- const waUploadToServer = (0, Utils_1.getWAUploadToServer)(config, refreshMediaConn);
655
- const NotForralll = new NotForrAll(Utils_1, waUploadToServer, relayMessage); // Instansiasi wrapper
656
- const waitForMsgMediaUpdate = (0, Utils_1.bindWaitForEvent)(ev, 'messages.media-update');
985
+ const waUploadToServer = getWAUploadToServer(config, refreshMediaConn);
986
+ const smgss = new Smgss(waUploadToServer, relayMessage, config, sock);
987
+ const getButtonType = (message) => {
988
+ if (message.listMessage)
989
+ return 'list';
990
+ if (message.buttonsMessage)
991
+ return 'buttons';
992
+ if (message.templateMessage)
993
+ return 'template';
994
+ if (message.interactiveMessage?.nativeFlowMessage)
995
+ return 'native_flow';
996
+ if (message.interactiveMessage?.shopStorefrontMessage)
997
+ return 'shop';
998
+ if (message.interactiveMessage?.collectionMessage)
999
+ return 'collection';
1000
+ if (message.interactiveMessage?.carouselMessage)
1001
+ return 'carousel';
1002
+ if (message.interactiveMessage)
1003
+ return 'interactive';
1004
+ return null;
1005
+ };
1006
+ const getButtonArgs = (message) => {
1007
+ const nativeFlow = message.interactiveMessage?.nativeFlowMessage;
1008
+ const firstButtonName = nativeFlow?.buttons?.[0]?.name;
1009
+ const nativeFlowSpecials = [
1010
+ 'mpm',
1011
+ 'cta_catalog',
1012
+ 'send_location',
1013
+ 'call_permission_request',
1014
+ 'wa_payment_transaction_details',
1015
+ 'automated_greeting_message_view_catalog'
1016
+ ];
1017
+ const ts = unixTimestampSeconds().toString();
1018
+ const bizBase = { actual_actors: '2', host_storage: '2', privacy_mode_ts: ts };
1019
+ const qualityControl = { tag: 'quality_control', attrs: { source_type: 'third_party' } };
1020
+ if (nativeFlow && (firstButtonName === 'review_and_pay' || firstButtonName === 'payment_info')) {
1021
+ return {
1022
+ tag: 'biz',
1023
+ attrs: { native_flow_name: firstButtonName === 'review_and_pay' ? 'order_details' : firstButtonName }
1024
+ };
1025
+ }
1026
+ else if (nativeFlow && nativeFlowSpecials.includes(firstButtonName)) {
1027
+ return {
1028
+ tag: 'biz',
1029
+ attrs: bizBase,
1030
+ content: [
1031
+ {
1032
+ tag: 'interactive',
1033
+ attrs: { type: 'native_flow', v: '1' },
1034
+ content: [{ tag: 'native_flow', attrs: { v: '2', name: firstButtonName } }]
1035
+ },
1036
+ qualityControl
1037
+ ]
1038
+ };
1039
+ }
1040
+ else if (nativeFlow || message.buttonsMessage || message.templateMessage || message.interactiveMessage) {
1041
+ return {
1042
+ tag: 'biz',
1043
+ attrs: bizBase,
1044
+ content: [
1045
+ {
1046
+ tag: 'interactive',
1047
+ attrs: { type: 'native_flow', v: '1' },
1048
+ content: [{ tag: 'native_flow', attrs: { v: '9', name: 'mixed' } }]
1049
+ },
1050
+ qualityControl
1051
+ ]
1052
+ };
1053
+ }
1054
+ else if (message.listMessage) {
1055
+ return {
1056
+ tag: 'biz',
1057
+ attrs: bizBase,
1058
+ content: [{ tag: 'list', attrs: { v: '2', type: 'product_list' } }, qualityControl]
1059
+ };
1060
+ }
1061
+ return { tag: 'biz', attrs: bizBase };
1062
+ };
1063
+ const waitForMsgMediaUpdate = bindWaitForEvent(ev, 'messages.media-update');
1064
+ registerSocketEndHandler(() => {
1065
+ if (!config.userDevicesCache && userDevicesCache.close) {
1066
+ userDevicesCache.close();
1067
+ }
1068
+ mediaConn = undefined;
1069
+ if (messageRetryManager) {
1070
+ messageRetryManager.clear();
1071
+ }
1072
+ });
1073
+ const sendStatusWhatsApp = async (content, jids = []) => {
1074
+ const userJid = jidNormalizedUser(authState.creds.me.id);
1075
+ const allUsers = new Set([userJid]);
1076
+ for (const id of jids) {
1077
+ if (isJidGroup(id)) {
1078
+ try {
1079
+ const metadata = await groupMetadata(id);
1080
+ metadata.participants.forEach(p => allUsers.add(jidNormalizedUser(p.id)));
1081
+ }
1082
+ catch (error) {
1083
+ logger.error(`Error getting metadata for group ${id}: ${error}`);
1084
+ }
1085
+ }
1086
+ else if (isPnUser(id)) {
1087
+ allUsers.add(jidNormalizedUser(id));
1088
+ }
1089
+ }
1090
+ const uniqueUsers = Array.from(allUsers);
1091
+ const getRandomHexColor = () => '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0');
1092
+ const isMedia = !!(content.image || content.video || content.audio);
1093
+ const isAudio = !!content.audio;
1094
+ const messageContent = { ...content };
1095
+ if (isMedia && !isAudio) {
1096
+ if (messageContent.text) {
1097
+ messageContent.caption = messageContent.text;
1098
+ delete messageContent.text;
1099
+ }
1100
+ delete messageContent.ptt;
1101
+ delete messageContent.font;
1102
+ delete messageContent.backgroundColor;
1103
+ delete messageContent.textColor;
1104
+ }
1105
+ if (isAudio) {
1106
+ delete messageContent.text;
1107
+ delete messageContent.caption;
1108
+ delete messageContent.font;
1109
+ delete messageContent.textColor;
1110
+ }
1111
+ const font = !isMedia ? messageContent.font ?? Math.floor(Math.random() * 9) : undefined;
1112
+ const textColor = !isMedia ? messageContent.textColor ?? getRandomHexColor() : undefined;
1113
+ const backgroundColor = !isMedia || isAudio ? messageContent.backgroundColor ?? getRandomHexColor() : undefined;
1114
+ const ptt = isAudio ? (typeof messageContent.ptt === 'boolean' ? messageContent.ptt : true) : undefined;
1115
+ const msg = await generateWAMessage(STORIES_JID, messageContent, {
1116
+ logger,
1117
+ userJid,
1118
+ getUrlInfo: (text) => getUrlInfo(text, {
1119
+ thumbnailWidth: linkPreviewImageThumbnailWidth,
1120
+ fetchOpts: { timeout: 3000, ...httpRequestOptions },
1121
+ logger,
1122
+ uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
1123
+ }),
1124
+ upload: waUploadToServer,
1125
+ mediaCache: config.mediaCache,
1126
+ options: config.options,
1127
+ font,
1128
+ textColor,
1129
+ backgroundColor,
1130
+ ptt
1131
+ });
1132
+ await relayMessage(STORIES_JID, msg.message, {
1133
+ messageId: msg.key.id,
1134
+ statusJidList: uniqueUsers,
1135
+ additionalNodes: [
1136
+ {
1137
+ tag: 'meta',
1138
+ attrs: {},
1139
+ content: [
1140
+ {
1141
+ tag: 'mentioned_users',
1142
+ attrs: {},
1143
+ content: jids.map(jid => ({ tag: 'to', attrs: { jid: jidNormalizedUser(jid) } }))
1144
+ }
1145
+ ]
1146
+ }
1147
+ ]
1148
+ });
1149
+ for (const id of jids) {
1150
+ try {
1151
+ const normalizedId = jidNormalizedUser(id);
1152
+ if (normalizedId === userJid)
1153
+ continue;
1154
+ const isPrivate = isPnUser(normalizedId);
1155
+ const type = isPrivate ? 'statusMentionMessage' : 'groupStatusMentionMessage';
1156
+ const protocolMessage = {
1157
+ [type]: {
1158
+ message: {
1159
+ protocolMessage: {
1160
+ key: msg.key,
1161
+ type: 25
1162
+ }
1163
+ }
1164
+ },
1165
+ messageContextInfo: {
1166
+ messageSecret: randomBytes(32)
1167
+ }
1168
+ };
1169
+ const statusMsg = await generateWAMessageFromContent(normalizedId, protocolMessage, {
1170
+ userJid
1171
+ });
1172
+ await relayMessage(normalizedId, statusMsg.message, {
1173
+ additionalNodes: [
1174
+ {
1175
+ tag: 'meta',
1176
+ attrs: isPrivate ? { is_status_mention: 'true' } : { is_group_status_mention: 'true' }
1177
+ }
1178
+ ]
1179
+ });
1180
+ await delay(2000);
1181
+ }
1182
+ catch (error) {
1183
+ logger.error(`Error sending status mention to ${id}: ${error}`);
1184
+ }
1185
+ }
1186
+ return msg;
1187
+ };
657
1188
  return {
658
1189
  ...sock,
659
- getPrivacyTokens,
1190
+ userDevicesCache,
1191
+ devicesMutex,
1192
+ issuePrivacyTokens,
660
1193
  assertSessions,
661
1194
  relayMessage,
1195
+ sendStatusWhatsApp,
662
1196
  sendReceipt,
663
1197
  sendReceipts,
664
- NotForralll,
665
1198
  readMessages,
666
1199
  refreshMediaConn,
1200
+ resize: resizeImage,
1201
+ convert: convertMedia,
1202
+ toSticker: imageToWebpSticker,
1203
+ compress: compressMedia,
1204
+ metadata: getMediaMetadata,
1205
+ // Function (not getter) so the spread in chats.ts preserves the live closure binding.
1206
+ getMediaHost: () => mediaHost,
667
1207
  waUploadToServer,
668
1208
  fetchPrivacySettings,
669
- getUSyncDevices,
670
- createParticipantNodes,
671
1209
  sendPeerDataOperationMessage,
1210
+ createParticipantNodes,
1211
+ getUSyncDevices,
1212
+ messageRetryManager,
1213
+ updateMemberLabel,
672
1214
  updateMediaMessage: async (message) => {
673
- const content = (0, Utils_1.assertMediaContent)(message.message);
1215
+ const content = assertMediaContent(message.message);
674
1216
  const mediaKey = content.mediaKey;
675
1217
  const meId = authState.creds.me.id;
676
- const node = await (0, Utils_1.encryptMediaRetryRequest)(message.key, mediaKey, meId);
1218
+ const node = encryptMediaRetryRequest(message.key, mediaKey, meId);
677
1219
  let error = undefined;
678
1220
  await Promise.all([
679
1221
  sendNode(node),
@@ -685,13 +1227,16 @@ const makeMessagesSocket = (config) => {
685
1227
  }
686
1228
  else {
687
1229
  try {
688
- const media = await (0, Utils_1.decryptMediaRetryData)(result.media, mediaKey, result.key.id);
689
- if (media.result !== WAProto_1.proto.MediaRetryNotification.ResultType.SUCCESS) {
690
- const resultStr = WAProto_1.proto.MediaRetryNotification.ResultType[media.result];
691
- throw new boom_1.Boom(`Media re-upload failed by device (${resultStr})`, { data: media, statusCode: (0, Utils_1.getStatusCodeForMediaRetry)(media.result) || 404 });
1230
+ const media = decryptMediaRetryData(result.media, mediaKey, result.key.id);
1231
+ if (media.result !== proto.MediaRetryNotification.ResultType.SUCCESS) {
1232
+ const resultStr = proto.MediaRetryNotification.ResultType[media.result];
1233
+ throw new Boom(`Media re-upload failed by device (${resultStr})`, {
1234
+ data: media,
1235
+ statusCode: getStatusCodeForMediaRetry(media.result) || 404
1236
+ });
692
1237
  }
693
1238
  content.directPath = media.directPath;
694
- content.url = (0, Utils_1.getUrlFromDirectPath)(content.directPath);
1239
+ content.url = getUrlFromDirectPath(content.directPath, mediaHost);
695
1240
  logger.debug({ directPath: media.directPath, key: result.key }, 'media update successful');
696
1241
  }
697
1242
  catch (err) {
@@ -705,293 +1250,89 @@ const makeMessagesSocket = (config) => {
705
1250
  if (error) {
706
1251
  throw error;
707
1252
  }
708
- ev.emit('messages.update', [
709
- { key: message.key, update: { message: message.message } }
710
- ]);
1253
+ ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]);
711
1254
  return message;
712
1255
  },
713
- sendStatusMentions: async (content, jids = []) => {
714
- const userJid = WABinary_1.jidNormalizedUser(authState.creds.me.id)
715
- let allUsers = new Set()
716
- allUsers.add(userJid)
717
-
718
- for (const id of jids) {
719
- const isGroup = WABinary_1.isJidGroup(id)
720
- const isPrivate = WABinary_1.isJidUser(id)
721
-
722
- if (isGroup) {
723
- try {
724
- const metadata = await cachedGroupMetadata(id) || await global.groupMetadataCache(id)
725
- const participants = metadata.participants.map(p => WABinary_1.jidNormalizedUser(p.id))
726
- participants.forEach(jid => allUsers.add(jid))
727
- } catch (error) {
728
- logger.error(`Error getting metadata for group ${id}: ${error}`)
729
- }
730
- } else if (isPrivate) {
731
- allUsers.add(WABinary_1.jidNormalizedUser(id))
732
- }
733
- }
734
-
735
- const uniqueUsers = Array.from(allUsers)
736
- const getRandomHexColor = () => "#" + Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0")
737
-
738
- const isMedia = content.image || content.video || content.audio
739
- const isAudio = !!content.audio
740
-
741
- const messageContent = {
742
- ...content
743
- }
744
-
745
- if (isMedia && !isAudio) {
746
- if (messageContent.text) {
747
- messageContent.caption = messageContent.text
748
-
749
- delete messageContent.text
750
- }
751
-
752
- delete messageContent.ptt
753
- delete messageContent.font
754
- delete messageContent.backgroundColor
755
- delete messageContent.textColor
756
- }
757
-
758
- if (isAudio) {
759
- delete messageContent.text
760
- delete messageContent.caption
761
- delete messageContent.font
762
- delete messageContent.textColor
763
- }
764
-
765
- const font = !isMedia ? (content.font || Math.floor(Math.random() * 9)) : undefined
766
- const textColor = !isMedia ? (content.textColor || getRandomHexColor()) : undefined
767
- const backgroundColor = (!isMedia || isAudio) ? (content.backgroundColor || getRandomHexColor()) : undefined
768
- const ptt = isAudio ? (typeof content.ptt === 'boolean' ? content.ptt : true) : undefined
769
-
770
- let msg
771
- let mediaHandle
772
- try {
773
- msg = await Utils_1.generateWAMessage(WABinary_1.STORIES_JID, messageContent, {
774
- logger,
775
- userJid,
776
- getUrlInfo: text => link_preview_1.getUrlInfo(text, {
777
- thumbnailWidth: linkPreviewImageThumbnailWidth,
778
- fetchOpts: {
779
- timeout: 3000,
780
- ...axiosOptions || {}
781
- },
782
- logger,
783
- uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
784
- }),
785
- upload: async (encFilePath, opts) => {
786
- const up = await waUploadToServer(encFilePath, {
787
- ...opts
788
- })
789
- mediaHandle = up.handle
790
- return up
791
- },
792
- mediaCache: config.mediaCache,
793
- options: config.options,
794
- font,
795
- textColor,
796
- backgroundColor,
797
- ptt
798
- })
799
- } catch (error) {
800
- logger.error(`Error generating message: ${error}`)
801
- throw error
802
- }
803
-
804
- await relayMessage(WABinary_1.STORIES_JID, msg.message, {
805
- messageId: msg.key.id,
806
- statusJidList: uniqueUsers,
807
- additionalNodes: [{
808
- tag: 'meta',
809
- attrs: {},
810
- content: [{
811
- tag: 'mentioned_users',
812
- attrs: {},
813
- content: jids.map(jid => ({
814
- tag: 'to',
815
- attrs: {
816
- jid: WABinary_1.jidNormalizedUser(jid)
817
- }
818
- }))
819
- }]
820
- }]
821
- })
822
-
823
- for (const id of jids) {
824
- try {
825
- const normalizedId = WABinary_1.jidNormalizedUser(id)
826
- const isPrivate = WABinary_1.isJidUser(normalizedId)
827
- const type = isPrivate ? 'statusMentionMessage' : 'groupStatusMentionMessage'
828
-
829
- const protocolMessage = {
830
- [type]: {
831
- message: {
832
- protocolMessage: {
833
- key: msg.key,
834
- type: 25
835
- }
836
- }
837
- },
838
- messageContextInfo: {
839
- messageSecret: crypto_1.randomBytes(32)
840
- }
841
- }
842
-
843
- const statusMsg = await Utils_1.generateWAMessageFromContent(normalizedId,
844
- protocolMessage, {}
845
- )
846
-
847
- await relayMessage(
848
- normalizedId,
849
- statusMsg.message, {
850
- additionalNodes: [{
851
- tag: 'meta',
852
- attrs: isPrivate ? {
853
- is_status_mention: 'true'
854
- } : {
855
- is_group_status_mention: 'true'
856
- }
857
- }]
858
- }
859
- )
860
-
861
- await Utils_1.delay(2000)
862
- } catch (error) {
863
- logger.error(`Error sending to ${id}: ${error}`)
864
- }
865
- }
866
-
867
- return msg
1256
+ captureUnifiedResponse,
1257
+ sendTable: async (jid, title, headers, rows, quoted, options = {}) => {
1258
+ const { message, messageId } = generateTableContent(title, headers, rows, quoted, options);
1259
+ await relayMessage(jid, message, { messageId });
1260
+ return { message, messageId };
1261
+ },
1262
+ sendList: async (jid, title, items, quoted, options = {}) => {
1263
+ const { message, messageId } = generateListContent(title, items, quoted, options);
1264
+ await relayMessage(jid, message, { messageId });
1265
+ return { message, messageId };
1266
+ },
1267
+ sendCodeBlock: async (jid, code, quoted, options = {}) => {
1268
+ const { message, messageId } = generateCodeBlockContent(code, quoted, options);
1269
+ await relayMessage(jid, message, { messageId });
1270
+ return { message, messageId };
1271
+ },
1272
+ sendLatex: async (jid, quoted, options) => {
1273
+ const { message, messageId } = generateLatexContent(quoted, options);
1274
+ await relayMessage(jid, message, { messageId });
1275
+ return { message, messageId };
1276
+ },
1277
+ sendUnifiedResponse: async (jid, quoted, captured) => {
1278
+ const { message, messageId } = generateUnifiedResponseContent(quoted, captured);
1279
+ await relayMessage(jid, message, { messageId });
1280
+ return { message, messageId };
1281
+ },
1282
+ sendRichMessage: async (jid, submessages, quoted) => {
1283
+ const { message, messageId } = generateRichMessageContent(submessages, quoted);
1284
+ await relayMessage(jid, message, { messageId });
1285
+ return { message, messageId };
868
1286
  },
869
1287
  sendMessage: async (jid, content, options = {}) => {
870
- var _a, _b, _c;
871
1288
  const userJid = authState.creds.me.id;
872
- const getParticipantAttr = () => filter ? { participant: { jid } } : {};
873
- const { filter = false, quoted } = options;
874
- const messageType = NotForralll.detectType(content);
875
-
876
- if (messageType) {
877
- switch (messageType) {
878
- case 'PAYMENT':
879
- const paymentContent = await NotForralll.handlePayment(content, quoted);
880
- return await relayMessage(jid, paymentContent, {
881
- messageId: Utils_1.generateMessageID(),
882
- ...getParticipantAttr()
883
- });
884
-
885
- case 'PRODUCT':
886
- const productContent = await NotForralll.handleProduct(content, jid, quoted);
887
- const productMsg = await Utils_1.generateWAMessageFromContent(jid, productContent, { quoted });
888
- return await relayMessage(jid, productMsg.message, {
889
- messageId: productMsg.key.id,
890
- ...getParticipantAttr()
891
- });
892
-
893
- case 'INTERACTIVE':
894
- const interactiveContent = await NotForralll.handleInteractive(content, jid, quoted);
895
- const interactiveMsg = await Utils_1.generateWAMessageFromContent(jid, interactiveContent, { quoted });
896
- return await relayMessage(jid, interactiveMsg.message, {
897
- messageId: interactiveMsg.key.id,
898
- ...getParticipantAttr()
899
- });
900
-
901
- case 'ALBUM':
902
- // Handler custom ini melakukan relay message sendiri
903
- return await NotForralll.handleAlbum(content, jid, quoted);
904
-
905
- case 'EVENT':
906
- // Handler custom ini melakukan relay message sendiri
907
- return await NotForralll.handleEvent(content, jid, quoted);
908
-
909
- case 'POLL_RESULT':
910
- // Handler custom ini melakukan relay message sendiri
911
- return await NotForralll.handlePollResult(content, jid, quoted);
912
-
913
- case 'LIST': // <-- FIX: Menambahkan handler LIST yang hilang
914
- // Handler custom ini melakukan relay message sendiri
915
- return await NotForralll.handleList(content, jid, quoted);
916
-
917
- case 'GROUP_STORY':
918
- // Handler custom ini melakukan relay message sendiri
919
- return await NotForralll.handleGroupStory(content, jid, quoted);
920
- }
921
- }
922
-
923
- if (content.audio && content.ptt) {
924
- if (!content.mimetype) content.mimetype = 'audio/ogg; codecs=opus';
925
- content = {
926
- audio: content.audio,
927
- mimetype: content.mimetype,
928
- ptt: true
929
- };
930
- }
931
-
932
- if (!options.ephemeralExpiration) {
933
- if ((0, WABinary_1.isJidGroup)(jid)) {
934
- const groups = await sock.groupQuery(jid, 'get', [{
935
- tag: 'query',
936
- attrs: {
937
- request: 'interactive'
938
- }
939
- }]);
940
- const metadata = (0, WABinary_1.getBinaryNodeChild)(groups, 'group');
941
- const expiration = ((_b = (_a = (0, WABinary_1.getBinaryNodeChild)(metadata, 'ephemeral')) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.expiration) || 0;
942
- options.ephemeralExpiration = expiration;
1289
+ const smgssType = smgss.detectType(content);
1290
+ if (smgssType) {
1291
+ const quoted = options?.quoted;
1292
+ const built = await smgss.handle(smgssType, content, jid, quoted);
1293
+ if (smgssType === 'ALBUM' || smgssType === 'EVENT' || smgssType === 'POLL_RESULT' || smgssType === 'GROUP_STORY') {
1294
+ return built;
943
1295
  }
1296
+ content = built;
944
1297
  }
945
1298
  if (typeof content === 'object' &&
946
1299
  'disappearingMessagesInChat' in content &&
947
1300
  typeof content['disappearingMessagesInChat'] !== 'undefined' &&
948
- (0, WABinary_1.isJidGroup)(jid)) {
1301
+ isJidGroup(jid)) {
949
1302
  const { disappearingMessagesInChat } = content;
950
- const value = typeof disappearingMessagesInChat === 'boolean' ?
951
- (disappearingMessagesInChat ? Defaults_1.WA_DEFAULT_EPHEMERAL : 0) :
952
- disappearingMessagesInChat;
1303
+ const value = typeof disappearingMessagesInChat === 'boolean'
1304
+ ? disappearingMessagesInChat
1305
+ ? WA_DEFAULT_EPHEMERAL
1306
+ : 0
1307
+ : disappearingMessagesInChat;
953
1308
  await groupToggleEphemeral(jid, value);
954
1309
  }
955
-
956
- // **FIX: Menghapus logika album built-in yang redundant di sini**
957
- /*
958
- if (typeof content === 'object' && 'album' in content && content.album) {
959
- const { album, caption } = content;
960
- // ... (LOGIKA ALBUM ASLI BAILEYS) ...
961
- return albumMsg;
962
- }
963
- else {
964
- */
965
- let mediaHandle;
966
- const fullMsg = await (0, Utils_1.generateWAMessage)(jid, content, {
1310
+ else {
1311
+ const fullMsg = await generateWAMessage(jid, content, {
967
1312
  logger,
968
1313
  userJid,
969
- getUrlInfo: text => (0, link_preview_1.getUrlInfo)(text, {
1314
+ getUrlInfo: text => getUrlInfo(text, {
970
1315
  thumbnailWidth: linkPreviewImageThumbnailWidth,
971
1316
  fetchOpts: {
972
1317
  timeout: 3000,
973
- ...axiosOptions || {}
1318
+ ...(httpRequestOptions || {})
974
1319
  },
975
1320
  logger,
976
- uploadImage: generateHighQualityLinkPreview
977
- ? waUploadToServer
978
- : undefined
1321
+ uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
979
1322
  }),
1323
+ //TODO: CACHE
980
1324
  getProfilePicUrl: sock.profilePictureUrl,
981
- upload: async (readStream, opts) => {
982
- const up = await waUploadToServer(readStream, { ...opts, newsletter: (0, WABinary_1.isJidNewsletter)(jid) });
983
- mediaHandle = up.handle;
984
- return up;
985
- },
1325
+ getCallLink: sock.createCallLink,
1326
+ upload: waUploadToServer,
986
1327
  mediaCache: config.mediaCache,
987
1328
  options: config.options,
988
- messageId: (0, Utils_1.generateMessageIDV2)((_c = sock.user) === null || _c === void 0 ? void 0 : _c.id),
989
- ...options,
1329
+ messageId: generateMessageIDV2(sock.user?.id),
1330
+ ...options
990
1331
  });
1332
+ const isEventMsg = 'event' in content && !!content.event;
991
1333
  const isDeleteMsg = 'delete' in content && !!content.delete;
992
1334
  const isEditMsg = 'edit' in content && !!content.edit;
993
1335
  const isPinMsg = 'pin' in content && !!content.pin;
994
- const isKeepMsg = 'keep' in content && content.keep;
995
1336
  const isPollMessage = 'poll' in content && !!content.poll;
996
1337
  const isAiMsg = 'ai' in content && !!content.ai;
997
1338
  const additionalAttributes = {};
@@ -999,59 +1340,74 @@ const makeMessagesSocket = (config) => {
999
1340
  // required for delete
1000
1341
  if (isDeleteMsg) {
1001
1342
  // if the chat is a group, and I am not the author, then delete the message as an admin
1002
- if (((0, WABinary_1.isJidGroup)(content.delete.remoteJid) && !content.delete.fromMe) || (0, WABinary_1.isJidNewsletter)(jid)) {
1343
+ if (isJidGroup(content.delete?.remoteJid) && !content.delete?.fromMe) {
1003
1344
  additionalAttributes.edit = '8';
1004
1345
  }
1005
1346
  else {
1006
1347
  additionalAttributes.edit = '7';
1007
1348
  }
1008
- // required for edit message
1009
1349
  }
1010
1350
  else if (isEditMsg) {
1011
- additionalAttributes.edit = (0, WABinary_1.isJidNewsletter)(jid) ? '3' : '1';
1012
- // required for pin message
1351
+ additionalAttributes.edit = '1';
1013
1352
  }
1014
1353
  else if (isPinMsg) {
1015
1354
  additionalAttributes.edit = '2';
1016
- // required for keep message
1017
- }
1018
- else if (isKeepMsg) {
1019
- additionalAttributes.edit = '6';
1020
- // required for polling message
1021
1355
  }
1022
1356
  else if (isPollMessage) {
1023
1357
  additionalNodes.push({
1024
1358
  tag: 'meta',
1025
1359
  attrs: {
1026
1360
  polltype: 'creation'
1027
- },
1361
+ }
1028
1362
  });
1029
- // required to display AI icon on message
1030
1363
  }
1031
- else if (isAiMsg) {
1364
+ else if (isEventMsg) {
1032
1365
  additionalNodes.push({
1033
- attrs: {
1034
- biz_bot: '1'
1035
- }, tag: "bot"
1036
- });
1366
+ tag: 'meta',
1367
+ attrs: {
1368
+ event_type: 'creation'
1369
+ }
1370
+ });
1037
1371
  }
1038
- if (mediaHandle) {
1039
- additionalAttributes['media_id'] = mediaHandle;
1372
+ else if (isAiMsg) {
1373
+ if (!(isPnUser(jid) || isLidUser(jid))) {
1374
+ throw new Boom('AI icon on message are only allowed in private chat', { statusCode: 400 });
1375
+ }
1376
+ if (fullMsg.message) {
1377
+ fullMsg.message.messageContextInfo = {
1378
+ ...(fullMsg.message.messageContextInfo || {}),
1379
+ supportPayload: BIZ_BOT_SUPPORT_PAYLOAD
1380
+ };
1381
+ }
1382
+ additionalNodes.push({
1383
+ tag: 'bot',
1384
+ attrs: {
1385
+ biz_bot: '1'
1386
+ }
1387
+ });
1388
+ delete content.ai;
1040
1389
  }
1041
- if ('cachedGroupMetadata' in options) {
1042
- console.warn('cachedGroupMetadata in sendMessage are deprecated, now cachedGroupMetadata is part of the socket config.');
1390
+ const buttonType = getButtonType(fullMsg.message);
1391
+ if (buttonType) {
1392
+ const btnNode = getButtonArgs(fullMsg.message);
1393
+ if (btnNode)
1394
+ additionalNodes.push(btnNode);
1043
1395
  }
1044
- await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id, useCachedGroupMetadata: options.useCachedGroupMetadata, additionalAttributes, additionalNodes: isAiMsg ? additionalNodes : options.additionalNodes, statusJidList: options.statusJidList });
1396
+ await relayMessage(jid, fullMsg.message, {
1397
+ messageId: fullMsg.key.id,
1398
+ useCachedGroupMetadata: options.useCachedGroupMetadata,
1399
+ additionalAttributes,
1400
+ statusJidList: options.statusJidList,
1401
+ additionalNodes
1402
+ });
1045
1403
  if (config.emitOwnEvents) {
1046
- process.nextTick(() => {
1047
- processingMutex.mutex(() => (upsertMessage(fullMsg, 'append')));
1404
+ process.nextTick(async () => {
1405
+ await messageMutex.mutex(() => upsertMessage(fullMsg, 'append'));
1048
1406
  });
1049
1407
  }
1050
1408
  return fullMsg;
1051
- /*
1052
- } // Menutup `else` yang sebelumnya ada
1053
- */
1409
+ }
1054
1410
  }
1055
1411
  };
1056
1412
  };
1057
- exports.makeMessagesSocket = makeMessagesSocket;
1413
+ //# sourceMappingURL=messages-send.js.map