@charape/baileys 1.0.8 → 1.0.10
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/lib/Defaults/index.js +4 -2
- package/lib/Socket/chats.js +39 -6
- package/lib/Socket/index.js +2 -1
- package/lib/Socket/message-builder.js +20 -8
- package/lib/Socket/messages-recv.js +44 -9
- package/lib/Socket/messages-send.js +139 -189
- package/lib/Socket/socket.js +41 -20
- package/lib/Store/make-cache-manager-store.js +22 -3
- package/lib/Utils/charape-runtime.js +230 -0
- package/lib/Utils/decode-wa-message.js +9 -3
- package/lib/Utils/index.js +1 -0
- package/lib/Utils/tc-token-utils.js +1 -1
- package/lib/index.cjs +494 -217
- package/lib/index.js +4 -3
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import NodeCache from '@cacheable/node-cache';
|
|
|
2
2
|
import { Boom } from '@hapi/boom';
|
|
3
3
|
import { proto } from '../../WAProto/index.js';
|
|
4
4
|
import { DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
|
|
5
|
-
import { aggregateMessageKeysNotFromMe, assertMediaContent, assertMeId, bindWaitForEvent, decryptMediaRetryData, DEF_MEDIA_HOST, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateIOSMessageID, generateParticipantHashV2, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, uploadFile, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, unixTimestampSeconds, setBotMessageSecret } from '../Utils/index.js';
|
|
5
|
+
import { aggregateMessageKeysNotFromMe, assertMediaContent, assertMeId, bindWaitForEvent, decryptMediaRetryData, DEF_MEDIA_HOST, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateIOSMessageID, generateParticipantHashV2, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, uploadFile, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, printCharapeChatLog, unixTimestampSeconds, setBotMessageSecret } from '../Utils/index.js';
|
|
6
6
|
import { getUrlInfo } from '../Utils/link-preview.js';
|
|
7
7
|
import { makeKeyedMutex, makeMutex } from '../Utils/make-mutex.js';
|
|
8
8
|
import { getMessageReportingToken, shouldIncludeReportingToken } from '../Utils/reporting-utils.js';
|
|
@@ -24,6 +24,12 @@ export const makeMessagesSocket = (config) => {
|
|
|
24
24
|
* Entries are always removed in `.finally()`, so the set is bounded by concurrency.
|
|
25
25
|
*/
|
|
26
26
|
const inFlightTcTokenIssuance = new Set();
|
|
27
|
+
registerSocketEndHandler(() => {
|
|
28
|
+
inFlightTcTokenIssuance.clear();
|
|
29
|
+
if (!config.userDevicesCache && userDevicesCache?.close) {
|
|
30
|
+
userDevicesCache.close();
|
|
31
|
+
}
|
|
32
|
+
});
|
|
27
33
|
const userDevicesCache = config.userDevicesCache ||
|
|
28
34
|
new NodeCache({
|
|
29
35
|
stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
|
|
@@ -312,33 +318,53 @@ export const makeMessagesSocket = (config) => {
|
|
|
312
318
|
}
|
|
313
319
|
if (jidsRequiringFetch.length) {
|
|
314
320
|
// LID if mapped, otherwise original
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
321
|
+
const pnJids = jidsRequiringFetch.filter(jid => !!isPnUser(jid) || !!isHostedPnUser(jid));
|
|
322
|
+
const lidMappings = pnJids.length
|
|
323
|
+
? ((await signalRepository.lidMapping.getLIDsForPNs(pnJids)) || [])
|
|
324
|
+
: [];
|
|
325
|
+
const mappedByPnKey = new Map();
|
|
326
|
+
for (const { pn, lid } of lidMappings) {
|
|
327
|
+
if (!pn || !lid)
|
|
328
|
+
continue;
|
|
329
|
+
const d = jidDecode(pn);
|
|
330
|
+
if (d?.user) {
|
|
331
|
+
mappedByPnKey.set(`${d.user}:${d.device || 0}:${d.server}`, lid);
|
|
332
|
+
}
|
|
333
|
+
mappedByPnKey.set(pn, lid);
|
|
334
|
+
}
|
|
335
|
+
const wireJids = [...new Set(jidsRequiringFetch.map(jid => {
|
|
336
|
+
if (isPnUser(jid) || isHostedPnUser(jid)) {
|
|
337
|
+
const d = jidDecode(jid);
|
|
338
|
+
const key = d?.user ? `${d.user}:${d.device || 0}:${d.server}` : jid;
|
|
339
|
+
return mappedByPnKey.get(key) || mappedByPnKey.get(jid) || jid;
|
|
340
|
+
}
|
|
341
|
+
return jid;
|
|
342
|
+
}))];
|
|
319
343
|
logger.debug({ jidsRequiringFetch, wireJids }, 'fetching sessions');
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
344
|
+
if (wireJids.length) {
|
|
345
|
+
const result = await query({
|
|
346
|
+
tag: 'iq',
|
|
347
|
+
attrs: {
|
|
348
|
+
xmlns: 'encrypt',
|
|
349
|
+
type: 'get',
|
|
350
|
+
to: S_WHATSAPP_NET
|
|
351
|
+
},
|
|
352
|
+
content: [
|
|
353
|
+
{
|
|
354
|
+
tag: 'key',
|
|
355
|
+
attrs: {},
|
|
356
|
+
content: wireJids.map(jid => {
|
|
357
|
+
const attrs = { jid };
|
|
358
|
+
if (force)
|
|
359
|
+
attrs.reason = 'identity';
|
|
360
|
+
return { tag: 'user', attrs };
|
|
361
|
+
})
|
|
362
|
+
}
|
|
363
|
+
]
|
|
364
|
+
});
|
|
365
|
+
await parseAndInjectE2ESessions(result, signalRepository);
|
|
366
|
+
didFetchNewSession = true;
|
|
367
|
+
}
|
|
342
368
|
}
|
|
343
369
|
return didFetchNewSession;
|
|
344
370
|
};
|
|
@@ -447,19 +473,25 @@ export const makeMessagesSocket = (config) => {
|
|
|
447
473
|
}
|
|
448
474
|
const ctx = target.contextInfo;
|
|
449
475
|
ctx.isForwarded = true;
|
|
450
|
-
ctx.forwardingScore
|
|
476
|
+
if (typeof ctx.forwardingScore !== 'number' || ctx.forwardingScore <= 0) {
|
|
477
|
+
ctx.forwardingScore = 999;
|
|
478
|
+
}
|
|
451
479
|
|
|
452
480
|
const existingFwd = ctx.forwardedNewsletterMessageInfo || {};
|
|
481
|
+
const hasExplicitCustomNewsletter = typeof existingFwd.newsletterJid === 'string' && existingFwd.newsletterJid.endsWith('@newsletter') && existingFwd.newsletterJid !== '0@newsletter';
|
|
453
482
|
const sMsgId = (typeof existingFwd.serverMessageId === 'number' && existingFwd.serverMessageId > 0)
|
|
454
483
|
? existingFwd.serverMessageId
|
|
455
484
|
: targetServerMessageId;
|
|
456
485
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
486
|
+
if (!hasExplicitCustomNewsletter) {
|
|
487
|
+
ctx.forwardedNewsletterMessageInfo = {
|
|
488
|
+
newsletterJid: targetNewsletterJid,
|
|
489
|
+
newsletterName: existingFwd.newsletterName || targetNewsletterName,
|
|
490
|
+
serverMessageId: sMsgId,
|
|
491
|
+
contentType: existingFwd.contentType || 1,
|
|
492
|
+
accessibilityText: existingFwd.accessibilityText || targetNewsletterName
|
|
493
|
+
};
|
|
494
|
+
}
|
|
463
495
|
};
|
|
464
496
|
|
|
465
497
|
const defaultMediaAnnotations = [
|
|
@@ -472,7 +504,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
472
504
|
],
|
|
473
505
|
newsletter: {
|
|
474
506
|
newsletterJid: targetNewsletterJid,
|
|
475
|
-
serverMessageId:
|
|
507
|
+
serverMessageId: targetServerMessageId,
|
|
476
508
|
newsletterName: targetNewsletterName,
|
|
477
509
|
contentType: 'UPDATE'
|
|
478
510
|
}
|
|
@@ -499,121 +531,48 @@ export const makeMessagesSocket = (config) => {
|
|
|
499
531
|
applyToContext(im.header.imageMessage);
|
|
500
532
|
applyMediaAnnotations(im.header.imageMessage);
|
|
501
533
|
}
|
|
502
|
-
if (im.header.documentMessage)
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
if (!im.nativeFlowMessage) {
|
|
506
|
-
im.nativeFlowMessage = { buttons: [], messageParamsJson: '' };
|
|
507
|
-
}
|
|
508
|
-
if (!Array.isArray(im.nativeFlowMessage.buttons)) {
|
|
509
|
-
im.nativeFlowMessage.buttons = [];
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
const buttons = im.nativeFlowMessage.buttons;
|
|
513
|
-
let ctaIndex = buttons.findIndex(b => b && b.name === 'cta_url');
|
|
514
|
-
|
|
515
|
-
if (ctaIndex !== -1) {
|
|
516
|
-
try {
|
|
517
|
-
const ctaParams = JSON.parse(buttons[ctaIndex].buttonParamsJson || '{}');
|
|
518
|
-
ctaParams.url = targetChannelUrl;
|
|
519
|
-
ctaParams.merchant_url = targetChannelUrl;
|
|
520
|
-
buttons[ctaIndex].buttonParamsJson = JSON.stringify(ctaParams);
|
|
521
|
-
} catch (_) {}
|
|
522
|
-
} else if (buttons.length > 0 && buttons[0]) {
|
|
523
|
-
ctaIndex = 0;
|
|
524
|
-
try {
|
|
525
|
-
const btn0Params = JSON.parse(buttons[0].buttonParamsJson || '{}');
|
|
526
|
-
btn0Params.url = targetChannelUrl;
|
|
527
|
-
btn0Params.merchant_url = targetChannelUrl;
|
|
528
|
-
btn0Params.canonical_url = targetChannelUrl;
|
|
529
|
-
buttons[0].buttonParamsJson = JSON.stringify(btn0Params);
|
|
530
|
-
} catch (_) {}
|
|
531
|
-
} else {
|
|
532
|
-
ctaIndex = 0;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
let params = {};
|
|
536
|
-
if (im.nativeFlowMessage.messageParamsJson) {
|
|
537
|
-
try {
|
|
538
|
-
params = typeof im.nativeFlowMessage.messageParamsJson === 'string'
|
|
539
|
-
? JSON.parse(im.nativeFlowMessage.messageParamsJson)
|
|
540
|
-
: (im.nativeFlowMessage.messageParamsJson || {});
|
|
541
|
-
} catch (_) {
|
|
542
|
-
params = {};
|
|
534
|
+
if (im.header.documentMessage) {
|
|
535
|
+
applyToContext(im.header.documentMessage);
|
|
543
536
|
}
|
|
544
537
|
}
|
|
545
538
|
|
|
546
|
-
//
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
params.limited_time_offer.text = targetNewsletterName;
|
|
558
|
-
params.limited_time_offer.copy_code = targetChannelUrl;
|
|
559
|
-
} else {
|
|
560
|
-
params.limited_time_offer = {
|
|
561
|
-
text: targetNewsletterName,
|
|
562
|
-
url: targetChannelUrl,
|
|
563
|
-
copy_code: targetChannelUrl,
|
|
564
|
-
expiration_time: Date.now() + 2592000000
|
|
565
|
-
};
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
im.nativeFlowMessage.messageParamsJson = JSON.stringify(params);
|
|
569
|
-
};
|
|
570
|
-
|
|
571
|
-
// 1. groupStatusMessageV2 (Story / Status Grup)
|
|
572
|
-
if (msg.groupStatusMessageV2) {
|
|
573
|
-
const statusMsg = msg.groupStatusMessageV2;
|
|
574
|
-
const inner = statusMsg.message;
|
|
575
|
-
if (inner && typeof inner === 'object') {
|
|
576
|
-
const subTypes = [
|
|
577
|
-
'extendedTextMessage',
|
|
578
|
-
'imageMessage',
|
|
579
|
-
'videoMessage',
|
|
580
|
-
'audioMessage',
|
|
581
|
-
'documentMessage',
|
|
582
|
-
'protocolMessage'
|
|
583
|
-
];
|
|
584
|
-
let foundSub = false;
|
|
585
|
-
for (const type of subTypes) {
|
|
586
|
-
if (inner[type]) {
|
|
587
|
-
applyToContext(inner[type]);
|
|
588
|
-
if (type === 'imageMessage' || type === 'videoMessage') {
|
|
589
|
-
applyMediaAnnotations(inner[type]);
|
|
590
|
-
}
|
|
591
|
-
foundSub = true;
|
|
539
|
+
// Preserve caller buttons/CTA links untouched; only attach non-destructive
|
|
540
|
+
// tap target metadata when media attachment exists without explicit buttons or tap target.
|
|
541
|
+
if (im.header?.hasMediaAttachment && im.nativeFlowMessage && Array.isArray(im.nativeFlowMessage.buttons) && im.nativeFlowMessage.buttons.length === 0) {
|
|
542
|
+
let params = {};
|
|
543
|
+
if (im.nativeFlowMessage.messageParamsJson) {
|
|
544
|
+
try {
|
|
545
|
+
params = typeof im.nativeFlowMessage.messageParamsJson === 'string'
|
|
546
|
+
? JSON.parse(im.nativeFlowMessage.messageParamsJson)
|
|
547
|
+
: (im.nativeFlowMessage.messageParamsJson || {});
|
|
548
|
+
} catch {
|
|
549
|
+
params = {};
|
|
592
550
|
}
|
|
593
551
|
}
|
|
594
|
-
if (!
|
|
595
|
-
|
|
552
|
+
if (!params.tap_target_configuration) {
|
|
553
|
+
params.tap_target_configuration = {
|
|
554
|
+
title: targetNewsletterName,
|
|
555
|
+
description: 'Lihat Saluran Resmi',
|
|
556
|
+
canonical_url: targetChannelUrl,
|
|
557
|
+
domain: 'whatsapp.com',
|
|
558
|
+
button_index: 0
|
|
559
|
+
};
|
|
560
|
+
im.nativeFlowMessage.messageParamsJson = JSON.stringify(params);
|
|
596
561
|
}
|
|
597
562
|
}
|
|
598
|
-
|
|
599
|
-
}
|
|
563
|
+
};
|
|
600
564
|
|
|
601
|
-
//
|
|
565
|
+
// 1. Protocol / non-display messages
|
|
602
566
|
if (msg.protocolMessage || msg.reactionMessage || msg.pollUpdateMessage ||
|
|
603
567
|
msg.senderKeyDistributionMessage || msg.fastRatchetSenderKeyDistributionMessage ||
|
|
604
568
|
msg.keepInChatMessage || msg.call || msg.chat) {
|
|
605
569
|
return msg;
|
|
606
570
|
}
|
|
607
571
|
|
|
608
|
-
// 3. Direct interactiveMessage
|
|
609
|
-
if (msg.interactiveMessage) {
|
|
610
|
-
processInteractiveMessage(msg.interactiveMessage);
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
// 4. Direct media & text types
|
|
614
572
|
const directTypes = [
|
|
615
573
|
'imageMessage',
|
|
616
574
|
'videoMessage',
|
|
575
|
+
'ptvMessage',
|
|
617
576
|
'audioMessage',
|
|
618
577
|
'documentMessage',
|
|
619
578
|
'stickerMessage',
|
|
@@ -625,25 +584,39 @@ export const makeMessagesSocket = (config) => {
|
|
|
625
584
|
'eventMessage'
|
|
626
585
|
];
|
|
627
586
|
|
|
628
|
-
|
|
629
|
-
|
|
587
|
+
const applyAttributionToContainer = (container) => {
|
|
588
|
+
if (!container || typeof container !== 'object') return false;
|
|
589
|
+
let didInject = false;
|
|
590
|
+
if (container.interactiveMessage) {
|
|
591
|
+
processInteractiveMessage(container.interactiveMessage);
|
|
592
|
+
didInject = true;
|
|
593
|
+
}
|
|
594
|
+
for (const type of directTypes) {
|
|
595
|
+
if (container[type] && typeof container[type] === 'object') {
|
|
596
|
+
applyToContext(container[type]);
|
|
597
|
+
if (type === 'imageMessage' || type === 'videoMessage' || type === 'ptvMessage') {
|
|
598
|
+
applyMediaAnnotations(container[type]);
|
|
599
|
+
}
|
|
600
|
+
didInject = true;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return didInject;
|
|
604
|
+
};
|
|
630
605
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
606
|
+
// 2. groupStatusMessageV2 (Story / Status Grup)
|
|
607
|
+
if (msg.groupStatusMessageV2) {
|
|
608
|
+
const inner = msg.groupStatusMessageV2.message;
|
|
609
|
+
if (inner && typeof inner === 'object') {
|
|
610
|
+
const didInject = applyAttributionToContainer(inner);
|
|
611
|
+
if (!didInject && inner.contextInfo) {
|
|
612
|
+
applyToContext(inner);
|
|
636
613
|
}
|
|
637
|
-
injected = true;
|
|
638
614
|
}
|
|
639
|
-
|
|
640
|
-
if (msg.ptvMessage) {
|
|
641
|
-
applyToContext(msg.ptvMessage);
|
|
642
|
-
applyMediaAnnotations(msg.ptvMessage);
|
|
643
|
-
injected = true;
|
|
615
|
+
return msg;
|
|
644
616
|
}
|
|
645
617
|
|
|
646
|
-
//
|
|
618
|
+
// 3. Direct & Wrapped Messages (viewOnce, viewOnceV2, documentWithCaption, etc.)
|
|
619
|
+
let injected = applyAttributionToContainer(msg);
|
|
647
620
|
const unwrapTargets = [
|
|
648
621
|
msg.viewOnceMessage?.message,
|
|
649
622
|
msg.viewOnceMessageV2?.message,
|
|
@@ -652,42 +625,12 @@ export const makeMessagesSocket = (config) => {
|
|
|
652
625
|
].filter(Boolean);
|
|
653
626
|
|
|
654
627
|
for (const target of unwrapTargets) {
|
|
655
|
-
|
|
656
|
-
if (target.interactiveMessage) {
|
|
657
|
-
processInteractiveMessage(target.interactiveMessage);
|
|
658
|
-
injected = true;
|
|
659
|
-
}
|
|
660
|
-
if (target.imageMessage) {
|
|
661
|
-
applyToContext(target.imageMessage);
|
|
662
|
-
applyMediaAnnotations(target.imageMessage);
|
|
663
|
-
injected = true;
|
|
664
|
-
}
|
|
665
|
-
if (target.videoMessage) {
|
|
666
|
-
applyToContext(target.videoMessage);
|
|
667
|
-
applyMediaAnnotations(target.videoMessage);
|
|
668
|
-
injected = true;
|
|
669
|
-
}
|
|
670
|
-
if (target.ptvMessage) {
|
|
671
|
-
applyToContext(target.ptvMessage);
|
|
672
|
-
applyMediaAnnotations(target.ptvMessage);
|
|
673
|
-
injected = true;
|
|
674
|
-
}
|
|
675
|
-
if (target.documentMessage) {
|
|
676
|
-
applyToContext(target.documentMessage);
|
|
628
|
+
if (applyAttributionToContainer(target)) {
|
|
677
629
|
injected = true;
|
|
678
630
|
}
|
|
679
|
-
for (const type of directTypes) {
|
|
680
|
-
if (target[type]) {
|
|
681
|
-
applyToContext(target[type]);
|
|
682
|
-
if (type === 'imageMessage' || type === 'videoMessage') {
|
|
683
|
-
applyMediaAnnotations(target[type]);
|
|
684
|
-
}
|
|
685
|
-
injected = true;
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
631
|
}
|
|
689
632
|
|
|
690
|
-
//
|
|
633
|
+
// 4. Plain text conversion to extendedTextMessage with channel attribution
|
|
691
634
|
if (!injected && msg.conversation && typeof msg.conversation === 'string') {
|
|
692
635
|
msg = {
|
|
693
636
|
extendedTextMessage: {
|
|
@@ -699,7 +642,8 @@ export const makeMessagesSocket = (config) => {
|
|
|
699
642
|
newsletterJid: targetNewsletterJid,
|
|
700
643
|
newsletterName: targetNewsletterName,
|
|
701
644
|
serverMessageId: targetServerMessageId,
|
|
702
|
-
contentType: 1
|
|
645
|
+
contentType: 1,
|
|
646
|
+
accessibilityText: targetNewsletterName
|
|
703
647
|
}
|
|
704
648
|
}
|
|
705
649
|
}
|
|
@@ -1152,14 +1096,11 @@ export const makeMessagesSocket = (config) => {
|
|
|
1152
1096
|
stanza.content.push(buttonsNode)
|
|
1153
1097
|
}
|
|
1154
1098
|
}
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
} else if (aiLabel && !isGroup && !isStatus && !isNewsletter) {
|
|
1159
|
-
const existingBizBot = getBinaryFilteredBizBot(additionalNodes || [])
|
|
1099
|
+
const isPeerMessage = additionalAttributes?.['category'] === 'peer'
|
|
1100
|
+
if (aiLabel === true && !isGroup && !isStatus && !isNewsletter && !isPeerMessage && (isJidMetaAI(destinationJid) || config.forceBizBotLabel === true)) {
|
|
1101
|
+
const existingBizBot = getBinaryFilteredBizBot(additionalNodes || []) || getBinaryFilteredBizBot(stanza.content)
|
|
1160
1102
|
if (!existingBizBot) stanza.content.push({ tag: 'bot', attrs: { biz_bot: '1' } })
|
|
1161
1103
|
}
|
|
1162
|
-
const isPeerMessage = additionalAttributes?.['category'] === 'peer'
|
|
1163
1104
|
const is1on1Send = !isGroup && !isRetryResend && !isStatus && !isNewsletter && !isPeerMessage
|
|
1164
1105
|
const tcTokenJid = is1on1Send ? await resolveTcTokenJid(destinationJid, getLIDForPN) : destinationJid
|
|
1165
1106
|
const contactTcTokenData = is1on1Send ? await authState.keys.get('tctoken', [tcTokenJid]) : {}
|
|
@@ -1728,22 +1669,31 @@ export const makeMessagesSocket = (config) => {
|
|
|
1728
1669
|
});
|
|
1729
1670
|
}
|
|
1730
1671
|
fullMsg.message = injectNewsletterWatermark(fullMsg.message, jid);
|
|
1672
|
+
const mergedAdditionalNodes = [
|
|
1673
|
+
...(options.additionalNodes || []),
|
|
1674
|
+
...additionalNodes
|
|
1675
|
+
];
|
|
1731
1676
|
await relayMessage(jid, fullMsg.message, {
|
|
1732
1677
|
messageId: fullMsg.key.id,
|
|
1733
1678
|
useCachedGroupMetadata: options.useCachedGroupMetadata,
|
|
1734
1679
|
additionalAttributes,
|
|
1735
1680
|
statusJidList: options.statusJidList,
|
|
1736
|
-
additionalNodes:
|
|
1681
|
+
additionalNodes: mergedAdditionalNodes.length > 0 ? mergedAdditionalNodes : options.additionalNodes,
|
|
1737
1682
|
participants: participant || undefined,
|
|
1738
1683
|
isSecret,
|
|
1739
1684
|
protected: protectedSend,
|
|
1740
1685
|
...(cstoken !== undefined ? { cstoken } : {})
|
|
1741
1686
|
});
|
|
1742
1687
|
if (config.emitOwnEvents) {
|
|
1743
|
-
process.nextTick(
|
|
1744
|
-
|
|
1688
|
+
process.nextTick(() => {
|
|
1689
|
+
Promise.resolve()
|
|
1690
|
+
.then(() => messageMutex.mutex(() => upsertMessage(fullMsg, 'append')))
|
|
1691
|
+
.catch(err => {
|
|
1692
|
+
logger?.error({ trace: err?.stack, msgId: fullMsg?.key?.id }, 'error in emitOwnEvents upsertMessage');
|
|
1693
|
+
});
|
|
1745
1694
|
});
|
|
1746
1695
|
}
|
|
1696
|
+
printCharapeChatLog('OUT', fullMsg, { enabled: config.charapeChatLog !== false });
|
|
1747
1697
|
return fullMsg;
|
|
1748
1698
|
}
|
|
1749
1699
|
},
|
package/lib/Socket/socket.js
CHANGED
|
@@ -406,6 +406,7 @@ export const makeSocket = (config) => {
|
|
|
406
406
|
let lastDateRecv;
|
|
407
407
|
let epoch = 1;
|
|
408
408
|
let keepAliveReq;
|
|
409
|
+
let missedKeepAlives = 0;
|
|
409
410
|
let qrTimer;
|
|
410
411
|
let closed = false;
|
|
411
412
|
const socketEndHandlers = [];
|
|
@@ -610,8 +611,11 @@ export const makeSocket = (config) => {
|
|
|
610
611
|
}
|
|
611
612
|
closed = true;
|
|
612
613
|
logger.info({ trace: error?.stack }, error ? 'connection errored' : 'connection closed');
|
|
614
|
+
missedKeepAlives = 0;
|
|
613
615
|
clearInterval(keepAliveReq);
|
|
616
|
+
keepAliveReq = undefined;
|
|
614
617
|
clearTimeout(qrTimer);
|
|
618
|
+
qrTimer = undefined;
|
|
615
619
|
ws.removeAllListeners('close');
|
|
616
620
|
ws.removeAllListeners('open');
|
|
617
621
|
ws.removeAllListeners('message');
|
|
@@ -661,20 +665,13 @@ export const makeSocket = (config) => {
|
|
|
661
665
|
ws.off('error', onClose);
|
|
662
666
|
});
|
|
663
667
|
};
|
|
664
|
-
const startKeepAliveRequest = () =>
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
it could be that the network is down
|
|
672
|
-
*/
|
|
673
|
-
if (diff > keepAliveIntervalMs + 5000) {
|
|
674
|
-
void end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost }));
|
|
675
|
-
}
|
|
676
|
-
else if (ws.isOpen) {
|
|
677
|
-
// if its all good, send a keep alive request
|
|
668
|
+
const startKeepAliveRequest = () => {
|
|
669
|
+
missedKeepAlives = 0;
|
|
670
|
+
const sendKeepAlivePing = () => {
|
|
671
|
+
if (!ws.isOpen) {
|
|
672
|
+
logger.warn('keep alive called when WS not open');
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
678
675
|
query({
|
|
679
676
|
tag: 'iq',
|
|
680
677
|
attrs: {
|
|
@@ -684,14 +681,38 @@ export const makeSocket = (config) => {
|
|
|
684
681
|
xmlns: 'w:p'
|
|
685
682
|
},
|
|
686
683
|
content: [{ tag: 'ping', attrs: {} }]
|
|
684
|
+
}).then(() => {
|
|
685
|
+
lastDateRecv = new Date();
|
|
686
|
+
missedKeepAlives = 0;
|
|
687
687
|
}).catch(err => {
|
|
688
|
-
logger.error({ trace: err
|
|
688
|
+
logger.error({ trace: err?.stack }, 'error in sending keep alive');
|
|
689
689
|
});
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
690
|
+
};
|
|
691
|
+
keepAliveReq = setInterval(() => {
|
|
692
|
+
if (!lastDateRecv) {
|
|
693
|
+
lastDateRecv = new Date();
|
|
694
|
+
}
|
|
695
|
+
const diff = Date.now() - lastDateRecv.getTime();
|
|
696
|
+
const maxGraceDiff = Math.max(keepAliveIntervalMs * 2.5, keepAliveIntervalMs + 20000);
|
|
697
|
+
if (diff > keepAliveIntervalMs + 5000) {
|
|
698
|
+
missedKeepAlives++;
|
|
699
|
+
if (missedKeepAlives >= 2 || diff > maxGraceDiff) {
|
|
700
|
+
void end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost }));
|
|
701
|
+
} else {
|
|
702
|
+
logger.debug({ diff, missedKeepAlives }, 'keep-alive latency tolerance, sending retry ping');
|
|
703
|
+
sendKeepAlivePing();
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
else if (ws.isOpen) {
|
|
707
|
+
missedKeepAlives = 0;
|
|
708
|
+
sendKeepAlivePing();
|
|
709
|
+
}
|
|
710
|
+
else {
|
|
711
|
+
logger.warn('keep alive called when WS not open');
|
|
712
|
+
}
|
|
713
|
+
}, keepAliveIntervalMs);
|
|
714
|
+
return keepAliveReq;
|
|
715
|
+
};
|
|
695
716
|
/** i have no idea why this exists. pls enlighten me */
|
|
696
717
|
const sendPassiveIq = (tag) => query({
|
|
697
718
|
tag: 'iq',
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import { createRequire } from "module";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { pathToFileURL } from "url";
|
|
4
|
+
|
|
5
|
+
let cacheManager;
|
|
6
|
+
const loadCacheManager = async () => {
|
|
7
|
+
if (cacheManager) return cacheManager;
|
|
8
|
+
if (typeof require === "function") {
|
|
9
|
+
cacheManager = require("cache-manager");
|
|
10
|
+
return cacheManager;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const mod = await import("cache-manager");
|
|
14
|
+
cacheManager = mod?.default || mod;
|
|
15
|
+
return cacheManager;
|
|
16
|
+
} catch {
|
|
17
|
+
const _require = createRequire(pathToFileURL(join(process.cwd(), "package.json")).href);
|
|
18
|
+
cacheManager = _require("cache-manager");
|
|
19
|
+
return cacheManager;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
4
22
|
|
|
5
23
|
import * as WAProto_1 from "../../WAProto/index.js";
|
|
6
24
|
import * as Utils_1 from "../Utils/index.js";
|
|
@@ -8,7 +26,8 @@ import logger from "../Utils/logger.js";
|
|
|
8
26
|
|
|
9
27
|
export default async function makeCacheManagerAuthState(store, sessionKey) {
|
|
10
28
|
const defaultKey = (file) => `${sessionKey}:${file}`;
|
|
11
|
-
const
|
|
29
|
+
const cm = await loadCacheManager();
|
|
30
|
+
const databaseConn = await cm.caching(store);
|
|
12
31
|
|
|
13
32
|
const writeData = async (file, data) => {
|
|
14
33
|
let ttl = undefined;
|