@nozez-lab/baileys 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -0
- package/index.d.ts +80 -0
- package/index.js +100 -39
- package/package.json +8 -4
- package/test.js +9 -120
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# @nozezlab/baileys 🚀
|
|
2
|
+
|
|
3
|
+
Customized premium wrapper for **@whiskeysockets/baileys** featuring native flow interactive buttons, single-select dropdown submenus, quick phone pairing, and automatic message serialization helper functions.
|
|
4
|
+
|
|
5
|
+
Designed as a 100% compatible, drop-in replacement!
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📦 Installation
|
|
10
|
+
|
|
11
|
+
To install this customized library:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @nozezlab/baileys
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## ✨ Core Features
|
|
18
|
+
|
|
19
|
+
* **Native Interactive Buttons** (`sendButtons`): Easily send interactive buttons (replies, links, copy codes).
|
|
20
|
+
* **Single-Select Dropdown Menus** (`sendList`): Send structured dropdown options.
|
|
21
|
+
* **Message Serializer** (`serializeMessage`): Extracted fields like `m.body` directly mapped (even for native button responses) and attached reply helpers like `m.replyButtons` and `m.replyList`.
|
|
22
|
+
* **Built-in Phone Pairing** (`pairWithPhoneNumber`): Connect instantly by displaying the pairing code cleanly in the terminal.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 🚀 Quick Start Example
|
|
27
|
+
|
|
28
|
+
Here is how easily you can initialize the socket and use the custom helpers:
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
const makeWASocket = require('@nozezlab/baileys').default;
|
|
32
|
+
const { useMultiFileAuthState } = require('@nozezlab/baileys');
|
|
33
|
+
|
|
34
|
+
async function startBot() {
|
|
35
|
+
const { state, saveCreds } = await useMultiFileAuthState('./session');
|
|
36
|
+
|
|
37
|
+
const sock = makeWASocket({
|
|
38
|
+
auth: state,
|
|
39
|
+
printQRInTerminal: false // Set to false to use Pairing Code
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
sock.ev.on('creds.update', saveCreds);
|
|
43
|
+
|
|
44
|
+
// 1. Phone pairing setup (if not registered yet)
|
|
45
|
+
if (!sock.authState.creds.registered) {
|
|
46
|
+
const phoneNumber = "628xxx"; // Change to your bot's phone number
|
|
47
|
+
await sock.pairWithPhoneNumber(phoneNumber);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
sock.ev.on('connection.update', (update) => {
|
|
51
|
+
const { connection } = update;
|
|
52
|
+
if (connection === 'open') {
|
|
53
|
+
console.log("✅ Bot connected successfully!");
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
sock.ev.on('messages.upsert', async (chatUpdate) => {
|
|
58
|
+
const mek = chatUpdate.messages[0];
|
|
59
|
+
if (!mek.message) return;
|
|
60
|
+
|
|
61
|
+
// Serialize message to get custom helpers & body parser
|
|
62
|
+
const m = sock.serializeMessage(mek);
|
|
63
|
+
|
|
64
|
+
// Command handler example
|
|
65
|
+
if (m.body === '.menu') {
|
|
66
|
+
const buttons = [
|
|
67
|
+
{ type: 'reply', displayText: '📁 Show All Features', id: '.allfeatures' },
|
|
68
|
+
{ type: 'url', displayText: '🌐 Visit Website', url: 'https://nozez.dev' },
|
|
69
|
+
{ type: 'copy', displayText: '🔑 Copy API Key', code: 'API_KEY_12345' }
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
// Send buttons cleanly!
|
|
73
|
+
await m.replyButtons(
|
|
74
|
+
"🤖 NOZEZLAB SYSTEM", // Header (Optional)
|
|
75
|
+
"Welcome to KChartify Bot. Please select one option:", // Body text
|
|
76
|
+
"© NozezLab Ecosystem", // Footer (Optional)
|
|
77
|
+
buttons // Button list
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
startBot();
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 🛠️ API Reference
|
|
89
|
+
|
|
90
|
+
### 1. `sock.sendButtons(jid, header, text, footer, buttons, quoted, mediaOptions)`
|
|
91
|
+
* `buttons` supports the following structures:
|
|
92
|
+
```javascript
|
|
93
|
+
const buttons = [
|
|
94
|
+
{ type: 'reply', displayText: 'Option A', id: 'opt_a' },
|
|
95
|
+
{ type: 'url', displayText: 'Open Website', url: 'https://example.com' },
|
|
96
|
+
{ type: 'copy', displayText: 'Copy Code', code: 'MY_CODE' }
|
|
97
|
+
]
|
|
98
|
+
```
|
|
99
|
+
* `mediaOptions` supports native image headers:
|
|
100
|
+
```javascript
|
|
101
|
+
await sock.sendButtons(jid, "Header", "Text", "Footer", buttons, null, {
|
|
102
|
+
image: "https://example.com/banner.png" // or local file buffer
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 2. `sock.sendList(jid, header, text, footer, buttonText, sections, quoted, mediaOptions)`
|
|
107
|
+
* `sections` structure:
|
|
108
|
+
```javascript
|
|
109
|
+
const sections = [
|
|
110
|
+
{
|
|
111
|
+
title: "Category 1",
|
|
112
|
+
rows: [
|
|
113
|
+
{ title: "Option 1", description: "Select Option 1", id: ".opt1" },
|
|
114
|
+
{ title: "Option 2", description: "Select Option 2", id: ".opt2" }
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
];
|
|
118
|
+
await sock.sendList(jid, "Menu", "Select below", "Footer", "Click here", sections);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 📄 License
|
|
124
|
+
|
|
125
|
+
MIT © NozezLab
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as Baileys from '@whiskeysockets/baileys';
|
|
2
|
+
|
|
3
|
+
export * from '@whiskeysockets/baileys';
|
|
4
|
+
|
|
5
|
+
export interface NativeButton {
|
|
6
|
+
type: 'reply' | 'url' | 'copy';
|
|
7
|
+
displayText?: string;
|
|
8
|
+
text?: string;
|
|
9
|
+
id?: string;
|
|
10
|
+
buttonId?: string;
|
|
11
|
+
url?: string;
|
|
12
|
+
code?: string;
|
|
13
|
+
copyCode?: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
buttonParamsJson?: string;
|
|
16
|
+
nativeFlowInfo?: {
|
|
17
|
+
name: string;
|
|
18
|
+
paramsJson: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface NativeListSection {
|
|
23
|
+
title: string;
|
|
24
|
+
highlight_label?: string;
|
|
25
|
+
rows: {
|
|
26
|
+
title: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
id: string;
|
|
29
|
+
}[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface CustomWASocket extends Omit<ReturnType<typeof Baileys.default>, 'sendMessage'> {
|
|
33
|
+
sendMessage(
|
|
34
|
+
jid: string,
|
|
35
|
+
content: {
|
|
36
|
+
text?: string;
|
|
37
|
+
caption?: string;
|
|
38
|
+
header?: string;
|
|
39
|
+
footer?: string;
|
|
40
|
+
buttons?: NativeButton[];
|
|
41
|
+
sections?: NativeListSection[];
|
|
42
|
+
buttonText?: string;
|
|
43
|
+
image?: any;
|
|
44
|
+
[key: string]: any;
|
|
45
|
+
},
|
|
46
|
+
options?: any
|
|
47
|
+
): Promise<any>;
|
|
48
|
+
|
|
49
|
+
sendButtons(
|
|
50
|
+
jid: string,
|
|
51
|
+
header: string,
|
|
52
|
+
text: string,
|
|
53
|
+
footer: string,
|
|
54
|
+
buttons: NativeButton[],
|
|
55
|
+
quoted?: any,
|
|
56
|
+
mediaOptions?: { image?: any }
|
|
57
|
+
): Promise<any>;
|
|
58
|
+
|
|
59
|
+
sendList(
|
|
60
|
+
jid: string,
|
|
61
|
+
header: string,
|
|
62
|
+
text: string,
|
|
63
|
+
footer: string,
|
|
64
|
+
buttonText: string,
|
|
65
|
+
sections: NativeListSection[],
|
|
66
|
+
quoted?: any,
|
|
67
|
+
mediaOptions?: { image?: any }
|
|
68
|
+
): Promise<any>;
|
|
69
|
+
|
|
70
|
+
serializeMessage(m: any): any;
|
|
71
|
+
|
|
72
|
+
pairWithPhoneNumber(
|
|
73
|
+
phoneNumber: string,
|
|
74
|
+
loggerCallback?: (code: string) => void
|
|
75
|
+
): Promise<string>;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function makeWASocket(config?: Parameters<typeof Baileys.default>[0]): CustomWASocket;
|
|
79
|
+
|
|
80
|
+
export default makeWASocket;
|
package/index.js
CHANGED
|
@@ -1,50 +1,83 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* @nozezlab/baileys - Premium Customized WhatsApp Baileys Library Wrapper
|
|
3
|
+
* Designed for NozezLab as a drop-in replacement for '@whiskeysockets/baileys'.
|
|
4
|
+
* Features native buttons, single-select dropdown submenus, phone pairing, and automatic serializations.
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
const Baileys = require('@whiskeysockets/baileys');
|
|
7
|
-
const { getContentType, prepareWAMessageMedia } = require('@whiskeysockets/baileys');
|
|
8
|
+
const { getContentType, prepareWAMessageMedia, generateWAMessageFromContent } = require('@whiskeysockets/baileys');
|
|
8
9
|
const chalk = require('chalk');
|
|
9
10
|
const pino = require('pino');
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
|
-
* Custom WASocket wrapper that injects premium features
|
|
13
|
+
* Custom WASocket wrapper that injects premium interactive features
|
|
13
14
|
*/
|
|
14
15
|
function makeWASocket(config = {}) {
|
|
15
16
|
// 1. Create the original socket connection
|
|
16
|
-
const sock = Baileys.default(config);
|
|
17
|
+
const sock = Baileys.default ? Baileys.default(config) : Baileys(config);
|
|
17
18
|
|
|
18
19
|
// 2. Add native Button helper on the socket object
|
|
19
20
|
sock.sendButtons = async (jid, header, text, footer, buttons, quoted = null, mediaOptions = {}) => {
|
|
20
21
|
const formattedButtons = buttons.map(btn => {
|
|
22
|
+
// Already formatted native flow format
|
|
23
|
+
if (btn.name && btn.buttonParamsJson) {
|
|
24
|
+
return btn;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// New wrapper helper format (reply)
|
|
21
28
|
if (btn.type === 'reply') {
|
|
22
29
|
return {
|
|
23
30
|
name: "quick_reply",
|
|
24
31
|
buttonParamsJson: JSON.stringify({
|
|
25
|
-
display_text: btn.displayText,
|
|
26
|
-
id: btn.id
|
|
32
|
+
display_text: btn.displayText || btn.text || "",
|
|
33
|
+
id: btn.id || btn.buttonId || ""
|
|
27
34
|
})
|
|
28
35
|
};
|
|
29
|
-
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// New wrapper helper format (url)
|
|
39
|
+
if (btn.type === 'url') {
|
|
30
40
|
return {
|
|
31
41
|
name: "cta_url",
|
|
32
42
|
buttonParamsJson: JSON.stringify({
|
|
33
|
-
display_text: btn.displayText,
|
|
43
|
+
display_text: btn.displayText || btn.text || "",
|
|
34
44
|
url: btn.url,
|
|
35
45
|
merchant_url: btn.url
|
|
36
46
|
})
|
|
37
47
|
};
|
|
38
|
-
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// New wrapper helper format (copy code)
|
|
51
|
+
if (btn.type === 'copy') {
|
|
39
52
|
return {
|
|
40
53
|
name: "cta_copy",
|
|
41
54
|
buttonParamsJson: JSON.stringify({
|
|
42
|
-
display_text: btn.displayText,
|
|
43
|
-
copy_code: btn.code
|
|
55
|
+
display_text: btn.displayText || btn.text || "",
|
|
56
|
+
copy_code: btn.code || btn.copyCode || ""
|
|
44
57
|
})
|
|
45
58
|
};
|
|
46
59
|
}
|
|
47
|
-
|
|
60
|
+
|
|
61
|
+
// Old Baileys style or Vellia Elyvia format
|
|
62
|
+
const buttonId = btn.buttonId || btn.id || "";
|
|
63
|
+
const displayText = btn.buttonText?.displayText || btn.displayText || btn.text || "";
|
|
64
|
+
|
|
65
|
+
// Interactive / Native Flow Button type 4
|
|
66
|
+
if (btn.type === 4 || btn.nativeFlowInfo) {
|
|
67
|
+
return {
|
|
68
|
+
name: btn.nativeFlowInfo?.name || "single_select",
|
|
69
|
+
buttonParamsJson: btn.nativeFlowInfo?.paramsJson || btn.buttonParamsJson || "{}"
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Fallback: Default to quick reply for Type 1 / generic buttons
|
|
74
|
+
return {
|
|
75
|
+
name: "quick_reply",
|
|
76
|
+
buttonParamsJson: JSON.stringify({
|
|
77
|
+
display_text: displayText,
|
|
78
|
+
id: buttonId
|
|
79
|
+
})
|
|
80
|
+
};
|
|
48
81
|
});
|
|
49
82
|
|
|
50
83
|
let headerObject = {
|
|
@@ -55,8 +88,9 @@ function makeWASocket(config = {}) {
|
|
|
55
88
|
// If an image header is provided, upload it natively to WhatsApp
|
|
56
89
|
if (mediaOptions.image) {
|
|
57
90
|
try {
|
|
91
|
+
const imageSource = typeof mediaOptions.image === 'string' ? { url: mediaOptions.image } : mediaOptions.image;
|
|
58
92
|
const media = await prepareWAMessageMedia(
|
|
59
|
-
{ image:
|
|
93
|
+
{ image: imageSource },
|
|
60
94
|
{ upload: sock.waUploadToServer }
|
|
61
95
|
);
|
|
62
96
|
headerObject = {
|
|
@@ -87,7 +121,13 @@ function makeWASocket(config = {}) {
|
|
|
87
121
|
}
|
|
88
122
|
};
|
|
89
123
|
|
|
90
|
-
|
|
124
|
+
const prep = generateWAMessageFromContent(jid, msg, {
|
|
125
|
+
quoted,
|
|
126
|
+
userJid: sock.user?.id
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
await sock.relayMessage(jid, prep.message, { messageId: prep.key.id });
|
|
130
|
+
return prep;
|
|
91
131
|
};
|
|
92
132
|
|
|
93
133
|
// 3. Add native List (single_select dropdown) helper on the socket object
|
|
@@ -100,8 +140,9 @@ function makeWASocket(config = {}) {
|
|
|
100
140
|
// If an image header is provided, upload it natively to WhatsApp
|
|
101
141
|
if (mediaOptions.image) {
|
|
102
142
|
try {
|
|
143
|
+
const imageSource = typeof mediaOptions.image === 'string' ? { url: mediaOptions.image } : mediaOptions.image;
|
|
103
144
|
const media = await prepareWAMessageMedia(
|
|
104
|
-
{ image:
|
|
145
|
+
{ image: imageSource },
|
|
105
146
|
{ upload: sock.waUploadToServer }
|
|
106
147
|
);
|
|
107
148
|
headerObject = {
|
|
@@ -140,10 +181,16 @@ function makeWASocket(config = {}) {
|
|
|
140
181
|
}
|
|
141
182
|
};
|
|
142
183
|
|
|
143
|
-
|
|
184
|
+
const prep = generateWAMessageFromContent(jid, msg, {
|
|
185
|
+
quoted,
|
|
186
|
+
userJid: sock.user?.id
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
await sock.relayMessage(jid, prep.message, { messageId: prep.key.id });
|
|
190
|
+
return prep;
|
|
144
191
|
};
|
|
145
192
|
|
|
146
|
-
// 4. Intercept
|
|
193
|
+
// 4. Intercept standard sendMessage to handle content.buttons and content.sections!
|
|
147
194
|
const originalSendMessage = sock.sendMessage;
|
|
148
195
|
sock.sendMessage = async (jid, content, options = {}) => {
|
|
149
196
|
// Intercept native buttons
|
|
@@ -155,11 +202,11 @@ function makeWASocket(config = {}) {
|
|
|
155
202
|
content.footer || "",
|
|
156
203
|
content.buttons,
|
|
157
204
|
options.quoted,
|
|
158
|
-
{ image: content.image }
|
|
205
|
+
{ image: content.image }
|
|
159
206
|
);
|
|
160
207
|
}
|
|
161
208
|
|
|
162
|
-
// Intercept native lists
|
|
209
|
+
// Intercept native lists (dropdowns)
|
|
163
210
|
if (content.sections && Array.isArray(content.sections)) {
|
|
164
211
|
return await sock.sendList(
|
|
165
212
|
jid,
|
|
@@ -169,11 +216,11 @@ function makeWASocket(config = {}) {
|
|
|
169
216
|
content.buttonText || "Choose Option",
|
|
170
217
|
content.sections,
|
|
171
218
|
options.quoted,
|
|
172
|
-
{ image: content.image }
|
|
219
|
+
{ image: content.image }
|
|
173
220
|
);
|
|
174
221
|
}
|
|
175
222
|
|
|
176
|
-
// Pass through
|
|
223
|
+
// Pass through for standard texts, images, documents, etc.
|
|
177
224
|
return await originalSendMessage.call(sock, jid, content, options);
|
|
178
225
|
};
|
|
179
226
|
|
|
@@ -183,7 +230,7 @@ function makeWASocket(config = {}) {
|
|
|
183
230
|
|
|
184
231
|
if (m.key) {
|
|
185
232
|
m.id = m.key.id;
|
|
186
|
-
m.isBot = m.id.startsWith('BAE5') || m.id.startsWith('HSK');
|
|
233
|
+
m.isBot = m.id.startsWith('BAE5') || m.id.startsWith('HSK') || m.id.startsWith('NZL');
|
|
187
234
|
m.chat = m.key.remoteJid;
|
|
188
235
|
m.isGroup = m.chat.endsWith('@g.us');
|
|
189
236
|
m.sender = m.isGroup ? (m.key.participant || m.chat) : m.chat;
|
|
@@ -194,14 +241,29 @@ function makeWASocket(config = {}) {
|
|
|
194
241
|
m.type = getContentType(m.message);
|
|
195
242
|
|
|
196
243
|
// Core body text extraction (including button responses)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
244
|
+
let bodyText = "";
|
|
245
|
+
if (m.type === 'conversation') {
|
|
246
|
+
bodyText = m.message.conversation;
|
|
247
|
+
} else if (m.type === 'extendedTextMessage') {
|
|
248
|
+
bodyText = m.message.extendedTextMessage.text;
|
|
249
|
+
} else if (m.type === 'imageMessage') {
|
|
250
|
+
bodyText = m.message.imageMessage.caption;
|
|
251
|
+
} else if (m.type === 'videoMessage') {
|
|
252
|
+
bodyText = m.message.videoMessage.caption;
|
|
253
|
+
} else if (m.type === 'templateButtonReplyMessage') {
|
|
254
|
+
bodyText = m.message.templateButtonReplyMessage.selectedId;
|
|
255
|
+
} else if (m.type === 'buttonsResponseMessage') {
|
|
256
|
+
bodyText = m.message.buttonsResponseMessage.selectedButtonId;
|
|
257
|
+
} else if (m.type === 'interactiveResponseMessage') {
|
|
258
|
+
try {
|
|
259
|
+
const params = JSON.parse(m.message.interactiveResponseMessage.nativeFlowResponseMessage.paramsJson);
|
|
260
|
+
bodyText = params.id || "";
|
|
261
|
+
} catch (e) {
|
|
262
|
+
bodyText = "";
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
m.body = bodyText || "";
|
|
205
267
|
|
|
206
268
|
// Handle quoting
|
|
207
269
|
const quotedMsg = m.message[m.type]?.contextInfo?.quotedMessage;
|
|
@@ -211,8 +273,8 @@ function makeWASocket(config = {}) {
|
|
|
211
273
|
sender: m.message[m.type].contextInfo.participant,
|
|
212
274
|
message: quotedMsg,
|
|
213
275
|
type: getContentType(quotedMsg),
|
|
214
|
-
body:
|
|
215
|
-
|
|
276
|
+
body: quotedMsg.conversation ? quotedMsg.conversation :
|
|
277
|
+
quotedMsg.extendedTextMessage?.text ? quotedMsg.extendedTextMessage.text : ""
|
|
216
278
|
};
|
|
217
279
|
} else {
|
|
218
280
|
m.quoted = null;
|
|
@@ -237,10 +299,10 @@ function makeWASocket(config = {}) {
|
|
|
237
299
|
return m;
|
|
238
300
|
};
|
|
239
301
|
|
|
240
|
-
// 6. Built-in, high-performance automated Pairing Code
|
|
302
|
+
// 6. Built-in, high-performance automated Pairing Code solicitor
|
|
241
303
|
sock.pairWithPhoneNumber = async (phoneNumber, loggerCallback = null) => {
|
|
242
304
|
if (sock.authState.creds.registered) {
|
|
243
|
-
return null; // Already
|
|
305
|
+
return null; // Already registered
|
|
244
306
|
}
|
|
245
307
|
|
|
246
308
|
const cleanNumber = phoneNumber.replace(/[^0-9]/g, '');
|
|
@@ -248,10 +310,9 @@ function makeWASocket(config = {}) {
|
|
|
248
310
|
throw new Error("Invalid phone number format. Must contain digits only.");
|
|
249
311
|
}
|
|
250
312
|
|
|
251
|
-
// Set up callback or default console printer
|
|
252
313
|
const printCode = loggerCallback || ((code) => {
|
|
253
314
|
console.log(chalk.black.bgGreen(`\n==============================================`));
|
|
254
|
-
console.log(chalk.black.bgGreen(` 🔑
|
|
315
|
+
console.log(chalk.black.bgGreen(` 🔑 NOZEZLAB-BAILEYS PAIRING CODE: ${code} `));
|
|
255
316
|
console.log(chalk.black.bgGreen(`==============================================\n`));
|
|
256
317
|
console.log(chalk.cyan(`How to pair:`));
|
|
257
318
|
console.log(chalk.gray(`1. Open WhatsApp on your phone.`));
|
|
@@ -259,7 +320,7 @@ function makeWASocket(config = {}) {
|
|
|
259
320
|
console.log(chalk.gray(`3. Enter the 8-character pairing code: `) + chalk.green.bold(code) + `\n`);
|
|
260
321
|
});
|
|
261
322
|
|
|
262
|
-
// Delay execution by 3.5 seconds to ensure
|
|
323
|
+
// Delay execution by 3.5 seconds to ensure connection stability
|
|
263
324
|
return new Promise((resolve, reject) => {
|
|
264
325
|
setTimeout(async () => {
|
|
265
326
|
try {
|
|
@@ -277,7 +338,7 @@ function makeWASocket(config = {}) {
|
|
|
277
338
|
return sock;
|
|
278
339
|
}
|
|
279
340
|
|
|
280
|
-
//
|
|
341
|
+
// Forward all original exports from @whiskeysockets/baileys so this remains 100% compatible!
|
|
281
342
|
module.exports = {
|
|
282
343
|
...Baileys,
|
|
283
344
|
default: makeWASocket,
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nozez-lab/baileys",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Premium drop-in replacement for '@whiskeysockets/baileys' featuring native interactive buttons, single-select submenus, automated phone pairing, and high-performance message serialization.",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"test": "node test.js"
|
|
8
9
|
},
|
|
@@ -10,10 +11,13 @@
|
|
|
10
11
|
"whatsapp",
|
|
11
12
|
"baileys",
|
|
12
13
|
"buttons",
|
|
14
|
+
"interactive-messages",
|
|
15
|
+
"native-flow",
|
|
13
16
|
"pairing-code",
|
|
14
|
-
"
|
|
17
|
+
"nozezlab",
|
|
18
|
+
"wa-bot"
|
|
15
19
|
],
|
|
16
|
-
"author": "
|
|
20
|
+
"author": "NozezLab",
|
|
17
21
|
"license": "MIT",
|
|
18
22
|
"dependencies": {
|
|
19
23
|
"@whiskeysockets/baileys": "^6.7.7",
|
package/test.js
CHANGED
|
@@ -1,122 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Shows how simple it is to build a bot using your own custom Baileys!
|
|
4
|
-
*/
|
|
1
|
+
const { makeWASocket } = require('./index');
|
|
2
|
+
const assert = require('assert');
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// 2. Setup Multi-File Authentication State
|
|
15
|
-
const { state, saveCreds } = await useMultiFileAuthState('nozez_session');
|
|
16
|
-
|
|
17
|
-
// 3. Connect using custom makeWASocket
|
|
18
|
-
const sock = makeWASocket({
|
|
19
|
-
auth: state,
|
|
20
|
-
logger: pino({ level: 'silent' }), // High performance quiet logging
|
|
21
|
-
printQRInTerminal: true // Prints QR automatically if not pairing
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
// Save credentials when updated
|
|
25
|
-
sock.ev.on('creds.update', saveCreds);
|
|
26
|
-
|
|
27
|
-
// 4. SUPPORTS PAIRING CODE NATIVELY WITH 1-LINE CALL!
|
|
28
|
-
const usePairingCode = false; // Set to true to link using pairing code instead of scanning QR
|
|
29
|
-
const phoneNumber = "6282211559988"; // Replace with your target WhatsApp number
|
|
30
|
-
|
|
31
|
-
if (usePairingCode && !sock.authState.creds.registered) {
|
|
32
|
-
console.log(`[INFO] Pairing active. Requesting pairing code for +${phoneNumber}...`);
|
|
33
|
-
await sock.pairWithPhoneNumber(phoneNumber);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// 5. Connection events handling
|
|
37
|
-
sock.ev.on('connection.update', (update) => {
|
|
38
|
-
const { connection, lastDisconnect } = update;
|
|
39
|
-
if (connection === 'close') {
|
|
40
|
-
const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut;
|
|
41
|
-
console.log(`[CONN] Connection closed. Reconnecting: ${shouldReconnect}`);
|
|
42
|
-
if (shouldReconnect) startBot();
|
|
43
|
-
} else if (connection === 'open') {
|
|
44
|
-
console.log('\n======================================================');
|
|
45
|
-
console.log('🎉 SUCCESS! Connected to WhatsApp using NozezBaileys! 🎉');
|
|
46
|
-
console.log('======================================================\n');
|
|
47
|
-
console.log('Ketik perintah berikut di chat WhatsApp bot Anda:');
|
|
48
|
-
console.log('👉 .testbutton (Untuk menguji tombol interaktif)');
|
|
49
|
-
console.log('👉 .testlist (Untuk menguji dropdown sub-menu)\n');
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// 6. Messages upsert listener
|
|
54
|
-
sock.ev.on('messages.upsert', async (chatUpdate) => {
|
|
55
|
-
const m = chatUpdate.messages[0];
|
|
56
|
-
if (!m.message) return;
|
|
57
|
-
|
|
58
|
-
// SUPPORTS BUILT-IN SERIALIZATION DIRECTLY ON THE SOCKET!
|
|
59
|
-
const parsed = sock.serializeMessage(m);
|
|
60
|
-
if (parsed.isBot) return; // Prevent loops
|
|
61
|
-
|
|
62
|
-
const body = parsed.body.trim().toLowerCase();
|
|
63
|
-
|
|
64
|
-
// 7. SUPPORTS SENDING NATIVE BUTTONS DIRECTLY VIA standard 'sendMessage'!
|
|
65
|
-
if (body === '.testbutton') {
|
|
66
|
-
await sock.sendMessage(parsed.chat, {
|
|
67
|
-
header: "✨ NozezBaileys Custom Buttons ✨",
|
|
68
|
-
text: "Halo! Ini adalah tombol interaktif native flow yang dikirim menggunakan standard `sendMessage` pada library buatan Anda sendiri!",
|
|
69
|
-
footer: "Mudah, ringkas, dan sangat optimal.",
|
|
70
|
-
buttons: [
|
|
71
|
-
{ type: 'reply', displayText: '🎯 Pilihan Pertama', id: 'pilihan_1' },
|
|
72
|
-
{ type: 'url', displayText: '🌐 Kunjungi Website', url: 'https://github.com' },
|
|
73
|
-
{ type: 'copy', displayText: '📋 Salin Kode Promo', code: 'NOZEZ2026' }
|
|
74
|
-
]
|
|
75
|
-
}, { quoted: m });
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// 8. SUPPORTS SENDING DROPDOWN SUB-MENUS DIRECTLY VIA standard 'sendMessage'!
|
|
79
|
-
if (body === '.testlist') {
|
|
80
|
-
await sock.sendMessage(parsed.chat, {
|
|
81
|
-
// To send an image header, simply pass a valid image buffer, stream, or URL!
|
|
82
|
-
image: { url: "https://raw.githubusercontent.com/WhiskeySockets/Baileys/master/assets/logo.png" },
|
|
83
|
-
header: "🖼️ Buttons dengan Gambar",
|
|
84
|
-
text: "Pilih aksi atau buka daftar pilihan:\n\n_Contoh buttons dengan header image & native flow list_",
|
|
85
|
-
footer: "CHATBOT ASSISTANCE v1 BY NOZEZ ⚡",
|
|
86
|
-
buttonText: "📋 Pilih Menu",
|
|
87
|
-
sections: [
|
|
88
|
-
{
|
|
89
|
-
title: "🌐 General",
|
|
90
|
-
rows: [
|
|
91
|
-
{ title: "🔍 Ping Bot", description: "Cek status dan latensi bot", id: "ping" },
|
|
92
|
-
{ title: "📋 Menu Lengkap", description: "Lihat semua perintah yang tersedia", id: "menu" }
|
|
93
|
-
]
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
title: "👑 Owner",
|
|
97
|
-
rows: [
|
|
98
|
-
{ title: "📡 Broadcast", description: "Kirim pesan ke semua user", id: "bc", highlight_label: "🔥 Eksklusif" }
|
|
99
|
-
]
|
|
100
|
-
}
|
|
101
|
-
]
|
|
102
|
-
}, { quoted: m });
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// 9. SUPPORTS INTERCEPTING BUTTON & SUBMENU DROPDOWN CLICKS NATIVELY!
|
|
106
|
-
if (body === 'pilihan_1') {
|
|
107
|
-
await parsed.reply("✅ Anda berhasil mengklik *Pilihan Pertama*!");
|
|
108
|
-
}
|
|
109
|
-
if (body === 'ping') {
|
|
110
|
-
await parsed.reply("⚡ *Ping Bot Terpilih!* Status bot Anda aktif dan sangat responsif.");
|
|
111
|
-
}
|
|
112
|
-
if (body === 'menu') {
|
|
113
|
-
await parsed.reply("📋 *Menu Lengkap Terpilih!* Membuka seluruh daftar fitur bot.");
|
|
114
|
-
}
|
|
115
|
-
if (body === 'bc') {
|
|
116
|
-
await parsed.reply("📡 *Broadcast Terpilih!* Fitur eksklusif ini dipicu karena Anda mengklik tombol berlabel lencana.");
|
|
117
|
-
}
|
|
118
|
-
});
|
|
4
|
+
try {
|
|
5
|
+
console.log("Testing @nozezlab/baileys compilation...");
|
|
6
|
+
assert.ok(typeof makeWASocket === 'function', "makeWASocket should be a function");
|
|
7
|
+
console.log("✅ Custom wrapper compilation successfully verified!");
|
|
8
|
+
} catch (e) {
|
|
9
|
+
console.error("❌ Test failed:", e.message);
|
|
10
|
+
process.exit(1);
|
|
119
11
|
}
|
|
120
|
-
|
|
121
|
-
// Start execution
|
|
122
|
-
startBot().catch(console.error);
|