@badzz88/baileys 8.5.4 → 8.5.5

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.
Files changed (107) hide show
  1. package/README.md +1 -1
  2. package/WAProto/WAProto.proto +75 -1256
  3. package/WAProto/index.d.ts +19729 -36122
  4. package/WAProto/index.js +132193 -178538
  5. package/engine-requirements.js +15 -7
  6. package/lib/Defaults/index.js +14 -22
  7. package/lib/Signal/Group/group_cipher.js +5 -5
  8. package/lib/Signal/Group/keyhelper.js +4 -4
  9. package/lib/Signal/Group/sender-chain-key.js +2 -2
  10. package/lib/Signal/Group/sender-key-distribution-message.js +1 -1
  11. package/lib/Signal/Group/sender-key-message.js +3 -3
  12. package/lib/Signal/Group/sender-key-record.js +1 -1
  13. package/lib/Signal/Group/sender-message-key.js +5 -5
  14. package/lib/Signal/libsignal.js +28 -39
  15. package/lib/Signal/lid-mapping.js +8 -28
  16. package/lib/Socket/aigroups.js +5 -5
  17. package/lib/Socket/business.js +11 -3
  18. package/lib/Socket/chats.js +319 -668
  19. package/lib/Socket/communities.js +89 -85
  20. package/lib/Socket/graphql.js +228 -435
  21. package/lib/Socket/groups.js +211 -132
  22. package/lib/Socket/index.js +7 -9
  23. package/lib/Socket/interactive-handler.js +60 -117
  24. package/lib/Socket/interop.js +175 -56
  25. package/lib/Socket/luxu.js +387 -0
  26. package/lib/Socket/managed-account.js +48 -79
  27. package/lib/Socket/messages-recv.js +340 -898
  28. package/lib/Socket/messages-send.js +160 -462
  29. package/lib/Socket/mex.js +53 -40
  30. package/lib/Socket/newsletter.js +295 -291
  31. package/lib/Socket/privacy.js +265 -77
  32. package/lib/Socket/registration.js +157 -164
  33. package/lib/Socket/socket.js +199 -181
  34. package/lib/Socket/text-router.js +83 -0
  35. package/lib/Socket/username.js +227 -144
  36. package/lib/Store/keyed-db.js +108 -0
  37. package/lib/Store/make-cache-manager-store.js +2 -2
  38. package/lib/Store/make-in-memory-store.js +141 -25
  39. package/lib/Types/Auth.js +3 -3
  40. package/lib/Types/Label.js +1 -1
  41. package/lib/Types/LabelAssociation.js +1 -1
  42. package/lib/Types/Mex.js +112 -0
  43. package/lib/Types/Newsletter.js +65 -96
  44. package/lib/Types/State.js +4 -4
  45. package/lib/Types/index.js +1 -1
  46. package/lib/Utils/auth-utils.js +57 -52
  47. package/lib/Utils/browser-utils.js +1 -1
  48. package/lib/Utils/business.js +6 -2
  49. package/lib/Utils/chat-utils.js +38 -102
  50. package/lib/Utils/command-loader.d.ts +31 -0
  51. package/lib/Utils/command-loader.js +100 -0
  52. package/lib/Utils/companion-reg-client-utils.js +42 -0
  53. package/lib/Utils/crypto.js +84 -54
  54. package/lib/Utils/curve25519-js.js +275 -0
  55. package/lib/Utils/decode-wa-message.js +83 -316
  56. package/lib/Utils/event-buffer.js +61 -37
  57. package/lib/Utils/generics.js +103 -157
  58. package/lib/Utils/group-history.js +12 -3
  59. package/lib/Utils/history.js +15 -15
  60. package/lib/Utils/index.js +5 -1
  61. package/lib/Utils/link-preview.js +8 -3
  62. package/lib/Utils/lt-hash.js +35 -2
  63. package/lib/Utils/make-mutex.js +1 -1
  64. package/lib/Utils/message-retry-manager.js +92 -27
  65. package/lib/Utils/messages-media.js +130 -159
  66. package/lib/Utils/messages.js +566 -144
  67. package/lib/Utils/meta-ai-msmsg.js +202 -62
  68. package/lib/Utils/native-bridge.js +82 -0
  69. package/lib/Utils/noise-handler.js +21 -19
  70. package/lib/Utils/offline-node-processor.js +8 -3
  71. package/lib/Utils/pre-key-manager.js +23 -13
  72. package/lib/Utils/process-message.js +106 -197
  73. package/lib/Utils/reporting-utils.js +2 -2
  74. package/lib/Utils/session-pool.d.ts +16 -0
  75. package/lib/Utils/session-pool.js +94 -0
  76. package/lib/Utils/signal.js +63 -28
  77. package/lib/Utils/stanza-ack.js +12 -39
  78. package/lib/Utils/sticker.d.ts +17 -0
  79. package/lib/Utils/sticker.js +145 -0
  80. package/lib/Utils/sync-action-utils.js +7 -4
  81. package/lib/Utils/tc-token-utils.js +25 -20
  82. package/lib/Utils/use-multi-file-auth-state.js +14 -30
  83. package/lib/Utils/validate-connection.js +19 -59
  84. package/lib/Utils/view-once-cache.d.ts +9 -0
  85. package/lib/Utils/view-once-cache.js +79 -0
  86. package/lib/WABinary/decode.js +16 -50
  87. package/lib/WABinary/encode.js +224 -54
  88. package/lib/WABinary/generic-utils.js +97 -7
  89. package/lib/WABinary/jid-utils.js +14 -27
  90. package/lib/WAM/encode.js +7 -7
  91. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +1 -58
  92. package/lib/WAUSync/Protocols/USyncContactProtocol.js +1 -7
  93. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +5 -13
  94. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +4 -1
  95. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +7 -20
  96. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +1 -1
  97. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +2 -2
  98. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +2 -7
  99. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +1 -1
  100. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +1 -2
  101. package/lib/WAUSync/Protocols/index.js +0 -1
  102. package/lib/WAUSync/USyncQuery.js +6 -77
  103. package/lib/WAUSync/USyncUser.js +8 -16
  104. package/lib/WAUSync/index.js +0 -1
  105. package/lib/antiban.js +854 -608
  106. package/lib/index.js +1 -1
  107. package/package.json +20 -16
