@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
|
@@ -13,12 +13,12 @@ exports.getBinaryNodeMessages =
|
|
|
13
13
|
exports.binaryNodeToString = binaryNodeToString
|
|
14
14
|
const boom_1 = require('@hapi/boom')
|
|
15
15
|
const index_js_1 = require('../../WAProto/index.js')
|
|
16
|
-
|
|
16
|
+
// some extra useful utilities
|
|
17
17
|
const indexCache = new WeakMap()
|
|
18
18
|
const getBinaryNodeChildren = (node, childTag) => {
|
|
19
19
|
if (!node || !Array.isArray(node.content)) return []
|
|
20
20
|
let index = indexCache.get(node)
|
|
21
|
-
|
|
21
|
+
// Build the index once per node
|
|
22
22
|
if (!index) {
|
|
23
23
|
index = new Map()
|
|
24
24
|
for (const child of node.content) {
|
|
@@ -28,7 +28,7 @@ const getBinaryNodeChildren = (node, childTag) => {
|
|
|
28
28
|
}
|
|
29
29
|
indexCache.set(node, index)
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
// Return first matching child
|
|
32
32
|
return index.get(childTag) || []
|
|
33
33
|
}
|
|
34
34
|
exports.getBinaryNodeChildren = getBinaryNodeChildren
|
|
@@ -53,7 +53,7 @@ exports.getBinaryNodeChildBuffer = getBinaryNodeChildBuffer
|
|
|
53
53
|
const getBinaryNodeChildString = (node, childTag) => {
|
|
54
54
|
const child = (0, exports.getBinaryNodeChild)(node, childTag)?.content
|
|
55
55
|
if (Buffer.isBuffer(child) || child instanceof Uint8Array) {
|
|
56
|
-
return Buffer.from(child).toString('
|
|
56
|
+
return Buffer.from(child).toString('utf-8')
|
|
57
57
|
} else if (typeof child === 'string') {
|
|
58
58
|
return child
|
|
59
59
|
}
|
|
@@ -61,9 +61,7 @@ const getBinaryNodeChildString = (node, childTag) => {
|
|
|
61
61
|
exports.getBinaryNodeChildString = getBinaryNodeChildString
|
|
62
62
|
const getBinaryNodeChildUInt = (node, childTag, length) => {
|
|
63
63
|
const buff = (0, exports.getBinaryNodeChildBuffer)(node, childTag)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (buff && buff.length >= length) {
|
|
64
|
+
if (buff) {
|
|
67
65
|
return bufferToUInt(buff, length)
|
|
68
66
|
}
|
|
69
67
|
}
|
|
@@ -119,6 +117,98 @@ const getBinaryFilteredBizBot = nodeContent => {
|
|
|
119
117
|
}
|
|
120
118
|
exports.getBinaryFilteredBizBot = getBinaryFilteredBizBot
|
|
121
119
|
|
|
120
|
+
const getAdditionalNode = name => {
|
|
121
|
+
if (name) name = name.toLowerCase()
|
|
122
|
+
const ts = Math.floor(Date.now() / 1000) - 77980457
|
|
123
|
+
const order_response_name = {
|
|
124
|
+
review_and_pay: 'order_details',
|
|
125
|
+
review_order: 'order_status',
|
|
126
|
+
order_status: 'order_status',
|
|
127
|
+
payment_info: 'payment_info',
|
|
128
|
+
payment_status: 'payment_status',
|
|
129
|
+
payment_method: 'payment_method',
|
|
130
|
+
catalog_message: 'catalog_message'
|
|
131
|
+
}
|
|
132
|
+
const flow_name = {
|
|
133
|
+
cta_catalog: 'cta_catalog',
|
|
134
|
+
mpm: 'mpm',
|
|
135
|
+
call_request: 'call_permission_request',
|
|
136
|
+
view_catalog: 'automated_greeting_message_view_catalog',
|
|
137
|
+
wa_pay_detail: 'wa_payment_transaction_details',
|
|
138
|
+
send_location: 'send_location',
|
|
139
|
+
payment_key_info: 'payment_key_info'
|
|
140
|
+
}
|
|
141
|
+
if (order_response_name[name]) {
|
|
142
|
+
return [
|
|
143
|
+
{
|
|
144
|
+
tag: 'biz',
|
|
145
|
+
attrs: {
|
|
146
|
+
native_flow_name: order_response_name[name]
|
|
147
|
+
},
|
|
148
|
+
content: []
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
} else if (flow_name[name] || name === 'interactive' || name === 'buttons') {
|
|
152
|
+
return [
|
|
153
|
+
{
|
|
154
|
+
tag: 'biz',
|
|
155
|
+
attrs: {
|
|
156
|
+
actual_actors: '2',
|
|
157
|
+
host_storage: '2',
|
|
158
|
+
privacy_mode_ts: `${ts}`
|
|
159
|
+
},
|
|
160
|
+
content: [
|
|
161
|
+
{
|
|
162
|
+
tag: 'engagement',
|
|
163
|
+
attrs: {
|
|
164
|
+
customer_service_state: 'open',
|
|
165
|
+
conversation_state: 'open'
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
tag: 'interactive',
|
|
170
|
+
attrs: {
|
|
171
|
+
type: 'native_flow',
|
|
172
|
+
v: '1'
|
|
173
|
+
},
|
|
174
|
+
content: [
|
|
175
|
+
{
|
|
176
|
+
tag: 'native_flow',
|
|
177
|
+
attrs: {
|
|
178
|
+
v: '9',
|
|
179
|
+
name: flow_name[name] ?? 'mixed'
|
|
180
|
+
},
|
|
181
|
+
content: []
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
} else {
|
|
189
|
+
return [
|
|
190
|
+
{
|
|
191
|
+
tag: 'biz',
|
|
192
|
+
attrs: {
|
|
193
|
+
actual_actors: '2',
|
|
194
|
+
host_storage: '2',
|
|
195
|
+
privacy_mode_ts: `${ts}`
|
|
196
|
+
},
|
|
197
|
+
content: [
|
|
198
|
+
{
|
|
199
|
+
tag: 'engagement',
|
|
200
|
+
attrs: {
|
|
201
|
+
customer_service_state: 'open',
|
|
202
|
+
conversation_state: 'open'
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
exports.getAdditionalNode = getAdditionalNode
|
|
211
|
+
|
|
122
212
|
function bufferToUInt(e, t) {
|
|
123
213
|
let a = 0
|
|
124
214
|
for (let i = 0; i < t; i++) {
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
3
|
exports.transferDevice =
|
|
4
4
|
exports.jidNormalizedUser =
|
|
5
|
-
exports.isJidLid =
|
|
6
5
|
exports.isJidBot =
|
|
7
6
|
exports.isHostedLidUser =
|
|
8
7
|
exports.isHostedPnUser =
|
|
@@ -24,13 +23,9 @@ exports.transferDevice =
|
|
|
24
23
|
exports.PSA_WID =
|
|
25
24
|
exports.SERVER_JID =
|
|
26
25
|
exports.OFFICIAL_BIZ_JID =
|
|
27
|
-
exports.BOT_WHATSAPP_NET =
|
|
28
|
-
exports.BOT_SERVER =
|
|
29
26
|
exports.S_WHATSAPP_NET =
|
|
30
27
|
void 0
|
|
31
28
|
exports.S_WHATSAPP_NET = '@s.whatsapp.net'
|
|
32
|
-
exports.BOT_WHATSAPP_NET = '@bot.whatsapp.net'
|
|
33
|
-
exports.BOT_SERVER = '@bot'
|
|
34
29
|
exports.OFFICIAL_BIZ_JID = '16505361212@c.us'
|
|
35
30
|
exports.SERVER_JID = 'server@c.us'
|
|
36
31
|
exports.PSA_WID = '0@c.us'
|
|
@@ -40,7 +35,6 @@ var WAJIDDomains
|
|
|
40
35
|
;(function (WAJIDDomains) {
|
|
41
36
|
WAJIDDomains[(WAJIDDomains['WHATSAPP'] = 0)] = 'WHATSAPP'
|
|
42
37
|
WAJIDDomains[(WAJIDDomains['LID'] = 1)] = 'LID'
|
|
43
|
-
WAJIDDomains[(WAJIDDomains['BOT'] = 2)] = 'BOT'
|
|
44
38
|
WAJIDDomains[(WAJIDDomains['HOSTED'] = 128)] = 'HOSTED'
|
|
45
39
|
WAJIDDomains[(WAJIDDomains['HOSTED_LID'] = 129)] = 'HOSTED_LID'
|
|
46
40
|
})(WAJIDDomains || (exports.WAJIDDomains = WAJIDDomains = {}))
|
|
@@ -48,8 +42,6 @@ const getServerFromDomainType = (initialServer, domainType) => {
|
|
|
48
42
|
switch (domainType) {
|
|
49
43
|
case WAJIDDomains.LID:
|
|
50
44
|
return 'lid'
|
|
51
|
-
case WAJIDDomains.BOT:
|
|
52
|
-
return 'bot'
|
|
53
45
|
case WAJIDDomains.HOSTED:
|
|
54
46
|
return 'hosted'
|
|
55
47
|
case WAJIDDomains.HOSTED_LID:
|
|
@@ -288,6 +280,7 @@ const jidEncode = (user, server, device, agent) => {
|
|
|
288
280
|
}
|
|
289
281
|
exports.jidEncode = jidEncode
|
|
290
282
|
const jidDecode = jid => {
|
|
283
|
+
// todo: investigate how to implement hosted ids in this case
|
|
291
284
|
const sepIdx = typeof jid === 'string' ? jid.indexOf('@') : -1
|
|
292
285
|
if (sepIdx < 0) {
|
|
293
286
|
return undefined
|
|
@@ -299,14 +292,12 @@ const jidDecode = jid => {
|
|
|
299
292
|
let domainType = WAJIDDomains.WHATSAPP
|
|
300
293
|
if (server === 'lid') {
|
|
301
294
|
domainType = WAJIDDomains.LID
|
|
302
|
-
} else if (server === 'bot') {
|
|
303
|
-
domainType = WAJIDDomains.BOT
|
|
304
295
|
} else if (server === 'hosted') {
|
|
305
296
|
domainType = WAJIDDomains.HOSTED
|
|
306
297
|
} else if (server === 'hosted.lid') {
|
|
307
298
|
domainType = WAJIDDomains.HOSTED_LID
|
|
308
299
|
} else if (agent) {
|
|
309
|
-
domainType = parseInt(agent
|
|
300
|
+
domainType = parseInt(agent)
|
|
310
301
|
}
|
|
311
302
|
return {
|
|
312
303
|
server: server,
|
|
@@ -316,45 +307,41 @@ const jidDecode = jid => {
|
|
|
316
307
|
}
|
|
317
308
|
}
|
|
318
309
|
exports.jidDecode = jidDecode
|
|
319
|
-
|
|
310
|
+
/** is the jid a user */
|
|
320
311
|
const areJidsSameUser = (jid1, jid2) => (0, exports.jidDecode)(jid1)?.user === (0, exports.jidDecode)(jid2)?.user
|
|
321
312
|
exports.areJidsSameUser = areJidsSameUser
|
|
322
|
-
|
|
313
|
+
/** is the jid Meta AI */
|
|
323
314
|
const isJidMetaAI = jid => jid?.endsWith('@bot')
|
|
324
315
|
exports.isJidMetaAI = isJidMetaAI
|
|
325
|
-
|
|
316
|
+
/** is the jid a PN user */
|
|
326
317
|
const isPnUser = jid => jid?.endsWith('@s.whatsapp.net')
|
|
327
318
|
exports.isPnUser = isPnUser
|
|
328
|
-
|
|
319
|
+
/** is the jid an interop (BirdyChat/Haiket) user */
|
|
329
320
|
const isInteropUser = jid => jid?.endsWith('@interop')
|
|
330
321
|
exports.isInteropUser = isInteropUser
|
|
331
|
-
|
|
322
|
+
/** is the jid a LID */
|
|
332
323
|
const isLidUser = jid => jid?.endsWith('@lid')
|
|
333
324
|
exports.isLidUser = isLidUser
|
|
334
|
-
|
|
335
|
-
const isJidLid = jid => jid?.endsWith('@lid')
|
|
336
|
-
exports.isJidLid = isJidLid
|
|
337
|
-
|
|
325
|
+
/** is the jid a broadcast */
|
|
338
326
|
const isJidBroadcast = jid => jid?.endsWith('@broadcast')
|
|
339
327
|
exports.isJidBroadcast = isJidBroadcast
|
|
340
|
-
|
|
328
|
+
/** is the jid a group */
|
|
341
329
|
const isJidGroup = jid => jid?.endsWith('@g.us')
|
|
342
330
|
exports.isJidGroup = isJidGroup
|
|
343
|
-
|
|
331
|
+
/** is the jid the status broadcast */
|
|
344
332
|
const isJidStatusBroadcast = jid => jid === 'status@broadcast'
|
|
345
333
|
exports.isJidStatusBroadcast = isJidStatusBroadcast
|
|
346
|
-
|
|
334
|
+
/** is the jid a newsletter */
|
|
347
335
|
const isJidNewsletter = jid => jid?.endsWith('@newsletter')
|
|
348
336
|
exports.isJidNewsletter = isJidNewsletter
|
|
349
|
-
|
|
337
|
+
/** is the jid a hosted PN */
|
|
350
338
|
const isHostedPnUser = jid => jid?.endsWith('@hosted')
|
|
351
339
|
exports.isHostedPnUser = isHostedPnUser
|
|
352
|
-
|
|
340
|
+
/** is the jid a hosted LID */
|
|
353
341
|
const isHostedLidUser = jid => jid?.endsWith('@hosted.lid')
|
|
354
342
|
exports.isHostedLidUser = isHostedLidUser
|
|
355
343
|
const botRegexp = /^1313555\d{4}$|^131655500\d{2}$/
|
|
356
|
-
|
|
357
|
-
const isJidBot = jid => jid && ((botRegexp.test(jid.split('@')[0]) && jid.endsWith('@c.us')) || jid.endsWith('@bot'))
|
|
344
|
+
const isJidBot = jid => jid && botRegexp.test(jid.split('@')[0]) && jid.endsWith('@c.us')
|
|
358
345
|
exports.isJidBot = isJidBot
|
|
359
346
|
const jidNormalizedUser = jid => {
|
|
360
347
|
const result = (0, exports.jidDecode)(jid)
|
package/lib/WAM/encode.js
CHANGED
|
@@ -18,12 +18,12 @@ const encodeWAM = binaryInfo => {
|
|
|
18
18
|
}
|
|
19
19
|
exports.encodeWAM = encodeWAM
|
|
20
20
|
function encodeWAMHeader(binaryInfo) {
|
|
21
|
-
const headerBuffer = Buffer.alloc(8)
|
|
21
|
+
const headerBuffer = Buffer.alloc(8) // starting buffer
|
|
22
22
|
headerBuffer.write('WAM', 0, 'utf8')
|
|
23
23
|
headerBuffer.writeUInt8(binaryInfo.protocolVersion, 3)
|
|
24
|
-
headerBuffer.writeUInt8(1, 4)
|
|
24
|
+
headerBuffer.writeUInt8(1, 4) //random flag
|
|
25
25
|
headerBuffer.writeUInt16BE(binaryInfo.sequence, 5)
|
|
26
|
-
headerBuffer.writeUInt8(0, 7)
|
|
26
|
+
headerBuffer.writeUInt8(0, 7) // regular channel
|
|
27
27
|
binaryInfo.buffer.push(headerBuffer)
|
|
28
28
|
}
|
|
29
29
|
function encodeGlobalAttributes(binaryInfo, globals) {
|
|
@@ -71,7 +71,7 @@ function serializeData(key, value, flag) {
|
|
|
71
71
|
return buffer
|
|
72
72
|
}
|
|
73
73
|
} else if (typeof value === 'number' && Number.isInteger(value)) {
|
|
74
|
-
|
|
74
|
+
// is number
|
|
75
75
|
if (value === 0 || value === 1) {
|
|
76
76
|
buffer = Buffer.alloc(bufferLength)
|
|
77
77
|
offset = serializeHeader(buffer, offset, key, flag | ((value + 1) << 4))
|
|
@@ -98,13 +98,13 @@ function serializeData(key, value, flag) {
|
|
|
98
98
|
return buffer
|
|
99
99
|
}
|
|
100
100
|
} else if (typeof value === 'number') {
|
|
101
|
-
|
|
101
|
+
// is float
|
|
102
102
|
buffer = Buffer.alloc(bufferLength + 8)
|
|
103
103
|
offset = serializeHeader(buffer, offset, key, flag | (7 << 4))
|
|
104
104
|
buffer.writeDoubleLE(value, offset)
|
|
105
105
|
return buffer
|
|
106
106
|
} else if (typeof value === 'string') {
|
|
107
|
-
|
|
107
|
+
// is string
|
|
108
108
|
const utf8Bytes = Buffer.byteLength(value, 'utf8')
|
|
109
109
|
if (utf8Bytes < 256) {
|
|
110
110
|
buffer = Buffer.alloc(bufferLength + 1 + utf8Bytes)
|
|
@@ -124,7 +124,7 @@ function serializeData(key, value, flag) {
|
|
|
124
124
|
buffer.write(value, offset, 'utf8')
|
|
125
125
|
return buffer
|
|
126
126
|
}
|
|
127
|
-
throw
|
|
127
|
+
throw 'missing'
|
|
128
128
|
}
|
|
129
129
|
function serializeHeader(buffer, offset, key, flag) {
|
|
130
130
|
if (key < 256) {
|
|
@@ -32,68 +32,11 @@ class USyncBusinessProtocol {
|
|
|
32
32
|
;(0, WABinary_1.assertNodeErrorFree)(node)
|
|
33
33
|
const verifiedNameNode = (0, WABinary_1.getBinaryNodeChild)(node, 'verified_name')
|
|
34
34
|
const profileNode = (0, WABinary_1.getBinaryNodeChild)(node, 'profile')
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
let businessHours = undefined
|
|
38
|
-
if (profileNode) {
|
|
39
|
-
const businessHoursNode = (0, WABinary_1.getBinaryNodeChild)(profileNode, 'business_hours')
|
|
40
|
-
if (businessHoursNode) {
|
|
41
|
-
const configs = (0, WABinary_1.getBinaryNodeChildren)(businessHoursNode, 'business_hours_config')
|
|
42
|
-
businessHours = {
|
|
43
|
-
timezone: businessHoursNode.attrs?.timezone ?? null,
|
|
44
|
-
config: configs.map(({ attrs }) => ({
|
|
45
|
-
dayOfWeek: attrs?.day_of_week ?? null,
|
|
46
|
-
openTime: attrs?.open_time ?? null,
|
|
47
|
-
closeTime: attrs?.close_time ?? null,
|
|
48
|
-
mode: attrs?.mode ?? null
|
|
49
|
-
}))
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const addressNode = profileNode ? (0, WABinary_1.getBinaryNodeChild)(profileNode, 'address') : null
|
|
56
|
-
const businessAddress = addressNode?.content
|
|
57
|
-
? Buffer.isBuffer(addressNode.content)
|
|
58
|
-
? addressNode.content.toString()
|
|
59
|
-
: String(addressNode.content)
|
|
60
|
-
: (profileNode?.attrs?.address ?? null)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const catalogStatus = profileNode
|
|
64
|
-
? {
|
|
65
|
-
exists: profileNode.attrs?.catalog_exists === 'true' || profileNode.attrs?.catalog_exists === true,
|
|
66
|
-
sendAll: profileNode.attrs?.catalog_send_all === 'true' || profileNode.attrs?.catalog_send_all === true
|
|
67
|
-
}
|
|
68
|
-
: null
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const cartEnabled =
|
|
72
|
-
profileNode?.attrs?.cart_enabled !== undefined
|
|
73
|
-
? profileNode.attrs.cart_enabled === 'true' || profileNode.attrs.cart_enabled === true
|
|
74
|
-
: null
|
|
75
|
-
const webCartEnabled =
|
|
76
|
-
profileNode?.attrs?.web_cart_enabled !== undefined
|
|
77
|
-
? profileNode.attrs.web_cart_enabled === 'true' || profileNode.attrs.web_cart_enabled === true
|
|
78
|
-
: null
|
|
79
|
-
const webCartOnOff = profileNode?.attrs?.web_cart_on_off ?? null
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const commerceExperience = profileNode?.attrs?.commerce_experience ?? null
|
|
83
|
-
|
|
84
35
|
return {
|
|
85
36
|
verifiedName: verifiedNameNode?.content ?? null,
|
|
86
37
|
verifiedLevel: verifiedNameNode?.attrs?.verified_level ?? null,
|
|
87
|
-
verifiedNameLevel: verifiedNameNode?.attrs?.verified_level ?? null,
|
|
88
38
|
profileTag: profileNode?.attrs?.tag ?? null,
|
|
89
|
-
pnJid: node.attrs?.pn_jid ?? null
|
|
90
|
-
businessHours: businessHours ?? null,
|
|
91
|
-
businessAddress,
|
|
92
|
-
catalogStatus,
|
|
93
|
-
cartEnabled,
|
|
94
|
-
webCartEnabled,
|
|
95
|
-
webCartOnOff,
|
|
96
|
-
commerceExperience
|
|
39
|
+
pnJid: node.attrs?.pn_jid ?? null
|
|
97
40
|
}
|
|
98
41
|
}
|
|
99
42
|
}
|
|
@@ -46,13 +46,7 @@ class USyncContactProtocol {
|
|
|
46
46
|
parser(node) {
|
|
47
47
|
if (node.tag === 'contact') {
|
|
48
48
|
;(0, WABinary_1.assertNodeErrorFree)(node)
|
|
49
|
-
|
|
50
|
-
const restrictionType = node?.attrs?.stella_addressbook_restriction_type
|
|
51
|
-
if (restrictionType !== undefined) {
|
|
52
|
-
|
|
53
|
-
return { inWA, stellaAddressbookRestrictionType: restrictionType }
|
|
54
|
-
}
|
|
55
|
-
return inWA
|
|
49
|
+
return node?.attrs?.type === 'in'
|
|
56
50
|
}
|
|
57
51
|
return false
|
|
58
52
|
}
|
|
@@ -14,19 +14,11 @@ class USyncDeviceProtocol {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
getUserElement(user) {
|
|
18
|
-
|
|
19
|
-
if
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const attrs = {}
|
|
23
|
-
if (deviceHash != null) attrs.device_hash = deviceHash
|
|
24
|
-
if (ts != null) attrs.ts = String(ts)
|
|
25
|
-
if (expectedTs != null) attrs.expected_ts = String(expectedTs)
|
|
26
|
-
return {
|
|
27
|
-
tag: 'devices',
|
|
28
|
-
attrs
|
|
29
|
-
}
|
|
17
|
+
getUserElement(/* user: USyncUser */) {
|
|
18
|
+
//TODO: Implement device phashing, ts and expectedTs
|
|
19
|
+
//TODO: if all are not present, return null <- current behavior
|
|
20
|
+
//TODO: otherwise return a node w tag 'devices' w those as attrs
|
|
21
|
+
return null
|
|
30
22
|
}
|
|
31
23
|
parser(node) {
|
|
32
24
|
const deviceList = []
|
|
@@ -20,7 +20,10 @@ class USyncDisappearingModeProtocol {
|
|
|
20
20
|
;(0, WABinary_1.assertNodeErrorFree)(node)
|
|
21
21
|
const duration = +node?.attrs.duration
|
|
22
22
|
const setAt = new Date(+(node?.attrs.t || 0) * 1000)
|
|
23
|
-
return {
|
|
23
|
+
return {
|
|
24
|
+
duration,
|
|
25
|
+
setAt
|
|
26
|
+
}
|
|
24
27
|
}
|
|
25
28
|
}
|
|
26
29
|
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
3
|
exports.USyncFeatureProtocol = exports.USYNC_FEATURES = void 0
|
|
4
4
|
const WABinary_1 = require('../../WABinary')
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
// Device feature flags that can be queried, ported from WhatsApp Web's
|
|
6
|
+
// WAWebUsyncFeature module.
|
|
7
7
|
exports.USYNC_FEATURES = [
|
|
8
8
|
'document',
|
|
9
9
|
'encrypt',
|
|
@@ -15,12 +15,12 @@ exports.USYNC_FEATURES = [
|
|
|
15
15
|
'encrypt_url',
|
|
16
16
|
'encrypt_v2',
|
|
17
17
|
'voip',
|
|
18
|
-
'
|
|
19
|
-
'multi_agent',
|
|
20
|
-
'bot_eligible'
|
|
18
|
+
'multi_agent'
|
|
21
19
|
]
|
|
22
20
|
class USyncFeatureProtocol {
|
|
23
|
-
|
|
21
|
+
/**
|
|
22
|
+
* @param {string[]} [features] feature names to query (defaults to all known)
|
|
23
|
+
*/
|
|
24
24
|
constructor(features) {
|
|
25
25
|
this.name = 'feature'
|
|
26
26
|
this.features = features && features.length ? features : exports.USYNC_FEATURES
|
|
@@ -46,24 +46,11 @@ class USyncFeatureProtocol {
|
|
|
46
46
|
errorText: errorNode.attrs?.text
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
const CAMEL_MAP = {
|
|
50
|
-
encrypt_v2: 'encryptV2',
|
|
51
|
-
voip_legacy: 'voipLegacy',
|
|
52
|
-
multi_agent: 'multiAgent',
|
|
53
|
-
bot_eligible: 'botEligible',
|
|
54
|
-
encrypt_blist: 'encryptBlist',
|
|
55
|
-
encrypt_contact: 'encryptContact',
|
|
56
|
-
encrypt_group_gen2: 'encryptGroupGen2',
|
|
57
|
-
encrypt_image: 'encryptImage',
|
|
58
|
-
encrypt_location: 'encryptLocation',
|
|
59
|
-
encrypt_url: 'encryptUrl'
|
|
60
|
-
}
|
|
61
49
|
const features = {}
|
|
62
50
|
const children = Array.isArray(node.content) ? node.content : []
|
|
63
51
|
for (const child of children) {
|
|
64
52
|
if (child?.attrs && child.attrs.value !== undefined) {
|
|
65
|
-
|
|
66
|
-
features[key] = child.attrs.value
|
|
53
|
+
features[child.tag] = child.attrs.value
|
|
67
54
|
}
|
|
68
55
|
}
|
|
69
56
|
return features
|
|
@@ -5,7 +5,7 @@ const WABinary_1 = require('../../WABinary')
|
|
|
5
5
|
class USyncSidelistProtocol {
|
|
6
6
|
constructor(useLidAddressing = true) {
|
|
7
7
|
this.name = 'sidelist'
|
|
8
|
-
|
|
8
|
+
// When true, sends addressing_mode="lid" — required for interop/LID-mode contacts
|
|
9
9
|
this.useLidAddressing = useLidAddressing
|
|
10
10
|
}
|
|
11
11
|
getQueryElement() {
|
|
@@ -22,7 +22,7 @@ class USyncSidelistProtocol {
|
|
|
22
22
|
parser(node) {
|
|
23
23
|
if (node.tag !== 'sidelist' && node.tag !== 'side_list') return null
|
|
24
24
|
;(0, WABinary_1.assertNodeErrorFree)(node)
|
|
25
|
-
|
|
25
|
+
// Returns minimal parsed data; the full side_list is parsed in USyncQuery
|
|
26
26
|
return { type: node.attrs?.type ?? null }
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -12,13 +12,8 @@ class USyncStatusProtocol {
|
|
|
12
12
|
attrs: {}
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
getUserElement(
|
|
16
|
-
|
|
17
|
-
return {
|
|
18
|
-
tag: 'tctoken',
|
|
19
|
-
attrs: {},
|
|
20
|
-
content: user.tcToken
|
|
21
|
-
}
|
|
15
|
+
getUserElement() {
|
|
16
|
+
return null
|
|
22
17
|
}
|
|
23
18
|
parser(node) {
|
|
24
19
|
if (node.tag === 'status') {
|
|
@@ -23,7 +23,7 @@ class USyncTextStatusProtocol {
|
|
|
23
23
|
const text = node.attrs?.text ?? null
|
|
24
24
|
const emojiNode = (0, WABinary_1.getBinaryNodeChild)(node, 'emoji')
|
|
25
25
|
const emoji = emojiNode?.attrs?.content ?? null
|
|
26
|
-
|
|
26
|
+
// expiry is lastUpdateTime + ephemeralDuration (both in ms); 0 means no expiry
|
|
27
27
|
const expiresAt = ephemeralDurationSec > 0
|
|
28
28
|
? new Date((lastUpdateTimeSec + ephemeralDurationSec) * 1000)
|
|
29
29
|
: null
|
|
@@ -19,8 +19,7 @@ class USyncUsernameProtocol {
|
|
|
19
19
|
parser(node) {
|
|
20
20
|
if (node.tag === 'username') {
|
|
21
21
|
;(0, WABinary_1.assertNodeErrorFree)(node)
|
|
22
|
-
|
|
23
|
-
return username && username.length > 0 ? username : null
|
|
22
|
+
return typeof node.content === 'string' ? node.content : null
|
|
24
23
|
}
|
|
25
24
|
return null
|
|
26
25
|
}
|
|
@@ -35,6 +35,5 @@ __exportStar(require('./USyncBotProfileProtocol'), exports)
|
|
|
35
35
|
__exportStar(require('./USyncBusinessProtocol'), exports)
|
|
36
36
|
__exportStar(require('./USyncPictureProtocol'), exports)
|
|
37
37
|
__exportStar(require('./USyncTextStatusProtocol'), exports)
|
|
38
|
-
__exportStar(require('./USyncLIDProtocol'), exports)
|
|
39
38
|
__exportStar(require('./USyncSidelistProtocol'), exports)
|
|
40
39
|
__exportStar(require('./USyncFeatureProtocol'), exports)
|
|
@@ -5,10 +5,10 @@ const WABinary_1 = require('../WABinary')
|
|
|
5
5
|
const USyncBotProfileProtocol_1 = require('./Protocols/USyncBotProfileProtocol')
|
|
6
6
|
const USyncLIDProtocol_1 = require('./Protocols/USyncLIDProtocol')
|
|
7
7
|
const USyncBusinessProtocol_1 = require('./Protocols/USyncBusinessProtocol')
|
|
8
|
-
const USyncFeatureProtocol_1 = require('./Protocols/USyncFeatureProtocol')
|
|
9
8
|
const USyncPictureProtocol_1 = require('./Protocols/USyncPictureProtocol')
|
|
10
9
|
const USyncTextStatusProtocol_1 = require('./Protocols/USyncTextStatusProtocol')
|
|
11
10
|
const USyncSidelistProtocol_1 = require('./Protocols/USyncSidelistProtocol')
|
|
11
|
+
const USyncFeatureProtocol_1 = require('./Protocols/USyncFeatureProtocol')
|
|
12
12
|
const Protocols_1 = require('./Protocols')
|
|
13
13
|
class USyncQuery {
|
|
14
14
|
constructor() {
|
|
@@ -39,85 +39,26 @@ class USyncQuery {
|
|
|
39
39
|
})
|
|
40
40
|
)
|
|
41
41
|
const queryResult = {
|
|
42
|
-
|
|
43
|
-
refresh: {},
|
|
42
|
+
// TODO: implement errors etc.
|
|
44
43
|
list: [],
|
|
45
44
|
sideList: []
|
|
46
45
|
}
|
|
47
46
|
const usyncNode = (0, WABinary_1.getBinaryNodeChild)(result, 'usync')
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const resultNode = usyncNode ? (0, WABinary_1.getBinaryNodeChild)(usyncNode, 'result') : undefined
|
|
53
|
-
if (resultNode) {
|
|
54
|
-
for (const protocol of this.protocols) {
|
|
55
|
-
const protocolNode = (0, WABinary_1.getBinaryNodeChild)(resultNode, protocol.name)
|
|
56
|
-
if (!protocolNode) continue
|
|
57
|
-
const errorNode = (0, WABinary_1.getBinaryNodeChild)(protocolNode, 'error')
|
|
58
|
-
if (errorNode) {
|
|
59
|
-
queryResult.errors[protocol.name] = {
|
|
60
|
-
errorCode: errorNode.attrs.code ? +errorNode.attrs.code : undefined,
|
|
61
|
-
errorText: errorNode.attrs.text,
|
|
62
|
-
errorBackoff: errorNode.attrs.backoff ? +errorNode.attrs.backoff : undefined
|
|
63
|
-
}
|
|
64
|
-
} else if (protocolNode.attrs.refresh !== undefined) {
|
|
65
|
-
queryResult.refresh[protocol.name] = +protocolNode.attrs.refresh
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
47
|
+
//TODO: implement error backoff, refresh etc.
|
|
48
|
+
//TODO: see if there are any errors in the result node
|
|
49
|
+
//const resultNode = getBinaryNodeChild(usyncNode, 'result')
|
|
69
50
|
const parseUserNodes = nodes => {
|
|
70
51
|
return nodes.reduce((acc, node) => {
|
|
71
52
|
const id = node?.attrs.jid
|
|
72
53
|
if (id) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const userErrorCode = node?.attrs?.error ? parseInt(node.attrs.error, 10) : 0
|
|
76
|
-
const isBlockedByAttr = userErrorCode === 401 || userErrorCode === 403 || userErrorCode === 405
|
|
77
|
-
|
|
78
54
|
const data = Array.isArray(node?.content)
|
|
79
55
|
? Object.fromEntries(
|
|
80
56
|
node.content
|
|
81
57
|
.map(content => {
|
|
82
58
|
const protocol = content.tag
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (protocol === 'privacy') {
|
|
87
|
-
const tokenNode = (0, WABinary_1.getBinaryNodeChild)(content, 'token')
|
|
88
|
-
const modeTsNode = (0, WABinary_1.getBinaryNodeChild)(content, 'mode_ts')
|
|
89
|
-
|
|
90
|
-
const tokenVal = tokenNode?.content || content.attrs?.token
|
|
91
|
-
const modeTsVal =
|
|
92
|
-
modeTsNode?.content?.toString?.() || modeTsNode?.attrs?.value || content.attrs?.mode_ts || null
|
|
93
|
-
if (tokenVal) {
|
|
94
|
-
return [
|
|
95
|
-
'privacy',
|
|
96
|
-
{
|
|
97
|
-
token:
|
|
98
|
-
Buffer.isBuffer(tokenVal) || tokenVal instanceof Uint8Array
|
|
99
|
-
? Buffer.from(tokenVal)
|
|
100
|
-
: tokenVal,
|
|
101
|
-
modeTs: modeTsVal
|
|
102
|
-
}
|
|
103
|
-
]
|
|
104
|
-
}
|
|
105
|
-
return ['privacy', null]
|
|
106
|
-
}
|
|
107
|
-
|
|
108
59
|
const parser = protocolMap[protocol]
|
|
109
60
|
if (parser) {
|
|
110
|
-
|
|
111
|
-
return [protocol, parser(content)]
|
|
112
|
-
} catch (err) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const errCode = err?.data ?? err?.output?.payload?.data
|
|
116
|
-
if (errCode === 401 || errCode === 403 || errCode === 405) {
|
|
117
|
-
return ['isBlockedByContact', true]
|
|
118
|
-
}
|
|
119
|
-
throw err
|
|
120
|
-
}
|
|
61
|
+
return [protocol, parser(content)]
|
|
121
62
|
} else {
|
|
122
63
|
return [protocol, null]
|
|
123
64
|
}
|
|
@@ -125,18 +66,6 @@ class USyncQuery {
|
|
|
125
66
|
.filter(([, b]) => b !== null)
|
|
126
67
|
)
|
|
127
68
|
: {}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (isBlockedByAttr) {
|
|
131
|
-
data.isBlockedByContact = true
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if ('disappearing_mode' in data) {
|
|
136
|
-
data.disappearingMode = data.disappearing_mode
|
|
137
|
-
delete data.disappearing_mode
|
|
138
|
-
}
|
|
139
|
-
|
|
140
69
|
acc.push({ ...data, id })
|
|
141
70
|
}
|
|
142
71
|
return acc
|