@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
@@ -29,6 +29,7 @@ const {
29
29
  } = require("../Utils")
30
30
  const { makeMutex } = require("../Utils/make-mutex")
31
31
  const {
32
+ isPnUser,
32
33
  getBinaryNodeChild,
33
34
  getBinaryNodeChildren,
34
35
  jidDecode,
@@ -44,24 +45,53 @@ const { makeSocket } = require("./socket")
44
45
  const MAX_SYNC_ATTEMPTS = 2
45
46
 
46
47
  const makeChatsSocket = (config) => {
47
- const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, } = config
48
+ const {
49
+ logger,
50
+ markOnlineOnConnect,
51
+ fireInitQueries,
52
+ appStateMacVerification,
53
+ shouldIgnoreJid,
54
+ shouldSyncHistoryMessage,
55
+ getMessage
56
+ } = config
57
+
48
58
  const suki = makeSocket(config)
49
- const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, groupFetchAllParticipating } = suki
50
59
 
60
+ const {
61
+ ev,
62
+ ws,
63
+ authState,
64
+ generateMessageTag,
65
+ sendNode,
66
+ query,
67
+ signalRepository,
68
+ onUnexpectedError
69
+ } = suki
70
+
51
71
  let privacySettings
52
72
  let syncState = SyncState.Connecting
53
73
 
54
- /** this mutex ensures that the notifications (receipts, messages etc.) are processed in order */
55
- const processingMutex = makeMutex()
74
+ /** this mutex ensures that messages are processed in order */
75
+ const messageMutex = makeMutex()
56
76
 
57
- // Timeout for AwaitingInitialSync State
58
- let awaitingSyncTimeout
77
+ /** this mutex ensures that receipts are processed in order */
78
+ const receiptMutex = makeMutex()
59
79
 
60
- const placeholderResendCache = config.placeholderResendCache || new NodeCache({
61
- stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY,
62
- useClones: false
63
- })
80
+ /** this mutex ensures that app state patches are processed in order */
81
+ const appStatePatchMutex = makeMutex()
64
82
 
83
+ /** this mutex ensures that notifications are processed in order */
84
+ const notificationMutex = makeMutex()
85
+
86
+ // Timeout for AwaitingInitialSync state
87
+ let awaitingSyncTimeout
88
+
89
+ const placeholderResendCache = config.placeholderResendCache ||
90
+ new NodeCache({
91
+ stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
92
+ useClones: false
93
+ })
94
+
65
95
  if (!config.placeholderResendCache) {
66
96
  config.placeholderResendCache = placeholderResendCache
67
97
  }
@@ -199,7 +229,7 @@ const makeChatsSocket = (config) => {
199
229
  throw new Boom('Please input a jid user')
200
230
  }
201
231
 
202
- if (!isJidUser(jid)) {
232
+ if (!isPnUser(jid)) {
203
233
  throw new Boom('Invalid JID: Not a user JID!')
204
234
  }
205
235
 
@@ -240,6 +270,7 @@ const makeChatsSocket = (config) => {
240
270
  return result.list
241
271
  }
242
272
  }
273
+
243
274
  const fetchDisappearingDuration = async (...jids) => {
244
275
  const usyncQuery = new USyncQuery().withDisappearingModeProtocol()
245
276
 
@@ -248,13 +279,14 @@ const makeChatsSocket = (config) => {
248
279
  }
249
280
 
250
281
  const result = await suki.executeUSyncQuery(usyncQuery)
282
+
251
283
  if (result) {
252
284
  return result.list
253
285
  }
254
286
  }
255
287
 
256
288
  /** update the profile picture for yourself or a group */
