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