@dyyxyzz/baileys-mod 6.0.46 → 6.0.49
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/Socket/messages-send.js +123 -236
- package/lib/Socket/socket.js +60 -63
- package/package.json +1 -1
|
@@ -18,76 +18,6 @@ const newsletter_1 = require("./newsletter");
|
|
|
18
18
|
const WAUSync_1 = require("../WAUSync")
|
|
19
19
|
const kikyy = require('./dugong');
|
|
20
20
|
var ListType = WAProto_1.proto.Message.ListMessage.ListType;
|
|
21
|
-
|
|
22
|
-
// TAMBAHAN BARU: Helper functions untuk button di newsletter
|
|
23
|
-
const getAdditionalNode = (buttonType) => {
|
|
24
|
-
const nodes = []
|
|
25
|
-
|
|
26
|
-
switch(buttonType) {
|
|
27
|
-
case 'list':
|
|
28
|
-
nodes.push({
|
|
29
|
-
tag: 'biz',
|
|
30
|
-
attrs: {},
|
|
31
|
-
content: [{
|
|
32
|
-
tag: 'list_message',
|
|
33
|
-
attrs: { v: '2' }
|
|
34
|
-
}]
|
|
35
|
-
})
|
|
36
|
-
break
|
|
37
|
-
|
|
38
|
-
case 'buttons':
|
|
39
|
-
nodes.push({
|
|
40
|
-
tag: 'biz',
|
|
41
|
-
attrs: {},
|
|
42
|
-
content: [{
|
|
43
|
-
tag: 'buttons_message',
|
|
44
|
-
attrs: { v: '2' }
|
|
45
|
-
}]
|
|
46
|
-
})
|
|
47
|
-
break
|
|
48
|
-
|
|
49
|
-
case 'interactive':
|
|
50
|
-
case 'native_flow':
|
|
51
|
-
nodes.push({
|
|
52
|
-
tag: 'biz',
|
|
53
|
-
attrs: {},
|
|
54
|
-
content: [{
|
|
55
|
-
tag: 'native_flow',
|
|
56
|
-
attrs: { v: '3' }
|
|
57
|
-
}]
|
|
58
|
-
})
|
|
59
|
-
break
|
|
60
|
-
|
|
61
|
-
case 'review_and_pay':
|
|
62
|
-
case 'review_order':
|
|
63
|
-
case 'payment_info':
|
|
64
|
-
case 'payment_status':
|
|
65
|
-
case 'payment_method':
|
|
66
|
-
nodes.push({
|
|
67
|
-
tag: 'biz',
|
|
68
|
-
attrs: {},
|
|
69
|
-
content: [{
|
|
70
|
-
tag: 'payment',
|
|
71
|
-
attrs: { v: '2' }
|
|
72
|
-
}]
|
|
73
|
-
})
|
|
74
|
-
break
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return nodes
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const getBinaryNodeFilter = (nodes) => {
|
|
81
|
-
if (!nodes || !Array.isArray(nodes) || nodes.length === 0) return false
|
|
82
|
-
|
|
83
|
-
return nodes.some(node =>
|
|
84
|
-
node.tag === 'biz' ||
|
|
85
|
-
node.tag === 'bot' ||
|
|
86
|
-
node.tag === 'native_flow' ||
|
|
87
|
-
node.tag === 'payment'
|
|
88
|
-
)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
21
|
const makeMessagesSocket = (config) => {
|
|
92
22
|
const {
|
|
93
23
|
logger,
|
|
@@ -361,8 +291,7 @@ const makeMessagesSocket = (config) => {
|
|
|
361
291
|
return node;
|
|
362
292
|
}));
|
|
363
293
|
return { nodes, shouldIncludeDeviceIdentity };
|
|
364
|
-
};
|
|
365
|
-
|
|
294
|
+
}; //apela
|
|
366
295
|
const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, cachedGroupMetadata, useCachedGroupMetadata, statusJidList, AI = false }) => {
|
|
367
296
|
const meId = authState.creds.me.id;
|
|
368
297
|
let shouldIncludeDeviceIdentity = false;
|
|
@@ -446,6 +375,15 @@ const makeMessagesSocket = (config) => {
|
|
|
446
375
|
participantsList.push(...statusJidList)
|
|
447
376
|
}
|
|
448
377
|
|
|
378
|
+
// if (!isStatus) {
|
|
379
|
+
// const expiration = await getEphemeralGroup(jid)
|
|
380
|
+
// additionalAttributes = {
|
|
381
|
+
// ...additionalAttributes,
|
|
382
|
+
// addressing_mode: 'pn',
|
|
383
|
+
// ...expiration ? { expiration: expiration.toString() } : null
|
|
384
|
+
// }
|
|
385
|
+
// }
|
|
386
|
+
|
|
449
387
|
const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false)
|
|
450
388
|
devices.push(...additionalDevices)
|
|
451
389
|
}
|
|
@@ -505,32 +443,10 @@ const makeMessagesSocket = (config) => {
|
|
|
505
443
|
|
|
506
444
|
const patched = await patchMessageBeforeSending(message, [])
|
|
507
445
|
const bytes = Utils_1.encodeNewsletterMessage(patched)
|
|
508
|
-
|
|
509
|
-
// Detect button type dan media type
|
|
510
|
-
const buttonType = getButtonType(patched)
|
|
511
|
-
const mediaType = getMediaType(patched)
|
|
512
|
-
|
|
513
|
-
// Set extraAttrs untuk newsletter
|
|
514
|
-
if (mediaType) {
|
|
515
|
-
extraAttrs['mediatype'] = mediaType
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
if (patched.pinInChatMessage || patched.keepInChatMessage ||
|
|
519
|
-
patched.reactionMessage || patched.protocolMessage?.editedMessage) {
|
|
520
|
-
extraAttrs['decrypt-fail'] = 'hide'
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
if (patched.interactiveResponseMessage?.nativeFlowResponseMessage) {
|
|
524
|
-
extraAttrs['native_flow_name'] = patched.interactiveResponseMessage?.nativeFlowResponseMessage.name
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
if (patched.interactiveMessage?.nativeFlowMessage) {
|
|
528
|
-
extraAttrs['native_flow_name'] = patched.interactiveMessage?.nativeFlowMessage?.name || 'flow'
|
|
529
|
-
}
|
|
530
446
|
|
|
531
447
|
binaryNodeContent.push({
|
|
532
448
|
tag: 'plaintext',
|
|
533
|
-
attrs: extraAttrs,
|
|
449
|
+
attrs: extraAttrs ? extraAttrs : {},
|
|
534
450
|
content: bytes
|
|
535
451
|
})
|
|
536
452
|
}
|
|
@@ -601,7 +517,6 @@ const makeMessagesSocket = (config) => {
|
|
|
601
517
|
},
|
|
602
518
|
content: binaryNodeContent
|
|
603
519
|
}
|
|
604
|
-
|
|
605
520
|
// if the participant to send to is explicitly specified (generally retry recp)
|
|
606
521
|
// ensure the message is only sent to that person
|
|
607
522
|
// if a retry receipt is sent to everyone -- it'll fail decryption for everyone else who received the msg
|
|
@@ -621,7 +536,6 @@ const makeMessagesSocket = (config) => {
|
|
|
621
536
|
else {
|
|
622
537
|
stanza.attrs.to = destinationJid;
|
|
623
538
|
}
|
|
624
|
-
|
|
625
539
|
if (shouldIncludeDeviceIdentity) {
|
|
626
540
|
stanza.content.push({
|
|
627
541
|
tag: 'device-identity',
|
|
@@ -631,7 +545,7 @@ const makeMessagesSocket = (config) => {
|
|
|
631
545
|
logger.debug({ jid }, 'adding device identity');
|
|
632
546
|
}
|
|
633
547
|
|
|
634
|
-
if (AI && isPrivate
|
|
548
|
+
if (AI && isPrivate) {
|
|
635
549
|
const botNode = {
|
|
636
550
|
tag: 'bot',
|
|
637
551
|
attrs: {
|
|
@@ -639,43 +553,31 @@ const makeMessagesSocket = (config) => {
|
|
|
639
553
|
}
|
|
640
554
|
}
|
|
641
555
|
|
|
642
|
-
const filteredBizBot = getBinaryNodeFilter(additionalNodes ? additionalNodes : [])
|
|
556
|
+
const filteredBizBot = WABinary_1.getBinaryNodeFilter(additionalNodes ? additionalNodes : [])
|
|
643
557
|
|
|
644
|
-
if (filteredBizBot
|
|
558
|
+
if (filteredBizBot) {
|
|
645
559
|
stanza.content.push(...additionalNodes)
|
|
646
560
|
didPushAdditional = true
|
|
647
561
|
}
|
|
562
|
+
|
|
648
563
|
else {
|
|
649
|
-
stanza.content.push(botNode)
|
|
650
|
-
didPushAdditional = true
|
|
564
|
+
stanza.content.push(botNode)
|
|
651
565
|
}
|
|
652
566
|
}
|
|
653
567
|
|
|
654
568
|
if(!isNewsletter && buttonType && !isStatus) {
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
if (filteredNode && additionalNodes) {
|
|
659
|
-
stanza.content.push(...additionalNodes)
|
|
660
|
-
didPushAdditional = true
|
|
661
|
-
}
|
|
662
|
-
else if (content && content.length > 0 && !didPushAdditional) {
|
|
663
|
-
stanza.content.push(...content)
|
|
664
|
-
didPushAdditional = true
|
|
665
|
-
}
|
|
666
|
-
logger.debug({ jid }, 'adding business node')
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
// KHUSUS NEWSLETTER: Tambah button node
|
|
670
|
-
if (isNewsletter && buttonType && !didPushAdditional) {
|
|
671
|
-
const content = getAdditionalNode(buttonType)
|
|
569
|
+
const content = WABinary_1.getAdditionalNode(buttonType)
|
|
570
|
+
const filteredNode = WABinary_1.getBinaryNodeFilter(additionalNodes)
|
|
672
571
|
|
|
673
|
-
if (
|
|
674
|
-
stanza.content.push(...content)
|
|
572
|
+
if (filteredNode) {
|
|
675
573
|
didPushAdditional = true
|
|
676
|
-
|
|
574
|
+
stanza.content.push(...additionalNodes)
|
|
575
|
+
}
|
|
576
|
+
else {
|
|
577
|
+
stanza.content.push(...content)
|
|
677
578
|
}
|
|
678
|
-
|
|
579
|
+
logger.debug({ jid }, 'adding business node')
|
|
580
|
+
}
|
|
679
581
|
|
|
680
582
|
if (!didPushAdditional && additionalNodes && additionalNodes.length > 0) {
|
|
681
583
|
stanza.content.push(...additionalNodes);
|
|
@@ -701,10 +603,10 @@ const makeMessagesSocket = (config) => {
|
|
|
701
603
|
}
|
|
702
604
|
|
|
703
605
|
return Types_1.WAProto.WebMessageInfo.fromObject(messageJSON)
|
|
606
|
+
// return msgId;
|
|
704
607
|
};
|
|
705
|
-
|
|
706
608
|
const getTypeMessage = (msg) => {
|
|
707
|
-
|
|
609
|
+
const message = Utils_1.normalizeMessageContent(msg)
|
|
708
610
|
if (message.reactionMessage) {
|
|
709
611
|
return 'reaction'
|
|
710
612
|
}
|
|
@@ -774,12 +676,6 @@ const makeMessagesSocket = (config) => {
|
|
|
774
676
|
else if (message.buttonsMessage) {
|
|
775
677
|
return 'buttons'
|
|
776
678
|
}
|
|
777
|
-
else if (message.viewOnceMessage?.message?.interactiveMessage) {
|
|
778
|
-
return 'interactive'
|
|
779
|
-
}
|
|
780
|
-
else if (message.viewOnceMessageV2?.message?.interactiveMessage) {
|
|
781
|
-
return 'interactive'
|
|
782
|
-
}
|
|
783
679
|
else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'review_and_pay') {
|
|
784
680
|
return 'review_and_pay'
|
|
785
681
|
}
|
|
@@ -795,14 +691,13 @@ const makeMessagesSocket = (config) => {
|
|
|
795
691
|
else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_method') {
|
|
796
692
|
return 'payment_method'
|
|
797
693
|
}
|
|
694
|
+
else if (message.interactiveMessage && message.interactiveMessage?.nativeFlowMessage) {
|
|
695
|
+
return 'interactive'
|
|
696
|
+
}
|
|
798
697
|
else if (message.interactiveMessage?.nativeFlowMessage) {
|
|
799
698
|
return 'native_flow'
|
|
800
699
|
}
|
|
801
|
-
else if (message.interactiveMessage) {
|
|
802
|
-
return 'interactive'
|
|
803
|
-
}
|
|
804
700
|
}
|
|
805
|
-
|
|
806
701
|
const getPrivacyTokens = async (jids) => {
|
|
807
702
|
const t = Utils_1.unixTimestampSeconds().toString();
|
|
808
703
|
const result = await query({
|
|
@@ -829,11 +724,9 @@ const makeMessagesSocket = (config) => {
|
|
|
829
724
|
});
|
|
830
725
|
return result;
|
|
831
726
|
}
|
|
832
|
-
|
|
833
727
|
const waUploadToServer = (0, Utils_1.getWAUploadToServer)(config, refreshMediaConn);
|
|
834
728
|
const rahmi = new kikyy(Utils_1, waUploadToServer, relayMessage);
|
|
835
729
|
const waitForMsgMediaUpdate = (0, Utils_1.bindWaitForEvent)(ev, 'messages.media-update');
|
|
836
|
-
|
|
837
730
|
return {
|
|
838
731
|
...sock,
|
|
839
732
|
getPrivacyTokens,
|
|
@@ -901,7 +794,6 @@ const makeMessagesSocket = (config) => {
|
|
|
901
794
|
const { filter = false, quoted } = options;
|
|
902
795
|
const getParticipantAttr = () => filter ? { participant: { jid } } : {};
|
|
903
796
|
const messageType = rahmi.detectType(content);
|
|
904
|
-
|
|
905
797
|
if (typeof content === 'object' && 'disappearingMessagesInChat' in content &&
|
|
906
798
|
typeof content['disappearingMessagesInChat'] !== 'undefined' && WABinary_1.isJidGroup(jid)) {
|
|
907
799
|
const { disappearingMessagesInChat } = content
|
|
@@ -912,112 +804,107 @@ const makeMessagesSocket = (config) => {
|
|
|
912
804
|
|
|
913
805
|
await groupToggleEphemeral(jid, value)
|
|
914
806
|
}
|
|
807
|
+
|
|
915
808
|
else {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
const productContent = await rahmi.handleProduct(content, jid, quoted);
|
|
927
|
-
const productMsg = await Utils_1.generateWAMessageFromContent(jid, productContent, { quoted });
|
|
928
|
-
return await relayMessage(jid, productMsg.message, {
|
|
929
|
-
messageId: productMsg.key.id,
|
|
930
|
-
...getParticipantAttr()
|
|
931
|
-
});
|
|
932
|
-
|
|
933
|
-
case 'INTERACTIVE':
|
|
934
|
-
const interactiveContent = await rahmi.handleInteractive(content, jid, quoted);
|
|
935
|
-
const interactiveMsg = await Utils_1.generateWAMessageFromContent(jid, interactiveContent, { quoted });
|
|
936
|
-
return await relayMessage(jid, interactiveMsg.message, {
|
|
937
|
-
messageId: interactiveMsg.key.id,
|
|
938
|
-
...getParticipantAttr()
|
|
939
|
-
});
|
|
940
|
-
|
|
941
|
-
case 'ALBUM':
|
|
942
|
-
return await rahmi.handleAlbum(content, jid, quoted)
|
|
943
|
-
|
|
944
|
-
case 'EVENT':
|
|
945
|
-
return await rahmi.handleEvent(content, jid, quoted)
|
|
946
|
-
|
|
947
|
-
case 'POLL_RESULT':
|
|
948
|
-
return await rahmi.handlePollResult(content, jid, quoted)
|
|
949
|
-
|
|
950
|
-
case 'GROUP_STORY':
|
|
951
|
-
return await rahmi.handleGroupStory(content, jid, quoted)
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
const fullMsg = await Utils_1.generateWAMessage(jid, content, {
|
|
956
|
-
logger,
|
|
957
|
-
userJid,
|
|
958
|
-
quoted,
|
|
959
|
-
getUrlInfo: text => link_preview_1.getUrlInfo(text, {
|
|
960
|
-
thumbnailWidth: linkPreviewImageThumbnailWidth,
|
|
961
|
-
fetchOpts: {
|
|
962
|
-
timeout: 3000,
|
|
963
|
-
...axiosOptions || {}
|
|
964
|
-
},
|
|
965
|
-
logger,
|
|
966
|
-
uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
|
|
967
|
-
}),
|
|
968
|
-
upload: async (readStream, opts) => {
|
|
969
|
-
const up = await waUploadToServer(readStream, {
|
|
970
|
-
...opts,
|
|
971
|
-
newsletter: WABinary_1.isJidNewsLetter(jid)
|
|
809
|
+
let mediaHandle
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
if (messageType) {
|
|
813
|
+
switch(messageType) {
|
|
814
|
+
case 'PAYMENT':
|
|
815
|
+
const paymentContent = await rahmi.handlePayment(content, quoted);
|
|
816
|
+
return await relayMessage(jid, paymentContent, {
|
|
817
|
+
messageId: Utils_1.generateMessageID(),
|
|
818
|
+
...getParticipantAttr()
|
|
972
819
|
});
|
|
973
|
-
return up;
|
|
974
|
-
},
|
|
975
|
-
mediaCache: config.mediaCache,
|
|
976
|
-
options: config.options,
|
|
977
|
-
...options
|
|
978
|
-
});
|
|
979
820
|
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
821
|
+
case 'PRODUCT':
|
|
822
|
+
const productContent = await rahmi.handleProduct(content, jid, quoted);
|
|
823
|
+
const productMsg = await Utils_1.generateWAMessageFromContent(jid, productContent, { quoted });
|
|
824
|
+
return await relayMessage(jid, productMsg.message, {
|
|
825
|
+
messageId: productMsg.key.id,
|
|
826
|
+
...getParticipantAttr()
|
|
827
|
+
});
|
|
983
828
|
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
829
|
+
case 'INTERACTIVE':
|
|
830
|
+
const interactiveContent = await rahmi.handleInteractive(content, jid, quoted);
|
|
831
|
+
const interactiveMsg = await Utils_1.generateWAMessageFromContent(jid, interactiveContent, { quoted });
|
|
832
|
+
return await relayMessage(jid, interactiveMsg.message, {
|
|
833
|
+
messageId: interactiveMsg.key.id,
|
|
834
|
+
...getParticipantAttr()
|
|
835
|
+
});
|
|
836
|
+
case 'ALBUM':
|
|
837
|
+
return await rahmi.handleAlbum(content, jid, quoted)
|
|
838
|
+
case 'EVENT':
|
|
839
|
+
return await rahmi.handleEvent(content, jid, quoted)
|
|
840
|
+
case 'POLL_RESULT':
|
|
841
|
+
return await rahmi.handlePollResult(content, jid, quoted)
|
|
842
|
+
case 'GROUP_STORY':
|
|
843
|
+
return await rahmi.handleGroupStory(content, jid, quoted)
|
|
999
844
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
845
|
+
}
|
|
846
|
+
const fullMsg = await Utils_1.generateWAMessage(jid, content, {
|
|
847
|
+
logger,
|
|
848
|
+
userJid,
|
|
849
|
+
quoted,
|
|
850
|
+
getUrlInfo: text => link_preview_1.getUrlInfo(text, {
|
|
851
|
+
thumbnailWidth: linkPreviewImageThumbnailWidth,
|
|
852
|
+
fetchOpts: {
|
|
853
|
+
timeout: 3000,
|
|
854
|
+
...axiosOptions || {}
|
|
855
|
+
},
|
|
856
|
+
logger,
|
|
857
|
+
uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
|
|
858
|
+
}),
|
|
859
|
+
upload: async (readStream, opts) => {
|
|
860
|
+
const up = await waUploadToServer(readStream, {
|
|
861
|
+
...opts,
|
|
862
|
+
newsletter: WABinary_1.isJidNewsLetter(jid)
|
|
1013
863
|
});
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
864
|
+
return up;
|
|
865
|
+
},
|
|
866
|
+
mediaCache: config.mediaCache,
|
|
867
|
+
options: config.options,
|
|
868
|
+
...options
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
const isDeleteMsg = 'delete' in content && !!content.delete;
|
|
872
|
+
const isEditMsg = 'edit' in content && !!content.edit;
|
|
873
|
+
const isAiMsg = 'ai' in content && !!content.ai;
|
|
874
|
+
|
|
875
|
+
const additionalAttributes = {};
|
|
876
|
+
const additionalNodes = [];
|
|
877
|
+
|
|
878
|
+
if (isDeleteMsg) {
|
|
879
|
+
const fromMe = content.delete?.fromMe;
|
|
880
|
+
const isGroup = WABinary_1.isJidGroup(content.delete?.remoteJid);
|
|
881
|
+
additionalAttributes.edit = (isGroup && !fromMe) || WABinary_1.isJidNewsLetter(jid) ? '8' : '7';
|
|
882
|
+
} else if (isEditMsg) {
|
|
883
|
+
additionalAttributes.edit = WABinary_1.isJidNewsLetter(jid) ? '3' : '1';
|
|
884
|
+
} else if (isAiMsg) {
|
|
885
|
+
additionalNodes.push({
|
|
886
|
+
attrs: {
|
|
887
|
+
biz_bot: '1'
|
|
888
|
+
}, tag: "bot"
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
await relayMessage(jid, fullMsg.message, {
|
|
893
|
+
messageId: fullMsg.key.id,
|
|
894
|
+
cachedGroupMetadata: options.cachedGroupMetadata,
|
|
895
|
+
additionalNodes: isAiMsg ? additionalNodes : options.additionalNodes,
|
|
896
|
+
additionalAttributes,
|
|
897
|
+
statusJidList: options.statusJidList
|
|
898
|
+
});
|
|
899
|
+
|
|
900
|
+
if (config.emitOwnEvents) {
|
|
901
|
+
process.nextTick(() => {
|
|
902
|
+
processingMutex.mutex(() => upsertMessage(fullMsg, 'append'));
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
return fullMsg;
|
|
1017
906
|
}
|
|
1018
907
|
}
|
|
1019
908
|
}
|
|
1020
909
|
};
|
|
1021
|
-
|
|
1022
910
|
exports.makeMessagesSocket = makeMessagesSocket;
|
|
1023
|
-
|
package/lib/Socket/socket.js
CHANGED
|
@@ -78,40 +78,36 @@ const makeSocket = (config) => {
|
|
|
78
78
|
return sendRawMessage(buff);
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
return pn;
|
|
83
|
-
};
|
|
81
|
+
const toLid = async (pn) => {
|
|
82
|
+
return pn;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const delay = async (ms) => {
|
|
86
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
87
|
+
};
|
|
84
88
|
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
const toPn = async (pn) => {
|
|
90
|
+
return pn;
|
|
91
|
+
};
|
|
88
92
|
|
|
89
|
-
const toPn = async (pn) => {
|
|
90
|
-
return pn;
|
|
91
|
-
};
|
|
92
93
|
/** log & process any unexpected errors */
|
|
93
94
|
const onUnexpectedError = (err, msg) => {
|
|
94
95
|
logger.error({ err }, `unexpected error in '${msg}'`);
|
|
95
96
|
const message = (err && ((err.stack || err.message) || String(err))).toLowerCase();
|
|
96
|
-
// auto recover from cryptographic desyncs by re-uploading prekeys
|
|
97
97
|
if (message.includes('bad mac') || (message.includes('mac') && message.includes('invalid'))) {
|
|
98
98
|
try {
|
|
99
99
|
uploadPreKeysToServerIfRequired(true)
|
|
100
100
|
.catch(e => logger.warn({ e }, 'failed to re-upload prekeys after bad mac'));
|
|
101
101
|
}
|
|
102
|
-
catch (_e) {
|
|
103
|
-
// ignore
|
|
104
|
-
}
|
|
102
|
+
catch (_e) {}
|
|
105
103
|
}
|
|
106
|
-
// gently back off when encountering rate limits (429)
|
|
107
104
|
if (message.includes('429') || message.includes('rate limit')) {
|
|
108
105
|
const wait = Math.min(30000, (config.backoffDelayMs || 5000));
|
|
109
106
|
logger.info({ wait }, 'backing off due to rate limit');
|
|
110
|
-
setTimeout(() => {
|
|
111
|
-
// intentionally empty; wait to delay further sends
|
|
112
|
-
}, wait);
|
|
107
|
+
setTimeout(() => {}, wait);
|
|
113
108
|
}
|
|
114
109
|
};
|
|
110
|
+
|
|
115
111
|
/** await the next incoming message */
|
|
116
112
|
const awaitNextMessage = async (sendMsg) => {
|
|
117
113
|
if (!ws.isOpen) {
|
|
@@ -138,11 +134,7 @@ const toPn = async (pn) => {
|
|
|
138
134
|
}
|
|
139
135
|
return result;
|
|
140
136
|
};
|
|
141
|
-
|
|
142
|
-
* Wait for a message with a certain tag to be received
|
|
143
|
-
* @param msgId the message tag to await
|
|
144
|
-
* @param timeoutMs timeout after which the promise will reject
|
|
145
|
-
*/
|
|
137
|
+
|
|
146
138
|
const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
|
|
147
139
|
let onRecv;
|
|
148
140
|
let onErr;
|
|
@@ -153,18 +145,18 @@ const toPn = async (pn) => {
|
|
|
153
145
|
reject(err || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }));
|
|
154
146
|
};
|
|
155
147
|
ws.on(`TAG:${msgId}`, onRecv);
|
|
156
|
-
ws.on('close', onErr);
|
|
148
|
+
ws.on('close', onErr);
|
|
157
149
|
ws.off('error', onErr);
|
|
158
150
|
});
|
|
159
151
|
return result;
|
|
160
152
|
}
|
|
161
153
|
finally {
|
|
162
154
|
ws.off(`TAG:${msgId}`, onRecv);
|
|
163
|
-
ws.off('close', onErr);
|
|
155
|
+
ws.off('close', onErr);
|
|
164
156
|
ws.off('error', onErr);
|
|
165
157
|
}
|
|
166
158
|
};
|
|
167
|
-
|
|
159
|
+
|
|
168
160
|
const query = async (node, timeoutMs) => {
|
|
169
161
|
if (!node.attrs.id) {
|
|
170
162
|
node.attrs.id = generateMessageTag();
|
|
@@ -179,6 +171,7 @@ const toPn = async (pn) => {
|
|
|
179
171
|
}
|
|
180
172
|
return result;
|
|
181
173
|
};
|
|
174
|
+
|
|
182
175
|
/** connection handshake */
|
|
183
176
|
const validateConnection = async () => {
|
|
184
177
|
let helloMsg = {
|
|
@@ -210,6 +203,7 @@ const toPn = async (pn) => {
|
|
|
210
203
|
noise.finishInit();
|
|
211
204
|
startKeepAliveRequest();
|
|
212
205
|
};
|
|
206
|
+
|
|
213
207
|
const getAvailablePreKeysOnServer = async () => {
|
|
214
208
|
const result = await query({
|
|
215
209
|
tag: 'iq',
|
|
@@ -226,7 +220,7 @@ const toPn = async (pn) => {
|
|
|
226
220
|
const countChild = (0, WABinary_1.getBinaryNodeChild)(result, 'count');
|
|
227
221
|
return +countChild.attrs.value;
|
|
228
222
|
};
|
|
229
|
-
|
|
223
|
+
|
|
230
224
|
const uploadPreKeys = async (count = Defaults_1.INITIAL_PREKEY_COUNT) => {
|
|
231
225
|
await keys.transaction(async () => {
|
|
232
226
|
logger.info({ count }, 'uploading pre-keys');
|
|
@@ -236,6 +230,7 @@ const toPn = async (pn) => {
|
|
|
236
230
|
logger.info({ count }, 'uploaded pre-keys');
|
|
237
231
|
});
|
|
238
232
|
};
|
|
233
|
+
|
|
239
234
|
const uploadPreKeysToServerIfRequired = async () => {
|
|
240
235
|
const preKeyCount = await getAvailablePreKeysOnServer();
|
|
241
236
|
logger.info(`${preKeyCount} pre-keys found on server`);
|
|
@@ -243,22 +238,19 @@ const toPn = async (pn) => {
|
|
|
243
238
|
await uploadPreKeys();
|
|
244
239
|
}
|
|
245
240
|
};
|
|
241
|
+
|
|
246
242
|
const onMessageReceived = (data) => {
|
|
247
243
|
noise.decodeFrame(data, frame => {
|
|
248
244
|
var _a;
|
|
249
|
-
// reset ping timeout
|
|
250
245
|
lastDateRecv = new Date();
|
|
251
246
|
let anyTriggered = false;
|
|
252
247
|
anyTriggered = ws.emit('frame', frame);
|
|
253
|
-
// if it's a binary node
|
|
254
248
|
if (!(frame instanceof Uint8Array)) {
|
|
255
249
|
const msgId = frame.attrs.id;
|
|
256
250
|
if (logger.level === 'trace') {
|
|
257
251
|
logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'recv xml' });
|
|
258
252
|
}
|
|
259
|
-
/* Check if this is a response to a message we sent */
|
|
260
253
|
anyTriggered = ws.emit(`${Defaults_1.DEF_TAG_PREFIX}${msgId}`, frame) || anyTriggered;
|
|
261
|
-
/* Check if this is a response to a message we are expecting */
|
|
262
254
|
const l0 = frame.tag;
|
|
263
255
|
const l1 = frame.attrs || {};
|
|
264
256
|
const l2 = Array.isArray(frame.content) ? (_a = frame.content[0]) === null || _a === void 0 ? void 0 : _a.tag : '';
|
|
@@ -275,6 +267,7 @@ const toPn = async (pn) => {
|
|
|
275
267
|
}
|
|
276
268
|
});
|
|
277
269
|
};
|
|
270
|
+
|
|
278
271
|
const end = (error) => {
|
|
279
272
|
if (closed) {
|
|
280
273
|
logger.trace({ trace: error === null || error === void 0 ? void 0 : error.stack }, 'connection already closed');
|
|
@@ -303,6 +296,7 @@ const toPn = async (pn) => {
|
|
|
303
296
|
});
|
|
304
297
|
ev.removeAllListeners('connection.update');
|
|
305
298
|
};
|
|
299
|
+
|
|
306
300
|
const waitForSocketOpen = async () => {
|
|
307
301
|
if (ws.isOpen) {
|
|
308
302
|
return;
|
|
@@ -325,20 +319,16 @@ const toPn = async (pn) => {
|
|
|
325
319
|
ws.off('error', onClose);
|
|
326
320
|
});
|
|
327
321
|
};
|
|
322
|
+
|
|
328
323
|
const startKeepAliveRequest = () => (keepAliveReq = setInterval(() => {
|
|
329
324
|
if (!lastDateRecv) {
|
|
330
325
|
lastDateRecv = new Date();
|
|
331
326
|
}
|
|
332
327
|
const diff = Date.now() - lastDateRecv.getTime();
|
|
333
|
-
/*
|
|
334
|
-
check if it's been a suspicious amount of time since the server responded with our last seen
|
|
335
|
-
it could be that the network is down
|
|
336
|
-
*/
|
|
337
328
|
if (diff > keepAliveIntervalMs + 5000) {
|
|
338
329
|
end(new boom_1.Boom('Connection was lost', { statusCode: Types_1.DisconnectReason.connectionLost }));
|
|
339
330
|
}
|
|
340
331
|
else if (ws.isOpen) {
|
|
341
|
-
// if its all good, send a keep alive request
|
|
342
332
|
query({
|
|
343
333
|
tag: 'iq',
|
|
344
334
|
attrs: {
|
|
@@ -357,7 +347,7 @@ const toPn = async (pn) => {
|
|
|
357
347
|
logger.warn('keep alive called when WS not open');
|
|
358
348
|
}
|
|
359
349
|
}, keepAliveIntervalMs));
|
|
360
|
-
|
|
350
|
+
|
|
361
351
|
const sendPassiveIq = (tag) => (query({
|
|
362
352
|
tag: 'iq',
|
|
363
353
|
attrs: {
|
|
@@ -369,7 +359,7 @@ const toPn = async (pn) => {
|
|
|
369
359
|
{ tag, attrs: {} }
|
|
370
360
|
]
|
|
371
361
|
}));
|
|
372
|
-
|
|
362
|
+
|
|
373
363
|
const logout = async (msg) => {
|
|
374
364
|
var _a;
|
|
375
365
|
const jid = (_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id;
|
|
@@ -395,7 +385,7 @@ const toPn = async (pn) => {
|
|
|
395
385
|
}
|
|
396
386
|
end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }));
|
|
397
387
|
};
|
|
398
|
-
|
|
388
|
+
|
|
399
389
|
/** This method was created by snowi, and implemented by KyuuRzy */
|
|
400
390
|
/** hey bro, if you delete this text */
|
|
401
391
|
/** you are the most cursed human being who likes to claim other people's property 😹🙌🏻 */
|
|
@@ -412,7 +402,13 @@ const toPn = async (pn) => {
|
|
|
412
402
|
};
|
|
413
403
|
|
|
414
404
|
ev.emit('creds.update', authState.creds);
|
|
415
|
-
|
|
405
|
+
|
|
406
|
+
// ── FIX: Platform ID 1 = Chrome, dikenali WA sebagai companion browser valid ──
|
|
407
|
+
// Sebelumnya pakai getPlatformId(browser[1]) yang return nilai tidak dikenal
|
|
408
|
+
// untuk string 'Android' sehingga WA tidak mengirimkan push notif pairing ke HP
|
|
409
|
+
const PLATFORM_ID = Buffer.from([1]); // 1 = Chrome/Browser companion
|
|
410
|
+
const PLATFORM_DISPLAY = Buffer.from('Chrome (Linux)', 'utf-8');
|
|
411
|
+
|
|
416
412
|
await sendNode({
|
|
417
413
|
tag: 'iq',
|
|
418
414
|
attrs: {
|
|
@@ -443,25 +439,26 @@ const toPn = async (pn) => {
|
|
|
443
439
|
{
|
|
444
440
|
tag: 'companion_platform_id',
|
|
445
441
|
attrs: {},
|
|
446
|
-
content:
|
|
442
|
+
content: PLATFORM_ID
|
|
447
443
|
},
|
|
448
444
|
{
|
|
449
445
|
tag: 'companion_platform_display',
|
|
450
446
|
attrs: {},
|
|
451
|
-
content:
|
|
447
|
+
content: PLATFORM_DISPLAY
|
|
452
448
|
},
|
|
453
449
|
{
|
|
454
450
|
tag: 'link_code_pairing_nonce',
|
|
455
451
|
attrs: {},
|
|
456
|
-
content:
|
|
452
|
+
content: Buffer.from('0', 'utf-8')
|
|
457
453
|
}
|
|
458
454
|
]
|
|
459
455
|
}
|
|
460
456
|
]
|
|
461
457
|
});
|
|
462
|
-
|
|
458
|
+
|
|
463
459
|
return authState.creds.pairingCode;
|
|
464
|
-
}
|
|
460
|
+
};
|
|
461
|
+
|
|
465
462
|
async function generatePairingKey() {
|
|
466
463
|
const salt = (0, crypto_1.randomBytes)(32);
|
|
467
464
|
const randomIv = (0, crypto_1.randomBytes)(16);
|
|
@@ -469,6 +466,7 @@ const toPn = async (pn) => {
|
|
|
469
466
|
const ciphered = (0, Utils_1.aesEncryptCTR)(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
|
|
470
467
|
return Buffer.concat([salt, randomIv, ciphered]);
|
|
471
468
|
}
|
|
469
|
+
|
|
472
470
|
const sendWAMBuffer = (wamBuffer) => {
|
|
473
471
|
return query({
|
|
474
472
|
tag: 'iq',
|
|
@@ -486,6 +484,7 @@ const toPn = async (pn) => {
|
|
|
486
484
|
]
|
|
487
485
|
});
|
|
488
486
|
};
|
|
487
|
+
|
|
489
488
|
ws.on('message', onMessageReceived);
|
|
490
489
|
ws.on('open', async () => {
|
|
491
490
|
try {
|
|
@@ -498,9 +497,8 @@ const toPn = async (pn) => {
|
|
|
498
497
|
});
|
|
499
498
|
ws.on('error', mapWebSocketError(end));
|
|
500
499
|
ws.on('close', () => end(new boom_1.Boom('Connection Terminated', { statusCode: Types_1.DisconnectReason.connectionClosed })));
|
|
501
|
-
// the server terminated the connection
|
|
502
500
|
ws.on('CB:xmlstreamend', () => end(new boom_1.Boom('Connection Terminated by Server', { statusCode: Types_1.DisconnectReason.connectionClosed })));
|
|
503
|
-
|
|
501
|
+
|
|
504
502
|
ws.on('CB:iq,type:set,pair-device', async (stanza) => {
|
|
505
503
|
const iq = {
|
|
506
504
|
tag: 'iq',
|
|
@@ -516,7 +514,7 @@ const toPn = async (pn) => {
|
|
|
516
514
|
const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64');
|
|
517
515
|
const identityKeyB64 = Buffer.from(creds.signedIdentityKey.public).toString('base64');
|
|
518
516
|
const advB64 = creds.advSecretKey;
|
|
519
|
-
let qrMs = qrTimeout || 60000;
|
|
517
|
+
let qrMs = qrTimeout || 60000;
|
|
520
518
|
const genPairQR = () => {
|
|
521
519
|
if (!ws.isOpen) {
|
|
522
520
|
return;
|
|
@@ -530,12 +528,11 @@ const toPn = async (pn) => {
|
|
|
530
528
|
const qr = [ref, noiseKeyB64, identityKeyB64, advB64].join(',');
|
|
531
529
|
ev.emit('connection.update', { qr });
|
|
532
530
|
qrTimer = setTimeout(genPairQR, qrMs);
|
|
533
|
-
qrMs = qrTimeout || 20000;
|
|
531
|
+
qrMs = qrTimeout || 20000;
|
|
534
532
|
};
|
|
535
533
|
genPairQR();
|
|
536
534
|
});
|
|
537
|
-
|
|
538
|
-
// if device pairs successfully, the server asks to restart the connection
|
|
535
|
+
|
|
539
536
|
ws.on('CB:iq,,pair-success', async (stanza) => {
|
|
540
537
|
logger.debug('pair success recv');
|
|
541
538
|
try {
|
|
@@ -550,13 +547,13 @@ const toPn = async (pn) => {
|
|
|
550
547
|
end(error);
|
|
551
548
|
}
|
|
552
549
|
});
|
|
553
|
-
|
|
550
|
+
|
|
554
551
|
ws.on('CB:success', async (node) => {
|
|
555
552
|
try {
|
|
556
553
|
await uploadPreKeysToServerIfRequired();
|
|
557
554
|
await sendPassiveIq('active');
|
|
558
555
|
logger.info('opened connection to WA');
|
|
559
|
-
clearTimeout(qrTimer);
|
|
556
|
+
clearTimeout(qrTimer);
|
|
560
557
|
ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } });
|
|
561
558
|
ev.emit('connection.update', { connection: 'open' });
|
|
562
559
|
}
|
|
@@ -565,19 +562,22 @@ const toPn = async (pn) => {
|
|
|
565
562
|
end(err);
|
|
566
563
|
}
|
|
567
564
|
});
|
|
565
|
+
|
|
568
566
|
ws.on('CB:stream:error', (node) => {
|
|
569
567
|
logger.error({ node }, 'stream errored out');
|
|
570
568
|
const { reason, statusCode } = (0, Utils_1.getErrorCodeFromStreamError)(node);
|
|
571
569
|
end(new boom_1.Boom(`Stream Errored (${reason})`, { statusCode, data: node }));
|
|
572
570
|
});
|
|
573
|
-
|
|
571
|
+
|
|
574
572
|
ws.on('CB:failure', (node) => {
|
|
575
573
|
const reason = +(node.attrs.reason || 500);
|
|
576
574
|
end(new boom_1.Boom('Connection Failure', { statusCode: reason, data: node.attrs }));
|
|
577
575
|
});
|
|
576
|
+
|
|
578
577
|
ws.on('CB:ib,,downgrade_webclient', () => {
|
|
579
578
|
end(new boom_1.Boom('Multi-device beta not joined', { statusCode: Types_1.DisconnectReason.multideviceMismatch }));
|
|
580
579
|
});
|
|
580
|
+
|
|
581
581
|
ws.on('CB:ib,,offline_preview', (node) => {
|
|
582
582
|
logger.info('offline preview received', JSON.stringify(node));
|
|
583
583
|
sendNode({
|
|
@@ -586,6 +586,7 @@ const toPn = async (pn) => {
|
|
|
586
586
|
content: [{ tag: 'offline_batch', attrs: { count: '100' } }]
|
|
587
587
|
});
|
|
588
588
|
});
|
|
589
|
+
|
|
589
590
|
ws.on('CB:ib,,edge_routing', (node) => {
|
|
590
591
|
const edgeRoutingNode = (0, WABinary_1.getBinaryNodeChild)(node, 'edge_routing');
|
|
591
592
|
const routingInfo = (0, WABinary_1.getBinaryNodeChild)(edgeRoutingNode, 'routing_info');
|
|
@@ -594,18 +595,17 @@ const toPn = async (pn) => {
|
|
|
594
595
|
ev.emit('creds.update', authState.creds);
|
|
595
596
|
}
|
|
596
597
|
});
|
|
598
|
+
|
|
597
599
|
let didStartBuffer = false;
|
|
598
600
|
process.nextTick(() => {
|
|
599
601
|
var _a;
|
|
600
602
|
if ((_a = creds.me) === null || _a === void 0 ? void 0 : _a.id) {
|
|
601
|
-
// start buffering important events
|
|
602
|
-
// if we're logged in
|
|
603
603
|
ev.buffer();
|
|
604
604
|
didStartBuffer = true;
|
|
605
605
|
}
|
|
606
606
|
ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false, qr: undefined });
|
|
607
607
|
});
|
|
608
|
-
|
|
608
|
+
|
|
609
609
|
ws.on('CB:ib,,offline', (node) => {
|
|
610
610
|
const child = (0, WABinary_1.getBinaryNodeChild)(node, 'offline');
|
|
611
611
|
const offlineNotifs = +((child === null || child === void 0 ? void 0 : child.attrs.count) || 0);
|
|
@@ -616,11 +616,10 @@ const toPn = async (pn) => {
|
|
|
616
616
|
}
|
|
617
617
|
ev.emit('connection.update', { receivedPendingNotifications: true });
|
|
618
618
|
});
|
|
619
|
-
|
|
619
|
+
|
|
620
620
|
ev.on('creds.update', update => {
|
|
621
621
|
var _a, _b;
|
|
622
622
|
const name = (_a = update.me) === null || _a === void 0 ? void 0 : _a.name;
|
|
623
|
-
// if name has just been received
|
|
624
623
|
if (((_b = creds.me) === null || _b === void 0 ? void 0 : _b.name) !== name) {
|
|
625
624
|
logger.debug({ name }, 'updated pushName');
|
|
626
625
|
sendNode({
|
|
@@ -633,9 +632,11 @@ const toPn = async (pn) => {
|
|
|
633
632
|
}
|
|
634
633
|
Object.assign(creds, update);
|
|
635
634
|
});
|
|
635
|
+
|
|
636
636
|
if (printQRInTerminal) {
|
|
637
637
|
(0, Utils_1.printQRIfNecessaryListener)(ev, logger);
|
|
638
638
|
}
|
|
639
|
+
|
|
639
640
|
return {
|
|
640
641
|
type: 'md',
|
|
641
642
|
ws,
|
|
@@ -663,16 +664,12 @@ const toPn = async (pn) => {
|
|
|
663
664
|
uploadPreKeys,
|
|
664
665
|
uploadPreKeysToServerIfRequired,
|
|
665
666
|
requestPairingCode,
|
|
666
|
-
/** Waits for the connection to WA to reach a state */
|
|
667
667
|
waitForConnectionUpdate: (0, Utils_1.bindWaitForConnectionUpdate)(ev),
|
|
668
668
|
sendWAMBuffer,
|
|
669
669
|
};
|
|
670
670
|
};
|
|
671
671
|
exports.makeSocket = makeSocket;
|
|
672
|
-
|
|
673
|
-
* map the websocket error to the right type
|
|
674
|
-
* so it can be retried by the caller
|
|
675
|
-
* */
|
|
672
|
+
|
|
676
673
|
function mapWebSocketError(handler) {
|
|
677
674
|
return (error) => {
|
|
678
675
|
handler(new boom_1.Boom(`WebSocket Error (${error === null || error === void 0 ? void 0 : error.message})`, { statusCode: (0, Utils_1.getCodeFromWSError)(error), data: error }));
|