@japofc/baileys 2.1.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 (342) hide show
  1. package/NOTICE.md +111 -0
  2. package/README.md +1254 -0
  3. package/WAProto/index.d.ts +9 -0
  4. package/WAProto/index.js +142276 -0
  5. package/engine-requirements.js +13 -0
  6. package/lib/Builders/A2UI.d.ts +242 -0
  7. package/lib/Builders/A2UI.js +308 -0
  8. package/lib/Builders/AIRich.d.ts +105 -0
  9. package/lib/Builders/AIRich.js +2286 -0
  10. package/lib/Builders/Button.d.ts +103 -0
  11. package/lib/Builders/Button.js +883 -0
  12. package/lib/Builders/ButtonV2.d.ts +28 -0
  13. package/lib/Builders/ButtonV2.js +144 -0
  14. package/lib/Builders/ButtonV3.d.ts +25 -0
  15. package/lib/Builders/ButtonV3.js +184 -0
  16. package/lib/Builders/Carousel.d.ts +22 -0
  17. package/lib/Builders/Carousel.js +111 -0
  18. package/lib/Builders/JapBaileys.d.ts +34 -0
  19. package/lib/Builders/JapBaileys.js +108 -0
  20. package/lib/Builders/Poll.d.ts +25 -0
  21. package/lib/Builders/Poll.js +128 -0
  22. package/lib/Builders/index.d.ts +17 -0
  23. package/lib/Builders/index.js +11 -0
  24. package/lib/Builders/shared.d.ts +67 -0
  25. package/lib/Builders/shared.js +652 -0
  26. package/lib/Defaults/index.d.ts +154 -0
  27. package/lib/Defaults/index.js +178 -0
  28. package/lib/Framework/Bot.d.ts +61 -0
  29. package/lib/Framework/Bot.js +248 -0
  30. package/lib/Framework/Context.d.ts +21 -0
  31. package/lib/Framework/Context.js +89 -0
  32. package/lib/Framework/MediaManager.d.ts +17 -0
  33. package/lib/Framework/MediaManager.js +151 -0
  34. package/lib/Framework/SessionManager.d.ts +13 -0
  35. package/lib/Framework/SessionManager.js +33 -0
  36. package/lib/Framework/StatsManager.d.ts +26 -0
  37. package/lib/Framework/StatsManager.js +119 -0
  38. package/lib/Framework/Store/SQLiteStore.d.ts +11 -0
  39. package/lib/Framework/Store/SQLiteStore.js +73 -0
  40. package/lib/Framework/index.d.ts +9 -0
  41. package/lib/Framework/index.js +10 -0
  42. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  43. package/lib/Signal/Group/ciphertext-message.js +11 -0
  44. package/lib/Signal/Group/group-session-builder.d.ts +7 -0
  45. package/lib/Signal/Group/group-session-builder.js +29 -0
  46. package/lib/Signal/Group/group_cipher.d.ts +10 -0
  47. package/lib/Signal/Group/group_cipher.js +81 -0
  48. package/lib/Signal/Group/index.d.ts +11 -0
  49. package/lib/Signal/Group/index.js +11 -0
  50. package/lib/Signal/Group/keyhelper.d.ts +6 -0
  51. package/lib/Signal/Group/keyhelper.js +17 -0
  52. package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
  53. package/lib/Signal/Group/sender-chain-key.js +25 -0
  54. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
  55. package/lib/Signal/Group/sender-key-distribution-message.js +62 -0
  56. package/lib/Signal/Group/sender-key-message.d.ts +18 -0
  57. package/lib/Signal/Group/sender-key-message.js +65 -0
  58. package/lib/Signal/Group/sender-key-name.d.ts +11 -0
  59. package/lib/Signal/Group/sender-key-name.js +47 -0
  60. package/lib/Signal/Group/sender-key-record.d.ts +12 -0
  61. package/lib/Signal/Group/sender-key-record.js +40 -0
  62. package/lib/Signal/Group/sender-key-state.d.ts +16 -0
  63. package/lib/Signal/Group/sender-key-state.js +83 -0
  64. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  65. package/lib/Signal/Group/sender-message-key.js +25 -0
  66. package/lib/Signal/libsignal.d.ts +54 -0
  67. package/lib/Signal/libsignal.js +430 -0
  68. package/lib/Signal/lid-mapping.d.ts +20 -0
  69. package/lib/Signal/lid-mapping.js +276 -0
  70. package/lib/Socket/Client/index.d.ts +2 -0
  71. package/lib/Socket/Client/index.js +2 -0
  72. package/lib/Socket/Client/types.d.ts +5 -0
  73. package/lib/Socket/Client/types.js +10 -0
  74. package/lib/Socket/Client/websocket.d.ts +12 -0
  75. package/lib/Socket/Client/websocket.js +53 -0
  76. package/lib/Socket/business.d.ts +395 -0
  77. package/lib/Socket/business.js +379 -0
  78. package/lib/Socket/chats.d.ts +136 -0
  79. package/lib/Socket/chats.js +1327 -0
  80. package/lib/Socket/communities.d.ts +562 -0
  81. package/lib/Socket/communities.js +439 -0
  82. package/lib/Socket/dugong.d.ts +117 -0
  83. package/lib/Socket/dugong.js +798 -0
  84. package/lib/Socket/groups.d.ts +285 -0
  85. package/lib/Socket/groups.js +354 -0
  86. package/lib/Socket/index.d.ts +585 -0
  87. package/lib/Socket/index.js +52 -0
  88. package/lib/Socket/messages-recv.d.ts +333 -0
  89. package/lib/Socket/messages-recv.js +1781 -0
  90. package/lib/Socket/messages-send.d.ts +353 -0
  91. package/lib/Socket/messages-send.js +1524 -0
  92. package/lib/Socket/mex.d.ts +1 -0
  93. package/lib/Socket/mex.js +41 -0
  94. package/lib/Socket/newsletter.d.ts +286 -0
  95. package/lib/Socket/newsletter.js +364 -0
  96. package/lib/Socket/socket.d.ts +60 -0
  97. package/lib/Socket/socket.js +1012 -0
  98. package/lib/Socket/username.d.ts +82 -0
  99. package/lib/Socket/username.js +159 -0
  100. package/lib/Store/index.d.ts +3 -0
  101. package/lib/Store/index.js +3 -0
  102. package/lib/Store/make-in-memory-store.d.ts +62 -0
  103. package/lib/Store/make-in-memory-store.js +428 -0
  104. package/lib/Store/make-ordered-dictionary.d.ts +12 -0
  105. package/lib/Store/make-ordered-dictionary.js +78 -0
  106. package/lib/Store/object-repository.d.ts +10 -0
  107. package/lib/Store/object-repository.js +23 -0
  108. package/lib/Types/Auth.d.ts +117 -0
  109. package/lib/Types/Auth.js +1 -0
  110. package/lib/Types/Bussines.d.ts +25 -0
  111. package/lib/Types/Call.d.ts +15 -0
  112. package/lib/Types/Call.js +1 -0
  113. package/lib/Types/Chat.d.ts +124 -0
  114. package/lib/Types/Chat.js +7 -0
  115. package/lib/Types/Contact.d.ts +26 -0
  116. package/lib/Types/Contact.js +1 -0
  117. package/lib/Types/Events.d.ts +256 -0
  118. package/lib/Types/Events.js +1 -0
  119. package/lib/Types/GroupMetadata.d.ts +71 -0
  120. package/lib/Types/GroupMetadata.js +1 -0
  121. package/lib/Types/Label.d.ts +5 -0
  122. package/lib/Types/Label.js +24 -0
  123. package/lib/Types/LabelAssociation.d.ts +6 -0
  124. package/lib/Types/LabelAssociation.js +6 -0
  125. package/lib/Types/Message.d.ts +62 -0
  126. package/lib/Types/Message.js +17 -0
  127. package/lib/Types/Mex.d.ts +2 -0
  128. package/lib/Types/Mex.js +38 -0
  129. package/lib/Types/Product.d.ts +79 -0
  130. package/lib/Types/Product.js +1 -0
  131. package/lib/Types/RichType.d.ts +2 -0
  132. package/lib/Types/RichType.js +22 -0
  133. package/lib/Types/Signal.d.ts +87 -0
  134. package/lib/Types/Signal.js +1 -0
  135. package/lib/Types/Socket.d.ts +138 -0
  136. package/lib/Types/Socket.js +1 -0
  137. package/lib/Types/State.d.ts +8 -0
  138. package/lib/Types/State.js +55 -0
  139. package/lib/Types/USync.d.ts +26 -0
  140. package/lib/Types/index.d.ts +68 -0
  141. package/lib/Types/index.js +27 -0
  142. package/lib/Utils/MessageBuilder.d.ts +2 -0
  143. package/lib/Utils/MessageBuilder.js +2 -0
  144. package/lib/Utils/PersistentStore.d.ts +60 -0
  145. package/lib/Utils/PersistentStore.js +592 -0
  146. package/lib/Utils/anti-delete.d.ts +74 -0
  147. package/lib/Utils/anti-delete.js +221 -0
  148. package/lib/Utils/auth-secure.d.ts +86 -0
  149. package/lib/Utils/auth-secure.js +764 -0
  150. package/lib/Utils/auth-utils.d.ts +57 -0
  151. package/lib/Utils/auth-utils.js +306 -0
  152. package/lib/Utils/auto-reply.d.ts +47 -0
  153. package/lib/Utils/auto-reply.js +157 -0
  154. package/lib/Utils/baileys-event-stream.d.ts +8 -0
  155. package/lib/Utils/baileys-event-stream.js +62 -0
  156. package/lib/Utils/browser-utils.d.ts +8 -0
  157. package/lib/Utils/browser-utils.js +27 -0
  158. package/lib/Utils/business.d.ts +49 -0
  159. package/lib/Utils/business.js +239 -0
  160. package/lib/Utils/button-helper-utils.d.ts +53 -0
  161. package/lib/Utils/button-helper-utils.js +312 -0
  162. package/lib/Utils/button-sender.d.ts +54 -0
  163. package/lib/Utils/button-sender.js +822 -0
  164. package/lib/Utils/chat-control.d.ts +159 -0
  165. package/lib/Utils/chat-control.js +230 -0
  166. package/lib/Utils/chat-history-helpers.d.ts +21 -0
  167. package/lib/Utils/chat-history-helpers.js +70 -0
  168. package/lib/Utils/chat-utils.d.ts +407 -0
  169. package/lib/Utils/chat-utils.js +885 -0
  170. package/lib/Utils/companion-reg-client-utils.d.ts +4 -0
  171. package/lib/Utils/companion-reg-client-utils.js +39 -0
  172. package/lib/Utils/crypto.d.ts +41 -0
  173. package/lib/Utils/crypto.js +147 -0
  174. package/lib/Utils/decode-wa-message.d.ts +83 -0
  175. package/lib/Utils/decode-wa-message.js +316 -0
  176. package/lib/Utils/event-buffer.d.ts +12 -0
  177. package/lib/Utils/event-buffer.js +635 -0
  178. package/lib/Utils/generics.d.ts +69 -0
  179. package/lib/Utils/generics.js +438 -0
  180. package/lib/Utils/history-share.d.ts +11 -0
  181. package/lib/Utils/history-share.js +70 -0
  182. package/lib/Utils/history.d.ts +90 -0
  183. package/lib/Utils/history.js +146 -0
  184. package/lib/Utils/humanizer.d.ts +12 -0
  185. package/lib/Utils/humanizer.js +73 -0
  186. package/lib/Utils/identity-change-handler.d.ts +13 -0
  187. package/lib/Utils/identity-change-handler.js +49 -0
  188. package/lib/Utils/index.d.ts +57 -0
  189. package/lib/Utils/index.js +56 -0
  190. package/lib/Utils/jid-tools.d.ts +6 -0
  191. package/lib/Utils/jid-tools.js +77 -0
  192. package/lib/Utils/link-preview.d.ts +12 -0
  193. package/lib/Utils/link-preview.js +84 -0
  194. package/lib/Utils/logger.d.ts +4 -0
  195. package/lib/Utils/logger.js +2 -0
  196. package/lib/Utils/lt-hash.d.ts +12 -0
  197. package/lib/Utils/lt-hash.js +26 -0
  198. package/lib/Utils/make-mutex.d.ts +6 -0
  199. package/lib/Utils/make-mutex.js +32 -0
  200. package/lib/Utils/media-messages.d.ts +18 -0
  201. package/lib/Utils/media-messages.js +70 -0
  202. package/lib/Utils/media-set.d.ts +13 -0
  203. package/lib/Utils/media-set.js +171 -0
  204. package/lib/Utils/message-kind.d.ts +32 -0
  205. package/lib/Utils/message-kind.js +136 -0
  206. package/lib/Utils/message-retry-manager.d.ts +79 -0
  207. package/lib/Utils/message-retry-manager.js +264 -0
  208. package/lib/Utils/message-search.d.ts +44 -0
  209. package/lib/Utils/message-search.js +188 -0
  210. package/lib/Utils/messages-media.d.ts +135 -0
  211. package/lib/Utils/messages-media.js +868 -0
  212. package/lib/Utils/messages.d.ts +44 -0
  213. package/lib/Utils/messages.js +2326 -0
  214. package/lib/Utils/meta-ai.d.ts +13 -0
  215. package/lib/Utils/meta-ai.js +74 -0
  216. package/lib/Utils/mini-app.d.ts +35 -0
  217. package/lib/Utils/mini-app.js +213 -0
  218. package/lib/Utils/noise-handler.d.ts +20 -0
  219. package/lib/Utils/noise-handler.js +200 -0
  220. package/lib/Utils/offline-node-processor.d.ts +9 -0
  221. package/lib/Utils/offline-node-processor.js +39 -0
  222. package/lib/Utils/past-participants.d.ts +14 -0
  223. package/lib/Utils/past-participants.js +40 -0
  224. package/lib/Utils/pre-key-manager.d.ts +25 -0
  225. package/lib/Utils/pre-key-manager.js +105 -0
  226. package/lib/Utils/process-message.d.ts +82 -0
  227. package/lib/Utils/process-message.js +808 -0
  228. package/lib/Utils/qr-render.d.ts +59 -0
  229. package/lib/Utils/qr-render.js +179 -0
  230. package/lib/Utils/qrcodegen.d.ts +79 -0
  231. package/lib/Utils/qrcodegen.js +848 -0
  232. package/lib/Utils/reporting-utils.d.ts +12 -0
  233. package/lib/Utils/reporting-utils.js +257 -0
  234. package/lib/Utils/rich-message-utils.d.ts +48 -0
  235. package/lib/Utils/rich-message-utils.js +444 -0
  236. package/lib/Utils/router.d.ts +37 -0
  237. package/lib/Utils/router.js +165 -0
  238. package/lib/Utils/scheduled-posts.d.ts +30 -0
  239. package/lib/Utils/scheduled-posts.js +110 -0
  240. package/lib/Utils/scheduling.d.ts +42 -0
  241. package/lib/Utils/scheduling.js +139 -0
  242. package/lib/Utils/signal.d.ts +82 -0
  243. package/lib/Utils/signal.js +200 -0
  244. package/lib/Utils/stanza-ack.d.ts +16 -0
  245. package/lib/Utils/stanza-ack.js +37 -0
  246. package/lib/Utils/status.d.ts +50 -0
  247. package/lib/Utils/status.js +107 -0
  248. package/lib/Utils/stickerpack.d.ts +51 -0
  249. package/lib/Utils/stickerpack.js +274 -0
  250. package/lib/Utils/sync-action-utils.d.ts +2 -0
  251. package/lib/Utils/sync-action-utils.js +48 -0
  252. package/lib/Utils/tag.d.ts +12 -0
  253. package/lib/Utils/tag.js +44 -0
  254. package/lib/Utils/tc-token-utils.d.ts +29 -0
  255. package/lib/Utils/tc-token-utils.js +162 -0
  256. package/lib/Utils/templates.d.ts +76 -0
  257. package/lib/Utils/templates.js +150 -0
  258. package/lib/Utils/transcribe.d.ts +12 -0
  259. package/lib/Utils/transcribe.js +107 -0
  260. package/lib/Utils/use-cache-manager-auth-state.d.ts +13 -0
  261. package/lib/Utils/use-cache-manager-auth-state.js +81 -0
  262. package/lib/Utils/use-multi-file-auth-state.d.ts +10 -0
  263. package/lib/Utils/use-multi-file-auth-state.js +166 -0
  264. package/lib/Utils/use-single-file-auth-state.d.ts +10 -0
  265. package/lib/Utils/use-single-file-auth-state.js +113 -0
  266. package/lib/Utils/use-sqlite-auth-state.d.ts +11 -0
  267. package/lib/Utils/use-sqlite-auth-state.js +169 -0
  268. package/lib/Utils/validate-connection.d.ts +42 -0
  269. package/lib/Utils/validate-connection.js +198 -0
  270. package/lib/Utils/vcard.d.ts +58 -0
  271. package/lib/Utils/vcard.js +104 -0
  272. package/lib/Utils/voice-note.d.ts +15 -0
  273. package/lib/Utils/voice-note.js +63 -0
  274. package/lib/VoIP/audio-feeder.d.ts +18 -0
  275. package/lib/VoIP/audio-feeder.js +160 -0
  276. package/lib/VoIP/call-recorder.d.ts +13 -0
  277. package/lib/VoIP/call-recorder.js +73 -0
  278. package/lib/VoIP/index.d.ts +86 -0
  279. package/lib/VoIP/index.js +611 -0
  280. package/lib/VoIP/relay-transport.d.ts +43 -0
  281. package/lib/VoIP/relay-transport.js +563 -0
  282. package/lib/VoIP/signaling.d.ts +26 -0
  283. package/lib/VoIP/signaling.js +662 -0
  284. package/lib/VoIP/types.d.ts +69 -0
  285. package/lib/VoIP/types.js +17 -0
  286. package/lib/VoIP/wasm-engine.d.ts +120 -0
  287. package/lib/VoIP/wasm-engine.js +1358 -0
  288. package/lib/VoIP/worker-bootstrap.d.ts +4 -0
  289. package/lib/VoIP/worker-bootstrap.js +1046 -0
  290. package/lib/WABinary/constants.d.ts +61 -0
  291. package/lib/WABinary/constants.js +1466 -0
  292. package/lib/WABinary/decode.d.ts +9 -0
  293. package/lib/WABinary/decode.js +261 -0
  294. package/lib/WABinary/encode.d.ts +2 -0
  295. package/lib/WABinary/encode.js +219 -0
  296. package/lib/WABinary/generic-utils.d.ts +74 -0
  297. package/lib/WABinary/generic-utils.js +276 -0
  298. package/lib/WABinary/index.d.ts +5 -0
  299. package/lib/WABinary/index.js +5 -0
  300. package/lib/WABinary/jid-utils.d.ts +28 -0
  301. package/lib/WABinary/jid-utils.js +95 -0
  302. package/lib/WABinary/types.d.ts +19 -0
  303. package/lib/WABinary/types.js +1 -0
  304. package/lib/WAM/BinaryInfo.d.ts +7 -0
  305. package/lib/WAM/BinaryInfo.js +9 -0
  306. package/lib/WAM/constants.d.ts +34926 -0
  307. package/lib/WAM/constants.js +22852 -0
  308. package/lib/WAM/encode.d.ts +1 -0
  309. package/lib/WAM/encode.js +149 -0
  310. package/lib/WAM/index.d.ts +3 -0
  311. package/lib/WAM/index.js +3 -0
  312. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +36 -0
  313. package/lib/WAUSync/Protocols/USyncContactProtocol.js +51 -0
  314. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +29 -0
  315. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +62 -0
  316. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  317. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +26 -0
  318. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  319. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +37 -0
  320. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +9 -0
  321. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +24 -0
  322. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +38 -0
  323. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +50 -0
  324. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +14 -0
  325. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +28 -0
  326. package/lib/WAUSync/Protocols/index.d.ts +7 -0
  327. package/lib/WAUSync/Protocols/index.js +7 -0
  328. package/lib/WAUSync/USyncQuery.d.ts +20 -0
  329. package/lib/WAUSync/USyncQuery.js +121 -0
  330. package/lib/WAUSync/USyncUser.d.ts +16 -0
  331. package/lib/WAUSync/USyncUser.js +30 -0
  332. package/lib/WAUSync/index.d.ts +3 -0
  333. package/lib/WAUSync/index.js +3 -0
  334. package/lib/assets/wasm/loader.d.ts +5 -0
  335. package/lib/assets/wasm/loader.js +5 -0
  336. package/lib/assets/wasm/whatsapp.wasm +0 -0
  337. package/lib/assets/wasm/worker-modules.d.ts +5 -0
  338. package/lib/assets/wasm/worker-modules.js +273 -0
  339. package/lib/index.d.ts +18 -0
  340. package/lib/index.js +23 -0
  341. package/package.json +180 -0
  342. package/postinstall-banner.js +82 -0
