@znan/wabot 0.2.0-beta.0 → 0.2.0-beta.4

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 (43) hide show
  1. package/.github/workflows/publish.yaml +35 -0
  2. package/README.md +596 -93
  3. package/lib/database/index.js +1 -80
  4. package/lib/database/local.js +1 -1
  5. package/lib/database/mongo.js +1 -1
  6. package/lib/database/mysql.js +1 -1
  7. package/lib/database/postgre.js +1 -1
  8. package/lib/database/sqlite.js +1 -1
  9. package/lib/socket/connection.js +1 -1
  10. package/lib/socket/connection.js.map +1 -1
  11. package/lib/socket/events/call.js +1 -1
  12. package/lib/socket/events/chats.update.js +1 -1
  13. package/lib/socket/events/contacts.update.js +1 -1
  14. package/lib/socket/events/group-participants.update.js +1 -1
  15. package/lib/socket/events/group.join-request.js +1 -1
  16. package/lib/socket/events/groups.update.js +1 -1
  17. package/lib/socket/events/index.js +1 -33
  18. package/lib/socket/events/lid-mapping.update.js +1 -1
  19. package/lib/socket/events/message-receipt.update.js +1 -1
  20. package/lib/socket/events/messages.reaction.js +1 -1
  21. package/lib/socket/events/messages.update.js +1 -1
  22. package/lib/socket/events/messages.upsert.js +1 -1
  23. package/lib/socket/events/presence.update.js +1 -1
  24. package/lib/socket/message.js +1 -1
  25. package/lib/socket/serialize.js +1 -1
  26. package/lib/socket/serialize.js.map +1 -1
  27. package/lib/socket/store.js +1 -1
  28. package/lib/socket/store.js.map +1 -1
  29. package/lib/system/converter.js +1 -1
  30. package/lib/system/exif.js +1 -1
  31. package/lib/system/function.js +1 -1
  32. package/lib/system/scraper.js +1 -1
  33. package/lib/utils/cache.js +1 -1
  34. package/lib/utils/cooldown.js +1 -1
  35. package/lib/utils/getcommand.js +1 -1
  36. package/lib/utils/logger.js +1 -1
  37. package/lib/utils/parsecommand.js +1 -1
  38. package/lib/utils/plugins.js +1 -1
  39. package/lib/utils/session.js +1 -1
  40. package/lib/utils/spam.js +1 -1
  41. package/package.json +1 -1
  42. package/lib/socket/builder.js +0 -1
  43. package/lib/socket/builder.js.map +0 -1
package/README.md CHANGED
@@ -1,138 +1,641 @@
1
- # @ZNAN/WABOT - Baileys WhatsApp Bot Module
1
+ # @znan/wabot
2
2
 
