@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
package/README.md ADDED
@@ -0,0 +1,1254 @@
1
+ <div align="center" id="top">
2
+
3
+ <img src="https://capsule-render.vercel.app/api?type=waving&color=0:2ecc71,100:1d6a23&height=180&section=header&text=%40japofc%2Fbaileys&fontSize=48&fontColor=ffffff&animation=fadeIn&fontAlignY=35&desc=WhatsApp%20Web%20API%20%E2%80%94%20typed%2C%20extended%2C%20battle-tested&descSize=16&descAlignY=55" width="100%" alt="@japofc/baileys banner"/>
4
+
5
+ <p>
6
+ <img src="https://readme-typing-svg.demolab.com?font=Fira+Code&size=18&pause=1200&color=2ECC71&center=true&vCenter=true&width=650&lines=Extended+interactive+messages+%26+native+flow;Status+tools+%2B+quality-of-life+fixes;WhatsApp+automation+toolkit" alt="Typing SVG" />
7
+ </p>
8
+
9
+ <p>
10
+ <a href="https://www.npmjs.com/package/@japofc/baileys" target="_blank"><img src="https://img.shields.io/npm/v/@japofc/baileys?color=2ecc71&label=npm&style=for-the-badge" alt="npm version"/></a>
11
+ <a href="https://www.npmjs.com/package/@japofc/baileys" target="_blank"><img src="https://img.shields.io/npm/dt/@japofc/baileys?color=3498db&style=for-the-badge" alt="npm downloads"/></a>
12
+ <a href="https://github.com/JAPofc/baileys/stargazers" target="_blank"><img src="https://img.shields.io/github/stars/JAPofc/baileys?color=f1c40f&style=for-the-badge" alt="GitHub stars"/></a>
13
+ <a href="https://github.com/JAPofc/baileys/issues" target="_blank"><img src="https://img.shields.io/github/issues/JAPofc/baileys?color=e74c3c&style=for-the-badge" alt="GitHub issues"/></a>
14
+ </p>
15
+ <p>
16
+ <a href="https://github.com/JAPofc/baileys/actions/workflows/ci.yml" target="_blank"><img src="https://img.shields.io/github/actions/workflow/status/JAPofc/baileys/ci.yml?branch=main&style=flat-square&label=CI&color=2ecc71" alt="CI status"/></a>
17
+ <img src="https://img.shields.io/badge/tests-174%20passing-2ecc71?style=flat-square" alt="Tests"/>
18
+ <img src="https://img.shields.io/badge/tsc%20--strict-clean-3178c6?style=flat-square&logo=typescript&logoColor=white" alt="tsc strict clean"/>
19
+ <img src="https://img.shields.io/github/last-commit/JAPofc/baileys?color=9b59b6&style=flat-square" alt="Last commit"/>
20
+ <img src="https://img.shields.io/github/languages/code-size/JAPofc/baileys?color=e67e22&style=flat-square" alt="Code size"/>
21
+ <img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen?style=flat-square" alt="Node >=20"/>
22
+ <img src="https://img.shields.io/badge/module-ESM-blue?style=flat-square" alt="ESM"/>
23
+ <img src="https://img.shields.io/badge/dependencies-zero%20QR%2FPNG%20deps-success?style=flat-square" alt="Zero extra deps"/>
24
+ <img src="https://img.shields.io/badge/license-see%20NOTICE-lightgrey?style=flat-square" alt="License"/>
25
+ </p>
26
+
27
+ <p>
28
+ <img src="https://komarev.com/ghpvc/?username=JAPofc&repo=baileys&color=2ecc71&style=for-the-badge&label=Repo+Views" alt="Visitor count"/>
29
+ </p>
30
+
31
+ <p>
32
+ <a href="#-why-this-fork">About</a> &#xa0;|&#xa0;
33
+ <a href="#-comparison">Comparison</a> &#xa0;|&#xa0;
34
+ <a href="#-features">Features</a> &#xa0;|&#xa0;
35
+ <a href="#-installation">Installation</a> &#xa0;|&#xa0;
36
+ <a href="#-quick-start">Quick Start</a> &#xa0;|&#xa0;
37
+ <a href="#-usage-examples">Examples</a> &#xa0;|&#xa0;
38
+ <a href="#-faq--troubleshooting">FAQ</a> &#xa0;|&#xa0;
39
+ <a href="#-contributing">Contributing</a> &#xa0;|&#xa0;
40
+ <a href="#-credits">Credits</a> &#xa0;|&#xa0;
41
+ <a href="#-maintainer">Maintainer</a>
42
+ </p>
43
+
44
+ <details>
45
+ <summary>📖 Full table of contents</summary>
46
+ <br/>
47
+
48
+ - [🍃 Why this fork](#-why-this-fork)
49
+ - [🆚 Comparison](#-comparison)
50
+ - [🧰 Built With](#-built-with)
51
+ - [🔥 Features](#-features)
52
+ - [✨ Exclusive J.AP Enhancements](#-exclusive-jap-enhancements)
53
+ - [📦 Installation](#-installation)
54
+ - [🚀 Quick Start](#-quick-start)
55
+ - [🔐 Authentication](#-authentication)
56
+ - [🗄️ Store Backends](#-store-backends)
57
+ - [💡 Usage Examples](#-usage-examples)
58
+ - [📨 Message Helpers](#-message-helpers)
59
+ - [🧰 Channels, History & Transcripts](#-channels-history--transcripts)
60
+ - [🔐 Security Pack](#-security-pack)
61
+ - [🆕 WA 2026 catch-up](#-wa-2026-catch-up)
62
+ - [🆕 Everyday Utilities](#-everyday-utilities)
63
+ - [Buttons & Native Flow](#buttons--native-flow)
64
+ - [Poll](#poll)
65
+ - [Carousel](#carousel)
66
+ - [AIRich — rich response cards](#airich--rich-response-cards)
67
+ - [📁 Builders Folder Map](#-builders-folder-map-libbuilders)
68
+ - [📌 Pin / Keep in Chat](#-pin--keep-in-chat)
69
+ - [📞 Scheduled Call](#-scheduled-call)
70
+ - [📱 Mini App](#-mini-app)
71
+ - [📞 Voice & Video Calls](#-voice--video-calls)
72
+ - [🔎 User Sync Queries](#-user-sync-queries)
73
+ - [👤 Username Management](#-username-management)
74
+ - [🤖 Bot Framework](#-bot-framework)
75
+ - [🧩 Utility Modules](#-utility-modules)
76
+ - [🛎️ System Notification Filter](#system-notification-filter)
77
+ - [🛠 Recommended Environment](#-recommended-environment)
78
+ - [📘 TypeScript Support](#-typescript-support)
79
+ - [❓ FAQ & Troubleshooting](#-faq--troubleshooting)
80
+ - [🤝 Contributing](#-contributing)
81
+ - [🙏 Credits](#-credits)
82
+ - [👑 Maintainer](#-maintainer)
83
+ - [⚠️ Disclaimer](#-disclaimer)
84
+ - [📝 Patch Notes](#-v210-patch-notes)
85
+
86
+ </details>
87
+
88
+ </div>
89
+
90
+ ---
91
+
92
+ ## 🍃 Why this fork?
93
+
94
+ This fork focuses on:
95
+
96
+ | | |
97
+ |---|---|
98
+ | 🚀 | Better developer experience |
99
+ | 🎯 | Extended native flow support |
100
+ | 📢 | Advanced status & broadcast features |
101
+ | 🧩 | More interactive message types |
102
+ | ⚡ | Cleaner implementation for bot developers |
103
+ | 🔧 | Extra utilities not available in standard Baileys forks |
104
+ | 🗄️ | Multiple auth & store backends out of the box (file, SQLite, MongoDB, MySQL, PostgreSQL, Redis) |
105
+ | 📞 | Experimental voice-call (VoIP) support |
106
+
107
+ ---
108
+
109
+ ## 🆚 Comparison
110
+
111
+ How `@japofc/baileys` stacks up against other Baileys libraries:
112
+
113
+ | Capability | `@japofc/baileys` | Other forks (typical) |
114
+ |---|:---:|:---:|
115
+ | Native Flow buttons (V1/V2/V3) | ✅ | ⚠️ partial |
116
+ | Carousel messages | ✅ | ❌ |
117
+ | Rich response cards (AIRich) | ✅ | ❌ |
118
+ | Commerce flow (catalog/order/payment) | ✅ | ⚠️ partial |
119
+ | Voice calling (VoIP) | ✅ experimental | ❌ |
120
+ | Multi-backend store (SQL/Mongo/Redis) | ✅ | ⚠️ partial |
121
+ | Full `.d.ts` TypeScript definitions | ✅ | ⚠️ partial |
122
+ | User sync queries (WAUSync) | ✅ | ✅ |
123
+ | Username management (check/set/pin/recommend) | ✅ | ❌ |
124
+ | Bot framework (middleware, session, stats) | ✅ | ❌ |
125
+ | Built-in QR render (terminal/SVG/PNG, zero deps) | ✅ | ❌ needs `qrcode-terminal` |
126
+ | Auto WA Web version resolution | ✅ | ❌ hardcoded |
127
+
128
+ > Tabel ini menggambarkan fitur di level package, bukan benchmark performa. PR untuk memperbarui/mengoreksi tabel ini dipersilakan lewat [Contributing](#-contributing).
129
+
130
+ ---
131
+
132
+ ## 🧰 Built With
133
+
134
+ <p>
135
+ <img src="https://img.shields.io/badge/node.js-%2343853D.svg?style=for-the-badge&logo=node.js&logoColor=white" alt="Node.js"/>
136
+ <img src="https://img.shields.io/badge/javascript-%23323330.svg?style=for-the-badge&logo=javascript&logoColor=%23F7DF1E" alt="JavaScript"/>
137
+ <img src="https://img.shields.io/badge/esm-%23F7DF1E.svg?style=for-the-badge&logo=javascript&logoColor=black" alt="ESM"/>
138
+ <img src="https://img.shields.io/badge/websocket-%23000000.svg?style=for-the-badge&logo=socket.io&logoColor=white" alt="WebSocket"/>
139
+ <img src="https://img.shields.io/badge/signal%20protocol-%233A76F0.svg?style=for-the-badge&logo=signal&logoColor=white" alt="Signal Protocol"/>
140
+ <img src="https://img.shields.io/badge/protobuf-%23345?style=for-the-badge&logo=google&logoColor=white" alt="Protobuf"/>
141
+ <img src="https://img.shields.io/badge/npm-%23CB3837.svg?style=for-the-badge&logo=npm&logoColor=white" alt="npm"/>
142
+ </p>
143
+
144
+ <p>
145
+ <a href="https://skillicons.dev">
146
+ <img src="https://skillicons.dev/icons?i=nodejs,js,ts,npm,docker,redis,mongodb,mysql,postgresql,sqlite" alt="Tech stack icons"/>
147
+ </a>
148
+ </p>
149
+
150
+ ---
151
+
152
+ ## 🔥 Features
153
+
154
+ <table>
155
+ <tr>
156
+ <th align="center">💬 Interactive Messages</th>
157
+ <th align="center">🛒 Commerce & Business</th>
158
+ <th align="center">🧩 Utility Features</th>
159
+ </tr>
160
+ <tr>
161
+ <td valign="top">
162
+
163
+ - Native Flow
164
+ - Buttons (V1 / V2 / V3)
165
+ - Lists
166
+ - Carousel Messages
167
+ - Poll & Quiz Messages
168
+ - Rich Response Messages (AIRich)
169
+ - CTA / Reply / URL Buttons
170
+ - Call Buttons
171
+ - OTP Buttons
172
+ - Authentication Buttons
173
+
174
+ </td>
175
+ <td valign="top">
176
+
177
+ - Catalog Message
178
+ - Order Details
179
+ - Order Status
180
+ - Review & Pay
181
+ - Payment Status
182
+ - Payment Method
183
+ - Track Order
184
+ - Reorder
185
+ - Cancel Order
186
+
187
+ </td>
188
+ <td valign="top">
189
+
190
+ - Group Status Support
191
+ - Mention All
192
+ - Lottie Sticker Support
193
+ - Newsletter Support
194
+ - ExternalAdReply Helper
195
+ - View Once Support
196
+ - Rich Formatting
197
+ - Code Highlighting
198
+
199
+ </td>
200
+ </tr>
201
+ </table>
202
+
203
+ <table>
204
+ <tr>
205
+ <th align="center">🔐 Auth & Storage</th>
206
+ <th align="center">📞 Realtime</th>
207
+ <th align="center">🛠 Developer Tooling</th>
208
+ </tr>
209
+ <tr>
210
+ <td valign="top">
211
+
212
+ - Multi-file auth state
213
+ - Single-file auth state
214
+ - SQLite auth state
215
+ - Cache-manager auth state
216
+ - In-memory store
217
+ - SQLite / MongoDB / MySQL /
218
+ PostgreSQL / Redis store adapters
219
+
220
+ </td>
221
+ <td valign="top">
222
+
223
+ - Voice calling (VoIP, WASM engine)
224
+ - User sync queries (WAUSync)
225
+ - Presence / status / device lookup
226
+ - Event buffer for high-volume bots
227
+
228
+ </td>
229
+ <td valign="top">
230
+
231
+ - Full TypeScript definitions (`.d.ts`)
232
+ - Anti-delete detection
233
+ - Message search helpers
234
+ - Auto-reply engine
235
+ - Scheduling helpers
236
+ - Message retry manager
237
+
238
+ </td>
239
+ </tr>
240
+ </table>
241
+
242
+ ---
243
+
244
+ ## ✨ Exclusive J.AP Enhancements
245
+
246
+ ### Audio Group Status Fix
247
+ Audio status uses a more compatible implementation to avoid unsupported-version errors on older WhatsApp clients.
248
+
249
+ ### AIRich — the rich-response message builder
250
+ A chainable builder (`AIRich`, also exported as `AIJap` / `LeafRich` / `JapAI` / `JapRich`) with 40+ `add*()`/`set*()` methods covering headings, formatted text (hyperlinks/citations/LaTeX), code blocks, tables, image/video/product/post cards, task & progress cards, tip banners, and quick-reply suggestions — the kind of rich card layout you'd normally only see from an official AI/assistant-style bot. See [Usage Examples](#airich--rich-response-cards) below.
251
+
252
+ ### Native Flow Expansion
253
+
254
+ <table>
255
+ <tr>
256
+ <td valign="top" width="33%">
257
+
258
+ **Buttons & Actions**
259
+ - cta_reminder
260
+ - cta_cancel_reminder
261
+ - otp_button
262
+ - authentication_button
263
+ - call_button
264
+ - url_button
265
+ - reply_button
266
+ - voice_call
267
+ - video_call_button
268
+
269
+ </td>
270
+ <td valign="top" width="33%">
271
+
272
+ **Commerce Flow**
273
+ - catalog_message
274
+ - mpm
275
+ - card_message
276
+ - order_details
277
+ - order_status
278
+ - review_and_pay
279
+ - payment_status
280
+ - payment_method
281
+
282
+ </td>
283
+ <td valign="top" width="33%">
284
+
285
+ **Navigation & Misc**
286
+ - address_message
287
+ - send_location
288
+ - track_order
289
+ - reorder
290
+ - cancel_order
291
+ - clear_chat
292
+ - navigateToScreen
293
+ - flow_action
294
+
295
+ </td>
296
+ </tr>
297
+ </table>
298
+
299
+ ### System Notification Filter
300
+
301
+ Messages include:
302
+
303
+ ```js
304
+ message.isSystemNotification
305
+ ```
306
+
307
+ Useful for filtering:
308
+
309
+ - E2E notices
310
+ - Meta service notices
311
+ - Other system-generated messages
312
+
313
+ ---
314
+
315
+ ## 📦 Installation
316
+
317
+ ```bash
318
+ npm install @japofc/baileys
319
+ ```
320
+
321
+ Directly from GitHub:
322
+
323
+ ```bash
324
+ npm install github:JAPofc/baileys
325
+ ```
326
+
327
+ > Requires **Node.js 20+** — install will refuse to run below that (checked by `engine-requirements.js` on `preinstall`).
328
+
329
+ ### Optional peer dependencies
330
+
331
+ Everything below is **optional** — the socket works without any of them. Install only what the features you use need; missing ones fail with a clear install hint instead of a silent crash.
332
+
333
+ | Package | Unlocks |
334
+ |---|---|
335
+ | `sharp` | Fast image resizing/processing (used by the message builders' `Toolkit.resize`) |
336
+ | `@napi-rs/image` | Lighter native alternative to `sharp` for image ops |
337
+ | `jimp` | Pure-JS image fallback when neither of the above is installed |
338
+ | `fluent-ffmpeg` | Audio/video conversion for media messages |
339
+ | `audio-decode` | Audio waveform/duration extraction (voice notes, VoIP capture) |
340
+ | `link-preview-js` | Rich link previews for URLs in outgoing text messages |
341
+ | `better-sqlite3` | SQLite auth state, SQLite store adapter, **and** the [Bot Framework](#-bot-framework)'s `SQLiteStore`/`StatsManager` |
342
+ | `node-webpmux` | Packname/author EXIF metadata on stickers made via `MediaManager.convertToSticker()` — not needed for plain sticker conversion |
343
+ | `mongodb` | MongoDB store adapter |
344
+ | `mysql2` | MySQL store adapter |
345
+ | `pg` | PostgreSQL store adapter |
346
+ | `ioredis` | Redis store adapter |
347
+ | `@roamhq/wrtc` | Native WebRTC bindings for [voice calling](#-voice--video-calls) |
348
+
349
+ ---
350
+
351
+ ## 🚀 Quick Start
352
+
353
+ ```js
354
+ import { makeWASocket, useMultiFileAuthState } from '@japofc/baileys'
355
+
356
+ const { state, saveCreds } = await useMultiFileAuthState('auth_info')
357
+
358
+ const sock = makeWASocket({
359
+ auth: state
360
+ })
361
+
362
+ // persist credentials whenever Baileys updates them
363
+ sock.ev.on('creds.update', saveCreds)
364
+
365
+ sock.ev.on('connection.update', (update) => {
366
+ const { connection, qr } = update
367
+
368
+ // Easiest: pass `printQRInTerminal: true` to makeWASocket and the QR is
369
+ // drawn automatically with the built-in zero-dependency renderer.
370
+ // Manual/custom rendering from the event also works:
371
+ // import { renderQRToTerminal, qrToSVG, qrToPNG } from '@japofc/baileys'
372
+ // if (qr) console.log(renderQRToTerminal(qr)) // terminal (▀▄█)
373
+ // if (qr) fs.writeFileSync('qr.svg', qrToSVG(qr)) // for a web UI
374
+ // if (qr) fs.writeFileSync('qr.png', qrToPNG(qr)) // raster (send anywhere)
375
+ if (qr) console.log('Got a pairing QR')
376
+
377
+ if (connection === 'open') console.log('🍃 Connected!')
378
+ })
379
+
380
+ sock.ev.on('messages.upsert', ({ messages }) => {
381
+ const msg = messages[0]
382
+ if (!msg.message || msg.key.fromMe) return
383
+ console.log('New message from', msg.key.remoteJid)
384
+ })
385
+ ```
386
+
387
+ ---
388
+
389
+ ## 🔐 Authentication
390
+
391
+ Four auth-state backends ship out of the box. All return the same `{ state, saveCreds }` shape expected by `makeWASocket({ auth })`, so they're drop-in interchangeable.
392
+
393
+ | Function | Storage | Best for |
394
+ |---|---|---|
395
+ | `useMultiFileAuthState(folder)` | One JSON file per key, on disk | Default choice — simple, debuggable, works everywhere |
396
+ | `useSingleFileAuthState(fileName)` | One JSON file, on disk | Small bots where a single file is easier to manage/back up |
397
+ | `useSqliteAuthState(opts)` | SQLite (`better-sqlite3`) | Bots that already use SQLite, or want auth in one embedded DB file |
398
+ | `useCacheManagerAuthState(store, sessionKey)` | Any [`cacheable`](https://www.npmjs.com/package/@cacheable/node-cache)-compatible store | Multi-session hosting panels, Redis-backed setups |
399
+
400
+ ```js
401
+ import { makeWASocket, useMultiFileAuthState } from '@japofc/baileys'
402
+
403
+ const { state, saveCreds } = await useMultiFileAuthState('auth_info')
404
+ const sock = makeWASocket({ auth: state })
405
+ sock.ev.on('creds.update', saveCreds)
406
+ ```
407
+
408
+ ```js
409
+ // SQLite variant
410
+ import { makeWASocket, useSqliteAuthState } from '@japofc/baileys'
411
+
412
+ const { state, saveCreds } = await useSqliteAuthState({ database: './auth.db' })
413
+ const sock = makeWASocket({ auth: state })
414
+ sock.ev.on('creds.update', saveCreds)
415
+ ```
416
+
417
+ `useMultiFileAuthState` also exports `pruneStaleAuthFiles(folder, options)` to clean up old sender-key files on a schedule — useful for long-running bots that accumulate thousands of stale key files.
418
+
419
+ ---
420
+
421
+ ## 🗄️ Store Backends
422
+
423
+ `makeInMemoryStore()` from `lib/Store` gives you the classic in-memory chat/contact/message cache. For anything that needs to survive a restart, `makePersistentStore()` (from `PersistentStore.js`) wraps one of five backends behind the same interface:
424
+
425
+ | Backend | Function |
426
+ |---|---|
427
+ | SQLite | `createSqliteStoreAdapter(opts)` |
428
+ | MongoDB | `createMongoStoreAdapter(opts)` |
429
+ | MySQL | `createMysqlStoreAdapter(opts)` |
430
+ | PostgreSQL | `createPostgresStoreAdapter(opts)` |
431
+ | Redis | `createRedisStoreAdapter(opts)` |
432
+
433
+ ```js
434
+ import { makeWASocket, makeInMemoryStore } from '@japofc/baileys'
435
+
436
+ const store = makeInMemoryStore({})
437
+ store.readFromFile('./baileys_store.json')
438
+ setInterval(() => store.writeToFile('./baileys_store.json'), 10_000)
439
+
440
+ const sock = makeWASocket({ /* ...auth etc */ })
441
+ store.bind(sock.ev)
442
+ ```
443
+
444
+ ---
445
+
446
+ ## 💡 Usage Examples
447
+
448
+ ### Buttons & Native Flow
449
+
450
+ ```js
451
+ import { Button } from '@japofc/baileys'
452
+
453
+ await new Button(sock)
454
+ .setTitle('Promo Spesial')
455
+ .setBody('Diskon 20% cuma hari ini')
456
+ .setFooter('@japofc/baileys')
457
+ .addReply('Klaim Sekarang', 'claim_promo')
458
+ .addUrl('Lihat Katalog', 'https://example.com/catalog')
459
+ .addCall('Hubungi Kami', '628123456789')
460
+ .send(jid)
461
+ ```
462
+
463
+ ### Poll
464
+
465
+ ```js
466
+ import { Poll } from '@japofc/baileys'
467
+
468
+ await new Poll(sock)
469
+ .setName('Mau makan apa hari ini?')
470
+ .addOptions(['Nasi Goreng', 'Mie Ayam', 'Bakso'])
471
+ .setSelectable(1)
472
+ .send(jid)
473
+ ```
474
+
475
+ ### Carousel
476
+
477
+ > Each card must be built with `Button(...).toCard()` first — a carousel card is really just a button card with an image/video header.
478
+
479
+ ```js
480
+ import { Button, Carousel } from '@japofc/baileys'
481
+
482
+ const cardA = await new Button(sock)
483
+ .setImage('https://example.com/a.jpg')
484
+ .setTitle('Produk A')
485
+ .addUrl('Lihat', 'https://example.com/a')
486
+ .toCard()
487
+
488
+ const cardB = await new Button(sock)
489
+ .setImage('https://example.com/b.jpg')
490
+ .setTitle('Produk B')
491
+ .addUrl('Lihat', 'https://example.com/b')
492
+ .toCard()
493
+
494
+ await new Carousel(sock)
495
+ .setBody('Pilih salah satu produk di bawah ini')
496
+ .addCard([cardA, cardB])
497
+ .send(jid)
498
+ ```
499
+
500
+ ### AIRich — rich response cards
501
+
502
+ ```js
503
+ import { AIRich } from '@japofc/baileys'
504
+
505
+ await new AIRich(sock)
506
+ .addHeading('Ringkasan Order')
507
+ .addText('Pesananmu sedang diproses.')
508
+ .addTable([
509
+ ['Item', 'Qty'],
510
+ ['Kopi Susu', '2']
511
+ ])
512
+ .addTip('Pesanan biasanya siap dalam 15 menit')
513
+ .addSuggest('Lacak Order')
514
+ .send(jid)
515
+ ```
516
+
517
+ `AIRich` supports `{ id, insertAt }` on every `add*()`/`set*()` call, so you can insert a block relative to one you added earlier instead of always appending to the end — handy for streaming/edit-in-place style responses combined with `sendEdit(jid, id)`.
518
+
519
+ Other builders worth knowing about: **`ButtonV2`** (simpler quick-reply-only buttons), **`ButtonV3`** (`loadFrom(msg)` to edit an existing template message in place), and **`Toolkit`** (static helpers: `Toolkit.resize()`, `Toolkit.fetchBuffer()`, `Toolkit.waitAllPromises()`, `Toolkit.extractIE()` for parsing `[label](url)` links/citations/LaTeX out of plain text).
520
+
521
+ ### 📁 Builders Folder Map (`lib/Builders/`)
522
+
523
+ Every message builder lives in its own file under `lib/Builders/`, so you can trace exactly where a class comes from instead of digging through one giant `MessageBuilder.js`. `index.js` is just the barrel file that re-exports everything below (plus their aliases) for the top-level `import { ... } from '@japofc/baileys'` syntax.
524
+
525
+ | File | Exports | What it's for |
526
+ |---|---|---|
527
+ | `shared.js` | `Toolkit`, `BaseBuilder`, `RowBuilder` | The shared foundation every other builder is built on. `BaseBuilder` holds the common chainable `send()`/context-info plumbing, `RowBuilder` is the shared row/section helper, and `Toolkit` is the static-helper grab bag (`resize`, `fetchBuffer`, `waitAllPromises`, `extractIE`, media-duration/preview helpers). Nothing here is meant to be instantiated directly in bot code — it exists so `Button`, `Poll`, `Carousel`, etc. don't each reimplement the same plumbing. |
528
+ | `Button.js` | `Button`, `CardBuilder` | The main interactive/native-flow button builder — headers (image/video/document), CTA helpers (`addUrl`, `addCall`, `addReply`, and the wider native-flow set), and `.toCard()` to turn a button message into a `Carousel` card. |
529
+ | `ButtonV2.js` | `ButtonV2` | A lighter-weight variant limited to simple quick-reply buttons — reach for this when you don't need the full native-flow surface of `Button`. |
530
+ | `ButtonV3.js` | `ButtonV3` | Built around `loadFrom(msg)` — loads an existing `templateMessage` (e.g. one you fetched or that was quoted) so you can edit it in place instead of building one from scratch. |
531
+ | `Carousel.js` | `Carousel` | Chains `Button(...).toCard()` results into a swipeable card carousel. Capped at `Carousel.MAX_CARDS` (10) since WhatsApp silently truncates anything beyond that. |
532
+ | `Poll.js` | `Poll` | Poll/vote message builder — question, options, single/multi-select, hidden-voter mode, correct-answer marking, expiry. |
533
+ | `AIRich.js` | `AIRich` (+ aliases `ORich`, `AIJap`, `LeafRich`, `JapAI`, `JapRich`, `RichJap`) | The rich AI-assistant-style response builder described above — headings, formatted text, tables, media/product/post cards, task/progress cards, tip banners, quick-reply suggestions. |
534
+ | `A2UI.js` | `A2UI`, `sendA2UIWidget` | Lower-level A2UI/Bloks widget builder. Builds the flat `components` tree (Column/Row → `children`, Card/Button → `child`, Modal → `trigger`/`content`) that Bloks widgets expect and sends it through the same `getBizBinaryNode()` path as `Button`/`ButtonV2`, so the wire-level node always matches the button names actually sent. |
535
+ | `JapBaileys.js` | `JapBaileys` | A unified builder **hub** — one object that wraps all the builders above behind short method names (`.button()`, `.buttonV2()`, `.buttonV3()`, `.carousel()`, `.poll()`, `.airich()`, `.a2ui()`), plus PascalCase aliases (`.Button()`, `.Carousel()`, `.Poll()`, `.AIRich()`, `.A2UI()`) for developers who prefer that naming style. Nothing new is implemented here — it's purely a single entry point over the individual classes. |
536
+ | `index.js` | everything above, plus `MESSAGE_BUILDER_VERSION` | The barrel file — re-exports every builder and its aliases so `import { Button, Poll, AIRich, JapBaileys } from '@japofc/baileys'` works without reaching into individual files. `MESSAGE_BUILDER_VERSION` tracks the builder API surface's own version, independent of the package version. |
537
+
538
+ **Unified hub example** — useful if you'd rather carry one object around than import each builder individually:
539
+
540
+ ```js
541
+ import { JapBaileys } from '@japofc/baileys'
542
+
543
+ const vx = new JapBaileys(sock)
544
+
545
+ await vx.button()
546
+ .setTitle('Promo Spesial')
547
+ .addReply('Klaim Sekarang', 'claim_promo')
548
+ .send(jid)
549
+
550
+ await vx.poll()
551
+ .setName('Mau makan apa hari ini?')
552
+ .addOptions(['Nasi Goreng', 'Mie Ayam'])
553
+ .send(jid)
554
+ ```
555
+
556
+ ---
557
+
558
+ ### 📌 Pin / Keep in Chat
559
+
560
+ ```js
561
+ // Pin a message for 7 days (default 24h), unpin, keep / unkeep in disappearing chats
562
+ await sock.sendPin(jid, msg.key, { durationSec: 7 * 86400 })
563
+ await sock.sendUnpin(jid, msg.key)
564
+ await sock.sendKeep(jid, msg.key)
565
+ await sock.sendUnkeep(jid, msg.key)
566
+ ```
567
+
568
+ ### 📅 Event
569
+
570
+ ```js
571
+ await sock.sendEvent(jid, {
572
+ name: 'Rapat Mingguan',
573
+ description: 'Bahas progres bot',
574
+ startDate: new Date('2026-09-15T10:00:00+07:00'),
575
+ endDate: new Date('2026-09-15T11:00:00+07:00'),
576
+ location: { name: 'Kantor', address: 'Jakarta' },
577
+ extraGuestsAllowed: true
578
+ })
579
+ ```
580
+
581
+ ### 📞 Scheduled Call
582
+
583
+ Native scheduled-call message (the "Schedule call" card with a join reminder):
584
+
585
+ ```js
586
+ // 'voice' (default) or 'video'
587
+ await sock.sendScheduledCall(jid, {
588
+ title: 'Daily standup',
589
+ scheduledAt: new Date('2026-09-15T09:00:00+07:00'),
590
+ callType: 'video'
591
+ })
592
+
593
+ // Cancel it later (needs the creation message's key)
594
+ await sock.cancelScheduledCall(jid, creationMsg.key)
595
+ ```
596
+
597
+ ### 📱 Mini App
598
+
599
+ Two modes — pass `url`, `flow`, or both (two buttons):
600
+
601
+ ```js
602
+ import { sendMiniApp } from '@japofc/baileys'
603
+
604
+ await sendMiniApp(sock, jid, {
605
+ title: 'My Mini App',
606
+ body: 'Tap the button to open the app 👇',
607
+ // 1) webview mode: rich card + CTA opening your web app
608
+ // (in-app webview when supported, else the browser)
609
+ url: 'https://myapp.example.com',
610
+ params: { ref: 'wa-bot' }, // → appended as ?ref=wa-bot
611
+ buttonText: '🚀 Open App',
612
+ // 2) Flows mode: TRUE native in-chat mini app (forms/screens inside
613
+ // WhatsApp, no browser). Needs a published Flow ID from Flows Manager.
614
+ flow: { id: '123456789', cta: '📝 Isi Form', screen: 'WELCOME' },
615
+ thumbnail: 'https://myapp.example.com/icon.png' // url or Buffer
616
+ })
617
+ // or as a socket method: await sock.sendMiniApp(jid, { ... })
618
+ ```
619
+
620
+ ---
621
+
622
+ ## 📨 Message Helpers
623
+
624
+ High-level one-liners for modern message types — validated, with friendly aliases:
625
+
626
+ ```js
627
+ await sock.sendLocation(jid, { lat: -6.2, lng: 106.8, name: 'Jakarta' });
628
+ await sock.sendContact(jid, { name: 'Budi', vcard: 'BEGIN:VCARD\n...' });
629
+ await sock.sendGroupInvite(jid, { code: 'AbC123', jid: groupJid, subject: 'Komunitas' });
630
+ await sock.sendPaymentRequest(jid, { currency: 'IDR', amount: 50000, note: 'kopi ☕' });
631
+ await sock.sendInvoice(jid, { note: 'INV-001' });
632
+ await sock.sendPollOption(jid, pollKey, ['Opsi baru']);
633
+ await sock.sendEventInvite(jid, { eventTitle: 'Party', startTime: new Date(...) });
634
+ await sock.sendNewsletterInvite(jid, { newsletterJid, newsletterName: 'News' });
635
+
636
+ // Poll upgrades (already wired end-to-end):
637
+ await sock.sendPoll(jid, {
638
+ name: 'Jam berapa?', values: ['Pagi', 'Sore'],
639
+ endDate: new Date('2026-09-16T00:00:00Z'), // auto-close
640
+ hideVoter: true, // anonymous poll
641
+ canAddOption: true, // voters may add options
642
+ });
643
+ ```
644
+
645
+ Music messages are experimental (real provider catalog IDs required):
646
+
647
+ ```js
648
+ await sock.sendMusic(jid, { songUri, artworkUri, embeddedMusic: { songId, title, author } });
649
+ ```
650
+
651
+ **Escape hatch:** every content key also works inline via `sendMessage`, and `{ raw: true, <AnyMessageField>: {...} }`
652
+ passes any proto field through untouched — full `WAProto` coverage with zero wrapper lag:
653
+
654
+ ```js
655
+ await sock.sendMessage(jid, { raw: true, musicMessage: { songUri } });
656
+ ```
657
+
658
+ TypeScript consumers get a typed `AnyMessageContent` (`import type { AnyMessageContent } from '@japofc/baileys'`).
659
+
660
+ ## 🧰 Channels, History & Transcripts
661
+
662
+ **Channel management** (live queries):
663
+
664
+ ```js
665
+ await sock.newsletterDelete(channelJid)
666
+ await sock.newsletterAdminCount(channelJid)
667
+ await sock.newsletterJoinInvite('invite-code')
668
+ await sock.newsletterChangeOwner(channelJid, newOwnerJid) // experimental
669
+ await sock.communityGetInviteCode(communityJid)
670
+ // ...plus existing follow/unfollow/mute/react/fetch + full community CRUD
671
+ ```
672
+
673
+ **Group history sharing** for new members (forwards recent messages to their DM):
674
+
675
+ ```js
676
+ import { getGroupHistoryFromStore } from '@japofc/baileys'
677
+ const messages = getGroupHistoryFromStore(store, groupJid, 10)
678
+ await sock.shareGroupHistory({ groupJid, members: newMemberJid, messages, greeting: true })
679
+ ```
680
+
681
+ **Voice-note transcription** (pluggable provider — cloud Whisper or your own):
682
+
683
+ ```js
684
+ import { openAIWhisperProvider } from '@japofc/baileys'
685
+ const provider = openAIWhisperProvider({ apiKey: process.env.OPENAI_API_KEY })
686
+ const { text } = await sock.transcribeMessage(voiceNoteMsg, { provider })
687
+ ```
688
+
689
+ **Mini-app deep links** (HMAC-signed params your web app can verify):
690
+
691
+ ```js
692
+ import { createMiniAppLink, parseMiniAppParams, buildFlowDataExchange } from '@japofc/baileys'
693
+ const link = createMiniAppLink('https://app.example.com/', { uid: '123' }, { secret: 's3cr3t' })
694
+ parseMiniAppParams(link, { secret: 's3cr3t' }) // → { uid: '123' } (throws if tampered)
695
+ buildFlowDataExchange('navigate', { screen: 'HOME' }) // Flows data_exchange payload
696
+ ```
697
+
698
+ **A2UI widgets** now include `Slider`, `Switch`, `List`, `ProgressBar`, `Avatar`,
699
+ `Badge`, `Spacer`, and `Tabs` alongside the existing Text/Image/Video/Button/Card/Modal
700
+ set (all ref-validated at `build()`).
701
+
702
+ ## 🔐 Security Pack
703
+
704
+ Drop-in hardening for auth state, secrets, and abuse — all in
705
+ `lib/Utils/auth-secure.js`, covered by `tests/security.test.js` (incl. fuzzing).
706
+
707
+ ```js
708
+ import {
709
+ useEncryptedFileAuthState, secureLogger, withPairingGuard,
710
+ createQRGuard, backupAuthState, writeAuthIntegrity, repairAuthState, secureLogout
711
+ } from '@japofc/baileys'
712
+
713
+ // 1. AES-256-GCM encrypted auth state (reads legacy plaintext, migrates on save)
714
+ const { state, saveCreds } = await useEncryptedFileAuthState('./auth', { password: process.env.AUTH_PW })
715
+ const sock = makeWASocket({
716
+ auth: state,
717
+ logger: secureLogger(pino({ level: 'info' })), // 7. redacts qr/tokens/keys in every log line
718
+ })
719
+
720
+ // 2. pairing-code rate limit: 5/hour per number, 30s between attempts
721
+ withPairingGuard(sock, { maxPerHour: 5, minIntervalMs: 30_000 })
722
+
723
+ // 3. QR fist-guard: handle the first QR, swallow re-emits for 60s
724
+ const qrGuard = createQRGuard({ ttlMs: 60_000 })
725
+ sock.ev.on('connection.update', ({ qr }) => { qr = qrGuard.handle(qr); if (qr) show(qr) })
726
+
727
+ // 6/8. encrypted backup + integrity snapshot
728
+ await backupAuthState('./auth', './auth.jabackup', { password: process.env.BACKUP_PW })
729
+ await writeAuthIntegrity('./auth', { secret: process.env.INT_PW })
730
+
731
+ // 9. repair corrupt stores (quarantines + restores creds from backup)
732
+ await repairAuthState('./auth', { password: process.env.AUTH_PW, backupFile: './auth.jabackup', backupPassword: process.env.BACKUP_PW })
733
+
734
+ // 4. logout + overwrite/unlink every auth file + scrub in-memory creds
735
+ await secureLogout(sock, { authFolder: './auth' })
736
+ ```
737
+
738
+ Single-file variant: `useEncryptedSingleFileAuthState(file, { password })`.
739
+
740
+ ## 🆕 WA 2026 catch-up
741
+
742
+ WhatsApp 2026 features, wired into JAP-Baileys. Everything here was audited against the
743
+ latest official clients — only gaps were added; what already worked is just documented.
744
+
745
+ ### Usernames (chat without phone numbers)
746
+
747
+ ```js
748
+ await sock.checkUsername('japstore'); // availability
749
+ await sock.setUsername('japstore'); // claim it
750
+ await sock.reserveUsername('japstore'); // reserve it (2026 reservation flow)
751
+ await sock.findUserByUsername('japstore'); // USync lookup → JID
752
+ const u = await sock.fetchContactUsernames(['62812@s.whatsapp.net']);
753
+ ```
754
+
755
+ ### Editable polls (`editPoll`)
756
+
757
+ Polls are editable for ~15 minutes after creation (server-side rule):
758
+
759
+ ```js
760
+ const sent = await sock.sendPoll(jid, { name: 'Jam berapa?', values: ['Pagi', 'Sore'] });
761
+ await sock.editPoll(jid, sent.key, { name: 'Jam berapa?', values: ['Pagi', 'Siang', 'Sore'] });
762
+ ```
763
+
764
+ ### Mass mention (`sendMentionAll`)
765
+
766
+ ```js
767
+ await sock.sendMentionAll(groupJid, 'Pengumuman: rapat jam 9!');
768
+ ```
769
+
770
+ > In groups with 32+ members `@all` is admin-only and the rule is enforced
771
+ > server-side — non-admin calls are silently dropped by WhatsApp.
772
+
773
+ ### Event reminders
774
+
775
+ ```js
776
+ await sock.sendMessage(jid, {
777
+ event: {
778
+ title: 'Rapat', description: 'Q3', startDate: new Date('2026-09-15T09:00:00+07:00'),
779
+ reminder: true, reminderOffsetSec: 1800, // remind 30 min before start
780
+ }
781
+ });
782
+ ```
783
+
784
+ ### Sender phone from LID events (`resolveSenderPn`)
785
+
786
+ Fixes LID-only payloads (e.g. call offers where `caller_pn` is missing):
787
+
788
+ ```js
789
+ sock.ev.on('messages.upsert', async ({ messages }) => {
790
+ for (const m of messages) console.log(await sock.resolveSenderPn(m)); // '62812…' | null
791
+ });
792
+ ```
793
+
794
+ ### View-once voice notes
795
+
796
+ `sendVoiceNote()` content composes with `viewOnce`:
797
+
798
+ ```js
799
+ await sock.sendMessage(jid, { ...(await buildVoiceNoteContent('./a.ogg')), viewOnce: true });
800
+ ```
801
+
802
+ ### Member tags (groups)
803
+
804
+ Already exposed — no new code, documented here:
805
+
806
+ ```js
807
+ await sock.updateMemberLabel({ groupJid, lid, label: 'Admin' });
808
+ ```
809
+
810
+ ### Honestly not implemented (and why)
811
+
812
+ - **Voice message transcripts** — generated on-device by official clients only; there is
813
+ no transcript API on the wire.
814
+ - **Group message history sharing** — the wire format isn't captured by any public Baileys
815
+ fork yet (verified against the latest upstream Baileys release, whose proto is 100+
816
+ fields behind this repo).
817
+ - **Music messages** — `MusicMessage` needs Spotify/Apple catalog IDs plus an artwork
818
+ upload flow we haven't captured; the proto struct exists, sending real ones doesn't.
819
+ - **`mediaKeyDomain` — IMPLEMENTED.** Backported from rc14 onto all 5 media types
820
+ (`Audio/Document/Image/Sticker/VideoMessage`, enum `UNSET/E2EE_CHAT/STATUS/CAPI/BOT`)
821
+ with a send passthrough: `sendMessage(jid, { image: buf, mediaKeyDomain: 1 })`.
822
+ Unset by default (recommended — the server labels it). Skipped only on
823
+ `MMSThumbnailMetadata`, where upstream's field number 8 collides with the newer
824
+ `messageHistoryMetadata` in our proto.
825
+
826
+ ## 🆕 Everyday Utilities
827
+
828
+ One-liners for daily bot work (also usable standalone — see `examples/`):
829
+
830
+ ```js
831
+ // 📊 Poll (chats/groups) + Quiz (channels only)
832
+ await sock.sendPoll(jid, { name: 'Makan apa?', options: ['Nasi', 'Mie'] })
833
+ await sock.sendQuiz(channelJid, { name: 'Kuis', options: ['A', 'B'], correctAnswer: 'A' })
834
+
835
+ // 🎙️ Voice note — auto-converts mp3/wav/… to Opus PTT (needs fluent-ffmpeg)
836
+ await sock.sendVoiceNote(jid, './hello.mp3') // path | Buffer | { url }
837
+
838
+ // 📞 Tag everyone (visible @list vs hidden)
839
+ await sock.tagAll(groupJid, 'Rapat jam 10!')
840
+ await sock.hideTag(groupJid, 'Pengumuman 📢')
841
+
842
+ // 🔍 LID → phone number (best-effort, null when unknown)
843
+ await sock.getPhoneNumber('12345@lid') // → '62812…'
844
+ await sock.getLidForPhone('62812…') // reverse lookup
845
+
846
+ // 🧍 Humanized send — typing… + natural delay + per-chat queue
847
+ await sock.sendHumanized(jid, { text: 'Halo!' })
848
+
849
+ // 🤖 Meta AI chat (experimental — needs Meta AI on the account/region)
850
+ const { text } = await sock.askMetaAI('Jelaskan black hole!')
851
+ ```
852
+
853
+ **Command router** for prefix bots (`!menu`, `.sticker`) with middleware + auto-help:
854
+
855
+ ```js
856
+ import { createRouter } from '@japofc/baileys'
857
+ const router = createRouter({ prefix: '!' })
858
+ router.command('ping', async (ctx) => ctx.reply('pong! 🏓'), { desc: 'Check bot' })
859
+ router.attach(sock) // → detach()
860
+ ```
861
+
862
+ **Status / channel schedulers** (in-memory):
863
+
864
+ ```js
865
+ import { StatusScheduler, ChannelScheduler, StatusHelper } from '@japofc/baileys'
866
+ new StatusScheduler(sock).schedule(StatusHelper.text('Pagi! ☀️'), new Date('2026-09-11T06:00:00+07:00'))
867
+ new ChannelScheduler(sock).schedule(channelJid, { text: 'Update' }, Date.now() + 3600_000)
868
+ ```
869
+
870
+ `npm test` runs the offline suite (`tests/`, 68 asserts, no network needed).
871
+
872
+ ---
873
+
874
+ ## 📞 Voice & Video Calls
875
+
876
+ Experimental audio-call support via a bundled WASM call stack + WebRTC relay. Requires the optional `@roamhq/wrtc` peer dependency.
877
+
878
+ ```js
879
+ import { VoipClient } from '@japofc/baileys'
880
+
881
+ const voip = new VoipClient({ resourcesPath: './voip-resources' })
882
+ await voip.connectWithSocket(sock)
883
+
884
+ const call = await voip.call('628123456789')
885
+
886
+ call.on('ringing', () => console.log('Ringing...'))
887
+ call.on('connected', () => console.log('Call connected'))
888
+ call.on('ended', (reason) => console.log('Call ended:', reason))
889
+ ```
890
+
891
+ `ActiveCall` (returned by `.call()`) and `CallState` are also exported directly if you need finer-grained control over call state.
892
+
893
+ **Answering inbound calls** — offers are tracked, so the bot can pick up (1:1) or join (group):
894
+
895
+ ```js
896
+ import { attachVoip } from '@japofc/baileys'
897
+ const voip = await attachVoip(sock) // also stored as sock.voip
898
+
899
+ voip.on('incoming-call', async ({ callId, from, isGroupCall, busy }) => {
900
+ if (busy) return
901
+ if (isGroupCall) await voip.joinGroupCall(callId, { audioSource: './greeting.mp3' })
902
+ else await voip.answerCall(callId, { audioSource: './greeting.mp3' })
903
+ })
904
+
905
+ // ...or fully automatic:
906
+ await attachVoip(sock, { autoAnswer: true }) // pick up 1:1 calls
907
+ await attachVoip(sock, { autoJoinGroup: true }) // join group calls
908
+ await attachVoip(sock, { autoReject: true, autoRejectText: 'Bot cannot take calls 🙏' })
909
+
910
+ // still-pending offers (answer before `offerTtlMs`, default 45s):
911
+ voip.getPendingCalls() // → [{ callId, from, isGroupCall, ... }]
912
+ ```
913
+
914
+ **Group / multi-party calls:**
915
+
916
+ ```js
917
+ const gcall = await voip.startGroupCall(groupJid, ['62812…', '62813…'], { chatName: 'Rapat' })
918
+ await voip.inviteToGroupCall('62814…')
919
+ await voip.removeGroupParticipant('62813@s.whatsapp.net')
920
+ await voip.rejoinGroupCall() // recovery after a drop
921
+
922
+ voip.on('group-call-started', console.log)
923
+ voip.on('group-call-joined', console.log)
924
+ ```
925
+
926
+ Calls also support reactions, hand-raise, recording, and call links:
927
+
928
+ ```js
929
+ const call = await voip.call('628123456789', { audioSource: './greeting.mp3' })
930
+ call.react('👍')
931
+ call.setHandRaised(true)
932
+ const stopRecording = call.recordToFile('./call.wav') // remote peer → .wav
933
+ await voip.previewCallLink('call-link-token')
934
+ ```
935
+
936
+ **Reconnect & recovery** — a watchdog monitors the relay transport during every call
937
+ (`watchdogIntervalMs`/`watchdogMaxSilent`); on a dead relay it emits `call-degraded`
938
+ and automatically re-sends the crypto rekey + offer. Manual controls:
939
+
940
+ ```js
941
+ voip.on('call-degraded', ({ callId }) => console.log('relay dead, recovering', callId))
942
+ voip.on('call-recovery', (r) => console.log('recovery result', r))
943
+ await voip.recoverCall({}) // manual: { rekey: true, offer: true }
944
+ voip.getStats() // { busy, callId, call, relay }
945
+ sock.ev.on('call', (calls) => { /* standard offer/reject path still works */ })
946
+ ```
947
+
948
+ **Refreshing the WASM stack** — if calls break after a WA Web update, re-fetch the official VoIP build from your own browser (Chrome with `--remote-debugging-port=9222` + web.whatsapp.com open):
949
+
950
+ ```bash
951
+ npm run voip:fetch-wasm
952
+ ```
953
+
954
+ ---
955
+
956
+ ## 🔎 User Sync Queries
957
+
958
+ `WAUSync` (`USyncQuery` / `USyncUser` + protocols) lets you check things like WhatsApp registration, device lists, status, and username info for a JID before you message it — the same mechanism behind `sock.onWhatsApp()`.
959
+
960
+ ```js
961
+ import { USyncQuery, USyncUser, USyncContactProtocol } from '@japofc/baileys'
962
+
963
+ const query = new USyncQuery()
964
+ .withContext('interactive')
965
+ .withMode('query')
966
+ .withUser(new USyncUser().withPhone('628123456789'))
967
+
968
+ query.protocols.push(new USyncContactProtocol())
969
+
970
+ const result = await sock.executeUSyncQuery(query)
971
+ ```
972
+
973
+ Available protocols: `USyncContactProtocol`, `USyncDeviceProtocol`, `USyncStatusProtocol`, `USyncUsernameProtocol`, `USyncDisappearingModeProtocol`, `UsyncBotProfileProtocol`, `UsyncLIDProtocol`.
974
+
975
+ ---
976
+
977
+ ## 👤 Username Management
978
+
979
+ High-level wrappers around WhatsApp's username feature (the `@username` handle you can set instead of exposing your phone number), sitting on top of `USyncUsernameProtocol`. Query IDs are captured from live WA Web sessions — if a call starts throwing `unexpected response structure`, WA has rotated them and they need re-capturing.
980
+
981
+ ```js
982
+ // Check availability + get suggestions if taken
983
+ const check = await sock.checkUsername('J.AP')
984
+ // { available: true, username: 'J.AP' }
985
+ // or: { available: false, suggestions: [...], rejectionReasons: [...] }
986
+
987
+ // Claim a username
988
+ await sock.setUsername('J.AP', { source: sock.USERNAME_SOURCE.USER_INPUT })
989
+
990
+ // Lock it behind a PIN so it can't be changed without one
991
+ await sock.setUsernamePin('123456')
992
+
993
+ // Read your own username / drop it
994
+ const mine = await sock.getMyUsername()
995
+ await sock.deleteUsername()
996
+
997
+ // Resolve a username to a JID (USync-based, like onWhatsApp() but by username)
998
+ const user = await sock.findUserByUsername('someone')
999
+ // { jid: '628...@s.whatsapp.net', contact: false }
1000
+
1001
+ // Batch-resolve usernames for a list of known contacts
1002
+ const usernames = await sock.fetchContactUsernames(jid1, jid2, jid3)
1003
+
1004
+ // Get WA's own suggestions (e.g. for onboarding flows)
1005
+ const recs = await sock.getUsernameRecommendations()
1006
+ ```
1007
+
1008
+ > Requires a Community/Contact-tier account in good standing — accounts under WA's usual restrictions for new/unverified numbers may see `INVALID` or empty suggestions regardless of the username's actual availability.
1009
+
1010
+ ---
1011
+
1012
+ <div align="center">
1013
+ <img src="https://capsule-render.vercel.app/api?type=soft&color=0:2ecc71,100:1d6a23&height=70&section=header" width="100%"/>
1014
+ </div>
1015
+
1016
+ ## 🤖 Bot Framework
1017
+
1018
+ An optional, higher-level layer on top of the raw socket: middleware routing, a `!command` dispatcher, a message queue that survives disconnects, exponential-backoff auto-reconnect, per-JID session storage, group activity stats, and media (sticker/voice-note) conversion helpers — so a new bot project doesn't have to hand-roll session/context management every time.
1019
+
1020
+ Needs the `better-sqlite3` peer dependency (session + stats storage) and `fluent-ffmpeg` (sticker/voice-note conversion, already listed above) — both fail with an install hint rather than crashing if you use a Framework feature that needs them without installing them first.
1021
+
1022
+ ```js
1023
+ import { Bot } from '@japofc/baileys'
1024
+
1025
+ const bot = new Bot({
1026
+ socketConfig: { printQRInTerminal: true },
1027
+ dbPath: './bot.db', // sessions + stats, defaults to 'baileys_store.db'
1028
+ enableStats: true // group message/sticker leaderboards + ghost detection
1029
+ })
1030
+
1031
+ bot.command('!ping', async (ctx) => {
1032
+ await ctx.reply({ text: 'pong' })
1033
+ })
1034
+
1035
+ bot.command('!sticker', async (ctx) => {
1036
+ if (!ctx.quoted?.imageMessage) return ctx.reply({ text: 'Reply to an image with !sticker' })
1037
+ // ctx.replySticker() handles the WebP conversion for you
1038
+ await ctx.replySticker(imageBuffer, { packname: 'J.AP Pack', author: 'you' })
1039
+ })
1040
+
1041
+ bot.onText(async (ctx) => {
1042
+ // ctx.session() / ctx.setSession() / ctx.updateSession() / ctx.clearSession()
1043
+ // persist small per-chat state (e.g. multi-step flows) to SQLite automatically
1044
+ const state = ctx.session()
1045
+ if (state?.awaitingReply) {
1046
+ ctx.updateSession((s) => ({ ...s, awaitingReply: false }))
1047
+ }
1048
+ })
1049
+
1050
+ await bot.start()
1051
+ ```
1052
+
1053
+ `Context`, `SessionManager`, `StatsManager`, `MediaManager`, and `SQLiteStore` are also exported individually if you only need one piece rather than the full `Bot` class.
1054
+
1055
+ > These files ship as plain `.js` for now — hand-written `.d.ts` declarations for the Framework module haven't been added yet, unlike the rest of this fork's fully-typed surface.
1056
+
1057
+ ---
1058
+
1059
+ ## 🧩 Utility Modules
1060
+
1061
+ A sample of the utilities exported from `lib/Utils` beyond the message builders above:
1062
+
1063
+ | Module | What it does |
1064
+ |---|---|
1065
+ | `anti-delete` | Detect and recover messages the sender deleted for everyone |
1066
+ | `auto-reply` | Simple keyword/pattern-based auto-responder engine |
1067
+ | `message-search` | Search cached/stored messages, peeling off ephemeral/view-once wrappers first |
1068
+ | `message-retry-manager` | Handles WhatsApp's retry-receipt protocol for undecryptable messages |
1069
+ | `scheduling` | Schedule messages/actions for later delivery |
1070
+ | `business` | Business-profile & catalog helpers |
1071
+ | `chat-control` | Pin, mute, archive, and mark-read/unread helpers |
1072
+ | `chat-history-helpers` | Work with synced chat history payloads |
1073
+ | `link-preview` | Generate link preview metadata for outgoing messages |
1074
+ | `stickerpack` | Build and send sticker packs (including animated/Lottie) |
1075
+ | `templates` | Legacy WhatsApp Business template message helpers |
1076
+ | `vcard` | Build vCard (contact card) payloads |
1077
+ | `status` | Post and manage WhatsApp Status updates |
1078
+ | `event-buffer` | Buffers/coalesces high-volume socket events for heavier bots |
1079
+
1080
+ Every module above ships a matching `.d.ts`, so your editor will show full hover-docs regardless of which ones you import.
1081
+
1082
+ ---
1083
+
1084
+ ## 🛠 Recommended Environment
1085
+
1086
+ | Requirement | Version |
1087
+ |---|---|
1088
+ | Node.js | 20+ |
1089
+ | Module system | ESM |
1090
+ | WhatsApp | Latest Multi Device |
1091
+
1092
+ ---
1093
+
1094
+ ## 📘 TypeScript Support
1095
+
1096
+ Full `.d.ts`: every shipped `.js` file has a matching TypeScript declaration (guarded by `tests/types-parity.test.js`), and the whole package verifies at zero errors under `tsc --strict`. `import { ... } from '@japofc/baileys'` resolves with no `@types/` package needed (beyond the standard `@types/node` every Node TS project has): `makeWASocket` incl. the username methods and `USERNAME_*` constants, all `Types/*` definitions, `WAProto`, stores, `Utils/*`, the message builders (`Button`, `Poll`, `Carousel`, `AIRich`, `A2UI`, … with Bloks node types), the Bot Framework (`Bot`, `Context`, …), and the VoIP client (`VoipClient`, `ActiveCall`, …). Complex wire payloads are typed as loose records where WhatsApp publishes no schema.
1097
+
1098
+ ---
1099
+
1100
+ ## ❓ FAQ & Troubleshooting
1101
+
1102
+ <details>
1103
+ <summary><b>Koneksi terus putus / reconnect loop</b></summary>
1104
+ <br/>
1105
+
1106
+ Cek `connection.update` untuk field `lastDisconnect.error`. Kalau status code-nya `401` (loggedOut), sesi memang sudah invalid dan perlu scan ulang QR — jangan auto-reconnect di kondisi ini. Untuk status lain (`428`, `440`, dsb.), reconnect dengan backoff biasanya cukup.
1107
+
1108
+ </details>
1109
+
1110
+ <details>
1111
+ <summary><b>QR tidak muncul / tidak ke-scan</b></summary>
1112
+ <br/>
1113
+
1114
+ Di upstream Baileys `printQRInTerminal` sudah dihapus, tapi di paket ini opsi tersebut **berfungsi lagi** — QR digambar otomatis oleh renderer bawaan (vendored [qrcodegen](https://github.com/nayuki/QR-Code-generator), tanpa dependency tambahan). Bisa juga render manual dari event `qr` dengan `renderQRToTerminal(qr)` / `qrToSVG(qr)` / `qrToPNG(qr)` / `qrToMatrix(qr)`. Kalau QR muncul tapi gagal linking, biasanya karena versi WA Web (`version` di `makeWASocket`) sudah kedaluwarsa; fetch versi terbaru lewat `fetchBestWaVersion()` (chain: sw.js WA → fork baileys → fallback). Framework `Bot` sudah melakukannya otomatis tiap `start()`/reconnect (matikan dengan `versionCheck: false`). QR kelihatan "kebalik" di terminal tema terang? Pakai `renderQRToTerminal(qr, { inverted: true })`.
1115
+
1116
+ </details>
1117
+
1118
+ <details>
1119
+ <summary><b>Error "Bad MAC" / pesan gagal didekripsi</b></summary>
1120
+ <br/>
1121
+
1122
+ Umumnya terjadi kalau folder auth state korup atau sesi dipakai di lebih dari satu proses secara bersamaan. Pastikan hanya satu instance yang menulis ke folder auth state yang sama, dan pertimbangkan `pruneStaleAuthFiles()` untuk membersihkan sender-key lama secara berkala.
1123
+
1124
+ </details>
1125
+
1126
+ <details>
1127
+ <summary><b>Memory terus naik di bot yang jalan lama</b></summary>
1128
+ <br/>
1129
+
1130
+ Kalau pakai `makeInMemoryStore()`, cache chat/message/contact akan terus tumbuh tanpa batas. Untuk bot yang jalan lama, pertimbangkan pindah ke salah satu backend `makePersistentStore()` (SQLite/Redis/dst) dan pakai `event-buffer` untuk meredam lonjakan event di trafik tinggi.
1131
+
1132
+ </details>
1133
+
1134
+ <details>
1135
+ <summary><b>Voice call gagal connect</b></summary>
1136
+ <br/>
1137
+
1138
+ Fitur ini masih experimental dan butuh peer dependency `@roamhq/wrtc` — pastikan sudah terinstall dan platform kamu didukung native binding-nya. Cek event `call.on('ended', reason => ...)` untuk detail penyebab gagalnya.
1139
+
1140
+ </details>
1141
+
1142
+ ---
1143
+
1144
+ ## 🤝 Contributing
1145
+
1146
+ Kontribusi dipersilakan, terutama untuk perbaikan bug, dokumentasi, dan enhancement pada `MessageBuilder` / `AIRich`.
1147
+
1148
+ 1. Fork repo ini, buat branch dari `main` (`feat/nama-fitur` atau `fix/nama-bug`)
1149
+ 2. Pastikan perubahan tetap ESM-only dan menyertakan/menyesuaikan `.d.ts` terkait
1150
+ 3. Uji perubahan pada minimal satu jalur auth state + satu store backend sebelum PR
1151
+ 4. Buka Pull Request dengan deskripsi singkat: apa yang berubah dan kenapa
1152
+
1153
+ Untuk laporan bug, sertakan versi Node.js, cara reproduksi, dan potongan log `lastDisconnect.error` bila relevan.
1154
+
1155
+ ---
1156
+
1157
+ ## 🙏 Credits
1158
+
1159
+ Built on the shoulders of the open-source WhatsApp community.
1160
+
1161
+ Full details and license terms per component: see [`NOTICE.md`](./NOTICE.md).
1162
+
1163
+ ---
1164
+
1165
+ ## 👑 Maintainer
1166
+
1167
+ <table>
1168
+ <tr>
1169
+ <td width="180" align="center">
1170
+ <img src="https://github.com/JAPofc.png" width="160" alt="J.AP avatar" style="border-radius:50%"/>
1171
+ </td>
1172
+ <td>
1173
+
1174
+ **J.AP**
1175
+
1176
+ - GitHub: [github.com/JAPofc](https://github.com/JAPofc)
1177
+ - Package: [`@japofc/baileys`](https://www.npmjs.com/package/@japofc/baileys)
1178
+ - ✦ Maintains this fork solo — issues & PRs are welcome and reviewed personally.
1179
+
1180
+ </td>
1181
+ </tr>
1182
+ </table>
1183
+
1184
+ <p align="center">
1185
+ <img src="https://raw.githubusercontent.com/JAPofc/JAPofc/output/github-contribution-grid-snake.svg" width="100%" alt="Contribution snake animation"/>
1186
+ </p>
1187
+
1188
+ ---
1189
+
1190
+ ## ⚠️ Disclaimer
1191
+
1192
+ This project is an independent fork.
1193
+ Use responsibly and follow WhatsApp Terms of Service.
1194
+
1195
+ ---
1196
+
1197
+ ## 📝 v2.1.0 Patch Notes
1198
+
1199
+ > Ringkasan — detail lengkap di [CHANGELOG.md](./CHANGELOG.md).
1200
+
1201
+ - **QR bawaan, nol dependency**: vendored [qrcodegen](https://github.com/nayuki/QR-Code-generator) (Nayuki, MIT) + renderer sendiri — `renderQRToTerminal` (half-block `▀▄█`, setengah tinggi renderer klasik), `qrToSVG`, `qrToPNG` (encoder PNG hand-rolled di atas zlib Node), `qrToMatrix`, `formatPairingCode`. Round-trip diverifikasi decoder independen (jsQR) di CI.
1202
+ - **`printQRInTerminal` berfungsi lagi** — bukan warning deprecated: QR digambar otomatis di terminal tiap `connection.update`.
1203
+ - **Fix spam VoIP `VoipStatsTracker is not a constructor`**: shim Metro di `worker-bootstrap.js` menggeser `module`/`exports` satu posisi (argumen ke-5 `null`). Diperbaiki untuk kedua konvensi export bundle FB Comet (flag-66 → arg 6, flag-98 → arg 7, 124/204 modul) + fallback `?.exports` di loader. Diverifikasi worker asli boot sampai `worker_ready` tanpa error shim.
1204
+ - **Auto WA-version di Framework `Bot`**: tiap `start()`/reconnect resolve versi tersegar via `fetchBestWaVersion()` (sw.js WA → fork → fallback), mencegah 405 pairing gara-gara versi basi. Opt-out: `versionCheck: false` atau pin `socketConfig.version`.
1205
+ - **Full `.d.ts` beneran**: setiap `.js` yang di-ship punya deklarasi pasangan, dijaga test parity + harness `tsc --strict` di CI.
1206
+ - **CI + release automation**: GitHub Actions (test di Node 20/22, type-check, pack sanity) dan publish workflow ber-provenance yang terpicu tag `v*`.
1207
+
1208
+ ---
1209
+
1210
+ ## 📝 V6 Patch Notes
1211
+
1212
+ - Fixed a `package.json` typo: the version field was mistakenly left at `1.0.1` instead of `2.0.1` after the V5 release — corrected to `2.0.1` so the published package version matches the intended release.
1213
+ - Expanded README documentation, especially around `lib/Builders/`:
1214
+ - Added the new [📁 Builders Folder Map](#-builders-folder-map-libbuilders) section — a per-file breakdown of everything under `lib/Builders/` (`shared.js`, `Button.js`, `ButtonV2.js`, `ButtonV3.js`, `Carousel.js`, `Poll.js`, `AIRich.js`, `A2UI.js`, `JapBaileys.js`, `index.js`), what each file exports, and what it's for — previously `A2UI` and `JapBaileys` in particular had no usage documentation at all.
1215
+ - Added a usage example for the `JapBaileys` unified builder hub.
1216
+ - Redesigned `postinstall-banner.js`: cleaner box layout with a divider separating the title block from a small info section (Node version + docs link), a 256-color palette instead of basic ANSI colors, and a plain-text fallback when stdout isn't a TTY or `NO_COLOR` is set (CI logs, piped output) instead of forcing a box that may render misaligned.
1217
+
1218
+ ---
1219
+
1220
+ ## 📝 V5 Patch Notes
1221
+
1222
+ - Added [Username Management](#-username-management): `checkUsername`, `checkUsernameMulti`, `setUsername`, `deleteUsername`, `getMyUsername`, `setUsernamePin`, `findUserByUsername`, `fetchContactUsernames`, `getUsernameRecommendations`, layered onto the existing `USyncUsernameProtocol` support.
1223
+ - Added the [Bot Framework](#-bot-framework) (`Bot`, `Context`, `SessionManager`, `StatsManager`, `MediaManager`, `SQLiteStore`). Adapted on the way in:
1224
+ - `SQLiteStore`/`StatsManager` construction moved behind an async `.create()` factory so `better-sqlite3` stays a lazily-loaded optional peer dep instead of a hard top-level import that would crash the Framework module for anyone without it installed.
1225
+ - `MediaManager`'s sticker/voice-note conversion now reuses this fork's existing lazy `fluent-ffmpeg` loader (see `Utils/MessageBuilder.js`) instead of adding `ffmpeg-static` + a second ffmpeg dependency; `node-webpmux` (sticker EXIF metadata) is lazy-loaded the same way and only when packname/author is actually requested.
1226
+ - `Bot`'s default logger now falls back to this fork's own pino instance instead of a silent no-op stub.
1227
+ - No `.d.ts` files were written for the new Framework module yet — see the note in that section.
1228
+ - Bumped to `1.0.1`.
1229
+
1230
+ ---
1231
+
1232
+ ## 📝 V4 Patch Notes
1233
+
1234
+ - Kept the existing J.AP custom MessageBuilder classes and AIRich implementation intact.
1235
+ - Added `whatsapp-rust-bridge@0.5.5` as a runtime dependency. The library already dynamically imports this module for LT Hash/app-state and crypto helpers; declaring it prevents accidental missing-module fallbacks in normal installations.
1236
+ - Existing guarded fallbacks for platforms where the native bridge cannot load remain in place.
1237
+ - ESM-only package metadata is preserved; no CommonJS build is included.
1238
+
1239
+
1240
+ ---
1241
+
1242
+ <div align="center">
1243
+
1244
+ Made with 🍃 by **JAP**
1245
+
1246
+ Thanks for visiting, bye 👋
1247
+
1248
+ <img src="https://capsule-render.vercel.app/api?type=waving&color=0:2ecc71,100:1d6a23&height=100&section=footer" width="100%"/>
1249
+
1250
+
1251
+
1252
+ <a href="#top">⬆️ Back to top</a>
1253
+
1254
+ </div>