@@ -9,28 +9,28 @@ const chats_1 = require('./chats')
9
9
  const mex_1 = require('./mex')
10
10
 
11
11
  const GROUP_MEX_QUERY_IDS = {
12
- QUERY_INFO: '25530136513328492',
13
- QUERY_INFO_BY_CODE: '24576337542042464',
14
- QUERY_BATCH: '26440064815661176',
15
- QUERY_INVITE_LINK: '24558418350455204',
16
- QUERY_PARTICIPATING: '26664341543184776',
17
- QUERY_SUGGESTED: '26012055225051916',
18
- QUERY_LINKED: '25629003043401452',
19
- QUERY_SUBGROUPS: '25554052094203120',
20
- ADD_PARTICIPANTS_V2: '32627550323510250',
21
- ADD_PARTICIPANTS_V3: '26581073158212628',
22
- SET_PROPERTY: '24688994337458820',
23
- RESET_INVITE_LINK: '24812851838367452',
24
- CREATE_INVITE_CODE: '25207706598901440',
25
- CREATE_GROUP: '32341779532133480',
26
- ALLOW_NON_ADMIN_GROUP_CREATION: '32024438593867696',
27
- GET_INVITE_INFO: '24745668928467084',
28
- GET_PRE_REG_ADD_REQUESTS: '25018599251091280',
29
- GET_SUGGESTED_CONTACTS: '27208468032086900',
30
- STORE_INVITES_SMS: '25508574885415376',
31
- LOG_SERVER_SENT_INVITE: '26580640204871220',
32
- QUERY_ONLINE_STATUS: '24599444653063564',
33
- QUERY_ONLINE_STATUS_LAST_SEEN: '24653084284365540'
12
+ QUERY_INFO: '25530136513328492', // QueryGroupInfo
13
+ QUERY_INFO_BY_CODE: '24576337542042464', // QueryGroupInfoByCode
14
+ QUERY_BATCH: '26440064815661176', // QueryBatchGetGroups
15
+ QUERY_INVITE_LINK: '24558418350455204', // QueryInviteLink
16
+ QUERY_PARTICIPATING: '26664341543184776', // QueryParticipatingGroups
17
+ QUERY_SUGGESTED: '26012055225051916', // QuerySuggestedGroups
18
+ QUERY_LINKED: '25629003043401452', // QueryLinkedGroupInfo
19
+ QUERY_SUBGROUPS: '25554052094203120', // QuerySubgroups
20
+ ADD_PARTICIPANTS_V2: '32627550323510250', // AddParticipantsToGroupV2
21
+ ADD_PARTICIPANTS_V3: '26581073158212628', // AddParticipantsToGroupsV3
22
+ SET_PROPERTY: '24688994337458820', // SetGroupProperty
23
+ RESET_INVITE_LINK: '24812851838367452', // SetGroupResetInviteLink
24
+ CREATE_INVITE_CODE: '25207706598901440', // CreateInviteCode
25
+ CREATE_GROUP: '32341779532133480', // CreateGroup
26
+ ALLOW_NON_ADMIN_GROUP_CREATION: '32024438593867696', // AllowNonAdminGroupCreation
27
+ GET_INVITE_INFO: '24745668928467084', // GetInviteInfo
28
+ GET_PRE_REG_ADD_REQUESTS: '25018599251091280', // GetPreRegGroupAddRequestsQuery
29
+ GET_SUGGESTED_CONTACTS: '27208468032086900', // GetSuggestedContacts
30
+ STORE_INVITES_SMS: '25508574885415376', // GroupsStoreInvitesSMSMutation
31
+ LOG_SERVER_SENT_INVITE: '26580640204871220', // LogServerSentInviteIntent
32
+ QUERY_ONLINE_STATUS: '24599444653063564', // QueryOnlineStatusFromPDP
33
+ QUERY_ONLINE_STATUS_LAST_SEEN: '24653084284365540' // QueryOnlineStatusLastSeenFromPDP
34
34
  }
