davexbaileys 2.5.21 → 2.5.23

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.
@@ -0,0 +1,430 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractCommunityMetadata = exports.makeCommunitiesSocket = void 0;
4
+ const WAProto_1 = require("../../WAProto");
5
+ const Types_1 = require("../Types");
6
+ const Utils_1 = require("../Utils");
7
+ const WABinary_1 = require("../WABinary");
8
+ const business_1 = require("./business");
9
+
10
+ const makeCommunitiesSocket = (config) => {
11
+ const sock = (0, business_1.makeBusinessSocket)(config);
12
+ const { authState, ev, query, upsertMessage } = sock;
13
+
14
+ const communityQuery = async (jid, type, content) => query({
15
+ tag: 'iq',
16
+ attrs: {
17
+ type,
18
+ xmlns: 'w:g2',
19
+ to: jid
20
+ },
21
+ content
22
+ });
23
+
24
+ const communityMetadata = async (jid) => {
25
+ const result = await communityQuery(jid, 'get', [{ tag: 'query', attrs: { request: 'interactive' } }]);
26
+ return (0, exports.extractCommunityMetadata)(result);
27
+ };
28
+
29
+ const communityFetchAllParticipating = async () => {
30
+ const result = await query({
31
+ tag: 'iq',
32
+ attrs: {
33
+ to: '@g.us',
34
+ xmlns: 'w:g2',
35
+ type: 'get'
36
+ },
37
+ content: [
38
+ {
39
+ tag: 'participating',
40
+ attrs: {},
41
+ content: [
42
+ { tag: 'participants', attrs: {} },
43
+ { tag: 'description', attrs: {} }
44
+ ]
45
+ }
46
+ ]
47
+ });
48
+ const data = {};
49
+ const communitiesChild = (0, WABinary_1.getBinaryNodeChild)(result, 'communities');
50
+ if (communitiesChild) {
51
+ const communities = (0, WABinary_1.getBinaryNodeChildren)(communitiesChild, 'community');
52
+ for (const communityNode of communities) {
53
+ const meta = (0, exports.extractCommunityMetadata)({
54
+ tag: 'result',
55
+ attrs: {},
56
+ content: [communityNode]
57
+ });
58
+ data[meta.id] = meta;
59
+ }
60
+ }
61
+ sock.ev.emit('groups.update', Object.values(data));
62
+ return data;
63
+ };
64
+
65
+ const Optional = {
66
+ empty: () => null,
67
+ of: (value) => (value !== null ? { value } : null)
68
+ };
69
+
70
+ async function parseGroupResult(node) {
71
+ const groupNode = (0, WABinary_1.getBinaryNodeChild)(node, 'group');
72
+ if (groupNode) {
73
+ try {
74
+ const metadata = await sock.groupMetadata(`${groupNode.attrs.id}@g.us`);
75
+ return metadata ? metadata : Optional.empty();
76
+ }
77
+ catch (error) {
78
+ console.error('Error parsing group metadata:', error);
79
+ return Optional.empty();
80
+ }
81
+ }
82
+ return Optional.empty();
83
+ }
84
+
85
+ sock.ws.on('CB:ib,,dirty', async (node) => {
86
+ const { attrs } = (0, WABinary_1.getBinaryNodeChild)(node, 'dirty');
87
+ if (attrs.type !== 'communities') {
88
+ return;
89
+ }
90
+ await communityFetchAllParticipating();
91
+ await sock.cleanDirtyBits('groups');
92
+ });
93
+
94
+ return {
95
+ ...sock,
96
+ communityMetadata,
97
+ communityCreate: async (subject, body) => {
98
+ const descriptionId = (0, Utils_1.generateMessageID)().substring(0, 12);
99
+ const result = await communityQuery('@g.us', 'set', [
100
+ {
101
+ tag: 'create',
102
+ attrs: { subject },
103
+ content: [
104
+ {
105
+ tag: 'description',
106
+ attrs: { id: descriptionId },
107
+ content: [
108
+ {
109
+ tag: 'body',
110
+ attrs: {},
111
+ content: Buffer.from(body || '', 'utf-8')
112
+ }
113
+ ]
114
+ },
115
+ {
116
+ tag: 'parent',
117
+ attrs: { default_membership_approval_mode: 'request_required' }
118
+ },
119
+ {
120
+ tag: 'allow_non_admin_sub_group_creation',
121
+ attrs: {}
122
+ },
123
+ {
124
+ tag: 'create_general_chat',
125
+ attrs: {}
126
+ }
127
+ ]
128
+ }
129
+ ]);
130
+ return await parseGroupResult(result);
131
+ },
132
+ communityCreateGroup: async (subject, participants, parentCommunityJid) => {
133
+ const key = (0, Utils_1.generateMessageIDV2)();
134
+ const result = await communityQuery('@g.us', 'set', [
135
+ {
136
+ tag: 'create',
137
+ attrs: {
138
+ subject,
139
+ key
140
+ },
141
+ content: [
142
+ ...participants.map(jid => ({
143
+ tag: 'participant',
144
+ attrs: { jid }
145
+ })),
146
+ { tag: 'linked_parent', attrs: { jid: parentCommunityJid } }
147
+ ]
148
+ }
149
+ ]);
150
+ return await parseGroupResult(result);
151
+ },
152
+ communityLeave: async (id) => {
153
+ await communityQuery('@g.us', 'set', [
154
+ {
155
+ tag: 'leave',
156
+ attrs: {},
157
+ content: [{ tag: 'community', attrs: { id } }]
158
+ }
159
+ ]);
160
+ },
161
+ communityUpdateSubject: async (jid, subject) => {
162
+ await communityQuery(jid, 'set', [
163
+ {
164
+ tag: 'subject',
165
+ attrs: {},
166
+ content: Buffer.from(subject, 'utf-8')
167
+ }
168
+ ]);
169
+ },
170
+ communityLinkGroup: async (groupJid, parentCommunityJid) => {
171
+ await communityQuery(parentCommunityJid, 'set', [
172
+ {
173
+ tag: 'links',
174
+ attrs: {},
175
+ content: [
176
+ {
177
+ tag: 'link',
178
+ attrs: { link_type: 'sub_group' },
179
+ content: [{ tag: 'group', attrs: { jid: groupJid } }]
180
+ }
181
+ ]
182
+ }
183
+ ]);
184
+ },
185
+ communityUnlinkGroup: async (groupJid, parentCommunityJid) => {
186
+ await communityQuery(parentCommunityJid, 'set', [
187
+ {
188
+ tag: 'unlink',
189
+ attrs: { unlink_type: 'sub_group' },
190
+ content: [{ tag: 'group', attrs: { jid: groupJid } }]
191
+ }
192
+ ]);
193
+ },
194
+ communityFetchLinkedGroups: async (jid) => {
195
+ let communityJid = jid;
196
+ let isCommunity = false;
197
+ const metadata = await sock.groupMetadata(jid);
198
+ if (metadata.linkedParent) {
199
+ communityJid = metadata.linkedParent;
200
+ }
201
+ else {
202
+ isCommunity = true;
203
+ }
204
+ const result = await communityQuery(communityJid, 'get', [{ tag: 'sub_groups', attrs: {} }]);
205
+ const linkedGroupsData = [];
206
+ const subGroupsNode = (0, WABinary_1.getBinaryNodeChild)(result, 'sub_groups');
207
+ if (subGroupsNode) {
208
+ const groupNodes = (0, WABinary_1.getBinaryNodeChildren)(subGroupsNode, 'group');
209
+ for (const groupNode of groupNodes) {
210
+ linkedGroupsData.push({
211
+ id: groupNode.attrs.id ? (0, WABinary_1.jidEncode)(groupNode.attrs.id, 'g.us') : undefined,
212
+ subject: groupNode.attrs.subject || '',
213
+ creation: groupNode.attrs.creation ? Number(groupNode.attrs.creation) : undefined,
214
+ owner: groupNode.attrs.creator ? (0, WABinary_1.jidNormalizedUser)(groupNode.attrs.creator) : undefined,
215
+ size: groupNode.attrs.size ? Number(groupNode.attrs.size) : undefined
216
+ });
217
+ }
218
+ }
219
+ return {
220
+ communityJid,
221
+ isCommunity,
222
+ linkedGroups: linkedGroupsData
223
+ };
224
+ },
225
+ communityRequestParticipantsList: async (jid) => {
226
+ const result = await communityQuery(jid, 'get', [
227
+ {
228
+ tag: 'membership_approval_requests',
229
+ attrs: {}
230
+ }
231
+ ]);
232
+ const node = (0, WABinary_1.getBinaryNodeChild)(result, 'membership_approval_requests');
233
+ const participants = (0, WABinary_1.getBinaryNodeChildren)(node, 'membership_approval_request');
234
+ return participants.map(v => v.attrs);
235
+ },
236
+ communityRequestParticipantsUpdate: async (jid, participants, action) => {
237
+ const result = await communityQuery(jid, 'set', [
238
+ {
239
+ tag: 'membership_requests_action',
240
+ attrs: {},
241
+ content: [
242
+ {
243
+ tag: action,
244
+ attrs: {},
245
+ content: participants.map(jid => ({
246
+ tag: 'participant',
247
+ attrs: { jid }
248
+ }))
249
+ }
250
+ ]
251
+ }
252
+ ]);
253
+ const node = (0, WABinary_1.getBinaryNodeChild)(result, 'membership_requests_action');
254
+ const nodeAction = (0, WABinary_1.getBinaryNodeChild)(node, action);
255
+ const participantsAffected = (0, WABinary_1.getBinaryNodeChildren)(nodeAction, 'participant');
256
+ return participantsAffected.map(p => {
257
+ return { status: p.attrs.error || '200', jid: p.attrs.jid };
258
+ });
259
+ },
260
+ communityParticipantsUpdate: async (jid, participants, action) => {
261
+ const result = await communityQuery(jid, 'set', [
262
+ {
263
+ tag: action,
264
+ attrs: action === 'remove' ? { linked_groups: 'true' } : {},
265
+ content: participants.map(jid => ({
266
+ tag: 'participant',
267
+ attrs: { jid }
268
+ }))
269
+ }
270
+ ]);
271
+ const node = (0, WABinary_1.getBinaryNodeChild)(result, action);
272
+ const participantsAffected = (0, WABinary_1.getBinaryNodeChildren)(node, 'participant');
273
+ return participantsAffected.map(p => {
274
+ return { status: p.attrs.error || '200', jid: p.attrs.jid, content: p };
275
+ });
276
+ },
277
+ communityUpdateDescription: async (jid, description) => {
278
+ const metadata = await communityMetadata(jid);
279
+ const prev = metadata.descId ?? null;
280
+ await communityQuery(jid, 'set', [
281
+ {
282
+ tag: 'description',
283
+ attrs: {
284
+ ...(description ? { id: (0, Utils_1.generateMessageID)() } : { delete: 'true' }),
285
+ ...(prev ? { prev } : {})
286
+ },
287
+ content: description
288
+ ? [{ tag: 'body', attrs: {}, content: Buffer.from(description, 'utf-8') }]
289
+ : undefined
290
+ }
291
+ ]);
292
+ },
293
+ communityInviteCode: async (jid) => {
294
+ const result = await communityQuery(jid, 'get', [{ tag: 'invite', attrs: {} }]);
295
+ const inviteNode = (0, WABinary_1.getBinaryNodeChild)(result, 'invite');
296
+ return inviteNode === null || inviteNode === void 0 ? void 0 : inviteNode.attrs.code;
297
+ },
298
+ communityRevokeInvite: async (jid) => {
299
+ const result = await communityQuery(jid, 'set', [{ tag: 'invite', attrs: {} }]);
300
+ const inviteNode = (0, WABinary_1.getBinaryNodeChild)(result, 'invite');
301
+ return inviteNode === null || inviteNode === void 0 ? void 0 : inviteNode.attrs.code;
302
+ },
303
+ communityAcceptInvite: async (code) => {
304
+ const results = await communityQuery('@g.us', 'set', [{ tag: 'invite', attrs: { code } }]);
305
+ const result = (0, WABinary_1.getBinaryNodeChild)(results, 'community');
306
+ return result === null || result === void 0 ? void 0 : result.attrs.jid;
307
+ },
308
+ communityRevokeInviteV4: async (communityJid, invitedJid) => {
309
+ const result = await communityQuery(communityJid, 'set', [
310
+ { tag: 'revoke', attrs: {}, content: [{ tag: 'participant', attrs: { jid: invitedJid } }] }
311
+ ]);
312
+ return !!result;
313
+ },
314
+ communityAcceptInviteV4: ev.createBufferedFunction(async (key, inviteMessage) => {
315
+ key = typeof key === 'string' ? { remoteJid: key } : key;
316
+ const results = await communityQuery(inviteMessage.groupJid, 'set', [
317
+ {
318
+ tag: 'accept',
319
+ attrs: {
320
+ code: inviteMessage.inviteCode,
321
+ expiration: inviteMessage.inviteExpiration.toString(),
322
+ admin: key.remoteJid
323
+ }
324
+ }
325
+ ]);
326
+ if (key.id) {
327
+ inviteMessage = WAProto_1.proto.Message.GroupInviteMessage.fromObject(inviteMessage);
328
+ inviteMessage.inviteExpiration = 0;
329
+ inviteMessage.inviteCode = '';
330
+ ev.emit('messages.update', [
331
+ {
332
+ key,
333
+ update: {
334
+ message: {
335
+ groupInviteMessage: inviteMessage
336
+ }
337
+ }
338
+ }
339
+ ]);
340
+ }
341
+ await upsertMessage({
342
+ key: {
343
+ remoteJid: inviteMessage.groupJid,
344
+ id: (0, Utils_1.generateMessageIDV2)(sock.user === null || sock.user === void 0 ? void 0 : sock.user.id),
345
+ fromMe: false,
346
+ participant: key.remoteJid
347
+ },
348
+ messageStubType: Types_1.WAMessageStubType.GROUP_PARTICIPANT_ADD,
349
+ messageStubParameters: [JSON.stringify(authState.creds.me)],
350
+ participant: key.remoteJid,
351
+ messageTimestamp: (0, Utils_1.unixTimestampSeconds)()
352
+ }, 'notify');
353
+ return results.attrs.from;
354
+ }),
355
+ communityGetInviteInfo: async (code) => {
356
+ const results = await communityQuery('@g.us', 'get', [{ tag: 'invite', attrs: { code } }]);
357
+ return (0, exports.extractCommunityMetadata)(results);
358
+ },
359
+ communityToggleEphemeral: async (jid, ephemeralExpiration) => {
360
+ const content = ephemeralExpiration
361
+ ? { tag: 'ephemeral', attrs: { expiration: ephemeralExpiration.toString() } }
362
+ : { tag: 'not_ephemeral', attrs: {} };
363
+ await communityQuery(jid, 'set', [content]);
364
+ },
365
+ communitySettingUpdate: async (jid, setting) => {
366
+ await communityQuery(jid, 'set', [{ tag: setting, attrs: {} }]);
367
+ },
368
+ communityMemberAddMode: async (jid, mode) => {
369
+ await communityQuery(jid, 'set', [{ tag: 'member_add_mode', attrs: {}, content: mode }]);
370
+ },
371
+ communityJoinApprovalMode: async (jid, mode) => {
372
+ await communityQuery(jid, 'set', [
373
+ {
374
+ tag: 'membership_approval_mode',
375
+ attrs: {},
376
+ content: [{ tag: 'community_join', attrs: { state: mode } }]
377
+ }
378
+ ]);
379
+ },
380
+ communityFetchAllParticipating
381
+ };
382
+ };
383
+ exports.makeCommunitiesSocket = makeCommunitiesSocket;
384
+
385
+ const extractCommunityMetadata = (result) => {
386
+ const community = (0, WABinary_1.getBinaryNodeChild)(result, 'community');
387
+ const descChild = (0, WABinary_1.getBinaryNodeChild)(community, 'description');
388
+ let desc;
389
+ let descId;
390
+ if (descChild) {
391
+ desc = (0, WABinary_1.getBinaryNodeChildString)(descChild, 'body');
392
+ descId = descChild.attrs.id;
393
+ }
394
+ const communityId = (community.attrs.id || '').includes('@')
395
+ ? community.attrs.id
396
+ : (0, WABinary_1.jidEncode)(community.attrs.id || '', 'g.us');
397
+ const eph = (0, WABinary_1.getBinaryNodeChild)(community, 'ephemeral');
398
+ const ephExpiration = eph === null || eph === void 0 ? void 0 : eph.attrs.expiration;
399
+ const memberAddMode = (0, WABinary_1.getBinaryNodeChildString)(community, 'member_add_mode') === 'all_member_add';
400
+ const metadata = {
401
+ id: communityId,
402
+ subject: community.attrs.subject || '',
403
+ subjectOwner: community.attrs.s_o,
404
+ subjectTime: Number(community.attrs.s_t || 0),
405
+ size: (0, WABinary_1.getBinaryNodeChildren)(community, 'participant').length,
406
+ creation: Number(community.attrs.creation || 0),
407
+ owner: community.attrs.creator ? (0, WABinary_1.jidNormalizedUser)(community.attrs.creator) : undefined,
408
+ desc,
409
+ descId,
410
+ linkedParent: ((0, WABinary_1.getBinaryNodeChild)(community, 'linked_parent') || {}).attrs
411
+ ? (0, WABinary_1.getBinaryNodeChild)(community, 'linked_parent').attrs.jid || undefined
412
+ : undefined,
413
+ restrict: !!(0, WABinary_1.getBinaryNodeChild)(community, 'locked'),
414
+ announce: !!(0, WABinary_1.getBinaryNodeChild)(community, 'announcement'),
415
+ isCommunity: !!(0, WABinary_1.getBinaryNodeChild)(community, 'parent'),
416
+ isCommunityAnnounce: !!(0, WABinary_1.getBinaryNodeChild)(community, 'default_sub_community'),
417
+ joinApprovalMode: !!(0, WABinary_1.getBinaryNodeChild)(community, 'membership_approval_mode'),
418
+ memberAddMode,
419
+ participants: (0, WABinary_1.getBinaryNodeChildren)(community, 'participant').map(({ attrs }) => {
420
+ return {
421
+ id: attrs.jid,
422
+ admin: (attrs.type || null)
423
+ };
424
+ }),
425
+ ephemeralDuration: ephExpiration ? +ephExpiration : undefined,
426
+ addressingMode: (0, WABinary_1.getBinaryNodeChildString)(community, 'addressing_mode')
427
+ };
428
+ return metadata;
429
+ };
430
+ exports.extractCommunityMetadata = extractCommunityMetadata;
@@ -368,11 +368,13 @@ const extractGroupMetadata = (result) => {
368
368
  let descId;
369
369
  let descOwner;
370
370
  let descOwnerJid;
371
+ let descOwnerUsername;
371
372
  let descTime;
372
373
  if (descChild) {
373
374
  desc = (0, WABinary_1.getBinaryNodeChildString)(descChild, 'body');
374
375
  descOwner = descChild.attrs.participant ? (0, WABinary_1.jidNormalizedUser)(descChild.attrs.participant) : undefined;
375
376
  descOwnerJid = descChild.attrs.participant_pn ? (0, WABinary_1.jidNormalizedUser)(descChild.attrs.participant_pn) : undefined;
377
+ descOwnerUsername = descChild.attrs.participant_username || undefined;
376
378
  descTime = +descChild.attrs.t;
377
379
  descId = descChild.attrs.id;
378
380
  }
@@ -385,15 +387,18 @@ const extractGroupMetadata = (result) => {
385
387
  subject: group.attrs.subject,
386
388
  subjectOwner: group.attrs.s_o,
387
389
  subjectOwnerJid: group.attrs.s_o_pn,
390
+ subjectOwnerUsername: group.attrs.s_o_username || undefined,
388
391
  subjectTime: +group.attrs.s_t,
389
392
  size: (0, WABinary_1.getBinaryNodeChildren)(group, 'participant').length,
390
393
  creation: +group.attrs.creation,
391
394
  owner: group.attrs.creator ? (0, WABinary_1.jidNormalizedUser)(group.attrs.creator) : undefined,
392
395
  ownerJid: group.attrs.creator_pn ? (0, WABinary_1.jidNormalizedUser)(group.attrs.creator_pn) : undefined,
396
+ ownerUsername: group.attrs.creator_username || undefined,
393
397
  desc,
394
398
  descId,
395
399
  descOwner,
396
400
  descOwnerJid,
401
+ descOwnerUsername,
397
402
  descTime,
398
403
  linkedParent: ((_b = (0, WABinary_1.getBinaryNodeChild)(group, 'linked_parent')) === null || _b === void 0 ? void 0 : _b.attrs.jid) || undefined,
399
404
  restrict: !!(0, WABinary_1.getBinaryNodeChild)(group, 'locked'),
@@ -418,7 +423,8 @@ const extractGroupMetadata = (result) => {
418
423
  pn,
419
424
  lid,
420
425
  jid: (0, WABinary_1.isJidUser)(attrs.jid) ? attrs.jid : (0, WABinary_1.jidNormalizedUser)(attrs.phone_number),
421
- admin: (attrs.type || null)
426
+ admin: (attrs.type || null),
427
+ username: attrs.participant_username || attrs.username || undefined
422
428
  };
423
429
  }) // Added missing closing parenthesis and brace for the map function
