violetics 7.0.7-alpha → 7.0.8-alpha

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 (411) hide show
  1. package/LICENSE +1 -2
  2. package/README.md +456 -978
  3. package/WAProto/GenerateStatics.sh +3 -0
  4. package/WAProto/WAProto.proto +5479 -0
  5. package/WAProto/fix-imports.js +81 -0
  6. package/WAProto/index.d.ts +14017 -0
  7. package/WAProto/index.js +2670 -9199
  8. package/engine-requirements.js +7 -10
  9. package/index.cjs +196 -0
  10. package/index.d.ts +30 -0
  11. package/lib/Defaults/index.d.ts +74 -0
  12. package/lib/Defaults/index.d.ts.map +1 -0
  13. package/lib/Defaults/index.js +14 -22
  14. package/lib/Defaults/index.js.map +1 -0
  15. package/lib/Defaults/phonenumber-mcc.json +223 -0
  16. package/lib/Signal/Group/ciphertext-message.d.ts +10 -0
  17. package/lib/Signal/Group/ciphertext-message.d.ts.map +1 -0
  18. package/lib/Signal/Group/ciphertext-message.js +2 -1
  19. package/lib/Signal/Group/ciphertext-message.js.map +1 -0
  20. package/lib/Signal/Group/group-session-builder.d.ts +15 -0
  21. package/lib/Signal/Group/group-session-builder.d.ts.map +1 -0
  22. package/lib/Signal/Group/group-session-builder.js +2 -1
  23. package/lib/Signal/Group/group-session-builder.js.map +1 -0
  24. package/lib/Signal/Group/group_cipher.d.ts +17 -0
  25. package/lib/Signal/Group/group_cipher.d.ts.map +1 -0
  26. package/lib/Signal/Group/group_cipher.js +2 -1
  27. package/lib/Signal/Group/group_cipher.js.map +1 -0
  28. package/lib/Signal/Group/index.d.ts +12 -0
  29. package/lib/Signal/Group/index.d.ts.map +1 -0
  30. package/lib/Signal/Group/index.js +2 -1
  31. package/lib/Signal/Group/index.js.map +1 -0
  32. package/lib/Signal/Group/keyhelper.d.ts +11 -0
  33. package/lib/Signal/Group/keyhelper.d.ts.map +1 -0
  34. package/lib/Signal/Group/keyhelper.js +2 -1
  35. package/lib/Signal/Group/keyhelper.js.map +1 -0
  36. package/lib/Signal/Group/sender-chain-key.d.ts +14 -0
  37. package/lib/Signal/Group/sender-chain-key.d.ts.map +1 -0
  38. package/lib/Signal/Group/sender-chain-key.js +2 -1
  39. package/lib/Signal/Group/sender-chain-key.js.map +1 -0
  40. package/lib/Signal/Group/sender-key-distribution-message.d.ts +17 -0
  41. package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -0
  42. package/lib/Signal/Group/sender-key-distribution-message.js +2 -1
  43. package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -0
  44. package/lib/Signal/Group/sender-key-message.d.ts +19 -0
  45. package/lib/Signal/Group/sender-key-message.d.ts.map +1 -0
  46. package/lib/Signal/Group/sender-key-message.js +2 -1
  47. package/lib/Signal/Group/sender-key-message.js.map +1 -0
  48. package/lib/Signal/Group/sender-key-name.d.ts +18 -0
  49. package/lib/Signal/Group/sender-key-name.d.ts.map +1 -0
  50. package/lib/Signal/Group/sender-key-name.js +2 -1
  51. package/lib/Signal/Group/sender-key-name.js.map +1 -0
  52. package/lib/Signal/Group/sender-key-record.d.ts +31 -0
  53. package/lib/Signal/Group/sender-key-record.d.ts.map +1 -0
  54. package/lib/Signal/Group/sender-key-record.js +2 -1
  55. package/lib/Signal/Group/sender-key-record.js.map +1 -0
  56. package/lib/Signal/Group/sender-key-state.d.ts +39 -0
  57. package/lib/Signal/Group/sender-key-state.d.ts.map +1 -0
  58. package/lib/Signal/Group/sender-key-state.js +2 -1
  59. package/lib/Signal/Group/sender-key-state.js.map +1 -0
  60. package/lib/Signal/Group/sender-message-key.d.ts +12 -0
  61. package/lib/Signal/Group/sender-message-key.d.ts.map +1 -0
  62. package/lib/Signal/Group/sender-message-key.js +2 -1
  63. package/lib/Signal/Group/sender-message-key.js.map +1 -0
  64. package/lib/Signal/libsignal.d.ts +5 -0
  65. package/lib/Signal/libsignal.d.ts.map +1 -0
  66. package/lib/Signal/libsignal.js +44 -8
  67. package/lib/Signal/libsignal.js.map +1 -0
  68. package/lib/Signal/lid-mapping.d.ts +19 -0
  69. package/lib/Signal/lid-mapping.d.ts.map +1 -0
  70. package/lib/Signal/lid-mapping.js +2 -1
  71. package/lib/Signal/lid-mapping.js.map +1 -0
  72. package/lib/Socket/Client/index.d.ts +3 -0
  73. package/lib/Socket/Client/index.d.ts.map +1 -0
  74. package/lib/Socket/Client/index.js +2 -1
  75. package/lib/Socket/Client/index.js.map +1 -0
  76. package/lib/Socket/Client/types.d.ts +16 -0
  77. package/lib/Socket/Client/types.d.ts.map +1 -0
  78. package/lib/Socket/Client/types.js +2 -1
  79. package/lib/Socket/Client/types.js.map +1 -0
  80. package/lib/Socket/Client/websocket.d.ts +13 -0
  81. package/lib/Socket/Client/websocket.d.ts.map +1 -0
  82. package/lib/Socket/Client/websocket.js +2 -1
  83. package/lib/Socket/Client/websocket.js.map +1 -0
  84. package/lib/Socket/business.d.ts +202 -0
  85. package/lib/Socket/business.d.ts.map +1 -0
  86. package/lib/Socket/business.js +2 -1
  87. package/lib/Socket/business.js.map +1 -0
  88. package/lib/Socket/chats.d.ts +111 -0
  89. package/lib/Socket/chats.d.ts.map +1 -0
  90. package/lib/Socket/chats.js +154 -69
  91. package/lib/Socket/chats.js.map +1 -0
  92. package/lib/Socket/communities.d.ts +258 -0
  93. package/lib/Socket/communities.d.ts.map +1 -0
  94. package/lib/Socket/communities.js +2 -1
  95. package/lib/Socket/communities.js.map +1 -0
  96. package/lib/Socket/community.js +361 -0
  97. package/lib/Socket/groups.d.ts +150 -0
  98. package/lib/Socket/groups.d.ts.map +1 -0
  99. package/lib/Socket/groups.js +140 -9
  100. package/lib/Socket/groups.js.map +1 -0
  101. package/lib/Socket/index.d.ts +245 -0
  102. package/lib/Socket/index.d.ts.map +1 -0
  103. package/lib/Socket/index.js +2 -1
  104. package/lib/Socket/index.js.map +1 -0
  105. package/lib/Socket/messages-recv.d.ts +187 -0
  106. package/lib/Socket/messages-recv.d.ts.map +1 -0
  107. package/lib/Socket/messages-recv.js +471 -253
  108. package/lib/Socket/messages-recv.js.map +1 -0
  109. package/lib/Socket/messages-send.d.ts +183 -0
  110. package/lib/Socket/messages-send.d.ts.map +1 -0
  111. package/lib/Socket/messages-send.js +620 -226
  112. package/lib/Socket/messages-send.js.map +1 -0
  113. package/lib/Socket/mex.d.ts +3 -0
  114. package/lib/Socket/mex.d.ts.map +1 -0
  115. package/lib/Socket/mex.js +2 -1
  116. package/lib/Socket/mex.js.map +1 -0
  117. package/lib/Socket/newsletter.d.ts +160 -0
  118. package/lib/Socket/newsletter.d.ts.map +1 -0
  119. package/lib/Socket/newsletter.js +109 -62
  120. package/lib/Socket/newsletter.js.map +1 -0
  121. package/lib/Socket/socket.d.ts +55 -0
  122. package/lib/Socket/socket.d.ts.map +1 -0
  123. package/lib/Socket/socket.js +12 -3
  124. package/lib/Socket/socket.js.map +1 -0
  125. package/lib/Socket/usync.js +76 -0
  126. package/lib/Store/index.js +2 -1
  127. package/lib/Store/make-cache-manager-store.js +77 -0
  128. package/lib/Store/make-in-memory-store.js +44 -65
  129. package/lib/Store/make-ordered-dictionary.js +1 -1
  130. package/lib/Store/object-repository.js +1 -1
  131. package/lib/Types/Auth.d.ts +116 -0
  132. package/lib/Types/Auth.d.ts.map +1 -0
  133. package/lib/Types/Auth.js +2 -1
  134. package/lib/Types/Auth.js.map +1 -0
  135. package/lib/Types/Bussines.d.ts +25 -0
  136. package/lib/Types/Bussines.d.ts.map +1 -0
  137. package/lib/Types/Bussines.js +2 -1
  138. package/lib/Types/Bussines.js.map +1 -0
  139. package/lib/Types/Call.d.ts +15 -0
  140. package/lib/Types/Call.d.ts.map +1 -0
  141. package/lib/Types/Call.js +2 -1
  142. package/lib/Types/Call.js.map +1 -0
  143. package/lib/Types/Chat.d.ts +123 -0
  144. package/lib/Types/Chat.d.ts.map +1 -0
  145. package/lib/Types/Chat.js +2 -1
  146. package/lib/Types/Chat.js.map +1 -0
  147. package/lib/Types/Contact.d.ts +24 -0
  148. package/lib/Types/Contact.d.ts.map +1 -0
  149. package/lib/Types/Contact.js +2 -1
  150. package/lib/Types/Contact.js.map +1 -0
  151. package/lib/Types/Events.d.ts +237 -0
  152. package/lib/Types/Events.d.ts.map +1 -0
  153. package/lib/Types/Events.js +2 -1
  154. package/lib/Types/Events.js.map +1 -0
  155. package/lib/Types/GroupMetadata.d.ts +67 -0
  156. package/lib/Types/GroupMetadata.d.ts.map +1 -0
  157. package/lib/Types/GroupMetadata.js +2 -1
  158. package/lib/Types/GroupMetadata.js.map +1 -0
  159. package/lib/Types/Label.d.ts +47 -0
  160. package/lib/Types/Label.d.ts.map +1 -0
  161. package/lib/Types/Label.js +2 -1
  162. package/lib/Types/Label.js.map +1 -0
  163. package/lib/Types/LabelAssociation.d.ts +30 -0
  164. package/lib/Types/LabelAssociation.d.ts.map +1 -0
  165. package/lib/Types/LabelAssociation.js +2 -1
  166. package/lib/Types/LabelAssociation.js.map +1 -0
  167. package/lib/Types/Message.d.ts +305 -0
  168. package/lib/Types/Message.d.ts.map +1 -0
  169. package/lib/Types/Message.js +2 -8
  170. package/lib/Types/Message.js.map +1 -0
  171. package/lib/Types/MexUpdates.js +9 -0
  172. package/lib/Types/Newsletter.d.ts +135 -0
  173. package/lib/Types/Newsletter.d.ts.map +1 -0
  174. package/lib/Types/Newsletter.js +14 -4
  175. package/lib/Types/Newsletter.js.map +1 -0
  176. package/lib/Types/Product.d.ts +79 -0
  177. package/lib/Types/Product.d.ts.map +1 -0
  178. package/lib/Types/Product.js +2 -1
  179. package/lib/Types/Product.js.map +1 -0
  180. package/lib/Types/Signal.d.ts +76 -0
  181. package/lib/Types/Signal.d.ts.map +1 -0
  182. package/lib/Types/Signal.js +2 -1
  183. package/lib/Types/Signal.js.map +1 -0
  184. package/lib/Types/Socket.d.ts +133 -0
  185. package/lib/Types/Socket.d.ts.map +1 -0
  186. package/lib/Types/Socket.js +2 -1
  187. package/lib/Types/Socket.js.map +1 -0
  188. package/lib/Types/State.d.ts +39 -0
  189. package/lib/Types/State.d.ts.map +1 -0
  190. package/lib/Types/State.js +2 -1
  191. package/lib/Types/State.js.map +1 -0
  192. package/lib/Types/USync.d.ts +26 -0
  193. package/lib/Types/USync.d.ts.map +1 -0
  194. package/lib/Types/USync.js +2 -1
  195. package/lib/Types/USync.js.map +1 -0
  196. package/lib/Types/index.d.ts +65 -0
  197. package/lib/Types/index.d.ts.map +1 -0
  198. package/lib/Types/index.js +3 -1
  199. package/lib/Types/index.js.map +1 -0
  200. package/lib/Utils/audioToBuffer.js +31 -0
  201. package/lib/Utils/auth-utils.d.ts +19 -0
  202. package/lib/Utils/auth-utils.d.ts.map +1 -0
  203. package/lib/Utils/auth-utils.js +2 -1
  204. package/lib/Utils/auth-utils.js.map +1 -0
  205. package/lib/Utils/baileys-event-stream.js +54 -0
  206. package/lib/Utils/browser-utils.d.ts +4 -0
  207. package/lib/Utils/browser-utils.d.ts.map +1 -0
  208. package/lib/Utils/browser-utils.js +35 -22
  209. package/lib/Utils/browser-utils.js.map +1 -0
  210. package/lib/Utils/business.d.ts +23 -0
  211. package/lib/Utils/business.d.ts.map +1 -0
  212. package/lib/Utils/business.js +2 -1
  213. package/lib/Utils/business.js.map +1 -0
  214. package/lib/Utils/chat-utils.d.ts +70 -0
  215. package/lib/Utils/chat-utils.d.ts.map +1 -0
  216. package/lib/Utils/chat-utils.js +2 -1
  217. package/lib/Utils/chat-utils.js.map +1 -0
  218. package/lib/Utils/crypto.d.ts +37 -0
  219. package/lib/Utils/crypto.d.ts.map +1 -0
  220. package/lib/Utils/crypto.js +2 -1
  221. package/lib/Utils/crypto.js.map +1 -0
  222. package/lib/Utils/decode-wa-message.d.ts +48 -0
  223. package/lib/Utils/decode-wa-message.d.ts.map +1 -0
  224. package/lib/Utils/decode-wa-message.js +2 -1
  225. package/lib/Utils/decode-wa-message.js.map +1 -0
  226. package/lib/Utils/event-buffer.d.ts +34 -0
  227. package/lib/Utils/event-buffer.d.ts.map +1 -0
  228. package/lib/Utils/event-buffer.js +2 -1
  229. package/lib/Utils/event-buffer.js.map +1 -0
  230. package/lib/Utils/generics.d.ts +91 -0
  231. package/lib/Utils/generics.d.ts.map +1 -0
  232. package/lib/Utils/generics.js +34 -6
  233. package/lib/Utils/generics.js.map +1 -0
  234. package/lib/Utils/history.d.ts +22 -0
  235. package/lib/Utils/history.d.ts.map +1 -0
  236. package/lib/Utils/history.js +2 -1
  237. package/lib/Utils/history.js.map +1 -0
  238. package/lib/Utils/identity-change-handler.d.ts +37 -0
  239. package/lib/Utils/identity-change-handler.d.ts.map +1 -0
  240. package/lib/Utils/identity-change-handler.js +2 -1
  241. package/lib/Utils/identity-change-handler.js.map +1 -0
  242. package/lib/Utils/index.d.ts +22 -0
  243. package/lib/Utils/index.d.ts.map +1 -0
  244. package/lib/Utils/index.js +7 -1
  245. package/lib/Utils/index.js.map +1 -0
  246. package/lib/Utils/link-preview.d.ts +21 -0
  247. package/lib/Utils/link-preview.d.ts.map +1 -0
  248. package/lib/Utils/link-preview.js +2 -1
  249. package/lib/Utils/link-preview.js.map +1 -0
  250. package/lib/Utils/logger.d.ts +13 -0
  251. package/lib/Utils/logger.d.ts.map +1 -0
  252. package/lib/Utils/logger.js +2 -1
  253. package/lib/Utils/logger.js.map +1 -0
  254. package/lib/Utils/lt-hash.d.ts +8 -0
  255. package/lib/Utils/lt-hash.d.ts.map +1 -0
  256. package/lib/Utils/lt-hash.js +2 -1
  257. package/lib/Utils/lt-hash.js.map +1 -0
  258. package/lib/Utils/make-mutex.d.ts +9 -0
  259. package/lib/Utils/make-mutex.d.ts.map +1 -0
  260. package/lib/Utils/make-mutex.js +2 -1
  261. package/lib/Utils/make-mutex.js.map +1 -0
  262. package/lib/Utils/message-retry-manager.d.ts +110 -0
  263. package/lib/Utils/message-retry-manager.d.ts.map +1 -0
  264. package/lib/Utils/message-retry-manager.js +2 -1
  265. package/lib/Utils/message-retry-manager.js.map +1 -0
  266. package/lib/Utils/messages-media.d.ts +130 -0
  267. package/lib/Utils/messages-media.d.ts.map +1 -0
  268. package/lib/Utils/messages-media.js +185 -185
  269. package/lib/Utils/messages-media.js.map +1 -0
  270. package/lib/Utils/messages-newsletter.d.ts +84 -0
  271. package/lib/Utils/messages-newsletter.js +316 -0
  272. package/lib/Utils/messages.d.ts +92 -0
  273. package/lib/Utils/messages.d.ts.map +1 -0
  274. package/lib/Utils/messages.js +932 -1120
  275. package/lib/Utils/messages.js.map +1 -0
  276. package/lib/Utils/noise-handler.d.ts +20 -0
  277. package/lib/Utils/noise-handler.d.ts.map +1 -0
  278. package/lib/Utils/noise-handler.js +2 -1
  279. package/lib/Utils/noise-handler.js.map +1 -0
  280. package/lib/Utils/pre-key-manager.d.ts +28 -0
  281. package/lib/Utils/pre-key-manager.d.ts.map +1 -0
  282. package/lib/Utils/pre-key-manager.js +2 -1
  283. package/lib/Utils/pre-key-manager.js.map +1 -0
  284. package/lib/Utils/process-message.d.ts +60 -0
  285. package/lib/Utils/process-message.d.ts.map +1 -0
  286. package/lib/Utils/process-message.js +2 -1
  287. package/lib/Utils/process-message.js.map +1 -0
  288. package/lib/Utils/reporting-utils.d.ts +11 -0
  289. package/lib/Utils/reporting-utils.d.ts.map +1 -0
  290. package/lib/Utils/reporting-utils.js +2 -1
  291. package/lib/Utils/reporting-utils.js.map +1 -0
  292. package/lib/Utils/resolve-jid.d.ts +43 -0
  293. package/lib/Utils/resolve-jid.js +101 -0
  294. package/lib/Utils/signal.d.ts +34 -0
  295. package/lib/Utils/signal.d.ts.map +1 -0
  296. package/lib/Utils/signal.js +2 -1
  297. package/lib/Utils/signal.js.map +1 -0
  298. package/lib/Utils/streamToBuffer.js +17 -0
  299. package/lib/Utils/sync-action-utils.d.ts +19 -0
  300. package/lib/Utils/sync-action-utils.d.ts.map +1 -0
  301. package/lib/Utils/sync-action-utils.js +2 -1
  302. package/lib/Utils/sync-action-utils.js.map +1 -0
  303. package/lib/Utils/tc-token-utils.d.ts +12 -0
  304. package/lib/Utils/tc-token-utils.d.ts.map +1 -0
  305. package/lib/Utils/tc-token-utils.js +2 -1
  306. package/lib/Utils/tc-token-utils.js.map +1 -0
  307. package/lib/Utils/use-mongo-file-auth-state.js +77 -0
  308. package/lib/Utils/use-multi-file-auth-state.d.ts +13 -0
  309. package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
  310. package/lib/Utils/use-multi-file-auth-state.js +2 -1
  311. package/lib/Utils/use-multi-file-auth-state.js.map +1 -0
  312. package/lib/Utils/use-single-file-auth-state.js +55 -77
  313. package/lib/Utils/validate-connection.d.ts +11 -0
  314. package/lib/Utils/validate-connection.d.ts.map +1 -0
  315. package/lib/Utils/validate-connection.js +4 -10
  316. package/lib/Utils/validate-connection.js.map +1 -0
  317. package/lib/WABinary/constants.d.ts +28 -0
  318. package/lib/WABinary/constants.d.ts.map +1 -0
  319. package/lib/WABinary/constants.js +2 -1
  320. package/lib/WABinary/constants.js.map +1 -0
  321. package/lib/WABinary/decode.d.ts +7 -0
  322. package/lib/WABinary/decode.d.ts.map +1 -0
  323. package/lib/WABinary/decode.js +2 -1
  324. package/lib/WABinary/decode.js.map +1 -0
  325. package/lib/WABinary/encode.d.ts +3 -0
  326. package/lib/WABinary/encode.d.ts.map +1 -0
  327. package/lib/WABinary/encode.js +2 -1
  328. package/lib/WABinary/encode.js.map +1 -0
  329. package/lib/WABinary/generic-utils.d.ts +15 -0
  330. package/lib/WABinary/generic-utils.d.ts.map +1 -0
  331. package/lib/WABinary/generic-utils.js +14 -113
  332. package/lib/WABinary/generic-utils.js.map +1 -0
  333. package/lib/WABinary/index.d.ts +6 -0
  334. package/lib/WABinary/index.d.ts.map +1 -0
  335. package/lib/WABinary/index.js +3 -1
  336. package/lib/WABinary/index.js.map +1 -0
  337. package/lib/WABinary/jid-utils.d.ts +48 -0
  338. package/lib/WABinary/jid-utils.d.ts.map +1 -0
  339. package/lib/WABinary/jid-utils.js +5 -2
  340. package/lib/WABinary/jid-utils.js.map +1 -0
  341. package/lib/WABinary/types.d.ts +19 -0
  342. package/lib/WABinary/types.d.ts.map +1 -0
  343. package/lib/WABinary/types.js +2 -1
  344. package/lib/WABinary/types.js.map +1 -0
  345. package/lib/WAM/BinaryInfo.d.ts +9 -0
  346. package/lib/WAM/BinaryInfo.d.ts.map +1 -0
  347. package/lib/WAM/BinaryInfo.js +2 -1
  348. package/lib/WAM/BinaryInfo.js.map +1 -0
  349. package/lib/WAM/constants.d.ts +40 -0
  350. package/lib/WAM/constants.d.ts.map +1 -0
  351. package/lib/WAM/constants.js +2 -1
  352. package/lib/WAM/constants.js.map +1 -0
  353. package/lib/WAM/encode.d.ts +3 -0
  354. package/lib/WAM/encode.d.ts.map +1 -0
  355. package/lib/WAM/encode.js +2 -1
  356. package/lib/WAM/encode.js.map +1 -0
  357. package/lib/WAM/index.d.ts +4 -0
  358. package/lib/WAM/index.d.ts.map +1 -0
  359. package/lib/WAM/index.js +2 -1
  360. package/lib/WAM/index.js.map +1 -0
  361. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +10 -0
  362. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -0
  363. package/lib/WAUSync/Protocols/USyncContactProtocol.js +2 -1
  364. package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -0
  365. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +23 -0
  366. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +1 -0
  367. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +2 -1
  368. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +1 -0
  369. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +13 -0
  370. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +1 -0
  371. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +2 -1
  372. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +1 -0
  373. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +13 -0
  374. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +1 -0
  375. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +2 -1
  376. package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +1 -0
  377. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +26 -0
  378. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +1 -0
  379. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +2 -1
  380. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +1 -0
  381. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +10 -0
  382. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +1 -0
  383. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +2 -1
  384. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +1 -0
  385. package/lib/WAUSync/Protocols/index.d.ts +5 -0
  386. package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
  387. package/lib/WAUSync/Protocols/index.js +3 -1
  388. package/lib/WAUSync/Protocols/index.js.map +1 -0
  389. package/lib/WAUSync/USyncQuery.d.ts +29 -0
  390. package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
  391. package/lib/WAUSync/USyncQuery.js +2 -1
  392. package/lib/WAUSync/USyncQuery.js.map +1 -0
  393. package/lib/WAUSync/USyncUser.d.ts +13 -0
  394. package/lib/WAUSync/USyncUser.d.ts.map +1 -0
  395. package/lib/WAUSync/USyncUser.js +2 -1
  396. package/lib/WAUSync/USyncUser.js.map +1 -0
  397. package/lib/WAUSync/index.d.ts +4 -0
  398. package/lib/WAUSync/index.d.ts.map +1 -0
  399. package/lib/WAUSync/index.js +2 -1
  400. package/lib/WAUSync/index.js.map +1 -0
  401. package/lib/index.d.ts +12 -0
  402. package/lib/index.d.ts.map +1 -0
  403. package/lib/index.js +22 -2
  404. package/lib/index.js.map +1 -0
  405. package/package.json +75 -53
  406. package/.github/workflows/publish.yml +0 -75
  407. package/.pnp.cjs +0 -8572
  408. package/.pnp.loader.mjs +0 -2126
  409. package/.yarn/install-state.gz +0 -0
  410. package/lib/Utils/offline-node-processor.js +0 -39
  411. package/lib/Utils/stanza-ack.js +0 -37