35
35
 
36
36
  const makeGroupsSocket = config => {
@@ -46,38 +46,25 @@ const makeGroupsSocket = config => {
46
46
  },
47
47
  content
48
48
  })
49
-
50
-
51
-
52
- const persistParticipantLidMappings = async participantLists => {
53
- const pairs = []
54
- for (const participants of participantLists) {
55
- for (const p of participants || []) {
56
- if (p.phoneNumber) pairs.push({ lid: p.id, pn: p.phoneNumber })
57
- else if (p.lid) pairs.push({ lid: p.lid, pn: p.id })
58
- }
59
- }
60
- if (!pairs.length) return
61
- try {
62
- await sock.signalRepository.lidMapping.storeLIDPNMappings(pairs)
63
- } catch (error) {
64
- sock.logger?.warn?.({ error }, 'failed to store LID/PN mappings from group metadata')
65
- }
66
- }
67
49
 
68
50
  const mexQuery = (variables, queryId, dataPath) =>
69
51
  (0, mex_1.executeWMexQuery)(variables, queryId, dataPath, query, generateMessageTag)
70
52
  const groupMetadata = async jid => {
71
53
  const result = await groupQuery(jid, 'get', [{ tag: 'query', attrs: { request: 'interactive' } }])
72
- const metadata = (0, exports.extractGroupMetadata)(result)
73
- persistParticipantLidMappings([metadata.participants]).catch(() => {})
74
- return metadata
54
+ return (0, exports.extractGroupMetadata)(result)
75
55
  }
76
-
56
+ /**
57
+ * Acknowledge a group. Ported from WhatsApp Web's WASmaxGroupsAcknowledgeGroupRPC
58
+ * (`<iq to=jid xmlns=w:g2 type=set><ack/></iq>`).
59
+ */
77
60
  const groupAcknowledge = async jid => {
78
61
  await groupQuery(jid, 'set', [{ tag: 'ack', attrs: {} }])
79
62
  }
80
-
63
+ /**
64
+ * Get the participants of a community's linked/sub groups. Ported from
65
+ * WhatsApp Web's WASmaxGroupsGetLinkedGroupsParticipantsRPC.
66
+ * @returns {Promise<Array<{ jid: string, phoneNumber?: string }>>}
67
+ */
81
68
  const groupGetLinkedParticipants = async jid => {
82
69
  const result = await groupQuery(jid, 'get', [{ tag: 'linked_groups_participants', attrs: {} }])
83
70
  const node = (0, WABinary_1.getBinaryNodeChild)(result, 'linked_groups_participants')
@@ -86,14 +73,26 @@ const makeGroupsSocket = config => {
86
73
  phoneNumber: p.attrs.phone_number || p.attrs.pn || undefined
87
74
  }))
88
75
  }
89
-
76
+ /**
77
+ * Join a community's linked/sub group (may raise a membership approval request).
78
+ * Ported from WhatsApp Web's WASmaxGroupsJoinLinkedGroupRPC.
79
+ * @param {string} parentJid community/parent group to address
80
+ * @param {string} linkedGroupJid linked/sub group to join
81
+ * @param {string} [type]
82
+ */
90
83
  const groupJoinLinked = async (parentJid, linkedGroupJid, type) => {
91
84
  const result = await groupQuery(parentJid, 'set', [
92
85
  { tag: 'join_linked_group', attrs: { jid: linkedGroupJid, ...(type ? { type } : {}) } }
93
86
  ])
94
87
  return { approvalRequested: !!(0, WABinary_1.getBinaryNodeChild)(result, 'membership_approval_request') }
95
88
  }