424
430
  };
@@ -1,10 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const Defaults_1 = require("../Defaults");
4
- const business_1 = require("./business");
5
- // export the last socket layer
6
- const makeWASocket = (config) => (0, business_1.makeBusinessSocket)({
7
- ...Defaults_1.DEFAULT_CONNECTION_CONFIG,
8
- ...config
9
- });
4
+ const communities_1 = require("./communities");
5
+ const makeWASocket = (config) => {
6
+ const newConfig = {
7
+ ...Defaults_1.DEFAULT_CONNECTION_CONFIG,
8
+ ...config
9
+ };
10
+ if (config.shouldSyncHistoryMessage === undefined) {
11
+ newConfig.shouldSyncHistoryMessage = () => !!newConfig.syncFullHistory;
12
+ }
13
+ return (0, communities_1.makeCommunitiesSocket)(newConfig);
14
+ };
10
15
  exports.default = makeWASocket;
@@ -37,32 +37,9 @@ const makeMessagesRecvSocket = (config) => {
37
37
  useClones: false
38
38
  });
39
39
  let sendActiveReceipts = false;
40
- const sendMessageAck = async ({ tag, attrs, content }, errorCode) => {
41
- const stanza = {
42
- tag: 'ack',
43
- attrs: {
44
- id: attrs.id,
45
- to: attrs.from,
46
- class: tag
47
- }
48
- };
49
- if (!!errorCode) {
50
- stanza.attrs.error = errorCode.toString();
51
- }
52
- if (!!attrs.participant) {
53
- stanza.attrs.participant = attrs.participant;
54
- }
55
- if (!!attrs.recipient) {
56
- stanza.attrs.recipient = attrs.recipient;
57
- }
58
- if (!!attrs.type &&
59
- (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
60
- stanza.attrs.type = attrs.type;
61
- }
62
- if (tag === 'message' && (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable')) {
63
- stanza.attrs.from = authState.creds.me.id;
64
- }
65
- logger.debug({ recv: { tag, attrs }, sent: stanza.attrs }, 'sent ack');
40
+ const sendMessageAck = async (node, errorCode) => {
41
+ const stanza = (0, Utils_1.buildAckStanza)(node, errorCode, authState.creds.me.id);
42
+ logger.debug({ recv: { tag: node.tag, attrs: node.attrs }, sent: stanza.attrs }, 'sent ack');
66
43
  await sendNode(stanza);
67
44
  };
68
45
  const rejectCall = async (callId, callFrom) => {
@@ -610,6 +587,11 @@ const makeMessagesRecvSocket = (config) => {
610
587
  (_a = msg.participant) !== null && _a !== void 0 ? _a : (msg.participant = node.attrs.participant);
611
588
  msg.messageTimestamp = +node.attrs.t;
612
589
  const fullMsg = WAProto_1.proto.WebMessageInfo.fromObject(msg);
590
+ // Reattach non-proto-schema fields stripped by fromObject so downstream
591
+ // consumers (e.g. process-message.js authorUsername) can read them.
592
+ if (node.attrs.participant_username && fullMsg.key) {
593
+ fullMsg.key.participantUsername = node.attrs.participant_username;
594
+ }
613
595
  await upsertMessage(fullMsg, 'append');
614
596
  }
615
597
  })
@@ -875,6 +857,20 @@ const makeMessagesRecvSocket = (config) => {
875
857
  };
876
858
  const offlineNodeProcessor = makeOfflineNodeProcessor();
877
859
  const processNode = (type, node, identifier, exec) => {
860
+ // Fast path: ack and drop ignored JIDs before entering the buffer/queue
861
+ const from = node.attrs.from;
862
+ let ignoreJid = from;
863
+ if (type === 'receipt' && from) {
864
+ const attrs = node.attrs;
865
+ const isLid = attrs.from && attrs.from.includes('lid');
866
+ const isNodeFromMe = (0, WABinary_1.areJidsSameUser)(attrs.participant || attrs.from, isLid ? authState.creds.me.lid : authState.creds.me.id);
867
+ ignoreJid = !isNodeFromMe || (0, WABinary_1.isJidGroup)(attrs.from) ? attrs.from : attrs.recipient;
868
+ }
869
+ if (ignoreJid && ignoreJid !== WABinary_1.S_WHATSAPP_NET && shouldIgnoreJid(ignoreJid)) {
870
+ sendMessageAck(node, type === 'message' ? Utils_1.NACK_REASONS.UnhandledError : undefined)
871
+ .catch(err => onUnexpectedError(err, `acking ignored ${type}`));
872
+ return;
873
+ }
878
874
  const isOffline = !!node.attrs.offline;
879
875
  if (isOffline) {
880
876
  offlineNodeProcessor.enqueue(type, node);
@@ -979,20 +975,37 @@ const makeMessagesRecvSocket = (config) => {
979
975
  // Handles mex newsletter notifications
980
976
  async function handleMexNewsletterNotification(node) {
981
977
  const mexNode = (0, WABinary_1.getBinaryNodeChild)(node, 'mex');
982
- if (!(mexNode === null || mexNode === void 0 ? void 0 : mexNode.content)) {
978
+ const updateNode = (mexNode === null || mexNode === void 0 ? void 0 : mexNode.content) ? null : ((0, WABinary_1.getBinaryNodeChild)(node, 'update') || (0, WABinary_1.getAllBinaryNodeChildren)(node)[0]);
979
+ const payloadNode = (mexNode === null || mexNode === void 0 ? void 0 : mexNode.content) ? mexNode : updateNode;
980
+ if (!(payloadNode === null || payloadNode === void 0 ? void 0 : payloadNode.content)) {
983
981
  logger.warn({ node }, 'Invalid mex newsletter notification');
984
982
  return;
985
983
  }
986
984
  let data;
987
985
  try {
988
- data = JSON.parse(mexNode.content.toString());
986
+ const payloadContent = payloadNode.content;
987
+ if (Array.isArray(payloadContent)) {
988
+ logger.warn({ payloadNode }, 'Invalid mex newsletter notification payload format');
989
+ return;
990
+ }
991
+ const contentBuf = typeof payloadContent === 'string'
992
+ ? Buffer.from(payloadContent, 'binary')
993
+ : Buffer.from(payloadContent);
994
+ data = JSON.parse(contentBuf.toString());
989
995
  }
990
996
  catch (error) {
991
997
  logger.error({ err: error, node }, 'Failed to parse mex newsletter notification');
992
998
  return;
993
999
  }
994
- const operation = data === null || data === void 0 ? void 0 : data.operation;
995
- const updates = data === null || data === void 0 ? void 0 : data.updates;
1000
+ const operation = (data === null || data === void 0 ? void 0 : data.operation)
1001
+ || ((payloadNode === null || payloadNode === void 0 ? void 0 : payloadNode.attrs) && (payloadNode === null || payloadNode === void 0 ? void 0 : payloadNode.attrs.op_name));
1002
+ let updates = data === null || data === void 0 ? void 0 : data.updates;
1003
+ if (!updates) {
1004
+ const linkedProfiles = (data === null || data === void 0 ? void 0 : data.data) === null || data === void 0 ? void 0 : (data.data.xwa2_notify_linked_profiles);
1005
+ if (linkedProfiles) {
1006
+ updates = [linkedProfiles];
1007
+ }
1008
+ }
996
1009
  if (!updates || !operation) {
997
1010
  logger.warn({ data }, 'Invalid mex newsletter notification content');
998
1011
  return;
@@ -1022,6 +1035,26 @@ const makeMessagesRecvSocket = (config) => {
1022
1035
  }
1023
1036
  }
1024
1037
  break;
1038
+ case 'NotificationLinkedProfilesUpdates':
1039
+ for (const update of updates) {
1040
+ const lid = update === null || update === void 0 ? void 0 : update.jid;
1041
+ const addedProfiles = Array.isArray(update === null || update === void 0 ? void 0 : update.added_profiles) ? update.added_profiles : [];
1042
+ const mappings = [];
1043
+ for (const profile of addedProfiles) {
1044
+ const pn = typeof profile === 'string' ? profile : (profile === null || profile === void 0 ? void 0 : profile.pn) || (profile === null || profile === void 0 ? void 0 : profile.jid) || null;
1045
+ if (lid && pn) {
1046
+ const mapping = { lid, pn };
1047
+ ev.emit('lid-mapping.update', mapping);
1048
+ mappings.push(mapping);
1049
+ }
1050
+ }
1051
+ if (mappings.length && signalRepository.lidMapping.storeLIDPNMappings) {
1052
+ signalRepository.lidMapping.storeLIDPNMappings(mappings).catch((err) => {
1053
+ logger.warn({ err }, 'failed to store LID/PN mappings from mex notification');
1054
+ });
1055
+ }
1056
+ }
1057
+ break;
1025
1058
  default:
1026
1059
  logger.info({ operation, data }, 'Unhandled mex newsletter notification');
1027
1060
  break;