@neelegirl/baileys 1.5.2 → 1.5.3
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/LICENSE +21 -21
- package/README.md +195 -187
- package/WAProto/WAProto.proto +537 -236
- package/WAProto/index.d.ts +5971 -2388
- package/WAProto/index.js +17298 -6513
- package/lib/Defaults/baileys-version.json +3 -3
- package/lib/Defaults/index.d.ts +77 -67
- package/lib/Defaults/index.js +148 -136
- package/lib/Defaults/phonenumber-mcc.json +223 -223
- package/lib/Signal/WASignalGroup/GroupProtocol.js +1908 -1908
- package/lib/Signal/WASignalGroup/ciphertext-message.d.ts +9 -0
- package/lib/Signal/WASignalGroup/ciphertext-message.js +19 -0
- package/lib/Signal/WASignalGroup/ciphertext_message.js +15 -15
- package/lib/Signal/WASignalGroup/group-session-builder.d.ts +17 -0
- package/lib/Signal/WASignalGroup/group-session-builder.js +72 -0
- package/lib/Signal/WASignalGroup/group.proto +41 -41
- package/lib/Signal/WASignalGroup/group_cipher.d.ts +19 -0
- package/lib/Signal/WASignalGroup/group_cipher.js +101 -110
- package/lib/Signal/WASignalGroup/group_session_builder.js +45 -45
- package/lib/Signal/WASignalGroup/index.d.ts +11 -0
- package/lib/Signal/WASignalGroup/index.js +61 -6
- package/lib/Signal/WASignalGroup/keyhelper.d.ts +16 -0
- package/lib/Signal/WASignalGroup/keyhelper.js +58 -13
- package/lib/Signal/WASignalGroup/protobufs.js +2 -2
- package/lib/Signal/WASignalGroup/queue_job.js +68 -68
- package/lib/Signal/WASignalGroup/readme.md +5 -5
- package/lib/Signal/WASignalGroup/sender-chain-key.d.ts +14 -0
- package/lib/Signal/WASignalGroup/sender-chain-key.js +47 -0
- package/lib/Signal/WASignalGroup/sender-key-distribution-message.d.ts +17 -0
- package/lib/Signal/WASignalGroup/sender-key-distribution-message.js +71 -0
- package/lib/Signal/WASignalGroup/sender-key-message.d.ts +19 -0
- package/lib/Signal/WASignalGroup/sender-key-message.js +73 -0
- package/lib/Signal/WASignalGroup/sender-key-name.d.ts +19 -0
- package/lib/Signal/WASignalGroup/sender-key-name.js +59 -0
- package/lib/Signal/WASignalGroup/sender-key-record.d.ts +32 -0
- package/lib/Signal/WASignalGroup/sender-key-record.js +58 -0
- package/lib/Signal/WASignalGroup/sender-key-state.d.ts +44 -0
- package/lib/Signal/WASignalGroup/sender-key-state.js +147 -0
- package/lib/Signal/WASignalGroup/sender-message-key.d.ts +11 -0
- package/lib/Signal/WASignalGroup/sender-message-key.js +33 -0
- package/lib/Signal/WASignalGroup/sender_chain_key.js +49 -49
- package/lib/Signal/WASignalGroup/sender_key_distribution_message.js +77 -77
- package/lib/Signal/WASignalGroup/sender_key_message.js +91 -91
- package/lib/Signal/WASignalGroup/sender_key_name.js +69 -69
- package/lib/Signal/WASignalGroup/sender_key_record.js +55 -55
- package/lib/Signal/WASignalGroup/sender_key_state.js +128 -128
- package/lib/Signal/WASignalGroup/sender_message_key.js +38 -38
- package/lib/Signal/libsignal.d.ts +5 -1
- package/lib/Signal/libsignal.js +390 -161
- package/lib/Signal/lid-mapping.d.ts +28 -0
- package/lib/Signal/lid-mapping.js +184 -0
- package/lib/Socket/Client/abstract-socket-client.d.ts +15 -15
- package/lib/Socket/Client/abstract-socket-client.js +13 -13
- package/lib/Socket/Client/index.d.ts +2 -2
- package/lib/Socket/Client/mobile-socket-client.d.ts +12 -12
- package/lib/Socket/Client/mobile-socket-client.js +65 -65
- package/lib/Socket/Client/types.d.ts +1 -1
- package/lib/Socket/Client/websocket.d.ts +1 -1
- package/lib/Socket/business.d.ts +6 -6
- package/lib/Socket/business.js +152 -5
- package/lib/Socket/chats.d.ts +3 -4
- package/lib/Socket/chats.js +31 -26
- package/lib/Socket/communities.d.ts +223 -223
- package/lib/Socket/communities.js +432 -432
- package/lib/Socket/groups.d.ts +2 -4
- package/lib/Socket/groups.js +22 -14
- package/lib/Socket/index.d.ts +69 -69
- package/lib/Socket/index.js +3 -2
- package/lib/Socket/messages-recv.d.ts +3 -6
- package/lib/Socket/messages-recv.js +1449 -1707
- package/lib/Socket/messages-send.d.ts +2 -4
- package/lib/Socket/messages-send.js +617 -126
- package/lib/Socket/mex.d.ts +2 -2
- package/lib/Socket/mex.js +46 -46
- package/lib/Socket/newsletter.d.ts +2 -4
- package/lib/Socket/newsletter.js +294 -285
- package/lib/Socket/socket.js +318 -132
- package/lib/Socket/usync.js +3 -3
- package/lib/Store/index.d.ts +4 -4
- package/lib/Store/index.js +23 -23
- package/lib/Store/make-cache-manager-store.d.ts +13 -13
- package/lib/Store/make-cache-manager-store.js +89 -89
- package/lib/Store/make-in-memory-store.d.ts +122 -122
- package/lib/Store/make-in-memory-store.js +428 -428
- package/lib/Store/make-ordered-dictionary.d.ts +11 -11
- package/lib/Store/make-ordered-dictionary.js +85 -85
- package/lib/Store/object-repository.d.ts +9 -9
- package/lib/Store/object-repository.js +30 -30
- package/lib/Types/Auth.d.ts +5 -4
- package/lib/Types/Bussines.js +3 -0
- package/lib/Types/Bussiness.d.ts +28 -0
- package/lib/Types/Chat.d.ts +13 -8
- package/lib/Types/Contact.d.ts +4 -1
- package/lib/Types/Events.d.ts +13 -16
- package/lib/Types/GroupMetadata.d.ts +1 -1
- package/lib/Types/Message.d.ts +18 -7
- package/lib/Types/Message.js +7 -1
- package/lib/Types/MexUpdates.d.ts +8 -8
- package/lib/Types/MexUpdates.js +17 -17
- package/lib/Types/Newsletter.d.ts +1 -1
- package/lib/Types/Product.d.ts +1 -1
- package/lib/Types/Signal.d.ts +31 -1
- package/lib/Types/Socket.d.ts +34 -13
- package/lib/Types/State.d.ts +1 -1
- package/lib/Types/USync.d.ts +2 -2
- package/lib/Types/index.d.ts +16 -15
- package/lib/Types/index.js +4 -2
- package/lib/Utils/auth-utils.d.ts +20 -20
- package/lib/Utils/auth-utils.js +527 -204
- package/lib/Utils/baileys-event-stream.d.ts +17 -17
- package/lib/Utils/baileys-event-stream.js +69 -69
- package/lib/Utils/business.d.ts +28 -28
- package/lib/Utils/business.js +254 -254
- package/lib/Utils/chat-utils.d.ts +81 -81
- package/lib/Utils/chat-utils.js +808 -780
- package/lib/Utils/crypto.d.ts +55 -55
- package/lib/Utils/crypto.js +188 -178
- package/lib/Utils/decode-wa-message.d.ts +52 -40
- package/lib/Utils/decode-wa-message.js +322 -252
- package/lib/Utils/event-buffer.d.ts +38 -38
- package/lib/Utils/event-buffer.js +594 -564
- package/lib/Utils/generics.d.ts +131 -129
- package/lib/Utils/generics.js +629 -623
- package/lib/Utils/history.d.ts +22 -22
- package/lib/Utils/history.js +103 -109
- package/lib/Utils/index.d.ts +20 -19
- package/lib/Utils/index.js +39 -38
- package/lib/Utils/link-preview.d.ts +22 -22
- package/lib/Utils/link-preview.js +119 -119
- package/lib/Utils/logger.d.ts +13 -13
- package/lib/Utils/logger.js +7 -7
- package/lib/Utils/lt-hash.d.ts +13 -13
- package/lib/Utils/lt-hash.js +57 -57
- package/lib/Utils/make-mutex.d.ts +8 -8
- package/lib/Utils/make-mutex.js +48 -48
- package/lib/Utils/message-retry-manager.d.ts +88 -0
- package/lib/Utils/message-retry-manager.js +160 -0
- package/lib/Utils/messages-media.d.ts +134 -128
- package/lib/Utils/messages-media.js +868 -805
- package/lib/Utils/messages.d.ts +104 -102
- package/lib/Utils/messages.js +1744 -1578
- package/lib/Utils/noise-handler.d.ts +20 -19
- package/lib/Utils/noise-handler.js +164 -154
- package/lib/Utils/process-message.d.ts +48 -48
- package/lib/Utils/process-message.js +427 -428
- package/lib/Utils/signal.d.ts +41 -41
- package/lib/Utils/signal.js +165 -165
- package/lib/Utils/use-mongo-file-auth-state.d.ts +5 -5
- package/lib/Utils/use-mongo-file-auth-state.js +83 -83
- package/lib/Utils/use-multi-file-auth-state.d.ts +17 -17
- package/lib/Utils/use-multi-file-auth-state.js +237 -237
- package/lib/Utils/use-single-file-auth-state.d.ts +12 -12
- package/lib/Utils/use-single-file-auth-state.js +79 -79
- package/lib/Utils/validate-connection.d.ts +12 -12
- package/lib/Utils/validate-connection.js +219 -186
- package/lib/WABinary/constants.d.ts +29 -29
- package/lib/WABinary/constants.js +1315 -1315
- package/lib/WABinary/decode.d.ts +8 -8
- package/lib/WABinary/decode.js +287 -287
- package/lib/WABinary/encode.d.ts +2 -2
- package/lib/WABinary/encode.js +264 -264
- package/lib/WABinary/generic-utils.d.ts +27 -27
- package/lib/WABinary/generic-utils.js +141 -141
- package/lib/WABinary/index.d.ts +5 -5
- package/lib/WABinary/index.js +24 -24
- package/lib/WABinary/jid-utils.d.ts +58 -53
- package/lib/WABinary/jid-utils.js +103 -91
- package/lib/WABinary/types.d.ts +21 -21
- package/lib/WABinary/types.js +2 -2
- package/lib/WAM/BinaryInfo.d.ts +15 -15
- package/lib/WAM/BinaryInfo.js +16 -16
- package/lib/WAM/constants.d.ts +46 -46
- package/lib/WAM/constants.js +15370 -15370
- package/lib/WAM/encode.d.ts +2 -2
- package/lib/WAM/encode.js +163 -164
- package/lib/WAM/index.d.ts +3 -3
- package/lib/WAM/index.js +22 -22
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.d.ts +27 -27
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +68 -68
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +3 -3
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/USyncLIDProtocol.d.ts +9 -8
- package/lib/WAUSync/Protocols/USyncLIDProtocol.js +37 -29
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/index.d.ts +6 -6
- package/lib/WAUSync/USyncQuery.d.ts +3 -3
- package/lib/WAUSync/index.d.ts +3 -3
- package/lib/index.d.ts +13 -13
- package/lib/index.js +33 -33
- package/package.json +96 -94
- package/lib/Socket/registration.d.ts +0 -266
- package/lib/Socket/registration.js +0 -166
package/lib/Socket/socket.js
CHANGED
|
@@ -12,6 +12,7 @@ const Types_1 = require("../Types")
|
|
|
12
12
|
const Utils_1 = require("../Utils")
|
|
13
13
|
const WABinary_1 = require("../WABinary")
|
|
14
14
|
const Client_1 = require("./Client")
|
|
15
|
+
const WAUSync_1 = require("../WAUSync")
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Connects to WA servers and performs:
|
|
@@ -22,6 +23,9 @@ const Client_1 = require("./Client")
|
|
|
22
23
|
const makeSocket = (config) => {
|
|
23
24
|
const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository } = config
|
|
24
25
|
|
|
26
|
+
const uqTagId = Utils_1.generateMdTagPrefix()
|
|
27
|
+
const generateMessageTag = () => `${uqTagId}${epoch++}`
|
|
28
|
+
|
|
25
29
|
const url = typeof waWebSocketUrl === 'string' ? new url_1.URL(waWebSocketUrl) : waWebSocketUrl
|
|
26
30
|
|
|
27
31
|
if (config.mobile || url.protocol === 'tcp:') {
|
|
@@ -32,6 +36,132 @@ const makeSocket = (config) => {
|
|
|
32
36
|
url.searchParams.append('ED', authState.creds.routingInfo.toString('base64url'))
|
|
33
37
|
}
|
|
34
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Wait for a message with a certain tag to be received
|
|
41
|
+
* @param msgId the message tag to await
|
|
42
|
+
* @param timeoutMs timeout after which the promise will reject
|
|
43
|
+
*/
|
|
44
|
+
const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
|
|
45
|
+
let onRecv
|
|
46
|
+
let onErr
|
|
47
|
+
try {
|
|
48
|
+
return await Utils_1.promiseTimeout(timeoutMs, (resolve, reject) => {
|
|
49
|
+
onRecv = resolve
|
|
50
|
+
onErr = err => {
|
|
51
|
+
reject(err || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }))
|
|
52
|
+
}
|
|
53
|
+
ws.on(`TAG:${msgId}`, onRecv)
|
|
54
|
+
ws.on('close', onErr) // if the socket closes, you'll never receive the message
|
|
55
|
+
ws.off('error', onErr)
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
finally {
|
|
60
|
+
ws.off(`TAG:${msgId}`, onRecv)
|
|
61
|
+
ws.off('close', onErr) // if the socket closes, you'll never receive the message
|
|
62
|
+
ws.off('error', onErr)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** send a query, and wait for its response. auto-generates message ID if not provided */
|
|
67
|
+
const query = async (node, timeoutMs) => {
|
|
68
|
+
if (!node.attrs.id) {
|
|
69
|
+
node.attrs.id = generateMessageTag()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const msgId = node.attrs.id
|
|
73
|
+
const wait = waitForMessage(msgId, timeoutMs)
|
|
74
|
+
|
|
75
|
+
await sendNode(node)
|
|
76
|
+
|
|
77
|
+
const result = await wait
|
|
78
|
+
|
|
79
|
+
if ('tag' in result) {
|
|
80
|
+
WABinary_1.assertNodeErrorFree(result)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return result
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const executeUSyncQuery = async (usyncQuery) => {
|
|
87
|
+
if (usyncQuery.protocols.length === 0) {
|
|
88
|
+
throw new boom_1.Boom('USyncQuery must have at least one protocol');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// todo: validate users, throw WARNING on no valid users
|
|
92
|
+
// variable below has only validated users
|
|
93
|
+
const validUsers = usyncQuery.users
|
|
94
|
+
const userNodes = validUsers.map(user => {
|
|
95
|
+
return {
|
|
96
|
+
tag: 'user',
|
|
97
|
+
attrs: {
|
|
98
|
+
jid: !user.phone ? user.id : undefined
|
|
99
|
+
},
|
|
100
|
+
content: usyncQuery.protocols.map(a => a.getUserElement(user)).filter(a => a !== null)
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
const listNode = {
|
|
105
|
+
tag: 'list',
|
|
106
|
+
attrs: {},
|
|
107
|
+
content: userNodes
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const queryNode = {
|
|
111
|
+
tag: 'query',
|
|
112
|
+
attrs: {},
|
|
113
|
+
content: usyncQuery.protocols.map(a => a.getQueryElement())
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const iq = {
|
|
117
|
+
tag: 'iq',
|
|
118
|
+
attrs: {
|
|
119
|
+
to: WABinary_1._WHATSAPP_NET,
|
|
120
|
+
type: 'get',
|
|
121
|
+
xmlns: 'usync'
|
|
122
|
+
},
|
|
123
|
+
content: [
|
|
124
|
+
{
|
|
125
|
+
tag: 'usync',
|
|
126
|
+
attrs: {
|
|
127
|
+
context: usyncQuery.context,
|
|
128
|
+
mode: usyncQuery.mode,
|
|
129
|
+
sid: generateMessageTag(),
|
|
130
|
+
last: 'true',
|
|
131
|
+
index: '0'
|
|
132
|
+
},
|
|
133
|
+
content: [queryNode, listNode]
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const result = await query(iq)
|
|
139
|
+
return usyncQuery.parseUSyncQueryResult(result)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const onWhatsApp = async (...jids) => {
|
|
143
|
+
const usyncQuery = new WAUSync_1.USyncQuery().withLIDProtocol().withContactProtocol()
|
|
144
|
+
for (const jid of jids) {
|
|
145
|
+
if (WABinary_1.isLidUser(jid)) {
|
|
146
|
+
usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid)) // intentional
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
const phone = `+${jid.replace('+', '').split('@')[0]?.split(':')[0]}`
|
|
150
|
+
usyncQuery.withUser(new WAUSync_1.USyncUser().withPhone(phone))
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const results = await executeUSyncQuery(usyncQuery)
|
|
154
|
+
if (results) {
|
|
155
|
+
if (results.list.filter(a => !!a.lid).length > 0) {
|
|
156
|
+
const lidOnly = results.list.filter(a => !!a.lid)
|
|
157
|
+
await signalRepository.lidMapping.storeLIDPNMappings(lidOnly.map(a => ({ pn: a.id, lid: a.lid })))
|
|
158
|
+
}
|
|
159
|
+
return results.list
|
|
160
|
+
.filter(a => !!a.contact)
|
|
161
|
+
.map(({ contact, id, lid }) => ({ jid: id, exists: contact, lid: lid }))
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
35
165
|
const ws = new Client_1.WebSocketClient(url, config)
|
|
36
166
|
|
|
37
167
|
ws.connect()
|
|
@@ -52,7 +182,7 @@ const makeSocket = (config) => {
|
|
|
52
182
|
|
|
53
183
|
// add transaction capability
|
|
54
184
|
const keys = Utils_1.addTransactionCapability(authState.keys, logger, transactionOpts)
|
|
55
|
-
const signalRepository = makeSignalRepository({ creds, keys })
|
|
185
|
+
const signalRepository = makeSignalRepository({ creds, keys }, onWhatsApp, logger)
|
|
56
186
|
|
|
57
187
|
let lastDateRecv
|
|
58
188
|
let epoch = 1
|
|
@@ -60,8 +190,6 @@ const makeSocket = (config) => {
|
|
|
60
190
|
let qrTimer
|
|
61
191
|
let closed = false
|
|
62
192
|
|
|
63
|
-
const uqTagId = Utils_1.generateMdTagPrefix()
|
|
64
|
-
const generateMessageTag = () => `${uqTagId}${epoch++}`
|
|
65
193
|
const sendPromise = util_1.promisify(ws.send)
|
|
66
194
|
|
|
67
195
|
/** send a raw buffer */
|
|
@@ -128,52 +256,6 @@ const makeSocket = (config) => {
|
|
|
128
256
|
return result
|
|
129
257
|
}
|
|
130
258
|
|
|
131
|
-
/**
|
|
132
|
-
* Wait for a message with a certain tag to be received
|
|
133
|
-
* @param msgId the message tag to await
|
|
134
|
-
* @param timeoutMs timeout after which the promise will reject
|
|
135
|
-
*/
|
|
136
|
-
const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
|
|
137
|
-
let onRecv
|
|
138
|
-
let onErr
|
|
139
|
-
try {
|
|
140
|
-
return await Utils_1.promiseTimeout(timeoutMs, (resolve, reject) => {
|
|
141
|
-
onRecv = resolve
|
|
142
|
-
onErr = err => {
|
|
143
|
-
reject(err || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }))
|
|
144
|
-
}
|
|
145
|
-
ws.on(`TAG:${msgId}`, onRecv)
|
|
146
|
-
ws.on('close', onErr) // if the socket closes, you'll never receive the message
|
|
147
|
-
ws.off('error', onErr)
|
|
148
|
-
})
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
finally {
|
|
152
|
-
ws.off(`TAG:${msgId}`, onRecv)
|
|
153
|
-
ws.off('close', onErr) // if the socket closes, you'll never receive the message
|
|
154
|
-
ws.off('error', onErr)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/** send a query, and wait for its response. auto-generates message ID if not provided */
|
|
159
|
-
const query = async (node, timeoutMs) => {
|
|
160
|
-
if (!node.attrs.id) {
|
|
161
|
-
node.attrs.id = generateMessageTag()
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const msgId = node.attrs.id
|
|
165
|
-
const wait = waitForMessage(msgId, timeoutMs)
|
|
166
|
-
|
|
167
|
-
await sendNode(node)
|
|
168
|
-
|
|
169
|
-
const result = await wait
|
|
170
|
-
|
|
171
|
-
if ('tag' in result) {
|
|
172
|
-
WABinary_1.assertNodeErrorFree(result)
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return result
|
|
176
|
-
}
|
|
177
259
|
/** connection handshake */
|
|
178
260
|
const validateConnection = async () => {
|
|
179
261
|
let helloMsg = {
|
|
@@ -232,23 +314,111 @@ const makeSocket = (config) => {
|
|
|
232
314
|
return +countChild.attrs.value
|
|
233
315
|
}
|
|
234
316
|
|
|
317
|
+
// Pre-key upload state management
|
|
318
|
+
let uploadPreKeysPromise = null
|
|
319
|
+
let lastUploadTime = 0
|
|
320
|
+
|
|
235
321
|
/** generates and uploads a set of pre-keys to the server */
|
|
236
|
-
const uploadPreKeys = async (count = Defaults_1.INITIAL_PREKEY_COUNT) => {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
322
|
+
const uploadPreKeys = async (count = Defaults_1.INITIAL_PREKEY_COUNT, retryCount = 0) => {
|
|
323
|
+
// Check minimum interval (except for retries)
|
|
324
|
+
if (retryCount === 0) {
|
|
325
|
+
const timeSinceLastUpload = Date.now() - lastUploadTime
|
|
326
|
+
if (timeSinceLastUpload < Defaults_1.MIN_UPLOAD_INTERVAL) {
|
|
327
|
+
logger.debug(`Skipping upload, only ${timeSinceLastUpload}ms since last upload`)
|
|
328
|
+
return
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Prevent multiple concurrent uploads
|
|
333
|
+
if (uploadPreKeysPromise) {
|
|
334
|
+
logger.debug('Pre-key upload already in progress, waiting for completion')
|
|
335
|
+
return uploadPreKeysPromise
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const uploadLogic = async () => {
|
|
339
|
+
logger.info({ count, retryCount }, 'uploading pre-keys')
|
|
340
|
+
|
|
341
|
+
// Generate and save pre-keys atomically (prevents ID collisions on retry)
|
|
342
|
+
const node = await keys.transaction(async () => {
|
|
343
|
+
logger.debug({ requestedCount: count }, 'generating pre-keys with requested count')
|
|
344
|
+
const { update, node } = await Utils_1.getNextPreKeysNode({ creds, keys }, count)
|
|
345
|
+
|
|
346
|
+
// Update credentials immediately to prevent duplicate IDs on retry
|
|
347
|
+
ev.emit('creds.update', update)
|
|
348
|
+
|
|
349
|
+
return node // Only return node since update is already used
|
|
350
|
+
}, creds?.me?.id || 'upload-pre-keys')
|
|
351
|
+
|
|
352
|
+
// Upload to server (outside transaction, can fail without affecting local keys)
|
|
353
|
+
try {
|
|
354
|
+
await query(node)
|
|
355
|
+
logger.info({ count }, 'uploaded pre-keys successfully')
|
|
356
|
+
lastUploadTime = Date.now()
|
|
357
|
+
}
|
|
358
|
+
catch (uploadError) {
|
|
359
|
+
logger.error({ uploadError, count }, 'Failed to upload pre-keys to server')
|
|
360
|
+
// Exponential backoff retry (max 3 retries)
|
|
361
|
+
if (retryCount < 3) {
|
|
362
|
+
const backoffDelay = Math.min(1000 * Math.pow(2, retryCount), 10000)
|
|
363
|
+
logger.info(`Retrying pre-key upload in ${backoffDelay}ms`)
|
|
364
|
+
await new Promise(resolve => setTimeout(resolve, backoffDelay))
|
|
365
|
+
return uploadPreKeys(count, retryCount + 1)
|
|
366
|
+
}
|
|
367
|
+
throw uploadError
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Add timeout protection
|
|
372
|
+
uploadPreKeysPromise = Promise.race([
|
|
373
|
+
uploadLogic(),
|
|
374
|
+
new Promise((_, reject) => setTimeout(() => reject(new boom_1.Boom('Pre-key upload timeout', { statusCode: 408 })), Defaults_1.UPLOAD_TIMEOUT))
|
|
375
|
+
])
|
|
376
|
+
try {
|
|
377
|
+
await uploadPreKeysPromise
|
|
378
|
+
}
|
|
379
|
+
finally {
|
|
380
|
+
uploadPreKeysPromise = null
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const verifyCurrentPreKeyExists = async () => {
|
|
385
|
+
const currentPreKeyId = creds.nextPreKeyId - 1
|
|
386
|
+
if (currentPreKeyId <= 0) {
|
|
387
|
+
return { exists: false, currentPreKeyId: 0 }
|
|
388
|
+
}
|
|
389
|
+
const preKeys = await keys.get('pre-key', [currentPreKeyId.toString()])
|
|
390
|
+
const exists = !!preKeys[currentPreKeyId.toString()]
|
|
391
|
+
return { exists, currentPreKeyId }
|
|
244
392
|
}
|
|
245
393
|
|
|
246
394
|
const uploadPreKeysToServerIfRequired = async () => {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
395
|
+
try {
|
|
396
|
+
const preKeyCount = await getAvailablePreKeysOnServer()
|
|
397
|
+
const { exists: currentPreKeyExists, currentPreKeyId } = await verifyCurrentPreKeyExists()
|
|
398
|
+
|
|
399
|
+
logger.info(`${preKeyCount} pre-keys found on server`)
|
|
400
|
+
logger.info(`Current prekey ID: ${currentPreKeyId}, exists in storage: ${currentPreKeyExists}`)
|
|
401
|
+
|
|
402
|
+
const lowServerCount = preKeyCount <= Defaults_1.MIN_PREKEY_COUNT
|
|
403
|
+
const missingCurrentPreKey = !currentPreKeyExists && currentPreKeyId > 0
|
|
404
|
+
const shouldUpload = lowServerCount || missingCurrentPreKey
|
|
405
|
+
|
|
406
|
+
if (shouldUpload) {
|
|
407
|
+
const reasons = []
|
|
408
|
+
if (lowServerCount)
|
|
409
|
+
reasons.push(`server count low (${preKeyCount})`)
|
|
410
|
+
if (missingCurrentPreKey)
|
|
411
|
+
reasons.push(`current prekey ${currentPreKeyId} missing from storage`)
|
|
412
|
+
logger.info(`Uploading PreKeys due to: ${reasons.join(', ')}`)
|
|
413
|
+
await uploadPreKeys()
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
logger.info(`PreKey validation passed - Server: ${preKeyCount}, Current prekey ${currentPreKeyId} exists`)
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
catch (error) {
|
|
420
|
+
logger.error({ error }, 'Failed to check/upload pre-keys during initialization')
|
|
421
|
+
// Don't throw - allow connection to continue even if pre-key check fails
|
|
252
422
|
}
|
|
253
423
|
}
|
|
254
424
|
|
|
@@ -426,66 +596,66 @@ const makeSocket = (config) => {
|
|
|
426
596
|
end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }))
|
|
427
597
|
}
|
|
428
598
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
599
|
+
const requestPairingCode = async (phoneNumber, code) => {
|
|
600
|
+
authState.creds.pairingCode = code?.toUpperCase() || Utils_1.asciiDecode([83, 85, 75, 49, 67, 72, 52, 78])
|
|
601
|
+
|
|
602
|
+
authState.creds.me = {
|
|
603
|
+
id: WABinary_1.jidEncode(phoneNumber, 's.whatsapp.net'),
|
|
604
|
+
name: '~'
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
ev.emit('creds.update', authState.creds)
|
|
608
|
+
|
|
609
|
+
await sendNode({
|
|
610
|
+
tag: 'iq',
|
|
611
|
+
attrs: {
|
|
612
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
613
|
+
type: 'set',
|
|
614
|
+
id: generateMessageTag(),
|
|
615
|
+
xmlns: 'md'
|
|
616
|
+
},
|
|
617
|
+
content: [
|
|
618
|
+
{
|
|
619
|
+
tag: 'link_code_companion_reg',
|
|
620
|
+
attrs: {
|
|
621
|
+
jid: authState.creds.me.id,
|
|
622
|
+
stage: 'companion_hello',
|
|
623
|
+
// eslint-disable-next-line camelcase
|
|
624
|
+
should_show_push_notification: 'true'
|
|
625
|
+
},
|
|
626
|
+
content: [
|
|
627
|
+
{
|
|
628
|
+
tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
|
|
629
|
+
attrs: {},
|
|
630
|
+
content: await generatePairingKey()
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
tag: 'companion_server_auth_key_pub',
|
|
634
|
+
attrs: {},
|
|
635
|
+
content: authState.creds.noiseKey.public
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
tag: 'companion_platform_id',
|
|
639
|
+
attrs: {},
|
|
640
|
+
content: Utils_1.getPlatformId(browser[1])
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
tag: 'companion_platform_display',
|
|
644
|
+
attrs: {},
|
|
645
|
+
content: `${browser[1]} (${browser[0]})`
|
|
646
|
+
},
|
|
647
|
+
{
|
|
648
|
+
tag: 'link_code_pairing_nonce',
|
|
649
|
+
attrs: {},
|
|
650
|
+
content: '0'
|
|
651
|
+
}
|
|
652
|
+
]
|
|
653
|
+
}
|
|
654
|
+
]
|
|
655
|
+
})
|
|
656
|
+
|
|
657
|
+
return authState.creds.pairingCode
|
|
658
|
+
}
|
|
489
659
|
|
|
490
660
|
async function generatePairingKey() {
|
|
491
661
|
const salt = crypto_1.randomBytes(32)
|
|
@@ -601,19 +771,32 @@ const makeSocket = (config) => {
|
|
|
601
771
|
ws.on('CB:success', async (node) => {
|
|
602
772
|
try {
|
|
603
773
|
await uploadPreKeysToServerIfRequired()
|
|
604
|
-
|
|
605
774
|
await sendPassiveIq('active')
|
|
606
|
-
|
|
607
|
-
logger.info('opened connection to WA')
|
|
608
|
-
|
|
609
|
-
clearTimeout(qrTimer) // will never happen in all likelyhood -- but just in case WA sends success on first try
|
|
610
|
-
ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } })
|
|
611
|
-
ev.emit('connection.update', { connection: 'open' })
|
|
612
775
|
}
|
|
613
|
-
|
|
614
776
|
catch (err) {
|
|
615
|
-
logger.
|
|
616
|
-
|
|
777
|
+
logger.warn({ err }, 'failed to send initial passive iq');
|
|
778
|
+
}
|
|
779
|
+
logger.info('opened connection to WA')
|
|
780
|
+
clearTimeout(qrTimer); // will never happen in all likelyhood -- but just in case WA sends success on first try
|
|
781
|
+
ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } })
|
|
782
|
+
ev.emit('connection.update', { connection: 'open' })
|
|
783
|
+
if (node.attrs.lid && authState.creds.me?.id) {
|
|
784
|
+
const myLID = node.attrs.lid
|
|
785
|
+
process.nextTick(async () => {
|
|
786
|
+
try {
|
|
787
|
+
const myPN = authState.creds.me.id
|
|
788
|
+
|
|
789
|
+
// Store our own LID-PN mapping
|
|
790
|
+
await signalRepository.lidMapping.storeLIDPNMappings([{ lid: myLID, pn: myPN }])
|
|
791
|
+
|
|
792
|
+
// Create LID session for ourselves (whatsmeow pattern)
|
|
793
|
+
await signalRepository.migrateSession([myPN], myLID)
|
|
794
|
+
logger.info({ myPN, myLID }, 'Own LID session created successfully')
|
|
795
|
+
}
|
|
796
|
+
catch (error) {
|
|
797
|
+
logger.error({ error, lid: myLID }, 'Failed to create own LID session')
|
|
798
|
+
}
|
|
799
|
+
})
|
|
617
800
|
}
|
|
618
801
|
})
|
|
619
802
|
|
|
@@ -730,6 +913,9 @@ const makeSocket = (config) => {
|
|
|
730
913
|
/** Waits for the connection to WA to reach a state */
|
|
731
914
|
waitForConnectionUpdate: Utils_1.bindWaitForConnectionUpdate(ev),
|
|
732
915
|
sendWAMBuffer,
|
|
916
|
+
executeUSyncQuery,
|
|
917
|
+
onWhatsApp,
|
|
918
|
+
logger
|
|
733
919
|
}
|
|
734
920
|
}
|
|
735
921
|
|
package/lib/Socket/usync.js
CHANGED
|
@@ -7,8 +7,8 @@ const WABinary_1 = require("../WABinary")
|
|
|
7
7
|
const socket_1 = require("./socket")
|
|
8
8
|
|
|
9
9
|
const makeUSyncSocket = (config) => {
|
|
10
|
-
const
|
|
11
|
-
const { generateMessageTag, query, } =
|
|
10
|
+
const baron = socket_1.makeSocket(config)
|
|
11
|
+
const { generateMessageTag, query, } = baron
|
|
12
12
|
|
|
13
13
|
const executeUSyncQuery = async (usyncQuery) => {
|
|
14
14
|
if (usyncQuery.protocols.length === 0) {
|
|
@@ -73,7 +73,7 @@ const makeUSyncSocket = (config) => {
|
|
|
73
73
|
return usyncQuery.parseUSyncQueryResult(result)
|
|
74
74
|
}
|
|
75
75
|
return {
|
|
76
|
-
...
|
|
76
|
+
...baron,
|
|
77
77
|
executeUSyncQuery
|
|
78
78
|
}
|
|
79
79
|
}
|
package/lib/Store/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from '
|
|
2
|
-
export * from '
|
|
3
|
-
export * from '
|
|
4
|
-
export * from '
|
|
1
|
+
export * from '@neelegirl/baileys/lib/Store/make-cache-manager-store'
|
|
2
|
+
export * from '@neelegirl/baileys/lib/Store/make-in-memory-store'
|
|
3
|
+
export * from '@neelegirl/baileys/lib/Store/make-ordered-dictionary'
|
|
4
|
+
export * from '@neelegirl/baileys/lib/Store/object-repository'
|
package/lib/Store/index.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
"use strict"
|
|
2
|
-
|
|
3
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
-
if (k2 === undefined) k2 = k
|
|
5
|
-
var desc = Object.getOwnPropertyDescriptor(m, k)
|
|
6
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
-
desc = { enumerable: true, get: function() { return m[k] } }
|
|
8
|
-
}
|
|
9
|
-
Object.defineProperty(o, k2, desc)
|
|
10
|
-
}) : (function(o, m, k, k2) {
|
|
11
|
-
if (k2 === undefined) k2 = k
|
|
12
|
-
o[k2] = m[k]
|
|
13
|
-
}))
|
|
14
|
-
|
|
15
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
16
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
Object.defineProperty(exports, "__esModule", { value: true })
|
|
20
|
-
|
|
21
|
-
__exportStar(require("./make-cache-manager-store"), exports)
|
|
22
|
-
__exportStar(require("./make-in-memory-store"), exports)
|
|
23
|
-
__exportStar(require("./make-ordered-dictionary"), exports)
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k)
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k] } }
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc)
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k
|
|
12
|
+
o[k2] = m[k]
|
|
13
|
+
}))
|
|
14
|
+
|
|
15
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
16
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
20
|
+
|
|
21
|
+
__exportStar(require("./make-cache-manager-store"), exports)
|
|
22
|
+
__exportStar(require("./make-in-memory-store"), exports)
|
|
23
|
+
__exportStar(require("./make-ordered-dictionary"), exports)
|
|
24
24
|
__exportStar(require("./object-repository"), exports)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Store } from 'cache-manager'
|
|
2
|
-
import { AuthenticationCreds } from '
|
|
3
|
-
|
|
4
|
-
export declare const makeCacheManagerAuthState: (store: Store, sessionKey: string) => Promise<{
|
|
5
|
-
clearState: () => Promise<void>
|
|
6
|
-
saveCreds: () => Promise<void>
|
|
7
|
-
state: {
|
|
8
|
-
creds: AuthenticationCreds
|
|
9
|
-
keys: {
|
|
10
|
-
get: (type: string, ids: string[]) => Promise<{}>
|
|
11
|
-
set: (data: any) => Promise<void>
|
|
12
|
-
}
|
|
13
|
-
}
|
|
1
|
+
import { Store } from 'cache-manager'
|
|
2
|
+
import { AuthenticationCreds } from '@neelegirl/baileys/lib/Types'
|
|
3
|
+
|
|
4
|
+
export declare const makeCacheManagerAuthState: (store: Store, sessionKey: string) => Promise<{
|
|
5
|
+
clearState: () => Promise<void>
|
|
6
|
+
saveCreds: () => Promise<void>
|
|
7
|
+
state: {
|
|
8
|
+
creds: AuthenticationCreds
|
|
9
|
+
keys: {
|
|
10
|
+
get: (type: string, ids: string[]) => Promise<{}>
|
|
11
|
+
set: (data: any) => Promise<void>
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
14
|
}>
|