@realvare/based 2.6.11 → 2.6.22

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.
@@ -11,6 +11,7 @@ const WAProto_1 = require("../../WAProto");
11
11
  const Defaults_1 = require("../Defaults");
12
12
  const Types_1 = require("../Types");
13
13
  const Utils_1 = require("../Utils");
14
+ const performance_config_1 = require("../Utils/performance-config");
14
15
  const make_mutex_1 = require("../Utils/make-mutex");
15
16
  const WABinary_1 = require("../WABinary");
16
17
  const groups_1 = require("./groups");
@@ -1048,25 +1049,48 @@ const makeMessagesRecvSocket = (config) => {
1048
1049
  upsertMessage(protoMsg, call.offline ? 'append' : 'notify');
1049
1050
  }
1050
1051
  });
1051
- ev.on('connection.update', ({ isOnline }) => {
1052
- if (typeof isOnline !== 'undefined') {
1053
- sendActiveReceipts = isOnline;
1052
+ ev.on('connection.update', (update) => {
1053
+ const { connection, lastDisconnect } = update;
1054
+
1055
+ if (connection === 'close') {
1056
+ const statusCode = lastDisconnect?.error?.output?.statusCode;
1057
+ const shouldReconnect = statusCode !== Types_1.DisconnectReason.loggedOut;
1058
+
1059
+ if (shouldReconnect) {
1060
+ logger.info('Connection closed, will handle reconnection automatically');
1061
+ } else {
1062
+ logger.warn('Logged out, manual re-authentication required');
1063
+ }
1064
+ } else if (connection === 'open') {
1065
+ sendActiveReceipts = true;
1066
+ }
1067
+
1068
+ // Update sendActiveReceipts based on connection status
1069
+ if (typeof update.isOnline !== 'undefined') {
1070
+ sendActiveReceipts = update.isOnline;
1054
1071
  logger.trace(`sendActiveReceipts set to "${sendActiveReceipts}"`);
1055
1072
  }
1056
1073
  });
1057
1074
 
1058
- // Retry logic for stuck pending messages
1075
+ // Enhanced retry logic for stuck pending messages with anti-ban delays
1059
1076
  ev.on('messages.update', (updates) => {
1077
+ const config = getPerformanceConfig();
1060
1078
  updates.forEach(update => {
1061
1079
  if (update.update.status === WAProto_1.proto.WebMessageInfo.Status.PENDING &&
1062
1080
  Date.now() - (update.update.timestamp || 0) > 30000) { // 30 seconds
1063
- logger.debug({ key: update.key }, 'retrying stuck pending message');
1064
- // Retry by re-sending the message
1065
- getMessage(update.key).then(msg => {
1066
- if (msg) {
1067
- relayMessage(update.key.remoteJid, msg, { messageId: update.key.id });
1081
+ logger.debug({ key: update.key }, 'retrying stuck pending message with anti-ban delay');
1082
+
1083
+ // Apply anti-ban delay before retry
1084
+ setTimeout(async () => {
1085
+ try {
1086
+ const msg = await getMessage(update.key);
1087
+ if (msg) {
1088
+ await relayMessage(update.key.remoteJid, msg, { messageId: update.key.id });
1089
+ }
1090
+ } catch (err) {
1091
+ logger.error({ err, key: update.key }, 'failed to retry stuck message');
1068
1092
  }
1069
- }).catch(err => logger.error({ err, key: update.key }, 'failed to retry stuck message'));
1093
+ }, config.security?.messageDelay?.min || 1000);
1070
1094
  }
1071
1095
  });
1072
1096
  });
@@ -16,10 +16,12 @@ const WABinary_1 = require("../WABinary");
16
16
  const WAUSync_1 = require("../WAUSync");
17
17
  const newsletter_1 = require("./newsletter");
18
18
  const rate_limiter_1 = __importDefault(require("../Utils/rate-limiter"));
19
+ const { generateThumbnail } = require("../Utils/thumbnail");
19
20
  const makeMessagesSocket = (config) => {
20
21
  const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: axiosOptions, patchMessageBeforeSending, cachedGroupMetadata, } = config;
21
22
  const sock = (0, newsletter_1.makeNewsletterSocket)(config);
22
23
  const { ev, authState, processingMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral, } = sock;
24
+
23
25
  const userDevicesCache = config.userDevicesCache || new node_cache_1.default({
24
26
  stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
25
27
  useClones: false
@@ -275,6 +277,26 @@ const makeMessagesSocket = (config) => {
275
277
  const isStatus = jid === statusJid;
276
278
  const isLid = server === 'lid';
277
279
  msgId = msgId || (0, Utils_1.generateMessageIDV2)((_a = sock.user) === null || _a === void 0 ? void 0 : _a.id);
280
+ if(message.contextInfo?.externalAdReply?.thumbnailUrl) {
281
+ try {
282
+ const { externalAdReply } = message.contextInfo;
283
+ const thumbnail = await generateThumbnail(externalAdReply.thumbnailUrl);
284
+ message.contextInfo.externalAdReply = {
285
+ ...externalAdReply,
286
+ thumbnail,
287
+ renderLargerThumbnail: false,
288
+ };
289
+ delete message.contextInfo.externalAdReply.thumbnailUrl;
290
+ logger?.debug('Successfully generated thumbnail for external ad reply');
291
+ } catch(err) {
292
+ logger?.warn({ trace: err.stack, msg: message.contextInfo.externalAdReply }, 'failed to generate thumbnail for external ad reply, keeping thumbnailUrl as fallback');
293
+ // Ensure renderLargerThumbnail is set to false even on failure
294
+ if (message.contextInfo.externalAdReply.renderLargerThumbnail === undefined) {
295
+ message.contextInfo.externalAdReply.renderLargerThumbnail = false;
296
+ }
297
+ }
298
+ }
299
+
278
300
  useUserDevicesCache = useUserDevicesCache !== false;
279
301
  useCachedGroupMetadata = useCachedGroupMetadata !== false && !isStatus;
280
302
  const participants = [];
@@ -766,9 +788,9 @@ const makeMessagesSocket = (config) => {
766
788
  parentMessageKey: albumMsg.key
767
789
  }
768
790
  };
769
- await relayMessage(jid, mediaMsg.message, {
791
+ await rateLimiter.add(() => relayMessage(jid, mediaMsg.message, {
770
792
  messageId: mediaMsg.key.id
771
- });
793
+ }));
772
794
  await new Promise(resolve => setTimeout(resolve, 800));
773
795
  }
774
796
  }
@@ -878,7 +900,7 @@ const makeMessagesSocket = (config) => {
878
900
  parentMessageKey: packMsg.key
879
901
  }
880
902
  };
881
- await relayMessage(jid, stickerMsg.message, { messageId: stickerMsg.key.id });
903
+ await rateLimiter.add(() => relayMessage(jid, stickerMsg.message, { messageId: stickerMsg.key.id }));
882
904
  lastMsg = stickerMsg;
883
905
  // Add delay between stickers to avoid rate limiting
884
906
  await new Promise(resolve => setTimeout(resolve, 800));
@@ -1128,9 +1150,9 @@ const makeMessagesSocket = (config) => {
1128
1150
  expectedVideoCount: album.filter(item => 'video' in item).length
1129
1151
  }
1130
1152
  }, { userJid, ...options });
1131
- await relayMessage(jid, albumMsg.message, {
1153
+ await rateLimiter.add(() => relayMessage(jid, albumMsg.message, {
1132
1154
  messageId: albumMsg.key.id
1133
- });
1155
+ }));
1134
1156
  for (const i in album) {
1135
1157
  const media = album[i];
1136
1158
  if ('image' in media) {
@@ -1291,18 +1313,17 @@ const makeMessagesSocket = (config) => {
1291
1313
  messageId: (0, Utils_1.generateMessageIDV2)((_c = sock.user) === null || _c === void 0 ? void 0 : _c.id),
1292
1314
  ...options,
1293
1315
  });
1294
- // Associate sticker with the pack message
1295
- stickerMsg.message.messageContextInfo = {
1296
- messageSecret: (0, crypto_1.randomBytes)(32),
1297
- messageAssociation: {
1298
- associationType: 1,
1299
- parentMessageKey: packMsg.key
1300
- }
1301
- };
1302
- await relayMessage(jid, stickerMsg.message, { messageId: stickerMsg.key.id });
1303
- lastMsg = stickerMsg;
1304
- // Add delay between stickers to avoid rate limiting
1305
- await new Promise(resolve => setTimeout(resolve, 800));
1316
+ // Associate sticker with the pack message
1317
+ stickerMsg.message.messageContextInfo = {
1318
+ messageSecret: (0, crypto_1.randomBytes)(32),
1319
+ messageAssociation: {
1320
+ associationType: 1,
1321
+ parentMessageKey: packMsg.key
1322
+ }
1323
+ };
1324
+ await rateLimiter.add(() => relayMessage(jid, stickerMsg.message, { messageId: stickerMsg.key.id }));
1325
+ lastMsg = stickerMsg;
1326
+ await new Promise(resolve => setTimeout(resolve, 800));
1306
1327
  }
1307
1328
  return lastMsg;
1308
1329
  }