96
-
89
+ /**
90
+ * Batch-fetch group profile pictures via w:g2. Ported from WhatsApp Web's
91
+ * WASmaxGroupsGetGroupProfilePicturesRPC. NOTE: untested against live WhatsApp —
92
+ * for a single group prefer profilePictureUrl().
93
+ * @param {string[]} jids group jids
94
+ * @param {'preview' | 'image'} [type]
95
+ */
97
96
  const getGroupProfilePictures = async (jids, type = 'preview') => {
98
97
  const result = await groupQuery(WABinary_1.S_WHATSAPP_NET, 'get', [
99
98
  {
@@ -109,26 +108,32 @@ const makeGroupsSocket = config => {
109
108
  url: pic.attrs.url
110
109
  }))
111
110
  }
112
-
111
+ /**
112
+ * Create a sub-group suggestion for a community. Ported from WhatsApp Web's
113
+ * WASmaxGroupsCreateSubGroupSuggestionRPC. The suggestion body (new vs existing
114
+ * groups) is caller-provided. NOTE: untested against live WhatsApp.
115
+ * @param {string} parentJid community/parent group to address
116
+ * @param {Array<{ tag: string, attrs?: object, content?: any }>} suggestion child node(s)
117
+ */
113
118
  const groupCreateSubGroupSuggestion = async (parentJid, suggestion) => {
114
119
  await groupQuery(parentJid, 'set', [{ tag: 'sub_group_suggestion', attrs: {}, content: suggestion }])
115
120
  }
116
-
121
+ /**
122
+ * Approve or reject sub-group suggestions for a community. Ported from WhatsApp
123
+ * Web's WASmaxGroupsSubGroupSuggestionsActionRPC. NOTE: untested against live WhatsApp.
124
+ * @param {string} parentJid community/parent group to address
125
+ * @param {'approve' | 'reject'} action
126
+ * @param {Array<{ creator: string, jid?: string }>} suggestions
127
+ */
117
128
  const groupSubGroupSuggestionsAction = async (parentJid, action, suggestions) => {
118
129
  await groupQuery(parentJid, 'set', [
119
130
  {
120
- tag: 'sub_group_suggestions_action',
131
+ tag: action,
121
132
  attrs: {},
122
- content: [
123
- {
124
- tag: action,
125
- attrs: {},
126
- content: suggestions.map(s => ({
127
- tag: 'sub_group_suggestion',
128
- attrs: action === 'cancel' ? { jid: s.jid } : { creator: s.creator }
129
- }))
130
- }
131
- ]
133
+ content: suggestions.map(s => ({
134
+ tag: 'sub_group_suggestion',
135
+ attrs: { creator: s.creator, ...(s.jid ? { jid: s.jid } : {}) }
136
+ }))
132
137
  }
133
138
  ])
134
139
  }
@@ -164,9 +169,8 @@ const makeGroupsSocket = config => {
164
169
  data[meta.id] = meta
165
170
  }
166
171
  }
167
- const allGroups = Object.values(data)
168
- persistParticipantLidMappings(allGroups.map(g => g.participants)).catch(() => {})
169
- sock.ev.emit('groups.update', allGroups)
172
+ // TODO: properly parse LID / PN DATA
173
+ sock.ev.emit('groups.update', Object.values(data))
170
174
  return data
171
175
  }
172
176
  sock.ws.on('CB:ib,,dirty', async node => {
@@ -302,14 +306,23 @@ const makeGroupsSocket = config => {
302
306
  const result = (0, WABinary_1.getBinaryNodeChild)(results, 'group')
303
307
  return result?.attrs.jid
304
308
  },
305
-
309
+ /**
310
+ * revoke a v4 invite for someone
311
+ * @param groupJid group jid
312
+ * @param invitedJid jid of person you invited
313
+ * @returns true if successful
314
+ */
306
315
  groupRevokeInviteV4: async (groupJid, invitedJid) => {
307
316
  const result = await groupQuery(groupJid, 'set', [
308
317
  { tag: 'revoke', attrs: {}, content: [{ tag: 'participant', attrs: { jid: invitedJid } }] }
309
318
  ])
310
319
  return !!result
311
320
  },
312
-
321
+ /**
322
+ * accept a GroupInviteMessage
323
+ * @param key the key of the invite message, or optionally only provide the jid of the person who sent the invite
324
+ * @param inviteMessage the message to accept
325
+ */
313
326
  groupAcceptInviteV4: ev.createBufferedFunction(async (key, inviteMessage) => {
314
327
  key = typeof key === 'string' ? { remoteJid: key } : key
315
328
  const results = await groupQuery(inviteMessage.groupJid, 'set', [
@@ -322,10 +335,10 @@ const makeGroupsSocket = config => {
322
335
  }
323
336
  }
324
337
  ])
325
-
326
-
338
+ // if we have the full message key
339
+ // update the invite message to be expired
327
340
  if (key.id) {
328
-
341
+ // create new invite message that is expired
329
342
  inviteMessage = index_js_1.proto.Message.GroupInviteMessage.fromObject(inviteMessage)
330
343
  inviteMessage.inviteExpiration = 0
331
344
  inviteMessage.inviteCode = ''
@@ -340,7 +353,7 @@ const makeGroupsSocket = config => {
340
353
  }
341
354
  ])
342
355
  }
343
-
356
+ // generate the group add message
344
357
  await upsertMessage(
345
358
  {
346
359
  key: {
@@ -379,7 +392,9 @@ const makeGroupsSocket = config => {
379
392
  { tag: 'membership_approval_mode', attrs: {}, content: [{ tag: 'group_join', attrs: { state: mode } }] }
380
393
  ])
381
394
  },
382
-
395
+ /**
396
+ * Get past participants of a group (left/removed members)
397
+ */
383
398
  groupGetPastParticipants: async jid => {
384
399
  const result = await groupQuery(jid, 'get', [{ tag: 'past_participants', attrs: {} }])
385
400
  const node = (0, WABinary_1.getBinaryNodeChild)(result, 'past_participants')
@@ -391,22 +406,23 @@ const makeGroupsSocket = config => {
391
406
  leaveTimestamp: p.attrs.t ? Number(p.attrs.t) : undefined
392
407
  }))
393
408
  },
