@realvare/based 2.5.5 → 2.5.7

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.
@@ -62,6 +62,21 @@ class CacheManager {
62
62
  return this.caches[cacheName]?.getStats();
63
63
  }
64
64
 
65
+ // Enhanced cleanup for bad ACK entries
66
+ on(event, callback) {
67
+ if (event === 'bad_ack') {
68
+ // Setup cleanup listener for bad ACKs
69
+ this.badAckCallback = callback;
70
+ }
71
+ }
72
+
73
+ // Method to trigger bad ACK cleanup
74
+ cleanupBadAck(key) {
75
+ if (this.badAckCallback) {
76
+ this.badAckCallback(key);
77
+ }
78
+ }
79
+
65
80
  shutdown() {
66
81
  if (this.memoryCheckInterval) {
67
82
  clearInterval(this.memoryCheckInterval);
@@ -70,4 +85,4 @@ class CacheManager {
70
85
  }
71
86
  }
72
87
 
73
- module.exports = new CacheManager();
88
+ module.exports = new CacheManager();
@@ -244,6 +244,38 @@ exports.generateForwardMessageContent = generateForwardMessageContent;
244
244
  const generateWAMessageContent = async (message, options) => {
245
245
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
246
246
  var _p, _q;
247
+
248
+ // iOS-specific externalAdReply handling
249
+ if (message.contextInfo?.externalAdReply) {
250
+ const externalAdReply = message.contextInfo.externalAdReply;
251
+
252
+ // If thumbnailUrl is provided but no thumbnail binary data, try to fetch and convert for iOS
253
+ if (externalAdReply.thumbnailUrl && !externalAdReply.thumbnail) {
254
+ try {
255
+ // Attempt to download the thumbnail image for iOS compatibility
256
+ const axiosResponse = await axios_1.default.get(externalAdReply.thumbnailUrl, {
257
+ responseType: 'arraybuffer',
258
+ timeout: 5000,
259
+ headers: {
260
+ 'User-Agent': 'WhatsApp/2.23.20.15 iOS/16.0 Device/iPhone'
261
+ }
262
+ });
263
+
264
+ if (axiosResponse.status === 200) {
265
+ externalAdReply.thumbnail = Buffer.from(axiosResponse.data);
266
+ // Clear thumbnailUrl since we now have binary data
267
+ delete externalAdReply.thumbnailUrl;
268
+ }
269
+ } catch (error) {
270
+ // If thumbnail download fails, keep thumbnailUrl as is
271
+ options.logger?.warn('Failed to download externalAdReply thumbnail for iOS:', error.message);
272
+ }
273
+ }
274
+
275
+ // Update the contextInfo with modified externalAdReply
276
+ message.contextInfo.externalAdReply = externalAdReply;
277
+ }
278
+
247
279
  let m = {};
248
280
  if ('text' in message) {
249
281
  const extContent = { text: message.text };
@@ -511,6 +543,41 @@ const generateWAMessageContent = async (message, options) => {
511
543
  else if ('newsletterMessage' in message) {
512
544
  m.newsletterMessage = Types_1.WAProto.Message.NewsletterMessage.fromObject(message.newsletterMessage);
513
545
  }
546
+ else if ('externalAdReply' in message) {
547
+ // Handle sendNyanCat functionality - external ad reply
548
+ const extAdReply = message.externalAdReply;
549
+ m.extendedTextMessage = {
550
+ text: message.text || '',
551
+ contextInfo: {
552
+ externalAdReply: {
553
+ title: extAdReply.title,
554
+ body: extAdReply.body,
555
+ mediaType: extAdReply.mediaType || 1,
556
+ thumbnailUrl: extAdReply.thumbnailUrl,
557
+ thumbnail: extAdReply.thumbnail,
558
+ sourceUrl: extAdReply.sourceUrl,
559
+ showAdAttribution: extAdReply.showAdAttribution || false,
560
+ renderLargerThumbnail: extAdReply.renderLargerThumbnail || false
561
+ }
562
+ }
563
+ };
564
+ }
565
+ else if ('payment' in message) {
566
+ // Handle sendPayment functionality
567
+ m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
568
+ currencyCodeIso4217: message.payment.currency || 'EUR',
569
+ amount1000: message.payment.amount1000 || message.payment.amount * 1000,
570
+ requestFrom: message.payment.requestFrom || message.payment.from,
571
+ noteMessage: {
572
+ extendedTextMessage: {
573
+ text: message.payment.text || message.payment.note || '',
574
+ contextInfo: message.payment.contextInfo
575
+ }
576
+ },
577
+ expiryTimestamp: message.payment.expiryTimestamp || message.payment.expiry,
578
+ background: message.payment.background
579
+ });
580
+ }
514
581
  else if ('album' in message) {
515
582
  const imageMessages = message.album.filter(item => 'image' in item);
516
583
  const videoMessages = message.album.filter(item => 'video' in item);
@@ -1277,7 +1344,7 @@ exports.getCacheStats = getCacheStats;
1277
1344
  const clearCache = () => {
1278
1345
  lidCache.clear();
1279
1346
  jidCache.clear();
1280
- console.log('Cache cleared successfully');
1347
+ console.log(chalk.bold.magenta('- 🎐 | Cache cancellata correttamente'));
1281
1348
  };
1282
1349
  exports.clearCache = clearCache;
1283
1350
 
@@ -14,6 +14,14 @@ export interface PerformanceSettings {
14
14
  batchSize: number;
15
15
  maxRetries: number;
16
16
  retryDelay: number;
17
+ retryBackoffMultiplier: number;
18
+ maxRetryDelay: number;
19
+ maxMsgRetryCount: number;
20
+ memoryThreshold: number;
21
+ // Anti-ban specific settings
22
+ markOnlineOnConnect?: boolean;
23
+ syncFullHistory?: boolean;
24
+ keepAliveIntervalMs?: number;
17
25
  }
18
26
 
19
27
  export interface DebugSettings {
@@ -26,17 +26,22 @@ class PerformanceConfig {
26
26
  }
27
27
  };
28
28
 
29
- // Performance settings
29
+ // Performance settings - Conservative defaults for anti-ban protection
30
30
  this.performance = {
31
31
  enableCache: true,
32
32
  enableLogging: false,
33
- enableMetrics: false,
34
- batchSize: 100,
35
- maxRetries: 5,
36
- retryDelay: 1000,
33
+ enableMetrics: true,
34
+ batchSize: 20, // Reduced from 50 for anti-ban
35
+ maxRetries: 3, // Reduced from 5 for anti-ban
36
+ retryDelay: 5000,
37
37
  retryBackoffMultiplier: 1.5,
38
- maxRetryDelay: 30000,
39
- memoryThreshold: 0.85 // 85% memory usage threshold
38
+ maxRetryDelay: 60000,
39
+ maxMsgRetryCount: 3,
40
+ memoryThreshold: 0.85, // 85% memory usage threshold
41
+ // Anti-ban specific settings
42
+ markOnlineOnConnect: false, // Don't appear always online
43
+ syncFullHistory: false, // Limit initial sync
44
+ keepAliveIntervalMs: 30000 // Maintain connection without excess
40
45
  };
41
46
 
42
47
  // Debug settings
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * RateLimiter class for controlling message sending frequency
5
+ * to prevent ban detection by simulating human-like behavior
6
+ */
7
+ class RateLimiter {
8
+ constructor(limitPerSecond = 1) {
9
+ this.limitPerSecond = limitPerSecond;
10
+ this.interval = 1000 / limitPerSecond; // milliseconds between messages
11
+ this.queue = [];
12
+ this.processing = false;
13
+ this.lastSendTime = 0;
14
+ }
15
+
16
+ /**
17
+ * Add a task to the rate limiting queue
18
+ * @param {Function} task - Async function to execute
19
+ * @returns {Promise} - Promise that resolves when task is complete
20
+ */
21
+ async add(task) {
22
+ return new Promise((resolve, reject) => {
23
+ this.queue.push({ task, resolve, reject });
24
+ if (!this.processing) {
25
+ this.process();
26
+ }
27
+ });
28
+ }
29
+
30
+ /**
31
+ * Process the queue with rate limiting
32
+ */
33
+ async process() {
34
+ if (this.processing || this.queue.length === 0) {
35
+ return;
36
+ }
37
+
38
+ this.processing = true;
39
+
40
+ while (this.queue.length > 0) {
41
+ const { task, resolve, reject } = this.queue.shift();
42
+ const now = Date.now();
43
+ const timeSinceLastSend = now - this.lastSendTime;
44
+
45
+ // Wait if we need to respect the rate limit
46
+ if (timeSinceLastSend < this.interval) {
47
+ const waitTime = this.interval - timeSinceLastSend;
48
+ await new Promise(r => setTimeout(r, waitTime));
49
+ }
50
+
51
+ try {
52
+ const result = await task();
53
+ this.lastSendTime = Date.now();
54
+ resolve(result);
55
+ } catch (error) {
56
+ reject(error);
57
+ }
58
+
59
+ // Add small random delay to simulate human behavior (0-500ms)
60
+ const randomDelay = Math.random() * 500;
61
+ await new Promise(r => setTimeout(r, randomDelay));
62
+ }
63
+
64
+ this.processing = false;
65
+ }
66
+
67
+ /**
68
+ * Update the rate limit
69
+ * @param {number} newLimit - New messages per second limit
70
+ */
71
+ setLimit(newLimit) {
72
+ this.limitPerSecond = newLimit;
73
+ this.interval = 1000 / newLimit;
74
+ }
75
+
76
+ /**
77
+ * Get current queue length
78
+ * @returns {number} - Number of pending tasks
79
+ */
80
+ getQueueLength() {
81
+ return this.queue.length;
82
+ }
83
+
84
+ /**
85
+ * Clear all pending tasks
86
+ */
87
+ clear() {
88
+ this.queue.forEach(({ reject }) => {
89
+ reject(new Error('Rate limiter cleared'));
90
+ });
91
+ this.queue = [];
92
+ }
93
+ }
94
+
95
+ module.exports = RateLimiter;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realvare/based",
3
- "version": "2.5.5",
3
+ "version": "2.5.7",
4
4
  "description": "whatsapp api by sam",
5
5
  "keywords": [
6
6
  "baileys",
@@ -37,7 +37,7 @@
37
37
  "lint:fix": "eslint src --fix --ext .js,.ts,.jsx,.tsx",
38
38
  "preinstall": "node ./engine-requirements.js",
39
39
  "release": "release-it",
40
- "test": "jest"
40
+ "test": "test"
41
41
  },
42
42
  "dependencies": {
43
43
  "@adiwajshing/keyed-db": "^0.2.4",
@@ -97,9 +97,6 @@
97
97
  "link-preview-js": {
98
98
  "optional": true
99
99
  },
100
- "qrcode-terminal": {
101
- "optional": true
102
- },
103
100
  "sharp": {
104
101
  "optional": true
105
102
  }
@@ -108,4 +105,4 @@
108
105
  "engines": {
109
106
  "node": ">=20.0.0"
110
107
  }
111
- }
108
+ }