@hansaka02/baileys 7.3.4 → 7.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +203 -247
  2. package/lib/Defaults/baileys-version.json +2 -2
  3. package/lib/Defaults/connection.js +1 -1
  4. package/lib/Defaults/constants.js +13 -1
  5. package/lib/Defaults/history.js +3 -1
  6. package/lib/Signal/Group/sender-chain-key.js +1 -14
  7. package/lib/Signal/Group/sender-key-distribution-message.js +2 -2
  8. package/lib/Signal/Group/sender-key-record.js +2 -11
  9. package/lib/Signal/Group/sender-key-state.js +11 -57
  10. package/lib/Signal/libsignal.js +200 -116
  11. package/lib/Signal/lid-mapping.js +121 -68
  12. package/lib/Socket/Client/websocket.js +9 -2
  13. package/lib/Socket/business.js +5 -1
  14. package/lib/Socket/chats.js +180 -89
  15. package/lib/Socket/community.js +169 -41
  16. package/lib/Socket/groups.js +25 -21
  17. package/lib/Socket/messages-recv.js +458 -333
  18. package/lib/Socket/messages-send.js +517 -572
  19. package/lib/Socket/mex.js +61 -0
  20. package/lib/Socket/newsletter.js +159 -252
  21. package/lib/Socket/socket.js +283 -100
  22. package/lib/Types/Newsletter.js +32 -25
  23. package/lib/Utils/auth-utils.js +189 -354
  24. package/lib/Utils/browser-utils.js +43 -0
  25. package/lib/Utils/chat-utils.js +166 -41
  26. package/lib/Utils/decode-wa-message.js +77 -35
  27. package/lib/Utils/event-buffer.js +80 -24
  28. package/lib/Utils/generics.js +28 -128
  29. package/lib/Utils/history.js +10 -8
  30. package/lib/Utils/index.js +1 -1
  31. package/lib/Utils/link-preview.js +17 -32
  32. package/lib/Utils/lt-hash.js +28 -22
  33. package/lib/Utils/make-mutex.js +26 -28
  34. package/lib/Utils/message-retry-manager.js +51 -3
  35. package/lib/Utils/messages-media.js +343 -151
  36. package/lib/Utils/messages.js +806 -792
  37. package/lib/Utils/noise-handler.js +33 -2
  38. package/lib/Utils/pre-key-manager.js +126 -0
  39. package/lib/Utils/process-message.js +115 -55
  40. package/lib/Utils/signal.js +45 -18
  41. package/lib/Utils/validate-connection.js +52 -29
  42. package/lib/WABinary/constants.js +1268 -1268
  43. package/lib/WABinary/decode.js +58 -4
  44. package/lib/WABinary/encode.js +54 -7
  45. package/lib/WABinary/jid-utils.js +58 -11
  46. package/lib/WAM/constants.js +19064 -11563
  47. package/lib/WAM/encode.js +57 -8
  48. package/lib/WAUSync/USyncQuery.js +35 -19
  49. package/package.json +9 -8
  50. package/lib/Socket/usync.js +0 -83
@@ -3,34 +3,37 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true })
4
4
 
5
5
  const { LRUCache } = require("lru-cache")
