@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.
- package/README.md +203 -247
- package/lib/Defaults/baileys-version.json +2 -2
- package/lib/Defaults/connection.js +1 -1
- package/lib/Defaults/constants.js +13 -1
- package/lib/Defaults/history.js +3 -1
- package/lib/Signal/Group/sender-chain-key.js +1 -14
- package/lib/Signal/Group/sender-key-distribution-message.js +2 -2
- package/lib/Signal/Group/sender-key-record.js +2 -11
- package/lib/Signal/Group/sender-key-state.js +11 -57
- package/lib/Signal/libsignal.js +200 -116
- package/lib/Signal/lid-mapping.js +121 -68
- package/lib/Socket/Client/websocket.js +9 -2
- package/lib/Socket/business.js +5 -1
- package/lib/Socket/chats.js +180 -89
- package/lib/Socket/community.js +169 -41
- package/lib/Socket/groups.js +25 -21
- package/lib/Socket/messages-recv.js +458 -333
- package/lib/Socket/messages-send.js +517 -572
- package/lib/Socket/mex.js +61 -0
- package/lib/Socket/newsletter.js +159 -252
- package/lib/Socket/socket.js +283 -100
- package/lib/Types/Newsletter.js +32 -25
- package/lib/Utils/auth-utils.js +189 -354
- package/lib/Utils/browser-utils.js +43 -0
- package/lib/Utils/chat-utils.js +166 -41
- package/lib/Utils/decode-wa-message.js +77 -35
- package/lib/Utils/event-buffer.js +80 -24
- package/lib/Utils/generics.js +28 -128
- package/lib/Utils/history.js +10 -8
- package/lib/Utils/index.js +1 -1
- package/lib/Utils/link-preview.js +17 -32
- package/lib/Utils/lt-hash.js +28 -22
- package/lib/Utils/make-mutex.js +26 -28
- package/lib/Utils/message-retry-manager.js +51 -3
- package/lib/Utils/messages-media.js +343 -151
- package/lib/Utils/messages.js +806 -792
- package/lib/Utils/noise-handler.js +33 -2
- package/lib/Utils/pre-key-manager.js +126 -0
- package/lib/Utils/process-message.js +115 -55
- package/lib/Utils/signal.js +45 -18
- package/lib/Utils/validate-connection.js +52 -29
- package/lib/WABinary/constants.js +1268 -1268
- package/lib/WABinary/decode.js +58 -4
- package/lib/WABinary/encode.js +54 -7
- package/lib/WABinary/jid-utils.js +58 -11
- package/lib/WAM/constants.js +19064 -11563
- package/lib/WAM/encode.js +57 -8
- package/lib/WAUSync/USyncQuery.js +35 -19
- package/package.json +9 -8
- package/lib/Socket/usync.js +0 -83
|
@@ -5,15 +5,16 @@ Object.defineProperty(exports, "__esModule", { value: true })
|
|
|
5
5
|
const { Boom } = require("@hapi/boom")
|
|
6
6
|
const { proto } = require("../../WAProto")
|
|
7
7
|
const {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
areJidsSameUser,
|
|
9
|
+
isHostedLidUser,
|
|
10
|
+
isHostedPnUser,
|
|
11
|
+
isJidBroadcast,
|
|
10
12
|
isJidGroup,
|
|
11
13
|
isJidMetaAI,
|
|
12
|
-
isJidBroadcast,
|
|
13
14
|
isJidNewsletter,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
isJidStatusBroadcast,
|
|
16
|
+
isLidUser,
|
|
17
|
+
isPnUser
|
|
17
18
|
} = require("../WABinary")
|
|
18
19
|
const { unpadRandomMax16 } = require("./generics")
|
|
19
20
|
const { getDevice } = require("./messages")
|
|
@@ -52,25 +53,23 @@ const extractAddressingContext = (stanza) => {
|
|
|
52
53
|
const sender = stanza.attrs.participant || stanza.attrs.from
|
|
53
54
|
const addressingMode = stanza.attrs.addressing_mode || (sender?.endsWith('lid') ? 'lid' : 'pn')
|
|
54
55
|
|
|
55
|
-
if (
|
|
56
|
+
if (addressingMode === 'lid') {
|
|
56
57
|
// Message is LID-addressed: sender is LID, extract corresponding PN
|
|
57
58
|
// without device data
|
|
58
59
|
senderAlt = stanza.attrs.participant_pn || stanza.attrs.sender_pn || stanza.attrs.peer_recipient_pn
|
|
59
60
|
recipientAlt = stanza.attrs.recipient_pn
|
|
60
61
|
// with device data
|
|
61
|
-
if (sender && senderAlt)
|
|
62
|
-
senderAlt = transferDevice(sender, senderAlt)
|
|
62
|
+
//if (sender && senderAlt) senderAlt = transferDevice(sender, senderAlt)
|
|
63
63
|
}
|
|
64
|
-
|
|
65
|
-
else if (isJidUser(sender)) {
|
|
64
|
+
else {
|
|
66
65
|
// Message is PN-addressed: sender is PN, extract corresponding LID
|
|
67
66
|
// without device data
|
|
68
67
|
senderAlt = stanza.attrs.participant_lid || stanza.attrs.sender_lid || stanza.attrs.peer_recipient_lid
|
|
69
68
|
recipientAlt = stanza.attrs.recipient_lid
|
|
70
69
|
//with device data
|
|
71
|
-
if (sender && senderAlt)
|
|
72
|
-
senderAlt = transferDevice(sender, senderAlt)
|
|
70
|
+
//if (sender && senderAlt) senderAlt = transferDevice(sender, senderAlt)
|
|
73
71
|
}
|
|
72
|
+
|
|
74
73
|
return {
|
|
75
74
|
addressingMode,
|
|
76
75
|
senderAlt,
|
|
@@ -79,18 +78,21 @@ const extractAddressingContext = (stanza) => {
|
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
const getDecryptionJid = async (sender, repository) => {
|
|
82
|
-
if (
|
|
81
|
+
if (isLidUser(sender) || isHostedLidUser(sender)) {
|
|
83
82
|
return sender
|
|
84
83
|
}
|
|
85
|
-
|
|
84
|
+
const mapped = await repository.lidMapping.getLIDForPN(sender)
|
|
85
|
+
return mapped || sender
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
const storeMappingFromEnvelope = async (stanza, sender,
|
|
88
|
+
const storeMappingFromEnvelope = async (stanza, sender, repository, decryptionJid, logger) => {
|
|
89
|
+
// TODO: Handle hosted IDs
|
|
89
90
|
const { senderAlt } = extractAddressingContext(stanza)
|
|
90
91
|
|
|
91
|
-
if (senderAlt && isLidUser(senderAlt) &&
|
|
92
|
+
if (senderAlt && isLidUser(senderAlt) && isPnUser(sender) && decryptionJid === sender) {
|
|
92
93
|
try {
|
|
93
94
|
await repository.lidMapping.storeLIDPNMappings([{ lid: senderAlt, pn: sender }])
|
|
95
|
+
await repository.migrateSession(sender, senderAlt)
|
|
94
96
|
logger.debug({ sender, senderAlt }, 'Stored LID mapping from envelope')
|
|
95
97
|
}
|
|
96
98
|
catch (error) {
|
|
@@ -103,73 +105,90 @@ const storeMappingFromEnvelope = async (stanza, sender, decryptionJid, repositor
|
|
|
103
105
|
* Decode the received node as a message.
|
|
104
106
|
* @note this will only parse the message, not decrypt it
|
|
105
107
|
*/
|
|
106
|
-
function decodeMessageNode(stanza, meId, meLid) {
|
|
108
|
+
function decodeMessageNode(stanza, meId, meLid) {
|
|
107
109
|
let msgType
|
|
108
110
|
let chatId
|
|
109
111
|
let author
|
|
110
112
|
let fromMe = false
|
|
113
|
+
|
|
111
114
|
const msgId = stanza.attrs.id
|
|
112
115
|
const from = stanza.attrs.from
|
|
113
116
|
const participant = stanza.attrs.participant
|
|
114
117
|
const recipient = stanza.attrs.recipient
|
|
115
|
-
const addressingContext = extractAddressingContext(stanza)
|
|
118
|
+
const addressingContext = extractAddressingContext(stanza)
|
|
116
119
|
const isMe = (jid) => areJidsSameUser(jid, meId)
|
|
117
120
|
const isMeLid = (jid) => areJidsSameUser(jid, meLid)
|
|
118
|
-
|
|
121
|
+
|
|
122
|
+
if (isPnUser(from) || isLidUser(from) || isHostedLidUser(from) || isHostedPnUser(from)) {
|
|
119
123
|
if (recipient && !isJidMetaAI(recipient)) {
|
|
120
124
|
if (!isMe(from) && !isMeLid(from)) {
|
|
121
125
|
throw new Boom('receipient present, but msg not from me', { data: stanza })
|
|
122
126
|
}
|
|
127
|
+
|
|
123
128
|
if (isMe(from) || isMeLid(from)) {
|
|
124
129
|
fromMe = true
|
|
125
130
|
}
|
|
131
|
+
|
|
126
132
|
chatId = recipient
|
|
127
133
|
}
|
|
128
134
|
else {
|
|
129
135
|
chatId = from
|
|
130
136
|
}
|
|
137
|
+
|
|
131
138
|
msgType = 'chat'
|
|
132
139
|
author = from
|
|
133
140
|
}
|
|
141
|
+
|
|
134
142
|
else if (isJidGroup(from)) {
|
|
135
143
|
if (!participant) {
|
|
136
144
|
throw new Boom('No participant in group message')
|
|
137
145
|
}
|
|
146
|
+
|
|
138
147
|
if (isMe(participant) || isMeLid(participant)) {
|
|
139
|
-
fromMe = true
|
|
148
|
+
fromMe = true
|
|
140
149
|
}
|
|
150
|
+
|
|
141
151
|
msgType = 'group'
|
|
142
152
|
author = participant
|
|
143
153
|
chatId = from
|
|
144
154
|
}
|
|
155
|
+
|
|
145
156
|
else if (isJidBroadcast(from)) {
|
|
146
157
|
if (!participant) {
|
|
147
158
|
throw new Boom('No participant in group message')
|
|
148
159
|
}
|
|
160
|
+
|
|
149
161
|
const isParticipantMe = isMe(participant)
|
|
162
|
+
|
|
150
163
|
if (isJidStatusBroadcast(from)) {
|
|
151
164
|
msgType = isParticipantMe ? 'direct_peer_status' : 'other_status'
|
|
152
165
|
}
|
|
166
|
+
|
|
153
167
|
else {
|
|
154
168
|
msgType = isParticipantMe ? 'peer_broadcast' : 'other_broadcast'
|
|
155
169
|
}
|
|
170
|
+
|
|
156
171
|
fromMe = isParticipantMe
|
|
157
172
|
chatId = from
|
|
158
173
|
author = participant
|
|
159
174
|
}
|
|
175
|
+
|
|
160
176
|
else if (isJidNewsletter(from)) {
|
|
161
177
|
msgType = 'newsletter'
|
|
162
178
|
chatId = from
|
|
163
179
|
author = from
|
|
180
|
+
|
|
164
181
|
if (isMe(from) || isMeLid(from)) {
|
|
165
|
-
fromMe = true
|
|
182
|
+
fromMe = true
|
|
166
183
|
}
|
|
167
184
|
}
|
|
185
|
+
|
|
168
186
|
else {
|
|
169
187
|
throw new Boom('Unknown message type', { data: stanza })
|
|
170
188
|
}
|
|
171
189
|
|
|
172
190
|
const pushname = stanza?.attrs?.notify
|
|
191
|
+
|
|
173
192
|
const key = {
|
|
174
193
|
remoteJid: chatId,
|
|
175
194
|
remoteJidAlt: !isJidGroup(chatId) ? addressingContext.senderAlt : undefined,
|
|
@@ -177,21 +196,24 @@ function decodeMessageNode(stanza, meId, meLid) {
|
|
|
177
196
|
id: msgId,
|
|
178
197
|
participant,
|
|
179
198
|
participantAlt: isJidGroup(chatId) ? addressingContext.senderAlt : undefined,
|
|
199
|
+
addressingMode: addressingContext.addressingMode,
|
|
200
|
+
...(msgType === 'newsletter' && stanza.attrs.server_id ? { server_id: stanza.attrs.server_id } : {})
|
|
180
201
|
}
|
|
202
|
+
|
|
181
203
|
const fullMessage = {
|
|
182
204
|
key,
|
|
205
|
+
category: stanza.attrs.category,
|
|
183
206
|
messageTimestamp: +stanza.attrs.t,
|
|
184
207
|
pushName: pushname,
|
|
208
|
+
platform: getDevice(key.id),
|
|
185
209
|
broadcast: isJidBroadcast(from),
|
|
186
|
-
newsletter: isJidNewsletter(from)
|
|
187
|
-
platform: getDevice(key.id)
|
|
188
|
-
}
|
|
189
|
-
if (msgType === 'newsletter') {
|
|
190
|
-
fullMessage.newsletter_server_id = +stanza.attrs?.server_id
|
|
210
|
+
newsletter: isJidNewsletter(from)
|
|
191
211
|
}
|
|
212
|
+
|
|
192
213
|
if (key.fromMe) {
|
|
193
214
|
fullMessage.status = proto.WebMessageInfo.Status.SERVER_ACK
|
|
194
215
|
}
|
|
216
|
+
|
|
195
217
|
return {
|
|
196
218
|
fullMessage,
|
|
197
219
|
author,
|
|
@@ -207,30 +229,43 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
|
|
|
207
229
|
author,
|
|
208
230
|
async decrypt() {
|
|
209
231
|
let decryptables = 0
|
|
232
|
+
|
|
210
233
|
if (Array.isArray(stanza.content)) {
|
|
211
234
|
for (const { tag, attrs, content } of stanza.content) {
|
|
212
235
|
if (tag === 'verified_name' && content instanceof Uint8Array) {
|
|
213
236
|
const cert = proto.VerifiedNameCertificate.decode(content)
|
|
214
237
|
const details = proto.VerifiedNameCertificate.Details.decode(cert.details)
|
|
238
|
+
|
|
215
239
|
fullMessage.verifiedBizName = details.verifiedName
|
|
216
240
|
}
|
|
241
|
+
|
|
217
242
|
if (tag === 'unavailable' && attrs.type === 'view_once') {
|
|
218
|
-
fullMessage.key.isViewOnce = true
|
|
243
|
+
fullMessage.key.isViewOnce = true // TODO: remove from here and add a STUB TYPE
|
|
219
244
|
}
|
|
245
|
+
|
|
246
|
+
if (attrs.count && tag === 'enc') {
|
|
247
|
+
fullMessage.retryCount = Number(attrs.count)
|
|
248
|
+
}
|
|
249
|
+
|
|
220
250
|
if (tag !== 'enc' && tag !== 'plaintext') {
|
|
221
251
|
continue
|
|
222
252
|
}
|
|
253
|
+
|
|
223
254
|
if (!(content instanceof Uint8Array)) {
|
|
224
255
|
continue
|
|
225
256
|
}
|
|
257
|
+
|
|
226
258
|
decryptables += 1
|
|
259
|
+
|
|
227
260
|
let msgBuffer
|
|
228
|
-
|
|
229
|
-
const decryptionJid = await getDecryptionJid(
|
|
261
|
+
|
|
262
|
+
const decryptionJid = await getDecryptionJid(author, repository)
|
|
230
263
|
|
|
231
264
|
if (tag !== 'plaintext') {
|
|
232
|
-
|
|
265
|
+
// TODO: Handle hosted devices
|
|
266
|
+
await storeMappingFromEnvelope(stanza, author, repository, decryptionJid, logger)
|
|
233
267
|
}
|
|
268
|
+
|
|
234
269
|
try {
|
|
235
270
|
const e2eType = tag === 'plaintext' ? 'plaintext' : attrs.type
|
|
236
271
|
switch (e2eType) {
|
|
@@ -255,27 +290,33 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
|
|
|
255
290
|
default:
|
|
256
291
|
throw new Error(`Unknown e2e type: ${e2eType}`)
|
|
257
292
|
}
|
|
293
|
+
|
|
258
294
|
let msg = proto.Message.decode(e2eType !== 'plaintext' ? unpadRandomMax16(msgBuffer) : msgBuffer)
|
|
295
|
+
|
|
259
296
|
msg = msg.deviceSentMessage?.message || msg
|
|
297
|
+
|
|
260
298
|
if (msg.senderKeyDistributionMessage) {
|
|
261
|
-
//eslint-disable-next-line max-depth
|
|
262
299
|
try {
|
|
263
300
|
await repository.processSenderKeyDistributionMessage({
|
|
264
301
|
authorJid: author,
|
|
265
302
|
item: msg.senderKeyDistributionMessage
|
|
266
303
|
})
|
|
267
304
|
}
|
|
305
|
+
|
|
268
306
|
catch (err) {
|
|
269
|
-
logger.error({ key: fullMessage.key, err }, 'failed to
|
|
307
|
+
logger.error({ key: fullMessage.key, err }, 'failed to process sender key distribution message')
|
|
270
308
|
}
|
|
271
309
|
}
|
|
310
|
+
|
|
272
311
|
if (fullMessage.message) {
|
|
273
312
|
Object.assign(fullMessage.message, msg)
|
|
274
313
|
}
|
|
314
|
+
|
|
275
315
|
else {
|
|
276
316
|
fullMessage.message = msg
|
|
277
317
|
}
|
|
278
318
|
}
|
|
319
|
+
|
|
279
320
|
catch (err) {
|
|
280
321
|
const errorContext = {
|
|
281
322
|
key: fullMessage.key,
|
|
@@ -285,7 +326,8 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
|
|
|
285
326
|
author,
|
|
286
327
|
isSessionRecordError: isSessionRecordError(err)
|
|
287
328
|
}
|
|
288
|
-
|
|
329
|
+
|
|
330
|
+
logger.error(errorContext, 'failed to decrypt message')
|
|
289
331
|
fullMessage.messageStubType = proto.WebMessageInfo.StubType.CIPHERTEXT
|
|
290
332
|
fullMessage.messageStubParameters = [err.message.toString()]
|
|
291
333
|
}
|
|
@@ -293,7 +335,7 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
|
|
|
293
335
|
}
|
|
294
336
|
|
|
295
337
|
// if nothing was found to decrypt
|
|
296
|
-
if (!decryptables) {
|
|
338
|
+
if (!decryptables && !fullMessage.key?.isViewOnce) {
|
|
297
339
|
fullMessage.messageStubType = proto.WebMessageInfo.StubType.CIPHERTEXT
|
|
298
340
|
fullMessage.messageStubParameters = [NO_MESSAGE_FOUND_ERROR_TEXT]
|
|
299
341
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const EventEmitter = require("events")
|
|
6
6
|
const { WAMessageStatus } = require("../Types")
|
|
7
7
|
const { trimUndefined } = require("./generics")
|
|
8
8
|
const {
|
|
@@ -34,7 +34,7 @@ const BUFFERABLE_EVENT_SET = new Set(BUFFERABLE_EVENT)
|
|
|
34
34
|
* making the data processing more efficient.
|
|
35
35
|
*/
|
|
36
36
|
const makeEventBuffer = (logger) => {
|
|
37
|
-
const ev = new
|
|
37
|
+
const ev = new EventEmitter()
|
|
38
38
|
const historyCache = new Set()
|
|
39
39
|
let data = makeBufferData()
|
|
40
40
|
let isBuffering = false
|
|
@@ -121,10 +121,37 @@ const makeEventBuffer = (logger) => {
|
|
|
121
121
|
}
|
|
122
122
|
},
|
|
123
123
|
emit(event, evData) {
|
|
124
|
+
// Check if this is a messages.upsert with a different type than what's buffered
|
|
125
|
+
// If so, flush the buffered messages first to avoid type overshadowing
|
|
126
|
+
if (event === 'messages.upsert') {
|
|
127
|
+
const { type } = evData
|
|
128
|
+
const existingUpserts = Object.values(data.messageUpserts)
|
|
129
|
+
|
|
130
|
+
if (existingUpserts.length > 0) {
|
|
131
|
+
const bufferedType = existingUpserts[0].type
|
|
132
|
+
|
|
133
|
+
if (bufferedType !== type) {
|
|
134
|
+
logger.debug({ bufferedType, newType: type }, 'messages.upsert type mismatch, emitting buffered messages')
|
|
135
|
+
|
|
136
|
+
// Emit the buffered messages with their correct type
|
|
137
|
+
ev.emit('event', {
|
|
138
|
+
'messages.upsert': {
|
|
139
|
+
messages: existingUpserts.map(m => m.message),
|
|
140
|
+
type: bufferedType
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
// Clear the message upserts from the buffer
|
|
145
|
+
data.messageUpserts = {}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
124
150
|
if (isBuffering && BUFFERABLE_EVENT_SET.has(event)) {
|
|
125
151
|
append(data, historyCache, event, evData, logger)
|
|
126
152
|
return true
|
|
127
153
|
}
|
|
154
|
+
|
|
128
155
|
return ev.emit('event', { [event]: evData })
|
|
129
156
|
},
|
|
130
157
|
isBuffering() {
|
|
@@ -192,42 +219,50 @@ const makeBufferData = () => {
|
|
|
192
219
|
}
|
|
193
220
|
|
|
194
221
|
function append(data, historyCache, event, eventData, logger) {
|
|
195
|
-
var _a, _b, _c
|
|
196
222
|
switch (event) {
|
|
197
223
|
case 'messaging-history.set':
|
|
198
224
|
for (const chat of eventData.chats) {
|
|
199
|
-
const
|
|
225
|
+
const id = chat.id || ''
|
|
226
|
+
const existingChat = data.historySets.chats[id]
|
|
227
|
+
|
|
200
228
|
if (existingChat) {
|
|
201
229
|
existingChat.endOfHistoryTransferType = chat.endOfHistoryTransferType
|
|
202
230
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
231
|
+
|
|
232
|
+
if (!existingChat && !historyCache.has(id)) {
|
|
233
|
+
data.historySets.chats[id] = chat
|
|
234
|
+
historyCache.add(id)
|
|
206
235
|
absorbingChatUpdate(chat)
|
|
207
236
|
}
|
|
208
237
|
}
|
|
238
|
+
|
|
209
239
|
for (const contact of eventData.contacts) {
|
|
210
240
|
const existingContact = data.historySets.contacts[contact.id]
|
|
241
|
+
|
|
211
242
|
if (existingContact) {
|
|
212
243
|
Object.assign(existingContact, trimUndefined(contact))
|
|
213
244
|
}
|
|
214
245
|
else {
|
|
215
246
|
const historyContactId = `c:${contact.id}`
|
|
216
247
|
const hasAnyName = contact.notify || contact.name || contact.verifiedName
|
|
248
|
+
|
|
217
249
|
if (!historyCache.has(historyContactId) || hasAnyName) {
|
|
218
250
|
data.historySets.contacts[contact.id] = contact
|
|
219
251
|
historyCache.add(historyContactId)
|
|
220
252
|
}
|
|
221
253
|
}
|
|
222
254
|
}
|
|
255
|
+
|
|
223
256
|
for (const message of eventData.messages) {
|
|
224
257
|
const key = stringifyMessageKey(message.key)
|
|
225
258
|
const existingMsg = data.historySets.messages[key]
|
|
259
|
+
|
|
226
260
|
if (!existingMsg && !historyCache.has(key)) {
|
|
227
261
|
data.historySets.messages[key] = message
|
|
228
262
|
historyCache.add(key)
|
|
229
263
|
}
|
|
230
264
|
}
|
|
265
|
+
|
|
231
266
|
data.historySets.empty = false
|
|
232
267
|
data.historySets.syncType = eventData.syncType
|
|
233
268
|
data.historySets.progress = eventData.progress
|
|
@@ -236,23 +271,30 @@ function append(data, historyCache, event, eventData, logger) {
|
|
|
236
271
|
break
|
|
237
272
|
case 'chats.upsert':
|
|
238
273
|
for (const chat of eventData) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
274
|
+
const id = chat.id || ''
|
|
275
|
+
|
|
276
|
+
let upsert = data.chatUpserts[id]
|
|
277
|
+
|
|
278
|
+
if (id && !upsert) {
|
|
279
|
+
upsert = data.historySets.chats[id]
|
|
280
|
+
|
|
242
281
|
if (upsert) {
|
|
243
|
-
logger.debug({ chatId:
|
|
282
|
+
logger.debug({ chatId: id }, 'absorbed chat upsert in chat set')
|
|
244
283
|
}
|
|
245
284
|
}
|
|
285
|
+
|
|
246
286
|
if (upsert) {
|
|
247
287
|
upsert = concatChats(upsert, chat)
|
|
248
288
|
}
|
|
249
289
|
else {
|
|
250
290
|
upsert = chat
|
|
251
|
-
data.chatUpserts[
|
|
291
|
+
data.chatUpserts[id] = upsert
|
|
252
292
|
}
|
|
293
|
+
|
|
253
294
|
absorbingChatUpdate(upsert)
|
|
254
|
-
|
|
255
|
-
|
|
295
|
+
|
|
296
|
+
if (data.chatDeletes.has(id)) {
|
|
297
|
+
data.chatDeletes.delete(id)
|
|
256
298
|
}
|
|
257
299
|
}
|
|
258
300
|
break
|
|
@@ -342,43 +384,51 @@ function append(data, historyCache, event, eventData, logger) {
|
|
|
342
384
|
break
|
|
343
385
|
case 'messages.upsert':
|
|
344
386
|
const { messages, type } = eventData
|
|
387
|
+
|
|
345
388
|
for (const message of messages) {
|
|
346
389
|
const key = stringifyMessageKey(message.key)
|
|
347
|
-
|
|
390
|
+
|
|
391
|
+
let existing = data.messageUpserts[key]?.message
|
|
392
|
+
|
|
348
393
|
if (!existing) {
|
|
349
394
|
existing = data.historySets.messages[key]
|
|
395
|
+
|
|
350
396
|
if (existing) {
|
|
351
397
|
logger.debug({ messageId: key }, 'absorbed message upsert in message set')
|
|
352
398
|
}
|
|
353
399
|
}
|
|
400
|
+
|
|
354
401
|
if (existing) {
|
|
355
402
|
message.messageTimestamp = existing.messageTimestamp
|
|
356
403
|
}
|
|
404
|
+
|
|
357
405
|
if (data.messageUpdates[key]) {
|
|
358
406
|
logger.debug('absorbed prior message update in message upsert')
|
|
359
407
|
Object.assign(message, data.messageUpdates[key].update)
|
|
360
408
|
delete data.messageUpdates[key]
|
|
361
409
|
}
|
|
410
|
+
|
|
362
411
|
if (data.historySets.messages[key]) {
|
|
363
412
|
data.historySets.messages[key] = message
|
|
364
413
|
}
|
|
365
414
|
else {
|
|
366
415
|
data.messageUpserts[key] = {
|
|
367
416
|
message,
|
|
368
|
-
type: type === 'notify' ||
|
|
369
|
-
? 'notify'
|
|
370
|
-
: type
|
|
417
|
+
type: type === 'notify' || data.messageUpserts[key]?.type === 'notify' ? 'notify' : type
|
|
371
418
|
}
|
|
372
419
|
}
|
|
373
420
|
}
|
|
374
421
|
break
|
|
375
422
|
case 'messages.update':
|
|
376
423
|
const msgUpdates = eventData
|
|
424
|
+
|
|
377
425
|
for (const { key, update } of msgUpdates) {
|
|
378
426
|
const keyStr = stringifyMessageKey(key)
|
|
379
|
-
const existing = data.historySets.messages[keyStr] ||
|
|
427
|
+
const existing = data.historySets.messages[keyStr] || data.messageUpserts[keyStr]?.message
|
|
428
|
+
|
|
380
429
|
if (existing) {
|
|
381
430
|
Object.assign(existing, update)
|
|
431
|
+
|
|
382
432
|
// if the message was received & read by us
|
|
383
433
|
// the chat counter must have been incremented
|
|
384
434
|
// so we need to decrement it
|
|
@@ -471,11 +521,14 @@ function append(data, historyCache, event, eventData, logger) {
|
|
|
471
521
|
default:
|
|
472
522
|
throw new Error(`"${event}" cannot be buffered`)
|
|
473
523
|
}
|
|
524
|
+
|
|
474
525
|
function absorbingChatUpdate(existing) {
|
|
475
|
-
const chatId = existing.id
|
|
526
|
+
const chatId = existing.id || ''
|
|
476
527
|
const update = data.chatUpdates[chatId]
|
|
528
|
+
|
|
477
529
|
if (update) {
|
|
478
530
|
const conditionMatches = update.conditional ? update.conditional(data) : true
|
|
531
|
+
|
|
479
532
|
if (conditionMatches) {
|
|
480
533
|
delete update.conditional
|
|
481
534
|
logger.debug({ chatId }, 'absorbed chat update in existing chat')
|
|
@@ -488,17 +541,20 @@ function append(data, historyCache, event, eventData, logger) {
|
|
|
488
541
|
}
|
|
489
542
|
}
|
|
490
543
|
}
|
|
544
|
+
|
|
491
545
|
function decrementChatReadCounterIfMsgDidUnread(message) {
|
|
492
546
|
// decrement chat unread counter
|
|
493
547
|
// if the message has already been marked read by us
|
|
494
548
|
const chatId = message.key.remoteJid
|
|
495
549
|
const chat = data.chatUpdates[chatId] || data.chatUpserts[chatId]
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
550
|
+
|
|
551
|
+
if (isRealMessage(message) &&
|
|
552
|
+
shouldIncrementChatUnread(message) &&
|
|
553
|
+
typeof chat?.unreadCount === 'number' &&
|
|
554
|
+
chat.unreadCount > 0) {
|
|
500
555
|
logger.debug({ chatId: chat.id }, 'decrementing chat counter')
|
|
501
556
|
chat.unreadCount -= 1
|
|
557
|
+
|
|
502
558
|
if (chat.unreadCount === 0) {
|
|
503
559
|
delete chat.unreadCount
|
|
504
560
|
}
|