@badzz88/baileys 8.4.9 → 8.5.1

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 (154) hide show
  1. package/README.md +1 -1
  2. package/WAProto/WAProto.proto +6 -347
  3. package/WAProto/fix-imports.js +85 -86
  4. package/WAProto/index.d.ts +25 -4913
  5. package/WAProto/index.js +93 -14069
  6. package/{src → lib}/Defaults/index.js +2 -13
  7. package/{src → lib}/Signal/Group/group_cipher.js +5 -5
  8. package/{src → lib}/Signal/Group/keyhelper.js +4 -4
  9. package/{src → lib}/Signal/Group/sender-chain-key.js +2 -2
  10. package/{src → lib}/Signal/Group/sender-key-distribution-message.js +1 -1
  11. package/{src → lib}/Signal/Group/sender-key-message.js +3 -3
  12. package/{src → lib}/Signal/Group/sender-key-record.js +1 -1
  13. package/{src → lib}/Signal/Group/sender-message-key.js +2 -2
  14. package/{src → lib}/Signal/libsignal.js +26 -6
  15. package/{src → lib}/Socket/chats.js +58 -616
  16. package/{src → lib}/Socket/communities.js +28 -59
  17. package/{src → lib}/Socket/graphql.js +103 -362
  18. package/{src → lib}/Socket/groups.js +29 -77
  19. package/{src → lib}/Socket/index.js +5 -3
  20. package/{src → lib}/Socket/interactive-handler.js +60 -117
  21. package/{src → lib}/Socket/interop.js +19 -36
  22. package/lib/Socket/luxu.js +387 -0
  23. package/{src → lib}/Socket/managed-account.js +27 -58
  24. package/{src → lib}/Socket/messages-recv.js +144 -715
  25. package/{src → lib}/Socket/messages-send.js +102 -412
  26. package/lib/Socket/mex.js +60 -0
  27. package/{src → lib}/Socket/newsletter.js +23 -266
  28. package/{src → lib}/Socket/privacy.js +38 -41
  29. package/{src → lib}/Socket/registration.js +106 -113
  30. package/{src → lib}/Socket/socket.js +101 -88
  31. package/{src → lib}/Socket/text-router.js +17 -1
  32. package/lib/Socket/username.js +243 -0
  33. package/lib/Store/keyed-db.js +108 -0
  34. package/{src → lib}/Store/make-in-memory-store.js +104 -6
  35. package/lib/Types/Mex.js +112 -0
  36. package/{src → lib}/Types/Newsletter.js +41 -72
  37. package/{src → lib}/Types/index.js +1 -0
  38. package/{src → lib}/Utils/chat-utils.js +9 -73
  39. package/lib/Utils/command-loader.d.ts +31 -0
  40. package/lib/Utils/command-loader.js +100 -0
  41. package/lib/Utils/companion-reg-client-utils.js +42 -0
  42. package/lib/Utils/crypto.js +155 -0
  43. package/lib/Utils/curve25519-js.js +275 -0
  44. package/{src → lib}/Utils/decode-wa-message.js +36 -284
  45. package/{src → lib}/Utils/event-buffer.js +27 -6
  46. package/{src → lib}/Utils/generics.js +37 -114
  47. package/{src → lib}/Utils/index.js +5 -1
  48. package/lib/Utils/lt-hash.js +39 -0
  49. package/{src → lib}/Utils/message-retry-manager.js +39 -0
  50. package/{src → lib}/Utils/messages-media.js +58 -105
  51. package/{src → lib}/Utils/messages.js +529 -115
  52. package/lib/Utils/meta-ai-msmsg.js +262 -0
  53. package/lib/Utils/native-bridge.js +82 -0
  54. package/{src → lib}/Utils/noise-handler.js +15 -13
  55. package/{src → lib}/Utils/process-message.js +55 -54
  56. package/{src → lib}/Utils/reporting-utils.js +2 -2
  57. package/lib/Utils/session-pool.d.ts +16 -0
  58. package/lib/Utils/session-pool.js +94 -0
  59. package/{src → lib}/Utils/signal.js +51 -19
  60. package/{src → lib}/Utils/stanza-ack.js +2 -36
  61. package/lib/Utils/sticker.d.ts +17 -0
  62. package/lib/Utils/sticker.js +145 -0
  63. package/{src → lib}/Utils/tc-token-utils.js +1 -1
  64. package/{src → lib}/Utils/validate-connection.js +11 -40
  65. package/lib/Utils/view-once-cache.d.ts +9 -0
  66. package/lib/Utils/view-once-cache.js +79 -0
  67. package/{src → lib}/WABinary/decode.js +4 -38
  68. package/lib/WABinary/encode.js +228 -0
  69. package/{src → lib}/WABinary/generic-utils.js +93 -1
  70. package/{src → lib}/WABinary/jid-utils.js +3 -16
  71. package/{src → lib}/WAM/encode.js +1 -1
  72. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +43 -0
  73. package/{src → lib}/WAUSync/Protocols/USyncContactProtocol.js +1 -7
  74. package/{src → lib}/WAUSync/Protocols/USyncDeviceProtocol.js +5 -13
  75. package/{src → lib}/WAUSync/Protocols/USyncDisappearingModeProtocol.js +4 -1
  76. package/{src → lib}/WAUSync/Protocols/USyncFeatureProtocol.js +2 -17
  77. package/{src → lib}/WAUSync/Protocols/USyncStatusProtocol.js +2 -7
  78. package/{src → lib}/WAUSync/Protocols/USyncUsernameProtocol.js +1 -2
  79. package/{src → lib}/WAUSync/Protocols/index.js +0 -1
  80. package/{src → lib}/WAUSync/USyncQuery.js +6 -77
  81. package/{src → lib}/WAUSync/USyncUser.js +8 -16
  82. package/{src → lib}/WAUSync/index.js +0 -1
  83. package/{src → lib}/antiban.js +266 -355
  84. package/{src → lib}/index.js +2 -2
  85. package/package.json +19 -16
  86. package/WAProto/fix-import.js +0 -38
  87. package/src/Socket/mex.js +0 -47
  88. package/src/Socket/username.js +0 -234
  89. package/src/Utils/crypto.js +0 -125
  90. package/src/Utils/lt-hash.js +0 -10
  91. package/src/Utils/message-inspect.js +0 -400
  92. package/src/Utils/meta-ai-msmsg.js +0 -133
  93. package/src/WABinary/encode.js +0 -58
  94. package/src/WAUSync/Protocols/USyncBusinessProtocol.js +0 -100
  95. package/src/WAUSync/USyncBackoff.js +0 -31
  96. /package/{src → lib}/Defaults/phonenumber-mcc.json +0 -0
  97. /package/{src → lib}/Signal/Group/ciphertext-message.js +0 -0
  98. /package/{src → lib}/Signal/Group/group-session-builder.js +0 -0
  99. /package/{src → lib}/Signal/Group/index.js +0 -0
  100. /package/{src → lib}/Signal/Group/sender-key-name.js +0 -0
  101. /package/{src → lib}/Signal/Group/sender-key-state.js +0 -0
  102. /package/{src → lib}/Signal/lid-mapping.js +0 -0
  103. /package/{src → lib}/Socket/Client/index.js +0 -0
  104. /package/{src → lib}/Socket/Client/types.js +0 -0
  105. /package/{src → lib}/Socket/Client/websocket.js +0 -0
  106. /package/{src → lib}/Socket/aigroups.js +0 -0
  107. /package/{src → lib}/Socket/business.js +0 -0
  108. /package/{src → lib}/Store/index.js +0 -0
  109. /package/{src → lib}/Store/make-cache-manager-store.js +0 -0
  110. /package/{src → lib}/Store/make-ordered-dictionary.js +0 -0
  111. /package/{src → lib}/Store/object-repository.js +0 -0
  112. /package/{src → lib}/Types/Auth.js +0 -0
  113. /package/{src → lib}/Types/Bussines.js +0 -0
  114. /package/{src → lib}/Types/Call.js +0 -0
  115. /package/{src → lib}/Types/Chat.js +0 -0
  116. /package/{src → lib}/Types/Contact.js +0 -0
  117. /package/{src → lib}/Types/Events.js +0 -0
  118. /package/{src → lib}/Types/GroupMetadata.js +0 -0
  119. /package/{src → lib}/Types/Label.js +0 -0
  120. /package/{src → lib}/Types/LabelAssociation.js +0 -0
  121. /package/{src → lib}/Types/Message.js +0 -0
  122. /package/{src → lib}/Types/Product.js +0 -0
  123. /package/{src → lib}/Types/Signal.js +0 -0
  124. /package/{src → lib}/Types/Socket.js +0 -0
  125. /package/{src → lib}/Types/State.js +0 -0
  126. /package/{src → lib}/Types/USync.js +0 -0
  127. /package/{src → lib}/Utils/auth-utils.js +0 -0
  128. /package/{src → lib}/Utils/browser-utils.js +0 -0
  129. /package/{src → lib}/Utils/business.js +0 -0
  130. /package/{src → lib}/Utils/consumer-application.js +0 -0
  131. /package/{src → lib}/Utils/group-history.js +0 -0
  132. /package/{src → lib}/Utils/history.js +0 -0
  133. /package/{src → lib}/Utils/identity-change-handler.js +0 -0
  134. /package/{src → lib}/Utils/jid-display-normalization.js +0 -0
  135. /package/{src → lib}/Utils/link-preview.js +0 -0
  136. /package/{src → lib}/Utils/logger.js +0 -0
  137. /package/{src → lib}/Utils/make-mutex.js +0 -0
  138. /package/{src → lib}/Utils/message-composer.js +0 -0
  139. /package/{src → lib}/Utils/offline-node-processor.js +0 -0
  140. /package/{src → lib}/Utils/pre-key-manager.js +0 -0
  141. /package/{src → lib}/Utils/sync-action-utils.js +0 -0
  142. /package/{src → lib}/Utils/use-multi-file-auth-state.js +0 -0
  143. /package/{src → lib}/Utils/voip-rekey.js +0 -0
  144. /package/{src → lib}/WABinary/constants.js +0 -0
  145. /package/{src → lib}/WABinary/index.js +0 -0
  146. /package/{src → lib}/WABinary/types.js +0 -0
  147. /package/{src → lib}/WAM/BinaryInfo.js +0 -0
  148. /package/{src → lib}/WAM/constants.js +0 -0
  149. /package/{src → lib}/WAM/index.js +0 -0
  150. /package/{src → lib}/WAUSync/Protocols/USyncBotProfileProtocol.js +0 -0
  151. /package/{src → lib}/WAUSync/Protocols/USyncLIDProtocol.js +0 -0
  152. /package/{src → lib}/WAUSync/Protocols/USyncPictureProtocol.js +0 -0
  153. /package/{src → lib}/WAUSync/Protocols/USyncSidelistProtocol.js +0 -0
  154. /package/{src → lib}/WAUSync/Protocols/USyncTextStatusProtocol.js +0 -0