@@ -0,0 +1,652 @@
1
+ /**
2
+ * lib/Utils/MessageBuilder.js — AIRich / Button / ButtonV2 / Carousel / Toolkit
3
+ *
4
+ * Part of @japofc/baileys 1.4.4. Third-party attribution for the base
5
+ * implementation this file was adapted from is kept in /NOTICE.md
6
+ * (not inline here) per the original author's license terms.
7
+ *
8
+ * JAP@Merge 15-08-26 --- Ported into @japofc/baileys 1.3.9 from the
9
+ * @blurose/baileys 1.1.13 fork (base, feature-complete) with perf defaults
10
+ * and message-authenticity fields backported from arslan-baileys 1.1.0 and
11
+ * this project's own rich-message-utils.js. See changes tagged "JAP@" below.
12
+ *
13
+ * JAP@Fix 23-08-26 --- v4.7 -> v4.8. addGenerating() now defaults to appending a
14
+ * FOATextPrimitive text fallback ('[ Sedang diproses... ]'), same pattern as
15
+ * addTask/addThinkingStatus/addBloks. Previously the card had no client-visible
16
+ * content until WA's own timeout swapped it for its built-in failed-generation
17
+ * text; this makes the fallback instant. Opt out with { textFallback: false }.
18
+ *
19
+ * JAP@Merge 22-08-26 --- v4.6 -> v4.7. Button class hardened + extended:
20
+ * - Bug fix: addCall() wrote its second arg into buttonParamsJson.id, but
21
+ * the cta_call native-flow schema keys on `phone_number` (id is ignored
22
+ * by WhatsApp for this button type). Confirmed against 3 independent
23
+ * current Baileys-fork call sites before changing the wire shape.
24
+ * - Required-field validation added to the CTA helpers that silently
25
+ * produced a button WA would render but never route correctly
26
+ * (empty id/url/copy_code/phone_number).
27
+ * - New native-flow helpers for names WA recognises beyond the "mixed"
28
+ * set (cta_catalog, open_webview, call_permission_request,
29
+ * automated_greeting_message_view_catalog, payment_info,
30
+ * review_and_pay, wa_payment_transaction_details, mpm) — see the
31
+ * Button.#SPECIAL_FLOW map and each method's JSDoc for the
32
+ * business/official-client gating caveat.
33
+ * - send() now picks the correct <native_flow v=.. name=..> node per the
34
+ * first button's name instead of always emitting v=9 name=mixed, which
35
+ * is required for the special names above to have a chance of
36
+ * rendering at all (mirrors the same class of bug already fixed for
37
+ * lone single_select in 1.3.x).
38
+ * - JSDoc added across Toolkit/BaseBuilder/Button/ButtonV2/Carousel/AIRich
39
+ * for editor hover-docs; kept in sync with MessageBuilder.d.ts.
40
+ * All additions above are original implementations written against public
41
+ * Baileys-ecosystem documentation of the native-flow wire format, not
42
+ * copied from any third-party fork.
43
+ */
44
+
45
+ 'use strict';
46
+
47
+ // JAP@Fix 24-08-26: use the exported builder version everywhere; the old
48
+ // verification helper referenced an undeclared `VERSION`, making every AIRich.build() fail.
49
+
50
+
51
+ import { generateWAMessageFromContent, prepareWAMessageMedia } from '../Utils/messages.js';
52
+ import { generateMessageIDV2 } from '../Utils/generics.js';
53
+ import { botMetadataSignature, botMetadataCertificate } from '../Utils/rich-message-utils.js';
54
+ // JAP@Fix 27-08-26: Button.send() was hand-rolling its own <biz> node with
55
+ // attrs: {} instead of reusing the canonical builder. Real client traffic
56
+ // (and the auto-attached biz node in Socket/messages-send.js) always carries
57
+ // actual_actors/host_storage/privacy_mode_ts on every <biz> node, including
58
+ // the one wrapping a lone single_select's <list> node. Missing them made the
59
+ // single_select wire payload diverge from what messages-send.js emits for
60
+ // every other message type -- import the shared helper instead of duplicating
61
+ // (and silently drifting from) its attrs.
62
+ import { getBizBinaryNode } from '../WABinary/index.js';
63
+ import crypto from 'crypto';
64
+ import { PassThrough, Readable } from 'stream';
65
+ // JAP@Fix 15-08-26 --- sharp/fluent-ffmpeg were statically imported in the blurose source.
66
+ // Both are optional peer deps here (see package.json peerDependenciesMeta); a static import
67
+ // throws at module-load time when they're not installed, which would crash the entire
68
+ // lib/Utils barrel export (and therefore bot startup) even for users who never call
69
+ // AIRich.addImage()/addVideo()/Toolkit.*. Lazy-load them instead, matching the pattern
70
+ // already used in messages-media.js's getImageProcessingLibrary().
71
+ let _sharp;
72
+ const getSharp = async () => {
73
+ if (_sharp === undefined) {
74
+ _sharp = await import('sharp').then((m) => m.default ?? m).catch(() => null);
75
+ }
76
+ if (!_sharp)
77
+ throw new Error('sharp is required for this operation. Install it with: npm i sharp');
78
+ return _sharp;
79
+ };
80
+ let _ffmpeg;
81
+ const getFfmpeg = async () => {
82
+ if (_ffmpeg === undefined) {
83
+ _ffmpeg = await import('fluent-ffmpeg').then((m) => m.default ?? m).catch(() => null);
84
+ }
85
+ if (!_ffmpeg)
86
+ throw new Error('fluent-ffmpeg is required for this operation. Install it with: npm i fluent-ffmpeg');
87
+ return _ffmpeg;
88
+ };
89
+
90
+ function extractIE(text, { extract = true, hyperlink = true, citation = true, latex = true } = {}) {
91
+ if (!extract) {
92
+ return {
93
+ text,
94
+ ie: [],
95
+ inline_entities: [],
96
+ };
97
+ }
98
+
99
+ const createIE = (type, ie) => {
100
+ if (type == 'hyperlink') {
101
+ return {
102
+ key: ie.key,
103
+ metadata: {
104
+ display_name: ie.text,
105
+ is_trusted: ie.is_trusted,
106
+ url: ie.url,
107
+ __typename: 'GenAIInlineLinkItem',
108
+ },
109
+ };
110
+ }
111
+
112
+ if (type == 'citation') {
113
+ return {
114
+ key: ie.key,
115
+ metadata: {
116
+ reference_id: ie.reference_id,
117
+ reference_url: ie.url,
118
+ reference_title: ie.url,
119
+ reference_display_name: ie.url,
120
+ sources: [],
121
+ __typename: 'GenAISearchCitationItem',
122
+ },
123
+ };
124
+ }
125
+
126
+ if (type == 'latex') {
127
+ return {
128
+ key: ie.key,
129
+ metadata: {
130
+ latex_expression: ie.text,
131
+ latex_image: {
132
+ url: ie.url,
133
+ width: Number(ie.width) || 100,
134
+ height: Number(ie.height) || 100,
135
+ },
136
+ font_height: Number(ie.font_height) || 83.333333333333,
137
+ padding: Number(ie.padding) || 15,
138
+ __typename: 'GenAILatexItem',
139
+ },
140
+ };
141
+ }
142
+ };
143
+
144
+ let ie = [];
145
+ let inline_entities = [];
146
+ let result = '';
147
+ let last = 0;
148
+ let citation_index = 1;
149
+ let hyperlink_index = 0;
150
+ let latex_index = 0;
151
+ let stack = [];
152
+
153
+ for (let i = 0; i < text.length; i++) {
154
+ if (text[i] == '[' && text[i - 1] != '\\') {
155
+ stack.push(i);
156
+ } else if (text[i] == ']' && (text[i + 1] == '(' || text[i + 1] == '<')) {
157
+ let start = stack.pop();
158
+
159
+ if (start == null) continue;
160
+
161
+ let open = text[i + 1];
162
+ let close = open == '(' ? ')' : '>';
163
+ let type = open == '(' ? 'link' : 'latex';
164
+ let end = i + 2;
165
+ let depth = 1;
166
+
167
+ while (end < text.length && depth) {
168
+ if (text[end] == open && text[end - 1] != '\\') depth++;
169
+ else if (text[end] == close && text[end - 1] != '\\') depth--;
170
+ end++;
171
+ }
172
+
173
+ if (depth) continue;
174
+
175
+ let raw = text.slice(start + 1, i).trim();
176
+ let url = text.slice(i + 2, end - 1).trim();
177
+
178
+ let key;
179
+ let tag;
180
+ let data;
181
+
182
+ if (type == 'latex') {
183
+ if (!latex) continue;
184
+
185
+ let [txt = '', width = null, height = null, font_height = null, padding = null] = raw.split('|');
186
+
187
+ key = `\u004E\u0049\u0058\u0045\u004C_LATEX_${latex_index++}`;
188
+ tag = `{{${key}}}${txt || 'image'}{{/${key}}}`;
189
+
190
+ data = {
191
+ type: 'latex',
192
+ ie: {
193
+ key,
194
+ text: txt,
195
+ url,
196
+ width,
197
+ height,
198
+ font_height,
199
+ padding,
200
+ },
201
+ };
202
+ } else if (raw) {
203
+ if (!hyperlink) continue;
204
+
205
+ const trusted = !url.startsWith('!');
206
+
207
+ if (!trusted) {
208
+ url = url.slice(1);
209
+ }
210
+
211
+ key = `\u004E\u0049\u0058\u0045\u004C_HYPERLINK_${hyperlink_index++}`;
212
+ tag = `{{${key}}}${url}{{/${key}}}`;
213
+
214
+ data = {
215
+ type: 'hyperlink',
216
+ ie: {
217
+ key,
218
+ text: raw,
219
+ url,
220
+ is_trusted: trusted,
221
+ },
222
+ };
223
+ } else {
224
+ if (!citation) continue;
225
+
226
+ key = `\u004E\u0049\u0058\u0045\u004C_CITATION_${citation_index - 1}`;
227
+ tag = `{{${key}}}${url}{{/${key}}}`;
228
+
229
+ data = {
230
+ type: 'citation',
231
+ ie: {
232
+ reference_id: citation_index++,
233
+ key,
234
+ text: '',
235
+ url,
236
+ },
237
+ };
238
+ }
239
+
240
+ result += text.slice(last, start) + tag;
241
+ last = end;
242
+
243
+ ie.push(data);
244
+
245
+ const entity = createIE(data.type, data.ie);
246
+
247
+ if (entity) {
248
+ inline_entities.push(entity);
249
+ }
250
+
251
+ i = end - 1;
252
+ }
253
+ }
254
+
255
+ result += text.slice(last);
256
+
257
+ return {
258
+ text: result,
259
+ ie,
260
+ inline_entities,
261
+ };
262
+ }
263
+
264
+ async function waitAllPromises(input) {
265
+ const isPromise = (v) => v && typeof v.then === 'function';
266
+ const isObject = (v) => v && typeof v === 'object';
267
+
268
+ const deep = async (v) => {
269
+ if (isPromise(v)) return deep(await v);
270
+ if (Array.isArray(v)) return Promise.all(v.map(deep));
271
+ if (isObject(v)) {
272
+ const entries = await Promise.all(Object.entries(v).map(async ([k, val]) => [k, await deep(val)]));
273
+ return Object.fromEntries(entries);
274
+ }
275
+ return v;
276
+ };
277
+
278
+ return deep(await input);
279
+ }
280
+
281
+ /** Static grab-bag of media/text helpers shared by the builder classes above. */
282
+ class Toolkit {
283
+ constructor() {}
284
+
285
+ /** Parse `[label](url)` hyperlinks, `[]()` citations, and `[expr]<img-url>` latex tags out of `text`. */
286
+ static extractIE(text, { extract = true, hyperlink = true, citation = true, latex = true } = {}) {
287
+ return extractIE(text, { extract, hyperlink, citation, latex });
288
+ }
289
+
290
+ /** Resize an image buffer to `x`×`y` via sharp (lazy-loaded; throws with an install hint if sharp isn't present). */
291
+ static async resize(buffer, x, y, fit = 'cover') {
292
+ const sharp = await getSharp();
293
+ return await sharp(buffer)
294
+ .resize(x, y, {
295
+ fit,
296
+ position: 'center',
297
+ background: { r: 0, g: 0, b: 0, alpha: 0 },
298
+ })
299
+ .png()
300
+ .toBuffer();
301
+ }
302
+
303
+ /** Deeply await every Promise nested in `input` (objects/arrays), resolving it into plain values. */
304
+ static async waitAllPromises(input) {
305
+ return await waitAllPromises(input);
306
+ }
307
+
308
+ /** Fetch `url` into a Buffer. @param {boolean} [silent] Return an empty Buffer instead of throwing on failure. @param {number} [timeout] Abort after this many ms (default 15s) instead of hanging indefinitely on a dead/slow host. */
309
+ static async fetchBuffer(url, options = {}, { silent = true, timeout = 15000 } = {}) {
310
+ const controller = new AbortController();
311
+ const timer = setTimeout(() => controller.abort(), timeout);
312
+ try {
313
+ let response = await fetch(url, { ...options, signal: options.signal ?? controller.signal });
314
+ if (!response.ok) throw Error(`HTTP ${response.status}`);
315
+ return Buffer.from(await response.arrayBuffer());
316
+ } catch (error) {
317
+ if (silent) return Buffer.alloc(0);
318
+ throw error;
319
+ } finally {
320
+ clearTimeout(timer);
321
+ }
322
+ }
323
+
324
+ /** Upload media to WhatsApp's media server and return its `url`/`directPath` descriptor. */
325
+ static async toUrl(_client, path, mediaType = 'document') {
326
+ if (!path) throw new Error('Url or buffer needed');
327
+
328
+ const media = await prepareWAMessageMedia(
329
+ {
330
+ [mediaType]: Buffer.isBuffer(path) ? path : { url: path },
331
+ },
332
+ {
333
+ upload: _client.waUploadToServer,
334
+ jid: '\u0040\u006e\u0065\u0077\u0073\u006c\u0065\u0074\u0074\u0065\u0072',
335
+ }
336
+ );
337
+
338
+ return Object.values(media)[0]?.url;
339
+ }
340
+
341
+ /** Normalize a url/buffer/array of either into the requested `result` shape ('url' | 'buffer' | 'base64'), optionally resizing and/or uploading to WA's media server first. */
342
+ static async resolveMedia(_client, media, mediaType = 'image', { resolveUrl = false, resolveWAUrl = false, result = 'url', resize = false, width = 300, height = 300 } = {}) {
343
+ const isUrl = (str) => /^https?:\/\/.+/i.test(str);
344
+
345
+ const isWAUrl = (str) => /^https?:\/\/[^/]*\.whatsapp\.net\//i.test(str);
346
+
347
+ // JAP@Fix (crash guard) --- keep the original raw url around so that if the
348
+ // resolveUrl=true upload-to-'@newsletter' round trip (Toolkit.toUrl -> prepareWAMessageMedia)
349
+ // throws/rejects (blocked account, network hiccup, WA server refusal, etc.), we can
350
+ // gracefully fall back to the raw url instead of letting the rejection bubble up
351
+ // unhandled through waitAllPromises() and take the whole process down. Only applies
352
+ // when the input was actually a url string; buffers/base64 have no such fallback.
353
+ const rawUrlFallback = typeof media === 'string' && isUrl(media) ? media : undefined;
354
+
355
+ if (Array.isArray(media)) {
356
+ return Promise.all(
357
+ media.map((item) =>
358
+ Toolkit.resolveMedia(_client, item, mediaType, {
359
+ resolveUrl,
360
+ resolveWAUrl,
361
+ result,
362
+ resize,
363
+ width,
364
+ height,
365
+ })
366
+ )
367
+ );
368
+ }
369
+
370
+ if (typeof media === 'string' && isUrl(media)) {
371
+ if (isWAUrl(media)) {
372
+ if (resolveWAUrl) {
373
+ media = await Toolkit.fetchBuffer(media, {}, { silent: true });
374
+ } else if (!resolveUrl) {
375
+ if (result === 'url') return media;
376
+
377
+ media = await Toolkit.fetchBuffer(media, {}, { silent: true });
378
+ }
379
+ } else {
380
+ if (!resolveUrl) {
381
+ if (result === 'url') return media;
382
+
383
+ media = await Toolkit.fetchBuffer(media, {}, { silent: true });
384
+ } else {
385
+ media = await Toolkit.fetchBuffer(media, {}, { silent: true });
386
+ }
387
+ }
388
+ }
389
+
390
+ if (typeof media === 'string' && !isUrl(media)) {
391
+ media = Buffer.from(media, 'base64');
392
+ }
393
+
394
+ if (!Buffer.isBuffer(media) || !media.length) {
395
+ return;
396
+ }
397
+
398
+ if (resize && Buffer.isBuffer(media)) {
399
+ media = await Toolkit.resize(media, width, height);
400
+ }
401
+
402
+ if (result === 'buffer') {
403
+ return media;
404
+ }
405
+
406
+ if (result === 'base64') {
407
+ return media.toString('base64');
408
+ }
409
+
410
+ // JAP@Fix 22-08-26 (v4.7) --- both branches of the old if/else here returned the exact
411
+ // same `Toolkit.toUrl(_client, media, mediaType)` call (dead branching left over from an
412
+ // earlier version that must have treated buffer vs non-buffer input differently). Collapsed
413
+ // to a single return; `originalIsBuffer` is now unused and removed below.
414
+ //
415
+ // JAP@Fix (crash guard) --- toUrl() uploads to WA's media server under a spoofed
416
+ // '@newsletter' jid; if that upload fails for any reason, fall back to the raw url
417
+ // (when we have one) instead of letting the exception propagate and crash the caller.
418
+ try {
419
+ return await Toolkit.toUrl(_client, media, mediaType);
420
+ } catch (err) {
421
+ if (rawUrlFallback) return rawUrlFallback;
422
+ throw err;
423
+ }
424
+ }
425
+
426
+ /** Read an mp4 buffer's duration (seconds) straight from its moov atom, no ffprobe needed. */
427
+ static getMp4Duration(buffer, { silent = true } = {}) {
428
+ try {
429
+ if (!Buffer.isBuffer(buffer) || buffer.length < 8) {
430
+ if (silent) return 0;
431
+ throw new Error('Invalid buffer');
432
+ }
433
+
434
+ let offset = 0;
435
+
436
+ while (offset < buffer.length - 8) {
437
+ const size = buffer.readUInt32BE(offset);
438
+
439
+ if (size < 8 || offset + size > buffer.length) {
440
+ if (silent) return 0;
441
+ throw new Error('Invalid atom size');
442
+ }
443
+
444
+ const type = buffer.toString('ascii', offset + 4, offset + 8);
445
+
446
+ if (type === 'moov') {
447
+ let moovOffset = offset + 8;
448
+ const moovEnd = offset + size;
449
+
450
+ while (moovOffset < moovEnd - 8) {
451
+ const childSize = buffer.readUInt32BE(moovOffset);
452
+
453
+ if (childSize < 8 || moovOffset + childSize > moovEnd) {
454
+ if (silent) return 0;
455
+ throw new Error('Invalid child atom size');
456
+ }
457
+
458
+ const childType = buffer.toString('ascii', moovOffset + 4, moovOffset + 8);
459
+
460
+ if (childType === 'mvhd') {
461
+ const version = buffer.readUInt8(moovOffset + 8);
462
+
463
+ if (version === 0) {
464
+ const timescale = buffer.readUInt32BE(moovOffset + 20);
465
+ const duration = buffer.readUInt32BE(moovOffset + 24);
466
+
467
+ if (!timescale) {
468
+ if (silent) return 0;
469
+ throw new Error('Invalid timescale');
470
+ }
471
+
472
+ return duration / timescale;
473
+ }
474
+
475
+ if (version === 1) {
476
+ const timescale = buffer.readUInt32BE(moovOffset + 32);
477
+ const duration = Number(buffer.readBigUInt64BE(moovOffset + 36));
478
+
479
+ if (!timescale) {
480
+ if (silent) return 0;
481
+ throw new Error('Invalid timescale');
482
+ }
483
+
484
+ return duration / timescale;
485
+ }
486
+ }
487
+
488
+ moovOffset += childSize;
489
+ }
490
+ }
491
+
492
+ offset += size;
493
+ }
494
+
495
+ if (silent) return 0;
496
+
497
+ throw new Error('No mvhd found!');
498
+ } catch (err) {
499
+ if (silent) return 0;
500
+ throw err;
501
+ }
502
+ }
503
+
504
+ /** Extract a single frame from an mp4 buffer as a thumbnail (ffmpeg lazy-loaded; throws with an install hint if missing). */
505
+ static getMp4Preview(videoBuffer, { time, result = 'buffer', resize = true, width = 300, height = 300, silent = true } = {}) {
506
+ return new Promise((resolve, reject) => {
507
+ const fail = (err) => {
508
+ if (silent) {
509
+ return resolve(result === 'base64' ? '' : Buffer.alloc(0));
510
+ }
511
+ return reject(err);
512
+ };
513
+
514
+ try {
515
+ if (!Buffer.isBuffer(videoBuffer) || !videoBuffer.length) {
516
+ return fail(new Error('videoBuffer tidak valid atau kosong'));
517
+ }
518
+
519
+ const inputStream = new Readable({ read() {} });
520
+ inputStream.push(videoBuffer);
521
+ inputStream.push(null);
522
+
523
+ const outputStream = new PassThrough();
524
+ const chunks = [];
525
+
526
+ outputStream.on('data', (chunk) => chunks.push(chunk));
527
+
528
+ outputStream.on('end', async () => {
529
+ try {
530
+ let output = Buffer.concat(chunks);
531
+
532
+ if (!output.length) {
533
+ return fail(new Error('Output kosong — cek format atau timestamp video'));
534
+ }
535
+
536
+ if (resize) {
537
+ output = await Toolkit.resize(output, width, height);
538
+ }
539
+
540
+ return resolve(result === 'base64' ? output.toString('base64') : output);
541
+ } catch (err) {
542
+ return fail(err);
543
+ }
544
+ });
545
+
546
+ outputStream.on('error', fail);
547
+
548
+ time ??= Math.min(Toolkit.getMp4Duration(videoBuffer) * 0.2, 10);
549
+
550
+ getFfmpeg()
551
+ .then((ffmpeg) => {
552
+ ffmpeg(inputStream)
553
+ .outputOptions([`-ss ${time}`, '-vframes 1', '-vcodec png', '-f image2pipe'])
554
+ .on('error', (err) => fail(new Error(`ffmpeg error: ${err.message}`)))
555
+ .pipe(outputStream, { end: true });
556
+ })
557
+ .catch(fail);
558
+ } catch (err) {
559
+ return fail(err);
560
+ }
561
+ });
562
+ }
563
+ }
564
+
565
+ /**
566
+ * Shared chaining base for Button/ButtonV2/Carousel/AIRich: title/subtitle/body/footer,
567
+ * contextInfo (quoted/mentions/etc.), and an escape-hatch payload merged verbatim
568
+ * into the generated message content.
569
+ * @abstract
570
+ */
571
+ class BaseBuilder {
572
+ constructor() {
573
+ this._title = '';
574
+ this._subtitle = '';
575
+ this._body = '';
576
+ this._footer = '';
577
+ this._contextInfo = {};
578
+ this._extraPayload = {};
579
+ }
580
+
581
+ /** @param {string} title */
582
+ setTitle(title) {
583
+ if (typeof title !== 'string') {
584
+ throw new TypeError('Title must be a string');
585
+ }
586
+ this._title = title;
587
+ return this;
588
+ }
589
+
590
+ /** @param {string} subtitle */
591
+ setSubtitle(subtitle) {
592
+ if (typeof subtitle !== 'string') {
593
+ throw new TypeError('Subtitle must be a string');
594
+ }
595
+ this._subtitle = subtitle;
596
+ return this;
597
+ }
598
+
599
+ /** @param {string} body Main message text. */
600
+ setBody(body) {
601
+ if (typeof body !== 'string') {
602
+ throw new TypeError('Body must be a string');
603
+ }
604
+ this._body = body;
605
+ return this;
606
+ }
607
+
608
+ /** @param {string} footer */
609
+ setFooter(footer) {
610
+ if (typeof footer !== 'string') {
611
+ throw new TypeError('Footer must be a string');
612
+ }
613
+ this._footer = footer;
614
+ return this;
615
+ }
616
+
617
+ /** @param {Record<string, any>} obj Raw `contextInfo` (quotedMessage, mentionedJid, etc.), merged verbatim. */
618
+ setContextInfo(obj) {
619
+ if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
620
+ throw new TypeError('ContextInfo must be a plain object');
621
+ }
622
+
623
+ this._contextInfo = obj;
624
+ return this;
625
+ }
626
+
627
+ /** Escape hatch: shallow-merge arbitrary keys into the generated message content, alongside whatever this builder produces. */
628
+ addPayload(obj) {
629
+ if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
630
+ throw new TypeError('Payload must be a plain object');
631
+ }
632
+
633
+ Object.assign(this._extraPayload, obj);
634
+
635
+ return this;
636
+ }
637
+ }
638
+
639
+ /** Tiny fluent helper for building a single quickReply button row (type 1). Standalone — not tied to Button/ButtonV2. */
640
+ class RowBuilder {
641
+ constructor() {
642
+ this.buttons = [];
643
+ }
644
+
645
+ button(displayText, buttonId) {
646
+ this.buttons.push({ buttonId, buttonText: { displayText }, type: 1 });
647
+ return this;
648
+ }
649
+ }
650
+
651
+
652
+ export { Toolkit, BaseBuilder, RowBuilder, extractIE, waitAllPromises, getSharp, getFfmpeg, generateWAMessageFromContent, prepareWAMessageMedia, generateMessageIDV2, botMetadataSignature, botMetadataCertificate, getBizBinaryNode, crypto, PassThrough, Readable };