@fer2809fl/baileys 7.0.4 → 7.0.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 +347 -50
- package/lib/Defaults/index.js +1 -1
- package/lib/Modded/message_builder.js +2356 -0
- package/lib/Socket/chats.d.ts +14 -0
- package/lib/Socket/chats.js +48 -0
- package/lib/Socket/index.d.ts +17 -0
- package/lib/Socket/messages-send.d.ts +18 -0
- package/lib/Socket/messages-send.js +50 -2
- package/lib/Utils/anti-ban.d.ts +41 -0
- package/lib/Utils/anti-ban.js +182 -0
- package/lib/Utils/banner.d.ts +8 -0
- package/lib/Utils/banner.js +76 -0
- package/lib/Utils/bot-utils.d.ts +57 -0
- package/lib/Utils/bot-utils.js +241 -0
- package/lib/Utils/enhanced-cache.d.ts +40 -0
- package/lib/Utils/enhanced-cache.js +242 -0
- package/lib/Utils/enhanced-logger.d.ts +41 -0
- package/lib/Utils/enhanced-logger.js +185 -0
- package/lib/Utils/index.d.ts +14 -0
- package/lib/Utils/index.js +13 -0
- package/lib/Utils/lid-utils.d.ts +139 -0
- package/lib/Utils/lid-utils.js +503 -0
- package/lib/Utils/message-queue.d.ts +47 -0
- package/lib/Utils/message-queue.js +226 -0
- package/lib/Utils/rich-message-utils.d.ts +21 -0
- package/lib/Utils/rich-message-utils.js +229 -0
- package/lib/Utils/rich-messages.d.ts +52 -0
- package/lib/Utils/rich-messages.js +185 -0
- package/lib/Utils/scheduled-messages.d.ts +122 -0
- package/lib/Utils/scheduled-messages.js +289 -0
- package/lib/Utils/smart-reconnect.d.ts +48 -0
- package/lib/Utils/smart-reconnect.js +207 -0
- package/lib/Utils/use-sqlite-auth-state.d.ts +11 -0
- package/lib/Utils/use-sqlite-auth-state.js +95 -0
- package/lib/VoIP/audio-feeder.d.ts +15 -0
- package/lib/VoIP/audio-feeder.js +132 -0
- package/lib/VoIP/index.js +277 -0
- package/lib/VoIP/relay-transport.d.ts +43 -0
- package/lib/VoIP/relay-transport.js +559 -0
- package/lib/VoIP/signaling.js +594 -0
- package/lib/VoIP/types.d.ts +69 -0
- package/lib/VoIP/types.js +17 -0
- package/lib/VoIP/wasm-engine.d.ts +103 -0
- package/lib/VoIP/wasm-engine.js +1214 -0
- package/lib/VoIP/worker-bootstrap.js +1042 -0
- package/lib/assets/wasm/loader.js +5 -0
- package/lib/assets/wasm/whatsapp.wasm +0 -0
- package/lib/assets/wasm/worker-modules.js +273 -0
- package/lib/index.d.ts +41 -0
- package/lib/index.js +3 -0
- package/package.json +10 -2
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
import { jidDecode } from '../WABinary/index.js';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
|
|
5
|
+
const lidCache = new Map();
|
|
6
|
+
const LID_CACHE_PATH = join(process.cwd(), 'database', 'lid-cache.json');
|
|
7
|
+
let _persistDirty = false;
|
|
8
|
+
let _persistTimer = null;
|
|
9
|
+
|
|
10
|
+
function loadPersistentCache() {
|
|
11
|
+
try {
|
|
12
|
+
if (existsSync(LID_CACHE_PATH)) {
|
|
13
|
+
const data = JSON.parse(readFileSync(LID_CACHE_PATH, 'utf8'));
|
|
14
|
+
if (data && typeof data === 'object') {
|
|
15
|
+
for (const [k, v] of Object.entries(data)) {
|
|
16
|
+
if (lidCache.has(k)) lidCache.set(k, v);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
} catch { }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function savePersistentCache() {
|
|
24
|
+
if (!_persistDirty) return;
|
|
25
|
+
try {
|
|
26
|
+
const dirPath = join(process.cwd(), 'database');
|
|
27
|
+
if (!existsSync(dirPath)) mkdirSync(dirPath, { recursive: true });
|
|
28
|
+
const obj = Object.fromEntries(lidCache);
|
|
29
|
+
writeFileSync(LID_CACHE_PATH, JSON.stringify(obj));
|
|
30
|
+
_persistDirty = false;
|
|
31
|
+
} catch { }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function markDirty() {
|
|
35
|
+
_persistDirty = true;
|
|
36
|
+
if (!_persistTimer) {
|
|
37
|
+
_persistTimer = setTimeout(() => {
|
|
38
|
+
_persistTimer = null;
|
|
39
|
+
savePersistentCache();
|
|
40
|
+
}, 10000);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
loadPersistentCache();
|
|
45
|
+
process.on('exit', savePersistentCache);
|
|
46
|
+
process.on('SIGINT', () => {
|
|
47
|
+
savePersistentCache();
|
|
48
|
+
process.exit(0);
|
|
49
|
+
});
|
|
50
|
+
process.on('uncaughtException', (err) => {
|
|
51
|
+
savePersistentCache();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Cache LID to JID mapping
|
|
56
|
+
* Panggil ini saat memproses group metadata untuk menyimpan mapping
|
|
57
|
+
*
|
|
58
|
+
* HANDLES TWO DIFFERENT STRUCTURES:
|
|
59
|
+
* 1. groupMetadata.participants: { id: PN, lid: LID, admin }
|
|
60
|
+
* 2. GroupHandler events: { id: LID, phoneNumber: PN, admin }
|
|
61
|
+
*
|
|
62
|
+
* @param {Object[]} participants - Array participant
|
|
63
|
+
*/
|
|
64
|
+
function cacheParticipantLids(participants = []) {
|
|
65
|
+
for (const p of participants) {
|
|
66
|
+
let pLid = '';
|
|
67
|
+
let pJid = '';
|
|
68
|
+
|
|
69
|
+
if (p.lid && p.lid.endsWith('@lid')) {
|
|
70
|
+
pLid = p.lid;
|
|
71
|
+
pJid = p.id || p.jid || '';
|
|
72
|
+
} else if (p.phoneNumber) {
|
|
73
|
+
pLid = p.id || '';
|
|
74
|
+
pJid = p.phoneNumber;
|
|
75
|
+
} else if (p.id && p.id.endsWith('@lid')) {
|
|
76
|
+
pLid = p.id;
|
|
77
|
+
pJid = p.jid || '';
|
|
78
|
+
} else {
|
|
79
|
+
pLid = p.lid || '';
|
|
80
|
+
pJid = p.id || p.jid || '';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (
|
|
84
|
+
pLid &&
|
|
85
|
+
pJid &&
|
|
86
|
+
pLid.endsWith('@lid') &&
|
|
87
|
+
!pJid.endsWith('@lid') &&
|
|
88
|
+
!isLidConverted(pJid)
|
|
89
|
+
) {
|
|
90
|
+
lidCache.set(pLid, pJid);
|
|
91
|
+
const lidNumber = pLid.replace('@lid', '');
|
|
92
|
+
lidCache.set(lidNumber + '@s.whatsapp.net', pJid);
|
|
93
|
+
markDirty();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get cached JID for a LID
|
|
100
|
+
* @param {string} lid - LID atau LID-converted JID
|
|
101
|
+
* @returns {string|null} Cached JID atau null jika tidak ada
|
|
102
|
+
*/
|
|
103
|
+
function getCachedJid(lid) {
|
|
104
|
+
return lidCache.get(lid) || null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Cek apakah JID adalah format LID
|
|
109
|
+
* @param {string} jid - JID untuk dicek
|
|
110
|
+
* @returns {boolean} True jika LID
|
|
111
|
+
*/
|
|
112
|
+
function isLid(jid) {
|
|
113
|
+
if (!jid) return false;
|
|
114
|
+
return jid.endsWith('@lid');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Cek apakah JID adalah hasil konversi LID yang salah
|
|
119
|
+
* (JID dengan suffix @s.whatsapp.net tapi nomornya adalah LID number, bukan phone number)
|
|
120
|
+
* LID number biasanya: sangat panjang, tidak dimulai dengan kode negara normal
|
|
121
|
+
* @param {string} jid - JID untuk dicek
|
|
122
|
+
* @returns {boolean} True jika kemungkinan LID yang sudah dikonversi
|
|
123
|
+
*/
|
|
124
|
+
function isLidConverted(jid) {
|
|
125
|
+
if (!jid) return false;
|
|
126
|
+
if (!jid.endsWith('@s.whatsapp.net')) return false;
|
|
127
|
+
const number = jid.replace('@s.whatsapp.net', '');
|
|
128
|
+
if (number.length > 14) return true;
|
|
129
|
+
const validCountryCodes = [
|
|
130
|
+
'1', '7', '20', '27', '30', '31', '32', '33', '34', '36', '39', '40', '41', '43', '44', '45',
|
|
131
|
+
'46', '47', '48', '49', '51', '52', '53', '54', '55', '56', '57', '58',
|
|
132
|
+
'60', '61', '62', '63', '64', '65', '66',
|
|
133
|
+
'81', '82', '84', '86', '90', '91', '92', '93', '94', '95', '98',
|
|
134
|
+
'212', '213', '216', '218', '220', '221', '234', '249', '254', '255', '256', '260', '263',
|
|
135
|
+
'351', '352', '353', '354', '355', '356', '357', '358', '359',
|
|
136
|
+
'370', '371', '372', '373', '374', '375', '376', '377', '378', '380', '381', '382', '383', '385', '386', '387', '389',
|
|
137
|
+
'420', '421', '423',
|
|
138
|
+
'852', '853', '855', '856', '880', '886',
|
|
139
|
+
'960', '961', '962', '963', '964', '965', '966', '967', '968', '970', '971', '972', '973', '974', '975', '976', '977',
|
|
140
|
+
'992', '993', '994', '995', '996', '998',
|
|
141
|
+
];
|
|
142
|
+
for (const code of validCountryCodes) {
|
|
143
|
+
if (
|
|
144
|
+
number.startsWith(code) &&
|
|
145
|
+
number.length >= code.length + 6 &&
|
|
146
|
+
number.length <= code.length + 12
|
|
147
|
+
) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Convert LID ke format JID standard
|
|
156
|
+
* CATATAN: LID memiliki ID unik yang berbeda dari nomor telepon.
|
|
157
|
+
* Fungsi ini hanya mengganti suffix, untuk mendapatkan nomor asli
|
|
158
|
+
* gunakan resolveLidFromParticipants dengan group metadata.
|
|
159
|
+
* @param {string} jid - JID yang mungkin LID
|
|
160
|
+
* @returns {string} JID dalam format @s.whatsapp.net
|
|
161
|
+
*/
|
|
162
|
+
function lidToJid(jid) {
|
|
163
|
+
if (!jid) return jid;
|
|
164
|
+
const cached = lidCache.get(jid);
|
|
165
|
+
if (cached && !isLidConverted(cached)) return cached;
|
|
166
|
+
if (jid.endsWith('@lid')) {
|
|
167
|
+
const swJid = jid.replace('@lid', '@s.whatsapp.net');
|
|
168
|
+
const cached2 = lidCache.get(swJid);
|
|
169
|
+
if (cached2 && !isLidConverted(cached2)) return cached2;
|
|
170
|
+
return swJid;
|
|
171
|
+
}
|
|
172
|
+
return jid;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function lidToJidSafe(jid) {
|
|
176
|
+
if (!jid) return null;
|
|
177
|
+
const cached = lidCache.get(jid);
|
|
178
|
+
if (cached && !isLidConverted(cached)) return cached;
|
|
179
|
+
if (jid.endsWith('@lid')) {
|
|
180
|
+
const swJid = jid.replace('@lid', '@s.whatsapp.net');
|
|
181
|
+
const cached2 = lidCache.get(swJid);
|
|
182
|
+
if (cached2 && !isLidConverted(cached2)) return cached2;
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Extract nomor dari JID apapun (termasuk LID)
|
|
189
|
+
* @param {string} jid - JID
|
|
190
|
+
* @returns {string} Nomor telepon
|
|
191
|
+
*/
|
|
192
|
+
async function extractNumber(jid) {
|
|
193
|
+
if (!jid) return '';
|
|
194
|
+
return jid.replace(/@.+/g, '');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Resolve LID atau LID-converted JID ke JID asli menggunakan group metadata
|
|
199
|
+
* Participant structure dari ourin (groups.js):
|
|
200
|
+
* - id: phone_number atau jid (tergantung addressingMode)
|
|
201
|
+
* - lid: LID format
|
|
202
|
+
* - admin: type admin
|
|
203
|
+
* @param {string} jid - JID yang mungkin LID atau LID-converted
|
|
204
|
+
* @param {Object[]} participants - Array participant dari group metadata
|
|
205
|
+
* @returns {string} JID yang sudah resolve ke nomor asli
|
|
206
|
+
*/
|
|
207
|
+
function resolveLidFromParticipants(jid, participants = []) {
|
|
208
|
+
if (!jid) return jid;
|
|
209
|
+
if (!participants || participants.length === 0) return jid;
|
|
210
|
+
|
|
211
|
+
const lidNumber = jid.replace(/@.*$/, '');
|
|
212
|
+
const lidFormat = lidNumber + '@lid';
|
|
213
|
+
|
|
214
|
+
for (const p of participants) {
|
|
215
|
+
let pLid = '';
|
|
216
|
+
let pJid = '';
|
|
217
|
+
|
|
218
|
+
if (p.lid && p.lid.endsWith('@lid')) {
|
|
219
|
+
pLid = p.lid;
|
|
220
|
+
pJid = p.id || p.jid || '';
|
|
221
|
+
} else if (p.phoneNumber) {
|
|
222
|
+
pLid = p.id || '';
|
|
223
|
+
pJid = p.phoneNumber;
|
|
224
|
+
} else if (p.id && p.id.endsWith('@lid')) {
|
|
225
|
+
pLid = p.id;
|
|
226
|
+
pJid = p.jid || '';
|
|
227
|
+
} else {
|
|
228
|
+
pLid = p.lid || '';
|
|
229
|
+
pJid = p.id || p.jid || '';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const pLidNumber = pLid.replace('@lid', '');
|
|
233
|
+
|
|
234
|
+
if (pLid === lidFormat || pLid === jid || pLidNumber === lidNumber) {
|
|
235
|
+
if (pJid && !pJid.endsWith('@lid') && !isLidConverted(pJid)) {
|
|
236
|
+
return pJid;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return isLid(jid) ? lidToJid(jid) : jid;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Resolve JID yang mungkin LID-converted ke JID asli
|
|
246
|
+
* Fungsi ini menangani case dimana JID sudah punya @s.whatsapp.net tapi nomornya adalah LID number
|
|
247
|
+
* @param {string} jid - JID untuk diresolve
|
|
248
|
+
* @param {Object[]} participants - Array participant dari group metadata
|
|
249
|
+
* @returns {string} JID dengan nomor telepon asli
|
|
250
|
+
*/
|
|
251
|
+
function resolveAnyLidToJid(jid, participants = []) {
|
|
252
|
+
if (!jid) return jid;
|
|
253
|
+
|
|
254
|
+
const cached = getCachedJid(jid);
|
|
255
|
+
if (cached) {
|
|
256
|
+
return cached;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (jid.endsWith('@s.whatsapp.net')) {
|
|
260
|
+
const lidFormat = jid.replace('@s.whatsapp.net', '@lid');
|
|
261
|
+
const cachedFromLid = getCachedJid(lidFormat);
|
|
262
|
+
if (cachedFromLid) {
|
|
263
|
+
return cachedFromLid;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (!participants || participants.length === 0) return jid;
|
|
268
|
+
|
|
269
|
+
cacheParticipantLids(participants);
|
|
270
|
+
|
|
271
|
+
if (isLid(jid)) {
|
|
272
|
+
const resolved = resolveLidFromParticipants(jid, participants);
|
|
273
|
+
if (resolved !== jid && !isLidConverted(resolved)) {
|
|
274
|
+
lidCache.set(jid, resolved);
|
|
275
|
+
}
|
|
276
|
+
return resolved;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (isLidConverted(jid)) {
|
|
280
|
+
const lidNumber = jid.replace('@s.whatsapp.net', '');
|
|
281
|
+
const lidFormat = lidNumber + '@lid';
|
|
282
|
+
|
|
283
|
+
for (const p of participants) {
|
|
284
|
+
let pLid = '';
|
|
285
|
+
let pJid = '';
|
|
286
|
+
|
|
287
|
+
if (p.lid && p.lid.endsWith('@lid')) {
|
|
288
|
+
pLid = p.lid;
|
|
289
|
+
pJid = p.id || p.jid || '';
|
|
290
|
+
} else if (p.phoneNumber) {
|
|
291
|
+
pLid = p.id || '';
|
|
292
|
+
pJid = p.phoneNumber;
|
|
293
|
+
} else if (p.id && p.id.endsWith('@lid')) {
|
|
294
|
+
pLid = p.id;
|
|
295
|
+
pJid = p.jid || '';
|
|
296
|
+
} else {
|
|
297
|
+
pLid = p.lid || '';
|
|
298
|
+
pJid = p.id || p.jid || '';
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (pLid === lidFormat || pLid === jid) {
|
|
302
|
+
if (pJid && !pJid.endsWith('@lid') && !isLidConverted(pJid)) {
|
|
303
|
+
lidCache.set(jid, pJid);
|
|
304
|
+
lidCache.set(lidFormat, pJid);
|
|
305
|
+
return pJid;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const pLidNumber = pLid.replace('@lid', '');
|
|
310
|
+
if (pLidNumber === lidNumber) {
|
|
311
|
+
if (pJid && !pJid.endsWith('@lid') && !isLidConverted(pJid)) {
|
|
312
|
+
lidCache.set(jid, pJid);
|
|
313
|
+
lidCache.set(pLid, pJid);
|
|
314
|
+
return pJid;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return jid;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Convert array of JIDs, replacing any LIDs or LID-converted JIDs
|
|
325
|
+
* @param {string[]} jids - Array of JIDs
|
|
326
|
+
* @param {Object[]} participants - Optional group participants
|
|
327
|
+
* @returns {string[]} Array of converted JIDs
|
|
328
|
+
*/
|
|
329
|
+
function convertLidArray(jids, participants = []) {
|
|
330
|
+
if (!Array.isArray(jids)) return [];
|
|
331
|
+
return jids.map((jid) => resolveAnyLidToJid(jid, participants));
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Decode JID dan kembalikan dalam format standard
|
|
336
|
+
* @param {string} jid - JID untuk didecode
|
|
337
|
+
* @returns {string|null} JID yang sudah didecode atau null
|
|
338
|
+
*/
|
|
339
|
+
function decodeAndNormalize(jid) {
|
|
340
|
+
if (!jid) return null;
|
|
341
|
+
if (isLid(jid)) {
|
|
342
|
+
jid = lidToJid(jid);
|
|
343
|
+
}
|
|
344
|
+
if (/:\d+@/gi.test(jid)) {
|
|
345
|
+
const decoded = jidDecode(jid) || {};
|
|
346
|
+
if (decoded.user && decoded.server) {
|
|
347
|
+
return decoded.user + '@' + decoded.server;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return jid;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Konversi participant JID dari message
|
|
355
|
+
* @param {Object} msg - Message object
|
|
356
|
+
* @param {Object} sock - Socket connection
|
|
357
|
+
* @returns {Promise<string>} Resolved participant JID
|
|
358
|
+
*/
|
|
359
|
+
async function resolveParticipant(msg, sock) {
|
|
360
|
+
const participant = msg.key?.participant;
|
|
361
|
+
if (!participant) return null;
|
|
362
|
+
if (!isLid(participant)) return participant;
|
|
363
|
+
|
|
364
|
+
if (msg.participantPn) {
|
|
365
|
+
return msg.participantPn;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (msg.key?.remoteJid?.endsWith('@g.us') && sock) {
|
|
369
|
+
try {
|
|
370
|
+
const metadata = await sock.groupMetadata(msg.key.remoteJid);
|
|
371
|
+
return resolveLidFromParticipants(participant, metadata.participants);
|
|
372
|
+
} catch {
|
|
373
|
+
// Fallback
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return lidToJid(participant);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Helper untuk mendapatkan JID asli dari participant (dengan group metadata)
|
|
382
|
+
* @param {Object} participant - Participant object dari groupMetadata.participants
|
|
383
|
+
* @returns {string} JID yang bisa digunakan untuk mention
|
|
384
|
+
*/
|
|
385
|
+
function getParticipantJid(participant) {
|
|
386
|
+
if (!participant) return '';
|
|
387
|
+
if (
|
|
388
|
+
participant.jid &&
|
|
389
|
+
!participant.jid.endsWith('@lid') &&
|
|
390
|
+
!isLidConverted(participant.jid)
|
|
391
|
+
) {
|
|
392
|
+
return participant.jid;
|
|
393
|
+
}
|
|
394
|
+
if (
|
|
395
|
+
participant.id &&
|
|
396
|
+
!participant.id.endsWith('@lid') &&
|
|
397
|
+
!isLidConverted(participant.id)
|
|
398
|
+
) {
|
|
399
|
+
return participant.id;
|
|
400
|
+
}
|
|
401
|
+
return lidToJid(participant.id || participant.lid || '');
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Convert semua participant IDs ke format yang bisa di-mention
|
|
406
|
+
* @param {Object[]} participants - Array participant dari groupMetadata
|
|
407
|
+
* @returns {string[]} Array of JIDs
|
|
408
|
+
*/
|
|
409
|
+
function getParticipantJids(participants = []) {
|
|
410
|
+
return participants.map((p) => getParticipantJid(p));
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function findParticipantByNumber(participants, targetJid) {
|
|
414
|
+
if (!participants || !targetJid) return null;
|
|
415
|
+
const targetNumber = targetJid.replace(/@.*$/, '');
|
|
416
|
+
for (const p of participants) {
|
|
417
|
+
const pId = (p.id || '').replace(/@.*$/, '');
|
|
418
|
+
const pJid = (p.jid || '').replace(/@.*$/, '');
|
|
419
|
+
const pLid = (p.lid || '').replace(/@.*$/, '');
|
|
420
|
+
if (
|
|
421
|
+
pId === targetNumber ||
|
|
422
|
+
pJid === targetNumber ||
|
|
423
|
+
pLid === targetNumber
|
|
424
|
+
) {
|
|
425
|
+
return p;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return null;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function normalizeToPhoneNumber(jid, participants = []) {
|
|
432
|
+
if (!jid) return '';
|
|
433
|
+
const cached = getCachedJid(jid);
|
|
434
|
+
if (cached && !isLidConverted(cached)) {
|
|
435
|
+
return cached.replace(/@.+/g, '').replace(/[^0-9]/g, '');
|
|
436
|
+
}
|
|
437
|
+
if (isLid(jid) || isLidConverted(jid)) {
|
|
438
|
+
const resolved = resolveAnyLidToJid(jid, participants);
|
|
439
|
+
if (resolved && !isLidConverted(resolved)) {
|
|
440
|
+
return resolved.replace(/@.+/g, '').replace(/[^0-9]/g, '');
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return jid.replace(/@.+/g, '').replace(/[^0-9]/g, '');
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
function cacheLidJid(lid, jid) {
|
|
447
|
+
if (!lid || !jid) return;
|
|
448
|
+
if (isLid(jid) || isLidConverted(jid)) return;
|
|
449
|
+
lidCache.set(lid, jid);
|
|
450
|
+
markDirty();
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
async function resolveFromSock(jid, sock) {
|
|
454
|
+
if (!jid || !sock) return jid;
|
|
455
|
+
try {
|
|
456
|
+
const repo = sock.signalRepository || sock.repository;
|
|
457
|
+
if (repo?.lidMapping?.getPNForLID) {
|
|
458
|
+
const pn = await repo.lidMapping.getPNForLID(jid);
|
|
459
|
+
if (pn && !isLid(pn) && !isLidConverted(pn)) {
|
|
460
|
+
cacheLidJid(jid, pn);
|
|
461
|
+
return pn;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
if (sock.store && sock.store.contacts) {
|
|
465
|
+
for (const [pnJid, contact] of Object.entries(sock.store.contacts)) {
|
|
466
|
+
if (contact.lid === jid || contact.id === jid) {
|
|
467
|
+
if (pnJid && !isLid(pnJid) && !isLidConverted(pnJid) && pnJid !== 'status@broadcast') {
|
|
468
|
+
cacheLidJid(jid, pnJid);
|
|
469
|
+
return pnJid;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
} catch { }
|
|
475
|
+
return jid;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
function getLidCacheSize() {
|
|
479
|
+
return lidCache.size;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
export {
|
|
483
|
+
isLid,
|
|
484
|
+
isLidConverted,
|
|
485
|
+
lidToJid,
|
|
486
|
+
lidToJidSafe,
|
|
487
|
+
extractNumber,
|
|
488
|
+
resolveLidFromParticipants,
|
|
489
|
+
resolveAnyLidToJid,
|
|
490
|
+
convertLidArray,
|
|
491
|
+
decodeAndNormalize,
|
|
492
|
+
resolveParticipant,
|
|
493
|
+
getParticipantJid,
|
|
494
|
+
getParticipantJids,
|
|
495
|
+
findParticipantByNumber,
|
|
496
|
+
cacheParticipantLids,
|
|
497
|
+
getCachedJid,
|
|
498
|
+
normalizeToPhoneNumber,
|
|
499
|
+
cacheLidJid,
|
|
500
|
+
resolveFromSock,
|
|
501
|
+
getLidCacheSize,
|
|
502
|
+
savePersistentCache,
|
|
503
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export declare const PRIORITY: {
|
|
2
|
+
CRITICAL: 0;
|
|
3
|
+
HIGH: 1;
|
|
4
|
+
NORMAL: 2;
|
|
5
|
+
LOW: 3;
|
|
6
|
+
BACKGROUND: 4;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export declare const QUEUE_CONFIG: {
|
|
10
|
+
MAX_QUEUE_SIZE: number;
|
|
11
|
+
PROCESS_INTERVAL: number;
|
|
12
|
+
RATE_LIMITS: Record<'message' | 'group' | 'media' | 'broadcast', { count: number; window: number }>;
|
|
13
|
+
DELAYS: Record<'message' | 'group' | 'media' | 'broadcast', number>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export declare class QueueItem {
|
|
17
|
+
constructor(task: (() => Promise<any>) | any, priority?: number, metadata?: { jid?: string; type?: string; maxAttempts?: number; allowDuplicate?: boolean; contentHash?: string });
|
|
18
|
+
id: string;
|
|
19
|
+
task: (() => Promise<any>) | any;
|
|
20
|
+
priority: number;
|
|
21
|
+
metadata: Record<string, any>;
|
|
22
|
+
createdAt: number;
|
|
23
|
+
attempts: number;
|
|
24
|
+
maxAttempts: number;
|
|
25
|
+
status: 'pending' | 'processing' | 'completed' | 'failed';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export declare class MessageQueue {
|
|
29
|
+
constructor(logger?: any, config?: Partial<typeof QUEUE_CONFIG>);
|
|
30
|
+
enqueue(task: (() => Promise<any>) | any, priority?: number, metadata?: { jid?: string; type?: string; maxAttempts?: number; allowDuplicate?: boolean; contentHash?: string }): string | null;
|
|
31
|
+
pause(): void;
|
|
32
|
+
resume(): void;
|
|
33
|
+
clear(priority?: number | null): void;
|
|
34
|
+
getStats(): {
|
|
35
|
+
totalQueued: number;
|
|
36
|
+
totalProcessed: number;
|
|
37
|
+
totalFailed: number;
|
|
38
|
+
averageWaitTime: number;
|
|
39
|
+
currentQueueSize: number;
|
|
40
|
+
isProcessing: boolean;
|
|
41
|
+
isPaused: boolean;
|
|
42
|
+
pendingByPriority: Record<'critical' | 'high' | 'normal' | 'low' | 'background', number>;
|
|
43
|
+
};
|
|
44
|
+
cleanup(): void;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export declare function createMessageQueue(logger?: any, customConfig?: Partial<typeof QUEUE_CONFIG>): MessageQueue;
|