@@ -11,6 +11,7 @@ exports.decryptMessageNode =
11
11
  void 0
12
12
  exports.decodeMessageNode = decodeMessageNode
13
13
  const boom_1 = require('@hapi/boom')
14
+ const index_js_1 = require('../../WAProto/index.js')
14
15
  const WAProto_1 = require('../../WAProto/index.js')
15
16
  const WABinary_1 = require('../WABinary')
16
17
  const generics_1 = require('./generics')
@@ -64,11 +65,12 @@ const getDecryptionJid = async (sender, repository) => {
64
65
  }
65
66
  exports.getDecryptionJid = getDecryptionJid
66
67
  const storeMappingFromEnvelope = async (stanza, sender, repository, decryptionJid, logger) => {
68
+ // TODO: Handle hosted IDs
67
69
  const { senderAlt } = (0, exports.extractAddressingContext)(stanza)
68
70
  if (
69
71
  senderAlt &&
70
- ((0, WABinary_1.isLidUser)(senderAlt) || (0, WABinary_1.isHostedLidUser)(senderAlt)) &&
71
- ((0, WABinary_1.isPnUser)(sender) || (0, WABinary_1.isHostedPnUser)(sender)) &&
72
+ (0, WABinary_1.isLidUser)(senderAlt) &&
73
+ (0, WABinary_1.isPnUser)(sender) &&
72
74
  decryptionJid === sender
73
75
  ) {
74
76
  try {
@@ -145,48 +147,10 @@ exports.extractAddressingContext = extractAddressingContext
145
147
  * @note this will only parse the message, not decrypt it
146
148
  */
147
149
  function decodeMessageNode(stanza, meId, meLid) {
148
- let nodey = []
149
150
  let msgType
150
151
  let chatId
151
152
  let author
152
153
  let fromMe = false
153
- for (const { tag, attrs, content } of stanza.content) {
154
- const clean = v => {
155
- if (Array.isArray(v)) return v.map(clean);
156
-
157
- if (v && typeof v === "object") {
158
- const keys = Object.keys(v);
159
-
160
- if (
161
- keys.length &&
162
- keys.every(k => /^\d+$/.test(k))
163
- ) {
164
- return "[bytes]";
165
- }
166
-
167
- if (
168
- v.type === "Buffer" &&
169
- Array.isArray(v.data)
170
- ) {
171
- return "[bytes]";
172
- }
173
-
174
- return Object.fromEntries(
175
- Object.entries(v).map(([k, val]) => [k, clean(val)])
176
- );
177
- }
178
-
179
- return v;
180
- }
181
- if (tag !== "plaintext" && tag !== "enc") {
182
- nodey.push(clean({
183
- tag: tag,
184
- attrs: attrs,
185
- content: content
186
- }))
187
- }
188
- }
189
-
190
154
  const msgId = stanza.attrs.id
191
155
  const from = stanza.attrs.from
192
156
  const participant = stanza.attrs.participant
@@ -288,12 +252,10 @@ content: content
288
252
  broadcast: (0, WABinary_1.isJidBroadcast)(from),
289
253
  newsletter: (0, WABinary_1.isJidNewsletter)(from),
290
254
  StanzaAttrs: stanza.attrs,
291
- nodes: nodey,
292
- Owner: 'Baron' // Non-WhatsApp attribute
293
-
255
+ Owner: 'xazbails' // Non-WhatsApp attribute
294
256
  }
295
257
  if (key.fromMe) {
296
- fullMessage.status = WAProto_1.proto.WebMessageInfo.Status.SERVER_ACK
258
+ fullMessage.status = index_js_1.proto.WebMessageInfo.Status.SERVER_ACK
297
259
  }
298
260
  if (msgType === 'newsletter') {
299
261
  fullMessage.newsletter_server_id = +stanza.attrs?.server_id
@@ -344,27 +306,14 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
344
306
  }
345
307
  }
346
308
 
347
- // Process unicast enc nodes (pkmsg/msg) before group enc nodes (skmsg/frskmsg)
348
- // so that any SenderKeyDistributionMessage carried in a unicast is installed
349
- // before GroupCipher.decrypt() runs for frskmsg in the same stanza.
350
- const _isGroupEnc = n => n.tag === 'enc' && (n.attrs?.type === 'skmsg' || n.attrs?.type === 'frskmsg')
351
- const _stanzaContent = [
352
- ...stanza.content.filter(n => !_isGroupEnc(n)),
353
- ...stanza.content.filter(n => _isGroupEnc(n))
354
- ]
355
- for (const { tag, attrs, content } of _stanzaContent) {
309
+ for (const { tag, attrs, content } of stanza.content) {
356
310
  if (tag === 'verified_name' && content instanceof Uint8Array) {
357
- const cert = WAProto_1.proto.VerifiedNameCertificate.decode(content)
358
- const details = WAProto_1.proto.VerifiedNameCertificate.Details.decode(cert.details)
311
+ const cert = index_js_1.proto.VerifiedNameCertificate.decode(content)
312
+ const details = index_js_1.proto.VerifiedNameCertificate.Details.decode(cert.details)
359
313
  fullMessage.verifiedBizName = details.verifiedName
360
- // Extract verified level from node attrs (LOW / HIGH / UNKNOWN)
361
- if (attrs?.verified_level) {
362
- fullMessage.verifiedNameLevel = attrs.verified_level
363
- }
364
314
  }
365
315
  if (tag === 'unavailable' && attrs.type === 'view_once') {
366
- fullMessage.key.isViewOnce = true
367
- fullMessage.messageStubType = WAProto_1.proto.WebMessageInfo.StubType.VIEWED_ONCE
316
+ fullMessage.key.isViewOnce = true // TODO: remove from here and add a STUB TYPE
368
317
  }
369
318
  if (attrs.count && tag === 'enc') {
370
319
  fullMessage.retryCount = Number(attrs.count)
@@ -379,15 +328,12 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
379
328
  let msgBuffer
380
329
  const decryptionJid = await (0, exports.getDecryptionJid)(author, repository)
381
330
  if (tag !== 'plaintext') {
382
- if ((0, WABinary_1.isHostedPnUser)(decryptionJid) || (0, WABinary_1.isHostedLidUser)(decryptionJid)) {
383
- fullMessage.isHostedDevice = true
384
- }
331
+ // TODO: Handle hosted devices
385
332
  await storeMappingFromEnvelope(stanza, author, repository, decryptionJid, logger)
386
333
  }
387
334
  try {
388
335
  const e2eType = tag === 'plaintext' ? 'plaintext' : attrs.type
389
336
  switch (e2eType) {
390
- case 'frskmsg':
391
337
  case 'skmsg':
392
338
  msgBuffer = await repository.decryptGroupMessage({
393
339
  group: sender,
@@ -396,36 +342,14 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
396
342
  })
397
343
  break
398
344
 
399
- case 'story_reply':
400
- case 'feed_reshare':
401
- case 'native_flow_response':
402
- case 'companion_enc_static':
403
- case 'avatar_sticker':
404
- case 'genai_sticker':
405
- case 'account_authentication_request':
406
- case 'motion_video':
407
- case 'motion_photo':
408
345
  case 'pkmsg':
409
- case 'msg': {
410
- const _unicastType =
411
- e2eType === 'story_reply' ||
412
- e2eType === 'feed_reshare' ||
413
- e2eType === 'native_flow_response' ||
414
- e2eType === 'companion_enc_static' ||
415
- e2eType === 'avatar_sticker' ||
416
- e2eType === 'genai_sticker' ||
417
- e2eType === 'account_authentication_request' ||
418
- e2eType === 'motion_video' ||
419
- e2eType === 'motion_photo'
420
- ? 'msg'
421
- : e2eType
346
+ case 'msg':
422
347
  msgBuffer = await repository.decryptMessage({
423
348
  jid: decryptionJid,
424
- type: _unicastType,
349
+ type: e2eType,
425
350
  ciphertext: content
426
351
  })
427
352
  break
428
- }
429
353
  case 'msmsg': //Message Secret Message
430
354
  // null = no bot node (non-streaming), 'full'/'last' = complete response
431
355
  // 'first' = streaming partial response, intentionally skipped
@@ -464,11 +388,17 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
464
388
  participant: author,
465
389
  meId: metaTargetSenderJid || `${meLid.split(`:`)[0]}@lid`,
466
390
  meLid,
391
+ conversationJid: sender,
392
+ senderJid: metaTargetSenderJid,
393
+ botType,
467
394
  botEditTargetId,
468
395
  metaTargetId,
469
- stanzaId: stanza.attrs?.id
396
+ stanzaId: stanza.attrs?.id,
397
+ targetId: botEditTargetId || metaTargetId || stanza.attrs?.id,
398
+ targetIdCandidates: secretIdCandidates
470
399
  }
471
400
  let decryptErr
401
+ const candidateAttemptSummaries = []
472
402
  for (const candidate of secretCandidates) {
473
403
  try {
474
404
  msgBuffer = await (0, meta_ai_msmsg_1.decryptMsmsgBotMessage)(candidate.secret, helperKey, msMsg)
@@ -476,16 +406,24 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
476
406
  break
477
407
  } catch (e) {
478
408
  decryptErr = e
409
+ if (Array.isArray(e?.attemptedStrategies) && e.attemptedStrategies.length) {
410
+ candidateAttemptSummaries.push({
411
+ secretSource: candidate.source,
412
+ attemptedStrategies: e.attemptedStrategies
413
+ })
414
+ }
479
415
  }
480
416
  }
481
- if (!msgBuffer && decryptErr) {
417
+ if (!msgBuffer && candidateAttemptSummaries.length) {
482
418
  logger.warn(
483
419
  {
484
420
  secretCandidateSources: secretCandidates.map(candidate => candidate.source),
485
- cause: decryptErr?.message
421
+ attemptsBySecret: candidateAttemptSummaries
486
422
  },
487
423
  'msmsg: helper decryption failed for all candidate secrets'
488
424
  )
425
+ }
426
+ if (!msgBuffer && decryptErr) {
489
427
  throw decryptErr
490
428
  }
491
429
  }
@@ -508,7 +446,9 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
508
446
  let msg =
509
447
  e2eType === 'msmsg'
510
448
  ? (0, meta_ai_msmsg_1.decodeDecryptedMsmsgMessage)(msgBuffer)
511
- : WAProto_1.proto.Message.decode(msgToDecode)
449
+ : index_js_1.proto.Message.decode(msgToDecode)
450
+ if (false) {
451
+ }
512
452
  const outerMessageContextInfo = msg.messageContextInfo
513
453
  msg = msg.deviceSentMessage?.message || msg
514
454
  // deviceSentMessage.message may not carry messageContextInfo (e.g. messageSecret for @bot)
@@ -527,199 +467,11 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
527
467
  logger.error({ key: fullMessage.key, err }, 'failed to process sender key distribution message')
528
468
  }
529
469
  }
530
- if (msg.fastRatchetKeySenderKeyDistributionMessage) {
531
- //eslint-disable-next-line max-depth
532
- try {
533
- await repository.processSenderKeyDistributionMessage({
534
- authorJid: author,
535
- item: msg.fastRatchetKeySenderKeyDistributionMessage
536
- })
537
- } catch (err) {
538
- logger.error(
539
- { key: fullMessage.key, err },
540
- 'failed to process fast ratchet sender key distribution message'
541
- )
542
- }
543
- }
544
470
  if (fullMessage.message) {
545
471
  Object.assign(fullMessage.message, msg)
546
472
  } else {
547
473
  fullMessage.message = msg
548
474
  }
549
- // --- story_reply metadata ---
550
- if (e2eType === 'story_reply') {
551
- fullMessage.storyReply = true
552
- // Secondary check: quoted status JID in the decoded message
553
- const quotedJid = msg.extendedTextMessage?.contextInfo?.remoteJid
554
- if (quotedJid && (0, WABinary_1.isJidStatusBroadcast)(quotedJid)) {
555
- fullMessage.storyReply = true
556
- }
557
- }
558
- // --- feed_reshare metadata ---
559
- if (e2eType === 'feed_reshare') {
560
- fullMessage.feedReshare = true
561
- }
562
- // --- view_once type from enc attributes ---
563
- if (attrs.view_once === 'read' || attrs.view_once === 'write') {
564
- fullMessage.viewOnceType = attrs.view_once
565
- }
566
- // --- XMA message ---
567
- if (msg.xmaMessage) {
568
- fullMessage.xma = msg.xmaMessage
569
- fullMessage.messageType = 'xma'
570
- }
571
- // --- native_flow_response ---
572
- if (e2eType === 'native_flow_response' || msg.nativeFlowResponseMessage) {
573
- fullMessage.messageType = 'native_flow_response'
574
- if (msg.nativeFlowResponseMessage) {
575
- fullMessage.nativeFlowResponse = msg.nativeFlowResponseMessage
576
- // SMB quick reply is a business-specific native flow variant
577
- if (msg.nativeFlowResponseMessage.name === 'md_smb_quick_reply') {
578
- fullMessage.smbQuickReply = true
579
- }
580
- }
581
- }
582
- // --- call_permission_request ---
583
- if (msg.callPermissionRequestMessage) {
584
- fullMessage.messageType = 'call_permission_request'
585
- fullMessage.callPermissionRequest = msg.callPermissionRequestMessage
586
- }
587
- // --- Product / Order / Catalog types ---
588
- if (msg.productMessage) {
589
- fullMessage.messageType = 'product'
590
- } else if (msg.orderMessage) {
591
- fullMessage.messageType = 'order'
592
- } else if (msg.catalogMessage || msg.listMessage?.catalogType) {
593
- fullMessage.messageType = 'catalog'
594
- }
595
- // --- Payment types ---
596
- if (msg.paymentMessage) {
597
- fullMessage.messageType = 'payment'
598
- const pm = msg.paymentMessage
599
- fullMessage.paymentInfo = {
600
- amount: pm.amount1000 ? pm.amount1000 / 1000 : null,
601
- currency: pm.currencyCodeIso4217 || null,
602
- status: pm.status || null,
603
- transactionTimestamp: pm.transactionTimestamp
604
- ? pm.transactionTimestamp.toNumber?.() || pm.transactionTimestamp
605
- : null,
606
- type: pm.type || null,
607
- method: pm.paymentMethod || null,
608
- futureProofed: pm.futureProofed || false
609
- }
610
- }
611
- if (msg.requestPaymentMessage) {
612
- fullMessage.messageType = 'request_payment'
613
- fullMessage.paymentRequest = {
614
- amount: msg.requestPaymentMessage.amount || null,
615
- currency: msg.requestPaymentMessage.currencyCodeIso4217 || null,
616
- expiry: msg.requestPaymentMessage.expiryTimestamp || null
617
- }
618
- }
619
- if (msg.sendPaymentMessage) {
620
- fullMessage.messageType = 'send_payment'
621
- }
622
- if (msg.cancelPaymentRequestMessage) {
623
- fullMessage.messageType = 'cancel_payment'
624
- }
625
- // --- Sticker flags ---
626
- if (msg.stickerMessage) {
627
- if (msg.stickerMessage.isAvatar) {
628
- fullMessage.isAvatarSticker = true
629
- }
630
- if (msg.stickerMessage.isAiSticker || msg.stickerMessage.isGenAI) {
631
- fullMessage.isAiSticker = true
632
- }
633
- }
634
- // --- StickerPackMessage ---
635
- if (msg.stickerPackMessage) {
636
- fullMessage.messageType = 'sticker_pack'
637
- const sp = msg.stickerPackMessage
638
- fullMessage.stickerPack = {
639
- id: sp.stickerPackId,
640
- name: sp.name,
641
- // 0 = FIRST_PARTY, 1 = THIRD_PARTY
642
- origin: sp.stickerPackOrigin,
643
- size: sp.stickerPackSize,
644
- stickers: sp.stickers || []
645
- }
646
- }
647
- // --- AI media collection metadata from bot context ---
648
- if (msg.messageContextInfo?.botMetadata?.aiMediaCollectionMetadata) {
649
- fullMessage.aiMediaCollectionMetadata = {
650
- collectionId: msg.messageContextInfo.botMetadata.aiMediaCollectionMetadata.collectionId,
651
- uploadOrderIndex: msg.messageContextInfo.botMetadata.aiMediaCollectionMetadata.uploadOrderIndex
652
- }
653
- }
654
- // --- ProtocolMessage: AI media collection coordination ---
655
- if (msg.protocolMessage?.aiMediaCollectionMessage) {
656
- fullMessage.messageType = 'ai_media_collection'
657
- const amc = msg.protocolMessage.aiMediaCollectionMessage
658
- fullMessage.aiMediaCollection = {
659
- collectionId: amc.collectionId,
660
- expectedMediaCount: amc.expectedMediaCount
661
- }
662
- }
663
- // --- SplitPaymentMessage ---
664
- if (msg.splitPaymentMessage) {
665
- fullMessage.messageType = 'split_payment'
666
- const sp = msg.splitPaymentMessage
667
- fullMessage.splitPayment = {
668
- splitId: sp.splitId,
669
- totalAmount: sp.totalAmount,
670
- description: sp.description,
671
- requesterJid: sp.requesterJid,
672
- participants: (sp.participants || []).map(p => ({
673
- jid: p.jid,
674
- amount: p.amount,
675
- // 0 = PENDING, 1 = PAID
676
- status: p.status
677
- })),
678
- createdAtMs: sp.createdAtMs ? sp.createdAtMs.toNumber?.() || sp.createdAtMs : null
679
- }
680
- }
681
- // --- PaymentInviteMessage (FBPAY / UPI / NOVI) ---
682
- if (msg.paymentInviteMessage) {
683
- fullMessage.messageType = 'payment_invite'
684
- const SERVICE_TYPE = { 0: 'UNKNOWN', 1: 'FBPAY', 2: 'NOVI', 3: 'UPI' }
685
- fullMessage.paymentInvite = {
686
- serviceType: SERVICE_TYPE[msg.paymentInviteMessage.serviceType] || 'UNKNOWN',
687
- expiry: msg.paymentInviteMessage.expiryTimestamp
688
- ? msg.paymentInviteMessage.expiryTimestamp.toNumber?.() || msg.paymentInviteMessage.expiryTimestamp
689
- : null,
690
- incentiveEligible: msg.paymentInviteMessage.incentiveEligible || false
691
- }
692
- }
693
- // --- PaymentReminderMessage ---
694
- if (msg.paymentReminderMessage) {
695
- fullMessage.messageType = 'payment_reminder'
696
- }
697
- // --- companion_enc_static ---
698
- if (e2eType === 'companion_enc_static') {
699
- fullMessage.companionEncStatic = true
700
- }
701
- // --- avatar_sticker / genai_sticker enc type ---
702
- if (e2eType === 'avatar_sticker' || e2eType === 'genai_sticker') {
703
- fullMessage.stickerType = e2eType
704
- }
705
- // --- account_authentication_request ---
706
- if (e2eType === 'account_authentication_request' || msg.accountAuthRequestMessage) {
707
- fullMessage.messageType = 'account_auth_request'
708
- }
709
- // --- motion_video ---
710
- if (e2eType === 'motion_video' || (msg.videoMessage && msg.videoMessage.motionVideo)) {
711
- fullMessage.messageType = 'motion_video'
712
- fullMessage.motionVideo = true
713
- }
714
- // --- motion_photo ---
715
- if (e2eType === 'motion_photo' || (msg.imageMessage && msg.imageMessage.motionPhoto)) {
716
- fullMessage.messageType = 'motion_photo'
717
- fullMessage.motionPhoto = true
718
- }
719
- // --- non-E2EE plaintext (newsletter / system channel messages) ---
720
- if (e2eType === 'plaintext') {
721
- fullMessage.isNonE2EE = true
722
- }
723
475
  // Auto-decode richResponseMessage text so m.msg.text is populated
724
476
  {
725
477
  const rich = fullMessage.message?.richResponseMessage
@@ -753,14 +505,14 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
753
505
  isSessionRecordError: isSessionRecordError(err)
754
506
  }
755
507
  logger.error(errorContext, 'failed to decrypt message')
756
- fullMessage.messageStubType = WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT
508
+ fullMessage.messageStubType = index_js_1.proto.WebMessageInfo.StubType.CIPHERTEXT
757
509
  fullMessage.messageStubParameters = [err.message.toString()]
758
510
  }
759
511
  }
760
512
  }
761
513
  // if nothing was found to decrypt
762
514
  if (!decryptables && !fullMessage.key?.isViewOnce) {
763
- fullMessage.messageStubType = WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT
515
+ fullMessage.messageStubType = index_js_1.proto.WebMessageInfo.StubType.CIPHERTEXT
764
516
  fullMessage.messageStubParameters = [exports.NO_MESSAGE_FOUND_ERROR_TEXT]
765
517
  }
766
518
  }
