@realvare/based 2.5.1 → 2.5.5
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 +1194 -829
- package/lib/Socket/messages-send.js +1406 -900
- package/lib/Socket/socket.js +41 -0
- package/lib/Utils/cache-manager.js +73 -0
- package/lib/Utils/messages.js +55 -39
- package/lib/Utils/performance-config.d.ts +60 -60
- package/lib/Utils/performance-config.js +153 -150
- package/lib/Utils/retry.js +66 -66
- package/lib/WABinary/decode.js +24 -10
- package/lib/WABinary/encode.js +15 -1
- package/lib/WABinary/jid-utils.js +217 -140
- package/lib/index.js +3 -4
- package/package.json +111 -111
- package/lib/WABinary/jid-utils.js.bak +0 -83
package/lib/Socket/socket.js
CHANGED
|
@@ -48,6 +48,47 @@ const makeSocket = (config) => {
|
|
|
48
48
|
let keepAliveReq;
|
|
49
49
|
let qrTimer;
|
|
50
50
|
let closed = false;
|
|
51
|
+
let reconnectAttempts = 0;
|
|
52
|
+
const performanceConfig = (0, Utils_1.getPerformanceConfig)();
|
|
53
|
+
|
|
54
|
+
const handleReconnect = async () => {
|
|
55
|
+
if (closed) return;
|
|
56
|
+
|
|
57
|
+
reconnectAttempts++;
|
|
58
|
+
const delay = Math.min(
|
|
59
|
+
performanceConfig.performance.retryDelay * Math.pow(
|
|
60
|
+
performanceConfig.performance.retryBackoffMultiplier,
|
|
61
|
+
reconnectAttempts - 1
|
|
62
|
+
),
|
|
63
|
+
performanceConfig.performance.maxRetryDelay
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
logger?.info({
|
|
67
|
+
reconnectAttempts,
|
|
68
|
+
delay
|
|
69
|
+
}, 'Attempting to reconnect...');
|
|
70
|
+
|
|
71
|
+
await (0, Utils_1.delay)(delay);
|
|
72
|
+
|
|
73
|
+
if (reconnectAttempts <= performanceConfig.performance.maxRetries) {
|
|
74
|
+
try {
|
|
75
|
+
ws.connect();
|
|
76
|
+
} catch (error) {
|
|
77
|
+
logger?.error({ error }, 'Reconnection attempt failed');
|
|
78
|
+
handleReconnect();
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
logger?.error('Max reconnection attempts reached');
|
|
82
|
+
ev.emit('connection.update', {
|
|
83
|
+
connection: 'close',
|
|
84
|
+
lastDisconnect: {
|
|
85
|
+
error: new boom_1.Boom('Max reconnection attempts reached', {
|
|
86
|
+
statusCode: Types_1.DisconnectReason.connectionClosed
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
};
|
|
51
92
|
const uqTagId = (0, Utils_1.generateMdTagPrefix)();
|
|
52
93
|
const generateMessageTag = () => `${uqTagId}${epoch++}`;
|
|
53
94
|
const sendPromise = (0, util_1.promisify)(ws.send);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const NodeCache = require('node-cache');
|
|
3
|
+
const { getPerformanceConfig } = require('./performance-config');
|
|
4
|
+
|
|
5
|
+
class CacheManager {
|
|
6
|
+
constructor() {
|
|
7
|
+
const config = getPerformanceConfig();
|
|
8
|
+
this.caches = {};
|
|
9
|
+
this.memoryCheckInterval = null;
|
|
10
|
+
|
|
11
|
+
// Inizializza le cache con TTL
|
|
12
|
+
Object.entries(config.cache).forEach(([name, options]) => {
|
|
13
|
+
this.caches[name] = new NodeCache({
|
|
14
|
+
stdTTL: options.ttl / 1000, // Converti da ms a secondi
|
|
15
|
+
checkperiod: options.cleanupInterval / 1000,
|
|
16
|
+
maxKeys: options.maxSize
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
if (config.performance.enableMetrics) {
|
|
21
|
+
this.startMemoryMonitoring(config.performance.memoryThreshold);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
startMemoryMonitoring(threshold) {
|
|
26
|
+
this.memoryCheckInterval = setInterval(() => {
|
|
27
|
+
const used = process.memoryUsage().heapUsed;
|
|
28
|
+
const total = process.memoryUsage().heapTotal;
|
|
29
|
+
const ratio = used / total;
|
|
30
|
+
|
|
31
|
+
if (ratio > threshold) {
|
|
32
|
+
this.evictLeastUsed();
|
|
33
|
+
}
|
|
34
|
+
}, 60000); // Controlla ogni minuto
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
evictLeastUsed() {
|
|
38
|
+
Object.values(this.caches).forEach(cache => {
|
|
39
|
+
const stats = cache.getStats();
|
|
40
|
+
if (stats.keys > 100) { // Mantieni almeno 100 chiavi
|
|
41
|
+
const keys = cache.keys();
|
|
42
|
+
// Rimuovi il 20% delle chiavi meno usate
|
|
43
|
+
const toRemove = Math.floor(keys.length * 0.2);
|
|
44
|
+
keys.slice(0, toRemove).forEach(key => cache.del(key));
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get(cacheName, key) {
|
|
50
|
+
return this.caches[cacheName]?.get(key);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
set(cacheName, key, value, ttl = undefined) {
|
|
54
|
+
return this.caches[cacheName]?.set(key, value, ttl);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
del(cacheName, key) {
|
|
58
|
+
return this.caches[cacheName]?.del(key);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
getStats(cacheName) {
|
|
62
|
+
return this.caches[cacheName]?.getStats();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
shutdown() {
|
|
66
|
+
if (this.memoryCheckInterval) {
|
|
67
|
+
clearInterval(this.memoryCheckInterval);
|
|
68
|
+
}
|
|
69
|
+
Object.values(this.caches).forEach(cache => cache.close());
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = new CacheManager();
|
package/lib/Utils/messages.js
CHANGED
|
@@ -248,10 +248,10 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
248
248
|
if ('text' in message) {
|
|
249
249
|
const extContent = { text: message.text };
|
|
250
250
|
let urlInfo = message.linkPreview;
|
|
251
|
-
if (
|
|
251
|
+
if (urlInfo === true) {
|
|
252
252
|
urlInfo = await (0, exports.generateLinkPreviewIfRequired)(message.text, options.getUrlInfo, options.logger);
|
|
253
253
|
}
|
|
254
|
-
if (urlInfo) {
|
|
254
|
+
if (urlInfo && typeof urlInfo === 'object') {
|
|
255
255
|
extContent.matchedText = urlInfo['matched-text'];
|
|
256
256
|
extContent.jpegThumbnail = urlInfo.jpegThumbnail;
|
|
257
257
|
extContent.description = urlInfo.description;
|
|
@@ -291,6 +291,9 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
291
291
|
else if ('location' in message) {
|
|
292
292
|
m.locationMessage = Types_1.WAProto.Message.LocationMessage.fromObject(message.location);
|
|
293
293
|
}
|
|
294
|
+
else if ('liveLocation' in message) {
|
|
295
|
+
m.liveLocationMessage = Types_1.WAProto.Message.LiveLocationMessage.fromObject(message.liveLocation);
|
|
296
|
+
}
|
|
294
297
|
else if ('react' in message) {
|
|
295
298
|
if (!message.react.senderTimestampMs) {
|
|
296
299
|
message.react.senderTimestampMs = Date.now();
|
|
@@ -459,23 +462,24 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
459
462
|
m.newsletterAdminInviteMessage.jpegThumbnail = message.inviteAdmin.thumbnail;
|
|
460
463
|
}
|
|
461
464
|
else if ('requestPayment' in message) {
|
|
462
|
-
const
|
|
463
|
-
|
|
465
|
+
const reqPayment = message.requestPayment;
|
|
466
|
+
const sticker = reqPayment.sticker ?
|
|
467
|
+
await (0, exports.prepareWAMessageMedia)({ sticker: reqPayment.sticker, ...options }, options)
|
|
464
468
|
: null;
|
|
465
469
|
let notes = {};
|
|
466
|
-
if (
|
|
470
|
+
if (reqPayment.sticker) {
|
|
467
471
|
notes = {
|
|
468
472
|
stickerMessage: {
|
|
469
|
-
...sticker
|
|
470
|
-
contextInfo:
|
|
473
|
+
...sticker.stickerMessage,
|
|
474
|
+
contextInfo: reqPayment.contextInfo
|
|
471
475
|
}
|
|
472
476
|
};
|
|
473
477
|
}
|
|
474
|
-
else if (
|
|
478
|
+
else if (reqPayment.note) {
|
|
475
479
|
notes = {
|
|
476
480
|
extendedTextMessage: {
|
|
477
|
-
text:
|
|
478
|
-
contextInfo:
|
|
481
|
+
text: reqPayment.note,
|
|
482
|
+
contextInfo: reqPayment.contextInfo,
|
|
479
483
|
}
|
|
480
484
|
};
|
|
481
485
|
}
|
|
@@ -483,12 +487,14 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
483
487
|
throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
|
|
484
488
|
}
|
|
485
489
|
m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
|
|
486
|
-
expiryTimestamp:
|
|
487
|
-
amount1000:
|
|
488
|
-
currencyCodeIso4217:
|
|
489
|
-
requestFrom:
|
|
490
|
+
expiryTimestamp: reqPayment.expiryTimestamp || reqPayment.expiry,
|
|
491
|
+
amount1000: reqPayment.amount1000 || reqPayment.amount,
|
|
492
|
+
currencyCodeIso4217: reqPayment.currencyCodeIso4217 || reqPayment.currency,
|
|
493
|
+
requestFrom: reqPayment.requestFrom || reqPayment.from,
|
|
490
494
|
noteMessage: { ...notes },
|
|
491
|
-
background:
|
|
495
|
+
background: reqPayment.background,
|
|
496
|
+
// Aggiungi altri parametri se disponibili
|
|
497
|
+
...reqPayment
|
|
492
498
|
});
|
|
493
499
|
}
|
|
494
500
|
else if ('sharePhoneNumber' in message) {
|
|
@@ -499,6 +505,12 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
499
505
|
else if ('requestPhoneNumber' in message) {
|
|
500
506
|
m.requestPhoneNumberMessage = {};
|
|
501
507
|
}
|
|
508
|
+
else if ('call' in message) {
|
|
509
|
+
m.callMessage = Types_1.WAProto.Message.CallMessage.fromObject(message.call);
|
|
510
|
+
}
|
|
511
|
+
else if ('newsletterMessage' in message) {
|
|
512
|
+
m.newsletterMessage = Types_1.WAProto.Message.NewsletterMessage.fromObject(message.newsletterMessage);
|
|
513
|
+
}
|
|
502
514
|
else if ('album' in message) {
|
|
503
515
|
const imageMessages = message.album.filter(item => 'image' in item);
|
|
504
516
|
const videoMessages = message.album.filter(item => 'video' in item);
|
|
@@ -541,29 +553,30 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
541
553
|
}
|
|
542
554
|
m = { buttonsMessage };
|
|
543
555
|
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
556
|
+
else if ('templateButtons' in message && !!message.templateButtons) {
|
|
557
|
+
const templateMsg = {
|
|
558
|
+
hydratedButtons: message.templateButtons
|
|
559
|
+
};
|
|
560
|
+
if ('text' in message) {
|
|
561
|
+
templateMsg.hydratedContentText = message.text;
|
|
562
|
+
}
|
|
563
|
+
else if ('caption' in message) {
|
|
564
|
+
templateMsg.hydratedContentText = message.caption;
|
|
565
|
+
}
|
|
566
|
+
if ('footer' in message && !!message.footer) {
|
|
567
|
+
templateMsg.hydratedFooterText = message.footer;
|
|
568
|
+
}
|
|
569
|
+
// Add media to template if present
|
|
570
|
+
if (m && Object.keys(m).length > 0) {
|
|
571
|
+
Object.assign(templateMsg, m);
|
|
572
|
+
}
|
|
573
|
+
m = {
|
|
574
|
+
templateMessage: {
|
|
575
|
+
fourRowTemplate: templateMsg,
|
|
576
|
+
hydratedTemplate: templateMsg
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
}
|
|
567
580
|
if ('sections' in message && !!message.sections) {
|
|
568
581
|
const listMessage = {
|
|
569
582
|
sections: message.sections,
|
|
@@ -759,7 +772,10 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
759
772
|
if ('contextInfo' in message && !!message.contextInfo) {
|
|
760
773
|
const [messageType] = Object.keys(m);
|
|
761
774
|
m[messageType] = m[messageType] || {};
|
|
762
|
-
m[messageType].contextInfo =
|
|
775
|
+
m[messageType].contextInfo = {
|
|
776
|
+
...m[messageType].contextInfo,
|
|
777
|
+
...message.contextInfo
|
|
778
|
+
};
|
|
763
779
|
}
|
|
764
780
|
return Types_1.WAProto.Message.fromObject(m);
|
|
765
781
|
};
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Configurazione performance per ottimizzazioni LID/JID
|
|
3
|
-
*/
|
|
4
|
-
export interface CacheConfig {
|
|
5
|
-
ttl: number;
|
|
6
|
-
maxSize: number;
|
|
7
|
-
cleanupInterval: number;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface PerformanceSettings {
|
|
11
|
-
enableCache: boolean;
|
|
12
|
-
enableLogging: boolean;
|
|
13
|
-
enableMetrics: boolean;
|
|
14
|
-
batchSize: number;
|
|
15
|
-
maxRetries: number;
|
|
16
|
-
retryDelay: number;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface DebugSettings {
|
|
20
|
-
enableLidLogging: boolean;
|
|
21
|
-
enablePerformanceLogging: boolean;
|
|
22
|
-
enableErrorLogging: boolean;
|
|
23
|
-
logLevel: 'error' | 'warn' | 'info' | 'debug';
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface PerformanceConfigInterface {
|
|
27
|
-
cache: {
|
|
28
|
-
lidCache: CacheConfig;
|
|
29
|
-
jidCache: CacheConfig;
|
|
30
|
-
lidToJidCache: CacheConfig;
|
|
31
|
-
};
|
|
32
|
-
performance: PerformanceSettings;
|
|
33
|
-
debug: DebugSettings;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export declare class PerformanceConfig implements PerformanceConfigInterface {
|
|
37
|
-
cache: {
|
|
38
|
-
lidCache: CacheConfig;
|
|
39
|
-
jidCache: CacheConfig;
|
|
40
|
-
lidToJidCache: CacheConfig;
|
|
41
|
-
};
|
|
42
|
-
performance: PerformanceSettings;
|
|
43
|
-
debug: DebugSettings;
|
|
44
|
-
|
|
45
|
-
updateCacheConfig(cacheType: string, config: Partial<CacheConfig>): void;
|
|
46
|
-
updatePerformanceConfig(config: Partial<PerformanceSettings>): void;
|
|
47
|
-
updateDebugConfig(config: Partial<DebugSettings>): void;
|
|
48
|
-
shouldLog(level: string): boolean;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export declare class Logger {
|
|
52
|
-
static error(message: string, ...args: any[]): void;
|
|
53
|
-
static warn(message: string, ...args: any[]): void;
|
|
54
|
-
static info(message: string, ...args: any[]): void;
|
|
55
|
-
static debug(message: string, ...args: any[]): void;
|
|
56
|
-
static performance(message: string, ...args: any[]): void;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export declare const getPerformanceConfig: () => PerformanceConfig;
|
|
60
|
-
export declare const setPerformanceConfig: (config: Partial<PerformanceConfigInterface> | PerformanceConfig) => void;
|
|
1
|
+
/**
|
|
2
|
+
* Configurazione performance per ottimizzazioni LID/JID
|
|
3
|
+
*/
|
|
4
|
+
export interface CacheConfig {
|
|
5
|
+
ttl: number;
|
|
6
|
+
maxSize: number;
|
|
7
|
+
cleanupInterval: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface PerformanceSettings {
|
|
11
|
+
enableCache: boolean;
|
|
12
|
+
enableLogging: boolean;
|
|
13
|
+
enableMetrics: boolean;
|
|
14
|
+
batchSize: number;
|
|
15
|
+
maxRetries: number;
|
|
16
|
+
retryDelay: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface DebugSettings {
|
|
20
|
+
enableLidLogging: boolean;
|
|
21
|
+
enablePerformanceLogging: boolean;
|
|
22
|
+
enableErrorLogging: boolean;
|
|
23
|
+
logLevel: 'error' | 'warn' | 'info' | 'debug';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface PerformanceConfigInterface {
|
|
27
|
+
cache: {
|
|
28
|
+
lidCache: CacheConfig;
|
|
29
|
+
jidCache: CacheConfig;
|
|
30
|
+
lidToJidCache: CacheConfig;
|
|
31
|
+
};
|
|
32
|
+
performance: PerformanceSettings;
|
|
33
|
+
debug: DebugSettings;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export declare class PerformanceConfig implements PerformanceConfigInterface {
|
|
37
|
+
cache: {
|
|
38
|
+
lidCache: CacheConfig;
|
|
39
|
+
jidCache: CacheConfig;
|
|
40
|
+
lidToJidCache: CacheConfig;
|
|
41
|
+
};
|
|
42
|
+
performance: PerformanceSettings;
|
|
43
|
+
debug: DebugSettings;
|
|
44
|
+
|
|
45
|
+
updateCacheConfig(cacheType: string, config: Partial<CacheConfig>): void;
|
|
46
|
+
updatePerformanceConfig(config: Partial<PerformanceSettings>): void;
|
|
47
|
+
updateDebugConfig(config: Partial<DebugSettings>): void;
|
|
48
|
+
shouldLog(level: string): boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export declare class Logger {
|
|
52
|
+
static error(message: string, ...args: any[]): void;
|
|
53
|
+
static warn(message: string, ...args: any[]): void;
|
|
54
|
+
static info(message: string, ...args: any[]): void;
|
|
55
|
+
static debug(message: string, ...args: any[]): void;
|
|
56
|
+
static performance(message: string, ...args: any[]): void;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export declare const getPerformanceConfig: () => PerformanceConfig;
|
|
60
|
+
export declare const setPerformanceConfig: (config: Partial<PerformanceConfigInterface> | PerformanceConfig) => void;
|