@nexustechpro/baileys 1.1.0 → 1.1.2

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 CHANGED
@@ -733,6 +733,42 @@ await sock.sendMessage(jid, {
733
733
  })
734
734
  ```
735
735
 
736
+ #### Pin Message
737
+ ```javascript
738
+ await sock.sendMessage(jid, {
739
+ pin: {
740
+ type: 1, // 0 to remove
741
+ time: 86400, // 24 hours in seconds
742
+ key: message.key
743
+ }
744
+ })
745
+ ```
746
+
747
+ **Pin Time Options:**
748
+
749
+ | Time | Seconds |
750
+ |------|-----------|
751
+ | 24h | 86,400 |
752
+ | 7d | 604,800 |
753
+ | 30d | 2,592,000 |
754
+
755
+ #### Keep Message
756
+ ```javascript
757
+ await sock.sendMessage(jid, {
758
+ keep: message.key,
759
+ type: 1, // 2 to unpin
760
+ time: 86400
761
+ })
762
+ ```
763
+
764
+ **Keep Time Options:**
765
+
766
+ | Time | Seconds |
767
+ |------|-----------|
768
+ | 24h | 86,400 |
769
+ | 7d | 604,800 |
770
+ | 30d | 2,592,000 |
771
+
736
772
  #### Poll Message
737
773
  ```javascript