257
- const updateProfilePicture = async (jid, content) => {
289
+ const updateProfilePicture = async (jid, content, dimensions) => {
258
290
  let targetJid
259
291
 
260
292
  if (!jid) {
@@ -265,15 +297,19 @@ const makeChatsSocket = (config) => {
265
297
  targetJid = jidNormalizedUser(jid) // in case it is someone other than us
266
298
  }
267
299
 
268
- const { img } = await generateProfilePicture(content)
300
+ else {
301
+ targetJid = undefined
302
+ }
303
+
304
+ const { img } = await generateProfilePicture(content, dimensions)
269
305
 
270
306
  await query({
271
307
  tag: 'iq',
272
308
  attrs: {
273
- target: targetJid,
274
309
  to: S_WHATSAPP_NET,
275
310
  type: 'set',
276
- xmlns: 'w:profile:picture'
311
+ xmlns: 'w:profile:picture',
312
+ ...(targetJid ? { target: targetJid } : {})
277
313
  },
278
314
  content: [
279
315
  {
@@ -297,13 +333,17 @@ const makeChatsSocket = (config) => {
297
333
  targetJid = jidNormalizedUser(jid) // in case it is someone other than us
298
334
  }
299
335
 
336
+ else {
337
+ targetJid = undefined
338
+ }
339
+
300
340
  await query({
301
341
  tag: 'iq',
302
342
  attrs: {
303
- target: targetJid,
304
343
  to: S_WHATSAPP_NET,
305
344
  type: 'set',
306
- xmlns: 'w:profile:picture'
345
+ xmlns: 'w:profile:picture',
346
+ ...(targetJid ? { target: targetJid } : {})
307
347
  }
308
348
  })
309
349
  }
@@ -450,10 +490,13 @@ const makeChatsSocket = (config) => {
450
490
  // otherwise when we resync from scratch -- all notifications will fire
451
491
  const initialVersionMap = {}
452
492
  const globalMutationMap = {}
493
+
453
494
  await authState.keys.transaction(async () => {
454
495
  const collectionsToHandle = new Set(collections)
496
+
455
497
  // in case something goes wrong -- ensure we don't enter a loop that cannot be exited from
456
498
  const attemptsMap = {}
499
+
457
500
  // keep executing till all collections are done
458
501
  // sometimes a single patch request will not return all the patches (God knows why)
459
502
  // so we fetch till they're all done (this is determined by the "has_more_patches" flag)
@@ -463,15 +506,19 @@ const makeChatsSocket = (config) => {
463
506
 
464
507
  for (const name of collectionsToHandle) {
465
508
  const result = await authState.keys.get('app-state-sync-version', [name])
509
+
466
510
  let state = result[name]
511
+
467
512
  if (state) {
468
513
  if (typeof initialVersionMap[name] === 'undefined') {
469
514
  initialVersionMap[name] = state.version
470
515
  }
471
516
  }
517
+
472
518
  else {
473
519
  state = newLTHashState()
474
520
  }
521
+
475
522
  states[name] = state
476
523
  logger.info(`resyncing ${name} from v${state.version}`)
477
524
  nodes.push({
@@ -480,7 +527,7 @@ const makeChatsSocket = (config) => {
480
527
  name,
481
528
  version: state.version.toString(),
482
529
  // return snapshot if being synced from scratch
483
- 'return_snapshot': (!state.version).toString()
530
+ return_snapshot: (!state.version).toString()
484
531
  }
485
532
  })
486
533
  }
@@ -507,57 +554,71 @@ const makeChatsSocket = (config) => {
507
554
  for (const key in decoded) {
508
555
  const name = key
509
556
  const { patches, hasMorePatches, snapshot } = decoded[name]
557
+
510
558
  try {
511
559
  if (snapshot) {
512
560
  const { state: newState, mutationMap } = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey, initialVersionMap[name], appStateMacVerification.snapshot)
561
+
513
562
  states[name] = newState
563
+
514
564
  Object.assign(globalMutationMap, mutationMap)
565
+
515
566
  logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`)
567
+
516
568
  await authState.keys.set({ 'app-state-sync-version': { [name]: newState } })
517
569
  }
518
570
 
519
571
  // only process if there are syncd patches
520
572
  if (patches.length) {
521
573
  const { state: newState, mutationMap } = await decodePatches(name, patches, states[name], getAppStateSyncKey, config.options, initialVersionMap[name], logger, appStateMacVerification.patch)
574
+
522
575
  await authState.keys.set({ 'app-state-sync-version': { [name]: newState } })
576
+
523
577
  logger.info(`synced ${name} to v${newState.version}`)
578
+
524
579
  initialVersionMap[name] = newState.version
580
+
525
581
  Object.assign(globalMutationMap, mutationMap)
526
582
  }
527
583
 
528
584
  if (hasMorePatches) {
529
585
  logger.info(`${name} has more patches...`)
530
- }
531
- else { // collection is done with sync
586
+ }
587
+
588
+ else {
589
+ // collection is done with sync
532
590
  collectionsToHandle.delete(name)
533
591
  }
534
- }
592
+ }
593
+
535
594
  catch (error) {
536
595
  // if retry attempts overshoot
537
596
  // or key not found
538
- const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS
539
- || error.output?.statusCode === 404
540
- || error.name === 'TypeError'
597
+ const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS ||
598
+ error.output?.statusCode === 404 ||
599
+ error.name === 'TypeError'
600
+
541
601
  logger.info({ name, error: error.stack }, `failed to sync state from version${isIrrecoverableError ? '' : ', removing and trying from scratch'}`)
602
+
542
603
  await authState.keys.set({ 'app-state-sync-version': { [name]: null } })
604
+
543
605
  // increment number of retries
544
606
  attemptsMap[name] = (attemptsMap[name] || 0) + 1
545
607
 
546
608
  if (isIrrecoverableError) {
547
609
  // stop retrying
548
- collectionsToHandle.delete(name)
610
+ collectionsToHandle.delete(name);
549
611
  }
550
612
  }
551
613
  }
552
614
  }
553
615
  }, authState?.creds?.me?.id || 'resync-app-state')
554
-
555
616
  const { onMutation } = newAppStateChunkHandler(isInitialSync)
556
617
 
557
618
  for (const key in globalMutationMap) {
558
619
  onMutation(globalMutationMap[key])
559
620
  }
560
- })
621
+ })
561
622
 
562
623
  // source: https://github.com/WhiskeySockets/Baileys/pull/1677
563
624
  const createCallLink = async (type, event, timeoutMs) => {
@@ -654,10 +715,11 @@ const makeChatsSocket = (config) => {
654
715
 
655
716
  const handlePresenceUpdate = ({ tag, attrs, content }) => {
656
717
  let presence
718
+
657
719
  const jid = attrs.from
658
720
  const participant = attrs.participant || attrs.from
659
721
 
660
- if (shouldIgnoreJid(jid) && jid !== '@s.whatsapp.net') {
722
+ if (shouldIgnoreJid(jid) && jid !== S_WHATSAPP_NET) {
661
723
  return
662
724
  }
663
725
 
@@ -670,6 +732,7 @@ const makeChatsSocket = (config) => {
670
732
 
671
733
  else if (Array.isArray(content)) {
672
734
  const [firstChild] = content
735
+
673
736
  let type = firstChild.tag
674
737
 
675
738
  if (type === 'paused') {
@@ -703,15 +766,18 @@ const makeChatsSocket = (config) => {
703
766
  let initial
704
767
  let encodeResult
705
768
 
706
- await processingMutex.mutex(async () => {
769
+ await appStatePatchMutex.mutex(async () => {
707
770
  await authState.keys.transaction(async () => {
708
771
  logger.debug({ patch: patchCreate }, 'applying app patch')
772
+
709
773
  await resyncAppState([name], false)
774
+
710
775
  const { [name]: currentSyncVersion } = await authState.keys.get('app-state-sync-version', [name])
776
+
711
777
  initial = currentSyncVersion || newLTHashState()
712
778
  encodeResult = await encodeSyncdPatch(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey)
713
- const { patch, state } = encodeResult
714
779
 
780
+ const { patch, state } = encodeResult
715
781
  const node = {
716
782
  tag: 'iq',
717
783
  attrs: {
@@ -729,7 +795,7 @@ const makeChatsSocket = (config) => {
729
795
  attrs: {
730
796
  name,
731
797
  version: (state.version - 1).toString(),
732
- 'return_snapshot': 'false'
798
+ return_snapshot: 'false'
733
799
  },
734
800
  content: [
735
801
  {
@@ -743,6 +809,7 @@ const makeChatsSocket = (config) => {
743
809
  }
744
810
  ]
745
811
  }
812
+
746
813
  await query(node)
747
814
  await authState.keys.set({ 'app-state-sync-version': { [name]: state } })
748
815
  }, authState?.creds?.me?.id || 'app-patch')
@@ -750,7 +817,7 @@ const makeChatsSocket = (config) => {
750
817
 
751
818
  if (config.emitOwnEvents) {
752
819
  const { onMutation } = newAppStateChunkHandler(false)
753
- const { mutationMap } = await decodePatches(name, [{ ...encodeResult.patch, version: { version: encodeResult.state.version }, }], initial, getAppStateSyncKey, config.options, undefined, logger)
820
+ const { mutationMap } = await decodePatches(name, [{ ...encodeResult.patch, version: { version: encodeResult.state.version } }], initial, getAppStateSyncKey, config.options, undefined, logger)
754
821
 
755
822
  for (const key in mutationMap) {
756
823
  onMutation(mutationMap[key])
@@ -760,18 +827,22 @@ const makeChatsSocket = (config) => {
760
827
 
761
828
  /** sending non-abt props may fix QR scan fail if server expects */
762
829
  const fetchProps = async () => {
830
+ //TODO: implement both protocol 1 and protocol 2 prop fetching, specially for abKey for WM
763
831
  const resultNode = await query({
764
832
  tag: 'iq',
765
833
  attrs: {
766
834
  to: S_WHATSAPP_NET,
767
835
  xmlns: 'w',
768
- type: 'get',
836
+ type: 'get'
769
837
  },
770
838
  content: [
771
- { tag: 'props', attrs: {
839
+ {
840
+ tag: 'props',
841
+ attrs: {
772
842
  protocol: '2',
773
843
  hash: authState?.creds?.lastPropHash || ''
774
- } }
844
+ }
845
+ }
775
846
  ]
776
847
  })
777
848
 
@@ -779,7 +850,8 @@ const makeChatsSocket = (config) => {
779
850
  let props = {}
780
851
 
781
852
  if (propsNode) {
782
- if (propsNode.attrs?.hash) { // on some clients, the hash is returning as undefined
853
+ if (propsNode.attrs?.hash) {
854
+ // on some clients, the hash is returning as undefined
783
855
  authState.creds.lastPropHash = propsNode?.attrs?.hash
784
856
  ev.emit('creds.update', authState.creds)
785
857
  }
@@ -787,6 +859,7 @@ const makeChatsSocket = (config) => {
787
859
  props = reduceBinaryNodeToDictionary(propsNode, 'prop')
788
860
  }
789
861
  logger.debug('fetched props')
862
+
790
863
  return props
791
864
  }
792
865
 
@@ -943,8 +1016,10 @@ const makeChatsSocket = (config) => {
943
1016
 
944
1017
  const upsertMessage = ev.createBufferedFunction(async (msg, type) => {
945
1018
  ev.emit('messages.upsert', { messages: [msg], type })
1019
+
946
1020
  if (!!msg.pushName) {
947
- let jid = msg.key.fromMe ? authState.creds.me.id : (msg.key.participant || msg.key.remoteJid)
1021
+ let jid = msg.key.fromMe ? authState.creds.me.id : msg.key.participant || msg.key.remoteJid
1022
+
948
1023
  jid = jidNormalizedUser(jid)
949
1024
 
950
1025
  if (!msg.key.fromMe) {
@@ -959,40 +1034,49 @@ const makeChatsSocket = (config) => {
959
1034
 
960
1035
  const historyMsg = getHistoryMsg(msg.message)
961
1036
  const shouldProcessHistoryMsg = historyMsg
962
- ? (shouldSyncHistoryMessage(historyMsg)
963
- && PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType))
1037
+ ? shouldSyncHistoryMessage(historyMsg) &&
1038
+ PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType)
964
1039
  : false
965
1040
 
1041
+ // State machine: decide on sync and flush
966
1042
  if (historyMsg && syncState === SyncState.AwaitingInitialSync) {
967
1043
  if (awaitingSyncTimeout) {
968
- clearTimeout(awaitingSyncTimeout)
969
- awaitingSyncTimeout = undefined
1044
+ clearTimeout(awaitingSyncTimeout)
1045
+ awaitingSyncTimeout = undefined
970
1046
  }
971
1047
 
972
1048
  if (shouldProcessHistoryMsg) {
973
- syncState = SyncState.Syncing
974
- logger.info('Transitioned to Syncing state')
975
- // Let doAppStateSync handle the final flush after it`s done
976
- } else {
977
- syncState = SyncState.Online
978
- logger.info('History sync skipped, transitioning to Online state and flushing buffer')
979
- ev.flush()
1049
+ syncState = SyncState.Syncing
1050
+ logger.info('Transitioned to Syncing state')
1051
+ // Let doAppStateSync handle the final flush after it's done
1052
+ }
1053
+
1054
+ else {
1055
+ syncState = SyncState.Online
1056
+
1057
+ logger.info('History sync skipped, transitioning to Online state and flushing buffer')
1058
+
1059
+ ev.flush()
980
1060
  }
981
1061
  }
982
1062
 
983
1063
  const doAppStateSync = async () => {
984
- if (syncState === SyncState.Syncing) {
985
- logger.info('Doing app state sync')
986
- await resyncAppState(ALL_WA_PATCH_NAMES, true)
987
-
988
- // Sync is complete, go online and flush everything
989
- syncState = SyncState.Online
990
- logger.info('App state sync complete, transitioning to Online state and flushing buffer')
991
- ev.flush()
992
-
993
- const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1
994
- ev.emit('creds.update', { accountSyncCounter })
995
- }
1064
+ if (syncState === SyncState.Syncing) {
1065
+ logger.info('Doing app state sync')
1066
+
1067
+ await resyncAppState(ALL_WA_PATCH_NAMES, true)
1068
+
1069
+ // Sync is complete, go online and flush everything
1070
+ syncState = SyncState.Online
1071
+
1072
+ logger.info('App state sync complete, transitioning to Online state and flushing buffer')
1073
+
1074
+ ev.flush()
1075
+
1076
+ const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1
1077
+
1078
+ ev.emit('creds.update', { accountSyncCounter })
1079
+ }
996
1080
  }
997
1081
 
998
1082
  await Promise.all([
@@ -1002,7 +1086,7 @@ const makeChatsSocket = (config) => {
1002
1086
  }
1003
1087
  })(),
1004
1088
  processMessage(msg, {
1005
- signalRepository,
1089
+ signalRepository,
1006
1090
  shouldProcessHistoryMsg,
1007
1091
  placeholderResendCache,
1008
1092
  ev,
@@ -1010,13 +1094,14 @@ const makeChatsSocket = (config) => {
1010
1094
  keyStore: authState.keys,
1011
1095
  logger,
1012
1096
  options: config.options,
1013
- getMessage: config.getMessage,
1097
+ getMessage
1014
1098
  })
1015
1099
  ])
1016
1100
 
1101
+ // If the app state key arrives and we are waiting to sync, trigger the sync now.
1017
1102
  if (msg.message?.protocolMessage?.appStateSyncKeyShare && syncState === SyncState.Syncing) {
1018
- logger.info('App state sync key arrived, triggering app state sync')
1019
- await doAppStateSync()
1103
+ logger.info('App state sync key arrived, triggering app state sync')
1104
+ await doAppStateSync()
1020
1105
  }
1021
1106
  })
1022
1107
 
@@ -1030,16 +1115,18 @@ const makeChatsSocket = (config) => {
1030
1115
  case 'account_sync':
1031
1116
  if (attrs.timestamp) {
1032
1117
  let { lastAccountSyncTimestamp } = authState.creds
1118
+
1033
1119
  if (lastAccountSyncTimestamp) {
1034
1120
  await cleanDirtyBits('account_sync', lastAccountSyncTimestamp)
1035
1121
  }
1122
+
1036
1123
  lastAccountSyncTimestamp = +attrs.timestamp
1124
+
1037
1125
  ev.emit('creds.update', { lastAccountSyncTimestamp })
1038
1126
  }
1039
1127
  break
1040
1128
  case 'groups':
1041
- await groupFetchAllParticipating()
1042
- await cleanDirtyBits('groups')
1129
+ // handled in groups.js
1043
1130
  break
1044
1131
  default:
1045
1132
  logger.info({ node }, 'received unknown sync')
@@ -1050,45 +1137,46 @@ const makeChatsSocket = (config) => {
1050
1137
  ev.on('connection.update', ({ connection, receivedPendingNotifications }) => {
1051
1138
  if (connection === 'open') {
1052
1139
  if (fireInitQueries) {
1053
- executeInitQueries()
1054
- .catch(error => onUnexpectedError(error, 'init queries'))
1140
+ executeInitQueries().catch(error => onUnexpectedError(error, 'init queries'))
1055
1141
  }
1056
- sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable')
1057
- .catch(error => onUnexpectedError(error, 'presence update requests'))
1142
+
1143
+ sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable').catch(error => onUnexpectedError(error, 'presence update requests'))
1058
1144
  }
1059
1145
 
1060
1146
  if (!receivedPendingNotifications || syncState !== SyncState.Connecting) {
1061
- return
1147
+ return
1062
1148
  }
1063
1149
 
1064
1150
  syncState = SyncState.AwaitingInitialSync
1065
- logger.info('Connection is now AwaitingInitialSync, buffering events')
1066
- ev.buffer()
1067
1151
 
1068
- const willSyncHistory = shouldSyncHistoryMessage(proto.Message.HistorySyncNotification.fromObject({
1069
- syncType: proto.HistorySync.HistorySyncType.RECENT
1070
- }))
1152
+ logger.info('Connection is now AwaitingInitialSync, buffering events')
1153
+ ev.buffer()
1154
+
1155
+ const willSyncHistory = shouldSyncHistoryMessage(proto.Message.HistorySyncNotification.create({
1156
+ syncType: proto.HistorySync.HistorySyncType.RECENT
1157
+ }))
1071
1158
 
1072
1159
  if (!willSyncHistory) {
1073
- logger.info('History sync is disabled by config, not waiting for notification. Transitioning to Online.')
1074
- syncState = SyncState.Online
1075
- setTimeout(() => ev.flush(), 0)
1076
- return
1160
+ logger.info('History sync is disabled by config, not waiting for notification. Transitioning to Online.')
1161
+ syncState = SyncState.Online
1162
+ setTimeout(() => ev.flush(), 0)
1163
+ return
1077
1164
  }
1078
1165
 
1079
- logger.info('History sync is enabled, awaiting notification with a 20s timeout.')
1166
+ logger.info('History sync is enabled, awaiting notification with a 20s timeout.')
1080
1167
 
1081
1168
  if (awaitingSyncTimeout) {
1082
- clearTimeout(awaitingSyncTimeout)
1169
+ clearTimeout(awaitingSyncTimeout);
1083
1170
  }
1084
1171
 
1085
1172
  awaitingSyncTimeout = setTimeout(() => {
1086
- if (syncState === SyncState.AwaitingInitialSync) {
1087
- logger.warn('Timeout in AwaitingInitialSync, forcing state to Online and flushing buffer')
1088
- syncState = SyncState.Online
1089
- ev.flush()
1090
- }
1091
- }, 20_000)
1173
+ if (syncState === SyncState.AwaitingInitialSync) {
1174
+ // TODO: investigate
1175
+ logger.warn('Timeout in AwaitingInitialSync, forcing state to Online and flushing buffer')
1176
+ syncState = SyncState.Online
1177
+ ev.flush()
1178
+ }
1179
+ }, 20000)
1092
1180
  })
1093
1181
 
1094
1182
  return {
@@ -1096,7 +1184,6 @@ const makeChatsSocket = (config) => {
1096
1184
  star,
1097
1185
  addOrEditContact,
1098
1186
  removeContact,
1099
- processingMutex,
1100
1187
  fetchPrivacySettings,
1101
1188
  upsertMessage,
1102
1189
  appPatch,
@@ -1104,6 +1191,10 @@ const makeChatsSocket = (config) => {
1104
1191
  sendPresenceUpdate,
1105
1192
  presenceSubscribe,
1106
1193
  getBotListV2,
1194
+ messageMutex,
1195
+ receiptMutex,
1196
+ appStatePatchMutex,
1197
+ notificationMutex,
1107
1198
  getLidUser,
1108
1199
  fetchBlocklist,
1109
1200
  fetchStatus,