394
-
409
+ /**
410
+ * Create a subgroup within a community
411
+ */
395
412
  groupCreateSubgroup: async (communityJid, subject, participants = []) => {
396
413
  const key = (0, Utils_1.generateMessageIDV2)()
397
414
  const result = await groupQuery('@g.us', 'set', [
398
415
  {
399
416
  tag: 'create',
400
- attrs: { subject, key },
401
- content: [
402
- ...participants.map(jid => ({ tag: 'participant', attrs: { jid } })),
403
- { tag: 'linked_parent', attrs: { jid: communityJid } }
404
- ]
417
+ attrs: { subject, key, parent_group_id: communityJid },
418
+ content: participants.map(jid => ({ tag: 'participant', attrs: { jid } }))
405
419
  }
406
420
  ])
407
421
  return (0, exports.extractGroupMetadata)(result)
408
422
  },
409
-
423
+ /**
424
+ * Link an existing group to a community
425
+ */
410
426
  groupLinkToCommunity: async (communityJid, groupJid) => {
411
427
  await groupQuery(communityJid, 'set', [
412
428
  {
@@ -418,7 +434,9 @@ const makeGroupsSocket = config => {
418
434
  }
419
435
  ])
420
436
  },
421
-
437
+ /**
438
+ * Unlink a group from a community
439
+ */
422
440
  groupUnlinkFromCommunity: async (communityJid, groupJid) => {
423
441
  await groupQuery(communityJid, 'set', [
424
442
  {
@@ -430,7 +448,12 @@ const makeGroupsSocket = config => {
430
448
  }
431
449
  ])
432
450
  },
433
-
451
+ /**
452
+ * Set a member label/tag in a group
453
+ * @param jid group JID
454
+ * @param participantJid participant JID to label
455
+ * @param label the label string ('' to remove)
456
+ */
434
457
  groupSetMemberLabel: async (jid, participantJid, label) => {
435
458
  await groupQuery(jid, 'set', [
436
459
  {
@@ -445,7 +468,9 @@ const makeGroupsSocket = config => {
445
468
  }
446
469
  ])
447
470
  },
448
-
471
+ /**
472
+ * Get community-linked subgroups for a community JID
473
+ */
449
474
  groupGetLinkedSubgroups: async communityJid => {
450
475
  const result = await groupQuery(communityJid, 'get', [{ tag: 'links', attrs: { link_type: 'sub_group' } }])
451
476
  const linksNode = (0, WABinary_1.getBinaryNodeChild)(result, 'links')
@@ -459,20 +484,26 @@ const makeGroupsSocket = config => {
459
484
  },
460
485
  groupFetchAllParticipating,
461
486
 
462
-
487
+ // ── MEX queries (JSON responses) ──────────────────────────────────────
463
488
 
464
-
465
- groupQueryInfo: jid => mexQuery({ group_id: jid }, GROUP_MEX_QUERY_IDS.QUERY_INFO, 'xwa2_group_query_by_id'),
489
+ /**
490
+ * Fetch group info via MEX (richer than IQ — includes invite link, LID addressing, etc.)
491
+ * @param {string} jid - Group JID
492
+ */
493
+ groupQueryInfo: jid =>
494
+ mexQuery({ group_id: jid }, GROUP_MEX_QUERY_IDS.QUERY_INFO, 'xwa2_group_query_by_id'),
466
495
 
467
-
496
+ /**
497
+ * Fetch group info by invite code via MEX.
498
+ * @param {string} code - Group invite code (without the link prefix)
499
+ */
468
500
  groupQueryInfoByCode: code =>
469
- mexQuery(
470
- { group_input: { invite_code: code } },
471
- GROUP_MEX_QUERY_IDS.QUERY_INFO_BY_CODE,
472
- 'xwa2_group_query_by_id'
473
- ),
501
+ mexQuery({ group_input: { invite_code: code } }, GROUP_MEX_QUERY_IDS.QUERY_INFO_BY_CODE, 'xwa2_group_query_by_id'),
474
502
 
475
-
503
+ /**
504
+ * Fetch multiple groups at once via MEX.
505
+ * @param {string[]} jids - Array of group JIDs
506
+ */
476
507
  groupQueryBatch: jids =>
477
508
  mexQuery(
478
509
  { groups_input: jids.map(group_id => ({ group_id })) },
@@ -480,15 +511,24 @@ const makeGroupsSocket = config => {
480
511
  'xwa2_group_query_batch'
481
512
  ),
482
513
 
483
-
514
+ /**
515
+ * Fetch invite link info via MEX (includes expiration, creator, etc.)
516
+ * @param {string} jid - Group JID
517
+ */
484
518
  groupQueryInviteLink: jid =>
485
519
  mexQuery({ group_input: { group_id: jid } }, GROUP_MEX_QUERY_IDS.QUERY_INVITE_LINK, 'xwa2_group_query_by_id'),
486
520
 
487
-
521
+ /**
522
+ * Fetch all groups the current user is participating in via MEX.
523
+ * Returns richer data than the IQ-based groupFetchAllParticipating.
524
+ */
488
525
  groupQueryParticipating: () =>
489
526
  mexQuery({}, GROUP_MEX_QUERY_IDS.QUERY_PARTICIPATING, 'xwa2_group_query_participating'),
490
527
 
491
-
528
+ /**
529
+ * Fetch suggested groups (community sub-group suggestions) via MEX.
530
+ * @param {string} communityJid - Community JID to get suggestions for
531
+ */
492
532
  groupQuerySuggested: communityJid =>
493
533
  mexQuery(
494
534
  { group_input: { group_id: communityJid } },
@@ -496,11 +536,17 @@ const makeGroupsSocket = config => {
496
536
  'xwa2_group_query_by_id'
497
537
  ),
498
538
 
499
-
539
+ /**
540
+ * Fetch linked subgroup info for a community group via MEX.
541
+ * @param {string} jid - Group or community JID
542
+ */
500
543
  groupQueryLinked: jid =>
501
544
  mexQuery({ group_input: { group_id: jid } }, GROUP_MEX_QUERY_IDS.QUERY_LINKED, 'xwa2_group_query_by_id'),
502
545
 
503
-
546
+ /**
547
+ * Fetch subgroups of a community via MEX.
548
+ * @param {string} communityJid - Community JID
549
+ */
504
550
  groupQuerySubgroups: communityJid =>
505
551
  mexQuery(
506
552
  { group_input: { group_id: communityJid } },
@@ -508,7 +554,12 @@ const makeGroupsSocket = config => {
508
554
  'xwa2_group_query_by_id'
509
555
  ),
510
556
 
511
-
557
+ /**
558
+ * Add participants to a group via MEX (V2 — supports LID, privacy metadata).
559
+ * Falls back to the IQ-based groupParticipantsUpdate for older servers.
560
+ * @param {string} jid - Group JID
561
+ * @param {string[]} participants - Array of JIDs to add
562
+ */
512
563
  groupAddParticipantsMex: (jid, participants) =>
513
564
  mexQuery(
514
565
  { group_id: jid, participants: participants.map(p => ({ user_jid: p })) },
@@ -516,15 +567,29 @@ const makeGroupsSocket = config => {
516
567
  'xwa2_group_add_participants'
517
568
  ),
518
569
 
519
-
570
+ /**
571
+ * Set a group property via MEX.
572
+ * Known properties: member_add_mode, membership_approval_mode_enabled, member_share_group_history_mode
573
+ * @param {string} jid - Group JID
574
+ * @param {string} property - Property name
575
+ * @param {*} value - Property value
576
+ */
520
577
  groupSetProperty: (jid, property, value) =>
521
- mexQuery({ group_id: jid, [property]: value }, GROUP_MEX_QUERY_IDS.SET_PROPERTY, 'xwa2_group_update_property'),
578
+ mexQuery({ group_id: jid, [property]: value }, GROUP_MEX_QUERY_IDS.SET_PROPERTY, 'xwa2_group_set_property'),
522
579
 
523
-
580
+ /**
581
+ * Reset a group's invite link via MEX (generates new code, invalidates old one).
582
+ * @param {string} jid - Group JID
583
+ */
524
584
  groupResetInviteLinkMex: jid =>
525
585
  mexQuery({ group_jid: jid }, GROUP_MEX_QUERY_IDS.RESET_INVITE_LINK, 'xwa2_group_reset_invite_link'),
526
586
 
527
-
587
+ /**
588
+ * Create a group via MEX.
589
+ * Confirmed from CreateGroup mutation — input: { subject, participants: [{jid}] }
590
+ * @param {string} subject - Group name
591
+ * @param {string[]} participantJids
592
+ */
528
593
  groupCreateMex: (subject, participantJids) =>
529
594
  mexQuery(
530
595
  { input: { subject, participants: participantJids.map(jid => ({ jid })) } },
@@ -532,7 +597,11 @@ const makeGroupsSocket = config => {
532
597
  'xwa2_group_create'
533
598
  ),
534
599
 
535
-
600
+ /**
601
+ * Allow non-admin community members to create subgroups.
602
+ * @param {string} communityJid - Community JID
603
+ * @param {boolean} allow
604
+ */
536
605
  groupAllowNonAdminCreation: (communityJid, allow) =>
537
606
  mexQuery(
538
607
  { group_jid: communityJid, allow_non_admin_sub_group_creation: allow },
@@ -540,19 +609,32 @@ const makeGroupsSocket = config => {
540
609
  'xwa2_group_allow_non_admin_creation'
541
610
  ),
542
611
 
543
-
612
+ /**
613
+ * Get info about a group invite link (before joining).
614
+ * @param {string} inviteCode - The raw invite code (not full URL)
615
+ */
544
616
  groupGetInviteInfo: inviteCode =>
545
617
  mexQuery({ invite_code: inviteCode }, GROUP_MEX_QUERY_IDS.GET_INVITE_INFO, 'xwa2_group_get_invite_info'),
546
618
 
547
-
619
+ /**
620
+ * Fetch pending add requests for pre-registration group invites.
621
+ * @param {string} jid - Group JID
622
+ */
548
623
  groupPreRegAddRequests: jid =>
549
624
  mexQuery({ group_jid: jid }, GROUP_MEX_QUERY_IDS.GET_PRE_REG_ADD_REQUESTS, 'xwa2_group_pre_reg_add_requests'),
550
625
 
551
-
626
+ /**
627
+ * Get suggested contacts to add to a group.
628
+ * @param {string} jid - Group JID
629
+ */
552
630
  groupSuggestedContacts: jid =>
553
631
  mexQuery({ group_jid: jid }, GROUP_MEX_QUERY_IDS.GET_SUGGESTED_CONTACTS, 'xwa2_group_suggested_contacts'),
554
632
 
555
-
633
+ /**
634
+ * Store SMS invite links for a group.
635
+ * @param {string} jid - Group JID
636
+ * @param {{ phone: string, inviteCode: string }[]} invites
637
+ */
556
638
  groupStoreInvitesSms: (jid, invites) =>
557
639
  mexQuery(
558
640
  { group_jid: jid, invites: invites.map(({ phone, inviteCode }) => ({ phone, invite_code: inviteCode })) },
@@ -560,7 +642,11 @@ const makeGroupsSocket = config => {
560
642
  'xwa2_group_store_invites_sms'
561
643
  ),
562
644
 
563
-
645
+ /**
646
+ * Log a server-sent invite intent (analytics).
647
+ * @param {string} jid - Group JID
648
+ * @param {string} inviteCode
649
+ */
564
650
  groupLogServerSentInvite: (jid, inviteCode) =>
565
651
  mexQuery(
566
652
  { group_jid: jid, invite_code: inviteCode },
@@ -568,10 +654,17 @@ const makeGroupsSocket = config => {
568
654
  'xwa2_group_log_server_sent_invite'
569
655
  ),
570
656
 
571
-
572
- queryOnlineStatus: jids => mexQuery({ jids }, GROUP_MEX_QUERY_IDS.QUERY_ONLINE_STATUS, 'xwa2_query_online_status'),
657
+ /**
658
+ * Query online status of users from PDP.
659
+ * @param {string[]} jids - User JIDs
660
+ */
661
+ queryOnlineStatus: jids =>
662
+ mexQuery({ jids }, GROUP_MEX_QUERY_IDS.QUERY_ONLINE_STATUS, 'xwa2_query_online_status'),
573
663
 
574
-
664
+ /**
665
+ * Query online status and last seen of users from PDP.
666
+ * @param {string[]} jids - User JIDs
667
+ */
575
668
  queryOnlineStatusLastSeen: jids =>
576
669
  mexQuery({ jids }, GROUP_MEX_QUERY_IDS.QUERY_ONLINE_STATUS_LAST_SEEN, 'xwa2_query_online_status_last_seen'),
577
670
 
@@ -605,11 +698,6 @@ const extractGroupMetadata = result => {
605
698
  const communityMemberAddGroupNode = (0, WABinary_1.getBinaryNodeChild)(group, 'allow_non_admin_sub_group_creation')
606
699
  const subGroupVisibilityNode = (0, WABinary_1.getBinaryNodeChild)(group, 'sub_groups_list')
607
700
  const membershipApprovalNode = (0, WABinary_1.getBinaryNodeChild)(group, 'membership_approval_mode')
608
- const capiNode = (0, WABinary_1.getBinaryNodeChild)(group, 'capi')
609
- const appealStatusNode = (0, WABinary_1.getBinaryNodeChild)(group, 'appeal_status')
610
- const defaultSubGroupNode = (0, WABinary_1.getBinaryNodeChild)(group, 'default_sub_group')
611
- const generalChatNode = (0, WABinary_1.getBinaryNodeChild)(group, 'general_chat')
612
- const hiddenGroupNode = (0, WABinary_1.getBinaryNodeChild)(group, 'hidden_group')
613
701
  const metadata = {
614
702
  id: groupId,
615
703
  notify: group.attrs.notify,
@@ -639,23 +727,15 @@ const extractGroupMetadata = result => {
639
727
  isCommunityAnnounce: !!(0, WABinary_1.getBinaryNodeChild)(group, 'default_sub_group'),
640
728
  joinApprovalMode: !!membershipApprovalNode,
641
729
  memberAddMode,
642
- memberShareHistoryMode:
643
- (0, WABinary_1.getBinaryNodeChildString)(group, 'member_share_group_history_mode') || undefined,
644
- memberLinkMode: (0, WABinary_1.getBinaryNodeChildString)(group, 'member_link_mode') || undefined,
645
- limitSharing: !!(0, WABinary_1.getBinaryNodeChild)(group, 'limit_sharing_enabled'),
646
- communityMemberAddGroupMode: communityMemberAddGroupNode?.attrs.state || undefined,
647
- capiCreatedGroup: !!capiNode || undefined,
648
- appealStatus: appealStatusNode?.attrs.type || undefined,
730
+ memberShareHistoryMode: (0, WABinary_1.getBinaryNodeChildString)(group, 'member_share_group_history_mode') || undefined,
731
+ memberLinkMode: (0, WABinary_1.getBinaryNodeChildString)(group, 'member_link_mode') || undefined,
732
+ limitSharing: !!(0, WABinary_1.getBinaryNodeChild)(group, 'limit_sharing_enabled'),
733
+ communityMemberAddGroupMode: communityMemberAddGroupNode?.attrs.state || undefined,
734
+ capiCreatedGroup: group.attrs.capi_created === 'true' || undefined,
735
+ appealStatus: group.attrs.appeal_status || undefined,
649
736
  isSubGroupHidden: group.attrs.sub_group_visibility === 'hidden' || undefined,
650
- membershipApprovalMode: group.attrs.membership_approval_mode || undefined,
651
- joinPermissions: group.attrs.join_permissions || undefined,
652
- isDefaultSubgroup: !!defaultSubGroupNode || undefined,
653
- isGeneralSubgroup: !!generalChatNode || undefined,
654
- isHiddenSubgroup: !!hiddenGroupNode || undefined,
655
737
  participants: (0, WABinary_1.getBinaryNodeChildren)(group, 'participant').map(({ attrs }) => {
656
-
657
-
658
-
738
+ // TODO: Store LID MAPPINGS
659
739
  return {
660
740
  id: attrs.jid,
661
741
  phoneNumber:
@@ -667,12 +747,11 @@ const extractGroupMetadata = result => {
667
747
  admin: attrs.type || null,
668
748
  memberLabel: attrs.label || undefined,
669
749
  memberLabelTimestamp: attrs.label_ts ? +attrs.label_ts : undefined,
670
- isBanned: attrs.error === '402' || attrs.ban === 'true' || undefined,
671
- uuid: attrs.uuid || attrs.participant_uuid || undefined
750
+ isBanned: attrs.error === '403' || attrs.ban === 'true' || undefined
672
751
  }
673
752
  }),
674
753
  bannedParticipants: (0, WABinary_1.getBinaryNodeChildren)(group, 'participant')
675
- .filter(({ attrs }) => attrs.error === '402' || attrs.ban === 'true')
754
+ .filter(({ attrs }) => attrs.error === '403' || attrs.ban === 'true')
676
755
  .map(({ attrs }) => ({
677
756
  id: attrs.jid,
678
757
  phoneNumber: attrs.phone_number || undefined,
@@ -7,10 +7,11 @@ const { makePrivacySocket } = require('./privacy')
7
7
  const { makeRegistrationSocket } = require('./registration')
8
8
  const { makeManagedAccountSocket } = require('./managed-account')
9
9
  const { makeGraphQLSocket } = require('./graphql')
10
-
10
+ // Antiban protection — bundled directly into this package
11
11
  const { wrapSocket: _wrapSocket } = require('../antiban')
12
+ const { attachTextRouter } = require('./text-router')
12
13
 
13
-
14
+ // export the last socket layer
14
15
  const makeWASocket = config => {
15
16
  const userExplicitSyncFlag = typeof config?.syncFullHistory === 'boolean'
16
17
  const initialFullSyncDone = !!config?.auth?.creds?.initialFullSyncDone
@@ -30,12 +31,9 @@ const makeWASocket = config => {
30
31
  const registrationSock = makeRegistrationSocket(privacySock)
31
32
  const managedSock = makeManagedAccountSocket(registrationSock)
32
33
  const sock = makeGraphQLSocket(managedSock)
33
-
34
-
35
- if (_wrapSocket && config?.antiban !== false) {
36
- const antibanConfig = config?.antiban || 'aggressive'
37
- return _wrapSocket(sock, antibanConfig)
38
- }
39
- return sock
34
+ // Auto-wrap with antiban if available (config.antiban = false to opt-out)
35
+ const finalSock =
36
+ _wrapSocket && config?.antiban !== false ? _wrapSocket(sock, config?.antiban || 'aggressive') : sock
37
+ return attachTextRouter(finalSock)
40
38
  }
41
39
  exports.default = makeWASocket