@@ -795,7 +547,7 @@ function decodeRichResponseMessage(richMsg) {
795
547
  }
796
548
  }
797
549
  return texts.join('\n')
798
- } catch {
550
+ } catch (e) {
799
551
  return ''
800
552
  }
801
553
  }
@@ -175,7 +175,6 @@ const makeEventBuffer = logger => {
175
175
  },
176
176
  on: (...args) => ev.on(...args),
177
177
  off: (...args) => ev.off(...args),
178
- once: (...args) => ev.once(...args),
179
178
  removeAllListeners: (...args) => ev.removeAllListeners(...args)
180
179
  }
181
180
  }
@@ -247,6 +246,30 @@ function append(
247
246
  }
248
247
  data.historySets.empty = false
249
248
  data.historySets.syncType = eventData.syncType
249
+ if (eventData.pastParticipants?.length) {
250
+ const merged = new Map()
251
+ const sigOf = p => `${p.userJid || ''}:${p.leaveTs || ''}:${p.leaveReason || ''}`
252
+ const ingest = entry => {
253
+ const key = entry.groupJid ?? JSON.stringify(entry)
254
+ const existing = merged.get(key)
255
+ if (!existing) {
256
+ merged.set(key, { ...entry, pastParticipants: [...(entry.pastParticipants || [])] })
257
+ return
258
+ }
259
+ const seen = new Set((existing.pastParticipants || []).map(sigOf))
260
+ for (const p of entry.pastParticipants || []) {
261
+ const sig = sigOf(p)
262
+ if (!seen.has(sig)) {
263
+ existing.pastParticipants.push(p)
264
+ seen.add(sig)
265
+ }
266
+ }
267
+ }
268
+ for (const entry of data.historySets.pastParticipants || []) ingest(entry)
269
+ for (const entry of eventData.pastParticipants) ingest(entry)
270
+ data.historySets.pastParticipants = [...merged.values()]
271
+ }
272
+ data.historySets.chunkOrder = eventData.chunkOrder
250
273
  data.historySets.progress = eventData.progress
