supunmd-bail 2.1.1 → 2.1.3
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/LICENSE +1 -1
- package/README.md +428 -0
- package/WAProto/index.js +130529 -45236
- package/engine-requirements.js +1 -1
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/index.d.ts +9 -18
- package/lib/Defaults/index.js +136 -104
- package/lib/Defaults/phonenumber-mcc.json +223 -0
- package/lib/Signal/Group/ciphertext-message.d.ts +0 -1
- package/lib/Signal/Group/ciphertext-message.js +5 -2
- package/lib/Signal/Group/group-session-builder.d.ts +3 -4
- package/lib/Signal/Group/group-session-builder.js +41 -7
- package/lib/Signal/Group/group_cipher.d.ts +4 -4
- package/lib/Signal/Group/group_cipher.js +51 -37
- package/lib/Signal/Group/index.d.ts +11 -12
- package/lib/Signal/Group/index.js +57 -12
- package/lib/Signal/Group/keyhelper.d.ts +1 -2
- package/lib/Signal/Group/keyhelper.js +44 -7
- package/lib/Signal/Group/queue-job.d.ts +0 -1
- package/lib/Signal/Group/queue-job.js +5 -2
- package/lib/Signal/Group/sender-chain-key.d.ts +2 -3
- package/lib/Signal/Group/sender-chain-key.js +15 -7
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +1 -2
- package/lib/Signal/Group/sender-key-distribution-message.js +11 -8
- package/lib/Signal/Group/sender-key-message.d.ts +1 -2
- package/lib/Signal/Group/sender-key-message.js +12 -9
- package/lib/Signal/Group/sender-key-name.d.ts +0 -1
- package/lib/Signal/Group/sender-key-name.js +5 -2
- package/lib/Signal/Group/sender-key-record.d.ts +2 -3
- package/lib/Signal/Group/sender-key-record.js +21 -9
- package/lib/Signal/Group/sender-key-state.d.ts +6 -7
- package/lib/Signal/Group/sender-key-state.js +42 -27
- package/lib/Signal/Group/sender-message-key.d.ts +0 -1
- package/lib/Signal/Group/sender-message-key.js +7 -4
- package/lib/Signal/libsignal.d.ts +3 -5
- package/lib/Signal/libsignal.js +90 -258
- package/lib/Socket/Client/{types.d.ts → abstract-socket-client.d.ts} +3 -2
- package/lib/Socket/Client/abstract-socket-client.js +13 -0
- package/lib/Socket/Client/index.d.ts +3 -3
- package/lib/Socket/Client/index.js +19 -3
- package/lib/Socket/Client/mobile-socket-client.d.ts +13 -0
- package/lib/Socket/Client/mobile-socket-client.js +65 -0
- package/lib/Socket/Client/{websocket.d.ts → web-socket-client.d.ts} +1 -2
- package/lib/Socket/Client/web-socket-client.js +62 -0
- package/lib/Socket/business.d.ts +108 -125
- package/lib/Socket/business.js +43 -159
- package/lib/Socket/chats.d.ts +239 -70
- package/lib/Socket/chats.js +384 -363
- package/lib/Socket/dugong.d.ts +254 -0
- package/lib/Socket/dugong.js +484 -0
- package/lib/Socket/groups.d.ts +56 -78
- package/lib/Socket/groups.js +96 -106
- package/lib/Socket/index.d.ts +115 -173
- package/lib/Socket/index.js +10 -17
- package/lib/Socket/messages-recv.d.ts +79 -91
- package/lib/Socket/messages-recv.js +521 -639
- package/lib/Socket/messages-send.d.ts +91 -111
- package/lib/Socket/messages-send.js +438 -599
- package/lib/Socket/newsletter.d.ts +84 -97
- package/lib/Socket/newsletter.js +1 -181
- package/lib/Socket/registration.d.ts +267 -0
- package/lib/Socket/registration.js +166 -0
- package/lib/Socket/socket.d.ts +18 -26
- package/lib/Socket/socket.js +230 -448
- package/lib/Socket/usync.d.ts +16 -17
- package/lib/Socket/usync.js +26 -19
- package/lib/Store/index.d.ts +3 -0
- package/lib/Store/index.js +10 -0
- package/lib/Store/make-cache-manager-store.d.ts +13 -0
- package/lib/Store/make-cache-manager-store.js +83 -0
- package/lib/Store/make-in-memory-store.d.ts +118 -0
- package/lib/Store/make-in-memory-store.js +427 -0
- package/lib/Store/make-ordered-dictionary.d.ts +13 -0
- package/lib/Store/make-ordered-dictionary.js +81 -0
- package/lib/Store/object-repository.d.ts +10 -0
- package/lib/Store/object-repository.js +27 -0
- package/lib/Types/Auth.d.ts +12 -13
- package/lib/Types/Auth.js +2 -2
- package/lib/Types/Call.d.ts +1 -2
- package/lib/Types/Call.js +2 -2
- package/lib/Types/Chat.d.ts +13 -34
- package/lib/Types/Chat.js +4 -8
- package/lib/Types/Contact.d.ts +1 -6
- package/lib/Types/Contact.js +2 -2
- package/lib/Types/Events.d.ts +15 -60
- package/lib/Types/Events.js +2 -2
- package/lib/Types/GroupMetadata.d.ts +5 -17
- package/lib/Types/GroupMetadata.js +2 -2
- package/lib/Types/Label.d.ts +0 -12
- package/lib/Types/Label.js +5 -3
- package/lib/Types/LabelAssociation.d.ts +0 -1
- package/lib/Types/LabelAssociation.js +5 -3
- package/lib/Types/Message.d.ts +54 -84
- package/lib/Types/Message.js +9 -11
- package/lib/Types/Newsletter.d.ts +98 -130
- package/lib/Types/Newsletter.js +38 -31
- package/lib/Types/Product.d.ts +1 -2
- package/lib/Types/Product.js +2 -2
- package/lib/Types/Signal.d.ts +1 -20
- package/lib/Types/Signal.js +2 -2
- package/lib/Types/Socket.d.ts +25 -47
- package/lib/Types/Socket.js +2 -3
- package/lib/Types/State.d.ts +2 -14
- package/lib/Types/State.js +2 -13
- package/lib/Types/USync.d.ts +2 -3
- package/lib/Types/USync.js +2 -2
- package/lib/Types/index.d.ts +14 -22
- package/lib/Types/index.js +31 -15
- package/lib/Utils/auth-utils.d.ts +6 -7
- package/lib/Utils/auth-utils.js +148 -199
- package/lib/Utils/baileys-event-stream.d.ts +1 -2
- package/lib/Utils/baileys-event-stream.js +22 -15
- package/lib/Utils/business.d.ts +2 -3
- package/lib/Utils/business.js +69 -66
- package/lib/Utils/chat-utils.d.ts +22 -21
- package/lib/Utils/chat-utils.js +226 -260
- package/lib/Utils/crypto.d.ts +19 -19
- package/lib/Utils/crypto.js +86 -77
- package/lib/Utils/decode-wa-message.d.ts +8 -37
- package/lib/Utils/decode-wa-message.js +83 -164
- package/lib/Utils/event-buffer.d.ts +8 -7
- package/lib/Utils/event-buffer.js +76 -110
- package/lib/Utils/generics.d.ts +29 -27
- package/lib/Utils/generics.js +210 -168
- package/lib/Utils/history.d.ts +8 -12
- package/lib/Utils/history.js +46 -34
- package/lib/Utils/index.d.ts +17 -20
- package/lib/Utils/index.js +33 -20
- package/lib/Utils/link-preview.d.ts +5 -5
- package/lib/Utils/link-preview.js +22 -14
- package/lib/Utils/logger.d.ts +3 -11
- package/lib/Utils/logger.js +7 -3
- package/lib/Utils/lt-hash.d.ts +8 -9
- package/lib/Utils/lt-hash.js +28 -25
- package/lib/Utils/make-mutex.d.ts +2 -3
- package/lib/Utils/make-mutex.js +10 -7
- package/lib/Utils/messages-media.d.ts +44 -42
- package/lib/Utils/messages-media.js +475 -319
- package/lib/Utils/messages.d.ts +18 -17
- package/lib/Utils/messages.js +259 -383
- package/lib/Utils/noise-handler.d.ts +15 -14
- package/lib/Utils/noise-handler.js +38 -30
- package/lib/Utils/process-message.d.ts +13 -14
- package/lib/Utils/process-message.js +147 -239
- package/lib/Utils/signal.d.ts +5 -7
- package/lib/Utils/signal.js +72 -78
- package/lib/Utils/use-multi-file-auth-state.d.ts +2 -2
- package/lib/Utils/use-multi-file-auth-state.js +27 -29
- package/lib/Utils/validate-connection.d.ts +7 -7
- package/lib/Utils/validate-connection.js +106 -72
- package/lib/WABinary/constants.d.ts +27 -25
- package/lib/WABinary/constants.js +20 -1281
- package/lib/WABinary/decode.d.ts +5 -5
- package/lib/WABinary/decode.js +42 -28
- package/lib/WABinary/encode.d.ts +3 -3
- package/lib/WABinary/encode.js +154 -105
- package/lib/WABinary/generic-utils.d.ts +7 -5
- package/lib/WABinary/generic-utils.js +63 -56
- package/lib/WABinary/index.d.ts +5 -6
- package/lib/WABinary/index.js +21 -6
- package/lib/WABinary/jid-utils.d.ts +8 -25
- package/lib/WABinary/jid-utils.js +40 -74
- package/lib/WABinary/types.d.ts +1 -2
- package/lib/WABinary/types.js +2 -2
- package/lib/WAM/BinaryInfo.d.ts +11 -3
- package/lib/WAM/BinaryInfo.js +5 -2
- package/lib/WAM/constants.d.ts +3 -5
- package/lib/WAM/constants.js +11958 -19461
- package/lib/WAM/encode.d.ts +3 -3
- package/lib/WAM/encode.js +22 -17
- package/lib/WAM/index.d.ts +3 -4
- package/lib/WAM/index.js +19 -4
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +3 -4
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +11 -8
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +2 -3
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +14 -11
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +2 -3
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +12 -9
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +2 -3
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +13 -9
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +3 -4
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +22 -20
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +3 -5
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +8 -13
- package/lib/WAUSync/Protocols/index.d.ts +4 -5
- package/lib/WAUSync/Protocols/index.js +20 -5
- package/lib/WAUSync/USyncQuery.d.ts +4 -5
- package/lib/WAUSync/USyncQuery.js +35 -40
- package/lib/WAUSync/USyncUser.d.ts +5 -6
- package/lib/WAUSync/USyncUser.js +5 -2
- package/lib/WAUSync/index.d.ts +3 -4
- package/lib/WAUSync/index.js +19 -4
- package/lib/index.d.ts +9 -19
- package/lib/index.js +1 -36
- package/package.json +109 -99
- package/WAProto/GenerateStatics.sh +0 -3
- package/WAProto/WAProto.proto +0 -5519
- package/WAProto/fix-imports.js +0 -29
- package/WAProto/index.d.ts +0 -11969
- package/lib/Signal/lid-mapping.d.ts +0 -23
- package/lib/Signal/lid-mapping.js +0 -171
- package/lib/Socket/Client/types.js +0 -11
- package/lib/Socket/Client/websocket.js +0 -50
- package/lib/Socket/communities.d.ts +0 -244
- package/lib/Socket/communities.js +0 -431
- package/lib/Socket/mex.d.ts +0 -3
- package/lib/Socket/mex.js +0 -42
- package/lib/Types/Bussines.d.ts +0 -25
- package/lib/Types/Bussines.js +0 -2
- package/lib/Utils/browser-utils.d.ts +0 -4
- package/lib/Utils/browser-utils.js +0 -28
- package/lib/Utils/message-retry-manager.d.ts +0 -82
- package/lib/Utils/message-retry-manager.js +0 -149
- package/lib/Utils/pre-key-manager.d.ts +0 -28
- package/lib/Utils/pre-key-manager.js +0 -106
- /package/lib/{supun → supunmd} +0 -0
|
@@ -1,218 +1,64 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.makeMessagesRecvSocket = void 0;
|
|
7
|
+
const boom_1 = require("@hapi/boom");
|
|
8
|
+
const crypto_1 = require("crypto");
|
|
9
|
+
const node_cache_1 = __importDefault(require("@cacheable/node-cache"));
|
|
10
|
+
const WAProto_1 = require("../../WAProto");
|
|
11
|
+
const Defaults_1 = require("../Defaults");
|
|
12
|
+
const Types_1 = require("../Types");
|
|
13
|
+
const Utils_1 = require("../Utils");
|
|
14
|
+
const make_mutex_1 = require("../Utils/make-mutex");
|
|
15
|
+
const WABinary_1 = require("../WABinary");
|
|
16
|
+
const groups_1 = require("./groups");
|
|
17
|
+
const messages_send_1 = require("./messages-send");
|
|
18
|
+
const makeMessagesRecvSocket = (config) => {
|
|
19
|
+
const {
|
|
20
|
+
logger,
|
|
21
|
+
retryRequestDelayMs,
|
|
22
|
+
maxMsgRetryCount,
|
|
23
|
+
getMessage,
|
|
24
|
+
shouldIgnoreJid
|
|
25
|
+
} = config;
|
|
26
|
+
const sock = (0, messages_send_1.makeMessagesSocket)(config);
|
|
27
|
+
const {
|
|
28
|
+
ev,
|
|
29
|
+
authState,
|
|
30
|
+
ws,
|
|
31
|
+
processingMutex,
|
|
32
|
+
signalRepository,
|
|
33
|
+
query,
|
|
34
|
+
upsertMessage,
|
|
35
|
+
resyncAppState,
|
|
36
|
+
groupMetadata,
|
|
37
|
+
onUnexpectedError,
|
|
38
|
+
assertSessions,
|
|
39
|
+
sendNode,
|
|
40
|
+
relayMessage,
|
|
41
|
+
sendReceipt,
|
|
42
|
+
uploadPreKeys,
|
|
43
|
+
createParticipantNodes,
|
|
44
|
+
getUSyncDevices,
|
|
45
|
+
sendPeerDataOperationMessage
|
|
46
|
+
} = sock;
|
|
17
47
|
/** this mutex ensures that each retryRequest will wait for the previous one to finish */
|
|
18
|
-
const retryMutex = makeMutex();
|
|
19
|
-
const msgRetryCache = config.msgRetryCounterCache ||
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
32
|
-
useClones: false
|
|
33
|
-
});
|
|
48
|
+
const retryMutex = (0, make_mutex_1.makeMutex)();
|
|
49
|
+
const msgRetryCache = config.msgRetryCounterCache || new node_cache_1.default({
|
|
50
|
+
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
51
|
+
useClones: false
|
|
52
|
+
});
|
|
53
|
+
const callOfferCache = config.callOfferCache || new node_cache_1.default({
|
|
54
|
+
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.CALL_OFFER, // 5 mins
|
|
55
|
+
useClones: false
|
|
56
|
+
});
|
|
57
|
+
const placeholderResendCache = config.placeholderResendCache || new node_cache_1.default({
|
|
58
|
+
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
59
|
+
useClones: false
|
|
60
|
+
});
|
|
34
61
|
let sendActiveReceipts = false;
|
|
35
|
-
const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
|
|
36
|
-
if (!authState.creds.me?.id) {
|
|
37
|
-
throw new Boom('Not authenticated');
|
|
38
|
-
}
|
|
39
|
-
const pdoMessage = {
|
|
40
|
-
historySyncOnDemandRequest: {
|
|
41
|
-
chatJid: oldestMsgKey.remoteJid,
|
|
42
|
-
oldestMsgFromMe: oldestMsgKey.fromMe,
|
|
43
|
-
oldestMsgId: oldestMsgKey.id,
|
|
44
|
-
oldestMsgTimestampMs: oldestMsgTimestamp,
|
|
45
|
-
onDemandMsgCount: count
|
|
46
|
-
},
|
|
47
|
-
peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
|
|
48
|
-
};
|
|
49
|
-
return sendPeerDataOperationMessage(pdoMessage);
|
|
50
|
-
};
|
|
51
|
-
const requestPlaceholderResend = async (messageKey) => {
|
|
52
|
-
if (!authState.creds.me?.id) {
|
|
53
|
-
throw new Boom('Not authenticated');
|
|
54
|
-
}
|
|
55
|
-
if (placeholderResendCache.get(messageKey?.id)) {
|
|
56
|
-
logger.debug({ messageKey }, 'already requested resend');
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
placeholderResendCache.set(messageKey?.id, true);
|
|
61
|
-
}
|
|
62
|
-
await delay(5000);
|
|
63
|
-
if (!placeholderResendCache.get(messageKey?.id)) {
|
|
64
|
-
logger.debug({ messageKey }, 'message received while resend requested');
|
|
65
|
-
return 'RESOLVED';
|
|
66
|
-
}
|
|
67
|
-
const pdoMessage = {
|
|
68
|
-
placeholderMessageResendRequest: [
|
|
69
|
-
{
|
|
70
|
-
messageKey
|
|
71
|
-
}
|
|
72
|
-
],
|
|
73
|
-
peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
|
|
74
|
-
};
|
|
75
|
-
setTimeout(() => {
|
|
76
|
-
if (placeholderResendCache.get(messageKey?.id)) {
|
|
77
|
-
logger.debug({ messageKey }, 'PDO message without response after 15 seconds. Phone possibly offline');
|
|
78
|
-
placeholderResendCache.del(messageKey?.id);
|
|
79
|
-
}
|
|
80
|
-
}, 15000);
|
|
81
|
-
return sendPeerDataOperationMessage(pdoMessage);
|
|
82
|
-
};
|
|
83
|
-
// Handles mex newsletter notifications
|
|
84
|
-
const handleMexNewsletterNotification = async (node) => {
|
|
85
|
-
const mexNode = getBinaryNodeChild(node, 'mex');
|
|
86
|
-
if (!mexNode?.content) {
|
|
87
|
-
logger.warn({ node }, 'Invalid mex newsletter notification');
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
let data;
|
|
91
|
-
try {
|
|
92
|
-
data = JSON.parse(mexNode.content.toString());
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
logger.error({ err: error, node }, 'Failed to parse mex newsletter notification');
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const operation = data?.operation;
|
|
99
|
-
const updates = data?.updates;
|
|
100
|
-
if (!updates || !operation) {
|
|
101
|
-
logger.warn({ data }, 'Invalid mex newsletter notification content');
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
logger.info({ operation, updates }, 'got mex newsletter notification');
|
|
105
|
-
switch (operation) {
|
|
106
|
-
case 'NotificationNewsletterUpdate':
|
|
107
|
-
for (const update of updates) {
|
|
108
|
-
if (update.jid && update.settings && Object.keys(update.settings).length > 0) {
|
|
109
|
-
ev.emit('newsletter-settings.update', {
|
|
110
|
-
id: update.jid,
|
|
111
|
-
update: update.settings
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
break;
|
|
116
|
-
case 'NotificationNewsletterAdminPromote':
|
|
117
|
-
for (const update of updates) {
|
|
118
|
-
if (update.jid && update.user) {
|
|
119
|
-
ev.emit('newsletter-participants.update', {
|
|
120
|
-
id: update.jid,
|
|
121
|
-
author: node.attrs.from,
|
|
122
|
-
user: update.user,
|
|
123
|
-
new_role: 'ADMIN',
|
|
124
|
-
action: 'promote'
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
break;
|
|
129
|
-
default:
|
|
130
|
-
logger.info({ operation, data }, 'Unhandled mex newsletter notification');
|
|
131
|
-
break;
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
// Handles newsletter notifications
|
|
135
|
-
const handleNewsletterNotification = async (node) => {
|
|
136
|
-
const from = node.attrs.from;
|
|
137
|
-
const child = getAllBinaryNodeChildren(node)[0];
|
|
138
|
-
const author = node.attrs.participant;
|
|
139
|
-
logger.info({ from, child }, 'got newsletter notification');
|
|
140
|
-
switch (child.tag) {
|
|
141
|
-
case 'reaction':
|
|
142
|
-
const reactionUpdate = {
|
|
143
|
-
id: from,
|
|
144
|
-
server_id: child.attrs.message_id,
|
|
145
|
-
reaction: {
|
|
146
|
-
code: getBinaryNodeChildString(child, 'reaction'),
|
|
147
|
-
count: 1
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
ev.emit('newsletter.reaction', reactionUpdate);
|
|
151
|
-
break;
|
|
152
|
-
case 'view':
|
|
153
|
-
const viewUpdate = {
|
|
154
|
-
id: from,
|
|
155
|
-
server_id: child.attrs.message_id,
|
|
156
|
-
count: parseInt(child.content?.toString() || '0', 10)
|
|
157
|
-
};
|
|
158
|
-
ev.emit('newsletter.view', viewUpdate);
|
|
159
|
-
break;
|
|
160
|
-
case 'participant':
|
|
161
|
-
const participantUpdate = {
|
|
162
|
-
id: from,
|
|
163
|
-
author,
|
|
164
|
-
user: child.attrs.jid,
|
|
165
|
-
action: child.attrs.action,
|
|
166
|
-
new_role: child.attrs.role
|
|
167
|
-
};
|
|
168
|
-
ev.emit('newsletter-participants.update', participantUpdate);
|
|
169
|
-
break;
|
|
170
|
-
case 'update':
|
|
171
|
-
const settingsNode = getBinaryNodeChild(child, 'settings');
|
|
172
|
-
if (settingsNode) {
|
|
173
|
-
const update = {};
|
|
174
|
-
const nameNode = getBinaryNodeChild(settingsNode, 'name');
|
|
175
|
-
if (nameNode?.content)
|
|
176
|
-
update.name = nameNode.content.toString();
|
|
177
|
-
const descriptionNode = getBinaryNodeChild(settingsNode, 'description');
|
|
178
|
-
if (descriptionNode?.content)
|
|
179
|
-
update.description = descriptionNode.content.toString();
|
|
180
|
-
ev.emit('newsletter-settings.update', {
|
|
181
|
-
id: from,
|
|
182
|
-
update
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
break;
|
|
186
|
-
case 'message':
|
|
187
|
-
const plaintextNode = getBinaryNodeChild(child, 'plaintext');
|
|
188
|
-
if (plaintextNode?.content) {
|
|
189
|
-
try {
|
|
190
|
-
const contentBuf = typeof plaintextNode.content === 'string'
|
|
191
|
-
? Buffer.from(plaintextNode.content, 'binary')
|
|
192
|
-
: Buffer.from(plaintextNode.content);
|
|
193
|
-
const messageProto = proto.Message.decode(contentBuf).toJSON();
|
|
194
|
-
const fullMessage = proto.WebMessageInfo.fromObject({
|
|
195
|
-
key: {
|
|
196
|
-
remoteJid: from,
|
|
197
|
-
id: child.attrs.message_id || child.attrs.server_id,
|
|
198
|
-
fromMe: false // TODO: is this really true though
|
|
199
|
-
},
|
|
200
|
-
message: messageProto,
|
|
201
|
-
messageTimestamp: +child.attrs.t
|
|
202
|
-
}).toJSON();
|
|
203
|
-
await upsertMessage(fullMessage, 'append');
|
|
204
|
-
logger.info('Processed plaintext newsletter message');
|
|
205
|
-
}
|
|
206
|
-
catch (error) {
|
|
207
|
-
logger.error({ error }, 'Failed to decode plaintext newsletter message');
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
break;
|
|
211
|
-
default:
|
|
212
|
-
logger.warn({ node }, 'Unknown newsletter notification');
|
|
213
|
-
break;
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
62
|
const sendMessageAck = async ({ tag, attrs, content }, errorCode) => {
|
|
217
63
|
const stanza = {
|
|
218
64
|
tag: 'ack',
|
|
@@ -221,7 +67,7 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
221
67
|
to: attrs.from,
|
|
222
68
|
class: tag
|
|
223
69
|
}
|
|
224
|
-
}
|
|
70
|
+
}
|
|
225
71
|
if (!!errorCode) {
|
|
226
72
|
stanza.attrs.error = errorCode.toString();
|
|
227
73
|
}
|
|
@@ -231,113 +77,143 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
231
77
|
if (!!attrs.recipient) {
|
|
232
78
|
stanza.attrs.recipient = attrs.recipient;
|
|
233
79
|
}
|
|
234
|
-
if (!!attrs.type &&
|
|
235
|
-
(tag !== 'message' || getBinaryNodeChild({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
|
|
80
|
+
if (!!attrs.type && (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
|
|
236
81
|
stanza.attrs.type = attrs.type;
|
|
237
82
|
}
|
|
238
|
-
if (tag === 'message' && getBinaryNodeChild({ tag, attrs, content }, 'unavailable')) {
|
|
83
|
+
if (tag === 'message' && (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable')) {
|
|
239
84
|
stanza.attrs.from = authState.creds.me.id;
|
|
240
85
|
}
|
|
241
|
-
logger.debug({
|
|
86
|
+
logger.debug({
|
|
87
|
+
recv: {
|
|
88
|
+
tag,
|
|
89
|
+
attrs
|
|
90
|
+
},
|
|
91
|
+
sent: stanza.attrs }, 'sent ack');
|
|
242
92
|
await sendNode(stanza);
|
|
243
93
|
};
|
|
94
|
+
const offerCall = async (toJid, isVideo = false) => {
|
|
95
|
+
const callId = (0, crypto_1.randomBytes)(16).toString('hex').toUpperCase().substring(0, 64);
|
|
96
|
+
const offerContent = [];
|
|
97
|
+
offerContent.push({
|
|
98
|
+
tag: 'audio',
|
|
99
|
+
attrs: {
|
|
100
|
+
enc: 'opus',
|
|
101
|
+
rate: '16000'
|
|
102
|
+
}, content: undefined
|
|
103
|
+
});
|
|
104
|
+
offerContent.push({
|
|
105
|
+
tag: 'audio',
|
|
106
|
+
attrs: {
|
|
107
|
+
enc: 'opus',
|
|
108
|
+
rate: '8000'
|
|
109
|
+
}, content: undefined
|
|
110
|
+
});
|
|
111
|
+
if (isVideo) {
|
|
112
|
+
offerContent.push({
|
|
113
|
+
tag: 'video',
|
|
114
|
+
attrs: {
|
|
115
|
+
orientation: '0',
|
|
116
|
+
'screen_width': '1920',
|
|
117
|
+
'screen_height': '1080',
|
|
118
|
+
'device_orientation': '0',
|
|
119
|
+
enc: 'vp8',
|
|
120
|
+
dec: 'vp8',
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
offerContent.push({
|
|
125
|
+
tag: 'net',
|
|
126
|
+
attrs: {
|
|
127
|
+
medium: '3'
|
|
128
|
+
}, content: undefined
|
|
129
|
+
});
|
|
130
|
+
offerContent.push({
|
|
131
|
+
tag: 'capability',
|
|
132
|
+
attrs: {
|
|
133
|
+
ver: '1'
|
|
134
|
+
}, content: new Uint8Array([1, 4, 255, 131, 207, 4]) });
|
|
135
|
+
offerContent.push({
|
|
136
|
+
tag: 'encopt',
|
|
137
|
+
attrs: {
|
|
138
|
+
keygen: '2'
|
|
139
|
+
}, content: undefined
|
|
140
|
+
})
|
|
141
|
+
const encKey = (0, crypto_1.randomBytes)(32);
|
|
142
|
+
const devices = (await getUSyncDevices([toJid], true, false)).map(({ user, device }) => (0, WABinary_1.jidEncode)(user, 's.whatsapp.net', device));
|
|
143
|
+
await assertSessions(devices, true);
|
|
144
|
+
const { nodes: destinations, shouldIncludeDeviceIdentity } = await createParticipantNodes(devices, {
|
|
145
|
+
call: {
|
|
146
|
+
callKey: encKey
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
offerContent.push({ tag: 'destination', attrs: {}, content: destinations });
|
|
150
|
+
if (shouldIncludeDeviceIdentity) {
|
|
151
|
+
offerContent.push({
|
|
152
|
+
tag: 'device-identity',
|
|
153
|
+
attrs: {},
|
|
154
|
+
content: (0, Utils_1.encodeSignedDeviceIdentity)(authState.creds.account, true)
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const stanza = ({
|
|
158
|
+
tag: 'call',
|
|
159
|
+
attrs: {
|
|
160
|
+
to: toJid,
|
|
161
|
+
},
|
|
162
|
+
content: [{
|
|
163
|
+
tag: 'offer',
|
|
164
|
+
attrs: {
|
|
165
|
+
'call-id': callId,
|
|
166
|
+
'call-creator': authState.creds.me.id,
|
|
167
|
+
},
|
|
168
|
+
content: offerContent,
|
|
169
|
+
}],
|
|
170
|
+
});
|
|
171
|
+
await query(stanza);
|
|
172
|
+
return {
|
|
173
|
+
callId,
|
|
174
|
+
toJid,
|
|
175
|
+
isVideo,
|
|
176
|
+
};
|
|
177
|
+
};
|
|
244
178
|
const rejectCall = async (callId, callFrom) => {
|
|
245
|
-
const stanza = {
|
|
179
|
+
const stanza = ({
|
|
246
180
|
tag: 'call',
|
|
247
181
|
attrs: {
|
|
248
182
|
from: authState.creds.me.id,
|
|
249
|
-
to: callFrom
|
|
183
|
+
to: callFrom,
|
|
250
184
|
},
|
|
251
|
-
content: [
|
|
252
|
-
{
|
|
185
|
+
content: [{
|
|
253
186
|
tag: 'reject',
|
|
254
187
|
attrs: {
|
|
255
188
|
'call-id': callId,
|
|
256
189
|
'call-creator': callFrom,
|
|
257
|
-
count: '0'
|
|
190
|
+
count: '0',
|
|
258
191
|
},
|
|
259
|
-
content: undefined
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
};
|
|
192
|
+
content: undefined,
|
|
193
|
+
}],
|
|
194
|
+
});
|
|
263
195
|
await query(stanza);
|
|
264
196
|
};
|
|
265
197
|
const sendRetryRequest = async (node, forceIncludeKeys = false) => {
|
|
266
|
-
const { fullMessage } = decodeMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '');
|
|
198
|
+
const { fullMessage } = (0, Utils_1.decodeMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '');
|
|
267
199
|
const { key: msgKey } = fullMessage;
|
|
268
200
|
const msgId = msgKey.id;
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
// Increment retry count using new system
|
|
277
|
-
const retryCount = messageRetryManager.incrementRetryCount(msgId);
|
|
278
|
-
// Use the new retry count for the rest of the logic
|
|
279
|
-
const key = `${msgId}:${msgKey?.participant}`;
|
|
280
|
-
msgRetryCache.set(key, retryCount);
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
// Fallback to old system
|
|
284
|
-
const key = `${msgId}:${msgKey?.participant}`;
|
|
285
|
-
let retryCount = (await msgRetryCache.get(key)) || 0;
|
|
286
|
-
if (retryCount >= maxMsgRetryCount) {
|
|
287
|
-
logger.debug({ retryCount, msgId }, 'reached retry limit, clearing');
|
|
288
|
-
msgRetryCache.del(key);
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
retryCount += 1;
|
|
292
|
-
await msgRetryCache.set(key, retryCount);
|
|
201
|
+
const key = `${msgId}:${msgKey === null || msgKey === void 0 ? void 0 : msgKey.participant}`;
|
|
202
|
+
let retryCount = msgRetryCache.get(key) || 0;
|
|
203
|
+
if (retryCount >= maxMsgRetryCount) {
|
|
204
|
+
logger.debug({ retryCount, msgId }, 'reached retry limit, clearing');
|
|
205
|
+
msgRetryCache.del(key);
|
|
206
|
+
return;
|
|
293
207
|
}
|
|
294
|
-
|
|
295
|
-
|
|
208
|
+
retryCount += 1;
|
|
209
|
+
msgRetryCache.set(key, retryCount);
|
|
296
210
|
const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds;
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (enableAutoSessionRecreation && messageRetryManager) {
|
|
302
|
-
try {
|
|
303
|
-
// Check if we have a session with this JID
|
|
304
|
-
const sessionId = signalRepository.jidToSignalProtocolAddress(fromJid);
|
|
305
|
-
const hasSession = await signalRepository.validateSession(fromJid);
|
|
306
|
-
const result = messageRetryManager.shouldRecreateSession(fromJid, retryCount, hasSession.exists);
|
|
307
|
-
shouldRecreateSession = result.recreate;
|
|
308
|
-
recreateReason = result.reason;
|
|
309
|
-
if (shouldRecreateSession) {
|
|
310
|
-
logger.debug({ fromJid, retryCount, reason: recreateReason }, 'recreating session for retry');
|
|
311
|
-
// Delete existing session to force recreation
|
|
312
|
-
await authState.keys.set({ session: { [sessionId]: null } });
|
|
313
|
-
forceIncludeKeys = true;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
catch (error) {
|
|
317
|
-
logger.warn({ error, fromJid }, 'failed to check session recreation');
|
|
318
|
-
}
|
|
211
|
+
if (retryCount === 1) {
|
|
212
|
+
//request a resend via phone
|
|
213
|
+
const msgId = await requestPlaceholderResend(msgKey);
|
|
214
|
+
logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId}`);
|
|
319
215
|
}
|
|
320
|
-
|
|
321
|
-
// Use new retry manager for phone requests if available
|
|
322
|
-
if (messageRetryManager) {
|
|
323
|
-
// Schedule phone request with delay (like whatsmeow)
|
|
324
|
-
messageRetryManager.schedulePhoneRequest(msgId, async () => {
|
|
325
|
-
try {
|
|
326
|
-
const requestId = await requestPlaceholderResend(msgKey);
|
|
327
|
-
logger.debug(`sendRetryRequest: requested placeholder resend (${requestId}) for message ${msgId} (scheduled)`);
|
|
328
|
-
}
|
|
329
|
-
catch (error) {
|
|
330
|
-
logger.warn({ error, msgId }, 'failed to send scheduled phone request');
|
|
331
|
-
}
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
// Fallback to immediate request
|
|
336
|
-
const msgId = await requestPlaceholderResend(msgKey);
|
|
337
|
-
logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId}`);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
const deviceIdentity = encodeSignedDeviceIdentity(account, true);
|
|
216
|
+
const deviceIdentity = (0, Utils_1.encodeSignedDeviceIdentity)(account, true);
|
|
341
217
|
await authState.keys.transaction(async () => {
|
|
342
218
|
const receipt = {
|
|
343
219
|
tag: 'receipt',
|
|
@@ -353,15 +229,13 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
353
229
|
count: retryCount.toString(),
|
|
354
230
|
id: node.attrs.id,
|
|
355
231
|
t: node.attrs.t,
|
|
356
|
-
v: '1'
|
|
357
|
-
// ADD ERROR FIELD
|
|
358
|
-
error: '0'
|
|
232
|
+
v: '1'
|
|
359
233
|
}
|
|
360
234
|
},
|
|
361
235
|
{
|
|
362
236
|
tag: 'registration',
|
|
363
237
|
attrs: {},
|
|
364
|
-
content: encodeBigEndian(authState.creds.registrationId)
|
|
238
|
+
content: (0, Utils_1.encodeBigEndian)(authState.creds.registrationId)
|
|
365
239
|
}
|
|
366
240
|
]
|
|
367
241
|
};
|
|
@@ -371,8 +245,8 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
371
245
|
if (node.attrs.participant) {
|
|
372
246
|
receipt.attrs.participant = node.attrs.participant;
|
|
373
247
|
}
|
|
374
|
-
if (retryCount > 1 || forceIncludeKeys
|
|
375
|
-
const { update, preKeys } = await getNextPreKeys(authState, 1);
|
|
248
|
+
if (retryCount > 1 || forceIncludeKeys) {
|
|
249
|
+
const { update, preKeys } = await (0, Utils_1.getNextPreKeys)(authState, 1);
|
|
376
250
|
const [keyId] = Object.keys(preKeys);
|
|
377
251
|
const key = preKeys[+keyId];
|
|
378
252
|
const content = receipt.content;
|
|
@@ -380,10 +254,10 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
380
254
|
tag: 'keys',
|
|
381
255
|
attrs: {},
|
|
382
256
|
content: [
|
|
383
|
-
{ tag: 'type', attrs: {}, content: Buffer.from(KEY_BUNDLE_TYPE) },
|
|
257
|
+
{ tag: 'type', attrs: {}, content: Buffer.from(Defaults_1.KEY_BUNDLE_TYPE) },
|
|
384
258
|
{ tag: 'identity', attrs: {}, content: identityKey.public },
|
|
385
|
-
xmppPreKey(key, +keyId),
|
|
386
|
-
xmppSignedPreKey(signedPreKey),
|
|
259
|
+
(0, Utils_1.xmppPreKey)(key, +keyId),
|
|
260
|
+
(0, Utils_1.xmppSignedPreKey)(signedPreKey),
|
|
387
261
|
{ tag: 'device-identity', attrs: {}, content: deviceIdentity }
|
|
388
262
|
]
|
|
389
263
|
});
|
|
@@ -391,21 +265,21 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
391
265
|
}
|
|
392
266
|
await sendNode(receipt);
|
|
393
267
|
logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt');
|
|
394
|
-
}
|
|
268
|
+
});
|
|
395
269
|
};
|
|
396
270
|
const handleEncryptNotification = async (node) => {
|
|
397
271
|
const from = node.attrs.from;
|
|
398
|
-
if (from === S_WHATSAPP_NET) {
|
|
399
|
-
const countChild = getBinaryNodeChild(node, 'count');
|
|
272
|
+
if (from === WABinary_1.S_WHATSAPP_NET) {
|
|
273
|
+
const countChild = (0, WABinary_1.getBinaryNodeChild)(node, 'count');
|
|
400
274
|
const count = +countChild.attrs.value;
|
|
401
|
-
const shouldUploadMorePreKeys = count < MIN_PREKEY_COUNT;
|
|
275
|
+
const shouldUploadMorePreKeys = count < Defaults_1.MIN_PREKEY_COUNT;
|
|
402
276
|
logger.debug({ count, shouldUploadMorePreKeys }, 'recv pre-key count');
|
|
403
277
|
if (shouldUploadMorePreKeys) {
|
|
404
278
|
await uploadPreKeys();
|
|
405
279
|
}
|
|
406
280
|
}
|
|
407
281
|
else {
|
|
408
|
-
const identityNode = getBinaryNodeChild(node, 'identity');
|
|
282
|
+
const identityNode = (0, WABinary_1.getBinaryNodeChild)(node, 'identity');
|
|
409
283
|
if (identityNode) {
|
|
410
284
|
logger.info({ jid: from }, 'identity changed');
|
|
411
285
|
// not handling right now
|
|
@@ -416,46 +290,38 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
416
290
|
}
|
|
417
291
|
}
|
|
418
292
|
};
|
|
419
|
-
const handleGroupNotification = (
|
|
420
|
-
|
|
421
|
-
const
|
|
422
|
-
|
|
423
|
-
const affectedParticipantLid = getBinaryNodeChild(child, 'participant')?.attrs?.jid || actingParticipantLid;
|
|
424
|
-
const affectedParticipantPn = getBinaryNodeChild(child, 'participant')?.attrs?.phone_number || actingParticipantPn;
|
|
425
|
-
switch (child?.tag) {
|
|
293
|
+
const handleGroupNotification = (participant, child, msg) => {
|
|
294
|
+
var _a, _b, _c, _d;
|
|
295
|
+
const participantJid = ((_b = (_a = (0, WABinary_1.getBinaryNodeChild)(child, 'participant')) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.jid) || participant;
|
|
296
|
+
switch (child === null || child === void 0 ? void 0 : child.tag) {
|
|
426
297
|
case 'create':
|
|
427
|
-
const metadata = extractGroupMetadata(child);
|
|
428
|
-
msg.messageStubType = WAMessageStubType.GROUP_CREATE;
|
|
298
|
+
const metadata = (0, groups_1.extractGroupMetadata)(child);
|
|
299
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CREATE;
|
|
429
300
|
msg.messageStubParameters = [metadata.subject];
|
|
430
|
-
msg.key = { participant: metadata.owner
|
|
431
|
-
ev.emit('chats.upsert', [
|
|
432
|
-
{
|
|
301
|
+
msg.key = { participant: metadata.owner };
|
|
302
|
+
ev.emit('chats.upsert', [{
|
|
433
303
|
id: metadata.id,
|
|
434
304
|
name: metadata.subject,
|
|
435
|
-
conversationTimestamp: metadata.creation
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
ev.emit('groups.upsert', [
|
|
439
|
-
{
|
|
305
|
+
conversationTimestamp: metadata.creation,
|
|
306
|
+
}]);
|
|
307
|
+
ev.emit('groups.upsert', [{
|
|
440
308
|
...metadata,
|
|
441
|
-
author:
|
|
442
|
-
|
|
443
|
-
}
|
|
444
|
-
]);
|
|
309
|
+
author: participant
|
|
310
|
+
}]);
|
|
445
311
|
break;
|
|
446
312
|
case 'ephemeral':
|
|
447
313
|
case 'not_ephemeral':
|
|
448
314
|
msg.message = {
|
|
449
315
|
protocolMessage: {
|
|
450
|
-
type: proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
|
|
316
|
+
type: WAProto_1.proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
|
|
451
317
|
ephemeralExpiration: +(child.attrs.expiration || 0)
|
|
452
318
|
}
|
|
453
319
|
};
|
|
454
320
|
break;
|
|
455
321
|
case 'modify':
|
|
456
|
-
const oldNumber = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid);
|
|
322
|
+
const oldNumber = (0, WABinary_1.getBinaryNodeChildren)(child, 'participant').map(p => p.attrs.jid);
|
|
457
323
|
msg.messageStubParameters = oldNumber || [];
|
|
458
|
-
msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER;
|
|
324
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER;
|
|
459
325
|
break;
|
|
460
326
|
case 'promote':
|
|
461
327
|
case 'demote':
|
|
@@ -463,90 +329,121 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
463
329
|
case 'add':
|
|
464
330
|
case 'leave':
|
|
465
331
|
const stubType = `GROUP_PARTICIPANT_${child.tag.toUpperCase()}`;
|
|
466
|
-
msg.messageStubType = WAMessageStubType[stubType];
|
|
467
|
-
const participants = getBinaryNodeChildren(child, 'participant').map(
|
|
468
|
-
// TODO: Store LID MAPPINGS
|
|
469
|
-
return {
|
|
470
|
-
id: attrs.jid,
|
|
471
|
-
phoneNumber: isLidUser(attrs.jid) && isPnUser(attrs.phone_number) ? attrs.phone_number : undefined,
|
|
472
|
-
lid: isPnUser(attrs.jid) && isLidUser(attrs.lid) ? attrs.lid : undefined,
|
|
473
|
-
admin: (attrs.type || null)
|
|
474
|
-
};
|
|
475
|
-
});
|
|
332
|
+
msg.messageStubType = Types_1.WAMessageStubType[stubType];
|
|
333
|
+
const participants = (0, WABinary_1.getBinaryNodeChildren)(child, 'participant').map(p => p.attrs.jid);
|
|
476
334
|
if (participants.length === 1 &&
|
|
477
335
|
// if recv. "remove" message and sender removed themselves
|
|
478
336
|
// mark as left
|
|
479
|
-
(areJidsSameUser(participants[0]
|
|
480
|
-
areJidsSameUser(participants[0].id, actingParticipantPn)) &&
|
|
337
|
+
(0, WABinary_1.areJidsSameUser)(participants[0], participant) &&
|
|
481
338
|
child.tag === 'remove') {
|
|
482
|
-
msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_LEAVE;
|
|
339
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_PARTICIPANT_LEAVE;
|
|
483
340
|
}
|
|
484
|
-
msg.messageStubParameters = participants
|
|
341
|
+
msg.messageStubParameters = participants;
|
|
485
342
|
break;
|
|
486
343
|
case 'subject':
|
|
487
|
-
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_SUBJECT;
|
|
344
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT;
|
|
488
345
|
msg.messageStubParameters = [child.attrs.subject];
|
|
489
346
|
break;
|
|
490
347
|
case 'description':
|
|
491
|
-
const description = getBinaryNodeChild(child, 'body')
|
|
492
|
-
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_DESCRIPTION;
|
|
348
|
+
const description = (_d = (_c = (0, WABinary_1.getBinaryNodeChild)(child, 'body')) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d.toString();
|
|
349
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_DESCRIPTION;
|
|
493
350
|
msg.messageStubParameters = description ? [description] : undefined;
|
|
494
351
|
break;
|
|
495
352
|
case 'announcement':
|
|
496
353
|
case 'not_announcement':
|
|
497
|
-
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_ANNOUNCE;
|
|
498
|
-
msg.messageStubParameters = [child.tag === 'announcement' ? 'on' : 'off'];
|
|
354
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE;
|
|
355
|
+
msg.messageStubParameters = [(child.tag === 'announcement') ? 'on' : 'off'];
|
|
499
356
|
break;
|
|
500
357
|
case 'locked':
|
|
501
358
|
case 'unlocked':
|
|
502
|
-
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_RESTRICT;
|
|
503
|
-
msg.messageStubParameters = [child.tag === 'locked' ? 'on' : 'off'];
|
|
359
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_RESTRICT;
|
|
360
|
+
msg.messageStubParameters = [(child.tag === 'locked') ? 'on' : 'off'];
|
|
504
361
|
break;
|
|
505
362
|
case 'invite':
|
|
506
|
-
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_INVITE_LINK;
|
|
363
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_INVITE_LINK;
|
|
507
364
|
msg.messageStubParameters = [child.attrs.code];
|
|
508
365
|
break;
|
|
509
366
|
case 'member_add_mode':
|
|
510
367
|
const addMode = child.content;
|
|
511
368
|
if (addMode) {
|
|
512
|
-
msg.messageStubType = WAMessageStubType.GROUP_MEMBER_ADD_MODE;
|
|
369
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBER_ADD_MODE;
|
|
513
370
|
msg.messageStubParameters = [addMode.toString()];
|
|
514
371
|
}
|
|
515
372
|
break;
|
|
516
373
|
case 'membership_approval_mode':
|
|
517
|
-
const approvalMode = getBinaryNodeChild(child, 'group_join');
|
|
374
|
+
const approvalMode = (0, WABinary_1.getBinaryNodeChild)(child, 'group_join');
|
|
518
375
|
if (approvalMode) {
|
|
519
|
-
msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE;
|
|
376
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE;
|
|
520
377
|
msg.messageStubParameters = [approvalMode.attrs.state];
|
|
521
378
|
}
|
|
522
379
|
break;
|
|
523
380
|
case 'created_membership_requests':
|
|
524
|
-
msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
|
|
525
|
-
msg.messageStubParameters = [
|
|
526
|
-
JSON.stringify({ lid: affectedParticipantLid, pn: affectedParticipantPn }),
|
|
527
|
-
'created',
|
|
528
|
-
child.attrs.request_method
|
|
529
|
-
];
|
|
381
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
|
|
382
|
+
msg.messageStubParameters = [participantJid, 'created', child.attrs.request_method];
|
|
530
383
|
break;
|
|
531
384
|
case 'revoked_membership_requests':
|
|
532
|
-
const isDenied = areJidsSameUser(
|
|
533
|
-
|
|
534
|
-
msg.
|
|
535
|
-
|
|
536
|
-
JSON.stringify({ lid: affectedParticipantLid, pn: affectedParticipantPn }),
|
|
537
|
-
isDenied ? 'revoked' : 'rejected'
|
|
538
|
-
];
|
|
385
|
+
const isDenied = (0, WABinary_1.areJidsSameUser)(participantJid, participant);
|
|
386
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
|
|
387
|
+
msg.messageStubParameters = [participantJid, isDenied ? 'revoked' : 'rejected'];
|
|
388
|
+
break;
|
|
539
389
|
break;
|
|
390
|
+
default:
|
|
391
|
+
// console.log("BAILEYS-DEBUG:", JSON.stringify({ ...child, content: Buffer.isBuffer(child.content) ? child.content.toString() : child.content, participant }, null, 2))
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
const handleNewsletterNotification = (id, node) => {
|
|
395
|
+
const messages = (0, WABinary_1.getBinaryNodeChild)(node, 'messages');
|
|
396
|
+
const message = (0, WABinary_1.getBinaryNodeChild)(messages, 'message');
|
|
397
|
+
const serverId = message.attrs.server_id;
|
|
398
|
+
const reactionsList = (0, WABinary_1.getBinaryNodeChild)(message, 'reactions');
|
|
399
|
+
const viewsList = (0, WABinary_1.getBinaryNodeChildren)(message, 'views_count');
|
|
400
|
+
if (reactionsList) {
|
|
401
|
+
const reactions = (0, WABinary_1.getBinaryNodeChildren)(reactionsList, 'reaction');
|
|
402
|
+
if (reactions.length === 0) {
|
|
403
|
+
ev.emit('newsletter.reaction', { id, 'server_id': serverId, reaction: { removed: true } });
|
|
404
|
+
}
|
|
405
|
+
reactions.forEach(item => {
|
|
406
|
+
var _a, _b;
|
|
407
|
+
ev.emit('newsletter.reaction', { id, 'server_id': serverId, reaction: { code: (_a = item.attrs) === null || _a === void 0 ? void 0 : _a.code, count: +((_b = item.attrs) === null || _b === void 0 ? void 0 : _b.count) } });
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
if (viewsList.length) {
|
|
411
|
+
viewsList.forEach(item => {
|
|
412
|
+
ev.emit('newsletter.view', { id, 'server_id': serverId, count: +item.attrs.count });
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
const handleMexNewsletterNotification = (id, node) => {
|
|
417
|
+
var _a;
|
|
418
|
+
const operation = node === null || node === void 0 ? void 0 : node.attrs.op_name;
|
|
419
|
+
const content = JSON.parse((_a = node === null || node === void 0 ? void 0 : node.content) === null || _a === void 0 ? void 0 : _a.toString());
|
|
420
|
+
let contentPath;
|
|
421
|
+
if (operation === Types_1.MexOperations.PROMOTE || operation === Types_1.MexOperations.DEMOTE) {
|
|
422
|
+
let action;
|
|
423
|
+
if (operation === Types_1.MexOperations.PROMOTE) {
|
|
424
|
+
action = 'promote';
|
|
425
|
+
contentPath = content.data[Types_1.XWAPaths.PROMOTE];
|
|
426
|
+
}
|
|
427
|
+
if (operation === Types_1.MexOperations.DEMOTE) {
|
|
428
|
+
action = 'demote';
|
|
429
|
+
contentPath = content.data[Types_1.XWAPaths.DEMOTE];
|
|
430
|
+
}
|
|
431
|
+
ev.emit('newsletter-participants.update', { id, author: contentPath.actor.pn, user: contentPath.user.pn, new_role: contentPath.user_new_role, action });
|
|
432
|
+
}
|
|
433
|
+
if (operation === Types_1.MexOperations.UPDATE) {
|
|
434
|
+
contentPath = content.data[Types_1.XWAPaths.METADATA_UPDATE];
|
|
435
|
+
ev.emit('newsletter-settings.update', { id, update: contentPath.thread_metadata.settings });
|
|
540
436
|
}
|
|
541
437
|
};
|
|
542
438
|
const processNotification = async (node) => {
|
|
439
|
+
var _a, _b;
|
|
543
440
|
const result = {};
|
|
544
|
-
const [child] = getAllBinaryNodeChildren(node);
|
|
441
|
+
const [child] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
|
|
545
442
|
const nodeType = node.attrs.type;
|
|
546
|
-
const from = jidNormalizedUser(node.attrs.from);
|
|
443
|
+
const from = (0, WABinary_1.jidNormalizedUser)(node.attrs.from);
|
|
547
444
|
switch (nodeType) {
|
|
548
445
|
case 'privacy_token':
|
|
549
|
-
const tokenList = getBinaryNodeChildren(child, 'token');
|
|
446
|
+
const tokenList = (0, WABinary_1.getBinaryNodeChildren)(child, 'token');
|
|
550
447
|
for (const { attrs, content } of tokenList) {
|
|
551
448
|
const jid = attrs.jid;
|
|
552
449
|
ev.emit('chats.update', [
|
|
@@ -559,57 +456,52 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
559
456
|
}
|
|
560
457
|
break;
|
|
561
458
|
case 'newsletter':
|
|
562
|
-
|
|
459
|
+
handleNewsletterNotification(node.attrs.from, child);
|
|
563
460
|
break;
|
|
564
461
|
case 'mex':
|
|
565
|
-
|
|
462
|
+
handleMexNewsletterNotification(node.attrs.from, child);
|
|
566
463
|
break;
|
|
567
464
|
case 'w:gp2':
|
|
568
|
-
|
|
569
|
-
handleGroupNotification(node, child, result);
|
|
465
|
+
handleGroupNotification(node.attrs.participant, child, result);
|
|
570
466
|
break;
|
|
571
467
|
case 'mediaretry':
|
|
572
|
-
const event = decodeMediaRetryNode(node);
|
|
468
|
+
const event = (0, Utils_1.decodeMediaRetryNode)(node);
|
|
573
469
|
ev.emit('messages.media-update', [event]);
|
|
574
470
|
break;
|
|
575
471
|
case 'encrypt':
|
|
576
472
|
await handleEncryptNotification(node);
|
|
577
473
|
break;
|
|
578
474
|
case 'devices':
|
|
579
|
-
const devices = getBinaryNodeChildren(child, 'device');
|
|
580
|
-
if (areJidsSameUser(child.attrs.jid, authState.creds.me.id)
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
logger.info({ deviceData }, 'my own devices changed');
|
|
475
|
+
const devices = (0, WABinary_1.getBinaryNodeChildren)(child, 'device');
|
|
476
|
+
if ((0, WABinary_1.areJidsSameUser)(child.attrs.jid, authState.creds.me.id)) {
|
|
477
|
+
const deviceJids = devices.map(d => d.attrs.jid);
|
|
478
|
+
logger.info({ deviceJids }, 'got my own devices');
|
|
584
479
|
}
|
|
585
|
-
//TODO: drop a new event, add hashes
|
|
586
480
|
break;
|
|
587
481
|
case 'server_sync':
|
|
588
|
-
const update = getBinaryNodeChild(node, 'collection');
|
|
482
|
+
const update = (0, WABinary_1.getBinaryNodeChild)(node, 'collection');
|
|
589
483
|
if (update) {
|
|
590
484
|
const name = update.attrs.name;
|
|
591
485
|
await resyncAppState([name], false);
|
|
592
486
|
}
|
|
593
487
|
break;
|
|
594
488
|
case 'picture':
|
|
595
|
-
const setPicture = getBinaryNodeChild(node, 'set');
|
|
596
|
-
const delPicture = getBinaryNodeChild(node, 'delete');
|
|
597
|
-
ev.emit('contacts.update', [
|
|
598
|
-
|
|
599
|
-
id: jidNormalizedUser(node?.attrs?.from) || (setPicture || delPicture)?.attrs?.hash || '',
|
|
489
|
+
const setPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'set');
|
|
490
|
+
const delPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'delete');
|
|
491
|
+
ev.emit('contacts.update', [{
|
|
492
|
+
id: from || ((_b = (_a = (setPicture || delPicture)) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.hash) || '',
|
|
600
493
|
imgUrl: setPicture ? 'changed' : 'removed'
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
if (isJidGroup(from)) {
|
|
494
|
+
}]);
|
|
495
|
+
if ((0, WABinary_1.isJidGroup)(from)) {
|
|
604
496
|
const node = setPicture || delPicture;
|
|
605
|
-
result.messageStubType = WAMessageStubType.GROUP_CHANGE_ICON;
|
|
497
|
+
result.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_ICON;
|
|
606
498
|
if (setPicture) {
|
|
607
499
|
result.messageStubParameters = [setPicture.attrs.id];
|
|
608
500
|
}
|
|
609
|
-
result.participant = node
|
|
501
|
+
result.participant = node === null || node === void 0 ? void 0 : node.attrs.author;
|
|
610
502
|
result.key = {
|
|
611
|
-
...
|
|
612
|
-
participant: setPicture
|
|
503
|
+
...result.key || {},
|
|
504
|
+
participant: setPicture === null || setPicture === void 0 ? void 0 : setPicture.attrs.author
|
|
613
505
|
};
|
|
614
506
|
}
|
|
615
507
|
break;
|
|
@@ -623,48 +515,44 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
623
515
|
...authState.creds.accountSettings,
|
|
624
516
|
defaultDisappearingMode: {
|
|
625
517
|
ephemeralExpiration: newDuration,
|
|
626
|
-
ephemeralSettingTimestamp: timestamp
|
|
627
|
-
}
|
|
518
|
+
ephemeralSettingTimestamp: timestamp,
|
|
519
|
+
},
|
|
628
520
|
}
|
|
629
521
|
});
|
|
630
522
|
}
|
|
631
523
|
else if (child.tag === 'blocklist') {
|
|
632
|
-
const blocklists = getBinaryNodeChildren(child, 'item');
|
|
524
|
+
const blocklists = (0, WABinary_1.getBinaryNodeChildren)(child, 'item');
|
|
633
525
|
for (const { attrs } of blocklists) {
|
|
634
526
|
const blocklist = [attrs.jid];
|
|
635
|
-
const type = attrs.action === 'block' ? 'add' : 'remove';
|
|
527
|
+
const type = (attrs.action === 'block') ? 'add' : 'remove';
|
|
636
528
|
ev.emit('blocklist.update', { blocklist, type });
|
|
637
529
|
}
|
|
638
530
|
}
|
|
639
531
|
break;
|
|
640
532
|
case 'link_code_companion_reg':
|
|
641
|
-
const linkCodeCompanionReg = getBinaryNodeChild(node, 'link_code_companion_reg');
|
|
642
|
-
const ref = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'link_code_pairing_ref'));
|
|
643
|
-
const primaryIdentityPublicKey = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'primary_identity_pub'));
|
|
644
|
-
const primaryEphemeralPublicKeyWrapped = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'link_code_pairing_wrapped_primary_ephemeral_pub'));
|
|
533
|
+
const linkCodeCompanionReg = (0, WABinary_1.getBinaryNodeChild)(node, 'link_code_companion_reg');
|
|
534
|
+
const ref = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_ref'));
|
|
535
|
+
const primaryIdentityPublicKey = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'primary_identity_pub'));
|
|
536
|
+
const primaryEphemeralPublicKeyWrapped = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_wrapped_primary_ephemeral_pub'));
|
|
645
537
|
const codePairingPublicKey = await decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped);
|
|
646
|
-
const companionSharedKey = Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey);
|
|
647
|
-
const random = randomBytes(32);
|
|
648
|
-
const linkCodeSalt = randomBytes(32);
|
|
649
|
-
const linkCodePairingExpanded = await hkdf(companionSharedKey, 32, {
|
|
538
|
+
const companionSharedKey = Utils_1.Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey);
|
|
539
|
+
const random = (0, crypto_1.randomBytes)(32);
|
|
540
|
+
const linkCodeSalt = (0, crypto_1.randomBytes)(32);
|
|
541
|
+
const linkCodePairingExpanded = await (0, Utils_1.hkdf)(companionSharedKey, 32, {
|
|
650
542
|
salt: linkCodeSalt,
|
|
651
543
|
info: 'link_code_pairing_key_bundle_encryption_key'
|
|
652
544
|
});
|
|
653
|
-
const encryptPayload = Buffer.concat([
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
random
|
|
657
|
-
]);
|
|
658
|
-
const encryptIv = randomBytes(12);
|
|
659
|
-
const encrypted = aesEncryptGCM(encryptPayload, linkCodePairingExpanded, encryptIv, Buffer.alloc(0));
|
|
545
|
+
const encryptPayload = Buffer.concat([Buffer.from(authState.creds.signedIdentityKey.public), primaryIdentityPublicKey, random]);
|
|
546
|
+
const encryptIv = (0, crypto_1.randomBytes)(12);
|
|
547
|
+
const encrypted = (0, Utils_1.aesEncryptGCM)(encryptPayload, linkCodePairingExpanded, encryptIv, Buffer.alloc(0));
|
|
660
548
|
const encryptedPayload = Buffer.concat([linkCodeSalt, encryptIv, encrypted]);
|
|
661
|
-
const identitySharedKey = Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey);
|
|
549
|
+
const identitySharedKey = Utils_1.Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey);
|
|
662
550
|
const identityPayload = Buffer.concat([companionSharedKey, identitySharedKey, random]);
|
|
663
|
-
authState.creds.advSecretKey = (await hkdf(identityPayload, 32, { info: 'adv_secret' })).toString('base64');
|
|
551
|
+
authState.creds.advSecretKey = (await (0, Utils_1.hkdf)(identityPayload, 32, { info: 'adv_secret' })).toString('base64');
|
|
664
552
|
await query({
|
|
665
553
|
tag: 'iq',
|
|
666
554
|
attrs: {
|
|
667
|
-
to: S_WHATSAPP_NET,
|
|
555
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
668
556
|
type: 'set',
|
|
669
557
|
id: sock.generateMessageTag(),
|
|
670
558
|
xmlns: 'md'
|
|
@@ -674,7 +562,7 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
674
562
|
tag: 'link_code_companion_reg',
|
|
675
563
|
attrs: {
|
|
676
564
|
jid: authState.creds.me.id,
|
|
677
|
-
stage: 'companion_finish'
|
|
565
|
+
stage: 'companion_finish',
|
|
678
566
|
},
|
|
679
567
|
content: [
|
|
680
568
|
{
|
|
@@ -706,90 +594,44 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
706
594
|
async function decipherLinkPublicKey(data) {
|
|
707
595
|
const buffer = toRequiredBuffer(data);
|
|
708
596
|
const salt = buffer.slice(0, 32);
|
|
709
|
-
const secretKey = await derivePairingCodeKey(authState.creds.pairingCode, salt);
|
|
597
|
+
const secretKey = await (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
|
|
710
598
|
const iv = buffer.slice(32, 48);
|
|
711
599
|
const payload = buffer.slice(48, 80);
|
|
712
|
-
return aesDecryptCTR(payload, secretKey, iv);
|
|
600
|
+
return (0, Utils_1.aesDecryptCTR)(payload, secretKey, iv);
|
|
713
601
|
}
|
|
714
602
|
function toRequiredBuffer(data) {
|
|
715
603
|
if (data === undefined) {
|
|
716
|
-
throw new Boom('Invalid buffer', { statusCode: 400 });
|
|
604
|
+
throw new boom_1.Boom('Invalid buffer', { statusCode: 400 });
|
|
717
605
|
}
|
|
718
606
|
return data instanceof Buffer ? data : Buffer.from(data);
|
|
719
607
|
}
|
|
720
|
-
const willSendMessageAgain =
|
|
608
|
+
const willSendMessageAgain = (id, participant) => {
|
|
721
609
|
const key = `${id}:${participant}`;
|
|
722
|
-
const retryCount =
|
|
610
|
+
const retryCount = msgRetryCache.get(key) || 0;
|
|
723
611
|
return retryCount < maxMsgRetryCount;
|
|
724
612
|
};
|
|
725
|
-
const updateSendMessageAgainCount =
|
|
613
|
+
const updateSendMessageAgainCount = (id, participant) => {
|
|
726
614
|
const key = `${id}:${participant}`;
|
|
727
|
-
const newValue = (
|
|
728
|
-
|
|
615
|
+
const newValue = (msgRetryCache.get(key) || 0) + 1;
|
|
616
|
+
msgRetryCache.set(key, newValue);
|
|
729
617
|
};
|
|
730
618
|
const sendMessagesAgain = async (key, ids, retryNode) => {
|
|
619
|
+
var _a;
|
|
620
|
+
// todo: implement a cache to store the last 256 sent messages (copy whatsmeow)
|
|
621
|
+
const msgs = await Promise.all(ids.map(id => getMessage({ ...key, id })));
|
|
731
622
|
const remoteJid = key.remoteJid;
|
|
732
623
|
const participant = key.participant || remoteJid;
|
|
733
|
-
const retryCount = +retryNode.attrs.count || 1;
|
|
734
|
-
// Try to get messages from cache first, then fallback to getMessage
|
|
735
|
-
const msgs = [];
|
|
736
|
-
for (const id of ids) {
|
|
737
|
-
let msg;
|
|
738
|
-
// Try to get from retry cache first if enabled
|
|
739
|
-
if (messageRetryManager) {
|
|
740
|
-
const cachedMsg = messageRetryManager.getRecentMessage(remoteJid, id);
|
|
741
|
-
if (cachedMsg) {
|
|
742
|
-
msg = cachedMsg.message;
|
|
743
|
-
logger.debug({ jid: remoteJid, id }, 'found message in retry cache');
|
|
744
|
-
// Mark retry as successful since we found the message
|
|
745
|
-
messageRetryManager.markRetrySuccess(id);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
// Fallback to getMessage if not found in cache
|
|
749
|
-
if (!msg) {
|
|
750
|
-
msg = await getMessage({ ...key, id });
|
|
751
|
-
if (msg) {
|
|
752
|
-
logger.debug({ jid: remoteJid, id }, 'found message via getMessage');
|
|
753
|
-
// Also mark as successful if found via getMessage
|
|
754
|
-
if (messageRetryManager) {
|
|
755
|
-
messageRetryManager.markRetrySuccess(id);
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
msgs.push(msg);
|
|
760
|
-
}
|
|
761
624
|
// if it's the primary jid sending the request
|
|
762
625
|
// just re-send the message to everyone
|
|
763
626
|
// prevents the first message decryption failure
|
|
764
|
-
const sendToAll = !jidDecode(participant)
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
let recreateReason = '';
|
|
768
|
-
if (enableAutoSessionRecreation && messageRetryManager) {
|
|
769
|
-
try {
|
|
770
|
-
const sessionId = signalRepository.jidToSignalProtocolAddress(participant);
|
|
771
|
-
const hasSession = await signalRepository.validateSession(participant);
|
|
772
|
-
const result = messageRetryManager.shouldRecreateSession(participant, retryCount, hasSession.exists);
|
|
773
|
-
shouldRecreateSession = result.recreate;
|
|
774
|
-
recreateReason = result.reason;
|
|
775
|
-
if (shouldRecreateSession) {
|
|
776
|
-
logger.debug({ participant, retryCount, reason: recreateReason }, 'recreating session for outgoing retry');
|
|
777
|
-
await authState.keys.set({ session: { [sessionId]: null } });
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
catch (error) {
|
|
781
|
-
logger.warn({ error, participant }, 'failed to check session recreation for outgoing retry');
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
await assertSessions([participant]);
|
|
785
|
-
if (isJidGroup(remoteJid)) {
|
|
627
|
+
const sendToAll = !((_a = (0, WABinary_1.jidDecode)(participant)) === null || _a === void 0 ? void 0 : _a.device);
|
|
628
|
+
await assertSessions([participant], true);
|
|
629
|
+
if ((0, WABinary_1.isJidGroup)(remoteJid)) {
|
|
786
630
|
await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } });
|
|
787
631
|
}
|
|
788
|
-
logger.debug({ participant, sendToAll
|
|
632
|
+
logger.debug({ participant, sendToAll }, 'forced new session for retry recp');
|
|
789
633
|
for (const [i, msg] of msgs.entries()) {
|
|
790
|
-
if (
|
|
791
|
-
continue;
|
|
792
|
-
if (msg && (await willSendMessageAgain(ids[i], participant))) {
|
|
634
|
+
if (msg) {
|
|
793
635
|
updateSendMessageAgainCount(ids[i], participant);
|
|
794
636
|
const msgRelayOpts = { messageId: ids[i] };
|
|
795
637
|
if (sendToAll) {
|
|
@@ -809,10 +651,11 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
809
651
|
}
|
|
810
652
|
};
|
|
811
653
|
const handleReceipt = async (node) => {
|
|
654
|
+
var _a, _b;
|
|
812
655
|
const { attrs, content } = node;
|
|
813
656
|
const isLid = attrs.from.includes('lid');
|
|
814
|
-
const isNodeFromMe = areJidsSameUser(attrs.participant || attrs.from, isLid ? authState.creds.me
|
|
815
|
-
const remoteJid = !isNodeFromMe || isJidGroup(attrs.from) ? attrs.from : attrs.recipient;
|
|
657
|
+
const isNodeFromMe = (0, WABinary_1.areJidsSameUser)(attrs.participant || attrs.from, isLid ? (_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.lid : (_b = authState.creds.me) === null || _b === void 0 ? void 0 : _b.id);
|
|
658
|
+
const remoteJid = !isNodeFromMe || (0, WABinary_1.isJidGroup)(attrs.from) ? attrs.from : attrs.recipient;
|
|
816
659
|
const fromMe = !attrs.recipient || ((attrs.type === 'retry' || attrs.type === 'sender') && isNodeFromMe);
|
|
817
660
|
const key = {
|
|
818
661
|
remoteJid,
|
|
@@ -820,31 +663,33 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
820
663
|
fromMe,
|
|
821
664
|
participant: attrs.participant
|
|
822
665
|
};
|
|
823
|
-
if (shouldIgnoreJid(remoteJid) && remoteJid !==
|
|
666
|
+
if (shouldIgnoreJid(remoteJid) && remoteJid !== '@s.whatsapp.net') {
|
|
824
667
|
logger.debug({ remoteJid }, 'ignoring receipt from jid');
|
|
825
668
|
await sendMessageAck(node);
|
|
826
669
|
return;
|
|
827
670
|
}
|
|
828
671
|
const ids = [attrs.id];
|
|
829
672
|
if (Array.isArray(content)) {
|
|
830
|
-
const items = getBinaryNodeChildren(content[0], 'item');
|
|
673
|
+
const items = (0, WABinary_1.getBinaryNodeChildren)(content[0], 'item');
|
|
831
674
|
ids.push(...items.map(i => i.attrs.id));
|
|
832
675
|
}
|
|
833
676
|
try {
|
|
834
677
|
await Promise.all([
|
|
835
678
|
processingMutex.mutex(async () => {
|
|
836
|
-
const status = getStatusFromReceiptType(attrs.type);
|
|
679
|
+
const status = (0, Utils_1.getStatusFromReceiptType)(attrs.type);
|
|
837
680
|
if (typeof status !== 'undefined' &&
|
|
681
|
+
(
|
|
838
682
|
// basically, we only want to know when a message from us has been delivered to/read by the other person
|
|
839
683
|
// or another device of ours has read some messages
|
|
840
|
-
|
|
841
|
-
|
|
684
|
+
status >= WAProto_1.proto.WebMessageInfo.Status.SERVER_ACK ||
|
|
685
|
+
!isNodeFromMe)) {
|
|
686
|
+
if ((0, WABinary_1.isJidGroup)(remoteJid) || (0, WABinary_1.isJidStatusBroadcast)(remoteJid)) {
|
|
842
687
|
if (attrs.participant) {
|
|
843
|
-
const updateKey = status === proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
|
|
688
|
+
const updateKey = status === WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
|
|
844
689
|
ev.emit('message-receipt.update', ids.map(id => ({
|
|
845
690
|
key: { ...key, id },
|
|
846
691
|
receipt: {
|
|
847
|
-
userJid: jidNormalizedUser(attrs.participant),
|
|
692
|
+
userJid: (0, WABinary_1.jidNormalizedUser)(attrs.participant),
|
|
848
693
|
[updateKey]: +attrs.t
|
|
849
694
|
}
|
|
850
695
|
})));
|
|
@@ -860,16 +705,15 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
860
705
|
if (attrs.type === 'retry') {
|
|
861
706
|
// correctly set who is asking for the retry
|
|
862
707
|
key.participant = key.participant || attrs.from;
|
|
863
|
-
const retryNode = getBinaryNodeChild(node, 'retry');
|
|
864
|
-
if (
|
|
708
|
+
const retryNode = (0, WABinary_1.getBinaryNodeChild)(node, 'retry');
|
|
709
|
+
if (willSendMessageAgain(ids[0], key.participant)) {
|
|
865
710
|
if (key.fromMe) {
|
|
866
711
|
try {
|
|
867
|
-
updateSendMessageAgainCount(ids[0], key.participant);
|
|
868
712
|
logger.debug({ attrs, key }, 'recv retry request');
|
|
869
713
|
await sendMessagesAgain(key, ids, retryNode);
|
|
870
714
|
}
|
|
871
715
|
catch (error) {
|
|
872
|
-
logger.error({ key, ids, trace: error
|
|
716
|
+
logger.error({ key, ids, trace: error.stack }, 'error in sending message again');
|
|
873
717
|
}
|
|
874
718
|
}
|
|
875
719
|
else {
|
|
@@ -889,7 +733,7 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
889
733
|
};
|
|
890
734
|
const handleNotification = async (node) => {
|
|
891
735
|
const remoteJid = node.attrs.from;
|
|
892
|
-
if (shouldIgnoreJid(remoteJid) && remoteJid !==
|
|
736
|
+
if (shouldIgnoreJid(remoteJid) && remoteJid !== '@s.whatsapp.net') {
|
|
893
737
|
logger.debug({ remoteJid, id: node.attrs.id }, 'ignored notification');
|
|
894
738
|
await sendMessageAck(node);
|
|
895
739
|
return;
|
|
@@ -897,22 +741,20 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
897
741
|
try {
|
|
898
742
|
await Promise.all([
|
|
899
743
|
processingMutex.mutex(async () => {
|
|
744
|
+
var _a;
|
|
900
745
|
const msg = await processNotification(node);
|
|
901
746
|
if (msg) {
|
|
902
|
-
const fromMe = areJidsSameUser(node.attrs.participant || remoteJid, authState.creds.me.id);
|
|
903
|
-
const { senderAlt: participantAlt, addressingMode } = extractAddressingContext(node);
|
|
747
|
+
const fromMe = (0, WABinary_1.areJidsSameUser)(node.attrs.participant || remoteJid, authState.creds.me.id);
|
|
904
748
|
msg.key = {
|
|
905
749
|
remoteJid,
|
|
906
750
|
fromMe,
|
|
907
751
|
participant: node.attrs.participant,
|
|
908
|
-
participantAlt,
|
|
909
|
-
addressingMode,
|
|
910
752
|
id: node.attrs.id,
|
|
911
753
|
...(msg.key || {})
|
|
912
754
|
};
|
|
913
|
-
msg.participant
|
|
755
|
+
(_a = msg.participant) !== null && _a !== void 0 ? _a : (msg.participant = node.attrs.participant);
|
|
914
756
|
msg.messageTimestamp = +node.attrs.t;
|
|
915
|
-
const fullMsg = proto.WebMessageInfo.fromObject(msg);
|
|
757
|
+
const fullMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
|
|
916
758
|
await upsertMessage(fullMsg, 'append');
|
|
917
759
|
}
|
|
918
760
|
})
|
|
@@ -923,152 +765,185 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
923
765
|
}
|
|
924
766
|
};
|
|
925
767
|
const handleMessage = async (node) => {
|
|
926
|
-
|
|
768
|
+
var _a, _b, _c;
|
|
769
|
+
if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !== '@s.whatsapp.net') {
|
|
927
770
|
logger.debug({ key: node.attrs.key }, 'ignored message');
|
|
928
|
-
await sendMessageAck(node
|
|
771
|
+
await sendMessageAck(node);
|
|
929
772
|
return;
|
|
930
773
|
}
|
|
931
|
-
const encNode = getBinaryNodeChild(node, 'enc');
|
|
774
|
+
const encNode = (0, WABinary_1.getBinaryNodeChild)(node, 'enc');
|
|
932
775
|
// TODO: temporary fix for crashes and issues resulting of failed msmsg decryption
|
|
933
776
|
if (encNode && encNode.attrs.type === 'msmsg') {
|
|
934
777
|
logger.debug({ key: node.attrs.key }, 'ignored msmsg');
|
|
935
|
-
await sendMessageAck(node
|
|
778
|
+
await sendMessageAck(node);
|
|
936
779
|
return;
|
|
937
780
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
if (!(await signalRepository.lidMapping.getPNForLID(alt))) {
|
|
946
|
-
await signalRepository.lidMapping.storeLIDPNMappings([{ lid: alt, pn: primaryJid }]);
|
|
947
|
-
await signalRepository.migrateSession(primaryJid, alt);
|
|
948
|
-
}
|
|
781
|
+
let response;
|
|
782
|
+
if ((0, WABinary_1.getBinaryNodeChild)(node, 'unavailable') && !encNode) {
|
|
783
|
+
await sendMessageAck(node);
|
|
784
|
+
const { key } = (0, Utils_1.decodeMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '').fullMessage;
|
|
785
|
+
response = await requestPlaceholderResend(key);
|
|
786
|
+
if (response === 'RESOLVED') {
|
|
787
|
+
return;
|
|
949
788
|
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
789
|
+
logger.debug('received unavailable message, acked and requested resend from phone');
|
|
790
|
+
}
|
|
791
|
+
else {
|
|
792
|
+
if (placeholderResendCache.get(node.attrs.id)) {
|
|
793
|
+
placeholderResendCache.del(node.attrs.id);
|
|
953
794
|
}
|
|
954
795
|
}
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
796
|
+
const { fullMessage: msg, category, author, decrypt } = (0, Utils_1.decryptMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
|
|
797
|
+
if (response && ((_a = msg === null || msg === void 0 ? void 0 : msg.messageStubParameters) === null || _a === void 0 ? void 0 : _a[0]) === Utils_1.NO_MESSAGE_FOUND_ERROR_TEXT) {
|
|
798
|
+
msg.messageStubParameters = [Utils_1.NO_MESSAGE_FOUND_ERROR_TEXT, response];
|
|
799
|
+
}
|
|
800
|
+
if (((_c = (_b = msg.message) === null || _b === void 0 ? void 0 : _b.protocolMessage) === null || _c === void 0 ? void 0 : _c.type) === WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER && node.attrs.sender_pn) {
|
|
801
|
+
ev.emit('chats.phoneNumberShare', { lid: node.attrs.from, jid: node.attrs.sender_pn });
|
|
961
802
|
}
|
|
962
803
|
try {
|
|
963
|
-
await
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
if (!ws.isOpen) {
|
|
977
|
-
logger.debug({ node }, 'Connection closed, skipping retry');
|
|
978
|
-
return;
|
|
979
|
-
}
|
|
980
|
-
// Handle pre-key errors with upload and delay
|
|
981
|
-
if (isPreKeyError) {
|
|
982
|
-
logger.info({ error: errorMessage }, 'PreKey error detected, uploading and retrying');
|
|
983
|
-
try {
|
|
984
|
-
logger.debug('Uploading pre-keys for error recovery');
|
|
985
|
-
await uploadPreKeys(5);
|
|
986
|
-
logger.debug('Waiting for server to process new pre-keys');
|
|
987
|
-
await delay(1000);
|
|
804
|
+
await Promise.all([
|
|
805
|
+
processingMutex.mutex(async () => {
|
|
806
|
+
var _a, _b, _c, _d, _e, _f;
|
|
807
|
+
await decrypt();
|
|
808
|
+
// message failed to decrypt
|
|
809
|
+
if (msg.messageStubType === WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT) {
|
|
810
|
+
if (((_a = msg === null || msg === void 0 ? void 0 : msg.messageStubParameters) === null || _a === void 0 ? void 0 : _a[0]) === Utils_1.MISSING_KEYS_ERROR_TEXT) {
|
|
811
|
+
return sendMessageAck(node, Utils_1.NACK_REASONS.ParsingError);
|
|
812
|
+
}
|
|
813
|
+
retryMutex.mutex(async () => {
|
|
814
|
+
if (ws.isOpen) {
|
|
815
|
+
if ((0, WABinary_1.getBinaryNodeChild)(node, 'unavailable')) {
|
|
816
|
+
return;
|
|
988
817
|
}
|
|
989
|
-
|
|
990
|
-
|
|
818
|
+
const encNode = (0, WABinary_1.getBinaryNodeChild)(node, 'enc');
|
|
819
|
+
await sendRetryRequest(node, !encNode);
|
|
820
|
+
if (retryRequestDelayMs) {
|
|
821
|
+
await (0, Utils_1.delay)(retryRequestDelayMs);
|
|
991
822
|
}
|
|
992
823
|
}
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
if (retryRequestDelayMs) {
|
|
996
|
-
await delay(retryRequestDelayMs);
|
|
824
|
+
else {
|
|
825
|
+
logger.debug({ node }, 'connection closed, ignoring retry req');
|
|
997
826
|
}
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
else {
|
|
830
|
+
// no type in the receipt => message delivered
|
|
831
|
+
let type = undefined;
|
|
832
|
+
if ((_b = msg.key.participant) === null || _b === void 0 ? void 0 : _b.endsWith('@lid')) {
|
|
833
|
+
msg.key.participant = node.attrs.participant_pn || authState.creds.me.id;
|
|
998
834
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
const
|
|
1004
|
-
|
|
835
|
+
if ((0, WABinary_1.isJidGroup)(msg.key.remoteJid) && ((_f = (_e = (_d = (_c = msg.message) === null || _c === void 0 ? void 0 : _c.extendedTextMessage) === null || _d === void 0 ? void 0 : _d.contextInfo) === null || _e === void 0 ? void 0 : _e.participant) === null || _f === void 0 ? void 0 : _f.endsWith('@lid'))) {
|
|
836
|
+
if (msg.message.extendedTextMessage.contextInfo) {
|
|
837
|
+
const metadata = await groupMetadata(msg.key.remoteJid);
|
|
838
|
+
const sender = msg.message.extendedTextMessage.contextInfo.participant;
|
|
839
|
+
const found = metadata.participants.find(p => p.id === sender);
|
|
840
|
+
msg.message.extendedTextMessage.contextInfo.participant = (found === null || found === void 0 ? void 0 : found.jid) || sender;
|
|
1005
841
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
842
|
+
}
|
|
843
|
+
if (!(0, WABinary_1.isJidGroup)(msg.key.remoteJid) && (0, WABinary_1.isLidUser)(msg.key.remoteJid)) {
|
|
844
|
+
msg.key.remoteJid = node.attrs.sender_pn || node.attrs.peer_recipient_pn;
|
|
845
|
+
}
|
|
846
|
+
let participant = msg.key.participant;
|
|
847
|
+
if (category === 'peer') { // special peer message
|
|
848
|
+
type = 'peer_msg';
|
|
849
|
+
}
|
|
850
|
+
else if (msg.key.fromMe) { // message was sent by us from a different device
|
|
851
|
+
type = 'sender';
|
|
852
|
+
// need to specially handle this case
|
|
853
|
+
if ((0, WABinary_1.isJidUser)(msg.key.remoteJid)) {
|
|
854
|
+
participant = author;
|
|
1008
855
|
}
|
|
1009
856
|
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
type = 'peer_msg';
|
|
1020
|
-
}
|
|
1021
|
-
else if (msg.key.fromMe) {
|
|
1022
|
-
// message was sent by us from a different device
|
|
1023
|
-
type = 'sender';
|
|
1024
|
-
// need to specially handle this case
|
|
1025
|
-
if (isLidUser(msg.key.remoteJid) || isLidUser(msg.key.remoteJidAlt)) {
|
|
1026
|
-
participant = author; // TODO: investigate sending receipts to LIDs and not PNs
|
|
857
|
+
else if (!sendActiveReceipts) {
|
|
858
|
+
type = 'inactive';
|
|
859
|
+
}
|
|
860
|
+
await sendReceipt(msg.key.remoteJid, participant, [msg.key.id], type);
|
|
861
|
+
// send ack for history message
|
|
862
|
+
const isAnyHistoryMsg = (0, Utils_1.getHistoryMsg)(msg.message);
|
|
863
|
+
if (isAnyHistoryMsg) {
|
|
864
|
+
const jid = (0, WABinary_1.jidNormalizedUser)(msg.key.remoteJid);
|
|
865
|
+
await sendReceipt(jid, undefined, [msg.key.id], 'hist_sync');
|
|
1027
866
|
}
|
|
1028
867
|
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
const isAnyHistoryMsg = getHistoryMsg(msg.message);
|
|
1035
|
-
if (isAnyHistoryMsg) {
|
|
1036
|
-
const jid = jidNormalizedUser(msg.key.remoteJid);
|
|
1037
|
-
await sendReceipt(jid, undefined, [msg.key.id], 'hist_sync');
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
cleanMessage(msg, authState.creds.me.id, authState.creds.me.lid);
|
|
1041
|
-
await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify');
|
|
1042
|
-
});
|
|
868
|
+
(0, Utils_1.cleanMessage)(msg, authState.creds.me.id);
|
|
869
|
+
await sendMessageAck(node);
|
|
870
|
+
await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify');
|
|
871
|
+
})
|
|
872
|
+
]);
|
|
1043
873
|
}
|
|
1044
874
|
catch (error) {
|
|
1045
|
-
logger.error({ error, node
|
|
875
|
+
logger.error({ error, node }, 'error in handling message');
|
|
876
|
+
}
|
|
877
|
+
};
|
|
878
|
+
const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
|
|
879
|
+
var _a;
|
|
880
|
+
if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
881
|
+
throw new boom_1.Boom('Not authenticated');
|
|
882
|
+
}
|
|
883
|
+
const pdoMessage = {
|
|
884
|
+
historySyncOnDemandRequest: {
|
|
885
|
+
chatJid: oldestMsgKey.remoteJid,
|
|
886
|
+
oldestMsgFromMe: oldestMsgKey.fromMe,
|
|
887
|
+
oldestMsgId: oldestMsgKey.id,
|
|
888
|
+
oldestMsgTimestampMs: oldestMsgTimestamp,
|
|
889
|
+
onDemandMsgCount: count
|
|
890
|
+
},
|
|
891
|
+
peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
|
|
892
|
+
};
|
|
893
|
+
return sendPeerDataOperationMessage(pdoMessage);
|
|
894
|
+
};
|
|
895
|
+
const requestPlaceholderResend = async (messageKey) => {
|
|
896
|
+
var _a;
|
|
897
|
+
if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
898
|
+
throw new boom_1.Boom('Not authenticated');
|
|
899
|
+
}
|
|
900
|
+
if (placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
|
|
901
|
+
logger.debug({ messageKey }, 'already requested resend');
|
|
902
|
+
return;
|
|
1046
903
|
}
|
|
904
|
+
else {
|
|
905
|
+
placeholderResendCache.set(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id, true);
|
|
906
|
+
}
|
|
907
|
+
await (0, Utils_1.delay)(5000);
|
|
908
|
+
if (!placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
|
|
909
|
+
logger.debug({ messageKey }, 'message received while resend requested');
|
|
910
|
+
return 'RESOLVED';
|
|
911
|
+
}
|
|
912
|
+
const pdoMessage = {
|
|
913
|
+
placeholderMessageResendRequest: [{
|
|
914
|
+
messageKey
|
|
915
|
+
}],
|
|
916
|
+
peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
|
|
917
|
+
};
|
|
918
|
+
setTimeout(() => {
|
|
919
|
+
if (placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
|
|
920
|
+
logger.debug({ messageKey }, 'PDO message without response after 15 seconds. Phone possibly offline');
|
|
921
|
+
placeholderResendCache.del(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id);
|
|
922
|
+
}
|
|
923
|
+
}, 15000);
|
|
924
|
+
return sendPeerDataOperationMessage(pdoMessage);
|
|
1047
925
|
};
|
|
1048
926
|
const handleCall = async (node) => {
|
|
1049
927
|
const { attrs } = node;
|
|
1050
|
-
const [infoChild] = getAllBinaryNodeChildren(node);
|
|
1051
|
-
const status = getCallStatusFromNode(infoChild);
|
|
1052
|
-
if (!infoChild) {
|
|
1053
|
-
throw new Boom('Missing call info in call node');
|
|
1054
|
-
}
|
|
928
|
+
const [infoChild] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
|
|
1055
929
|
const callId = infoChild.attrs['call-id'];
|
|
1056
930
|
const from = infoChild.attrs.from || infoChild.attrs['call-creator'];
|
|
931
|
+
const status = (0, Utils_1.getCallStatusFromNode)(infoChild);
|
|
1057
932
|
const call = {
|
|
1058
933
|
chatId: attrs.from,
|
|
1059
934
|
from,
|
|
1060
935
|
id: callId,
|
|
1061
936
|
date: new Date(+attrs.t * 1000),
|
|
1062
937
|
offline: !!attrs.offline,
|
|
1063
|
-
status
|
|
938
|
+
status,
|
|
1064
939
|
};
|
|
1065
940
|
if (status === 'offer') {
|
|
1066
|
-
call.isVideo = !!getBinaryNodeChild(infoChild, 'video');
|
|
941
|
+
call.isVideo = !!(0, WABinary_1.getBinaryNodeChild)(infoChild, 'video');
|
|
1067
942
|
call.isGroup = infoChild.attrs.type === 'group' || !!infoChild.attrs['group-jid'];
|
|
1068
943
|
call.groupJid = infoChild.attrs['group-jid'];
|
|
1069
|
-
|
|
944
|
+
callOfferCache.set(call.id, call);
|
|
1070
945
|
}
|
|
1071
|
-
const existingCall =
|
|
946
|
+
const existingCall = callOfferCache.get(call.id);
|
|
1072
947
|
// use existing call info to populate this event
|
|
1073
948
|
if (existingCall) {
|
|
1074
949
|
call.isVideo = existingCall.isVideo;
|
|
@@ -1076,26 +951,34 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
1076
951
|
}
|
|
1077
952
|
// delete data once call has ended
|
|
1078
953
|
if (status === 'reject' || status === 'accept' || status === 'timeout' || status === 'terminate') {
|
|
1079
|
-
|
|
954
|
+
callOfferCache.del(call.id);
|
|
1080
955
|
}
|
|
1081
956
|
ev.emit('call', [call]);
|
|
1082
957
|
await sendMessageAck(node);
|
|
1083
958
|
};
|
|
1084
959
|
const handleBadAck = async ({ attrs }) => {
|
|
1085
|
-
const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id };
|
|
1086
|
-
//
|
|
1087
|
-
//
|
|
1088
|
-
//
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
960
|
+
const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id, 'server_id': attrs === null || attrs === void 0 ? void 0 : attrs.server_id };
|
|
961
|
+
// current hypothesis is that if pash is sent in the ack
|
|
962
|
+
// it means -- the message hasn't reached all devices yet
|
|
963
|
+
// we'll retry sending the message here
|
|
964
|
+
if (attrs.phash) {
|
|
965
|
+
logger.info({ attrs }, 'received phash in ack, resending message...');
|
|
966
|
+
const cacheKey = `${key.remoteJid}:${key.id}`;
|
|
967
|
+
if ((msgRetryCache.get(cacheKey) || 0) >= maxMsgRetryCount) {
|
|
968
|
+
logger.warn({ attrs }, 'reached max retry count, not sending message again');
|
|
969
|
+
msgRetryCache.del(cacheKey);
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
const retryCount = msgRetryCache.get(cacheKey) || 0;
|
|
973
|
+
const msg = await getMessage(key);
|
|
974
|
+
if (msg) {
|
|
975
|
+
await relayMessage(key.remoteJid, msg, { messageId: key.id, useUserDevicesCache: false });
|
|
976
|
+
msgRetryCache.set(cacheKey, retryCount + 1);
|
|
977
|
+
}
|
|
978
|
+
else {
|
|
979
|
+
logger.warn({ attrs }, 'could not send message again, as it was not found');
|
|
980
|
+
}
|
|
981
|
+
}
|
|
1099
982
|
// error in acknowledgement,
|
|
1100
983
|
// device could not display the message
|
|
1101
984
|
if (attrs.error) {
|
|
@@ -1104,8 +987,10 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
1104
987
|
{
|
|
1105
988
|
key,
|
|
1106
989
|
update: {
|
|
1107
|
-
status: WAMessageStatus.ERROR,
|
|
1108
|
-
messageStubParameters: [
|
|
990
|
+
status: Types_1.WAMessageStatus.ERROR,
|
|
991
|
+
messageStubParameters: [
|
|
992
|
+
attrs.error
|
|
993
|
+
]
|
|
1109
994
|
}
|
|
1110
995
|
}
|
|
1111
996
|
]);
|
|
@@ -1118,7 +1003,8 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
1118
1003
|
await execTask();
|
|
1119
1004
|
ev.flush();
|
|
1120
1005
|
function execTask() {
|
|
1121
|
-
return exec(node, false)
|
|
1006
|
+
return exec(node, false)
|
|
1007
|
+
.catch(err => onUnexpectedError(err, identifier));
|
|
1122
1008
|
}
|
|
1123
1009
|
};
|
|
1124
1010
|
const makeOfflineNodeProcessor = () => {
|
|
@@ -1176,12 +1062,10 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
1176
1062
|
processNode('notification', node, 'handling notification', handleNotification);
|
|
1177
1063
|
});
|
|
1178
1064
|
ws.on('CB:ack,class:message', (node) => {
|
|
1179
|
-
handleBadAck(node)
|
|
1065
|
+
handleBadAck(node)
|
|
1066
|
+
.catch(error => onUnexpectedError(error, 'handling bad ack'));
|
|
1180
1067
|
});
|
|
1181
1068
|
ev.on('call', ([call]) => {
|
|
1182
|
-
if (!call) {
|
|
1183
|
-
return;
|
|
1184
|
-
}
|
|
1185
1069
|
// missed call + group call notification message generation
|
|
1186
1070
|
if (call.status === 'timeout' || (call.status === 'offer' && call.isGroup)) {
|
|
1187
1071
|
const msg = {
|
|
@@ -1190,22 +1074,20 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
1190
1074
|
id: call.id,
|
|
1191
1075
|
fromMe: false
|
|
1192
1076
|
},
|
|
1193
|
-
messageTimestamp: unixTimestampSeconds(call.date)
|
|
1077
|
+
messageTimestamp: (0, Utils_1.unixTimestampSeconds)(call.date),
|
|
1194
1078
|
};
|
|
1195
1079
|
if (call.status === 'timeout') {
|
|
1196
1080
|
if (call.isGroup) {
|
|
1197
|
-
msg.messageStubType = call.isVideo
|
|
1198
|
-
? WAMessageStubType.CALL_MISSED_GROUP_VIDEO
|
|
1199
|
-
: WAMessageStubType.CALL_MISSED_GROUP_VOICE;
|
|
1081
|
+
msg.messageStubType = call.isVideo ? Types_1.WAMessageStubType.CALL_MISSED_GROUP_VIDEO : Types_1.WAMessageStubType.CALL_MISSED_GROUP_VOICE;
|
|
1200
1082
|
}
|
|
1201
1083
|
else {
|
|
1202
|
-
msg.messageStubType = call.isVideo ? WAMessageStubType.CALL_MISSED_VIDEO : WAMessageStubType.CALL_MISSED_VOICE;
|
|
1084
|
+
msg.messageStubType = call.isVideo ? Types_1.WAMessageStubType.CALL_MISSED_VIDEO : Types_1.WAMessageStubType.CALL_MISSED_VOICE;
|
|
1203
1085
|
}
|
|
1204
1086
|
}
|
|
1205
1087
|
else {
|
|
1206
1088
|
msg.message = { call: { callKey: Buffer.from(call.id) } };
|
|
1207
1089
|
}
|
|
1208
|
-
const protoMsg = proto.WebMessageInfo.fromObject(msg);
|
|
1090
|
+
const protoMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
|
|
1209
1091
|
upsertMessage(protoMsg, call.offline ? 'append' : 'notify');
|
|
1210
1092
|
}
|
|
1211
1093
|
});
|
|
@@ -1220,9 +1102,9 @@ export const makeMessagesRecvSocket = (config) => {
|
|
|
1220
1102
|
sendMessageAck,
|
|
1221
1103
|
sendRetryRequest,
|
|
1222
1104
|
rejectCall,
|
|
1105
|
+
offerCall,
|
|
1223
1106
|
fetchMessageHistory,
|
|
1224
1107
|
requestPlaceholderResend,
|
|
1225
|
-
messageRetryManager
|
|
1226
1108
|
};
|
|
1227
1109
|
};
|
|
1228
|
-
|
|
1110
|
+
exports.makeMessagesRecvSocket = makeMessagesRecvSocket;
|