@badzz88/baileys 8.4.9 → 8.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/WAProto/WAProto.proto +6 -347
- package/WAProto/fix-imports.js +85 -86
- package/WAProto/index.d.ts +25 -4913
- package/WAProto/index.js +93 -14069
- package/{src → lib}/Defaults/index.js +2 -13
- package/{src → lib}/Signal/Group/group_cipher.js +5 -5
- package/{src → lib}/Signal/Group/keyhelper.js +4 -4
- package/{src → lib}/Signal/Group/sender-chain-key.js +2 -2
- package/{src → lib}/Signal/Group/sender-key-distribution-message.js +1 -1
- package/{src → lib}/Signal/Group/sender-key-message.js +3 -3
- package/{src → lib}/Signal/Group/sender-key-record.js +1 -1
- package/{src → lib}/Signal/Group/sender-message-key.js +2 -2
- package/{src → lib}/Signal/libsignal.js +26 -6
- package/{src → lib}/Socket/chats.js +58 -616
- package/{src → lib}/Socket/communities.js +28 -59
- package/{src → lib}/Socket/graphql.js +103 -362
- package/{src → lib}/Socket/groups.js +29 -77
- package/{src → lib}/Socket/index.js +5 -3
- package/{src → lib}/Socket/interactive-handler.js +60 -117
- package/{src → lib}/Socket/interop.js +19 -36
- package/lib/Socket/luxu.js +387 -0
- package/{src → lib}/Socket/managed-account.js +27 -58
- package/{src → lib}/Socket/messages-recv.js +143 -715
- package/{src → lib}/Socket/messages-send.js +102 -412
- package/lib/Socket/mex.js +60 -0
- package/{src → lib}/Socket/newsletter.js +23 -266
- package/{src → lib}/Socket/privacy.js +38 -41
- package/{src → lib}/Socket/registration.js +106 -113
- package/{src → lib}/Socket/socket.js +101 -88
- package/{src → lib}/Socket/text-router.js +17 -1
- package/lib/Socket/username.js +243 -0
- package/lib/Store/keyed-db.js +108 -0
- package/{src → lib}/Store/make-in-memory-store.js +104 -6
- package/lib/Types/Mex.js +112 -0
- package/{src → lib}/Types/Newsletter.js +41 -72
- package/{src → lib}/Types/index.js +1 -0
- package/{src → lib}/Utils/chat-utils.js +9 -73
- 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 +155 -0
- package/lib/Utils/curve25519-js.js +275 -0
- package/{src → lib}/Utils/decode-wa-message.js +36 -284
- package/{src → lib}/Utils/event-buffer.js +27 -6
- package/{src → lib}/Utils/generics.js +37 -114
- package/{src → lib}/Utils/index.js +5 -1
- package/lib/Utils/lt-hash.js +39 -0
- package/{src → lib}/Utils/message-retry-manager.js +39 -0
- package/{src → lib}/Utils/messages-media.js +58 -105
- package/{src → lib}/Utils/messages.js +529 -115
- package/lib/Utils/meta-ai-msmsg.js +262 -0
- package/lib/Utils/native-bridge.js +82 -0
- package/{src → lib}/Utils/noise-handler.js +15 -13
- package/{src → lib}/Utils/process-message.js +55 -54
- package/{src → 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/{src → lib}/Utils/signal.js +51 -19
- package/{src → lib}/Utils/stanza-ack.js +2 -36
- package/lib/Utils/sticker.d.ts +17 -0
- package/lib/Utils/sticker.js +145 -0
- package/{src → lib}/Utils/tc-token-utils.js +1 -1
- package/{src → lib}/Utils/validate-connection.js +11 -40
- package/lib/Utils/view-once-cache.d.ts +9 -0
- package/lib/Utils/view-once-cache.js +79 -0
- package/{src → lib}/WABinary/decode.js +4 -38
- package/lib/WABinary/encode.js +228 -0
- package/{src → lib}/WABinary/generic-utils.js +93 -1
- package/{src → lib}/WABinary/jid-utils.js +3 -16
- package/{src → lib}/WAM/encode.js +1 -1
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +43 -0
- package/{src → lib}/WAUSync/Protocols/USyncContactProtocol.js +1 -7
- package/{src → lib}/WAUSync/Protocols/USyncDeviceProtocol.js +5 -13
- package/{src → lib}/WAUSync/Protocols/USyncDisappearingModeProtocol.js +4 -1
- package/{src → lib}/WAUSync/Protocols/USyncFeatureProtocol.js +2 -17
- package/{src → lib}/WAUSync/Protocols/USyncStatusProtocol.js +2 -7
- package/{src → lib}/WAUSync/Protocols/USyncUsernameProtocol.js +1 -2
- package/{src → lib}/WAUSync/Protocols/index.js +0 -1
- package/{src → lib}/WAUSync/USyncQuery.js +6 -77
- package/{src → lib}/WAUSync/USyncUser.js +8 -16
- package/{src → lib}/WAUSync/index.js +0 -1
- package/{src → lib}/antiban.js +266 -355
- package/{src → lib}/index.js +2 -2
- package/package.json +18 -15
- package/WAProto/fix-import.js +0 -38
- package/src/Socket/mex.js +0 -47
- package/src/Socket/username.js +0 -234
- package/src/Utils/crypto.js +0 -125
- package/src/Utils/lt-hash.js +0 -10
- package/src/Utils/message-inspect.js +0 -400
- package/src/Utils/meta-ai-msmsg.js +0 -133
- package/src/WABinary/encode.js +0 -58
- package/src/WAUSync/Protocols/USyncBusinessProtocol.js +0 -100
- package/src/WAUSync/USyncBackoff.js +0 -31
- /package/{src → lib}/Defaults/phonenumber-mcc.json +0 -0
- /package/{src → lib}/Signal/Group/ciphertext-message.js +0 -0
- /package/{src → lib}/Signal/Group/group-session-builder.js +0 -0
- /package/{src → lib}/Signal/Group/index.js +0 -0
- /package/{src → lib}/Signal/Group/sender-key-name.js +0 -0
- /package/{src → lib}/Signal/Group/sender-key-state.js +0 -0
- /package/{src → lib}/Signal/lid-mapping.js +0 -0
- /package/{src → lib}/Socket/Client/index.js +0 -0
- /package/{src → lib}/Socket/Client/types.js +0 -0
- /package/{src → lib}/Socket/Client/websocket.js +0 -0
- /package/{src → lib}/Socket/aigroups.js +0 -0
- /package/{src → lib}/Socket/business.js +0 -0
- /package/{src → lib}/Store/index.js +0 -0
- /package/{src → lib}/Store/make-cache-manager-store.js +0 -0
- /package/{src → lib}/Store/make-ordered-dictionary.js +0 -0
- /package/{src → lib}/Store/object-repository.js +0 -0
- /package/{src → lib}/Types/Auth.js +0 -0
- /package/{src → lib}/Types/Bussines.js +0 -0
- /package/{src → lib}/Types/Call.js +0 -0
- /package/{src → lib}/Types/Chat.js +0 -0
- /package/{src → lib}/Types/Contact.js +0 -0
- /package/{src → lib}/Types/Events.js +0 -0
- /package/{src → lib}/Types/GroupMetadata.js +0 -0
- /package/{src → lib}/Types/Label.js +0 -0
- /package/{src → lib}/Types/LabelAssociation.js +0 -0
- /package/{src → lib}/Types/Message.js +0 -0
- /package/{src → lib}/Types/Product.js +0 -0
- /package/{src → lib}/Types/Signal.js +0 -0
- /package/{src → lib}/Types/Socket.js +0 -0
- /package/{src → lib}/Types/State.js +0 -0
- /package/{src → lib}/Types/USync.js +0 -0
- /package/{src → lib}/Utils/auth-utils.js +0 -0
- /package/{src → lib}/Utils/browser-utils.js +0 -0
- /package/{src → lib}/Utils/business.js +0 -0
- /package/{src → lib}/Utils/consumer-application.js +0 -0
- /package/{src → lib}/Utils/group-history.js +0 -0
- /package/{src → lib}/Utils/history.js +0 -0
- /package/{src → lib}/Utils/identity-change-handler.js +0 -0
- /package/{src → lib}/Utils/jid-display-normalization.js +0 -0
- /package/{src → lib}/Utils/link-preview.js +0 -0
- /package/{src → lib}/Utils/logger.js +0 -0
- /package/{src → lib}/Utils/make-mutex.js +0 -0
- /package/{src → lib}/Utils/message-composer.js +0 -0
- /package/{src → lib}/Utils/offline-node-processor.js +0 -0
- /package/{src → lib}/Utils/pre-key-manager.js +0 -0
- /package/{src → lib}/Utils/sync-action-utils.js +0 -0
- /package/{src → lib}/Utils/use-multi-file-auth-state.js +0 -0
- /package/{src → lib}/Utils/voip-rekey.js +0 -0
- /package/{src → lib}/WABinary/constants.js +0 -0
- /package/{src → lib}/WABinary/index.js +0 -0
- /package/{src → lib}/WABinary/types.js +0 -0
- /package/{src → lib}/WAM/BinaryInfo.js +0 -0
- /package/{src → lib}/WAM/constants.js +0 -0
- /package/{src → lib}/WAM/index.js +0 -0
- /package/{src → lib}/WAUSync/Protocols/USyncBotProfileProtocol.js +0 -0
- /package/{src → lib}/WAUSync/Protocols/USyncLIDProtocol.js +0 -0
- /package/{src → lib}/WAUSync/Protocols/USyncPictureProtocol.js +0 -0
- /package/{src → lib}/WAUSync/Protocols/USyncSidelistProtocol.js +0 -0
- /package/{src → lib}/WAUSync/Protocols/USyncTextStatusProtocol.js +0 -0
|
@@ -46,32 +46,12 @@ const makeGroupsSocket = config => {
|
|
|
46
46
|
},
|
|
47
47
|
content
|
|
48
48
|
})
|
|
49
|
-
// Group metadata carries authoritative LID<->PN pairs for free (per-participant
|
|
50
|
-
// jid + phone_number/lid attrs). Persist them so the rest of the app can resolve
|
|
51
|
-
// PN<->LID without a separate usync round trip.
|
|
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
|
/**
|
|
77
57
|
* Acknowledge a group. Ported from WhatsApp Web's WASmaxGroupsAcknowledgeGroupRPC
|
|
@@ -139,29 +119,21 @@ const makeGroupsSocket = config => {
|
|
|
139
119
|
await groupQuery(parentJid, 'set', [{ tag: 'sub_group_suggestion', attrs: {}, content: suggestion }])
|
|
140
120
|
}
|
|
141
121
|
/**
|
|
142
|
-
* Approve
|
|
143
|
-
*
|
|
144
|
-
* approve/reject address suggestions by creator jid; cancel addresses them by
|
|
145
|
-
* the suggested group's jid (WASmaxOutGroupsSubGroupSuggestionsActionRequest).
|
|
122
|
+
* Approve or reject sub-group suggestions for a community. Ported from WhatsApp
|
|
123
|
+
* Web's WASmaxGroupsSubGroupSuggestionsActionRPC. NOTE: untested against live WhatsApp.
|
|
146
124
|
* @param {string} parentJid community/parent group to address
|
|
147
|
-
* @param {'approve' | 'reject'
|
|
148
|
-
* @param {Array<{ creator
|
|
125
|
+
* @param {'approve' | 'reject'} action
|
|
126
|
+
* @param {Array<{ creator: string, jid?: string }>} suggestions
|
|
149
127
|
*/
|
|
150
128
|
const groupSubGroupSuggestionsAction = async (parentJid, action, suggestions) => {
|
|
151
129
|
await groupQuery(parentJid, 'set', [
|
|
152
130
|
{
|
|
153
|
-
tag:
|
|
131
|
+
tag: action,
|
|
154
132
|
attrs: {},
|
|
155
|
-
content:
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
content: suggestions.map(s => ({
|
|
160
|
-
tag: 'sub_group_suggestion',
|
|
161
|
-
attrs: action === 'cancel' ? { jid: s.jid } : { creator: s.creator }
|
|
162
|
-
}))
|
|
163
|
-
}
|
|
164
|
-
]
|
|
133
|
+
content: suggestions.map(s => ({
|
|
134
|
+
tag: 'sub_group_suggestion',
|
|
135
|
+
attrs: { creator: s.creator, ...(s.jid ? { jid: s.jid } : {}) }
|
|
136
|
+
}))
|
|
165
137
|
}
|
|
166
138
|
])
|
|
167
139
|
}
|
|
@@ -197,9 +169,8 @@ const makeGroupsSocket = config => {
|
|
|
197
169
|
data[meta.id] = meta
|
|
198
170
|
}
|
|
199
171
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
sock.ev.emit('groups.update', allGroups)
|
|
172
|
+
// TODO: properly parse LID / PN DATA
|
|
173
|
+
sock.ev.emit('groups.update', Object.values(data))
|
|
203
174
|
return data
|
|
204
175
|
}
|
|
205
176
|
sock.ws.on('CB:ib,,dirty', async node => {
|
|
@@ -443,11 +414,8 @@ const makeGroupsSocket = config => {
|
|
|
443
414
|
const result = await groupQuery('@g.us', 'set', [
|
|
444
415
|
{
|
|
445
416
|
tag: 'create',
|
|
446
|
-
attrs: { subject, key },
|
|
447
|
-
content:
|
|
448
|
-
...participants.map(jid => ({ tag: 'participant', attrs: { jid } })),
|
|
449
|
-
{ tag: 'linked_parent', attrs: { jid: communityJid } }
|
|
450
|
-
]
|
|
417
|
+
attrs: { subject, key, parent_group_id: communityJid },
|
|
418
|
+
content: participants.map(jid => ({ tag: 'participant', attrs: { jid } }))
|
|
451
419
|
}
|
|
452
420
|
])
|
|
453
421
|
return (0, exports.extractGroupMetadata)(result)
|
|
@@ -522,18 +490,15 @@ const makeGroupsSocket = config => {
|
|
|
522
490
|
* Fetch group info via MEX (richer than IQ — includes invite link, LID addressing, etc.)
|
|
523
491
|
* @param {string} jid - Group JID
|
|
524
492
|
*/
|
|
525
|
-
groupQueryInfo: jid =>
|
|
493
|
+
groupQueryInfo: jid =>
|
|
494
|
+
mexQuery({ group_id: jid }, GROUP_MEX_QUERY_IDS.QUERY_INFO, 'xwa2_group_query_by_id'),
|
|
526
495
|
|
|
527
496
|
/**
|
|
528
497
|
* Fetch group info by invite code via MEX.
|
|
529
498
|
* @param {string} code - Group invite code (without the link prefix)
|
|
530
499
|
*/
|
|
531
500
|
groupQueryInfoByCode: code =>
|
|
532
|
-
mexQuery(
|
|
533
|
-
{ group_input: { invite_code: code } },
|
|
534
|
-
GROUP_MEX_QUERY_IDS.QUERY_INFO_BY_CODE,
|
|
535
|
-
'xwa2_group_query_by_id'
|
|
536
|
-
),
|
|
501
|
+
mexQuery({ group_input: { invite_code: code } }, GROUP_MEX_QUERY_IDS.QUERY_INFO_BY_CODE, 'xwa2_group_query_by_id'),
|
|
537
502
|
|
|
538
503
|
/**
|
|
539
504
|
* Fetch multiple groups at once via MEX.
|
|
@@ -610,7 +575,7 @@ const makeGroupsSocket = config => {
|
|
|
610
575
|
* @param {*} value - Property value
|
|
611
576
|
*/
|
|
612
577
|
groupSetProperty: (jid, property, value) =>
|
|
613
|
-
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'),
|
|
614
579
|
|
|
615
580
|
/**
|
|
616
581
|
* Reset a group's invite link via MEX (generates new code, invalidates old one).
|
|
@@ -693,7 +658,8 @@ const makeGroupsSocket = config => {
|
|
|
693
658
|
* Query online status of users from PDP.
|
|
694
659
|
* @param {string[]} jids - User JIDs
|
|
695
660
|
*/
|
|
696
|
-
queryOnlineStatus: jids =>
|
|
661
|
+
queryOnlineStatus: jids =>
|
|
662
|
+
mexQuery({ jids }, GROUP_MEX_QUERY_IDS.QUERY_ONLINE_STATUS, 'xwa2_query_online_status'),
|
|
697
663
|
|
|
698
664
|
/**
|
|
699
665
|
* Query online status and last seen of users from PDP.
|
|
@@ -732,11 +698,6 @@ const extractGroupMetadata = result => {
|
|
|
732
698
|
const communityMemberAddGroupNode = (0, WABinary_1.getBinaryNodeChild)(group, 'allow_non_admin_sub_group_creation')
|
|
733
699
|
const subGroupVisibilityNode = (0, WABinary_1.getBinaryNodeChild)(group, 'sub_groups_list')
|
|
734
700
|
const membershipApprovalNode = (0, WABinary_1.getBinaryNodeChild)(group, 'membership_approval_mode')
|
|
735
|
-
const capiNode = (0, WABinary_1.getBinaryNodeChild)(group, 'capi')
|
|
736
|
-
const appealStatusNode = (0, WABinary_1.getBinaryNodeChild)(group, 'appeal_status')
|
|
737
|
-
const defaultSubGroupNode = (0, WABinary_1.getBinaryNodeChild)(group, 'default_sub_group')
|
|
738
|
-
const generalChatNode = (0, WABinary_1.getBinaryNodeChild)(group, 'general_chat')
|
|
739
|
-
const hiddenGroupNode = (0, WABinary_1.getBinaryNodeChild)(group, 'hidden_group')
|
|
740
701
|
const metadata = {
|
|
741
702
|
id: groupId,
|
|
742
703
|
notify: group.attrs.notify,
|
|
@@ -766,23 +727,15 @@ const extractGroupMetadata = result => {
|
|
|
766
727
|
isCommunityAnnounce: !!(0, WABinary_1.getBinaryNodeChild)(group, 'default_sub_group'),
|
|
767
728
|
joinApprovalMode: !!membershipApprovalNode,
|
|
768
729
|
memberAddMode,
|
|
769
|
-
memberShareHistoryMode:
|
|
770
|
-
(0, WABinary_1.getBinaryNodeChildString)(group, '
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
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,
|
|
776
736
|
isSubGroupHidden: group.attrs.sub_group_visibility === 'hidden' || undefined,
|
|
777
|
-
membershipApprovalMode: group.attrs.membership_approval_mode || undefined,
|
|
778
|
-
joinPermissions: group.attrs.join_permissions || undefined,
|
|
779
|
-
isDefaultSubgroup: !!defaultSubGroupNode || undefined,
|
|
780
|
-
isGeneralSubgroup: !!generalChatNode || undefined,
|
|
781
|
-
isHiddenSubgroup: !!hiddenGroupNode || undefined,
|
|
782
737
|
participants: (0, WABinary_1.getBinaryNodeChildren)(group, 'participant').map(({ attrs }) => {
|
|
783
|
-
//
|
|
784
|
-
// callers (groupMetadata, groupFetchAllParticipating) persist the LID/PN
|
|
785
|
-
// pairs surfaced here via persistParticipantLidMappings.
|
|
738
|
+
// TODO: Store LID MAPPINGS
|
|
786
739
|
return {
|
|
787
740
|
id: attrs.jid,
|
|
788
741
|
phoneNumber:
|
|
@@ -794,12 +747,11 @@ const extractGroupMetadata = result => {
|
|
|
794
747
|
admin: attrs.type || null,
|
|
795
748
|
memberLabel: attrs.label || undefined,
|
|
796
749
|
memberLabelTimestamp: attrs.label_ts ? +attrs.label_ts : undefined,
|
|
797
|
-
isBanned: attrs.error === '
|
|
798
|
-
uuid: attrs.uuid || attrs.participant_uuid || undefined
|
|
750
|
+
isBanned: attrs.error === '403' || attrs.ban === 'true' || undefined
|
|
799
751
|
}
|
|
800
752
|
}),
|
|
801
753
|
bannedParticipants: (0, WABinary_1.getBinaryNodeChildren)(group, 'participant')
|
|
802
|
-
.filter(({ attrs }) => attrs.error === '
|
|
754
|
+
.filter(({ attrs }) => attrs.error === '403' || attrs.ban === 'true')
|
|
803
755
|
.map(({ attrs }) => ({
|
|
804
756
|
id: attrs.jid,
|
|
805
757
|
phoneNumber: attrs.phone_number || undefined,
|
|
@@ -7,9 +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
|
|
|
14
|
+
// export the last socket layer
|
|
13
15
|
const makeWASocket = config => {
|
|
14
16
|
const userExplicitSyncFlag = typeof config?.syncFullHistory === 'boolean'
|
|
15
17
|
const initialFullSyncDone = !!config?.auth?.creds?.initialFullSyncDone
|
|
@@ -29,9 +31,9 @@ const makeWASocket = config => {
|
|
|
29
31
|
const registrationSock = makeRegistrationSocket(privacySock)
|
|
30
32
|
const managedSock = makeManagedAccountSocket(registrationSock)
|
|
31
33
|
const sock = makeGraphQLSocket(managedSock)
|
|
34
|
+
// Auto-wrap with antiban if available (config.antiban = false to opt-out)
|
|
32
35
|
const finalSock =
|
|
33
36
|
_wrapSocket && config?.antiban !== false ? _wrapSocket(sock, config?.antiban || 'aggressive') : sock
|
|
34
|
-
|
|
35
37
|
return attachTextRouter(finalSock)
|
|
36
38
|
}
|
|
37
|
-
exports.default = makeWASocket
|
|
39
|
+
exports.default = makeWASocket
|
|
@@ -14,7 +14,7 @@ const {
|
|
|
14
14
|
} = require('../Utils/index.js')
|
|
15
15
|
const { isJidGroup, isPnUser, jidNormalizedUser, STORIES_JID } = require('../WABinary/index.js')
|
|
16
16
|
|
|
17
|
-
class
|
|
17
|
+
class InteractiveMessageHandler {
|
|
18
18
|
constructor(waUploadToServer, relayMessageFn, config, sock) {
|
|
19
19
|
this.relayMessage = relayMessageFn
|
|
20
20
|
this.waUploadToServer = waUploadToServer
|
|
@@ -24,12 +24,13 @@ class Badzz88Handler {
|
|
|
24
24
|
detectType(content) {
|
|
25
25
|
if (content.requestPaymentMessage) return 'PAYMENT'
|
|
26
26
|
if (content.productMessage) return 'PRODUCT'
|
|
27
|
-
if (content.interactiveButtons) return 'INTERACTIVE_BUTTONS'
|
|
28
27
|
if (content.interactiveMessage) return 'INTERACTIVE'
|
|
29
28
|
if (content.albumMessage || content.album) return 'ALBUM'
|
|
30
29
|
if (content.eventMessage) return 'EVENT'
|
|
31
30
|
if (content.pollResultMessage) return 'POLL_RESULT'
|
|
32
31
|
if (content.groupStatusMessage) return 'GROUP_STORY'
|
|
32
|
+
if (content.orderMessage) return 'ORDER'
|
|
33
|
+
if (content.groupLabel) return 'GROUP_LABEL'
|
|
33
34
|
return null
|
|
34
35
|
}
|
|
35
36
|
async handlePayment(content, quoted) {
|
|
@@ -222,114 +223,6 @@ class Badzz88Handler {
|
|
|
222
223
|
}
|
|
223
224
|
return { interactiveMessage }
|
|
224
225
|
}
|
|
225
|
-
async handleInteractiveButtons(content, _jid, _quoted) {
|
|
226
|
-
const {
|
|
227
|
-
text,
|
|
228
|
-
caption,
|
|
229
|
-
title,
|
|
230
|
-
subtitle,
|
|
231
|
-
footer,
|
|
232
|
-
interactiveButtons,
|
|
233
|
-
hasMediaAttachment,
|
|
234
|
-
image,
|
|
235
|
-
video,
|
|
236
|
-
document,
|
|
237
|
-
mimetype,
|
|
238
|
-
jpegThumbnail,
|
|
239
|
-
location,
|
|
240
|
-
product,
|
|
241
|
-
businessOwnerJid
|
|
242
|
-
} = content
|
|
243
|
-
const bodyText = text || caption || ''
|
|
244
|
-
const buttons = interactiveButtons.map(btn => ({
|
|
245
|
-
name: btn.name,
|
|
246
|
-
buttonParamsJson:
|
|
247
|
-
typeof btn.buttonParamsJson === 'string' ? btn.buttonParamsJson : JSON.stringify(btn.buttonParamsJson)
|
|
248
|
-
}))
|
|
249
|
-
let headerContent = {}
|
|
250
|
-
let mediaAttached = typeof hasMediaAttachment === 'boolean' ? hasMediaAttachment : false
|
|
251
|
-
if (image) {
|
|
252
|
-
const src = typeof image === 'object' && image.url ? { image: { url: image.url } } : { image }
|
|
253
|
-
const uploaded = await prepareWAMessageMedia(src, { upload: this.waUploadToServer })
|
|
254
|
-
headerContent = { ...uploaded }
|
|
255
|
-
mediaAttached = typeof hasMediaAttachment === 'boolean' ? hasMediaAttachment : true
|
|
256
|
-
} else if (video) {
|
|
257
|
-
const src = typeof video === 'object' && video.url ? { video: { url: video.url } } : { video }
|
|
258
|
-
const uploaded = await prepareWAMessageMedia(src, { upload: this.waUploadToServer })
|
|
259
|
-
headerContent = { ...uploaded }
|
|
260
|
-
mediaAttached = typeof hasMediaAttachment === 'boolean' ? hasMediaAttachment : true
|
|
261
|
-
} else if (document) {
|
|
262
|
-
const docPayload =
|
|
263
|
-
typeof document === 'object' && document.url ? { document: { url: document.url } } : { document }
|
|
264
|
-
if (mimetype) docPayload.mimetype = mimetype
|
|
265
|
-
const uploaded = await prepareWAMessageMedia(docPayload, { upload: this.waUploadToServer })
|
|
266
|
-
if (jpegThumbnail) {
|
|
267
|
-
uploaded.documentMessage.jpegThumbnail =
|
|
268
|
-
typeof jpegThumbnail === 'string' ? Buffer.from(jpegThumbnail, 'base64') : jpegThumbnail
|
|
269
|
-
}
|
|
270
|
-
headerContent = { ...uploaded }
|
|
271
|
-
mediaAttached = typeof hasMediaAttachment === 'boolean' ? hasMediaAttachment : true
|
|
272
|
-
} else if (location) {
|
|
273
|
-
headerContent = {
|
|
274
|
-
locationMessage: {
|
|
275
|
-
degreesLatitude: location.degressLatitude || location.degreesLatitude || 0,
|
|
276
|
-
degreesLongitude: location.degressLongitude || location.degreesLongitude || 0,
|
|
277
|
-
name: location.name || ''
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
mediaAttached = typeof hasMediaAttachment === 'boolean' ? hasMediaAttachment : true
|
|
281
|
-
} else if (product) {
|
|
282
|
-
let productImage
|
|
283
|
-
if (product.productImage) {
|
|
284
|
-
const imgSrc =
|
|
285
|
-
typeof product.productImage === 'object' && product.productImage.url
|
|
286
|
-
? { image: { url: product.productImage.url } }
|
|
287
|
-
: { image: product.productImage }
|
|
288
|
-
const uploaded = await prepareWAMessageMedia(imgSrc, { upload: this.waUploadToServer })
|
|
289
|
-
productImage = uploaded.imageMessage
|
|
290
|
-
}
|
|
291
|
-
headerContent = {
|
|
292
|
-
productMessage: {
|
|
293
|
-
product: {
|
|
294
|
-
productImage,
|
|
295
|
-
productId: product.productId,
|
|
296
|
-
title: product.title,
|
|
297
|
-
description: product.description,
|
|
298
|
-
currencyCode: product.currencyCode || 'IDR',
|
|
299
|
-
priceAmount1000: product.priceAmount1000,
|
|
300
|
-
retailerId: product.retailerId,
|
|
301
|
-
url: product.url,
|
|
302
|
-
productImageCount: product.productImageCount || 1
|
|
303
|
-
},
|
|
304
|
-
businessOwnerJid: businessOwnerJid || '0@s.whatsapp.net'
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
mediaAttached = typeof hasMediaAttachment === 'boolean' ? hasMediaAttachment : true
|
|
308
|
-
}
|
|
309
|
-
const interactiveMessage = {
|
|
310
|
-
body: { text: bodyText },
|
|
311
|
-
footer: { text: footer || '' },
|
|
312
|
-
header: {
|
|
313
|
-
title: title || '',
|
|
314
|
-
subtitle: subtitle || '',
|
|
315
|
-
hasMediaAttachment: mediaAttached,
|
|
316
|
-
...headerContent
|
|
317
|
-
},
|
|
318
|
-
nativeFlowMessage: { buttons }
|
|
319
|
-
}
|
|
320
|
-
return {
|
|
321
|
-
viewOnceMessage: {
|
|
322
|
-
message: {
|
|
323
|
-
messageContextInfo: {
|
|
324
|
-
deviceListMetadata: {},
|
|
325
|
-
deviceListMetadataVersion: 2,
|
|
326
|
-
messageSecret: crypto.randomBytes(32)
|
|
327
|
-
},
|
|
328
|
-
interactiveMessage
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
226
|
async handleAlbum(content, jid, quoted) {
|
|
334
227
|
const array = content.albumMessage || content.album
|
|
335
228
|
const ctxInfo = content.contextInfo || {}
|
|
@@ -344,7 +237,7 @@ class Badzz88Handler {
|
|
|
344
237
|
expectedVideoCount: array.filter(a => 'video' in a).length
|
|
345
238
|
}
|
|
346
239
|
},
|
|
347
|
-
{ userJid: jidNormalizedUser(this.sock.authState?.creds?.me?.id || '') }
|
|
240
|
+
{ userJid: jidNormalizedUser(this.sock.authState?.creds?.me?.id || ''), browser: this.config?.browser }
|
|
348
241
|
)
|
|
349
242
|
await this.relayMessage(jid, album.message, {
|
|
350
243
|
messageId: album.key.id
|
|
@@ -394,18 +287,18 @@ class Badzz88Handler {
|
|
|
394
287
|
joinLink: eventData.joinLink || '',
|
|
395
288
|
startTime:
|
|
396
289
|
typeof eventData.startTime === 'string'
|
|
397
|
-
? parseInt(eventData.startTime
|
|
290
|
+
? parseInt(eventData.startTime)
|
|
398
291
|
: eventData.startTime || Date.now(),
|
|
399
292
|
endTime:
|
|
400
293
|
typeof eventData.endTime === 'string'
|
|
401
|
-
? parseInt(eventData.endTime
|
|
294
|
+
? parseInt(eventData.endTime)
|
|
402
295
|
: eventData.endTime || Date.now() + 3600000,
|
|
403
296
|
extraGuestsAllowed: eventData.extraGuestsAllowed !== false
|
|
404
297
|
}
|
|
405
298
|
}
|
|
406
299
|
}
|
|
407
300
|
},
|
|
408
|
-
{ quoted, userJid: jidNormalizedUser(this.sock.authState?.creds?.me?.id || '') }
|
|
301
|
+
{ quoted, userJid: jidNormalizedUser(this.sock.authState?.creds?.me?.id || ''), browser: this.config?.browser }
|
|
409
302
|
)
|
|
410
303
|
await this.relayMessage(jid, msg.message, {
|
|
411
304
|
messageId: msg.key.id
|
|
@@ -426,7 +319,7 @@ class Badzz88Handler {
|
|
|
426
319
|
}))
|
|
427
320
|
}
|
|
428
321
|
},
|
|
429
|
-
{ quoted, userJid: jidNormalizedUser(this.sock.authState?.creds?.me?.id || '') }
|
|
322
|
+
{ quoted, userJid: jidNormalizedUser(this.sock.authState?.creds?.me?.id || ''), browser: this.config?.browser }
|
|
430
323
|
)
|
|
431
324
|
await this.relayMessage(jid, msg.message, {
|
|
432
325
|
messageId: msg.key.id
|
|
@@ -454,6 +347,55 @@ class Badzz88Handler {
|
|
|
454
347
|
messageId: generateMessageID()
|
|
455
348
|
})
|
|
456
349
|
}
|
|
350
|
+
async handleOrderMessage(content, jid, quoted) {
|
|
351
|
+
const orderData = content.orderMessage
|
|
352
|
+
const orderMsg = await generateWAMessageFromContent(jid, {
|
|
353
|
+
orderMessage: {
|
|
354
|
+
orderId: orderData.orderId || 'ORDER' + generateMessageID(),
|
|
355
|
+
thumbnail: orderData.thumbnail || null,
|
|
356
|
+
itemCount: orderData.itemCount || 0,
|
|
357
|
+
status: orderData.status || 'ACCEPTED',
|
|
358
|
+
surface: orderData.surface || 'CATALOG',
|
|
359
|
+
message: orderData.message,
|
|
360
|
+
orderTitle: orderData.orderTitle,
|
|
361
|
+
sellerJid: orderData.sellerJid || jid,
|
|
362
|
+
token: orderData.token || generateMessageID(),
|
|
363
|
+
totalAmount1000: orderData.totalAmount1000 || 0,
|
|
364
|
+
totalCurrencyCode: orderData.totalCurrencyCode || 'IDR',
|
|
365
|
+
messageVersion: 2
|
|
366
|
+
}
|
|
367
|
+
}, { quoted, browser: this.config?.browser })
|
|
368
|
+
await this.relayMessage(jid, orderMsg.message, {
|
|
369
|
+
messageId: orderMsg.key.id
|
|
370
|
+
})
|
|
371
|
+
return orderMsg
|
|
372
|
+
}
|
|
373
|
+
async handleGbLabel(content, jid) {
|
|
374
|
+
const labelData = content.groupLabel
|
|
375
|
+
if (!isJidGroup(jid)) {
|
|
376
|
+
throw new Error('handleGbLabel requires a group jid')
|
|
377
|
+
}
|
|
378
|
+
const msg = await generateWAMessageFromContent(jid, {
|
|
379
|
+
protocolMessage: {
|
|
380
|
+
type: 'GROUP_MEMBER_LABEL_CHANGE',
|
|
381
|
+
memberLabel: {
|
|
382
|
+
label: labelData.labelText.slice(0, 30)
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}, { browser: this.config?.browser })
|
|
386
|
+
return await this.relayMessage(jid, msg.message, {
|
|
387
|
+
additionalNodes: [
|
|
388
|
+
{
|
|
389
|
+
tag: 'meta',
|
|
390
|
+
attrs: {
|
|
391
|
+
tag_reason: 'user_update',
|
|
392
|
+
appdata: 'member_tag'
|
|
393
|
+
},
|
|
394
|
+
content: undefined
|
|
395
|
+
}
|
|
396
|
+
]
|
|
397
|
+
})
|
|
398
|
+
}
|
|
457
399
|
async sendStatusWhatsApp(content, jids = []) {
|
|
458
400
|
const userJid = jidNormalizedUser(this.sock.authState.creds.me.id)
|
|
459
401
|
const allUsers = new Set()
|
|
@@ -557,7 +499,8 @@ class Badzz88Handler {
|
|
|
557
499
|
}
|
|
558
500
|
}
|
|
559
501
|
const statusMsg = await generateWAMessageFromContent(normalizedId, protocolMessage, {
|
|
560
|
-
userJid: jidNormalizedUser(this.sock.authState?.creds?.me?.id || '')
|
|
502
|
+
userJid: jidNormalizedUser(this.sock.authState?.creds?.me?.id || ''),
|
|
503
|
+
browser: this.config?.browser
|
|
561
504
|
})
|
|
562
505
|
await this.relayMessage(normalizedId, statusMsg.message, {
|
|
563
506
|
additionalNodes: [
|
|
@@ -576,4 +519,4 @@ class Badzz88Handler {
|
|
|
576
519
|
}
|
|
577
520
|
}
|
|
578
521
|
|
|
579
|
-
module.exports = {
|
|
522
|
+
module.exports = { InteractiveMessageHandler }
|
|
@@ -5,19 +5,14 @@ exports.makeInteropSocket = void 0
|
|
|
5
5
|
const { getBinaryNodeChild, getBinaryNodeChildren, S_WHATSAPP_NET } = require('../WABinary')
|
|
6
6
|
const { executeWMexQuery } = require('./mex')
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* w:mex query IDs for interop group and privacy operations.
|
|
10
|
-
*
|
|
11
|
-
* Source: whatsapp-android-mex_client_persist_ids.json (WA 2.26.26.4 APK assets)
|
|
12
|
-
*/
|
|
13
8
|
const INTEROP_MEX_QUERY_IDS = {
|
|
14
|
-
CREATE_GROUP: '
|
|
15
|
-
LEAVE_GROUP: '
|
|
16
|
-
ADD_PARTICIPANTS: '
|
|
17
|
-
QUERY_GROUP_INFO: '
|
|
18
|
-
PRIVACY_SETTINGS_QUERY: '
|
|
19
|
-
PRIVACY_SETTINGS_UPDATE: '
|
|
20
|
-
PRIVACY_SETTINGS_WITH_CONTACT_LIST: '
|
|
9
|
+
CREATE_GROUP: '25726817620301612', // GroupsCreateInteropGroup
|
|
10
|
+
LEAVE_GROUP: '25346167795013270', // LeaveInteropGroup
|
|
11
|
+
ADD_PARTICIPANTS: '25732168276369452', // AddParticipantsToInteropGroup
|
|
12
|
+
QUERY_GROUP_INFO: '32734144032867936', // QueryInteropGroupInfo
|
|
13
|
+
PRIVACY_SETTINGS_QUERY: '24849123668112656', // InteropPrivacySettingsQuery
|
|
14
|
+
PRIVACY_SETTINGS_UPDATE: '25421856497452764', // InteropPrivacySettingsUpdate
|
|
15
|
+
PRIVACY_SETTINGS_WITH_CONTACT_LIST: '24913399124998600' // InteropPrivacySettingWithContactListUpdate
|
|
21
16
|
}
|
|
22
17
|
|
|
23
18
|
/**
|
|
@@ -40,7 +35,7 @@ const TOS_RESULT_ACCEPTED = '160'
|
|
|
40
35
|
const INTEROP_BATCH_MAX = 256
|
|
41
36
|
|
|
42
37
|
const makeInteropSocket = sock => {
|
|
43
|
-
const { query, generateMessageTag, logger, signalRepository
|
|
38
|
+
const { query, generateMessageTag, logger, signalRepository } = sock
|
|
44
39
|
|
|
45
40
|
const mexQuery = (variables, queryId, dataPath) =>
|
|
46
41
|
executeWMexQuery(variables, queryId, dataPath, query, generateMessageTag)
|
|
@@ -67,7 +62,7 @@ const makeInteropSocket = sock => {
|
|
|
67
62
|
return getBinaryNodeChildren(listNode, 'integrator').map(node => {
|
|
68
63
|
const featuresNode = getBinaryNodeChild(node, 'features')
|
|
69
64
|
return {
|
|
70
|
-
id: parseInt(node.attrs.id
|
|
65
|
+
id: parseInt(node.attrs.id),
|
|
71
66
|
name: node.attrs.name,
|
|
72
67
|
// "active" | "onboarding" | "removed"
|
|
73
68
|
status: node.attrs.status,
|
|
@@ -197,9 +192,9 @@ const makeInteropSocket = sock => {
|
|
|
197
192
|
if (errorNode) {
|
|
198
193
|
return {
|
|
199
194
|
externalId: userNode.attrs.external_id,
|
|
200
|
-
integratorId: parseInt(userNode.attrs.integrator_id
|
|
195
|
+
integratorId: parseInt(userNode.attrs.integrator_id),
|
|
201
196
|
error: {
|
|
202
|
-
code: parseInt(errorNode.attrs.code
|
|
197
|
+
code: parseInt(errorNode.attrs.code),
|
|
203
198
|
text: errorNode.attrs.text
|
|
204
199
|
}
|
|
205
200
|
}
|
|
@@ -208,7 +203,7 @@ const makeInteropSocket = sock => {
|
|
|
208
203
|
jid: userNode.attrs.jid,
|
|
209
204
|
externalId: userNode.attrs.external_id,
|
|
210
205
|
normalizedExternalId: userNode.attrs.normalized_external_id,
|
|
211
|
-
integratorId: parseInt(userNode.attrs.integrator_id
|
|
206
|
+
integratorId: parseInt(userNode.attrs.integrator_id)
|
|
212
207
|
}
|
|
213
208
|
})
|
|
214
209
|
}
|
|
@@ -239,7 +234,7 @@ const makeInteropSocket = sock => {
|
|
|
239
234
|
enabled: settingsNode.attrs?.enabled,
|
|
240
235
|
users: getBinaryNodeChildren(settingsNode, 'user').map(n => ({
|
|
241
236
|
externalId: n.attrs.external_id,
|
|
242
|
-
integratorId: parseInt(n.attrs.integrator_id
|
|
237
|
+
integratorId: parseInt(n.attrs.integrator_id),
|
|
243
238
|
jid: n.attrs.jid
|
|
244
239
|
}))
|
|
245
240
|
}
|
|
@@ -351,13 +346,7 @@ const makeInteropSocket = sock => {
|
|
|
351
346
|
} catch (err) {
|
|
352
347
|
logger.warn({ err }, 'interop: failed to opt-in integrators')
|
|
353
348
|
}
|
|
354
|
-
logger.info({ integrators: toOptIn.map(i => i.name) }, 'interop:
|
|
355
|
-
logger.warn(
|
|
356
|
-
{ integrators: toOptIn.map(i => i.name) },
|
|
357
|
-
'interop: receiving messages from interop contacts (BirdyChat/Haiket) is NOT YET SUPPORTED. ' +
|
|
358
|
-
'The interop bridge only delivers to device 0 (primary phone) via a single Signal session — ' +
|
|
359
|
-
'no fan-out to companion devices. Opt-in and sending may work, but inbound messages will not arrive.'
|
|
360
|
-
)
|
|
349
|
+
logger.info({ integrators: toOptIn.map(i => i.name) }, 'interop: initialized')
|
|
361
350
|
return integrators
|
|
362
351
|
}
|
|
363
352
|
|
|
@@ -439,7 +428,11 @@ const makeInteropSocket = sock => {
|
|
|
439
428
|
*/
|
|
440
429
|
const queryInteropGroupInfo = async groupJid => {
|
|
441
430
|
const gid = groupJid.split('@')[0]
|
|
442
|
-
return mexQuery(
|
|
431
|
+
return mexQuery(
|
|
432
|
+
{ group_input: { gid } },
|
|
433
|
+
INTEROP_MEX_QUERY_IDS.QUERY_GROUP_INFO,
|
|
434
|
+
'xwa2_interop_group_query_by_id'
|
|
435
|
+
)
|
|
443
436
|
}
|
|
444
437
|
|
|
445
438
|
/**
|
|
@@ -490,15 +483,6 @@ const makeInteropSocket = sock => {
|
|
|
490
483
|
)
|
|
491
484
|
}
|
|
492
485
|
|
|
493
|
-
/**
|
|
494
|
-
* Query all interop privacy settings via MEX.
|
|
495
|
-
* Uses InteropPrivacySettingsQuery (doc_id: 24849123668112654).
|
|
496
|
-
* Returns the current value for each privacy feature (e.g. GROUPADD).
|
|
497
|
-
* dataPath: xwa2_interop_privacy_settings
|
|
498
|
-
*/
|
|
499
|
-
const queryInteropPrivacySettings = () =>
|
|
500
|
-
mexQuery({}, INTEROP_MEX_QUERY_IDS.PRIVACY_SETTINGS_QUERY, 'xwa2_interop_privacy_settings')
|
|
501
|
-
|
|
502
486
|
/**
|
|
503
487
|
* Check whether an interop user allows being added to groups (GROUPADD privacy).
|
|
504
488
|
* Returns true if the user can be added, false if blocked by their privacy settings.
|
|
@@ -553,7 +537,6 @@ const makeInteropSocket = sock => {
|
|
|
553
537
|
leaveInteropGroup,
|
|
554
538
|
addParticipantsToInteropGroup,
|
|
555
539
|
queryInteropGroupInfo,
|
|
556
|
-
queryInteropPrivacySettings,
|
|
557
540
|
updateInteropPrivacySetting,
|
|
558
541
|
updateInteropPrivacySettingWithContactList,
|
|
559
542
|
getInteropGroupAddPrivacy,
|