251
274
  data.historySets.peerDataRequestSessionId = eventData.peerDataRequestSessionId
252
275
  data.historySets.isLatest = eventData.isLatest || data.historySets.isLatest
@@ -419,11 +442,7 @@ function append(
419
442
  }
420
443
  }
421
444
  } else {
422
- // Reserved for a whole-chat-clear variant ({ jid, all: true }); nothing in
423
- // this codebase emits that shape today (the only emitter is chat-utils.js,
424
- // always with `keys`), and the flush loop below only supports one payload
425
- // per event name, so consolidating it properly needs that loop reworked
426
- // first — not adding untested handling for a shape with no current caller.
445
+ // TODO: add support
427
446
  }
428
447
  break
429
448
  case 'messages.reaction':
@@ -507,9 +526,11 @@ function consolidateEvents(data) {
507
526
  chats: Object.values(data.historySets.chats),
508
527
  messages: Object.values(data.historySets.messages),
509
528
  contacts: Object.values(data.historySets.contacts),
529
+ pastParticipants: data.historySets.pastParticipants,
510
530
  syncType: data.historySets.syncType,
511
531
  progress: data.historySets.progress,
512
532
  isLatest: data.historySets.isLatest,
533
+ chunkOrder: data.historySets.chunkOrder,
513
534
  peerDataRequestSessionId: data.historySets.peerDataRequestSessionId
514
535
  }
515
536
  }