@hbmodsofc/baileys 1.7.8 → 2.0.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/WAProto/index.js +157084 -24729
- package/lib/Defaults/baileys-version.json +3 -0
- package/lib/Defaults/index.d.ts +8 -12
- package/lib/Defaults/index.js +124 -90
- package/lib/Defaults/phonenumber-mcc.json +223 -0
- package/lib/Signal/Group/group_cipher.d.ts +1 -0
- package/lib/Signal/Group/group_cipher.js +39 -28
- 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 +1 -1
- package/lib/Signal/Group/sender-chain-key.js +2 -9
- package/lib/Signal/Group/sender-key-distribution-message.js +3 -3
- package/lib/Signal/Group/sender-key-message.js +3 -3
- package/lib/Signal/Group/sender-key-state.d.ts +4 -4
- package/lib/Signal/Group/sender-key-state.js +16 -47
- package/lib/Signal/libsignal.d.ts +3 -7
- package/lib/Signal/libsignal.js +39 -224
- package/lib/Socket/Client/{types.d.ts → abstract-socket-client.d.ts} +3 -1
- package/lib/Socket/Client/index.d.ts +3 -2
- package/lib/Socket/Client/index.js +3 -2
- package/lib/Socket/Client/mobile-socket-client.d.ts +13 -0
- package/lib/Socket/Client/mobile-socket-client.js +65 -0
- package/lib/Socket/Client/{websocket.d.ts → web-socket-client.d.ts} +1 -1
- package/lib/Socket/Client/{websocket.js → web-socket-client.js} +16 -10
- package/lib/Socket/business.d.ts +78 -94
- package/lib/Socket/business.js +11 -130
- package/lib/Socket/chats.d.ts +233 -63
- package/lib/Socket/chats.js +184 -234
- package/lib/Socket/groups.d.ts +41 -62
- package/lib/Socket/groups.js +64 -76
- package/lib/Socket/hbmods.d.ts +253 -0
- package/lib/Socket/hbmods.js +1 -0
- package/lib/Socket/index.d.ts +83 -129
- package/lib/Socket/index.js +6 -13
- package/lib/Socket/messages-recv.d.ts +48 -59
- package/lib/Socket/messages-recv.js +371 -516
- package/lib/Socket/messages-send.d.ts +67 -86
- package/lib/Socket/messages-send.js +1 -1091
- package/lib/Socket/newsletter.d.ts +64 -76
- package/lib/Socket/newsletter.js +1 -184
- package/lib/Socket/registration.d.ts +267 -0
- package/lib/Socket/registration.js +166 -0
- package/lib/Socket/socket.d.ts +13 -19
- package/lib/Socket/socket.js +1 -805
- package/lib/Socket/usync.d.ts +36 -0
- package/lib/Socket/usync.js +70 -0
- package/lib/Types/Auth.d.ts +10 -4
- package/lib/Types/Call.d.ts +1 -1
- package/lib/Types/Chat.d.ts +9 -29
- package/lib/Types/Chat.js +1 -7
- package/lib/Types/Contact.d.ts +1 -5
- package/lib/Types/Events.d.ts +14 -55
- package/lib/Types/GroupMetadata.d.ts +5 -15
- package/lib/Types/Label.d.ts +0 -11
- package/lib/Types/Label.js +1 -1
- package/lib/Types/LabelAssociation.js +1 -1
- package/lib/Types/Message.d.ts +49 -75
- package/lib/Types/Message.js +7 -10
- package/lib/Types/Newsletter.d.ts +98 -129
- package/lib/Types/Newsletter.js +38 -33
- package/lib/Types/Product.d.ts +1 -1
- package/lib/Types/Signal.d.ts +1 -29
- package/lib/Types/Socket.d.ts +22 -48
- package/lib/Types/State.d.ts +2 -13
- package/lib/Types/State.js +0 -12
- package/lib/Types/USync.d.ts +1 -1
- package/lib/Types/index.d.ts +3 -10
- package/lib/Types/index.js +2 -2
- package/lib/Utils/auth-utils.d.ts +3 -3
- package/lib/Utils/auth-utils.js +102 -378
- package/lib/Utils/baileys-event-stream.js +1 -1
- package/lib/Utils/business.d.ts +2 -2
- package/lib/Utils/business.js +13 -19
- package/lib/Utils/chat-utils.d.ts +22 -21
- package/lib/Utils/chat-utils.js +154 -201
- package/lib/Utils/crypto.d.ts +19 -18
- package/lib/Utils/crypto.js +37 -78
- package/lib/Utils/decode-wa-message.d.ts +7 -34
- package/lib/Utils/decode-wa-message.js +66 -138
- package/lib/Utils/event-buffer.d.ts +8 -6
- package/lib/Utils/event-buffer.js +43 -81
- package/lib/Utils/generics.d.ts +27 -27
- package/lib/Utils/generics.js +133 -128
- package/lib/Utils/history.d.ts +5 -9
- package/lib/Utils/history.js +23 -17
- package/lib/Utils/index.d.ts +0 -2
- package/lib/Utils/index.js +0 -2
- package/lib/Utils/link-preview.d.ts +4 -4
- package/lib/Utils/link-preview.js +12 -40
- package/lib/Utils/logger.d.ts +3 -11
- package/lib/Utils/lt-hash.d.ts +8 -8
- package/lib/Utils/lt-hash.js +24 -23
- package/lib/Utils/make-mutex.d.ts +2 -2
- package/lib/Utils/make-mutex.js +2 -3
- package/lib/Utils/messages-media.d.ts +41 -37
- package/lib/Utils/messages-media.js +368 -252
- package/lib/Utils/messages.d.ts +15 -13
- package/lib/Utils/messages.js +261 -274
- package/lib/Utils/noise-handler.d.ts +15 -13
- package/lib/Utils/noise-handler.js +26 -20
- package/lib/Utils/process-message.d.ts +8 -9
- package/lib/Utils/process-message.js +93 -157
- package/lib/Utils/signal.d.ts +5 -6
- package/lib/Utils/signal.js +29 -37
- package/lib/Utils/use-multi-file-auth-state.d.ts +2 -1
- package/lib/Utils/use-multi-file-auth-state.js +7 -12
- package/lib/Utils/validate-connection.d.ts +6 -5
- package/lib/Utils/validate-connection.js +97 -39
- package/lib/WABinary/constants.d.ts +27 -24
- package/lib/WABinary/constants.js +13 -1276
- package/lib/WABinary/decode.d.ts +4 -3
- package/lib/WABinary/decode.js +14 -28
- package/lib/WABinary/encode.d.ts +2 -1
- package/lib/WABinary/encode.js +147 -134
- package/lib/WABinary/generic-utils.d.ts +7 -4
- package/lib/WABinary/generic-utils.js +125 -40
- package/lib/WABinary/jid-utils.d.ts +8 -13
- package/lib/WABinary/jid-utils.js +16 -27
- package/lib/WAM/BinaryInfo.d.ts +11 -2
- package/lib/WAM/constants.d.ts +2 -3
- package/lib/WAM/constants.js +2359 -2252
- package/lib/WAM/encode.d.ts +2 -1
- package/lib/WAM/encode.js +11 -8
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +4 -3
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +5 -5
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +5 -5
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +6 -5
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +1 -1
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +3 -4
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +3 -11
- package/lib/WAUSync/USyncQuery.d.ts +2 -2
- package/lib/WAUSync/USyncQuery.js +15 -19
- package/lib/WAUSync/USyncUser.d.ts +5 -5
- package/lib/WAUSync/index.d.ts +1 -1
- package/lib/WAUSync/index.js +1 -1
- package/package.json +102 -104
- package/lib/Signal/lid-mapping.d.ts +0 -26
- package/lib/Signal/lid-mapping.js +0 -146
- package/lib/Socket/communities.d.ts +0 -232
- package/lib/Socket/communities.js +0 -402
- package/lib/Socket/mex.d.ts +0 -2
- package/lib/Socket/mex.js +0 -45
- package/lib/Types/Bussines.d.ts +0 -24
- package/lib/Types/Bussines.js +0 -2
- package/lib/Utils/lidToJid-test.d.ts +0 -11
- package/lib/Utils/lidToJid-test.js +0 -27
- package/lib/Utils/message-retry-manager.d.ts +0 -81
- package/lib/Utils/message-retry-manager.js +0 -152
- /package/lib/Socket/Client/{types.js → abstract-socket-client.js} +0 -0
|
@@ -4,10 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.makeMessagesRecvSocket = void 0;
|
|
7
|
-
const node_cache_1 = __importDefault(require("@cacheable/node-cache"));
|
|
8
7
|
const boom_1 = require("@hapi/boom");
|
|
9
8
|
const crypto_1 = require("crypto");
|
|
10
|
-
const
|
|
9
|
+
const node_cache_1 = __importDefault(require("@cacheable/node-cache"));
|
|
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");
|
|
@@ -16,208 +16,49 @@ const WABinary_1 = require("../WABinary");
|
|
|
16
16
|
const groups_1 = require("./groups");
|
|
17
17
|
const messages_send_1 = require("./messages-send");
|
|
18
18
|
const makeMessagesRecvSocket = (config) => {
|
|
19
|
-
const {
|
|
19
|
+
const {
|
|
20
|
+
logger,
|
|
21
|
+
retryRequestDelayMs,
|
|
22
|
+
maxMsgRetryCount,
|
|
23
|
+
getMessage,
|
|
24
|
+
shouldIgnoreJid
|
|
25
|
+
} = config;
|
|
20
26
|
const sock = (0, messages_send_1.makeMessagesSocket)(config);
|
|
21
|
-
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;
|
|
22
47
|
/** this mutex ensures that each retryRequest will wait for the previous one to finish */
|
|
23
48
|
const retryMutex = (0, make_mutex_1.makeMutex)();
|
|
24
|
-
const msgRetryCache = config.msgRetryCounterCache ||
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
37
|
-
useClones: false
|
|
38
|
-
});
|
|
49
|
+
const msgRetryCache = config.msgRetryCounterCache || new node_cache_1.default({
|
|
50
|
+
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
51
|
+
useClones: false
|
|
52
|
+
});
|
|
53
|
+
const callOfferCache = config.callOfferCache || new node_cache_1.default({
|
|
54
|
+
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.CALL_OFFER, // 5 mins
|
|
55
|
+
useClones: false
|
|
56
|
+
});
|
|
57
|
+
const placeholderResendCache = config.placeholderResendCache || new node_cache_1.default({
|
|
58
|
+
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
59
|
+
useClones: false
|
|
60
|
+
});
|
|
39
61
|
let sendActiveReceipts = false;
|
|
40
|
-
const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
|
|
41
|
-
if (!authState.creds.me?.id) {
|
|
42
|
-
throw new boom_1.Boom('Not authenticated');
|
|
43
|
-
}
|
|
44
|
-
const pdoMessage = {
|
|
45
|
-
historySyncOnDemandRequest: {
|
|
46
|
-
chatJid: oldestMsgKey.remoteJid,
|
|
47
|
-
oldestMsgFromMe: oldestMsgKey.fromMe,
|
|
48
|
-
oldestMsgId: oldestMsgKey.id,
|
|
49
|
-
oldestMsgTimestampMs: oldestMsgTimestamp,
|
|
50
|
-
onDemandMsgCount: count
|
|
51
|
-
},
|
|
52
|
-
peerDataOperationRequestType: index_js_1.proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
|
|
53
|
-
};
|
|
54
|
-
return sendPeerDataOperationMessage(pdoMessage);
|
|
55
|
-
};
|
|
56
|
-
const requestPlaceholderResend = async (messageKey) => {
|
|
57
|
-
if (!authState.creds.me?.id) {
|
|
58
|
-
throw new boom_1.Boom('Not authenticated');
|
|
59
|
-
}
|
|
60
|
-
if (placeholderResendCache.get(messageKey?.id)) {
|
|
61
|
-
logger.debug({ messageKey }, 'already requested resend');
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
placeholderResendCache.set(messageKey?.id, true);
|
|
66
|
-
}
|
|
67
|
-
await (0, Utils_1.delay)(5000);
|
|
68
|
-
if (!placeholderResendCache.get(messageKey?.id)) {
|
|
69
|
-
logger.debug({ messageKey }, 'message received while resend requested');
|
|
70
|
-
return 'RESOLVED';
|
|
71
|
-
}
|
|
72
|
-
const pdoMessage = {
|
|
73
|
-
placeholderMessageResendRequest: [
|
|
74
|
-
{
|
|
75
|
-
messageKey
|
|
76
|
-
}
|
|
77
|
-
],
|
|
78
|
-
peerDataOperationRequestType: index_js_1.proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
|
|
79
|
-
};
|
|
80
|
-
setTimeout(() => {
|
|
81
|
-
if (placeholderResendCache.get(messageKey?.id)) {
|
|
82
|
-
logger.debug({ messageKey }, 'PDO message without response after 15 seconds. Phone possibly offline');
|
|
83
|
-
placeholderResendCache.del(messageKey?.id);
|
|
84
|
-
}
|
|
85
|
-
}, 15000);
|
|
86
|
-
return sendPeerDataOperationMessage(pdoMessage);
|
|
87
|
-
};
|
|
88
|
-
// Handles mex newsletter notifications
|
|
89
|
-
const handleMexNewsletterNotification = async (node) => {
|
|
90
|
-
const mexNode = (0, WABinary_1.getBinaryNodeChild)(node, 'mex');
|
|
91
|
-
if (!mexNode?.content) {
|
|
92
|
-
logger.warn({ node }, 'Invalid mex newsletter notification');
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
let data;
|
|
96
|
-
try {
|
|
97
|
-
data = JSON.parse(mexNode.content.toString());
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
logger.error({ err: error, node }, 'Failed to parse mex newsletter notification');
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
const operation = data?.operation;
|
|
104
|
-
const updates = data?.updates;
|
|
105
|
-
if (!updates || !operation) {
|
|
106
|
-
logger.warn({ data }, 'Invalid mex newsletter notification content');
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
logger.info({ operation, updates }, 'got mex newsletter notification');
|
|
110
|
-
switch (operation) {
|
|
111
|
-
case 'NotificationNewsletterUpdate':
|
|
112
|
-
for (const update of updates) {
|
|
113
|
-
if (update.jid && update.settings && Object.keys(update.settings).length > 0) {
|
|
114
|
-
ev.emit('newsletter-settings.update', {
|
|
115
|
-
id: update.jid,
|
|
116
|
-
update: update.settings
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
break;
|
|
121
|
-
case 'NotificationNewsletterAdminPromote':
|
|
122
|
-
for (const update of updates) {
|
|
123
|
-
if (update.jid && update.user) {
|
|
124
|
-
ev.emit('newsletter-participants.update', {
|
|
125
|
-
id: update.jid,
|
|
126
|
-
author: node.attrs.from,
|
|
127
|
-
user: update.user,
|
|
128
|
-
new_role: 'ADMIN',
|
|
129
|
-
action: 'promote'
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
break;
|
|
134
|
-
default:
|
|
135
|
-
logger.info({ operation, data }, 'Unhandled mex newsletter notification');
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
// Handles newsletter notifications
|
|
140
|
-
const handleNewsletterNotification = async (node) => {
|
|
141
|
-
const from = node.attrs.from;
|
|
142
|
-
const child = (0, WABinary_1.getAllBinaryNodeChildren)(node)[0];
|
|
143
|
-
const author = node.attrs.participant;
|
|
144
|
-
logger.info({ from, child }, 'got newsletter notification');
|
|
145
|
-
switch (child.tag) {
|
|
146
|
-
case 'reaction':
|
|
147
|
-
const reactionUpdate = {
|
|
148
|
-
id: from,
|
|
149
|
-
server_id: child.attrs.message_id,
|
|
150
|
-
reaction: {
|
|
151
|
-
code: (0, WABinary_1.getBinaryNodeChildString)(child, 'reaction'),
|
|
152
|
-
count: 1
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
ev.emit('newsletter.reaction', reactionUpdate);
|
|
156
|
-
break;
|
|
157
|
-
case 'view':
|
|
158
|
-
const viewUpdate = {
|
|
159
|
-
id: from,
|
|
160
|
-
server_id: child.attrs.message_id,
|
|
161
|
-
count: parseInt(child.content?.toString() || '0', 10)
|
|
162
|
-
};
|
|
163
|
-
ev.emit('newsletter.view', viewUpdate);
|
|
164
|
-
break;
|
|
165
|
-
case 'participant':
|
|
166
|
-
const participantUpdate = {
|
|
167
|
-
id: from,
|
|
168
|
-
author,
|
|
169
|
-
user: child.attrs.jid,
|
|
170
|
-
action: child.attrs.action,
|
|
171
|
-
new_role: child.attrs.role
|
|
172
|
-
};
|
|
173
|
-
ev.emit('newsletter-participants.update', participantUpdate);
|
|
174
|
-
break;
|
|
175
|
-
case 'update':
|
|
176
|
-
const settingsNode = (0, WABinary_1.getBinaryNodeChild)(child, 'settings');
|
|
177
|
-
if (settingsNode) {
|
|
178
|
-
const update = {};
|
|
179
|
-
const nameNode = (0, WABinary_1.getBinaryNodeChild)(settingsNode, 'name');
|
|
180
|
-
if (nameNode?.content)
|
|
181
|
-
update.name = nameNode.content.toString();
|
|
182
|
-
const descriptionNode = (0, WABinary_1.getBinaryNodeChild)(settingsNode, 'description');
|
|
183
|
-
if (descriptionNode?.content)
|
|
184
|
-
update.description = descriptionNode.content.toString();
|
|
185
|
-
ev.emit('newsletter-settings.update', {
|
|
186
|
-
id: from,
|
|
187
|
-
update
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
break;
|
|
191
|
-
case 'message':
|
|
192
|
-
const plaintextNode = (0, WABinary_1.getBinaryNodeChild)(child, 'plaintext');
|
|
193
|
-
if (plaintextNode?.content) {
|
|
194
|
-
try {
|
|
195
|
-
const contentBuf = typeof plaintextNode.content === 'string'
|
|
196
|
-
? Buffer.from(plaintextNode.content, 'binary')
|
|
197
|
-
: Buffer.from(plaintextNode.content);
|
|
198
|
-
const messageProto = index_js_1.proto.Message.decode(contentBuf);
|
|
199
|
-
const fullMessage = index_js_1.proto.WebMessageInfo.create({
|
|
200
|
-
key: {
|
|
201
|
-
remoteJid: from,
|
|
202
|
-
id: child.attrs.message_id || child.attrs.server_id,
|
|
203
|
-
fromMe: false
|
|
204
|
-
},
|
|
205
|
-
message: messageProto,
|
|
206
|
-
messageTimestamp: +child.attrs.t
|
|
207
|
-
});
|
|
208
|
-
await upsertMessage(fullMessage, 'append');
|
|
209
|
-
logger.info('Processed plaintext newsletter message');
|
|
210
|
-
}
|
|
211
|
-
catch (error) {
|
|
212
|
-
logger.error({ error }, 'Failed to decode plaintext newsletter message');
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
break;
|
|
216
|
-
default:
|
|
217
|
-
logger.warn({ node }, 'Unknown newsletter notification');
|
|
218
|
-
break;
|
|
219
|
-
}
|
|
220
|
-
};
|
|
221
62
|
const sendMessageAck = async ({ tag, attrs, content }, errorCode) => {
|
|
222
63
|
const stanza = {
|
|
223
64
|
tag: 'ack',
|
|
@@ -226,7 +67,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
226
67
|
to: attrs.from,
|
|
227
68
|
class: tag
|
|
228
69
|
}
|
|
229
|
-
}
|
|
70
|
+
}
|
|
230
71
|
if (!!errorCode) {
|
|
231
72
|
stanza.attrs.error = errorCode.toString();
|
|
232
73
|
}
|
|
@@ -236,111 +77,141 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
236
77
|
if (!!attrs.recipient) {
|
|
237
78
|
stanza.attrs.recipient = attrs.recipient;
|
|
238
79
|
}
|
|
239
|
-
if (!!attrs.type &&
|
|
240
|
-
(tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
|
|
80
|
+
if (!!attrs.type && (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
|
|
241
81
|
stanza.attrs.type = attrs.type;
|
|
242
82
|
}
|
|
243
83
|
if (tag === 'message' && (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable')) {
|
|
244
84
|
stanza.attrs.from = authState.creds.me.id;
|
|
245
85
|
}
|
|
246
|
-
logger.debug({
|
|
86
|
+
logger.debug({
|
|
87
|
+
recv: {
|
|
88
|
+
tag,
|
|
89
|
+
attrs
|
|
90
|
+
},
|
|
91
|
+
sent: stanza.attrs }, 'sent ack');
|
|
247
92
|
await sendNode(stanza);
|
|
248
93
|
};
|
|
94
|
+
const offerCall = async (toJid, isVideo = false) => {
|
|
95
|
+
const callId = (0, crypto_1.randomBytes)(16).toString('hex').toUpperCase().substring(0, 64);
|
|
96
|
+
const offerContent = [];
|
|
97
|
+
offerContent.push({
|
|
98
|
+
tag: 'audio',
|
|
99
|
+
attrs: {
|
|
100
|
+
enc: 'opus',
|
|
101
|
+
rate: '16000'
|
|
102
|
+
}, content: undefined
|
|
103
|
+
});
|
|
104
|
+
offerContent.push({
|
|
105
|
+
tag: 'audio',
|
|
106
|
+
attrs: {
|
|
107
|
+
enc: 'opus',
|
|
108
|
+
rate: '8000'
|
|
109
|
+
}, content: undefined
|
|
110
|
+
});
|
|
111
|
+
if (isVideo) {
|
|
112
|
+
offerContent.push({
|
|
113
|
+
tag: 'video',
|
|
114
|
+
attrs: {
|
|
115
|
+
orientation: '0',
|
|
116
|
+
'screen_width': '1920',
|
|
117
|
+
'screen_height': '1080',
|
|
118
|
+
'device_orientation': '0',
|
|
119
|
+
enc: 'vp8',
|
|
120
|
+
dec: 'vp8',
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
offerContent.push({
|
|
125
|
+
tag: 'net',
|
|
126
|
+
attrs: {
|
|
127
|
+
medium: '3'
|
|
128
|
+
}, content: undefined
|
|
129
|
+
});
|
|
130
|
+
offerContent.push({
|
|
131
|
+
tag: 'capability',
|
|
132
|
+
attrs: {
|
|
133
|
+
ver: '1'
|
|
134
|
+
}, content: new Uint8Array([1, 4, 255, 131, 207, 4]) });
|
|
135
|
+
offerContent.push({
|
|
136
|
+
tag: 'encopt',
|
|
137
|
+
attrs: {
|
|
138
|
+
keygen: '2'
|
|
139
|
+
}, content: undefined
|
|
140
|
+
})
|
|
141
|
+
const encKey = (0, crypto_1.randomBytes)(32);
|
|
142
|
+
const devices = (await getUSyncDevices([toJid], true, false)).map(({ user, device }) => (0, WABinary_1.jidEncode)(user, 's.whatsapp.net', device));
|
|
143
|
+
await assertSessions(devices, true);
|
|
144
|
+
const { nodes: destinations, shouldIncludeDeviceIdentity } = await createParticipantNodes(devices, {
|
|
145
|
+
call: {
|
|
146
|
+
callKey: encKey
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
offerContent.push({ tag: 'destination', attrs: {}, content: destinations });
|
|
150
|
+
if (shouldIncludeDeviceIdentity) {
|
|
151
|
+
offerContent.push({
|
|
152
|
+
tag: 'device-identity',
|
|
153
|
+
attrs: {},
|
|
154
|
+
content: (0, Utils_1.encodeSignedDeviceIdentity)(authState.creds.account, true)
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const stanza = ({
|
|
158
|
+
tag: 'call',
|
|
159
|
+
attrs: {
|
|
160
|
+
to: toJid,
|
|
161
|
+
},
|
|
162
|
+
content: [{
|
|
163
|
+
tag: 'offer',
|
|
164
|
+
attrs: {
|
|
165
|
+
'call-id': callId,
|
|
166
|
+
'call-creator': authState.creds.me.id,
|
|
167
|
+
},
|
|
168
|
+
content: offerContent,
|
|
169
|
+
}],
|
|
170
|
+
});
|
|
171
|
+
await query(stanza);
|
|
172
|
+
return {
|
|
173
|
+
callId,
|
|
174
|
+
toJid,
|
|
175
|
+
isVideo,
|
|
176
|
+
};
|
|
177
|
+
};
|
|
249
178
|
const rejectCall = async (callId, callFrom) => {
|
|
250
|
-
const stanza = {
|
|
179
|
+
const stanza = ({
|
|
251
180
|
tag: 'call',
|
|
252
181
|
attrs: {
|
|
253
182
|
from: authState.creds.me.id,
|
|
254
|
-
to: callFrom
|
|
183
|
+
to: callFrom,
|
|
255
184
|
},
|
|
256
|
-
content: [
|
|
257
|
-
{
|
|
185
|
+
content: [{
|
|
258
186
|
tag: 'reject',
|
|
259
187
|
attrs: {
|
|
260
188
|
'call-id': callId,
|
|
261
189
|
'call-creator': callFrom,
|
|
262
|
-
count: '0'
|
|
190
|
+
count: '0',
|
|
263
191
|
},
|
|
264
|
-
content: undefined
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
};
|
|
192
|
+
content: undefined,
|
|
193
|
+
}],
|
|
194
|
+
});
|
|
268
195
|
await query(stanza);
|
|
269
196
|
};
|
|
270
197
|
const sendRetryRequest = async (node, forceIncludeKeys = false) => {
|
|
271
198
|
const { fullMessage } = (0, Utils_1.decodeMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '');
|
|
272
199
|
const { key: msgKey } = fullMessage;
|
|
273
200
|
const msgId = msgKey.id;
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
281
|
-
// Increment retry count using new system
|
|
282
|
-
const retryCount = messageRetryManager.incrementRetryCount(msgId);
|
|
283
|
-
// Use the new retry count for the rest of the logic
|
|
284
|
-
const key = `${msgId}:${msgKey?.participant}`;
|
|
285
|
-
msgRetryCache.set(key, retryCount);
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
// Fallback to old system
|
|
289
|
-
const key = `${msgId}:${msgKey?.participant}`;
|
|
290
|
-
let retryCount = (await msgRetryCache.get(key)) || 0;
|
|
291
|
-
if (retryCount >= maxMsgRetryCount) {
|
|
292
|
-
logger.debug({ retryCount, msgId }, 'reached retry limit, clearing');
|
|
293
|
-
msgRetryCache.del(key);
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
retryCount += 1;
|
|
297
|
-
await msgRetryCache.set(key, retryCount);
|
|
201
|
+
const key = `${msgId}:${msgKey === null || msgKey === void 0 ? void 0 : msgKey.participant}`;
|
|
202
|
+
let retryCount = msgRetryCache.get(key) || 0;
|
|
203
|
+
if (retryCount >= maxMsgRetryCount) {
|
|
204
|
+
logger.debug({ retryCount, msgId }, 'reached retry limit, clearing');
|
|
205
|
+
msgRetryCache.del(key);
|
|
206
|
+
return;
|
|
298
207
|
}
|
|
299
|
-
|
|
300
|
-
|
|
208
|
+
retryCount += 1;
|
|
209
|
+
msgRetryCache.set(key, retryCount);
|
|
301
210
|
const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds;
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
if (enableAutoSessionRecreation && messageRetryManager) {
|
|
307
|
-
try {
|
|
308
|
-
// Check if we have a session with this JID
|
|
309
|
-
const sessionId = signalRepository.jidToSignalProtocolAddress(fromJid);
|
|
310
|
-
const hasSession = await signalRepository.validateSession(fromJid);
|
|
311
|
-
const result = messageRetryManager.shouldRecreateSession(fromJid, retryCount, hasSession.exists);
|
|
312
|
-
shouldRecreateSession = result.recreate;
|
|
313
|
-
recreateReason = result.reason;
|
|
314
|
-
if (shouldRecreateSession) {
|
|
315
|
-
logger.info({ fromJid, retryCount, reason: recreateReason }, 'recreating session for retry');
|
|
316
|
-
// Delete existing session to force recreation
|
|
317
|
-
await authState.keys.set({ session: { [sessionId]: null } });
|
|
318
|
-
forceIncludeKeys = true;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
catch (error) {
|
|
322
|
-
logger.warn({ error, fromJid }, 'failed to check session recreation');
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
if (retryCount <= 2) {
|
|
326
|
-
// Use new retry manager for phone requests if available
|
|
327
|
-
if (messageRetryManager) {
|
|
328
|
-
// Schedule phone request with delay (like whatsmeow)
|
|
329
|
-
messageRetryManager.schedulePhoneRequest(msgId, async () => {
|
|
330
|
-
try {
|
|
331
|
-
const msgId = await requestPlaceholderResend(msgKey);
|
|
332
|
-
logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId} (scheduled)`);
|
|
333
|
-
}
|
|
334
|
-
catch (error) {
|
|
335
|
-
logger.warn({ error, msgId }, 'failed to send scheduled phone request');
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
// Fallback to immediate request
|
|
341
|
-
const msgId = await requestPlaceholderResend(msgKey);
|
|
342
|
-
logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId}`);
|
|
343
|
-
}
|
|
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}`);
|
|
344
215
|
}
|
|
345
216
|
const deviceIdentity = (0, Utils_1.encodeSignedDeviceIdentity)(account, true);
|
|
346
217
|
await authState.keys.transaction(async () => {
|
|
@@ -374,7 +245,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
374
245
|
if (node.attrs.participant) {
|
|
375
246
|
receipt.attrs.participant = node.attrs.participant;
|
|
376
247
|
}
|
|
377
|
-
if (retryCount > 1 || forceIncludeKeys
|
|
248
|
+
if (retryCount > 1 || forceIncludeKeys) {
|
|
378
249
|
const { update, preKeys } = await (0, Utils_1.getNextPreKeys)(authState, 1);
|
|
379
250
|
const [keyId] = Object.keys(preKeys);
|
|
380
251
|
const key = preKeys[+keyId];
|
|
@@ -394,7 +265,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
394
265
|
}
|
|
395
266
|
await sendNode(receipt);
|
|
396
267
|
logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt');
|
|
397
|
-
}
|
|
268
|
+
});
|
|
398
269
|
};
|
|
399
270
|
const handleEncryptNotification = async (node) => {
|
|
400
271
|
const from = node.attrs.from;
|
|
@@ -420,33 +291,29 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
420
291
|
}
|
|
421
292
|
};
|
|
422
293
|
const handleGroupNotification = (participant, child, msg) => {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
switch (child
|
|
294
|
+
var _a, _b, _c, _d;
|
|
295
|
+
const participantJid = ((_b = (_a = (0, WABinary_1.getBinaryNodeChild)(child, 'participant')) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.jid) || participant;
|
|
296
|
+
switch (child === null || child === void 0 ? void 0 : child.tag) {
|
|
426
297
|
case 'create':
|
|
427
298
|
const metadata = (0, groups_1.extractGroupMetadata)(child);
|
|
428
299
|
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CREATE;
|
|
429
300
|
msg.messageStubParameters = [metadata.subject];
|
|
430
301
|
msg.key = { participant: metadata.owner };
|
|
431
|
-
ev.emit('chats.upsert', [
|
|
432
|
-
{
|
|
302
|
+
ev.emit('chats.upsert', [{
|
|
433
303
|
id: metadata.id,
|
|
434
304
|
name: metadata.subject,
|
|
435
|
-
conversationTimestamp: metadata.creation
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
ev.emit('groups.upsert', [
|
|
439
|
-
{
|
|
305
|
+
conversationTimestamp: metadata.creation,
|
|
306
|
+
}]);
|
|
307
|
+
ev.emit('groups.upsert', [{
|
|
440
308
|
...metadata,
|
|
441
309
|
author: participant
|
|
442
|
-
}
|
|
443
|
-
]);
|
|
310
|
+
}]);
|
|
444
311
|
break;
|
|
445
312
|
case 'ephemeral':
|
|
446
313
|
case 'not_ephemeral':
|
|
447
314
|
msg.message = {
|
|
448
315
|
protocolMessage: {
|
|
449
|
-
type:
|
|
316
|
+
type: WAProto_1.proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
|
|
450
317
|
ephemeralExpiration: +(child.attrs.expiration || 0)
|
|
451
318
|
}
|
|
452
319
|
};
|
|
@@ -478,19 +345,19 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
478
345
|
msg.messageStubParameters = [child.attrs.subject];
|
|
479
346
|
break;
|
|
480
347
|
case 'description':
|
|
481
|
-
const description = (0, WABinary_1.getBinaryNodeChild)(child, 'body')
|
|
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();
|
|
482
349
|
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_DESCRIPTION;
|
|
483
350
|
msg.messageStubParameters = description ? [description] : undefined;
|
|
484
351
|
break;
|
|
485
352
|
case 'announcement':
|
|
486
353
|
case 'not_announcement':
|
|
487
354
|
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE;
|
|
488
|
-
msg.messageStubParameters = [child.tag === 'announcement' ? 'on' : 'off'];
|
|
355
|
+
msg.messageStubParameters = [(child.tag === 'announcement') ? 'on' : 'off'];
|
|
489
356
|
break;
|
|
490
357
|
case 'locked':
|
|
491
358
|
case 'unlocked':
|
|
492
359
|
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_RESTRICT;
|
|
493
|
-
msg.messageStubParameters = [child.tag === 'locked' ? 'on' : 'off'];
|
|
360
|
+
msg.messageStubParameters = [(child.tag === 'locked') ? 'on' : 'off'];
|
|
494
361
|
break;
|
|
495
362
|
case 'invite':
|
|
496
363
|
msg.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_INVITE_LINK;
|
|
@@ -519,9 +386,57 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
519
386
|
msg.messageStubType = Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
|
|
520
387
|
msg.messageStubParameters = [participantJid, isDenied ? 'revoked' : 'rejected'];
|
|
521
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 });
|
|
522
436
|
}
|
|
523
437
|
};
|
|
524
438
|
const processNotification = async (node) => {
|
|
439
|
+
var _a, _b;
|
|
525
440
|
const result = {};
|
|
526
441
|
const [child] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
|
|
527
442
|
const nodeType = node.attrs.type;
|
|
@@ -541,10 +456,10 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
541
456
|
}
|
|
542
457
|
break;
|
|
543
458
|
case 'newsletter':
|
|
544
|
-
|
|
459
|
+
handleNewsletterNotification(node.attrs.from, child);
|
|
545
460
|
break;
|
|
546
461
|
case 'mex':
|
|
547
|
-
|
|
462
|
+
handleMexNewsletterNotification(node.attrs.from, child);
|
|
548
463
|
break;
|
|
549
464
|
case 'w:gp2':
|
|
550
465
|
handleGroupNotification(node.attrs.participant, child, result);
|
|
@@ -558,12 +473,10 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
558
473
|
break;
|
|
559
474
|
case 'devices':
|
|
560
475
|
const devices = (0, WABinary_1.getBinaryNodeChildren)(child, 'device');
|
|
561
|
-
if ((0, WABinary_1.areJidsSameUser)(child.attrs.jid, authState.creds.me.id)
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
logger.info({ deviceData }, 'my own devices changed');
|
|
476
|
+
if ((0, WABinary_1.areJidsSameUser)(child.attrs.jid, authState.creds.me.id)) {
|
|
477
|
+
const deviceJids = devices.map(d => d.attrs.jid);
|
|
478
|
+
logger.info({ deviceJids }, 'got my own devices');
|
|
565
479
|
}
|
|
566
|
-
//TODO: drop a new event, add hashes
|
|
567
480
|
break;
|
|
568
481
|
case 'server_sync':
|
|
569
482
|
const update = (0, WABinary_1.getBinaryNodeChild)(node, 'collection');
|
|
@@ -575,22 +488,20 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
575
488
|
case 'picture':
|
|
576
489
|
const setPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'set');
|
|
577
490
|
const delPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'delete');
|
|
578
|
-
ev.emit('contacts.update', [
|
|
579
|
-
|
|
580
|
-
id: (0, WABinary_1.jidNormalizedUser)(node?.attrs?.from) || (setPicture || delPicture)?.attrs?.hash || '',
|
|
491
|
+
ev.emit('contacts.update', [{
|
|
492
|
+
id: from || ((_b = (_a = (setPicture || delPicture)) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.hash) || '',
|
|
581
493
|
imgUrl: setPicture ? 'changed' : 'removed'
|
|
582
|
-
}
|
|
583
|
-
]);
|
|
494
|
+
}]);
|
|
584
495
|
if ((0, WABinary_1.isJidGroup)(from)) {
|
|
585
496
|
const node = setPicture || delPicture;
|
|
586
497
|
result.messageStubType = Types_1.WAMessageStubType.GROUP_CHANGE_ICON;
|
|
587
498
|
if (setPicture) {
|
|
588
499
|
result.messageStubParameters = [setPicture.attrs.id];
|
|
589
500
|
}
|
|
590
|
-
result.participant = node
|
|
501
|
+
result.participant = node === null || node === void 0 ? void 0 : node.attrs.author;
|
|
591
502
|
result.key = {
|
|
592
|
-
...
|
|
593
|
-
participant: setPicture
|
|
503
|
+
...result.key || {},
|
|
504
|
+
participant: setPicture === null || setPicture === void 0 ? void 0 : setPicture.attrs.author
|
|
594
505
|
};
|
|
595
506
|
}
|
|
596
507
|
break;
|
|
@@ -604,8 +515,8 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
604
515
|
...authState.creds.accountSettings,
|
|
605
516
|
defaultDisappearingMode: {
|
|
606
517
|
ephemeralExpiration: newDuration,
|
|
607
|
-
ephemeralSettingTimestamp: timestamp
|
|
608
|
-
}
|
|
518
|
+
ephemeralSettingTimestamp: timestamp,
|
|
519
|
+
},
|
|
609
520
|
}
|
|
610
521
|
});
|
|
611
522
|
}
|
|
@@ -613,7 +524,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
613
524
|
const blocklists = (0, WABinary_1.getBinaryNodeChildren)(child, 'item');
|
|
614
525
|
for (const { attrs } of blocklists) {
|
|
615
526
|
const blocklist = [attrs.jid];
|
|
616
|
-
const type = attrs.action === 'block' ? 'add' : 'remove';
|
|
527
|
+
const type = (attrs.action === 'block') ? 'add' : 'remove';
|
|
617
528
|
ev.emit('blocklist.update', { blocklist, type });
|
|
618
529
|
}
|
|
619
530
|
}
|
|
@@ -631,11 +542,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
631
542
|
salt: linkCodeSalt,
|
|
632
543
|
info: 'link_code_pairing_key_bundle_encryption_key'
|
|
633
544
|
});
|
|
634
|
-
const encryptPayload = Buffer.concat([
|
|
635
|
-
Buffer.from(authState.creds.signedIdentityKey.public),
|
|
636
|
-
primaryIdentityPublicKey,
|
|
637
|
-
random
|
|
638
|
-
]);
|
|
545
|
+
const encryptPayload = Buffer.concat([Buffer.from(authState.creds.signedIdentityKey.public), primaryIdentityPublicKey, random]);
|
|
639
546
|
const encryptIv = (0, crypto_1.randomBytes)(12);
|
|
640
547
|
const encrypted = (0, Utils_1.aesEncryptGCM)(encryptPayload, linkCodePairingExpanded, encryptIv, Buffer.alloc(0));
|
|
641
548
|
const encryptedPayload = Buffer.concat([linkCodeSalt, encryptIv, encrypted]);
|
|
@@ -655,7 +562,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
655
562
|
tag: 'link_code_companion_reg',
|
|
656
563
|
attrs: {
|
|
657
564
|
jid: authState.creds.me.id,
|
|
658
|
-
stage: 'companion_finish'
|
|
565
|
+
stage: 'companion_finish',
|
|
659
566
|
},
|
|
660
567
|
content: [
|
|
661
568
|
{
|
|
@@ -698,79 +605,33 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
698
605
|
}
|
|
699
606
|
return data instanceof Buffer ? data : Buffer.from(data);
|
|
700
607
|
}
|
|
701
|
-
const willSendMessageAgain =
|
|
608
|
+
const willSendMessageAgain = (id, participant) => {
|
|
702
609
|
const key = `${id}:${participant}`;
|
|
703
|
-
const retryCount =
|
|
610
|
+
const retryCount = msgRetryCache.get(key) || 0;
|
|
704
611
|
return retryCount < maxMsgRetryCount;
|
|
705
612
|
};
|
|
706
|
-
const updateSendMessageAgainCount =
|
|
613
|
+
const updateSendMessageAgainCount = (id, participant) => {
|
|
707
614
|
const key = `${id}:${participant}`;
|
|
708
|
-
const newValue = (
|
|
709
|
-
|
|
615
|
+
const newValue = (msgRetryCache.get(key) || 0) + 1;
|
|
616
|
+
msgRetryCache.set(key, newValue);
|
|
710
617
|
};
|
|
711
618
|
const sendMessagesAgain = async (key, ids, retryNode) => {
|
|
619
|
+
var _a;
|
|
620
|
+
// todo: implement a cache to store the last 256 sent messages (copy whatsmeow)
|
|
621
|
+
const msgs = await Promise.all(ids.map(id => getMessage({ ...key, id })));
|
|
712
622
|
const remoteJid = key.remoteJid;
|
|
713
623
|
const participant = key.participant || remoteJid;
|
|
714
|
-
const retryCount = +retryNode.attrs.count || 1;
|
|
715
|
-
// Try to get messages from cache first, then fallback to getMessage
|
|
716
|
-
const msgs = [];
|
|
717
|
-
for (const id of ids) {
|
|
718
|
-
let msg;
|
|
719
|
-
// Try to get from retry cache first if enabled
|
|
720
|
-
if (messageRetryManager) {
|
|
721
|
-
const cachedMsg = messageRetryManager.getRecentMessage(remoteJid, id);
|
|
722
|
-
if (cachedMsg) {
|
|
723
|
-
msg = cachedMsg.message;
|
|
724
|
-
logger.debug({ jid: remoteJid, id }, 'found message in retry cache');
|
|
725
|
-
// Mark retry as successful since we found the message
|
|
726
|
-
messageRetryManager.markRetrySuccess(id);
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
// Fallback to getMessage if not found in cache
|
|
730
|
-
if (!msg) {
|
|
731
|
-
msg = await getMessage({ ...key, id });
|
|
732
|
-
if (msg) {
|
|
733
|
-
logger.debug({ jid: remoteJid, id }, 'found message via getMessage');
|
|
734
|
-
// Also mark as successful if found via getMessage
|
|
735
|
-
if (messageRetryManager) {
|
|
736
|
-
messageRetryManager.markRetrySuccess(id);
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
msgs.push(msg);
|
|
741
|
-
}
|
|
742
624
|
// if it's the primary jid sending the request
|
|
743
625
|
// just re-send the message to everyone
|
|
744
626
|
// prevents the first message decryption failure
|
|
745
|
-
const sendToAll = !(0, WABinary_1.jidDecode)(participant)
|
|
746
|
-
|
|
747
|
-
let shouldRecreateSession = false;
|
|
748
|
-
let recreateReason = '';
|
|
749
|
-
if (enableAutoSessionRecreation && messageRetryManager) {
|
|
750
|
-
try {
|
|
751
|
-
const sessionId = signalRepository.jidToSignalProtocolAddress(participant);
|
|
752
|
-
const hasSession = await signalRepository.validateSession(participant);
|
|
753
|
-
const result = messageRetryManager.shouldRecreateSession(participant, retryCount, hasSession.exists);
|
|
754
|
-
shouldRecreateSession = result.recreate;
|
|
755
|
-
recreateReason = result.reason;
|
|
756
|
-
if (shouldRecreateSession) {
|
|
757
|
-
logger.info({ participant, retryCount, reason: recreateReason }, 'recreating session for outgoing retry');
|
|
758
|
-
await authState.keys.set({ session: { [sessionId]: null } });
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
catch (error) {
|
|
762
|
-
logger.warn({ error, participant }, 'failed to check session recreation for outgoing retry');
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
await assertSessions([participant], shouldRecreateSession);
|
|
627
|
+
const sendToAll = !((_a = (0, WABinary_1.jidDecode)(participant)) === null || _a === void 0 ? void 0 : _a.device);
|
|
628
|
+
await assertSessions([participant], true);
|
|
766
629
|
if ((0, WABinary_1.isJidGroup)(remoteJid)) {
|
|
767
630
|
await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } });
|
|
768
631
|
}
|
|
769
|
-
logger.debug({ participant, sendToAll
|
|
632
|
+
logger.debug({ participant, sendToAll }, 'forced new session for retry recp');
|
|
770
633
|
for (const [i, msg] of msgs.entries()) {
|
|
771
|
-
if (
|
|
772
|
-
continue;
|
|
773
|
-
if (msg && (await willSendMessageAgain(ids[i], participant))) {
|
|
634
|
+
if (msg) {
|
|
774
635
|
updateSendMessageAgainCount(ids[i], participant);
|
|
775
636
|
const msgRelayOpts = { messageId: ids[i] };
|
|
776
637
|
if (sendToAll) {
|
|
@@ -790,9 +651,10 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
790
651
|
}
|
|
791
652
|
};
|
|
792
653
|
const handleReceipt = async (node) => {
|
|
654
|
+
var _a, _b;
|
|
793
655
|
const { attrs, content } = node;
|
|
794
656
|
const isLid = attrs.from.includes('lid');
|
|
795
|
-
const isNodeFromMe = (0, WABinary_1.areJidsSameUser)(attrs.participant || attrs.from, isLid ? authState.creds.me
|
|
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);
|
|
796
658
|
const remoteJid = !isNodeFromMe || (0, WABinary_1.isJidGroup)(attrs.from) ? attrs.from : attrs.recipient;
|
|
797
659
|
const fromMe = !attrs.recipient || ((attrs.type === 'retry' || attrs.type === 'sender') && isNodeFromMe);
|
|
798
660
|
const key = {
|
|
@@ -816,12 +678,14 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
816
678
|
processingMutex.mutex(async () => {
|
|
817
679
|
const status = (0, Utils_1.getStatusFromReceiptType)(attrs.type);
|
|
818
680
|
if (typeof status !== 'undefined' &&
|
|
681
|
+
(
|
|
819
682
|
// basically, we only want to know when a message from us has been delivered to/read by the other person
|
|
820
683
|
// or another device of ours has read some messages
|
|
821
|
-
|
|
684
|
+
status >= WAProto_1.proto.WebMessageInfo.Status.SERVER_ACK ||
|
|
685
|
+
!isNodeFromMe)) {
|
|
822
686
|
if ((0, WABinary_1.isJidGroup)(remoteJid) || (0, WABinary_1.isJidStatusBroadcast)(remoteJid)) {
|
|
823
687
|
if (attrs.participant) {
|
|
824
|
-
const updateKey = status ===
|
|
688
|
+
const updateKey = status === WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
|
|
825
689
|
ev.emit('message-receipt.update', ids.map(id => ({
|
|
826
690
|
key: { ...key, id },
|
|
827
691
|
receipt: {
|
|
@@ -842,15 +706,14 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
842
706
|
// correctly set who is asking for the retry
|
|
843
707
|
key.participant = key.participant || attrs.from;
|
|
844
708
|
const retryNode = (0, WABinary_1.getBinaryNodeChild)(node, 'retry');
|
|
845
|
-
if (
|
|
709
|
+
if (willSendMessageAgain(ids[0], key.participant)) {
|
|
846
710
|
if (key.fromMe) {
|
|
847
711
|
try {
|
|
848
|
-
updateSendMessageAgainCount(ids[0], key.participant);
|
|
849
712
|
logger.debug({ attrs, key }, 'recv retry request');
|
|
850
713
|
await sendMessagesAgain(key, ids, retryNode);
|
|
851
714
|
}
|
|
852
715
|
catch (error) {
|
|
853
|
-
logger.error({ key, ids, trace: error
|
|
716
|
+
logger.error({ key, ids, trace: error.stack }, 'error in sending message again');
|
|
854
717
|
}
|
|
855
718
|
}
|
|
856
719
|
else {
|
|
@@ -878,6 +741,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
878
741
|
try {
|
|
879
742
|
await Promise.all([
|
|
880
743
|
processingMutex.mutex(async () => {
|
|
744
|
+
var _a;
|
|
881
745
|
const msg = await processNotification(node);
|
|
882
746
|
if (msg) {
|
|
883
747
|
const fromMe = (0, WABinary_1.areJidsSameUser)(node.attrs.participant || remoteJid, authState.creds.me.id);
|
|
@@ -888,9 +752,9 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
888
752
|
id: node.attrs.id,
|
|
889
753
|
...(msg.key || {})
|
|
890
754
|
};
|
|
891
|
-
msg.participant
|
|
755
|
+
(_a = msg.participant) !== null && _a !== void 0 ? _a : (msg.participant = node.attrs.participant);
|
|
892
756
|
msg.messageTimestamp = +node.attrs.t;
|
|
893
|
-
const fullMsg =
|
|
757
|
+
const fullMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
|
|
894
758
|
await upsertMessage(fullMsg, 'append');
|
|
895
759
|
}
|
|
896
760
|
})
|
|
@@ -901,6 +765,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
901
765
|
}
|
|
902
766
|
};
|
|
903
767
|
const handleMessage = async (node) => {
|
|
768
|
+
var _a, _b, _c;
|
|
904
769
|
if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !== '@s.whatsapp.net') {
|
|
905
770
|
logger.debug({ key: node.attrs.key }, 'ignored message');
|
|
906
771
|
await sendMessageAck(node);
|
|
@@ -910,129 +775,83 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
910
775
|
// TODO: temporary fix for crashes and issues resulting of failed msmsg decryption
|
|
911
776
|
if (encNode && encNode.attrs.type === 'msmsg') {
|
|
912
777
|
logger.debug({ key: node.attrs.key }, 'ignored msmsg');
|
|
913
|
-
await sendMessageAck(node
|
|
778
|
+
await sendMessageAck(node);
|
|
914
779
|
return;
|
|
915
780
|
}
|
|
916
781
|
let response;
|
|
917
782
|
if ((0, WABinary_1.getBinaryNodeChild)(node, 'unavailable') && !encNode) {
|
|
918
783
|
await sendMessageAck(node);
|
|
919
784
|
const { key } = (0, Utils_1.decodeMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '').fullMessage;
|
|
920
|
-
response = await requestPlaceholderResend(key);
|
|
785
|
+
response = await requestPlaceholderResend(key);
|
|
921
786
|
if (response === 'RESOLVED') {
|
|
922
787
|
return;
|
|
923
788
|
}
|
|
924
789
|
logger.debug('received unavailable message, acked and requested resend from phone');
|
|
925
790
|
}
|
|
926
791
|
else {
|
|
927
|
-
if (
|
|
928
|
-
|
|
792
|
+
if (placeholderResendCache.get(node.attrs.id)) {
|
|
793
|
+
placeholderResendCache.del(node.attrs.id);
|
|
929
794
|
}
|
|
930
795
|
}
|
|
931
796
|
const { fullMessage: msg, category, author, decrypt } = (0, Utils_1.decryptMessageNode)(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
|
|
932
|
-
if (response && msg
|
|
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) {
|
|
933
798
|
msg.messageStubParameters = [Utils_1.NO_MESSAGE_FOUND_ERROR_TEXT, response];
|
|
934
799
|
}
|
|
935
|
-
if (msg.message
|
|
936
|
-
node.attrs.sender_pn)
|
|
937
|
-
const lid = (0, WABinary_1.jidNormalizedUser)(node.attrs.from), pn = (0, WABinary_1.jidNormalizedUser)(node.attrs.sender_pn);
|
|
938
|
-
ev.emit('lid-mapping.update', { lid, pn });
|
|
939
|
-
await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }]);
|
|
940
|
-
}
|
|
941
|
-
const alt = msg.key.participantAlt || msg.key.remoteJidAlt;
|
|
942
|
-
// store new mappings we didn't have before
|
|
943
|
-
if (!!alt) {
|
|
944
|
-
const altServer = (0, WABinary_1.jidDecode)(alt)?.server;
|
|
945
|
-
if (altServer === 'lid') {
|
|
946
|
-
if (typeof (await signalRepository.lidMapping.getPNForLID(alt)) === 'string') {
|
|
947
|
-
await signalRepository.lidMapping.storeLIDPNMappings([
|
|
948
|
-
{ lid: alt, pn: msg.key.participant || msg.key.remoteJid }
|
|
949
|
-
]);
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
else {
|
|
953
|
-
if (typeof (await signalRepository.lidMapping.getLIDForPN(alt)) === 'string') {
|
|
954
|
-
await signalRepository.lidMapping.storeLIDPNMappings([
|
|
955
|
-
{ lid: msg.key.participant || msg.key.remoteJid, pn: alt }
|
|
956
|
-
]);
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
if (msg.key?.remoteJid && msg.key?.id && messageRetryManager) {
|
|
961
|
-
messageRetryManager.addRecentMessage(msg.key.remoteJid, msg.key.id, msg.message);
|
|
962
|
-
logger.debug({
|
|
963
|
-
jid: msg.key.remoteJid,
|
|
964
|
-
id: msg.key.id
|
|
965
|
-
}, 'Added message to recent cache for retry receipts');
|
|
800
|
+
if (((_c = (_b = msg.message) === null || _b === void 0 ? void 0 : _b.protocolMessage) === null || _c === void 0 ? void 0 : _c.type) === WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER && node.attrs.sender_pn) {
|
|
801
|
+
ev.emit('chats.phoneNumberShare', { lid: node.attrs.from, jid: node.attrs.sender_pn });
|
|
966
802
|
}
|
|
967
803
|
try {
|
|
968
804
|
await Promise.all([
|
|
969
805
|
processingMutex.mutex(async () => {
|
|
806
|
+
var _a, _b, _c, _d, _e, _f;
|
|
970
807
|
await decrypt();
|
|
971
808
|
// message failed to decrypt
|
|
972
|
-
if (msg.messageStubType ===
|
|
973
|
-
if (msg
|
|
809
|
+
if (msg.messageStubType === WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT) {
|
|
810
|
+
if (((_a = msg === null || msg === void 0 ? void 0 : msg.messageStubParameters) === null || _a === void 0 ? void 0 : _a[0]) === Utils_1.MISSING_KEYS_ERROR_TEXT) {
|
|
974
811
|
return sendMessageAck(node, Utils_1.NACK_REASONS.ParsingError);
|
|
975
812
|
}
|
|
976
|
-
const errorMessage = msg?.messageStubParameters?.[0] || '';
|
|
977
|
-
const isPreKeyError = errorMessage.includes('PreKey');
|
|
978
|
-
logger.debug(`[handleMessage] Attempting retry request for failed decryption`);
|
|
979
|
-
// Handle both pre-key and normal retries in single mutex
|
|
980
813
|
retryMutex.mutex(async () => {
|
|
981
|
-
|
|
982
|
-
if (!ws.isOpen) {
|
|
983
|
-
logger.debug({ node }, 'Connection closed, skipping retry');
|
|
984
|
-
return;
|
|
985
|
-
}
|
|
814
|
+
if (ws.isOpen) {
|
|
986
815
|
if ((0, WABinary_1.getBinaryNodeChild)(node, 'unavailable')) {
|
|
987
|
-
logger.debug('Message unavailable, skipping retry');
|
|
988
816
|
return;
|
|
989
817
|
}
|
|
990
|
-
// Handle pre-key errors with upload and delay
|
|
991
|
-
if (isPreKeyError) {
|
|
992
|
-
logger.info({ error: errorMessage }, 'PreKey error detected, uploading and retrying');
|
|
993
|
-
try {
|
|
994
|
-
logger.debug('Uploading pre-keys for error recovery');
|
|
995
|
-
await uploadPreKeys(5);
|
|
996
|
-
logger.debug('Waiting for server to process new pre-keys');
|
|
997
|
-
await (0, Utils_1.delay)(1000);
|
|
998
|
-
}
|
|
999
|
-
catch (uploadErr) {
|
|
1000
|
-
logger.error({ uploadErr }, 'Pre-key upload failed, proceeding with retry anyway');
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
818
|
const encNode = (0, WABinary_1.getBinaryNodeChild)(node, 'enc');
|
|
1004
819
|
await sendRetryRequest(node, !encNode);
|
|
1005
820
|
if (retryRequestDelayMs) {
|
|
1006
821
|
await (0, Utils_1.delay)(retryRequestDelayMs);
|
|
1007
822
|
}
|
|
1008
823
|
}
|
|
1009
|
-
|
|
1010
|
-
logger.
|
|
1011
|
-
// Still attempt retry even if pre-key upload failed
|
|
1012
|
-
try {
|
|
1013
|
-
const encNode = (0, WABinary_1.getBinaryNodeChild)(node, 'enc');
|
|
1014
|
-
await sendRetryRequest(node, !encNode);
|
|
1015
|
-
}
|
|
1016
|
-
catch (retryErr) {
|
|
1017
|
-
logger.error({ retryErr }, 'Failed to send retry after error handling');
|
|
1018
|
-
}
|
|
824
|
+
else {
|
|
825
|
+
logger.debug({ node }, 'connection closed, ignoring retry req');
|
|
1019
826
|
}
|
|
1020
827
|
});
|
|
1021
828
|
}
|
|
1022
829
|
else {
|
|
1023
830
|
// no type in the receipt => message delivered
|
|
1024
831
|
let type = undefined;
|
|
832
|
+
if ((_b = msg.key.participant) === null || _b === void 0 ? void 0 : _b.endsWith('@lid')) {
|
|
833
|
+
msg.key.participant = node.attrs.participant_pn || authState.creds.me.id;
|
|
834
|
+
}
|
|
835
|
+
if ((0, WABinary_1.isJidGroup)(msg.key.remoteJid) && ((_f = (_e = (_d = (_c = msg.message) === null || _c === void 0 ? void 0 : _c.extendedTextMessage) === null || _d === void 0 ? void 0 : _d.contextInfo) === null || _e === void 0 ? void 0 : _e.participant) === null || _f === void 0 ? void 0 : _f.endsWith('@lid'))) {
|
|
836
|
+
if (msg.message.extendedTextMessage.contextInfo) {
|
|
837
|
+
const metadata = await groupMetadata(msg.key.remoteJid);
|
|
838
|
+
const sender = msg.message.extendedTextMessage.contextInfo.participant;
|
|
839
|
+
const found = metadata.participants.find(p => p.id === sender);
|
|
840
|
+
msg.message.extendedTextMessage.contextInfo.participant = (found === null || found === void 0 ? void 0 : found.jid) || sender;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
if (!(0, WABinary_1.isJidGroup)(msg.key.remoteJid) && (0, WABinary_1.isLidUser)(msg.key.remoteJid)) {
|
|
844
|
+
msg.key.remoteJid = node.attrs.sender_pn || node.attrs.peer_recipient_pn;
|
|
845
|
+
}
|
|
1025
846
|
let participant = msg.key.participant;
|
|
1026
|
-
if (category === 'peer') {
|
|
1027
|
-
// special peer message
|
|
847
|
+
if (category === 'peer') { // special peer message
|
|
1028
848
|
type = 'peer_msg';
|
|
1029
849
|
}
|
|
1030
|
-
else if (msg.key.fromMe) {
|
|
1031
|
-
// message was sent by us from a different device
|
|
850
|
+
else if (msg.key.fromMe) { // message was sent by us from a different device
|
|
1032
851
|
type = 'sender';
|
|
1033
852
|
// need to specially handle this case
|
|
1034
|
-
if ((0, WABinary_1.
|
|
1035
|
-
participant = author;
|
|
853
|
+
if ((0, WABinary_1.isJidUser)(msg.key.remoteJid)) {
|
|
854
|
+
participant = author;
|
|
1036
855
|
}
|
|
1037
856
|
}
|
|
1038
857
|
else if (!sendActiveReceipts) {
|
|
@@ -1056,46 +875,75 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1056
875
|
logger.error({ error, node }, 'error in handling message');
|
|
1057
876
|
}
|
|
1058
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
|
+
};
|
|
1059
926
|
const handleCall = async (node) => {
|
|
1060
|
-
let status;
|
|
1061
927
|
const { attrs } = node;
|
|
1062
928
|
const [infoChild] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
|
|
1063
|
-
if (!infoChild) {
|
|
1064
|
-
throw new boom_1.Boom('Missing call info in call node');
|
|
1065
|
-
}
|
|
1066
929
|
const callId = infoChild.attrs['call-id'];
|
|
1067
930
|
const from = infoChild.attrs.from || infoChild.attrs['call-creator'];
|
|
1068
|
-
status = (0, Utils_1.getCallStatusFromNode)(infoChild);
|
|
1069
|
-
if ((0, WABinary_1.isLidUser)(from) && infoChild.tag === 'relaylatency') {
|
|
1070
|
-
const verify = await callOfferCache.get(callId);
|
|
1071
|
-
if (!verify) {
|
|
1072
|
-
status = 'offer';
|
|
1073
|
-
const callLid = {
|
|
1074
|
-
chatId: attrs.from,
|
|
1075
|
-
from,
|
|
1076
|
-
id: callId,
|
|
1077
|
-
date: new Date(+attrs.t * 1000),
|
|
1078
|
-
offline: !!attrs.offline,
|
|
1079
|
-
status
|
|
1080
|
-
};
|
|
1081
|
-
await callOfferCache.set(callId, callLid);
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
931
|
+
const status = (0, Utils_1.getCallStatusFromNode)(infoChild);
|
|
1084
932
|
const call = {
|
|
1085
933
|
chatId: attrs.from,
|
|
1086
934
|
from,
|
|
1087
935
|
id: callId,
|
|
1088
936
|
date: new Date(+attrs.t * 1000),
|
|
1089
937
|
offline: !!attrs.offline,
|
|
1090
|
-
status
|
|
938
|
+
status,
|
|
1091
939
|
};
|
|
1092
940
|
if (status === 'offer') {
|
|
1093
941
|
call.isVideo = !!(0, WABinary_1.getBinaryNodeChild)(infoChild, 'video');
|
|
1094
942
|
call.isGroup = infoChild.attrs.type === 'group' || !!infoChild.attrs['group-jid'];
|
|
1095
943
|
call.groupJid = infoChild.attrs['group-jid'];
|
|
1096
|
-
|
|
944
|
+
callOfferCache.set(call.id, call);
|
|
1097
945
|
}
|
|
1098
|
-
const existingCall =
|
|
946
|
+
const existingCall = callOfferCache.get(call.id);
|
|
1099
947
|
// use existing call info to populate this event
|
|
1100
948
|
if (existingCall) {
|
|
1101
949
|
call.isVideo = existingCall.isVideo;
|
|
@@ -1103,26 +951,34 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1103
951
|
}
|
|
1104
952
|
// delete data once call has ended
|
|
1105
953
|
if (status === 'reject' || status === 'accept' || status === 'timeout' || status === 'terminate') {
|
|
1106
|
-
|
|
954
|
+
callOfferCache.del(call.id);
|
|
1107
955
|
}
|
|
1108
956
|
ev.emit('call', [call]);
|
|
1109
957
|
await sendMessageAck(node);
|
|
1110
958
|
};
|
|
1111
959
|
const handleBadAck = async ({ attrs }) => {
|
|
1112
|
-
const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id };
|
|
1113
|
-
//
|
|
1114
|
-
//
|
|
1115
|
-
//
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
960
|
+
const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id, 'server_id': attrs === null || attrs === void 0 ? void 0 : attrs.server_id };
|
|
961
|
+
// current hypothesis is that if pash is sent in the ack
|
|
962
|
+
// it means -- the message hasn't reached all devices yet
|
|
963
|
+
// we'll retry sending the message here
|
|
964
|
+
if (attrs.phash) {
|
|
965
|
+
logger.info({ attrs }, 'received phash in ack, resending message...');
|
|
966
|
+
const cacheKey = `${key.remoteJid}:${key.id}`;
|
|
967
|
+
if ((msgRetryCache.get(cacheKey) || 0) >= maxMsgRetryCount) {
|
|
968
|
+
logger.warn({ attrs }, 'reached max retry count, not sending message again');
|
|
969
|
+
msgRetryCache.del(cacheKey);
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
const retryCount = msgRetryCache.get(cacheKey) || 0;
|
|
973
|
+
const msg = await getMessage(key);
|
|
974
|
+
if (msg) {
|
|
975
|
+
await relayMessage(key.remoteJid, msg, { messageId: key.id, useUserDevicesCache: false });
|
|
976
|
+
msgRetryCache.set(cacheKey, retryCount + 1);
|
|
977
|
+
}
|
|
978
|
+
else {
|
|
979
|
+
logger.warn({ attrs }, 'could not send message again, as it was not found');
|
|
980
|
+
}
|
|
981
|
+
}
|
|
1126
982
|
// error in acknowledgement,
|
|
1127
983
|
// device could not display the message
|
|
1128
984
|
if (attrs.error) {
|
|
@@ -1132,7 +988,9 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1132
988
|
key,
|
|
1133
989
|
update: {
|
|
1134
990
|
status: Types_1.WAMessageStatus.ERROR,
|
|
1135
|
-
messageStubParameters: [
|
|
991
|
+
messageStubParameters: [
|
|
992
|
+
attrs.error
|
|
993
|
+
]
|
|
1136
994
|
}
|
|
1137
995
|
}
|
|
1138
996
|
]);
|
|
@@ -1145,7 +1003,8 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1145
1003
|
await execTask();
|
|
1146
1004
|
ev.flush();
|
|
1147
1005
|
function execTask() {
|
|
1148
|
-
return exec(node, false)
|
|
1006
|
+
return exec(node, false)
|
|
1007
|
+
.catch(err => onUnexpectedError(err, identifier));
|
|
1149
1008
|
}
|
|
1150
1009
|
};
|
|
1151
1010
|
const makeOfflineNodeProcessor = () => {
|
|
@@ -1203,12 +1062,10 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1203
1062
|
processNode('notification', node, 'handling notification', handleNotification);
|
|
1204
1063
|
});
|
|
1205
1064
|
ws.on('CB:ack,class:message', (node) => {
|
|
1206
|
-
handleBadAck(node)
|
|
1065
|
+
handleBadAck(node)
|
|
1066
|
+
.catch(error => onUnexpectedError(error, 'handling bad ack'));
|
|
1207
1067
|
});
|
|
1208
1068
|
ev.on('call', ([call]) => {
|
|
1209
|
-
if (!call) {
|
|
1210
|
-
return;
|
|
1211
|
-
}
|
|
1212
1069
|
// missed call + group call notification message generation
|
|
1213
1070
|
if (call.status === 'timeout' || (call.status === 'offer' && call.isGroup)) {
|
|
1214
1071
|
const msg = {
|
|
@@ -1217,13 +1074,11 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1217
1074
|
id: call.id,
|
|
1218
1075
|
fromMe: false
|
|
1219
1076
|
},
|
|
1220
|
-
messageTimestamp: (0, Utils_1.unixTimestampSeconds)(call.date)
|
|
1077
|
+
messageTimestamp: (0, Utils_1.unixTimestampSeconds)(call.date),
|
|
1221
1078
|
};
|
|
1222
1079
|
if (call.status === 'timeout') {
|
|
1223
1080
|
if (call.isGroup) {
|
|
1224
|
-
msg.messageStubType = call.isVideo
|
|
1225
|
-
? Types_1.WAMessageStubType.CALL_MISSED_GROUP_VIDEO
|
|
1226
|
-
: Types_1.WAMessageStubType.CALL_MISSED_GROUP_VOICE;
|
|
1081
|
+
msg.messageStubType = call.isVideo ? Types_1.WAMessageStubType.CALL_MISSED_GROUP_VIDEO : Types_1.WAMessageStubType.CALL_MISSED_GROUP_VOICE;
|
|
1227
1082
|
}
|
|
1228
1083
|
else {
|
|
1229
1084
|
msg.messageStubType = call.isVideo ? Types_1.WAMessageStubType.CALL_MISSED_VIDEO : Types_1.WAMessageStubType.CALL_MISSED_VOICE;
|
|
@@ -1232,7 +1087,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1232
1087
|
else {
|
|
1233
1088
|
msg.message = { call: { callKey: Buffer.from(call.id) } };
|
|
1234
1089
|
}
|
|
1235
|
-
const protoMsg =
|
|
1090
|
+
const protoMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
|
|
1236
1091
|
upsertMessage(protoMsg, call.offline ? 'append' : 'notify');
|
|
1237
1092
|
}
|
|
1238
1093
|
});
|
|
@@ -1247,9 +1102,9 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1247
1102
|
sendMessageAck,
|
|
1248
1103
|
sendRetryRequest,
|
|
1249
1104
|
rejectCall,
|
|
1105
|
+
offerCall,
|
|
1250
1106
|
fetchMessageHistory,
|
|
1251
1107
|
requestPlaceholderResend,
|
|
1252
|
-
messageRetryManager
|
|
1253
1108
|
};
|
|
1254
1109
|
};
|
|
1255
1110
|
exports.makeMessagesRecvSocket = makeMessagesRecvSocket;
|