738
774
  await sock.sendMessage(jid, {
@@ -1337,51 +1373,6 @@ await sock.chatModify({ pin: true }, jid)
1337
1373
  await sock.chatModify({ pin: false }, jid)
1338
1374
  ```
1339
1375
 
1340
-
1341
- #### Pin Message
1342
- ```javascript
1343
- // Method 1: Using boolean (requires quoted message)
1344
- await sock.sendMessage(jid, { pin: true }, { quoted: message })
1345
-
1346
- // Method 2: Using pin object with message key
1347
- await sock.sendMessage(jid, {
1348
- pin: {
1349
- key: message.key // or stanzaId, id, etc.
1350
- }
1351
- })
1352
-
1353
- // Unpin message
1354
- await sock.sendMessage(jid, {
1355
- pin: {
1356
- key: message.key,
1357
- unpin: true
1358
- }
1359
- })
1360
-
1361
- // Alternative unpin syntax
1362
- await sock.sendMessage(jid, { pin: false }, { quoted: message })
1363
- ```
1364
-
1365
- #### Keep Message
1366
- ```javascript
1367
- await sock.sendMessage(jid, {
1368
- keep: message.key,
1369
- type: 1 // 1 to keep, 2 to unkeep
1370
- })
1371
- ```
1372
-
1373
- **Pin/Keep Details:**
1374
-
1375
- | Operation | Method | Syntax |
1376
- |-----------|--------|--------|
1377
- | Pin (quoted) | Boolean | `{ pin: true }` with `{ quoted: message }` |
1378
- | Pin (object) | Object | `{ pin: { key: message.key } }` |
1379
- | Unpin (quoted) | Boolean | `{ pin: false }` with `{ quoted: message }` |
1380
- | Unpin (object) | Object | `{ pin: { key: message.key, unpin: true } }` |
1381
- | Keep | Key | `{ keep: message.key, type: 1 }` |
1382
- | Unkeep | Key | `{ keep: message.key, type: 2 }` |
1383
-
1384
-
1385
1376
  ### Delete Chat
1386
1377
  ```javascript
1387
1378
  const lastMsg = await getLastMessageInChat(jid)
@@ -9,6 +9,7 @@ export const CALL_VIDEO_PREFIX = 'https://call.whatsapp.com/video/';
9
9
  export const CALL_AUDIO_PREFIX = 'https://call.whatsapp.com/voice/';
10
10
  export const DEF_CALLBACK_PREFIX = 'CB:';
11
11
  export const DEF_TAG_PREFIX = 'TAG:';
12
+ export const BATCH_SIZE = 500; // Maximum items to keep in batch storage
12
13
  export const PHONE_CONNECTION_CB = 'CB:Pong';
13
14
  export const WA_ADV_ACCOUNT_SIG_PREFIX = Buffer.from([6, 0]);
14
15
  export const WA_ADV_DEVICE_SIG_PREFIX = Buffer.from([6, 1]);
@@ -38,7 +39,7 @@ export const DEFAULT_CONNECTION_CONFIG = {
38
39
  version: version,
39
40
  browser: Browsers.macOS('Safari'),
40
41
  waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat',
41
- connectTimeoutMs: 20000,
42
+ connectTimeoutMs: 600000, // 10 minutes - allow massive messages to encode/send
42
43
  keepAliveIntervalMs: 30000,
43
44
  logger: logger.child({ class: 'baileys' }),
44
45
  emitOwnEvents: true,
@@ -97,7 +97,8 @@ export class WebSocketClient extends AbstractSocketClient {
97
97
  this.socket = null
98
98
  }
99
99
  this._queue = []
100
- this._reconnectAttempts = 0
100
+ // Do NOT reset reconnect attempts here - let socket.js manage the attempt counter
101
+ // this._reconnectAttempts = 0
101
102
  this._reconnectDelay = 1000
102
103
  this._isManualClose = false
103
104
  this._shouldReconnect = true
@@ -5,7 +5,7 @@ import { promisify } from "util"
5
5
  import { proto } from "../../WAProto/index.js"
6
6
  import {
7
7
  DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, INITIAL_PREKEY_COUNT, MIN_PREKEY_COUNT,
8
- MIN_UPLOAD_INTERVAL, NOISE_WA_HEADER, UPLOAD_TIMEOUT
8
+ MIN_UPLOAD_INTERVAL, NOISE_WA_HEADER, UPLOAD_TIMEOUT, BATCH_SIZE
9
9
  } from "../Defaults/index.js"
10
10
  import { DisconnectReason } from "../Types/index.js"
11
11
  import {
@@ -448,54 +448,6 @@ export const makeSocket = (config) => {
448
448
  }
449
449
  }
450
450
 
451
- // Cleanup device-list batch to keep only 500 recent entries
452
- const cleanupDeviceListFiles = async () => {
453
- try {
454
- logger.info("Starting device-list cleanup...")
455
- const batchData = await keys.get("device-list", ["_index"])
456
- const deviceListBatch = batchData?.['_index'] || {}
457
- const batchSize = Object.keys(deviceListBatch).length
458
-
459
- if (batchSize > 500) {
460
- logger.info(`Device-list batch size is ${batchSize}, trimming to 500 most recent`)
461
- const userKeys = Object.keys(deviceListBatch).sort()
462
- const recentUsers = userKeys.slice(-500)
463
- const trimmedBatch = {}
464
- recentUsers.forEach(userId => {
465
- trimmedBatch[userId] = deviceListBatch[userId]
466
- })
467
- await keys.set({ "device-list": { "_index": trimmedBatch } })
468
- const deleted = batchSize - Object.keys(trimmedBatch).length
469
- logger.info(`✅ Trimmed device-list batch: removed ${deleted} old entries (kept 500)`)
470
- } else {
471
- logger.debug(`Device-list batch size (${batchSize}) is healthy, no cleanup needed`)
472
- }
473
- logger.info("Device-list cleanup complete")
474
- } catch (error) {
475
- logger.error({ error }, "Device-list cleanup failed")
476
- }
477
- }
478
-
479
- // Start device-list cleanup interval (every 10 minutes)
480
- const startDeviceListCleanup = () => {
481
- if (deviceListCleanupInterval) clearInterval(deviceListCleanupInterval)
482
- deviceListCleanupInterval = setInterval(() => {
483
- cleanupDeviceListFiles().catch(err =>
484
- logger.error({ err }, "Scheduled device-list cleanup failed")
485
- )
486
- }, 10 * 60 * 1000)
487
- logger.info("Started device-list cleanup (every 10 minutes)")
488
- }
489
-
490
- // Stop device-list cleanup
491
- const stopDeviceListCleanup = () => {
492
- if (deviceListCleanupInterval) {
493
- clearInterval(deviceListCleanupInterval)
494
- deviceListCleanupInterval = null
495
- logger.debug("Stopped device-list cleanup")
496
- }
497
- }
498
-
499
451
  // Cleanup session batch to keep only 1000 recent entries
500
452
  const cleanupSessionFiles = async () => {
501
453
  try {
@@ -587,7 +539,6 @@ export const makeSocket = (config) => {
587
539
  clearInterval(sessionHealthCheck)
588
540
  clearTimeout(qrTimer)
589
541
  stopPreKeyBackgroundMonitor()
590
- stopDeviceListCleanup()
591
542
  stopSessionCleanup()
592
543
 
593
544
  ws.removeAllListeners("close")
@@ -790,6 +741,13 @@ export const makeSocket = (config) => {
790
741
  } else {
791
742
  logger.warn(errorDetails, "WebSocket error occurred")
792
743
  }
744
+
745
+ // Trigger reconnection on critical errors
746
+ if (isNetworkError && !closed) {
747
+ attemptReconnection("websocket-error").catch(err => {
748
+ logger.error({ err }, "Reconnection attempt failed after WebSocket error")
749
+ })
750
+ }
793
751
  })
794
752
 
795
753
  ws.on("close", (code, reason) => {
@@ -864,7 +822,6 @@ export const makeSocket = (config) => {
864
822
  clearTimeout(qrTimer)
865
823
  triggerPreKeyCheck("connection-established", "high")
866
824
  startPreKeyBackgroundMonitor()
867
- startDeviceListCleanup()
868
825
  startSessionCleanup()
869
826
  ev.emit("creds.update", { me: { ...authState.creds.me, lid: node.attrs.lid } })
870
827
  ev.emit("connection.update", { connection: "open" })
@@ -882,6 +839,17 @@ export const makeSocket = (config) => {
882
839
  const existingData = await authState.keys.get("device-list", ["_index"])
883
840
  const currentBatch = existingData?.['_index'] || {}
884
841
  currentBatch[user] = [device?.toString() || "0"]
842
+
843
+ // Enforce batch size limit with cleanup of old entries
844
+ const deviceKeys = Object.keys(currentBatch).filter(k => k !== '_index')
845
+ if (deviceKeys.length > BATCH_SIZE) {
846
+ // Sort and remove oldest entries (keep most recent)
847
+ deviceKeys.sort()
848
+ const toRemove = deviceKeys.slice(0, deviceKeys.length - BATCH_SIZE)
849
+ toRemove.forEach(k => delete currentBatch[k])
850
+ logger.debug(`Cleaned up ${toRemove.length} old device-list entries (kept ${BATCH_SIZE})`)
851
+ }
852
+
885
853
  await authState.keys.set({ "device-list": { "_index": currentBatch } })
886
854
  await signalRepository.migrateSession(myPN, myLID)
887
855
  logger.info({ myPN, myLID }, "Own LID session created successfully")
@@ -15,6 +15,11 @@ import {
15
15
  } from "../WABinary/index.js"
16
16
  import { unpadRandomMax16 } from "./generics.js"
17
17
  export const getDecryptionJid = async (sender, repository, logger) => {
18
+ // Skip LID mapping for newsletters, status broadcasts, and meta AI - they don't use it
19
+ if (isJidNewsletter(sender) || isJidStatusBroadcast(sender) || isJidMetaAI(sender)) {
20
+ return sender
21
+ }
22
+
18
23
  if (isLidUser(sender) || isHostedLidUser(sender)) {
19
24
  return sender
20
25
  }
@@ -144,7 +144,7 @@ export const generateMessageIDV2 = (userId) => {
144
144
  return '3EB0' + hash.toString('hex').toUpperCase().substring(0, 18);
145
145
  };
146
146
  // generate a random ID to attach to a message
147
- export const generateMessageID = () => '3EB0' + randomBytes(18).toString('hex').toUpperCase();
147
+ export const generateMessageID = () => 'NEXUSTECHPRO-' + randomBytes(6).toString('hex').toUpperCase();
148
148
  export function bindWaitForEvent(ev, event) {
149
149
  return async (check, timeoutMs) => {
150
150
  let listener;
package/lib/index.js CHANGED
@@ -31,7 +31,7 @@ const banner = `
31
31
  const info = `
32
32
  ┌───────────────────────────────────────────────────────────────────────┐
33
33
  │ 📦 Package: @nexustechpro/baileys │
34
- │ 🔖 Version: 1.1.0
34
+ │ 🔖 Version: 1.1.2
35
35
  │ ⚡ Status: Production Ready │
36
36
  ├───────────────────────────────────────────────────────────────────────┤
37
37
  │ 🚀 Advanced WhatsApp Web API Client │
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nexustechpro/baileys",
3
3
  "type": "module",
4
- "version": "1.1.0",
4
+ "version": "1.1.2",
5
5
  "description": "Advanced WhatsApp Web API client with interactive messages, product catalogs, carousels, events, payments, and polls.",
6
6
  "keywords": [
7
7
  "whatsapp",