@@ -2,20 +2,24 @@ import NodeCache from '@cacheable/node-cache';
2
2
  import { Boom } from '@hapi/boom';
3
3
  import { randomBytes } from 'crypto';
4
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, bindWaitForEvent, decryptMediaRetryData, delay, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateParticipantHashV2, generateWAMessageFromContent, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, hasValidAlbumMedia, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, shouldIncludeBizBinaryNode, unixTimestampSeconds } from '../Utils/index.js';
7
- import { AssociationType } from '../Types/index.js';
5
+ import { DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
6
+ import { aggregateMessageKeysNotFromMe, assertMediaContent, bindWaitForEvent, decryptMediaRetryData, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateParticipantHashV2, generateWAMessage, generateWAMessageFromContent, prepareWAMessageMedia, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils/index.js';
8
7
  import { getUrlInfo } from '../Utils/link-preview.js';
9
8
  import { makeKeyedMutex } from '../Utils/make-mutex.js';
10
9
  import { getMessageReportingToken, shouldIncludeReportingToken } from '../Utils/reporting-utils.js';
11
- import { areJidsSameUser, getBinaryNodeChild, getBinaryNodeChildren, getBizBinaryNode, isHostedLidUser, isHostedPnUser, isJidGroup, isJidNewsletter, isLidUser, isPnUser, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET } from '../WABinary/index.js';
10
+ import { areJidsSameUser, getBinaryFilteredBizBot, getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isJidGroup, isJidUser, isLidUser, isPnUser, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, STORIES_JID } from '../WABinary/index.js';
11
+ import { delay } from '../Utils/generics.js';
12
+
12
13
  import { USyncQuery, USyncUser } from '../WAUSync/index.js';
13
14
  import { makeNewsletterSocket } from './newsletter.js';
15
+ // Inline helper — no external import needed
16
+ const _isNewsletterJid = (jid) => typeof jid === 'string' && jid.endsWith('@newsletter');
17
+
14
18
  export const makeMessagesSocket = (config) => {
15
19
  const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: httpRequestOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache, maxMsgRetryCount } = config;
16
20
  const sock = makeNewsletterSocket(config);
17
21
  const { ev, authState, messageMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral } = sock;
18
- const userDevicesCache = config.userDevicesCache ??=
22
+ const userDevicesCache = config.userDevicesCache ||
19
23
  new NodeCache({
20
24
  stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
21
25
  useClones: false
@@ -242,7 +246,7 @@ export const makeMessagesSocket = (config) => {
242
246
  const userDeviceUpdates = {};
243
247
  for (const [userId, devices] of Object.entries(deviceMap)) {
244
248
  if (devices && devices.length > 0) {
245
- userDeviceUpdates[userId] = devices.map(d => d.device?.toString());
249
+ userDeviceUpdates[userId] = devices.map(d => d.device?.toString() || '0');
246
250
  }
247
251
  }
248
252
  if (Object.keys(userDeviceUpdates).length > 0) {
@@ -429,10 +433,10 @@ export const makeMessagesSocket = (config) => {
429
433
  }
430
434
  return { nodes, shouldIncludeDeviceIdentity };
431
435
  };
432
- const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, addBizAttributes, statusJidList }) => {
436
+ const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList, AI = false }) => {
433
437
  const meId = authState.creds.me.id;
434
438
  const meLid = authState.creds.me?.lid;
435
- const isRetryResend = !!participant?.jid;
439
+ const isRetryResend = Boolean(participant?.jid);
436
440
  let shouldIncludeDeviceIdentity = isRetryResend;
437
441
  const statusJid = 'status@broadcast';
438
442
  const { user, server } = jidDecode(jid);
@@ -470,50 +474,110 @@ export const makeMessagesSocket = (config) => {
470
474
  });
471
475
  }
472
476
  await authState.keys.transaction(async () => {
473
- // Lia@Changes 02-02-26 --- Normalize message first to extract the original message and valid media type
474
- const innerMessage = normalizeMessageContent(message);
475
- const mediaType = getMediaType(innerMessage);
477
+ const mediaType = getMediaType(message);
476
478
  if (mediaType) {
477
479
  extraAttrs['mediatype'] = mediaType;
478
480
  }
479
481
  if (isNewsletter) {
480
- if (innerMessage.productMessage) {
481
- extraAttrs['mediatype'] = 'image'; // Lia@Note 02-02-26 --- Treat product message as image message to avoid the "479" error (⁠✷⁠‿⁠✷⁠)
482
+ // Handle edit
483
+ if (message.protocolMessage?.editedMessage) {
484
+ msgId = message.protocolMessage.key?.id;
485
+ message = message.protocolMessage.editedMessage;
482
486
  }
487
+ // Handle delete/revoke
488
+ if (message.protocolMessage?.type === proto.Message.ProtocolMessage.Type.REVOKE) {
489
+ msgId = message.protocolMessage.key?.id;
490
+ message = {};
491
+ }
492
+ // ── Newsletter Button Compatibility Patch ──────────────────────
493
+ // interactiveMessage (quick_reply / single_select / cta_url) bisa
494
+ // dikirim ke newsletter langsung — WA menerima via proto encoding.
495
+ // listMessage & buttonsMessage dikonversi ke interactiveMessage
496
+ // supaya konsisten dengan cara bot menulis pesan.
497
+ // ──────────────────────────────────────────────────────────────
498
+ if (message.listMessage) {
499
+ const list = message.listMessage;
500
+ message = {
501
+ interactiveMessage: {
502
+ nativeFlowMessage: {
503
+ buttons: [{
504
+ name: 'single_select',
505
+ buttonParamsJson: JSON.stringify({
506
+ title: list.buttonText || 'Select',
507
+ sections: (list.sections || []).map(sec => ({
508
+ title: sec.title || '',
509
+ highlight_label: '',
510
+ rows: (sec.rows || []).map(row => ({
511
+ header: '',
512
+ title: row.title || '',
513
+ description: row.description || '',
514
+ id: row.rowId || row.id || ''
515
+ }))
516
+ }))
517
+ })
518
+ }],
519
+ messageParamsJson: '',
520
+ messageVersion: 1
521
+ },
522
+ body: { text: list.description || '' },
523
+ ...(list.footerText ? { footer: { text: list.footerText } } : {}),
524
+ ...(list.title ? { header: { title: list.title, hasMediaAttachment: false, subtitle: '' } } : {})
525
+ }
526
+ };
527
+ }
528
+ else if (message.buttonsMessage) {
529
+ const bMsg = message.buttonsMessage;
530
+ message = {
531
+ interactiveMessage: {
532
+ nativeFlowMessage: {
533
+ buttons: (bMsg.buttons || []).map(btn => ({
534
+ name: 'quick_reply',
535
+ buttonParamsJson: JSON.stringify({
536
+ display_text: btn.buttonText?.displayText || btn.buttonText || '',
537
+ id: btn.buttonId || btn.buttonText?.displayText || ''
538
+ })
539
+ })),
540
+ messageParamsJson: '',
541
+ messageVersion: 1
542
+ },
543
+ body: { text: bMsg.contentText || bMsg.text || '' },
544
+ ...(bMsg.footerText ? { footer: { text: bMsg.footerText } } : {}),
545
+ }
546
+ };
547
+ }
548
+ // ── End Newsletter Button Compatibility Patch ──────────────────
483
549
  const patched = patchMessageBeforeSending ? await patchMessageBeforeSending(message, []) : message;
550
+ if (Array.isArray(patched)) {
551
+ throw new Error('Per-jid patching is not supported in channel');
552
+ }
484
553
  const bytes = encodeNewsletterMessage(patched);
485
- // Lia@Changes 08-02-26 --- Add "additionalNodes" for newsletter too (⁠っ⁠˘̩⁠╭⁠╮⁠˘̩⁠)⁠っ
486
- if (additionalNodes && additionalNodes.length > 0) {
487
- ;
488
- binaryNodeContent.push(...additionalNodes);
554
+ // Set mediatype for interactive messages
555
+ if (patched.interactiveMessage && !extraAttrs['mediatype']) {
556
+ extraAttrs['mediatype'] = 'interactive';
489
557
  }
558
+ // extraAttrs already has mediatype set above if media message
490
559
  binaryNodeContent.push({
491
560
  tag: 'plaintext',
492
- attrs: extraAttrs, // Lia@Changes 02-02-26 --- Add extraAttrs to fix media being rejected when sending to newsletter (⁠◠⁠‿⁠◕⁠)
561
+ attrs: extraAttrs,
493
562
  content: bytes
494
563
  });
564
+ logger.debug({ msgId, extraAttrs }, `sending newsletter message to ${jid}`);
495
565
  const stanza = {
496
566
  tag: 'message',
497
567
  attrs: {
498
568
  to: jid,
499
569
  id: msgId,
500
- type: getMessageType(innerMessage),
570
+ type: getMessageType(message),
501
571
  ...(additionalAttributes || {})
502
572
  },
503
573
  content: binaryNodeContent
504
574
  };
505
- logger.debug({ msgId }, `sending newsletter message to ${jid}`);
506
575
  await sendNode(stanza);
507
576
  return;
508
577
  }
509
- // Lia@Changes 02-02-26 --- Add keepInChat, editedMessage, mediaNotifyMessage and pollUpdateMessage
510
- if (innerMessage?.pinInChatMessage || innerMessage?.pollUpdateMessage || innerMessage?.keepInChatMessage || innerMessage?.protocolMessage?.editedMessage || innerMessage?.protocolMessage?.mediaNotifyMessage || innerMessage?.reactionMessage) {
578
+ if (normalizeMessageContent(message)?.pinInChatMessage || normalizeMessageContent(message)?.reactionMessage) {
511
579
  extraAttrs['decrypt-fail'] = 'hide'; // todo: expand for reactions and other types
512
580
  }
513
- // Lia@Changes 02-02-26 --- Add native_flow_name to extraAttrs when sending interactiveResponseMessage
514
- if (innerMessage?.interactiveResponseMessage?.nativeFlowResponseMessage) {
515
- extraAttrs['native_flow_name'] = innerMessage.interactiveResponseMessage.nativeFlowResponseMessage.name;
516
- }
517
581
  if (isGroupOrStatus && !isRetryResend) {
518
582
  const [groupData, senderKeyMap] = await Promise.all([
519
583
  (async () => {
@@ -554,6 +618,147 @@ export const makeMessagesSocket = (config) => {
554
618
  addressing_mode: groupData?.addressingMode || 'lid'
555
619
  };
556
620
  }
621
+ // Ensure groupStatusMessageV2 always has messageContextInfo.messageSecret
622
+ if (message?.groupStatusMessageV2 && !message?.messageContextInfo?.messageSecret) {
623
+ const { randomBytes } = await import('node:crypto');
624
+ message = {
625
+ ...message,
626
+ messageContextInfo: {
627
+ ...(message.messageContextInfo || {}),
628
+ messageSecret: randomBytes(32)
629
+ },
630
+ groupStatusMessageV2: {
631
+ ...message.groupStatusMessageV2,
632
+ message: {
633
+ ...(message.groupStatusMessageV2.message || {}),
634
+ messageContextInfo: {
635
+ ...(message.groupStatusMessageV2.message?.messageContextInfo || {}),
636
+ messageSecret: message.messageContextInfo?.messageSecret || randomBytes(32)
637
+ }
638
+ }
639
+ }
640
+ };
641
+ }
642
+ // ── Group Interactive Message Compatibility Patch ──────────────
643
+ // WhatsApp groups do NOT render listMessage, buttonsMessage, or
644
+ // templateMessage natively in MD protocol. All must be converted
645
+ // to interactiveMessage with nativeFlowMessage so they display
646
+ // and are interactive in group chats.
647
+ // ──────────────────────────────────────────────────────────────
648
+
649
+ // 1. listMessage → interactiveMessage single_select
650
+ if (message.listMessage) {
651
+ const list = message.listMessage;
652
+ const interactiveMessage = {
653
+ nativeFlowMessage: {
654
+ buttons: [{
655
+ name: 'single_select',
656
+ buttonParamsJson: JSON.stringify({
657
+ title: list.buttonText || 'Select',
658
+ sections: (list.sections || []).map(section => ({
659
+ title: section.title || '',
660
+ highlight_label: '',
661
+ rows: (section.rows || []).map(row => ({
662
+ header: '',
663
+ title: row.title || '',
664
+ description: row.description || '',
665
+ id: row.rowId || row.id || ''
666
+ }))
667
+ }))
668
+ })
669
+ }],
670
+ messageParamsJson: '',
671
+ messageVersion: 1
672
+ },
673
+ body: { text: list.description || '' },
674
+ footer: list.footerText ? { text: list.footerText } : undefined,
675
+ header: list.title ? { title: list.title, hasMediaAttachment: false, subtitle: '' } : undefined,
676
+ contextInfo: list.contextInfo
677
+ };
678
+ message = { interactiveMessage };
679
+ }
680
+
681
+ // 2. buttonsMessage → interactiveMessage nativeFlowMessage quick_reply buttons
682
+ else if (message.buttonsMessage) {
683
+ const bMsg = message.buttonsMessage;
684
+ const buttons = (bMsg.buttons || []).map(btn => ({
685
+ name: 'quick_reply',
686
+ buttonParamsJson: JSON.stringify({
687
+ display_text: btn.buttonText?.displayText || btn.buttonText || '',
688
+ id: btn.buttonId || btn.buttonText?.displayText || ''
689
+ })
690
+ }));
691
+ const interactiveMessage = {
692
+ nativeFlowMessage: {
693
+ buttons,
694
+ messageParamsJson: '',
695
+ messageVersion: 1
696
+ },
697
+ body: { text: bMsg.contentText || bMsg.text || '' },
698
+ footer: bMsg.footerText ? { text: bMsg.footerText } : undefined,
699
+ header: bMsg.text
700
+ ? { title: bMsg.text, hasMediaAttachment: false, subtitle: '' }
701
+ : (bMsg.imageMessage || bMsg.videoMessage || bMsg.documentMessage
702
+ ? { hasMediaAttachment: true, ...(bMsg.imageMessage ? { imageMessage: bMsg.imageMessage } : {}), ...(bMsg.videoMessage ? { videoMessage: bMsg.videoMessage } : {}) }
703
+ : undefined),
704
+ contextInfo: bMsg.contextInfo
705
+ };
706
+ message = { interactiveMessage };
707
+ }
708
+
709
+ // 3. templateMessage (hydratedFourRowTemplate) → interactiveMessage nativeFlowMessage
710
+ else if (message.templateMessage) {
711
+ const tmpl = message.templateMessage.hydratedTemplate || message.templateMessage.fourRowTemplate;
712
+ if (tmpl) {
713
+ const hydratedButtons = tmpl.hydratedButtons || [];
714
+ const buttons = hydratedButtons.map(hBtn => {
715
+ if (hBtn.quickReplyButton) {
716
+ return {
717
+ name: 'quick_reply',
718
+ buttonParamsJson: JSON.stringify({
719
+ display_text: hBtn.quickReplyButton.displayText || '',
720
+ id: hBtn.quickReplyButton.id || hBtn.quickReplyButton.displayText || ''
721
+ })
722
+ };
723
+ } else if (hBtn.urlButton) {
724
+ return {
725
+ name: 'cta_url',
726
+ buttonParamsJson: JSON.stringify({
727
+ display_text: hBtn.urlButton.displayText || '',
728
+ url: hBtn.urlButton.url || '',
729
+ merchant_url: hBtn.urlButton.url || ''
730
+ })
731
+ };
732
+ } else if (hBtn.callButton) {
733
+ return {
734
+ name: 'cta_call',
735
+ buttonParamsJson: JSON.stringify({
736
+ display_text: hBtn.callButton.displayText || '',
737
+ phone_number: hBtn.callButton.phoneNumber || ''
738
+ })
739
+ };
740
+ }
741
+ return null;
742
+ }).filter(Boolean);
743
+ const interactiveMessage = {
744
+ nativeFlowMessage: {
745
+ buttons,
746
+ messageParamsJson: '',
747
+ messageVersion: 1
748
+ },
749
+ body: { text: tmpl.hydratedContentText || tmpl.contentText || '' },
750
+ footer: tmpl.hydratedFooterText ? { text: tmpl.hydratedFooterText } : undefined,
751
+ header: tmpl.hydratedTitleText
752
+ ? { title: tmpl.hydratedTitleText, hasMediaAttachment: false, subtitle: '' }
753
+ : (tmpl.imageMessage || tmpl.videoMessage || tmpl.documentMessage
754
+ ? { hasMediaAttachment: true, ...(tmpl.imageMessage ? { imageMessage: tmpl.imageMessage } : {}), ...(tmpl.videoMessage ? { videoMessage: tmpl.videoMessage } : {}) }
755
+ : undefined),
756
+ contextInfo: tmpl.contextInfo
757
+ };
758
+ message = { interactiveMessage };
759
+ }
760
+ }
761
+ // ── End Group Interactive Message Compatibility Patch ──────────
557
762
  const patched = await patchMessageBeforeSending(message);
558
763
  if (Array.isArray(patched)) {
559
764
  throw new Boom('Per-jid patching is not supported in groups');
@@ -706,7 +911,7 @@ export const makeMessagesSocket = (config) => {
706
911
  attrs: {
707
912
  v: '2',
708
913
  type,
709
- count: participant.count?.toString() || '0'
914
+ count: participant.count.toString()
710
915
  },
711
916
  content: encryptedContent
712
917
  });
@@ -731,7 +936,7 @@ export const makeMessagesSocket = (config) => {
731
936
  attrs: {
732
937
  id: msgId,
733
938
  to: destinationJid,
734
- type: getMessageType(innerMessage),
939
+ type: getMessageType(message),
735
940
  ...(additionalAttributes || {})
736
941
  },
737
942
  content: binaryNodeContent
@@ -797,15 +1002,22 @@ export const makeMessagesSocket = (config) => {
797
1002
  content: tcTokenBuffer
798
1003
  });
799
1004
  }
800
- if (additionalNodes && additionalNodes.length > 0) {
1005
+ if (AI && !isGroup && !isStatus && !isNewsletter) {
1006
+ const existingBizBot = getBinaryFilteredBizBot(additionalNodes || []);
1007
+ if (existingBizBot) {
1008
+ if (additionalNodes && additionalNodes.length > 0) {
1009
+ stanza.content.push(...additionalNodes);
1010
+ }
1011
+ } else {
1012
+ stanza.content.push({ tag: 'bot', attrs: { biz_bot: '1' } });
1013
+ if (additionalNodes && additionalNodes.length > 0) {
1014
+ stanza.content.push(...additionalNodes);
1015
+ }
1016
+ }
1017
+ } else if (additionalNodes && additionalNodes.length > 0) {
801
1018
  ;
802
1019
  stanza.content.push(...additionalNodes);
803
1020
  }
804
- // Lia@Changes 30-01-26 --- Add Biz Binary Node to support button messages
805
- if (shouldIncludeBizBinaryNode(innerMessage) || addBizAttributes) {
806
- const bizNode = getBizBinaryNode(innerMessage, addBizAttributes);
807
- stanza.content.push(bizNode);
808
- }
809
1021
  logger.debug({ msgId }, `sending message to ${participants.length} devices`);
810
1022
  await sendNode(stanza);
811
1023
  // Add message to retry cache if enabled
@@ -816,23 +1028,30 @@ export const makeMessagesSocket = (config) => {
816
1028
  return msgId;
817
1029
  };
818
1030
  const getMessageType = (message) => {
819
- if (!message)
1031
+ // groupStatusMessageV2 must be checked BEFORE normalizeMessageContent
1032
+ // because normalizeMessageContent will unwrap it into inner message
1033
+ if (message?.groupStatusMessageV2 || message?.groupStatusMessage) {
1034
+ return 'text';
1035
+ }
1036
+ const normalizedMessage = normalizeMessageContent(message);
1037
+ if (!normalizedMessage)
820
1038
  return 'text';
821
- if (message.reactionMessage || message.encReactionMessage) {
1039
+ if (normalizedMessage.reactionMessage || normalizedMessage.encReactionMessage) {
822
1040
  return 'reaction';
823
1041
  }
824
- if (message.pollCreationMessage ||
825
- message.pollCreationMessageV2 ||
826
- message.pollCreationMessageV3 ||
827
- message.pollCreationMessageV5 ||
828
- message.pollCreationMessageV6 ||
829
- message.pollUpdateMessage) {
1042
+ if (normalizedMessage.pollCreationMessage ||
1043
+ normalizedMessage.pollCreationMessageV2 ||
1044
+ normalizedMessage.pollCreationMessageV3 ||
1045
+ normalizedMessage.pollUpdateMessage) {
830
1046
  return 'poll';
831
1047
  }
832
- if (message.eventMessage) {
1048
+ if (normalizedMessage.eventMessage) {
833
1049
  return 'event';
834
1050
  }
835
- if (getMediaType(message) !== '') {
1051
+ if (normalizedMessage.interactiveMessage) {
1052
+ return 'text';
1053
+ }
1054
+ if (getMediaType(normalizedMessage) !== '') {
836
1055
  return 'media';
837
1056
  }
838
1057
  return 'text';
@@ -844,15 +1063,12 @@ export const makeMessagesSocket = (config) => {
844
1063
  else if (message.videoMessage) {
845
1064
  return message.videoMessage.gifPlayback ? 'gif' : 'video';
846
1065
  }
847
- else if (message.stickerMessage) {
848
- return message.stickerMessage.isLottie ? '1p_sticker' : message.stickerMessage.isAvatar ? 'avatar_sticker' : 'sticker';
1066
+ else if (message.ptvMessage) {
1067
+ return 'video';
849
1068
  }
850
1069
  else if (message.audioMessage) {
851
1070
  return message.audioMessage.ptt ? 'ptt' : 'audio';
852
1071
  }
853
- else if (message.albumMessage) {
854
- return 'collection';
855
- }
856
1072
  else if (message.contactMessage) {
857
1073
  return 'vcard';
858
1074
  }
@@ -865,6 +1081,9 @@ export const makeMessagesSocket = (config) => {
865
1081
  else if (message.liveLocationMessage) {
866
1082
  return 'livelocation';
867
1083
  }
1084
+ else if (message.stickerMessage) {
1085
+ return 'sticker';
1086
+ }
868
1087
  else if (message.stickerPackMessage) {
869
1088
  return 'sticker_pack';
870
1089
  }
@@ -886,17 +1105,10 @@ export const makeMessagesSocket = (config) => {
886
1105
  else if (message.interactiveResponseMessage) {
887
1106
  return 'native_flow_response';
888
1107
  }
889
- else if (message.extendedTextMessage?.matchedText || message.groupInviteMessage) {
1108
+ else if (message.groupInviteMessage) {
890
1109
  return 'url';
891
1110
  }
892
- // Lia@Note 02-02-26 --- Add more message type here
893
- else if ((message.extendedTextMessage?.text || message.conversation || '').includes('://wa.me/c/')) {
894
- return 'cataloglink';
895
- }
896
- else if ((message.extendedTextMessage?.text || message.conversation || '').includes('://wa.me/p/')) {
897
- return 'productlink';
898
- }
899
- return ''
1111
+ return '';
900
1112
  };
901
1113
  const getPrivacyTokens = async (jids) => {
902
1114
  const t = unixTimestampSeconds().toString();
@@ -926,6 +1138,64 @@ export const makeMessagesSocket = (config) => {
926
1138
  };
927
1139
  const waUploadToServer = getWAUploadToServer(config, refreshMediaConn);
928
1140
  const waitForMsgMediaUpdate = bindWaitForEvent(ev, 'messages.media-update');
1141
+ // ── Button type helpers (ported from itsukichan) ──────────────────────────
1142
+ const getButtonType = (message) => {
1143
+ if (message.listMessage) return 'list';
1144
+ if (message.buttonsMessage) return 'buttons';
1145
+ if (message.templateMessage) return 'template';
1146
+ if (message.interactiveMessage?.nativeFlowMessage) return 'native_flow';
1147
+ if (message.interactiveMessage?.shopStorefrontMessage) return 'shop';
1148
+ if (message.interactiveMessage?.collectionMessage) return 'collection';
1149
+ if (message.interactiveMessage?.carouselMessage) return 'carousel';
1150
+ if (message.interactiveMessage) return 'interactive';
1151
+ return null;
1152
+ };
1153
+ const getButtonArgs = (message) => {
1154
+ const nativeFlow = message.interactiveMessage?.nativeFlowMessage;
1155
+ const firstButtonName = nativeFlow?.buttons?.[0]?.name;
1156
+ const nativeFlowSpecials = [
1157
+ 'mpm', 'cta_catalog', 'send_location',
1158
+ 'call_permission_request', 'wa_payment_transaction_details',
1159
+ 'automated_greeting_message_view_catalog'
1160
+ ];
1161
+ const ts = unixTimestampSeconds().toString();
1162
+ const bizBase = { actual_actors: '2', host_storage: '2', privacy_mode_ts: ts };
1163
+ const qualityControl = { tag: 'quality_control', attrs: { source_type: 'third_party' } };
1164
+ if (nativeFlow && (firstButtonName === 'review_and_pay' || firstButtonName === 'payment_info')) {
1165
+ return {
1166
+ tag: 'biz',
1167
+ attrs: { native_flow_name: firstButtonName === 'review_and_pay' ? 'order_details' : firstButtonName }
1168
+ };
1169
+ } else if (nativeFlow && nativeFlowSpecials.includes(firstButtonName)) {
1170
+ return {
1171
+ tag: 'biz', attrs: bizBase,
1172
+ content: [{
1173
+ tag: 'interactive', attrs: { type: 'native_flow', v: '1' },
1174
+ content: [{ tag: 'native_flow', attrs: { v: '2', name: firstButtonName } }]
1175
+ }, qualityControl]
1176
+ };
1177
+ } else if (nativeFlow || message.buttonsMessage || message.templateMessage || message.interactiveMessage) {
1178
+ // All interactive types in groups use native_flow biz node
1179
+ // This covers: nativeFlowMessage, buttonsMessage→interactiveMessage,
1180
+ // templateMessage→interactiveMessage, and direct interactiveMessage
1181
+ return {
1182
+ tag: 'biz', attrs: bizBase,
1183
+ content: [{
1184
+ tag: 'interactive', attrs: { type: 'native_flow', v: '1' },
1185
+ content: [{ tag: 'native_flow', attrs: { v: '9', name: 'mixed' } }]
1186
+ }, qualityControl]
1187
+ };
1188
+ } else if (message.listMessage) {
1189
+ // Standalone listMessage (private chat) keeps the list biz node
1190
+ return {
1191
+ tag: 'biz', attrs: bizBase,
1192
+ content: [{ tag: 'list', attrs: { v: '2', type: 'product_list' } }, qualityControl]
1193
+ };
1194
+ } else {
1195
+ return { tag: 'biz', attrs: bizBase };
1196
+ }
1197
+ };
1198
+ // ── End button type helpers ───────────────────────────────────────────────
929
1199
  return {
930
1200
  ...sock,
931
1201
  getPrivacyTokens,
@@ -984,105 +1254,263 @@ export const makeMessagesSocket = (config) => {
984
1254
  ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]);
985
1255
  return message;
986
1256
  },
987
- // Lia@Changes 30-01-26 --- Add support for modifying additionalNodes and additionalAttributes using "options" in sendMessage()
988
- sendMessage: async (jid, content, options = {}) => {
989
- const userJid = authState.creds.me.id;
990
- // Lia@Changes 13-03-26 --- Add status mentions!
991
- if (Array.isArray(jid)) {
992
- const { delayMs = 1500 } = options;
993
- const allUsers = new Set();
994
- const fullMsg = await generateWAMessage('status@broadcast', content, {
1257
+ resize: async (media, width, height) => {
1258
+ const { getStream, toBuffer } = await import('../Utils/messages-media.js');
1259
+ let sharp;
1260
+ try { sharp = (await import('sharp')).default; } catch (_) {}
1261
+ if (!sharp) throw new Error('sharp is required for resize');
1262
+ const { stream } = await getStream(media);
1263
+ const buf = await toBuffer(stream);
1264
+ return sharp(buf).resize(width, height, { fit: 'cover' }).toBuffer();
1265
+ },
1266
+ sendStatusMentions: async (content, jids = []) => {
1267
+ const userJid = jidNormalizedUser(authState.creds.me.id);
1268
+ let allUsers = new Set();
1269
+ allUsers.add(userJid);
1270
+
1271
+ for (const id of jids) {
1272
+ const isGroup = isJidGroup(id);
1273
+ const isPrivate = isJidUser(id);
1274
+ if (isGroup) {
1275
+ try {
1276
+ const metadata = (cachedGroupMetadata ? await cachedGroupMetadata(id) : null) || await groupMetadata(id);
1277
+ const participants = metadata.participants.map(p => jidNormalizedUser(p.id));
1278
+ participants.forEach(j => allUsers.add(j));
1279
+ } catch (error) {
1280
+ logger.error(`Error getting metadata for group ${id}: ${error}`);
1281
+ }
1282
+ } else if (isPrivate) {
1283
+ allUsers.add(jidNormalizedUser(id));
1284
+ }
1285
+ }
1286
+
1287
+ const uniqueUsers = Array.from(allUsers);
1288
+ const getRandomHexColor = () => '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0');
1289
+
1290
+ const isMedia = content.image || content.video || content.audio;
1291
+ const isAudio = !!content.audio;
1292
+
1293
+ const messageContent = { ...content };
1294
+
1295
+ if (isMedia && !isAudio) {
1296
+ if (messageContent.text) {
1297
+ messageContent.caption = messageContent.text;
1298
+ delete messageContent.text;
1299
+ }
1300
+ delete messageContent.ptt;
1301
+ delete messageContent.font;
1302
+ delete messageContent.backgroundColor;
1303
+ delete messageContent.textColor;
1304
+ }
1305
+ if (isAudio) {
1306
+ delete messageContent.text;
1307
+ delete messageContent.caption;
1308
+ delete messageContent.font;
1309
+ delete messageContent.textColor;
1310
+ }
1311
+
1312
+ const font = !isMedia ? (content.font ?? Math.floor(Math.random() * 9)) : undefined;
1313
+ const textColor = !isMedia ? (content.textColor ?? getRandomHexColor()) : undefined;
1314
+ const backgroundColor = (!isMedia || isAudio) ? (content.backgroundColor ?? getRandomHexColor()) : undefined;
1315
+ const ptt = isAudio ? (typeof content.ptt === 'boolean' ? content.ptt : true) : undefined;
1316
+
1317
+ let msg;
1318
+ let mediaHandle;
1319
+ try {
1320
+ msg = await generateWAMessage(STORIES_JID, messageContent, {
995
1321
  logger,
996
1322
  userJid,
997
- upload: waUploadToServer,
1323
+ getUrlInfo: text => getUrlInfo(text, {
1324
+ thumbnailWidth: linkPreviewImageThumbnailWidth,
1325
+ fetchOpts: { timeout: 3000 },
1326
+ logger,
1327
+ uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
1328
+ }),
1329
+ upload: async (encFilePath, opts) => {
1330
+ const up = await waUploadToServer(encFilePath, { ...opts });
1331
+ mediaHandle = up.handle;
1332
+ return up;
1333
+ },
998
1334
  mediaCache: config.mediaCache,
999
1335
  options: config.options,
1000
- ...options,
1001
- messageId: generateMessageIDV2(userJid)
1002
- });
1003
- for (const id of jid) {
1004
- if (isJidGroup(id)) {
1005
- try {
1006
- const groupData = (cachedGroupMetadata ? await cachedGroupMetadata(id) : null) || await groupMetadata(id);
1007
- for (const participant of groupData.participants) {
1008
- if (allUsers.has(participant.id))
1009
- continue;
1010
- allUsers.add(participant.id);
1011
- }
1012
- }
1013
- catch (error) {
1014
- logger.error(`Error getting metadata group from ${id}: ${error}`);
1015
- }
1016
- }
1017
- else if (!allUsers.has(id)) {
1018
- allUsers.add(id);
1019
- }
1020
- }
1021
- await relayMessage('status@broadcast', fullMsg.message, {
1022
- messageId: fullMsg.key.id,
1023
- statusJidList: Array.from(allUsers),
1024
- additionalNodes: [
1025
- {
1026
- tag: 'meta',
1027
- attrs: {},
1028
- content: [
1029
- {
1030
- tag: 'mentioned_users',
1031
- attrs: {},
1032
- content: jid.map(id => ({
1033
- tag: 'to',
1034
- attrs: { jid: id },
1035
- content: undefined
1036
- }))
1037
- }
1038
- ]
1039
- }
1040
- ]
1336
+ font,
1337
+ textColor,
1338
+ backgroundColor,
1339
+ ptt
1041
1340
  });
1042
- if (config.emitOwnEvents) {
1043
- process.nextTick(async () => {
1044
- await messageMutex.mutex(() => upsertMessage(fullMsg, 'append'));
1045
- });
1046
- }
1047
- for (const id of jid) {
1048
- const isGroup = isJidGroup(id)
1049
- const sendType = isGroup ? 'groupStatusMentionMessage' : 'statusMentionMessage';
1050
- const mentionMsg = generateWAMessageFromContent(id, {
1051
- messageContextInfo: {
1052
- messageSecret: randomBytes(32)
1053
- },
1054
- [sendType]: {
1341
+ } catch (error) {
1342
+ logger.error(`Error generating status message: ${error}`);
1343
+ throw error;
1344
+ }
1345
+
1346
+ await relayMessage(STORIES_JID, msg.message, {
1347
+ messageId: msg.key.id,
1348
+ statusJidList: uniqueUsers,
1349
+ additionalNodes: [{
1350
+ tag: 'meta',
1351
+ attrs: {},
1352
+ content: [{
1353
+ tag: 'mentioned_users',
1354
+ attrs: {},
1355
+ content: jids.map(jid => ({
1356
+ tag: 'to',
1357
+ attrs: { jid: jidNormalizedUser(jid) }
1358
+ }))
1359
+ }]
1360
+ }]
1361
+ });
1362
+
1363
+ for (const id of jids) {
1364
+ try {
1365
+ const normalizedId = jidNormalizedUser(id);
1366
+ const isPrivate = isJidUser(normalizedId);
1367
+ const type = isPrivate ? 'statusMentionMessage' : 'groupStatusMentionMessage';
1368
+ const protocolMessage = {
1369
+ [type]: {
1055
1370
  message: {
1056
1371
  protocolMessage: {
1057
- key: fullMsg.key,
1372
+ key: msg.key,
1058
1373
  type: 25
1059
1374
  }
1060
1375
  }
1376
+ },
1377
+ messageContextInfo: {
1378
+ messageSecret: randomBytes(32)
1061
1379
  }
1062
- }, {
1063
- userJid
1064
- });
1065
- await relayMessage(id, mentionMsg.message, {
1066
- additionalNodes: [
1067
- {
1068
- tag: 'meta',
1069
- attrs: isGroup ?
1070
- { is_group_status_mention: 'true' } :
1071
- { is_status_mention: 'true' },
1072
- content: undefined
1073
- }
1074
- ]
1380
+ };
1381
+ const statusMsg = await generateWAMessageFromContent(normalizedId, protocolMessage, {});
1382
+ await relayMessage(normalizedId, statusMsg.message, {
1383
+ additionalNodes: [{
1384
+ tag: 'meta',
1385
+ attrs: isPrivate
1386
+ ? { is_status_mention: 'true' }
1387
+ : { is_group_status_mention: 'true' }
1388
+ }]
1075
1389
  });
1076
- if (config.emitOwnEvents) {
1077
- process.nextTick(async () => {
1078
- await messageMutex.mutex(() => upsertMessage(mentionMsg, 'append'));
1079
- });
1390
+ await delay(2000);
1391
+ } catch (error) {
1392
+ logger.error(`Error sending status mention to ${id}: ${error}`);
1393
+ }
1394
+ }
1395
+
1396
+ return msg;
1397
+ },
1398
+ sendMessage: async (jid, content, options = {}) => {
1399
+ const userJid = authState.creds.me.id;
1400
+ // ── Normalize: buttons[].nativeFlowInfo -> interactiveButtons ──────
1401
+ if (
1402
+ typeof content === 'object' &&
1403
+ Array.isArray(content.buttons) &&
1404
+ content.buttons.length > 0 &&
1405
+ content.buttons.some(b => b.nativeFlowInfo)
1406
+ ) {
1407
+ const interactiveButtons = content.buttons.map(b => {
1408
+ if (b.nativeFlowInfo) {
1409
+ return {
1410
+ name: b.nativeFlowInfo.name,
1411
+ buttonParamsJson: b.nativeFlowInfo.paramsJson || '{}'
1412
+ };
1080
1413
  }
1081
- await delay(delayMs);
1414
+ return {
1415
+ name: 'quick_reply',
1416
+ buttonParamsJson: JSON.stringify({
1417
+ display_text: b.buttonText?.displayText || b.buttonId || 'Button',
1418
+ id: b.buttonId || b.buttonText?.displayText || 'btn'
1419
+ })
1420
+ };
1421
+ });
1422
+ const { buttons, headerType, viewOnce, ...rest } = content;
1423
+ content = { ...rest, interactiveButtons };
1424
+ }
1425
+ // ── Interactive Button (sendButton logic) ──────────────────────────
1426
+ if (typeof content === 'object' && Array.isArray(content.interactiveButtons) && content.interactiveButtons.length > 0) {
1427
+ const {
1428
+ text = '',
1429
+ caption = '',
1430
+ title = '',
1431
+ footer = '',
1432
+ interactiveButtons,
1433
+ hasMediaAttachment = false,
1434
+ image = null,
1435
+ video = null,
1436
+ document = null,
1437
+ mimetype = null,
1438
+ jpegThumbnail = null,
1439
+ location = null,
1440
+ product = null,
1441
+ businessOwnerJid = null,
1442
+ externalAdReply = null,
1443
+ } = content;
1444
+ // Normalize buttons
1445
+ const processedButtons = [];
1446
+ for (let i = 0; i < interactiveButtons.length; i++) {
1447
+ const btn = interactiveButtons[i];
1448
+ if (!btn || typeof btn !== 'object') throw new Error(`interactiveButtons[${i}] must be an object`);
1449
+ if (btn.name && btn.buttonParamsJson) { processedButtons.push(btn); continue; }
1450
+ if (btn.id || btn.text || btn.displayText) {
1451
+ processedButtons.push({ name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: btn.text || btn.displayText || `Button ${i + 1}`, id: btn.id || `quick_${i + 1}` }) });
1452
+ continue;
1453
+ }
1454
+ if (btn.buttonId && btn.buttonText?.displayText) {
1455
+ processedButtons.push({ name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: btn.buttonText.displayText, id: btn.buttonId }) });
1456
+ continue;
1457
+ }
1458
+ throw new Error(`interactiveButtons[${i}] has invalid shape`);
1082
1459
  }
1083
- return fullMsg;
1460
+ let messageContent = {};
1461
+ // Header
1462
+ if (image) {
1463
+ const mi = Buffer.isBuffer(image) ? { image } : { image: { url: typeof image === 'object' ? image.url : image } };
1464
+ const pm = await prepareWAMessageMedia(mi, { upload: waUploadToServer });
1465
+ messageContent.header = { title: title || '', hasMediaAttachment: true, imageMessage: pm.imageMessage };
1466
+ } else if (video) {
1467
+ const mi = Buffer.isBuffer(video) ? { video } : { video: { url: typeof video === 'object' ? video.url : video } };
1468
+ const pm = await prepareWAMessageMedia(mi, { upload: waUploadToServer });
1469
+ messageContent.header = { title: title || '', hasMediaAttachment: true, videoMessage: pm.videoMessage };
1470
+ } else if (document) {
1471
+ const mi = Buffer.isBuffer(document) ? { document } : { document: { url: typeof document === 'object' ? document.url : document } };
1472
+ if (mimetype && typeof mi.document === 'object') mi.document.mimetype = mimetype;
1473
+ if (jpegThumbnail) {
1474
+ const thumb = Buffer.isBuffer(jpegThumbnail) ? jpegThumbnail : await (async () => { try { const r = await fetch(jpegThumbnail); return Buffer.from(await r.arrayBuffer()); } catch { return undefined; } })();
1475
+ if (thumb) mi.document.jpegThumbnail = thumb;
1476
+ }
1477
+ const pm = await prepareWAMessageMedia(mi, { upload: waUploadToServer });
1478
+ messageContent.header = { title: title || '', hasMediaAttachment: true, documentMessage: pm.documentMessage };
1479
+ } else if (location && typeof location === 'object') {
1480
+ messageContent.header = { title: title || location.name || 'Location', hasMediaAttachment: false, locationMessage: { degreesLatitude: location.degreesLatitude || location.degressLatitude || 0, degreesLongitude: location.degreesLongitude || location.degressLongitude || 0, name: location.name || '', address: location.address || '' } };
1481
+ } else if (product && typeof product === 'object') {
1482
+ let productImageMessage = null;
1483
+ if (product.productImage) {
1484
+ const mi = Buffer.isBuffer(product.productImage) ? { image: product.productImage } : { image: { url: typeof product.productImage === 'object' ? product.productImage.url : product.productImage } };
1485
+ const pm = await prepareWAMessageMedia(mi, { upload: waUploadToServer });
1486
+ productImageMessage = pm.imageMessage;
1487
+ }
1488
+ messageContent.header = { title: title || product.title || 'Product', hasMediaAttachment: false, productMessage: { product: { productImage: productImageMessage, productId: product.productId || '', title: product.title || '', description: product.description || '', currencyCode: product.currencyCode || 'USD', priceAmount1000: parseInt(product.priceAmount1000) || 0, retailerId: product.retailerId || '', url: product.url || '', productImageCount: product.productImageCount || 1 }, businessOwnerJid: businessOwnerJid || product.businessOwnerJid || userJid } };
1489
+ } else if (title) {
1490
+ messageContent.header = { title, hasMediaAttachment: false };
1491
+ }
1492
+ const hasMedia = !!(image || video || document || location || product);
1493
+ const bodyText = hasMedia ? caption : text || caption;
1494
+ if (bodyText) messageContent.body = { text: bodyText };
1495
+ if (footer) messageContent.footer = { text: footer };
1496
+ messageContent.nativeFlowMessage = { buttons: processedButtons };
1497
+ // Context info
1498
+ if (externalAdReply && typeof externalAdReply === 'object') {
1499
+ messageContent.contextInfo = { externalAdReply: { title: externalAdReply.title || '', body: externalAdReply.body || '', mediaType: externalAdReply.mediaType || 1, sourceUrl: externalAdReply.sourceUrl || externalAdReply.url || '', thumbnailUrl: externalAdReply.thumbnailUrl || externalAdReply.thumbnail || '', renderLargerThumbnail: externalAdReply.renderLargerThumbnail || false, showAdAttribution: externalAdReply.showAdAttribution !== false, containsAutoReply: externalAdReply.containsAutoReply || false, ...(externalAdReply.mediaUrl && { mediaUrl: externalAdReply.mediaUrl }), ...(Buffer.isBuffer(externalAdReply.thumbnail) && { thumbnail: externalAdReply.thumbnail }), ...(externalAdReply.jpegThumbnail && { jpegThumbnail: externalAdReply.jpegThumbnail }) }, ...(options.mentionedJid && { mentionedJid: options.mentionedJid }) };
1500
+ } else if (options.mentionedJid) {
1501
+ messageContent.contextInfo = { mentionedJid: options.mentionedJid };
1502
+ }
1503
+ const payload = proto.Message.InteractiveMessage.create(messageContent);
1504
+ const msg = generateWAMessageFromContent(jid, { viewOnceMessage: { message: { interactiveMessage: payload } } }, { userJid, quoted: options?.quoted || null });
1505
+ const additionalNodes = [{ tag: 'biz', attrs: {}, content: [{ tag: 'interactive', attrs: { type: 'native_flow', v: '1' }, content: [{ tag: 'native_flow', attrs: { v: '9', name: 'mixed' } }] }] }];
1506
+ await relayMessage(jid, msg.message, { messageId: msg.key.id, additionalNodes });
1507
+ return msg;
1084
1508
  }
1085
- else if ('disappearingMessagesInChat' in content && isJidGroup(jid)) {
1509
+ // ── End Interactive Button ─────────────────────────────────────────
1510
+ if (typeof content === 'object' &&
1511
+ 'disappearingMessagesInChat' in content &&
1512
+ typeof content['disappearingMessagesInChat'] !== 'undefined' &&
1513
+ isJidGroup(jid)) {
1086
1514
  const { disappearingMessagesInChat } = content;
1087
1515
  const value = typeof disappearingMessagesInChat === 'boolean'
1088
1516
  ? disappearingMessagesInChat
@@ -1092,6 +1520,7 @@ export const makeMessagesSocket = (config) => {
1092
1520
  await groupToggleEphemeral(jid, value);
1093
1521
  }
1094
1522
  else {
1523
+ let mediaHandle;
1095
1524
  const fullMsg = await generateWAMessage(jid, content, {
1096
1525
  logger,
1097
1526
  userJid,
@@ -1107,28 +1536,45 @@ export const makeMessagesSocket = (config) => {
1107
1536
  //TODO: CACHE
1108
1537
  getProfilePicUrl: sock.profilePictureUrl,
1109
1538
  getCallLink: sock.createCallLink,
1110
- upload: waUploadToServer,
1539
+ newsletter: _isNewsletterJid(jid),
1540
+ upload: async (encFilePath, opts) => {
1541
+ const up = await waUploadToServer(encFilePath, { ...opts, newsletter: _isNewsletterJid(jid) });
1542
+ mediaHandle = up.handle;
1543
+ return up;
1544
+ },
1111
1545
  mediaCache: config.mediaCache,
1112
1546
  options: config.options,
1113
- ...options,
1114
- messageId: generateMessageIDV2(userJid)
1547
+ messageId: generateMessageIDV2(sock.user?.id),
1548
+ ...options
1115
1549
  });
1116
- const isNewsletter = isJidNewsletter(jid);
1550
+ if (content?.audio && options?.contextInfo) {
1551
+ const msgContent = fullMsg.message;
1552
+ if (msgContent?.audioMessage) {
1553
+ msgContent.audioMessage.contextInfo = options.contextInfo;
1554
+ }
1555
+ }
1556
+ // Extract handle from newsletter upload (set by prepareWAMessageMedia)
1557
+ if (!mediaHandle) {
1558
+ const msgContent = fullMsg.message;
1559
+ const msgTypes = ['audioMessage','imageMessage','videoMessage','documentMessage','stickerMessage'];
1560
+ for (const t of msgTypes) {
1561
+ if (msgContent?.[t]?._uploadHandle) {
1562
+ mediaHandle = msgContent[t]._uploadHandle;
1563
+
1564
+ delete msgContent[t]._uploadHandle;
1565
+ break;
1566
+ }
1567
+ }
1568
+ }
1117
1569
  const isEventMsg = 'event' in content && !!content.event;
1118
1570
  const isDeleteMsg = 'delete' in content && !!content.delete;
1119
1571
  const isEditMsg = 'edit' in content && !!content.edit;
1120
1572
  const isPinMsg = 'pin' in content && !!content.pin;
1121
- const isKeepMsg = 'keep' in content && !!content.keep;
1122
- const isPollMsg = 'poll' in content && !!content.poll;
1123
- const isQuizMsg = 'poll' in content && !!content.poll.pollType;
1124
- const isPollResultMsg = 'pollResult' in content && !!content.pollResult;
1125
- const isPollUpdateMsg = 'pollUpdate' in content && !!content.pollUpdate;
1126
- const isAiMsg = 'ai' in content && !!content.ai;
1127
- const isNeedBizAttrs = 'secureMetaServiceLabel' in content && !!content.secureMetaServiceLabel;
1128
- const additionalAttributes = options.additionalAttributes || {};
1129
- const additionalNodes = options.additionalNodes || [];
1573
+ const isPollMessage = 'poll' in content && !!content.poll;
1574
+ const additionalAttributes = {};
1575
+ const additionalNodes = [];
1130
1576
  // required for delete
1131
- if (isDeleteMsg || isKeepMsg) {
1577
+ if (isDeleteMsg) {
1132
1578
  // if the chat is a group, and I am not the author, then delete the message as an admin
1133
1579
  if (isJidGroup(content.delete?.remoteJid) && !content.delete?.fromMe) {
1134
1580
  additionalAttributes.edit = '8';
@@ -1138,23 +1584,17 @@ export const makeMessagesSocket = (config) => {
1138
1584
  }
1139
1585
  }
1140
1586
  else if (isEditMsg) {
1141
- additionalAttributes.edit = isNewsletter ? '3' : '1';
1587
+ additionalAttributes.edit = '1';
1142
1588
  }
1143
1589
  else if (isPinMsg) {
1144
1590
  additionalAttributes.edit = '2';
1145
1591
  }
1146
- else if (isPollMsg) {
1147
- if (!isNewsletter && isQuizMsg) {
1148
- throw new Boom('Quiz are only allowed for newsletter', { statusCode: 400 });
1149
- }
1592
+ else if (isPollMessage) {
1150
1593
  additionalNodes.push({
1151
1594
  tag: 'meta',
1152
1595
  attrs: {
1153
- // Lia@Note 08-02-26 --- Still a hypothesis regarding PollResult ༎ຶ⁠‿⁠༎ຶ
1154
- polltype: isQuizMsg ? 'quiz_creation' : isPollResultMsg || isPollUpdateMsg ? 'vote' : 'creation',
1155
- contenttype: isPollMsg && isNewsletter ? 'text' : undefined
1156
- },
1157
- content: undefined
1596
+ polltype: 'creation'
1597
+ }
1158
1598
  });
1159
1599
  }
1160
1600
  else if (isEventMsg) {
@@ -1162,80 +1602,34 @@ export const makeMessagesSocket = (config) => {
1162
1602
  tag: 'meta',
1163
1603
  attrs: {
1164
1604
  event_type: 'creation'
1165
- },
1166
- content: undefined
1605
+ }
1167
1606
  });
1168
1607
  }
1169
- // Lia@Changes 30-01-26 --- Add support for AI label in message when "ai" is true, but works only in private chat
1170
- else if (isAiMsg) {
1171
- if (!(isPnUser(jid) || isLidUser(jid))) {
1172
- throw new Boom('AI labeled message are only allowed in private chat', { statusCode: 400 });
1173
- }
1174
- if ('messageContextInfo' in fullMsg.message && !!fullMsg.message.messageContextInfo) {
1175
- fullMsg.message.messageContextInfo.supportPayload = BIZ_BOT_SUPPORT_PAYLOAD;
1176
- };
1177
- additionalNodes.push({
1178
- tag: 'bot',
1179
- attrs: {
1180
- biz_bot: '1'
1181
- },
1182
- content: undefined
1183
- });
1184
- delete content.ai;
1608
+ // Auto-attach biz node for button/list/interactive messages
1609
+ const buttonType = getButtonType(fullMsg.message);
1610
+ if (buttonType) {
1611
+ const btnNode = getButtonArgs(fullMsg.message);
1612
+ if (btnNode) additionalNodes.push(btnNode);
1613
+ }
1614
+ if (mediaHandle) {
1615
+ additionalAttributes['media_id'] = mediaHandle;
1185
1616
  }
1186
1617
  await relayMessage(jid, fullMsg.message, {
1187
1618
  messageId: fullMsg.key.id,
1188
1619
  useCachedGroupMetadata: options.useCachedGroupMetadata,
1189
- addBizAttributes: isNeedBizAttrs,
1190
- statusJidList: options.statusJidList,
1191
1620
  additionalAttributes,
1192
- additionalNodes
1621
+ statusJidList: options.statusJidList,
1622
+ additionalNodes,
1623
+ AI: options.ai || false
1193
1624
  });
1194
1625
  if (config.emitOwnEvents) {
1195
1626
  process.nextTick(async () => {
1196
1627
  await messageMutex.mutex(() => upsertMessage(fullMsg, 'append'));
1197
1628
  });
1198
1629
  }
1199
- // Lia@Changes 31-01-26 --- Add support for album messages
1200
- // Lia@Note 06-02-26 --- Refactored to reduce high RSS usage (⁠╥⁠﹏⁠╥⁠)
1201
- if ('album' in content) {
1202
- const { delayMs = 1500 } = options;
1203
- for (const albumMedia of content.album) {
1204
- const albumMsg = await generateWAMessage(jid, albumMedia, {
1205
- logger,
1206
- userJid,
1207
- upload: waUploadToServer,
1208
- mediaCache: config.mediaCache,
1209
- options: config.options,
1210
- ...options,
1211
- messageId: generateMessageIDV2(userJid)
1212
- });
1213
- if (!hasValidAlbumMedia(normalizeMessageContent(albumMsg.message))) {
1214
- throw new Boom('Invalid message type for album', { statusCode: 400 });
1215
- }
1216
- albumMsg.message.messageContextInfo ||= {};
1217
- albumMsg.message.messageContextInfo.messageAssociation = {
1218
- parentMessageKey: fullMsg.key,
1219
- associationType: AssociationType.MEDIA_ALBUM
1220
- };
1221
- await relayMessage(jid, albumMsg.message, {
1222
- messageId: albumMsg.key.id,
1223
- useCachedGroupMetadata: options.useCachedGroupMetadata,
1224
- addBizAttributes: isNeedBizAttrs,
1225
- statusJidList: options.statusJidList,
1226
- additionalAttributes,
1227
- additionalNodes
1228
- });
1229
- if (config.emitOwnEvents) {
1230
- process.nextTick(async () => {
1231
- await messageMutex.mutex(() => upsertMessage(albumMsg, 'append'));
1232
- });
1233
- }
1234
- await delay(delayMs);
1235
- }
1236
- }
1237
1630
  return fullMsg;
1238
1631
  }
1239
1632
  }
1240
1633
  };
1241
- };
1634
+ };
1635
+ //# sourceMappingURL=messages-send.js.map