@periskope/baileys 6.7.19 → 7.0.0-alpha-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/WAProto/GenerateStatics.sh +2 -2
- package/WAProto/index.d.ts +2793 -45578
- package/WAProto/index.js +19344 -147065
- package/lib/Defaults/index.d.ts +7 -1
- package/lib/Defaults/index.d.ts.map +1 -1
- package/lib/Defaults/index.js +11 -4
- package/lib/Defaults/index.js.map +1 -1
- package/lib/Signal/Group/group_cipher.d.ts +0 -1
- package/lib/Signal/Group/group_cipher.d.ts.map +1 -1
- package/lib/Signal/Group/group_cipher.js +28 -36
- package/lib/Signal/Group/group_cipher.js.map +1 -1
- package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -1
- package/lib/Signal/Group/sender-key-distribution-message.js +1 -1
- package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -1
- package/lib/Signal/Group/sender-key-message.d.ts.map +1 -1
- package/lib/Signal/Group/sender-key-message.js +1 -1
- package/lib/Signal/Group/sender-key-message.js.map +1 -1
- package/lib/Signal/Group/sender-key-state.d.ts.map +1 -1
- package/lib/Signal/Group/sender-key-state.js +6 -1
- package/lib/Signal/Group/sender-key-state.js.map +1 -1
- package/lib/Signal/libsignal.d.ts +5 -1
- package/lib/Signal/libsignal.d.ts.map +1 -1
- package/lib/Signal/libsignal.js +211 -38
- package/lib/Signal/libsignal.js.map +1 -1
- package/lib/Signal/lid-mapping.d.ts +14 -3
- package/lib/Signal/lid-mapping.d.ts.map +1 -0
- package/lib/Signal/lid-mapping.js +53 -65
- package/lib/Signal/lid-mapping.js.map +1 -0
- package/lib/Socket/business.d.ts +25 -13
- package/lib/Socket/business.d.ts.map +1 -1
- package/lib/Socket/business.js +122 -1
- package/lib/Socket/business.js.map +1 -1
- package/lib/Socket/chats.d.ts +14 -8
- package/lib/Socket/chats.d.ts.map +1 -1
- package/lib/Socket/chats.js +54 -21
- package/lib/Socket/chats.js.map +1 -1
- package/lib/Socket/communities.d.ts +24 -10
- package/lib/Socket/communities.d.ts.map +1 -1
- package/lib/Socket/communities.js +45 -1
- package/lib/Socket/communities.js.map +1 -1
- package/lib/Socket/groups.d.ts +13 -8
- package/lib/Socket/groups.d.ts.map +1 -1
- package/lib/Socket/groups.js +12 -11
- package/lib/Socket/groups.js.map +1 -1
- package/lib/Socket/index.d.ts +24 -10
- package/lib/Socket/index.d.ts.map +1 -1
- package/lib/Socket/messages-recv.d.ts +18 -10
- package/lib/Socket/messages-recv.d.ts.map +1 -1
- package/lib/Socket/messages-recv.js +383 -220
- package/lib/Socket/messages-recv.js.map +1 -1
- package/lib/Socket/messages-send.d.ts +19 -10
- package/lib/Socket/messages-send.d.ts.map +1 -1
- package/lib/Socket/messages-send.js +454 -62
- package/lib/Socket/messages-send.js.map +1 -1
- package/lib/Socket/newsletter.d.ts +15 -11
- package/lib/Socket/newsletter.d.ts.map +1 -1
- package/lib/Socket/newsletter.js +3 -1
- package/lib/Socket/newsletter.js.map +1 -1
- package/lib/Socket/socket.d.ts +9 -2
- package/lib/Socket/socket.d.ts.map +1 -1
- package/lib/Socket/socket.js +266 -70
- package/lib/Socket/socket.js.map +1 -1
- package/lib/Types/Auth.d.ts +2 -1
- package/lib/Types/Auth.d.ts.map +1 -1
- package/lib/Types/Bussines.d.ts +25 -0
- package/lib/Types/Bussines.d.ts.map +1 -0
- package/lib/Types/Bussines.js +2 -0
- package/lib/Types/Bussines.js.map +1 -0
- package/lib/Types/Chat.d.ts +5 -0
- package/lib/Types/Chat.d.ts.map +1 -1
- package/lib/Types/Chat.js.map +1 -1
- package/lib/Types/Contact.d.ts +4 -4
- package/lib/Types/Contact.d.ts.map +1 -1
- package/lib/Types/Events.d.ts +2 -2
- package/lib/Types/Events.d.ts.map +1 -1
- package/lib/Types/GroupMetadata.d.ts +6 -4
- package/lib/Types/GroupMetadata.d.ts.map +1 -1
- package/lib/Types/Message.d.ts +28 -7
- package/lib/Types/Message.d.ts.map +1 -1
- package/lib/Types/Message.js +5 -1
- package/lib/Types/Message.js.map +1 -1
- package/lib/Types/Signal.d.ts +24 -0
- package/lib/Types/Signal.d.ts.map +1 -1
- package/lib/Types/Socket.d.ts +9 -1
- package/lib/Types/Socket.d.ts.map +1 -1
- package/lib/Utils/auth-utils.d.ts.map +1 -1
- package/lib/Utils/auth-utils.js +362 -78
- package/lib/Utils/auth-utils.js.map +1 -1
- package/lib/Utils/chat-utils.d.ts +2 -2
- package/lib/Utils/chat-utils.d.ts.map +1 -1
- package/lib/Utils/chat-utils.js +20 -3
- package/lib/Utils/chat-utils.js.map +1 -1
- package/lib/Utils/decode-wa-message.d.ts +10 -0
- package/lib/Utils/decode-wa-message.d.ts.map +1 -1
- package/lib/Utils/decode-wa-message.js +84 -13
- package/lib/Utils/decode-wa-message.js.map +1 -1
- package/lib/Utils/event-buffer.d.ts +0 -1
- package/lib/Utils/event-buffer.d.ts.map +1 -1
- package/lib/Utils/event-buffer.js +48 -4
- package/lib/Utils/event-buffer.js.map +1 -1
- package/lib/Utils/generics.d.ts.map +1 -1
- package/lib/Utils/generics.js +17 -8
- package/lib/Utils/generics.js.map +1 -1
- package/lib/Utils/history.d.ts.map +1 -1
- package/lib/Utils/history.js +1 -2
- package/lib/Utils/history.js.map +1 -1
- package/lib/Utils/index.d.ts +1 -0
- package/lib/Utils/index.d.ts.map +1 -1
- package/lib/Utils/index.js +1 -0
- package/lib/Utils/index.js.map +1 -1
- package/lib/Utils/message-retry-manager.d.ts +82 -0
- package/lib/Utils/message-retry-manager.d.ts.map +1 -0
- package/lib/Utils/message-retry-manager.js +149 -0
- package/lib/Utils/message-retry-manager.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +3 -2
- package/lib/Utils/messages-media.d.ts.map +1 -1
- package/lib/Utils/messages-media.js +4 -1
- package/lib/Utils/messages-media.js.map +1 -1
- package/lib/Utils/messages.d.ts.map +1 -1
- package/lib/Utils/messages.js +35 -15
- package/lib/Utils/messages.js.map +1 -1
- package/lib/Utils/process-message.d.ts +3 -2
- package/lib/Utils/process-message.d.ts.map +1 -1
- package/lib/Utils/process-message.js +13 -2
- package/lib/Utils/process-message.js.map +1 -1
- package/lib/Utils/use-multi-file-auth-state.js +1 -1
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -1
- package/lib/Utils/validate-connection.d.ts.map +1 -1
- package/lib/Utils/validate-connection.js +5 -4
- package/lib/Utils/validate-connection.js.map +1 -1
- package/lib/WABinary/jid-utils.d.ts +6 -5
- package/lib/WABinary/jid-utils.d.ts.map +1 -1
- package/lib/WABinary/jid-utils.js +11 -5
- package/lib/WABinary/jid-utils.js.map +1 -1
- package/lib/WAM/encode.d.ts.map +1 -1
- package/lib/WAM/encode.js +0 -1
- package/lib/WAM/encode.js.map +1 -1
- package/package.json +12 -8
|
@@ -2,21 +2,26 @@ import NodeCache from '@cacheable/node-cache';
|
|
|
2
2
|
import { Boom } from '@hapi/boom';
|
|
3
3
|
import { proto } from '../../WAProto/index.js';
|
|
4
4
|
import { DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
|
|
5
|
-
import {
|
|
5
|
+
import { WAMessageAddressingMode } from '../Types/index.js';
|
|
6
|
+
import { aggregateMessageKeysNotFromMe, assertMediaContent, bindWaitForEvent, decryptMediaRetryData, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils/index.js';
|
|
6
7
|
import { getUrlInfo } from '../Utils/link-preview.js';
|
|
7
|
-
import {
|
|
8
|
+
import { makeKeyedMutex } from '../Utils/make-mutex.js';
|
|
9
|
+
import { areJidsSameUser, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, isPnUser, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, transferDevice } from '../WABinary/index.js';
|
|
8
10
|
import { USyncQuery, USyncUser } from '../WAUSync/index.js';
|
|
9
|
-
import { makeGroupsSocket } from './groups.js';
|
|
10
11
|
import { makeNewsletterSocket } from './newsletter.js';
|
|
11
12
|
export const makeMessagesSocket = (config) => {
|
|
12
|
-
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: axiosOptions, patchMessageBeforeSending, cachedGroupMetadata } = config;
|
|
13
|
-
const sock = makeNewsletterSocket(
|
|
13
|
+
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: axiosOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache, maxMsgRetryCount } = config;
|
|
14
|
+
const sock = makeNewsletterSocket(config);
|
|
14
15
|
const { ev, authState, processingMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral } = sock;
|
|
15
16
|
const userDevicesCache = config.userDevicesCache ||
|
|
16
17
|
new NodeCache({
|
|
17
18
|
stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
|
|
18
19
|
useClones: false
|
|
19
20
|
});
|
|
21
|
+
// Initialize message retry manager if enabled
|
|
22
|
+
const messageRetryManager = enableRecentMessageCache ? new MessageRetryManager(logger, maxMsgRetryCount) : null;
|
|
23
|
+
// Prevent race conditions in Signal session encryption by user
|
|
24
|
+
const encryptionMutex = makeKeyedMutex();
|
|
20
25
|
let mediaConn;
|
|
21
26
|
const refreshMediaConn = async (forceGet = false) => {
|
|
22
27
|
const media = await mediaConn;
|
|
@@ -65,7 +70,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
65
70
|
if (isReadReceipt) {
|
|
66
71
|
node.attrs.t = unixTimestampSeconds().toString();
|
|
67
72
|
}
|
|
68
|
-
if (type === 'sender' &&
|
|
73
|
+
if (type === 'sender' && isPnUser(jid)) {
|
|
69
74
|
node.attrs.recipient = jid;
|
|
70
75
|
node.attrs.to = participant;
|
|
71
76
|
}
|
|
@@ -108,6 +113,34 @@ export const makeMessagesSocket = (config) => {
|
|
|
108
113
|
const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self';
|
|
109
114
|
await sendReceipts(keys, readType);
|
|
110
115
|
};
|
|
116
|
+
/**
|
|
117
|
+
* Deduplicate JIDs when both LID and PN versions exist for same user
|
|
118
|
+
* Prefers LID over PN to maintain single encryption layer
|
|
119
|
+
*/
|
|
120
|
+
const deduplicateLidPnJids = (jids) => {
|
|
121
|
+
const lidUsers = new Set();
|
|
122
|
+
const filteredJids = [];
|
|
123
|
+
// Collect all LID users
|
|
124
|
+
for (const jid of jids) {
|
|
125
|
+
if (jid.includes('@lid')) {
|
|
126
|
+
const user = jidDecode(jid)?.user;
|
|
127
|
+
if (user)
|
|
128
|
+
lidUsers.add(user);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Filter out PN versions when LID exists
|
|
132
|
+
for (const jid of jids) {
|
|
133
|
+
if (jid.includes('@s.whatsapp.net')) {
|
|
134
|
+
const user = jidDecode(jid)?.user;
|
|
135
|
+
if (user && lidUsers.has(user)) {
|
|
136
|
+
logger.debug({ jid }, 'Skipping PN - LID version exists');
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
filteredJids.push(jid);
|
|
141
|
+
}
|
|
142
|
+
return filteredJids;
|
|
143
|
+
};
|
|
111
144
|
/** Fetch all the devices we've to send a message to */
|
|
112
145
|
const getUSyncDevices = async (jids, useCache, ignoreZeroDevices) => {
|
|
113
146
|
const deviceResults = [];
|
|
@@ -115,14 +148,33 @@ export const makeMessagesSocket = (config) => {
|
|
|
115
148
|
logger.debug('not using cache for devices');
|
|
116
149
|
}
|
|
117
150
|
const toFetch = [];
|
|
118
|
-
|
|
151
|
+
// Deduplicate and normalize JIDs
|
|
152
|
+
jids = deduplicateLidPnJids(Array.from(new Set(jids)));
|
|
119
153
|
for (let jid of jids) {
|
|
120
|
-
const
|
|
154
|
+
const decoded = jidDecode(jid);
|
|
155
|
+
const user = decoded?.user;
|
|
156
|
+
const device = decoded?.device;
|
|
157
|
+
const isExplicitDevice = typeof device === 'number' && device >= 0;
|
|
158
|
+
// Handle explicit device JIDs directly
|
|
159
|
+
if (isExplicitDevice && user) {
|
|
160
|
+
deviceResults.push({
|
|
161
|
+
user,
|
|
162
|
+
device,
|
|
163
|
+
wireJid: jid // Preserve exact JID format for wire protocol
|
|
164
|
+
});
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
// For user JIDs, normalize and prepare for device enumeration
|
|
121
168
|
jid = jidNormalizedUser(jid);
|
|
122
169
|
if (useCache) {
|
|
123
170
|
const devices = userDevicesCache.get(user);
|
|
124
171
|
if (devices) {
|
|
125
|
-
|
|
172
|
+
const isLidJid = jid.includes('@lid');
|
|
173
|
+
const devicesWithWire = devices.map(d => ({
|
|
174
|
+
...d,
|
|
175
|
+
wireJid: isLidJid ? jidEncode(d.user, 'lid', d.device) : jidEncode(d.user, 's.whatsapp.net', d.device)
|
|
176
|
+
}));
|
|
177
|
+
deviceResults.push(...devicesWithWire);
|
|
126
178
|
logger.trace({ user }, 'using cache for devices');
|
|
127
179
|
}
|
|
128
180
|
else {
|
|
@@ -136,6 +188,14 @@ export const makeMessagesSocket = (config) => {
|
|
|
136
188
|
if (!toFetch.length) {
|
|
137
189
|
return deviceResults;
|
|
138
190
|
}
|
|
191
|
+
const requestedLidUsers = new Set();
|
|
192
|
+
for (const jid of toFetch) {
|
|
193
|
+
if (jid.includes('@lid')) {
|
|
194
|
+
const user = jidDecode(jid)?.user;
|
|
195
|
+
if (user)
|
|
196
|
+
requestedLidUsers.add(user);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
139
199
|
const query = new USyncQuery().withContext('message').withDeviceProtocol();
|
|
140
200
|
for (const jid of toFetch) {
|
|
141
201
|
query.withUser(new USyncUser().withId(jid));
|
|
@@ -147,7 +207,26 @@ export const makeMessagesSocket = (config) => {
|
|
|
147
207
|
for (const item of extracted) {
|
|
148
208
|
deviceMap[item.user] = deviceMap[item.user] || [];
|
|
149
209
|
deviceMap[item.user]?.push(item);
|
|
150
|
-
|
|
210
|
+
}
|
|
211
|
+
// Process each user's devices as a group for bulk LID migration
|
|
212
|
+
for (const [user, userDevices] of Object.entries(deviceMap)) {
|
|
213
|
+
const isLidUser = requestedLidUsers.has(user);
|
|
214
|
+
// Process all devices for this user
|
|
215
|
+
for (const item of userDevices) {
|
|
216
|
+
const finalWireJid = isLidUser
|
|
217
|
+
? jidEncode(user, 'lid', item.device)
|
|
218
|
+
: jidEncode(item.user, 's.whatsapp.net', item.device);
|
|
219
|
+
deviceResults.push({
|
|
220
|
+
...item,
|
|
221
|
+
wireJid: finalWireJid
|
|
222
|
+
});
|
|
223
|
+
logger.debug({
|
|
224
|
+
user: item.user,
|
|
225
|
+
device: item.device,
|
|
226
|
+
finalWireJid,
|
|
227
|
+
usedLid: isLidUser
|
|
228
|
+
}, 'Processed device with LID priority');
|
|
229
|
+
}
|
|
151
230
|
}
|
|
152
231
|
for (const key in deviceMap) {
|
|
153
232
|
userDevicesCache.set(key, deviceMap[key]);
|
|
@@ -155,24 +234,176 @@ export const makeMessagesSocket = (config) => {
|
|
|
155
234
|
}
|
|
156
235
|
return deviceResults;
|
|
157
236
|
};
|
|
237
|
+
// Helper to check if JID has migrated LID session
|
|
238
|
+
const checkForMigratedLidSession = async (jid) => {
|
|
239
|
+
if (!jid.includes('@s.whatsapp.net'))
|
|
240
|
+
return false;
|
|
241
|
+
const lidMapping = signalRepository.getLIDMappingStore();
|
|
242
|
+
const lidForPN = await lidMapping.getLIDForPN(jid);
|
|
243
|
+
if (!lidForPN?.includes('@lid'))
|
|
244
|
+
return false;
|
|
245
|
+
const lidSignalId = signalRepository.jidToSignalProtocolAddress(lidForPN);
|
|
246
|
+
const lidSessions = await authState.keys.get('session', [lidSignalId]);
|
|
247
|
+
return !!lidSessions[lidSignalId];
|
|
248
|
+
};
|
|
158
249
|
const assertSessions = async (jids, force) => {
|
|
159
250
|
let didFetchNewSession = false;
|
|
160
|
-
|
|
251
|
+
const jidsRequiringFetch = [];
|
|
252
|
+
// Apply same deduplication as in getUSyncDevices
|
|
253
|
+
jids = deduplicateLidPnJids(jids);
|
|
161
254
|
if (force) {
|
|
162
|
-
|
|
255
|
+
// Check which sessions are missing (with LID migration check)
|
|
256
|
+
const addrs = jids.map(jid => signalRepository.jidToSignalProtocolAddress(jid));
|
|
257
|
+
const sessions = await authState.keys.get('session', addrs);
|
|
258
|
+
// Helper to check session for a JID
|
|
259
|
+
const checkJidSession = async (jid) => {
|
|
260
|
+
const signalId = signalRepository.jidToSignalProtocolAddress(jid);
|
|
261
|
+
let hasSession = !!sessions[signalId];
|
|
262
|
+
// Check for migrated LID session if PN session missing
|
|
263
|
+
if (!hasSession) {
|
|
264
|
+
hasSession = await checkForMigratedLidSession(jid);
|
|
265
|
+
if (hasSession) {
|
|
266
|
+
logger.debug({ jid }, 'Found migrated LID session during force assert, skipping PN fetch');
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// Add to fetch list if no session exists
|
|
270
|
+
if (!hasSession) {
|
|
271
|
+
if (jid.includes('@lid')) {
|
|
272
|
+
logger.debug({ jid }, 'No LID session found, will create new LID session');
|
|
273
|
+
}
|
|
274
|
+
jidsRequiringFetch.push(jid);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
// Process all JIDs
|
|
278
|
+
for (const jid of jids) {
|
|
279
|
+
await checkJidSession(jid);
|
|
280
|
+
}
|
|
163
281
|
}
|
|
164
282
|
else {
|
|
283
|
+
const lidMapping = signalRepository.getLIDMappingStore();
|
|
165
284
|
const addrs = jids.map(jid => signalRepository.jidToSignalProtocolAddress(jid));
|
|
166
285
|
const sessions = await authState.keys.get('session', addrs);
|
|
286
|
+
// Group JIDs by user for bulk migration
|
|
287
|
+
const userGroups = new Map();
|
|
167
288
|
for (const jid of jids) {
|
|
168
|
-
const
|
|
169
|
-
if (!
|
|
170
|
-
|
|
289
|
+
const user = jidNormalizedUser(jid);
|
|
290
|
+
if (!userGroups.has(user)) {
|
|
291
|
+
userGroups.set(user, []);
|
|
292
|
+
}
|
|
293
|
+
userGroups.get(user).push(jid);
|
|
294
|
+
}
|
|
295
|
+
// Helper to check LID mapping for a user
|
|
296
|
+
const checkUserLidMapping = async (user, userJids) => {
|
|
297
|
+
if (!userJids.some(jid => jid.includes('@s.whatsapp.net'))) {
|
|
298
|
+
return { shouldMigrate: false, lidForPN: undefined };
|
|
299
|
+
}
|
|
300
|
+
try {
|
|
301
|
+
const mapping = await lidMapping.getLIDForPN(user);
|
|
302
|
+
if (mapping?.includes('@lid')) {
|
|
303
|
+
logger.debug({ user, lidForPN: mapping, deviceCount: userJids.length }, 'User has LID mapping - preparing bulk migration');
|
|
304
|
+
return { shouldMigrate: true, lidForPN: mapping };
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
logger.debug({ user, error }, 'Failed to check LID mapping for user');
|
|
309
|
+
}
|
|
310
|
+
return { shouldMigrate: false, lidForPN: undefined };
|
|
311
|
+
};
|
|
312
|
+
// Helper to migrate a single device
|
|
313
|
+
const migrateDeviceToLid = async (jid, lidForPN) => {
|
|
314
|
+
if (!jid.includes('@s.whatsapp.net'))
|
|
315
|
+
return;
|
|
316
|
+
try {
|
|
317
|
+
const lidWithDevice = transferDevice(jid, lidForPN);
|
|
318
|
+
await signalRepository.migrateSession(jid, lidWithDevice);
|
|
319
|
+
logger.debug({ fromJid: jid, toJid: lidWithDevice }, 'Migrated device session to LID');
|
|
320
|
+
// Delete PN session after successful migration
|
|
321
|
+
try {
|
|
322
|
+
await signalRepository.deleteSession(jid);
|
|
323
|
+
logger.debug({ deletedPNSession: jid }, 'Deleted PN session after migration');
|
|
324
|
+
}
|
|
325
|
+
catch (deleteError) {
|
|
326
|
+
logger.warn({ jid, error: deleteError }, 'Failed to delete PN session');
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
catch (migrationError) {
|
|
330
|
+
logger.warn({ jid, error: migrationError }, 'Failed to migrate device session');
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
// Process each user group for potential bulk LID migration
|
|
334
|
+
for (const [user, userJids] of userGroups) {
|
|
335
|
+
const mappingResult = await checkUserLidMapping(user, userJids);
|
|
336
|
+
const shouldMigrateUser = mappingResult.shouldMigrate;
|
|
337
|
+
const lidForPN = mappingResult.lidForPN;
|
|
338
|
+
// Migrate all devices for this user if LID mapping exists
|
|
339
|
+
if (shouldMigrateUser && lidForPN) {
|
|
340
|
+
// Migrate each device individually
|
|
341
|
+
for (const jid of userJids) {
|
|
342
|
+
await migrateDeviceToLid(jid, lidForPN);
|
|
343
|
+
}
|
|
344
|
+
logger.info({
|
|
345
|
+
user,
|
|
346
|
+
lidMapping: lidForPN,
|
|
347
|
+
deviceCount: userJids.length
|
|
348
|
+
}, 'Completed migration attempt for user devices');
|
|
349
|
+
}
|
|
350
|
+
// Helper to check session for migrated user
|
|
351
|
+
const checkMigratedSession = async (jid) => {
|
|
352
|
+
const signalId = signalRepository.jidToSignalProtocolAddress(jid);
|
|
353
|
+
let hasSession = !!sessions[signalId];
|
|
354
|
+
let jidToFetch = jid;
|
|
355
|
+
// Check if we should use migrated LID session instead
|
|
356
|
+
if (shouldMigrateUser && lidForPN && jid.includes('@s.whatsapp.net')) {
|
|
357
|
+
const originalDecoded = jidDecode(jid);
|
|
358
|
+
const deviceId = originalDecoded?.device || 0;
|
|
359
|
+
const lidDecoded = jidDecode(lidForPN);
|
|
360
|
+
const lidWithDevice = jidEncode(lidDecoded?.user, 'lid', deviceId);
|
|
361
|
+
// Check if LID session exists
|
|
362
|
+
const lidSignalId = signalRepository.jidToSignalProtocolAddress(lidWithDevice);
|
|
363
|
+
const lidSessions = await authState.keys.get('session', [lidSignalId]);
|
|
364
|
+
hasSession = !!lidSessions[lidSignalId];
|
|
365
|
+
jidToFetch = lidWithDevice;
|
|
366
|
+
if (hasSession) {
|
|
367
|
+
logger.debug({ originalJid: jid, lidJid: lidWithDevice }, '✅ Found bulk-migrated LID session');
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// Add to fetch list if no session exists
|
|
371
|
+
if (!hasSession) {
|
|
372
|
+
jidsRequiringFetch.push(jidToFetch);
|
|
373
|
+
logger.debug({ jid: jidToFetch, originalJid: jid !== jidToFetch ? jid : undefined }, 'Adding to session fetch list');
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
// Now check which sessions need to be fetched for this user
|
|
377
|
+
for (const jid of userJids) {
|
|
378
|
+
await checkMigratedSession(jid);
|
|
171
379
|
}
|
|
172
380
|
}
|
|
173
381
|
}
|
|
174
382
|
if (jidsRequiringFetch.length) {
|
|
175
383
|
logger.debug({ jidsRequiringFetch }, 'fetching sessions');
|
|
384
|
+
// DEBUG: Check if there are PN versions of LID users being fetched
|
|
385
|
+
const lidUsersBeingFetched = new Set();
|
|
386
|
+
const pnUsersBeingFetched = new Set();
|
|
387
|
+
for (const jid of jidsRequiringFetch) {
|
|
388
|
+
const user = jidDecode(jid)?.user;
|
|
389
|
+
if (user) {
|
|
390
|
+
if (jid.includes('@lid')) {
|
|
391
|
+
lidUsersBeingFetched.add(user);
|
|
392
|
+
}
|
|
393
|
+
else if (jid.includes('@s.whatsapp.net')) {
|
|
394
|
+
pnUsersBeingFetched.add(user);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
// Find overlaps
|
|
399
|
+
const overlapping = Array.from(pnUsersBeingFetched).filter(user => lidUsersBeingFetched.has(user));
|
|
400
|
+
if (overlapping.length > 0) {
|
|
401
|
+
logger.warn({
|
|
402
|
+
overlapping,
|
|
403
|
+
lidUsersBeingFetched: Array.from(lidUsersBeingFetched),
|
|
404
|
+
pnUsersBeingFetched: Array.from(pnUsersBeingFetched)
|
|
405
|
+
}, 'Fetching both LID and PN sessions for same users');
|
|
406
|
+
}
|
|
176
407
|
const result = await query({
|
|
177
408
|
tag: 'iq',
|
|
178
409
|
attrs: {
|
|
@@ -216,43 +447,132 @@ export const makeMessagesSocket = (config) => {
|
|
|
216
447
|
});
|
|
217
448
|
return msgId;
|
|
218
449
|
};
|
|
219
|
-
const createParticipantNodes = async (jids, message, extraAttrs) => {
|
|
450
|
+
const createParticipantNodes = async (jids, message, extraAttrs, dsmMessage) => {
|
|
220
451
|
let patched = await patchMessageBeforeSending(message, jids);
|
|
221
452
|
if (!Array.isArray(patched)) {
|
|
222
453
|
patched = jids ? jids.map(jid => ({ recipientJid: jid, ...patched })) : [patched];
|
|
223
454
|
}
|
|
224
455
|
let shouldIncludeDeviceIdentity = false;
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
456
|
+
const meId = authState.creds.me.id;
|
|
457
|
+
const meLid = authState.creds.me?.lid;
|
|
458
|
+
const meLidUser = meLid ? jidDecode(meLid)?.user : null;
|
|
459
|
+
const devicesByUser = new Map();
|
|
460
|
+
for (const patchedMessageWithJid of patched) {
|
|
461
|
+
const { recipientJid: wireJid, ...patchedMessage } = patchedMessageWithJid;
|
|
462
|
+
if (!wireJid)
|
|
463
|
+
continue;
|
|
464
|
+
// Extract user from JID for grouping
|
|
465
|
+
const decoded = jidDecode(wireJid);
|
|
466
|
+
const user = decoded?.user;
|
|
467
|
+
if (!user)
|
|
468
|
+
continue;
|
|
469
|
+
if (!devicesByUser.has(user)) {
|
|
470
|
+
devicesByUser.set(user, []);
|
|
471
|
+
}
|
|
472
|
+
devicesByUser.get(user).push({ recipientJid: wireJid, patchedMessage });
|
|
473
|
+
}
|
|
474
|
+
// Process each user's devices sequentially, but different users in parallel
|
|
475
|
+
const userEncryptionPromises = Array.from(devicesByUser.entries()).map(([user, userDevices]) => encryptionMutex.mutex(user, async () => {
|
|
476
|
+
logger.debug({ user, deviceCount: userDevices.length }, 'Acquiring encryption lock for user devices');
|
|
477
|
+
const userNodes = [];
|
|
478
|
+
// Helper to get encryption JID with LID migration
|
|
479
|
+
const getEncryptionJid = async (wireJid) => {
|
|
480
|
+
if (!wireJid.includes('@s.whatsapp.net'))
|
|
481
|
+
return wireJid;
|
|
482
|
+
try {
|
|
483
|
+
const lidMapping = signalRepository.getLIDMappingStore();
|
|
484
|
+
const lidForPN = await lidMapping.getLIDForPN(wireJid);
|
|
485
|
+
if (!lidForPN?.includes('@lid'))
|
|
486
|
+
return wireJid;
|
|
487
|
+
// Preserve device ID from original wire JID
|
|
488
|
+
const wireDecoded = jidDecode(wireJid);
|
|
489
|
+
const deviceId = wireDecoded?.device || 0;
|
|
490
|
+
const lidDecoded = jidDecode(lidForPN);
|
|
491
|
+
const lidWithDevice = jidEncode(lidDecoded?.user, 'lid', deviceId);
|
|
492
|
+
// Migrate session to LID for unified encryption layer
|
|
493
|
+
try {
|
|
494
|
+
await signalRepository.migrateSession(wireJid, lidWithDevice);
|
|
495
|
+
const recipientUser = jidNormalizedUser(wireJid);
|
|
496
|
+
const ownPnUser = jidNormalizedUser(meId);
|
|
497
|
+
const isOwnDevice = recipientUser === ownPnUser;
|
|
498
|
+
logger.info({ wireJid, lidWithDevice, isOwnDevice }, 'Migrated to LID encryption');
|
|
499
|
+
// Delete PN session after successful migration
|
|
500
|
+
try {
|
|
501
|
+
await signalRepository.deleteSession(wireJid);
|
|
502
|
+
logger.debug({ deletedPNSession: wireJid }, 'Deleted PN session');
|
|
503
|
+
}
|
|
504
|
+
catch (deleteError) {
|
|
505
|
+
logger.warn({ wireJid, error: deleteError }, 'Failed to delete PN session');
|
|
506
|
+
}
|
|
507
|
+
return lidWithDevice;
|
|
247
508
|
}
|
|
248
|
-
|
|
509
|
+
catch (migrationError) {
|
|
510
|
+
logger.warn({ wireJid, error: migrationError }, 'Failed to migrate session');
|
|
511
|
+
return wireJid;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
catch (error) {
|
|
515
|
+
logger.debug({ wireJid, error }, 'Failed to check LID mapping');
|
|
516
|
+
return wireJid;
|
|
517
|
+
}
|
|
249
518
|
};
|
|
250
|
-
|
|
519
|
+
// Encrypt to this user's devices sequentially to prevent session corruption
|
|
520
|
+
for (const { recipientJid: wireJid, patchedMessage } of userDevices) {
|
|
521
|
+
// DSM logic: Use DSM for own other devices (following whatsmeow implementation)
|
|
522
|
+
let messageToEncrypt = patchedMessage;
|
|
523
|
+
if (dsmMessage) {
|
|
524
|
+
const { user: targetUser } = jidDecode(wireJid);
|
|
525
|
+
const { user: ownPnUser } = jidDecode(meId);
|
|
526
|
+
const ownLidUser = meLidUser;
|
|
527
|
+
// Check if this is our device (same user, different device)
|
|
528
|
+
const isOwnUser = targetUser === ownPnUser || (ownLidUser && targetUser === ownLidUser);
|
|
529
|
+
// Exclude exact sender device (whatsmeow: if jid == ownJID || jid == ownLID { continue })
|
|
530
|
+
const isExactSenderDevice = wireJid === meId || (authState.creds.me?.lid && wireJid === authState.creds.me.lid);
|
|
531
|
+
if (isOwnUser && !isExactSenderDevice) {
|
|
532
|
+
messageToEncrypt = dsmMessage;
|
|
533
|
+
logger.debug({ wireJid, targetUser }, 'Using DSM for own device');
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
const bytes = encodeWAMessage(messageToEncrypt);
|
|
537
|
+
// Get encryption JID with LID migration
|
|
538
|
+
const encryptionJid = await getEncryptionJid(wireJid);
|
|
539
|
+
// ENCRYPT: Use the determined encryption identity (prefers migrated LID)
|
|
540
|
+
const { type, ciphertext } = await signalRepository.encryptMessage({
|
|
541
|
+
jid: encryptionJid, // Unified encryption layer (LID when available)
|
|
542
|
+
data: bytes
|
|
543
|
+
});
|
|
544
|
+
if (type === 'pkmsg') {
|
|
545
|
+
shouldIncludeDeviceIdentity = true;
|
|
546
|
+
}
|
|
547
|
+
const node = {
|
|
548
|
+
tag: 'to',
|
|
549
|
+
attrs: { jid: wireJid }, // Always use original wire identity in envelope
|
|
550
|
+
content: [
|
|
551
|
+
{
|
|
552
|
+
tag: 'enc',
|
|
553
|
+
attrs: {
|
|
554
|
+
v: '2',
|
|
555
|
+
type,
|
|
556
|
+
...(extraAttrs || {})
|
|
557
|
+
},
|
|
558
|
+
content: ciphertext
|
|
559
|
+
}
|
|
560
|
+
]
|
|
561
|
+
};
|
|
562
|
+
userNodes.push(node);
|
|
563
|
+
}
|
|
564
|
+
logger.debug({ user, nodesCreated: userNodes.length }, 'Releasing encryption lock for user devices');
|
|
565
|
+
return userNodes;
|
|
251
566
|
}));
|
|
567
|
+
// Wait for all users to complete (users are processed in parallel)
|
|
568
|
+
const userNodesArrays = await Promise.all(userEncryptionPromises);
|
|
569
|
+
const nodes = userNodesArrays.flat();
|
|
252
570
|
return { nodes, shouldIncludeDeviceIdentity };
|
|
253
571
|
};
|
|
254
572
|
const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList }) => {
|
|
255
573
|
const meId = authState.creds.me.id;
|
|
574
|
+
const meLid = authState.creds.me?.lid;
|
|
575
|
+
// ADDRESSING CONSISTENCY: Keep envelope addressing as user provided, handle LID migration in encryption
|
|
256
576
|
let shouldIncludeDeviceIdentity = false;
|
|
257
577
|
const { user, server } = jidDecode(jid);
|
|
258
578
|
const statusJid = 'status@broadcast';
|
|
@@ -260,11 +580,22 @@ export const makeMessagesSocket = (config) => {
|
|
|
260
580
|
const isStatus = jid === statusJid;
|
|
261
581
|
const isLid = server === 'lid';
|
|
262
582
|
const isNewsletter = server === 'newsletter';
|
|
583
|
+
// Keep user's original JID choice for envelope addressing
|
|
584
|
+
const finalJid = jid;
|
|
585
|
+
// ADDRESSING CONSISTENCY: Match own identity to conversation context
|
|
586
|
+
let ownId = meId;
|
|
587
|
+
if (isLid && meLid) {
|
|
588
|
+
ownId = meLid;
|
|
589
|
+
logger.debug({ to: jid, ownId }, 'Using LID identity for @lid conversation');
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
logger.debug({ to: jid, ownId }, 'Using PN identity for @s.whatsapp.net conversation');
|
|
593
|
+
}
|
|
263
594
|
msgId = msgId || generateMessageIDV2(sock.user?.id);
|
|
264
595
|
useUserDevicesCache = useUserDevicesCache !== false;
|
|
265
596
|
useCachedGroupMetadata = useCachedGroupMetadata !== false && !isStatus;
|
|
266
597
|
const participants = [];
|
|
267
|
-
const destinationJid = !isStatus ?
|
|
598
|
+
const destinationJid = !isStatus ? finalJid : statusJid;
|
|
268
599
|
const binaryNodeContent = [];
|
|
269
600
|
const devices = [];
|
|
270
601
|
const meMsg = {
|
|
@@ -283,7 +614,11 @@ export const makeMessagesSocket = (config) => {
|
|
|
283
614
|
additionalAttributes = { ...additionalAttributes, device_fanout: 'false' };
|
|
284
615
|
}
|
|
285
616
|
const { user, device } = jidDecode(participant.jid);
|
|
286
|
-
devices.push({
|
|
617
|
+
devices.push({
|
|
618
|
+
user,
|
|
619
|
+
device,
|
|
620
|
+
wireJid: participant.jid // Use the participant JID as wire JID
|
|
621
|
+
});
|
|
287
622
|
}
|
|
288
623
|
await authState.keys.transaction(async () => {
|
|
289
624
|
const mediaType = getMediaType(message);
|
|
@@ -342,9 +677,10 @@ export const makeMessagesSocket = (config) => {
|
|
|
342
677
|
participantsList.push(...statusJidList);
|
|
343
678
|
}
|
|
344
679
|
if (!isStatus) {
|
|
680
|
+
const groupAddressingMode = groupData?.addressingMode || (isLid ? WAMessageAddressingMode.LID : WAMessageAddressingMode.PN);
|
|
345
681
|
additionalAttributes = {
|
|
346
682
|
...additionalAttributes,
|
|
347
|
-
addressing_mode:
|
|
683
|
+
addressing_mode: groupAddressingMode
|
|
348
684
|
};
|
|
349
685
|
}
|
|
350
686
|
const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false);
|
|
@@ -355,19 +691,24 @@ export const makeMessagesSocket = (config) => {
|
|
|
355
691
|
throw new Boom('Per-jid patching is not supported in groups');
|
|
356
692
|
}
|
|
357
693
|
const bytes = encodeWAMessage(patched);
|
|
694
|
+
// This should match the group's addressing mode and conversation context
|
|
695
|
+
const groupAddressingMode = groupData?.addressingMode || (isLid ? 'lid' : 'pn');
|
|
696
|
+
const groupSenderIdentity = groupAddressingMode === 'lid' && meLid ? meLid : meId;
|
|
358
697
|
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({
|
|
359
698
|
group: destinationJid,
|
|
360
699
|
data: bytes,
|
|
361
|
-
meId
|
|
700
|
+
meId: groupSenderIdentity
|
|
362
701
|
});
|
|
363
702
|
const senderKeyJids = [];
|
|
364
703
|
// ensure a connection is established with every device
|
|
365
|
-
for (const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
704
|
+
for (const device of devices) {
|
|
705
|
+
// This preserves the LID migration results from getUSyncDevices
|
|
706
|
+
const deviceJid = device.wireJid;
|
|
707
|
+
const hasKey = !!senderKeyMap[deviceJid];
|
|
708
|
+
if (!hasKey || !!participant) {
|
|
709
|
+
senderKeyJids.push(deviceJid);
|
|
369
710
|
// store that this person has had the sender keys sent to them
|
|
370
|
-
senderKeyMap[
|
|
711
|
+
senderKeyMap[deviceJid] = true;
|
|
371
712
|
}
|
|
372
713
|
}
|
|
373
714
|
// if there are some participants with whom the session has not been established
|
|
@@ -393,23 +734,54 @@ export const makeMessagesSocket = (config) => {
|
|
|
393
734
|
await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } });
|
|
394
735
|
}
|
|
395
736
|
else {
|
|
396
|
-
const { user:
|
|
737
|
+
const { user: ownUser } = jidDecode(ownId);
|
|
397
738
|
if (!participant) {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
739
|
+
const targetUserServer = isLid ? 'lid' : 's.whatsapp.net';
|
|
740
|
+
devices.push({
|
|
741
|
+
user,
|
|
742
|
+
device: 0,
|
|
743
|
+
wireJid: jidEncode(user, targetUserServer, 0)
|
|
744
|
+
});
|
|
745
|
+
// Own user matches conversation addressing mode
|
|
746
|
+
if (user !== ownUser) {
|
|
747
|
+
const ownUserServer = isLid ? 'lid' : 's.whatsapp.net';
|
|
748
|
+
const ownUserForAddressing = isLid && meLid ? jidDecode(meLid).user : jidDecode(meId).user;
|
|
749
|
+
devices.push({
|
|
750
|
+
user: ownUserForAddressing,
|
|
751
|
+
device: 0,
|
|
752
|
+
wireJid: jidEncode(ownUserForAddressing, ownUserServer, 0)
|
|
753
|
+
});
|
|
401
754
|
}
|
|
402
755
|
if (additionalAttributes?.['category'] !== 'peer') {
|
|
403
|
-
|
|
404
|
-
devices.
|
|
756
|
+
// Clear placeholders and enumerate actual devices
|
|
757
|
+
devices.length = 0;
|
|
758
|
+
// Use conversation-appropriate sender identity
|
|
759
|
+
const senderIdentity = isLid && meLid
|
|
760
|
+
? jidEncode(jidDecode(meLid)?.user, 'lid', undefined)
|
|
761
|
+
: jidEncode(jidDecode(meId)?.user, 's.whatsapp.net', undefined);
|
|
762
|
+
// Enumerate devices for sender and target with consistent addressing
|
|
763
|
+
const sessionDevices = await getUSyncDevices([senderIdentity, jid], false, false);
|
|
764
|
+
devices.push(...sessionDevices);
|
|
765
|
+
logger.debug({
|
|
766
|
+
deviceCount: devices.length,
|
|
767
|
+
devices: devices.map(d => `${d.user}:${d.device}@${jidDecode(d.wireJid)?.server}`)
|
|
768
|
+
}, 'Device enumeration complete with unified addressing');
|
|
405
769
|
}
|
|
406
770
|
}
|
|
407
771
|
const allJids = [];
|
|
408
772
|
const meJids = [];
|
|
409
773
|
const otherJids = [];
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
774
|
+
const { user: mePnUser } = jidDecode(meId);
|
|
775
|
+
const { user: meLidUser } = meLid ? jidDecode(meLid) : { user: null };
|
|
776
|
+
for (const { user, wireJid } of devices) {
|
|
777
|
+
const isExactSenderDevice = wireJid === meId || (meLid && wireJid === meLid);
|
|
778
|
+
if (isExactSenderDevice) {
|
|
779
|
+
logger.debug({ wireJid, meId, meLid }, 'Skipping exact sender device (whatsmeow pattern)');
|
|
780
|
+
continue;
|
|
781
|
+
}
|
|
782
|
+
// Check if this is our device (could match either PN or LID user)
|
|
783
|
+
const isMe = user === mePnUser || (meLidUser && user === meLidUser);
|
|
784
|
+
const jid = wireJid;
|
|
413
785
|
if (isMe) {
|
|
414
786
|
meJids.push(jid);
|
|
415
787
|
}
|
|
@@ -418,10 +790,11 @@ export const makeMessagesSocket = (config) => {
|
|
|
418
790
|
}
|
|
419
791
|
allJids.push(jid);
|
|
420
792
|
}
|
|
421
|
-
await assertSessions(
|
|
793
|
+
await assertSessions([...otherJids, ...meJids], false);
|
|
422
794
|
const [{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 }, { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }] = await Promise.all([
|
|
423
|
-
|
|
424
|
-
createParticipantNodes(
|
|
795
|
+
// For own devices: use DSM if available (1:1 chats only)
|
|
796
|
+
createParticipantNodes(meJids, meMsg || message, extraAttrs),
|
|
797
|
+
createParticipantNodes(otherJids, message, extraAttrs, meMsg)
|
|
425
798
|
]);
|
|
426
799
|
participants.push(...meNodes);
|
|
427
800
|
participants.push(...otherNodes);
|
|
@@ -446,6 +819,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
446
819
|
tag: 'message',
|
|
447
820
|
attrs: {
|
|
448
821
|
id: msgId,
|
|
822
|
+
to: destinationJid,
|
|
449
823
|
type: getMessageType(message),
|
|
450
824
|
...(additionalAttributes || {})
|
|
451
825
|
},
|
|
@@ -485,13 +859,20 @@ export const makeMessagesSocket = (config) => {
|
|
|
485
859
|
}
|
|
486
860
|
logger.debug({ msgId }, `sending message to ${participants.length} devices`);
|
|
487
861
|
await sendNode(stanza);
|
|
488
|
-
|
|
862
|
+
// Add message to retry cache if enabled
|
|
863
|
+
if (messageRetryManager && !participant) {
|
|
864
|
+
messageRetryManager.addRecentMessage(destinationJid, msgId, message);
|
|
865
|
+
}
|
|
866
|
+
}, meId);
|
|
489
867
|
return msgId;
|
|
490
868
|
};
|
|
491
869
|
const getMessageType = (message) => {
|
|
492
870
|
if (message.pollCreationMessage || message.pollCreationMessageV2 || message.pollCreationMessageV3) {
|
|
493
871
|
return 'poll';
|
|
494
872
|
}
|
|
873
|
+
if (message.eventMessage) {
|
|
874
|
+
return 'event';
|
|
875
|
+
}
|
|
495
876
|
return 'text';
|
|
496
877
|
};
|
|
497
878
|
const getMediaType = (message) => {
|
|
@@ -583,6 +964,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
583
964
|
sendPeerDataOperationMessage,
|
|
584
965
|
createParticipantNodes,
|
|
585
966
|
getUSyncDevices,
|
|
967
|
+
messageRetryManager,
|
|
586
968
|
updateMediaMessage: async (message) => {
|
|
587
969
|
const content = assertMediaContent(message.message);
|
|
588
970
|
const mediaKey = content.mediaKey;
|
|
@@ -654,12 +1036,14 @@ export const makeMessagesSocket = (config) => {
|
|
|
654
1036
|
}),
|
|
655
1037
|
//TODO: CACHE
|
|
656
1038
|
getProfilePicUrl: sock.profilePictureUrl,
|
|
1039
|
+
getCallLink: sock.createCallLink,
|
|
657
1040
|
upload: waUploadToServer,
|
|
658
1041
|
mediaCache: config.mediaCache,
|
|
659
1042
|
options: config.options,
|
|
660
1043
|
messageId: generateMessageIDV2(sock.user?.id),
|
|
661
1044
|
...options
|
|
662
1045
|
});
|
|
1046
|
+
const isEventMsg = 'event' in content && !!content.event;
|
|
663
1047
|
const isDeleteMsg = 'delete' in content && !!content.delete;
|
|
664
1048
|
const isEditMsg = 'edit' in content && !!content.edit;
|
|
665
1049
|
const isPinMsg = 'pin' in content && !!content.pin;
|
|
@@ -690,6 +1074,14 @@ export const makeMessagesSocket = (config) => {
|
|
|
690
1074
|
}
|
|
691
1075
|
});
|
|
692
1076
|
}
|
|
1077
|
+
else if (isEventMsg) {
|
|
1078
|
+
additionalNodes.push({
|
|
1079
|
+
tag: 'meta',
|
|
1080
|
+
attrs: {
|
|
1081
|
+
event_type: 'creation'
|
|
1082
|
+
}
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
693
1085
|
if ('cachedGroupMetadata' in options) {
|
|
694
1086
|
console.warn('cachedGroupMetadata in sendMessage are deprecated, now cachedGroupMetadata is part of the socket config.');
|
|
695
1087
|
}
|