3
3
  [![NPM Version](https://img.shields.io/npm/v/@znan/wabot?color=blue&style=flat-square)](https://www.npmjs.com/package/@znan/wabot)
4
4
  [![NPM Downloads](https://img.shields.io/npm/dt/@znan/wabot?color=blue&style=flat-square)](https://www.npmjs.com/package/@znan/wabot)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
 
7
- ## ℹ️ Introduction
7
+ Socket-based WhatsApp bot module built on [@whiskeysockets/baileys](https://github.com/WhiskeySockets/Baileys) v7. Handles LID migration, session management, and event processing out of the box.
8
8
 
9
- Welcome to **@ZNAN/WABOT**! This module, built upon the robust **Baileys** library, offers a streamlined, elegant, and easy-to-understand approach to developing your own WhatsApp bots. It's designed for developers seeking an efficient way to build and deploy WhatsApp bot scripts.
10
-
11
- ## ✨ Key Features
12
-
13
- * **Simplified Baileys Integration**: Leverage the power of Baileys with a more user-friendly interface.
14
- * **Flexible Configuration**: Extensive options to tailor your bot's behavior.
15
- * **Efficient Session Management**: Robust handling of connection sessions.
16
- * **Comprehensive Event Handling**: Supports various Baileys events for bot responsiveness.
17
- * **Developer-Centric Design**: Built with ease of use and learning in mind.
9
+ ---
18
10
 
19
- ## 🔰 Installation
11
+ ## Table of Contents
12
+
13
+ - [Installation](#installation)
14
+ - [Quick Start](#quick-start)
15
+ - [Connection](#connection)
16
+ - [Events](#events)
17
+ - [Custom Events](#custom-events)
18
+ - [Raw Events](#raw-events)
19
+ - [Payload Details](#payload-details)
20
+ - [Plugin System](#plugin-system)
21
+ - [Session Management](#session-management)
22
+ - [Database](#database)
23
+ - [Migration Guide](#migration-guide)
24
+ - [Error Handling](#error-handling)
25
+ - [Advanced Examples](#advanced-examples)
26
+ - [License](#license)
20
27
 
21
- Install the module using npm or yarn:
28
+ ---
22
29
 
23
- **Using npm:**
30
+ ## Installation
24
31
 
25
32
  ```bash
26
33
  npm install @znan/wabot
27
34
  ```
28
35
 
29
- **Using yarn:**
36
+ ---
37
+
38
+ ## Quick Start
30
39
 
31
- ```bash
32
- yarn add @znan/wabot
40
+ ```javascript
41
+ const { Connection } = require('@znan/wabot')
42
+
43
+ const conn = new Connection({
44
+ plugins_dir: 'plugins',
45
+ session_dir: './session',
46
+ online: true,
47
+ presence: true,
48
+ bypass_ephemeral: true,
49
+ })
50
+
51
+ conn.on('connect', x => console.log(x.message))
52
+ conn.on('prepare', x => console.log(x.message))
53
+ conn.on('error', x => console.error(x.message))
54
+ ```
55
+
56
+ ---
57
+
58
+ ## Connection
59
+
60
+ ### Constructor
61
+
62
+ ```javascript
63
+ new Connection(options, extra?)
64
+ ```
65
+
66
+ ### Options
67
+
68
+ | Option | Type | Default | Description |
69
+ |---|---|---|---|
70
+ | `plugins_dir` | `string` | `'plugins'` | Plugin directory path |
71
+ | `session_dir` | `string` | `'./session'` | Session storage path |
72
+ | `online` | `boolean` | `false` | Maintain online presence |
73
+ | `presence` | `boolean` | `false` | Emit presence updates |
74
+ | `bypass_ephemeral` | `boolean` | `false` | Ignore ephemeral message settings |
75
+ | `pairing.state` | `boolean` | `false` | Enable pairing code mode (instead of QR) |
76
+ | `pairing.number` | `string` | `''` | Phone number for pairing code |
77
+ | `pairing.code` | `string` | `''` | Custom 8-character pairing code |
78
+
79
+ ### Extra Options
80
+
81
+ Passed directly to Baileys `makeWASocket`. Common options:
82
+
83
+ ```javascript
84
+ const conn = new Connection(options, {
85
+ browser: ['Ubuntu', 'Firefox', '20.0.00'],
86
+ version: [2, 3000, 1029030078], // Baileys version override
87
+ shouldIgnoreJid: jid => /(newsletter|bot)/.test(jid), // Ignore specific JIDs
88
+ getMessage: async key => { /* custom message retrieval */ },
89
+ groupMetadata: async jid => { /* custom group cache */ },
90
+ // ... any Baileys SocketConfig option
91
+ })
33
92
  ```
34
93
 
35
- ## 🔌 Connection
94
+ ---
95
+
96
+ ## Events
36
97
 
37
- Here's an example of how to initialize your bot connection:
98
+ Events are split into two categories: **Custom Events** (processed, LID-resolved) and **Raw Events** (passthrough from Baileys with `baileys:` prefix).
99
+
100
+ ### Custom Events
101
+
102
+ #### Connection Lifecycle
103
+
104
+ | Event | Listener Count | Description |
105
+ |---|---|---|
106
+ | `connect` | `on` | Fires on every connection attempt (includes reconnects) |
107
+ | `prepare` | `once` | Bot is ready — session loaded, plugins watching |
108
+ | `error` | `on` | Connection or runtime error |
38
109
 
39
110
  ```javascript
40
- // Import the module
41
- const { Connection } = require('@znan/wabot'); // or import { Connection } from '@znan/wabot';
111
+ conn.on('connect', ({ display, message }) => console.log(display, message))
112
+ conn.on('prepare', ({ display, message }) => {
113
+ console.log(display, message)
114
+ // Bot is ready — start your services here
115
+ })
116
+ conn.on('error', ({ display, message }) => console.error(display, message))
117
+ ```
118
+
119
+ #### Messages
42
120
 
43
- // Initialize connection with options
44
- const Conn = new Connection({
45
- plugins_dir: 'plugins', // Directory for your bot plugins
46
- session_dir: 'session', // Directory for session data
47
- online: true, // Set bot presence to online
48
- presence: true, // Send presence updates
49
- bypass_ephemeral: true, // Bypass ephemeral messages (if supported)
50
- pairing: {
51
- state: true, // Enable pairing mode (QR code scan)
52
- number: 6283175395970, // Your phone number (optional, for automatic pairing)
53
- code: 'MOONXBOT' // Unique code for your session (optional)
121
+ | Event | Description |
122
+ |---|---|
123
+ | `import` | Message received, serialized, and parsed (includes command parsing) |
124
+ | `poll` | Poll vote detected and decrypted |
125
+ | `stories` | Status broadcast received |
126
+ | `messages.update` | Raw message update (emit passthrough) |
127
+ | `message.delete` | Message deleted or revoked |
128
+ | `message.receipt` | Message receipt update (read status) |
129
+
130
+ ```javascript
131
+ conn.on('import', x => {
132
+ // x.m — serialized message with sender, body, command, args, etc.
133
+ // x.isCommand — boolean if message matches prefix
134
+ // x.command — command name (e.g. 'menu', 'help')
135
+ // x.args — array of arguments
136
+ // x.text — full text after command
137
+ // x.prefix — detected prefix
138
+ // x.prefixes — all active prefixes
139
+ // x.store — global store reference
140
+ if (x.isCommand) {
141
+ console.log(`Command: ${x.command} from ${x.m.sender}`)
142
+ }
143
+ })
144
+
145
+ conn.on('poll', x => {
146
+ console.log(`Poll vote: ${x.selected} by ${x.sender}`)
147
+ })
148
+
149
+ conn.on('message.delete', x => {
150
+ if (x) console.log(`Message deleted in ${x.jid}`)
151
+ })
152
+ ```
153
+
154
+ #### Groups
155
+
156
+ | Event | Description |
157
+ |---|---|
158
+ | `group.add` | Participant added to group |
159
+ | `group.remove` | Participant removed from group |
160
+ | `group.promote` | Participant promoted to admin |
161
+ | `group.demote` | Participant demoted from admin |
162
+ | `group.subject` | Group name changed |
163
+ | `group.desc` | Group description changed |
164
+ | `group.announce` | Group opened or closed |
165
+ | `group.restrict` | Edit info permission changed |
166
+ | `group.memberAddMode` | Member add mode toggled |
167
+ | `group.joinApprovalMode` | Join approval mode toggled |
168
+ | `group.request` | Join request created, approved, or rejected |
169
+ | `groups.update` | Legacy — any group metadata change |
170
+
171
+ ```javascript
172
+ conn.on('group.add', x => {
173
+ // x.jid — group ID
174
+ // x.author — who added (resolved to PN)
175
+ // x.member — who was added (resolved to PN)
176
+ // x.subject — group name
177
+ // x.groupMetadata — full group metadata
178
+ console.log(`${x.member} added to ${x.subject} by ${x.author}`)
179
+ })
180
+
181
+ conn.on('group.remove', x => {
182
+ console.log(`${x.member} removed from ${x.subject}`)
183
+ })
184
+
185
+ conn.on('group.request', x => {
186
+ if (x.action === 'created') {
187
+ console.log(`Join request from ${x.participant}`)
188
+ } else if (x.action === 'approved') {
189
+ console.log(`Request approved by ${x.author}`)
190
+ } else if (x.action === 'rejected') {
191
+ console.log(`Request rejected by ${x.author}`)
54
192
  }
55
- }, {
56
- browser: ['Ubuntu', 'Firefox', '20.0.00'], // Simulated browser info
57
- version: [2, 3000, 1029030078], // Simulated Baileys version
58
- shouldIgnoreJid: jid => { // Function to ignore specific JIDs (e.g., newsletters, other bots)
59
- return /(newsletter|bot)/.test(jid);
193
+ })
194
+ ```
195
+
196
+ #### Other
197
+
198
+ | Event | Description |
199
+ |---|---|
200
+ | `presence.update` | User presence changed (resolved to PN) |
201
+ | `call` | Incoming call event |
202
+ | `lid-mapping.update` | New LID→PN mapping received |
203
+
204
+ ```javascript
205
+ conn.on('presence.update', ({ id, presences }) => {
206
+ for (const [jid, data] of Object.entries(presences)) {
207
+ if (data.lastKnownPresence === 'composing') {
208
+ console.log(`${jid} is typing in ${id}`)
209
+ }
210
+ }
211
+ })
212
+
213
+ conn.on('call', async calls => {
214
+ for (const call of calls) {
215
+ if (call.status === 'offer') {
216
+ await conn.sock.rejectCall(call.id, call.from)
217
+ }
218
+ }
219
+ })
220
+ ```
221
+
222
+ ### Raw Events
223
+
224
+ All Baileys native events are forwarded with `baileys:` prefix. This gives you access to every event Baileys emits, even ones not covered by custom events:
225
+
226
+ ```javascript
227
+ conn.on('baileys:connection.update', state => { ... })
228
+ conn.on('baileys:messaging-history.set', data => { ... })
229
+ conn.on('baileys:messaging-history.status', status => { ... })
230
+ conn.on('baileys:chats.upsert', chats => { ... })
231
+ conn.on('baileys:chats.update', updates => { ... })
232
+ conn.on('baileys:chats.delete', ids => { ... })
233
+ conn.on('baileys:chats.lock', data => { ... })
234
+ conn.on('baileys:contacts.upsert', contacts => { ... })
235
+ conn.on('baileys:contacts.update', updates => { ... })
236
+ conn.on('baileys:messages.upsert', data => { ... })
237
+ conn.on('baileys:messages.update', updates => { ... })
238
+ conn.on('baileys:messages.delete', data => { ... })
239
+ conn.on('baileys:messages.media-update', updates => { ... })
240
+ conn.on('baileys:messages.reaction', reactions => { ... })
241
+ conn.on('baileys:message-receipt.update', receipts => { ... })
242
+ conn.on('baileys:groups.upsert', groups => { ... })
243
+ conn.on('baileys:groups.update', updates => { ... })
244
+ conn.on('baileys:group-participants.update', update => { ... })
245
+ conn.on('baileys:group.join-request', request => { ... })
246
+ conn.on('baileys:group.member-tag.update', update => { ... })
247
+ conn.on('baileys:blocklist.set', data => { ... })
248
+ conn.on('baileys:blocklist.update', data => { ... })
249
+ conn.on('baileys:labels.edit', label => { ... })
250
+ conn.on('baileys:labels.association', data => { ... })
251
+ conn.on('baileys:newsletter.reaction', data => { ... })
252
+ conn.on('baileys:newsletter.view', data => { ... })
253
+ conn.on('baileys:newsletter-participants.update', data => { ... })
254
+ conn.on('baileys:newsletter-settings.update', data => { ... })
255
+ conn.on('baileys:message-capping.update', data => { ... })
256
+ conn.on('baileys:settings.update', data => { ... })
257
+ ```
258
+
259
+ Events **not** forwarded as raw (managed internally):
260
+ - `connection.update` — handled by connection lifecycle
261
+ - `creds.update` — handled by session persistence
262
+ - `contacts.upsert` — handled by contact store
263
+
264
+ ### Payload Details
265
+
266
+ #### `import` — Full Message Object
267
+
268
+ After serialization, `x.m` includes:
269
+
270
+ | Property | Type | Description |
271
+ |---|---|---|
272
+ | `m.id` | `string` | Unique message ID |
273
+ | `m.chat` | `string` | Chat JID |
274
+ | `m.sender` | `string` | Sender JID (resolved to PN) |
275
+ | `m.fromMe` | `boolean` | Sent by self |
276
+ | `m.isGroup` | `boolean` | Is group chat |
277
+ | `m.mtype` | `string` | Message type (e.g. `extendedTextMessage`, `imageMessage`) |
278
+ | `m.msg` | `object` | Message content (text, caption, media metadata) |
279
+ | `m.text` | `string` | Extracted text content |
280
+ | `m.mentionedJid` | `string[]` | Mentioned JIDs (resolved to PN) |
281
+ | `m.isMedia` | `boolean` | Has media attachment |
282
+ | `m.isBot` | `boolean` | Sent by bot |
283
+ | `m.device` | `string` | Sender device (`web`, `android`, `ios`, `desktop`) |
284
+ | `m.quoted` | `object` | Quoted/replied message (if any) |
285
+ | `m.quoted.sender` | `string` | Quoted sender (resolved to PN) |
286
+ | `m.quoted.mentionedJid` | `string[]` | Quoted mentions (resolved to PN) |
287
+ | `m.key` | `object` | Raw Baileys message key |
288
+ | `m.reply(text, opts?)` | `function` | Quick reply helper |
289
+ | `m.react(emoji, key?)` | `function` | Quick reaction helper |
290
+ | `m.download()` | `function` | Download media |
291
+
292
+ #### `group.*` — Group Events
293
+
294
+ ```javascript
295
+ conn.on('group.add', {
296
+ action: 'add', // 'add' | 'remove' | 'promote' | 'demote'
297
+ jid: '...@g.us', // Group JID
298
+ author: '...@s.whatsapp.net', // Who performed the action (resolved)
299
+ subject: 'Group Name', // Group subject
300
+ member: '...@s.whatsapp.net', // Target member (resolved)
301
+ groupMetadata: { ... } // Full GroupMetadata object
302
+ })
303
+ ```
304
+
305
+ #### `group.request`
306
+
307
+ ```javascript
308
+ conn.on('group.request', {
309
+ id: '...@g.us',
310
+ author: '...@s.whatsapp.net', // Admin who approved/rejected (null on 'created')
311
+ participant: '...@s.whatsapp.net', // User who requested
312
+ action: 'created', // 'created' | 'approved' | 'rejected'
313
+ method: 'invite_link' // Request method
314
+ })
315
+ ```
316
+
317
+ ---
318
+
319
+ ## Plugin System
320
+
321
+ ### Structure
322
+
323
+ ```
324
+ plugins/
325
+ ├── menu.js
326
+ ├── group.js
327
+ ├── owner/
328
+ │ ├── ban.js
329
+ │ └── eval.js
330
+ └── ...
331
+ ```
332
+
333
+ ### Plugin Format
334
+
335
+ Each plugin file exports an object:
336
+
337
+ ```javascript
338
+ module.exports = {
339
+ command: 'menu',
340
+ alias: ['help', 'h'],
341
+ category: 'main',
342
+ description: 'Show bot menu',
343
+ loading: true,
344
+ async run(m, { sock, Func, config, db, plugins }) {
345
+ // m — serialized message
346
+ // sock — Baileys socket
347
+ // Func — utility functions
348
+ // config — environment config
349
+ // db — global database
350
+ // plugins — all loaded plugins
351
+ m.reply('Hello from menu plugin!')
352
+ }
353
+ }
354
+ ```
355
+
356
+ ### Plugin Properties
357
+
358
+ | Property | Type | Default | Description |
359
+ |---|---|---|---|
360
+ | `command` | `string` | required | Command name (without prefix) |
361
+ | `alias` | `string[]` | `[]` | Alternative names |
362
+ | `category` | `string` | `'main'` | Grouping category |
363
+ | `description` | `string` | `''` | Help text |
364
+ | `loading` | `boolean` | `true` | Show typing indicator |
365
+ | `run` | `function` | required | Command handler |
366
+
367
+ ### Event Plugins
368
+
369
+ ```javascript
370
+ module.exports = {
371
+ command: 'antilink',
372
+ event: 'group.add', // Listen to a custom event instead of commands
373
+ async run(x, { sock, db }) {
374
+ // x — event payload
375
+ // Runs automatically when 'group.add' fires
60
376
  }
61
- });
377
+ }
62
378
  ```
63
379
 
64
- ## 💡 Usage (Event Handling)
380
+ ---
381
+
382
+ ## Session Management
65
383
 
66
- Once connected, you can listen for various events. Here's a sample of common event handlers:
384
+ ### File-Based Session (Default)
67
385
 
68
386
  ```javascript
69
- // Handle connection event
70
- Conn.on('connect', () => {
71
- console.log('Bot connected successfully!');
72
- // Implement actions after connection, e.g., broadcast messages
73
- });
387
+ const conn = new Connection({
388
+ session_dir: './session' // Multi-file auth state stored here
389
+ })
390
+ ```
74
391
 
75
- // Handle connection errors
76
- Conn.on('error', (error) => {
77
- console.error('Connection error:', error);
78
- });
392
+ ### Custom Session Provider
79
393
 
80
- // Handle bot preparation state
81
- Conn.on('prepare', () => {
82
- console.log('Bot is preparing...');
83
- });
394
+ Pass an async object implementing the auth state interface:
84
395
 
85
- // Handle message updates (incoming/outgoing)
86
- Conn.on('messages.update', (messageUpdate) => {
87
- // console.log('Message update:', messageUpdate);
88
- // Process incoming messages here or in a dedicated handler
89
- });
396
+ ```javascript
397
+ const { Connection } = require('@znan/wabot')
398
+ const customSession = {
399
+ state: { creds: {}, keys: {} },
400
+ saveCreds: () => {},
401
+ deleteCreds: () => {},
402
+ restoreCreds: async () => {},
403
+ }
404
+
405
+ const conn = new Connection({
406
+ session_dir: customSession // Custom session provider
407
+ })
408
+ ```
90
409
 
91
- // Handle message reactions
92
- Conn.on('messages.reaction', (reaction) => {
93
- console.log('Message reaction:', reaction);
94
- });
410
+ ### Auto-Backup & Restore
95
411
 
96
- // Handle message receipts (read status)
97
- Conn.on('messages.receipt', (receipt) => {
98
- console.log('Message received:', receipt);
99
- });
412
+ Module automatically:
413
+ - Backs up session when connected
414
+ - Detects session corruption on `badSession` disconnect
415
+ - Restores from backup if available
416
+ - Reconnects with restored session
100
417
 
101
- // Handle deleted messages
102
- Conn.on('messages.delete', (deletedMessage) => {
103
- console.log('Message deleted:', deletedMessage);
104
- });
418
+ ### Session Cleanup
105
419
 
106
- // Handle presence updates
107
- Conn.on('presence.update', (presenceUpdate) => {
108
- // console.log('Presence update:', presenceUpdate);
109
- });
420
+ Auto-delete old session files (midnight cron):
110
421
 
111
- // Handle story updates (if supported)
112
- Conn.on('stories', (stories) => {
113
- console.log('Stories update:', stories);
114
- });
422
+ ```javascript
423
+ const conn = new Connection({
424
+ session_dir: './session',
425
+ // Auto-delete old data at midnight
426
+ })
427
+ ```
115
428
 
116
- // Handle group participant updates
117
- Conn.on('group-participants.update', (groupUpdate) => {
118
- console.log('Group participants updated:', groupUpdate);
119
- });
429
+ ---
430
+
431
+ ## Database
432
+
433
+ The module supports multiple database backends via `Database.create()`:
434
+
435
+ ### Supported Drivers
436
+
437
+ | Driver | Connection String |
438
+ |---|---|
439
+ | **MongoDB** | `mongodb://user:pass@host:port/db` |
440
+ | **MySQL** | `mysql://user:pass@host:port/db` |
441
+ | **PostgreSQL** | `postgresql://user:pass@host:port/db` |
442
+ | **SQLite** | File path (e.g. `./database.db`) |
443
+ | **JSON** | File path (e.g. `./database.json`) |
120
444
 
121
- // Handle group information updates
122
- Conn.on('groups.update', (groupInfoUpdate) => {
123
- console.log('Group info updated:', groupInfoUpdate);
124
- });
445
+ ### Usage
125
446
 
126
- // Handle call information
127
- Conn.on('call', (callInfo) => {
128
- console.log('Call info:', callInfo);
129
- });
447
+ ```javascript
448
+ const { Connection, Database } = require('@znan/wabot')
449
+
450
+ const start = async () => {
451
+ const db = Database.create(process.env.DATABASE_URL, {
452
+ type: 'json', // or 'mongodb', 'mysql', 'postgresql', 'sqlite'
453
+ dir: './db'
454
+ })
455
+
456
+ const conn = new Connection({
457
+ plugins_dir: 'plugins',
458
+ session_dir: db.session || './session',
459
+ })
460
+
461
+ conn.on('connect', async () => {
462
+ global.db = { users: {}, groups: {}, setting: {}, ...(await db.fetch() || {}) }
463
+ await db.save(global.db)
464
+ })
465
+
466
+ // Auto-save every 30 seconds
467
+ setInterval(() => {
468
+ if (global.db) db.save(global.db)
469
+ }, 30000)
470
+ }
130
471
  ```
131
472
 
132
- ## 📜 License
473
+ ---
474
+
475
+ ## Migration Guide
476
+
477
+ ### From v0.x to v1.x (Baileys v7 LID)
133
478
 
134
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
479
+ #### Breaking Changes
480
+
481
+ 1. **Event name changes**
482
+
483
+ | Old | New | Reason |
484
+ |---|---|---|
485
+ | `group-participants.update` | `group.add` / `.remove` / `.promote` / `.demote` | Split per action |
486
+ | `groups.update` | `group.subject` / `.desc` / `.announce` / `.restrict` / `.memberAddMode` / `.joinApprovalMode` | Split per field |
487
+ | — | `group.request` | New Baileys v7 event |
488
+ | — | `poll` | New — poll decryption added |
489
+ | — | `baileys:<event>` | Raw event forwarding (new) |
490
+
491
+ 2. **`getRealJid` is now async**
492
+
493
+ ```javascript
494
+ // Old
495
+ const jid = conn.getRealJid(lid)
496
+
497
+ // New
498
+ const jid = await conn.getRealJid(lid)
499
+ ```
500
+
501
+ 3. **`conn.user.lid`** — may be undefined in v7. Use `conn.user.id` instead.
502
+
503
+ 4. **`getUserId`** — no longer returns `lid` field:
504
+
505
+ ```javascript
506
+ // Old
507
+ const { jid, lid } = await conn.getUserId('62812...')
508
+
509
+ // New
510
+ const { jid } = await conn.getUserId('62812...')
511
+ ```
512
+
513
+ 5. **`onWhatsApp`** — no longer returns LID in results. Use `signalRepository.lidMapping.getPNForLID()` for reverse lookups.
514
+
515
+ #### What Changed Internally
516
+
517
+ - Custom XMPP node parsing for LID mapping (`CB:message` listener) removed — Baileys v7 handles this internally via `signalRepository.lidMapping`
518
+ - `lid_map` storage removed — mapping persisted in auth state automatically
519
+ - `lidMap` cache removed — group participant data already includes `phoneNumber`
520
+ - All sender/participant resolution uses Baileys built-in `Alt` fields + `getPNForLID()`
135
521
 
136
522
  ---
137
523
 
138
- *Developed with dedication by Znan.*
524
+ ## Error Handling
525
+
526
+ ### Disconnect Reasons
527
+
528
+ The module automatically handles all Baileys disconnect reasons:
529
+
530
+ | Reason | Behavior |
531
+ |---|---|
532
+ | `connectionClosed` | Auto-reconnect |
533
+ | `connectionLost` | Auto-reconnect |
534
+ | `connectionReplaced` | Exit (session active elsewhere) |
535
+ | `timedOut` | Auto-reconnect |
536
+ | `loggedOut` | Clear session, exit |
537
+ | `badSession` | Restore from backup, reconnect |
538
+ | `restartRequired` | Auto-reconnect |
539
+ | `multideviceMismatch` | Clear session, reconnect |
540
+ | `forbidden` (403) | Clear session, exit (banned) |
541
+
542
+ ### Custom Error Handling
543
+
544
+ ```javascript
545
+ conn.on('error', x => {
546
+ console.error(x.message)
547
+ // Log to file, send notification, etc.
548
+ })
549
+ ```
550
+
551
+ ### Session Corruption Recovery
552
+
553
+ When `badSession` is detected, the module:
554
+ 1. Checks for session backup
555
+ 2. Restores from backup if available
556
+ 3. Clears corrupted session
557
+ 4. Reconnects automatically
558
+
559
+ ---
560
+
561
+ ## Advanced Examples
562
+
563
+ ### AI Bot Reply
564
+
565
+ ```javascript
566
+ // Requires AI module integration
567
+ conn.on('import', async x => {
568
+ if (!x.isCommand && !x.m.fromMe) {
569
+ const reply = await generateAIResponse(x.m.text)
570
+ x.m.reply(reply)
571
+ }
572
+ })
573
+ ```
574
+
575
+ ### Anti-Delete
576
+
577
+ ```javascript
578
+ conn.on('message.delete', x => {
579
+ if (x && !x.msg.key.fromMe && !x.msg.isBot) {
580
+ const groupSet = global.db.groups[x.jid]
581
+ if (groupSet?.antidelete) {
582
+ conn.sock.copyNForward(x.jid, x.msg)
583
+ }
584
+ }
585
+ })
586
+ ```
587
+
588
+ ### Auto-React to Stories
589
+
590
+ ```javascript
591
+ conn.on('stories', x => {
592
+ conn.sock.sendMessage('status@broadcast', {
593
+ react: { text: '👍', key: x.key }
594
+ }, { statusJidList: [x.sender] })
595
+ })
596
+ ```
597
+
598
+ ### Welcome Card with Canvas
599
+
600
+ ```javascript
601
+ conn.on('group.add', async x => {
602
+ const avatar = await conn.sock.profilePictureUrl(x.member, 'image')
603
+ const card = await welcomeCard(avatar, x.member.split('@')[0], x.subject)
604
+ conn.sock.sendFile(x.jid, card, 'welcome.jpg', `Welcome @${x.member.split('@')[0]}!`, null)
605
+ })
606
+ ```
607
+
608
+ ### AFK Detection via Presence
609
+
610
+ ```javascript
611
+ conn.on('presence.update', ({ id, presences }) => {
612
+ for (const [jid, data] of Object.entries(presences)) {
613
+ if (data.lastKnownPresence === 'composing') {
614
+ const groupSet = global.db.groups[id]
615
+ const member = groupSet?.member?.[jid]
616
+ if (member && member.afk > -1) {
617
+ conn.sock.reply(id, `@${jid.split('@')[0]} back from AFK (${member.afkReason})`, null)
618
+ member.afk = -1
619
+ }
620
+ }
621
+ }
622
+ })
623
+ ```
624
+
625
+ ### Using Raw Events for Newsletter Tracking
626
+
627
+ ```javascript
628
+ conn.on('baileys:newsletter.reaction', data => {
629
+ console.log(`Newsletter ${data.id} got reaction:`, data.reaction)
630
+ })
631
+
632
+ conn.on('baileys:newsletter.view', data => {
633
+ console.log(`Newsletter ${data.id} has ${data.count} views`)
634
+ })
635
+ ```
636
+
637
+ ---
638
+
639
+ ## License
640
+
641
+ MIT