6
- const {
6
+ const {
7
+ isHostedPnUser,
8
+ isLidUser,
9
+ isPnUser,
7
10
  jidDecode,
8
- isJidUser,
9
- isLidUser
11
+ jidNormalizedUser,
12
+ WAJIDDomains
10
13
  } = require("../WABinary")
11
14
 
12
15
  class LIDMappingStore {
13
- constructor(keys, onWhatsAppFunc, logger) {
14
- this.mappingCache = new LRUCache({
15
- ttl: 7 * 24 * 60 * 60 * 1000, // 7 days
16
+ constructor(keys, logger, pnToLIDFunc) {
17
+ this.mappingCache = new LRUCache({
18
+ ttl: 3 * 24 * 60 * 60 * 1000, // 7 days
16
19
  ttlAutopurge: true,
17
20
  updateAgeOnGet: true
18
21
  })
19
- this.keys = keys
20
- this.logger = logger
21
- this.onWhatsAppFunc = onWhatsAppFunc // needed to get LID from PN if not found
22
- }
23
- /**
22
+ this.keys = keys
23
+ this.pnToLIDFunc = pnToLIDFunc
24
+ this.logger = logger
25
+ }
26
+
27
+ /**
24
28
  * Store LID-PN mapping - USER LEVEL
25
29
  */
26
30
  async storeLIDPNMappings(pairs) {
27
31
  // Validate inputs
28
32
  const pairMap = {}
29
- const logger = this.logger
30
33
 
31
34
  for (const { lid, pn } of pairs) {
32
- if (!((isLidUser(lid) && isJidUser(pn)) || (isJidUser(lid) && isLidUser(pn)))) {
33
- logger.warn(`Invalid LID-PN mapping: ${lid}, ${pn}`)
35
+ if (!((isLidUser(lid) && isPnUser(pn)) || (isPnUser(lid) && isLidUser(pn)))) {
36
+ this.logger.warn(`Invalid LID-PN mapping: ${lid}, ${pn}`)
34
37
  continue
35
38
  }
36
39
 
@@ -42,11 +45,11 @@ class LIDMappingStore {
42
45
  const pnUser = pnDecoded.user
43
46
  const lidUser = lidDecoded.user
44
47
 
45
- // Check if mapping already exists (cache first, then database)
46
48
  let existingLidUser = this.mappingCache.get(`pn:${pnUser}`)
47
49
 
48
50
  if (!existingLidUser) {
49
- // Cache miss - check database
51
+ this.logger.trace(`Cache miss for PN user ${pnUser}; checking database`)
52
+
50
53
  const stored = await this.keys.get('lid-mapping', [pnUser])
51
54
 
52
55
  existingLidUser = stored[pnUser]
@@ -59,102 +62,150 @@ class LIDMappingStore {
59
62
  }
60
63
 
61
64
  if (existingLidUser === lidUser) {
62
- logger.debug({ pnUser, lidUser }, 'LID mapping already exists, skipping')
65
+ this.logger.debug({ pnUser, lidUser }, 'LID mapping already exists, skipping')
63
66
  continue
64
67
  }
65
68
 
66
69
  pairMap[pnUser] = lidUser
67
70
  }
68
71
 
69
- logger.trace({ pairMap }, `Storing ${Object.keys(pairMap).length} pn mappings`)
72
+ this.logger.trace({ pairMap }, `Storing ${Object.keys(pairMap).length} pn mappings`)
70
73
 
71
74
  await this.keys.transaction(async () => {
72
75
  for (const [pnUser, lidUser] of Object.entries(pairMap)) {
73
76
  await this.keys.set({
74
77
  'lid-mapping': {
75
- [pnUser]: lidUser, // "554396160286" -> "102765716062358"
76
- [`${lidUser}_reverse`]: pnUser // "102765716062358_reverse" -> "554396160286"
78
+ [pnUser]: lidUser,
79
+ [`${lidUser}_reverse`]: pnUser
77
80
  }
78
81
  })
79
82
 
80
- // Update cache with both directions
81
83
  this.mappingCache.set(`pn:${pnUser}`, lidUser)
82
84
  this.mappingCache.set(`lid:${lidUser}`, pnUser)
83
85
  }
84
86
  }, 'lid-mapping')
85
87
  }
88
+
86
89
  /**
87
90
  * Get LID for PN - Returns device-specific LID based on user mapping
88
91
  */
89
92
  async getLIDForPN(pn) {
90
- if (!isJidUser(pn)) return null
91
-
92
- const logger = this.logger
93
- const decoded = jidDecode(pn)
94
-
95
- if (!decoded) return null
96
-
97
- // Check cache first for PN → LID mapping
98
- const pnUser = decoded.user
93
+ return (await this.getLIDsForPNs([pn]))?.[0]?.lid || null
94
+ }
95
+
96
+ async getLIDsForPNs(pns) {
97
+ const usyncFetch = {}
99
98
 
100
- let lidUser = this.mappingCache.get(`pn:${pnUser}`)
99
+ // mapped from pn to lid mapping to prevent duplication in results later
100
+ const successfulPairs = {}
101
101
 
102
- if (!lidUser) {
103
- // Cache miss - check database
104
- const stored = await this.keys.get('lid-mapping', [pnUser])
102
+ for (const pn of pns) {
103
+ if (!isPnUser(pn) && !isHostedPnUser(pn)) continue
105
104
 
106
- lidUser = stored[pnUser]
105
+ const decoded = jidDecode(pn)
106
+ if (!decoded) continue
107
107
 
108
- if (lidUser) {
109
- // Cache the database result
110
- this.mappingCache.set(`pn:${pnUser}`, lidUser)
111
- }
108
+ // Check cache first for PN → LID mapping
109
+ const pnUser = decoded.user
112
110
 
113
- else {
114
- // Not in database - try USync
115
- logger.trace(`No LID mapping found for PN user ${pnUser}; getting from USync`)
111
+ let lidUser = this.mappingCache.get(`pn:${pnUser}`)
112
+
113
+ if (!lidUser) {
114
+ // Cache miss - check database
115
+ const stored = await this.keys.get('lid-mapping', [pnUser])
116
116
 
117
- const { exists, lid } = (await this.onWhatsAppFunc?.(pn))?.[0] // this function already adds LIDs to mapping
117
+ lidUser = stored[pnUser]
118
118
 
119
- if (exists && lid) {
120
- lidUser = jidDecode(lid)?.user
121
-
122
- if (lidUser) {
123
- // Cache the USync result
124
- this.mappingCache.set(`pn:${pnUser}`, lidUser)
125
- }
119
+ if (lidUser) {
120
+ this.mappingCache.set(`pn:${pnUser}`, lidUser)
121
+ this.mappingCache.set(`lid:${lidUser}`, pnUser)
126
122
  }
127
123
 
128
124
  else {
129
- return null
125
+ this.logger.trace(`No LID mapping found for PN user ${pnUser}; batch getting from USync`)
126
+
127
+ const device = decoded.device || 0
128
+
129
+ let normalizedPn = jidNormalizedUser(pn)
130
+
131
+ if (isHostedPnUser(normalizedPn)) {
132
+ normalizedPn = `${pnUser}@s.whatsapp.net`
133
+ }
134
+
135
+ if (!usyncFetch[normalizedPn]) {
136
+ usyncFetch[normalizedPn] = [device]
137
+ }
138
+
139
+ else {
140
+ usyncFetch[normalizedPn]?.push(device)
141
+ }
142
+
143
+ continue
130
144
  }
131
145
  }
146
+
147
+ lidUser = lidUser.toString()
148
+
149
+ if (!lidUser) {
150
+ this.logger.warn(`Invalid or empty LID user for PN ${pn}: lidUser = "${lidUser}"`)
151
+ return null
152
+ }
153
+
154
+ // Push the PN device ID to the LID to maintain device separation
155
+ const pnDevice = decoded.device !== undefined ? decoded.device : 0
156
+ const deviceSpecificLid = `${lidUser}${!!pnDevice ? `:${pnDevice}` : ``}@${decoded.server === 'hosted' ? 'hosted.lid' : 'lid'}`
157
+
158
+ this.logger.trace(`getLIDForPN: ${pn} → ${deviceSpecificLid} (user mapping with device ${pnDevice})`)
159
+
160
+ successfulPairs[pn] = { lid: deviceSpecificLid, pn }
132
161
  }
133
162
 
134
- if (typeof lidUser !== 'string' || !lidUser) {
135
- logger.warn(`Invalid or empty LID user for PN ${pn}: lidUser = "${lidUser}"`)
136
- return null
163
+ if (Object.keys(usyncFetch).length > 0) {
164
+ const result = await this.pnToLIDFunc?.(Object.keys(usyncFetch)) // this function already adds LIDs to mapping
165
+
166
+ if (result && result.length > 0) {
167
+ await this.storeLIDPNMappings(result)
168
+
169
+ for (const pair of result) {
170
+ const pnDecoded = jidDecode(pair.pn)
171
+ const pnUser = pnDecoded?.user
172
+
173
+ if (!pnUser) continue
174
+
175
+ const lidUser = jidDecode(pair.lid)?.user
176
+
177
+ if (!lidUser) continue
178
+
179
+ for (const device of usyncFetch[pair.pn]) {
180
+ const deviceSpecificLid = `${lidUser}${!!device ? `:${device}` : ``}@${device === 99 ? 'hosted.lid' : 'lid'}`
181
+
182
+ this.logger.trace(`getLIDForPN: USYNC success for ${pair.pn} → ${deviceSpecificLid} (user mapping with device ${device})`)
183
+
184
+ const deviceSpecificPn = `${pnUser}${!!device ? `:${device}` : ``}@${device === 99 ? 'hosted' : 's.whatsapp.net'}`
185
+
186
+ successfulPairs[deviceSpecificPn] = { lid: deviceSpecificLid, pn: deviceSpecificPn }
187
+ }
188
+ }
189
+ }
190
+
191
+ else {
192
+ return null
193
+ }
137
194
  }
138
195
 
139
- // Push the PN device ID to the LID to maintain device separation
140
- const pnDevice = decoded.device !== undefined ? decoded.device : 0
141
- const deviceSpecificLid = `${lidUser}:${pnDevice}@lid`
142
-
143
- logger.trace(`getLIDForPN: ${pn} → ${deviceSpecificLid} (user mapping with device ${pnDevice})`)
144
-
145
- return deviceSpecificLid
196
+ return Object.values(successfulPairs)
146
197
  }
198
+
147
199
  /**
148
200
  * Get PN for LID - USER LEVEL with device construction
149
201
  */
150
202
  async getPNForLID(lid) {
151
203
  if (!isLidUser(lid)) return null
152
-
153
- const logger = this.logger
204
+
154
205
  const decoded = jidDecode(lid)
155
206
 
156
207
  if (!decoded) return null
157
-
208
+
158
209
  // Check cache first for LID → PN mapping
159
210
  const lidUser = decoded.user
160
211
 
@@ -162,11 +213,12 @@ class LIDMappingStore {
162
213
 
163
214
  if (!pnUser || typeof pnUser !== 'string') {
164
215
  // Cache miss - check database
165
- const stored = await this.keys.get('lid-mapping', [`${lidUser}_reverse`]);
216
+ const stored = await this.keys.get('lid-mapping', [`${lidUser}_reverse`])
217
+
166
218
  pnUser = stored[`${lidUser}_reverse`]
167
219
 
168
220
  if (!pnUser || typeof pnUser !== 'string') {
169
- logger.trace(`No reverse mapping found for LID user: ${lidUser}`)
221
+ this.logger.trace(`No reverse mapping found for LID user: ${lidUser}`)
170
222
  return null
171
223
  }
172
224
 
@@ -175,8 +227,9 @@ class LIDMappingStore {
175
227
 
176
228
  // Construct device-specific PN JID
177
229
  const lidDevice = decoded.device !== undefined ? decoded.device : 0
178
- const pnJid = `${pnUser}:${lidDevice}@s.whatsapp.net`
179
- logger.trace(`Found reverse mapping: ${lid} → ${pnJid}`)
230
+ const pnJid = `${pnUser}:${lidDevice}@${decoded.domainType === WAJIDDomains.HOSTED_LID ? 'hosted' : 's.whatsapp.net'}`
231
+
232
+ this.logger.trace(`Found reverse mapping: ${lid} → ${pnJid}`)
180
233
 
181
234
  return pnJid
182
235
  }
@@ -17,19 +17,24 @@ class WebSocketClient extends AbstractSocketClient {
17
17
  super(...arguments)
18
18
  this.socket = null
19
19
  }
20
+
20
21
  get isOpen() {
21
22
  return this.socket?.readyState === OPEN
22
23
  }
24
+
23
25
  get isClosed() {
24
26
  return this.socket?.readyState === CLOSED
25
27
  }
28
+
26
29
  get isClosing() {
27
30
  this.socket?.readyState === CLOSING
28
31
  }
32
+
29
33
  get isConnecting() {
30
34
  this.socket?.readyState === CONNECTING
31
35
  }
32
- async connect() {
36
+
37
+ connect() {
33
38
  if (this.socket) {
34
39
  return
35
40
  }
@@ -46,13 +51,15 @@ class WebSocketClient extends AbstractSocketClient {
46
51
  this.socket?.on(event, (...args) => this.emit(event, ...args))
47
52
  }
48
53
  }
49
- async close() {
54
+
55
+ close() {
50
56
  if (!this.socket) {
51
57
  return
52
58
  }
53
59
  this.socket.close()
54
60
  this.socket = null
55
61
  }
62
+
56
63
  send(str, cb) {
57
64
  this.socket?.send(str, cb)
58
65
  return Boolean(this.socket)
@@ -19,7 +19,11 @@ const { makeMessagesRecvSocket } = require("./messages-recv")
19
19
 
20
20
  const makeBusinessSocket = (config) => {
21
21
  const suki = makeMessagesRecvSocket(config)
22
- const { authState, query, waUploadToServer } = suki
22
+ const {
23
+ authState,
24
+ query,
25
+ waUploadToServer
26
+ } = suki
23
27
 
24
28
  const updateBussinesProfile = async (args) => {
25
29
  const node = []