@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.
Files changed (5) hide show
  1. package/README.md +125 -0
  2. package/index.d.ts +80 -0
  3. package/index.js +100 -39
  4. package/package.json +8 -4
  5. 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
- * NozezBaileys - Custom WhatsApp Baileys Library Wrapper
3
- * Acts as a drop-in replacement for '@whiskeysockets/baileys' with native button, image headers, list badges & pairing code.
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
- } else if (btn.type === 'url') {
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
- } else if (btn.type === 'copy') {
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
- return btn;
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: mediaOptions.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
- return await sock.relayMessage(jid, msg, { quoted });
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: mediaOptions.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
- return await sock.relayMessage(jid, msg, { quoted });
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 the standard sendMessage function to support native buttons & lists!
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 } // Pass the image header parameter
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 } // Pass the image header parameter
219
+ { image: content.image }
173
220
  );
174
221
  }
175
222
 
176
- // Pass through to original sendMessage for standard texts, images, etc.
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
- m.body = (m.type === 'conversation') ? m.message.conversation :
198
- (m.type === 'extendedTextMessage') ? m.message.extendedTextMessage.text :
199
- (m.type === 'imageMessage') ? m.message.imageMessage.caption :
200
- (m.type === 'videoMessage') ? m.message.videoMessage.caption :
201
- (m.type === 'templateButtonReplyMessage') ? m.message.templateButtonReplyMessage.selectedId :
202
- (m.type === 'buttonsResponseMessage') ? m.message.buttonsResponseMessage.selectedButtonId :
203
- (m.type === 'interactiveResponseMessage') ? JSON.parse(m.message.interactiveResponseMessage.nativeFlowResponseMessage.paramsJson).id :
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: (quotedMsg.conversation) ? quotedMsg.conversation :
215
- (quotedMsg.extendedTextMessage?.text) ? quotedMsg.extendedTextMessage.text : ""
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 requester
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 connected
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(` 🔑 WHATSAPP PAIRING CODE: ${code} `));
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 the WebSocket connection is open and ready
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
- // Export everything from WhiskeySockets Baileys so this works as a drop-in replacement!
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.0.0",
4
- "description": "Customized WhatsApp Baileys library supporting native buttons, single select submenus, and simplified pairing code connections",
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
- "nozezbaileys"
17
+ "nozezlab",
18
+ "wa-bot"
15
19
  ],
16
- "author": "Nozez",
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
- * test.js - Demo / Testing Script for NozezBaileys Custom Library
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
- // 1. Import your own customized Baileys!
7
- const { default: makeWASocket, useMultiFileAuthState, DisconnectReason } = require('./index');
8
- const pino = require('pino');
9
- const path = require('path');
10
-
11
- async function startBot() {
12
- console.log("🚀 Starting connection using custom NozezBaileys library...\n");
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);