@badzz88/baileys 8.5.3 → 8.5.4

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 (110) hide show
  1. package/README.md +1 -1
  2. package/WAProto/WAProto.proto +1256 -75
  3. package/WAProto/index.d.ts +36042 -19649
  4. package/WAProto/index.js +181990 -135645
  5. package/engine-requirements.js +7 -15
  6. package/lib/Defaults/index.js +22 -17
  7. package/lib/Signal/Group/group_cipher.js +5 -5
  8. package/lib/Signal/Group/keyhelper.js +4 -4
  9. package/lib/Signal/Group/sender-chain-key.js +2 -2
  10. package/lib/Signal/Group/sender-key-distribution-message.js +1 -1
  11. package/lib/Signal/Group/sender-key-message.js +3 -3
  12. package/lib/Signal/Group/sender-key-record.js +1 -1
  13. package/lib/Signal/Group/sender-message-key.js +5 -5
  14. package/lib/Signal/libsignal.js +39 -59
  15. package/lib/Signal/lid-mapping.js +28 -10
  16. package/lib/Socket/aigroups.js +5 -5
  17. package/lib/Socket/business.js +3 -11
  18. package/lib/Socket/chats.js +668 -319
  19. package/lib/Socket/communities.js +85 -89
  20. package/lib/Socket/graphql.js +435 -228
  21. package/lib/Socket/groups.js +132 -211
  22. package/lib/Socket/index.js +9 -7
  23. package/lib/Socket/interactive-handler.js +117 -60
  24. package/lib/Socket/interop.js +56 -175
  25. package/lib/Socket/managed-account.js +79 -48
  26. package/lib/Socket/messages-recv.js +898 -340
  27. package/lib/Socket/messages-send.js +462 -160
  28. package/lib/Socket/mex.js +40 -53
  29. package/lib/Socket/newsletter.js +291 -295
  30. package/lib/Socket/privacy.js +77 -265
  31. package/lib/Socket/registration.js +164 -157
  32. package/lib/Socket/socket.js +181 -199
  33. package/lib/Socket/username.js +144 -227
  34. package/lib/Store/make-cache-manager-store.js +2 -2
  35. package/lib/Store/make-in-memory-store.js +25 -141
  36. package/lib/Types/Auth.js +3 -3
  37. package/lib/Types/Label.js +1 -1
  38. package/lib/Types/LabelAssociation.js +1 -1
  39. package/lib/Types/Newsletter.js +96 -65
  40. package/lib/Types/State.js +4 -4
  41. package/lib/Types/index.js +1 -1
  42. package/lib/Utils/auth-utils.js +52 -57
  43. package/lib/Utils/browser-utils.js +1 -1
  44. package/lib/Utils/business.js +2 -6
  45. package/lib/Utils/chat-utils.js +102 -38
  46. package/lib/Utils/crypto.js +54 -84
  47. package/lib/Utils/decode-wa-message.js +316 -83
  48. package/lib/Utils/event-buffer.js +37 -61
  49. package/lib/Utils/generics.js +157 -103
  50. package/lib/Utils/group-history.js +3 -12
  51. package/lib/Utils/history.js +15 -15
  52. package/lib/Utils/index.js +1 -5
  53. package/lib/Utils/link-preview.js +3 -8
  54. package/lib/Utils/lt-hash.js +2 -35
  55. package/lib/Utils/make-mutex.js +1 -1
  56. package/lib/Utils/message-inspect.js +393 -0
  57. package/lib/Utils/message-retry-manager.js +27 -92
  58. package/lib/Utils/messages-media.js +159 -130
  59. package/lib/Utils/messages.js +144 -566
  60. package/lib/Utils/meta-ai-msmsg.js +62 -202
  61. package/lib/Utils/noise-handler.js +19 -21
  62. package/lib/Utils/offline-node-processor.js +3 -8
  63. package/lib/Utils/pre-key-manager.js +13 -23
  64. package/lib/Utils/process-message.js +197 -106
  65. package/lib/Utils/reporting-utils.js +2 -2
  66. package/lib/Utils/signal.js +28 -63
  67. package/lib/Utils/stanza-ack.js +39 -12
  68. package/lib/Utils/sync-action-utils.js +4 -7
  69. package/lib/Utils/tc-token-utils.js +20 -25
  70. package/lib/Utils/use-multi-file-auth-state.js +30 -14
  71. package/lib/Utils/validate-connection.js +59 -19
  72. package/lib/WABinary/decode.js +50 -16
  73. package/lib/WABinary/encode.js +54 -224
  74. package/lib/WABinary/generic-utils.js +7 -97
  75. package/lib/WABinary/jid-utils.js +27 -14
  76. package/lib/WAM/encode.js +7 -7
  77. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +58 -1
  78. package/lib/WAUSync/Protocols/USyncContactProtocol.js +7 -1
  79. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +13 -5
  80. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -4
  81. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +20 -7
  82. package/lib/WAUSync/Protocols/USyncNewsletterProtocol.js +865 -0
  83. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +1 -1
  84. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +2 -2
  85. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +7 -2
  86. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +1 -1
  87. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +2 -1
  88. package/lib/WAUSync/Protocols/index.js +1 -0
  89. package/lib/WAUSync/USyncBackoff.js +26 -0
  90. package/lib/WAUSync/USyncQuery.js +77 -6
  91. package/lib/WAUSync/USyncUser.js +16 -8
  92. package/lib/WAUSync/index.js +1 -0
  93. package/lib/antiban.js +608 -854
  94. package/lib/index.js +1 -1
  95. package/package.json +16 -20
  96. package/lib/Socket/luxu.js +0 -387
  97. package/lib/Socket/text-router.js +0 -83
  98. package/lib/Store/keyed-db.js +0 -108
  99. package/lib/Types/Mex.js +0 -112
  100. package/lib/Utils/command-loader.d.ts +0 -31
  101. package/lib/Utils/command-loader.js +0 -100
  102. package/lib/Utils/companion-reg-client-utils.js +0 -42
  103. package/lib/Utils/curve25519-js.js +0 -275
  104. package/lib/Utils/native-bridge.js +0 -82
  105. package/lib/Utils/session-pool.d.ts +0 -16
  106. package/lib/Utils/session-pool.js +0 -94
  107. package/lib/Utils/sticker.d.ts +0 -17
  108. package/lib/Utils/sticker.js +0 -145
  109. package/lib/Utils/view-once-cache.d.ts +0 -9
  110. package/lib/Utils/view-once-cache.js +0 -79
