@zetagoaurum-socket/decagramton 3.2.4 → 3.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -91
- package/WAProto/index.js +56886 -17506
- package/engine-requirements.js +91 -0
- package/lib/Defaults/index.js +47 -2
- package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
- package/lib/Signal/Group/ciphertext-message.js +15 -0
- package/lib/Signal/Group/group-session-builder.d.ts +14 -0
- package/lib/Signal/Group/group-session-builder.js +64 -0
- package/lib/Signal/Group/group_cipher.d.ts +17 -0
- package/lib/Signal/Group/group_cipher.js +96 -0
- package/lib/Signal/Group/index.d.ts +11 -0
- package/lib/Signal/Group/index.js +57 -0
- package/lib/Signal/Group/keyhelper.d.ts +10 -0
- package/lib/Signal/Group/keyhelper.js +55 -0
- package/lib/Signal/Group/queue-job.d.ts +1 -0
- package/lib/Signal/Group/queue-job.js +57 -0
- package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
- package/lib/Signal/Group/sender-chain-key.js +34 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
- package/lib/Signal/Group/sender-key-message.d.ts +18 -0
- package/lib/Signal/Group/sender-key-message.js +69 -0
- package/lib/Signal/Group/sender-key-name.d.ts +17 -0
- package/lib/Signal/Group/sender-key-name.js +51 -0
- package/lib/Signal/Group/sender-key-record.d.ts +30 -0
- package/lib/Signal/Group/sender-key-record.js +53 -0
- package/lib/Signal/Group/sender-key-state.d.ts +38 -0
- package/lib/Signal/Group/sender-key-state.js +99 -0
- package/lib/Signal/Group/sender-message-key.d.ts +11 -0
- package/{WASignalGroup/sender_message_key.js → lib/Signal/Group/sender-message-key.js} +6 -16
- package/lib/Signal/libsignal.js +51 -29
- package/lib/Socket/business.d.ts +3 -2
- package/lib/Socket/chats.d.ts +215 -28
- package/lib/Socket/chats.js +166 -70
- package/lib/Socket/dugong.d.ts +254 -0
- package/lib/Socket/dugong.js +432 -141
- package/lib/Socket/groups.js +20 -23
- package/lib/Socket/index.js +2 -15
- package/lib/Socket/messages-recv.d.ts +56 -55
- package/lib/Socket/messages-recv.js +367 -131
- package/lib/Socket/messages-send.d.ts +3 -2
- package/lib/Socket/messages-send.js +423 -380
- package/lib/Socket/newsletter.js +147 -21
- package/lib/Socket/socket.js +156 -148
- package/lib/Socket/usync.d.ts +3 -3
- package/lib/Types/GroupMetadata.d.ts +1 -0
- package/lib/Types/Newsletter.d.ts +97 -86
- package/lib/Types/Newsletter.js +38 -32
- package/lib/Types/USync.d.ts +25 -0
- package/lib/Types/USync.js +2 -0
- package/lib/Utils/anti-crash.js +31 -0
- package/lib/Utils/chat-utils.js +6 -1
- package/lib/Utils/generics.js +66 -34
- package/lib/Utils/history.js +6 -1
- package/lib/Utils/index.js +0 -1
- package/lib/Utils/link-preview.js +1 -1
- package/lib/Utils/messages-media.js +145 -57
- package/lib/Utils/messages.js +92 -306
- package/lib/Utils/signal.js +48 -46
- package/lib/Utils/use-multi-file-auth-state.js +45 -6
- package/lib/Utils/validate-connection.js +89 -65
- package/lib/WABinary/constants.d.ts +27 -24
- package/lib/WABinary/encode.js +160 -123
- package/lib/WABinary/generic-utils.d.ts +2 -0
- package/lib/WABinary/generic-utils.js +124 -36
- package/lib/WABinary/jid-utils.js +5 -26
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +56 -0
- package/package.json +107 -101
- package/LICENSE +0 -21
- package/WAProto/GenerateStatics.sh +0 -4
- package/WAProto/WAProto.proto +0 -3344
- package/WAProto/index.d.ts +0 -37016
- package/WASignalGroup/GroupProtocol.js +0 -1697
- package/WASignalGroup/ciphertext_message.js +0 -16
- package/WASignalGroup/group_cipher.js +0 -120
- package/WASignalGroup/group_session_builder.js +0 -46
- package/WASignalGroup/index.js +0 -5
- package/WASignalGroup/keyhelper.js +0 -21
- package/WASignalGroup/protobufs.js +0 -3
- package/WASignalGroup/queue_job.js +0 -69
- package/WASignalGroup/sender_chain_key.js +0 -50
- package/WASignalGroup/sender_key_distribution_message.js +0 -78
- package/WASignalGroup/sender_key_message.js +0 -92
- package/WASignalGroup/sender_key_name.js +0 -70
- package/WASignalGroup/sender_key_record.js +0 -56
- package/WASignalGroup/sender_key_state.js +0 -129
- package/decagramton.jpg +0 -0
- package/lib/Utils/rate-limiter.js +0 -55
- package/lib/WAUSync/Fall +0 -1
- package/lib/WAUSync/Protocols/Fal +0 -1
|
@@ -6,78 +6,146 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.makeMessagesRecvSocket = void 0;
|
|
7
7
|
const boom_1 = require("@hapi/boom");
|
|
8
8
|
const crypto_1 = require("crypto");
|
|
9
|
-
const node_cache_1 = __importDefault(require("node-cache"));
|
|
9
|
+
const node_cache_1 = __importDefault(require("@cacheable/node-cache"));
|
|
10
10
|
const WAProto_1 = require("../../WAProto");
|
|
11
11
|
const Defaults_1 = require("../Defaults");
|
|
12
12
|
const Types_1 = require("../Types");
|
|
13
13
|
const Utils_1 = require("../Utils");
|
|
14
|
-
const Utils_2 = require("../Utils");
|
|
15
14
|
const make_mutex_1 = require("../Utils/make-mutex");
|
|
16
15
|
const WABinary_1 = require("../WABinary");
|
|
17
16
|
const groups_1 = require("./groups");
|
|
18
17
|
const messages_send_1 = require("./messages-send");
|
|
19
18
|
const makeMessagesRecvSocket = (config) => {
|
|
20
|
-
const {
|
|
19
|
+
const {
|
|
20
|
+
logger,
|
|
21
|
+
retryRequestDelayMs,
|
|
22
|
+
maxMsgRetryCount,
|
|
23
|
+
getMessage,
|
|
24
|
+
shouldIgnoreJid
|
|
25
|
+
} = config;
|
|
21
26
|
const sock = (0, messages_send_1.makeMessagesSocket)(config);
|
|
22
|
-
const {
|
|
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;
|
|
23
47
|
/** this mutex ensures that each retryRequest will wait for the previous one to finish */
|
|
24
48
|
const retryMutex = (0, make_mutex_1.makeMutex)();
|
|
25
49
|
const msgRetryCache = config.msgRetryCounterCache || new node_cache_1.default({
|
|
26
|
-
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY,
|
|
50
|
+
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
27
51
|
useClones: false
|
|
28
52
|
});
|
|
29
53
|
const callOfferCache = config.callOfferCache || new node_cache_1.default({
|
|
30
|
-
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.CALL_OFFER,
|
|
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
|
|
31
59
|
useClones: false
|
|
32
60
|
});
|
|
33
61
|
let sendActiveReceipts = false;
|
|
34
|
-
const sendMessageAck = async ({ tag, attrs, content }) => {
|
|
62
|
+
const sendMessageAck = async ({ tag, attrs, content }, errorCode) => {
|
|
35
63
|
const stanza = {
|
|
36
64
|
tag: 'ack',
|
|
37
65
|
attrs: {
|
|
38
66
|
id: attrs.id,
|
|
39
67
|
to: attrs.from,
|
|
40
|
-
class: tag
|
|
68
|
+
class: tag
|
|
41
69
|
}
|
|
42
|
-
}
|
|
70
|
+
}
|
|
71
|
+
if (!!errorCode) {
|
|
72
|
+
stanza.attrs.error = errorCode.toString();
|
|
73
|
+
}
|
|
43
74
|
if (!!attrs.participant) {
|
|
44
75
|
stanza.attrs.participant = attrs.participant;
|
|
45
76
|
}
|
|
46
77
|
if (!!attrs.recipient) {
|
|
47
78
|
stanza.attrs.recipient = attrs.recipient;
|
|
48
79
|
}
|
|
49
|
-
if (!!attrs.type && (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable'))) {
|
|
80
|
+
if (!!attrs.type && (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
|
|
50
81
|
stanza.attrs.type = attrs.type;
|
|
51
82
|
}
|
|
52
83
|
if (tag === 'message' && (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable')) {
|
|
53
84
|
stanza.attrs.from = authState.creds.me.id;
|
|
54
85
|
}
|
|
55
|
-
logger.debug({
|
|
86
|
+
logger.debug({
|
|
87
|
+
recv: {
|
|
88
|
+
tag,
|
|
89
|
+
attrs
|
|
90
|
+
},
|
|
91
|
+
sent: stanza.attrs }, 'sent ack');
|
|
56
92
|
await sendNode(stanza);
|
|
57
93
|
};
|
|
58
94
|
const offerCall = async (toJid, isVideo = false) => {
|
|
59
95
|
const callId = (0, crypto_1.randomBytes)(16).toString('hex').toUpperCase().substring(0, 64);
|
|
60
96
|
const offerContent = [];
|
|
61
|
-
offerContent.push({
|
|
62
|
-
|
|
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
|
+
});
|
|
63
111
|
if (isVideo) {
|
|
64
112
|
offerContent.push({
|
|
65
113
|
tag: 'video',
|
|
66
|
-
attrs: {
|
|
67
|
-
|
|
114
|
+
attrs: {
|
|
115
|
+
orientation: '0',
|
|
116
|
+
'screen_width': '1920',
|
|
117
|
+
'screen_height': '1080',
|
|
118
|
+
'device_orientation': '0',
|
|
119
|
+
enc: 'vp8',
|
|
120
|
+
dec: 'vp8',
|
|
121
|
+
}
|
|
68
122
|
});
|
|
69
123
|
}
|
|
70
|
-
offerContent.push({
|
|
71
|
-
|
|
72
|
-
|
|
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
|
+
})
|
|
73
141
|
const encKey = (0, crypto_1.randomBytes)(32);
|
|
74
142
|
const devices = (await getUSyncDevices([toJid], true, false)).map(({ user, device }) => (0, WABinary_1.jidEncode)(user, 's.whatsapp.net', device));
|
|
75
143
|
await assertSessions(devices, true);
|
|
76
144
|
const { nodes: destinations, shouldIncludeDeviceIdentity } = await createParticipantNodes(devices, {
|
|
77
145
|
call: {
|
|
78
|
-
callKey:
|
|
146
|
+
callKey: encKey
|
|
79
147
|
}
|
|
80
|
-
}
|
|
148
|
+
});
|
|
81
149
|
offerContent.push({ tag: 'destination', attrs: {}, content: destinations });
|
|
82
150
|
if (shouldIncludeDeviceIdentity) {
|
|
83
151
|
offerContent.push({
|
|
@@ -89,7 +157,6 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
89
157
|
const stanza = ({
|
|
90
158
|
tag: 'call',
|
|
91
159
|
attrs: {
|
|
92
|
-
id: (0, Utils_1.generateMessageIDV2)(),
|
|
93
160
|
to: toJid,
|
|
94
161
|
},
|
|
95
162
|
content: [{
|
|
@@ -103,8 +170,9 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
103
170
|
});
|
|
104
171
|
await query(stanza);
|
|
105
172
|
return {
|
|
106
|
-
|
|
107
|
-
|
|
173
|
+
callId,
|
|
174
|
+
toJid,
|
|
175
|
+
isVideo,
|
|
108
176
|
};
|
|
109
177
|
};
|
|
110
178
|
const rejectCall = async (callId, callFrom) => {
|
|
@@ -127,16 +195,24 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
127
195
|
await query(stanza);
|
|
128
196
|
};
|
|
129
197
|
const sendRetryRequest = async (node, forceIncludeKeys = false) => {
|
|
130
|
-
const
|
|
131
|
-
|
|
198
|
+
const { fullMessage } = (0, Utils_1.decodeMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '');
|
|
199
|
+
const { key: msgKey } = fullMessage;
|
|
200
|
+
const msgId = msgKey.id;
|
|
201
|
+
const key = `${msgId}:${msgKey === null || msgKey === void 0 ? void 0 : msgKey.participant}`;
|
|
202
|
+
let retryCount = msgRetryCache.get(key) || 0;
|
|
132
203
|
if (retryCount >= maxMsgRetryCount) {
|
|
133
204
|
logger.debug({ retryCount, msgId }, 'reached retry limit, clearing');
|
|
134
|
-
msgRetryCache.del(
|
|
205
|
+
msgRetryCache.del(key);
|
|
135
206
|
return;
|
|
136
207
|
}
|
|
137
208
|
retryCount += 1;
|
|
138
|
-
msgRetryCache.set(
|
|
209
|
+
msgRetryCache.set(key, retryCount);
|
|
139
210
|
const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds;
|
|
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}`);
|
|
215
|
+
}
|
|
140
216
|
const deviceIdentity = (0, Utils_1.encodeSignedDeviceIdentity)(account, true);
|
|
141
217
|
await authState.keys.transaction(async () => {
|
|
142
218
|
const receipt = {
|
|
@@ -215,6 +291,8 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
215
291
|
}
|
|
216
292
|
};
|
|
217
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;
|
|
218
296
|
switch (child === null || child === void 0 ? void 0 : child.tag) {
|
|
219
297
|
case 'create':
|
|
220
298
|
const metadata = (0, groups_1.extractGroupMetadata)(child);
|
|
@@ -240,6 +318,11 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
240
318
|
}
|
|
241
319
|
};
|
|
242
320
|
break;
|
|
321
|
+
case 'modify':
|
|
322
|
+
const oldNumber = (0, WABinary_1.getBinaryNodeChildren)(child, 'participant').map(p => p.attrs.jid);
|
|
323
|
+
msg.messageStubParameters = oldNumber || [];
|
|
324
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER;
|
|
325
|
+
break;
|
|
243
326
|
case 'promote':
|
|
244
327
|
case 'demote':
|
|
245
328
|
case 'remove':
|
|
@@ -261,6 +344,11 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
261
344
|
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT;
|
|
262
345
|
msg.messageStubParameters = [child.attrs.subject];
|
|
263
346
|
break;
|
|
347
|
+
case '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;
|
|
350
|
+
msg.messageStubParameters = description ? [description] : undefined;
|
|
351
|
+
break;
|
|
264
352
|
case 'announcement':
|
|
265
353
|
case 'not_announcement':
|
|
266
354
|
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE;
|
|
@@ -289,10 +377,66 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
289
377
|
msg.messageStubParameters = [approvalMode.attrs.state];
|
|
290
378
|
}
|
|
291
379
|
break;
|
|
380
|
+
case 'created_membership_requests':
|
|
381
|
+
msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
|
|
382
|
+
msg.messageStubParameters = [participantJid, 'created', child.attrs.request_method];
|
|
383
|
+
break;
|
|
384
|
+
case 'revoked_membership_requests':
|
|
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;
|
|
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 });
|
|
292
436
|
}
|
|
293
437
|
};
|
|
294
438
|
const processNotification = async (node) => {
|
|
295
|
-
var _a, _b
|
|
439
|
+
var _a, _b;
|
|
296
440
|
const result = {};
|
|
297
441
|
const [child] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
|
|
298
442
|
const nodeType = node.attrs.type;
|
|
@@ -311,6 +455,12 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
311
455
|
logger.debug({ jid }, 'got privacy token update');
|
|
312
456
|
}
|
|
313
457
|
break;
|
|
458
|
+
case 'newsletter':
|
|
459
|
+
handleNewsletterNotification(node.attrs.from, child);
|
|
460
|
+
break;
|
|
461
|
+
case 'mex':
|
|
462
|
+
handleMexNewsletterNotification(node.attrs.from, child);
|
|
463
|
+
break;
|
|
314
464
|
case 'w:gp2':
|
|
315
465
|
handleGroupNotification(node.attrs.participant, child, result);
|
|
316
466
|
break;
|
|
@@ -321,9 +471,6 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
321
471
|
case 'encrypt':
|
|
322
472
|
await handleEncryptNotification(node);
|
|
323
473
|
break;
|
|
324
|
-
case 'newsletter':
|
|
325
|
-
// TO DO
|
|
326
|
-
break;
|
|
327
474
|
case 'devices':
|
|
328
475
|
const devices = (0, WABinary_1.getBinaryNodeChildren)(child, 'device');
|
|
329
476
|
if ((0, WABinary_1.areJidsSameUser)(child.attrs.jid, authState.creds.me.id)) {
|
|
@@ -342,7 +489,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
342
489
|
const setPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'set');
|
|
343
490
|
const delPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'delete');
|
|
344
491
|
ev.emit('contacts.update', [{
|
|
345
|
-
id:
|
|
492
|
+
id: from || ((_b = (_a = (setPicture || delPicture)) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.hash) || '',
|
|
346
493
|
imgUrl: setPicture ? 'changed' : 'removed'
|
|
347
494
|
}]);
|
|
348
495
|
if ((0, WABinary_1.isJidGroup)(from)) {
|
|
@@ -387,11 +534,11 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
387
534
|
const ref = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_ref'));
|
|
388
535
|
const primaryIdentityPublicKey = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'primary_identity_pub'));
|
|
389
536
|
const primaryEphemeralPublicKeyWrapped = toRequiredBuffer((0, WABinary_1.getBinaryNodeChildBuffer)(linkCodeCompanionReg, 'link_code_pairing_wrapped_primary_ephemeral_pub'));
|
|
390
|
-
const codePairingPublicKey = decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped);
|
|
537
|
+
const codePairingPublicKey = await decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped);
|
|
391
538
|
const companionSharedKey = Utils_1.Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey);
|
|
392
539
|
const random = (0, crypto_1.randomBytes)(32);
|
|
393
540
|
const linkCodeSalt = (0, crypto_1.randomBytes)(32);
|
|
394
|
-
const linkCodePairingExpanded = (0, Utils_1.hkdf)(companionSharedKey, 32, {
|
|
541
|
+
const linkCodePairingExpanded = await (0, Utils_1.hkdf)(companionSharedKey, 32, {
|
|
395
542
|
salt: linkCodeSalt,
|
|
396
543
|
info: 'link_code_pairing_key_bundle_encryption_key'
|
|
397
544
|
});
|
|
@@ -401,7 +548,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
401
548
|
const encryptedPayload = Buffer.concat([linkCodeSalt, encryptIv, encrypted]);
|
|
402
549
|
const identitySharedKey = Utils_1.Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey);
|
|
403
550
|
const identityPayload = Buffer.concat([companionSharedKey, identitySharedKey, random]);
|
|
404
|
-
authState.creds.advSecretKey = (0, Utils_1.hkdf)(identityPayload, 32, { info: 'adv_secret' }).toString('base64');
|
|
551
|
+
authState.creds.advSecretKey = (await (0, Utils_1.hkdf)(identityPayload, 32, { info: 'adv_secret' })).toString('base64');
|
|
405
552
|
await query({
|
|
406
553
|
tag: 'iq',
|
|
407
554
|
attrs: {
|
|
@@ -444,10 +591,10 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
444
591
|
return result;
|
|
445
592
|
}
|
|
446
593
|
};
|
|
447
|
-
function decipherLinkPublicKey(data) {
|
|
594
|
+
async function decipherLinkPublicKey(data) {
|
|
448
595
|
const buffer = toRequiredBuffer(data);
|
|
449
596
|
const salt = buffer.slice(0, 32);
|
|
450
|
-
const secretKey = (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
|
|
597
|
+
const secretKey = await (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
|
|
451
598
|
const iv = buffer.slice(32, 48);
|
|
452
599
|
const payload = buffer.slice(48, 80);
|
|
453
600
|
return (0, Utils_1.aesDecryptCTR)(payload, secretKey, iv);
|
|
@@ -470,6 +617,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
470
617
|
};
|
|
471
618
|
const sendMessagesAgain = async (key, ids, retryNode) => {
|
|
472
619
|
var _a;
|
|
620
|
+
// todo: implement a cache to store the last 256 sent messages (copy whatsmeow)
|
|
473
621
|
const msgs = await Promise.all(ids.map(id => getMessage({ ...key, id })));
|
|
474
622
|
const remoteJid = key.remoteJid;
|
|
475
623
|
const participant = key.participant || remoteJid;
|
|
@@ -482,8 +630,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
482
630
|
await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } });
|
|
483
631
|
}
|
|
484
632
|
logger.debug({ participant, sendToAll }, 'forced new session for retry recp');
|
|
485
|
-
for (
|
|
486
|
-
const msg = msgs[i];
|
|
633
|
+
for (const [i, msg] of msgs.entries()) {
|
|
487
634
|
if (msg) {
|
|
488
635
|
updateSendMessageAgainCount(ids[i], participant);
|
|
489
636
|
const msgRelayOpts = { messageId: ids[i] };
|
|
@@ -509,7 +656,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
509
656
|
const isLid = attrs.from.includes('lid');
|
|
510
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);
|
|
511
658
|
const remoteJid = !isNodeFromMe || (0, WABinary_1.isJidGroup)(attrs.from) ? attrs.from : attrs.recipient;
|
|
512
|
-
const fromMe = !attrs.recipient || (attrs.type === 'retry' && isNodeFromMe);
|
|
659
|
+
const fromMe = !attrs.recipient || ((attrs.type === 'retry' || attrs.type === 'sender') && isNodeFromMe);
|
|
513
660
|
const key = {
|
|
514
661
|
remoteJid,
|
|
515
662
|
id: '',
|
|
@@ -526,59 +673,63 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
526
673
|
const items = (0, WABinary_1.getBinaryNodeChildren)(content[0], 'item');
|
|
527
674
|
ids.push(...items.map(i => i.attrs.id));
|
|
528
675
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
(
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
if (
|
|
540
|
-
|
|
541
|
-
|
|
676
|
+
try {
|
|
677
|
+
await Promise.all([
|
|
678
|
+
processingMutex.mutex(async () => {
|
|
679
|
+
const status = (0, Utils_1.getStatusFromReceiptType)(attrs.type);
|
|
680
|
+
if (typeof status !== 'undefined' &&
|
|
681
|
+
(
|
|
682
|
+
// basically, we only want to know when a message from us has been delivered to/read by the other person
|
|
683
|
+
// or another device of ours has read some messages
|
|
684
|
+
status >= WAProto_1.proto.WebMessageInfo.Status.SERVER_ACK ||
|
|
685
|
+
!isNodeFromMe)) {
|
|
686
|
+
if ((0, WABinary_1.isJidGroup)(remoteJid) || (0, WABinary_1.isJidStatusBroadcast)(remoteJid)) {
|
|
687
|
+
if (attrs.participant) {
|
|
688
|
+
const updateKey = status === WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
|
|
689
|
+
ev.emit('message-receipt.update', ids.map(id => ({
|
|
690
|
+
key: { ...key, id },
|
|
691
|
+
receipt: {
|
|
692
|
+
userJid: (0, WABinary_1.jidNormalizedUser)(attrs.participant),
|
|
693
|
+
[updateKey]: +attrs.t
|
|
694
|
+
}
|
|
695
|
+
})));
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
ev.emit('messages.update', ids.map(id => ({
|
|
542
700
|
key: { ...key, id },
|
|
543
|
-
|
|
544
|
-
userJid: (0, WABinary_1.jidNormalizedUser)(attrs.participant),
|
|
545
|
-
[updateKey]: +attrs.t
|
|
546
|
-
}
|
|
701
|
+
update: { status }
|
|
547
702
|
})));
|
|
548
703
|
}
|
|
549
704
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
try {
|
|
564
|
-
logger.debug({ attrs, key }, 'recv retry request');
|
|
565
|
-
await sendMessagesAgain(key, ids, retryNode);
|
|
705
|
+
if (attrs.type === 'retry') {
|
|
706
|
+
// correctly set who is asking for the retry
|
|
707
|
+
key.participant = key.participant || attrs.from;
|
|
708
|
+
const retryNode = (0, WABinary_1.getBinaryNodeChild)(node, 'retry');
|
|
709
|
+
if (willSendMessageAgain(ids[0], key.participant)) {
|
|
710
|
+
if (key.fromMe) {
|
|
711
|
+
try {
|
|
712
|
+
logger.debug({ attrs, key }, 'recv retry request');
|
|
713
|
+
await sendMessagesAgain(key, ids, retryNode);
|
|
714
|
+
}
|
|
715
|
+
catch (error) {
|
|
716
|
+
logger.error({ key, ids, trace: error.stack }, 'error in sending message again');
|
|
717
|
+
}
|
|
566
718
|
}
|
|
567
|
-
|
|
568
|
-
logger.
|
|
719
|
+
else {
|
|
720
|
+
logger.info({ attrs, key }, 'recv retry for not fromMe message');
|
|
569
721
|
}
|
|
570
722
|
}
|
|
571
723
|
else {
|
|
572
|
-
logger.info({ attrs, key }, '
|
|
724
|
+
logger.info({ attrs, key }, 'will not send message again, as sent too many times');
|
|
573
725
|
}
|
|
574
726
|
}
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
]);
|
|
727
|
+
})
|
|
728
|
+
]);
|
|
729
|
+
}
|
|
730
|
+
finally {
|
|
731
|
+
await sendMessageAck(node);
|
|
732
|
+
}
|
|
582
733
|
};
|
|
583
734
|
const handleNotification = async (node) => {
|
|
584
735
|
const remoteJid = node.attrs.from;
|
|
@@ -587,27 +738,31 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
587
738
|
await sendMessageAck(node);
|
|
588
739
|
return;
|
|
589
740
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
741
|
+
try {
|
|
742
|
+
await Promise.all([
|
|
743
|
+
processingMutex.mutex(async () => {
|
|
744
|
+
var _a;
|
|
745
|
+
const msg = await processNotification(node);
|
|
746
|
+
if (msg) {
|
|
747
|
+
const fromMe = (0, WABinary_1.areJidsSameUser)(node.attrs.participant || remoteJid, authState.creds.me.id);
|
|
748
|
+
msg.key = {
|
|
749
|
+
remoteJid,
|
|
750
|
+
fromMe,
|
|
751
|
+
participant: node.attrs.participant,
|
|
752
|
+
id: node.attrs.id,
|
|
753
|
+
...(msg.key || {})
|
|
754
|
+
};
|
|
755
|
+
(_a = msg.participant) !== null && _a !== void 0 ? _a : (msg.participant = node.attrs.participant);
|
|
756
|
+
msg.messageTimestamp = +node.attrs.t;
|
|
757
|
+
const fullMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
|
|
758
|
+
await upsertMessage(fullMsg, 'append');
|
|
759
|
+
}
|
|
760
|
+
})
|
|
761
|
+
]);
|
|
762
|
+
}
|
|
763
|
+
finally {
|
|
764
|
+
await sendMessageAck(node);
|
|
765
|
+
}
|
|
611
766
|
};
|
|
612
767
|
const handleMessage = async (node) => {
|
|
613
768
|
var _a, _b, _c;
|
|
@@ -638,25 +793,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
638
793
|
placeholderResendCache.del(node.attrs.id);
|
|
639
794
|
}
|
|
640
795
|
}
|
|
641
|
-
|
|
642
|
-
let category;
|
|
643
|
-
let author;
|
|
644
|
-
let decrypt;
|
|
645
|
-
|
|
646
|
-
try {
|
|
647
|
-
const decryptionResult = (0, Utils_1.decryptMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
|
|
648
|
-
msg = decryptionResult.fullMessage;
|
|
649
|
-
category = decryptionResult.category;
|
|
650
|
-
author = decryptionResult.author;
|
|
651
|
-
decrypt = decryptionResult.decrypt;
|
|
652
|
-
} catch (error) {
|
|
653
|
-
if (error.message.includes('Bad MAC')) {
|
|
654
|
-
logger.error({ key: node.attrs.key, error: error.stack }, 'Bad MAC error, triggering retry');
|
|
655
|
-
await sendRetryRequest(node, true); // Force include keys to reset session
|
|
656
|
-
return;
|
|
657
|
-
}
|
|
658
|
-
throw error;
|
|
659
|
-
}
|
|
796
|
+
const { fullMessage: msg, category, author, decrypt } = (0, Utils_1.decryptMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
|
|
660
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) {
|
|
661
798
|
msg.messageStubParameters = [Utils_1.NO_MESSAGE_FOUND_ERROR_TEXT, response];
|
|
662
799
|
}
|
|
@@ -738,6 +875,54 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
738
875
|
logger.error({ error, node }, 'error in handling message');
|
|
739
876
|
}
|
|
740
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;
|
|
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);
|
|
925
|
+
};
|
|
741
926
|
const handleCall = async (node) => {
|
|
742
927
|
const { attrs } = node;
|
|
743
928
|
const [infoChild] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
|
|
@@ -765,22 +950,30 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
765
950
|
call.isGroup = existingCall.isGroup;
|
|
766
951
|
}
|
|
767
952
|
// delete data once call has ended
|
|
768
|
-
if (status === 'reject' || status === 'accept' || status === 'timeout') {
|
|
953
|
+
if (status === 'reject' || status === 'accept' || status === 'timeout' || status === 'terminate') {
|
|
769
954
|
callOfferCache.del(call.id);
|
|
770
955
|
}
|
|
771
956
|
ev.emit('call', [call]);
|
|
772
957
|
await sendMessageAck(node);
|
|
773
958
|
};
|
|
774
959
|
const handleBadAck = async ({ attrs }) => {
|
|
775
|
-
const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id };
|
|
960
|
+
const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id, 'server_id': attrs === null || attrs === void 0 ? void 0 : attrs.server_id };
|
|
776
961
|
// current hypothesis is that if pash is sent in the ack
|
|
777
962
|
// it means -- the message hasn't reached all devices yet
|
|
778
963
|
// we'll retry sending the message here
|
|
779
964
|
if (attrs.phash) {
|
|
780
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;
|
|
781
973
|
const msg = await getMessage(key);
|
|
782
974
|
if (msg) {
|
|
783
975
|
await relayMessage(key.remoteJid, msg, { messageId: key.id, useUserDevicesCache: false });
|
|
976
|
+
msgRetryCache.set(cacheKey, retryCount + 1);
|
|
784
977
|
}
|
|
785
978
|
else {
|
|
786
979
|
logger.warn({ attrs }, 'could not send message again, as it was not found');
|
|
@@ -810,22 +1003,63 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
810
1003
|
await execTask();
|
|
811
1004
|
ev.flush();
|
|
812
1005
|
function execTask() {
|
|
813
|
-
return exec(node)
|
|
1006
|
+
return exec(node, false)
|
|
814
1007
|
.catch(err => onUnexpectedError(err, identifier));
|
|
815
1008
|
}
|
|
816
1009
|
};
|
|
1010
|
+
const makeOfflineNodeProcessor = () => {
|
|
1011
|
+
const nodeProcessorMap = new Map([
|
|
1012
|
+
['message', handleMessage],
|
|
1013
|
+
['call', handleCall],
|
|
1014
|
+
['receipt', handleReceipt],
|
|
1015
|
+
['notification', handleNotification]
|
|
1016
|
+
]);
|
|
1017
|
+
const nodes = [];
|
|
1018
|
+
let isProcessing = false;
|
|
1019
|
+
const enqueue = (type, node) => {
|
|
1020
|
+
nodes.push({ type, node });
|
|
1021
|
+
if (isProcessing) {
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
isProcessing = true;
|
|
1025
|
+
const promise = async () => {
|
|
1026
|
+
while (nodes.length && ws.isOpen) {
|
|
1027
|
+
const { type, node } = nodes.shift();
|
|
1028
|
+
const nodeProcessor = nodeProcessorMap.get(type);
|
|
1029
|
+
if (!nodeProcessor) {
|
|
1030
|
+
onUnexpectedError(new Error(`unknown offline node type: ${type}`), 'processing offline node');
|
|
1031
|
+
continue;
|
|
1032
|
+
}
|
|
1033
|
+
await nodeProcessor(node);
|
|
1034
|
+
}
|
|
1035
|
+
isProcessing = false;
|
|
1036
|
+
};
|
|
1037
|
+
promise().catch(error => onUnexpectedError(error, 'processing offline nodes'));
|
|
1038
|
+
};
|
|
1039
|
+
return { enqueue };
|
|
1040
|
+
};
|
|
1041
|
+
const offlineNodeProcessor = makeOfflineNodeProcessor();
|
|
1042
|
+
const processNode = (type, node, identifier, exec) => {
|
|
1043
|
+
const isOffline = !!node.attrs.offline;
|
|
1044
|
+
if (isOffline) {
|
|
1045
|
+
offlineNodeProcessor.enqueue(type, node);
|
|
1046
|
+
}
|
|
1047
|
+
else {
|
|
1048
|
+
processNodeWithBuffer(node, identifier, exec);
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
817
1051
|
// recv a message
|
|
818
1052
|
ws.on('CB:message', (node) => {
|
|
819
|
-
|
|
1053
|
+
processNode('message', node, 'processing message', handleMessage);
|
|
820
1054
|
});
|
|
821
1055
|
ws.on('CB:call', async (node) => {
|
|
822
|
-
|
|
1056
|
+
processNode('call', node, 'handling call', handleCall);
|
|
823
1057
|
});
|
|
824
1058
|
ws.on('CB:receipt', node => {
|
|
825
|
-
|
|
1059
|
+
processNode('receipt', node, 'handling receipt', handleReceipt);
|
|
826
1060
|
});
|
|
827
1061
|
ws.on('CB:notification', async (node) => {
|
|
828
|
-
|
|
1062
|
+
processNode('notification', node, 'handling notification', handleNotification);
|
|
829
1063
|
});
|
|
830
1064
|
ws.on('CB:ack,class:message', (node) => {
|
|
831
1065
|
handleBadAck(node)
|
|
@@ -867,8 +1101,10 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
867
1101
|
...sock,
|
|
868
1102
|
sendMessageAck,
|
|
869
1103
|
sendRetryRequest,
|
|
1104
|
+
rejectCall,
|
|
870
1105
|
offerCall,
|
|
871
|
-
|
|
1106
|
+
fetchMessageHistory,
|
|
1107
|
+
requestPlaceholderResend,
|
|
872
1108
|
};
|
|
873
1109
|
};
|
|
874
1110
|
exports.makeMessagesRecvSocket = makeMessagesRecvSocket;
|