@@ -29,7 +29,7 @@ export type SocketConfig = {
29
29
  connectTimeoutMs: number;
30
30
  /** Default timeout for queries, undefined for no timeout */
31
31
  defaultQueryTimeoutMs: number | undefined;
32
- /** ping-pong interval for WS connection */
32
+ /** ping- inpongterval for WS connection */
33
33
  keepAliveIntervalMs: number;
34
34
  /** should baileys use the mobile api instead of the multi device api
35
35
  * @deprecated This feature has been removed
@@ -7,20 +7,24 @@ class CacheManager {
7
7
  const config = getPerformanceConfig();
8
8
  this.caches = {};
9
9
  this.memoryCheckInterval = null;
10
-
10
+ this.msgStore = null;
11
+
11
12
  // Inizializza le cache con TTL
12
13
  Object.entries(config.cache).forEach(([name, options]) => {
13
14
  this.caches[name] = new NodeCache({
14
- stdTTL: options.ttl / 1000, // Converti da ms a secondi
15
+ stdTTL: options.ttl / 1000,
15
16
  checkperiod: options.cleanupInterval / 1000,
16
17
  maxKeys: options.maxSize
17
18
  });
18
19
  });
19
-
20
+
20
21
  if (config.performance.enableMetrics) {
21
22
  this.startMemoryMonitoring(config.performance.memoryThreshold);
22
23
  }
23
24
  }
25
+ setMessageStore(msgStore) {
26
+ this.msgStore = msgStore;
27
+ }
24
28
 
25
29
  startMemoryMonitoring(threshold) {
26
30
  this.memoryCheckInterval = setInterval(() => {
@@ -4,4 +4,56 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const pino_1 = __importDefault(require("pino"));
7
- exports.default = (0, pino_1.default)({ timestamp: () => `,"time":"${new Date().toJSON()}"` });
7
+ const { getPerformanceConfig } = require('./performance-config');
8
+ const defaultLogger = (0, pino_1.default)({ timestamp: () => `,"time":"${new Date().toJSON()}"` });
9
+ class EnhancedLogger {
10
+ constructor() {
11
+ this.config = getPerformanceConfig();
12
+ }
13
+
14
+ static error(...args) {
15
+ if (defaultLogger.isLevelEnabled('error')) {
16
+ defaultLogger.error(...args);
17
+ }
18
+ // Additional error tracking if enabled
19
+ if (this.config?.debug?.enableErrorTracking) {
20
+ // Could send to external monitoring service
21
+ console.error('[ERROR TRACK]', ...args);
22
+ }
23
+ }
24
+
25
+ static warn(...args) {
26
+ if (defaultLogger.isLevelEnabled('warn')) {
27
+ defaultLogger.warn(...args);
28
+ }
29
+ }
30
+
31
+ static info(...args) {
32
+ if (this.config?.debug?.enableInfoLogging && defaultLogger.isLevelEnabled('info')) {
33
+ defaultLogger.info(...args);
34
+ }
35
+ }
36
+
37
+ static debug(...args) {
38
+ if (this.config?.debug?.enableDebugLogging && defaultLogger.isLevelEnabled('debug')) {
39
+ defaultLogger.debug(...args);
40
+ }
41
+ }
42
+ static createBaileysLogger(level = 'info', prefix = 'Based') {
43
+ return {
44
+ level,
45
+ debug: (...args) => this.debug(`[${prefix}]`, ...args),
46
+ info: (...args) => this.info(`[${prefix}]`, ...args),
47
+ warn: (...args) => this.warn(`[${prefix}]`, ...args),
48
+ error: (...args) => this.error(`[${prefix}]`, ...args),
49
+ trace: (...args) => this.debug(`[${prefix} TRACE]`, ...args),
50
+ child: (bindings) => ({
51
+ ...this.createBaileysLogger(level, prefix),
52
+ bindings
53
+ })
54
+ };
55
+ }
56
+ }
57
+
58
+ exports.EnhancedLogger = EnhancedLogger;
59
+ exports.default = defaultLogger;
@@ -275,8 +275,8 @@ const generateWAMessageContent = async (message, options) => {
275
275
 
276
276
  // Ensure renderLargerThumbnail is set for better display across platforms
277
277
  if (externalAdReply.renderLargerThumbnail === undefined) {
278
- externalAdReply.renderLargerThumbnail = true;
279
- options.logger?.debug('Set renderLargerThumbnail=true for improved cross-platform display');
278
+ externalAdReply.renderLargerThumbnail = false;
279
+ options.logger?.debug('Set renderLargerThumbnail=false for improved cross-platform display');
280
280
  }
281
281
 
282
282
  // Update the contextInfo with modified externalAdReply
@@ -1194,187 +1194,50 @@ const assertMediaContent = (content) => {
1194
1194
  return mediaContent;
1195
1195
  };
1196
1196
  exports.assertMediaContent = assertMediaContent;
1197
-
1198
- // Cache per ottimizzare le conversioni LID/JID
1199
- const lidCache = new Map();
1200
- const jidCache = new Map();
1201
- const CACHE_TTL = 5 * 60 * 1000; // 5 minuti
1202
- const MAX_CACHE_SIZE = 10000; // Massimo 10k entries
1203
-
1204
- // Funzione per pulire cache scadute
1205
- const cleanExpiredCache = (cache) => {
1206
- const now = Date.now();
1207
- for (const [key, value] of cache.entries()) {
1208
- if (now - value.timestamp > CACHE_TTL) {
1209
- cache.delete(key);
1210
- }
1211
- }
1212
-
1213
- // Se la cache è troppo grande, rimuovi le entry più vecchie
1214
- if (cache.size > MAX_CACHE_SIZE) {
1215
- const entries = Array.from(cache.entries());
1216
- entries.sort((a, b) => a[1].timestamp - b[1].timestamp);
1217
- const toRemove = entries.slice(0, Math.floor(MAX_CACHE_SIZE * 0.2));
1218
- toRemove.forEach(([key]) => cache.delete(key));
1219
- }
1197
+ const getNormalizedJid = (jid) => {
1198
+ if (!jid) return jid;
1199
+ return (0, WABinary_1.jidNormalizedUser)(jid);
1220
1200
  };
1201
+ exports.getNormalizedJid = getNormalizedJid;
1221
1202
 
1222
- // Pulisci cache ogni 2 minuti
1223
- setInterval(() => {
1224
- cleanExpiredCache(lidCache);
1225
- cleanExpiredCache(jidCache);
1226
- }, 2 * 60 * 1000);
1203
+ const isLidFormat = (jid) => {
1204
+ return (0, WABinary_1.isLidUser)(jid);
1205
+ };
1206
+ exports.isLidFormat = isLidFormat;
1227
1207
 
1208
+ // Legacy compatibility functions - deprecated, use native APIs
1228
1209
  const toJid = (id) => {
1229
- try {
1230
- if (!id || typeof id !== 'string') {
1231
- return '';
1232
- }
1233
-
1234
- // Controlla cache
1235
- if (jidCache.has(id)) {
1236
- const cached = jidCache.get(id);
1237
- if (Date.now() - cached.timestamp < CACHE_TTL) {
1238
- return cached.result;
1239
- } else {
1240
- jidCache.delete(id);
1241
- }
1242
- }
1243
-
1244
- let result = '';
1245
-
1246
- if (id.endsWith('@lid')) {
1247
- result = id.replace('@lid', '@s.whatsapp.net');
1248
- } else if (id.includes('@')) {
1249
- result = id;
1250
- } else {
1251
- result = `${id}@s.whatsapp.net`;
1252
- }
1253
-
1254
- // Salva in cache
1255
- jidCache.set(id, {
1256
- result,
1257
- timestamp: Date.now()
1258
- });
1259
-
1260
- return result;
1261
- } catch (error) {
1262
- console.error('Error in toJid:', error.message, 'Input:', id);
1263
- return id || '';
1264
- }
1210
+ console.warn('toJid is deprecated. Use getNormalizedJid instead.');
1211
+ return getNormalizedJid(id);
1265
1212
  };
1266
1213
  exports.toJid = toJid;
1267
1214
 
1268
1215
  const getSenderLid = (message) => {
1269
- try {
1270
- if (!message?.key) {
1271
- throw new Error('Invalid message: missing key property');
1272
- }
1273
-
1274
- const sender = message.key.participant || message.key.remoteJid;
1275
- if (!sender) {
1276
- throw new Error('Invalid message: missing sender information');
1277
- }
1278
-
1279
- // Controlla cache
1280
- if (lidCache.has(sender)) {
1281
- const cached = lidCache.get(sender);
1282
- if (Date.now() - cached.timestamp < CACHE_TTL) {
1283
- return cached.result;
1284
- } else {
1285
- lidCache.delete(sender);
1286
- }
1287
- }
1288
-
1289
- const decoded = (0, WABinary_1.jidDecode)(sender);
1290
- if (!decoded?.user) {
1291
- throw new Error(`Invalid JID format: ${sender}`);
1292
- }
1293
-
1294
- const user = decoded.user;
1295
- const lid = (0, WABinary_1.jidEncode)(user, 'lid');
1296
-
1297
- const result = {
1298
- jid: sender,
1299
- lid,
1300
- isValid: true,
1301
- user,
1302
- timestamp: Date.now()
1303
- };
1304
-
1305
- // Log solo in debug mode
1306
- if (process.env.DEBUG_LID === 'true') {
1307
- console.log('sender lid:', lid, 'user:', user);
1308
- }
1309
-
1310
- // Salva in cache
1311
- lidCache.set(sender, {
1312
- result,
1313
- timestamp: Date.now()
1314
- });
1315
-
1316
- return result;
1317
-
1318
- } catch (error) {
1319
- console.error('Error in getSenderLid:', error.message, 'Message:', message?.key);
1320
-
1321
- // Ritorna un oggetto di fallback valido
1322
- return {
1323
- jid: message?.key?.remoteJid || 'unknown',
1324
- lid: 'unknown@lid',
1325
- isValid: false,
1326
- user: 'unknown',
1327
- error: error.message,
1328
- timestamp: Date.now()
1329
- };
1330
- }
1331
- };
1332
- exports.getSenderLid = getSenderLid;
1216
+ console.warn('getSenderLid is deprecated. Use getNormalizedJid and isLidFormat instead.');
1217
+ const sender = message?.key?.participant || message?.key?.remoteJid;
1218
+ if (!sender) return null;
1333
1219
 
1334
- // Utility functions per performance e debugging
1335
- const getCacheStats = () => {
1220
+ const normalized = getNormalizedJid(sender);
1336
1221
  return {
1337
- lidCache: {
1338
- size: lidCache.size,
1339
- maxSize: MAX_CACHE_SIZE,
1340
- ttl: CACHE_TTL
1341
- },
1342
- jidCache: {
1343
- size: jidCache.size,
1344
- maxSize: MAX_CACHE_SIZE,
1345
- ttl: CACHE_TTL
1346
- }
1222
+ jid: sender,
1223
+ lid: normalized,
1224
+ isValid: true,
1225
+ user: (0, WABinary_1.jidDecode)(normalized)?.user || 'unknown'
1347
1226
  };
1348
1227
  };
1349
- exports.getCacheStats = getCacheStats;
1350
-
1351
- const clearCache = () => {
1352
- lidCache.clear();
1353
- jidCache.clear();
1354
- console.log(chalk.bold.magenta('- 🎐 | Cache cancellata correttamente'));
1355
- };
1356
- exports.clearCache = clearCache;
1228
+ exports.getSenderLid = getSenderLid;
1357
1229
 
1358
1230
  const validateJid = (jid) => {
1231
+ console.warn('validateJid is deprecated. Use native Baileys validation.');
1359
1232
  if (!jid || typeof jid !== 'string') {
1360
1233
  return { isValid: false, error: 'Invalid JID: must be a non-empty string' };
1361
1234
  }
1362
-
1363
- const parts = jid.split('@');
1364
- if (parts.length !== 2) {
1365
- return { isValid: false, error: 'Invalid JID format: must contain exactly one @' };
1366
- }
1367
-
1368
- const [user, server] = parts;
1369
- if (!user || !server) {
1370
- return { isValid: false, error: 'Invalid JID: user and server parts cannot be empty' };
1371
- }
1372
-
1373
- const validServers = ['s.whatsapp.net', 'g.us', 'broadcast', 'newsletter', 'lid', 'c.us'];
1374
- if (!validServers.includes(server)) {
1375
- return { isValid: false, error: `Invalid server: ${server}. Must be one of: ${validServers.join(', ')}` };
1235
+
1236
+ try {
1237
+ const decoded = (0, WABinary_1.jidDecode)(jid);
1238
+ return { isValid: !!decoded };
1239
+ } catch {
1240
+ return { isValid: false, error: 'Invalid JID format' };
1376
1241
  }
1377
-
1378
- return { isValid: true };
1379
1242
  };
1380
1243
  exports.validateJid = validateJid;
@@ -7,41 +7,39 @@ exports.PerformanceConfig = exports.setPerformanceConfig = exports.getPerformanc
7
7
  */
8
8
  class PerformanceConfig {
9
9
  constructor() {
10
- // Cache settings
11
10
  this.cache = {
12
11
  lidCache: {
13
- ttl: 5 * 60 * 1000, // 5 minuti
12
+ ttl: 5 * 60 * 1000,
14
13
  maxSize: 10000,
15
- cleanupInterval: 2 * 60 * 1000 // 2 minuti
14
+ cleanupInterval: 2 * 60 * 1000
16
15
  },
17
16
  jidCache: {
18
- ttl: 5 * 60 * 1000, // 5 minuti
17
+ ttl: 5 * 60 * 1000,
19
18
  maxSize: 10000,
20
- cleanupInterval: 2 * 60 * 1000 // 2 minuti
19
+ cleanupInterval: 2 * 60 * 1000
21
20
  },
22
21
  lidToJidCache: {
23
- ttl: 5 * 60 * 1000, // 5 minuti
22
+ ttl: 5 * 60 * 1000,
24
23
  maxSize: 5000,
25
- cleanupInterval: 3 * 60 * 1000 // 3 minuti
24
+ cleanupInterval: 3 * 60 * 1000
26
25
  }
27
26
  };
28
27
 
29
- // Performance settings - Conservative defaults for anti-ban protection
30
28
  this.performance = {
31
29
  enableCache: true,
32
30
  enableLogging: false,
33
31
  enableMetrics: true,
34
- batchSize: 20, // Reduced from 50 for anti-ban
35
- maxRetries: 3, // Reduced from 5 for anti-ban
36
- retryDelay: 5000,
37
- retryBackoffMultiplier: 1.5,
38
- maxRetryDelay: 60000,
32
+ batchSize: 30,
33
+ maxRetries: 3,
34
+ retryDelay: 8000,
35
+ retryBackoffMultiplier: 2.0,
36
+ maxRetryDelay: 120000,
39
37
  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
38
+ memoryThreshold: 0.85,
39
+ markOnlineOnConnect: false,
40
+ syncFullHistory: true,
41
+ keepAliveIntervalMs: 30000,
42
+ enableNativeLidCache: true
45
43
  };
46
44
 
47
45
  // Debug settings
@@ -0,0 +1,35 @@
1
+ const sharp = require('sharp');
2
+ const fs = require('fs/promises');
3
+ const fetch = require('node-fetch');
4
+
5
+ /**
6
+ * Generates an optimized JPEG thumbnail buffer for externalAdReply.
7
+ * @param {string | Buffer} imagePathOrBuffer - Path to image file, Buffer, or URL.
8
+ * @param {number} [size=150] - Target square size (default 150 for balance between quality and load time).
9
+ * @param {number} [quality=85] - JPEG quality (1-100, default 85).
10
+ * @returns {Promise<Buffer>} - Optimized thumbnail buffer.
11
+ */
12
+ async function generateThumbnail(imagePathOrBuffer, size = 150, quality = 85) {
13
+ let input;
14
+
15
+ if (typeof imagePathOrBuffer === 'string') {
16
+ if (imagePathOrBuffer.startsWith('http')) {
17
+ // Fetch from URL
18
+ const response = await fetch(imagePathOrBuffer);
19
+ input = Buffer.from(await response.arrayBuffer());
20
+ } else {
21
+ // Local file
22
+ input = await fs.readFile(imagePathOrBuffer);
23
+ }
24
+ } else {
25
+ input = imagePathOrBuffer;
26
+ }
27
+
28
+ return sharp(input)
29
+ .resize(size, size, { fit: 'cover', kernel: sharp.kernel.lanczos3 }) // Lanczos for sharp resizing
30
+ .sharpen() // Optional: Adds slight sharpness to counter blurring
31
+ .jpeg({ quality, mozjpeg: true }) // Use high-quality JPEG compression
32
+ .toBuffer();
33
+ }
34
+
35
+ module.exports = { generateThumbnail };
@@ -88,7 +88,11 @@ const useMultiFileAuthState = async (folder) => {
88
88
  await (0, promises_1.mkdir)(folder, { recursive: true });
89
89
  }
90
90
  const fixFileName = (file) => { var _a; return (_a = file === null || file === void 0 ? void 0 : file.replace(/\//g, '__')) === null || _a === void 0 ? void 0 : _a.replace(/:/g, '-'); };
91
- const creds = await readData('creds.json') || (0, auth_utils_1.initAuthCreds)();
91
+ let creds = await readData('creds.json');
92
+ if (!creds) {
93
+ creds = (0, auth_utils_1.initAuthCreds)();
94
+ }
95
+
92
96
  return {
93
97
  state: {
94
98
  creds,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@realvare/based",
3
- "version": "2.6.11",
4
- "description": "whatsapp api by sam",
3
+ "version": "2.6.22",
4
+ "description": "WhatsApp Web API by Sam",
5
5
  "keywords": [
6
6
  "baileys",
7
7
  "whatsapp",
@@ -9,7 +9,9 @@
9
9
  "whatsapp-web",
10
10
  "whatsapp-bot",
11
11
  "automation",
12
- "multi-device"
12
+ "multi-device",
13
+ "lid",
14
+ "anti-ban"
13
15
  ],
14
16
  "homepage": "https://github.com/realvare/based.git",
15
17
  "repository": {
@@ -56,6 +58,7 @@
56
58
  "music-metadata": "^7.12.3",
57
59
  "pino": "^9.6",
58
60
  "protobufjs": "^7.2.5",
61
+ "sharp": "^0.33.5",
59
62
  "uuid": "^10.0.0",
60
63
  "ws": "^8.18.0"
61
64
  },
@@ -96,9 +99,6 @@
96
99
  },
97
100
  "link-preview-js": {
98
101
  "optional": true
99
- },
100
- "sharp": {
101
- "optional": true
102
102
  }
103
103
  },
104
104
  "packageManager": "yarn@1.22.19",