@@ -16,21 +16,25 @@ const Defaults_1 = require('../Defaults')
16
16
  const crypto_2 = require('./crypto')
17
17
  const generics_1 = require('./generics')
18
18
  const pre_key_manager_1 = require('./pre-key-manager')
19
- /**
20
- * Adds caching capability to a SignalKeyStore
21
- * @param store the store to add caching to
22
- * @param logger to log trace events
23
- * @param _cache cache store to use
24
- */
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+ const sharedTxStorage = new async_hooks_1.AsyncLocalStorage()
28
+
25
29
  function makeCacheableSignalKeyStore(store, logger, _cache) {
26
30
  const cache =
27
31
  _cache ||
28
32
  new node_cache_1.default({
29
- stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.SIGNAL_STORE, // 5 minutes
33
+ stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.SIGNAL_STORE,
30
34
  useClones: false,
31
35
  deleteOnExpire: true
32
36
  })
33
- // Mutex for protecting cache operations
37
+
34
38
  const cacheMutex = new async_mutex_1.Mutex()
35
39
  function getUniqueId(type, id) {
36
40
  return `${type}.${id}`
@@ -55,7 +59,7 @@ function makeCacheableSignalKeyStore(store, logger, _cache) {
55
59
  const item = fetched[id]
56
60
  if (item) {
57
61
  data[id] = item
58
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
62
+
59
63
  await cache.set(getUniqueId(type, id), item)
60
64
  }
61
65
  }
@@ -82,34 +86,32 @@ function makeCacheableSignalKeyStore(store, logger, _cache) {
82
86
  }
83
87
  }
84
88
  }
