@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.
- package/README.md +1 -1
- package/WAProto/WAProto.proto +75 -1256
- package/WAProto/index.d.ts +19729 -36122
- package/WAProto/index.js +132193 -178538
- package/engine-requirements.js +15 -7
- package/lib/Defaults/index.js +14 -22
- package/lib/Signal/Group/group_cipher.js +5 -5
- package/lib/Signal/Group/keyhelper.js +4 -4
- package/lib/Signal/Group/sender-chain-key.js +2 -2
- package/lib/Signal/Group/sender-key-distribution-message.js +1 -1
- package/lib/Signal/Group/sender-key-message.js +3 -3
- package/lib/Signal/Group/sender-key-record.js +1 -1
- package/lib/Signal/Group/sender-message-key.js +5 -5
- package/lib/Signal/libsignal.js +28 -39
- package/lib/Signal/lid-mapping.js +8 -28
- package/lib/Socket/aigroups.js +5 -5
- package/lib/Socket/business.js +11 -3
- package/lib/Socket/chats.js +319 -668
- package/lib/Socket/communities.js +89 -85
- package/lib/Socket/graphql.js +228 -435
- package/lib/Socket/groups.js +211 -132
- package/lib/Socket/index.js +7 -9
- package/lib/Socket/interactive-handler.js +60 -117
- package/lib/Socket/interop.js +175 -56
- package/lib/Socket/luxu.js +387 -0
- package/lib/Socket/managed-account.js +48 -79
- package/lib/Socket/messages-recv.js +340 -898
- package/lib/Socket/messages-send.js +160 -462
- package/lib/Socket/mex.js +53 -40
- package/lib/Socket/newsletter.js +295 -291
- package/lib/Socket/privacy.js +265 -77
- package/lib/Socket/registration.js +157 -164
- package/lib/Socket/socket.js +199 -181
- package/lib/Socket/text-router.js +83 -0
- package/lib/Socket/username.js +227 -144
- package/lib/Store/keyed-db.js +108 -0
- package/lib/Store/make-cache-manager-store.js +2 -2
- package/lib/Store/make-in-memory-store.js +141 -25
- package/lib/Types/Auth.js +3 -3
- package/lib/Types/Label.js +1 -1
- package/lib/Types/LabelAssociation.js +1 -1
- package/lib/Types/Mex.js +112 -0
- package/lib/Types/Newsletter.js +65 -96
- package/lib/Types/State.js +4 -4
- package/lib/Types/index.js +1 -1
- package/lib/Utils/auth-utils.js +57 -52
- package/lib/Utils/browser-utils.js +1 -1
- package/lib/Utils/business.js +6 -2
- package/lib/Utils/chat-utils.js +38 -102
- package/lib/Utils/command-loader.d.ts +31 -0
- package/lib/Utils/command-loader.js +100 -0
- package/lib/Utils/companion-reg-client-utils.js +42 -0
- package/lib/Utils/crypto.js +84 -54
- package/lib/Utils/curve25519-js.js +275 -0
- package/lib/Utils/decode-wa-message.js +83 -316
- package/lib/Utils/event-buffer.js +61 -37
- package/lib/Utils/generics.js +103 -157
- package/lib/Utils/group-history.js +12 -3
- package/lib/Utils/history.js +15 -15
- package/lib/Utils/index.js +5 -1
- package/lib/Utils/link-preview.js +8 -3
- package/lib/Utils/lt-hash.js +35 -2
- package/lib/Utils/make-mutex.js +1 -1
- package/lib/Utils/message-retry-manager.js +92 -27
- package/lib/Utils/messages-media.js +130 -159
- package/lib/Utils/messages.js +566 -144
- package/lib/Utils/meta-ai-msmsg.js +202 -62
- package/lib/Utils/native-bridge.js +82 -0
- package/lib/Utils/noise-handler.js +21 -19
- package/lib/Utils/offline-node-processor.js +8 -3
- package/lib/Utils/pre-key-manager.js +23 -13
- package/lib/Utils/process-message.js +106 -197
- package/lib/Utils/reporting-utils.js +2 -2
- package/lib/Utils/session-pool.d.ts +16 -0
- package/lib/Utils/session-pool.js +94 -0
- package/lib/Utils/signal.js +63 -28
- package/lib/Utils/stanza-ack.js +12 -39
- package/lib/Utils/sticker.d.ts +17 -0
- package/lib/Utils/sticker.js +145 -0
- package/lib/Utils/sync-action-utils.js +7 -4
- package/lib/Utils/tc-token-utils.js +25 -20
- package/lib/Utils/use-multi-file-auth-state.js +14 -30
- package/lib/Utils/validate-connection.js +19 -59
- package/lib/Utils/view-once-cache.d.ts +9 -0
- package/lib/Utils/view-once-cache.js +79 -0
- package/lib/WABinary/decode.js +16 -50
- package/lib/WABinary/encode.js +224 -54
- package/lib/WABinary/generic-utils.js +97 -7
- package/lib/WABinary/jid-utils.js +14 -27
- package/lib/WAM/encode.js +7 -7
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +1 -58
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +1 -7
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +5 -13
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +4 -1
- package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +7 -20
- package/lib/WAUSync/Protocols/USyncPictureProtocol.js +1 -1
- package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +2 -2
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +2 -7
- package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +1 -1
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +1 -2
- package/lib/WAUSync/Protocols/index.js +0 -1
- package/lib/WAUSync/USyncQuery.js +6 -77
- package/lib/WAUSync/USyncUser.js +8 -16
- package/lib/WAUSync/index.js +0 -1
- package/lib/antiban.js +854 -608
- package/lib/index.js +1 -1
- package/package.json +20 -16
package/lib/Socket/groups.js
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
131
|
+
tag: action,
|
|
121
132
|
attrs: {},
|
|
122
|
-
content:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
168
|
-
|
|
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
|
-
|
|
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, '
|
|
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
|
-
|
|
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, '
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
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 === '
|
|
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 === '
|
|
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,
|
package/lib/Socket/index.js
CHANGED
|
@@ -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
|
-
|
|
36
|
-
|
|
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
|