@badzz88/baileys 8.4.7 → 8.4.9
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/LICENSE +21 -0
- package/README.md +1055 -337
- package/WAProto/WAProto.proto +347 -6
- package/WAProto/fix-import.js +38 -0
- package/WAProto/fix-imports.js +86 -85
- package/WAProto/index.d.ts +4913 -25
- package/WAProto/index.js +14074 -98
- package/package.json +50 -90
- package/src/Defaults/index.js +201 -0
- package/src/Defaults/phonenumber-mcc.json +223 -0
- package/src/Signal/Group/ciphertext-message.js +15 -0
- package/src/Signal/Group/group-session-builder.js +92 -0
- package/src/Signal/Group/group_cipher.js +89 -0
- package/src/Signal/Group/index.js +136 -0
- package/src/Signal/Group/keyhelper.js +73 -0
- package/src/Signal/Group/sender-chain-key.js +32 -0
- package/src/Signal/Group/sender-key-distribution-message.js +66 -0
- package/src/Signal/Group/sender-key-message.js +69 -0
- package/src/Signal/Group/sender-key-name.js +50 -0
- package/src/Signal/Group/sender-key-record.js +44 -0
- package/src/Signal/Group/sender-key-state.js +97 -0
- package/src/Signal/Group/sender-message-key.js +30 -0
- package/src/Signal/libsignal.js +470 -0
- package/src/Signal/lid-mapping.js +262 -0
- package/src/Socket/Client/index.js +30 -0
- package/src/Socket/Client/types.js +13 -0
- package/src/Socket/Client/websocket.js +62 -0
- package/src/Socket/aigroups.js +240 -0
- package/src/Socket/business.js +422 -0
- package/src/Socket/chats.js +2374 -0
- package/src/Socket/communities.js +580 -0
- package/src/Socket/graphql.js +915 -0
- package/src/Socket/groups.js +812 -0
- package/src/Socket/index.js +37 -0
- package/src/Socket/interactive-handler.js +579 -0
- package/src/Socket/interop.js +566 -0
- package/src/Socket/managed-account.js +214 -0
- package/src/Socket/messages-recv.js +3012 -0
- package/src/Socket/messages-send.js +2163 -0
- package/{lib → src}/Socket/mex.js +11 -5
- package/src/Socket/newsletter.js +1057 -0
- package/src/Socket/privacy.js +452 -0
- package/src/Socket/registration.js +434 -0
- package/src/Socket/socket.js +1079 -0
- package/src/Socket/text-router.js +67 -0
- package/src/Socket/username.js +234 -0
- package/src/Store/index.js +36 -0
- package/src/Store/make-cache-manager-store.js +90 -0
- package/src/Store/make-in-memory-store.js +506 -0
- package/src/Store/make-ordered-dictionary.js +81 -0
- package/src/Store/object-repository.js +29 -0
- package/src/Types/Auth.js +38 -0
- package/src/Types/Bussines.js +2 -0
- package/src/Types/Call.js +2 -0
- package/src/Types/Chat.js +4 -0
- package/src/Types/Contact.js +2 -0
- package/src/Types/Events.js +2 -0
- package/src/Types/GroupMetadata.js +2 -0
- package/src/Types/Label.js +27 -0
- package/src/Types/LabelAssociation.js +9 -0
- package/src/Types/Message.js +95 -0
- package/src/Types/Newsletter.js +152 -0
- package/src/Types/Product.js +2 -0
- package/src/Types/Signal.js +2 -0
- package/src/Types/Socket.js +2 -0
- package/src/Types/State.js +70 -0
- package/src/Types/USync.js +2 -0
- package/src/Types/index.js +54 -0
- package/src/Utils/auth-utils.js +306 -0
- package/src/Utils/browser-utils.js +114 -0
- package/src/Utils/business.js +247 -0
- package/src/Utils/chat-utils.js +1272 -0
- package/src/Utils/consumer-application.js +107 -0
- package/src/Utils/crypto.js +125 -0
- package/src/Utils/decode-wa-message.js +808 -0
- package/src/Utils/event-buffer.js +586 -0
- package/src/Utils/generics.js +640 -0
- package/src/Utils/group-history.js +60 -0
- package/src/Utils/history.js +244 -0
- package/src/Utils/identity-change-handler.js +52 -0
- package/src/Utils/index.js +53 -0
- package/src/Utils/jid-display-normalization.js +218 -0
- package/src/Utils/link-preview.js +143 -0
- package/src/Utils/logger.js +9 -0
- package/src/Utils/lt-hash.js +10 -0
- package/src/Utils/make-mutex.js +36 -0
- package/src/Utils/message-composer.js +479 -0
- package/src/Utils/message-inspect.js +400 -0
- package/src/Utils/message-retry-manager.js +231 -0
- package/src/Utils/messages-media.js +943 -0
- package/src/Utils/messages.js +2490 -0
- package/src/Utils/meta-ai-msmsg.js +133 -0
- package/src/Utils/noise-handler.js +194 -0
- package/src/Utils/offline-node-processor.js +42 -0
- package/src/Utils/pre-key-manager.js +107 -0
- package/src/Utils/process-message.js +1047 -0
- package/src/Utils/reporting-utils.js +262 -0
- package/src/Utils/signal.js +192 -0
- package/src/Utils/stanza-ack.js +74 -0
- package/src/Utils/sync-action-utils.js +54 -0
- package/src/Utils/tc-token-utils.js +161 -0
- package/src/Utils/use-multi-file-auth-state.js +121 -0
- package/src/Utils/validate-connection.js +248 -0
- package/src/Utils/voip-rekey.js +22 -0
- package/src/WABinary/constants.js +1304 -0
- package/src/WABinary/decode.js +377 -0
- package/src/WABinary/encode.js +58 -0
- package/src/WABinary/generic-utils.js +148 -0
- package/src/WABinary/index.js +33 -0
- package/src/WABinary/jid-utils.js +374 -0
- package/src/WABinary/types.js +2 -0
- package/src/WAM/BinaryInfo.js +13 -0
- package/src/WAM/constants.js +39486 -0
- package/src/WAM/encode.js +142 -0
- package/src/WAM/index.js +31 -0
- package/src/WAUSync/Protocols/USyncBotProfileProtocol.js +55 -0
- package/src/WAUSync/Protocols/USyncBusinessProtocol.js +100 -0
- package/src/WAUSync/Protocols/USyncContactProtocol.js +60 -0
- package/src/WAUSync/Protocols/USyncDeviceProtocol.js +65 -0
- package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
- package/src/WAUSync/Protocols/USyncFeatureProtocol.js +74 -0
- package/src/WAUSync/Protocols/USyncLIDProtocol.js +31 -0
- package/src/WAUSync/Protocols/USyncPictureProtocol.js +32 -0
- package/src/WAUSync/Protocols/USyncSidelistProtocol.js +29 -0
- package/src/WAUSync/Protocols/USyncStatusProtocol.js +44 -0
- package/src/WAUSync/Protocols/USyncTextStatusProtocol.js +38 -0
- package/src/WAUSync/Protocols/USyncUsernameProtocol.js +28 -0
- package/src/WAUSync/Protocols/index.js +40 -0
- package/src/WAUSync/USyncBackoff.js +31 -0
- package/src/WAUSync/USyncQuery.js +204 -0
- package/src/WAUSync/USyncUser.js +58 -0
- package/src/WAUSync/index.js +32 -0
- package/src/antiban.js +4726 -0
- package/{lib → src}/index.js +48 -15
- package/lib/Defaults/index.js +0 -130
- package/lib/Signal/Group/ciphertext-message.js +0 -12
- package/lib/Signal/Group/group-session-builder.js +0 -30
- package/lib/Signal/Group/group_cipher.js +0 -82
- package/lib/Signal/Group/index.js +0 -12
- package/lib/Signal/Group/keyhelper.js +0 -18
- package/lib/Signal/Group/sender-chain-key.js +0 -26
- package/lib/Signal/Group/sender-key-distribution-message.js +0 -63
- package/lib/Signal/Group/sender-key-message.js +0 -66
- package/lib/Signal/Group/sender-key-name.js +0 -48
- package/lib/Signal/Group/sender-key-record.js +0 -41
- package/lib/Signal/Group/sender-key-state.js +0 -84
- package/lib/Signal/Group/sender-message-key.js +0 -26
- package/lib/Signal/libsignal.js +0 -431
- package/lib/Signal/lid-mapping.js +0 -277
- package/lib/Socket/Client/index.js +0 -3
- package/lib/Socket/Client/types.js +0 -11
- package/lib/Socket/Client/websocket.js +0 -54
- package/lib/Socket/business.js +0 -379
- package/lib/Socket/chats.js +0 -1193
- package/lib/Socket/communities.js +0 -431
- package/lib/Socket/groups.js +0 -374
- package/lib/Socket/index.js +0 -12
- package/lib/Socket/luxu.js +0 -386
- package/lib/Socket/messages-recv.js +0 -1916
- package/lib/Socket/messages-send.js +0 -1453
- package/lib/Socket/newsletter.js +0 -251
- package/lib/Socket/socket.js +0 -980
- package/lib/Socket/username.js +0 -146
- package/lib/Store/index.js +0 -10
- package/lib/Store/keyed-db.js +0 -108
- package/lib/Store/make-cache-manager-store.js +0 -85
- package/lib/Store/make-in-memory-store.js +0 -198
- package/lib/Store/make-ordered-dictionary.js +0 -75
- package/lib/Store/object-repository.js +0 -32
- package/lib/Types/Auth.js +0 -2
- package/lib/Types/Bussines.js +0 -2
- package/lib/Types/Call.js +0 -2
- package/lib/Types/Chat.js +0 -8
- package/lib/Types/Contact.js +0 -2
- package/lib/Types/Events.js +0 -2
- package/lib/Types/GroupMetadata.js +0 -2
- package/lib/Types/Label.js +0 -25
- package/lib/Types/LabelAssociation.js +0 -7
- package/lib/Types/Message.js +0 -11
- package/lib/Types/Mex.js +0 -37
- package/lib/Types/Product.js +0 -2
- package/lib/Types/Signal.js +0 -2
- package/lib/Types/Socket.js +0 -3
- package/lib/Types/State.js +0 -56
- package/lib/Types/USync.js +0 -2
- package/lib/Types/index.js +0 -26
- package/lib/Utils/auth-utils.js +0 -302
- package/lib/Utils/browser-utils.js +0 -49
- package/lib/Utils/business.js +0 -231
- package/lib/Utils/chat-utils.js +0 -872
- package/lib/Utils/companion-reg-client-utils.js +0 -35
- package/lib/Utils/crypto.js +0 -118
- package/lib/Utils/decode-wa-message.js +0 -350
- package/lib/Utils/event-buffer.js +0 -622
- package/lib/Utils/generics.js +0 -403
- package/lib/Utils/history.js +0 -134
- package/lib/Utils/identity-change-handler.js +0 -50
- package/lib/Utils/index.js +0 -23
- package/lib/Utils/link-preview.js +0 -85
- package/lib/Utils/logger.js +0 -3
- package/lib/Utils/lt-hash.js +0 -8
- package/lib/Utils/make-mutex.js +0 -33
- package/lib/Utils/message-composer.js +0 -273
- package/lib/Utils/message-retry-manager.js +0 -265
- package/lib/Utils/messages-media.js +0 -788
- package/lib/Utils/messages.js +0 -1260
- package/lib/Utils/noise-handler.js +0 -201
- package/lib/Utils/offline-node-processor.js +0 -40
- package/lib/Utils/pre-key-manager.js +0 -106
- package/lib/Utils/process-message.js +0 -630
- package/lib/Utils/reporting-utils.js +0 -258
- package/lib/Utils/signal.js +0 -201
- package/lib/Utils/stanza-ack.js +0 -38
- package/lib/Utils/sync-action-utils.js +0 -49
- package/lib/Utils/tc-token-utils.js +0 -163
- package/lib/Utils/use-multi-file-auth-state.js +0 -121
- package/lib/Utils/validate-connection.js +0 -203
- package/lib/WABinary/constants.js +0 -1301
- package/lib/WABinary/decode.js +0 -262
- package/lib/WABinary/encode.js +0 -220
- package/lib/WABinary/generic-utils.js +0 -204
- package/lib/WABinary/index.js +0 -6
- package/lib/WABinary/jid-utils.js +0 -98
- package/lib/WABinary/types.js +0 -2
- package/lib/WAM/BinaryInfo.js +0 -10
- package/lib/WAM/constants.js +0 -22853
- package/lib/WAM/encode.js +0 -150
- package/lib/WAM/index.js +0 -4
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +0 -52
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +0 -54
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +0 -27
- package/lib/WAUSync/Protocols/USyncNewsletterProtocol.js +0 -263
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +0 -38
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +0 -25
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +0 -51
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +0 -29
- package/lib/WAUSync/Protocols/index.js +0 -6
- package/lib/WAUSync/USyncQuery.js +0 -98
- package/lib/WAUSync/USyncUser.js +0 -31
- package/lib/WAUSync/index.js +0 -4
package/README.md
CHANGED
|
@@ -1,393 +1,1111 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @badzz88/baileys
|
|
2
2
|
|
|
3
|
+
A high-performance WhatsApp Web library built on [Baileys](https://github.com/WhiskeySockets/Baileys), with critical paths accelerated via a [Rust WASM bridge](https://github.com/7ucg/whatsapp-rust-bridge).
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img alt="package" src="https://img.shields.io/badge/package-%40badzz88%2Fbaileys-25D366?style=for-the-badge&logo=whatsapp&logoColor=white">
|
|
7
|
+
<img alt="version" src="https://img.shields.io/badge/version-1.1.8-blue?style=for-the-badge">
|
|
8
|
+
</p>
|
|
3
9
|
<p align="center">
|
|
4
|
-
<
|
|
10
|
+
<a href="https://t.me/FoxsSql"><img alt="Telegram" src="https://img.shields.io/badge/Telegram-FoxsSql-26A5E4?style=for-the-badge&logo=telegram&logoColor=white"></a>
|
|
11
|
+
<a href="https://github.com/Badzz88"><img alt="GitHub" src="https://img.shields.io/badge/GitHub-Badzz88-181717?style=for-the-badge&logo=github&logoColor=white"></a>
|
|
5
12
|
</p>
|
|
6
13
|
|
|
7
|
-
|
|
14
|
+
| | |
|
|
15
|
+
|---|---|
|
|
16
|
+
| 📦 **Package** | `@badzz88/baileys` |
|
|
17
|
+
| 🏷️ **Version** | `8.4.9` |
|
|
18
|
+
| 💬 **Telegram** | [t.me/FoxsSql](https://t.me/FoxsSql) |
|
|
19
|
+
| 🐙 **GitHub** | [github.com/Badzz88](https://github.com/Badzz88) |
|
|
20
|
+
|
|
21
|
+
---
|
|
8
22
|
|
|
9
|
-
|
|
23
|
+
## Index
|
|
10
24
|
|
|
11
|
-
|
|
25
|
+
- [What's Different](#whats-different)
|
|
26
|
+
- [Installation](#installation)
|
|
27
|
+
- [Running on Termux / Android](#running-on-termux--android)
|
|
28
|
+
- [Running on Pterodactyl](#running-on-pterodactyl)
|
|
29
|
+
- [Connecting Account](#connecting-account)
|
|
30
|
+
- [QR Code](#qr-code)
|
|
31
|
+
- [Pairing Code](#pairing-code)
|
|
32
|
+
- [Receive Full History](#receive-full-history)
|
|
33
|
+
- [Socket Config Notes](#socket-config-notes)
|
|
34
|
+
- [Saving & Restoring Sessions](#saving--restoring-sessions)
|
|
35
|
+
- [Handling Events](#handling-events)
|
|
36
|
+
- [Text Routing (onText / hears / command)](#text-routing-onText--hears--command)
|
|
37
|
+
- [Anti-Ban System](#anti-ban-system)
|
|
38
|
+
- [RateLimiter](#ratelimiter--throttle-outbound-messages)
|
|
39
|
+
- [WarmUp](#warmup--gradual-daily-limit-increase-for-new-numbers)
|
|
40
|
+
- [HealthMonitor](#healthmonitor--detect-ban-risk)
|
|
41
|
+
- [TimelockGuard](#timelockguard--handle-wa-463-reachout-blocks)
|
|
42
|
+
- [PresenceChoreographer](#presencechoreographer--human-like-typing-simulation)
|
|
43
|
+
- [wrapSocket](#wrapsocket--apply-all-anti-ban-layers-at-once)
|
|
44
|
+
- [Sending Messages](#sending-messages)
|
|
45
|
+
- [Text & Basic](#text--basic)
|
|
46
|
+
- [Buttons & Interactive](#buttons--interactive)
|
|
47
|
+
- [Media](#media)
|
|
48
|
+
- [Meta AI / Rich Responses](#meta-ai--rich-responses)
|
|
49
|
+
- [Status / Stories](#status--stories)
|
|
50
|
+
- [Modifying Messages](#modifying-messages)
|
|
51
|
+
- [Manipulating Media](#manipulating-media)
|
|
52
|
+
- [Groups](#groups)
|
|
53
|
+
- [Privacy](#privacy)
|
|
54
|
+
- [User Queries](#user-queries)
|
|
55
|
+
- [Change Profile](#change-profile)
|
|
56
|
+
- [Chat Modifiers](#chat-modifiers)
|
|
57
|
+
- [Writing Custom Functionality](#writing-custom-functionality)
|
|
58
|
+
- [Extra Utilities](#extra-utilities)
|
|
59
|
+
- [Sticker Maker](#sticker-maker)
|
|
60
|
+
- [Auto-Cache View-Once Media](#auto-cache-view-once-media)
|
|
61
|
+
- [Folder-Based Command Loader](#folder-based-command-loader)
|
|
62
|
+
- [Multi-Account Session Pool](#multi-account-session-pool)
|
|
63
|
+
- [Store Auto-Save, Message Limits & Encryption](#store-auto-save-message-limits--encryption)
|
|
64
|
+
- [Rust WASM Bridge](#rust-wasm-bridge)
|
|
12
65
|
|
|
13
66
|
---
|
|
14
67
|
|
|
15
|
-
|
|
68
|
+
## What's Different
|
|
16
69
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
70
|
+
**Performance — Rust WASM**
|
|
71
|
+
|
|
72
|
+
| Area | Upstream Baileys | This fork |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| Binary decode | JS | Rust WASM |
|
|
75
|
+
| Noise handshake | JS | Rust WASM |
|
|
76
|
+
| AES / HMAC / HKDF | JS (`crypto`) | Rust WASM |
|
|
77
|
+
| Signal protocol | `libsignal-node` | Rust WASM |
|
|
78
|
+
|
|
79
|
+
**Extra Features**
|
|
80
|
+
|
|
81
|
+
| Feature | Notes |
|
|
82
|
+
|---|---|
|
|
83
|
+
| Meta AI / msmsg decrypt | Full `messageSecret`-encrypted AI message decryption |
|
|
84
|
+
| Meta AI message handling | Receive and process Meta AI bot responses |
|
|
85
|
+
| Rich AI composer | Send tables, lists, code blocks, LaTeX via Meta AI format |
|
|
86
|
+
| Interactive buttons | List, reply, template, cards, product list, PIX/PAY |
|
|
87
|
+
| Interop (FB/IG) | Near-parity with mobile & web for cross-platform JIDs |
|
|
88
|
+
| Anti-ban measures | Connection fingerprinting aligned with official clients |
|
|
89
|
+
| Album messages | Send multiple media as an album |
|
|
90
|
+
| Sticker packs | Sticker pack message support |
|
|
91
|
+
| Newsletter messages | Follower invite messages |
|
|
92
|
+
| Top-level call signalling | Emits `call` for both `<call>`-wrapped and top-level `<offer>`/`<terminate>` stanzas (+ acks them) |
|
|
25
93
|
|
|
26
94
|
---
|
|
27
95
|
|
|
28
|
-
##
|
|
96
|
+
## Installation
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npm install npm:@badzz88/baileys
|
|
100
|
+
# or
|
|
101
|
+
yarn add npm:@badzz88/baileys
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Requirements:** Node.js ≥ 20
|
|
105
|
+
|
|
106
|
+
**Optional peer dependencies:**
|
|
107
|
+
|
|
108
|
+
| Package | Purpose |
|
|
109
|
+
|---|---|
|
|
110
|
+
| `sharp` | Image processing / thumbnails |
|
|
111
|
+
| `jimp` | Fallback image processing |
|
|
112
|
+
| `audio-decode` | Voice message metadata |
|
|
113
|
+
| `link-preview-js` | Link preview generation |
|
|
114
|
+
|
|
115
|
+
### Running on Termux / Android
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
pkg install nodejs-lts
|
|
119
|
+
npm install npm:@badzz88/baileys
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`whatsapp-rust-bridge` compiles to **WASM**, not a platform-specific native binary, and
|
|
123
|
+
ships a prebuilt `.wasm` artifact — so a normal `npm install` typically works on Termux
|
|
124
|
+
without installing a Rust toolchain at all (WASM bytecode runs the same on ARM, x86,
|
|
125
|
+
etc., unlike a native N-API `.node` addon). It's still marked as an **optional**
|
|
126
|
+
dependency as a safety net: on the rare setup where the prebuilt doesn't load (very old
|
|
127
|
+
CPUs lacking WASM SIMD, an unusual libc, etc.), `npm install` will **not** fail, and the
|
|
128
|
+
package still loads and works:
|
|
129
|
+
|
|
130
|
+
- MD5, SHA-256, HMAC-SHA256, AES-GCM/CTR/CBC, and HKDF transparently fall back to
|
|
131
|
+
Node's built-in `crypto` module — no functionality lost, no native module needed.
|
|
132
|
+
- WABinary node encoding/decoding fall back to a pure-JS implementation.
|
|
133
|
+
- **X25519 key exchange and XEdDSA signing** (used for identity/pre-key generation
|
|
134
|
+
and signing) also fall back to pure JS — X25519 itself via Node's own built-in
|
|
135
|
+
`crypto` (native, audited), and XEdDSA signing via a small hand-written
|
|
136
|
+
Edwards-curve implementation validated against the official RFC 8032 Ed25519 test
|
|
137
|
+
vectors and hundreds of randomized Montgomery↔Edwards interop checks (see
|
|
138
|
+
`Utils/curve25519-js.js`).
|
|
139
|
+
- **The Noise handshake and the Signal Double Ratchet session** genuinely need the
|
|
140
|
+
module (hand-rolling a full protocol session state machine from scratch is a much
|
|
141
|
+
larger correctness/security risk than a single curve operation, so there's no JS
|
|
142
|
+
fallback for these). Without the native module, connecting a WhatsApp session will
|
|
143
|
+
throw a clear error rather than silently failing — everything else (stickers, the
|
|
144
|
+
in-memory store, USync helpers, the command loader, session pool, key generation,
|
|
145
|
+
etc.) keeps working.
|
|
146
|
+
|
|
147
|
+
If you ever do need to build it from source (e.g. `WHATSAPP_RUST_BRIDGE_SKIP_PREBUILT=1`):
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pkg install rust binutils
|
|
151
|
+
npm install npm:@badzz88/baileys
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
> **Note:** some published versions of the bridge ship a `package.json` whose
|
|
155
|
+
> `"exports"` map is missing a `.` entry, which makes a plain `require()` throw
|
|
156
|
+
> `ERR_PACKAGE_PATH_NOT_EXPORTED` even though the module itself works fine. This
|
|
157
|
+
> package works around that automatically (it locates the installed module's real
|
|
158
|
+
> entry file and requires it directly) — no action needed on your end.
|
|
159
|
+
|
|
160
|
+
Other Termux notes:
|
|
161
|
+
- `sharp` needs `pkg install libvips` to build; if that's not available, install
|
|
162
|
+
`jimp` instead (`npm install jimp`) — it's a pure-JS fallback used automatically.
|
|
163
|
+
- Animated stickers (`videoToWebpSticker`) need `ffmpeg` on PATH: `pkg install ffmpeg`.
|
|
164
|
+
|
|
165
|
+
### Running on Pterodactyl
|
|
166
|
+
|
|
167
|
+
Works fine on a standard Node.js egg — Pterodactyl containers are normal x86_64 Linux
|
|
168
|
+
(Debian/Alpine-based) Docker images, which is the best-supported target for both the
|
|
169
|
+
prebuilt WASM bridge and `sharp`'s prebuilt binaries. Checklist:
|
|
29
170
|
|
|
30
|
-
|
|
171
|
+
- Pick a **Node.js ≥ 20** egg/variable (the package's `engines` field enforces this).
|
|
172
|
+
- If you want animated stickers, make sure `ffmpeg` is available in the container —
|
|
173
|
+
either an egg/image that already bundles it, or add an install script step
|
|
174
|
+
(`apt-get install -y ffmpeg` on Debian-based yolks). Static stickers only need
|
|
175
|
+
`sharp`, which installs normally.
|
|
176
|
+
- Persistent storage: point `useMultiFileAuthState`/the store's `writeToFile` at a path
|
|
177
|
+
under the server's data volume so sessions survive container restarts/reinstalls.
|
|
178
|
+
- If the egg's image is Alpine/musl-based rather than Debian/glibc-based, the
|
|
179
|
+
prebuilt WASM/`sharp` binaries are less likely to match — everything still installs
|
|
180
|
+
(thanks to the fallbacks above), but a live connection needs the native bridge to
|
|
181
|
+
work, so prefer a glibc-based Node image if you have the choice.
|
|
31
182
|
|
|
32
183
|
---
|
|
33
184
|
|
|
34
|
-
##
|
|
185
|
+
## Connecting Account
|
|
186
|
+
|
|
187
|
+
### QR Code
|
|
188
|
+
|
|
189
|
+
```js
|
|
190
|
+
const { makeWASocket, useMultiFileAuthState, DisconnectReason } = require('@badzz88/baileys')
|
|
191
|
+
const { Boom } = require('@hapi/boom')
|
|
192
|
+
|
|
193
|
+
const { state, saveCreds } = await useMultiFileAuthState('./auth')
|
|
194
|
+
|
|
195
|
+
const sock = makeWASocket({ auth: state, printQRInTerminal: true })
|
|
196
|
+
|
|
197
|
+
sock.ev.on('creds.update', saveCreds)
|
|
198
|
+
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
|
|
199
|
+
if (connection === 'close') {
|
|
200
|
+
const shouldReconnect = new Boom(lastDisconnect?.error)?.output?.statusCode !== DisconnectReason.loggedOut
|
|
201
|
+
if (shouldReconnect) connect()
|
|
202
|
+
}
|
|
203
|
+
})
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Pairing Code
|
|
35
207
|
|
|
36
|
-
|
|
37
|
-
|
|
208
|
+
```js
|
|
209
|
+
const sock = makeWASocket({ auth: state, printQRInTerminal: false })
|
|
38
210
|
|
|
39
|
-
|
|
40
|
-
await sock.
|
|
211
|
+
if (!state.creds.registered) {
|
|
212
|
+
const code = await sock.requestPairingCode('49123456789') // phone number without +
|
|
213
|
+
console.log('Pairing code:', code)
|
|
214
|
+
}
|
|
41
215
|
```
|
|
42
216
|
|
|
43
|
-
###
|
|
44
|
-
You can see the status of blocked numbers here
|
|
217
|
+
### Receive Full History
|
|
45
218
|
|
|
46
|
-
```
|
|
47
|
-
|
|
219
|
+
```js
|
|
220
|
+
const sock = makeWASocket({
|
|
221
|
+
auth: state,
|
|
222
|
+
syncFullHistory: true
|
|
223
|
+
})
|
|
48
224
|
```
|
|
49
225
|
|
|
50
226
|
---
|
|
51
227
|
|
|
52
|
-
##
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
```javascript
|
|
69
|
-
await sock.sendMessage(target, {
|
|
70
|
-
albumMessage: [
|
|
71
|
-
{ image: cihuy, caption: "#BADZZNE" },
|
|
72
|
-
{ image: { url: "URL IMAGE" }, caption: "#BADZZNE" }
|
|
73
|
-
]
|
|
74
|
-
}, { quoted: m });
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Event Message
|
|
78
|
-
Create and send WhatsApp event invitations:
|
|
79
|
-
|
|
80
|
-
```javascript
|
|
81
|
-
await sock.sendMessage(target, {
|
|
82
|
-
eventMessage: {
|
|
83
|
-
isCanceled: false,
|
|
84
|
-
name: "#BADZZNE",
|
|
85
|
-
description: "#BADZZNE",
|
|
86
|
-
location: {
|
|
87
|
-
degreesLatitude: 0,
|
|
88
|
-
degreesLongitude: 0,
|
|
89
|
-
name: "#BADZZNE"
|
|
90
|
-
},
|
|
91
|
-
joinLink: "https://call.whatsapp.com/video/badzzne2",
|
|
92
|
-
startTime: "1763019000",
|
|
93
|
-
endTime: "1763026200",
|
|
94
|
-
extraGuestsAllowed: false
|
|
95
|
-
}
|
|
96
|
-
}, { quoted: m });
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Poll Result Message
|
|
100
|
-
Display poll results with vote counts:
|
|
101
|
-
|
|
102
|
-
```javascript
|
|
103
|
-
await sock.sendMessage(target, {
|
|
104
|
-
pollResultMessage: {
|
|
105
|
-
name: "#BADZZNE",
|
|
106
|
-
pollVotes: [
|
|
107
|
-
{
|
|
108
|
-
optionName: "#BADZZNE",
|
|
109
|
-
optionVoteCount: "112233"
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
optionName: "#BADZZNE",
|
|
113
|
-
optionVoteCount: "1"
|
|
114
|
-
}
|
|
115
|
-
]
|
|
116
|
-
}
|
|
117
|
-
}, { quoted: m });
|
|
228
|
+
## Socket Config Notes
|
|
229
|
+
|
|
230
|
+
```js
|
|
231
|
+
const sock = makeWASocket({
|
|
232
|
+
auth: state,
|
|
233
|
+
|
|
234
|
+
// Cache group metadata to reduce WA queries (recommended)
|
|
235
|
+
cachedGroupMetadata: async (jid) => groupCache.get(jid),
|
|
236
|
+
|
|
237
|
+
// Improve retry system and enable poll vote decryption
|
|
238
|
+
getMessage: async (key) => store.getMsg(key),
|
|
239
|
+
|
|
240
|
+
// Suppress notifications on the phone while connected
|
|
241
|
+
markOnlineOnConnect: false,
|
|
242
|
+
})
|
|
118
243
|
```
|
|
119
244
|
|
|
120
|
-
|
|
121
|
-
Send basic interactive messages with copy button functionality:
|
|
245
|
+
---
|
|
122
246
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
247
|
+
## Saving & Restoring Sessions
|
|
248
|
+
|
|
249
|
+
```js
|
|
250
|
+
const { useMultiFileAuthState } = require('@badzz88/baileys')
|
|
251
|
+
|
|
252
|
+
const { state, saveCreds } = await useMultiFileAuthState('./auth')
|
|
253
|
+
// Pass state to makeWASocket, call saveCreds on creds.update
|
|
254
|
+
sock.ev.on('creds.update', saveCreds)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Handling Events
|
|
260
|
+
|
|
261
|
+
### Messages
|
|
262
|
+
|
|
263
|
+
```js
|
|
264
|
+
// New or received messages
|
|
265
|
+
sock.ev.on('messages.upsert', ({ messages, type }) => { })
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
> **Prefer routing by text pattern instead of parsing `messages.upsert` by hand?**
|
|
269
|
+
> Every socket also comes with Telegraf/node-telegram-bot-api-style helpers — see
|
|
270
|
+
> [`onText` / `hears` / `command`](#text-routing-onText--hears--command) below.
|
|
271
|
+
|
|
272
|
+
```js
|
|
273
|
+
// Status updates (read receipts, delivery, edits, reactions)
|
|
274
|
+
sock.ev.on('messages.update', updates => { })
|
|
275
|
+
|
|
276
|
+
// Message deleted / cleared
|
|
277
|
+
sock.ev.on('messages.delete', ({ keys }) => { })
|
|
278
|
+
|
|
279
|
+
// Media decryption key update
|
|
280
|
+
sock.ev.on('messages.media-update', updates => { })
|
|
281
|
+
|
|
282
|
+
// Reaction on a message
|
|
283
|
+
sock.ev.on('messages.reaction', reactions => { })
|
|
284
|
+
|
|
285
|
+
// Comment on a message
|
|
286
|
+
sock.ev.on('message.comment', ({ message, comment }) => { })
|
|
287
|
+
|
|
288
|
+
// Message quarantined by WA
|
|
289
|
+
sock.ev.on('message.quarantined', ({ message }) => { })
|
|
290
|
+
|
|
291
|
+
// Poll — new option added
|
|
292
|
+
sock.ev.on('poll.add-option', ({ key, senderTimestampMs }) => { })
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Text Routing (`onText` / `hears` / `command`)
|
|
296
|
+
|
|
297
|
+
Every socket returned by `makeWASocket()` already has these — no wrapping or setup
|
|
298
|
+
needed. They're built on top of `messages.upsert` internally (one shared listener
|
|
299
|
+
regardless of how many routes you add), so you don't have to parse
|
|
300
|
+
`msg.message.conversation` / `extendedTextMessage.text` / captions by hand.
|
|
301
|
+
|
|
302
|
+
```js
|
|
303
|
+
// RegExp — handler gets (msg, match), match = pattern.exec(text)
|
|
304
|
+
sock.onText(/^ping$/i, (msg, match) => {
|
|
305
|
+
sock.sendMessage(msg.key.remoteJid, { text: 'pong' }, { quoted: msg })
|
|
306
|
+
})
|
|
307
|
+
|
|
308
|
+
// Exact string match
|
|
309
|
+
sock.hears('menu', (msg) => {
|
|
310
|
+
sock.sendMessage(msg.key.remoteJid, { text: '1. Foo\n2. Bar' })
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
// Slash commands — matches /start, /start@BotName, /start extra args
|
|
314
|
+
// match[1] is whatever comes after the command (or undefined)
|
|
315
|
+
sock.command('start', (msg, match) => {
|
|
316
|
+
sock.sendMessage(msg.key.remoteJid, { text: `Started with: ${match[1] ?? '(no args)'}` })
|
|
317
|
+
})
|
|
318
|
+
|
|
319
|
+
// Multiple aliases for one command
|
|
320
|
+
sock.command(['help', 'h'], (msg) => {
|
|
321
|
+
sock.sendMessage(msg.key.remoteJid, { text: 'Available commands: ...' })
|
|
322
|
+
})
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
All three (`onText`, `hears`, `command`) return an unsubscribe function:
|
|
326
|
+
|
|
327
|
+
```js
|
|
328
|
+
const stop = sock.onText(/^bye$/i, (msg) => { /* ... */ })
|
|
329
|
+
stop() // removes just this route
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Chats & Contacts
|
|
333
|
+
|
|
334
|
+
```js
|
|
335
|
+
sock.ev.on('chats.upsert', chats => { })
|
|
336
|
+
sock.ev.on('chats.update', chats => { })
|
|
337
|
+
sock.ev.on('chats.delete', ids => { })
|
|
338
|
+
sock.ev.on('chats.lock', ({ id, locked }) => { })
|
|
339
|
+
|
|
340
|
+
sock.ev.on('contacts.upsert', contacts => { })
|
|
341
|
+
sock.ev.on('contacts.update', contacts => { })
|
|
342
|
+
|
|
343
|
+
// Blocklist changed
|
|
344
|
+
sock.ev.on('blocklist.update', ({ blocklist, type }) => { })
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Groups
|
|
348
|
+
|
|
349
|
+
```js
|
|
350
|
+
sock.ev.on('groups.upsert', groups => { })
|
|
351
|
+
sock.ev.on('groups.update', updates => { })
|
|
352
|
+
sock.ev.on('group-participants.update', ({ id, participants, action }) => { })
|
|
353
|
+
|
|
354
|
+
// Someone requested to join
|
|
355
|
+
sock.ev.on('group.join-request', ({ id, participant, action }) => { })
|
|
356
|
+
|
|
357
|
+
// Member tag / mention update
|
|
358
|
+
sock.ev.on('group.member-tag.update', ({ id, participant }) => { })
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Newsletters
|
|
362
|
+
|
|
363
|
+
```js
|
|
364
|
+
sock.ev.on('newsletter-settings.update', update => { })
|
|
365
|
+
sock.ev.on('newsletter-participants.update', update => { })
|
|
366
|
+
sock.ev.on('newsletter.reaction', update => { })
|
|
367
|
+
sock.ev.on('newsletter.view', update => { })
|
|
368
|
+
sock.ev.on('newsletter.live-update', update => { })
|
|
369
|
+
sock.ev.on('newsletter.pin', update => { })
|
|
370
|
+
sock.ev.on('newsletter.invite', update => { })
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Connection & Auth
|
|
374
|
+
|
|
375
|
+
```js
|
|
376
|
+
sock.ev.on('connection.update', ({ connection, qr, lastDisconnect, isOnline, reachoutTimeLock }) => { })
|
|
377
|
+
sock.ev.on('creds.update', saveCreds)
|
|
378
|
+
|
|
379
|
+
// Security alert (e.g. linked device removed)
|
|
380
|
+
sock.ev.on('security.alert', data => { })
|
|
381
|
+
|
|
382
|
+
// Identity key change for a contact
|
|
383
|
+
sock.ev.on('identity.update', ({ jid }) => { })
|
|
384
|
+
|
|
385
|
+
// Server config received
|
|
386
|
+
sock.ev.on('server.config', config => { })
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Calls
|
|
390
|
+
|
|
391
|
+
```js
|
|
392
|
+
// `call` fires for both <call>-wrapped and top-level (<offer>/<terminate>) signalling
|
|
393
|
+
sock.ev.on('call', calls => { })
|
|
394
|
+
sock.ev.on('call.scheduled', ({ call }) => { })
|
|
395
|
+
sock.ev.on('call.schedule-cancelled', ({ call }) => { })
|
|
396
|
+
|
|
397
|
+
// Call links — create + toggle the link's waiting room
|
|
398
|
+
const token = await sock.createCallLink('audio')
|
|
399
|
+
await sock.toggleCallLinkWaitingRoom(token, true, 'audio')
|
|
400
|
+
|
|
401
|
+
// WA-Web coexistence (FB/IG) & business privacy-sync pushes
|
|
402
|
+
sock.ev.on('coexistence.update', u => { }) // { kind: 'onboarding' | 'offboarding', status?, productSurface? }
|
|
403
|
+
sock.ev.on('business.privacy-settings-sync', s => { })
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Labels
|
|
407
|
+
|
|
408
|
+
```js
|
|
409
|
+
sock.ev.on('labels.edit', ({ label }) => { })
|
|
410
|
+
sock.ev.on('labels.association', ({ association, type }) => { })
|
|
411
|
+
sock.ev.on('labels.reorder', ({ labelIds }) => { })
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Presence & Devices
|
|
415
|
+
|
|
416
|
+
```js
|
|
417
|
+
sock.ev.on('presence.update', ({ id, presences }) => { })
|
|
418
|
+
sock.ev.on('devices.update', ({ id, devices, isSelf }) => { })
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### Bot / Meta AI
|
|
422
|
+
|
|
423
|
+
```js
|
|
424
|
+
sock.ev.on('bot.feedback', ({ message }) => { })
|
|
425
|
+
sock.ev.on('bot.stop-generation', ({ message }) => { })
|
|
426
|
+
sock.ev.on('bot.welcome-request', ({ message }) => { })
|
|
427
|
+
sock.ev.on('bot.psi-metadata', ({ message }) => { })
|
|
428
|
+
sock.ev.on('bot.query-fanout', ({ message }) => { })
|
|
429
|
+
sock.ev.on('bot.media-collection', ({ message }) => { })
|
|
430
|
+
sock.ev.on('bot.memu-onboarding', ({ message }) => { })
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Sync & Settings
|
|
434
|
+
|
|
435
|
+
```js
|
|
436
|
+
sock.ev.on('messaging-history.set', ({ chats, contacts, messages, isLatest }) => { })
|
|
437
|
+
sock.ev.on('messaging-history.status', ({ progress, hasMore }) => { })
|
|
438
|
+
sock.ev.on('settings.update', ({ setting, value }) => { })
|
|
439
|
+
sock.ev.on('lid-mapping.update', ({ lid, pn }) => { })
|
|
440
|
+
sock.ev.on('status.psa', ({ message }) => { })
|
|
441
|
+
sock.ev.on('status.mention', ({ message }) => { })
|
|
442
|
+
sock.ev.on('media.notify', ({ message }) => { })
|
|
443
|
+
sock.ev.on('reminder.update', ({ message }) => { })
|
|
444
|
+
sock.ev.on('payment.split', ({ message }) => { })
|
|
445
|
+
sock.ev.on('payment.reminder', ({ message }) => { })
|
|
446
|
+
sock.ev.on('cloud.thread.control', ({ message }) => { })
|
|
447
|
+
sock.ev.on('galaxy.flow.completed', ({ message }) => { })
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Decrypt Poll Votes
|
|
451
|
+
|
|
452
|
+
```js
|
|
453
|
+
const { getAggregateVotesInPollMessage } = require('@badzz88/baileys')
|
|
454
|
+
|
|
455
|
+
sock.ev.on('messages.update', async updates => {
|
|
456
|
+
for (const { key, update } of updates) {
|
|
457
|
+
if (update.pollUpdates) {
|
|
458
|
+
const pollCreation = await getMessage(key)
|
|
459
|
+
if (pollCreation) {
|
|
460
|
+
const votes = getAggregateVotesInPollMessage({ message: pollCreation, pollUpdates: update.pollUpdates })
|
|
461
|
+
console.log(votes)
|
|
269
462
|
}
|
|
270
|
-
|
|
463
|
+
}
|
|
271
464
|
}
|
|
272
|
-
}
|
|
465
|
+
})
|
|
273
466
|
```
|
|
274
467
|
|
|
275
|
-
|
|
276
|
-
Send interactive messages with document from buffer (file system) - **Note: Documents only support buffer**:
|
|
468
|
+
---
|
|
277
469
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
470
|
+
## Anti-Ban System
|
|
471
|
+
|
|
472
|
+
Import from `@badzz88/baileys/src/antiban.js`:
|
|
473
|
+
|
|
474
|
+
```js
|
|
475
|
+
const {
|
|
476
|
+
AntiBan, RateLimiter, WarmUp, HealthMonitor,
|
|
477
|
+
TimelockGuard, ReplyRatioGuard, ContactGraphWarmer,
|
|
478
|
+
PresenceChoreographer, PostReconnectThrottle,
|
|
479
|
+
RetryReasonTracker, LidResolver, JidCanonicalizer,
|
|
480
|
+
MessageQueue, Scheduler, wrapSocket
|
|
481
|
+
} = require('@badzz88/baileys/src/antiban')
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### RateLimiter — throttle outbound messages
|
|
485
|
+
|
|
486
|
+
```js
|
|
487
|
+
const limiter = new RateLimiter({
|
|
488
|
+
maxPerMinute: 8,
|
|
489
|
+
maxPerHour: 200,
|
|
490
|
+
maxPerDay: 1500,
|
|
491
|
+
minDelayMs: 1500,
|
|
492
|
+
maxDelayMs: 5000,
|
|
493
|
+
newChatDelayMs: 3000
|
|
494
|
+
})
|
|
495
|
+
|
|
496
|
+
const delay = await limiter.getDelay(jid, text)
|
|
497
|
+
if (delay === -1) return // blocked
|
|
498
|
+
if (delay > 0) await sleep(delay)
|
|
499
|
+
|
|
500
|
+
await sock.sendMessage(jid, { text })
|
|
501
|
+
limiter.record(jid, text)
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### WarmUp — gradual daily limit increase for new numbers
|
|
505
|
+
|
|
506
|
+
```js
|
|
507
|
+
const warmup = new WarmUp({ warmUpDays: 7, day1Limit: 20, growthFactor: 1.8 })
|
|
508
|
+
|
|
509
|
+
if (!warmup.canSend()) return
|
|
510
|
+
await sock.sendMessage(jid, { text })
|
|
511
|
+
warmup.record()
|
|
512
|
+
|
|
513
|
+
console.log(warmup.getStatus())
|
|
514
|
+
// { phase: 'warming', day: 2, todayLimit: 36, todaySent: 12, progress: 28 }
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### HealthMonitor — detect ban risk
|
|
518
|
+
|
|
519
|
+
```js
|
|
520
|
+
const health = new HealthMonitor({ autoPauseAt: 'high' })
|
|
521
|
+
|
|
522
|
+
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
|
|
523
|
+
if (connection === 'close') health.recordDisconnect(lastDisconnect?.error)
|
|
524
|
+
if (connection === 'open') health.recordReconnect()
|
|
525
|
+
})
|
|
526
|
+
|
|
527
|
+
const status = health.getStatus()
|
|
528
|
+
// { risk: 'low'|'medium'|'high'|'critical', score, recommendation, stats }
|
|
529
|
+
|
|
530
|
+
if (health.isPaused()) return // auto-pauses at configured risk level
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
### TimelockGuard — handle WA 463 reachout blocks
|
|
534
|
+
|
|
535
|
+
```js
|
|
536
|
+
const guard = new TimelockGuard()
|
|
537
|
+
|
|
538
|
+
// Feed connection.update events
|
|
539
|
+
sock.ev.on('connection.update', ({ reachoutTimeLock }) => {
|
|
540
|
+
if (reachoutTimeLock) guard.onTimelockUpdate(reachoutTimeLock)
|
|
541
|
+
})
|
|
542
|
+
|
|
543
|
+
// Check before sending to new contacts
|
|
544
|
+
const { allowed, reason } = guard.canSend(jid)
|
|
545
|
+
if (!allowed) return console.log(reason)
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### PresenceChoreographer — human-like typing simulation
|
|
549
|
+
|
|
550
|
+
```js
|
|
551
|
+
const choreo = new PresenceChoreographer({
|
|
552
|
+
enabled: true,
|
|
553
|
+
typingWPM: 45,
|
|
554
|
+
enableCircadianRhythm: true,
|
|
555
|
+
timezone: 'Europe/Berlin'
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
const plan = choreo.computeTypingPlan(text.length)
|
|
559
|
+
await choreo.executeTypingPlan(sock, jid, plan)
|
|
560
|
+
await sock.sendMessage(jid, { text })
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### wrapSocket — apply all anti-ban layers at once
|
|
564
|
+
|
|
565
|
+
```js
|
|
566
|
+
const { wrapSocket, resolveConfig, PRESETS } = require('@badzz88/baileys/src/antiban')
|
|
567
|
+
|
|
568
|
+
const wrappedSock = wrapSocket(sock, resolveConfig(PRESETS.SAFE))
|
|
569
|
+
// All outbound sendMessage calls are now automatically rate-limited,
|
|
570
|
+
// presence-simulated, and timelock-aware.
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
## Sending Messages
|
|
576
|
+
|
|
577
|
+
### Text & Basic
|
|
578
|
+
|
|
579
|
+
```js
|
|
580
|
+
// Text
|
|
581
|
+
await sock.sendMessage(jid, { text: 'Hello!' })
|
|
582
|
+
|
|
583
|
+
// Quote
|
|
584
|
+
await sock.sendMessage(jid, { text: 'Reply' }, { quoted: msg })
|
|
585
|
+
|
|
586
|
+
// Mention
|
|
587
|
+
await sock.sendMessage(jid, { text: '@49123456789', mentions: ['49123456789@s.whatsapp.net'] })
|
|
588
|
+
|
|
589
|
+
// Forward
|
|
590
|
+
await sock.sendMessage(jid, { forward: msg })
|
|
591
|
+
|
|
592
|
+
// Location
|
|
593
|
+
await sock.sendMessage(jid, { location: { degreesLatitude: 52.5, degreesLongitude: 13.4 } })
|
|
594
|
+
|
|
595
|
+
// Live Location
|
|
596
|
+
await sock.sendMessage(jid, {
|
|
597
|
+
liveLocation: { degreesLatitude: 52.5, degreesLongitude: 13.4 },
|
|
598
|
+
accuracyInMeters: 10,
|
|
599
|
+
speedInMps: 0,
|
|
600
|
+
degreesClockwisefromMagneticNorth: 0,
|
|
601
|
+
caption: 'Live',
|
|
602
|
+
sequenceNumber: 1
|
|
603
|
+
})
|
|
604
|
+
|
|
605
|
+
// Contact
|
|
606
|
+
await sock.sendMessage(jid, { contacts: { displayName: 'Name', contacts: [{ vcard: '...' }] } })
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
### Rich Response (table / code / latex / images)
|
|
610
|
+
|
|
611
|
+
Renders as WhatsApp's native AI-assistant-style rich card (the same UI Meta AI uses
|
|
612
|
+
for search results). `table` accepts either a plain 2D array (first row = header) or
|
|
613
|
+
`{ rows: [...] }`.
|
|
614
|
+
|
|
615
|
+
```js
|
|
616
|
+
await sock.sendMessage(jid, {
|
|
617
|
+
richResponse: {
|
|
618
|
+
text: 'Badzz88',
|
|
619
|
+
table: [
|
|
620
|
+
['header1', 'header2'],
|
|
621
|
+
['X1', 'X2']
|
|
622
|
+
],
|
|
623
|
+
// code: 'console.log("hi")', language: 'javascript',
|
|
624
|
+
// latex: 'x^2 + y^2 = z^2',
|
|
625
|
+
// imageUrl: 'https://...', // or imageUrls: ['https://...', ...]
|
|
626
|
+
// map: { latitude: 52.5, longitude: 13.4, zoom: 14, title: 'Berlin' }
|
|
313
627
|
}
|
|
314
|
-
}, {
|
|
628
|
+
}, { /* opts */ })
|
|
315
629
|
```
|
|
316
630
|
|
|
317
|
-
|
|
318
|
-
|
|
631
|
+
```js
|
|
632
|
+
// Reaction
|
|
633
|
+
await sock.sendMessage(jid, { react: { text: '👍', key: msg.key } })
|
|
319
634
|
|
|
320
|
-
|
|
321
|
-
await sock.sendMessage(
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
635
|
+
// Pin
|
|
636
|
+
await sock.sendMessage(jid, { pin: { type: 1, time: 86400, key: msg.key } })
|
|
637
|
+
|
|
638
|
+
// Poll
|
|
639
|
+
await sock.sendMessage(jid, {
|
|
640
|
+
poll: { name: 'Vote?', values: ['Yes', 'No'], selectableCount: 1 }
|
|
641
|
+
})
|
|
642
|
+
|
|
643
|
+
// Call
|
|
644
|
+
await sock.sendMessage(jid, { call: { callId: '...', callType: 'audio' } })
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
### Buttons & Interactive
|
|
648
|
+
|
|
649
|
+
```js
|
|
650
|
+
// Reply buttons
|
|
651
|
+
await sock.sendMessage(jid, {
|
|
652
|
+
buttonsMessage: {
|
|
653
|
+
text: 'Choose:',
|
|
330
654
|
buttons: [
|
|
331
|
-
{
|
|
332
|
-
|
|
333
|
-
buttonParamsJson: JSON.stringify({
|
|
334
|
-
display_text: "Telegram",
|
|
335
|
-
url: "https://t.me/badzzne2",
|
|
336
|
-
merchant_url: "https://t.me/badzzne2"
|
|
337
|
-
})
|
|
338
|
-
}
|
|
655
|
+
{ buttonId: '1', buttonText: { displayText: 'Option A' } },
|
|
656
|
+
{ buttonId: '2', buttonText: { displayText: 'Option B' } }
|
|
339
657
|
]
|
|
340
658
|
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
659
|
+
})
|
|
660
|
+
|
|
661
|
+
// List message
|
|
662
|
+
await sock.sendMessage(jid, {
|
|
663
|
+
listMessage: {
|
|
664
|
+
title: 'Menu',
|
|
665
|
+
description: 'Pick one',
|
|
666
|
+
buttonText: 'Open',
|
|
667
|
+
listType: 1,
|
|
668
|
+
sections: [{
|
|
669
|
+
title: 'Section',
|
|
670
|
+
rows: [{ title: 'Item 1', rowId: 'item1' }]
|
|
671
|
+
}]
|
|
672
|
+
}
|
|
673
|
+
})
|
|
674
|
+
|
|
675
|
+
// Template buttons
|
|
676
|
+
await sock.sendMessage(jid, {
|
|
677
|
+
templateMessage: {
|
|
678
|
+
hydratedTemplate: {
|
|
679
|
+
hydratedContentText: 'Hello',
|
|
680
|
+
hydratedButtons: [
|
|
681
|
+
{ quickReplyButton: { displayText: 'Yes', id: 'yes' } },
|
|
682
|
+
{ urlButton: { displayText: 'Visit', url: 'https://example.com' } }
|
|
683
|
+
]
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
})
|
|
687
|
+
|
|
688
|
+
// Interactive message
|
|
689
|
+
await sock.sendMessage(jid, {
|
|
690
|
+
interactiveMessage: {
|
|
691
|
+
body: { text: 'Choose' },
|
|
692
|
+
footer: { text: 'Footer' },
|
|
693
|
+
nativeFlowMessage: {
|
|
694
|
+
buttons: [{ name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: 'Yes', id: 'yes' }) }]
|
|
366
695
|
}
|
|
367
696
|
}
|
|
368
|
-
}
|
|
697
|
+
})
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
### Media
|
|
701
|
+
|
|
702
|
+
```js
|
|
703
|
+
// Image
|
|
704
|
+
await sock.sendMessage(jid, { image: { url: './image.jpg' }, caption: 'Caption' })
|
|
705
|
+
|
|
706
|
+
// Video
|
|
707
|
+
await sock.sendMessage(jid, { video: { url: './video.mp4' }, caption: 'Video' })
|
|
708
|
+
|
|
709
|
+
// Audio
|
|
710
|
+
await sock.sendMessage(jid, { audio: { url: './audio.mp3' }, mimetype: 'audio/mp4' })
|
|
711
|
+
|
|
712
|
+
// Voice note (PTT)
|
|
713
|
+
await sock.sendMessage(jid, { audio: { url: './audio.ogg' }, mimetype: 'audio/ogg; codecs=opus', ptt: true })
|
|
714
|
+
|
|
715
|
+
// GIF
|
|
716
|
+
await sock.sendMessage(jid, { video: { url: './anim.mp4' }, gifPlayback: true })
|
|
717
|
+
|
|
718
|
+
// PTV (video note)
|
|
719
|
+
await sock.sendMessage(jid, { video: { url: './clip.mp4' }, ptv: true })
|
|
720
|
+
|
|
721
|
+
// View once
|
|
722
|
+
await sock.sendMessage(jid, { image: { url: './secret.jpg' }, viewOnce: true })
|
|
723
|
+
|
|
724
|
+
// Album
|
|
725
|
+
await sock.sendAlbumMessage(jid, [
|
|
726
|
+
{ image: { url: './1.jpg' } },
|
|
727
|
+
{ image: { url: './2.jpg' } },
|
|
728
|
+
{ video: { url: './3.mp4' } }
|
|
729
|
+
], { caption: 'Album' })
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
### Meta AI / Rich Responses
|
|
733
|
+
|
|
734
|
+
```js
|
|
735
|
+
// Rich AI response (table, list, code, LaTeX)
|
|
736
|
+
await sock.sendRichAIResponse(jid, {
|
|
737
|
+
table: { headers: ['Name', 'Value'], rows: [['Foo', '1'], ['Bar', '2']] }
|
|
738
|
+
})
|
|
739
|
+
|
|
740
|
+
await sock.sendRichAIResponse(jid, {
|
|
741
|
+
list: { items: ['Item 1', 'Item 2', 'Item 3'] }
|
|
742
|
+
})
|
|
743
|
+
|
|
744
|
+
await sock.sendRichAIResponse(jid, {
|
|
745
|
+
codeBlock: { language: 'js', code: 'console.log("hello")' }
|
|
746
|
+
})
|
|
747
|
+
|
|
748
|
+
await sock.sendRichAIResponse(jid, {
|
|
749
|
+
latex: 'E = mc^2'
|
|
750
|
+
})
|
|
751
|
+
|
|
752
|
+
// Capture & resend a Meta AI unified response
|
|
753
|
+
await sock.captureAndResendUnifiedResponse(jid, metaAiMsg)
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
### Status / Stories
|
|
757
|
+
|
|
758
|
+
```js
|
|
759
|
+
// Status with mentions
|
|
760
|
+
await sock.sendMessage('status@broadcast', {
|
|
761
|
+
text: 'Hello @49123',
|
|
762
|
+
mentions: ['49123@s.whatsapp.net'],
|
|
763
|
+
statusMentionedJids: ['49123@s.whatsapp.net']
|
|
764
|
+
})
|
|
765
|
+
|
|
766
|
+
// Status sticker interaction
|
|
767
|
+
await sock.sendMessage('status@broadcast', {
|
|
768
|
+
stickerInteraction: { sticker: { url: './sticker.webp' }, reactionKey: msg.key }
|
|
769
|
+
})
|
|
770
|
+
|
|
771
|
+
// Quote a status
|
|
772
|
+
await sock.sendMessage(jid, { text: 'Reply to status' }, { quoted: statusMsg })
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
---
|
|
776
|
+
|
|
777
|
+
## Modifying Messages
|
|
778
|
+
|
|
779
|
+
```js
|
|
780
|
+
// Delete for everyone
|
|
781
|
+
await sock.sendMessage(jid, { delete: msg.key })
|
|
782
|
+
|
|
783
|
+
// Edit
|
|
784
|
+
await sock.sendMessage(jid, { edit: msg.key, text: 'Updated text' })
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
---
|
|
788
|
+
|
|
789
|
+
## Manipulating Media
|
|
790
|
+
|
|
791
|
+
```js
|
|
792
|
+
const { downloadMediaMessage } = require('@badzz88/baileys')
|
|
793
|
+
|
|
794
|
+
// Download
|
|
795
|
+
const buffer = await downloadMediaMessage(msg, 'buffer', {})
|
|
796
|
+
|
|
797
|
+
// Re-upload to WhatsApp
|
|
798
|
+
const { url } = await sock.waUploadToServer(buffer, { mimetype: 'image/jpeg' })
|
|
369
799
|
```
|
|
370
800
|
|
|
371
801
|
---
|
|
372
802
|
|
|
373
|
-
##
|
|
803
|
+
## Groups
|
|
804
|
+
|
|
805
|
+
```js
|
|
806
|
+
// Create
|
|
807
|
+
const group = await sock.groupCreate('Name', ['49123@s.whatsapp.net'])
|
|
808
|
+
|
|
809
|
+
// Add / Remove / Promote / Demote
|
|
810
|
+
await sock.groupParticipantsUpdate(jid, ['49123@s.whatsapp.net'], 'add') // add | remove | promote | demote
|
|
811
|
+
|
|
812
|
+
// Change name
|
|
813
|
+
await sock.groupUpdateSubject(jid, 'New Name')
|
|
814
|
+
|
|
815
|
+
// Change description
|
|
816
|
+
await sock.groupUpdateDescription(jid, 'Description')
|
|
817
|
+
|
|
818
|
+
// Change settings
|
|
819
|
+
await sock.groupSettingUpdate(jid, 'announcement') // announcement | not_announcement | locked | unlocked
|
|
820
|
+
|
|
821
|
+
// Leave
|
|
822
|
+
await sock.groupLeave(jid)
|
|
823
|
+
|
|
824
|
+
// Invite link
|
|
825
|
+
const code = await sock.groupInviteCode(jid)
|
|
826
|
+
await sock.groupRevokeInvite(jid)
|
|
827
|
+
await sock.groupAcceptInvite(code)
|
|
828
|
+
|
|
829
|
+
// Metadata (now also returns memberShareHistoryMode, memberLinkMode, limitSharing)
|
|
830
|
+
const meta = await sock.groupMetadata(jid)
|
|
831
|
+
|
|
832
|
+
// Join requests
|
|
833
|
+
const requests = await sock.groupRequestParticipantsList(jid)
|
|
834
|
+
await sock.groupRequestParticipantsUpdate(jid, ['49123@s.whatsapp.net'], 'approve') // approve | reject
|
|
374
835
|
|
|
375
|
-
|
|
836
|
+
// All groups
|
|
837
|
+
const all = await sock.groupFetchAllParticipating()
|
|
838
|
+
|
|
839
|
+
// Ephemeral
|
|
840
|
+
await sock.groupToggleEphemeral(jid, 86400) // seconds, 0 = off
|
|
841
|
+
|
|
842
|
+
// Acknowledge a group
|
|
843
|
+
await sock.groupAcknowledge(jid)
|
|
844
|
+
|
|
845
|
+
// Communities — linked/sub-group participants, join a sub-group, batch profile pictures
|
|
846
|
+
const linkedParts = await sock.groupGetLinkedParticipants(communityJid)
|
|
847
|
+
await sock.groupJoinLinked(communityJid, subGroupJid)
|
|
848
|
+
const pics = await sock.getGroupProfilePictures([jid1, jid2], 'preview')
|
|
849
|
+
```
|
|
376
850
|
|
|
377
851
|
---
|
|
378
852
|
|
|
379
|
-
|
|
853
|
+
## Privacy
|
|
854
|
+
|
|
855
|
+
```js
|
|
856
|
+
// Block / Unblock
|
|
857
|
+
await sock.updateBlockStatus(jid, 'block') // block | unblock
|
|
858
|
+
|
|
859
|
+
// Get settings
|
|
860
|
+
const privacy = await sock.fetchPrivacySettings()
|
|
861
|
+
// { last: 'all', online: 'all', profile: 'contacts', groupadd: 'all', calladd: 'all', ... }
|
|
862
|
+
|
|
863
|
+
// Force fresh fetch (bypass cache)
|
|
864
|
+
const fresh = await sock.fetchPrivacySettings(true)
|
|
865
|
+
|
|
866
|
+
// Get blocklist
|
|
867
|
+
const list = await sock.fetchBlocklist()
|
|
868
|
+
|
|
869
|
+
// Update individual settings (IQ-based, lowercase values, works on all accounts)
|
|
870
|
+
await sock.updateLastSeenPrivacy('contacts') // all | contacts | contact_blacklist | none
|
|
871
|
+
await sock.updateOnlinePrivacy('all')
|
|
872
|
+
await sock.updateProfilePicturePrivacy('contacts')
|
|
873
|
+
await sock.updateStatusPrivacy('contacts')
|
|
874
|
+
await sock.updateReadReceiptsPrivacy('all')
|
|
875
|
+
await sock.updateGroupsAddPrivacy('contacts')
|
|
876
|
+
await sock.updateCallPrivacy('all')
|
|
877
|
+
await sock.updateDefaultDisappearingMode(86400) // seconds, 0 = off
|
|
878
|
+
|
|
879
|
+
// Set via MEX GraphQL (UPPERCASE values required)
|
|
880
|
+
await sock.setPrivacySetting('LAST_SEEN', 'CONTACTS')
|
|
881
|
+
await sock.setPrivacySetting('GROUPS', 'CONTACT_BLACKLIST')
|
|
882
|
+
await sock.setPrivacySetting('CALLS', 'NONE')
|
|
883
|
+
|
|
884
|
+
// Manage contact lists for CONTACT_BLACKLIST / CONTACTS settings
|
|
885
|
+
await sock.updatePrivacyContactList('groupadd', 'contact_blacklist', [jid1, jid2])
|
|
886
|
+
const current = await sock.getPrivacyContactList('groupadd', 'contact_blacklist')
|
|
887
|
+
|
|
888
|
+
// "Block messages from unknown accounts" toggle (WA Web w:comms:chat)
|
|
889
|
+
const blockStatus = await sock.getChatBlockingStatus() // 'blocked' | 'unblocked'
|
|
890
|
+
await sock.updateChatBlockingStatus('block') // block | unblock
|
|
891
|
+
|
|
892
|
+
// Pending TOS disclosures · feature opt-out list · push config
|
|
893
|
+
const notices = await sock.getUserDisclosures()
|
|
894
|
+
const optOut = await sock.getOptOutList()
|
|
895
|
+
const push = await sock.getPushConfig()
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
---
|
|
899
|
+
|
|
900
|
+
## User Queries
|
|
901
|
+
|
|
902
|
+
```js
|
|
903
|
+
// Check if number exists on WA
|
|
904
|
+
const results = await sock.onWhatsApp('49123456789')
|
|
905
|
+
// results[0] === { jid: '49123456789@s.whatsapp.net', exists: true }
|
|
906
|
+
|
|
907
|
+
// Profile picture
|
|
908
|
+
const ppUrl = await sock.profilePictureUrl(jid, 'image')
|
|
909
|
+
|
|
910
|
+
// Status text (legacy)
|
|
911
|
+
const status = await sock.fetchStatus(jid)
|
|
912
|
+
|
|
913
|
+
// About text (MEX)
|
|
914
|
+
const abouts = await sock.getTextStatusList([jid])
|
|
915
|
+
// [{ jid, text: 'Hey there!', emoji: '👋', timestamp: 1234567890 }]
|
|
916
|
+
|
|
917
|
+
// Business profile
|
|
918
|
+
const biz = await sock.getBusinessProfile(jid)
|
|
919
|
+
|
|
920
|
+
// Presence (typing/online)
|
|
921
|
+
await sock.subscribePresence(jid)
|
|
922
|
+
sock.ev.on('presence.update', ({ id, presences }) => { })
|
|
923
|
+
|
|
924
|
+
// Chat history
|
|
925
|
+
await sock.fetchMessageHistory(50, oldestMsg.key, oldestMsg.messageTimestamp)
|
|
926
|
+
|
|
927
|
+
// Find user by @username
|
|
928
|
+
const user = await sock.findUserByUsername('someusername')
|
|
929
|
+
// { jid: '49123456789@s.whatsapp.net', contact: false } or null
|
|
930
|
+
|
|
931
|
+
// Verify a JID before opening a chat
|
|
932
|
+
const integrity = await sock.contactIntegrityQuery([jid])
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
---
|
|
936
|
+
|
|
937
|
+
## Change Profile
|
|
938
|
+
|
|
939
|
+
```js
|
|
940
|
+
// Status
|
|
941
|
+
await sock.updateProfileStatus('My status')
|
|
942
|
+
|
|
943
|
+
// Name
|
|
944
|
+
await sock.updateProfileName('New Name')
|
|
945
|
+
|
|
946
|
+
// Picture
|
|
947
|
+
await sock.updateProfilePicture(jid, { url: './photo.jpg' })
|
|
948
|
+
|
|
949
|
+
// Remove picture
|
|
950
|
+
await sock.removeProfilePicture(jid)
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
---
|
|
954
|
+
|
|
955
|
+
## Chat Modifiers
|
|
956
|
+
|
|
957
|
+
```js
|
|
958
|
+
// Archive
|
|
959
|
+
await sock.chatModify({ archive: true, lastMessages: [msg] }, jid)
|
|
960
|
+
|
|
961
|
+
// Mute (ms timestamp)
|
|
962
|
+
await sock.chatModify({ mute: Date.now() + 8 * 60 * 60 * 1000 }, jid)
|
|
963
|
+
|
|
964
|
+
// Mark read/unread
|
|
965
|
+
await sock.chatModify({ markRead: false, lastMessages: [msg] }, jid)
|
|
966
|
+
|
|
967
|
+
// Delete message for me
|
|
968
|
+
await sock.chatModify({ clear: { messages: [{ id: msg.key.id, fromMe: msg.key.fromMe }] } }, jid)
|
|
969
|
+
|
|
970
|
+
// Delete chat
|
|
971
|
+
await sock.chatModify({ delete: true, lastMessages: [msg] }, jid)
|
|
972
|
+
|
|
973
|
+
// Star / Unstar
|
|
974
|
+
await sock.chatModify({ star: { messages: [{ id: msg.key.id, fromMe: msg.key.fromMe }], star: true } }, jid)
|
|
975
|
+
|
|
976
|
+
// Disappearing messages
|
|
977
|
+
await sock.sendMessage(jid, { disappearingMessagesInChat: 86400 })
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
---
|
|
981
|
+
|
|
982
|
+
## Writing Custom Functionality
|
|
983
|
+
|
|
984
|
+
```js
|
|
985
|
+
// Enable debug logs
|
|
986
|
+
const sock = makeWASocket({ logger: pino({ level: 'debug' }) })
|
|
987
|
+
|
|
988
|
+
// Raw websocket events
|
|
989
|
+
sock.ws.on('CB:message', node => console.log(node))
|
|
990
|
+
|
|
991
|
+
// Register callback for specific WA nodes
|
|
992
|
+
sock.ws.on('CB:iq,,result', node => { })
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
---
|
|
996
|
+
|
|
997
|
+
## Extra Utilities
|
|
998
|
+
|
|
999
|
+
A handful of batteries-included helpers on top of stock Baileys, importable from the
|
|
1000
|
+
main package (`require('@badzz88/baileys')` / top-level `Utils` exports):
|
|
1001
|
+
|
|
1002
|
+
### Sticker Maker
|
|
1003
|
+
|
|
1004
|
+
```js
|
|
1005
|
+
const { imageToWebpSticker, videoToWebpSticker } = require('@badzz88/baileys')
|
|
1006
|
+
|
|
1007
|
+
const stickerBuf = await imageToWebpSticker(imageBuffer, {
|
|
1008
|
+
packName: 'My Pack',
|
|
1009
|
+
packPublisher: 'Me'
|
|
1010
|
+
})
|
|
1011
|
+
await sock.sendMessage(jid, { sticker: stickerBuf })
|
|
1012
|
+
|
|
1013
|
+
// animated stickers need ffmpeg on PATH
|
|
1014
|
+
const animatedBuf = await videoToWebpSticker(videoBuffer, { packName: 'My Pack', packPublisher: 'Me' })
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
### Auto-Cache View-Once Media
|
|
1018
|
+
|
|
1019
|
+
Downloads and saves view-once photos/videos/voice notes to disk the moment they arrive,
|
|
1020
|
+
before the sender's app can mark them as opened.
|
|
1021
|
+
|
|
1022
|
+
```js
|
|
1023
|
+
const { autoCacheViewOnceMedia } = require('@badzz88/baileys')
|
|
1024
|
+
|
|
1025
|
+
const stop = autoCacheViewOnceMedia(sock, { cacheDir: './viewonce-cache' })
|
|
1026
|
+
// stop() to remove the listener later
|
|
1027
|
+
```
|
|
1028
|
+
|
|
1029
|
+
### Folder-Based Command Loader
|
|
1030
|
+
|
|
1031
|
+
```js
|
|
1032
|
+
const { createCommandHandler } = require('@badzz88/baileys')
|
|
1033
|
+
|
|
1034
|
+
createCommandHandler(sock, { commandsDir: './commands', prefix: '.' })
|
|
1035
|
+
```
|
|
1036
|
+
|
|
1037
|
+
```js
|
|
1038
|
+
// ./commands/ping.js
|
|
1039
|
+
module.exports = {
|
|
1040
|
+
name: 'ping',
|
|
1041
|
+
aliases: ['p'],
|
|
1042
|
+
async execute({ sock, jid }) {
|
|
1043
|
+
await sock.sendMessage(jid, { text: 'pong' })
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
### Multi-Account Session Pool
|
|
1049
|
+
|
|
1050
|
+
Runs several accounts side by side and auto-reconnects any that drop (except on
|
|
1051
|
+
logout) with exponential backoff + jitter, instead of hand-rolling a reconnect loop
|
|
1052
|
+
per project.
|
|
1053
|
+
|
|
1054
|
+
```js
|
|
1055
|
+
const { createSessionPool } = require('@badzz88/baileys')
|
|
1056
|
+
|
|
1057
|
+
const pool = createSessionPool({
|
|
1058
|
+
makeSocket: async sessionId => {
|
|
1059
|
+
const { state, saveCreds } = await useMultiFileAuthState(`./sessions/${sessionId}`)
|
|
1060
|
+
const sock = makeWASocket({ auth: state })
|
|
1061
|
+
sock.ev.on('creds.update', saveCreds)
|
|
1062
|
+
return sock
|
|
1063
|
+
},
|
|
1064
|
+
logger
|
|
1065
|
+
})
|
|
1066
|
+
|
|
1067
|
+
await pool.add('account-1')
|
|
1068
|
+
await pool.add('account-2')
|
|
1069
|
+
```
|
|
1070
|
+
|
|
1071
|
+
### Store Auto-Save, Message Limits & Encryption
|
|
1072
|
+
|
|
1073
|
+
`makeInMemoryStore` now persists **everything** (`chats`, `contacts`, `messages`,
|
|
1074
|
+
`labels`, `groupMetadata`, `presences`, `state`) instead of a subset, and supports:
|
|
1075
|
+
|
|
1076
|
+
```js
|
|
1077
|
+
const store = makeInMemoryStore({
|
|
1078
|
+
socket: sock,
|
|
1079
|
+
maxMessagesPerChat: 500, // cap memory usage per chat
|
|
1080
|
+
encryptionKey: process.env.STORE_KEY // optional, AES-256-GCM at rest
|
|
1081
|
+
})
|
|
1082
|
+
|
|
1083
|
+
store.readFromFile('./store.json')
|
|
1084
|
+
const stopAutoSave = store.startAutoSave('./store.json', 30_000) // every 30s + on socket close
|
|
1085
|
+
```
|
|
1086
|
+
|
|
1087
|
+
---
|
|
1088
|
+
|
|
1089
|
+
## Rust WASM Bridge
|
|
1090
|
+
|
|
1091
|
+
The native module lives at [7ucg/whatsapp-rust-bridge](https://github.com/7ucg/whatsapp-rust-bridge).
|
|
1092
|
+
Pre-built and bundled — **no Rust toolchain needed** to use this package.
|
|
1093
|
+
|
|
1094
|
+
Functions offloaded to Rust:
|
|
380
1095
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
1096
|
+
| Function | Description |
|
|
1097
|
+
|---|---|
|
|
1098
|
+
| `decodeNode` | WABinary protocol decoding |
|
|
1099
|
+
| `NoiseSession` | Noise_XX_25519_AESGCM_SHA256 handshake + framing |
|
|
1100
|
+
| `hkdf` | HKDF key derivation |
|
|
1101
|
+
| `hmacSign` | HMAC-SHA256 signing |
|
|
1102
|
+
| `sha256` | SHA-256 hashing |
|
|
1103
|
+
| `aesEncrypt` / `aesDecrypt` | AES-256-CBC |
|
|
1104
|
+
| `aesEncryptGCM` / `aesDecryptGCM` | AES-256-GCM |
|
|
1105
|
+
| `aesEncryptCTR` / `aesDecryptCTR` | AES-256-CTR |
|
|
388
1106
|
|
|
389
1107
|
---
|
|
390
1108
|
|
|
391
|
-
|
|
1109
|
+
## License
|
|
392
1110
|
|
|
393
|
-
|
|
1111
|
+
MIT
|