@queenanya/baileys 9.2.1 → 9.4.1
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.
- package/README.md +349 -1171
- package/WAProto/fix-imports.js +74 -18
- package/WAProto/index.js +201 -160
- package/engine-requirements.js +7 -7
- package/lib/Defaults/index.d.ts +19 -0
- package/lib/Defaults/index.d.ts.map +1 -1
- package/lib/Defaults/index.js +32 -6
- package/lib/Defaults/index.js.map +1 -1
- package/lib/Signal/libsignal.d.ts.map +1 -1
- package/lib/Signal/libsignal.js +61 -2
- package/lib/Signal/libsignal.js.map +1 -1
- package/lib/Signal/lid-mapping.d.ts +5 -9
- package/lib/Signal/lid-mapping.d.ts.map +1 -1
- package/lib/Signal/lid-mapping.js +170 -70
- package/lib/Signal/lid-mapping.js.map +1 -1
- package/lib/Socket/Client/websocket.d.ts +1 -1
- package/lib/Socket/Client/websocket.d.ts.map +1 -1
- package/lib/Socket/Client/websocket.js +5 -1
- package/lib/Socket/Client/websocket.js.map +1 -1
- package/lib/Socket/business.d.ts +125 -5
- package/lib/Socket/business.d.ts.map +1 -1
- package/lib/Socket/business.js +11 -8
- package/lib/Socket/business.js.map +1 -1
- package/lib/Socket/chats.d.ts +22 -3
- package/lib/Socket/chats.d.ts.map +1 -1
- package/lib/Socket/chats.js +277 -58
- package/lib/Socket/chats.js.map +1 -1
- package/lib/Socket/communities.d.ts +125 -5
- package/lib/Socket/communities.d.ts.map +1 -1
- package/lib/Socket/groups.d.ts +19 -3
- package/lib/Socket/groups.d.ts.map +1 -1
- package/lib/Socket/groups.js +7 -1
- package/lib/Socket/groups.js.map +1 -1
- package/lib/Socket/index.d.ts +125 -5
- package/lib/Socket/index.d.ts.map +1 -1
- package/lib/Socket/index.js +0 -6
- package/lib/Socket/index.js.map +1 -1
- package/lib/Socket/messages-recv.d.ts +126 -6
- package/lib/Socket/messages-recv.d.ts.map +1 -1
- package/lib/Socket/messages-recv.js +771 -177
- package/lib/Socket/messages-recv.js.map +1 -1
- package/lib/Socket/messages-send.d.ts +129 -7
- package/lib/Socket/messages-send.d.ts.map +1 -1
- package/lib/Socket/messages-send.js +430 -119
- package/lib/Socket/messages-send.js.map +1 -1
- package/lib/Socket/newsletter.d.ts +20 -5
- package/lib/Socket/newsletter.d.ts.map +1 -1
- package/lib/Socket/newsletter.js +2 -47
- package/lib/Socket/newsletter.js.map +1 -1
- package/lib/Socket/socket.d.ts +3 -1
- package/lib/Socket/socket.d.ts.map +1 -1
- package/lib/Socket/socket.js +151 -29
- package/lib/Socket/socket.js.map +1 -1
- package/lib/Types/Auth.d.ts +2 -0
- package/lib/Types/Auth.d.ts.map +1 -1
- package/lib/Types/Call.d.ts +10 -1
- package/lib/Types/Call.d.ts.map +1 -1
- package/lib/Types/Contact.d.ts +2 -0
- package/lib/Types/Contact.d.ts.map +1 -1
- package/lib/Types/Events.d.ts +60 -6
- package/lib/Types/Events.d.ts.map +1 -1
- package/lib/Types/GroupMetadata.d.ts +4 -0
- package/lib/Types/GroupMetadata.d.ts.map +1 -1
- package/lib/Types/Message.d.ts +530 -16
- package/lib/Types/Message.d.ts.map +1 -1
- package/lib/Types/Message.js.map +1 -1
- package/lib/Types/Newsletter.d.ts +32 -45
- package/lib/Types/Newsletter.d.ts.map +1 -1
- package/lib/Types/Newsletter.js +25 -23
- package/lib/Types/Newsletter.js.map +1 -1
- package/lib/Types/State.d.ts +54 -0
- package/lib/Types/State.d.ts.map +1 -1
- package/lib/Types/State.js +42 -0
- package/lib/Types/State.js.map +1 -1
- package/lib/Types/index.d.ts +9 -0
- package/lib/Types/index.d.ts.map +1 -1
- package/lib/Types/index.js.map +1 -1
- package/lib/Utils/auth-utils.d.ts.map +1 -1
- package/lib/Utils/auth-utils.js +53 -20
- package/lib/Utils/auth-utils.js.map +1 -1
- package/lib/Utils/browser-utils.d.ts +13 -0
- package/lib/Utils/browser-utils.d.ts.map +1 -1
- package/lib/Utils/browser-utils.js +90 -10
- package/lib/Utils/browser-utils.js.map +1 -1
- package/lib/Utils/chat-utils.d.ts +30 -0
- package/lib/Utils/chat-utils.d.ts.map +1 -1
- package/lib/Utils/chat-utils.js +134 -59
- package/lib/Utils/chat-utils.js.map +1 -1
- package/lib/Utils/companion-reg-client-utils.d.ts +17 -0
- package/lib/Utils/companion-reg-client-utils.d.ts.map +1 -0
- package/lib/Utils/companion-reg-client-utils.js +34 -0
- package/lib/Utils/companion-reg-client-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +4 -8
- package/lib/Utils/crypto.d.ts.map +1 -1
- package/lib/Utils/crypto.js +2 -26
- package/lib/Utils/crypto.js.map +1 -1
- package/lib/Utils/decode-wa-message.d.ts +12 -0
- package/lib/Utils/decode-wa-message.d.ts.map +1 -1
- package/lib/Utils/decode-wa-message.js +16 -0
- package/lib/Utils/decode-wa-message.js.map +1 -1
- package/lib/Utils/event-buffer.d.ts.map +1 -1
- package/lib/Utils/event-buffer.js +43 -8
- package/lib/Utils/event-buffer.js.map +1 -1
- package/lib/Utils/generics.d.ts +3 -1
- package/lib/Utils/generics.d.ts.map +1 -1
- package/lib/Utils/generics.js +17 -4
- package/lib/Utils/generics.js.map +1 -1
- package/lib/Utils/history.d.ts +8 -3
- package/lib/Utils/history.d.ts.map +1 -1
- package/lib/Utils/history.js +60 -16
- package/lib/Utils/history.js.map +1 -1
- package/lib/Utils/identity-change-handler.d.ts +44 -0
- package/lib/Utils/identity-change-handler.d.ts.map +1 -0
- package/lib/Utils/identity-change-handler.js +50 -0
- package/lib/Utils/identity-change-handler.js.map +1 -0
- package/lib/Utils/index.d.ts +6 -0
- package/lib/Utils/index.d.ts.map +1 -1
- package/lib/Utils/index.js +6 -0
- package/lib/Utils/index.js.map +1 -1
- package/lib/Utils/interactive-message.d.ts +201 -0
- package/lib/Utils/interactive-message.d.ts.map +1 -0
- package/lib/Utils/interactive-message.js +256 -0
- package/lib/Utils/interactive-message.js.map +1 -0
- package/lib/Utils/lt-hash.d.ts +7 -12
- package/lib/Utils/lt-hash.d.ts.map +1 -1
- package/lib/Utils/lt-hash.js +2 -42
- package/lib/Utils/lt-hash.js.map +1 -1
- package/lib/Utils/make-mutex.d.ts +1 -0
- package/lib/Utils/make-mutex.d.ts.map +1 -1
- package/lib/Utils/make-mutex.js +20 -27
- package/lib/Utils/make-mutex.js.map +1 -1
- package/lib/Utils/message-composer.d.ts +5 -0
- package/lib/Utils/message-composer.d.ts.map +1 -0
- package/lib/Utils/message-composer.js +5 -0
- package/lib/Utils/message-composer.js.map +1 -0
- package/lib/Utils/message-retry-manager.d.ts +30 -2
- package/lib/Utils/message-retry-manager.d.ts.map +1 -1
- package/lib/Utils/message-retry-manager.js +58 -5
- package/lib/Utils/message-retry-manager.js.map +1 -1
- package/lib/Utils/messages-media.d.ts +35 -5
- package/lib/Utils/messages-media.d.ts.map +1 -1
- package/lib/Utils/messages-media.js +171 -51
- package/lib/Utils/messages-media.js.map +1 -1
- package/lib/Utils/messages.d.ts +2 -0
- package/lib/Utils/messages.d.ts.map +1 -1
- package/lib/Utils/messages.js +475 -35
- package/lib/Utils/messages.js.map +1 -1
- package/lib/Utils/noise-handler.d.ts +4 -4
- package/lib/Utils/noise-handler.d.ts.map +1 -1
- package/lib/Utils/noise-handler.js +139 -85
- package/lib/Utils/noise-handler.js.map +1 -1
- package/lib/Utils/offline-node-processor.d.ts +17 -0
- package/lib/Utils/offline-node-processor.d.ts.map +1 -0
- package/lib/Utils/offline-node-processor.js +40 -0
- package/lib/Utils/offline-node-processor.js.map +1 -0
- package/lib/Utils/process-message.d.ts.map +1 -1
- package/lib/Utils/process-message.js +115 -16
- package/lib/Utils/process-message.js.map +1 -1
- package/lib/Utils/reporting-utils.d.ts +11 -0
- package/lib/Utils/reporting-utils.d.ts.map +1 -0
- package/lib/Utils/reporting-utils.js +258 -0
- package/lib/Utils/reporting-utils.js.map +1 -0
- package/lib/Utils/stanza-ack.d.ts +11 -0
- package/lib/Utils/stanza-ack.d.ts.map +1 -0
- package/lib/Utils/stanza-ack.js +38 -0
- package/lib/Utils/stanza-ack.js.map +1 -0
- package/lib/Utils/sync-action-utils.d.ts +19 -0
- package/lib/Utils/sync-action-utils.d.ts.map +1 -0
- package/lib/Utils/sync-action-utils.js +49 -0
- package/lib/Utils/sync-action-utils.js.map +1 -0
- package/lib/Utils/tc-token-utils.d.ts +37 -0
- package/lib/Utils/tc-token-utils.d.ts.map +1 -0
- package/lib/Utils/tc-token-utils.js +163 -0
- package/lib/Utils/tc-token-utils.js.map +1 -0
- package/lib/Utils/use-mongo-file-auth-state.d.ts +16 -0
- package/lib/Utils/use-mongo-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-mongo-file-auth-state.js +60 -0
- package/lib/Utils/use-mongo-file-auth-state.js.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +1 -1
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -1
- package/lib/Utils/use-single-file-auth-state.d.ts.map +1 -1
- package/lib/Utils/use-single-file-auth-state.js.map +1 -1
- package/lib/Utils/validate-connection.d.ts.map +1 -1
- package/lib/Utils/validate-connection.js +11 -1
- package/lib/Utils/validate-connection.js.map +1 -1
- package/lib/WABinary/decode.d.ts.map +1 -1
- package/lib/WABinary/decode.js +24 -0
- package/lib/WABinary/decode.js.map +1 -1
- package/lib/WABinary/encode.js +5 -1
- package/lib/WABinary/encode.js.map +1 -1
- package/lib/WABinary/generic-utils.d.ts +10 -1
- package/lib/WABinary/generic-utils.d.ts.map +1 -1
- package/lib/WABinary/generic-utils.js +42 -8
- package/lib/WABinary/generic-utils.js.map +1 -1
- package/lib/WABinary/jid-utils.js.map +1 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +26 -3
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -1
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/index.d.ts +1 -0
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/index.js +1 -0
- package/lib/WAUSync/Protocols/index.js.map +1 -1
- package/lib/WAUSync/USyncQuery.d.ts +1 -0
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -1
- package/lib/WAUSync/USyncQuery.js +6 -2
- package/lib/WAUSync/USyncQuery.js.map +1 -1
- package/lib/WAUSync/USyncUser.d.ts +4 -0
- package/lib/WAUSync/USyncUser.d.ts.map +1 -1
- package/lib/WAUSync/USyncUser.js +8 -0
- package/lib/WAUSync/USyncUser.js.map +1 -1
- package/lib/addons/anti-delete.d.ts +72 -0
- package/lib/addons/anti-delete.d.ts.map +1 -0
- package/lib/addons/anti-delete.js +165 -0
- package/lib/addons/anti-delete.js.map +1 -0
- package/lib/addons/auto-reply.d.ts +67 -0
- package/lib/addons/auto-reply.d.ts.map +1 -0
- package/lib/addons/auto-reply.js +145 -0
- package/lib/addons/auto-reply.js.map +1 -0
- package/lib/addons/browser-presets.d.ts +16 -0
- package/lib/addons/browser-presets.d.ts.map +1 -0
- package/lib/addons/browser-presets.js +24 -0
- package/lib/addons/browser-presets.js.map +1 -0
- package/lib/addons/button-sender.d.ts +260 -0
- package/lib/addons/button-sender.d.ts.map +1 -0
- package/lib/addons/button-sender.js +771 -0
- package/lib/addons/button-sender.js.map +1 -0
- package/lib/addons/call-handler.d.ts +79 -0
- package/lib/addons/call-handler.d.ts.map +1 -0
- package/lib/addons/call-handler.js +342 -0
- package/lib/addons/call-handler.js.map +1 -0
- package/lib/addons/from-chats.d.ts +30 -0
- package/lib/addons/from-chats.d.ts.map +1 -0
- package/lib/addons/from-chats.js +38 -0
- package/lib/addons/from-chats.js.map +1 -0
- package/lib/addons/from-messages-recv.d.ts +59 -0
- package/lib/addons/from-messages-recv.d.ts.map +1 -0
- package/lib/addons/from-messages-recv.js +326 -0
- package/lib/addons/from-messages-recv.js.map +1 -0
- package/lib/addons/from-messages-send.d.ts +50 -0
- package/lib/addons/from-messages-send.d.ts.map +1 -0
- package/lib/addons/from-messages-send.js +148 -0
- package/lib/addons/from-messages-send.js.map +1 -0
- package/lib/addons/from-messages.d.ts +52 -0
- package/lib/addons/from-messages.d.ts.map +1 -0
- package/lib/addons/from-messages.js +304 -0
- package/lib/addons/from-messages.js.map +1 -0
- package/lib/addons/index.d.ts +67 -0
- package/lib/addons/index.d.ts.map +1 -0
- package/lib/addons/index.js +86 -0
- package/lib/addons/index.js.map +1 -0
- package/lib/addons/interactive-message.d.ts +201 -0
- package/lib/addons/interactive-message.d.ts.map +1 -0
- package/lib/addons/interactive-message.js +256 -0
- package/lib/addons/interactive-message.js.map +1 -0
- package/lib/addons/jid-plot.d.ts +49 -0
- package/lib/addons/jid-plot.d.ts.map +1 -0
- package/lib/addons/jid-plot.js +84 -0
- package/lib/addons/jid-plot.js.map +1 -0
- package/lib/addons/jid-plotting.d.ts +54 -0
- package/lib/addons/jid-plotting.d.ts.map +1 -0
- package/lib/addons/jid-plotting.js +150 -0
- package/lib/addons/jid-plotting.js.map +1 -0
- package/lib/addons/lid-support.d.ts +41 -0
- package/lib/addons/lid-support.d.ts.map +1 -0
- package/lib/addons/lid-support.js +42 -0
- package/lib/addons/lid-support.js.map +1 -0
- package/lib/addons/message-composer.d.ts +142 -0
- package/lib/addons/message-composer.d.ts.map +1 -0
- package/lib/addons/message-composer.js +377 -0
- package/lib/addons/message-composer.js.map +1 -0
- package/lib/addons/message-scheduler.d.ts +77 -0
- package/lib/addons/message-scheduler.d.ts.map +1 -0
- package/lib/addons/message-scheduler.js +108 -0
- package/lib/addons/message-scheduler.js.map +1 -0
- package/lib/addons/message-search.d.ts +51 -0
- package/lib/addons/message-search.d.ts.map +1 -0
- package/lib/addons/message-search.js +171 -0
- package/lib/addons/message-search.js.map +1 -0
- package/lib/addons/message-utils.d.ts +88 -0
- package/lib/addons/message-utils.d.ts.map +1 -0
- package/lib/addons/message-utils.js +292 -0
- package/lib/addons/message-utils.js.map +1 -0
- package/lib/addons/outgoing-calls.d.ts +64 -0
- package/lib/addons/outgoing-calls.d.ts.map +1 -0
- package/lib/addons/outgoing-calls.js +139 -0
- package/lib/addons/outgoing-calls.js.map +1 -0
- package/lib/addons/pairing-fix.d.ts +31 -0
- package/lib/addons/pairing-fix.d.ts.map +1 -0
- package/lib/addons/pairing-fix.js +74 -0
- package/lib/addons/pairing-fix.js.map +1 -0
- package/lib/addons/past-participants.d.ts +42 -0
- package/lib/addons/past-participants.d.ts.map +1 -0
- package/lib/addons/past-participants.js +41 -0
- package/lib/addons/past-participants.js.map +1 -0
- package/lib/addons/rich-response.d.ts +111 -0
- package/lib/addons/rich-response.d.ts.map +1 -0
- package/lib/addons/rich-response.js +152 -0
- package/lib/addons/rich-response.js.map +1 -0
- package/lib/addons/scheduling.d.ts +41 -0
- package/lib/addons/scheduling.d.ts.map +1 -0
- package/lib/addons/scheduling.js +110 -0
- package/lib/addons/scheduling.js.map +1 -0
- package/lib/addons/status-posting.d.ts +177 -0
- package/lib/addons/status-posting.d.ts.map +1 -0
- package/lib/addons/status-posting.js +240 -0
- package/lib/addons/status-posting.js.map +1 -0
- package/lib/addons/stickerpack.d.ts +37 -0
- package/lib/addons/stickerpack.d.ts.map +1 -0
- package/lib/addons/stickerpack.js +39 -0
- package/lib/addons/stickerpack.js.map +1 -0
- package/lib/addons/templates.d.ts +72 -0
- package/lib/addons/templates.d.ts.map +1 -0
- package/lib/addons/templates.js +145 -0
- package/lib/addons/templates.js.map +1 -0
- package/lib/addons/vcard.d.ts +59 -0
- package/lib/addons/vcard.d.ts.map +1 -0
- package/lib/addons/vcard.js +88 -0
- package/lib/addons/vcard.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,1306 +1,484 @@
|
|
|
1
|
-
<h1 align='center'
|
|
1
|
+
<h1 align='center'>
|
|
2
|
+
<img alt="anya-bail logo" src="https://raw.githubusercontent.com/WhiskeySockets/Baileys/refs/heads/master/Media/logo.png" height="75"/>
|
|
3
|
+
</h1>
|
|
2
4
|
|
|
3
|
-
<div align='center'>
|
|
5
|
+
<div align='center'>
|
|
4
6
|
|
|
7
|
+
**anya-bail** — A heavily extended fork of [WhiskeySockets/Baileys](https://github.com/WhiskeySockets/Baileys), the WhatsApp Web API library.
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
> NOTICE OF BREAKING CHANGE.
|
|
8
|
-
>
|
|
9
|
-
> As of 7.0.0, multiple breaking changes were introduced into the library.
|
|
10
|
-
>
|
|
11
|
-
> Please check out https://whiskey.so/migrate-latest for more information.
|
|
9
|
+
Maintained for [@queenanya/baileys](https://github.com/QueenAnya/ANYA-MD) | Last updated: **April 2026**
|
|
12
10
|
|
|
13
|
-
#
|
|
14
|
-
This is a temporary README.md, the new guide is in development and will this file will be replaced with .github/README.md (already a default on GitHub).
|
|
11
|
+
[](#) [](#)
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
</div>
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
If you'd like to financially support this project, you can do so by supporting the current maintainer [here](https://purpshell.dev/sponsor).
|
|
15
|
+
---
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with WhatsApp or any of its subsidiaries or its affiliates.
|
|
23
|
-
The official WhatsApp website can be found at whatsapp.com. "WhatsApp" as well as related names, marks, emblems and images are registered trademarks of their respective owners.
|
|
17
|
+
## What's Different from Upstream
|
|
24
18
|
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
| Feature | Upstream Baileys | anya-bail |
|
|
20
|
+
| ------------------------------------- | ---------------- | ----------------------------------------- |
|
|
21
|
+
| Interactive / button messages | ❌ | ✅ Full support |
|
|
22
|
+
| Template messages | ❌ | ✅ |
|
|
23
|
+
| List messages | ❌ | ✅ |
|
|
24
|
+
| Cards / Carousel messages | ❌ | ✅ |
|
|
25
|
+
| Album messages | ❌ | ✅ |
|
|
26
|
+
| Sticker pack messages | ❌ | ✅ |
|
|
27
|
+
| Share / Request phone number | ❌ | ✅ |
|
|
28
|
+
| AI icon on messages | ❌ | ✅ |
|
|
29
|
+
| Rich response / Meta AI messages | ❌ | ✅ |
|
|
30
|
+
| Outgoing call API | ❌ | ✅ |
|
|
31
|
+
| Full MEX notification dispatcher | Partial | ✅ |
|
|
32
|
+
| `messaging-history.status` event | ❌ | ✅ |
|
|
33
|
+
| `message-capping.update` event | ❌ | ✅ |
|
|
34
|
+
| Reachout timelock event | ❌ | ✅ |
|
|
35
|
+
| MongoDB auth state | ❌ | ✅ |
|
|
36
|
+
| Single-file auth state | ❌ | ✅ |
|
|
37
|
+
| iOS / Android / KaiOS browser support | Limited | ✅ Extended |
|
|
38
|
+
| Pairing race-condition fix | ❌ | ✅ |
|
|
39
|
+
| Username in contacts / groups | ❌ | ✅ |
|
|
40
|
+
| `authorUsername` in group events | ❌ | ✅ |
|
|
41
|
+
| `chunkOrder` in history sync | ❌ | ✅ |
|
|
42
|
+
| tctoken prune on reconnect | ❌ | ✅ |
|
|
43
|
+
| App state sync resilience | Partial | ✅ `forceSnapshot` + `blockedCollections` |
|
|
44
|
+
| Message ID prefix | `3EB0` | `4NY4W3B` |
|
|
45
|
+
| Addons layer | ❌ | ✅ 18 addon files |
|
|
27
46
|
|
|
28
|
-
|
|
47
|
+
---
|
|
29
48
|
|
|
30
|
-
|
|
31
|
-
- Not running Selenium or Chromium saves you like **half a gig** of ram :/
|
|
32
|
-
- Baileys supports interacting with the multi-device & web versions of WhatsApp.
|
|
33
|
-
- Thank you to [@pokearaujo](https://github.com/pokearaujo/multidevice) for writing his observations on the workings of WhatsApp Multi-Device. Also, thank you to [@Sigalor](https://github.com/sigalor/whatsapp-web-reveng) for writing his observations on the workings of WhatsApp Web and thanks to [@Rhymen](https://github.com/Rhymen/go-whatsapp/) for the __go__ implementation.
|
|
49
|
+
## Installation
|
|
34
50
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
## Example
|
|
41
|
-
|
|
42
|
-
Do check out & run [example.ts](Example/example.ts) to see an example usage of the library.
|
|
43
|
-
The script covers most common use cases.
|
|
44
|
-
To run the example script, download or clone the repo and then type the following in a terminal:
|
|
45
|
-
1. ``` cd path/to/Baileys ```
|
|
46
|
-
2. ``` yarn ```
|
|
47
|
-
3. ``` yarn example ```
|
|
48
|
-
|
|
49
|
-
## Install
|
|
50
|
-
|
|
51
|
-
Use the stable version:
|
|
52
|
-
```
|
|
53
|
-
yarn add @whiskeysockets/baileys
|
|
51
|
+
```bash
|
|
52
|
+
npm install anya-bail
|
|
53
|
+
# or
|
|
54
|
+
yarn add anya-bail
|
|
54
55
|
```
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
yarn add github:WhiskeySockets/Baileys
|
|
59
|
-
```
|
|
57
|
+
---
|
|
60
58
|
|
|
61
|
-
|
|
62
|
-
```ts
|
|
63
|
-
import makeWASocket from '@whiskeysockets/baileys'
|
|
64
|
-
```
|
|
59
|
+
## Table of Contents
|
|
65
60
|
|
|
66
|
-
#
|
|
67
|
-
|
|
68
|
-
- [Discord](https://discord.gg/WeJM5FP9GG)
|
|
69
|
-
- [Docs](https://guide.whiskeysockets.io/)
|
|
70
|
-
|
|
71
|
-
# Index
|
|
72
|
-
|
|
73
|
-
- [Connecting Account](#connecting-account)
|
|
74
|
-
- [Connect with QR-CODE](#starting-socket-with-qr-code)
|
|
75
|
-
- [Connect with Pairing Code](#starting-socket-with-pairing-code)
|
|
76
|
-
- [Receive Full History](#receive-full-history)
|
|
77
|
-
- [Important Notes About Socket Config](#important-notes-about-socket-config)
|
|
78
|
-
- [Caching Group Metadata (Recommended)](#caching-group-metadata-recommended)
|
|
79
|
-
- [Improve Retry System & Decrypt Poll Votes](#improve-retry-system--decrypt-poll-votes)
|
|
80
|
-
- [Receive Notifications in Whatsapp App](#receive-notifications-in-whatsapp-app)
|
|
81
|
-
|
|
82
|
-
- [Save Auth Info](#saving--restoring-sessions)
|
|
83
|
-
- [Handling Events](#handling-events)
|
|
84
|
-
- [Example to Start](#example-to-start)
|
|
85
|
-
- [Decrypt Poll Votes](#decrypt-poll-votes)
|
|
86
|
-
- [Summary of Events on First Connection](#summary-of-events-on-first-connection)
|
|
87
|
-
- [Implementing a Data Store](#implementing-a-data-store)
|
|
88
|
-
- [Whatsapp IDs Explain](#whatsapp-ids-explain)
|
|
89
|
-
- [Utility Functions](#utility-functions)
|
|
61
|
+
- [Connecting](#connecting)
|
|
90
62
|
- [Sending Messages](#sending-messages)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
- [
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
- [
|
|
109
|
-
- [
|
|
110
|
-
|
|
111
|
-
- [
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
- [Delete a Message for Me](#delete-a-message-for-me)
|
|
124
|
-
- [Delete a Chat](#delete-a-chat)
|
|
125
|
-
- [Star/Unstar a Message](#starunstar-a-message)
|
|
126
|
-
- [Disappearing Messages](#disappearing-messages)
|
|
127
|
-
- [User Querys](#user-querys)
|
|
128
|
-
- [Check If ID Exists in Whatsapp](#check-if-id-exists-in-whatsapp)
|
|
129
|
-
- [Query Chat History (groups too)](#query-chat-history-groups-too)
|
|
130
|
-
- [Fetch Status](#fetch-status)
|
|
131
|
-
- [Fetch Profile Picture (groups too)](#fetch-profile-picture-groups-too)
|
|
132
|
-
- [Fetch Bussines Profile (such as description or category)](#fetch-bussines-profile-such-as-description-or-category)
|
|
133
|
-
- [Fetch Someone's Presence (if they're typing or online)](#fetch-someones-presence-if-theyre-typing-or-online)
|
|
134
|
-
- [Change Profile](#change-profile)
|
|
135
|
-
- [Change Profile Status](#change-profile-status)
|
|
136
|
-
- [Change Profile Name](#change-profile-name)
|
|
137
|
-
- [Change Display Picture (groups too)](#change-display-picture-groups-too)
|
|
138
|
-
- [Remove display picture (groups too)](#remove-display-picture-groups-too)
|
|
139
|
-
- [Groups](#groups)
|
|
140
|
-
- [Create a Group](#create-a-group)
|
|
141
|
-
- [Add/Remove or Demote/Promote](#addremove-or-demotepromote)
|
|
142
|
-
- [Change Subject (name)](#change-subject-name)
|
|
143
|
-
- [Change Description](#change-description)
|
|
144
|
-
- [Change Settings](#change-settings)
|
|
145
|
-
- [Leave a Group](#leave-a-group)
|
|
146
|
-
- [Get Invite Code](#get-invite-code)
|
|
147
|
-
- [Revoke Invite Code](#revoke-invite-code)
|
|
148
|
-
- [Join Using Invitation Code](#join-using-invitation-code)
|
|
149
|
-
- [Get Group Info by Invite Code](#get-group-info-by-invite-code)
|
|
150
|
-
- [Query Metadata (participants, name, description...)](#query-metadata-participants-name-description)
|
|
151
|
-
- [Join using groupInviteMessage](#join-using-groupinvitemessage)
|
|
152
|
-
- [Get Request Join List](#get-request-join-list)
|
|
153
|
-
- [Approve/Reject Request Join](#approvereject-request-join)
|
|
154
|
-
- [Get All Participating Groups Metadata](#get-all-participating-groups-metadata)
|
|
155
|
-
- [Toggle Ephemeral](#toggle-ephemeral)
|
|
156
|
-
- [Change Add Mode](#change-add-mode)
|
|
157
|
-
- [Privacy](#privacy)
|
|
158
|
-
- [Block/Unblock User](#blockunblock-user)
|
|
159
|
-
- [Get Privacy Settings](#get-privacy-settings)
|
|
160
|
-
- [Get BlockList](#get-blocklist)
|
|
161
|
-
- [Update LastSeen Privacy](#update-lastseen-privacy)
|
|
162
|
-
- [Update Online Privacy](#update-online-privacy)
|
|
163
|
-
- [Update Profile Picture Privacy](#update-profile-picture-privacy)
|
|
164
|
-
- [Update Status Privacy](#update-status-privacy)
|
|
165
|
-
- [Update Read Receipts Privacy](#update-read-receipts-privacy)
|
|
166
|
-
- [Update Groups Add Privacy](#update-groups-add-privacy)
|
|
167
|
-
- [Update Default Disappearing Mode](#update-default-disappearing-mode)
|
|
168
|
-
- [Broadcast Lists & Stories](#broadcast-lists--stories)
|
|
169
|
-
- [Send Broadcast & Stories](#send-broadcast--stories)
|
|
170
|
-
- [Query a Broadcast List's Recipients & Name](#query-a-broadcast-lists-recipients--name)
|
|
171
|
-
- [Writing Custom Functionality](#writing-custom-functionality)
|
|
172
|
-
- [Enabling Debug Level in Baileys Logs](#enabling-debug-level-in-baileys-logs)
|
|
173
|
-
- [How Whatsapp Communicate With Us](#how-whatsapp-communicate-with-us)
|
|
174
|
-
- [Register a Callback for Websocket Events](#register-a-callback-for-websocket-events)
|
|
175
|
-
|
|
176
|
-
## Connecting Account
|
|
177
|
-
|
|
178
|
-
WhatsApp provides a multi-device API that allows Baileys to be authenticated as a second WhatsApp client by scanning a **QR code** or **Pairing Code** with WhatsApp on your phone.
|
|
179
|
-
|
|
180
|
-
> [!NOTE]
|
|
181
|
-
> **[Here](#example-to-start) is a simple example of event handling**
|
|
182
|
-
|
|
183
|
-
> [!TIP]
|
|
184
|
-
> **You can see all supported socket configs [here](https://baileys.whiskeysockets.io/types/SocketConfig.html) (Recommended)**
|
|
185
|
-
|
|
186
|
-
### Starting socket with **QR-CODE**
|
|
187
|
-
|
|
188
|
-
> [!TIP]
|
|
189
|
-
> You can customize browser name if you connect with **QR-CODE**, with `Browser` constant, we have some browsers config, **see [here](https://baileys.whiskeysockets.io/types/BrowsersMap.html)**
|
|
190
|
-
|
|
191
|
-
```ts
|
|
192
|
-
import makeWASocket from '@whiskeysockets/baileys'
|
|
193
|
-
|
|
194
|
-
const sock = makeWASocket({
|
|
195
|
-
// can provide additional config here
|
|
196
|
-
browser: Browsers.ubuntu('My App'),
|
|
197
|
-
printQRInTerminal: true
|
|
198
|
-
})
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
If the connection is successful, you will see a QR code printed on your terminal screen, scan it with WhatsApp on your phone and you'll be logged in!
|
|
202
|
-
|
|
203
|
-
### Starting socket with **Pairing Code**
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
> [!IMPORTANT]
|
|
207
|
-
> Pairing Code isn't Mobile API, it's a method to connect Whatsapp Web without QR-CODE, you can connect only with one device, see [here](https://faq.whatsapp.com/1324084875126592/?cms_platform=web)
|
|
208
|
-
|
|
209
|
-
The phone number can't have `+` or `()` or `-`, only numbers, you must provide country code
|
|
210
|
-
|
|
211
|
-
```ts
|
|
212
|
-
import makeWASocket from '@whiskeysockets/baileys'
|
|
213
|
-
|
|
214
|
-
const sock = makeWASocket({
|
|
215
|
-
// can provide additional config here
|
|
216
|
-
printQRInTerminal: false //need to be false
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
if (!sock.authState.creds.registered) {
|
|
220
|
-
const number = 'XXXXXXXXXXX'
|
|
221
|
-
const code = await sock.requestPairingCode(number)
|
|
222
|
-
console.log(code)
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### Receive Full History
|
|
63
|
+
- [Text](#text-message)
|
|
64
|
+
- [Media](#image--video--audio--document)
|
|
65
|
+
- [Buttons](#button-message)
|
|
66
|
+
- [Template](#template-message)
|
|
67
|
+
- [Interactive / List](#interactive--list-message)
|
|
68
|
+
- [Album](#album-message)
|
|
69
|
+
- [Sticker Pack](#sticker-pack-message)
|
|
70
|
+
- [Share Phone Number](#share-phone-number-message)
|
|
71
|
+
- [Request Phone Number](#request-phone-number-message)
|
|
72
|
+
- [AI Icon Feature](#ai-icon-feature)
|
|
73
|
+
- [Rich Response / Meta AI Messages](#rich-response-message)
|
|
74
|
+
- [sendTable](#sendtable)
|
|
75
|
+
- [sendList](#sendlist)
|
|
76
|
+
- [sendCodeBlock](#sendcodeblock)
|
|
77
|
+
- [sendLatex](#sendlatex)
|
|
78
|
+
- [sendLatexImage](#sendlateximage)
|
|
79
|
+
- [sendLatexInlineImage](#sendlatexinlineimage)
|
|
80
|
+
- [sendRichMessage](#sendrichmessage)
|
|
81
|
+
- [captureUnifiedResponse / sendUnifiedResponse](#captureunifiedresponse--sendunifiedresponse)
|
|
82
|
+
- [Calls](#calls)
|
|
83
|
+
- [Auth State](#auth-state)
|
|
84
|
+
- [MEX Notifications](#mex-notifications)
|
|
85
|
+
- [Addons](#addons)
|
|
86
|
+
- [Changelog](#changelog)
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Connecting
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import makeWASocket, { DisconnectReason, useMultiFileAuthState } from 'anya-bail'
|
|
94
|
+
import { Boom } from '@hapi/boom'
|
|
227
95
|
|
|
228
|
-
|
|
229
|
-
2. Baileys, by default, use chrome browser config
|
|
230
|
-
- If you'd like to emulate a desktop connection (and receive more message history), this browser setting to your Socket config:
|
|
96
|
+
const { state, saveCreds } = await useMultiFileAuthState('./auth_info')
|
|
231
97
|
|
|
232
|
-
```ts
|
|
233
98
|
const sock = makeWASocket({
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
browser: Browsers.macOS('Desktop'),
|
|
237
|
-
syncFullHistory: true
|
|
99
|
+
auth: state,
|
|
100
|
+
printQRInTerminal: true
|
|
238
101
|
})
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
## Important Notes About Socket Config
|
|
242
|
-
|
|
243
|
-
### Caching Group Metadata (Recommended)
|
|
244
|
-
- If you use baileys for groups, we recommend you to set `cachedGroupMetadata` in socket config, you need to implement a cache like this:
|
|
245
|
-
|
|
246
|
-
```ts
|
|
247
|
-
const groupCache = new NodeCache({stdTTL: 5 * 60, useClones: false})
|
|
248
|
-
|
|
249
|
-
const sock = makeWASocket({
|
|
250
|
-
cachedGroupMetadata: async (jid) => groupCache.get(jid)
|
|
251
|
-
})
|
|
252
|
-
|
|
253
|
-
sock.ev.on('groups.update', async ([event]) => {
|
|
254
|
-
const metadata = await sock.groupMetadata(event.id)
|
|
255
|
-
groupCache.set(event.id, metadata)
|
|
256
|
-
})
|
|
257
|
-
|
|
258
|
-
sock.ev.on('group-participants.update', async (event) => {
|
|
259
|
-
const metadata = await sock.groupMetadata(event.id)
|
|
260
|
-
groupCache.set(event.id, metadata)
|
|
261
|
-
})
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
### Improve Retry System & Decrypt Poll Votes
|
|
265
|
-
- If you want to improve sending message, retrying when error occurs and decrypt poll votes, you need to have a store and set `getMessage` config in socket like this:
|
|
266
|
-
```ts
|
|
267
|
-
const sock = makeWASocket({
|
|
268
|
-
getMessage: async (key) => await getMessageFromStore(key)
|
|
269
|
-
})
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### Receive Notifications in Whatsapp App
|
|
273
|
-
- If you want to receive notifications in whatsapp app, set `markOnlineOnConnect` to `false`
|
|
274
|
-
```ts
|
|
275
|
-
const sock = makeWASocket({
|
|
276
|
-
markOnlineOnConnect: false
|
|
277
|
-
})
|
|
278
|
-
```
|
|
279
|
-
## Saving & Restoring Sessions
|
|
280
|
-
|
|
281
|
-
You obviously don't want to keep scanning the QR code every time you want to connect.
|
|
282
|
-
|
|
283
|
-
So, you can load the credentials to log back in:
|
|
284
|
-
```ts
|
|
285
|
-
import makeWASocket, { useMultiFileAuthState } from '@whiskeysockets/baileys'
|
|
286
|
-
|
|
287
|
-
const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')
|
|
288
102
|
|
|
289
|
-
// will use the given state to connect
|
|
290
|
-
// so if valid credentials are available -- it'll connect without QR
|
|
291
|
-
const sock = makeWASocket({ auth: state })
|
|
292
|
-
|
|
293
|
-
// this will be called as soon as the credentials are updated
|
|
294
103
|
sock.ev.on('creds.update', saveCreds)
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
> [!IMPORTANT]
|
|
298
|
-
> `useMultiFileAuthState` is a utility function to help save the auth state in a single folder, this function serves as a good guide to help write auth & key states for SQL/no-SQL databases, which I would recommend in any production grade system.
|
|
299
|
-
|
|
300
|
-
> [!NOTE]
|
|
301
|
-
> When a message is received/sent, due to signal sessions needing updating, the auth keys (`authState.keys`) will update. Whenever that happens, you must save the updated keys (`authState.keys.set()` is called). Not doing so will prevent your messages from reaching the recipient & cause other unexpected consequences. The `useMultiFileAuthState` function automatically takes care of that, but for any other serious implementation -- you will need to be very careful with the key state management.
|
|
302
|
-
|
|
303
|
-
## Handling Events
|
|
304
|
-
|
|
305
|
-
- Baileys uses the EventEmitter syntax for events.
|
|
306
|
-
They're all nicely typed up, so you shouldn't have any issues with an Intellisense editor like VS Code.
|
|
307
|
-
|
|
308
|
-
> [!IMPORTANT]
|
|
309
|
-
> **The events are [these](https://baileys.whiskeysockets.io/types/BaileysEventMap.html)**, it's important you see all events
|
|
310
|
-
|
|
311
|
-
You can listen to these events like this:
|
|
312
|
-
```ts
|
|
313
|
-
const sock = makeWASocket()
|
|
314
|
-
sock.ev.on('messages.upsert', ({ messages }) => {
|
|
315
|
-
console.log('got messages', messages)
|
|
316
|
-
})
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
### Example to Start
|
|
320
|
-
|
|
321
|
-
> [!NOTE]
|
|
322
|
-
> This example includes basic auth storage too
|
|
323
|
-
|
|
324
|
-
> [!NOTE]
|
|
325
|
-
> For reliable serialization of the authentication state, especially when storing as JSON, always use the BufferJSON utility.
|
|
326
104
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
const sock = makeWASocket({
|
|
334
|
-
// can provide additional config here
|
|
335
|
-
auth: state,
|
|
336
|
-
printQRInTerminal: true
|
|
337
|
-
})
|
|
338
|
-
sock.ev.on('connection.update', (update) => {
|
|
339
|
-
const { connection, lastDisconnect } = update
|
|
340
|
-
if(connection === 'close') {
|
|
341
|
-
const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
|
|
342
|
-
console.log('connection closed due to ', lastDisconnect.error, ', reconnecting ', shouldReconnect)
|
|
343
|
-
// reconnect if not logged out
|
|
344
|
-
if(shouldReconnect) {
|
|
345
|
-
connectToWhatsApp()
|
|
346
|
-
}
|
|
347
|
-
} else if(connection === 'open') {
|
|
348
|
-
console.log('opened connection')
|
|
349
|
-
}
|
|
350
|
-
})
|
|
351
|
-
sock.ev.on('messages.upsert', event => {
|
|
352
|
-
for (const m of event.messages) {
|
|
353
|
-
console.log(JSON.stringify(m, undefined, 2))
|
|
354
|
-
|
|
355
|
-
console.log('replying to', m.key.remoteJid)
|
|
356
|
-
await sock.sendMessage(m.key.remoteJid!, { text: 'Hello Word' })
|
|
357
|
-
}
|
|
358
|
-
})
|
|
359
|
-
|
|
360
|
-
// to storage creds (session info) when it updates
|
|
361
|
-
sock.ev.on('creds.update', saveCreds)
|
|
362
|
-
}
|
|
363
|
-
// run in main file
|
|
364
|
-
connectToWhatsApp()
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
> [!IMPORTANT]
|
|
368
|
-
> In `messages.upsert` it's recommended to use a loop like `for (const message of event.messages)` to handle all messages in array
|
|
369
|
-
|
|
370
|
-
### Decrypt Poll Votes
|
|
371
|
-
|
|
372
|
-
- By default poll votes are encrypted and handled in `messages.update`
|
|
373
|
-
- That's a simple example
|
|
374
|
-
```ts
|
|
375
|
-
sock.ev.on('messages.update', event => {
|
|
376
|
-
for(const { key, update } of event) {
|
|
377
|
-
if(update.pollUpdates) {
|
|
378
|
-
const pollCreation = await getMessage(key)
|
|
379
|
-
if(pollCreation) {
|
|
380
|
-
console.log(
|
|
381
|
-
'got poll update, aggregation: ',
|
|
382
|
-
getAggregateVotesInPollMessage({
|
|
383
|
-
message: pollCreation,
|
|
384
|
-
pollUpdates: update.pollUpdates,
|
|
385
|
-
})
|
|
386
|
-
)
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
105
|
+
sock.ev.on('connection.update', update => {
|
|
106
|
+
const { connection, lastDisconnect } = update
|
|
107
|
+
if (connection === 'close') {
|
|
108
|
+
const shouldReconnect = (lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
|
|
109
|
+
if (shouldReconnect) connectToWhatsApp()
|
|
110
|
+
}
|
|
390
111
|
})
|
|
391
112
|
```
|
|
392
113
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
### Summary of Events on First Connection
|
|
396
|
-
|
|
397
|
-
1. When you connect first time, `connection.update` will be fired requesting you to restart sock
|
|
398
|
-
2. Then, history messages will be received in `messaging.history-set`
|
|
399
|
-
|
|
400
|
-
## Implementing a Data Store
|
|
401
|
-
|
|
402
|
-
- Baileys does not come with a defacto storage for chats, contacts, or messages. However, a simple in-memory implementation has been provided. The store listens for chat updates, new messages, message updates, etc., to always have an up-to-date version of the data.
|
|
403
|
-
|
|
404
|
-
> [!IMPORTANT]
|
|
405
|
-
> I highly recommend building your own data store, as storing someone's entire chat history in memory is a terrible waste of RAM.
|
|
406
|
-
|
|
407
|
-
It can be used as follows:
|
|
114
|
+
**Pairing Code (instead of QR):**
|
|
408
115
|
|
|
409
116
|
```ts
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
// can be written out to a file & read from it
|
|
413
|
-
const store = makeInMemoryStore({ })
|
|
414
|
-
// can be read from a file
|
|
415
|
-
store.readFromFile('./baileys_store.json')
|
|
416
|
-
// saves the state to a file every 10s
|
|
417
|
-
setInterval(() => {
|
|
418
|
-
store.writeToFile('./baileys_store.json')
|
|
419
|
-
}, 10_000)
|
|
420
|
-
|
|
421
|
-
const sock = makeWASocket({ })
|
|
422
|
-
// will listen from this socket
|
|
423
|
-
// the store can listen from a new socket once the current socket outlives its lifetime
|
|
424
|
-
store.bind(sock.ev)
|
|
425
|
-
|
|
426
|
-
sock.ev.on('chats.upsert', () => {
|
|
427
|
-
// can use 'store.chats' however you want, even after the socket dies out
|
|
428
|
-
// 'chats' => a KeyedDB instance
|
|
429
|
-
console.log('got chats', store.chats.all())
|
|
430
|
-
})
|
|
431
|
-
|
|
432
|
-
sock.ev.on('contacts.upsert', () => {
|
|
433
|
-
console.log('got contacts', Object.values(store.contacts))
|
|
434
|
-
})
|
|
435
|
-
|
|
117
|
+
const code = await sock.requestPairingCode('+91XXXXXXXXXX')
|
|
118
|
+
console.log('Pairing code:', code)
|
|
436
119
|
```
|
|
437
120
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
## Whatsapp IDs Explain
|
|
441
|
-
|
|
442
|
-
- `id` is the WhatsApp ID, called `jid` too, of the person or group you're sending the message to.
|
|
443
|
-
- It must be in the format ```[country code][phone number]@s.whatsapp.net```
|
|
444
|
-
- Example for people: ```+19999999999@s.whatsapp.net```.
|
|
445
|
-
- For groups, it must be in the format ``` 123456789-123345@g.us ```.
|
|
446
|
-
- For broadcast lists, it's `[timestamp of creation]@broadcast`.
|
|
447
|
-
- For stories, the ID is `status@broadcast`.
|
|
448
|
-
|
|
449
|
-
## Utility Functions
|
|
450
|
-
|
|
451
|
-
- `getContentType`, returns the content type for any message
|
|
452
|
-
- `getDevice`, returns the device from message
|
|
453
|
-
- `makeCacheableSignalKeyStore`, make auth store more fast
|
|
454
|
-
- `downloadContentFromMessage`, download content from any message
|
|
121
|
+
---
|
|
455
122
|
|
|
456
123
|
## Sending Messages
|
|
457
124
|
|
|
458
|
-
|
|
459
|
-
- **[Here](https://baileys.whiskeysockets.io/types/AnyMessageContent.html) you can see all message contents supported, like text message**
|
|
460
|
-
- **[Here](https://baileys.whiskeysockets.io/types/MiscMessageGenerationOptions.html) you can see all options supported, like quote message**
|
|
461
|
-
|
|
462
|
-
```ts
|
|
463
|
-
const jid: string
|
|
464
|
-
const content: AnyMessageContent
|
|
465
|
-
const options: MiscMessageGenerationOptions
|
|
466
|
-
|
|
467
|
-
sock.sendMessage(jid, content, options)
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
### Non-Media Messages
|
|
471
|
-
|
|
472
|
-
#### Text Message
|
|
473
|
-
```ts
|
|
474
|
-
await sock.sendMessage(jid, { text: 'hello word' })
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
#### Quote Message (works with all types)
|
|
478
|
-
```ts
|
|
479
|
-
await sock.sendMessage(jid, { text: 'hello word' }, { quoted: message })
|
|
480
|
-
```
|
|
481
|
-
|
|
482
|
-
#### Mention User (works with most types)
|
|
483
|
-
- @number is to mention in text, it's optional
|
|
484
|
-
```ts
|
|
485
|
-
await sock.sendMessage(
|
|
486
|
-
jid,
|
|
487
|
-
{
|
|
488
|
-
text: '@12345678901',
|
|
489
|
-
mentions: ['12345678901@s.whatsapp.net']
|
|
490
|
-
}
|
|
491
|
-
)
|
|
492
|
-
```
|
|
125
|
+
### Text Message
|
|
493
126
|
|
|
494
|
-
#### Forward Messages
|
|
495
|
-
- You need to have message object, can be retrieved from [store](#implementing-a-data-store) or use a [message](https://baileys.whiskeysockets.io/types/WAMessage.html) object
|
|
496
127
|
```ts
|
|
497
|
-
|
|
498
|
-
await sock.sendMessage(jid, { forward: msg }) // WA forward the message!
|
|
128
|
+
await sock.sendMessage(jid, { text: 'Hello World!' })
|
|
499
129
|
```
|
|
500
130
|
|
|
501
|
-
|
|
502
|
-
```ts
|
|
503
|
-
await sock.sendMessage(
|
|
504
|
-
jid,
|
|
505
|
-
{
|
|
506
|
-
location: {
|
|
507
|
-
degreesLatitude: 24.121231,
|
|
508
|
-
degreesLongitude: 55.1121221
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
)
|
|
512
|
-
```
|
|
513
|
-
#### Contact Message
|
|
514
|
-
```ts
|
|
515
|
-
const vcard = 'BEGIN:VCARD\n' // metadata of the contact card
|
|
516
|
-
+ 'VERSION:3.0\n'
|
|
517
|
-
+ 'FN:Jeff Singh\n' // full name
|
|
518
|
-
+ 'ORG:Ashoka Uni;\n' // the organization of the contact
|
|
519
|
-
+ 'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890\n' // WhatsApp ID + phone number
|
|
520
|
-
+ 'END:VCARD'
|
|
521
|
-
|
|
522
|
-
await sock.sendMessage(
|
|
523
|
-
id,
|
|
524
|
-
{
|
|
525
|
-
contacts: {
|
|
526
|
-
displayName: 'Jeff',
|
|
527
|
-
contacts: [{ vcard }]
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
)
|
|
531
|
-
```
|
|
131
|
+
### Image / Video / Audio / Document
|
|
532
132
|
|
|
533
|
-
#### Reaction Message
|
|
534
|
-
- You need to pass the key of message, you can retrieve from [store](#implementing-a-data-store) or use a [key](https://baileys.whiskeysockets.io/types/WAMessageKey.html) object
|
|
535
133
|
```ts
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
{
|
|
539
|
-
react: {
|
|
540
|
-
text: '💖', // use an empty string to remove the reaction
|
|
541
|
-
key: message.key
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
)
|
|
545
|
-
```
|
|
546
|
-
|
|
547
|
-
#### Pin Message
|
|
548
|
-
- You need to pass the key of message, you can retrieve from [store](#implementing-a-data-store) or use a [key](https://baileys.whiskeysockets.io/types/WAMessageKey.html) object
|
|
134
|
+
// Image
|
|
135
|
+
await sock.sendMessage(jid, { image: { url: './image.jpg' }, caption: 'caption' })
|
|
549
136
|
|
|
550
|
-
|
|
137
|
+
// Video
|
|
138
|
+
await sock.sendMessage(jid, { video: { url: './video.mp4' }, caption: 'caption' })
|
|
551
139
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
| 24h | 86.400 |
|
|
555
|
-
| 7d | 604.800 |
|
|
556
|
-
| 30d | 2.592.000 |
|
|
557
|
-
|
|
558
|
-
```ts
|
|
559
|
-
await sock.sendMessage(
|
|
560
|
-
jid,
|
|
561
|
-
{
|
|
562
|
-
pin: {
|
|
563
|
-
type: 1, // 0 to remove
|
|
564
|
-
time: 86400
|
|
565
|
-
key: message.key
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
)
|
|
569
|
-
```
|
|
140
|
+
// Audio (PTT)
|
|
141
|
+
await sock.sendMessage(jid, { audio: { url: './audio.mp3' }, mimetype: 'audio/mp4', ptt: true })
|
|
570
142
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
await sock.sendMessage(
|
|
574
|
-
jid,
|
|
575
|
-
{
|
|
576
|
-
poll: {
|
|
577
|
-
name: 'My Poll',
|
|
578
|
-
values: ['Option 1', 'Option 2', ...],
|
|
579
|
-
selectableCount: 1,
|
|
580
|
-
toAnnouncementGroup: false // or true
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
)
|
|
143
|
+
// Document
|
|
144
|
+
await sock.sendMessage(jid, { document: { url: './file.pdf' }, mimetype: 'application/pdf', fileName: 'file.pdf' })
|
|
584
145
|
```
|
|
585
146
|
|
|
586
|
-
###
|
|
147
|
+
### Button Message
|
|
587
148
|
|
|
588
|
-
1. By default, wa does not have link generation when sent from the web
|
|
589
|
-
2. Baileys has a function to generate the content for these link previews
|
|
590
|
-
3. To enable this function's usage, add `link-preview-js` as a dependency to your project with `yarn add link-preview-js`
|
|
591
|
-
4. Send a link:
|
|
592
149
|
```ts
|
|
593
|
-
await sock.sendMessage(
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
150
|
+
await sock.sendMessage(jid, {
|
|
151
|
+
buttons: [
|
|
152
|
+
{ buttonId: 'btn1', buttonText: { displayText: 'Option 1' }, type: 1 },
|
|
153
|
+
{ buttonId: 'btn2', buttonText: { displayText: 'Option 2' }, type: 1 }
|
|
154
|
+
],
|
|
155
|
+
text: 'Pick an option:',
|
|
156
|
+
footer: 'Powered by anya-bail'
|
|
157
|
+
})
|
|
599
158
|
```
|
|
600
159
|
|
|
601
|
-
###
|
|
602
|
-
|
|
603
|
-
Sending media (video, stickers, images) is easier & more efficient than ever.
|
|
604
|
-
|
|
605
|
-
> [!NOTE]
|
|
606
|
-
> In media messages, you can pass `{ stream: Stream }` or `{ url: Url }` or `Buffer` directly, you can see more [here](https://baileys.whiskeysockets.io/types/WAMediaUpload.html)
|
|
607
|
-
|
|
608
|
-
- When specifying a media url, Baileys never loads the entire buffer into memory; it even encrypts the media as a readable stream.
|
|
160
|
+
### Template Message
|
|
609
161
|
|
|
610
|
-
> [!TIP]
|
|
611
|
-
> It's recommended to use Stream or Url to save memory
|
|
612
|
-
|
|
613
|
-
#### Gif Message
|
|
614
|
-
- Whatsapp doesn't support `.gif` files, that's why we send gifs as common `.mp4` video with `gifPlayback` flag
|
|
615
|
-
```ts
|
|
616
|
-
await sock.sendMessage(
|
|
617
|
-
jid,
|
|
618
|
-
{
|
|
619
|
-
video: fs.readFileSync('Media/ma_gif.mp4'),
|
|
620
|
-
caption: 'hello word',
|
|
621
|
-
gifPlayback: true
|
|
622
|
-
}
|
|
623
|
-
)
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
#### Video Message
|
|
627
162
|
```ts
|
|
628
|
-
await sock.sendMessage(
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
)
|
|
163
|
+
await sock.sendMessage(jid, {
|
|
164
|
+
templateButtons: [
|
|
165
|
+
{ index: 1, urlButton: { displayText: 'Visit', url: 'https://example.com' } },
|
|
166
|
+
{ index: 2, callButton: { displayText: 'Call', phoneNumber: '+91XXXXXXXXXX' } },
|
|
167
|
+
{ index: 3, quickReplyButton: { displayText: 'Reply', id: 'id1' } }
|
|
168
|
+
],
|
|
169
|
+
text: 'Template body',
|
|
170
|
+
footer: 'footer'
|
|
171
|
+
})
|
|
638
172
|
```
|
|
639
173
|
|
|
640
|
-
|
|
641
|
-
- To audio message work in all devices you need to convert with some tool like `ffmpeg` with this flags:
|
|
642
|
-
```bash
|
|
643
|
-
codec: libopus //ogg file
|
|
644
|
-
ac: 1 //one channel
|
|
645
|
-
avoid_negative_ts
|
|
646
|
-
make_zero
|
|
647
|
-
```
|
|
648
|
-
- Example:
|
|
649
|
-
```bash
|
|
650
|
-
ffmpeg -i input.mp4 -avoid_negative_ts make_zero -ac 1 output.ogg
|
|
651
|
-
```
|
|
652
|
-
```ts
|
|
653
|
-
await sock.sendMessage(
|
|
654
|
-
jid,
|
|
655
|
-
{
|
|
656
|
-
audio: {
|
|
657
|
-
url: './Media/audio.mp3'
|
|
658
|
-
},
|
|
659
|
-
mimetype: 'audio/mp4'
|
|
660
|
-
}
|
|
661
|
-
)
|
|
662
|
-
```
|
|
174
|
+
### Interactive / List Message
|
|
663
175
|
|
|
664
|
-
#### Image Message
|
|
665
176
|
```ts
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
)
|
|
675
|
-
```
|
|
676
|
-
|
|
677
|
-
#### View Once Message
|
|
678
|
-
|
|
679
|
-
- You can send all messages above as `viewOnce`, you only need to pass `viewOnce: true` in content object
|
|
177
|
+
// Interactive buttons
|
|
178
|
+
await sock.sendMessage(jid, {
|
|
179
|
+
interactiveButtons: [
|
|
180
|
+
{ name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: 'Yes', id: 'yes' }) },
|
|
181
|
+
{ name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: 'No', id: 'no' }) }
|
|
182
|
+
],
|
|
183
|
+
body: { text: 'Are you sure?' },
|
|
184
|
+
footer: { text: 'anya-bail' }
|
|
185
|
+
})
|
|
680
186
|
|
|
681
|
-
|
|
682
|
-
await sock.sendMessage(
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
187
|
+
// List message
|
|
188
|
+
await sock.sendMessage(jid, {
|
|
189
|
+
sections: [
|
|
190
|
+
{
|
|
191
|
+
title: 'Section 1',
|
|
192
|
+
rows: [
|
|
193
|
+
{ title: 'Row 1', rowId: 'r1', description: 'Description 1' },
|
|
194
|
+
{ title: 'Row 2', rowId: 'r2', description: 'Description 2' }
|
|
195
|
+
]
|
|
196
|
+
}
|
|
197
|
+
],
|
|
198
|
+
title: 'List Title',
|
|
199
|
+
text: 'List body',
|
|
200
|
+
footer: 'footer',
|
|
201
|
+
buttonText: 'Open List'
|
|
202
|
+
})
|
|
692
203
|
```
|
|
693
204
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
### Deleting Messages (for everyone)
|
|
205
|
+
### Album Message
|
|
697
206
|
|
|
698
207
|
```ts
|
|
699
|
-
|
|
700
|
-
|
|
208
|
+
await sock.sendMessage(jid, {
|
|
209
|
+
album: {
|
|
210
|
+
expectedImageCount: 2,
|
|
211
|
+
expectedVideoCount: 1
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
// Then send each media with albumParentKey
|
|
215
|
+
await sock.sendMessage(jid, {
|
|
216
|
+
image: { url: './photo1.jpg' },
|
|
217
|
+
caption: 'First',
|
|
218
|
+
albumParentKey: albumMsg.key
|
|
219
|
+
})
|
|
701
220
|
```
|
|
702
221
|
|
|
703
|
-
|
|
222
|
+
### Sticker Pack Message
|
|
704
223
|
|
|
705
|
-
### Editing Messages
|
|
706
|
-
|
|
707
|
-
- You can pass all editable contents here
|
|
708
224
|
```ts
|
|
709
225
|
await sock.sendMessage(jid, {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
226
|
+
stickerPack: {
|
|
227
|
+
stickers: [
|
|
228
|
+
{
|
|
229
|
+
fileSha256: Buffer.from('...'),
|
|
230
|
+
fileEncSha256: Buffer.from('...'),
|
|
231
|
+
mediaKey: Buffer.from('...'),
|
|
232
|
+
directPath: '/v/...',
|
|
233
|
+
fileLength: 12345
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
})
|
|
713
238
|
```
|
|
714
239
|
|
|
715
|
-
|
|
240
|
+
### Share Phone Number Message
|
|
716
241
|
|
|
717
|
-
### Thumbnail in Media Messages
|
|
718
|
-
- For media messages, the thumbnail can be generated automatically for images & stickers provided you add `jimp` or `sharp` as a dependency in your project using `yarn add jimp` or `yarn add sharp`.
|
|
719
|
-
- Thumbnails for videos can also be generated automatically, though, you need to have `ffmpeg` installed on your system.
|
|
720
|
-
|
|
721
|
-
### Downloading Media Messages
|
|
722
|
-
|
|
723
|
-
If you want to save the media you received
|
|
724
242
|
```ts
|
|
725
|
-
|
|
726
|
-
import { downloadMediaMessage, getContentType } from '@whiskeysockets/baileys'
|
|
727
|
-
|
|
728
|
-
sock.ev.on('messages.upsert', async ({ [m] }) => {
|
|
729
|
-
if (!m.message) return // if there is no text or media message
|
|
730
|
-
const messageType = getContentType(m) // get what type of message it is (text, image, video...)
|
|
731
|
-
|
|
732
|
-
// if the message is an image
|
|
733
|
-
if (messageType === 'imageMessage') {
|
|
734
|
-
// download the message
|
|
735
|
-
const stream = await downloadMediaMessage(
|
|
736
|
-
m,
|
|
737
|
-
'stream', // can be 'buffer' too
|
|
738
|
-
{ },
|
|
739
|
-
{
|
|
740
|
-
logger,
|
|
741
|
-
// pass this so that baileys can request a reupload of media
|
|
742
|
-
// that has been deleted
|
|
743
|
-
reuploadRequest: sock.updateMediaMessage
|
|
744
|
-
}
|
|
745
|
-
)
|
|
746
|
-
// save to file
|
|
747
|
-
const writeStream = createWriteStream('./my-download.jpeg')
|
|
748
|
-
stream.pipe(writeStream)
|
|
749
|
-
}
|
|
750
|
-
}
|
|
243
|
+
await sock.sendMessage(jid, { sharePhoneNumber: true })
|
|
751
244
|
```
|
|
752
245
|
|
|
753
|
-
###
|
|
246
|
+
### Request Phone Number Message
|
|
754
247
|
|
|
755
|
-
- WhatsApp automatically removes old media from their servers. For the device to access said media -- a re-upload is required by another device that has it. This can be accomplished using:
|
|
756
248
|
```ts
|
|
757
|
-
await sock.
|
|
249
|
+
await sock.sendMessage(jid, { requestPhoneNumber: true })
|
|
758
250
|
```
|
|
759
251
|
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
- You can obtain `callId` and `callFrom` from `call` event
|
|
252
|
+
### AI Icon Feature
|
|
763
253
|
|
|
764
254
|
```ts
|
|
765
|
-
|
|
255
|
+
// Adds Meta AI bot icon to any message
|
|
256
|
+
await sock.sendMessage(jid, { text: 'I am a bot!' }, { ai: true })
|
|
766
257
|
```
|
|
767
258
|
|
|
768
|
-
|
|
259
|
+
### Rich Response Message
|
|
769
260
|
|
|
770
|
-
|
|
771
|
-
- A set of message [keys](https://baileys.whiskeysockets.io/types/WAMessageKey.html) must be explicitly marked read now.
|
|
772
|
-
- You cannot mark an entire 'chat' read as it were with Baileys Web.
|
|
773
|
-
This means you have to keep track of unread messages.
|
|
261
|
+
#### sendTable
|
|
774
262
|
|
|
775
263
|
```ts
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
264
|
+
await sock.sendTable(
|
|
265
|
+
jid,
|
|
266
|
+
'Results',
|
|
267
|
+
['Name', 'Score'],
|
|
268
|
+
[
|
|
269
|
+
['Alice', '98'],
|
|
270
|
+
['Bob', '87']
|
|
271
|
+
],
|
|
272
|
+
quotedMsg,
|
|
273
|
+
{ headerText: 'Leaderboard:', footer: 'Updated now' }
|
|
274
|
+
)
|
|
779
275
|
```
|
|
780
276
|
|
|
781
|
-
|
|
782
|
-
On a `WAMessage`, the `messageID` can be accessed using ```messageID = message.key.id```.
|
|
783
|
-
|
|
784
|
-
### Update Presence
|
|
785
|
-
|
|
786
|
-
- ``` presence ``` can be one of [these](https://baileys.whiskeysockets.io/types/WAPresence.html)
|
|
787
|
-
- The presence expires after about 10 seconds.
|
|
788
|
-
- This lets the person/group with `jid` know whether you're online, offline, typing etc.
|
|
277
|
+
#### sendList
|
|
789
278
|
|
|
790
279
|
```ts
|
|
791
|
-
await sock.
|
|
280
|
+
await sock.sendList(jid, 'Todo', ['Buy milk', 'Call mom', 'Push code'], quotedMsg)
|
|
792
281
|
```
|
|
793
282
|
|
|
794
|
-
|
|
795
|
-
> If a desktop client is active, WA doesn't send push notifications to the device. If you would like to receive said notifications -- mark your Baileys client offline using `sock.sendPresenceUpdate('unavailable')`
|
|
796
|
-
|
|
797
|
-
## Modifying Chats
|
|
798
|
-
|
|
799
|
-
WA uses an encrypted form of communication to send chat/app updates. This has been implemented mostly and you can send the following updates:
|
|
283
|
+
#### sendCodeBlock
|
|
800
284
|
|
|
801
|
-
> [!IMPORTANT]
|
|
802
|
-
> If you mess up one of your updates, WA can log you out of all your devices and you'll have to log in again.
|
|
803
|
-
|
|
804
|
-
### Archive a Chat
|
|
805
285
|
```ts
|
|
806
|
-
const
|
|
807
|
-
|
|
286
|
+
await sock.sendCodeBlock(jid, `const greet = name => \`Hello \${name}\``, quotedMsg, {
|
|
287
|
+
title: 'Example',
|
|
288
|
+
language: 'javascript'
|
|
289
|
+
})
|
|
290
|
+
// Supported: javascript, typescript, python (js, ts, py)
|
|
808
291
|
```
|
|
809
|
-
### Mute/Unmute a Chat
|
|
810
292
|
|
|
811
|
-
|
|
293
|
+
#### sendLatex
|
|
812
294
|
|
|
813
|
-
| Time | Miliseconds |
|
|
814
|
-
|-------|-----------------|
|
|
815
|
-
| Remove | null |
|
|
816
|
-
| 8h | 86.400.000 |
|
|
817
|
-
| 7d | 604.800.000 |
|
|
818
|
-
|
|
819
|
-
```ts
|
|
820
|
-
// mute for 8 hours
|
|
821
|
-
await sock.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid)
|
|
822
|
-
// unmute
|
|
823
|
-
await sock.chatModify({ mute: null }, jid)
|
|
824
|
-
```
|
|
825
|
-
### Mark a Chat Read/Unread
|
|
826
295
|
```ts
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
296
|
+
await sock.sendLatex(jid, quotedMsg, {
|
|
297
|
+
text: 'Quadratic formula:',
|
|
298
|
+
expressions: [{ latexExpression: 'x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}' }]
|
|
299
|
+
})
|
|
830
300
|
```
|
|
831
301
|
|
|
832
|
-
|
|
833
|
-
```ts
|
|
834
|
-
await sock.chatModify(
|
|
835
|
-
{
|
|
836
|
-
clear: {
|
|
837
|
-
messages: [
|
|
838
|
-
{
|
|
839
|
-
id: 'ATWYHDNNWU81732J',
|
|
840
|
-
fromMe: true,
|
|
841
|
-
timestamp: '1654823909'
|
|
842
|
-
}
|
|
843
|
-
]
|
|
844
|
-
}
|
|
845
|
-
},
|
|
846
|
-
jid
|
|
847
|
-
)
|
|
302
|
+
#### sendLatexImage
|
|
848
303
|
|
|
849
|
-
```
|
|
850
|
-
### Delete a Chat
|
|
851
|
-
```ts
|
|
852
|
-
const lastMsgInChat = await getLastMessageInChat(jid) // implement this on your end
|
|
853
|
-
await sock.chatModify({
|
|
854
|
-
delete: true,
|
|
855
|
-
lastMessages: [
|
|
856
|
-
{
|
|
857
|
-
key: lastMsgInChat.key,
|
|
858
|
-
messageTimestamp: lastMsgInChat.messageTimestamp
|
|
859
|
-
}
|
|
860
|
-
]
|
|
861
|
-
},
|
|
862
|
-
jid
|
|
863
|
-
)
|
|
864
|
-
```
|
|
865
|
-
### Pin/Unpin a Chat
|
|
866
304
|
```ts
|
|
867
|
-
await sock.
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
305
|
+
await sock.sendLatexImage(
|
|
306
|
+
jid,
|
|
307
|
+
quotedMsg,
|
|
308
|
+
{ expressions: [{ latexExpression: 'e^{i\\pi}+1=0' }] },
|
|
309
|
+
async latex => renderToPng(latex), // → { buffer, width, height }
|
|
310
|
+
async (buf, type) => uploadToWA(buf, type) // → { url?, directPath? }
|
|
871
311
|
)
|
|
872
312
|
```
|
|
873
|
-
### Star/Unstar a Message
|
|
874
|
-
```ts
|
|
875
|
-
await sock.chatModify({
|
|
876
|
-
star: {
|
|
877
|
-
messages: [
|
|
878
|
-
{
|
|
879
|
-
id: 'messageID',
|
|
880
|
-
fromMe: true // or `false`
|
|
881
|
-
}
|
|
882
|
-
],
|
|
883
|
-
star: true // - true: Star Message; false: Unstar Message
|
|
884
|
-
}
|
|
885
|
-
},
|
|
886
|
-
jid
|
|
887
|
-
)
|
|
888
|
-
```
|
|
889
|
-
|
|
890
|
-
### Disappearing Messages
|
|
891
313
|
|
|
892
|
-
|
|
314
|
+
#### sendLatexInlineImage
|
|
893
315
|
|
|
894
|
-
|
|
895
|
-
|-------|----------------|
|
|
896
|
-
| Remove | 0 |
|
|
897
|
-
| 24h | 86.400 |
|
|
898
|
-
| 7d | 604.800 |
|
|
899
|
-
| 90d | 7.776.000 |
|
|
316
|
+
Same as `sendLatexImage` but each expression renders as its own inline image block.
|
|
900
317
|
|
|
901
|
-
|
|
318
|
+
#### sendRichMessage
|
|
902
319
|
|
|
903
320
|
```ts
|
|
904
|
-
|
|
905
|
-
await sock.sendMessage(
|
|
906
|
-
jid,
|
|
907
|
-
// this is 1 week in seconds -- how long you want messages to appear for
|
|
908
|
-
{ disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL }
|
|
909
|
-
)
|
|
910
|
-
|
|
911
|
-
// will send as a disappearing message
|
|
912
|
-
await sock.sendMessage(jid, { text: 'hello' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL })
|
|
321
|
+
import { RichSubMessageType } from 'anya-bail'
|
|
913
322
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
323
|
+
await sock.sendRichMessage(
|
|
324
|
+
jid,
|
|
325
|
+
[
|
|
326
|
+
{ messageType: RichSubMessageType.TEXT, messageText: 'Hello from bot!' },
|
|
327
|
+
{
|
|
328
|
+
messageType: RichSubMessageType.TABLE,
|
|
329
|
+
tableMetadata: {
|
|
330
|
+
title: 'Data',
|
|
331
|
+
rows: [{ items: ['Key', 'Value'], isHeading: true }, { items: ['status', 'ok'] }]
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
],
|
|
335
|
+
quotedMsg
|
|
918
336
|
)
|
|
919
337
|
```
|
|
920
338
|
|
|
921
|
-
|
|
339
|
+
#### captureUnifiedResponse / sendUnifiedResponse
|
|
922
340
|
|
|
923
|
-
### Check If ID Exists in Whatsapp
|
|
924
341
|
```ts
|
|
925
|
-
|
|
926
|
-
|
|
342
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
343
|
+
for (const msg of messages) {
|
|
344
|
+
const captured = sock.captureUnifiedResponse(msg.message)
|
|
345
|
+
if (captured) {
|
|
346
|
+
await sock.sendUnifiedResponse(otherJid, quotedMsg, captured)
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
})
|
|
927
350
|
```
|
|
928
351
|
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
- You need to have oldest message in chat
|
|
932
|
-
```ts
|
|
933
|
-
const msg = await getOldestMessageInChat(jid) // implement this on your end
|
|
934
|
-
await sock.fetchMessageHistory(
|
|
935
|
-
50, //quantity (max: 50 per query)
|
|
936
|
-
msg.key,
|
|
937
|
-
msg.messageTimestamp
|
|
938
|
-
)
|
|
939
|
-
```
|
|
940
|
-
- Messages will be received in `messaging.history-set` event
|
|
352
|
+
---
|
|
941
353
|
|
|
942
|
-
|
|
943
|
-
```ts
|
|
944
|
-
const status = await sock.fetchStatus(jid)
|
|
945
|
-
console.log('status: ' + status)
|
|
946
|
-
```
|
|
354
|
+
## Calls
|
|
947
355
|
|
|
948
|
-
### Fetch Profile Picture (groups too)
|
|
949
|
-
- To get the display picture of some person/group
|
|
950
356
|
```ts
|
|
951
|
-
//
|
|
952
|
-
const
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
357
|
+
// Outgoing call
|
|
358
|
+
const { callId } = await sock.initiateCall(jid, { isVideo: false })
|
|
359
|
+
await sock.acceptCall(jid, callId)
|
|
360
|
+
await sock.preacceptCall(jid, callId)
|
|
361
|
+
await sock.muteCall(jid, callId, { isMuted: true })
|
|
362
|
+
await sock.terminateCall(jid, callId)
|
|
363
|
+
await sock.cancelCall(jid, callId)
|
|
958
364
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
console.log('business description: ' + profile.description + ', category: ' + profile.category)
|
|
365
|
+
// Group call links
|
|
366
|
+
const link = await sock.queryCallLink(callLinkToken)
|
|
367
|
+
await sock.joinCallLink(callLinkToken)
|
|
963
368
|
```
|
|
964
369
|
|
|
965
|
-
|
|
966
|
-
```ts
|
|
967
|
-
// the presence update is fetched and called here
|
|
968
|
-
sock.ev.on('presence.update', console.log)
|
|
969
|
-
|
|
970
|
-
// request updates for a chat
|
|
971
|
-
await sock.presenceSubscribe(jid)
|
|
972
|
-
```
|
|
370
|
+
---
|
|
973
371
|
|
|
974
|
-
##
|
|
372
|
+
## Auth State
|
|
975
373
|
|
|
976
|
-
### Change Profile Status
|
|
977
|
-
```ts
|
|
978
|
-
await sock.updateProfileStatus('Hello World!')
|
|
979
|
-
```
|
|
980
|
-
### Change Profile Name
|
|
981
374
|
```ts
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
### Change Display Picture (groups too)
|
|
985
|
-
- To change your display picture or a group's
|
|
375
|
+
// Multi-file (default)
|
|
376
|
+
const { state, saveCreds } = await useMultiFileAuthState('./auth_info')
|
|
986
377
|
|
|
987
|
-
|
|
988
|
-
|
|
378
|
+
// Single-file
|
|
379
|
+
import { useSingleFileAuthState } from 'anya-bail'
|
|
380
|
+
const { state, saveState } = useSingleFileAuthState('./auth.json')
|
|
989
381
|
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
### Remove display picture (groups too)
|
|
994
|
-
```ts
|
|
995
|
-
await sock.removeProfilePicture(jid)
|
|
382
|
+
// MongoDB
|
|
383
|
+
import { useMongoFileAuthState } from 'anya-bail'
|
|
384
|
+
const { state, saveCreds } = await useMongoFileAuthState(mongoCollection)
|
|
996
385
|
```
|
|
997
386
|
|
|
998
|
-
|
|
387
|
+
---
|
|
999
388
|
|
|
1000
|
-
|
|
389
|
+
## MEX Notifications
|
|
1001
390
|
|
|
1002
|
-
### Create a Group
|
|
1003
|
-
```ts
|
|
1004
|
-
// title & participants
|
|
1005
|
-
const group = await sock.groupCreate('My Fab Group', ['1234@s.whatsapp.net', '4564@s.whatsapp.net'])
|
|
1006
|
-
console.log('created group with id: ' + group.gid)
|
|
1007
|
-
await sock.sendMessage(group.id, { text: 'hello there' }) // say hello to everyone on the group
|
|
1008
|
-
```
|
|
1009
|
-
### Add/Remove or Demote/Promote
|
|
1010
|
-
```ts
|
|
1011
|
-
// id & people to add to the group (will throw error if it fails)
|
|
1012
|
-
await sock.groupParticipantsUpdate(
|
|
1013
|
-
jid,
|
|
1014
|
-
['abcd@s.whatsapp.net', 'efgh@s.whatsapp.net'],
|
|
1015
|
-
'add' // replace this parameter with 'remove' or 'demote' or 'promote'
|
|
1016
|
-
)
|
|
1017
|
-
```
|
|
1018
|
-
### Change Subject (name)
|
|
1019
|
-
```ts
|
|
1020
|
-
await sock.groupUpdateSubject(jid, 'New Subject!')
|
|
1021
|
-
```
|
|
1022
|
-
### Change Description
|
|
1023
|
-
```ts
|
|
1024
|
-
await sock.groupUpdateDescription(jid, 'New Description!')
|
|
1025
|
-
```
|
|
1026
|
-
### Change Settings
|
|
1027
|
-
```ts
|
|
1028
|
-
// only allow admins to send messages
|
|
1029
|
-
await sock.groupSettingUpdate(jid, 'announcement')
|
|
1030
|
-
// allow everyone to send messages
|
|
1031
|
-
await sock.groupSettingUpdate(jid, 'not_announcement')
|
|
1032
|
-
// allow everyone to modify the group's settings -- like display picture etc.
|
|
1033
|
-
await sock.groupSettingUpdate(jid, 'unlocked')
|
|
1034
|
-
// only allow admins to modify the group's settings
|
|
1035
|
-
await sock.groupSettingUpdate(jid, 'locked')
|
|
1036
|
-
```
|
|
1037
|
-
### Leave a Group
|
|
1038
|
-
```ts
|
|
1039
|
-
// will throw error if it fails
|
|
1040
|
-
await sock.groupLeave(jid)
|
|
1041
|
-
```
|
|
1042
|
-
### Get Invite Code
|
|
1043
|
-
- To create link with code use `'https://chat.whatsapp.com/' + code`
|
|
1044
|
-
```ts
|
|
1045
|
-
const code = await sock.groupInviteCode(jid)
|
|
1046
|
-
console.log('group code: ' + code)
|
|
1047
|
-
```
|
|
1048
|
-
### Revoke Invite Code
|
|
1049
391
|
```ts
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
### Join Using Invitation Code
|
|
1054
|
-
- Code can't have `https://chat.whatsapp.com/`, only code
|
|
1055
|
-
```ts
|
|
1056
|
-
const response = await sock.groupAcceptInvite(code)
|
|
1057
|
-
console.log('joined to: ' + response)
|
|
1058
|
-
```
|
|
1059
|
-
### Get Group Info by Invite Code
|
|
1060
|
-
```ts
|
|
1061
|
-
const response = await sock.groupGetInviteInfo(code)
|
|
1062
|
-
console.log('group information: ' + response)
|
|
1063
|
-
```
|
|
1064
|
-
### Query Metadata (participants, name, description...)
|
|
1065
|
-
```ts
|
|
1066
|
-
const metadata = await sock.groupMetadata(jid)
|
|
1067
|
-
console.log(metadata.id + ', title: ' + metadata.subject + ', description: ' + metadata.desc)
|
|
1068
|
-
```
|
|
1069
|
-
### Join using `groupInviteMessage`
|
|
1070
|
-
```ts
|
|
1071
|
-
const response = await sock.groupAcceptInviteV4(jid, groupInviteMessage)
|
|
1072
|
-
console.log('joined to: ' + response)
|
|
1073
|
-
```
|
|
1074
|
-
### Get Request Join List
|
|
1075
|
-
```ts
|
|
1076
|
-
const response = await sock.groupRequestParticipantsList(jid)
|
|
1077
|
-
console.log(response)
|
|
1078
|
-
```
|
|
1079
|
-
### Approve/Reject Request Join
|
|
1080
|
-
```ts
|
|
1081
|
-
const response = await sock.groupRequestParticipantsUpdate(
|
|
1082
|
-
jid, // group id
|
|
1083
|
-
['abcd@s.whatsapp.net', 'efgh@s.whatsapp.net'],
|
|
1084
|
-
'approve' // or 'reject'
|
|
1085
|
-
)
|
|
1086
|
-
console.log(response)
|
|
1087
|
-
```
|
|
1088
|
-
### Get All Participating Groups Metadata
|
|
1089
|
-
```ts
|
|
1090
|
-
const response = await sock.groupFetchAllParticipating()
|
|
1091
|
-
console.log(response)
|
|
1092
|
-
```
|
|
1093
|
-
### Toggle Ephemeral
|
|
392
|
+
// Newsletter
|
|
393
|
+
sock.ev.on('newsletter-settings.update', ({ id, update }) => {})
|
|
394
|
+
sock.ev.on('newsletter-participants.update', ({ id, user, new_role }) => {})
|
|
1094
395
|
|
|
1095
|
-
|
|
396
|
+
// Linked profiles (LID ↔ PN mapping)
|
|
397
|
+
sock.ev.on('lid-mapping.update', ({ lid, pn }) => {})
|
|
1096
398
|
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
| Remove | 0 |
|
|
1100
|
-
| 24h | 86.400 |
|
|
1101
|
-
| 7d | 604.800 |
|
|
1102
|
-
| 90d | 7.776.000 |
|
|
399
|
+
// Message capping quota
|
|
400
|
+
sock.ev.on('message-capping.update', ({ used_quota, total_quota }) => {})
|
|
1103
401
|
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
```ts
|
|
1110
|
-
await sock.groupMemberAddMode(
|
|
1111
|
-
jid,
|
|
1112
|
-
'all_member_add' // or 'admin_add'
|
|
1113
|
-
)
|
|
1114
|
-
```
|
|
1115
|
-
|
|
1116
|
-
## Privacy
|
|
1117
|
-
|
|
1118
|
-
### Block/Unblock User
|
|
1119
|
-
```ts
|
|
1120
|
-
await sock.updateBlockStatus(jid, 'block') // Block user
|
|
1121
|
-
await sock.updateBlockStatus(jid, 'unblock') // Unblock user
|
|
1122
|
-
```
|
|
1123
|
-
### Get Privacy Settings
|
|
1124
|
-
```ts
|
|
1125
|
-
const privacySettings = await sock.fetchPrivacySettings(true)
|
|
1126
|
-
console.log('privacy settings: ' + privacySettings)
|
|
1127
|
-
```
|
|
1128
|
-
### Get BlockList
|
|
1129
|
-
```ts
|
|
1130
|
-
const response = await sock.fetchBlocklist()
|
|
1131
|
-
console.log(response)
|
|
1132
|
-
```
|
|
1133
|
-
### Update LastSeen Privacy
|
|
1134
|
-
```ts
|
|
1135
|
-
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
|
|
1136
|
-
await sock.updateLastSeenPrivacy(value)
|
|
1137
|
-
```
|
|
1138
|
-
### Update Online Privacy
|
|
1139
|
-
```ts
|
|
1140
|
-
const value = 'all' // 'match_last_seen'
|
|
1141
|
-
await sock.updateOnlinePrivacy(value)
|
|
1142
|
-
```
|
|
1143
|
-
### Update Profile Picture Privacy
|
|
1144
|
-
```ts
|
|
1145
|
-
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
|
|
1146
|
-
await sock.updateProfilePicturePrivacy(value)
|
|
1147
|
-
```
|
|
1148
|
-
### Update Status Privacy
|
|
1149
|
-
```ts
|
|
1150
|
-
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
|
|
1151
|
-
await sock.updateStatusPrivacy(value)
|
|
1152
|
-
```
|
|
1153
|
-
### Update Read Receipts Privacy
|
|
1154
|
-
```ts
|
|
1155
|
-
const value = 'all' // 'none'
|
|
1156
|
-
await sock.updateReadReceiptsPrivacy(value)
|
|
1157
|
-
```
|
|
1158
|
-
### Update Groups Add Privacy
|
|
1159
|
-
```ts
|
|
1160
|
-
const value = 'all' // 'contacts' | 'contact_blacklist'
|
|
1161
|
-
await sock.updateGroupsAddPrivacy(value)
|
|
1162
|
-
```
|
|
1163
|
-
### Update Default Disappearing Mode
|
|
1164
|
-
|
|
1165
|
-
- Like [this](#disappearing-messages), ephemeral can be:
|
|
1166
|
-
|
|
1167
|
-
| Time | Seconds |
|
|
1168
|
-
|-------|----------------|
|
|
1169
|
-
| Remove | 0 |
|
|
1170
|
-
| 24h | 86.400 |
|
|
1171
|
-
| 7d | 604.800 |
|
|
1172
|
-
| 90d | 7.776.000 |
|
|
1173
|
-
|
|
1174
|
-
```ts
|
|
1175
|
-
const ephemeral = 86400
|
|
1176
|
-
await sock.updateDefaultDisappearingMode(ephemeral)
|
|
1177
|
-
```
|
|
1178
|
-
|
|
1179
|
-
## Broadcast Lists & Stories
|
|
1180
|
-
|
|
1181
|
-
### Send Broadcast & Stories
|
|
1182
|
-
- Messages can be sent to broadcasts & stories. You need to add the following message options in sendMessage, like this:
|
|
1183
|
-
```ts
|
|
1184
|
-
await sock.sendMessage(
|
|
1185
|
-
jid,
|
|
1186
|
-
{
|
|
1187
|
-
image: {
|
|
1188
|
-
url: url
|
|
1189
|
-
},
|
|
1190
|
-
caption: caption
|
|
1191
|
-
},
|
|
1192
|
-
{
|
|
1193
|
-
backgroundColor: backgroundColor,
|
|
1194
|
-
font: font,
|
|
1195
|
-
statusJidList: statusJidList,
|
|
1196
|
-
broadcast: true
|
|
1197
|
-
}
|
|
1198
|
-
)
|
|
1199
|
-
```
|
|
1200
|
-
- Message body can be a `extendedTextMessage` or `imageMessage` or `videoMessage` or `voiceMessage`, see [here](https://baileys.whiskeysockets.io/types/AnyRegularMessageContent.html)
|
|
1201
|
-
- You can add `backgroundColor` and other options in the message options, see [here](https://baileys.whiskeysockets.io/types/MiscMessageGenerationOptions.html)
|
|
1202
|
-
- `broadcast: true` enables broadcast mode
|
|
1203
|
-
- `statusJidList`: a list of people that you can get which you need to provide, which are the people who will get this status message.
|
|
1204
|
-
|
|
1205
|
-
- You can send messages to broadcast lists the same way you send messages to groups & individual chats.
|
|
1206
|
-
- Right now, WA Web does not support creating broadcast lists, but you can still delete them.
|
|
1207
|
-
- Broadcast IDs are in the format `12345678@broadcast`
|
|
1208
|
-
### Query a Broadcast List's Recipients & Name
|
|
1209
|
-
```ts
|
|
1210
|
-
const bList = await sock.getBroadcastListInfo('1234@broadcast')
|
|
1211
|
-
console.log (`list name: ${bList.name}, recps: ${bList.recipients}`)
|
|
1212
|
-
```
|
|
1213
|
-
|
|
1214
|
-
## Writing Custom Functionality
|
|
1215
|
-
Baileys is written with custom functionality in mind. Instead of forking the project & re-writing the internals, you can simply write your own extensions.
|
|
1216
|
-
|
|
1217
|
-
### Enabling Debug Level in Baileys Logs
|
|
1218
|
-
First, enable the logging of unhandled messages from WhatsApp by setting:
|
|
1219
|
-
```ts
|
|
1220
|
-
const sock = makeWASocket({
|
|
1221
|
-
logger: P({ level: 'debug' }),
|
|
402
|
+
// WA Business reachout timelock
|
|
403
|
+
sock.ev.on('connection.update', ({ reachoutTimeLock }) => {
|
|
404
|
+
if (reachoutTimeLock?.isActive) {
|
|
405
|
+
console.log('Restricted until:', reachoutTimeLock.timeEnforcementEnds)
|
|
406
|
+
}
|
|
1222
407
|
})
|
|
1223
|
-
```
|
|
1224
|
-
This will enable you to see all sorts of messages WhatsApp sends in the console.
|
|
1225
|
-
|
|
1226
|
-
### How Whatsapp Communicate With Us
|
|
1227
|
-
|
|
1228
|
-
> [!TIP]
|
|
1229
|
-
> If you want to learn whatsapp protocol, we recommend to study about Libsignal Protocol and Noise Protocol
|
|
1230
|
-
|
|
1231
|
-
- **Example:** Functionality to track the battery percentage of your phone. You enable logging and you'll see a message about your battery pop up in the console:
|
|
1232
|
-
```
|
|
1233
|
-
{
|
|
1234
|
-
"level": 10,
|
|
1235
|
-
"fromMe": false,
|
|
1236
|
-
"frame": {
|
|
1237
|
-
"tag": "ib",
|
|
1238
|
-
"attrs": {
|
|
1239
|
-
"from": "@s.whatsapp.net"
|
|
1240
|
-
},
|
|
1241
|
-
"content": [
|
|
1242
|
-
{
|
|
1243
|
-
"tag": "edge_routing",
|
|
1244
|
-
"attrs": {},
|
|
1245
|
-
"content": [
|
|
1246
|
-
{
|
|
1247
|
-
"tag": "routing_info",
|
|
1248
|
-
"attrs": {},
|
|
1249
|
-
"content": {
|
|
1250
|
-
"type": "Buffer",
|
|
1251
|
-
"data": [8,2,8,5]
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
]
|
|
1255
|
-
}
|
|
1256
|
-
]
|
|
1257
|
-
},
|
|
1258
|
-
"msg":"communication"
|
|
1259
|
-
}
|
|
1260
|
-
```
|
|
1261
|
-
|
|
1262
|
-
The `'frame'` is what the message received is, it has three components:
|
|
1263
|
-
- `tag` -- what this frame is about (eg. message will have 'message')
|
|
1264
|
-
- `attrs` -- a string key-value pair with some metadata (contains ID of the message usually)
|
|
1265
|
-
- `content` -- the actual data (eg. a message node will have the actual message content in it)
|
|
1266
|
-
- read more about this format [here](/src/WABinary/readme.md)
|
|
1267
|
-
|
|
1268
|
-
### Register a Callback for Websocket Events
|
|
1269
|
-
|
|
1270
|
-
> [!TIP]
|
|
1271
|
-
> Recommended to see `onMessageReceived` function in `socket.ts` file to understand how websockets events are fired
|
|
1272
408
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
// for any message with tag 'edge_routing' and id attribute = abcd
|
|
1278
|
-
sock.ws.on('CB:edge_routing,id:abcd', (node: BinaryNode) => { })
|
|
1279
|
-
|
|
1280
|
-
// for any message with tag 'edge_routing', id attribute = abcd & first content node routing_info
|
|
1281
|
-
sock.ws.on('CB:edge_routing,id:abcd,routing_info', (node: BinaryNode) => { })
|
|
409
|
+
// History sync completion / stall
|
|
410
|
+
sock.ev.on('messaging-history.status', ({ syncType, status, explicit }) => {
|
|
411
|
+
console.log(`History sync ${status} (${syncType}) explicit=${explicit}`)
|
|
412
|
+
})
|
|
1282
413
|
```
|
|
1283
414
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## Addons
|
|
418
|
+
|
|
419
|
+
```ts
|
|
420
|
+
import { buildVCard, AutoReplyEngine, createScheduler, ... } from 'anya-bail'
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
| Addon | Description |
|
|
424
|
+
| --------------------- | ---------------------------------------------------- |
|
|
425
|
+
| `message-composer` | Rich/bot message builders (table, list, code, latex) |
|
|
426
|
+
| `button-sender` | Interactive / native-flow button helpers |
|
|
427
|
+
| `call-handler` | Inbound call handling |
|
|
428
|
+
| `auto-reply` | Rule-based auto-reply engine |
|
|
429
|
+
| `scheduling` | Message queue + scheduled sending |
|
|
430
|
+
| `anti-delete` | Detect and recover deleted messages |
|
|
431
|
+
| `vcard` | Build vCard contact strings |
|
|
432
|
+
| `message-search` | Search messages by type/text/regex |
|
|
433
|
+
| `status-posting` | Broadcast statuses to multiple JIDs |
|
|
434
|
+
| `jid-plotting` | JID resolution + LID/PN mapping helpers |
|
|
435
|
+
| `templates` | Template message variable helpers |
|
|
436
|
+
| `interactive-message` | Interactive message utilities |
|
|
437
|
+
| `from-messages` | Message processing helpers |
|
|
438
|
+
| `from-messages-recv` | Inbound message helpers |
|
|
439
|
+
| `from-messages-send` | Outbound message helpers |
|
|
440
|
+
| `from-chats` | Chat event helpers |
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Changelog
|
|
445
|
+
|
|
446
|
+
### v8.0.0 — April 2026 (anya-bail)
|
|
447
|
+
|
|
448
|
+
**Based on:** WhiskeySockets/Baileys master (April 2026) + InnovatorsSOFT Baileys additions
|
|
449
|
+
|
|
450
|
+
**Added over upstream:**
|
|
451
|
+
|
|
452
|
+
- Full interactive/button/template/list/cards/carousel message system
|
|
453
|
+
- Album messages with `albumParentKey` support
|
|
454
|
+
- Sticker pack messages
|
|
455
|
+
- Share/Request phone number messages
|
|
456
|
+
- AI icon on any message (`options.ai = true`)
|
|
457
|
+
- Rich response / Meta AI messages — `sendTable`, `sendList`, `sendCodeBlock`, `sendLatex`, `sendLatexImage`, `sendLatexInlineImage`, `sendRichMessage`, `captureUnifiedResponse`, `sendUnifiedResponse`
|
|
458
|
+
- Full outgoing call API (`initiateCall`, `acceptCall`, `preacceptCall`, `muteCall`, `terminateCall`, `cancelCall`, `queryCallLink`, `joinCallLink`)
|
|
459
|
+
- Full MEX notification dispatcher — reachout timelock, message capping, linked profiles, newsletter ops
|
|
460
|
+
- `messaging-history.status` event with pause timeout (120s)
|
|
461
|
+
- `message-capping.update` event
|
|
462
|
+
- `authorUsername` in group participant events
|
|
463
|
+
- `chunkOrder` in history sync
|
|
464
|
+
- MongoDB + single-file auth states
|
|
465
|
+
- Extended browser map: iOS, Android, androidCompanion, Linux, KaiOS, ChromeOS
|
|
466
|
+
- `getPlatformDisplayName()` utility
|
|
467
|
+
- Pairing race-condition fix (`sendPairingIQ` + queue)
|
|
468
|
+
- `buildPairingQRData` from companion-reg-client-utils
|
|
469
|
+
- tctoken issuance + prune system (daily cleanup on reconnect)
|
|
470
|
+
- App state sync resilience: `forceSnapshotCollections`, `blockedCollections`
|
|
471
|
+
- `ensureLTHashStateVersion`, `isMissingKeyError`, `isAppStateSyncIrrecoverable`, `MAX_SYNC_ATTEMPTS`
|
|
472
|
+
- `storeTcTokensFromHistorySync` — saves tctokens from history sync chats
|
|
473
|
+
- `SERVER_ERROR_CODES` (463 MissingTcToken, 479 SmaxInvalid)
|
|
474
|
+
- Username fields in Contact, GroupMetadata, GroupParticipant, WAMessageKey
|
|
475
|
+
- `isJidBot`, `isJidMetaAI`, `PSA_WID` exports
|
|
476
|
+
- `onBeforeSessionRefresh` in identity change handler
|
|
477
|
+
- `QueryIdd`, `MexOperations`, `XWAPathsMexUpdates` in Newsletter types
|
|
478
|
+
- 18-file addons layer
|
|
479
|
+
- Message ID prefix: `4NY4W3B`
|
|
480
|
+
- WA version: `2.3000.1037656372`
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
> Based on [WhiskeySockets/Baileys](https://github.com/WhiskeySockets/Baileys) and [InnovatorsSOFT/Baileys](https://github.com/InnovatorsSOFT/Baileys). Not affiliated with WhatsApp or Meta.
|