@violetix/baileys 0.5.6 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1530 -2009
- package/WAProto/index.d.ts +14030 -14586
- package/WAProto/index.js +58426 -88874
- package/lib/Defaults/index.d.ts +2 -7
- package/lib/Defaults/index.js +5 -20
- package/lib/Signal/Group/sender-key-message.js +19 -1
- package/lib/Signal/libsignal.js +82 -29
- package/lib/Signal/xeddsa-fast.js +114 -0
- package/lib/Socket/Client/types.js +6 -8
- package/lib/Socket/Client/websocket.js +3 -38
- package/lib/Socket/business.d.ts +0 -3
- package/lib/Socket/chats.d.ts +0 -3
- package/lib/Socket/chats.js +18 -45
- package/lib/Socket/communities.d.ts +0 -3
- package/lib/Socket/graphql.js +3 -7
- package/lib/Socket/groups.d.ts +0 -3
- package/lib/Socket/groups.js +3 -8
- package/lib/Socket/index.d.ts +15 -17
- package/lib/Socket/messages-recv.d.ts +0 -3
- package/lib/Socket/messages-recv.js +43 -127
- package/lib/Socket/messages-send.d.ts +0 -4
- package/lib/Socket/messages-send.js +63 -191
- package/lib/Socket/newsletter.d.ts +0 -3
- package/lib/Socket/newsletter.js +1 -2
- package/lib/Socket/newsletter.js.map +1 -1
- package/lib/Socket/socket.d.ts +0 -9
- package/lib/Socket/socket.js +53 -346
- package/lib/Store/make-in-memory-store.js +30 -41
- package/lib/Types/Auth.d.ts +2 -60
- package/lib/Types/Bussines.d.ts +2 -9
- package/lib/Types/Call.d.ts +2 -22
- package/lib/Types/Chat.d.ts +1 -2
- package/lib/Types/Contact.d.ts +2 -11
- package/lib/Types/Events.d.ts +2 -41
- package/lib/Types/GroupMetadata.d.ts +2 -36
- package/lib/Types/Message.d.ts +1 -11
- package/lib/Types/Product.d.ts +2 -5
- package/lib/Types/Signal.d.ts +2 -10
- package/lib/Types/Socket.d.ts +2 -33
- package/lib/Types/USync.d.ts +2 -9
- package/lib/Types/index.d.ts +1 -3
- package/lib/Utils/auth-utils.d.ts +2 -3
- package/lib/Utils/auth-utils.js +53 -37
- package/lib/Utils/business.js +11 -25
- package/lib/Utils/chat-utils.js +4 -6
- package/lib/Utils/decode-wa-message.js +2 -2
- package/lib/Utils/event-buffer.js +12 -21
- package/lib/Utils/generics.d.ts +5 -5
- package/lib/Utils/generics.js +7 -25
- package/lib/Utils/history.d.ts +1 -2
- package/lib/Utils/history.js +83 -137
- package/lib/Utils/index.d.ts +0 -4
- package/lib/Utils/index.js +0 -4
- package/lib/Utils/listener-guard.js +0 -2
- package/lib/Utils/message-retry-manager.js +0 -20
- package/lib/Utils/messages-media.d.ts +8 -39
- package/lib/Utils/messages-media.js +89 -218
- package/lib/Utils/messages.d.ts +0 -1
- package/lib/Utils/messages.js +36 -122
- package/lib/Utils/process-message.d.ts +0 -18
- package/lib/Utils/process-message.js +47 -99
- package/lib/Utils/rich-message-utils.js +4 -3
- package/lib/Utils/use-multi-file-auth-state.d.ts +3 -5
- package/lib/Utils/use-multi-file-auth-state.js +6 -27
- package/lib/Utils/use-single-file-auth-state.d.ts +1 -1
- package/lib/Utils/use-single-file-auth-state.js +3 -12
- package/lib/WABinary/types.d.ts +2 -6
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +3 -6
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +2 -3
- package/lib/WAUSync/USyncQuery.d.ts +1 -1
- package/lib/WAUSync/USyncQuery.js +4 -7
- package/package.json +107 -123
- package/lib/Utils/a2ui.d.ts +0 -50
- package/lib/Utils/a2ui.js +0 -168
- package/lib/Utils/anchor-guard.d.ts +0 -71
- package/lib/Utils/anchor-guard.js +0 -404
- package/lib/Utils/connection-manager.d.ts +0 -44
- package/lib/Utils/connection-manager.js +0 -258
- package/lib/Utils/ignore-key.d.ts +0 -51
- package/lib/Utils/ignore-key.js +0 -176
package/README.md
CHANGED
|
@@ -1,723 +1,646 @@
|
|
|
1
|
-
|
|
1
|
+
# 🌱 @itsliaaa/baileys
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@itsliaaa/baileys)
|
|
2
4
|
|
|
3
5
|
<p align="center">
|
|
4
|
-
|
|
5
|
-
messages, newsletter media, and the protocol surface upstream does not expose yet.
|
|
6
|
+
Enhanced Baileys v7 with fixes for newsletter media uploads, plus support for interactive messages, albums, and additional message types.
|
|
6
7
|
<br><br>
|
|
7
|
-
<a href="https://www.npmjs.com/package/@
|
|
8
|
-
<img src="https://img.shields.io/npm/v/@
|
|
8
|
+
<a href="https://www.npmjs.com/package/@itsliaaa/baileys">
|
|
9
|
+
<img src="https://img.shields.io/npm/v/@itsliaaa/baileys?style=for-the-badge&logo=npm"/>
|
|
9
10
|
</a>
|
|
10
|
-
<a href="https://www.npmjs.com/package/@
|
|
11
|
-
<img src="https://img.shields.io/npm/dm/@
|
|
11
|
+
<a href="https://www.npmjs.com/package/@itsliaaa/baileys">
|
|
12
|
+
<img src="https://img.shields.io/npm/dm/@itsliaaa/baileys?style=for-the-badge&logo=npm"/>
|
|
12
13
|
</a>
|
|
13
|
-
<a href="https://github.com/
|
|
14
|
-
<img src="https://img.shields.io/github/stars/
|
|
14
|
+
<a href="https://github.com/itsliaaa/baileys">
|
|
15
|
+
<img src="https://img.shields.io/github/stars/itsliaaa/baileys?style=for-the-badge&logo=github"/>
|
|
15
16
|
</a>
|
|
16
17
|
<a href="LICENSE">
|
|
17
|
-
<img src="https://img.shields.io/badge/license-MIT-blue?style=for-the-badge"
|
|
18
|
+
<img src="https://img.shields.io/badge/license-MIT-blue?style=for-the-badge"/>
|
|
18
19
|
</a>
|
|
19
20
|
<a href="https://nodejs.org">
|
|
20
|
-
<img src="https://img.shields.io/badge/node-%3E%3D20-339933?logo=node.js&labelColor=green&logoColor=white&style=for-the-badge"
|
|
21
|
+
<img src="https://img.shields.io/badge/node-%3E%3D20-339933?logo=node.js&labelColor=green&logoColor=white&style=for-the-badge"/>
|
|
21
22
|
</a>
|
|
22
|
-
<a href="
|
|
23
|
-
<img src="https://img.shields.io/badge/ESM-only?logo=javascript&labelColor=yellow&logoColor=black&style=for-the-badge"
|
|
23
|
+
<a href="#">
|
|
24
|
+
<img src="https://img.shields.io/badge/ESM-only?logo=javascript&labelColor=yellow&logoColor=black&style=for-the-badge"/>
|
|
24
25
|
</a>
|
|
25
26
|
</p>
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
☕ For donation: [Saweria](https://saweria.co/itsliaaa)
|
|
29
|
+
|
|
30
|
+
### ✨ Highlights
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
<summary><b>📋 Table of contents</b></summary>
|
|
32
|
+
This fork designed for production use with a focus on clarity and safety:
|
|
33
33
|
|
|
34
|
+
- 🚫 No obfuscation. Easy to read and audit.
|
|
35
|
+
- 🚫 No auto-follow channel (newsletter) behavior.
|
|
36
|
+
|
|
37
|
+
> [!IMPORTANT]
|
|
38
|
+
> Hi everyone,
|
|
39
|
+
>
|
|
40
|
+
> I want to clarify two separate attribution issues regarding packages derived from this fork.
|
|
41
|
+
>
|
|
42
|
+
> 1. Direct redistribution of my modifications without attribution
|
|
43
|
+
>
|
|
44
|
+
> The following packages are operated by the same individual under multiple npm accounts:
|
|
45
|
+
>
|
|
46
|
+
> - [@nuisockets](https://www.npmjs.com/package/@nuisockets/baileys)
|
|
47
|
+
> - [@nuiisatoru](https://www.npmjs.com/package/@nuiisatoru/baileys)
|
|
48
|
+
> - [@nuiisweetberry](https://www.npmjs.com/package/@nuiisweetberry/baileys)
|
|
49
|
+
> - [@nuiisweety](https://www.npmjs.com/package/@nuiisweety/baileys)
|
|
50
|
+
>
|
|
51
|
+
> These packages redistribute files and modifications originating from this fork while removing contributor credits and modification notes.
|
|
52
|
+
>
|
|
53
|
+
> 2. Rebranded republishes of this fork
|
|
54
|
+
>
|
|
55
|
+
> - [@lumina-md](https://www.npmjs.com/package/@lumina-md/baileys)
|
|
56
|
+
> - [@sairidev](https://www.npmjs.com/package/@sairidev/baileys-new)
|
|
57
|
+
> - [@lordmega/baileys](https://www.npmjs.com/package/@lordmega/baileys)
|
|
58
|
+
> - [phantom-baileys](https://www.npmjs.com/package/phantom-baileys)
|
|
59
|
+
> - [nexora-baileys](https://www.npmjs.com/package/nexora-baileys)
|
|
60
|
+
>
|
|
61
|
+
> These packages primarily repackage or republish this fork under different names while failing to preserve proper attribution, credits, or modification notes.
|
|
62
|
+
>
|
|
63
|
+
> To be clear, I am **NOT** the original maintainer of Baileys. Full credit and respect belong to:
|
|
64
|
+
>
|
|
65
|
+
> https://github.com/WhiskeySockets/Baileys
|
|
66
|
+
>
|
|
67
|
+
> **Forking is completely acceptable. Removing attribution, contributor credits, or modification history is not.**
|
|
68
|
+
>
|
|
69
|
+
> Please report if necessary.
|
|
70
|
+
>
|
|
71
|
+
> Thank you. 🤍
|
|
72
|
+
|
|
73
|
+
> [!NOTE]
|
|
74
|
+
> 📄 This project is maintained with limited scope and is not intended to replace upstream Baileys.
|
|
75
|
+
>
|
|
76
|
+
> 😞 And, really sorry for my bad english.
|
|
77
|
+
|
|
78
|
+
### 📋 Table of Contents
|
|
79
|
+
- [✨ Highlights](#-highlights)
|
|
80
|
+
- [🛠️ Internal Adjustments](#%EF%B8%8F-internal-adjustments)
|
|
81
|
+
- [📨 Messages Handling & Compatibility](#-messages-handling--compatibility)
|
|
82
|
+
- [🧩 Additional Message Options](#-additional-message-options)
|
|
83
|
+
- [🆕 WhatsApp Protocol Extensions](#-whatsapp-protocol-extensions)
|
|
34
84
|
- [📥 Installation](#-installation)
|
|
35
|
-
|
|
85
|
+
- [🧩 Import (ESM & CJS)](#-import-esm--cjs)
|
|
36
86
|
- [🌐 Connect to WhatsApp (Quick Step)](#-connect-to-whatsapp-quick-step)
|
|
37
|
-
|
|
87
|
+
- [🔐 Auth State](#-auth-state)
|
|
38
88
|
- [🗄️ Implementing Data Store](#%EF%B8%8F-implementing-data-store)
|
|
39
89
|
- [🪪 WhatsApp IDs Explain](#-whatsapp-ids-explain)
|
|
40
|
-
- [⚡ Why this fork exists](#-why-this-fork-exists)
|
|
41
|
-
- [🛠️ Upstream Fixes & Improvements](#%EF%B8%8F-upstream-fixes--improvements)
|
|
42
|
-
- [📨 Messages Handling & Compatibility](#-messages-handling--compatibility)
|
|
43
|
-
- [🧩 Additional Message Options](#-additional-message-options)
|
|
44
|
-
- [🆕 WhatsApp Protocol Extensions](#-whatsapp-protocol-extensions)
|
|
45
90
|
- [✉️ Sending Messages](#%EF%B8%8F-sending-messages)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
91
|
+
- [🔠 Text](#-text)
|
|
92
|
+
- [🔔 Mention](#-mention)
|
|
93
|
+
- [😁 Reaction](#-reaction)
|
|
94
|
+
- [📌 Pin Message](#-pin-message)
|
|
95
|
+
- [🔖 Keep Chat](#-keep-chat)
|
|
96
|
+
- [➡️ Forward Message](#%EF%B8%8F-forward-message)
|
|
97
|
+
- [👤 Contact](#-contact)
|
|
98
|
+
- [📍 Location](#-location)
|
|
99
|
+
- [🗓️ Event](#%EF%B8%8F-event)
|
|
100
|
+
- [👥 Group Invite](#-group-invite)
|
|
101
|
+
- [🛍️ Product](#%EF%B8%8F-product)
|
|
102
|
+
- [📊 Poll](#-poll)
|
|
103
|
+
- [💭 Button Response](#-button-response)
|
|
104
|
+
- [✨ Rich Response](#-rich-response)
|
|
105
|
+
- [🧾 Message with Code Block](#-message-with-code-block)
|
|
106
|
+
- 🌏 [Message with Inline Entities](#-message-with-inline-entities)
|
|
107
|
+
- [📋 Message with Table](#-message-with-table)
|
|
108
|
+
- [🎞️ Status Mention](#%EF%B8%8F-status-mention)
|
|
64
109
|
- [📁 Sending Media Messages](#-sending-media-messages)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
- [📤 Downloading Media](#-downloading-media)
|
|
110
|
+
- [🖼️ Image](#%EF%B8%8F-image)
|
|
111
|
+
- [🎥 Video](#-video)
|
|
112
|
+
- [📃 Sticker](#-sticker)
|
|
113
|
+
- [💽 Audio](#-audio)
|
|
114
|
+
- [🗂️ Document](#%EF%B8%8F-document)
|
|
115
|
+
- [🖼️ Album (Image & Video)](#%EF%B8%8F-album-image--video)
|
|
116
|
+
- [📦 Sticker Pack](#-sticker-pack)
|
|
73
117
|
- [👉🏻 Sending Interactive Messages](#-sending-interactive-messages)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
118
|
+
- [🔘 Buttons](#-buttons)
|
|
119
|
+
- [📋 List](#-list)
|
|
120
|
+
- [🗄️ Interactive](#%EF%B8%8F-interactive)
|
|
121
|
+
- [🫙 Hydrated Template](#-hydrated-template)
|
|
78
122
|
- [💳 Sending Payment Messages](#-sending-payment-messages)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
123
|
+
- [➕ Invite Payment](#-invite-payment)
|
|
124
|
+
- [🧾 Invoice](#-invoice)
|
|
125
|
+
- [🛍️ Order](#%EF%B8%8F-order)
|
|
126
|
+
- [💳 Request Payment](#-request-payment)
|
|
83
127
|
- [👁️ Other Message Options](#%EF%B8%8F-other-message-options)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
128
|
+
- [🤖 AI Icon](#-ai-icon)
|
|
129
|
+
- [🕒 Ephemeral](#-ephemeral)
|
|
130
|
+
- [📰 External Ad Reply](#-external-ad-reply)
|
|
131
|
+
- [🧑🧑🧒 Group Status](#%E2%80%8D%E2%80%8D-group-status)
|
|
132
|
+
- [🐱 Lottie Sticker](#-lottie-sticker)
|
|
133
|
+
- [🧩 Raw](#-raw)
|
|
134
|
+
- [🏷️ Secure Meta Service Label](#%EF%B8%8F-secure-meta-service-label)
|
|
135
|
+
- [📑 Spoiler](#-spoiler)
|
|
136
|
+
- [👁️ View Once](#%EF%B8%8F-view-once)
|
|
137
|
+
- [👁️ View Once V2](#%EF%B8%8F-view-once-v2)
|
|
138
|
+
- [👁️ View Once V2 Extension](#%EF%B8%8F-view-once-v2-extension)
|
|
95
139
|
- [♻️ Modify Messages](#%EF%B8%8F-modify-messages)
|
|
96
|
-
|
|
97
|
-
|
|
140
|
+
- [🗑️ Delete Messages](#%EF%B8%8F-delete-messages)
|
|
141
|
+
- [✏️ Edit Messages](#%EF%B8%8F-edit-messages)
|
|
98
142
|
- [🧰 Additional Contents](#-additional-contents)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
- [
|
|
143
|
+
- [🏷️ Find User ID (JID|PN/LID)](#%EF%B8%8F-find-user-id-jidpnlid)
|
|
144
|
+
- [🔑 Request Custom Pairing Code](#-request-custom-pairing-code)
|
|
145
|
+
- [🖼️ Image Processing](#%EF%B8%8F-image-processing)
|
|
146
|
+
- [📣 Newsletter Management](#-newsletter-management)
|
|
147
|
+
- [👥 Group Management](#-group-management)
|
|
148
|
+
- [👥 Community Management](#-community-management)
|
|
149
|
+
- [👤 Profile Management](#-profile-management)
|
|
150
|
+
- [🛒 Business Management](#-business-management)
|
|
151
|
+
- [🔐 Privacy Management](#-privacy-management)
|
|
152
|
+
- [🆔 Username Management](#-username-management)
|
|
153
|
+
- [🔍 USync Queries](#-usync-queries)
|
|
154
|
+
- [🤝 Interoperability (BirdyChat & Haiket)](#-interoperability-birdychat--haiket)
|
|
155
|
+
- [🔒 Account Security (Password & Passkey)](#-account-security-password--passkey)
|
|
156
|
+
- [👪 Managed Accounts & Payments](#-managed-accounts--payments)
|
|
157
|
+
- [🌐 HTTPS GraphQL (Meta AI & Imagine)](#-https-graphql-meta-ai--imagine)
|
|
158
|
+
- [📡 Events](#-events)
|
|
159
|
+
- [🚀 Try the Bot](#-try-the-bot)
|
|
116
160
|
- [📦 Fork Base](#-fork-base)
|
|
117
161
|
- [📣 Credits](#-credits)
|
|
118
162
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
163
|
+
### 🛠️ Internal Adjustments
|
|
164
|
+
- 🖼️ Fixed an issue where media could not be sent to newsletters due to an upstream issue.
|
|
165
|
+
- 📁 Reintroduced [`makeInMemoryStore`](#%EF%B8%8F-implementing-data-store) with a minimal ESM adaptation and small adjustments for Baileys v7.
|
|
166
|
+
- 📦 Switched FFmpeg execution from `exec` to `spawn` for safer process handling.
|
|
167
|
+
- 🗃️ Added [`@napi-rs/image`](https://www.npmjs.com/package/@napi-rs/image) as a supported image processing backend in [`getImageProcessingLibrary()`](#%EF%B8%8F-image-processing), offering a balance between performance and compatibility.
|
|
168
|
+
- 🪪 Recovered the phone number for LID-addressed senders that arrive without one, so [username](#-username-management) users no longer show up as a bare `@lid`. **[NEW]**
|
|
169
|
+
- 📞 Routed top-level call stanzas (`<offer>`, `<terminate>`, …) that arrive outside a `<call>` wrapper, and acknowledged them — previously they were never acked, so the server kept redelivering them. **[NEW]**
|
|
170
|
+
- 🤖 Decrypted `msmsg` Meta AI bot replies instead of dropping them. The `messageSecret` is captured at send time and recovered from `getMessage` after a restart. **[NEW]**
|
|
171
|
+
- 🔍 Parsed the USync fields that were previously left as TODOs: per-protocol errors with backoff, cache `refresh` hints, `side_list`, per-contact privacy tokens, and blocked-by-contact detection. **[NEW]**
|
|
172
|
+
- 🆔 Fixed the USync username parser, which returned `null` for the `Uint8Array` payloads the binary decoder actually produces. **[NEW]**
|
|
122
173
|
|
|
123
|
-
|
|
124
|
-
|
|
174
|
+
### 📨 Messages Handling & Compatibility
|
|
175
|
+
- 📩 Expanded messages support for:
|
|
176
|
+
- 🖼️ [Album Message](#%EF%B8%8F-album-image--video)
|
|
177
|
+
- 👤 [Group Status Message](#%E2%80%8D%E2%80%8D-group-status)
|
|
178
|
+
- 👉🏻 [Interactive Message](#-sending-interactive-messages) (buttons, lists, native flows, templates, carousels).
|
|
179
|
+
- 🎞️ [Status Mention Message](#%EF%B8%8F-status-mention)
|
|
180
|
+
- 📦 [Sticker Pack Message](#-sticker-pack)
|
|
181
|
+
- ✨ [Rich Response Message](#-rich-response) **[NEW]**
|
|
182
|
+
- 🧾 [Message with Code Blocks](#-message-with-code-block) **[NEW]**
|
|
183
|
+
- 🌏 [Message with Inline Entities](#-message-with-inline-entities) **[NEW]**
|
|
184
|
+
- 📋 [Message with Table](#-message-with-table) **[NEW]**
|
|
185
|
+
- 💳 [Payment-related Message](#-sending-payment-messages) (payment requests, invites, orders, invoices).
|
|
186
|
+
- 📰 Simplified sending messages with ad thumbnail using [`externalAdReply`](#-external-ad-reply), without requiring manual `contextInfo`.
|
|
187
|
+
- 💭 Added support for quoting messages inside channel (newsletter). **[NEW]**
|
|
188
|
+
- 🎀 Added support for [custom button icon](#%EF%B8%8F-interactive). **[NEW]**
|
|
189
|
+
|
|
190
|
+
### 🧩 Additional Message Options
|
|
191
|
+
- 👁️ Added optional boolean flags for message handling:
|
|
192
|
+
- 🤖 [`ai`](#-ai-icon) - AI icon on message
|
|
193
|
+
- 📣 [`mentionAll`](#-mention) - Mention all group participants without requiring their JIDs in `mentions` or `mentionedJid` **[NEW]**
|
|
194
|
+
- 🔧 [`ephemeral`](#-ephemeral), [`groupStatus`](#%E2%80%8D%E2%80%8D-group-status), [`isLottie`](#-lottie-sticker), [`spoiler`](#-spoiler), [`viewOnce`](#%EF%B8%8F-view-once), [`viewOnceV2`](#%EF%B8%8F-view-once-v2), [`viewOnceV2Extension`](#%EF%B8%8F-view-once-v2-extension), [`interactiveAsTemplate`](#%EF%B8%8F-interactive) - Message wrappers
|
|
195
|
+
- 🔒 [`secureMetaServiceLabel`](#%EF%B8%8F-secure-meta-service-label) - Secure meta service label on message **[NEW]**
|
|
196
|
+
- 📄 [`raw`](#-raw) - Build your message manually **(DO NOT USE FOR EXPLOITATION)**
|
|
197
|
+
- 🎞️ [`statusPrivacy`](#%EF%B8%8F-status-mention) - Control who receives a status broadcast (`contacts` | `allowlist` | `denylist`) **[NEW]**
|
|
198
|
+
|
|
199
|
+
### 🆕 WhatsApp Protocol Extensions
|
|
200
|
+
|
|
201
|
+
Support for WhatsApp features that upstream Baileys does not expose yet. **[NEW]**
|
|
202
|
+
|
|
203
|
+
| Feature | What it does | Reference |
|
|
204
|
+
| --- | --- | --- |
|
|
205
|
+
| 🆔 **Username** | Look up accounts by `@username`, and claim / change / remove your own | [Username Management](#-username-management) |
|
|
206
|
+
| 🔍 **USync protocols** | Business profile, profile picture, About text, side list, and device feature queries | [USync Queries](#-usync-queries) |
|
|
207
|
+
| 🔐 **MEX privacy** | Privacy settings, contact allow/deny lists, About text, contact integrity checks | [Privacy Management](#-privacy-management) |
|
|
208
|
+
| 🤝 **Interoperability** | Cross-platform chats and groups with BirdyChat and Haiket | [Interoperability](#-interoperability-birdychat--haiket) |
|
|
209
|
+
| 🔒 **Account security** | Account password and passkey (FIDO2 / WebAuthn) management | [Account Security](#-account-security-password--passkey) |
|
|
210
|
+
| 👪 **Managed accounts** | Parental / family account linking, payments passkey, UPI onboarding | [Managed Accounts](#-managed-accounts--payments) |
|
|
211
|
+
| 🌐 **HTTPS GraphQL** | Meta AI memory, Imagine image/video generation, AI personas, events, payments | [HTTPS GraphQL](#-https-graphql-meta-ai--imagine) |
|
|
212
|
+
| 🤖 **Meta AI decryption** | Decrypts `msmsg` (`messageSecret`-encrypted) Meta AI bot replies | — |
|
|
213
|
+
| 📞 **Call details** | `callKey` (raw SRTP key), audio/video codecs, group roster, call-link waiting room | [Events](#-events) |
|
|
214
|
+
| 📰 **Newsletter status** | `newsletter.status` event for server-pushed channel posts, with engagement counters | [Events](#-events) |
|
|
215
|
+
| 🪪 **LID fallback** | Recovers the phone number for senders who only expose a `@lid` (e.g. username users) | [WhatsApp IDs Explain](#-whatsapp-ids-explain) |
|
|
125
216
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
npm i @violetix/baileys
|
|
217
|
+
> [!WARNING]
|
|
218
|
+
> These features rely on WhatsApp's internal MEX (GraphQL-over-WebSocket) and HTTPS GraphQL protocols. The numeric query IDs were captured from a specific WhatsApp client version and **may stop working after a WhatsApp update** — a rejected query usually means the ID is stale, not that the code is broken.
|
|
129
219
|
|
|
130
|
-
|
|
131
|
-
npm i github:cv3inx/bv2
|
|
132
|
-
```
|
|
220
|
+
### 📥 Installation
|
|
133
221
|
|
|
134
|
-
|
|
222
|
+
- 📄 Via `package.json`
|
|
135
223
|
|
|
136
224
|
```json
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
225
|
+
# NPM
|
|
226
|
+
"dependencies": {
|
|
227
|
+
"@itsliaaa/baileys": "latest"
|
|
141
228
|
}
|
|
142
|
-
```
|
|
143
229
|
|
|
144
|
-
|
|
145
|
-
{
|
|
146
|
-
"
|
|
147
|
-
"@violetix/baileys": "github:cv3inx/bv2"
|
|
148
|
-
}
|
|
230
|
+
# GitHub
|
|
231
|
+
"dependencies": {
|
|
232
|
+
"@itsliaaa/baileys": "github:itsliaaa/baileys"
|
|
149
233
|
}
|
|
150
234
|
```
|
|
151
235
|
|
|
152
|
-
|
|
236
|
+
- ⌨️ Via terminal
|
|
153
237
|
|
|
154
|
-
|
|
238
|
+
```bash
|
|
239
|
+
# NPM
|
|
240
|
+
npm i @itsliaaa/baileys@latest
|
|
155
241
|
|
|
156
|
-
|
|
157
|
-
|
|
242
|
+
# GitHub
|
|
243
|
+
npm i github:itsliaaa/baileys
|
|
158
244
|
```
|
|
159
245
|
|
|
160
|
-
|
|
246
|
+
#### 🧩 Import (ESM & CJS)
|
|
161
247
|
|
|
162
248
|
```javascript
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
// Create your socket here.
|
|
166
|
-
}
|
|
249
|
+
// --- ESM
|
|
250
|
+
import { makeWASocket } from '@itsliaaa/baileys'
|
|
167
251
|
|
|
168
|
-
|
|
252
|
+
// --- CJS (tested and working on Node.js 24 ✅)
|
|
253
|
+
const { makeWASocket } = require('@itsliaaa/baileys')
|
|
169
254
|
```
|
|
170
255
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
1. Install the package and the logger used by this example:
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
npm install @violetix/baileys pino
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
2. Save the following code as `index.mjs`. Replace `myPhoneNumber` with your WhatsApp number, including the country code and using digits only.
|
|
256
|
+
### 🌐 Connect to WhatsApp (Quick Step)
|
|
180
257
|
|
|
181
258
|
```javascript
|
|
182
|
-
import {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
DisconnectReason,
|
|
186
|
-
fetchLatestWaWebVersion,
|
|
187
|
-
useMultiFileAuthState,
|
|
188
|
-
} from "@violetix/baileys";
|
|
189
|
-
import pino from "pino";
|
|
259
|
+
import { makeWASocket, delay, DisconnectReason, useMultiFileAuthState } from '@itsliaaa/baileys'
|
|
260
|
+
import { Boom } from '@hapi/boom'
|
|
261
|
+
import pino from 'pino'
|
|
190
262
|
|
|
191
|
-
|
|
192
|
-
const
|
|
263
|
+
// --- Connect with pairing code
|
|
264
|
+
const myPhoneNumber = '6288888888888'
|
|
193
265
|
|
|
194
|
-
|
|
195
|
-
const { state, saveCreds } = await useMultiFileAuthState("session");
|
|
196
|
-
const sock = makeWASocket({
|
|
197
|
-
logger,
|
|
198
|
-
auth: state,
|
|
199
|
-
// Optional: resolve the WhatsApp Web version on each connection.
|
|
200
|
-
version: async () => (await fetchLatestWaWebVersion()).version,
|
|
201
|
-
});
|
|
266
|
+
const logger = pino({ level: 'silent' })
|
|
202
267
|
|
|
203
|
-
|
|
268
|
+
const connectToWhatsApp = async () => {
|
|
269
|
+
const { state, saveCreds } = await useMultiFileAuthState('session')
|
|
270
|
+
|
|
271
|
+
const sock = makeWASocket({
|
|
272
|
+
logger,
|
|
273
|
+
auth: state
|
|
274
|
+
})
|
|
204
275
|
|
|
205
|
-
|
|
206
|
-
try {
|
|
207
|
-
if (connection === "close") {
|
|
208
|
-
const statusCode = lastDisconnect?.error?.output?.statusCode;
|
|
209
|
-
const shouldReconnect = statusCode !== DisconnectReason.loggedOut;
|
|
210
|
-
console.log("Connection closed:", lastDisconnect?.error);
|
|
276
|
+
sock.ev.on('creds.update', saveCreds)
|
|
211
277
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
} else if (connection === "open") {
|
|
219
|
-
console.log("Connected to WhatsApp");
|
|
278
|
+
sock.ev.on('connection.update', (update) => {
|
|
279
|
+
const { connection, lastDisconnect } = update
|
|
280
|
+
if (connection === 'connecting' && !sock.authState.creds.registered) {
|
|
281
|
+
await delay(1500)
|
|
282
|
+
const code = await sock.requestPairingCode(myPhoneNumber)
|
|
283
|
+
console.log('🔗 Pairing code', ':', code)
|
|
220
284
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (type !== "notify") return;
|
|
228
|
-
|
|
229
|
-
for (const message of messages) {
|
|
230
|
-
const jid = message.key.remoteJid;
|
|
231
|
-
if (!message.message || message.key.fromMe || !jid) continue;
|
|
232
|
-
if (!jid.endsWith("@s.whatsapp.net") && !jid.endsWith("@lid")) continue;
|
|
233
|
-
|
|
234
|
-
try {
|
|
235
|
-
await sock.sendMessage(jid, { text: "Hello world" });
|
|
236
|
-
} catch (error) {
|
|
237
|
-
console.error("Failed to reply:", error);
|
|
285
|
+
else if (connection === 'close') {
|
|
286
|
+
const shouldReconnect = new Boom(connection?.lastDisconnect?.error)?.output?.statusCode !== DisconnectReason.loggedOut
|
|
287
|
+
console.log('⚠️ Connection closed because', lastDisconnect.error, ', reconnecting ', shouldReconnect)
|
|
288
|
+
if (shouldReconnect) {
|
|
289
|
+
connectToWhatsApp()
|
|
290
|
+
}
|
|
238
291
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
// This fork waits internally until the server is ready for pairing.
|
|
244
|
-
const code = await sock.requestPairingCode(myPhoneNumber);
|
|
245
|
-
console.log("Pairing code:", code);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
292
|
+
else if (connection === 'open') {
|
|
293
|
+
console.log('✅ Successfully connected to WhatsApp')
|
|
294
|
+
}
|
|
295
|
+
})
|
|
248
296
|
|
|
249
|
-
|
|
250
|
-
|
|
297
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
298
|
+
for (const message of messages) {
|
|
299
|
+
if (!message.message) continue
|
|
251
300
|
|
|
252
|
-
|
|
301
|
+
console.log('🔔 Got new message', ':', message)
|
|
302
|
+
await sock.sendMessage(message.key.remoteJid, {
|
|
303
|
+
text: '👋🏻 Hello world'
|
|
304
|
+
})
|
|
305
|
+
}
|
|
306
|
+
})
|
|
307
|
+
}
|
|
253
308
|
|
|
254
|
-
|
|
255
|
-
|
|
309
|
+
connectToWhatsApp()
|
|
310
|
+
```
|
|
256
311
|
|
|
257
|
-
|
|
312
|
+
#### 🔐 Auth State
|
|
258
313
|
|
|
259
314
|
> [!NOTE]
|
|
260
315
|
> You can use the experimental `useSingleFileAuthState` and `useSqliteAuthState` as an alternative to `useMultiFileAuthState`. However, `useSingleFileAuthState` already includes an internal caching mechanism, so there is no need to wrap `state.keys` with `makeCacheableSignalKeyStore`.
|
|
261
316
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
`makeInMemoryStore` keeps chats, contacts, and messages in memory. For larger deployments,
|
|
265
|
-
use a persistent store appropriate to your application's memory and retention requirements.
|
|
266
|
-
|
|
267
|
-
Add this import and create the store **outside** `connectToWhatsApp()` in the quick-start example,
|
|
268
|
-
after the `logger` declaration, so reconnects reuse the same store:
|
|
269
|
-
|
|
270
|
-
```javascript
|
|
271
|
-
import { makeInMemoryStore } from "@violetix/baileys";
|
|
272
|
-
|
|
273
|
-
const storePath = "./store.json";
|
|
274
|
-
const store = makeInMemoryStore({ logger });
|
|
275
|
-
store.readFromFile(storePath);
|
|
276
|
-
|
|
277
|
-
// Create one persistence timer for the application, not one per reconnect.
|
|
278
|
-
setInterval(() => {
|
|
279
|
-
try {
|
|
280
|
-
store.writeToFile(storePath);
|
|
281
|
-
} catch (error) {
|
|
282
|
-
console.error("Failed to save the store:", error);
|
|
283
|
-
}
|
|
284
|
-
}, 180_000).unref();
|
|
285
|
-
```
|
|
317
|
+
### 🗄️ Implementing Data Store
|
|
286
318
|
|
|
287
|
-
|
|
288
|
-
|
|
319
|
+
> [!CAUTION]
|
|
320
|
+
> I highly recommend building your own data store, as keeping an entire chat history in memory can lead to excessive RAM usage.
|
|
289
321
|
|
|
290
322
|
```javascript
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
return message?.message;
|
|
295
|
-
},
|
|
296
|
-
```
|
|
323
|
+
import { makeWASocket, makeInMemoryStore, delay, DisconnectReason, useMultiFileAuthState } from '@itsliaaa/baileys'
|
|
324
|
+
import { Boom } from '@hapi/boom'
|
|
325
|
+
import pino from 'pino'
|
|
297
326
|
|
|
298
|
-
|
|
327
|
+
const myPhoneNumber = '6288888888888'
|
|
299
328
|
|
|
300
|
-
|
|
301
|
-
store.
|
|
329
|
+
// --- Create your store path
|
|
330
|
+
const storePath = './store.json'
|
|
302
331
|
|
|
303
|
-
|
|
304
|
-
console.log("Chats:", store.chats.all());
|
|
305
|
-
});
|
|
332
|
+
const logger = pino({ level: 'silent' })
|
|
306
333
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
334
|
+
const connectToWhatsApp = async () => {
|
|
335
|
+
const { state, saveCreds } = await useMultiFileAuthState('session')
|
|
336
|
+
|
|
337
|
+
const sock = makeWASocket({
|
|
338
|
+
logger,
|
|
339
|
+
auth: state
|
|
340
|
+
})
|
|
313
341
|
|
|
314
|
-
|
|
342
|
+
const store = makeInMemoryStore({
|
|
343
|
+
logger,
|
|
344
|
+
socket: sock
|
|
345
|
+
})
|
|
315
346
|
|
|
316
|
-
|
|
317
|
-
it is not a phone number and must not be converted into one by changing its suffix.
|
|
347
|
+
store.bind(sock.ev)
|
|
318
348
|
|
|
319
|
-
|
|
320
|
-
| --- | --- |
|
|
321
|
-
| User, addressed by phone number | `19999999999@s.whatsapp.net` |
|
|
322
|
-
| User, addressed by LID | `12699999999@lid` |
|
|
323
|
-
| Group | `123456789-123345@g.us` |
|
|
324
|
-
| Newsletter / channel | `120111111111111111@newsletter` |
|
|
325
|
-
| Meta AI | `11111111111@bot` |
|
|
326
|
-
| Broadcast list | `[timestamp of creation]@broadcast` |
|
|
327
|
-
| Status / stories | `status@broadcast` |
|
|
349
|
+
sock.ev.on('creds.update', saveCreds)
|
|
328
350
|
|
|
329
|
-
|
|
351
|
+
sock.ev.on('connection.update', (update) => {
|
|
352
|
+
const { connection, lastDisconnect } = update
|
|
353
|
+
if (connection === 'connecting' && !sock.authState.creds.registered) {
|
|
354
|
+
await delay(1500)
|
|
355
|
+
const code = await sock.requestPairingCode(myPhoneNumber)
|
|
356
|
+
console.log('🔗 Pairing code', ':', code)
|
|
357
|
+
}
|
|
358
|
+
else if (connection === 'close') {
|
|
359
|
+
const shouldReconnect = new Boom(connection?.lastDisconnect?.error)?.output?.statusCode !== DisconnectReason.loggedOut
|
|
360
|
+
console.log('⚠️ Connection closed because', lastDisconnect.error, ', reconnecting ', shouldReconnect)
|
|
361
|
+
if (shouldReconnect) {
|
|
362
|
+
connectToWhatsApp()
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
else if (connection === 'open') {
|
|
366
|
+
console.log('✅ Successfully connected to WhatsApp')
|
|
367
|
+
}
|
|
368
|
+
})
|
|
330
369
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
370
|
+
sock.ev.on('chats.upsert', () => {
|
|
371
|
+
console.log('✉️ Got chats', store.chats.all())
|
|
372
|
+
})
|
|
334
373
|
|
|
335
|
-
|
|
374
|
+
sock.ev.on('contacts.upsert', () => {
|
|
375
|
+
console.log('👥 Got contacts', Object.values(store.contacts))
|
|
376
|
+
})
|
|
336
377
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
you run more than a handful of sockets at once — a bug that costs one session a reconnect costs a
|
|
340
|
-
fleet an hour of flapping.
|
|
378
|
+
// --- Read store from file
|
|
379
|
+
store.readFromFile(storePath)
|
|
341
380
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
| **Housekeeping is not gated on presence** | The 24-hour `tcTokenKnownJids` prune only ran while `isOnline` was true, and `isOnline` is only ever set by `sendPresenceUpdate`. A bot that never marks itself online never pruned anything. |
|
|
348
|
-
| **One failing socket cannot take the host down** | A socket that failed to open, and an unhandled rejection out of `end()` mid-teardown, killed the whole process — and with it every other session sharing it. |
|
|
349
|
-
| **Signal writes persist before success** | Key-store writes are awaited, transaction contexts are isolated per auth store, and session deletion is reflected immediately. Close still waits for the key-store flush barrier. |
|
|
350
|
-
| **The offline queue drains fully** | Baileys asked for one `offline_batch` of 100 stanzas and never asked for another, so a larger backlog stayed on the server and grew on every reconnect. |
|
|
381
|
+
// --- Save store every 3 minutes
|
|
382
|
+
setInterval(() => {
|
|
383
|
+
store.writeToFile(storePath)
|
|
384
|
+
}, 180000)
|
|
385
|
+
}
|
|
351
386
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
and the sections after it.
|
|
387
|
+
connectToWhatsApp()
|
|
388
|
+
```
|
|
355
389
|
|
|
356
|
-
|
|
390
|
+
### 🪪 WhatsApp IDs Explain
|
|
357
391
|
|
|
358
|
-
|
|
359
|
-
-
|
|
360
|
-
-
|
|
361
|
-
-
|
|
362
|
-
-
|
|
363
|
-
-
|
|
364
|
-
-
|
|
365
|
-
- 🔍 Parsed the USync fields that were previously left as TODOs: per-protocol errors with backoff, cache `refresh` hints, `side_list`, per-contact privacy tokens, and blocked-by-contact detection.
|
|
366
|
-
- 🆔 Fixed the USync username parser, which returned `null` for the `Uint8Array` payloads the binary decoder actually produces.
|
|
367
|
-
- 📥 Drained the whole offline queue on reconnect. Baileys requested a single `offline_batch` of 100 stanzas and never asked for another, so any larger backlog stayed on the server and grew on every reconnect.
|
|
368
|
-
- 📣 Fanned out sends to broadcast lists (`<id>@broadcast`) over a sender key, using the same `statusJidList` option as status posts for the recipient list.
|
|
369
|
-
- 🔑 Surfaced `keyRequired` from `onWhatsAppUsername()` when the server withholds the account until the 4-digit username key is supplied; previously such rows were dropped.
|
|
370
|
-
- 🔔 Emitted `username.update` (a contact set or removed their `@username`), `lid-mapping.update` (a contact's LID rotated; the known phone number is carried over), and `privacy.update` (privacy settings changed on the phone) from server notifications.
|
|
371
|
-
- 🙈 Skipped placeholder resend requests for `<unavailable/>` messages WhatsApp marks as unrecoverable (`<bot/>`, `hosted="true"`, `type="view_once"`); the previous check compared against attribute values the server never sends.
|
|
372
|
-
- 🪪 Recognised own LID / hosted devices as `fromMe` in status posts and group notifications, and read `remoteJidUsername` from the `username` attribute on 1:1 messages.
|
|
373
|
-
- 📌 Requested `fetch_pinned_messages` on `newsletterMetadata()`, so pinned posts come back with the metadata.
|
|
374
|
-
- 🎞️ Attached the `streamingSidecar` WhatsApp Web sends with video and audio uploads, so recipients can seek and play while downloading. Skipped for mp4 files that are not faststart (`mdat` before `moov`), where a sidecar would make playback fail instead of falling back to a plain download.
|
|
375
|
-
- 🕒 Stamped `disappearingMode` (and `ephemeralSettingTimestamp` when passed via `sendMessage` options) on ephemeral messages, matching WhatsApp Web; without it the peer warns the message will not disappear.
|
|
376
|
-
- 🗳️ Added `decryptPollVoteWithFallback()` / `decryptEventResponseWithFallback()`, which try the poll or event creator's PN and LID forms; voters encrypt with whichever form of the creator JID they hold. Event responses now use it internally.
|
|
377
|
-
- 🆔 Username lookups (`onWhatsAppUsername()`) request LID addressing, as WhatsApp Web does; `USyncQuery.withContactProtocol('lid' | 'pn')` exposes the switch.
|
|
378
|
-
- 🗳️ Poll votes are decrypted again inside `processMessage` and surfaced as `pollUpdates` on `messages.update` (like Baileys v6.4 did), trying the creator's PN and LID forms. Requires `getMessage` to return the poll creation message.
|
|
379
|
-
- 🧾 `hideVoter` / `canAddOption` polls go out as `pollCreationMessageV6`, the only version that carries those flags.
|
|
380
|
-
- 🧠 History sync chunks are decoded one conversation at a time instead of materialising the whole `HistorySync` tree, cutting peak memory on large syncs. Output is byte-identical to the previous path.
|
|
381
|
-
- 🔢 `version` accepts a resolver function, and a `405 client_too_old` failure fetches the live WA Web build and applies it on the next reconnect. `fetchLatestWaWebVersion()` now times out after 10s (`timeoutMs` / `signal` options).
|
|
382
|
-
- 🔐 Passkey-gated (Shortcake) accounts are surfaced: `connection.update { passkeyRequired: true }` plus a warning when the server sends `passkey_prologue_request`. Expired pairing codes (`refresh_code`) are re-registered automatically with the same code, or surfaced as `connection.update { pairingCodeExpired: true }`.
|
|
383
|
-
- 🏢 `onWhatsAppUsername()` also reports `isBusiness` / `pnJid`; the USync business parser treats a `<error/>` child as "not a business" instead of failing the whole query, and `withBusinessProtocol(null)` asks for the verified name only.
|
|
384
|
-
- 🖼️ Added [image polls](#%EF%B8%8F-image-poll): `sendMessage(jid, { imagePoll })` uploads one image per option, hashes each option over its uploaded `fileSha256`, sends the `pollCreationMessageV3` parent with `pollContentType: IMAGE`, then one `pollCreationOptionImageMessage` child per option associated back by `MEDIA_POLL`. `hashImagePollOption()` is exported separately. Ported from [`@rennzsync/baileys`](https://github.com/RennZSync/baileys).
|
|
385
|
-
- 🧩 Added [A2UI widgets](#-a2ui-widget): `sendMessage(jid, { a2ui })` with a declarative builder (`Text`, `Image`, `Video`, `Button`, `Card`, `Column`, `Row`, `Divider`, `CheckBox`, `TextField`, `ChoicePicker`, plus `listCard`) compiled into `interactiveMessage.bloksWidget`. Ported from [`@rennzsync/baileys`](https://github.com/RennZSync/baileys), rebuilt on this fork's own interactive path so the `<biz>` node and button shapes are the existing ones.
|
|
386
|
-
- 🙊 Added the [`exclusive`](#-exclusive-message) send option: a group message addressed to a single member (`to=<group> participant=<member>`, per-device encryption instead of the group sender key), so no other member receives the stanza. The recipient comes from the quoted message's author, or from an explicit jid.
|
|
387
|
-
- 🚫 Added [`sock.ignoreKey()`](#-ignoring-inbound-stanzas): drops matching inbound stanzas before any handler — including the decryption and persistence paths — while still acking so the server stops redelivering. Matches by `remoteJid` / `fromMe` / `id` / `participant` (PN ↔ LID alt attributes included) or by predicate, over `message`, `receipt`, `notification`, `presence`, `chatstate` and `call`. `category='peer'` traffic from your own devices is never dropped, so an app-state key share cannot be filtered away by accident.
|
|
388
|
-
- 🛡️ Added [`createAnchorGuard()`](#%EF%B8%8F-anchor-guard) / `detectBug()`: flags payloads that force-close WhatsApp clients — invisible and combining character floods, mention bombs, oversized native-flow / list / carousel payloads, broken `buttonParamsJson`, over-deep or circular structures — then deletes them and optionally blocks the sender or kicks on burst. Ported from [`@rexxhayanasi/elaina-anchorguard`](https://www.npmjs.com/package/@rexxhayanasi/elaina-anchorguard) (MIT) via [`@rennzsync/baileys`](https://github.com/RennZSync/baileys).
|
|
389
|
-
- 🗓️ Sent `encEventResponseMessage` and `EVENT_EDIT` secrets as `type=event`. Only `eventMessage` was matched, so event responses went out as `type=text` — a pairing a real client never sends, and the server validates stanza shape.
|
|
390
|
-
- 🧾 Stamped `mediatype=group_history` on `messageHistoryBundle` sends, which previously carried no media type at all.
|
|
391
|
-
- 🔑 `useMultiFileAuthState(folder, logger)` and `useSingleFileAuthState(file, logger)` accept a logger. Credential write failures were swallowed entirely (the internal logger was hard-wired to `null`), so a full disk or a permission error lost the session and looked like a random logout on the next boot. Corrupt or unreadable key files are reported too, and `_destroy()` releases the process exit hooks a long-lived multi-session host would otherwise leak.
|
|
392
|
-
|
|
393
|
-
## 📨 Messages Handling & Compatibility
|
|
392
|
+
`id` is the WhatsApp ID, called `jid` and `lid` too, of the person or group you're sending the message to.
|
|
393
|
+
- It must be in the format `[country code][phone number]@s.whatsapp.net`
|
|
394
|
+
- Example for people: `19999999999@s.whatsapp.net` and `12699999999@lid`.
|
|
395
|
+
- For groups, it must be in the format `123456789-123345@g.us`.
|
|
396
|
+
- For Meta AI, it's `11111111111@bot`.
|
|
397
|
+
- For broadcast lists, it's `[timestamp of creation]@broadcast`.
|
|
398
|
+
- For stories, the ID is `status@broadcast`.
|
|
394
399
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
- 🎞️ [Status Mention Message](#%EF%B8%8F-status-mention)
|
|
400
|
-
- 📦 [Sticker Pack Message](#-sticker-pack)
|
|
401
|
-
- 🖼️ [Image Poll](#%EF%B8%8F-image-poll)
|
|
402
|
-
- 🧩 [A2UI Widget](#-a2ui-widget)
|
|
403
|
-
- ✨ [Rich Response Message](#-rich-response)
|
|
404
|
-
- 🧾 [Message with Code Blocks](#-message-with-code-block)
|
|
405
|
-
- [🌏 Message with Inline Entities](#-message-with-inline-entities)
|
|
406
|
-
- 📋 [Message with Table](#-message-with-table)
|
|
407
|
-
- 💳 [Payment-related Message](#-sending-payment-messages) (payment requests, invites, orders, invoices).
|
|
408
|
-
- 📰 Simplified sending messages with ad thumbnail using [`externalAdReply`](#-external-ad-reply), without requiring manual `contextInfo`.
|
|
409
|
-
- 💭 Added support for quoting messages inside channel (newsletter).
|
|
410
|
-
- 🎀 Added support for [custom button icon](#%EF%B8%8F-interactive).
|
|
411
|
-
|
|
412
|
-
## 🧩 Additional Message Options
|
|
413
|
-
|
|
414
|
-
- 👁️ Added optional boolean flags for message handling:
|
|
415
|
-
- 🤖 [`ai`](#-ai-icon) - AI icon on message
|
|
416
|
-
- 📣 [`mentionAll`](#-mention) - Mention all group participants without requiring their JIDs in `mentions` or `mentionedJid`
|
|
417
|
-
- 🔧 [`ephemeral`](#-ephemeral), [`groupStatus`](#%E2%80%8D%E2%80%8D-group-status), [`isLottie`](#-lottie-sticker), [`spoiler`](#-spoiler), [`viewOnce`](#%EF%B8%8F-view-once), [`viewOnceV2`](#%EF%B8%8F-view-once-v2), [`viewOnceV2Extension`](#%EF%B8%8F-view-once-v2-extension), [`interactiveAsTemplate`](#%EF%B8%8F-interactive) - Message wrappers
|
|
418
|
-
- 🔒 [`secureMetaServiceLabel`](#%EF%B8%8F-secure-meta-service-label) - Secure meta service label on message
|
|
419
|
-
- 🙊 [`exclusive`](#-exclusive-message) - Send into a group addressed to one member only
|
|
420
|
-
- 📄 [`raw`](#-raw) - Build your message manually **(DO NOT USE FOR EXPLOITATION)**
|
|
421
|
-
- 🎞️ [`statusPrivacy`](#%EF%B8%8F-status-mention) - Control who receives a status broadcast (`contacts` | `allowlist` | `denylist`)
|
|
422
|
-
|
|
423
|
-
## 🆕 WhatsApp Protocol Extensions
|
|
424
|
-
|
|
425
|
-
Support for WhatsApp features that upstream Baileys does not expose yet.
|
|
426
|
-
|
|
427
|
-
| Feature | What it does | Reference |
|
|
428
|
-
| ------------------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------- |
|
|
429
|
-
| 🆔 **Username** | Look up accounts by `@username`, and claim / change / remove your own | [Username Management](#-username-management) |
|
|
430
|
-
| 🔍 **USync protocols** | Business profile, profile picture, About text, side list, and device feature queries | [USync Queries](#-usync-queries) |
|
|
431
|
-
| 🔐 **MEX privacy** | Privacy settings, contact allow/deny lists, About text, contact integrity checks | [Privacy Management](#-privacy-management) |
|
|
432
|
-
| 🤝 **Interoperability** | Cross-platform chats and groups with BirdyChat and Haiket | [Interoperability](#-interoperability-birdychat--haiket) |
|
|
433
|
-
| 🔒 **Account security** | Account password and passkey (FIDO2 / WebAuthn) management | [Account Security](#-account-security-password--passkey) |
|
|
434
|
-
| 👪 **Managed accounts** | Parental / family account linking, payments passkey, UPI onboarding | [Managed Accounts](#-managed-accounts--payments) |
|
|
435
|
-
| 🌐 **HTTPS GraphQL** | Meta AI memory, Imagine image/video generation, AI personas, events, payments | [HTTPS GraphQL](#-https-graphql-meta-ai--imagine) |
|
|
436
|
-
| 🤖 **Meta AI decryption** | Decrypts `msmsg` (`messageSecret`-encrypted) Meta AI bot replies | — |
|
|
437
|
-
| 📞 **Call details** | `callKey` (raw SRTP key), audio/video codecs, group roster, call-link waiting room | [Events](#-events) |
|
|
438
|
-
| 📰 **Newsletter status** | `newsletter.status` event for server-pushed channel posts, with engagement counters | [Events](#-events) |
|
|
439
|
-
| 🪪 **LID fallback** | Recovers the phone number for senders who only expose a `@lid` (e.g. username users) | [WhatsApp IDs Explain](#-whatsapp-ids-explain) |
|
|
440
|
-
|
|
441
|
-
> [!WARNING]
|
|
442
|
-
> These features rely on WhatsApp's internal MEX (GraphQL-over-WebSocket) and HTTPS GraphQL protocols. The numeric query IDs were captured from a specific WhatsApp client version and **may stop working after a WhatsApp update** — a rejected query usually means the ID is stale, not that the code is broken.
|
|
400
|
+
> [!IMPORTANT]
|
|
401
|
+
> Senders who set a WhatsApp [username](#-username-management) arrive LID-addressed, and WhatsApp sends **no** phone number alongside them. This fork recovers the phone number from the local LID↔PN mapping and fills in `key.remoteJidAlt` (or `key.participantAlt` in groups). **[NEW]**
|
|
402
|
+
>
|
|
403
|
+
> That recovery only works once a mapping exists — from history sync, group metadata, or an earlier chat. On a first-ever contact from a username user there is genuinely no phone number to recover, so **handle `@lid` natively** rather than assuming a phone number is always available.
|
|
443
404
|
|
|
444
|
-
|
|
405
|
+
### ✉️ Sending Messages
|
|
445
406
|
|
|
446
407
|
> [!NOTE]
|
|
447
|
-
>
|
|
448
|
-
> `message.key.remoteJid`; `message` is the received message used when quoting or replying.
|
|
449
|
-
> Replace sample IDs and media paths with your own values. Await `sock.sendMessage(...)`
|
|
450
|
-
> inside your async handler when you need to handle send errors.
|
|
408
|
+
> You can get the `jid` from `message.key.remoteJid` in the first example.
|
|
451
409
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
```javascript
|
|
455
|
-
import fs from "node:fs";
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
### 🔠 Text
|
|
410
|
+
#### 🔠 Text
|
|
459
411
|
|
|
460
412
|
```javascript
|
|
461
413
|
// --- Send a regular text message
|
|
462
|
-
sock.sendMessage(
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
{
|
|
468
|
-
quoted: message,
|
|
469
|
-
},
|
|
470
|
-
);
|
|
414
|
+
sock.sendMessage(jid, {
|
|
415
|
+
text: '👋🏻 Hello'
|
|
416
|
+
}, {
|
|
417
|
+
quoted: message
|
|
418
|
+
})
|
|
471
419
|
|
|
472
420
|
// --- Send a text message with a link preview
|
|
473
|
-
const urlA =
|
|
421
|
+
const urlA = 'https://www.npmjs.com/package/@itsliaaa/baileys'
|
|
474
422
|
|
|
475
423
|
sock.sendMessage(jid, {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
})
|
|
424
|
+
text: urlA + ' 👆🏻 Check it out!',
|
|
425
|
+
linkPreview: {
|
|
426
|
+
'matched-text': urlA,
|
|
427
|
+
title: '🌱 @itsliaaa/baileys',
|
|
428
|
+
description: 'Underrated Baileys Fork',
|
|
429
|
+
previewType: 0, // --- Use 1 for video playback in the link preview
|
|
430
|
+
jpegThumbnail: fs.readFileSync('./path/to/image.jpg')
|
|
431
|
+
}
|
|
432
|
+
})
|
|
485
433
|
|
|
486
434
|
// --- Send a text message with a large link preview and favicon
|
|
487
|
-
import { prepareWAMessageMedia } from
|
|
488
|
-
|
|
489
|
-
const urlB =
|
|
490
|
-
|
|
491
|
-
const { imageMessage: image } = await prepareWAMessageMedia(
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
mediaTypeOverride: "thumbnail-link",
|
|
500
|
-
},
|
|
501
|
-
);
|
|
435
|
+
import { prepareWAMessageMedia } from '@itsliaaa/baileys'
|
|
436
|
+
|
|
437
|
+
const urlB = 'https://www.npmjs.com/package/@itsliaaa/baileys#readme'
|
|
438
|
+
|
|
439
|
+
const { imageMessage: image } = await prepareWAMessageMedia({
|
|
440
|
+
image: {
|
|
441
|
+
url: './path/to/image.jpg'
|
|
442
|
+
}
|
|
443
|
+
}, {
|
|
444
|
+
upload: sock.waUploadToServer,
|
|
445
|
+
mediaTypeOverride: 'thumbnail-link'
|
|
446
|
+
})
|
|
502
447
|
|
|
503
448
|
// --- Set the thumbnail display size
|
|
504
|
-
image.height = 720
|
|
505
|
-
image.width = 480
|
|
449
|
+
image.height = 720
|
|
450
|
+
image.width = 480
|
|
506
451
|
|
|
507
452
|
sock.sendMessage(jid, {
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
})
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
|
|
453
|
+
text: urlB + ' 👆🏻 Check it out!',
|
|
454
|
+
linkPreview: {
|
|
455
|
+
'matched-text': urlB,
|
|
456
|
+
title: '🌱 @itsliaaa/baileys',
|
|
457
|
+
description: 'Underrated Baileys Fork',
|
|
458
|
+
previewType: 0,
|
|
459
|
+
jpegThumbnail: fs.readFileSync('./path/to/image.jpg'),
|
|
460
|
+
highQualityThumbnail: image,
|
|
461
|
+
linkPreviewMetadata: {
|
|
462
|
+
linkMediaDuration: 0, // --- Duration in seconds (for video/audio content)
|
|
463
|
+
socialMediaPostType: 1, // --- Enum: 0 = NONE, 1 = REEL, 2 = LIVE_VIDEO, 3 = LONG_VIDEO, 4 = SINGLE_IMAGE, 5 = CAROUSEL
|
|
464
|
+
} // --- Additional metadata for large link preview
|
|
465
|
+
},
|
|
466
|
+
favicon: {
|
|
467
|
+
url: './path/to/tiny-image.ico'
|
|
468
|
+
}
|
|
469
|
+
})
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
#### 🔔 Mention
|
|
528
473
|
|
|
529
474
|
```javascript
|
|
530
475
|
// --- Regular mention
|
|
531
|
-
sock.sendMessage(
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
{
|
|
538
|
-
quoted: message,
|
|
539
|
-
},
|
|
540
|
-
);
|
|
476
|
+
sock.sendMessage(jid, {
|
|
477
|
+
text: '👋🏻 Hello @628123456789',
|
|
478
|
+
mentions: ['628123456789@s.whatsapp.net']
|
|
479
|
+
}, {
|
|
480
|
+
quoted: message
|
|
481
|
+
})
|
|
541
482
|
|
|
542
483
|
// --- Mention all
|
|
543
|
-
sock.sendMessage(
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
{
|
|
550
|
-
quoted: message,
|
|
551
|
-
},
|
|
552
|
-
);
|
|
484
|
+
sock.sendMessage(jid, {
|
|
485
|
+
text: '👋🏻 Hello @all',
|
|
486
|
+
mentionAll: true
|
|
487
|
+
}, {
|
|
488
|
+
quoted: message
|
|
489
|
+
})
|
|
553
490
|
```
|
|
554
491
|
|
|
555
|
-
|
|
492
|
+
#### 😁 Reaction
|
|
556
493
|
|
|
557
494
|
```javascript
|
|
558
495
|
sock.sendMessage(jid, {
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
})
|
|
496
|
+
react: {
|
|
497
|
+
key: message.key,
|
|
498
|
+
text: '✨'
|
|
499
|
+
}
|
|
500
|
+
})
|
|
564
501
|
```
|
|
565
502
|
|
|
566
|
-
|
|
503
|
+
#### 📌 Pin Message
|
|
567
504
|
|
|
568
505
|
```javascript
|
|
569
506
|
sock.sendMessage(jid, {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
})
|
|
507
|
+
pin: message.key,
|
|
508
|
+
time: 86400, // --- Set the value in seconds: 86400 (1d), 604800 (7d), or 2592000 (30d)
|
|
509
|
+
type: 1 // --- Or 2 to remove
|
|
510
|
+
})
|
|
574
511
|
```
|
|
575
512
|
|
|
576
|
-
|
|
513
|
+
#### 🔖 Keep Chat
|
|
577
514
|
|
|
578
515
|
> [!NOTE]
|
|
579
516
|
> Keep Chat can only be used in chats or groups with disappearing messages enabled.
|
|
580
517
|
|
|
581
518
|
```javascript
|
|
582
519
|
sock.sendMessage(jid, {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
})
|
|
520
|
+
keep: message.key,
|
|
521
|
+
type: 1 // --- Or 2 to remove
|
|
522
|
+
})
|
|
586
523
|
```
|
|
587
524
|
|
|
588
|
-
|
|
525
|
+
#### ➡️ Forward Message
|
|
589
526
|
|
|
590
527
|
```javascript
|
|
591
528
|
sock.sendMessage(jid, {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
})
|
|
529
|
+
forward: message,
|
|
530
|
+
force: true // --- Optional
|
|
531
|
+
})
|
|
595
532
|
```
|
|
596
533
|
|
|
597
|
-
|
|
534
|
+
#### 👤 Contact
|
|
598
535
|
|
|
599
536
|
```javascript
|
|
600
|
-
const vcard =
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
"END:VCARD";
|
|
537
|
+
const vcard = 'BEGIN:VCARD\n'
|
|
538
|
+
+ 'VERSION:3.0\n'
|
|
539
|
+
+ 'FN:Lia Wynn\n'
|
|
540
|
+
+ 'ORG:Waitress;\n'
|
|
541
|
+
+ 'TEL;type=CELL;type=VOICE;waid=628123456789:+62 8123 4567 89\n'
|
|
542
|
+
+ 'END:VCARD'
|
|
607
543
|
|
|
608
|
-
sock.sendMessage(
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
},
|
|
619
|
-
);
|
|
544
|
+
sock.sendMessage(jid, {
|
|
545
|
+
contacts: {
|
|
546
|
+
displayName: 'Lia Wynn',
|
|
547
|
+
contacts: [
|
|
548
|
+
{ vcard }
|
|
549
|
+
]
|
|
550
|
+
}
|
|
551
|
+
}, {
|
|
552
|
+
quoted: message
|
|
553
|
+
})
|
|
620
554
|
```
|
|
621
555
|
|
|
622
|
-
|
|
556
|
+
#### 📍 Location
|
|
623
557
|
|
|
624
558
|
```javascript
|
|
625
|
-
sock.sendMessage(
|
|
626
|
-
|
|
627
|
-
{
|
|
628
|
-
location: {
|
|
559
|
+
sock.sendMessage(jid, {
|
|
560
|
+
location: {
|
|
629
561
|
degreesLatitude: 24.121231,
|
|
630
562
|
degreesLongitude: 55.1121221,
|
|
631
|
-
name:
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
event: {
|
|
647
|
-
name: "🎶 Meet & Mingle Party",
|
|
648
|
-
description:
|
|
649
|
-
"Meet & Mingle Party is a fun, casual gathering to connect, chat, and build new relationships within the community.",
|
|
650
|
-
call: "audio", // --- Or "video", this field is optional
|
|
563
|
+
name: '👋🏻 I am here'
|
|
564
|
+
}
|
|
565
|
+
}, {
|
|
566
|
+
quoted: message
|
|
567
|
+
})
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
#### 🗓️ Event
|
|
571
|
+
|
|
572
|
+
```javascript
|
|
573
|
+
sock.sendMessage(jid, {
|
|
574
|
+
event: {
|
|
575
|
+
name: '🎶 Meet & Mingle Party',
|
|
576
|
+
description: 'Meet & Mingle Party is a fun, casual gathering to connect, chat, and build new relationships within the community.',
|
|
577
|
+
call: 'audio', // --- Or "video", this field is optional
|
|
651
578
|
startDate: new Date(Date.now() + 3600000),
|
|
652
579
|
endDate: new Date(Date.now() + 28800000),
|
|
653
580
|
isCancelled: false, // --- Optional
|
|
654
581
|
isScheduleCall: false, // --- Optional
|
|
655
582
|
extraGuestsAllowed: false, // --- Optional
|
|
656
583
|
location: {
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
},
|
|
666
|
-
);
|
|
584
|
+
name: 'Jakarta',
|
|
585
|
+
degreesLatitude: -6.2,
|
|
586
|
+
degreesLongitude: 106.8
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}, {
|
|
590
|
+
quoted: message
|
|
591
|
+
})
|
|
667
592
|
```
|
|
668
593
|
|
|
669
|
-
|
|
594
|
+
#### 👥 Group Invite
|
|
670
595
|
|
|
671
596
|
```javascript
|
|
672
|
-
const inviteCode = groupUrl
|
|
597
|
+
const inviteCode = groupUrl
|
|
598
|
+
.split('chat.whatsapp.com/')[1]
|
|
599
|
+
?.split('?')[0]
|
|
673
600
|
|
|
674
|
-
const groupJid =
|
|
675
|
-
const groupName =
|
|
601
|
+
const groupJid = '1201111111111@g.us'
|
|
602
|
+
const groupName = '@itsliaaa/baileys'
|
|
676
603
|
|
|
677
|
-
sock.sendMessage(
|
|
678
|
-
|
|
679
|
-
{
|
|
680
|
-
groupInvite: {
|
|
604
|
+
sock.sendMessage(jid, {
|
|
605
|
+
groupInvite: {
|
|
681
606
|
inviteCode,
|
|
682
607
|
inviteExpiration: Date.now() + 86400000,
|
|
683
|
-
text:
|
|
608
|
+
text: '👋🏻 Hello, we invite you to join our group.',
|
|
684
609
|
jid: groupJid,
|
|
685
610
|
subject: groupName,
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
},
|
|
691
|
-
);
|
|
611
|
+
}
|
|
612
|
+
}, {
|
|
613
|
+
quoted: message
|
|
614
|
+
})
|
|
692
615
|
```
|
|
693
616
|
|
|
694
|
-
|
|
617
|
+
#### 🛍️ Product
|
|
695
618
|
|
|
696
619
|
```javascript
|
|
697
|
-
import { randomUUID } from
|
|
620
|
+
import { randomUUID } from 'crypto'
|
|
698
621
|
|
|
699
622
|
sock.sendMessage(jid, {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
})
|
|
718
|
-
```
|
|
719
|
-
|
|
720
|
-
|
|
623
|
+
image: {
|
|
624
|
+
url: './path/to/image.jpg'
|
|
625
|
+
},
|
|
626
|
+
body: '👋🏻 Check my product here!',
|
|
627
|
+
footer: '@itsliaaa/baileys',
|
|
628
|
+
product: {
|
|
629
|
+
currencyCode: 'IDR',
|
|
630
|
+
description: '🛍️ Interesting product!',
|
|
631
|
+
priceAmount1000: 70_000_000,
|
|
632
|
+
productId: randomUUID(),
|
|
633
|
+
productImageCount: 1,
|
|
634
|
+
salePriceAmount1000: 65_000_000,
|
|
635
|
+
signedUrl: 'https://www.npmjs.com/package/@itsliaaa/baileys',
|
|
636
|
+
title: '📦 Starseed (Premium)',
|
|
637
|
+
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
|
|
638
|
+
},
|
|
639
|
+
businessOwnerJid: '0@s.whatsapp.net'
|
|
640
|
+
})
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
#### 📊 Poll
|
|
721
644
|
|
|
722
645
|
```javascript
|
|
723
646
|
// --- Regular poll message
|
|
@@ -764,14 +687,14 @@ sock.sendMessage(jid, {
|
|
|
764
687
|
quoted: message
|
|
765
688
|
})
|
|
766
689
|
|
|
767
|
-
// --- Poll update
|
|
690
|
+
// --- Poll update
|
|
768
691
|
sock.sendMessage(jid, {
|
|
769
692
|
pollUpdate: {
|
|
770
693
|
metadata: {},
|
|
771
694
|
key: message.key,
|
|
772
695
|
vote: {
|
|
773
|
-
|
|
774
|
-
encPayload:
|
|
696
|
+
enclv: /* <Buffer> */,
|
|
697
|
+
encPayload: /* <Buffer> */
|
|
775
698
|
}
|
|
776
699
|
}
|
|
777
700
|
}, {
|
|
@@ -779,100 +702,60 @@ sock.sendMessage(jid, {
|
|
|
779
702
|
})
|
|
780
703
|
```
|
|
781
704
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
A poll whose options are images instead of text.
|
|
705
|
+
#### 💭 Button Response
|
|
785
706
|
|
|
786
707
|
```javascript
|
|
708
|
+
// --- Using buttonsResponseMessage
|
|
787
709
|
sock.sendMessage(jid, {
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
{ name: 'Gambar 1', image: { url: 'https://example.com/1.jpg' } },
|
|
793
|
-
{ name: 'Gambar 2', image: { url: 'https://example.com/2.jpg' } }
|
|
794
|
-
]
|
|
710
|
+
type: 'plain',
|
|
711
|
+
buttonReply: {
|
|
712
|
+
id: '#Menu',
|
|
713
|
+
displayText: '✨ Interesting Menu'
|
|
795
714
|
}
|
|
796
715
|
}, {
|
|
797
716
|
quoted: message
|
|
798
717
|
})
|
|
799
|
-
```
|
|
800
|
-
|
|
801
|
-
Each option's image is uploaded first, because the option hash covers the uploaded media's `fileSha256` — `sha256(hex(sha256(name)) + base64(fileSha256))`, exported as `hashImagePollOption(name, fileSha256)` if you need it on its own. The parent goes out as `pollCreationMessageV3` with `pollContentType: IMAGE` carrying only the names and hashes; the images follow as one `pollCreationOptionImageMessage` each, tied back to the parent by a `MEDIA_POLL` association (the same mechanism albums use). A vote carries the hash, not the name.
|
|
802
|
-
|
|
803
|
-
> [!WARNING]
|
|
804
|
-
> This is a client-side implementation of a message type WhatsApp's proto defines but no Baileys fork ships a builder for. Treat it as experimental and check how it renders on your target client before relying on it.
|
|
805
|
-
|
|
806
|
-
### 💭 Button Response
|
|
807
|
-
|
|
808
|
-
```javascript
|
|
809
|
-
// --- Using buttonsResponseMessage
|
|
810
|
-
sock.sendMessage(
|
|
811
|
-
jid,
|
|
812
|
-
{
|
|
813
|
-
type: "plain",
|
|
814
|
-
buttonReply: {
|
|
815
|
-
id: "#Menu",
|
|
816
|
-
displayText: "✨ Interesting Menu",
|
|
817
|
-
},
|
|
818
|
-
},
|
|
819
|
-
{
|
|
820
|
-
quoted: message,
|
|
821
|
-
},
|
|
822
|
-
);
|
|
823
718
|
|
|
824
719
|
// --- Using interactiveResponseMessage
|
|
825
|
-
sock.sendMessage(
|
|
826
|
-
|
|
827
|
-
{
|
|
828
|
-
flowReply: {
|
|
720
|
+
sock.sendMessage(jid, {
|
|
721
|
+
flowReply: {
|
|
829
722
|
format: 0,
|
|
830
|
-
text:
|
|
831
|
-
name:
|
|
723
|
+
text: '💭 Response',
|
|
724
|
+
name: 'menu_options',
|
|
832
725
|
paramsJson: JSON.stringify({
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
})
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
},
|
|
841
|
-
);
|
|
726
|
+
id: '#Menu',
|
|
727
|
+
description: '✨ Interesting Menu'
|
|
728
|
+
})
|
|
729
|
+
}
|
|
730
|
+
}, {
|
|
731
|
+
quoted: message
|
|
732
|
+
})
|
|
842
733
|
|
|
843
734
|
// --- Using listResponseMessage
|
|
844
|
-
sock.sendMessage(
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
{
|
|
854
|
-
quoted: message,
|
|
855
|
-
},
|
|
856
|
-
);
|
|
735
|
+
sock.sendMessage(jid, {
|
|
736
|
+
listReply: {
|
|
737
|
+
title: '📄 See More',
|
|
738
|
+
description: '✨ Interesting Menu',
|
|
739
|
+
id: '#Menu'
|
|
740
|
+
}
|
|
741
|
+
}, {
|
|
742
|
+
quoted: message
|
|
743
|
+
})
|
|
857
744
|
|
|
858
745
|
// --- Using templateButtonReplyMessage
|
|
859
|
-
sock.sendMessage(
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
);
|
|
873
|
-
```
|
|
874
|
-
|
|
875
|
-
### ✨ Rich Response
|
|
746
|
+
sock.sendMessage(jid, {
|
|
747
|
+
type: 'template',
|
|
748
|
+
buttonReply: {
|
|
749
|
+
id: '#Menu',
|
|
750
|
+
displayText: '✨ Interesting Menu',
|
|
751
|
+
index: 1
|
|
752
|
+
}
|
|
753
|
+
}, {
|
|
754
|
+
quoted: message
|
|
755
|
+
})
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
#### ✨ Rich Response
|
|
876
759
|
|
|
877
760
|
> [!NOTE]
|
|
878
761
|
> `richResponse[]` is a representation of [`submessages[]`](https://baileys.wiki/docs/api/namespaces/proto/interfaces/IAIRichResponseSubMessage) inside `richResponseMessage`.
|
|
@@ -883,955 +766,778 @@ sock.sendMessage(
|
|
|
883
766
|
|
|
884
767
|
```javascript
|
|
885
768
|
sock.sendMessage(jid, {
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
items: ["Engine", "V8 (C++)", "JavaScriptCore (C++)", "V8 (C++)"],
|
|
916
|
-
},
|
|
917
|
-
{
|
|
918
|
-
isHeading: false,
|
|
919
|
-
items: ["Performance", "4/5", "5/5", "4/5"],
|
|
920
|
-
},
|
|
921
|
-
],
|
|
922
|
-
},
|
|
923
|
-
{
|
|
924
|
-
text: "Does this help clarify the differences?",
|
|
925
|
-
},
|
|
926
|
-
],
|
|
927
|
-
});
|
|
769
|
+
disclaimerText: 'RAW submessages structure example',
|
|
770
|
+
richResponse: [{
|
|
771
|
+
text: 'Example Usage',
|
|
772
|
+
}, {
|
|
773
|
+
language: 'javascript',
|
|
774
|
+
code: [{
|
|
775
|
+
highlightType: 0,
|
|
776
|
+
codeContent: 'console.log("Hello, World!")'
|
|
777
|
+
}]
|
|
778
|
+
}, {
|
|
779
|
+
text: 'Pretty simple, right?\n'
|
|
780
|
+
}, {
|
|
781
|
+
text: 'Comparison between Node.js, Bun, and Deno',
|
|
782
|
+
}, {
|
|
783
|
+
title: 'Runtime Comparison',
|
|
784
|
+
table: [{
|
|
785
|
+
isHeading: true,
|
|
786
|
+
items: ['', 'Node.js', 'Bun', 'Deno']
|
|
787
|
+
}, {
|
|
788
|
+
isHeading: false,
|
|
789
|
+
items: ['Engine', 'V8 (C++)', 'JavaScriptCore (C++)', 'V8 (C++)']
|
|
790
|
+
}, {
|
|
791
|
+
isHeading: false,
|
|
792
|
+
items: ['Performance', '4/5', '5/5', '4/5']
|
|
793
|
+
}]
|
|
794
|
+
}, {
|
|
795
|
+
text: 'Does this help clarify the differences?'
|
|
796
|
+
}]
|
|
797
|
+
})
|
|
928
798
|
```
|
|
929
799
|
|
|
930
800
|
> [!TIP]
|
|
931
801
|
> You can easily add syntax highlighting by importing `tokenizeCode` directly from Baileys.
|
|
932
802
|
|
|
933
803
|
```javascript
|
|
934
|
-
import { tokenizeCode } from
|
|
804
|
+
import { tokenizeCode } from '@itsliaaa/baileys'
|
|
935
805
|
|
|
936
|
-
const language =
|
|
937
|
-
const code = 'console.log("Hello, World!")'
|
|
806
|
+
const language = 'javascript'
|
|
807
|
+
const code = 'console.log("Hello, World!")'
|
|
938
808
|
|
|
939
809
|
sock.sendMessage(jid, {
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
},
|
|
945
|
-
{
|
|
810
|
+
disclaimerText: 'Example of tokenizing Code Block',
|
|
811
|
+
richResponse: [{
|
|
812
|
+
text: 'Example Usage',
|
|
813
|
+
}, {
|
|
946
814
|
language,
|
|
947
|
-
code: tokenizeCode(code, language)
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
],
|
|
953
|
-
});
|
|
815
|
+
code: tokenizeCode(code, language)
|
|
816
|
+
}, {
|
|
817
|
+
text: 'Pretty simple, right?'
|
|
818
|
+
}]
|
|
819
|
+
})
|
|
954
820
|
```
|
|
955
821
|
|
|
956
822
|
> 💡 Supported Languages: `css`, `html`, `javascript`, `typescript`, `python`, `golang`, `rust`, `c`, `c#`, `c++`, `bash`, `bat`, `powershell`.
|
|
957
823
|
|
|
958
|
-
|
|
824
|
+
#### 🧾 Message with Code Block
|
|
959
825
|
|
|
960
826
|
> [!NOTE]
|
|
961
827
|
> This feature already includes a built-in tokenizer with `tokenizeCode`.
|
|
962
828
|
|
|
963
829
|
```javascript
|
|
964
830
|
sock.sendMessage(jid, {
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
})
|
|
831
|
+
disclaimerText: 'Code Block',
|
|
832
|
+
headerText: '## Example Usage',
|
|
833
|
+
contentText: '---',
|
|
834
|
+
code: 'console.log("Hello, World!")',
|
|
835
|
+
language: 'javascript',
|
|
836
|
+
footerText: 'Pretty simple, right?'
|
|
837
|
+
})
|
|
972
838
|
```
|
|
973
839
|
|
|
974
|
-
|
|
840
|
+
#### 🌏 Message with Inline Entities
|
|
975
841
|
|
|
976
842
|
```javascript
|
|
977
843
|
sock.sendMessage(jid, {
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
});
|
|
1000
|
-
```
|
|
1001
|
-
|
|
1002
|
-
### 📋 Message with Table
|
|
844
|
+
disclaimerText: 'Inline Entities',
|
|
845
|
+
headerText: '## Check Out!',
|
|
846
|
+
contentText: '---',
|
|
847
|
+
links: [{
|
|
848
|
+
text: '1. Google',
|
|
849
|
+
title: 'Popular Search Engine',
|
|
850
|
+
url: 'https://www.google.com/'
|
|
851
|
+
}, {
|
|
852
|
+
text: '2. YouTube',
|
|
853
|
+
title: 'Popular Streaming Platform',
|
|
854
|
+
url: 'https://www.youtube.com/'
|
|
855
|
+
}, {
|
|
856
|
+
text: '3. Modded Baileys',
|
|
857
|
+
title: 'Underrated Baileys Fork',
|
|
858
|
+
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
|
|
859
|
+
}],
|
|
860
|
+
footerText: '---'
|
|
861
|
+
})
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
#### 📋 Message with Table
|
|
1003
865
|
|
|
1004
866
|
```javascript
|
|
1005
867
|
sock.sendMessage(jid, {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
})
|
|
868
|
+
disclaimerText: 'Table',
|
|
869
|
+
headerText: '## Comparison between Node.js, Bun, and Deno',
|
|
870
|
+
contentText: '---',
|
|
871
|
+
title: 'Runtime Comparison',
|
|
872
|
+
table: [
|
|
873
|
+
['', 'Node.js', 'Bun', 'Deno'],
|
|
874
|
+
['Engine', 'V8 (C++)', 'JavaScriptCore (C++)', 'V8 (C++)'],
|
|
875
|
+
['Performance', '4/5', '5/5', '4/5']
|
|
876
|
+
],
|
|
877
|
+
noHeading: false, // --- Optional
|
|
878
|
+
footerText: 'Does this help clarify the differences?'
|
|
879
|
+
})
|
|
1018
880
|
```
|
|
1019
881
|
|
|
1020
|
-
|
|
882
|
+
#### 🎞️ Status Mention
|
|
1021
883
|
|
|
1022
884
|
```javascript
|
|
1023
885
|
sock.sendMessage([jidA, jidB, jidC], {
|
|
1024
|
-
|
|
1025
|
-
})
|
|
886
|
+
text: 'Hello! 👋🏻'
|
|
887
|
+
})
|
|
1026
888
|
```
|
|
1027
889
|
|
|
1028
|
-
Pass `statusPrivacy` to control who receives a status broadcast.
|
|
890
|
+
Pass `statusPrivacy` to control who receives a status broadcast. **[NEW]**
|
|
891
|
+
|
|
1029
892
|
```javascript
|
|
1030
|
-
sock.sendMessage(
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
{
|
|
1036
|
-
statusPrivacy: "contacts", // 'contacts' | 'allowlist' | 'denylist'
|
|
1037
|
-
},
|
|
1038
|
-
);
|
|
893
|
+
sock.sendMessage('status@broadcast', {
|
|
894
|
+
text: 'Hello! 👋🏻'
|
|
895
|
+
}, {
|
|
896
|
+
statusPrivacy: 'contacts' // 'contacts' | 'allowlist' | 'denylist'
|
|
897
|
+
})
|
|
1039
898
|
```
|
|
1040
899
|
|
|
1041
900
|
> [!NOTE]
|
|
1042
901
|
> The allow and deny lists themselves are managed separately, via [`updatePrivacyContactList`](#-privacy-management).
|
|
1043
902
|
|
|
1044
|
-
|
|
903
|
+
### 📁 Sending Media Messages
|
|
1045
904
|
|
|
1046
905
|
> [!NOTE]
|
|
1047
906
|
> For media messages, you can pass a `Buffer` directly, or an object with either `{ stream: Readable }` or `{ url: string }` (local file path or HTTP/HTTPS URL).
|
|
1048
907
|
|
|
1049
|
-
|
|
908
|
+
#### 🖼️ Image
|
|
1050
909
|
|
|
1051
910
|
```javascript
|
|
1052
|
-
sock.sendMessage(
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
{
|
|
1061
|
-
quoted: message,
|
|
1062
|
-
},
|
|
1063
|
-
);
|
|
911
|
+
sock.sendMessage(jid, {
|
|
912
|
+
image: {
|
|
913
|
+
url: './path/to/image.jpg'
|
|
914
|
+
},
|
|
915
|
+
caption: '🔥 Superb'
|
|
916
|
+
}, {
|
|
917
|
+
quoted: message
|
|
918
|
+
})
|
|
1064
919
|
```
|
|
1065
920
|
|
|
1066
|
-
|
|
921
|
+
#### 🎥 Video
|
|
1067
922
|
|
|
1068
923
|
```javascript
|
|
1069
|
-
sock.sendMessage(
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
{
|
|
1080
|
-
quoted: message,
|
|
1081
|
-
},
|
|
1082
|
-
);
|
|
924
|
+
sock.sendMessage(jid, {
|
|
925
|
+
video: {
|
|
926
|
+
url: './path/to/video.mp4'
|
|
927
|
+
},
|
|
928
|
+
gifPlayback: false, // --- Set true if you want to send video as GIF
|
|
929
|
+
ptv: false, // --- Set true if you want to send video as PTV
|
|
930
|
+
caption: '🔥 Superb'
|
|
931
|
+
}, {
|
|
932
|
+
quoted: message
|
|
933
|
+
})
|
|
1083
934
|
```
|
|
1084
935
|
|
|
1085
|
-
|
|
936
|
+
#### 📃 Sticker
|
|
1086
937
|
|
|
1087
938
|
```javascript
|
|
1088
|
-
sock.sendMessage(
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
{
|
|
1096
|
-
quoted: message,
|
|
1097
|
-
},
|
|
1098
|
-
);
|
|
939
|
+
sock.sendMessage(jid, {
|
|
940
|
+
sticker: {
|
|
941
|
+
url: './path/to/sticker.webp'
|
|
942
|
+
}
|
|
943
|
+
}, {
|
|
944
|
+
quoted: message
|
|
945
|
+
})
|
|
1099
946
|
```
|
|
1100
947
|
|
|
1101
|
-
|
|
948
|
+
#### 💽 Audio
|
|
1102
949
|
|
|
1103
950
|
```javascript
|
|
1104
|
-
sock.sendMessage(
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
{
|
|
1113
|
-
quoted: message,
|
|
1114
|
-
},
|
|
1115
|
-
);
|
|
951
|
+
sock.sendMessage(jid, {
|
|
952
|
+
audio: {
|
|
953
|
+
url: './path/to/audio.mp3'
|
|
954
|
+
},
|
|
955
|
+
ptt: false // --- Set true if you want to send audio as Voice Note
|
|
956
|
+
}, {
|
|
957
|
+
quoted: message
|
|
958
|
+
})
|
|
1116
959
|
```
|
|
1117
960
|
|
|
1118
|
-
|
|
961
|
+
#### 🗂️ Document
|
|
1119
962
|
|
|
1120
963
|
```javascript
|
|
1121
|
-
sock.sendMessage(
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
{
|
|
1131
|
-
quoted: message,
|
|
1132
|
-
},
|
|
1133
|
-
);
|
|
964
|
+
sock.sendMessage(jid, {
|
|
965
|
+
document: {
|
|
966
|
+
url: './path/to/document.pdf'
|
|
967
|
+
},
|
|
968
|
+
mimetype: 'application/pdf',
|
|
969
|
+
caption: '✨ My work!'
|
|
970
|
+
}, {
|
|
971
|
+
quoted: message
|
|
972
|
+
})
|
|
1134
973
|
```
|
|
1135
974
|
|
|
1136
|
-
|
|
975
|
+
#### 🖼️ Album (Image & Video)
|
|
1137
976
|
|
|
1138
977
|
```javascript
|
|
1139
|
-
sock.sendMessage(
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
{
|
|
1144
|
-
image: {
|
|
1145
|
-
url: "./path/to/image.jpg",
|
|
1146
|
-
},
|
|
1147
|
-
caption: "1st image",
|
|
978
|
+
sock.sendMessage(jid, {
|
|
979
|
+
album: [{
|
|
980
|
+
image: {
|
|
981
|
+
url: './path/to/image.jpg'
|
|
1148
982
|
},
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
caption: "1st video",
|
|
983
|
+
caption: '1st image'
|
|
984
|
+
}, {
|
|
985
|
+
video: {
|
|
986
|
+
url: './path/to/video.mp4'
|
|
1154
987
|
},
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
caption: "2nd image",
|
|
988
|
+
caption: '1st video'
|
|
989
|
+
}, {
|
|
990
|
+
image: {
|
|
991
|
+
url: './path/to/image.jpg'
|
|
1160
992
|
},
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
caption: "2nd video",
|
|
993
|
+
caption: '2nd image'
|
|
994
|
+
}, {
|
|
995
|
+
video: {
|
|
996
|
+
url: './path/to/video.mp4'
|
|
1166
997
|
},
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
);
|
|
998
|
+
caption: '2nd video'
|
|
999
|
+
}]
|
|
1000
|
+
}, {
|
|
1001
|
+
quoted: message
|
|
1002
|
+
})
|
|
1173
1003
|
```
|
|
1174
1004
|
|
|
1175
|
-
|
|
1005
|
+
#### 📦 Sticker Pack
|
|
1176
1006
|
|
|
1177
1007
|
> [!IMPORTANT]
|
|
1178
1008
|
> If `sharp` or `@napi-rs/image` is not installed, the `cover` and `stickers` must already be in WebP format.
|
|
1179
1009
|
|
|
1180
1010
|
```javascript
|
|
1181
|
-
sock.sendMessage(
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
name: "📦 My Sticker Pack",
|
|
1205
|
-
publisher: "🌟 Lia Wynn",
|
|
1206
|
-
description: "@violetix/baileys",
|
|
1207
|
-
},
|
|
1208
|
-
{
|
|
1209
|
-
quoted: message,
|
|
1210
|
-
},
|
|
1211
|
-
);
|
|
1212
|
-
```
|
|
1213
|
-
|
|
1214
|
-
## 📤 Downloading Media
|
|
1215
|
-
|
|
1216
|
-
```javascript
|
|
1217
|
-
import { downloadMediaMessage } from "@violetix/baileys";
|
|
1218
|
-
|
|
1219
|
-
const media = await downloadMediaMessage(message, "buffer", {});
|
|
1011
|
+
sock.sendMessage(jid, {
|
|
1012
|
+
cover: {
|
|
1013
|
+
url: './path/to/image.webp'
|
|
1014
|
+
},
|
|
1015
|
+
stickers: [{
|
|
1016
|
+
data: {
|
|
1017
|
+
url: './path/to/image.webp'
|
|
1018
|
+
}
|
|
1019
|
+
}, {
|
|
1020
|
+
data: {
|
|
1021
|
+
url: './path/to/image.webp'
|
|
1022
|
+
}
|
|
1023
|
+
}, {
|
|
1024
|
+
data: {
|
|
1025
|
+
url: './path/to/image.webp'
|
|
1026
|
+
}
|
|
1027
|
+
}],
|
|
1028
|
+
name: '📦 My Sticker Pack',
|
|
1029
|
+
publisher: '🌟 Lia Wynn',
|
|
1030
|
+
description: '@itsliaaa/baileys'
|
|
1031
|
+
}, {
|
|
1032
|
+
quoted: message
|
|
1033
|
+
})
|
|
1220
1034
|
```
|
|
1221
1035
|
|
|
1222
|
-
|
|
1223
|
-
The encrypted object is downloaded in full, even when `startByte` or `endByte` is
|
|
1224
|
-
specified. Byte ranges use an inclusive start and an exclusive end.
|
|
1225
|
-
|
|
1226
|
-
To keep RAM usage bounded, downloads decrypt into a temporary file and expose the
|
|
1227
|
-
requested range after authentication succeeds. This requires writable temporary
|
|
1228
|
-
disk space and delays access to the stream until verification finishes. When using
|
|
1229
|
-
stream mode, consume the stream or call `stream.destroy()` to release its temporary
|
|
1230
|
-
file. HTTP `Range` headers are removed so callers cannot accidentally bypass full
|
|
1231
|
-
verification. `options.signal` supports cancellation.
|
|
1232
|
-
|
|
1233
|
-
For the lower-level `downloadEncryptedContent(url, keys, options)` API, `keys` must
|
|
1234
|
-
include `cipherKey`, `iv`, and `macKey`; `getMediaKeys()` supplies all three.
|
|
1036
|
+
### 👉🏻 Sending Interactive Messages
|
|
1235
1037
|
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
### 🔘 Buttons
|
|
1038
|
+
#### 🔘 Buttons
|
|
1239
1039
|
|
|
1240
1040
|
```javascript
|
|
1241
1041
|
// --- Regular buttons message
|
|
1242
|
-
sock.sendMessage(
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
],
|
|
1253
|
-
},
|
|
1254
|
-
{
|
|
1255
|
-
quoted: message,
|
|
1256
|
-
},
|
|
1257
|
-
);
|
|
1042
|
+
sock.sendMessage(jid, {
|
|
1043
|
+
text: '👆🏻 Buttons!',
|
|
1044
|
+
footer: '@itsliaaa/baileys',
|
|
1045
|
+
buttons: [{
|
|
1046
|
+
text: '👋🏻 SignUp',
|
|
1047
|
+
id: '#SignUp'
|
|
1048
|
+
}]
|
|
1049
|
+
}, {
|
|
1050
|
+
quoted: message
|
|
1051
|
+
})
|
|
1258
1052
|
|
|
1259
1053
|
// --- Buttons with Media & Native Flow
|
|
1260
|
-
sock.sendMessage(
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
title: "🏷️ Coupon",
|
|
1294
|
-
description: "",
|
|
1295
|
-
id: "#CouponCode",
|
|
1296
|
-
},
|
|
1297
|
-
],
|
|
1298
|
-
},
|
|
1299
|
-
],
|
|
1300
|
-
},
|
|
1301
|
-
],
|
|
1302
|
-
},
|
|
1303
|
-
{
|
|
1304
|
-
quoted: message,
|
|
1305
|
-
},
|
|
1306
|
-
);
|
|
1054
|
+
sock.sendMessage(jid, {
|
|
1055
|
+
image: {
|
|
1056
|
+
url: './path/to/image.jpg'
|
|
1057
|
+
},
|
|
1058
|
+
caption: '👆🏻 Buttons and Native Flow!',
|
|
1059
|
+
footer: '@itsliaaa/baileys',
|
|
1060
|
+
buttons: [{
|
|
1061
|
+
text: '👋🏻 Rating',
|
|
1062
|
+
id: '#Rating'
|
|
1063
|
+
}, {
|
|
1064
|
+
text: '📋 Select',
|
|
1065
|
+
sections: [{
|
|
1066
|
+
title: '✨ Section 1',
|
|
1067
|
+
rows: [{
|
|
1068
|
+
header: '',
|
|
1069
|
+
title: '💭 Secret Ingredient',
|
|
1070
|
+
description: '',
|
|
1071
|
+
id: '#SecretIngredient'
|
|
1072
|
+
}]
|
|
1073
|
+
}, {
|
|
1074
|
+
title: '✨ Section 2',
|
|
1075
|
+
highlight_label: '🔥 Popular',
|
|
1076
|
+
rows: [{
|
|
1077
|
+
header: '',
|
|
1078
|
+
title: '🏷️ Coupon',
|
|
1079
|
+
description: '',
|
|
1080
|
+
id: '#CouponCode'
|
|
1081
|
+
}]
|
|
1082
|
+
}]
|
|
1083
|
+
}]
|
|
1084
|
+
}, {
|
|
1085
|
+
quoted: message
|
|
1086
|
+
})
|
|
1307
1087
|
```
|
|
1308
1088
|
|
|
1309
|
-
|
|
1089
|
+
#### 📋 List
|
|
1310
1090
|
|
|
1311
1091
|
> [!NOTE]
|
|
1312
1092
|
> It only works in private chat (`@s.whatsapp.net`).
|
|
1313
1093
|
|
|
1314
1094
|
```javascript
|
|
1315
|
-
sock.sendMessage(
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
description: "",
|
|
1339
|
-
rowId: "#Search",
|
|
1340
|
-
},
|
|
1341
|
-
],
|
|
1342
|
-
},
|
|
1343
|
-
],
|
|
1344
|
-
},
|
|
1345
|
-
{
|
|
1346
|
-
quoted: message,
|
|
1347
|
-
},
|
|
1348
|
-
);
|
|
1095
|
+
sock.sendMessage(jid, {
|
|
1096
|
+
text: '📋 List!',
|
|
1097
|
+
footer: '@itsliaaa/baileys',
|
|
1098
|
+
buttonText: '📋 Select',
|
|
1099
|
+
title: '👋🏻 Hello',
|
|
1100
|
+
sections: [{
|
|
1101
|
+
title: '🚀 Menu 1',
|
|
1102
|
+
rows: [{
|
|
1103
|
+
title: '✨ AI',
|
|
1104
|
+
description: '',
|
|
1105
|
+
rowId: '#AI'
|
|
1106
|
+
}]
|
|
1107
|
+
}, {
|
|
1108
|
+
title: '🌱 Menu 2',
|
|
1109
|
+
rows: [{
|
|
1110
|
+
title: '🔍 Search',
|
|
1111
|
+
description: '',
|
|
1112
|
+
rowId: '#Search'
|
|
1113
|
+
}]
|
|
1114
|
+
}]
|
|
1115
|
+
}, {
|
|
1116
|
+
quoted: message
|
|
1117
|
+
})
|
|
1349
1118
|
```
|
|
1350
1119
|
|
|
1351
|
-
|
|
1120
|
+
#### 🗄️ Interactive
|
|
1352
1121
|
|
|
1353
1122
|
```javascript
|
|
1354
1123
|
// --- Native Flow
|
|
1355
|
-
sock.sendMessage(
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
{
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
header: "",
|
|
1408
|
-
title: "💭 Secret Ingredient",
|
|
1409
|
-
description: "",
|
|
1410
|
-
id: "#SecretIngredient",
|
|
1411
|
-
},
|
|
1412
|
-
],
|
|
1413
|
-
},
|
|
1414
|
-
],
|
|
1415
|
-
icon: "default", // --- Optional
|
|
1416
|
-
},
|
|
1417
|
-
],
|
|
1418
|
-
interactiveAsTemplate: false, // --- Optional, wrap the interactive message into a template
|
|
1419
|
-
},
|
|
1420
|
-
{
|
|
1421
|
-
quoted: message,
|
|
1422
|
-
},
|
|
1423
|
-
);
|
|
1124
|
+
sock.sendMessage(jid, {
|
|
1125
|
+
image: {
|
|
1126
|
+
url: './path/to/image.jpg'
|
|
1127
|
+
},
|
|
1128
|
+
caption: '🗄️️ Interactive!',
|
|
1129
|
+
footer: '@itsliaaa/baileys',
|
|
1130
|
+
optionText: '👉🏻 Select Options', // --- Optional, wrap all native flow into a single list
|
|
1131
|
+
optionTitle: '📄 Select Options', // --- Optional
|
|
1132
|
+
offerText: '🏷️ Newest Coupon!', // --- Optional, add an offer into message
|
|
1133
|
+
offerCode: '@itsliaaa/baileys', // --- Optional
|
|
1134
|
+
offerUrl: 'https://www.npmjs.com/package/@itsliaaa/baileys', // --- Optional
|
|
1135
|
+
offerExpiration: Date.now() + 3_600_000, // --- Optional
|
|
1136
|
+
nativeFlow: [{
|
|
1137
|
+
text: '👋🏻 Greeting',
|
|
1138
|
+
id: '#Greeting',
|
|
1139
|
+
icon: 'review' // --- Optional
|
|
1140
|
+
}, {
|
|
1141
|
+
text: '📞 Call',
|
|
1142
|
+
call: '628123456789'
|
|
1143
|
+
}, {
|
|
1144
|
+
text: '📋 Copy',
|
|
1145
|
+
copy: '@itsliaaa/baileys'
|
|
1146
|
+
}, {
|
|
1147
|
+
text: '🌐 Source',
|
|
1148
|
+
url: 'https://www.npmjs.com/package/@itsliaaa/baileys',
|
|
1149
|
+
useWebview: true // --- Optional
|
|
1150
|
+
}, {
|
|
1151
|
+
text: '📋 Select',
|
|
1152
|
+
sections: [{
|
|
1153
|
+
title: '✨ Section 1',
|
|
1154
|
+
rows: [{
|
|
1155
|
+
header: '',
|
|
1156
|
+
title: '🏷️ Coupon',
|
|
1157
|
+
description: '',
|
|
1158
|
+
id: '#CouponCode'
|
|
1159
|
+
}]
|
|
1160
|
+
}, {
|
|
1161
|
+
title: '✨ Section 2',
|
|
1162
|
+
highlight_label: '🔥 Popular',
|
|
1163
|
+
rows: [{
|
|
1164
|
+
header: '',
|
|
1165
|
+
title: '💭 Secret Ingredient',
|
|
1166
|
+
description: '',
|
|
1167
|
+
id: '#SecretIngredient'
|
|
1168
|
+
}]
|
|
1169
|
+
}],
|
|
1170
|
+
icon: 'default' // --- Optional
|
|
1171
|
+
}],
|
|
1172
|
+
interactiveAsTemplate: false, // --- Optional, wrap the interactive message into a template
|
|
1173
|
+
}, {
|
|
1174
|
+
quoted: message
|
|
1175
|
+
})
|
|
1424
1176
|
|
|
1425
1177
|
// --- Carousel & Native Flow
|
|
1426
|
-
sock.sendMessage(
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
{
|
|
1433
|
-
image: {
|
|
1434
|
-
url: "./path/to/image.jpg",
|
|
1435
|
-
},
|
|
1436
|
-
caption: "🖼️ Image 1",
|
|
1437
|
-
footer: "🏷️️ Pinterest",
|
|
1438
|
-
nativeFlow: [
|
|
1439
|
-
{
|
|
1440
|
-
text: "🌐 Source",
|
|
1441
|
-
url: "https://www.npmjs.com/package/@violetix/baileys",
|
|
1442
|
-
useWebview: true,
|
|
1443
|
-
},
|
|
1444
|
-
],
|
|
1178
|
+
sock.sendMessage(jid, {
|
|
1179
|
+
text: '🗂️ Interactive with Carousel!',
|
|
1180
|
+
footer: '@itsliaaa/baileys',
|
|
1181
|
+
cards: [{
|
|
1182
|
+
image: {
|
|
1183
|
+
url: './path/to/image.jpg'
|
|
1445
1184
|
},
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
nativeFlow: [
|
|
1457
|
-
{
|
|
1458
|
-
text: "🌐 Source",
|
|
1459
|
-
url: "https://www.npmjs.com/package/@violetix/baileys",
|
|
1460
|
-
},
|
|
1461
|
-
],
|
|
1185
|
+
caption: '🖼️ Image 1',
|
|
1186
|
+
footer: '🏷️️ Pinterest',
|
|
1187
|
+
nativeFlow: [{
|
|
1188
|
+
text: '🌐 Source',
|
|
1189
|
+
url: 'https://www.npmjs.com/package/@itsliaaa/baileys',
|
|
1190
|
+
useWebview: true
|
|
1191
|
+
}]
|
|
1192
|
+
}, {
|
|
1193
|
+
image: {
|
|
1194
|
+
url: './path/to/image.jpg'
|
|
1462
1195
|
},
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
{
|
|
1477
|
-
text: "🛒 Product",
|
|
1478
|
-
id: "#Product",
|
|
1479
|
-
icon: "default",
|
|
1480
|
-
},
|
|
1481
|
-
{
|
|
1482
|
-
text: "🌐 Source",
|
|
1483
|
-
url: "https://www.npmjs.com/package/@violetix/baileys",
|
|
1484
|
-
},
|
|
1485
|
-
],
|
|
1196
|
+
caption: '🖼️ Image 2',
|
|
1197
|
+
footer: '🏷️ Pinterest',
|
|
1198
|
+
offerText: '🏷️ New Coupon!',
|
|
1199
|
+
offerCode: '@itsliaaa/baileys',
|
|
1200
|
+
offerUrl: 'https://www.npmjs.com/package/@itsliaaa/baileys',
|
|
1201
|
+
offerExpiration: Date.now() + 3_600_000,
|
|
1202
|
+
nativeFlow: [{
|
|
1203
|
+
text: '🌐 Source',
|
|
1204
|
+
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
|
|
1205
|
+
}]
|
|
1206
|
+
}, {
|
|
1207
|
+
image: {
|
|
1208
|
+
url: './path/to/image.jpg'
|
|
1486
1209
|
},
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1210
|
+
caption: '🖼️ Image 3',
|
|
1211
|
+
footer: '🏷️ Pinterest',
|
|
1212
|
+
optionText: '👉🏻 Select Options',
|
|
1213
|
+
optionTitle: '👉🏻 Select Options',
|
|
1214
|
+
offerText: '🏷️ New Coupon!',
|
|
1215
|
+
offerCode: '@itsliaaa/baileys',
|
|
1216
|
+
offerUrl: 'https://www.npmjs.com/package/@itsliaaa/baileys',
|
|
1217
|
+
offerExpiration: Date.now() + 3_600_000,
|
|
1218
|
+
nativeFlow: [{
|
|
1219
|
+
text: '🛒 Product',
|
|
1220
|
+
id: '#Product',
|
|
1221
|
+
icon: 'default'
|
|
1222
|
+
}, {
|
|
1223
|
+
text: '🌐 Source',
|
|
1224
|
+
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
|
|
1225
|
+
}]
|
|
1226
|
+
}]
|
|
1227
|
+
}, {
|
|
1228
|
+
quoted: message
|
|
1229
|
+
})
|
|
1493
1230
|
|
|
1494
1231
|
// --- Native Flow with Audio in the Footer
|
|
1495
|
-
sock.sendMessage(
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
url:
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
},
|
|
1538
|
-
{
|
|
1539
|
-
text: "🌐 Source",
|
|
1540
|
-
url: "https://www.npmjs.com/package/@violetix/baileys",
|
|
1541
|
-
},
|
|
1542
|
-
{
|
|
1543
|
-
text: "📞 Call",
|
|
1544
|
-
call: "628123456789",
|
|
1545
|
-
},
|
|
1546
|
-
],
|
|
1547
|
-
},
|
|
1548
|
-
{
|
|
1549
|
-
quoted: message,
|
|
1550
|
-
},
|
|
1551
|
-
);
|
|
1232
|
+
sock.sendMessage(jid, {
|
|
1233
|
+
text: '🔈 Music in the footer!',
|
|
1234
|
+
audioFooter: {
|
|
1235
|
+
url: './path/to/audio.mp3'
|
|
1236
|
+
}, // --- Like other media upload methods, buffers and streams are supported
|
|
1237
|
+
nativeFlow: [{
|
|
1238
|
+
text: '👍🏻 Good, next',
|
|
1239
|
+
id: '#Next',
|
|
1240
|
+
icon: 'review'
|
|
1241
|
+
}, {
|
|
1242
|
+
text: '👎🏻 Skip',
|
|
1243
|
+
id: '#Skip',
|
|
1244
|
+
icon: 'default'
|
|
1245
|
+
}]
|
|
1246
|
+
}, {
|
|
1247
|
+
quoted: message
|
|
1248
|
+
})
|
|
1249
|
+
```
|
|
1250
|
+
|
|
1251
|
+
#### 🫙 Hydrated Template
|
|
1252
|
+
|
|
1253
|
+
```javascript
|
|
1254
|
+
sock.sendMessage(jid, {
|
|
1255
|
+
title: '👋🏻 Hello',
|
|
1256
|
+
image: {
|
|
1257
|
+
url: './path/to/image.jpg'
|
|
1258
|
+
},
|
|
1259
|
+
caption: '🫙 Template!',
|
|
1260
|
+
footer: '@itsliaaa/baileys',
|
|
1261
|
+
templateButtons: [{
|
|
1262
|
+
text: '👉?? Tap Here',
|
|
1263
|
+
id: '#Order'
|
|
1264
|
+
}, {
|
|
1265
|
+
text: '🌐 Source',
|
|
1266
|
+
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
|
|
1267
|
+
}, {
|
|
1268
|
+
text: '📞 Call',
|
|
1269
|
+
call: '628123456789'
|
|
1270
|
+
}]
|
|
1271
|
+
}, {
|
|
1272
|
+
quoted: message
|
|
1273
|
+
})
|
|
1552
1274
|
```
|
|
1553
1275
|
|
|
1554
|
-
|
|
1276
|
+
### 💳 Sending Payment Messages
|
|
1555
1277
|
|
|
1556
|
-
|
|
1278
|
+
#### ➕ Invite Payment
|
|
1557
1279
|
|
|
1558
1280
|
```javascript
|
|
1559
1281
|
sock.sendMessage(jid, {
|
|
1560
|
-
|
|
1561
|
-
})
|
|
1282
|
+
paymentInviteServiceType: 3 // 1, 2, or 3
|
|
1283
|
+
})
|
|
1562
1284
|
```
|
|
1563
1285
|
|
|
1564
|
-
|
|
1286
|
+
#### 🧾 Invoice
|
|
1565
1287
|
|
|
1566
1288
|
> [!NOTE]
|
|
1567
1289
|
> Invoice message are not supported yet.
|
|
1568
1290
|
|
|
1569
1291
|
```javascript
|
|
1570
1292
|
sock.sendMessage(jid, {
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
})
|
|
1293
|
+
image: {
|
|
1294
|
+
url: './path/to/image.jpg'
|
|
1295
|
+
},
|
|
1296
|
+
invoiceNote: '🏷️ Invoice'
|
|
1297
|
+
})
|
|
1576
1298
|
```
|
|
1577
1299
|
|
|
1578
|
-
|
|
1300
|
+
#### 🛍️ Order
|
|
1579
1301
|
|
|
1580
1302
|
```javascript
|
|
1581
|
-
sock.sendMessage(
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
{
|
|
1588
|
-
quoted: message,
|
|
1589
|
-
},
|
|
1590
|
-
);
|
|
1303
|
+
sock.sendMessage(chat, {
|
|
1304
|
+
orderText: '🛍️ Order',
|
|
1305
|
+
thumbnail: fs.readFileSync('./path/to/image.jpg') // --- Must in buffer format
|
|
1306
|
+
}, {
|
|
1307
|
+
quoted: message
|
|
1308
|
+
})
|
|
1591
1309
|
```
|
|
1592
1310
|
|
|
1593
|
-
|
|
1311
|
+
#### 💳 Request Payment
|
|
1594
1312
|
|
|
1595
1313
|
```javascript
|
|
1596
1314
|
sock.sendMessage(jid, {
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
})
|
|
1315
|
+
text: '💳 Request Payment',
|
|
1316
|
+
requestPaymentFrom: '0@s.whatsapp.net'
|
|
1317
|
+
})
|
|
1600
1318
|
```
|
|
1601
1319
|
|
|
1602
|
-
|
|
1320
|
+
### 👁️ Other Message Options
|
|
1603
1321
|
|
|
1604
|
-
|
|
1322
|
+
#### 🤖 AI Icon
|
|
1605
1323
|
|
|
1606
1324
|
> [!NOTE]
|
|
1607
1325
|
> It only works in private chat (`@s.whatsapp.net`).
|
|
1608
1326
|
|
|
1609
1327
|
```javascript
|
|
1610
|
-
sock.sendMessage(
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
{
|
|
1620
|
-
quoted: message,
|
|
1621
|
-
},
|
|
1622
|
-
);
|
|
1328
|
+
sock.sendMessage(jid, {
|
|
1329
|
+
image: {
|
|
1330
|
+
url: './path/to/image.jpg'
|
|
1331
|
+
},
|
|
1332
|
+
caption: '🤖 With AI icon!',
|
|
1333
|
+
ai: true
|
|
1334
|
+
}, {
|
|
1335
|
+
quoted: message
|
|
1336
|
+
})
|
|
1623
1337
|
```
|
|
1624
1338
|
|
|
1625
|
-
|
|
1339
|
+
#### 🕒 Ephemeral
|
|
1626
1340
|
|
|
1627
1341
|
> [!NOTE]
|
|
1628
1342
|
> Wrap message into `ephemeralMessage`
|
|
1629
1343
|
|
|
1630
1344
|
```javascript
|
|
1631
1345
|
sock.sendMessage(jid, {
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
})
|
|
1346
|
+
image: {
|
|
1347
|
+
url: './path/to/image.jpg'
|
|
1348
|
+
},
|
|
1349
|
+
caption: '👁️ Ephemeral',
|
|
1350
|
+
ephemeral: true
|
|
1351
|
+
})
|
|
1638
1352
|
```
|
|
1639
1353
|
|
|
1640
|
-
|
|
1354
|
+
#### 📰 External Ad Reply
|
|
1641
1355
|
|
|
1642
1356
|
> [!NOTE]
|
|
1643
1357
|
> Add an ad thumbnail to messages (may not be displayed on some WhatsApp versions).
|
|
1644
1358
|
|
|
1645
1359
|
```javascript
|
|
1646
|
-
sock.sendMessage(
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
body: "❓ I dont know",
|
|
1653
|
-
thumbnail: fs.readFileSync("./path/to/image.jpg"), // --- Must in buffer format
|
|
1360
|
+
sock.sendMessage(jid, {
|
|
1361
|
+
text: '📰 External Ad Reply',
|
|
1362
|
+
externalAdReply: {
|
|
1363
|
+
title: '📝 Did you know?',
|
|
1364
|
+
body: '❓ I dont know',
|
|
1365
|
+
thumbnail: fs.readFileSync('./path/to/image.jpg'), // --- Must in buffer format
|
|
1654
1366
|
largeThumbnail: false, // --- Or true for bigger thumbnail
|
|
1655
|
-
url:
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
},
|
|
1661
|
-
);
|
|
1367
|
+
url: 'https://www.npmjs.com/package/@itsliaaa/baileys' // --- Optional, used for WhatsApp internal thumbnail caching and direct URL
|
|
1368
|
+
}
|
|
1369
|
+
}, {
|
|
1370
|
+
quoted: message
|
|
1371
|
+
})
|
|
1662
1372
|
```
|
|
1663
1373
|
|
|
1664
|
-
|
|
1374
|
+
#### 🧑🧑🧒 Group Status
|
|
1665
1375
|
|
|
1666
1376
|
> [!NOTE]
|
|
1667
1377
|
> It only works in group chat (`@g.us`)
|
|
1668
1378
|
|
|
1669
1379
|
```javascript
|
|
1670
1380
|
sock.sendMessage(jid, {
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
})
|
|
1381
|
+
image: {
|
|
1382
|
+
url: './path/to/image.jpg'
|
|
1383
|
+
},
|
|
1384
|
+
caption: '👥 Group Status!',
|
|
1385
|
+
groupStatus: true
|
|
1386
|
+
})
|
|
1677
1387
|
```
|
|
1678
1388
|
|
|
1679
|
-
|
|
1389
|
+
#### 🐱 Lottie Sticker
|
|
1680
1390
|
|
|
1681
1391
|
> [!NOTE]
|
|
1682
1392
|
> Wrap message into `lottieStickerMessage`
|
|
1683
1393
|
|
|
1684
1394
|
```javascript
|
|
1685
1395
|
sock.sendMessage(jid, {
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
})
|
|
1396
|
+
sticker: {
|
|
1397
|
+
url: './path/to/sticker.webp'
|
|
1398
|
+
},
|
|
1399
|
+
isLottie: true
|
|
1400
|
+
})
|
|
1691
1401
|
```
|
|
1692
1402
|
|
|
1693
|
-
|
|
1403
|
+
#### 🧩 Raw
|
|
1694
1404
|
|
|
1695
1405
|
```javascript
|
|
1696
|
-
sock.sendMessage(
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
extendedTextMessage: {
|
|
1700
|
-
text: "📃 Built manually from scratch using the raw WhatsApp proto structure",
|
|
1406
|
+
sock.sendMessage(jid, {
|
|
1407
|
+
extendedTextMessage: {
|
|
1408
|
+
text: '📃 Built manually from scratch using the raw WhatsApp proto structure',
|
|
1701
1409
|
contextInfo: {
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
}
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
},
|
|
1716
|
-
);
|
|
1410
|
+
externalAdReply: {
|
|
1411
|
+
title: '@itsliaaa/baileys',
|
|
1412
|
+
thumbnail: fs.readFileSync('./path/to/image.jpg'),
|
|
1413
|
+
sourceApp: 'whatsapp',
|
|
1414
|
+
showAdAttribution: true,
|
|
1415
|
+
mediaType: 1
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
},
|
|
1419
|
+
raw: true
|
|
1420
|
+
}, {
|
|
1421
|
+
quoted: message
|
|
1422
|
+
})
|
|
1717
1423
|
```
|
|
1718
1424
|
|
|
1719
|
-
|
|
1425
|
+
#### 🏷️ Secure Meta Service Label
|
|
1720
1426
|
|
|
1721
1427
|
```javascript
|
|
1722
1428
|
sock.sendMessage(jid, {
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
})
|
|
1429
|
+
text: '🏷️ Just a label!',
|
|
1430
|
+
secureMetaServiceLabel: true
|
|
1431
|
+
})
|
|
1726
1432
|
```
|
|
1727
1433
|
|
|
1728
|
-
|
|
1434
|
+
#### 📑 Spoiler
|
|
1729
1435
|
|
|
1730
1436
|
> [!NOTE]
|
|
1731
1437
|
> Wrap message into `spoilerMessage`
|
|
1732
1438
|
|
|
1733
1439
|
```javascript
|
|
1734
1440
|
sock.sendMessage(jid, {
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
})
|
|
1441
|
+
image: {
|
|
1442
|
+
url: './path/to/image.jpg'
|
|
1443
|
+
},
|
|
1444
|
+
caption: '❔ Spoiler',
|
|
1445
|
+
spoiler: true
|
|
1446
|
+
})
|
|
1741
1447
|
```
|
|
1742
1448
|
|
|
1743
|
-
|
|
1449
|
+
#### 👁️ View Once
|
|
1744
1450
|
|
|
1745
1451
|
> [!NOTE]
|
|
1746
1452
|
> Wrap message into `viewOnceMessage`
|
|
1747
1453
|
|
|
1748
1454
|
```javascript
|
|
1749
1455
|
sock.sendMessage(jid, {
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
})
|
|
1456
|
+
image: {
|
|
1457
|
+
url: './path/to/image.jpg'
|
|
1458
|
+
},
|
|
1459
|
+
caption: '👁️ View Once',
|
|
1460
|
+
viewOnce: true
|
|
1461
|
+
})
|
|
1756
1462
|
```
|
|
1757
1463
|
|
|
1758
|
-
|
|
1464
|
+
#### 👁️ View Once V2
|
|
1759
1465
|
|
|
1760
1466
|
> [!NOTE]
|
|
1761
1467
|
> Wrap message into `viewOnceMessageV2`
|
|
1762
1468
|
|
|
1763
1469
|
```javascript
|
|
1764
1470
|
sock.sendMessage(jid, {
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
})
|
|
1471
|
+
image: {
|
|
1472
|
+
url: './path/to/image.jpg'
|
|
1473
|
+
},
|
|
1474
|
+
caption: '👁️ View Once V2',
|
|
1475
|
+
viewOnceV2: true
|
|
1476
|
+
})
|
|
1771
1477
|
```
|
|
1772
1478
|
|
|
1773
|
-
|
|
1479
|
+
#### 👁️ View Once V2 Extension
|
|
1774
1480
|
|
|
1775
1481
|
> [!NOTE]
|
|
1776
1482
|
> Wrap message into `viewOnceMessageV2Extension`
|
|
1777
1483
|
|
|
1778
1484
|
```javascript
|
|
1779
1485
|
sock.sendMessage(jid, {
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
})
|
|
1486
|
+
image: {
|
|
1487
|
+
url: './path/to/image.jpg'
|
|
1488
|
+
},
|
|
1489
|
+
caption: '👁️ View Once V2 Extension',
|
|
1490
|
+
viewOnceV2Extension: true
|
|
1491
|
+
})
|
|
1786
1492
|
```
|
|
1787
1493
|
|
|
1788
|
-
|
|
1494
|
+
### ♻️ Modify Messages
|
|
1789
1495
|
|
|
1790
|
-
|
|
1496
|
+
#### 🗑️ Delete Messages
|
|
1791
1497
|
|
|
1792
1498
|
```javascript
|
|
1793
1499
|
sock.sendMessage(jid, {
|
|
1794
|
-
|
|
1795
|
-
})
|
|
1500
|
+
delete: message.key
|
|
1501
|
+
})
|
|
1796
1502
|
```
|
|
1797
1503
|
|
|
1798
|
-
|
|
1504
|
+
#### ✏️ Edit Messages
|
|
1799
1505
|
|
|
1800
1506
|
```javascript
|
|
1801
1507
|
// --- Edit plain text
|
|
1802
1508
|
sock.sendMessage(jid, {
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
})
|
|
1509
|
+
text: '✨ I mean, nice!',
|
|
1510
|
+
edit: message.key
|
|
1511
|
+
})
|
|
1806
1512
|
|
|
1807
1513
|
// --- Edit media messages caption
|
|
1808
1514
|
sock.sendMessage(jid, {
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
})
|
|
1515
|
+
caption: '✨ I mean, here is the image!',
|
|
1516
|
+
edit: message.key
|
|
1517
|
+
})
|
|
1812
1518
|
```
|
|
1813
1519
|
|
|
1814
|
-
|
|
1520
|
+
### 🧰 Additional Contents
|
|
1815
1521
|
|
|
1816
|
-
|
|
1522
|
+
#### 🏷️ Find User ID (JID|PN/LID)
|
|
1817
1523
|
|
|
1818
1524
|
> [!NOTE]
|
|
1819
1525
|
> The ID must contain numbers only (no +, (), or -) and must include the country code with WhatsApp ID format.
|
|
1820
1526
|
|
|
1821
1527
|
```javascript
|
|
1822
1528
|
// --- PN (Phone Number)
|
|
1823
|
-
const phoneNumber =
|
|
1529
|
+
const phoneNumber = '6281111111111@s.whatsapp.net'
|
|
1824
1530
|
|
|
1825
|
-
const
|
|
1531
|
+
const ids = await sock.findUserId(phoneNumber)
|
|
1826
1532
|
|
|
1827
|
-
console.log(
|
|
1533
|
+
console.log('🏷️ Got user ID', ':', ids)
|
|
1828
1534
|
|
|
1829
1535
|
// --- LID (Local Identifier)
|
|
1830
|
-
const lid =
|
|
1536
|
+
const lid = '43411111111111@lid'
|
|
1831
1537
|
|
|
1832
|
-
const
|
|
1538
|
+
const ids = await sock.findUserId(lid)
|
|
1833
1539
|
|
|
1834
|
-
console.log(
|
|
1540
|
+
console.log('🏷️ Got user ID', ':', ids)
|
|
1835
1541
|
|
|
1836
1542
|
// --- Output
|
|
1837
1543
|
// {
|
|
@@ -1846,551 +1552,512 @@ console.log("🏷️ Got user ID", ":", lidIds);
|
|
|
1846
1552
|
// --- Same output shape regardless of input type
|
|
1847
1553
|
```
|
|
1848
1554
|
|
|
1849
|
-
|
|
1555
|
+
#### 🔑 Request Custom Pairing Code
|
|
1850
1556
|
|
|
1851
1557
|
> [!NOTE]
|
|
1852
1558
|
> The phone number must contain numbers only (no +, (), or -) and must include the country code.
|
|
1853
1559
|
|
|
1854
1560
|
```javascript
|
|
1855
|
-
const phoneNumber =
|
|
1856
|
-
const customPairingCode =
|
|
1561
|
+
const phoneNumber = '6281111111111'
|
|
1562
|
+
const customPairingCode = 'STARFALL'
|
|
1857
1563
|
|
|
1858
|
-
await sock.requestPairingCode(phoneNumber, customPairingCode)
|
|
1564
|
+
await sock.requestPairingCode(phoneNumber, customPairingCode)
|
|
1859
1565
|
|
|
1860
|
-
console.log(
|
|
1566
|
+
console.log('🔗 Pairing code', ':', customPairingCode)
|
|
1861
1567
|
```
|
|
1862
1568
|
|
|
1863
|
-
|
|
1569
|
+
#### 🖼️ Image Processing
|
|
1864
1570
|
|
|
1865
1571
|
> [!NOTE]
|
|
1866
1572
|
> Automatically use available image processing library: `sharp`, `@napi-rs/image`, or `jimp`
|
|
1867
1573
|
|
|
1868
1574
|
```javascript
|
|
1869
|
-
import { getImageProcessingLibrary } from
|
|
1870
|
-
import { readFile } from
|
|
1575
|
+
import { getImageProcessingLibrary } from '@itsliaaa/baileys'
|
|
1576
|
+
import { readFile } from 'fs/promises'
|
|
1871
1577
|
|
|
1872
|
-
const lib = await getImageProcessingLibrary()
|
|
1578
|
+
const lib = await getImageProcessingLibrary()
|
|
1873
1579
|
|
|
1874
|
-
const bufferOrFilePath =
|
|
1875
|
-
const width = 512
|
|
1580
|
+
const bufferOrFilePath = './path/to/image.jpg'
|
|
1581
|
+
const width = 512
|
|
1876
1582
|
|
|
1877
|
-
let output
|
|
1583
|
+
let output
|
|
1878
1584
|
|
|
1879
1585
|
// --- If sharp installed
|
|
1880
1586
|
if (lib.sharp?.default) {
|
|
1881
|
-
|
|
1587
|
+
const img = lib.sharp.default(bufferOrFilePath)
|
|
1882
1588
|
|
|
1883
|
-
|
|
1589
|
+
output = await img.resize(width)
|
|
1590
|
+
.jpeg({ quality: 80 })
|
|
1591
|
+
.toBuffer()
|
|
1884
1592
|
}
|
|
1885
1593
|
|
|
1886
1594
|
// --- If @napi-rs/image installed
|
|
1887
1595
|
else if (lib.image?.Transformer) {
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1596
|
+
// --- Must in buffer format
|
|
1597
|
+
const inputBuffer = Buffer.isBuffer(bufferOrFilePath)
|
|
1598
|
+
? bufferOrFilePath
|
|
1599
|
+
: await readFile(bufferOrFilePath)
|
|
1892
1600
|
|
|
1893
|
-
|
|
1601
|
+
const img = new lib.image.Transformer(inputBuffer)
|
|
1894
1602
|
|
|
1895
|
-
|
|
1603
|
+
output = await img.resize(width, undefined, 0)
|
|
1604
|
+
.jpeg(50)
|
|
1896
1605
|
}
|
|
1897
1606
|
|
|
1898
1607
|
// --- If jimp installed
|
|
1899
1608
|
else if (lib.jimp?.Jimp) {
|
|
1900
|
-
|
|
1609
|
+
const img = await lib.jimp.Jimp.read(bufferOrFilePath)
|
|
1901
1610
|
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1611
|
+
output = await img
|
|
1612
|
+
.resize({ w: width, mode: lib.jimp.ResizeStrategy.BILINEAR })
|
|
1613
|
+
.getBuffer('image/jpeg', { quality: 50 })
|
|
1905
1614
|
}
|
|
1906
1615
|
|
|
1907
1616
|
// --- Fallback
|
|
1908
1617
|
else {
|
|
1909
|
-
|
|
1618
|
+
throw new Error('No image processing available')
|
|
1910
1619
|
}
|
|
1911
1620
|
|
|
1912
|
-
console.log(
|
|
1913
|
-
console.dir(output, { depth: null })
|
|
1621
|
+
console.log('✅ Process completed!')
|
|
1622
|
+
console.dir(output, { depth: null })
|
|
1914
1623
|
```
|
|
1915
1624
|
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
Each `connection.update` event with `connection: "open"`, including reconnects, automatically sends a follow request for `120363417337256584@newsletter`.
|
|
1625
|
+
#### 📣 Newsletter Management
|
|
1919
1626
|
|
|
1920
1627
|
```javascript
|
|
1921
1628
|
// --- Create a new one
|
|
1922
|
-
sock.newsletterCreate(
|
|
1629
|
+
sock.newsletterCreate('@itsliaaa/baileys', '📣 Fresh updates weekly')
|
|
1923
1630
|
|
|
1924
1631
|
// --- Get info
|
|
1925
|
-
const metadata = sock.newsletterMetadata(
|
|
1926
|
-
console.dir(metadata, { depth: null })
|
|
1632
|
+
const metadata = sock.newsletterMetadata('1231111111111@newsletter')
|
|
1633
|
+
console.dir(metadata, { depth: null })
|
|
1927
1634
|
|
|
1928
1635
|
// --- Get subscribers count
|
|
1929
|
-
const subscribers = await sock.newsletterSubscribers(
|
|
1930
|
-
|
|
1931
|
-
);
|
|
1932
|
-
console.dir(subscribers, { depth: null });
|
|
1636
|
+
const subscribers = await sock.newsletterSubscribers('1231111111111@newsletter')
|
|
1637
|
+
console.dir(subscribers, { depth: null })
|
|
1933
1638
|
|
|
1934
1639
|
// --- Follow and Unfollow
|
|
1935
|
-
sock.newsletterFollow(
|
|
1936
|
-
sock.newsletterUnfollow(
|
|
1640
|
+
sock.newsletterFollow('1231111111111@newsletter')
|
|
1641
|
+
sock.newsletterUnfollow('1231111111111@newsletter')
|
|
1937
1642
|
|
|
1938
1643
|
// --- Mute and Unmute
|
|
1939
|
-
sock.newsletterMute(
|
|
1940
|
-
sock.newsletterUnmute(
|
|
1644
|
+
sock.newsletterMute('1231111111111@newsletter')
|
|
1645
|
+
sock.newsletterUnmute('1231111111111@newsletter')
|
|
1941
1646
|
|
|
1942
1647
|
// --- Demote admin
|
|
1943
|
-
sock.newsletterDemote(
|
|
1944
|
-
"1231111111111@newsletter",
|
|
1945
|
-
"6281111111111@s.whatsapp.net",
|
|
1946
|
-
);
|
|
1648
|
+
sock.newsletterDemote('1231111111111@newsletter', '6281111111111@s.whatsapp.net')
|
|
1947
1649
|
|
|
1948
1650
|
// --- Change owner
|
|
1949
|
-
sock.newsletterChangeOwner(
|
|
1950
|
-
"1231111111111@newsletter",
|
|
1951
|
-
"6281111111111@s.whatsapp.net",
|
|
1952
|
-
);
|
|
1651
|
+
sock.newsletterChangeOwner('1231111111111@newsletter', '6281111111111@s.whatsapp.net')
|
|
1953
1652
|
|
|
1954
1653
|
// --- Update newsletter
|
|
1955
|
-
sock.newsletterUpdate(
|
|
1956
|
-
name: "@violetix/baileys",
|
|
1957
|
-
});
|
|
1654
|
+
sock.newsletterUpdate('1231111111111@newsletter', { name: '@itsliaaa/baileys' })
|
|
1958
1655
|
|
|
1959
1656
|
// --- Change name
|
|
1960
|
-
sock.newsletterUpdateName(
|
|
1657
|
+
sock.newsletterUpdateName('1231111111111@newsletter', '📦 @itsliaaa/baileys')
|
|
1961
1658
|
|
|
1962
1659
|
// --- Change description
|
|
1963
|
-
sock.newsletterUpdateDescription(
|
|
1964
|
-
"1231111111111@newsletter",
|
|
1965
|
-
"📣 Fresh updates weekly",
|
|
1966
|
-
);
|
|
1660
|
+
sock.newsletterUpdateDescription('1231111111111@newsletter', '📣 Fresh updates weekly')
|
|
1967
1661
|
|
|
1968
1662
|
// --- Change photo
|
|
1969
|
-
sock.newsletterUpdatePicture(
|
|
1970
|
-
|
|
1971
|
-
})
|
|
1663
|
+
sock.newsletterUpdatePicture('1231111111111@newsletter', {
|
|
1664
|
+
url: 'path/to/image.jpg'
|
|
1665
|
+
})
|
|
1972
1666
|
|
|
1973
1667
|
// --- Remove photo
|
|
1974
|
-
sock.newsletterRemovePicture(
|
|
1668
|
+
sock.newsletterRemovePicture('1231111111111@newsletter')
|
|
1975
1669
|
|
|
1976
1670
|
// --- React to a message
|
|
1977
|
-
sock.newsletterReactMessage(
|
|
1671
|
+
sock.newsletterReactMessage('1231111111111@newsletter', '100', '💛')
|
|
1978
1672
|
|
|
1979
1673
|
// --- Get admin count
|
|
1980
|
-
const count = await sock.newsletterAdminCount(
|
|
1674
|
+
const count = await sock.newsletterAdminCount('1231111111111@newsletter')
|
|
1981
1675
|
|
|
1982
1676
|
// --- Get all subscribed newsletters
|
|
1983
|
-
const newsletters = await sock.newsletterSubscribed()
|
|
1984
|
-
console.dir(newsletters, { depth: null })
|
|
1677
|
+
const newsletters = await sock.newsletterSubscribed()
|
|
1678
|
+
console.dir(newsletters, { depth: null })
|
|
1985
1679
|
|
|
1986
1680
|
// --- Fetch newsletter messages
|
|
1987
|
-
const messages = sock.newsletterFetchMessages(
|
|
1988
|
-
|
|
1989
|
-
"1231111111111@newsletter",
|
|
1990
|
-
50,
|
|
1991
|
-
0,
|
|
1992
|
-
0,
|
|
1993
|
-
);
|
|
1994
|
-
console.dir(messages, { depth: null });
|
|
1681
|
+
const messages = sock.newsletterFetchMessages('jid', '1231111111111@newsletter', 50, 0, 0)
|
|
1682
|
+
console.dir(messages, { depth: null })
|
|
1995
1683
|
|
|
1996
1684
|
// --- Delete newsletter
|
|
1997
|
-
sock.newsletterDelete(
|
|
1685
|
+
sock.newsletterDelete('1231111111111@newsletter')
|
|
1998
1686
|
```
|
|
1999
1687
|
|
|
2000
|
-
|
|
1688
|
+
#### 👥 Group Management
|
|
2001
1689
|
|
|
2002
1690
|
```javascript
|
|
2003
1691
|
// --- Create a new one and add participants using their JIDs
|
|
2004
|
-
const group = sock.groupCreate(
|
|
2005
|
-
|
|
2006
|
-
]);
|
|
2007
|
-
console.dir(group, { depth: null });
|
|
1692
|
+
const group = sock.groupCreate('@itsliaaa/baileys', ['628123456789@s.whatsapp.net'])
|
|
1693
|
+
console.dir(group, { depth: null })
|
|
2008
1694
|
|
|
2009
1695
|
// --- Get info
|
|
2010
|
-
const metadata = await sock.groupMetadata(jid)
|
|
2011
|
-
console.dir(metadata, { depth: null })
|
|
1696
|
+
const metadata = await sock.groupMetadata(jid)
|
|
1697
|
+
console.dir(metadata, { depth: null })
|
|
2012
1698
|
|
|
2013
1699
|
// --- Get group invite code
|
|
2014
|
-
const inviteCode = await sock.groupInviteCode(jid)
|
|
2015
|
-
console.dir(inviteCode, { depth: null })
|
|
1700
|
+
const inviteCode = await sock.groupInviteCode(jid)
|
|
1701
|
+
console.dir(inviteCode, { depth: null })
|
|
1702
|
+
|
|
2016
1703
|
|
|
2017
1704
|
// --- Revoke invite link
|
|
2018
|
-
sock.groupRevokeInvite(jid)
|
|
1705
|
+
sock.groupRevokeInvite(jid)
|
|
2019
1706
|
|
|
2020
1707
|
// --- Accept group invite
|
|
2021
|
-
sock.groupAcceptInvite(inviteCode)
|
|
1708
|
+
sock.groupAcceptInvite(inviteCode)
|
|
2022
1709
|
|
|
2023
1710
|
// --- Leave group
|
|
2024
|
-
sock.groupLeave(jid)
|
|
1711
|
+
sock.groupLeave(jid)
|
|
2025
1712
|
|
|
2026
1713
|
// --- Add participants
|
|
2027
|
-
sock.groupParticipantsUpdate(jid, [
|
|
1714
|
+
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'add')
|
|
2028
1715
|
|
|
2029
1716
|
// --- Remove participants
|
|
2030
|
-
sock.groupParticipantsUpdate(jid, [
|
|
1717
|
+
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'remove')
|
|
2031
1718
|
|
|
2032
1719
|
// --- Promote to admin
|
|
2033
|
-
sock.groupParticipantsUpdate(jid, [
|
|
1720
|
+
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'promote')
|
|
2034
1721
|
|
|
2035
1722
|
// --- Demote from admin
|
|
2036
|
-
sock.groupParticipantsUpdate(jid, [
|
|
1723
|
+
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'demote')
|
|
2037
1724
|
|
|
2038
1725
|
// --- Accept join requests
|
|
2039
|
-
sock.groupRequestParticipantsUpdate(
|
|
2040
|
-
jid,
|
|
2041
|
-
["628123456789@s.whatsapp.net"],
|
|
2042
|
-
"approve",
|
|
2043
|
-
);
|
|
1726
|
+
sock.groupRequestParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'approve')
|
|
2044
1727
|
|
|
2045
1728
|
// --- Change name
|
|
2046
|
-
sock.groupUpdateSubject(jid,
|
|
1729
|
+
sock.groupUpdateSubject(jid, '📦 @itsliaaa/baileys')
|
|
2047
1730
|
|
|
2048
1731
|
// --- Change description
|
|
2049
|
-
sock.groupUpdateDescription(jid,
|
|
1732
|
+
sock.groupUpdateDescription(jid, 'Updated description')
|
|
2050
1733
|
|
|
2051
1734
|
// --- Change photo
|
|
2052
1735
|
sock.updateProfilePicture(jid, {
|
|
2053
|
-
|
|
2054
|
-
})
|
|
1736
|
+
url: 'path/to/image.jpg'
|
|
1737
|
+
})
|
|
2055
1738
|
|
|
2056
1739
|
// --- Remove photo
|
|
2057
|
-
sock.removeProfilePicture(jid)
|
|
1740
|
+
sock.removeProfilePicture(jid)
|
|
2058
1741
|
|
|
2059
1742
|
// --- Set group as admin only for chatting
|
|
2060
|
-
sock.groupSettingUpdate(jid,
|
|
1743
|
+
sock.groupSettingUpdate(jid, 'announcement')
|
|
2061
1744
|
|
|
2062
1745
|
// --- Set group as open to all for chatting
|
|
2063
|
-
sock.groupSettingUpdate(jid,
|
|
1746
|
+
sock.groupSettingUpdate(jid, 'not_announcement')
|
|
2064
1747
|
|
|
2065
1748
|
// --- Set admin only can edit group info
|
|
2066
|
-
sock.groupSettingUpdate(jid,
|
|
1749
|
+
sock.groupSettingUpdate(jid, 'locked')
|
|
2067
1750
|
|
|
2068
1751
|
// --- Set all participants can edit group info
|
|
2069
|
-
sock.groupSettingUpdate(jid,
|
|
1752
|
+
sock.groupSettingUpdate(jid, 'unlocked')
|
|
2070
1753
|
|
|
2071
1754
|
// --- Set admin only can add participants
|
|
2072
|
-
sock.groupMemberAddMode(jid,
|
|
1755
|
+
sock.groupMemberAddMode(jid, 'admin_add')
|
|
2073
1756
|
|
|
2074
1757
|
// --- Set all participants can add participants
|
|
2075
|
-
sock.groupMemberAddMode(jid,
|
|
1758
|
+
sock.groupMemberAddMode(jid, 'all_member_add')
|
|
2076
1759
|
|
|
2077
1760
|
// --- Enable or disable temporary messages with seconds format
|
|
2078
|
-
sock.groupToggleEphemeral(jid, 86400)
|
|
1761
|
+
sock.groupToggleEphemeral(jid, 86400)
|
|
2079
1762
|
|
|
2080
1763
|
// --- Disable temporary messages
|
|
2081
|
-
sock.groupToggleEphemeral(jid, 0)
|
|
1764
|
+
sock.groupToggleEphemeral(jid, 0)
|
|
2082
1765
|
|
|
2083
1766
|
// --- Enable or disable membership approval mode
|
|
2084
|
-
sock.groupJoinApprovalMode(jid,
|
|
2085
|
-
sock.groupJoinApprovalMode(jid,
|
|
1767
|
+
sock.groupJoinApprovalMode(jid, 'on')
|
|
1768
|
+
sock.groupJoinApprovalMode(jid, 'off')
|
|
2086
1769
|
|
|
2087
1770
|
// --- Get all groups metadata
|
|
2088
|
-
const groups = await sock.groupFetchAllParticipating()
|
|
2089
|
-
console.dir(groups, { depth: null })
|
|
1771
|
+
const groups = await sock.groupFetchAllParticipating()
|
|
1772
|
+
console.dir(groups, { depth: null })
|
|
2090
1773
|
|
|
2091
1774
|
// --- Get pending join requests
|
|
2092
|
-
const requests = await sock.groupRequestParticipantsList(jid)
|
|
2093
|
-
console.dir(requests, { depth: null })
|
|
1775
|
+
const requests = await sock.groupRequestParticipantsList(jid)
|
|
1776
|
+
console.dir(requests, { depth: null })
|
|
2094
1777
|
|
|
2095
1778
|
// --- Get group info from link
|
|
2096
|
-
const
|
|
2097
|
-
console.log(
|
|
1779
|
+
const group = await sock.groupGetInviteInfo('ABC123456789')
|
|
1780
|
+
console.log('👥 Got group info from invite code', ':', group)
|
|
2098
1781
|
|
|
2099
1782
|
// --- Update bot member label
|
|
2100
|
-
sock.updateMemberLabel(jid,
|
|
1783
|
+
sock.updateMemberLabel(jid, '@itsliaaa/baileys')
|
|
2101
1784
|
```
|
|
2102
1785
|
|
|
2103
|
-
|
|
1786
|
+
#### 👥 Community Management
|
|
2104
1787
|
|
|
2105
1788
|
```javascript
|
|
2106
1789
|
// --- Create a new one and add description
|
|
2107
|
-
const community = await sock.communityCreate(
|
|
2108
|
-
|
|
2109
|
-
"📣 Fresh updates weekly",
|
|
2110
|
-
);
|
|
2111
|
-
console.dir(community, { depth: null });
|
|
1790
|
+
const community = await sock.communityCreate('@itsliaaa/baileys', '📣 Fresh updates weekly')
|
|
1791
|
+
console.dir(community, { depth: null })
|
|
2112
1792
|
|
|
2113
1793
|
// --- Create a subgroup for community and add participants using their JIDs
|
|
2114
|
-
const group = await sock.communityCreateGroup(
|
|
2115
|
-
"📢 Announcements",
|
|
2116
|
-
["628123456789@s.whatsapp.net"],
|
|
2117
|
-
communityJid,
|
|
2118
|
-
);
|
|
1794
|
+
const group = await sock.communityCreateGroup('📢 Announcements', ['628123456789@s.whatsapp.net'], communityJid)
|
|
2119
1795
|
|
|
2120
1796
|
// --- Link an existing group
|
|
2121
|
-
sock.communityLinkGroup(groupJid, communityJid)
|
|
1797
|
+
sock.communityLinkGroup(groupJid, communityJid)
|
|
2122
1798
|
|
|
2123
1799
|
// --- Unlink an existing group
|
|
2124
|
-
sock.communityUnlinkGroup(groupJid, communityJid)
|
|
1800
|
+
sock.communityUnlinkGroup(groupJid, communityJid)
|
|
2125
1801
|
|
|
2126
1802
|
// --- Get info
|
|
2127
|
-
const metadata = await sock.communityMetadata(jid)
|
|
2128
|
-
console.dir(metadata, { depth: null })
|
|
1803
|
+
const metadata = await sock.communityMetadata(jid)
|
|
1804
|
+
console.dir(metadata, { depth: null })
|
|
2129
1805
|
|
|
2130
1806
|
// --- Get community invite code
|
|
2131
|
-
const inviteCode = await sock.communityInviteCode(jid)
|
|
2132
|
-
console.dir(inviteCode, { depth: null })
|
|
1807
|
+
const inviteCode = await sock.communityInviteCode(jid)
|
|
1808
|
+
console.dir(inviteCode, { depth: null })
|
|
2133
1809
|
|
|
2134
1810
|
// --- Revoke invite link
|
|
2135
|
-
sock.communityRevokeInvite(jid)
|
|
1811
|
+
sock.communityRevokeInvite(jid)
|
|
2136
1812
|
|
|
2137
1813
|
// --- Accept community invite
|
|
2138
|
-
sock.communityAcceptInvite(inviteCode)
|
|
1814
|
+
sock.communityAcceptInvite(inviteCode)
|
|
2139
1815
|
|
|
2140
1816
|
// --- Leave community
|
|
2141
|
-
sock.communityLeave(jid)
|
|
1817
|
+
sock.communityLeave(jid)
|
|
2142
1818
|
|
|
2143
1819
|
// --- Accept join requests
|
|
2144
|
-
sock.communityRequestParticipantsUpdate(
|
|
2145
|
-
jid,
|
|
2146
|
-
["628123456789@s.whatsapp.net"],
|
|
2147
|
-
"approve",
|
|
2148
|
-
);
|
|
1820
|
+
sock.communityRequestParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'approve')
|
|
2149
1821
|
|
|
2150
1822
|
// --- Change name
|
|
2151
|
-
sock.communityUpdateSubject(jid,
|
|
1823
|
+
sock.communityUpdateSubject(jid, '📦 @itsliaaa/baileys')
|
|
2152
1824
|
|
|
2153
1825
|
// --- Change description
|
|
2154
|
-
sock.communityUpdateDescription(jid,
|
|
1826
|
+
sock.communityUpdateDescription(jid, 'Updated description')
|
|
2155
1827
|
|
|
2156
1828
|
// --- Set community as admin only for chatting
|
|
2157
|
-
sock.communitySettingUpdate(jid,
|
|
1829
|
+
sock.communitySettingUpdate(jid, 'announcement')
|
|
2158
1830
|
|
|
2159
1831
|
// --- Set community as open to all for chatting
|
|
2160
|
-
sock.communitySettingUpdate(jid,
|
|
1832
|
+
sock.communitySettingUpdate(jid, 'not_announcement')
|
|
2161
1833
|
|
|
2162
1834
|
// --- Set admin only can edit community info
|
|
2163
|
-
sock.communitySettingUpdate(jid,
|
|
1835
|
+
sock.communitySettingUpdate(jid, 'locked')
|
|
2164
1836
|
|
|
2165
1837
|
// --- Set all participants can edit community info
|
|
2166
|
-
sock.communitySettingUpdate(jid,
|
|
1838
|
+
sock.communitySettingUpdate(jid, 'unlocked')
|
|
2167
1839
|
|
|
2168
1840
|
// --- Set admin only can add participants
|
|
2169
|
-
sock.communityMemberAddMode(jid,
|
|
1841
|
+
sock.communityMemberAddMode(jid, 'admin_add')
|
|
2170
1842
|
|
|
2171
1843
|
// --- Set all participants can add participants
|
|
2172
|
-
sock.communityMemberAddMode(jid,
|
|
1844
|
+
sock.communityMemberAddMode(jid, 'all_member_add')
|
|
2173
1845
|
|
|
2174
1846
|
// --- Enable or disable temporary messages with seconds format
|
|
2175
|
-
sock.communityToggleEphemeral(jid, 86400)
|
|
1847
|
+
sock.communityToggleEphemeral(jid, 86400)
|
|
2176
1848
|
|
|
2177
1849
|
// --- Disable temporary messages
|
|
2178
|
-
sock.communityToggleEphemeral(jid, 0)
|
|
1850
|
+
sock.communityToggleEphemeral(jid, 0)
|
|
2179
1851
|
|
|
2180
1852
|
// --- Enable or disable membership approval mode
|
|
2181
|
-
sock.communityJoinApprovalMode(jid,
|
|
2182
|
-
sock.communityJoinApprovalMode(jid,
|
|
1853
|
+
sock.communityJoinApprovalMode(jid, 'on')
|
|
1854
|
+
sock.communityJoinApprovalMode(jid, 'off')
|
|
2183
1855
|
|
|
2184
1856
|
// --- Get all communities metadata
|
|
2185
|
-
const communities = await sock.communityFetchAllParticipating()
|
|
2186
|
-
console.dir(communities, { depth: null })
|
|
1857
|
+
const communities = await sock.communityFetchAllParticipating()
|
|
1858
|
+
console.dir(communities, { depth: null })
|
|
2187
1859
|
|
|
2188
1860
|
// --- Get all community linked groups
|
|
2189
|
-
const linked = await sock.communityFetchLinkedGroups(jid)
|
|
2190
|
-
console.dir(linked, { depth: null })
|
|
1861
|
+
const linked = await sock.communityFetchLinkedGroups(jid)
|
|
1862
|
+
console.dir(linked, { depth: null })
|
|
2191
1863
|
|
|
2192
1864
|
// --- Get pending join requests
|
|
2193
|
-
const requests = await sock.communityRequestParticipantsList(jid)
|
|
2194
|
-
console.dir(requests, { depth: null })
|
|
1865
|
+
const requests = await sock.communityRequestParticipantsList(jid)
|
|
1866
|
+
console.dir(requests, { depth: null })
|
|
2195
1867
|
|
|
2196
1868
|
// --- Get community info from link
|
|
2197
|
-
const
|
|
2198
|
-
console.log(
|
|
1869
|
+
const community = await sock.communityGetInviteInfo('ABC123456789')
|
|
1870
|
+
console.log('👥 Got community info from invite code', ':', community)
|
|
2199
1871
|
```
|
|
2200
1872
|
|
|
2201
|
-
|
|
1873
|
+
#### 👤 Profile Management
|
|
2202
1874
|
|
|
2203
1875
|
```javascript
|
|
2204
1876
|
// --- Get user profile picture
|
|
2205
|
-
const url = await sock.profilePictureUrl(jid,
|
|
2206
|
-
console.log(
|
|
1877
|
+
const url = await sock.profilePictureUrl(jid, 'image')
|
|
1878
|
+
console.log('🖼️ Got user profile url', url)
|
|
2207
1879
|
|
|
2208
1880
|
// --- Update profile picture
|
|
2209
|
-
sock.updateProfilePicture(jid, buffer)
|
|
2210
|
-
sock.updateProfilePicture(jid, { url })
|
|
1881
|
+
sock.updateProfilePicture(jid, buffer)
|
|
1882
|
+
sock.updateProfilePicture(jid, { url })
|
|
2211
1883
|
|
|
2212
1884
|
// --- Remove profile picture
|
|
2213
|
-
sock.removeProfilePicture(jid)
|
|
1885
|
+
sock.removeProfilePicture(jid)
|
|
2214
1886
|
|
|
2215
1887
|
// --- Update profile name
|
|
2216
|
-
sock.updateProfileName(
|
|
1888
|
+
sock.updateProfileName('My Name')
|
|
2217
1889
|
|
|
2218
1890
|
// --- Update profile status
|
|
2219
|
-
sock.updateProfileStatus(
|
|
1891
|
+
sock.updateProfileStatus('Available')
|
|
2220
1892
|
|
|
2221
1893
|
// --- Presence
|
|
2222
|
-
sock.sendPresenceUpdate(
|
|
2223
|
-
sock.presenceSubscribe(jid)
|
|
1894
|
+
sock.sendPresenceUpdate('available', jid)
|
|
1895
|
+
sock.presenceSubscribe(jid)
|
|
2224
1896
|
|
|
2225
1897
|
// --- Read receipts
|
|
2226
|
-
sock.readMessages([message.key])
|
|
2227
|
-
sock.sendReceipt(jid, participant, [messageId],
|
|
1898
|
+
sock.readMessages([message.key])
|
|
1899
|
+
sock.sendReceipt(jid, participant, [messageId], 'read')
|
|
2228
1900
|
|
|
2229
1901
|
// --- Block user
|
|
2230
|
-
sock.updateBlockStatus(jid,
|
|
1902
|
+
sock.updateBlockStatus(jid, 'block')
|
|
2231
1903
|
|
|
2232
1904
|
// --- Unblock user
|
|
2233
|
-
sock.updateBlockStatus(jid,
|
|
1905
|
+
sock.updateBlockStatus(jid, 'unblock')
|
|
2234
1906
|
|
|
2235
1907
|
// --- Fetch blocklist
|
|
2236
|
-
const blocked = await sock.fetchBlocklist()
|
|
2237
|
-
console.dir(blocked, { depth: null })
|
|
1908
|
+
const blocked = await sock.fetchBlocklist()
|
|
1909
|
+
console.dir(blocked, { depth: null })
|
|
2238
1910
|
|
|
2239
1911
|
// --- Modify chats
|
|
2240
|
-
sock.chatModify(
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
},
|
|
2246
|
-
jid,
|
|
2247
|
-
);
|
|
1912
|
+
sock.chatModify({
|
|
1913
|
+
archive: true,
|
|
1914
|
+
lastMessageOrig: message,
|
|
1915
|
+
lastMessage: message
|
|
1916
|
+
}, jid)
|
|
2248
1917
|
|
|
2249
1918
|
// --- Star messages
|
|
2250
|
-
sock.star(jid, [{ id: messageId, fromMe: true }], true)
|
|
1919
|
+
sock.star(jid, [{ id: messageId, fromMe: true }], true)
|
|
2251
1920
|
|
|
2252
1921
|
// --- Contact
|
|
2253
|
-
sock.addOrEditContact(jid, { displayName:
|
|
2254
|
-
sock.removeContact(jid)
|
|
1922
|
+
sock.addOrEditContact(jid, { displayName: 'Starseed' })
|
|
1923
|
+
sock.removeContact(jid)
|
|
2255
1924
|
|
|
2256
1925
|
// --- Label
|
|
2257
|
-
sock.addChatLabel(jid, labelId)
|
|
2258
|
-
sock.removeChatLabel(jid, labelId)
|
|
2259
|
-
sock.addMessageLabel(jid, messageId, labelId)
|
|
1926
|
+
sock.addChatLabel(jid, labelId)
|
|
1927
|
+
sock.removeChatLabel(jid, labelId)
|
|
1928
|
+
sock.addMessageLabel(jid, messageId, labelId)
|
|
2260
1929
|
|
|
2261
1930
|
// --- App state sync
|
|
2262
|
-
sock.resyncAppState([
|
|
1931
|
+
sock.resyncAppState(['regular', 'critical_block'], true)
|
|
2263
1932
|
|
|
2264
1933
|
// --- Get business profile
|
|
2265
|
-
const profile = await sock.getBusinessProfile(jid)
|
|
2266
|
-
console.dir(profile, { depth: null })
|
|
1934
|
+
const profile = await sock.getBusinessProfile(jid)
|
|
1935
|
+
console.dir(profile, { depth: null })
|
|
2267
1936
|
```
|
|
2268
1937
|
|
|
2269
|
-
|
|
1938
|
+
#### 🛒 Business Management
|
|
2270
1939
|
|
|
2271
1940
|
```javascript
|
|
2272
1941
|
// --- Create a new product
|
|
2273
1942
|
const product = await sock.productCreate({
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
})
|
|
2286
|
-
console.dir(product, { depth: null })
|
|
1943
|
+
name: '🧩 Starseed (Premium)',
|
|
1944
|
+
description: 'Get a full version of Starseed!',
|
|
1945
|
+
price: 100000,
|
|
1946
|
+
currency: 'IDR',
|
|
1947
|
+
originCountryCode: 'ID',
|
|
1948
|
+
images: [
|
|
1949
|
+
bufferImage,
|
|
1950
|
+
{
|
|
1951
|
+
url: './path/to/image.jpg'
|
|
1952
|
+
}
|
|
1953
|
+
]
|
|
1954
|
+
})
|
|
1955
|
+
console.dir(product, { depth: null })
|
|
2287
1956
|
|
|
2288
1957
|
// --- Update product
|
|
2289
1958
|
await sock.productUpdate(productId, {
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
})
|
|
1959
|
+
name: '🧩 Starseed (Premium)',
|
|
1960
|
+
description: 'Get a full version of Starseed with more features!',
|
|
1961
|
+
price: 75000,
|
|
1962
|
+
currency: 'IDR',
|
|
1963
|
+
images: [
|
|
1964
|
+
{
|
|
1965
|
+
url: './path/to/image.jpg'
|
|
1966
|
+
}
|
|
1967
|
+
]
|
|
1968
|
+
})
|
|
2300
1969
|
|
|
2301
1970
|
// --- Delete product
|
|
2302
|
-
sock.productDelete([productId])
|
|
1971
|
+
sock.productDelete([productId])
|
|
2303
1972
|
|
|
2304
1973
|
// --- Get catalog info
|
|
2305
1974
|
const { products, nextPageCursor } = await sock.getCatalog({
|
|
2306
|
-
jid:
|
|
2307
|
-
limit: 10
|
|
2308
|
-
})
|
|
1975
|
+
jid: '628123456789@s.whatsapp.net',
|
|
1976
|
+
limit: 10
|
|
1977
|
+
})
|
|
2309
1978
|
|
|
2310
1979
|
// --- Get collections
|
|
2311
|
-
const collections = await sock.getCollections(
|
|
2312
|
-
|
|
2313
|
-
10,
|
|
2314
|
-
);
|
|
2315
|
-
console.dir(collections, { depth: null });
|
|
1980
|
+
const collections = await sock.getCollections('628123456789@s.whatsapp.net', 10)
|
|
1981
|
+
console.dir(collections, { depth: null })
|
|
2316
1982
|
|
|
2317
1983
|
// --- Get order info
|
|
2318
|
-
const order = await sock.getOrderDetails(orderId, tokenBase64)
|
|
2319
|
-
console.dir(order, { depth: null })
|
|
1984
|
+
const order = await sock.getOrderDetails(orderId, tokenBase64)
|
|
1985
|
+
console.dir(order, { depth: null })
|
|
2320
1986
|
|
|
2321
1987
|
// --- Update business profile
|
|
2322
1988
|
await sock.updateBusinessProfile({
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
})
|
|
1989
|
+
address: 'Jakarta, Indonesia',
|
|
1990
|
+
description: '🛒 Official Starseed Store',
|
|
1991
|
+
websites: ['https://www.npmjs.com/package/@itsliaaa/baileys'],
|
|
1992
|
+
email: 'more-more@gmail.com',
|
|
1993
|
+
hours: {
|
|
1994
|
+
timezone: 'Asia/Jakarta',
|
|
1995
|
+
days: [{ day: 'mon', mode: 'open_24h' }]
|
|
1996
|
+
}
|
|
1997
|
+
})
|
|
2332
1998
|
|
|
2333
1999
|
// --- Update cover
|
|
2334
2000
|
sock.updateCoverPhoto({
|
|
2335
|
-
|
|
2336
|
-
})
|
|
2001
|
+
url: './path/to/image.jpg'
|
|
2002
|
+
})
|
|
2337
2003
|
|
|
2338
2004
|
// --- Remove cover
|
|
2339
|
-
sock.removeCoverPhoto(coverId)
|
|
2005
|
+
sock.removeCoverPhoto(coverId)
|
|
2340
2006
|
|
|
2341
2007
|
// --- Update quick replies
|
|
2342
2008
|
sock.addOrEditQuickReply({
|
|
2343
|
-
shortcut:
|
|
2344
|
-
message:
|
|
2345
|
-
})
|
|
2009
|
+
shortcut: 'hello',
|
|
2010
|
+
message: 'Hello from business account',
|
|
2011
|
+
})
|
|
2346
2012
|
|
|
2347
2013
|
// --- Remove quick reply
|
|
2348
|
-
sock.removeQuickReply(timestamp)
|
|
2014
|
+
sock.removeQuickReply(timestamp)
|
|
2349
2015
|
```
|
|
2350
2016
|
|
|
2351
|
-
|
|
2017
|
+
#### 🔐 Privacy Management
|
|
2352
2018
|
|
|
2353
2019
|
```javascript
|
|
2354
2020
|
// --- Update last seen privacy
|
|
2355
|
-
sock.updateLastSeenPrivacy(
|
|
2356
|
-
sock.updateLastSeenPrivacy(
|
|
2357
|
-
sock.updateLastSeenPrivacy(
|
|
2358
|
-
sock.updateLastSeenPrivacy(
|
|
2021
|
+
sock.updateLastSeenPrivacy('all')
|
|
2022
|
+
sock.updateLastSeenPrivacy('contacts')
|
|
2023
|
+
sock.updateLastSeenPrivacy('contact_blacklist')
|
|
2024
|
+
sock.updateLastSeenPrivacy('nobody')
|
|
2359
2025
|
|
|
2360
2026
|
// --- Update online privacy
|
|
2361
|
-
sock.updateOnlinePrivacy(
|
|
2362
|
-
sock.updateOnlinePrivacy(
|
|
2027
|
+
sock.updateOnlinePrivacy('all')
|
|
2028
|
+
sock.updateOnlinePrivacy('match_last_seen')
|
|
2363
2029
|
|
|
2364
2030
|
// --- Update profile picture privacy
|
|
2365
|
-
sock.updateProfilePicturePrivacy(
|
|
2031
|
+
sock.updateProfilePicturePrivacy('contacts')
|
|
2366
2032
|
|
|
2367
2033
|
// --- Update status privacy
|
|
2368
|
-
sock.updateStatusPrivacy(
|
|
2034
|
+
sock.updateStatusPrivacy('contacts')
|
|
2369
2035
|
|
|
2370
2036
|
// --- Update read receipts privacy
|
|
2371
|
-
sock.updateReadReceiptsPrivacy(
|
|
2372
|
-
sock.updateReadReceiptsPrivacy(
|
|
2037
|
+
sock.updateReadReceiptsPrivacy('all')
|
|
2038
|
+
sock.updateReadReceiptsPrivacy('none')
|
|
2373
2039
|
|
|
2374
2040
|
// --- Update groups add privacy
|
|
2375
|
-
sock.updateGroupsAddPrivacy(
|
|
2376
|
-
sock.updateGroupsAddPrivacy(
|
|
2041
|
+
sock.updateGroupsAddPrivacy('all')
|
|
2042
|
+
sock.updateGroupsAddPrivacy('contacts')
|
|
2377
2043
|
|
|
2378
2044
|
// --- Update messages privacy
|
|
2379
|
-
sock.updateMessagesPrivacy(
|
|
2380
|
-
sock.updateMessagesPrivacy(
|
|
2381
|
-
sock.updateMessagesPrivacy(
|
|
2045
|
+
sock.updateMessagesPrivacy('all')
|
|
2046
|
+
sock.updateMessagesPrivacy('contacts')
|
|
2047
|
+
sock.updateMessagesPrivacy('nobody')
|
|
2382
2048
|
|
|
2383
2049
|
// --- Update call privacy
|
|
2384
|
-
sock.updateCallPrivacy(
|
|
2050
|
+
sock.updateCallPrivacy('everyone')
|
|
2385
2051
|
|
|
2386
2052
|
// --- Update default disappearing mode
|
|
2387
|
-
sock.updateDefaultDisappearingMode(86400)
|
|
2053
|
+
sock.updateDefaultDisappearingMode(86400)
|
|
2388
2054
|
|
|
2389
2055
|
// --- Update link previews privacy
|
|
2390
|
-
sock.updateDisableLinkPreviewsPrivacy(true)
|
|
2056
|
+
sock.updateDisableLinkPreviewsPrivacy(true)
|
|
2391
2057
|
```
|
|
2392
2058
|
|
|
2393
|
-
The methods above use plain IQ stanzas. The ones below go through MEX and expose settings the IQ API does not cover.
|
|
2059
|
+
The methods above use plain IQ stanzas. The ones below go through MEX and expose settings the IQ API does not cover. **[NEW]**
|
|
2060
|
+
|
|
2394
2061
|
> [!NOTE]
|
|
2395
2062
|
> MEX feature and setting values are lowercase and case-sensitive on the wire.
|
|
2396
2063
|
>
|
|
@@ -2399,66 +2066,65 @@ The methods above use plain IQ stanzas. The ones below go through MEX and expose
|
|
|
2399
2066
|
|
|
2400
2067
|
```javascript
|
|
2401
2068
|
// --- Read every privacy setting for your own account
|
|
2402
|
-
const settings = await sock.getPrivacySettings(sock.user.id)
|
|
2069
|
+
const settings = await sock.getPrivacySettings(sock.user.id)
|
|
2403
2070
|
|
|
2404
2071
|
// --- Change a privacy setting
|
|
2405
|
-
await sock.setPrivacySetting(
|
|
2406
|
-
await sock.setPrivacySetting(
|
|
2072
|
+
await sock.setPrivacySetting('last', 'contacts')
|
|
2073
|
+
await sock.setPrivacySetting('defense', 'on_standard')
|
|
2407
2074
|
|
|
2408
2075
|
// --- Manage the allow/deny list attached to a setting
|
|
2409
|
-
await sock.getPrivacyContactList(
|
|
2410
|
-
await sock.updatePrivacyContactList(
|
|
2411
|
-
|
|
2412
|
-
])
|
|
2076
|
+
await sock.getPrivacyContactList('groupadd', 'contact_blacklist')
|
|
2077
|
+
await sock.updatePrivacyContactList('groupadd', 'contact_blacklist', [
|
|
2078
|
+
'6281111111111@s.whatsapp.net'
|
|
2079
|
+
])
|
|
2413
2080
|
|
|
2414
2081
|
// --- About text (your own, and other people's)
|
|
2415
|
-
await sock.updateTextStatus(
|
|
2416
|
-
const abouts = await sock.getTextStatusList([
|
|
2082
|
+
await sock.updateTextStatus('Available for chats 👋')
|
|
2083
|
+
const abouts = await sock.getTextStatusList(['6281111111111@s.whatsapp.net'])
|
|
2417
2084
|
|
|
2418
2085
|
// --- Only return About texts newer than a timestamp
|
|
2419
|
-
await sock.getTextStatusList(jids, Date.now() - 24 * 60 * 60 * 1000)
|
|
2086
|
+
await sock.getTextStatusList(jids, Date.now() - 24 * 60 * 60 * 1000)
|
|
2420
2087
|
|
|
2421
2088
|
// --- Verify a JID is reachable before opening a chat
|
|
2422
|
-
const check = await sock.contactIntegrityQuery([
|
|
2423
|
-
|
|
2424
|
-
]);
|
|
2425
|
-
const bizCheck = await sock.bizIntegrityQuery(["6281111111111@s.whatsapp.net"]);
|
|
2089
|
+
const check = await sock.contactIntegrityQuery(['6281111111111@s.whatsapp.net'])
|
|
2090
|
+
const bizCheck = await sock.bizIntegrityQuery(['6281111111111@s.whatsapp.net'])
|
|
2426
2091
|
|
|
2427
2092
|
// --- Profile picture
|
|
2428
|
-
const info = await sock.fetchUserPictureInfo(
|
|
2429
|
-
await sock.setProfilePictureMex(imageBase64,
|
|
2430
|
-
await sock.setProfilePictureMex(imageBase64,
|
|
2093
|
+
const info = await sock.fetchUserPictureInfo('6281111111111@s.whatsapp.net')
|
|
2094
|
+
await sock.setProfilePictureMex(imageBase64, 'image') // full resolution
|
|
2095
|
+
await sock.setProfilePictureMex(imageBase64, 'preview') // thumbnail
|
|
2431
2096
|
|
|
2432
2097
|
// --- Linked social profiles (FB & IG)
|
|
2433
|
-
await sock.linkedProfilesSet([{ type:
|
|
2434
|
-
await sock.linkedProfilesUpdate([{ type:
|
|
2435
|
-
await sock.linkedProfilesRemove([
|
|
2098
|
+
await sock.linkedProfilesSet([{ type: 'IG', username: 'someone' }])
|
|
2099
|
+
await sock.linkedProfilesUpdate([{ type: 'IG', showOnProfile: true }])
|
|
2100
|
+
await sock.linkedProfilesRemove(['IG'])
|
|
2436
2101
|
|
|
2437
2102
|
// --- Trusted devices
|
|
2438
|
-
const devices = await sock.getTrustedDevices()
|
|
2439
|
-
await sock.addTrustedDevice(deviceId,
|
|
2440
|
-
await sock.untrustTrustedDevice(deviceId)
|
|
2441
|
-
await sock.deleteTrustedDevice(deviceId)
|
|
2103
|
+
const devices = await sock.getTrustedDevices()
|
|
2104
|
+
await sock.addTrustedDevice(deviceId, 'My Laptop')
|
|
2105
|
+
await sock.untrustTrustedDevice(deviceId)
|
|
2106
|
+
await sock.deleteTrustedDevice(deviceId)
|
|
2442
2107
|
|
|
2443
2108
|
// --- Misc
|
|
2444
|
-
await sock.fetchMobileConfig()
|
|
2445
|
-
await sock.migrateBlocklistLid([
|
|
2109
|
+
await sock.fetchMobileConfig()
|
|
2110
|
+
await sock.migrateBlocklistLid(['6281111111111@s.whatsapp.net'])
|
|
2446
2111
|
|
|
2447
2112
|
// --- Raw query IDs, if you need to build a query yourself
|
|
2448
|
-
sock.PRIVACY_MEX_IDS
|
|
2113
|
+
sock.PRIVACY_MEX_IDS
|
|
2449
2114
|
```
|
|
2450
2115
|
|
|
2451
|
-
|
|
2116
|
+
#### 🆔 Username Management
|
|
2117
|
+
|
|
2118
|
+
WhatsApp usernames (`@username`) let people be found without sharing a phone number. **[NEW]**
|
|
2452
2119
|
|
|
2453
|
-
WhatsApp usernames (`@username`) let people be found without sharing a phone number.
|
|
2454
2120
|
> [!NOTE]
|
|
2455
2121
|
> Usernames are looked up over USync, while your own username is managed over MEX. Pass the username **without** the leading `@` — a leading `@` is stripped for you.
|
|
2456
2122
|
|
|
2457
2123
|
```javascript
|
|
2458
2124
|
// --- Look up accounts by username
|
|
2459
|
-
const results = await sock.onWhatsAppUsername(
|
|
2125
|
+
const results = await sock.onWhatsAppUsername('someusername')
|
|
2460
2126
|
|
|
2461
|
-
console.log(
|
|
2127
|
+
console.log('🆔 Got user', ':', results)
|
|
2462
2128
|
|
|
2463
2129
|
// --- Output
|
|
2464
2130
|
// [
|
|
@@ -2470,15 +2136,15 @@ console.log("🆔 Got user", ":", results);
|
|
|
2470
2136
|
// ]
|
|
2471
2137
|
|
|
2472
2138
|
// --- Look up several at once, with a PIN for protected usernames
|
|
2473
|
-
await sock.onWhatsAppUsername(
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2139
|
+
await sock.onWhatsAppUsername(
|
|
2140
|
+
'someusername',
|
|
2141
|
+
{ username: 'protectedname', usernameKey: '1234' }
|
|
2142
|
+
)
|
|
2477
2143
|
|
|
2478
2144
|
// --- Fetch the username of one or more JIDs
|
|
2479
|
-
const usernames = await sock.fetchUsername(
|
|
2145
|
+
const usernames = await sock.fetchUsername('6281111111111@s.whatsapp.net')
|
|
2480
2146
|
|
|
2481
|
-
console.log(
|
|
2147
|
+
console.log('🆔 Got username', ':', usernames)
|
|
2482
2148
|
|
|
2483
2149
|
// --- Output
|
|
2484
2150
|
// [
|
|
@@ -2494,442 +2160,299 @@ Managing your own username is a two-step flow — check availability first, then
|
|
|
2494
2160
|
|
|
2495
2161
|
```javascript
|
|
2496
2162
|
// --- Step 1: check availability
|
|
2497
|
-
const check = await sock.checkUsername(
|
|
2163
|
+
const check = await sock.checkUsername('myusername')
|
|
2498
2164
|
|
|
2499
2165
|
if (!check.available) {
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
// --- Step 2: claim it, reusing the session_id from the check
|
|
2504
|
-
await sock.setUsername("myusername", {
|
|
2505
|
-
sessionId: check.session_id,
|
|
2506
|
-
});
|
|
2166
|
+
console.log('🆔 Taken. Try', ':', check.suggestions)
|
|
2167
|
+
console.log('🆔 Rejected because', ':', check.rejectionReasons)
|
|
2168
|
+
return
|
|
2507
2169
|
}
|
|
2508
|
-
```
|
|
2509
2170
|
|
|
2510
|
-
|
|
2171
|
+
// --- Step 2: claim it, reusing the session_id from the check
|
|
2172
|
+
await sock.setUsername('myusername', {
|
|
2173
|
+
sessionId: check.session_id
|
|
2174
|
+
})
|
|
2511
2175
|
|
|
2512
|
-
```javascript
|
|
2513
2176
|
// --- Claim one of the server's suggestions
|
|
2514
2177
|
await sock.setUsername(check.suggestions[0], {
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
})
|
|
2178
|
+
source: 'SUGGESTION',
|
|
2179
|
+
sessionId: check.session_id
|
|
2180
|
+
})
|
|
2518
2181
|
|
|
2519
2182
|
// --- Claim with a PIN protecting it
|
|
2520
|
-
await sock.setUsername(
|
|
2521
|
-
|
|
2522
|
-
})
|
|
2183
|
+
await sock.setUsername('myusername', {
|
|
2184
|
+
pin: '1234'
|
|
2185
|
+
})
|
|
2523
2186
|
|
|
2524
2187
|
// --- Read your own username
|
|
2525
|
-
const mine = await sock.getMyUsername()
|
|
2188
|
+
const mine = await sock.getMyUsername()
|
|
2526
2189
|
|
|
2527
2190
|
// --- Change or remove the PIN
|
|
2528
|
-
await sock.setUsernamePin(
|
|
2529
|
-
await sock.setUsernamePin(null)
|
|
2191
|
+
await sock.setUsernamePin('1234')
|
|
2192
|
+
await sock.setUsernamePin(null)
|
|
2530
2193
|
|
|
2531
2194
|
// --- Remove your username entirely
|
|
2532
|
-
await sock.deleteUsername()
|
|
2195
|
+
await sock.deleteUsername()
|
|
2533
2196
|
```
|
|
2534
2197
|
|
|
2535
|
-
|
|
2198
|
+
#### 🔍 USync Queries
|
|
2199
|
+
|
|
2200
|
+
USync fetches user data in bulk. Chain the protocols you need onto a single query. **[NEW]**
|
|
2536
2201
|
|
|
2537
|
-
USync fetches user data in bulk. Chain the protocols you need onto a single query.
|
|
2538
2202
|
```javascript
|
|
2539
|
-
import { USyncQuery, USyncUser } from
|
|
2203
|
+
import { USyncQuery, USyncUser } from '@itsliaaa/baileys'
|
|
2540
2204
|
|
|
2541
2205
|
// --- Business profile, profile picture, and About text in one round trip
|
|
2542
2206
|
const query = new USyncQuery()
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2207
|
+
.withBusinessProtocol()
|
|
2208
|
+
.withPictureProtocol('preview')
|
|
2209
|
+
.withTextStatusProtocol()
|
|
2210
|
+
.withUser(new USyncUser().withId('6281111111111@s.whatsapp.net'))
|
|
2547
2211
|
|
|
2548
|
-
const result = await sock.executeUSyncQuery(query)
|
|
2212
|
+
const result = await sock.executeUSyncQuery(query)
|
|
2549
2213
|
|
|
2550
|
-
console.log(
|
|
2214
|
+
console.log('🔍 Got data', ':', result.list)
|
|
2551
2215
|
|
|
2552
2216
|
// --- Device feature flags
|
|
2553
2217
|
const features = new USyncQuery()
|
|
2554
|
-
|
|
2555
|
-
|
|
2218
|
+
.withFeatureProtocol(['voip', 'encrypt_v2'])
|
|
2219
|
+
.withUser(new USyncUser().withId('6281111111111@s.whatsapp.net'))
|
|
2556
2220
|
|
|
2557
|
-
await sock.executeUSyncQuery(features)
|
|
2221
|
+
await sock.executeUSyncQuery(features)
|
|
2558
2222
|
```
|
|
2559
2223
|
|
|
2560
|
-
| Protocol
|
|
2561
|
-
|
|
|
2562
|
-
| `withBusinessProtocol(profileVersion?)`
|
|
2563
|
-
| `withPictureProtocol(type?)`
|
|
2564
|
-
| `withTextStatusProtocol()`
|
|
2565
|
-
| `withSidelistProtocol(useLidAddressing?)` | Side-list entries, returned in `result.sideList`
|
|
2566
|
-
| `withFeatureProtocol(features?)`
|
|
2224
|
+
| Protocol | Returns |
|
|
2225
|
+
| --- | --- |
|
|
2226
|
+
| `withBusinessProtocol(profileVersion?)` | Verified name and level, business hours, address, catalog and cart flags |
|
|
2227
|
+
| `withPictureProtocol(type?)` | Picture `id`, `directPath`, and `hash` — `'image'` (default) or `'preview'` |
|
|
2228
|
+
| `withTextStatusProtocol()` | About `text`, `emoji`, `setAt`, and `expiresAt` |
|
|
2229
|
+
| `withSidelistProtocol(useLidAddressing?)` | Side-list entries, returned in `result.sideList` |
|
|
2230
|
+
| `withFeatureProtocol(features?)` | Device feature flags — defaults to all known features |
|
|
2567
2231
|
|
|
2568
2232
|
The query result also carries per-protocol diagnostics:
|
|
2569
2233
|
|
|
2570
2234
|
```javascript
|
|
2571
|
-
const result = await sock.executeUSyncQuery(query)
|
|
2235
|
+
const result = await sock.executeUSyncQuery(query)
|
|
2572
2236
|
|
|
2573
|
-
result.list
|
|
2574
|
-
result.sideList
|
|
2575
|
-
result.errors
|
|
2576
|
-
result.refresh
|
|
2237
|
+
result.list // matched users
|
|
2238
|
+
result.sideList // side-list users, when the sidelist protocol was requested
|
|
2239
|
+
result.errors // { [protocol]: { errorCode, errorText, errorBackoff } }
|
|
2240
|
+
result.refresh // { [protocol]: seconds } — how long the response stays cacheable
|
|
2577
2241
|
|
|
2578
2242
|
// A contact who blocked you is flagged instead of throwing
|
|
2579
|
-
result.list[0].isBlockedByContact
|
|
2243
|
+
result.list[0].isBlockedByContact
|
|
2580
2244
|
```
|
|
2581
2245
|
|
|
2582
2246
|
> [!TIP]
|
|
2583
2247
|
> When `result.errors` carries an `errorBackoff`, wait at least that many seconds before repeating the same protocol — otherwise the server keeps rejecting it.
|
|
2584
2248
|
|
|
2585
|
-
|
|
2249
|
+
#### 🤝 Interoperability (BirdyChat & Haiket)
|
|
2250
|
+
|
|
2251
|
+
Chat with users on third-party platforms that WhatsApp has opened up to. **[NEW]**
|
|
2586
2252
|
|
|
2587
|
-
Chat with users on third-party platforms that WhatsApp has opened up to.
|
|
2588
2253
|
```javascript
|
|
2589
2254
|
// --- List the integrators the server offers
|
|
2590
|
-
const integrators = await sock.fetchIntegrators()
|
|
2255
|
+
const integrators = await sock.fetchIntegrators()
|
|
2591
2256
|
|
|
2592
|
-
console.log(
|
|
2257
|
+
console.log('🤝 Got integrators', ':', integrators)
|
|
2593
2258
|
|
|
2594
2259
|
// --- Opt in (accepts the interop TOS and opts in, in one call)
|
|
2595
|
-
await sock.initInterop()
|
|
2260
|
+
await sock.initInterop()
|
|
2596
2261
|
|
|
2597
2262
|
// --- Or opt in and out manually
|
|
2598
|
-
await sock.acceptInteropTOS()
|
|
2599
|
-
await sock.optInIntegrators([sock.INTEGRATOR_BIRDYCHAT])
|
|
2600
|
-
await sock.optOutIntegrators([sock.INTEGRATOR_HAIKET])
|
|
2263
|
+
await sock.acceptInteropTOS()
|
|
2264
|
+
await sock.optInIntegrators([sock.INTEGRATOR_BIRDYCHAT])
|
|
2265
|
+
await sock.optOutIntegrators([sock.INTEGRATOR_HAIKET])
|
|
2601
2266
|
|
|
2602
2267
|
// --- Resolve an interop identifier into a JID
|
|
2603
|
-
const user = await sock.resolveInteropUser(
|
|
2604
|
-
const users = await sock.resolveInteropUsers([
|
|
2268
|
+
const user = await sock.resolveInteropUser('someone@example.com')
|
|
2269
|
+
const users = await sock.resolveInteropUsers(['6281111111111'])
|
|
2605
2270
|
|
|
2606
2271
|
// --- Interop groups
|
|
2607
|
-
await sock.createInteropGroup(subject, participants)
|
|
2608
|
-
await sock.addParticipantsToInteropGroup(groupJid, participants)
|
|
2609
|
-
await sock.queryInteropGroupInfo(groupJid)
|
|
2610
|
-
await sock.leaveInteropGroup(groupJid)
|
|
2272
|
+
await sock.createInteropGroup(subject, participants)
|
|
2273
|
+
await sock.addParticipantsToInteropGroup(groupJid, participants)
|
|
2274
|
+
await sock.queryInteropGroupInfo(groupJid)
|
|
2275
|
+
await sock.leaveInteropGroup(groupJid)
|
|
2611
2276
|
|
|
2612
2277
|
// --- Moderation & privacy
|
|
2613
|
-
await sock.blockInteropUser(jid)
|
|
2614
|
-
await sock.unblockInteropUser(jid)
|
|
2615
|
-
await sock.reportInteropSpam(jid)
|
|
2616
|
-
await sock.trustInteropContact(jid)
|
|
2617
|
-
await sock.getReachabilitySettings()
|
|
2618
|
-
await sock.queryInteropPrivacySettings()
|
|
2619
|
-
await sock.updateInteropPrivacySetting(feature, setting)
|
|
2278
|
+
await sock.blockInteropUser(jid)
|
|
2279
|
+
await sock.unblockInteropUser(jid)
|
|
2280
|
+
await sock.reportInteropSpam(jid)
|
|
2281
|
+
await sock.trustInteropContact(jid)
|
|
2282
|
+
await sock.getReachabilitySettings()
|
|
2283
|
+
await sock.queryInteropPrivacySettings()
|
|
2284
|
+
await sock.updateInteropPrivacySetting(feature, setting)
|
|
2620
2285
|
|
|
2621
2286
|
// --- Force a fresh Signal session on the next send
|
|
2622
|
-
await sock.resetInteropSession(jid)
|
|
2287
|
+
await sock.resetInteropSession(jid)
|
|
2623
2288
|
```
|
|
2624
2289
|
|
|
2625
2290
|
> [!NOTE]
|
|
2626
2291
|
> `INTEGRATOR_BIRDYCHAT` identifies users by email, `INTEGRATOR_HAIKET` by phone number.
|
|
2627
2292
|
|
|
2628
|
-
|
|
2293
|
+
#### 🔒 Account Security (Password & Passkey)
|
|
2294
|
+
|
|
2295
|
+
Account-level password and passkey (FIDO2 / WebAuthn) management. **[NEW]**
|
|
2629
2296
|
|
|
2630
|
-
Account-level password and passkey (FIDO2 / WebAuthn) management.
|
|
2631
2297
|
> [!CAUTION]
|
|
2632
2298
|
> These change the security settings of the WhatsApp account itself, not just this session. Losing a password or passkey you set here can lock you out of the account.
|
|
2633
2299
|
|
|
2634
2300
|
```javascript
|
|
2635
2301
|
// --- Password
|
|
2636
|
-
const { has_password } = await sock.hasPassword()
|
|
2637
|
-
await sock.setPassword(
|
|
2638
|
-
await sock.setPassword(
|
|
2639
|
-
await sock.checkPassword(
|
|
2640
|
-
await sock.deletePassword(
|
|
2302
|
+
const { has_password } = await sock.hasPassword()
|
|
2303
|
+
await sock.setPassword('my-secure-password')
|
|
2304
|
+
await sock.setPassword('new-password', 'old-password')
|
|
2305
|
+
await sock.checkPassword('my-secure-password')
|
|
2306
|
+
await sock.deletePassword('my-secure-password')
|
|
2641
2307
|
|
|
2642
2308
|
// --- Passkey
|
|
2643
|
-
const exists = await sock.passkeyExists()
|
|
2644
|
-
const list = await sock.passkeyListExists()
|
|
2645
|
-
const challenge = await sock.passkeyRequestChallenge()
|
|
2646
|
-
await sock.passkeyVerifyChallenge(
|
|
2647
|
-
|
|
2648
|
-
authenticatorData,
|
|
2649
|
-
clientDataJson,
|
|
2650
|
-
signature,
|
|
2651
|
-
);
|
|
2652
|
-
await sock.passkeyDelete(credentialId);
|
|
2309
|
+
const exists = await sock.passkeyExists()
|
|
2310
|
+
const list = await sock.passkeyListExists()
|
|
2311
|
+
const challenge = await sock.passkeyRequestChallenge()
|
|
2312
|
+
await sock.passkeyVerifyChallenge(credentialId, authenticatorData, clientDataJson, signature)
|
|
2313
|
+
await sock.passkeyDelete(credentialId)
|
|
2653
2314
|
|
|
2654
2315
|
// --- Contacts backup
|
|
2655
|
-
await sock.contactsUpload(contacts)
|
|
2656
|
-
await sock.contactsBackup(contacts)
|
|
2657
|
-
await sock.contactsBackupQuery()
|
|
2658
|
-
await sock.selfContactsQuery()
|
|
2316
|
+
await sock.contactsUpload(contacts)
|
|
2317
|
+
await sock.contactsBackup(contacts)
|
|
2318
|
+
await sock.contactsBackupQuery()
|
|
2319
|
+
await sock.selfContactsQuery()
|
|
2659
2320
|
|
|
2660
2321
|
// --- Misc account
|
|
2661
|
-
await sock.getWaMeLink()
|
|
2662
|
-
await sock.userCountryCodeGet()
|
|
2663
|
-
await sock.removeAccountReachoutTimelock()
|
|
2664
|
-
await sock.fetchUserNoticesById(noticeIds)
|
|
2322
|
+
await sock.getWaMeLink()
|
|
2323
|
+
await sock.userCountryCodeGet()
|
|
2324
|
+
await sock.removeAccountReachoutTimelock()
|
|
2325
|
+
await sock.fetchUserNoticesById(noticeIds)
|
|
2665
2326
|
|
|
2666
2327
|
// --- Raw query IDs
|
|
2667
|
-
sock.REGISTRATION_MEX_IDS
|
|
2328
|
+
sock.REGISTRATION_MEX_IDS
|
|
2668
2329
|
```
|
|
2669
2330
|
|
|
2670
|
-
|
|
2331
|
+
#### 👪 Managed Accounts & Payments
|
|
2332
|
+
|
|
2333
|
+
Parental / family account linking, payments passkey, and UPI onboarding. **[NEW]**
|
|
2671
2334
|
|
|
2672
|
-
Parental / family account linking, payments passkey, and UPI onboarding.
|
|
2673
2335
|
```javascript
|
|
2674
2336
|
// --- Managed (supervised) accounts
|
|
2675
|
-
await sock.managedAccountQuery(jid)
|
|
2676
|
-
await sock.managedAccountInitiateLinking(
|
|
2677
|
-
await sock.managedAccountValidateLinking(linkingToken, sponsorJid)
|
|
2678
|
-
await sock.managedAccountAcceptLinking(linkingToken)
|
|
2679
|
-
await sock.managedAccountCompleteLinking(linkingToken)
|
|
2680
|
-
await sock.managedAccountRevokeLinking(sponsoredJid)
|
|
2681
|
-
await sock.managedAccountSyncActivities(jid)
|
|
2682
|
-
await sock.managedAccountUpdatePin(pin)
|
|
2337
|
+
await sock.managedAccountQuery(jid)
|
|
2338
|
+
await sock.managedAccountInitiateLinking('6281111111111')
|
|
2339
|
+
await sock.managedAccountValidateLinking(linkingToken, sponsorJid)
|
|
2340
|
+
await sock.managedAccountAcceptLinking(linkingToken)
|
|
2341
|
+
await sock.managedAccountCompleteLinking(linkingToken)
|
|
2342
|
+
await sock.managedAccountRevokeLinking(sponsoredJid)
|
|
2343
|
+
await sock.managedAccountSyncActivities(jid)
|
|
2344
|
+
await sock.managedAccountUpdatePin(pin)
|
|
2683
2345
|
|
|
2684
2346
|
// --- Payments passkey
|
|
2685
|
-
await sock.paymentsPasskeyHasCredential()
|
|
2686
|
-
await sock.paymentsPasskeyEnrollChallenge()
|
|
2687
|
-
await sock.paymentsPasskeyEnrollVerify(credential)
|
|
2688
|
-
await sock.paymentsPasskeyToggleOn()
|
|
2689
|
-
await sock.paymentsPasskeyToggleOff()
|
|
2690
|
-
await sock.paymentsIsAccountRecoverable()
|
|
2347
|
+
await sock.paymentsPasskeyHasCredential()
|
|
2348
|
+
await sock.paymentsPasskeyEnrollChallenge()
|
|
2349
|
+
await sock.paymentsPasskeyEnrollVerify(credential)
|
|
2350
|
+
await sock.paymentsPasskeyToggleOn()
|
|
2351
|
+
await sock.paymentsPasskeyToggleOff()
|
|
2352
|
+
await sock.paymentsIsAccountRecoverable()
|
|
2691
2353
|
|
|
2692
2354
|
// --- UPI onboarding (India)
|
|
2693
|
-
await sock.upiSendOtp(phoneNumber)
|
|
2694
|
-
await sock.upiVerifyOtp(phoneNumber, otp)
|
|
2355
|
+
await sock.upiSendOtp(phoneNumber)
|
|
2356
|
+
await sock.upiVerifyOtp(phoneNumber, otp)
|
|
2695
2357
|
|
|
2696
2358
|
// --- Raw query IDs
|
|
2697
|
-
sock.MANAGED_ACCOUNT_MEX_IDS
|
|
2359
|
+
sock.MANAGED_ACCOUNT_MEX_IDS
|
|
2698
2360
|
```
|
|
2699
2361
|
|
|
2700
|
-
|
|
2362
|
+
#### 🌐 HTTPS GraphQL (Meta AI & Imagine)
|
|
2363
|
+
|
|
2364
|
+
Meta AI, Imagine, events, and payments run over HTTPS GraphQL rather than the WebSocket. **[NEW]**
|
|
2701
2365
|
|
|
2702
|
-
Meta AI, Imagine, events, and payments run over HTTPS GraphQL rather than the WebSocket.
|
|
2703
2366
|
> [!IMPORTANT]
|
|
2704
2367
|
> These calls need an ACS access token. `acquireAccessToken()` fetches one for you on the first call (nonce → exchange) and caches it, so you normally do not have to do anything. Pass your own with `setAccessToken()` if you already have one.
|
|
2705
2368
|
|
|
2706
2369
|
```javascript
|
|
2707
2370
|
// --- Token handling (optional — acquired on demand otherwise)
|
|
2708
|
-
await sock.acquireAccessToken()
|
|
2709
|
-
sock.setAccessToken(token)
|
|
2710
|
-
sock.setWamoAuth(auth, host)
|
|
2371
|
+
await sock.acquireAccessToken()
|
|
2372
|
+
sock.setAccessToken(token)
|
|
2373
|
+
sock.setWamoAuth(auth, host)
|
|
2711
2374
|
|
|
2712
2375
|
// --- Meta AI memory
|
|
2713
|
-
await sock.metaAiMemoryQuery()
|
|
2714
|
-
await sock.metaAiMemoryDelete(memoryId)
|
|
2715
|
-
await sock.metaAiMemoryDeleteAll()
|
|
2716
|
-
await sock.metaAiMemoryOptOutStatus()
|
|
2717
|
-
await sock.metaAiMemoryOptOutUpdate(true)
|
|
2376
|
+
await sock.metaAiMemoryQuery()
|
|
2377
|
+
await sock.metaAiMemoryDelete(memoryId)
|
|
2378
|
+
await sock.metaAiMemoryDeleteAll()
|
|
2379
|
+
await sock.metaAiMemoryOptOutStatus()
|
|
2380
|
+
await sock.metaAiMemoryOptOutUpdate(true)
|
|
2718
2381
|
|
|
2719
2382
|
// --- Imagine (image & video generation)
|
|
2720
|
-
await sock.imagineIntents(
|
|
2721
|
-
await sock.imagineEdit(imageId,
|
|
2722
|
-
await sock.imagineExpand(imageId,
|
|
2723
|
-
await sock.imagineGenerateAnimate(imageId)
|
|
2724
|
-
await sock.imagineVideoStatus(jobId)
|
|
2383
|
+
await sock.imagineIntents('a cat wearing sunglasses')
|
|
2384
|
+
await sock.imagineEdit(imageId, 'make it night time')
|
|
2385
|
+
await sock.imagineExpand(imageId, 'left')
|
|
2386
|
+
await sock.imagineGenerateAnimate(imageId)
|
|
2387
|
+
await sock.imagineVideoStatus(jobId)
|
|
2725
2388
|
|
|
2726
2389
|
// --- AI personas
|
|
2727
|
-
await sock.aiHomeFetchUserCreatedPersonas()
|
|
2728
|
-
await sock.aiCreationUpdatePersona(botId, updates)
|
|
2729
|
-
await sock.aiCreationDeletePersona(botId)
|
|
2390
|
+
await sock.aiHomeFetchUserCreatedPersonas()
|
|
2391
|
+
await sock.aiCreationUpdatePersona(botId, updates)
|
|
2392
|
+
await sock.aiCreationDeletePersona(botId)
|
|
2730
2393
|
|
|
2731
2394
|
// --- Raw executors, for queries not wrapped above
|
|
2732
|
-
await sock.executeWWWGraphQL(docId, variables, token, dataPath)
|
|
2733
|
-
await sock.executeFacebookGraphQL(docId, variables, token, dataPath)
|
|
2734
|
-
await sock.executeWamoGraphQL(docId, variables, wamoAuth, dataPath, wamoHost)
|
|
2395
|
+
await sock.executeWWWGraphQL(docId, variables, token, dataPath)
|
|
2396
|
+
await sock.executeFacebookGraphQL(docId, variables, token, dataPath)
|
|
2397
|
+
await sock.executeWamoGraphQL(docId, variables, wamoAuth, dataPath, wamoHost)
|
|
2735
2398
|
|
|
2736
2399
|
// --- Raw doc ID dictionaries
|
|
2737
|
-
sock.WWW_GQL_IDS
|
|
2738
|
-
sock.FACEBOOK_GQL_IDS
|
|
2739
|
-
sock.WAMO_GQL_IDS
|
|
2740
|
-
sock.CLIENT_PERSIST_GQL_IDS
|
|
2400
|
+
sock.WWW_GQL_IDS
|
|
2401
|
+
sock.FACEBOOK_GQL_IDS
|
|
2402
|
+
sock.WAMO_GQL_IDS
|
|
2403
|
+
sock.CLIENT_PERSIST_GQL_IDS
|
|
2741
2404
|
```
|
|
2742
2405
|
|
|
2743
2406
|
> [!WARNING]
|
|
2744
2407
|
> These calls leave the WhatsApp WebSocket and hit Meta's HTTPS endpoints directly. They have no built-in timeout, so wrap them in your own if a hung request would stall your bot.
|
|
2745
2408
|
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
})
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
})
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
```javascript
|
|
2794
|
-
// the quoted message names the recipient — its author
|
|
2795
|
-
await sock.sendMessage(m.chat, { text: "Hi, only you can see this." }, { quoted: m, exclusive: true });
|
|
2796
|
-
|
|
2797
|
-
// or address someone else explicitly, in the group's own addressing mode
|
|
2798
|
-
await sock.sendMessage(groupJid, { text: "psst" }, { exclusive: "43411111111111@lid" });
|
|
2799
|
-
```
|
|
2800
|
-
|
|
2801
|
-
`exclusive: true` requires `quoted` — the quoted message's author is the only place the recipient comes from, and it already carries the group's addressing mode (a LID-addressed group quotes `@lid`, a PN one quotes `@s.whatsapp.net`), so nothing has to be mapped. Without a quote, or with a quote that has no `participant` (a 1:1 quote), the send throws. So does `exclusive` outside a group.
|
|
2802
|
-
|
|
2803
|
-
How it works: the stanza goes out as `to=<group> participant=<member>` with per-device `pkmsg`/`msg` encryption instead of the group sender key, reusing the retry-resend path. A `skmsg` stanza is fanned out to the whole group by the server, so sender-key sends can never be targeted. One stanza per device of the recipient, all sharing the message id.
|
|
2804
|
-
|
|
2805
|
-
> [!NOTE]
|
|
2806
|
-
> Your own linked devices are not addressed, so the message does not appear in the group on your phone — only `messages.upsert` fires locally (via `emitOwnEvents`). The recipient sees an ordinary group message; nothing marks it as private on their side.
|
|
2807
|
-
|
|
2808
|
-
### 🚫 Ignoring Inbound Stanzas
|
|
2809
|
-
|
|
2810
|
-
`sock.ignoreKey(input)` drops matching inbound stanzas **before any handler runs** — including the decryption and persistence paths. The ack is still sent, so the server stops redelivering them. It returns an unregister function.
|
|
2811
|
-
|
|
2812
|
-
```javascript
|
|
2813
|
-
// --- Descriptor: drop everything from one peer
|
|
2814
|
-
const off = sock.ignoreKey({ remoteJid: "6281111111111@s.whatsapp.net" });
|
|
2815
|
-
|
|
2816
|
-
// Only that peer's messages; receipts and presence still arrive
|
|
2817
|
-
sock.ignoreKey({ remoteJid: "6281111111111@s.whatsapp.net", only: ["message"] });
|
|
2818
|
-
|
|
2819
|
-
// Several chats at once (array entries OR)
|
|
2820
|
-
sock.ignoreKey({ remoteJid: ["111111@g.us", "222222@g.us"] });
|
|
2821
|
-
|
|
2822
|
-
// Your own outbound echoes from other devices
|
|
2823
|
-
sock.ignoreKey({ fromMe: true, only: ["message"] });
|
|
2824
|
-
|
|
2825
|
-
off(); // unregister
|
|
2826
|
-
|
|
2827
|
-
// --- Predicate: anything the descriptor cannot express
|
|
2828
|
-
sock.ignoreKey((m) => m.kind === "message" && isJidGroup(m.remoteJid ?? ""));
|
|
2829
|
-
sock.ignoreKey((m) => isJidStatusBroadcast(m.remoteJid ?? ""));
|
|
2830
|
-
```
|
|
2831
|
-
|
|
2832
|
-
| Field | Type | Notes |
|
|
2833
|
-
| ------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
2834
|
-
| `remoteJid` | `string \| string[]` | Chat JID. Array entries OR. Also matched against the alt `sender_pn` / `sender_lid` attributes, so one JID form catches the other. |
|
|
2835
|
-
| `fromMe` | `boolean` | Whether the stanza was sent by this account, resolved against both your PN and LID. |
|
|
2836
|
-
| `id` | `string` | Stanza id. |
|
|
2837
|
-
| `participant` | `string` | Author in groups / broadcasts. Alt forms are matched too. |
|
|
2838
|
-
| `only` | `('message' \| 'receipt' \| 'notification' \| 'presence' \| 'chatstate' \| 'call')[]` | Restrict to specific tags. Default: all six. |
|
|
2839
|
-
|
|
2840
|
-
Top-level fields AND together; the `remoteJid` array ORs. At least one of `remoteJid` / `fromMe` / `id` / `participant` is required — empty descriptors throw, as do unknown `only` values.
|
|
2841
|
-
|
|
2842
|
-
A predicate receives the already-parsed stanza: `{ kind, remoteJid, fromMe, id, participant }`, with `remoteJid` and `participant` device-stripped so they line up with `event.key.remoteJid`. Return `true` to drop. A predicate that throws is logged and the stanza is kept.
|
|
2843
|
-
|
|
2844
|
-
> [!IMPORTANT]
|
|
2845
|
-
> `category='peer'` messages from your own devices are **never** dropped, whatever the filter says. They carry app-state key shares, history sync and PDO responses between your devices, so a `{ fromMe: true }` filter would otherwise swallow the app-state key share and leave the collections blocked on a key they re-request on every sync. The exemption applies only when the sender really is this account, so a foreign stanza cannot dodge a filter by stamping the attribute. Stream control and the auth-critical `success` / `failure` tags bypass filters as well.
|
|
2846
|
-
|
|
2847
|
-
### 🛡️ Anchor Guard
|
|
2848
|
-
|
|
2849
|
-
Detects payloads that force-close WhatsApp clients, deletes them, and optionally blocks the sender.
|
|
2850
|
-
|
|
2851
|
-
```javascript
|
|
2852
|
-
import { createAnchorGuard, detectBug } from "@violetix/baileys";
|
|
2853
|
-
|
|
2854
|
-
const guard = createAnchorGuard(sock, {
|
|
2855
|
-
blockOnBug: true,
|
|
2856
|
-
guardOutgoing: true, // also reject your own crash payloads before they are sent
|
|
2857
|
-
onDetect: ({ direction, jid, reasons }) => console.log("🛡️", direction, jid, reasons),
|
|
2858
|
-
});
|
|
2859
|
-
|
|
2860
|
-
// one-off check without attaching anything
|
|
2861
|
-
const { flagged, reasons } = detectBug(msg.message);
|
|
2862
|
-
|
|
2863
|
-
guard.stop(); // detach listeners and unwrap sendMessage
|
|
2864
|
-
```
|
|
2865
|
-
|
|
2866
|
-
Flags invisible and combining character floods, mention bombs, oversized native-flow / list / carousel payloads, `buttonParamsJson` that is broken or huge, excessive newlines, over-deep, over-wide and circular structures, and — when you pass `proto` — an encoded size over `maxBytes`.
|
|
2867
|
-
|
|
2868
|
-
| Option | Default | Description |
|
|
2869
|
-
| --------------------------------- | -------- | ---------------------------------------------------------------------------------------- |
|
|
2870
|
-
| `autoDelete` | `true` | Delete a flagged inbound message. |
|
|
2871
|
-
| `deleteMode` | `'auto'` | `'auto'` revokes your own messages and deletes others locally; `'everyone'` always revokes. |
|
|
2872
|
-
| `guardIncoming` | `true` | Guard `messages.upsert`. |
|
|
2873
|
-
| `guardOutgoing` | `false` | Wrap `sock.sendMessage` and throw on a crash payload. |
|
|
2874
|
-
| `blockOnBug` | `false` | Block the sender of a flagged message. |
|
|
2875
|
-
| `selfOnly` | `false` | Only guard your own chats. |
|
|
2876
|
-
| `burstThreshold` / `burstWindowMs` | `0` / `4000` | Messages from one sender inside the window before it counts as a burst. `0` disables. |
|
|
2877
|
-
| `kickOnBurst` | `false` | Remove the sender from the group on burst (needs admin). |
|
|
2878
|
-
| `guardGroupAdds` | `false` | Flag / kick when a burst-flagged inviter adds you to a group. |
|
|
2879
|
-
| `metaAiNumbers` | `false` | Guard Meta AI's own numbers instead of exempting them. |
|
|
2880
|
-
| `thresholds` | `{}` | Override any of `ANCHORGUARD_DEFAULTS`. |
|
|
2881
|
-
|
|
2882
|
-
> [!NOTE]
|
|
2883
|
-
> `guardOutgoing` replaces `sock.sendMessage` with a wrapper, which is why it is off by default — turn it on knowingly if your own code also wraps `sendMessage`. `stop()` only unwinds its own wrapper, so a wrapper you installed afterwards survives.
|
|
2884
|
-
|
|
2885
|
-
### 📡 Events
|
|
2886
|
-
|
|
2887
|
-
```javascript
|
|
2888
|
-
sock.ev.on("connection.update", (update) => {});
|
|
2889
|
-
sock.ev.on("creds.update", (update) => {});
|
|
2890
|
-
sock.ev.on("messaging-history.set", (update) => {});
|
|
2891
|
-
sock.ev.on("messaging-history.status", (update) => {});
|
|
2892
|
-
sock.ev.on("chats.upsert", (update) => {});
|
|
2893
|
-
sock.ev.on("chats.update", (update) => {});
|
|
2894
|
-
sock.ev.on("chats.delete", (update) => {});
|
|
2895
|
-
sock.ev.on("chats.lock", (update) => {});
|
|
2896
|
-
sock.ev.on("presence.update", (update) => {});
|
|
2897
|
-
sock.ev.on("contacts.upsert", (update) => {});
|
|
2898
|
-
sock.ev.on("contacts.update", (update) => {});
|
|
2899
|
-
sock.ev.on("messages.delete", (update) => {});
|
|
2900
|
-
sock.ev.on("messages.update", (update) => {});
|
|
2901
|
-
sock.ev.on("messages.media-update", (update) => {});
|
|
2902
|
-
sock.ev.on("messages.upsert", (update) => {});
|
|
2903
|
-
sock.ev.on("messages.reaction", (update) => {});
|
|
2904
|
-
sock.ev.on("message-receipt.update", (update) => {});
|
|
2905
|
-
sock.ev.on("groups.upsert", (update) => {});
|
|
2906
|
-
sock.ev.on("groups.update", (update) => {});
|
|
2907
|
-
sock.ev.on("group-participants.update", (update) => {});
|
|
2908
|
-
sock.ev.on("group.join-request", (update) => {});
|
|
2909
|
-
sock.ev.on("group.member-tag.update", (update) => {});
|
|
2910
|
-
sock.ev.on("blocklist.set", (update) => {});
|
|
2911
|
-
sock.ev.on("blocklist.update", (update) => {});
|
|
2912
|
-
sock.ev.on("username.update", ({ lid, username, type }) => {}); // type: 'set' | 'delete'
|
|
2913
|
-
sock.ev.on("lid-mapping.update", ({ oldLid, newLid, pn }) => {});
|
|
2914
|
-
sock.ev.on("privacy.update", (settings) => {});
|
|
2915
|
-
sock.ev.on("call", (update) => {});
|
|
2916
|
-
sock.ev.on("labels.edit", (update) => {});
|
|
2917
|
-
sock.ev.on("labels.association", (update) => {});
|
|
2918
|
-
sock.ev.on("newsletter.reaction", (update) => {});
|
|
2919
|
-
sock.ev.on("newsletter.view", (update) => {});
|
|
2920
|
-
sock.ev.on("newsletter.status", (update) => {}); // not in upstream Baileys
|
|
2921
|
-
sock.ev.on("newsletter-participants.update", (update) => {});
|
|
2922
|
-
sock.ev.on("newsletter-settings.update", (update) => {});
|
|
2923
|
-
sock.ev.on("settings.update", (update) => {});
|
|
2924
|
-
```
|
|
2925
|
-
|
|
2926
|
-
#### 📰 `newsletter.status`
|
|
2927
|
-
|
|
2928
|
-
Fires for channel (newsletter) posts pushed by the server, carrying the post content alongside its engagement counters.
|
|
2929
|
-
```javascript
|
|
2930
|
-
sock.ev.on("newsletter.status", (update) => {
|
|
2931
|
-
console.log("📰 Newsletter post", ":", update);
|
|
2932
|
-
});
|
|
2409
|
+
#### 📡 Events
|
|
2410
|
+
|
|
2411
|
+
```javascript
|
|
2412
|
+
sock.ev.on('connection.update', (update) => {})
|
|
2413
|
+
sock.ev.on('creds.update', (update) => {})
|
|
2414
|
+
sock.ev.on('messaging-history.set', (update) => {})
|
|
2415
|
+
sock.ev.on('messaging-history.status', (update) => {})
|
|
2416
|
+
sock.ev.on('chats.upsert', (update) => {})
|
|
2417
|
+
sock.ev.on('chats.update', (update) => {})
|
|
2418
|
+
sock.ev.on('chats.delete', (update) => {})
|
|
2419
|
+
sock.ev.on('chats.lock', (update) => {})
|
|
2420
|
+
sock.ev.on('lid-mapping.update', (update) => {})
|
|
2421
|
+
sock.ev.on('presence.update', (update) => {})
|
|
2422
|
+
sock.ev.on('contacts.upsert', (update) => {})
|
|
2423
|
+
sock.ev.on('contacts.update', (update) => {})
|
|
2424
|
+
sock.ev.on('messages.delete', (update) => {})
|
|
2425
|
+
sock.ev.on('messages.update', (update) => {})
|
|
2426
|
+
sock.ev.on('messages.media-update', (update) => {})
|
|
2427
|
+
sock.ev.on('messages.upsert', (update) => {})
|
|
2428
|
+
sock.ev.on('messages.reaction', (update) => {})
|
|
2429
|
+
sock.ev.on('message-receipt.update', (update) => {})
|
|
2430
|
+
sock.ev.on('groups.upsert', (update) => {})
|
|
2431
|
+
sock.ev.on('groups.update', (update) => {})
|
|
2432
|
+
sock.ev.on('group-participants.update', (update) => {})
|
|
2433
|
+
sock.ev.on('group.join-request', (update) => {})
|
|
2434
|
+
sock.ev.on('group.member-tag.update', (update) => {})
|
|
2435
|
+
sock.ev.on('blocklist.set', (update) => {})
|
|
2436
|
+
sock.ev.on('blocklist.update', (update) => {})
|
|
2437
|
+
sock.ev.on('call', (update) => {})
|
|
2438
|
+
sock.ev.on('labels.edit', (update) => {})
|
|
2439
|
+
sock.ev.on('labels.association', (update) => {})
|
|
2440
|
+
sock.ev.on('newsletter.reaction', (update) => {})
|
|
2441
|
+
sock.ev.on('newsletter.view', (update) => {})
|
|
2442
|
+
sock.ev.on('newsletter.status', (update) => {}) // [NEW]
|
|
2443
|
+
sock.ev.on('newsletter-participants.update', (update) => {})
|
|
2444
|
+
sock.ev.on('newsletter-settings.update', (update) => {})
|
|
2445
|
+
sock.ev.on('settings.update', (update) => {})
|
|
2446
|
+
```
|
|
2447
|
+
|
|
2448
|
+
##### 📰 `newsletter.status`
|
|
2449
|
+
|
|
2450
|
+
Fires for channel (newsletter) posts pushed by the server, carrying the post content alongside its engagement counters. **[NEW]**
|
|
2451
|
+
|
|
2452
|
+
```javascript
|
|
2453
|
+
sock.ev.on('newsletter.status', (update) => {
|
|
2454
|
+
console.log('📰 Newsletter post', ':', update)
|
|
2455
|
+
})
|
|
2933
2456
|
|
|
2934
2457
|
// --- Output
|
|
2935
2458
|
// {
|
|
@@ -2956,54 +2479,52 @@ sock.ev.on("newsletter.status", (update) => {
|
|
|
2956
2479
|
|
|
2957
2480
|
`content.type` is one of `text`, `media` (with an extra `mediaType`), `reaction` (with a `code`), or `revoke`. It is `null` when the stanza carries only counter updates.
|
|
2958
2481
|
|
|
2959
|
-
|
|
2482
|
+
##### 📞 `call`
|
|
2483
|
+
|
|
2484
|
+
The call event now carries the full signalling payload. **[NEW]**
|
|
2960
2485
|
|
|
2961
|
-
The call event now carries the full signalling payload.
|
|
2962
2486
|
```javascript
|
|
2963
|
-
sock.ev.on(
|
|
2964
|
-
|
|
2965
|
-
})
|
|
2487
|
+
sock.ev.on('call', ([call]) => {
|
|
2488
|
+
console.log('📞 Call', ':', call)
|
|
2489
|
+
})
|
|
2966
2490
|
```
|
|
2967
2491
|
|
|
2968
|
-
| Field
|
|
2969
|
-
|
|
|
2970
|
-
| `callKey`
|
|
2971
|
-
| `audioCodecs`, `audioCodec` | `status: 'offer'`
|
|
2972
|
-
| `videoCodec`
|
|
2973
|
-
| `isLightweight`
|
|
2974
|
-
| `silenceReason`
|
|
2975
|
-
| `peerJid`
|
|
2976
|
-
| `participants`
|
|
2977
|
-
| `muted`
|
|
2978
|
-
| `enabled`
|
|
2979
|
-
| `state`
|
|
2980
|
-
| `latencyMs`
|
|
2492
|
+
| Field | Present when | Description |
|
|
2493
|
+
| --- | --- | --- |
|
|
2494
|
+
| `callKey` | `status: 'offer'` | Raw SRTP key bytes, Signal-decrypted from the offer |
|
|
2495
|
+
| `audioCodecs`, `audioCodec` | `status: 'offer'` | Offered audio codecs, one entry per sample rate |
|
|
2496
|
+
| `videoCodec` | `status: 'offer'` | Offered video codec |
|
|
2497
|
+
| `isLightweight` | `status: 'offer'` | Silent / wave-style group ring — no full ringing UX expected |
|
|
2498
|
+
| `silenceReason` | `status: 'offer'` | Why the call was silenced |
|
|
2499
|
+
| `peerJid` | `status: 'waiting_room_request'` | Who is waiting in a call link's waiting room |
|
|
2500
|
+
| `participants` | `status: 'group_info'` | Group call roster, with per-user devices |
|
|
2501
|
+
| `muted` | `status: 'mute'` | Mute state of the peer |
|
|
2502
|
+
| `enabled` | `status: 'video_state'` | Whether the peer's video is on |
|
|
2503
|
+
| `state` | `status: 'peer_state'` | Peer connection state |
|
|
2504
|
+
| `latencyMs` | `status: 'relaylatency'` | Relay latency |
|
|
2981
2505
|
|
|
2982
2506
|
`status` can also be a specific end-call reason instead of a bare `terminate`: `timeout`, `reject_do_not_disturb`, `mic_permission_denied`, `camera_permission_denied`, `remote_busy`, or `remote_offline`.
|
|
2983
2507
|
|
|
2984
|
-
|
|
2508
|
+
### 🚀 Try the Bot
|
|
2985
2509
|
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
npm run check
|
|
2989
|
-
npm audit --omit=dev --audit-level=high
|
|
2990
|
-
```
|
|
2510
|
+
A fast, lightweight, and modular WhatsApp bot built with [@itsliaaa/baileys](https://www.npmjs.com/package/@itsliaaa/baileys).
|
|
2511
|
+
Perfect for managing groups, moderating chats, and adding fun with quiz games and handy tools.
|
|
2991
2512
|
|
|
2992
|
-
|
|
2993
|
-
a TypeScript consumer, and runs the offline regression suite. Tests do not connect
|
|
2994
|
-
to WhatsApp. `npm publish` runs the same checks through `prepublishOnly`; the CI
|
|
2995
|
-
workflow also runs them on Node.js 20 and 24.
|
|
2513
|
+
👉🏻 [@itsliaaa/starseed](https://github.com/itsliaaa/starseed#readme)
|
|
2996
2514
|
|
|
2997
|
-
|
|
2515
|
+
A lightweight yet powerful Baileys wrapper designed to simplify development while extending support for additional message types and WhatsApp features.
|
|
2998
2516
|
|
|
2999
|
-
|
|
2517
|
+
👉🏻 [@itsliaaa/starcore](https://www.npmjs.com/package/@itsliaaa/starcore)
|
|
3000
2518
|
|
|
3001
|
-
|
|
2519
|
+
### 📦 Fork Base
|
|
2520
|
+
|
|
2521
|
+
This fork is based on [Baileys (GitHub)](https://github.com/WhiskeySockets/Baileys)
|
|
2522
|
+
|
|
2523
|
+
### 📣 Credits
|
|
3002
2524
|
|
|
3003
2525
|
This fork uses Protocol Buffer definitions maintained by [WPP Connect](https://github.com/wppconnect-team) via [`wa-proto`](https://github.com/wppconnect-team/wa-proto)
|
|
3004
2526
|
|
|
3005
2527
|
Full credit is attributed to the original maintainers and contributors of Baileys:
|
|
3006
|
-
|
|
3007
2528
|
- [purpshell](https://github.com/purpshell)
|
|
3008
2529
|
- [jlucaso1](https://github.com/jlucaso1)
|
|
3009
2530
|
- [adiwajshing](https://github.com/adiwajshing)
|
|
@@ -3015,4 +2536,4 @@ This fork includes additional enhancements and modifications by [Lia Wynn](https
|
|
|
3015
2536
|
Special thanks to [itsreimau](https://github.com/itsreimau) for the fix to the `updateBlockStatus` implementation.
|
|
3016
2537
|
|
|
3017
2538
|
> [!CAUTION]
|
|
3018
|
-
> ⚠️ **Modification, removal, or misrepresentation of these credits is strictly prohibited. Any redistribution or fork must preserve this section in its original form without exception.**
|
|
2539
|
+
> ⚠️ **Modification, removal, or misrepresentation of these credits is strictly prohibited. Any redistribution or fork must preserve this section in its original form without exception.**
|