85
- /**
86
- * Adds DB-like transaction capability to the SignalKeyStore
87
- * Uses AsyncLocalStorage for automatic context management
88
- * @param state the key store to apply this capability to
89
- * @param logger logger to log events
90
- * @returns SignalKeyStore with transaction capability
91
- */
89
+
92
90
  const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetweenTriesMs }) => {
93
- const txStorage = new async_hooks_1.AsyncLocalStorage()
94
- // Queues for concurrency control (keyed by signal data type - bounded set)
91
+ const txStorage = sharedTxStorage
92
+
93
+
94
+
95
+ const storeToken = Symbol('addTransactionCapability')
96
+ const getOwnStore = () => {
97
+ const ctx = txStorage.getStore()
98
+ return ctx && ctx.token === storeToken ? ctx : undefined
99
+ }
100
+
95
101
  const keyQueues = new Map()
96
- // Transaction mutexes with reference counting for cleanup
102
+
97
103
  const txMutexes = new Map()
98
104
  const txMutexRefCounts = new Map()
99
- // Pre-key manager for specialized operations
105
+
100
106
  const preKeyManager = new pre_key_manager_1.PreKeyManager(state, logger)
101
- /**
102
- * Get or create a queue for a specific key type
103
- */
107
+
104
108
  function getQueue(key) {
105
109
  if (!keyQueues.has(key)) {
106
110
  keyQueues.set(key, new p_queue_1.default({ concurrency: 1 }))
107
111
  }
108
112
  return keyQueues.get(key)
109
113
  }
110
- /**
111
- * Get or create a transaction mutex
112
- */
114
+
113
115
  function getTxMutex(key) {
114
116
  if (!txMutexes.has(key)) {
115
117
  txMutexes.set(key, new async_mutex_1.Mutex())
@@ -117,20 +119,16 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
117
119
  }
118
120
  return txMutexes.get(key)
119
121
  }
120
- /**
121
- * Acquire a reference to a transaction mutex
122
- */
122
+
123
123
  function acquireTxMutexRef(key) {
124
124
  const count = txMutexRefCounts.get(key) ?? 0
125
125
  txMutexRefCounts.set(key, count + 1)
126
126
  }
127
- /**
128
- * Release a reference to a transaction mutex and cleanup if no longer needed
129
- */
127
+
130
128
  function releaseTxMutexRef(key) {
131
129
  const count = (txMutexRefCounts.get(key) ?? 1) - 1
132
130
  txMutexRefCounts.set(key, count)
133
- // Cleanup if no more references and mutex is not locked
131
+
134
132
  if (count <= 0) {
135
133
  const mutex = txMutexes.get(key)
136
134
  if (mutex && !mutex.isLocked()) {
@@ -139,15 +137,11 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
139
137
  }
140
138
  }
141
139
  }
142
- /**
143
- * Check if currently in a transaction
144
- */
140
+
145
141
  function isInTransaction() {
146
- return !!txStorage.getStore()
142
+ return !!getOwnStore()
147
143
  }
148
- /**
149
- * Commit transaction with retries
150
- */
144
+
151
145
  async function commitWithRetry(mutations) {
152
146
  if (Object.keys(mutations).length === 0) {
153
147
  logger.trace('no mutations in transaction')
@@ -171,23 +165,23 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
171
165
  }
172
166
  return {
173
167
  get: async (type, ids) => {
174
- const ctx = txStorage.getStore()
168
+ const ctx = getOwnStore()
175
169
  if (!ctx) {
176
- // No transaction - direct read without exclusive lock for concurrency
170
+
177
171
  return state.get(type, ids)
178
172
  }
179
- // In transaction - check cache first
173
+
180
174
  const cached = ctx.cache[type] || {}
181
175
  const missing = ids.filter(id => !(id in cached))
182
176
  if (missing.length > 0) {
183
177
  ctx.dbQueries++
184
178
  logger.trace({ type, count: missing.length }, 'fetching missing keys in transaction')
185
179
  const fetched = await getTxMutex(type).runExclusive(() => state.get(type, missing))
186
- // Update cache
180
+
187
181
  ctx.cache[type] = ctx.cache[type] || {}
188
182
  Object.assign(ctx.cache[type], fetched)
189
183
  }
190
- // Return requested ids from cache
184
+
191
185
  const result = {}
192
186
  for (const id of ids) {
193
187
  const value = ctx.cache[type]?.[id]
@@ -198,18 +192,18 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
198
192
  return result
199
193
  },
200
194
  set: async data => {
201
- const ctx = txStorage.getStore()
195
+ const ctx = getOwnStore()
202
196
  if (!ctx) {
203
- // No transaction - direct write with queue protection
197
+
204
198
  const types = Object.keys(data)
205
- // Process pre-keys with validation
199
+
206
200
  for (const type_ of types) {
207
201
  const type = type_
208
202
  if (type === 'pre-key') {
209
203
  await preKeyManager.validateDeletions(data, type)
210
204
  }
211
205
  }
212
- // Write all data in parallel
206
+
213
207
  await Promise.all(
214
208
  types.map(type =>
215
209
  getQueue(type).add(async () => {
@@ -220,18 +214,18 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
220
214
  )
221
215
  return
222
216
  }
223
- // In transaction - update cache and mutations
217
+
224
218
  logger.trace({ types: Object.keys(data) }, 'caching in transaction')
225
219
  for (const key_ in data) {
226
220
  const key = key_
227
- // Ensure structures exist
221
+
228
222
  ctx.cache[key] = ctx.cache[key] || {}
229
223
  ctx.mutations[key] = ctx.mutations[key] || {}
230
- // Special handling for pre-keys
224
+
231
225
  if (key === 'pre-key') {
232
226
  await preKeyManager.processOperations(data, key, ctx.cache, ctx.mutations, true)
233
227
  } else {
234
- // Normal key types
228
+
235
229
  Object.assign(ctx.cache[key], data[key])
236
230
  Object.assign(ctx.mutations[key], data[key])
237
231
  }
@@ -239,18 +233,19 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
239
233
  },
240
234
  isInTransaction,
241
235
  transaction: async (work, key) => {
242
- const existing = txStorage.getStore()
243
- // Nested transaction - reuse existing context
236
+ const existing = getOwnStore()
237
+
244
238
  if (existing) {
245
239
  logger.trace('reusing existing transaction context')
246
240
  return work()
247
241
  }
248
- // New transaction - acquire mutex and create context
242
+
249
243
  const mutex = getTxMutex(key)
250
244
  acquireTxMutexRef(key)
251
245
  try {
252
246
  return await mutex.runExclusive(async () => {
253
247
  const ctx = {
248
+ token: storeToken,
254
249
  cache: {},
255
250
  mutations: {},
256
251
  dbQueries: 0
@@ -258,7 +253,7 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
258
253
  logger.trace('entering transaction')
259
254
  try {
260
255
  const result = await txStorage.run(ctx, work)
261
- // Commit mutations
256
+
262
257
  await commitWithRetry(ctx.mutations)
263
258
  logger.trace({ dbQueries: ctx.dbQueries }, 'transaction completed')
264
259
  return result
@@ -109,6 +109,6 @@ exports.Browsers = {
109
109
  }
110
110
  const getPlatformId = browser => {
111
111
  const platformType = index_js_1.proto.DeviceProps.PlatformType[browser.toUpperCase()]
112
- return platformType ? platformType.toString() : '1' //chrome
112
+ return platformType ? platformType.toString() : '1'
113
113
  }
114
114
  exports.getPlatformId = getPlatformId
@@ -186,9 +186,7 @@ const parseProductNode = productNode => {
186
186
  return product
187
187
  }
188
188
  exports.parseProductNode = parseProductNode
189
- /**
190
- * Uploads images not already uploaded to WA's servers
191
- */
189
+
192
190
  async function uploadingNecessaryImagesOfProduct(product, waUploadToServer, timeoutMs = 30000) {
193
191
  product = {
194
192
  ...product,
@@ -198,9 +196,7 @@ async function uploadingNecessaryImagesOfProduct(product, waUploadToServer, time
198
196
  }
199
197
  return product
200
198
  }
201
- /**
202
- * Uploads images not already uploaded to WA's servers
203
- */
199
+
204
200
  const uploadingNecessaryImages = async (images, waUploadToServer, timeoutMs = 30000) => {
205
201
  const results = await Promise.all(
206
202
  images.map(async img => {
@@ -13,6 +13,7 @@ exports.processSyncAction =
13
13
  exports.newLTHashState =
14
14
  void 0
15
15
  const boom_1 = require('@hapi/boom')
16
+ const whatsapp_rust_bridge_1 = require('whatsapp-rust-bridge')
16
17
  const index_js_1 = require('../../WAProto/index.js')
17
18
  const LabelAssociation_1 = require('../Types/LabelAssociation')
18
19
  const WABinary_1 = require('../WABinary')
@@ -22,16 +23,13 @@ const lt_hash_1 = require('./lt-hash')
22
23
  const messages_media_1 = require('./messages-media')
23
24
  const sync_action_utils_1 = require('./sync-action-utils')
24
25
  const mutationKeys = keydata => {
25
- // app-state mutation keys are just HKDF-expanded sub-keys of a single 32-byte
26
- // key, no elliptic-curve math involved -- this is the standard derivation
27
- // used across the Baileys ecosystem.
28
- const expanded = (0, crypto_1.hkdf)(keydata, 160, { info: 'WhatsApp Mutation Keys' })
26
+ const keys = (0, whatsapp_rust_bridge_1.expandAppStateKeys)(keydata)
29
27
  return {
30
- indexKey: expanded.subarray(0, 32),
31
- valueEncryptionKey: expanded.subarray(32, 64),
32
- valueMacKey: expanded.subarray(64, 96),
33
- snapshotMacKey: expanded.subarray(96, 128),
34
- patchMacKey: expanded.subarray(128, 160)
28
+ indexKey: keys.indexKey,
29
+ valueEncryptionKey: keys.valueEncryptionKey,
30
+ valueMacKey: keys.valueMacKey,
31
+ snapshotMacKey: keys.snapshotMacKey,
32
+ patchMacKey: keys.patchMacKey
35
33
  }
36
34
  }
37
35
  const generateMac = (operation, data, keyId, key) => {
@@ -66,11 +64,11 @@ const makeLtHashGenerator = ({ indexValueMap, hash }) => {
66
64
  if (!prevOp) {
67
65
  throw new boom_1.Boom('tried remove, but no previous op', { data: { indexMac, valueMac } })
68
66
  }
69
- // remove from index value mac, since this mutation is erased
67
+
70
68
  delete indexValueMap[indexMacBase64]
71
69
  } else {
72
70
  addBuffs.push(valueMac)
73
- // add this index into the history map
71
+
74
72
  indexValueMap[indexMacBase64] = { valueMac }
75
73
  }
76
74
  if (prevOp) {
@@ -137,7 +135,7 @@ const encodeSyncdPatch = async (
137
135
  const encValue = (0, crypto_1.aesEncrypt)(encoded, keyValue.valueEncryptionKey)
138
136
  const valueMac = generateMac(operation, encValue, encKeyId, keyValue.valueMacKey)
139
137
  const indexMac = (0, crypto_1.hmacSign)(indexBuffer, keyValue.indexKey)
140
- // update LT hash
138
+
141
139
  const generator = makeLtHashGenerator(state)
142
140
  generator.mix({ indexMac, valueMac, operation })
143
141
  Object.assign(state, generator.finish())
@@ -170,12 +168,12 @@ exports.encodeSyncdPatch = encodeSyncdPatch
170
168
  const decodeSyncdMutations = async (msgMutations, initialState, getAppStateSyncKey, onMutation, validateMacs) => {
171
169
  const ltGenerator = makeLtHashGenerator(initialState)
172
170
  const derivedKeyCache = new Map()
173
- // indexKey used to HMAC sign record.index.blob
174
- // valueEncryptionKey used to AES-256-CBC encrypt record.value.blob[0:-32]
175
- // the remaining record.value.blob[0:-32] is the mac, it the HMAC sign of key.keyId + decoded proto data + length of bytes in keyId
171
+
172
+
173
+
176
174
  for (const msgMutation of msgMutations) {
177
- // if it's a syncdmutation, get the operation property
178
- // otherwise, if it's only a record -- it'll be a SET mutation
175
+
176
+
179
177
  const operation =
180
178
  'operation' in msgMutation ? msgMutation.operation : index_js_1.proto.SyncdMutation.SyncdOperation.SET
181
179
  const record = 'record' in msgMutation && !!msgMutation.record ? msgMutation.record : msgMutation
@@ -399,7 +397,7 @@ const decodePatches = async (
399
397
  throw new boom_1.Boom(`failed to verify LTHash at ${newState.version} of ${name}`)
400
398
  }
401
399
  }
402
- // clear memory used up by the mutations
400
+
403
401
  syncd.mutations = []
404
402
  }
405
403
  return { state: newState, mutationMap }
@@ -497,7 +495,7 @@ const chatModificationToAppPatch = (mod, jid) => {
497
495
  messageRange: getMessageRange(mod.lastMessages)
498
496
  }
499
497
  },
500
- index: ['clearChat', jid, '1' /*the option here is 0 when keep starred messages is enabled*/, '0'],
498
+ index: ['clearChat', jid, '1' , '0'],
501
499
  type: 'regular_high',
502
500
  apiVersion: 6,
503
501
  operation: OP.SET
@@ -843,6 +841,45 @@ const chatModificationToAppPatch = (mod, jid) => {
843
841
  apiVersion: 1,
844
842
  operation: OP.SET
845
843
  }
844
+ } else if ('externalWebBeta' in mod) {
845
+ patch = {
846
+ syncAction: {
847
+ externalWebBetaAction: { isOptIn: !!mod.externalWebBeta }
848
+ },
849
+ index: ['setting_external_web_beta'],
850
+ type: 'regular',
851
+ apiVersion: 1,
852
+ operation: OP.SET
853
+ }
854
+ } else if ('maibaAIFeatures' in mod) {
855
+ const statusEnum = index_js_1.proto.SyncActionValue.MaibaAIFeaturesControlAction.MaibaAIFeatureStatus
856
+ const replyModeEnum = index_js_1.proto.SyncActionValue.MaibaAIFeaturesControlAction.MaibaAIReplyMode
857
+ const statusMap = {
858
+ enabled: statusEnum.ENABLED,
859
+ enabled_has_learning: statusEnum.ENABLED_HAS_LEARNING,
860
+ disabled: statusEnum.DISABLED
861
+ }
862
+ const replyModeMap = {
863
+ muted: replyModeEnum.MUTED,
864
+ ai_agent: replyModeEnum.AI_AGENT,
865
+ suggestions: replyModeEnum.SUGGESTIONS
866
+ }
867
+ const aiFeatures = mod.maibaAIFeatures
868
+ const status =
869
+ typeof aiFeatures.status === 'string' ? (statusMap[aiFeatures.status] ?? statusEnum.ENABLED) : aiFeatures.status
870
+ const replyMode =
871
+ typeof aiFeatures.replyMode === 'string'
872
+ ? (replyModeMap[aiFeatures.replyMode] ?? replyModeEnum.SUGGESTIONS)
873
+ : aiFeatures.replyMode
874
+ patch = {
875
+ syncAction: {
876
+ maibaAiFeaturesControlAction: { aiFeatureStatus: status, aiReplyMode: replyMode }
877
+ },
878
+ index: ['setting_maiba_ai'],
879
+ type: 'regular',
880
+ apiVersion: 1,
881
+ operation: OP.SET
882
+ }
846
883
  } else {
847
884
  throw new boom_1.Boom('not supported')
848
885
  }
@@ -867,25 +904,25 @@ const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
867
904
  }
868
905
  ])
869
906
  } else if (action?.archiveChatAction || type === 'archive' || type === 'unarchive') {
870
- // okay so we've to do some annoying computation here
871
- // when we're initially syncing the app state
872
- // there are a few cases we need to handle
873
- // 1. if the account unarchiveChats setting is true
874
- // a. if the chat is archived, and no further messages have been received -- simple, keep archived
875
- // b. if the chat was archived, and the user received messages from the other person afterwards
876
- // then the chat should be marked unarchved --
877
- // we compare the timestamp of latest message from the other person to determine this
878
- // 2. if the account unarchiveChats setting is false -- then it doesn't matter,
879
- // it'll always take an app state action to mark in unarchived -- which we'll get anyway
907
+
908
+
909
+
910
+
911
+
912
+
913
+
914
+
915
+
916
+
880
917
  const archiveAction = action?.archiveChatAction
881
918
  const isArchived = archiveAction ? archiveAction.archived : type === 'archive'
882
- // // basically we don't need to fire an "archive" update if the chat is being marked unarchvied
883
- // // this only applies for the initial sync
884
- // if(isInitialSync && !isArchived) {
885
- // isArchived = false
886
- // }
919
+
920
+
921
+
922
+
923
+
887
924
  const msgRange = !accountSettings?.unarchiveChats ? undefined : archiveAction?.messageRange
888
- // logger?.debug({ chat: id, syncAction }, 'message range archive')
925
+
889
926
  ev.emit('chats.update', [
890
927
  {
891
928
  id,
@@ -895,9 +932,9 @@ const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
895
932
  ])
896
933
  } else if (action?.markChatAsReadAction) {
897
934
  const markReadAction = action.markChatAsReadAction
898
- // basically we don't need to fire an "read" update if the chat is being marked as read
899
- // because the chat is read by default
900
- // this only applies for the initial sync
935
+
936
+
937
+
901
938
  const isNullUpdate = isInitialSync && markReadAction.read
902
939
  ev.emit('chats.update', [
903
940
  {
@@ -1186,6 +1223,33 @@ const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) => {
1186
1223
  ev.emit('settings.update', { setting: 'businessBroadcastInsights', value: action.businessBroadcastInsightsAction })
1187
1224
  } else if (action?.bizAiSettingsNudgeAction) {
1188
1225
  ev.emit('settings.update', { setting: 'bizAiSettingsNudge', value: action.bizAiSettingsNudgeAction })
1226
+ } else if (action?.clearChatAction) {
1227
+ ev.emit('chats.update', [
1228
+ {
1229
+ id,
1230
+ lastMessageRecvTimestamp: 0,
1231
+ conditional: getChatUpdateConditional(id, action.clearChatAction?.messageRange)
1232
+ }
1233
+ ])
1234
+ } else if (action?.deviceCapabilities) {
1235
+ ev.emit('settings.update', { setting: 'deviceCapabilities', value: action.deviceCapabilities })
1236
+ } else if (action?.ugcBot) {
1237
+ ev.emit('settings.update', { setting: 'ugcBot', value: action.ugcBot })
1238
+ } else if (action?.coexV2VersionAction) {
1239
+ ev.emit('settings.update', { setting: 'coexV2Version', value: action.coexV2VersionAction })
1240
+ } else if (action?.wasaRootSecretAction) {
1241
+ ev.emit('settings.update', { setting: 'wasaRootSecret', value: action.wasaRootSecretAction })
1242
+ } else if (action?.bubbleLockMessageAction) {
1243
+ ev.emit('messages.update', [
1244
+ {
1245
+ key: { remoteJid: id, id: msgId, fromMe: fromMe === '1' },
1246
+ update: { bubbleLocked: action.bubbleLockMessageAction?.locked }
1247
+ }
1248
+ ])
1249
+ } else if (action?.labelSublistAction) {
1250
+ ev.emit('chats.update', [
1251
+ { id, labelSublistId: action.labelSublistAction?.subListId, conditional: getChatUpdateConditional(id, undefined) }
1252
+ ])
1189
1253
  } else {
1190
1254
  logger?.debug({ syncAction, id }, 'unprocessable update')
1191
1255
  }