@crysnovax/baileys 2.5.0 → 2.5.5
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 +1430 -285
- package/WAProto/index.js +14789 -3578
- package/lib/Defaults/index.js +19 -11
- package/lib/Signal/libsignal.js +42 -18
- package/lib/Socket/Client//342/234/230 +1 -0
- package/lib/Socket/chats.js +246 -91
- package/lib/Socket/messages-recv.js +618 -322
- package/lib/Socket/messages-send.js +174 -74
- package/lib/Socket/newsletter.js +2 -2
- package/lib/Socket/socket.js +12 -20
- package/lib/Socket//342/230/201/357/270/216 +1 -0
- package/lib/Types/Mex.js +39 -0
- package/lib/Types/index.js +1 -0
- package/lib/Types//342/234/206 +1 -0
- package/lib/Utils/index.js +1 -0
- package/lib/Utils/messages.js +148 -114
- package/lib/Utils/use-sqlite-auth-state.js +109 -0
- package/lib/Utils//342/232/211 +1 -0
- package/lib/WABinary/constants.js +99 -5
- package/lib/WABinary//342/216/231 +1 -0
- package/package.json +43 -9
package/README.md
CHANGED
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="https://readme-typing-svg.demolab.com?font=Fira+Code&weight=700&size=40&duration=3000&pause=800&color=10B981¢er=true&vCenter=true&width=600&lines=%F0%9F%91%8B+Hey%2C+I'm+CRYSNOVA;%F0%9F%92%BB+Full+Stack+Developer;%F0%9F%9A%80+Building+the+Future;%F0%9F%94%A5+Open+Source+Lover" alt="Typing Animation" />
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
<p align="center">
|
|
6
|
-
<img src="https://img.shields.io/github/followers/crysnovax?style=for-the-badge&logo=github&color=10b981&labelColor=0a0f0a" />
|
|
7
|
-
<img src="https://img.shields.io/github/stars/crysnovax?style=for-the-badge&logo=github&color=10b981&labelColor=0a0f0a" />
|
|
8
|
-
<img src="https://komarev.com/ghpvc/?username=crysnovax&style=for-the-badge&color=10b981&label=PROFILE+VIEWS" />
|
|
9
|
-
</p>
|
|
10
|
-
|
|
11
|
-
<br />
|
|
12
|
-
|
|
13
|
-
<div align="center">
|
|
14
|
-
<img src="https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif" width="700">
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
|
-
<br />
|
|
18
1
|
|
|
19
2
|
<h2 align="center">
|
|
20
3
|
<img src="https://media2.giphy.com/media/QssGEmpkyEOhBCb7e1/giphy.gif?cid=ecf05e47a0n3gi1bfqntqmob8g9aid1oyj2wr3ds3mg700bl&rid=giphy.gif" width="28" />
|
|
@@ -64,254 +47,841 @@ const crysnova = {
|
|
|
64
47
|
|
|
65
48
|
| 🚀 Project | ⭐ Stars | 📝 Description |
|
|
66
49
|
|-----------|---------|---------------|
|
|
67
|
-
| **CRYSNOVA AI** | [](https://github.com/crysnovax/CRYSNOVA_AI) |
|
|
50
|
+
| **CRYSNOVA AI** | [](https://github.com/crysnovax/CRYSNOVA_AI) | 550+ Command WhatsApp Bot with AI Integration |
|
|
68
51
|
| **API Gateway** | [](https://github.com/crysnovax/API) | Nexray Endpoints Unified API Gateway |
|
|
69
52
|
| **Economy Engine** | [](https://github.com/crysnovax) | Realistic Virtual Economy with Banking System |
|
|
70
53
|
|
|
71
54
|
</div>
|
|
72
55
|
|
|
73
|
-
<br />
|
|
74
56
|
|
|
75
|
-
<h2 align="center">
|
|
76
|
-
<img src="https://media.giphy.com/media/W5eoZHPpUx9sapR0eu/giphy.gif" width="28" />
|
|
77
|
-
GitHub Stats
|
|
78
|
-
<img src="https://media.giphy.com/media/W5eoZHPpUx9sapR0eu/giphy.gif" width="28" />
|
|
79
|
-
</h2>
|
|
80
57
|
|
|
81
|
-
<
|
|
82
|
-
<
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
58
|
+
<p align="center">
|
|
59
|
+
<img src="https://readme-typing-svg.demolab.com?font=Fira+Code&weight=700&size=32&duration=3000&pause=800&color=10B981¢er=true&vCenter=true&width=650&lines=%F0%9F%9A%80+%40crysnovax%2Fbailey%3B+WhatsApp+API+for+Node.js%3B+Rich+Messages+%7C+Meta+AI+Style%3B+Production+Ready+%E2%9C%85" alt="Typing Animation" />
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<img src="https://img.shields.io/npm/v/@crysnovax/bailey?style=for-the-badge&logo=npm&color=10b981&labelColor=0a0f0a" />
|
|
64
|
+
<img src="https://img.shields.io/github/stars/crysnovax/baileys?style=for-the-badge&logo=github&color=10b981&labelColor=0a0f0a" />
|
|
65
|
+
<img src="https://img.shields.io/badge/License-MIT-10b981?style=for-the-badge&labelColor=0a0f0a" />
|
|
66
|
+
<img src="https://img.shields.io/badge/Node.js-%3E%3D18-10b981?style=for-the-badge&logo=node.js&labelColor=0a0f0a" />
|
|
67
|
+
</p>
|
|
89
68
|
|
|
90
69
|
<br />
|
|
91
70
|
|
|
92
71
|
<div align="center">
|
|
93
|
-
<
|
|
94
|
-
<img src="https://github-readme-streak-stats.herokuapp.com/?user=crysnovax&theme=dark&ring=10b981&fire=10b981&currStreakLabel=10b981&sideNums=10b981&sideLabels=e2f5e8&dates=6aa886&background=0a0f0a&hide_border=true" />
|
|
95
|
-
</a>
|
|
72
|
+
<img src="https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif" width="700">
|
|
96
73
|
</div>
|
|
97
74
|
|
|
98
75
|
<br />
|
|
99
76
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
77
|
+
## Table of Contents
|
|
78
|
+
|
|
79
|
+
| # | Section | Description |
|
|
80
|
+
|---|---------|-------------|
|
|
81
|
+
| 1 | [Overview](#overview) | What this package is and what sets it apart |
|
|
82
|
+
| 2 | [Installation](#installation) | NPM, GitHub, ESM & CJS imports |
|
|
83
|
+
| 3 | [Quick Start](#quick-start) | Minimal working connection example |
|
|
84
|
+
| 4 | [Authentication](#authentication) | Auth states, pairing codes, SQLite |
|
|
85
|
+
| 5 | [Sending Messages](#sending-messages) | Text, mentions, reactions, contacts, locations, events, polls, forward, edit |
|
|
86
|
+
| 6 | [Media Messages](#media-messages) | Images, videos, audio, documents, stickers, albums |
|
|
87
|
+
| 7 | [Interactive Messages](#interactive-messages) | Buttons, lists, native flows, carousels, hydrated templates |
|
|
88
|
+
| 8 | [Rich Content](#rich-content) | Code blocks, tables, inline entities, rich response arrays |
|
|
89
|
+
| 9 | [Meta AI Features](#meta-ai-features) | Meta typing, meta compositing, replay planning |
|
|
90
|
+
| 10 | [Welcome Flow](#welcome-flow) | Auto-greet new contacts with FAQ menus |
|
|
91
|
+
| 11 | [Payment Messages](#payment-messages) | Invites, invoices, orders, payment requests |
|
|
92
|
+
| 12 | [Message Options](#message-options) | AI icon, ephemeral, spoilers, view once, raw, and more |
|
|
93
|
+
| 13 | [Newsletter Management](#newsletter-management) | Create, update, follow, react, delete newsletters |
|
|
94
|
+
| 14 | [Group Management](#group-management) | Create, settings, participants, invites, metadata |
|
|
95
|
+
| 15 | [Community Management](#community-management) | Communities, subgroups, linked groups |
|
|
96
|
+
| 16 | [Profile & Business](#profile--business) | Profile pictures, business catalog, products, quick replies |
|
|
97
|
+
| 17 | [Privacy & Security](#privacy--security) | Last seen, online, status, read receipts, calls |
|
|
98
|
+
| 18 | [Events Reference](#events-reference) | Full list of socket event listeners |
|
|
99
|
+
| 19 | [Image Processing](#image-processing) | Sharp, NAPI-RS, Jimp auto-detection |
|
|
100
|
+
| 20 | [Condition of Use](#condition-of-use) | Channel follow agreement |
|
|
101
|
+
| 21 | [Credits](#credits) | Attribution and enhancements |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Overview
|
|
106
|
+
|
|
107
|
+
`@crysnovax/bailey` is a powerful, production-ready WhatsApp API wrapper for Node.js, built on top of the Baileys protocol. It extends the core with rich messaging capabilities, Meta AI-style compositing, and a streamlined developer experience.
|
|
108
|
+
|
|
109
|
+
### What Sets It Apart
|
|
110
|
+
|
|
111
|
+
| Feature | Status | Notes |
|
|
112
|
+
|---------|--------|-------|
|
|
113
|
+
| Rich Messages | ✅ | Code blocks, tables, inline entities, carousel cards |
|
|
114
|
+
| Meta AI Style | ✅ | Live thinking indicators without "edited" badges |
|
|
115
|
+
| Welcome Flow | ✅ | Auto-greet new contacts with interactive FAQ menus |
|
|
116
|
+
| No Obfuscation | ✅ | Fully readable, auditable source code |
|
|
117
|
+
| Newsletter Ready | ✅ | Full media support, quoting, quiz polls |
|
|
118
|
+
| Image Processing | ✅ | Auto-detects `sharp`, `@napi-rs/image`, or `jimp` |
|
|
119
|
+
| Safe FFmpeg | ✅ | Uses `spawn` instead of `exec` |
|
|
120
|
+
| In-Memory Store | ✅ | Reintroduced with minimal ESM adaptation |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Installation
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# NPM
|
|
128
|
+
npm install @crysnovax/bailey
|
|
129
|
+
|
|
130
|
+
# GitHub
|
|
131
|
+
npm install github:crysnovax/baileys
|
|
132
|
+
```
|
|
103
133
|
|
|
104
|
-
|
|
134
|
+
### Import (ESM & CJS)
|
|
105
135
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
<img src="https://media.giphy.com/media/LnQjpWaON8nhr21vNW/giphy.gif" width="28" />
|
|
110
|
-
</h2>
|
|
136
|
+
```javascript
|
|
137
|
+
// ESM
|
|
138
|
+
import { makeWASocket } from '@crysnovax/bailey'
|
|
111
139
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
</a>
|
|
116
|
-
<a href="https://youtube.com/@crysnovax">
|
|
117
|
-
<img src="https://img.shields.io/badge/YouTube-FF0000?style=for-the-badge&logo=youtube&logoColor=white&labelColor=0a0f0a&color=10b981" />
|
|
118
|
-
</a>
|
|
119
|
-
<a href="https://discord.com/users/crysnovadesigns">
|
|
120
|
-
<img src="https://img.shields.io/badge/Discord-crysnovadesigns-5865F2?style=for-the-badge&logo=discord&logoColor=white&labelColor=0a0f0a&color=10b981" />
|
|
121
|
-
</a>
|
|
122
|
-
<a href="https://github.com/crysnovax">
|
|
123
|
-
<img src="https://img.shields.io/badge/GitHub-181717?style=for-the-badge&logo=github&logoColor=white&labelColor=0a0f0a&color=10b981" />
|
|
124
|
-
</a>
|
|
125
|
-
<a href="mailto:crysnovax@gmail.com">
|
|
126
|
-
<img src="https://img.shields.io/badge/Email-D14836?style=for-the-badge&logo=gmail&logoColor=white&labelColor=0a0f0a&color=10b981" />
|
|
127
|
-
</a>
|
|
128
|
-
</p>
|
|
140
|
+
// CJS (Node.js 24+)
|
|
141
|
+
const { makeWASocket } = require('@crysnovax/bailey')
|
|
142
|
+
```
|
|
129
143
|
|
|
130
|
-
|
|
144
|
+
---
|
|
131
145
|
|
|
132
|
-
|
|
133
|
-
<img src="https://quotes-github-readme.vercel.app/api?type=horizontal&theme=dark"e=Code+is+like+humor.+When+you+have+to+explain+it,+it's+bad.&author=Cory+House" />
|
|
134
|
-
</div>
|
|
146
|
+
## Quick Start
|
|
135
147
|
|
|
136
|
-
|
|
148
|
+
```javascript
|
|
149
|
+
import { makeWASocket, delay, DisconnectReason, useMultiFileAuthState } from '@crysnovax/bailey'
|
|
150
|
+
import { Boom } from '@hapi/boom'
|
|
151
|
+
import pino from 'pino'
|
|
137
152
|
|
|
138
|
-
|
|
153
|
+
const myPhoneNumber = '6288888888888'
|
|
154
|
+
const logger = pino({ level: 'silent' })
|
|
139
155
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
This fork will automatically follow the two official Crysnovax WhatsApp channels<br/>
|
|
143
|
-
on first connection. This happens once and will not repeat on reconnects.<br/><br/>
|
|
144
|
-
<b>The channels are:</b><br/>
|
|
145
|
-
📢 <a href="https://whatsapp.com/channel/120363402922206865">Crysnovax Channel 1</a><br/>
|
|
146
|
-
📢 <a href="https://whatsapp.com/channel/120363423670814885">Crysnovax Channel 2</a><br/><br/>
|
|
147
|
-
This is how you stay updated with new features, patches, and releases.<br/>
|
|
148
|
-
If you do not agree to this condition, do not use this fork.
|
|
149
|
-
</p>
|
|
156
|
+
const connectToWhatsApp = async () => {
|
|
157
|
+
const { state, saveCreds } = await useMultiFileAuthState('session')
|
|
150
158
|
|
|
151
|
-
|
|
159
|
+
const sock = makeWASocket({
|
|
160
|
+
logger,
|
|
161
|
+
auth: state
|
|
162
|
+
})
|
|
152
163
|
|
|
153
|
-
|
|
154
|
-
<img src="https://media.giphy.com/media/W5eoZHPpUx9sapR0eu/giphy.gif" width="28" />
|
|
155
|
-
Welcome Flow — Startup Template
|
|
156
|
-
<img src="https://media.giphy.com/media/W5eoZHPpUx9sapR0eu/giphy.gif" width="28" />
|
|
157
|
-
</h2>
|
|
164
|
+
sock.ev.on('creds.update', saveCreds)
|
|
158
165
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
from any new contact with an interactive FAQ menu. Once per contact, never repeats.
|
|
162
|
-
</p>
|
|
166
|
+
sock.ev.on('connection.update', async (update) => {
|
|
167
|
+
const { connection, lastDisconnect } = update
|
|
163
168
|
|
|
164
|
-
|
|
169
|
+
if (connection === 'connecting' && !sock.authState.creds.registered) {
|
|
170
|
+
await delay(1500)
|
|
171
|
+
const code = await sock.requestPairingCode(myPhoneNumber)
|
|
172
|
+
console.log('Pairing code:', code)
|
|
173
|
+
}
|
|
174
|
+
else if (connection === 'close') {
|
|
175
|
+
const shouldReconnect = new Boom(lastDisconnect?.error)?.output?.statusCode !== DisconnectReason.loggedOut
|
|
176
|
+
console.log('Connection closed, reconnecting:', shouldReconnect)
|
|
177
|
+
if (shouldReconnect) connectToWhatsApp()
|
|
178
|
+
}
|
|
179
|
+
else if (connection === 'open') {
|
|
180
|
+
console.log('Connected to WhatsApp')
|
|
181
|
+
}
|
|
182
|
+
})
|
|
165
183
|
|
|
166
|
-
|
|
184
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
185
|
+
for (const msg of messages) {
|
|
186
|
+
if (!msg.message) continue
|
|
187
|
+
await sock.sendMessage(msg.key.remoteJid, { text: 'Hello world!' })
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
}
|
|
167
191
|
|
|
168
|
-
|
|
169
|
-
|
|
192
|
+
connectToWhatsApp()
|
|
193
|
+
```
|
|
170
194
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Authentication
|
|
198
|
+
|
|
199
|
+
### Multi-File Auth State (Recommended)
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
import { useMultiFileAuthState } from '@crysnovax/bailey'
|
|
203
|
+
|
|
204
|
+
const { state, saveCreds } = await useMultiFileAuthState('session')
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Single-File Auth State (Experimental)
|
|
208
|
+
|
|
209
|
+
```javascript
|
|
210
|
+
import { useSingleFileAuthState } from '@crysnovax/bailey'
|
|
211
|
+
|
|
212
|
+
const { state, saveCreds } = await useSingleFileAuthState('session.json')
|
|
213
|
+
// Already includes internal caching — no need for makeCacheableSignalKeyStore
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### SQLite Auth State (Experimental)
|
|
217
|
+
|
|
218
|
+
```javascript
|
|
219
|
+
import { useSqliteAuthState } from '@crysnovax/bailey'
|
|
220
|
+
|
|
221
|
+
const { state, saveCreds } = await useSqliteAuthState('session.db')
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Custom Pairing Code
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
const phoneNumber = '6281111111111'
|
|
228
|
+
const customCode = 'STARFALL'
|
|
229
|
+
|
|
230
|
+
await sock.requestPairingCode(phoneNumber, customCode)
|
|
231
|
+
console.log('Pairing code:', customCode)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Sending Messages
|
|
237
|
+
|
|
238
|
+
### Text & Mentions
|
|
239
|
+
|
|
240
|
+
```javascript
|
|
241
|
+
// Plain text
|
|
242
|
+
sock.sendMessage(jid, { text: 'Hello!' }, { quoted: message })
|
|
243
|
+
|
|
244
|
+
// With link preview
|
|
245
|
+
const url = 'https://www.npmjs.com/package/@crysnovax/bailey'
|
|
246
|
+
sock.sendMessage(jid, {
|
|
247
|
+
text: url + ' Check it out!',
|
|
248
|
+
linkPreview: {
|
|
249
|
+
'matched-text': url,
|
|
250
|
+
title: '@crysnovax/bailey',
|
|
251
|
+
description: 'WhatsApp API for Node.js',
|
|
252
|
+
previewType: 0,
|
|
253
|
+
jpegThumbnail: fs.readFileSync('./thumb.jpg')
|
|
254
|
+
}
|
|
182
255
|
})
|
|
183
256
|
|
|
184
|
-
|
|
257
|
+
// Large link preview with favicon
|
|
258
|
+
import { prepareWAMessageMedia } from '@crysnovax/bailey'
|
|
259
|
+
|
|
260
|
+
const { imageMessage: image } = await prepareWAMessageMedia(
|
|
261
|
+
{ image: { url: './thumb.jpg' } },
|
|
262
|
+
{ upload: sock.waUploadToServer, mediaTypeOverride: 'thumbnail-link' }
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
image.height = 720
|
|
266
|
+
image.width = 480
|
|
267
|
+
|
|
268
|
+
sock.sendMessage(jid, {
|
|
269
|
+
text: url + ' Check it out!',
|
|
270
|
+
linkPreview: {
|
|
271
|
+
'matched-text': url,
|
|
272
|
+
title: '@crysnovax/bailey',
|
|
273
|
+
description: 'WhatsApp API for Node.js',
|
|
274
|
+
previewType: 0,
|
|
275
|
+
jpegThumbnail: fs.readFileSync('./thumb.jpg'),
|
|
276
|
+
highQualityThumbnail: image,
|
|
277
|
+
linkPreviewMetadata: {
|
|
278
|
+
linkMediaDuration: 0,
|
|
279
|
+
socialMediaPostType: 1 // 0=NONE, 1=REEL, 2=LIVE, 3=LONG, 4=IMAGE, 5=CAROUSEL
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
favicon: { url: './favicon.ico' }
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
// Mention specific users
|
|
286
|
+
sock.sendMessage(jid, {
|
|
287
|
+
text: 'Hello @628123456789',
|
|
288
|
+
mentions: ['628123456789@s.whatsapp.net']
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
// Mention all group participants
|
|
292
|
+
sock.sendMessage(jid, {
|
|
293
|
+
text: 'Hello @all',
|
|
294
|
+
mentionAll: true
|
|
295
|
+
})
|
|
185
296
|
```
|
|
186
297
|
|
|
187
|
-
|
|
298
|
+
### Reactions & Pins
|
|
299
|
+
|
|
300
|
+
```javascript
|
|
301
|
+
// Reaction
|
|
302
|
+
sock.sendMessage(jid, {
|
|
303
|
+
react: { key: message.key, text: '✨' }
|
|
304
|
+
})
|
|
188
305
|
|
|
189
|
-
|
|
306
|
+
// Pin message (86400=1d, 604800=7d, 2592000=30d)
|
|
307
|
+
sock.sendMessage(jid, {
|
|
308
|
+
pin: message.key,
|
|
309
|
+
time: 86400,
|
|
310
|
+
type: 1 // 1=pin, 2=unpin
|
|
311
|
+
})
|
|
190
312
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
313
|
+
// Keep chat (disappearing messages only)
|
|
314
|
+
sock.sendMessage(jid, {
|
|
315
|
+
keep: message.key,
|
|
316
|
+
type: 1 // 1=keep, 2=remove
|
|
317
|
+
})
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Contacts & Locations
|
|
321
|
+
|
|
322
|
+
```javascript
|
|
323
|
+
// Contact card
|
|
324
|
+
const vcard = 'BEGIN:VCARD\nVERSION:3.0\nFN:John Doe\nORG:Company;\nTEL;type=CELL;type=VOICE;waid=628123456789:+62 8123 4567 89\nEND:VCARD'
|
|
325
|
+
|
|
326
|
+
sock.sendMessage(jid, {
|
|
327
|
+
contacts: {
|
|
328
|
+
displayName: 'John Doe',
|
|
329
|
+
contacts: [{ vcard }]
|
|
330
|
+
}
|
|
331
|
+
})
|
|
332
|
+
|
|
333
|
+
// Location
|
|
334
|
+
sock.sendMessage(jid, {
|
|
335
|
+
location: {
|
|
336
|
+
degreesLatitude: 24.121231,
|
|
337
|
+
degreesLongitude: 55.1121221,
|
|
338
|
+
name: 'I am here'
|
|
339
|
+
}
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
// Group invite
|
|
343
|
+
const inviteCode = groupUrl.split('chat.whatsapp.com/')[1]?.split('?')[0]
|
|
344
|
+
|
|
345
|
+
sock.sendMessage(jid, {
|
|
346
|
+
groupInvite: {
|
|
347
|
+
inviteCode,
|
|
348
|
+
inviteExpiration: Date.now() + 86400000,
|
|
349
|
+
text: 'Join our group!',
|
|
350
|
+
jid: groupJid,
|
|
351
|
+
subject: groupName
|
|
352
|
+
}
|
|
353
|
+
})
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Events & Polls
|
|
357
|
+
|
|
358
|
+
```javascript
|
|
359
|
+
// Calendar event
|
|
360
|
+
sock.sendMessage(jid, {
|
|
361
|
+
event: {
|
|
362
|
+
name: 'Meet & Mingle Party',
|
|
363
|
+
description: 'A fun gathering to connect and chat.',
|
|
364
|
+
call: 'audio', // or 'video'
|
|
365
|
+
startDate: new Date(Date.now() + 3600000),
|
|
366
|
+
endDate: new Date(Date.now() + 28800000),
|
|
367
|
+
isCancelled: false,
|
|
368
|
+
isScheduleCall: false,
|
|
369
|
+
extraGuestsAllowed: false,
|
|
370
|
+
location: {
|
|
371
|
+
name: 'Jakarta',
|
|
372
|
+
degreesLatitude: -6.2,
|
|
373
|
+
degreesLongitude: 106.8
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
})
|
|
377
|
+
|
|
378
|
+
// Poll
|
|
379
|
+
sock.sendMessage(jid, {
|
|
380
|
+
poll: {
|
|
381
|
+
name: 'Voting time',
|
|
382
|
+
values: ['Yes', 'No'],
|
|
383
|
+
selectableCount: 1,
|
|
384
|
+
toAnnouncementGroup: false,
|
|
385
|
+
endDate: new Date(Date.now() + 28800000),
|
|
386
|
+
hideVoter: false,
|
|
387
|
+
canAddOption: false
|
|
388
|
+
}
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
// Quiz (newsletter only)
|
|
392
|
+
sock.sendMessage('1211111111111@newsletter', {
|
|
393
|
+
poll: {
|
|
394
|
+
name: 'Quiz',
|
|
395
|
+
values: ['Yes', 'No'],
|
|
396
|
+
correctAnswer: 'Yes',
|
|
397
|
+
pollType: 1
|
|
398
|
+
}
|
|
399
|
+
})
|
|
400
|
+
|
|
401
|
+
// Poll result
|
|
402
|
+
sock.sendMessage(jid, {
|
|
403
|
+
pollResult: {
|
|
404
|
+
name: 'Poll Result',
|
|
405
|
+
votes: [
|
|
406
|
+
{ name: 'Nice', voteCount: 10 },
|
|
407
|
+
{ name: 'Nah', voteCount: 2 }
|
|
198
408
|
],
|
|
409
|
+
pollType: 0
|
|
410
|
+
}
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
// Poll update
|
|
414
|
+
sock.sendMessage(jid, {
|
|
415
|
+
pollUpdate: {
|
|
416
|
+
metadata: {},
|
|
417
|
+
key: message.key,
|
|
418
|
+
vote: { enclv: buffer, encPayload: buffer }
|
|
419
|
+
}
|
|
420
|
+
})
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Forward & Edit
|
|
424
|
+
|
|
425
|
+
```javascript
|
|
426
|
+
// Forward
|
|
427
|
+
sock.sendMessage(jid, {
|
|
428
|
+
forward: message,
|
|
429
|
+
force: true
|
|
430
|
+
})
|
|
431
|
+
|
|
432
|
+
// Delete
|
|
433
|
+
sock.sendMessage(jid, { delete: message.key })
|
|
434
|
+
|
|
435
|
+
// Edit text
|
|
436
|
+
sock.sendMessage(jid, {
|
|
437
|
+
text: 'Updated text!',
|
|
438
|
+
edit: message.key
|
|
439
|
+
})
|
|
440
|
+
|
|
441
|
+
// Edit media caption
|
|
442
|
+
sock.sendMessage(jid, {
|
|
443
|
+
caption: 'Updated caption!',
|
|
444
|
+
edit: message.key
|
|
445
|
+
})
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
## Media Messages
|
|
451
|
+
|
|
452
|
+
### Images & Videos
|
|
453
|
+
|
|
454
|
+
```javascript
|
|
455
|
+
// Image
|
|
456
|
+
sock.sendMessage(jid, {
|
|
457
|
+
image: { url: './image.jpg' },
|
|
458
|
+
caption: 'Check this out!'
|
|
459
|
+
})
|
|
460
|
+
|
|
461
|
+
// Video
|
|
462
|
+
sock.sendMessage(jid, {
|
|
463
|
+
video: { url: './video.mp4' },
|
|
464
|
+
gifPlayback: false, // true = send as GIF
|
|
465
|
+
ptv: false, // true = send as PTV
|
|
466
|
+
caption: 'Watch this!'
|
|
467
|
+
})
|
|
468
|
+
|
|
469
|
+
// Status mention (multiple jids)
|
|
470
|
+
sock.sendMessage([jidA, jidB, jidC], {
|
|
471
|
+
text: 'Hello!'
|
|
472
|
+
})
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### Audio & Documents
|
|
476
|
+
|
|
477
|
+
```javascript
|
|
478
|
+
// Audio
|
|
479
|
+
sock.sendMessage(jid, {
|
|
480
|
+
audio: { url: './audio.mp3' },
|
|
481
|
+
ptt: false // true = voice note
|
|
482
|
+
})
|
|
483
|
+
|
|
484
|
+
// Document
|
|
485
|
+
sock.sendMessage(jid, {
|
|
486
|
+
document: { url: './file.pdf' },
|
|
487
|
+
mimetype: 'application/pdf',
|
|
488
|
+
caption: 'My document'
|
|
489
|
+
})
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### Stickers & Albums
|
|
493
|
+
|
|
494
|
+
```javascript
|
|
495
|
+
// Sticker
|
|
496
|
+
sock.sendMessage(jid, {
|
|
497
|
+
sticker: { url: './sticker.webp' }
|
|
498
|
+
})
|
|
499
|
+
|
|
500
|
+
// Album (images + videos)
|
|
501
|
+
sock.sendMessage(jid, {
|
|
502
|
+
album: [
|
|
503
|
+
{ image: { url: './img1.jpg' }, caption: 'First image' },
|
|
504
|
+
{ video: { url: './vid1.mp4' }, caption: 'First video' },
|
|
505
|
+
{ image: { url: './img2.jpg' }, caption: 'Second image' }
|
|
506
|
+
]
|
|
507
|
+
})
|
|
508
|
+
|
|
509
|
+
// Sticker pack
|
|
510
|
+
sock.sendMessage(jid, {
|
|
511
|
+
cover: { url: './cover.webp' },
|
|
512
|
+
stickers: [
|
|
513
|
+
{ data: { url: './sticker1.webp' } },
|
|
514
|
+
{ data: { url: './sticker2.webp' } }
|
|
515
|
+
],
|
|
516
|
+
name: 'My Sticker Pack',
|
|
517
|
+
publisher: 'CRYSNOVA',
|
|
518
|
+
description: '@crysnovax/bailey'
|
|
519
|
+
})
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## Interactive Messages
|
|
525
|
+
|
|
526
|
+
### Buttons & Lists
|
|
527
|
+
|
|
528
|
+
```javascript
|
|
529
|
+
// Buttons
|
|
530
|
+
sock.sendMessage(jid, {
|
|
531
|
+
text: 'Choose an option!',
|
|
532
|
+
footer: '@crysnovax/bailey',
|
|
533
|
+
buttons: [
|
|
534
|
+
{ text: 'Sign Up', id: '#SignUp' }
|
|
535
|
+
]
|
|
536
|
+
})
|
|
199
537
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
538
|
+
// Buttons with media and native flow
|
|
539
|
+
sock.sendMessage(jid, {
|
|
540
|
+
image: { url: './image.jpg' },
|
|
541
|
+
caption: 'Interactive buttons!',
|
|
542
|
+
footer: '@crysnovax/bailey',
|
|
543
|
+
buttons: [
|
|
544
|
+
{ text: 'Rating', id: '#Rating' },
|
|
545
|
+
{
|
|
546
|
+
text: 'Select',
|
|
547
|
+
sections: [
|
|
548
|
+
{
|
|
549
|
+
title: 'Section 1',
|
|
550
|
+
rows: [
|
|
551
|
+
{ header: '', title: 'Secret Ingredient', description: '', id: '#SecretIngredient' }
|
|
552
|
+
]
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
title: 'Section 2',
|
|
556
|
+
highlight_label: 'Popular',
|
|
557
|
+
rows: [
|
|
558
|
+
{ header: '', title: 'Coupon', description: '', id: '#CouponCode' }
|
|
559
|
+
]
|
|
560
|
+
}
|
|
561
|
+
]
|
|
562
|
+
}
|
|
563
|
+
]
|
|
564
|
+
})
|
|
565
|
+
|
|
566
|
+
// List (private chat only)
|
|
567
|
+
sock.sendMessage(jid, {
|
|
568
|
+
text: 'List menu!',
|
|
569
|
+
footer: '@crysnovax/bailey',
|
|
570
|
+
buttonText: 'Select',
|
|
571
|
+
title: 'Hello',
|
|
572
|
+
sections: [
|
|
573
|
+
{
|
|
574
|
+
title: 'Menu 1',
|
|
575
|
+
rows: [
|
|
576
|
+
{ title: 'AI', description: '', rowId: '#AI' }
|
|
577
|
+
]
|
|
203
578
|
},
|
|
579
|
+
{
|
|
580
|
+
title: 'Menu 2',
|
|
581
|
+
rows: [
|
|
582
|
+
{ title: 'Search', description: '', rowId: '#Search' }
|
|
583
|
+
]
|
|
584
|
+
}
|
|
585
|
+
]
|
|
586
|
+
})
|
|
587
|
+
```
|
|
204
588
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
589
|
+
### Native Flows & Carousels
|
|
590
|
+
|
|
591
|
+
```javascript
|
|
592
|
+
// Native flow with options
|
|
593
|
+
sock.sendMessage(jid, {
|
|
594
|
+
image: { url: './image.jpg' },
|
|
595
|
+
caption: 'Interactive!',
|
|
596
|
+
footer: '@crysnovax/bailey',
|
|
597
|
+
optionText: 'Select Options',
|
|
598
|
+
optionTitle: 'Select Options',
|
|
599
|
+
offerText: 'New Coupon!',
|
|
600
|
+
offerCode: 'SAVE20',
|
|
601
|
+
offerUrl: 'https://example.com',
|
|
602
|
+
offerExpiration: Date.now() + 3600000,
|
|
603
|
+
nativeFlow: [
|
|
604
|
+
{ text: 'Greeting', id: '#Greeting', icon: 'review' },
|
|
605
|
+
{ text: 'Call', call: '628123456789' },
|
|
606
|
+
{ text: 'Copy', copy: '@crysnovax/bailey' },
|
|
607
|
+
{ text: 'Source', url: 'https://example.com', useWebview: true },
|
|
608
|
+
{
|
|
609
|
+
text: 'Select',
|
|
610
|
+
sections: [
|
|
611
|
+
{
|
|
612
|
+
title: 'Section 1',
|
|
613
|
+
rows: [
|
|
614
|
+
{ header: '', title: 'Coupon', description: '', id: '#CouponCode' }
|
|
615
|
+
]
|
|
217
616
|
}
|
|
617
|
+
],
|
|
618
|
+
icon: 'default'
|
|
218
619
|
}
|
|
620
|
+
],
|
|
621
|
+
interactiveAsTemplate: false
|
|
219
622
|
})
|
|
220
623
|
|
|
221
|
-
|
|
624
|
+
// Carousel with cards
|
|
625
|
+
sock.sendMessage(jid, {
|
|
626
|
+
text: 'Carousel!',
|
|
627
|
+
footer: '@crysnovax/bailey',
|
|
628
|
+
cards: [
|
|
629
|
+
{
|
|
630
|
+
image: { url: './img1.jpg' },
|
|
631
|
+
caption: 'Image 1',
|
|
632
|
+
footer: 'Pinterest',
|
|
633
|
+
nativeFlow: [
|
|
634
|
+
{ text: 'Source', url: 'https://example.com', useWebview: true }
|
|
635
|
+
]
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
image: { url: './img2.jpg' },
|
|
639
|
+
caption: 'Image 2',
|
|
640
|
+
footer: 'Pinterest',
|
|
641
|
+
offerText: 'New Coupon!',
|
|
642
|
+
offerCode: 'SAVE20',
|
|
643
|
+
offerUrl: 'https://example.com',
|
|
644
|
+
offerExpiration: Date.now() + 3600000,
|
|
645
|
+
nativeFlow: [
|
|
646
|
+
{ text: 'Source', url: 'https://example.com' }
|
|
647
|
+
]
|
|
648
|
+
}
|
|
649
|
+
]
|
|
650
|
+
})
|
|
651
|
+
|
|
652
|
+
// Native flow with audio footer
|
|
653
|
+
sock.sendMessage(jid, {
|
|
654
|
+
text: 'Music in footer!',
|
|
655
|
+
audioFooter: { url: './audio.mp3' },
|
|
656
|
+
nativeFlow: [
|
|
657
|
+
{ text: 'Good, next', id: '#Next', icon: 'review' },
|
|
658
|
+
{ text: 'Skip', id: '#Skip', icon: 'default' }
|
|
659
|
+
]
|
|
660
|
+
})
|
|
222
661
|
```
|
|
223
662
|
|
|
224
|
-
|
|
663
|
+
### Hydrated Templates
|
|
225
664
|
|
|
226
|
-
|
|
665
|
+
```javascript
|
|
666
|
+
sock.sendMessage(jid, {
|
|
667
|
+
title: 'Hello',
|
|
668
|
+
image: { url: './image.jpg' },
|
|
669
|
+
caption: 'Template!',
|
|
670
|
+
footer: '@crysnovax/bailey',
|
|
671
|
+
templateButtons: [
|
|
672
|
+
{ text: 'Tap Here', id: '#Order' },
|
|
673
|
+
{ text: 'Source', url: 'https://example.com' },
|
|
674
|
+
{ text: 'Call', call: '628123456789' }
|
|
675
|
+
]
|
|
676
|
+
})
|
|
677
|
+
```
|
|
227
678
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
679
|
+
---
|
|
680
|
+
|
|
681
|
+
## Rich Content
|
|
682
|
+
|
|
683
|
+
### Code Blocks
|
|
684
|
+
|
|
685
|
+
```javascript
|
|
686
|
+
// Built-in tokenizer
|
|
687
|
+
sock.sendMessage(jid, {
|
|
688
|
+
disclaimerText: 'Code Block',
|
|
689
|
+
headerText: '## Example Usage',
|
|
690
|
+
contentText: '---',
|
|
691
|
+
code: 'console.log("Hello, World!")',
|
|
692
|
+
language: 'javascript',
|
|
693
|
+
footerText: 'Pretty simple, right?'
|
|
694
|
+
})
|
|
695
|
+
|
|
696
|
+
// Supported languages: css, html, javascript, typescript, python, golang, rust, c, c#, c++, bash, bat, powershell
|
|
697
|
+
|
|
698
|
+
// Manual tokenization
|
|
699
|
+
import { tokenizeCode } from '@crysnovax/bailey'
|
|
700
|
+
|
|
701
|
+
const language = 'javascript'
|
|
702
|
+
const code = 'console.log("Hello, World!")'
|
|
703
|
+
|
|
704
|
+
sock.sendMessage(jid, {
|
|
705
|
+
disclaimerText: 'Tokenized Code',
|
|
706
|
+
richResponse: [
|
|
707
|
+
{ text: 'Example Usage' },
|
|
708
|
+
{ language, code: tokenizeCode(code, language) },
|
|
709
|
+
{ text: 'Pretty simple, right?' }
|
|
710
|
+
]
|
|
233
711
|
})
|
|
234
712
|
```
|
|
235
713
|
|
|
236
|
-
|
|
714
|
+
### Tables & Inline Entities
|
|
237
715
|
|
|
238
|
-
|
|
716
|
+
```javascript
|
|
717
|
+
// Table message
|
|
718
|
+
sock.sendMessage(jid, {
|
|
719
|
+
disclaimerText: 'Table',
|
|
720
|
+
headerText: '## Comparison',
|
|
721
|
+
contentText: '---',
|
|
722
|
+
title: 'Runtime Comparison',
|
|
723
|
+
table: [
|
|
724
|
+
['', 'Node.js', 'Bun', 'Deno'],
|
|
725
|
+
['Engine', 'V8', 'JavaScriptCore', 'V8'],
|
|
726
|
+
['Performance', '4/5', '5/5', '4/5']
|
|
727
|
+
],
|
|
728
|
+
noHeading: false,
|
|
729
|
+
footerText: 'Does this help?'
|
|
730
|
+
})
|
|
239
731
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
732
|
+
// Inline entities (links)
|
|
733
|
+
sock.sendMessage(jid, {
|
|
734
|
+
disclaimerText: 'Inline Entities',
|
|
735
|
+
headerText: '## Check Out!',
|
|
736
|
+
contentText: '---',
|
|
737
|
+
links: [
|
|
738
|
+
{ text: '1. Google', title: 'Search Engine', url: 'https://google.com' },
|
|
739
|
+
{ text: '2. YouTube', title: 'Streaming', url: 'https://youtube.com' }
|
|
740
|
+
],
|
|
741
|
+
footerText: '---'
|
|
742
|
+
})
|
|
246
743
|
```
|
|
247
744
|
|
|
248
|
-
|
|
745
|
+
### Rich Response Arrays
|
|
249
746
|
|
|
250
|
-
|
|
747
|
+
```javascript
|
|
748
|
+
// Full rich response with mixed content
|
|
749
|
+
sock.sendMessage(jid, {
|
|
750
|
+
disclaimerText: 'Rich Response',
|
|
751
|
+
richResponse: [
|
|
752
|
+
{ text: 'Example Usage' },
|
|
753
|
+
{
|
|
754
|
+
language: 'javascript',
|
|
755
|
+
code: [
|
|
756
|
+
{ highlightType: 0, codeContent: 'console.log("Hello, World!")' }
|
|
757
|
+
]
|
|
758
|
+
},
|
|
759
|
+
{ text: 'Pretty simple, right?\n' },
|
|
760
|
+
{ text: 'Comparison table:' },
|
|
761
|
+
{
|
|
762
|
+
title: 'Runtime Comparison',
|
|
763
|
+
table: [
|
|
764
|
+
{ isHeading: true, items: ['', 'Node.js', 'Bun', 'Deno'] },
|
|
765
|
+
{ isHeading: false, items: ['Engine', 'V8', 'JavaScriptCore', 'V8'] },
|
|
766
|
+
{ isHeading: false, items: ['Performance', '4/5', '5/5', '4/5'] }
|
|
767
|
+
]
|
|
768
|
+
},
|
|
769
|
+
{ text: 'Does this help clarify?' }
|
|
770
|
+
]
|
|
771
|
+
})
|
|
772
|
+
```
|
|
251
773
|
|
|
252
|
-
|
|
253
|
-
|--------|------|---------|-------------|
|
|
254
|
-
| `greeting` | `string` | `'👋 Welcome!...'` | Body text of the welcome message |
|
|
255
|
-
| `footer` | `string` | `'Powered by @crysnovax/bailey'` | Footer text |
|
|
256
|
-
| `buttonText` | `string` | `'📋 Choose an option'` | List button label |
|
|
257
|
-
| `sectionTitle` | `string` | `'How can we help?'` | Section header in the list |
|
|
258
|
-
| `faqs` | `Array` | 4 default items | `{ id, title, description }` objects |
|
|
259
|
-
| `typingDelayMs` | `number` | `1200` | Typing indicator duration before greeting |
|
|
260
|
-
| `persistPath` | `string\|null` | `null` | JSON file path to persist seen JIDs |
|
|
261
|
-
| `ignoreGroups` | `boolean` | `true` | Skip group chats |
|
|
262
|
-
| `ignoreNewsletter` | `boolean` | `true` | Skip newsletter messages |
|
|
263
|
-
| `ignoreBroadcast` | `boolean` | `true` | Skip broadcast messages |
|
|
264
|
-
| `onGreet` | `async fn` | `null` | Called after greeting is sent |
|
|
265
|
-
| `onFaqReply` | `async fn` | `null` | Called when user selects a FAQ option |
|
|
774
|
+
---
|
|
266
775
|
|
|
267
|
-
|
|
268
|
-
<img src="https://media.giphy.com/media/W5eoZHPpUx9sapR0eu/giphy.gif" width="28" />
|
|
269
|
-
</h2>
|
|
776
|
+
## Meta AI Features
|
|
270
777
|
|
|
271
|
-
|
|
272
|
-
Live Meta AI-style reasoning feed — each step visibly completes in real time,<br/>
|
|
273
|
-
then the final rich message lands clean. <b>No "edited" badge. Ever.</b>
|
|
274
|
-
</p>
|
|
778
|
+
### Meta Typing Indicator
|
|
275
779
|
|
|
276
|
-
|
|
780
|
+
Show a live thinking indicator that you control. Delete it manually when ready — no "edited" badge ever appears.
|
|
781
|
+
|
|
782
|
+
```javascript
|
|
783
|
+
import { metaTyping, buildSteps, PlanningStepStatus } from '@crysnovax/bailey'
|
|
784
|
+
|
|
785
|
+
const placeholder = await metaTyping(sock, jid, {
|
|
786
|
+
description: 'Thinking…',
|
|
787
|
+
steps: buildSteps(['Reading your message…', 'Writing response…'])
|
|
788
|
+
})
|
|
789
|
+
|
|
790
|
+
// Do your work here…
|
|
791
|
+
|
|
792
|
+
// Delete the indicator cleanly
|
|
793
|
+
await sock.sendMessage(jid, { delete: placeholder.key })
|
|
794
|
+
|
|
795
|
+
// Send the real message
|
|
796
|
+
await sock.sendMessage(jid, { text: 'Here is your answer!' })
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
### Meta Compositing
|
|
800
|
+
|
|
801
|
+
Full flow: indicator shows → auto-deletes → clean final message lands. Works with every rich content type.
|
|
802
|
+
|
|
803
|
+
```javascript
|
|
804
|
+
import { sendMetaComposited, PlanningStepStatus } from '@crysnovax/bailey'
|
|
805
|
+
|
|
806
|
+
// With code block
|
|
807
|
+
await sendMetaComposited(
|
|
808
|
+
sock, jid,
|
|
809
|
+
{ code: 'const x = 1 + 1', language: 'javascript' },
|
|
810
|
+
{
|
|
811
|
+
thinkingMs: 3000,
|
|
812
|
+
description: 'Analyzing…',
|
|
813
|
+
steps: [
|
|
814
|
+
{ title: 'Reading context…', status: PlanningStepStatus.DONE },
|
|
815
|
+
{ title: 'Writing code…', status: PlanningStepStatus.IN_PROGRESS }
|
|
816
|
+
]
|
|
817
|
+
}
|
|
818
|
+
)
|
|
819
|
+
|
|
820
|
+
// With table
|
|
821
|
+
await sendMetaComposited(
|
|
822
|
+
sock, jid,
|
|
823
|
+
{
|
|
824
|
+
title: 'Comparison',
|
|
825
|
+
table: [
|
|
826
|
+
['Feature', 'Baileys', 'Crysnovax'],
|
|
827
|
+
['Rich Messages', '❌', '✅'],
|
|
828
|
+
['Meta Compositing', '❌', '✅']
|
|
829
|
+
]
|
|
830
|
+
},
|
|
831
|
+
{ thinkingMs: 2500, description: 'Building table…' }
|
|
832
|
+
)
|
|
833
|
+
|
|
834
|
+
// With rich response array
|
|
835
|
+
await sendMetaComposited(
|
|
836
|
+
sock, jid,
|
|
837
|
+
{
|
|
838
|
+
richResponse: [
|
|
839
|
+
{ text: 'Here is your result:' },
|
|
840
|
+
{ code: 'console.log("hello")', language: 'javascript' },
|
|
841
|
+
{ text: 'Run it with `node index.js`' }
|
|
842
|
+
]
|
|
843
|
+
},
|
|
844
|
+
{ thinkingMs: 2000 }
|
|
845
|
+
)
|
|
846
|
+
```
|
|
277
847
|
|
|
278
|
-
|
|
848
|
+
### Replay Planning
|
|
279
849
|
|
|
280
|
-
|
|
850
|
+
Live Meta AI-style reasoning feed — each step visibly completes in real time, then the final rich message lands clean.
|
|
851
|
+
|
|
852
|
+
```javascript
|
|
281
853
|
import { replayPlanning, mixedSteps } from '@crysnovax/bailey'
|
|
282
854
|
|
|
283
855
|
await replayPlanning(
|
|
284
|
-
|
|
856
|
+
sock, jid,
|
|
285
857
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
858
|
+
// Steps — status managed automatically
|
|
859
|
+
mixedSteps([
|
|
860
|
+
{ title: 'Understanding your question…', type: 'reasoning' },
|
|
861
|
+
{ title: 'Searching for data…', type: 'search' },
|
|
862
|
+
{ title: 'Writing the answer…' }
|
|
863
|
+
]),
|
|
292
864
|
|
|
293
|
-
|
|
294
|
-
|
|
865
|
+
// Final rich message
|
|
866
|
+
{ code: 'const answer = 42', language: 'javascript' },
|
|
295
867
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
868
|
+
// Options
|
|
869
|
+
{
|
|
870
|
+
description: 'Thinking…',
|
|
871
|
+
stepDelayMs: 900,
|
|
872
|
+
finalPauseMs: 600
|
|
873
|
+
}
|
|
302
874
|
)
|
|
303
875
|
```
|
|
304
876
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
**Step type helpers** — each renders a different visual in the Meta bubble.
|
|
877
|
+
**Step type helpers:**
|
|
308
878
|
|
|
309
|
-
```
|
|
879
|
+
```javascript
|
|
310
880
|
import {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
881
|
+
buildReasoningSteps, // isReasoning: true
|
|
882
|
+
buildSearchSteps, // isEnhancedSearch: true
|
|
883
|
+
mixedSteps, // mix any combination
|
|
884
|
+
buildSteps // plain steps
|
|
315
885
|
} from '@crysnovax/bailey'
|
|
316
886
|
|
|
317
887
|
// All reasoning
|
|
@@ -322,145 +892,720 @@ buildSearchSteps(['Searching the web…', 'Reading top results…'])
|
|
|
322
892
|
|
|
323
893
|
// Mixed — most realistic Meta AI look
|
|
324
894
|
mixedSteps([
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
895
|
+
{ title: 'Reading your message…', type: 'reasoning' },
|
|
896
|
+
{ title: 'Searching sources…', type: 'search' },
|
|
897
|
+
{ title: 'Composing response…' }
|
|
328
898
|
])
|
|
329
899
|
```
|
|
330
900
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
**`replayPlanningOnly`** — run the animation without sending a final message. You control what comes next.
|
|
901
|
+
**Replay planning only (no final message):**
|
|
334
902
|
|
|
335
|
-
```
|
|
903
|
+
```javascript
|
|
336
904
|
import { replayPlanningOnly, buildSearchSteps } from '@crysnovax/bailey'
|
|
337
905
|
|
|
338
|
-
await replayPlanningOnly(
|
|
339
|
-
|
|
340
|
-
|
|
906
|
+
await replayPlanningOnly(
|
|
907
|
+
sock, jid,
|
|
908
|
+
buildSearchSteps(['Looking up prices…', 'Comparing results…']),
|
|
909
|
+
{ stepDelayMs: 1200 }
|
|
341
910
|
)
|
|
342
911
|
|
|
343
912
|
// Send whatever you want after — no badge, no trace
|
|
344
913
|
await sock.sendMessage(jid, { text: 'Here are the results!' })
|
|
345
914
|
```
|
|
346
915
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
**Options reference**
|
|
916
|
+
**Options reference:**
|
|
350
917
|
|
|
351
918
|
| Option | Type | Default | Description |
|
|
352
919
|
|--------|------|---------|-------------|
|
|
353
920
|
| `description` | `string` | `'Thinking…'` | Top label on the indicator bubble |
|
|
354
|
-
| `placeholderText` | `string` | `''` | Body text
|
|
355
|
-
| `stepDelayMs` | `number` | `900` | Ms between each step
|
|
356
|
-
| `finalPauseMs` | `number` | `600` | Ms to hold after all steps
|
|
357
|
-
| `abortOnDisconnect` | `boolean` | `true` | Stops
|
|
358
|
-
| `sendOptions` | `object` | `{}` | Extra options
|
|
921
|
+
| `placeholderText` | `string` | `''` | Body text while steps run |
|
|
922
|
+
| `stepDelayMs` | `number` | `900` | Ms between each step completing |
|
|
923
|
+
| `finalPauseMs` | `number` | `600` | Ms to hold after all steps done |
|
|
924
|
+
| `abortOnDisconnect` | `boolean` | `true` | Stops cleanly if socket closes |
|
|
925
|
+
| `sendOptions` | `object` | `{}` | Extra options for final `sendMessage` |
|
|
359
926
|
|
|
360
|
-
|
|
927
|
+
---
|
|
361
928
|
|
|
362
|
-
|
|
363
|
-
<img src="https://media.giphy.com/media/W5eoZHPpUx9sapR0eu/giphy.gif" width="28" />
|
|
364
|
-
Meta Compositing & Meta Typing
|
|
365
|
-
<img src="https://media.giphy.com/media/W5eoZHPpUx9sapR0eu/giphy.gif" width="28" />
|
|
366
|
-
</h2>
|
|
929
|
+
## Welcome Flow
|
|
367
930
|
|
|
368
|
-
|
|
369
|
-
Send rich messages with a Meta AI-style thinking indicator — no <b>"edited"</b> badge, ever.<br/>
|
|
370
|
-
The placeholder shows, then silently deletes, then the final message lands clean.
|
|
371
|
-
</p>
|
|
931
|
+
Auto-greet new contacts with an interactive FAQ menu. Fires once per contact, never repeats.
|
|
372
932
|
|
|
373
|
-
|
|
933
|
+
### Basic Setup
|
|
374
934
|
|
|
375
|
-
|
|
935
|
+
```javascript
|
|
936
|
+
import { createWelcomeFlow } from '@crysnovax/bailey'
|
|
376
937
|
|
|
377
|
-
|
|
378
|
-
|
|
938
|
+
const welcome = createWelcomeFlow(sock, {
|
|
939
|
+
greeting: 'Welcome! How can I help you today?',
|
|
940
|
+
footer: 'Powered by MyBot',
|
|
941
|
+
buttonText: 'Choose an option',
|
|
942
|
+
sectionTitle: 'How can we help?',
|
|
943
|
+
faqs: [
|
|
944
|
+
{ id: 'order', title: 'Track my order', description: 'Check order status' },
|
|
945
|
+
{ id: 'billing', title: 'Billing & payments', description: 'Payment issues' },
|
|
946
|
+
{ id: 'support', title: 'Technical support', description: 'Get help' },
|
|
947
|
+
{ id: 'human', title: 'Talk to a human', description: 'Connect with staff' }
|
|
948
|
+
]
|
|
949
|
+
})
|
|
379
950
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
951
|
+
welcome.listen() // start
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
### With Callbacks
|
|
955
|
+
|
|
956
|
+
```javascript
|
|
957
|
+
const welcome = createWelcomeFlow(sock, {
|
|
958
|
+
greeting: 'Hi there! What brings you here today?',
|
|
959
|
+
faqs: [
|
|
960
|
+
{ id: 'pricing', title: 'Pricing', description: 'Plans and costs' },
|
|
961
|
+
{ id: 'demo', title: 'Request demo', description: 'See it in action' },
|
|
962
|
+
{ id: 'support', title: 'Support', description: 'Get help' }
|
|
963
|
+
],
|
|
964
|
+
|
|
965
|
+
onGreet: async (jid, message) => {
|
|
966
|
+
console.log(`Greeted new contact: ${jid}`)
|
|
967
|
+
},
|
|
968
|
+
|
|
969
|
+
onFaqReply: async (jid, faqId, message) => {
|
|
970
|
+
switch (faqId) {
|
|
971
|
+
case 'pricing':
|
|
972
|
+
await sock.sendMessage(jid, { text: 'Our plans start at $9/month…' })
|
|
973
|
+
break
|
|
974
|
+
case 'demo':
|
|
975
|
+
await sock.sendMessage(jid, { text: 'Book a demo here: https://…' })
|
|
976
|
+
break
|
|
977
|
+
case 'support':
|
|
978
|
+
await sock.sendMessage(jid, { text: 'Describe your issue and we will help!' })
|
|
979
|
+
break
|
|
980
|
+
}
|
|
981
|
+
}
|
|
383
982
|
})
|
|
384
983
|
|
|
385
|
-
|
|
386
|
-
await sock.sendMessage(jid, { delete: placeholder.key })
|
|
984
|
+
welcome.listen()
|
|
387
985
|
```
|
|
388
986
|
|
|
389
|
-
|
|
987
|
+
### Persist Across Restarts
|
|
988
|
+
|
|
989
|
+
```javascript
|
|
990
|
+
const welcome = createWelcomeFlow(sock, {
|
|
991
|
+
greeting: 'Welcome!',
|
|
992
|
+
faqs: [...],
|
|
993
|
+
persistPath: './data/greeted-contacts.json'
|
|
994
|
+
})
|
|
995
|
+
```
|
|
390
996
|
|
|
391
|
-
|
|
997
|
+
### Control Methods
|
|
392
998
|
|
|
393
|
-
|
|
999
|
+
```javascript
|
|
1000
|
+
welcome.listen() // start listening
|
|
1001
|
+
welcome.stop() // stop listening
|
|
1002
|
+
welcome.reset(jid) // force re-greet one contact
|
|
1003
|
+
welcome.resetAll() // clear all seen contacts
|
|
1004
|
+
welcome.hasGreeted(jid) // check if greeted → boolean
|
|
1005
|
+
```
|
|
394
1006
|
|
|
395
|
-
|
|
396
|
-
import { sendMetaComposited, PlanningStepStatus } from '@crysnovax/bailey'
|
|
1007
|
+
### Config Reference
|
|
397
1008
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
1009
|
+
| Option | Type | Default | Description |
|
|
1010
|
+
|--------|------|---------|-------------|
|
|
1011
|
+
| `greeting` | `string` | `'Welcome!…'` | Body text of welcome message |
|
|
1012
|
+
| `footer` | `string` | `'Powered by @crysnovax/bailey'` | Footer text |
|
|
1013
|
+
| `buttonText` | `string` | `'Choose an option'` | List button label |
|
|
1014
|
+
| `sectionTitle` | `string` | `'How can we help?'` | Section header |
|
|
1015
|
+
| `faqs` | `Array` | 4 defaults | `{ id, title, description }` |
|
|
1016
|
+
| `typingDelayMs` | `number` | `1200` | Typing indicator duration |
|
|
1017
|
+
| `persistPath` | `string\|null` | `null` | JSON file to persist JIDs |
|
|
1018
|
+
| `ignoreGroups` | `boolean` | `true` | Skip group chats |
|
|
1019
|
+
| `ignoreNewsletter` | `boolean` | `true` | Skip newsletters |
|
|
1020
|
+
| `ignoreBroadcast` | `boolean` | `true` | Skip broadcasts |
|
|
1021
|
+
| `onGreet` | `async fn` | `null` | Called after greeting sent |
|
|
1022
|
+
| `onFaqReply` | `async fn` | `null` | Called on FAQ selection |
|
|
1023
|
+
|
|
1024
|
+
---
|
|
1025
|
+
|
|
1026
|
+
## Payment Messages
|
|
1027
|
+
|
|
1028
|
+
```javascript
|
|
1029
|
+
// Payment invite
|
|
1030
|
+
sock.sendMessage(jid, {
|
|
1031
|
+
paymentInviteServiceType: 3 // 1, 2, or 3
|
|
1032
|
+
})
|
|
1033
|
+
|
|
1034
|
+
// Invoice (not supported yet)
|
|
1035
|
+
sock.sendMessage(jid, {
|
|
1036
|
+
image: { url: './image.jpg' },
|
|
1037
|
+
invoiceNote: 'Invoice'
|
|
1038
|
+
})
|
|
1039
|
+
|
|
1040
|
+
// Order
|
|
1041
|
+
sock.sendMessage(chat, {
|
|
1042
|
+
orderText: 'Order',
|
|
1043
|
+
thumbnail: fs.readFileSync('./image.jpg')
|
|
1044
|
+
})
|
|
1045
|
+
|
|
1046
|
+
// Request payment
|
|
1047
|
+
sock.sendMessage(jid, {
|
|
1048
|
+
text: 'Request Payment',
|
|
1049
|
+
requestPaymentFrom: '0@s.whatsapp.net'
|
|
1050
|
+
})
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
---
|
|
1054
|
+
|
|
1055
|
+
## Message Options
|
|
1056
|
+
|
|
1057
|
+
```javascript
|
|
1058
|
+
// AI icon (private chat only)
|
|
1059
|
+
sock.sendMessage(jid, {
|
|
1060
|
+
image: { url: './image.jpg' },
|
|
1061
|
+
caption: 'With AI icon!',
|
|
1062
|
+
ai: true
|
|
1063
|
+
})
|
|
1064
|
+
|
|
1065
|
+
// Ephemeral
|
|
1066
|
+
sock.sendMessage(jid, {
|
|
1067
|
+
image: { url: './image.jpg' },
|
|
1068
|
+
caption: 'Ephemeral',
|
|
1069
|
+
ephemeral: true
|
|
1070
|
+
})
|
|
1071
|
+
|
|
1072
|
+
// External ad reply
|
|
1073
|
+
sock.sendMessage(jid, {
|
|
1074
|
+
text: 'External Ad Reply',
|
|
1075
|
+
externalAdReply: {
|
|
1076
|
+
title: 'Did you know?',
|
|
1077
|
+
body: 'I dont know',
|
|
1078
|
+
thumbnail: fs.readFileSync('./image.jpg'),
|
|
1079
|
+
largeThumbnail: false,
|
|
1080
|
+
url: 'https://example.com'
|
|
1081
|
+
}
|
|
1082
|
+
})
|
|
1083
|
+
|
|
1084
|
+
// Group status (group chat only)
|
|
1085
|
+
sock.sendMessage(jid, {
|
|
1086
|
+
image: { url: './image.jpg' },
|
|
1087
|
+
caption: 'Group Status!',
|
|
1088
|
+
groupStatus: true
|
|
1089
|
+
})
|
|
1090
|
+
|
|
1091
|
+
// Lottie sticker
|
|
1092
|
+
sock.sendMessage(jid, {
|
|
1093
|
+
sticker: { url: './sticker.webp' },
|
|
1094
|
+
isLottie: true
|
|
1095
|
+
})
|
|
1096
|
+
|
|
1097
|
+
// Raw (build manually)
|
|
1098
|
+
sock.sendMessage(jid, {
|
|
1099
|
+
extendedTextMessage: {
|
|
1100
|
+
text: 'Built manually',
|
|
1101
|
+
contextInfo: {
|
|
1102
|
+
externalAdReply: {
|
|
1103
|
+
title: '@crysnovax/bailey',
|
|
1104
|
+
thumbnail: fs.readFileSync('./image.jpg'),
|
|
1105
|
+
sourceApp: 'whatsapp',
|
|
1106
|
+
showAdAttribution: true,
|
|
1107
|
+
mediaType: 1
|
|
1108
|
+
}
|
|
408
1109
|
}
|
|
409
|
-
|
|
1110
|
+
},
|
|
1111
|
+
raw: true
|
|
1112
|
+
})
|
|
410
1113
|
|
|
411
|
-
//
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
['Feature', 'Baileys', 'Crysnovax'],
|
|
417
|
-
['Rich Messages', '❌', '✅'],
|
|
418
|
-
['Meta Compositing', '❌', '✅'],
|
|
419
|
-
['Code Blocks', '❌', '✅']
|
|
420
|
-
]
|
|
421
|
-
},
|
|
422
|
-
{ thinkingMs: 2500, description: 'Building table…' }
|
|
423
|
-
)
|
|
1114
|
+
// Secure meta service label
|
|
1115
|
+
sock.sendMessage(jid, {
|
|
1116
|
+
text: 'Just a label!',
|
|
1117
|
+
secureMetaServiceLabel: true
|
|
1118
|
+
})
|
|
424
1119
|
|
|
425
|
-
//
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
1120
|
+
// Spoiler
|
|
1121
|
+
sock.sendMessage(jid, {
|
|
1122
|
+
image: { url: './image.jpg' },
|
|
1123
|
+
caption: 'Spoiler',
|
|
1124
|
+
spoiler: true
|
|
1125
|
+
})
|
|
1126
|
+
|
|
1127
|
+
// View once
|
|
1128
|
+
sock.sendMessage(jid, {
|
|
1129
|
+
image: { url: './image.jpg' },
|
|
1130
|
+
caption: 'View Once',
|
|
1131
|
+
viewOnce: true
|
|
1132
|
+
})
|
|
1133
|
+
|
|
1134
|
+
// View once v2
|
|
1135
|
+
sock.sendMessage(jid, {
|
|
1136
|
+
image: { url: './image.jpg' },
|
|
1137
|
+
caption: 'View Once V2',
|
|
1138
|
+
viewOnceV2: true
|
|
1139
|
+
})
|
|
1140
|
+
|
|
1141
|
+
// View once v2 extension
|
|
1142
|
+
sock.sendMessage(jid, {
|
|
1143
|
+
image: { url: './image.jpg' },
|
|
1144
|
+
caption: 'View Once V2 Extension',
|
|
1145
|
+
viewOnceV2Extension: true
|
|
1146
|
+
})
|
|
1147
|
+
```
|
|
1148
|
+
|
|
1149
|
+
---
|
|
1150
|
+
|
|
1151
|
+
## Newsletter Management
|
|
1152
|
+
|
|
1153
|
+
```javascript
|
|
1154
|
+
// Create
|
|
1155
|
+
sock.newsletterCreate('@crysnovax/bailey', 'Fresh updates weekly')
|
|
1156
|
+
|
|
1157
|
+
// Metadata
|
|
1158
|
+
const metadata = await sock.newsletterMetadata('1231111111111@newsletter')
|
|
1159
|
+
|
|
1160
|
+
// Subscribers count
|
|
1161
|
+
const subscribers = await sock.newsletterSubscribers('1231111111111@newsletter')
|
|
1162
|
+
|
|
1163
|
+
// Follow / Unfollow
|
|
1164
|
+
sock.newsletterFollow('1231111111111@newsletter')
|
|
1165
|
+
sock.newsletterUnfollow('1231111111111@newsletter')
|
|
1166
|
+
|
|
1167
|
+
// Mute / Unmute
|
|
1168
|
+
sock.newsletterMute('1231111111111@newsletter')
|
|
1169
|
+
sock.newsletterUnmute('1231111111111@newsletter')
|
|
1170
|
+
|
|
1171
|
+
// Admin management
|
|
1172
|
+
sock.newsletterDemote('1231111111111@newsletter', '6281111111111@s.whatsapp.net')
|
|
1173
|
+
sock.newsletterChangeOwner('1231111111111@newsletter', '6281111111111@s.whatsapp.net')
|
|
1174
|
+
|
|
1175
|
+
// Update
|
|
1176
|
+
sock.newsletterUpdate('1231111111111@newsletter', { name: '@crysnovax/bailey' })
|
|
1177
|
+
sock.newsletterUpdateName('1231111111111@newsletter', '@crysnovax/bailey')
|
|
1178
|
+
sock.newsletterUpdateDescription('1231111111111@newsletter', 'Fresh updates weekly')
|
|
1179
|
+
sock.newsletterUpdatePicture('1231111111111@newsletter', { url: 'path/to/image.jpg' })
|
|
1180
|
+
sock.newsletterRemovePicture('1231111111111@newsletter')
|
|
1181
|
+
|
|
1182
|
+
// React to message
|
|
1183
|
+
sock.newsletterReactMessage('1231111111111@newsletter', '100', '💛')
|
|
1184
|
+
|
|
1185
|
+
// Admin count
|
|
1186
|
+
const count = await sock.newsletterAdminCount('1231111111111@newsletter')
|
|
1187
|
+
|
|
1188
|
+
// Get all subscribed
|
|
1189
|
+
const newsletters = await sock.newsletterSubscribed()
|
|
1190
|
+
|
|
1191
|
+
// Fetch messages
|
|
1192
|
+
const messages = sock.newsletterFetchMessages('jid', '1231111111111@newsletter', 50, 0, 0)
|
|
1193
|
+
|
|
1194
|
+
// Delete
|
|
1195
|
+
sock.newsletterDelete('1231111111111@newsletter')
|
|
1196
|
+
```
|
|
1197
|
+
|
|
1198
|
+
---
|
|
1199
|
+
|
|
1200
|
+
## Group Management
|
|
1201
|
+
|
|
1202
|
+
```javascript
|
|
1203
|
+
// Create
|
|
1204
|
+
const group = await sock.groupCreate('@crysnovax/bailey', ['628123456789@s.whatsapp.net'])
|
|
1205
|
+
|
|
1206
|
+
// Metadata
|
|
1207
|
+
const metadata = await sock.groupMetadata(jid)
|
|
1208
|
+
|
|
1209
|
+
// Invite
|
|
1210
|
+
const inviteCode = await sock.groupInviteCode(jid)
|
|
1211
|
+
sock.groupRevokeInvite(jid)
|
|
1212
|
+
sock.groupAcceptInvite(inviteCode)
|
|
1213
|
+
|
|
1214
|
+
// Leave
|
|
1215
|
+
sock.groupLeave(jid)
|
|
1216
|
+
|
|
1217
|
+
// Participants
|
|
1218
|
+
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'add')
|
|
1219
|
+
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'remove')
|
|
1220
|
+
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'promote')
|
|
1221
|
+
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'demote')
|
|
1222
|
+
|
|
1223
|
+
// Join requests
|
|
1224
|
+
sock.groupRequestParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'approve')
|
|
1225
|
+
|
|
1226
|
+
// Info updates
|
|
1227
|
+
sock.groupUpdateSubject(jid, '@crysnovax/bailey')
|
|
1228
|
+
sock.groupUpdateDescription(jid, 'Updated description')
|
|
1229
|
+
sock.updateProfilePicture(jid, { url: 'path/to/image.jpg' })
|
|
1230
|
+
sock.removeProfilePicture(jid)
|
|
1231
|
+
|
|
1232
|
+
// Settings
|
|
1233
|
+
sock.groupSettingUpdate(jid, 'announcement') // admin only chat
|
|
1234
|
+
sock.groupSettingUpdate(jid, 'not_announcement') // open chat
|
|
1235
|
+
sock.groupSettingUpdate(jid, 'locked') // admin only edit info
|
|
1236
|
+
sock.groupSettingUpdate(jid, 'unlocked') // all edit info
|
|
1237
|
+
|
|
1238
|
+
// Add mode
|
|
1239
|
+
sock.groupMemberAddMode(jid, 'admin_add')
|
|
1240
|
+
sock.groupMemberAddMode(jid, 'all_member_add')
|
|
1241
|
+
|
|
1242
|
+
// Ephemeral
|
|
1243
|
+
sock.groupToggleEphemeral(jid, 86400) // enable
|
|
1244
|
+
sock.groupToggleEphemeral(jid, 0) // disable
|
|
1245
|
+
|
|
1246
|
+
// Approval mode
|
|
1247
|
+
sock.groupJoinApprovalMode(jid, 'on')
|
|
1248
|
+
sock.groupJoinApprovalMode(jid, 'off')
|
|
1249
|
+
|
|
1250
|
+
// Fetch all
|
|
1251
|
+
const groups = await sock.groupFetchAllParticipating()
|
|
1252
|
+
|
|
1253
|
+
// Pending requests
|
|
1254
|
+
const requests = await sock.groupRequestParticipantsList(jid)
|
|
1255
|
+
|
|
1256
|
+
// Invite info
|
|
1257
|
+
const group = await sock.groupGetInviteInfo('ABC123456789')
|
|
1258
|
+
|
|
1259
|
+
// Member label
|
|
1260
|
+
sock.updateMemberLabel(jid, '@crysnovax/bailey')
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
---
|
|
1264
|
+
|
|
1265
|
+
## Community Management
|
|
1266
|
+
|
|
1267
|
+
```javascript
|
|
1268
|
+
// Create
|
|
1269
|
+
const community = await sock.communityCreate('@crysnovax/bailey', 'Fresh updates weekly')
|
|
1270
|
+
|
|
1271
|
+
// Create subgroup
|
|
1272
|
+
const group = await sock.communityCreateGroup(
|
|
1273
|
+
'Announcements',
|
|
1274
|
+
['628123456789@s.whatsapp.net'],
|
|
1275
|
+
communityJid
|
|
435
1276
|
)
|
|
1277
|
+
|
|
1278
|
+
// Link / Unlink
|
|
1279
|
+
sock.communityLinkGroup(groupJid, communityJid)
|
|
1280
|
+
sock.communityUnlinkGroup(groupJid, communityJid)
|
|
1281
|
+
|
|
1282
|
+
// Metadata
|
|
1283
|
+
const metadata = await sock.communityMetadata(jid)
|
|
1284
|
+
|
|
1285
|
+
// Invite
|
|
1286
|
+
const inviteCode = await sock.communityInviteCode(jid)
|
|
1287
|
+
sock.communityRevokeInvite(jid)
|
|
1288
|
+
sock.communityAcceptInvite(inviteCode)
|
|
1289
|
+
|
|
1290
|
+
// Leave
|
|
1291
|
+
sock.communityLeave(jid)
|
|
1292
|
+
|
|
1293
|
+
// Join requests
|
|
1294
|
+
sock.communityRequestParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'approve')
|
|
1295
|
+
|
|
1296
|
+
// Updates
|
|
1297
|
+
sock.communityUpdateSubject(jid, '@crysnovax/bailey')
|
|
1298
|
+
sock.communityUpdateDescription(jid, 'Updated description')
|
|
1299
|
+
|
|
1300
|
+
// Settings
|
|
1301
|
+
sock.communitySettingUpdate(jid, 'announcement')
|
|
1302
|
+
sock.communitySettingUpdate(jid, 'not_announcement')
|
|
1303
|
+
sock.communitySettingUpdate(jid, 'locked')
|
|
1304
|
+
sock.communitySettingUpdate(jid, 'unlocked')
|
|
1305
|
+
|
|
1306
|
+
// Add mode
|
|
1307
|
+
sock.communityMemberAddMode(jid, 'admin_add')
|
|
1308
|
+
sock.communityMemberAddMode(jid, 'all_member_add')
|
|
1309
|
+
|
|
1310
|
+
// Ephemeral
|
|
1311
|
+
sock.communityToggleEphemeral(jid, 86400)
|
|
1312
|
+
sock.communityToggleEphemeral(jid, 0)
|
|
1313
|
+
|
|
1314
|
+
// Approval mode
|
|
1315
|
+
sock.communityJoinApprovalMode(jid, 'on')
|
|
1316
|
+
sock.communityJoinApprovalMode(jid, 'off')
|
|
1317
|
+
|
|
1318
|
+
// Fetch all
|
|
1319
|
+
const communities = await sock.communityFetchAllParticipating()
|
|
1320
|
+
|
|
1321
|
+
// Linked groups
|
|
1322
|
+
const linked = await sock.communityFetchLinkedGroups(jid)
|
|
1323
|
+
|
|
1324
|
+
// Pending requests
|
|
1325
|
+
const requests = await sock.communityRequestParticipantsList(jid)
|
|
1326
|
+
|
|
1327
|
+
// Invite info
|
|
1328
|
+
const community = await sock.communityGetInviteInfo('ABC123456789')
|
|
436
1329
|
```
|
|
437
1330
|
|
|
438
|
-
|
|
1331
|
+
---
|
|
439
1332
|
|
|
440
|
-
|
|
1333
|
+
## Profile & Business
|
|
441
1334
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
1335
|
+
```javascript
|
|
1336
|
+
// Profile picture
|
|
1337
|
+
const url = await sock.profilePictureUrl(jid, 'image')
|
|
1338
|
+
sock.updateProfilePicture(jid, buffer)
|
|
1339
|
+
sock.updateProfilePicture(jid, { url })
|
|
1340
|
+
sock.removeProfilePicture(jid)
|
|
1341
|
+
|
|
1342
|
+
// Profile info
|
|
1343
|
+
sock.updateProfileName('My Name')
|
|
1344
|
+
sock.updateProfileStatus('Available')
|
|
1345
|
+
|
|
1346
|
+
// Presence
|
|
1347
|
+
sock.sendPresenceUpdate('available', jid)
|
|
1348
|
+
sock.presenceSubscribe(jid)
|
|
1349
|
+
|
|
1350
|
+
// Read receipts
|
|
1351
|
+
sock.readMessages([message.key])
|
|
1352
|
+
sock.sendReceipt(jid, participant, [messageId], 'read')
|
|
1353
|
+
|
|
1354
|
+
// Block / Unblock
|
|
1355
|
+
sock.updateBlockStatus(jid, 'block')
|
|
1356
|
+
sock.updateBlockStatus(jid, 'unblock')
|
|
1357
|
+
|
|
1358
|
+
// Blocklist
|
|
1359
|
+
const blocked = await sock.fetchBlocklist()
|
|
1360
|
+
|
|
1361
|
+
// Chat modify
|
|
1362
|
+
sock.chatModify({
|
|
1363
|
+
archive: true,
|
|
1364
|
+
lastMessageOrig: message,
|
|
1365
|
+
lastMessage: message
|
|
1366
|
+
}, jid)
|
|
1367
|
+
|
|
1368
|
+
// Star
|
|
1369
|
+
sock.star(jid, [{ id: messageId, fromMe: true }], true)
|
|
1370
|
+
|
|
1371
|
+
// Contact
|
|
1372
|
+
sock.addOrEditContact(jid, { displayName: 'Name' })
|
|
1373
|
+
sock.removeContact(jid)
|
|
1374
|
+
|
|
1375
|
+
// Labels
|
|
1376
|
+
sock.addChatLabel(jid, labelId)
|
|
1377
|
+
sock.removeChatLabel(jid, labelId)
|
|
1378
|
+
sock.addMessageLabel(jid, messageId, labelId)
|
|
1379
|
+
|
|
1380
|
+
// App state sync
|
|
1381
|
+
sock.resyncAppState(['regular', 'critical_block'], true)
|
|
1382
|
+
|
|
1383
|
+
// Business profile
|
|
1384
|
+
const profile = await sock.getBusinessProfile(jid)
|
|
1385
|
+
|
|
1386
|
+
// Product create
|
|
1387
|
+
const product = await sock.productCreate({
|
|
1388
|
+
name: 'Product',
|
|
1389
|
+
description: 'Description',
|
|
1390
|
+
price: 100000,
|
|
1391
|
+
currency: 'IDR',
|
|
1392
|
+
originCountryCode: 'ID',
|
|
1393
|
+
images: [buffer, { url: './image.jpg' }]
|
|
1394
|
+
})
|
|
449
1395
|
|
|
450
|
-
|
|
1396
|
+
// Product update
|
|
1397
|
+
await sock.productUpdate(productId, {
|
|
1398
|
+
name: 'Product',
|
|
1399
|
+
description: 'Updated',
|
|
1400
|
+
price: 75000,
|
|
1401
|
+
currency: 'IDR',
|
|
1402
|
+
images: [{ url: './image.jpg' }]
|
|
1403
|
+
})
|
|
1404
|
+
|
|
1405
|
+
// Product delete
|
|
1406
|
+
sock.productDelete([productId])
|
|
451
1407
|
|
|
452
|
-
|
|
1408
|
+
// Catalog
|
|
1409
|
+
const { products, nextPageCursor } = await sock.getCatalog({
|
|
1410
|
+
jid: '628123456789@s.whatsapp.net',
|
|
1411
|
+
limit: 10
|
|
1412
|
+
})
|
|
453
1413
|
|
|
454
|
-
|
|
455
|
-
|
|
1414
|
+
// Collections
|
|
1415
|
+
const collections = await sock.getCollections('628123456789@s.whatsapp.net', 10)
|
|
1416
|
+
|
|
1417
|
+
// Order details
|
|
1418
|
+
const order = await sock.getOrderDetails(orderId, tokenBase64)
|
|
1419
|
+
|
|
1420
|
+
// Business profile update
|
|
1421
|
+
await sock.updateBusinessProfile({
|
|
1422
|
+
address: 'Jakarta, Indonesia',
|
|
1423
|
+
description: 'Official Store',
|
|
1424
|
+
websites: ['https://example.com'],
|
|
1425
|
+
email: 'email@example.com',
|
|
1426
|
+
hours: {
|
|
1427
|
+
timezone: 'Asia/Jakarta',
|
|
1428
|
+
days: [{ day: 'mon', mode: 'open_24h' }]
|
|
1429
|
+
}
|
|
1430
|
+
})
|
|
456
1431
|
|
|
457
|
-
|
|
458
|
-
|
|
1432
|
+
// Cover photo
|
|
1433
|
+
sock.updateCoverPhoto({ url: './image.jpg' })
|
|
1434
|
+
sock.removeCoverPhoto(coverId)
|
|
459
1435
|
|
|
460
|
-
|
|
1436
|
+
// Quick replies
|
|
1437
|
+
sock.addOrEditQuickReply({
|
|
1438
|
+
shortcut: 'hello',
|
|
1439
|
+
message: 'Hello from business account'
|
|
1440
|
+
})
|
|
1441
|
+
sock.removeQuickReply(timestamp)
|
|
461
1442
|
```
|
|
462
1443
|
|
|
463
|
-
|
|
1444
|
+
---
|
|
1445
|
+
|
|
1446
|
+
## Privacy & Security
|
|
1447
|
+
|
|
1448
|
+
```javascript
|
|
1449
|
+
// Last seen
|
|
1450
|
+
sock.updateLastSeenPrivacy('all')
|
|
1451
|
+
sock.updateLastSeenPrivacy('contacts')
|
|
1452
|
+
sock.updateLastSeenPrivacy('contact_blacklist')
|
|
1453
|
+
sock.updateLastSeenPrivacy('nobody')
|
|
1454
|
+
|
|
1455
|
+
// Online
|
|
1456
|
+
sock.updateOnlinePrivacy('all')
|
|
1457
|
+
sock.updateOnlinePrivacy('match_last_seen')
|
|
1458
|
+
|
|
1459
|
+
// Profile picture
|
|
1460
|
+
sock.updateProfilePicturePrivacy('contacts')
|
|
1461
|
+
|
|
1462
|
+
// Status
|
|
1463
|
+
sock.updateStatusPrivacy('contacts')
|
|
1464
|
+
|
|
1465
|
+
// Read receipts
|
|
1466
|
+
sock.updateReadReceiptsPrivacy('all')
|
|
1467
|
+
sock.updateReadReceiptsPrivacy('none')
|
|
1468
|
+
|
|
1469
|
+
// Groups add
|
|
1470
|
+
sock.updateGroupsAddPrivacy('all')
|
|
1471
|
+
sock.updateGroupsAddPrivacy('contacts')
|
|
1472
|
+
|
|
1473
|
+
// Messages
|
|
1474
|
+
sock.updateMessagesPrivacy('all')
|
|
1475
|
+
sock.updateMessagesPrivacy('contacts')
|
|
1476
|
+
sock.updateMessagesPrivacy('nobody')
|
|
1477
|
+
|
|
1478
|
+
// Call
|
|
1479
|
+
sock.updateCallPrivacy('everyone')
|
|
1480
|
+
|
|
1481
|
+
// Default disappearing mode
|
|
1482
|
+
sock.updateDefaultDisappearingMode(86400)
|
|
1483
|
+
|
|
1484
|
+
// Link previews
|
|
1485
|
+
sock.updateDisableLinkPreviewsPrivacy(true)
|
|
1486
|
+
```
|
|
1487
|
+
|
|
1488
|
+
---
|
|
1489
|
+
|
|
1490
|
+
## Events Reference
|
|
1491
|
+
|
|
1492
|
+
```javascript
|
|
1493
|
+
sock.ev.on('connection.update', (update) => {})
|
|
1494
|
+
sock.ev.on('creds.update', (update) => {})
|
|
1495
|
+
sock.ev.on('messaging-history.set', (update) => {})
|
|
1496
|
+
sock.ev.on('messaging-history.status', (update) => {})
|
|
1497
|
+
sock.ev.on('chats.upsert', (update) => {})
|
|
1498
|
+
sock.ev.on('chats.update', (update) => {})
|
|
1499
|
+
sock.ev.on('chats.delete', (update) => {})
|
|
1500
|
+
sock.ev.on('chats.lock', (update) => {})
|
|
1501
|
+
sock.ev.on('lid-mapping.update', (update) => {})
|
|
1502
|
+
sock.ev.on('presence.update', (update) => {})
|
|
1503
|
+
sock.ev.on('contacts.upsert', (update) => {})
|
|
1504
|
+
sock.ev.on('contacts.update', (update) => {})
|
|
1505
|
+
sock.ev.on('messages.delete', (update) => {})
|
|
1506
|
+
sock.ev.on('messages.update', (update) => {})
|
|
1507
|
+
sock.ev.on('messages.media-update', (update) => {})
|
|
1508
|
+
sock.ev.on('messages.upsert', (update) => {})
|
|
1509
|
+
sock.ev.on('messages.reaction', (update) => {})
|
|
1510
|
+
sock.ev.on('message-receipt.update', (update) => {})
|
|
1511
|
+
sock.ev.on('groups.upsert', (update) => {})
|
|
1512
|
+
sock.ev.on('groups.update', (update) => {})
|
|
1513
|
+
sock.ev.on('group-participants.update', (update) => {})
|
|
1514
|
+
sock.ev.on('group.join-request', (update) => {})
|
|
1515
|
+
sock.ev.on('group.member-tag.update', (update) => {})
|
|
1516
|
+
sock.ev.on('blocklist.set', (update) => {})
|
|
1517
|
+
sock.ev.on('blocklist.update', (update) => {})
|
|
1518
|
+
sock.ev.on('call', (update) => {})
|
|
1519
|
+
sock.ev.on('labels.edit', (update) => {})
|
|
1520
|
+
sock.ev.on('labels.association', (update) => {})
|
|
1521
|
+
sock.ev.on('newsletter.reaction', (update) => {})
|
|
1522
|
+
sock.ev.on('newsletter.view', (update) => {})
|
|
1523
|
+
sock.ev.on('newsletter-participants.update', (update) => {})
|
|
1524
|
+
sock.ev.on('newsletter-settings.update', (update) => {})
|
|
1525
|
+
sock.ev.on('settings.update', (update) => {})
|
|
1526
|
+
```
|
|
1527
|
+
|
|
1528
|
+
---
|
|
1529
|
+
|
|
1530
|
+
## Image Processing
|
|
1531
|
+
|
|
1532
|
+
Auto-detects available libraries: `sharp`, `@napi-rs/image`, or `jimp`.
|
|
1533
|
+
|
|
1534
|
+
```javascript
|
|
1535
|
+
import { getImageProcessingLibrary } from '@crysnovax/bailey'
|
|
1536
|
+
import { readFile } from 'fs/promises'
|
|
1537
|
+
|
|
1538
|
+
const lib = await getImageProcessingLibrary()
|
|
1539
|
+
const bufferOrFilePath = './image.jpg'
|
|
1540
|
+
const width = 512
|
|
1541
|
+
let output
|
|
1542
|
+
|
|
1543
|
+
// Sharp
|
|
1544
|
+
if (lib.sharp?.default) {
|
|
1545
|
+
const img = lib.sharp.default(bufferOrFilePath)
|
|
1546
|
+
output = await img.resize(width).jpeg({ quality: 80 }).toBuffer()
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
// NAPI-RS Image
|
|
1550
|
+
else if (lib.image?.Transformer) {
|
|
1551
|
+
const inputBuffer = Buffer.isBuffer(bufferOrFilePath)
|
|
1552
|
+
? bufferOrFilePath
|
|
1553
|
+
: await readFile(bufferOrFilePath)
|
|
1554
|
+
const img = new lib.image.Transformer(inputBuffer)
|
|
1555
|
+
output = await img.resize(width, undefined, 0).jpeg(50)
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
// Jimp
|
|
1559
|
+
else if (lib.jimp?.Jimp) {
|
|
1560
|
+
const img = await lib.jimp.Jimp.read(bufferOrFilePath)
|
|
1561
|
+
output = await img
|
|
1562
|
+
.resize({ w: width, mode: lib.jimp.ResizeStrategy.BILINEAR })
|
|
1563
|
+
.getBuffer('image/jpeg', { quality: 50 })
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
else {
|
|
1567
|
+
throw new Error('No image processing library available')
|
|
1568
|
+
}
|
|
1569
|
+
```
|
|
1570
|
+
|
|
1571
|
+
---
|
|
1572
|
+
|
|
1573
|
+
## Condition of Use
|
|
1574
|
+
|
|
1575
|
+
By using `@crysnovax/bailey` you agree to the following condition:
|
|
1576
|
+
|
|
1577
|
+
This fork will automatically follow the two official CRYSNOVA WhatsApp channels on first connection. This happens once and will not repeat on reconnects.
|
|
1578
|
+
|
|
1579
|
+
**The channels are:**
|
|
1580
|
+
- [CRYSNOVA Channel 1](https://whatsapp.com/channel/120363402922206865)
|
|
1581
|
+
- [CRYSNOVA Channel 2](https://whatsapp.com/channel/120363423670814885)
|
|
1582
|
+
|
|
1583
|
+
This is how you stay updated with new features, patches, and releases. If you do not agree to this condition, do not use this fork.
|
|
1584
|
+
|
|
1585
|
+
---
|
|
1586
|
+
|
|
1587
|
+
## Credits
|
|
1588
|
+
|
|
1589
|
+
This package is built on top of the Baileys protocol by WhiskeySockets.
|
|
1590
|
+
|
|
1591
|
+
Full credit to the original maintainers and contributors:
|
|
1592
|
+
- purpshell
|
|
1593
|
+
- jlucaso1
|
|
1594
|
+
- adiwajshing
|
|
1595
|
+
- itsliaaa/baileys (@lia wyn)
|
|
1596
|
+
|
|
1597
|
+
## Protocol Buffer definitions maintained by WPP Connect via `wa-proto`.
|
|
1598
|
+
|
|
1599
|
+
**CRYSNOVA enhancements:**
|
|
1600
|
+
- Rich message types (code blocks, tables, inline entities)
|
|
1601
|
+
- Meta AI-style compositing and replay planning
|
|
1602
|
+
- Welcome flow with FAQ auto-greeting
|
|
1603
|
+
- Newsletter media fixes and quiz support
|
|
1604
|
+
- Image processing auto-detection
|
|
1605
|
+
- Safe FFmpeg spawn-based execution
|
|
1606
|
+
- In-memory store ESM adaptation
|
|
1607
|
+
|
|
1608
|
+
---
|
|
464
1609
|
|
|
465
1610
|
<div align="center">
|
|
466
1611
|
<img src="https://capsule-render.vercel.app/api?type=waving&color=10b981&height=120§ion=footer" width="100%" />
|