@pontalabs/baileys 1.0.4 → 1.0.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/LICENSE +1 -1
- package/README.md +267 -839
- package/WAProto/GenerateStatics.sh +3 -4
- package/WAProto/WAProto.proto +1215 -511
- package/WAProto/fix-imports.js +85 -0
- package/WAProto/index.d.ts +14017 -55
- package/WAProto/index.js +97689 -29
- package/engine-requirements.js +10 -0
- package/lib/Defaults/index.d.ts +72 -74
- package/lib/Defaults/index.d.ts.map +1 -0
- package/lib/Defaults/index.js +94 -108
- package/lib/Defaults/index.js.map +1 -0
- package/lib/Signal/Group/ciphertext-message.d.ts +8 -7
- package/lib/Signal/Group/ciphertext-message.d.ts.map +1 -0
- package/lib/Signal/Group/ciphertext-message.js +9 -16
- package/lib/Signal/Group/ciphertext-message.js.map +1 -0
- package/lib/Signal/Group/group-session-builder.d.ts +11 -13
- package/lib/Signal/Group/group-session-builder.d.ts.map +1 -0
- package/lib/Signal/Group/group-session-builder.js +19 -61
- package/lib/Signal/Group/group-session-builder.js.map +1 -0
- package/lib/Signal/Group/group_cipher.d.ts +14 -16
- package/lib/Signal/Group/group_cipher.d.ts.map +1 -0
- package/lib/Signal/Group/group_cipher.js +41 -70
- package/lib/Signal/Group/group_cipher.js.map +1 -0
- package/lib/Signal/Group/index.d.ts +12 -11
- package/lib/Signal/Group/index.d.ts.map +1 -0
- package/lib/Signal/Group/index.js +12 -61
- package/lib/Signal/Group/index.js.map +1 -0
- package/lib/Signal/Group/keyhelper.d.ts +9 -14
- package/lib/Signal/Group/keyhelper.d.ts.map +1 -0
- package/lib/Signal/Group/keyhelper.js +10 -58
- package/lib/Signal/Group/keyhelper.js.map +1 -0
- package/lib/Signal/Group/sender-chain-key.d.ts +13 -13
- package/lib/Signal/Group/sender-chain-key.d.ts.map +1 -0
- package/lib/Signal/Group/sender-chain-key.js +13 -34
- package/lib/Signal/Group/sender-chain-key.js.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -16
- package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +28 -36
- package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-message.d.ts +18 -18
- package/lib/Signal/Group/sender-key-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-message.js +38 -45
- package/lib/Signal/Group/sender-key-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-name.d.ts +14 -15
- package/lib/Signal/Group/sender-key-name.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-name.js +20 -31
- package/lib/Signal/Group/sender-key-name.js.map +1 -0
- package/lib/Signal/Group/sender-key-record.d.ts +24 -25
- package/lib/Signal/Group/sender-key-record.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-record.js +18 -35
- package/lib/Signal/Group/sender-key-record.js.map +1 -0
- package/lib/Signal/Group/sender-key-state.d.ts +29 -34
- package/lib/Signal/Group/sender-key-state.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-state.js +37 -100
- package/lib/Signal/Group/sender-key-state.js.map +1 -0
- package/lib/Signal/Group/sender-message-key.d.ts +11 -10
- package/lib/Signal/Group/sender-message-key.d.ts.map +1 -0
- package/lib/Signal/Group/sender-message-key.js +15 -22
- package/lib/Signal/Group/sender-message-key.js.map +1 -0
- package/lib/Signal/libsignal.d.ts +5 -8
- package/lib/Signal/libsignal.d.ts.map +1 -0
- package/lib/Signal/libsignal.js +279 -121
- package/lib/Signal/libsignal.js.map +1 -0
- package/lib/Signal/lid-mapping.d.ts +23 -28
- package/lib/Signal/lid-mapping.d.ts.map +1 -0
- package/lib/Signal/lid-mapping.js +277 -184
- package/lib/Signal/lid-mapping.js.map +1 -0
- package/lib/Socket/Client/index.d.ts +3 -2
- package/lib/Socket/Client/index.d.ts.map +1 -0
- package/lib/Socket/Client/index.js +3 -22
- package/lib/Socket/Client/index.js.map +1 -0
- package/lib/Socket/Client/types.d.ts +15 -15
- package/lib/Socket/Client/types.d.ts.map +1 -0
- package/lib/Socket/Client/types.js +8 -15
- package/lib/Socket/Client/types.js.map +1 -0
- package/lib/Socket/Client/websocket.d.ts +12 -12
- package/lib/Socket/Client/websocket.d.ts.map +1 -0
- package/lib/Socket/Client/websocket.js +29 -37
- package/lib/Socket/Client/websocket.js.map +1 -0
- package/lib/Socket/business.d.ts +208 -178
- package/lib/Socket/business.d.ts.map +1 -0
- package/lib/Socket/business.js +91 -127
- package/lib/Socket/business.js.map +1 -0
- package/lib/Socket/chats.d.ts +120 -93
- package/lib/Socket/chats.d.ts.map +1 -0
- package/lib/Socket/chats.js +727 -652
- package/lib/Socket/chats.js.map +1 -0
- package/lib/Socket/communities.d.ts +273 -0
- package/lib/Socket/communities.d.ts.map +1 -0
- package/lib/Socket/communities.js +431 -0
- package/lib/Socket/communities.js.map +1 -0
- package/lib/Socket/dugong.js +261 -0
- package/lib/Socket/dugong.js.bak +204 -0
- package/lib/Socket/groups.d.ts +143 -111
- package/lib/Socket/groups.d.ts.map +1 -0
- package/lib/Socket/groups.js +165 -177
- package/lib/Socket/groups.js.map +1 -0
- package/lib/Socket/index.d.ts +252 -183
- package/lib/Socket/index.d.ts.map +1 -0
- package/lib/Socket/index.js +38 -18
- package/lib/Socket/index.js.bak +44 -0
- package/lib/Socket/index.js.map +1 -0
- package/lib/Socket/messages-recv.d.ts +196 -167
- package/lib/Socket/messages-recv.d.ts.map +1 -0
- package/lib/Socket/messages-recv.js +1443 -1563
- package/lib/Socket/messages-recv.js.map +1 -0
- package/lib/Socket/messages-send.d.ts +192 -158
- package/lib/Socket/messages-send.d.ts.map +1 -0
- package/lib/Socket/messages-send.js +1102 -1208
- package/lib/Socket/messages-send.js.bak +1400 -0
- package/lib/Socket/messages-send.js.map +1 -0
- package/lib/Socket/mex.d.ts +3 -0
- package/lib/Socket/mex.d.ts.map +1 -0
- package/lib/Socket/mex.js +42 -0
- package/lib/Socket/mex.js.map +1 -0
- package/lib/Socket/newsletter.d.ts +163 -138
- package/lib/Socket/newsletter.d.ts.map +1 -0
- package/lib/Socket/newsletter.js +153 -249
- package/lib/Socket/newsletter.js.map +1 -0
- package/lib/Socket/socket.d.ts +50 -36
- package/lib/Socket/socket.d.ts.map +1 -0
- package/lib/Socket/socket.js +749 -820
- package/lib/Socket/socket.js.map +1 -0
- package/lib/Store/index.d.ts +4 -4
- package/lib/Store/index.d.ts.map +1 -0
- package/lib/Store/index.js +4 -24
- package/lib/Store/index.js.map +1 -0
- package/lib/Store/make-in-memory-store.d.ts +44 -104
- package/lib/Store/make-in-memory-store.d.ts.map +1 -0
- package/lib/Store/make-in-memory-store.js +199 -213
- package/lib/Store/make-in-memory-store.js.map +1 -0
- package/lib/Store/make-ordered-dictionary.d.ts +13 -12
- package/lib/Store/make-ordered-dictionary.d.ts.map +1 -0
- package/lib/Store/make-ordered-dictionary.js +38 -45
- package/lib/Store/make-ordered-dictionary.js.map +1 -0
- package/lib/Store/object-repository.d.ts +11 -10
- package/lib/Store/object-repository.d.ts.map +1 -0
- package/lib/Store/object-repository.js +9 -16
- package/lib/Store/object-repository.js.map +1 -0
- package/lib/Types/Auth.d.ts +93 -97
- package/lib/Types/Auth.d.ts.map +1 -0
- package/lib/Types/Auth.js +2 -3
- package/lib/Types/Auth.js.map +1 -0
- package/lib/Types/Bussines.d.ts +25 -0
- package/lib/Types/Bussines.d.ts.map +1 -0
- package/lib/Types/Bussines.js +2 -3
- package/lib/Types/Bussines.js.map +1 -0
- package/lib/Types/Call.d.ts +14 -13
- package/lib/Types/Call.d.ts.map +1 -0
- package/lib/Types/Call.js +2 -3
- package/lib/Types/Call.js.map +1 -0
- package/lib/Types/Chat.d.ts +78 -97
- package/lib/Types/Chat.d.ts.map +1 -0
- package/lib/Types/Chat.js +8 -9
- package/lib/Types/Chat.js.map +1 -0
- package/lib/Types/Contact.d.ts +12 -9
- package/lib/Types/Contact.d.ts.map +1 -0
- package/lib/Types/Contact.js +2 -3
- package/lib/Types/Contact.js.map +1 -0
- package/lib/Types/Events.d.ts +206 -176
- package/lib/Types/Events.d.ts.map +1 -0
- package/lib/Types/Events.js +2 -3
- package/lib/Types/Events.js.map +1 -0
- package/lib/Types/GroupMetadata.d.ts +53 -48
- package/lib/Types/GroupMetadata.d.ts.map +1 -0
- package/lib/Types/GroupMetadata.js +2 -3
- package/lib/Types/GroupMetadata.js.map +1 -0
- package/lib/Types/Label.d.ts +13 -14
- package/lib/Types/Label.d.ts.map +1 -0
- package/lib/Types/Label.js +24 -30
- package/lib/Types/Label.js.map +1 -0
- package/lib/Types/LabelAssociation.d.ts +15 -20
- package/lib/Types/LabelAssociation.d.ts.map +1 -0
- package/lib/Types/LabelAssociation.js +6 -12
- package/lib/Types/LabelAssociation.js.map +1 -0
- package/lib/Types/Message.d.ts +248 -412
- package/lib/Types/Message.d.ts.map +1 -0
- package/lib/Types/Message.js +17 -19
- package/lib/Types/Message.js.map +1 -0
- package/lib/Types/Mex.d.ts +141 -0
- package/lib/Types/Mex.d.ts.map +1 -0
- package/lib/Types/Mex.js +37 -0
- package/lib/Types/Mex.js.map +1 -0
- package/lib/Types/Product.d.ts +58 -71
- package/lib/Types/Product.d.ts.map +1 -0
- package/lib/Types/Product.js +2 -3
- package/lib/Types/Product.js.map +1 -0
- package/lib/Types/RichType.d.ts +3 -0
- package/lib/Types/RichType.d.ts.map +1 -0
- package/lib/Types/RichType.js +23 -0
- package/lib/Types/RichType.js.bak +23 -0
- package/lib/Types/RichType.js.map +1 -0
- package/lib/Types/Signal.d.ts +71 -82
- package/lib/Types/Signal.d.ts.map +1 -0
- package/lib/Types/Signal.js +2 -3
- package/lib/Types/Signal.js.map +1 -0
- package/lib/Types/Socket.d.ts +76 -81
- package/lib/Types/Socket.d.ts.map +1 -0
- package/lib/Types/Socket.js +3 -3
- package/lib/Types/Socket.js.map +1 -0
- package/lib/Types/State.d.ts +75 -19
- package/lib/Types/State.d.ts.map +1 -0
- package/lib/Types/State.js +56 -14
- package/lib/Types/State.js.map +1 -0
- package/lib/Types/USync.d.ts +8 -8
- package/lib/Types/USync.d.ts.map +1 -0
- package/lib/Types/USync.js +2 -3
- package/lib/Types/USync.js.map +1 -0
- package/lib/Types/index.d.ts +47 -62
- package/lib/Types/index.d.ts.map +1 -0
- package/lib/Types/index.js +26 -50
- package/lib/Types/index.js.map +1 -0
- package/lib/Utils/auth-utils.d.ts +13 -10
- package/lib/Utils/auth-utils.d.ts.map +1 -0
- package/lib/Utils/auth-utils.js +213 -454
- package/lib/Utils/auth-utils.js.map +1 -0
- package/lib/Utils/browser-utils.d.ts +4 -0
- package/lib/Utils/browser-utils.d.ts.map +1 -0
- package/lib/Utils/browser-utils.js +28 -0
- package/lib/Utils/browser-utils.js.map +1 -0
- package/lib/Utils/business.d.ts +14 -20
- package/lib/Utils/business.d.ts.map +1 -0
- package/lib/Utils/business.js +110 -134
- package/lib/Utils/business.js.map +1 -0
- package/lib/Utils/chat-utils.d.ts +88 -70
- package/lib/Utils/chat-utils.d.ts.map +1 -0
- package/lib/Utils/chat-utils.js +466 -403
- package/lib/Utils/chat-utils.js.map +1 -0
- package/lib/Utils/companion-reg-client-utils.d.ts +17 -0
- package/lib/Utils/companion-reg-client-utils.d.ts.map +1 -0
- package/lib/Utils/companion-reg-client-utils.js +35 -0
- package/lib/Utils/companion-reg-client-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +27 -46
- package/lib/Utils/crypto.d.ts.map +1 -0
- package/lib/Utils/crypto.js +117 -188
- package/lib/Utils/crypto.js.map +1 -0
- package/lib/Utils/decode-wa-message.d.ts +58 -45
- package/lib/Utils/decode-wa-message.d.ts.map +1 -0
- package/lib/Utils/decode-wa-message.js +213 -303
- package/lib/Utils/decode-wa-message.js.map +1 -0
- package/lib/Utils/event-buffer.d.ts +14 -17
- package/lib/Utils/event-buffer.d.ts.map +1 -0
- package/lib/Utils/event-buffer.js +321 -296
- package/lib/Utils/event-buffer.js.map +1 -0
- package/lib/Utils/generics.d.ts +66 -92
- package/lib/Utils/generics.d.ts.map +1 -0
- package/lib/Utils/generics.js +270 -436
- package/lib/Utils/generics.js.map +1 -0
- package/lib/Utils/history.d.ts +24 -23
- package/lib/Utils/history.d.ts.map +1 -0
- package/lib/Utils/history.js +106 -76
- package/lib/Utils/history.js.map +1 -0
- package/lib/Utils/identity-change-handler.d.ts +44 -0
- package/lib/Utils/identity-change-handler.d.ts.map +1 -0
- package/lib/Utils/identity-change-handler.js +50 -0
- package/lib/Utils/identity-change-handler.js.map +1 -0
- package/lib/Utils/index.d.ts +24 -21
- package/lib/Utils/index.d.ts.map +1 -0
- package/lib/Utils/index.js +24 -41
- package/lib/Utils/index.js.map +1 -0
- package/lib/Utils/link-preview.d.ts +12 -14
- package/lib/Utils/link-preview.d.ts.map +1 -0
- package/lib/Utils/link-preview.js +40 -75
- package/lib/Utils/link-preview.js.map +1 -0
- package/lib/Utils/logger.d.ts +10 -11
- package/lib/Utils/logger.d.ts.map +1 -0
- package/lib/Utils/logger.js +3 -7
- package/lib/Utils/logger.js.map +1 -0
- package/lib/Utils/lt-hash.d.ts +8 -14
- package/lib/Utils/lt-hash.d.ts.map +1 -0
- package/lib/Utils/lt-hash.js +3 -53
- package/lib/Utils/lt-hash.js.map +1 -0
- package/lib/Utils/make-mutex.d.ts +7 -7
- package/lib/Utils/make-mutex.d.ts.map +1 -0
- package/lib/Utils/make-mutex.js +28 -44
- package/lib/Utils/make-mutex.js.map +1 -0
- package/lib/Utils/message-retry-manager.d.ts +115 -88
- package/lib/Utils/message-retry-manager.d.ts.map +1 -0
- package/lib/Utils/message-retry-manager.js +265 -160
- package/lib/Utils/message-retry-manager.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +105 -107
- package/lib/Utils/messages-media.d.ts.map +1 -0
- package/lib/Utils/messages-media.js +548 -619
- package/lib/Utils/messages-media.js.bak +786 -0
- package/lib/Utils/messages-media.js.map +1 -0
- package/lib/Utils/messages.d.ts +52 -66
- package/lib/Utils/messages.d.ts.map +1 -0
- package/lib/Utils/messages.js +1730 -1558
- package/lib/Utils/messages.js.backup +1768 -0
- package/lib/Utils/messages.js.bak +1809 -0
- package/lib/Utils/messages.js.bak2 +893 -0
- package/lib/Utils/messages.js.bak3 +1183 -0
- package/lib/Utils/messages.js.map +1 -0
- package/lib/Utils/noise-handler.d.ts +18 -18
- package/lib/Utils/noise-handler.d.ts.map +1 -0
- package/lib/Utils/noise-handler.js +176 -130
- package/lib/Utils/noise-handler.js.map +1 -0
- package/lib/Utils/offline-node-processor.d.ts +17 -0
- package/lib/Utils/offline-node-processor.d.ts.map +1 -0
- package/lib/Utils/offline-node-processor.js +40 -0
- package/lib/Utils/offline-node-processor.js.map +1 -0
- package/lib/Utils/pre-key-manager.d.ts +28 -0
- package/lib/Utils/pre-key-manager.d.ts.map +1 -0
- package/lib/Utils/pre-key-manager.js +106 -0
- package/lib/Utils/pre-key-manager.js.map +1 -0
- package/lib/Utils/process-message.d.ts +43 -32
- package/lib/Utils/process-message.d.ts.map +1 -0
- package/lib/Utils/process-message.js +484 -282
- package/lib/Utils/process-message.js.map +1 -0
- package/lib/Utils/reporting-utils.d.ts +11 -0
- package/lib/Utils/reporting-utils.d.ts.map +1 -0
- package/lib/Utils/reporting-utils.js +258 -0
- package/lib/Utils/reporting-utils.js.map +1 -0
- package/lib/Utils/rich-message-utils.d.ts +49 -0
- package/lib/Utils/rich-message-utils.d.ts.map +1 -0
- package/lib/Utils/rich-message-utils.js +1220 -724
- package/lib/Utils/rich-message-utils.js.backup +706 -0
- package/lib/Utils/rich-message-utils.js.bak +246 -0
- package/lib/Utils/rich-message-utils.js.map +1 -0
- package/lib/Utils/rich-message-utils.js.original +1332 -0
- package/lib/Utils/signal.d.ts +37 -32
- package/lib/Utils/signal.d.ts.map +1 -0
- package/lib/Utils/signal.js +140 -105
- package/lib/Utils/signal.js.map +1 -0
- package/lib/Utils/stanza-ack.d.ts +11 -0
- package/lib/Utils/stanza-ack.d.ts.map +1 -0
- package/lib/Utils/stanza-ack.js +38 -0
- package/lib/Utils/stanza-ack.js.map +1 -0
- package/lib/Utils/sync-action-utils.d.ts +19 -0
- package/lib/Utils/sync-action-utils.d.ts.map +1 -0
- package/lib/Utils/sync-action-utils.js +49 -0
- package/lib/Utils/sync-action-utils.js.map +1 -0
- package/lib/Utils/tc-token-utils.d.ts +37 -0
- package/lib/Utils/tc-token-utils.d.ts.map +1 -0
- package/lib/Utils/tc-token-utils.js +163 -0
- package/lib/Utils/tc-token-utils.js.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts +5 -5
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +70 -120
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -0
- package/lib/Utils/use-single-file-auth-state.d.ts +11 -13
- package/lib/Utils/use-single-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-single-file-auth-state.js +92 -66
- package/lib/Utils/use-single-file-auth-state.js.map +1 -0
- package/lib/Utils/use-sqlite-auth-state.d.ts +11 -0
- package/lib/Utils/use-sqlite-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-sqlite-auth-state.js +109 -0
- package/lib/Utils/use-sqlite-auth-state.js.map +1 -0
- package/lib/Utils/validate-connection.d.ts +11 -13
- package/lib/Utils/validate-connection.d.ts.map +1 -0
- package/lib/Utils/validate-connection.js +128 -113
- package/lib/Utils/validate-connection.js.map +1 -0
- package/lib/WABinary/constants.d.ts +25 -27
- package/lib/WABinary/constants.d.ts.map +1 -0
- package/lib/WABinary/constants.js +1451 -1292
- package/lib/WABinary/constants.js.bak +1373 -0
- package/lib/WABinary/constants.js.map +1 -0
- package/lib/WABinary/decode.d.ts +7 -9
- package/lib/WABinary/decode.d.ts.map +1 -0
- package/lib/WABinary/decode.js +163 -189
- package/lib/WABinary/decode.js.map +1 -0
- package/lib/WABinary/encode.d.ts +3 -3
- package/lib/WABinary/encode.d.ts.map +1 -0
- package/lib/WABinary/encode.js +110 -155
- package/lib/WABinary/encode.js.map +1 -0
- package/lib/WABinary/generic-utils.d.ts +14 -27
- package/lib/WABinary/generic-utils.d.ts.map +1 -0
- package/lib/WABinary/generic-utils.js +177 -105
- package/lib/WABinary/generic-utils.js.map +1 -0
- package/lib/WABinary/index.d.ts +6 -5
- package/lib/WABinary/index.d.ts.map +1 -0
- package/lib/WABinary/index.js +6 -25
- package/lib/WABinary/index.js.map +1 -0
- package/lib/WABinary/jid-utils.d.ts +41 -51
- package/lib/WABinary/jid-utils.d.ts.map +1 -0
- package/lib/WABinary/jid-utils.js +83 -120
- package/lib/WABinary/jid-utils.js.map +1 -0
- package/lib/WABinary/types.d.ts +10 -13
- package/lib/WABinary/types.d.ts.map +1 -0
- package/lib/WABinary/types.js +2 -3
- package/lib/WABinary/types.js.map +1 -0
- package/lib/WAM/BinaryInfo.d.ts +8 -15
- package/lib/WAM/BinaryInfo.d.ts.map +1 -0
- package/lib/WAM/BinaryInfo.js +7 -14
- package/lib/WAM/BinaryInfo.js.map +1 -0
- package/lib/WAM/constants.d.ts +30 -37
- package/lib/WAM/constants.d.ts.map +1 -0
- package/lib/WAM/constants.js +19193 -11711
- package/lib/WAM/constants.js.map +1 -0
- package/lib/WAM/encode.d.ts +3 -3
- package/lib/WAM/encode.d.ts.map +1 -0
- package/lib/WAM/encode.js +95 -109
- package/lib/WAM/encode.js.map +1 -0
- package/lib/WAM/index.d.ts +4 -3
- package/lib/WAM/index.d.ts.map +1 -0
- package/lib/WAM/index.js +4 -23
- package/lib/WAM/index.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -9
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +37 -21
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +19 -22
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +18 -26
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +11 -12
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +12 -20
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +11 -12
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +16 -24
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +26 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +51 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/index.d.ts +6 -6
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/index.js +6 -26
- package/lib/WAUSync/Protocols/index.js.map +1 -0
- package/lib/WAUSync/USyncQuery.d.ts +27 -28
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
- package/lib/WAUSync/USyncQuery.js +68 -62
- package/lib/WAUSync/USyncQuery.js.map +1 -0
- package/lib/WAUSync/USyncUser.d.ts +15 -10
- package/lib/WAUSync/USyncUser.d.ts.map +1 -0
- package/lib/WAUSync/USyncUser.js +20 -19
- package/lib/WAUSync/USyncUser.js.map +1 -0
- package/lib/WAUSync/index.d.ts +4 -3
- package/lib/WAUSync/index.d.ts.map +1 -0
- package/lib/WAUSync/index.js +4 -23
- package/lib/WAUSync/index.js.map +1 -0
- package/lib/index.d.ts +11 -12
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +12 -39
- package/lib/index.js.map +1 -0
- package/package.json +86 -42
package/lib/Socket/chats.js
CHANGED
|
@@ -1,80 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
1
|
+
import NodeCache from '@cacheable/node-cache';
|
|
2
|
+
import { Boom } from '@hapi/boom';
|
|
3
|
+
import { proto } from '../../WAProto/index.js';
|
|
4
|
+
import { DEFAULT_CACHE_TTLS, HISTORY_SYNC_PAUSED_TIMEOUT_MS, PROCESSABLE_HISTORY_TYPES } from '../Defaults/index.js';
|
|
5
|
+
import { ALL_WA_PATCH_NAMES } from '../Types/index.js';
|
|
6
|
+
import { SyncState } from '../Types/State.js';
|
|
7
|
+
import { chatModificationToAppPatch, decodePatches, decodeSyncdSnapshot, encodeSyncdPatch, ensureLTHashStateVersion, extractSyncdPatches, generateProfilePicture, getHistoryMsg, isAppStateSyncIrrecoverable, isMissingKeyError, MAX_SYNC_ATTEMPTS, newLTHashState, processSyncAction } from '../Utils/index.js';
|
|
8
|
+
import { makeMutex } from '../Utils/make-mutex.js';
|
|
9
|
+
import processMessage from '../Utils/process-message.js';
|
|
10
|
+
import { buildTcTokenFromJid } from '../Utils/tc-token-utils.js';
|
|
11
|
+
import { getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isLidUser, isPnUser, jidDecode, jidNormalizedUser, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary/index.js';
|
|
12
|
+
import { USyncQuery, USyncUser } from '../WAUSync/index.js';
|
|
13
|
+
import { makeSocket } from './socket.js';
|
|
14
|
+
export const makeChatsSocket = (config) => {
|
|
15
|
+
const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, getMessage } = config;
|
|
16
|
+
const sock = makeSocket(config);
|
|
17
|
+
const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, sendUnifiedSession, registerSocketEndHandler } = sock;
|
|
18
|
+
const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping);
|
|
19
|
+
let privacySettings;
|
|
20
|
+
/** Server-assigned AB props for protocol behavior. */
|
|
21
|
+
const serverProps = {
|
|
22
|
+
/** AB prop 10518: gate tctoken on 1:1 messages. Default true (safe: avoids 463). */
|
|
23
|
+
privacyTokenOn1to1: true,
|
|
24
|
+
/** AB prop 9666: gate tctoken on profile picture IQs. WA Web default: true. */
|
|
25
|
+
profilePicPrivacyToken: true,
|
|
26
|
+
/** AB prop 14303: issue tctokens to LID instead of PN. WA Web default: false. */
|
|
27
|
+
lidTrustedTokenIssueToLid: false
|
|
28
|
+
};
|
|
29
|
+
let syncState = SyncState.Connecting;
|
|
30
|
+
/** this mutex ensures that messages are processed in order */
|
|
31
|
+
const messageMutex = makeMutex();
|
|
32
|
+
/** this mutex ensures that receipts are processed in order */
|
|
33
|
+
const receiptMutex = makeMutex();
|
|
34
|
+
/** this mutex ensures that app state patches are processed in order */
|
|
35
|
+
const appStatePatchMutex = makeMutex();
|
|
36
|
+
/** this mutex ensures that notifications are processed in order */
|
|
37
|
+
const notificationMutex = makeMutex();
|
|
38
|
+
// Timeout for AwaitingInitialSync state
|
|
39
|
+
let awaitingSyncTimeout;
|
|
40
|
+
// In-memory history sync completion tracking (resets on reconnection)
|
|
41
|
+
const historySyncStatus = {
|
|
42
|
+
initialBootstrapComplete: false,
|
|
43
|
+
recentSyncComplete: false
|
|
44
|
+
};
|
|
45
|
+
let historySyncPausedTimeout;
|
|
46
|
+
// Collections blocked on missing app state sync keys (mirrors WA Web's "Blocked" state).
|
|
47
|
+
// When a key arrives via APP_STATE_SYNC_KEY_SHARE, these are re-synced.
|
|
48
|
+
const blockedCollections = new Set();
|
|
49
|
+
const placeholderResendCache = config.placeholderResendCache ||
|
|
50
|
+
new NodeCache({
|
|
51
|
+
stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
52
|
+
useClones: false
|
|
53
|
+
});
|
|
44
54
|
/** helper function to fetch the given app state sync key */
|
|
45
55
|
const getAppStateSyncKey = async (keyId) => {
|
|
46
|
-
const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId])
|
|
47
|
-
return key
|
|
48
|
-
}
|
|
49
|
-
|
|
56
|
+
const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId]);
|
|
57
|
+
return key;
|
|
58
|
+
};
|
|
50
59
|
const fetchPrivacySettings = async (force = false) => {
|
|
51
60
|
if (!privacySettings || force) {
|
|
52
61
|
const { content } = await query({
|
|
53
62
|
tag: 'iq',
|
|
54
63
|
attrs: {
|
|
55
64
|
xmlns: 'privacy',
|
|
56
|
-
to:
|
|
65
|
+
to: S_WHATSAPP_NET,
|
|
57
66
|
type: 'get'
|
|
58
67
|
},
|
|
59
|
-
content: [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
})
|
|
63
|
-
privacySettings = WABinary_1.reduceBinaryNodeToDictionary(content?.[0], 'category')
|
|
68
|
+
content: [{ tag: 'privacy', attrs: {} }]
|
|
69
|
+
});
|
|
70
|
+
privacySettings = reduceBinaryNodeToDictionary(content?.[0], 'category');
|
|
64
71
|
}
|
|
65
|
-
return privacySettings
|
|
66
|
-
}
|
|
67
|
-
|
|
72
|
+
return privacySettings;
|
|
73
|
+
};
|
|
68
74
|
/** helper function to run a privacy IQ query */
|
|
69
75
|
const privacyQuery = async (name, value) => {
|
|
70
76
|
await query({
|
|
71
77
|
tag: 'iq',
|
|
72
78
|
attrs: {
|
|
73
79
|
xmlns: 'privacy',
|
|
74
|
-
to:
|
|
80
|
+
to: S_WHATSAPP_NET,
|
|
75
81
|
type: 'set'
|
|
76
82
|
},
|
|
77
|
-
content: [
|
|
83
|
+
content: [
|
|
84
|
+
{
|
|
78
85
|
tag: 'privacy',
|
|
79
86
|
attrs: {},
|
|
80
87
|
content: [
|
|
@@ -83,172 +90,123 @@ const makeChatsSocket = (config) => {
|
|
|
83
90
|
attrs: { name, value }
|
|
84
91
|
}
|
|
85
92
|
]
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
});
|
|
96
|
+
};
|
|
90
97
|
const updateMessagesPrivacy = async (value) => {
|
|
91
|
-
await privacyQuery('messages', value)
|
|
92
|
-
}
|
|
93
|
-
|
|
98
|
+
await privacyQuery('messages', value);
|
|
99
|
+
};
|
|
94
100
|
const updateCallPrivacy = async (value) => {
|
|
95
|
-
await privacyQuery('calladd', value)
|
|
96
|
-
}
|
|
97
|
-
|
|
101
|
+
await privacyQuery('calladd', value);
|
|
102
|
+
};
|
|
98
103
|
const updateLastSeenPrivacy = async (value) => {
|
|
99
|
-
await privacyQuery('last', value)
|
|
100
|
-
}
|
|
101
|
-
|
|
104
|
+
await privacyQuery('last', value);
|
|
105
|
+
};
|
|
102
106
|
const updateOnlinePrivacy = async (value) => {
|
|
103
|
-
await privacyQuery('online', value)
|
|
104
|
-
}
|
|
105
|
-
|
|
107
|
+
await privacyQuery('online', value);
|
|
108
|
+
};
|
|
106
109
|
const updateProfilePicturePrivacy = async (value) => {
|
|
107
|
-
await privacyQuery('profile', value)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
+
await privacyQuery('profile', value);
|
|
111
|
+
};
|
|
110
112
|
const updateStatusPrivacy = async (value) => {
|
|
111
|
-
await privacyQuery('status', value)
|
|
112
|
-
}
|
|
113
|
-
|
|
113
|
+
await privacyQuery('status', value);
|
|
114
|
+
};
|
|
114
115
|
const updateReadReceiptsPrivacy = async (value) => {
|
|
115
|
-
await privacyQuery('readreceipts', value)
|
|
116
|
-
}
|
|
117
|
-
|
|
116
|
+
await privacyQuery('readreceipts', value);
|
|
117
|
+
};
|
|
118
118
|
const updateGroupsAddPrivacy = async (value) => {
|
|
119
|
-
await privacyQuery('groupadd', value)
|
|
120
|
-
}
|
|
121
|
-
|
|
119
|
+
await privacyQuery('groupadd', value);
|
|
120
|
+
};
|
|
122
121
|
const updateDefaultDisappearingMode = async (duration) => {
|
|
123
122
|
await query({
|
|
124
123
|
tag: 'iq',
|
|
125
124
|
attrs: {
|
|
126
125
|
xmlns: 'disappearing_mode',
|
|
127
|
-
to:
|
|
126
|
+
to: S_WHATSAPP_NET,
|
|
128
127
|
type: 'set'
|
|
129
128
|
},
|
|
130
|
-
content: [
|
|
129
|
+
content: [
|
|
130
|
+
{
|
|
131
131
|
tag: 'disappearing_mode',
|
|
132
132
|
attrs: {
|
|
133
133
|
duration: duration.toString()
|
|
134
134
|
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
139
|
const getBotListV2 = async () => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return botList
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const getLidUser = async (jid) => {
|
|
173
|
-
if (!jid) {
|
|
174
|
-
throw new boom_1.Boom('Please input a jid user')
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if (!WABinary_1.isJidUser(jid)) {
|
|
178
|
-
throw new boom_1.Boom('Invalid JID: Not a user JID!')
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const targetJid = WABinary_1.jidNormalizedUser(jid)
|
|
182
|
-
|
|
183
|
-
const usyncQuery = new WAUSync_1.USyncQuery()
|
|
184
|
-
usyncQuery.protocols.push({
|
|
185
|
-
name: 'lid',
|
|
186
|
-
getQueryElement: () => ({
|
|
187
|
-
tag: 'lid',
|
|
188
|
-
attrs: {},
|
|
189
|
-
content: undefined
|
|
190
|
-
}),
|
|
191
|
-
getUserElement: () => null,
|
|
192
|
-
parser: (node) => node.attrs.val
|
|
193
|
-
})
|
|
194
|
-
usyncQuery.users.push({
|
|
195
|
-
id: targetJid
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
const result = await sock.executeUSyncQuery(usyncQuery)
|
|
199
|
-
|
|
200
|
-
if (result) {
|
|
201
|
-
return result.list
|
|
140
|
+
const resp = await query({
|
|
141
|
+
tag: 'iq',
|
|
142
|
+
attrs: {
|
|
143
|
+
xmlns: 'bot',
|
|
144
|
+
to: S_WHATSAPP_NET,
|
|
145
|
+
type: 'get'
|
|
146
|
+
},
|
|
147
|
+
content: [
|
|
148
|
+
{
|
|
149
|
+
tag: 'bot',
|
|
150
|
+
attrs: {
|
|
151
|
+
v: '2'
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
});
|
|
156
|
+
const botNode = getBinaryNodeChild(resp, 'bot');
|
|
157
|
+
const botList = [];
|
|
158
|
+
for (const section of getBinaryNodeChildren(botNode, 'section')) {
|
|
159
|
+
if (section.attrs.type === 'all') {
|
|
160
|
+
for (const bot of getBinaryNodeChildren(section, 'bot')) {
|
|
161
|
+
botList.push({
|
|
162
|
+
jid: bot.attrs.jid,
|
|
163
|
+
personaId: bot.attrs['persona_id']
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
202
167
|
}
|
|
203
|
-
|
|
204
|
-
|
|
168
|
+
return botList;
|
|
169
|
+
};
|
|
205
170
|
const fetchStatus = async (...jids) => {
|
|
206
|
-
const usyncQuery = new
|
|
207
|
-
|
|
171
|
+
const usyncQuery = new USyncQuery().withStatusProtocol();
|
|
208
172
|
for (const jid of jids) {
|
|
209
|
-
usyncQuery.withUser(new
|
|
173
|
+
usyncQuery.withUser(new USyncUser().withId(jid));
|
|
210
174
|
}
|
|
211
|
-
|
|
212
|
-
const result = await sock.executeUSyncQuery(usyncQuery)
|
|
213
|
-
|
|
175
|
+
const result = await sock.executeUSyncQuery(usyncQuery);
|
|
214
176
|
if (result) {
|
|
215
|
-
return result.list
|
|
177
|
+
return result.list;
|
|
216
178
|
}
|
|
217
|
-
}
|
|
218
|
-
const fetchDisappearingDuration = async (...jids) => {
|
|
219
|
-
const usyncQuery = new
|
|
220
|
-
|
|
179
|
+
};
|
|
180
|
+
const fetchDisappearingDuration = async (...jids) => {
|
|
181
|
+
const usyncQuery = new USyncQuery().withDisappearingModeProtocol();
|
|
221
182
|
for (const jid of jids) {
|
|
222
|
-
usyncQuery.withUser(new
|
|
183
|
+
usyncQuery.withUser(new USyncUser().withId(jid));
|
|
223
184
|
}
|
|
224
|
-
|
|
225
|
-
const result = await sock.executeUSyncQuery(usyncQuery)
|
|
185
|
+
const result = await sock.executeUSyncQuery(usyncQuery);
|
|
226
186
|
if (result) {
|
|
227
|
-
return result.list
|
|
187
|
+
return result.list;
|
|
228
188
|
}
|
|
229
|
-
}
|
|
230
|
-
|
|
189
|
+
};
|
|
231
190
|
/** update the profile picture for yourself or a group */
|
|
232
|
-
const updateProfilePicture = async (jid, content) => {
|
|
233
|
-
let targetJid
|
|
234
|
-
|
|
191
|
+
const updateProfilePicture = async (jid, content, dimensions) => {
|
|
192
|
+
let targetJid;
|
|
235
193
|
if (!jid) {
|
|
236
|
-
throw new
|
|
194
|
+
throw new Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
|
|
195
|
+
}
|
|
196
|
+
if (jidNormalizedUser(jid) !== jidNormalizedUser(authState.creds.me.id)) {
|
|
197
|
+
targetJid = jidNormalizedUser(jid); // in case it is someone other than us
|
|
237
198
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
targetJid = WABinary_1.jidNormalizedUser(jid) // in case it is someone other than us
|
|
199
|
+
else {
|
|
200
|
+
targetJid = undefined;
|
|
241
201
|
}
|
|
242
|
-
|
|
243
|
-
const { img } = await Utils_1.generateProfilePicture(content)
|
|
244
|
-
|
|
202
|
+
const { img } = await generateProfilePicture(content, dimensions);
|
|
245
203
|
await query({
|
|
246
204
|
tag: 'iq',
|
|
247
205
|
attrs: {
|
|
248
|
-
|
|
249
|
-
to: WABinary_1.S_WHATSAPP_NET,
|
|
206
|
+
to: S_WHATSAPP_NET,
|
|
250
207
|
type: 'set',
|
|
251
|
-
xmlns: 'w:profile:picture'
|
|
208
|
+
xmlns: 'w:profile:picture',
|
|
209
|
+
...(targetJid ? { target: targetJid } : {})
|
|
252
210
|
},
|
|
253
211
|
content: [
|
|
254
212
|
{
|
|
@@ -257,38 +215,36 @@ const makeChatsSocket = (config) => {
|
|
|
257
215
|
content: img
|
|
258
216
|
}
|
|
259
217
|
]
|
|
260
|
-
})
|
|
261
|
-
}
|
|
262
|
-
|
|
218
|
+
});
|
|
219
|
+
};
|
|
263
220
|
/** remove the profile picture for yourself or a group */
|
|
264
221
|
const removeProfilePicture = async (jid) => {
|
|
265
|
-
let targetJid
|
|
266
|
-
|
|
222
|
+
let targetJid;
|
|
267
223
|
if (!jid) {
|
|
268
|
-
throw new
|
|
224
|
+
throw new Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
|
|
269
225
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
226
|
+
if (jidNormalizedUser(jid) !== jidNormalizedUser(authState.creds.me.id)) {
|
|
227
|
+
targetJid = jidNormalizedUser(jid); // in case it is someone other than us
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
targetJid = undefined;
|
|
273
231
|
}
|
|
274
|
-
|
|
275
232
|
await query({
|
|
276
233
|
tag: 'iq',
|
|
277
234
|
attrs: {
|
|
278
|
-
|
|
279
|
-
to: WABinary_1.S_WHATSAPP_NET,
|
|
235
|
+
to: S_WHATSAPP_NET,
|
|
280
236
|
type: 'set',
|
|
281
|
-
xmlns: 'w:profile:picture'
|
|
237
|
+
xmlns: 'w:profile:picture',
|
|
238
|
+
...(targetJid ? { target: targetJid } : {})
|
|
282
239
|
}
|
|
283
|
-
})
|
|
284
|
-
}
|
|
285
|
-
|
|
240
|
+
});
|
|
241
|
+
};
|
|
286
242
|
/** update the profile status for yourself */
|
|
287
243
|
const updateProfileStatus = async (status) => {
|
|
288
244
|
await query({
|
|
289
245
|
tag: 'iq',
|
|
290
246
|
attrs: {
|
|
291
|
-
to:
|
|
247
|
+
to: S_WHATSAPP_NET,
|
|
292
248
|
type: 'set',
|
|
293
249
|
xmlns: 'status'
|
|
294
250
|
},
|
|
@@ -299,48 +255,75 @@ const makeChatsSocket = (config) => {
|
|
|
299
255
|
content: Buffer.from(status, 'utf-8')
|
|
300
256
|
}
|
|
301
257
|
]
|
|
302
|
-
})
|
|
303
|
-
}
|
|
304
|
-
|
|
258
|
+
});
|
|
259
|
+
};
|
|
305
260
|
const updateProfileName = async (name) => {
|
|
306
|
-
await chatModify({ pushNameSetting: name }, '')
|
|
307
|
-
}
|
|
308
|
-
|
|
261
|
+
await chatModify({ pushNameSetting: name }, '');
|
|
262
|
+
};
|
|
309
263
|
const fetchBlocklist = async () => {
|
|
310
264
|
const result = await query({
|
|
311
265
|
tag: 'iq',
|
|
312
266
|
attrs: {
|
|
313
267
|
xmlns: 'blocklist',
|
|
314
|
-
to:
|
|
268
|
+
to: S_WHATSAPP_NET,
|
|
315
269
|
type: 'get'
|
|
316
270
|
}
|
|
317
|
-
})
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
return WABinary_1.getBinaryNodeChildren(listNode, 'item').map((n) => n.attrs.jid)
|
|
322
|
-
}
|
|
323
|
-
|
|
271
|
+
});
|
|
272
|
+
const listNode = getBinaryNodeChild(result, 'list');
|
|
273
|
+
return getBinaryNodeChildren(listNode, 'item').map(n => n.attrs.jid);
|
|
274
|
+
};
|
|
324
275
|
const updateBlockStatus = async (jid, action) => {
|
|
276
|
+
const normalizedJid = jidNormalizedUser(jid);
|
|
277
|
+
let lid;
|
|
278
|
+
let pn_jid;
|
|
279
|
+
if (isLidUser(normalizedJid) || isHostedLidUser(normalizedJid)) {
|
|
280
|
+
lid = normalizedJid;
|
|
281
|
+
if (action === 'block') {
|
|
282
|
+
const pn = await signalRepository.lidMapping.getPNForLID(normalizedJid);
|
|
283
|
+
if (!pn) {
|
|
284
|
+
throw new Boom(`Unable to resolve PN JID for LID: ${jid}`, { statusCode: 400 });
|
|
285
|
+
}
|
|
286
|
+
pn_jid = jidNormalizedUser(pn);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
else if (isPnUser(normalizedJid) || isHostedPnUser(normalizedJid)) {
|
|
290
|
+
const mapped = await signalRepository.lidMapping.getLIDForPN(normalizedJid);
|
|
291
|
+
if (!mapped) {
|
|
292
|
+
throw new Boom(`Unable to resolve LID for PN JID: ${jid}`, { statusCode: 400 });
|
|
293
|
+
}
|
|
294
|
+
lid = mapped;
|
|
295
|
+
if (action === 'block') {
|
|
296
|
+
pn_jid = jidNormalizedUser(normalizedJid);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
throw new Boom(`Invalid jid: ${jid}`, { statusCode: 400 });
|
|
301
|
+
}
|
|
302
|
+
const itemAttrs = {
|
|
303
|
+
action,
|
|
304
|
+
jid: lid
|
|
305
|
+
};
|
|
306
|
+
if (action === 'block') {
|
|
307
|
+
if (!pn_jid) {
|
|
308
|
+
throw new Boom(`pn_jid required for block: ${jid}`, { statusCode: 400 });
|
|
309
|
+
}
|
|
310
|
+
itemAttrs.pn_jid = pn_jid;
|
|
311
|
+
}
|
|
325
312
|
await query({
|
|
326
313
|
tag: 'iq',
|
|
327
314
|
attrs: {
|
|
328
315
|
xmlns: 'blocklist',
|
|
329
|
-
to:
|
|
316
|
+
to: S_WHATSAPP_NET,
|
|
330
317
|
type: 'set'
|
|
331
318
|
},
|
|
332
319
|
content: [
|
|
333
320
|
{
|
|
334
321
|
tag: 'item',
|
|
335
|
-
attrs:
|
|
336
|
-
action,
|
|
337
|
-
jid
|
|
338
|
-
}
|
|
322
|
+
attrs: itemAttrs
|
|
339
323
|
}
|
|
340
324
|
]
|
|
341
|
-
})
|
|
342
|
-
}
|
|
343
|
-
|
|
325
|
+
});
|
|
326
|
+
};
|
|
344
327
|
const getBusinessProfile = async (jid) => {
|
|
345
328
|
const results = await query({
|
|
346
329
|
tag: 'iq',
|
|
@@ -349,121 +332,133 @@ const makeChatsSocket = (config) => {
|
|
|
349
332
|
xmlns: 'w:biz',
|
|
350
333
|
type: 'get'
|
|
351
334
|
},
|
|
352
|
-
content: [
|
|
335
|
+
content: [
|
|
336
|
+
{
|
|
353
337
|
tag: 'business_profile',
|
|
354
338
|
attrs: { v: '244' },
|
|
355
|
-
content: [
|
|
339
|
+
content: [
|
|
340
|
+
{
|
|
356
341
|
tag: 'profile',
|
|
357
342
|
attrs: { jid }
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const profiles =
|
|
365
|
-
|
|
343
|
+
}
|
|
344
|
+
]
|
|
345
|
+
}
|
|
346
|
+
]
|
|
347
|
+
});
|
|
348
|
+
const profileNode = getBinaryNodeChild(results, 'business_profile');
|
|
349
|
+
const profiles = getBinaryNodeChild(profileNode, 'profile');
|
|
366
350
|
if (profiles) {
|
|
367
|
-
const address =
|
|
368
|
-
const description =
|
|
369
|
-
const website =
|
|
370
|
-
const email =
|
|
371
|
-
const category =
|
|
372
|
-
const businessHours =
|
|
351
|
+
const address = getBinaryNodeChild(profiles, 'address');
|
|
352
|
+
const description = getBinaryNodeChild(profiles, 'description');
|
|
353
|
+
const website = getBinaryNodeChild(profiles, 'website');
|
|
354
|
+
const email = getBinaryNodeChild(profiles, 'email');
|
|
355
|
+
const category = getBinaryNodeChild(getBinaryNodeChild(profiles, 'categories'), 'category');
|
|
356
|
+
const businessHours = getBinaryNodeChild(profiles, 'business_hours');
|
|
373
357
|
const businessHoursConfig = businessHours
|
|
374
|
-
?
|
|
375
|
-
: undefined
|
|
376
|
-
const websiteStr = website?.content?.toString()
|
|
377
|
-
|
|
358
|
+
? getBinaryNodeChildren(businessHours, 'business_hours_config')
|
|
359
|
+
: undefined;
|
|
360
|
+
const websiteStr = website?.content?.toString();
|
|
378
361
|
return {
|
|
379
|
-
wid: profiles
|
|
362
|
+
wid: profiles.attrs?.jid,
|
|
380
363
|
address: address?.content?.toString(),
|
|
381
364
|
description: description?.content?.toString() || '',
|
|
382
365
|
website: websiteStr ? [websiteStr] : [],
|
|
383
366
|
email: email?.content?.toString(),
|
|
384
367
|
category: category?.content?.toString(),
|
|
385
|
-
|
|
368
|
+
business_hours: {
|
|
386
369
|
timezone: businessHours?.attrs?.timezone,
|
|
387
|
-
|
|
370
|
+
business_config: businessHoursConfig?.map(({ attrs }) => attrs)
|
|
388
371
|
}
|
|
389
|
-
}
|
|
372
|
+
};
|
|
390
373
|
}
|
|
391
|
-
}
|
|
392
|
-
|
|
374
|
+
};
|
|
393
375
|
const cleanDirtyBits = async (type, fromTimestamp) => {
|
|
394
|
-
logger.info({ fromTimestamp }, 'clean dirty bits ' + type)
|
|
376
|
+
logger.info({ fromTimestamp }, 'clean dirty bits ' + type);
|
|
395
377
|
await sendNode({
|
|
396
378
|
tag: 'iq',
|
|
397
379
|
attrs: {
|
|
398
|
-
to:
|
|
380
|
+
to: S_WHATSAPP_NET,
|
|
399
381
|
type: 'set',
|
|
400
382
|
xmlns: 'urn:xmpp:whatsapp:dirty',
|
|
401
|
-
id: generateMessageTag()
|
|
383
|
+
id: generateMessageTag()
|
|
402
384
|
},
|
|
403
385
|
content: [
|
|
404
386
|
{
|
|
405
387
|
tag: 'clean',
|
|
406
388
|
attrs: {
|
|
407
389
|
type,
|
|
408
|
-
...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null)
|
|
390
|
+
...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null)
|
|
409
391
|
}
|
|
410
392
|
}
|
|
411
393
|
]
|
|
412
|
-
})
|
|
413
|
-
}
|
|
414
|
-
|
|
394
|
+
});
|
|
395
|
+
};
|
|
415
396
|
const newAppStateChunkHandler = (isInitialSync) => {
|
|
416
397
|
return {
|
|
417
398
|
onMutation(mutation) {
|
|
418
|
-
|
|
399
|
+
processSyncAction(mutation, ev, authState.creds.me, isInitialSync ? { accountSettings: authState.creds.accountSettings } : undefined, logger);
|
|
419
400
|
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
401
|
+
};
|
|
402
|
+
};
|
|
423
403
|
const resyncAppState = ev.createBufferedFunction(async (collections, isInitialSync) => {
|
|
404
|
+
const appStateSyncKeyCache = new Map();
|
|
405
|
+
const getCachedAppStateSyncKey = async (keyId) => {
|
|
406
|
+
if (appStateSyncKeyCache.has(keyId)) {
|
|
407
|
+
return appStateSyncKeyCache.get(keyId) ?? undefined;
|
|
408
|
+
}
|
|
409
|
+
const key = await getAppStateSyncKey(keyId);
|
|
410
|
+
appStateSyncKeyCache.set(keyId, key ?? null);
|
|
411
|
+
return key;
|
|
412
|
+
};
|
|
424
413
|
// we use this to determine which events to fire
|
|
425
414
|
// otherwise when we resync from scratch -- all notifications will fire
|
|
426
|
-
const initialVersionMap = {}
|
|
427
|
-
const globalMutationMap = {}
|
|
415
|
+
const initialVersionMap = {};
|
|
416
|
+
const globalMutationMap = {};
|
|
428
417
|
await authState.keys.transaction(async () => {
|
|
429
|
-
const collectionsToHandle = new Set(collections)
|
|
418
|
+
const collectionsToHandle = new Set(collections);
|
|
430
419
|
// in case something goes wrong -- ensure we don't enter a loop that cannot be exited from
|
|
431
|
-
const attemptsMap = {}
|
|
420
|
+
const attemptsMap = {};
|
|
421
|
+
// collections that failed and need a full snapshot on retry
|
|
422
|
+
// mirrors WA Web's ErrorFatal -> force snapshot behavior
|
|
423
|
+
const forceSnapshotCollections = new Set();
|
|
432
424
|
// keep executing till all collections are done
|
|
433
425
|
// sometimes a single patch request will not return all the patches (God knows why)
|
|
434
426
|
// so we fetch till they're all done (this is determined by the "has_more_patches" flag)
|
|
435
427
|
while (collectionsToHandle.size) {
|
|
436
|
-
const states = {}
|
|
437
|
-
const nodes = []
|
|
438
|
-
|
|
428
|
+
const states = {};
|
|
429
|
+
const nodes = [];
|
|
439
430
|
for (const name of collectionsToHandle) {
|
|
440
|
-
const result = await authState.keys.get('app-state-sync-version', [name])
|
|
441
|
-
let state = result[name]
|
|
431
|
+
const result = await authState.keys.get('app-state-sync-version', [name]);
|
|
432
|
+
let state = result[name];
|
|
442
433
|
if (state) {
|
|
434
|
+
state = ensureLTHashStateVersion(state);
|
|
443
435
|
if (typeof initialVersionMap[name] === 'undefined') {
|
|
444
|
-
initialVersionMap[name] = state.version
|
|
436
|
+
initialVersionMap[name] = state.version;
|
|
445
437
|
}
|
|
446
438
|
}
|
|
447
439
|
else {
|
|
448
|
-
state =
|
|
440
|
+
state = newLTHashState();
|
|
441
|
+
}
|
|
442
|
+
states[name] = state;
|
|
443
|
+
const shouldForceSnapshot = forceSnapshotCollections.has(name);
|
|
444
|
+
if (shouldForceSnapshot) {
|
|
445
|
+
forceSnapshotCollections.delete(name);
|
|
449
446
|
}
|
|
450
|
-
|
|
451
|
-
logger.info(`resyncing ${name} from v${state.version}`)
|
|
447
|
+
logger.info(`resyncing ${name} from v${state.version}${shouldForceSnapshot ? ' (forcing snapshot)' : ''}`);
|
|
452
448
|
nodes.push({
|
|
453
449
|
tag: 'collection',
|
|
454
450
|
attrs: {
|
|
455
451
|
name,
|
|
456
452
|
version: state.version.toString(),
|
|
457
|
-
// return snapshot if
|
|
458
|
-
|
|
453
|
+
// return snapshot if syncing from scratch or forcing after a failed attempt
|
|
454
|
+
return_snapshot: (shouldForceSnapshot || !state.version).toString()
|
|
459
455
|
}
|
|
460
|
-
})
|
|
456
|
+
});
|
|
461
457
|
}
|
|
462
|
-
|
|
463
458
|
const result = await query({
|
|
464
459
|
tag: 'iq',
|
|
465
460
|
attrs: {
|
|
466
|
-
to:
|
|
461
|
+
to: S_WHATSAPP_NET,
|
|
467
462
|
xmlns: 'w:sync:app:state',
|
|
468
463
|
type: 'set'
|
|
469
464
|
},
|
|
@@ -474,125 +469,159 @@ const makeChatsSocket = (config) => {
|
|
|
474
469
|
content: nodes
|
|
475
470
|
}
|
|
476
471
|
]
|
|
477
|
-
})
|
|
478
|
-
|
|
472
|
+
});
|
|
479
473
|
// extract from binary node
|
|
480
|
-
const decoded = await
|
|
481
|
-
|
|
474
|
+
const decoded = await extractSyncdPatches(result, config?.options);
|
|
482
475
|
for (const key in decoded) {
|
|
483
|
-
const name = key
|
|
484
|
-
const { patches, hasMorePatches, snapshot } = decoded[name]
|
|
476
|
+
const name = key;
|
|
477
|
+
const { patches, hasMorePatches, snapshot } = decoded[name];
|
|
485
478
|
try {
|
|
486
479
|
if (snapshot) {
|
|
487
|
-
const { state: newState, mutationMap } = await
|
|
488
|
-
states[name] = newState
|
|
489
|
-
Object.assign(globalMutationMap, mutationMap)
|
|
490
|
-
logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`)
|
|
491
|
-
await authState.keys.set({ 'app-state-sync-version': { [name]: newState } })
|
|
480
|
+
const { state: newState, mutationMap } = await decodeSyncdSnapshot(name, snapshot, getCachedAppStateSyncKey, initialVersionMap[name], appStateMacVerification.snapshot, logger);
|
|
481
|
+
states[name] = newState;
|
|
482
|
+
Object.assign(globalMutationMap, mutationMap);
|
|
483
|
+
logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`);
|
|
484
|
+
await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
|
|
492
485
|
}
|
|
493
|
-
|
|
494
486
|
// only process if there are syncd patches
|
|
495
487
|
if (patches.length) {
|
|
496
|
-
const { state: newState, mutationMap } = await
|
|
497
|
-
await authState.keys.set({ 'app-state-sync-version': { [name]: newState } })
|
|
498
|
-
logger.info(`synced ${name} to v${newState.version}`)
|
|
499
|
-
initialVersionMap[name] = newState.version
|
|
500
|
-
Object.assign(globalMutationMap, mutationMap)
|
|
488
|
+
const { state: newState, mutationMap } = await decodePatches(name, patches, states[name], getCachedAppStateSyncKey, config.options, initialVersionMap[name], logger, appStateMacVerification.patch);
|
|
489
|
+
await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
|
|
490
|
+
logger.info(`synced ${name} to v${newState.version}`);
|
|
491
|
+
initialVersionMap[name] = newState.version;
|
|
492
|
+
Object.assign(globalMutationMap, mutationMap);
|
|
501
493
|
}
|
|
502
|
-
|
|
503
494
|
if (hasMorePatches) {
|
|
504
|
-
logger.info(`${name} has more patches...`)
|
|
505
|
-
}
|
|
506
|
-
else { // collection is done with sync
|
|
507
|
-
collectionsToHandle.delete(name)
|
|
495
|
+
logger.info(`${name} has more patches...`);
|
|
508
496
|
}
|
|
509
|
-
|
|
497
|
+
else {
|
|
498
|
+
// collection is done with sync
|
|
499
|
+
collectionsToHandle.delete(name);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
510
502
|
catch (error) {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
//
|
|
523
|
-
|
|
503
|
+
attemptsMap[name] = (attemptsMap[name] || 0) + 1;
|
|
504
|
+
const logData = {
|
|
505
|
+
name,
|
|
506
|
+
attempt: attemptsMap[name],
|
|
507
|
+
version: states[name].version,
|
|
508
|
+
statusCode: error.output?.statusCode,
|
|
509
|
+
errorType: error.name,
|
|
510
|
+
error: error.stack
|
|
511
|
+
};
|
|
512
|
+
if (isMissingKeyError(error) && attemptsMap[name] >= MAX_SYNC_ATTEMPTS) {
|
|
513
|
+
// WA Web treats missing keys as "Blocked" — park the collection
|
|
514
|
+
// until the key arrives via APP_STATE_SYNC_KEY_SHARE.
|
|
515
|
+
logger.warn(logData, `${name} blocked on missing key from v${states[name].version}, parking after ${attemptsMap[name]} attempts`);
|
|
516
|
+
blockedCollections.add(name);
|
|
517
|
+
collectionsToHandle.delete(name);
|
|
518
|
+
}
|
|
519
|
+
else if (isMissingKeyError(error)) {
|
|
520
|
+
// Retry with a snapshot which may use a different key.
|
|
521
|
+
logger.info(logData, `${name} blocked on missing key from v${states[name].version}, retrying with snapshot`);
|
|
522
|
+
forceSnapshotCollections.add(name);
|
|
523
|
+
}
|
|
524
|
+
else if (isAppStateSyncIrrecoverable(error, attemptsMap[name])) {
|
|
525
|
+
logger.warn(logData, `failed to sync ${name} from v${states[name].version}, giving up`);
|
|
526
|
+
collectionsToHandle.delete(name);
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
logger.info(logData, `failed to sync ${name} from v${states[name].version}, forcing snapshot retry`);
|
|
530
|
+
// force a full snapshot on retry to recover from
|
|
531
|
+
// corrupted local state (e.g. LTHash MAC mismatch)
|
|
532
|
+
forceSnapshotCollections.add(name);
|
|
524
533
|
}
|
|
525
534
|
}
|
|
526
535
|
}
|
|
527
536
|
}
|
|
528
|
-
}, authState?.creds?.me?.id || 'resync-app-state')
|
|
529
|
-
|
|
530
|
-
const { onMutation } = newAppStateChunkHandler(isInitialSync)
|
|
531
|
-
|
|
537
|
+
}, authState?.creds?.me?.id || 'resync-app-state');
|
|
538
|
+
const { onMutation } = newAppStateChunkHandler(isInitialSync);
|
|
532
539
|
for (const key in globalMutationMap) {
|
|
533
|
-
onMutation(globalMutationMap[key])
|
|
540
|
+
onMutation(globalMutationMap[key]);
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
/**
|
|
544
|
+
* fetch the profile picture of a user/group
|
|
545
|
+
* type = "preview" for a low res picture
|
|
546
|
+
* type = "image for the high res picture"
|
|
547
|
+
*/
|
|
548
|
+
const profilePictureUrl = async (jid, type = 'preview', timeoutMs) => {
|
|
549
|
+
const baseContent = [{ tag: 'picture', attrs: { type, query: 'url' } }];
|
|
550
|
+
// WA Web only includes tctoken for user JIDs (not groups/newsletters)
|
|
551
|
+
// and never for own profile pic (Chat model for self has no tcToken).
|
|
552
|
+
// Including tctoken for own JID causes the server to never respond.
|
|
553
|
+
const normalizedJid = jidNormalizedUser(jid);
|
|
554
|
+
const isUserJid = isPnUser(normalizedJid) || isLidUser(normalizedJid);
|
|
555
|
+
const me = authState.creds.me;
|
|
556
|
+
const isSelf = me && (normalizedJid === jidNormalizedUser(me.id) || (me.lid && normalizedJid === jidNormalizedUser(me.lid)));
|
|
557
|
+
let content = baseContent;
|
|
558
|
+
if (serverProps.profilePicPrivacyToken && isUserJid && !isSelf) {
|
|
559
|
+
content = await buildTcTokenFromJid({
|
|
560
|
+
authState,
|
|
561
|
+
jid: normalizedJid,
|
|
562
|
+
baseContent,
|
|
563
|
+
getLIDForPN
|
|
564
|
+
});
|
|
534
565
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
566
|
+
jid = jidNormalizedUser(jid);
|
|
567
|
+
const result = await query({
|
|
568
|
+
tag: 'iq',
|
|
569
|
+
attrs: {
|
|
570
|
+
target: jid,
|
|
571
|
+
to: S_WHATSAPP_NET,
|
|
572
|
+
type: 'get',
|
|
573
|
+
xmlns: 'w:profile:picture'
|
|
574
|
+
},
|
|
575
|
+
content
|
|
576
|
+
}, timeoutMs);
|
|
577
|
+
const child = getBinaryNodeChild(result, 'picture');
|
|
578
|
+
return child?.attrs?.url;
|
|
579
|
+
};
|
|
538
580
|
const createCallLink = async (type, event, timeoutMs) => {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
content: event ? [{
|
|
557
|
-
tag: 'event',
|
|
558
|
-
attrs: {
|
|
559
|
-
start_time: String(event)
|
|
560
|
-
}
|
|
561
|
-
}] : undefined
|
|
562
|
-
}]
|
|
563
|
-
}, timeoutMs)
|
|
564
|
-
|
|
565
|
-
const child = WABinary_1.getBinaryNodeChild(result, 'link_create')
|
|
566
|
-
const token = child?.attrs?.token
|
|
567
|
-
|
|
568
|
-
return type === 'audio' ? Defaults_1.CALL_AUDIO_PREFIX + token : Defaults_1.CALL_VIDEO_PREFIX + token
|
|
569
|
-
}
|
|
570
|
-
|
|
581
|
+
const result = await query({
|
|
582
|
+
tag: 'call',
|
|
583
|
+
attrs: {
|
|
584
|
+
id: generateMessageTag(),
|
|
585
|
+
to: '@call'
|
|
586
|
+
},
|
|
587
|
+
content: [
|
|
588
|
+
{
|
|
589
|
+
tag: 'link_create',
|
|
590
|
+
attrs: { media: type },
|
|
591
|
+
content: event ? [{ tag: 'event', attrs: { start_time: String(event.startTime) } }] : undefined
|
|
592
|
+
}
|
|
593
|
+
]
|
|
594
|
+
}, timeoutMs);
|
|
595
|
+
const child = getBinaryNodeChild(result, 'link_create');
|
|
596
|
+
return child?.attrs?.token;
|
|
597
|
+
};
|
|
571
598
|
const sendPresenceUpdate = async (type, toJid) => {
|
|
572
|
-
const me = authState.creds.me
|
|
573
|
-
|
|
574
|
-
if (
|
|
599
|
+
const me = authState.creds.me;
|
|
600
|
+
const isAvailableType = type === 'available';
|
|
601
|
+
if (isAvailableType || type === 'unavailable') {
|
|
575
602
|
if (!me.name) {
|
|
576
|
-
logger.warn('no name present, ignoring presence update request...')
|
|
577
|
-
return
|
|
603
|
+
logger.warn('no name present, ignoring presence update request...');
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
ev.emit('connection.update', { isOnline: isAvailableType });
|
|
607
|
+
if (isAvailableType) {
|
|
608
|
+
void sendUnifiedSession();
|
|
578
609
|
}
|
|
579
|
-
|
|
580
|
-
ev.emit('connection.update', { isOnline: type === 'available' })
|
|
581
610
|
await sendNode({
|
|
582
611
|
tag: 'presence',
|
|
583
612
|
attrs: {
|
|
584
613
|
name: me.name.replace(/@/g, ''),
|
|
585
614
|
type
|
|
586
615
|
}
|
|
587
|
-
})
|
|
616
|
+
});
|
|
588
617
|
}
|
|
589
618
|
else {
|
|
590
|
-
|
|
591
|
-
|
|
619
|
+
const { server } = jidDecode(toJid);
|
|
620
|
+
const isLid = server === 'lid';
|
|
592
621
|
await sendNode({
|
|
593
622
|
tag: 'chatstate',
|
|
594
623
|
attrs: {
|
|
595
|
-
from:
|
|
624
|
+
from: isLid ? me.lid : me.id,
|
|
596
625
|
to: toJid
|
|
597
626
|
},
|
|
598
627
|
content: [
|
|
@@ -601,96 +630,82 @@ const makeChatsSocket = (config) => {
|
|
|
601
630
|
attrs: type === 'recording' ? { media: 'audio' } : {}
|
|
602
631
|
}
|
|
603
632
|
]
|
|
604
|
-
})
|
|
633
|
+
});
|
|
605
634
|
}
|
|
606
|
-
}
|
|
607
|
-
|
|
635
|
+
};
|
|
608
636
|
/**
|
|
609
637
|
* @param toJid the jid to subscribe to
|
|
610
638
|
* @param tcToken token for subscription, use if present
|
|
611
639
|
*/
|
|
612
|
-
const presenceSubscribe = (toJid
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
}
|
|
629
|
-
|
|
640
|
+
const presenceSubscribe = async (toJid) => {
|
|
641
|
+
// Only include tctoken for user JIDs — groups/newsletters don't use tctokens
|
|
642
|
+
const normalizedToJid = jidNormalizedUser(toJid);
|
|
643
|
+
const isUserJid = isPnUser(normalizedToJid) || isLidUser(normalizedToJid);
|
|
644
|
+
const tcTokenContent = isUserJid
|
|
645
|
+
? await buildTcTokenFromJid({ authState, jid: normalizedToJid, getLIDForPN })
|
|
646
|
+
: undefined;
|
|
647
|
+
return sendNode({
|
|
648
|
+
tag: 'presence',
|
|
649
|
+
attrs: {
|
|
650
|
+
to: toJid,
|
|
651
|
+
id: generateMessageTag(),
|
|
652
|
+
type: 'subscribe'
|
|
653
|
+
},
|
|
654
|
+
content: tcTokenContent
|
|
655
|
+
});
|
|
656
|
+
};
|
|
630
657
|
const handlePresenceUpdate = ({ tag, attrs, content }) => {
|
|
631
|
-
let presence
|
|
632
|
-
const jid = attrs.from
|
|
633
|
-
const participant = attrs.participant || attrs.from
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
return
|
|
658
|
+
let presence;
|
|
659
|
+
const jid = attrs.from;
|
|
660
|
+
const participant = attrs.participant || attrs.from;
|
|
661
|
+
if (shouldIgnoreJid(jid) && jid !== S_WHATSAPP_NET) {
|
|
662
|
+
return;
|
|
637
663
|
}
|
|
638
|
-
|
|
639
664
|
if (tag === 'presence') {
|
|
640
665
|
presence = {
|
|
641
666
|
lastKnownPresence: attrs.type === 'unavailable' ? 'unavailable' : 'available',
|
|
642
|
-
lastSeen: attrs.last && attrs.last !== 'deny' ? +attrs.last : undefined
|
|
643
|
-
|
|
667
|
+
lastSeen: attrs.last && attrs.last !== 'deny' ? +attrs.last : undefined,
|
|
668
|
+
groupOnlineCount: attrs.count ? +attrs.count : undefined
|
|
669
|
+
};
|
|
644
670
|
}
|
|
645
|
-
|
|
646
671
|
else if (Array.isArray(content)) {
|
|
647
|
-
const [firstChild] = content
|
|
648
|
-
let type = firstChild.tag
|
|
649
|
-
|
|
672
|
+
const [firstChild] = content;
|
|
673
|
+
let type = firstChild.tag;
|
|
650
674
|
if (type === 'paused') {
|
|
651
|
-
type = 'available'
|
|
675
|
+
type = 'available';
|
|
652
676
|
}
|
|
653
|
-
|
|
654
677
|
if (firstChild.attrs?.media === 'audio') {
|
|
655
|
-
type = 'recording'
|
|
678
|
+
type = 'recording';
|
|
656
679
|
}
|
|
657
|
-
|
|
658
|
-
presence = { lastKnownPresence: type }
|
|
680
|
+
presence = { lastKnownPresence: type };
|
|
659
681
|
}
|
|
660
|
-
|
|
661
682
|
else {
|
|
662
|
-
logger.error({ tag, attrs, content }, 'recv invalid presence node')
|
|
683
|
+
logger.error({ tag, attrs, content }, 'recv invalid presence node');
|
|
663
684
|
}
|
|
664
|
-
|
|
665
685
|
if (presence) {
|
|
666
|
-
ev.emit('presence.update', { id: jid, presences: { [participant]: presence } })
|
|
686
|
+
ev.emit('presence.update', { id: jid, presences: { [participant]: presence } });
|
|
667
687
|
}
|
|
668
|
-
}
|
|
669
|
-
|
|
688
|
+
};
|
|
670
689
|
const appPatch = async (patchCreate) => {
|
|
671
|
-
const name = patchCreate.type
|
|
672
|
-
const myAppStateKeyId = authState.creds.myAppStateKeyId
|
|
673
|
-
|
|
690
|
+
const name = patchCreate.type;
|
|
691
|
+
const myAppStateKeyId = authState.creds.myAppStateKeyId;
|
|
674
692
|
if (!myAppStateKeyId) {
|
|
675
|
-
throw new
|
|
693
|
+
throw new Boom('App state key not present!', { statusCode: 400 });
|
|
676
694
|
}
|
|
677
|
-
|
|
678
|
-
let
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
await processingMutex.mutex(async () => {
|
|
695
|
+
let initial;
|
|
696
|
+
let encodeResult;
|
|
697
|
+
await appStatePatchMutex.mutex(async () => {
|
|
682
698
|
await authState.keys.transaction(async () => {
|
|
683
|
-
logger.debug({ patch: patchCreate }, 'applying app patch')
|
|
684
|
-
await resyncAppState([name], false)
|
|
685
|
-
const { [name]: currentSyncVersion } = await authState.keys.get('app-state-sync-version', [name])
|
|
686
|
-
initial = currentSyncVersion
|
|
687
|
-
encodeResult = await
|
|
688
|
-
const { patch, state } = encodeResult
|
|
689
|
-
|
|
699
|
+
logger.debug({ patch: patchCreate }, 'applying app patch');
|
|
700
|
+
await resyncAppState([name], false);
|
|
701
|
+
const { [name]: currentSyncVersion } = await authState.keys.get('app-state-sync-version', [name]);
|
|
702
|
+
initial = currentSyncVersion ? ensureLTHashStateVersion(currentSyncVersion) : newLTHashState();
|
|
703
|
+
encodeResult = await encodeSyncdPatch(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey);
|
|
704
|
+
const { patch, state } = encodeResult;
|
|
690
705
|
const node = {
|
|
691
706
|
tag: 'iq',
|
|
692
707
|
attrs: {
|
|
693
|
-
to:
|
|
708
|
+
to: S_WHATSAPP_NET,
|
|
694
709
|
type: 'set',
|
|
695
710
|
xmlns: 'w:sync:app:state'
|
|
696
711
|
},
|
|
@@ -704,88 +719,94 @@ const makeChatsSocket = (config) => {
|
|
|
704
719
|
attrs: {
|
|
705
720
|
name,
|
|
706
721
|
version: (state.version - 1).toString(),
|
|
707
|
-
|
|
722
|
+
return_snapshot: 'false'
|
|
708
723
|
},
|
|
709
724
|
content: [
|
|
710
725
|
{
|
|
711
726
|
tag: 'patch',
|
|
712
727
|
attrs: {},
|
|
713
|
-
content:
|
|
728
|
+
content: proto.SyncdPatch.encode(patch).finish()
|
|
714
729
|
}
|
|
715
730
|
]
|
|
716
731
|
}
|
|
717
732
|
]
|
|
718
733
|
}
|
|
719
734
|
]
|
|
720
|
-
}
|
|
721
|
-
await query(node)
|
|
722
|
-
await authState.keys.set({ 'app-state-sync-version': { [name]: state } })
|
|
723
|
-
}, authState?.creds?.me?.id || 'app-patch')
|
|
724
|
-
})
|
|
725
|
-
|
|
735
|
+
};
|
|
736
|
+
await query(node);
|
|
737
|
+
await authState.keys.set({ 'app-state-sync-version': { [name]: state } });
|
|
738
|
+
}, authState?.creds?.me?.id || 'app-patch');
|
|
739
|
+
});
|
|
726
740
|
if (config.emitOwnEvents) {
|
|
727
|
-
const { onMutation } = newAppStateChunkHandler(false)
|
|
728
|
-
const { mutationMap } = await
|
|
729
|
-
|
|
741
|
+
const { onMutation } = newAppStateChunkHandler(false);
|
|
742
|
+
const { mutationMap } = await decodePatches(name, [{ ...encodeResult.patch, version: { version: encodeResult.state.version } }], initial, getAppStateSyncKey, config.options, undefined, logger);
|
|
730
743
|
for (const key in mutationMap) {
|
|
731
|
-
onMutation(mutationMap[key])
|
|
744
|
+
onMutation(mutationMap[key]);
|
|
732
745
|
}
|
|
733
746
|
}
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
/** sending non-abt props may fix QR scan fail if server expects */
|
|
747
|
+
};
|
|
748
|
+
/** fetch AB props */
|
|
737
749
|
const fetchProps = async () => {
|
|
738
750
|
const resultNode = await query({
|
|
739
751
|
tag: 'iq',
|
|
740
752
|
attrs: {
|
|
741
|
-
to:
|
|
742
|
-
xmlns: '
|
|
743
|
-
type: 'get'
|
|
753
|
+
to: S_WHATSAPP_NET,
|
|
754
|
+
xmlns: 'abt',
|
|
755
|
+
type: 'get'
|
|
744
756
|
},
|
|
745
757
|
content: [
|
|
746
|
-
{
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
758
|
+
{
|
|
759
|
+
tag: 'props',
|
|
760
|
+
attrs: {
|
|
761
|
+
protocol: '1',
|
|
762
|
+
...(authState?.creds?.lastPropHash ? { hash: authState.creds.lastPropHash } : {})
|
|
763
|
+
}
|
|
764
|
+
}
|
|
750
765
|
]
|
|
751
|
-
})
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
let props = {}
|
|
755
|
-
|
|
766
|
+
});
|
|
767
|
+
const propsNode = getBinaryNodeChild(resultNode, 'props');
|
|
768
|
+
let props = {};
|
|
756
769
|
if (propsNode) {
|
|
757
|
-
if (propsNode.attrs?.hash) {
|
|
758
|
-
|
|
759
|
-
|
|
770
|
+
if (propsNode.attrs?.hash) {
|
|
771
|
+
// on some clients, the hash is returning as undefined
|
|
772
|
+
authState.creds.lastPropHash = propsNode?.attrs?.hash;
|
|
773
|
+
ev.emit('creds.update', authState.creds);
|
|
760
774
|
}
|
|
761
|
-
|
|
762
|
-
props = WABinary_1.reduceBinaryNodeToDictionary(propsNode, 'prop')
|
|
775
|
+
props = reduceBinaryNodeToDictionary(propsNode, 'prop');
|
|
763
776
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
777
|
+
// Extract protocol-relevant AB props (only the ones we need)
|
|
778
|
+
const privacyTokenProp = props['10518'] ?? props['privacy_token_sending_on_all_1_on_1_messages'];
|
|
779
|
+
if (privacyTokenProp !== undefined) {
|
|
780
|
+
serverProps.privacyTokenOn1to1 = privacyTokenProp === 'true' || privacyTokenProp === '1';
|
|
781
|
+
}
|
|
782
|
+
const profilePicProp = props['9666'] ?? props['profile_scraping_privacy_token_in_photo_iq'];
|
|
783
|
+
if (profilePicProp !== undefined) {
|
|
784
|
+
serverProps.profilePicPrivacyToken = profilePicProp === 'true' || profilePicProp === '1';
|
|
785
|
+
}
|
|
786
|
+
const lidIssueProp = props['14303'] ?? props['lid_trusted_token_issue_to_lid'];
|
|
787
|
+
if (lidIssueProp !== undefined) {
|
|
788
|
+
serverProps.lidTrustedTokenIssueToLid = lidIssueProp === 'true' || lidIssueProp === '1';
|
|
789
|
+
}
|
|
790
|
+
logger.debug({ serverProps }, 'fetched props');
|
|
791
|
+
return props;
|
|
792
|
+
};
|
|
768
793
|
/**
|
|
769
794
|
* modify a chat -- mark unread, read etc.
|
|
770
795
|
* lastMessages must be sorted in reverse chronologically
|
|
771
|
-
* requires the last messages till the last message received required for archive & unread
|
|
772
|
-
|
|
796
|
+
* requires the last messages till the last message received; required for archive & unread
|
|
797
|
+
*/
|
|
773
798
|
const chatModify = (mod, jid) => {
|
|
774
|
-
const patch =
|
|
775
|
-
return appPatch(patch)
|
|
776
|
-
}
|
|
777
|
-
|
|
799
|
+
const patch = chatModificationToAppPatch(mod, jid);
|
|
800
|
+
return appPatch(patch);
|
|
801
|
+
};
|
|
778
802
|
/**
|
|
779
803
|
* Enable/Disable link preview privacy, not related to baileys link preview generation
|
|
780
804
|
*/
|
|
781
805
|
const updateDisableLinkPreviewsPrivacy = (isPreviewsDisabled) => {
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
}, '')
|
|
787
|
-
}
|
|
788
|
-
|
|
806
|
+
return chatModify({
|
|
807
|
+
disableLinkPreviews: { isPreviewsDisabled }
|
|
808
|
+
}, '');
|
|
809
|
+
};
|
|
789
810
|
/**
|
|
790
811
|
* Star or Unstar a message
|
|
791
812
|
*/
|
|
@@ -795,27 +816,24 @@ const makeChatsSocket = (config) => {
|
|
|
795
816
|
messages,
|
|
796
817
|
star
|
|
797
818
|
}
|
|
798
|
-
}, jid)
|
|
799
|
-
}
|
|
800
|
-
|
|
819
|
+
}, jid);
|
|
820
|
+
};
|
|
801
821
|
/**
|
|
802
|
-
* Add
|
|
822
|
+
* Add or Edit Contact
|
|
803
823
|
*/
|
|
804
824
|
const addOrEditContact = (jid, contact) => {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
}, jid)
|
|
808
|
-
}
|
|
809
|
-
|
|
825
|
+
return chatModify({
|
|
826
|
+
contact
|
|
827
|
+
}, jid);
|
|
828
|
+
};
|
|
810
829
|
/**
|
|
811
830
|
* Remove Contact
|
|
812
831
|
*/
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
832
|
+
const removeContact = (jid) => {
|
|
833
|
+
return chatModify({
|
|
834
|
+
contact: null
|
|
835
|
+
}, jid);
|
|
836
|
+
};
|
|
819
837
|
/**
|
|
820
838
|
* Adds label
|
|
821
839
|
*/
|
|
@@ -824,9 +842,8 @@ const makeChatsSocket = (config) => {
|
|
|
824
842
|
addLabel: {
|
|
825
843
|
...labels
|
|
826
844
|
}
|
|
827
|
-
}, jid)
|
|
828
|
-
}
|
|
829
|
-
|
|
845
|
+
}, jid);
|
|
846
|
+
};
|
|
830
847
|
/**
|
|
831
848
|
* Adds label for the chats
|
|
832
849
|
*/
|
|
@@ -835,9 +852,8 @@ const makeChatsSocket = (config) => {
|
|
|
835
852
|
addChatLabel: {
|
|
836
853
|
labelId
|
|
837
854
|
}
|
|
838
|
-
}, jid)
|
|
839
|
-
}
|
|
840
|
-
|
|
855
|
+
}, jid);
|
|
856
|
+
};
|
|
841
857
|
/**
|
|
842
858
|
* Removes label for the chat
|
|
843
859
|
*/
|
|
@@ -846,9 +862,8 @@ const makeChatsSocket = (config) => {
|
|
|
846
862
|
removeChatLabel: {
|
|
847
863
|
labelId
|
|
848
864
|
}
|
|
849
|
-
}, jid)
|
|
850
|
-
}
|
|
851
|
-
|
|
865
|
+
}, jid);
|
|
866
|
+
};
|
|
852
867
|
/**
|
|
853
868
|
* Adds label for the message
|
|
854
869
|
*/
|
|
@@ -858,9 +873,8 @@ const makeChatsSocket = (config) => {
|
|
|
858
873
|
messageId,
|
|
859
874
|
labelId
|
|
860
875
|
}
|
|
861
|
-
}, jid)
|
|
862
|
-
}
|
|
863
|
-
|
|
876
|
+
}, jid);
|
|
877
|
+
};
|
|
864
878
|
/**
|
|
865
879
|
* Removes label for the message
|
|
866
880
|
*/
|
|
@@ -870,114 +884,129 @@ const makeChatsSocket = (config) => {
|
|
|
870
884
|
messageId,
|
|
871
885
|
labelId
|
|
872
886
|
}
|
|
873
|
-
}, jid)
|
|
874
|
-
}
|
|
875
|
-
|
|
887
|
+
}, jid);
|
|
888
|
+
};
|
|
876
889
|
/**
|
|
877
|
-
* Removes Chats
|
|
878
|
-
*/
|
|
879
|
-
const clearMessage = (jid, key, timeStamp) => {
|
|
880
|
-
return chatModify({
|
|
881
|
-
delete: true,
|
|
882
|
-
lastMessages: [{
|
|
883
|
-
key: key,
|
|
884
|
-
messageTimestamp: timeStamp
|
|
885
|
-
}],
|
|
886
|
-
}, jid)
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
/**
|
|
890
890
|
* Add or Edit Quick Reply
|
|
891
891
|
*/
|
|
892
892
|
const addOrEditQuickReply = (quickReply) => {
|
|
893
893
|
return chatModify({
|
|
894
894
|
quickReply
|
|
895
|
-
}, '')
|
|
896
|
-
}
|
|
897
|
-
|
|
895
|
+
}, '');
|
|
896
|
+
};
|
|
898
897
|
/**
|
|
899
898
|
* Remove Quick Reply
|
|
900
899
|
*/
|
|
901
900
|
const removeQuickReply = (timestamp) => {
|
|
902
901
|
return chatModify({
|
|
903
902
|
quickReply: { timestamp, deleted: true }
|
|
904
|
-
}, '')
|
|
905
|
-
}
|
|
906
|
-
|
|
903
|
+
}, '');
|
|
904
|
+
};
|
|
907
905
|
/**
|
|
908
906
|
* queries need to be fired on connection open
|
|
909
907
|
* help ensure parity with WA Web
|
|
910
908
|
* */
|
|
911
909
|
const executeInitQueries = async () => {
|
|
912
|
-
await Promise.all([
|
|
913
|
-
|
|
914
|
-
fetchBlocklist(),
|
|
915
|
-
fetchPrivacySettings(),
|
|
916
|
-
])
|
|
917
|
-
}
|
|
918
|
-
|
|
910
|
+
await Promise.all([fetchProps(), fetchBlocklist(), fetchPrivacySettings()]);
|
|
911
|
+
};
|
|
919
912
|
const upsertMessage = ev.createBufferedFunction(async (msg, type) => {
|
|
920
|
-
ev.emit('messages.upsert', { messages: [msg], type })
|
|
913
|
+
ev.emit('messages.upsert', { messages: [msg], type });
|
|
921
914
|
if (!!msg.pushName) {
|
|
922
|
-
let jid = msg.key.fromMe ? authState.creds.me.id :
|
|
923
|
-
jid =
|
|
924
|
-
|
|
915
|
+
let jid = msg.key.fromMe ? authState.creds.me.id : msg.key.participant || msg.key.remoteJid;
|
|
916
|
+
jid = jidNormalizedUser(jid);
|
|
925
917
|
if (!msg.key.fromMe) {
|
|
926
|
-
ev.emit('contacts.update', [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName }])
|
|
918
|
+
ev.emit('contacts.update', [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName }]);
|
|
927
919
|
}
|
|
928
|
-
|
|
929
920
|
// update our pushname too
|
|
930
921
|
if (msg.key.fromMe && msg.pushName && authState.creds.me?.name !== msg.pushName) {
|
|
931
|
-
ev.emit('creds.update', { me: { ...authState.creds.me, name: msg.pushName } })
|
|
922
|
+
ev.emit('creds.update', { me: { ...authState.creds.me, name: msg.pushName } });
|
|
932
923
|
}
|
|
933
924
|
}
|
|
934
|
-
|
|
935
|
-
const historyMsg = Utils_1.getHistoryMsg(msg.message)
|
|
925
|
+
const historyMsg = getHistoryMsg(msg.message);
|
|
936
926
|
const shouldProcessHistoryMsg = historyMsg
|
|
937
|
-
?
|
|
938
|
-
|
|
939
|
-
: false
|
|
940
|
-
|
|
941
|
-
|
|
927
|
+
? shouldSyncHistoryMessage(historyMsg) &&
|
|
928
|
+
PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType)
|
|
929
|
+
: false;
|
|
930
|
+
if (historyMsg && shouldProcessHistoryMsg) {
|
|
931
|
+
const syncType = historyMsg.syncType;
|
|
932
|
+
// INITIAL_BOOTSTRAP — fire immediately, no progress check (same as WA Web K function)
|
|
933
|
+
if (syncType === proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP &&
|
|
934
|
+
!historySyncStatus.initialBootstrapComplete) {
|
|
935
|
+
historySyncStatus.initialBootstrapComplete = true;
|
|
936
|
+
ev.emit('messaging-history.status', {
|
|
937
|
+
syncType,
|
|
938
|
+
status: 'complete',
|
|
939
|
+
explicit: true
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
// RECENT with progress === 100 — explicit completion
|
|
943
|
+
if (syncType === proto.HistorySync.HistorySyncType.RECENT &&
|
|
944
|
+
historyMsg.progress === 100 &&
|
|
945
|
+
!historySyncStatus.recentSyncComplete) {
|
|
946
|
+
historySyncStatus.recentSyncComplete = true;
|
|
947
|
+
clearTimeout(historySyncPausedTimeout);
|
|
948
|
+
historySyncPausedTimeout = undefined;
|
|
949
|
+
ev.emit('messaging-history.status', {
|
|
950
|
+
syncType,
|
|
951
|
+
status: 'complete',
|
|
952
|
+
explicit: true
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
// Reset 120s paused timeout on any RECENT chunk (like WA Web's handleChunkProgress)
|
|
956
|
+
if (syncType === proto.HistorySync.HistorySyncType.RECENT && !historySyncStatus.recentSyncComplete) {
|
|
957
|
+
clearTimeout(historySyncPausedTimeout);
|
|
958
|
+
historySyncPausedTimeout = setTimeout(() => {
|
|
959
|
+
if (!historySyncStatus.recentSyncComplete) {
|
|
960
|
+
historySyncStatus.recentSyncComplete = true;
|
|
961
|
+
ev.emit('messaging-history.status', {
|
|
962
|
+
syncType: proto.HistorySync.HistorySyncType.RECENT,
|
|
963
|
+
status: 'paused',
|
|
964
|
+
explicit: false
|
|
965
|
+
});
|
|
966
|
+
}
|
|
967
|
+
historySyncPausedTimeout = undefined;
|
|
968
|
+
}, HISTORY_SYNC_PAUSED_TIMEOUT_MS);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
// State machine: decide on sync and flush
|
|
972
|
+
if (historyMsg && syncState === SyncState.AwaitingInitialSync) {
|
|
942
973
|
if (awaitingSyncTimeout) {
|
|
943
|
-
|
|
944
|
-
|
|
974
|
+
clearTimeout(awaitingSyncTimeout);
|
|
975
|
+
awaitingSyncTimeout = undefined;
|
|
945
976
|
}
|
|
946
|
-
|
|
947
977
|
if (shouldProcessHistoryMsg) {
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
978
|
+
syncState = SyncState.Syncing;
|
|
979
|
+
logger.info('Transitioned to Syncing state');
|
|
980
|
+
// Let doAppStateSync handle the final flush after it's done
|
|
981
|
+
}
|
|
982
|
+
else {
|
|
983
|
+
syncState = SyncState.Online;
|
|
984
|
+
logger.info('History sync skipped, transitioning to Online state and flushing buffer');
|
|
985
|
+
ev.flush();
|
|
955
986
|
}
|
|
956
987
|
}
|
|
957
|
-
|
|
958
988
|
const doAppStateSync = async () => {
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
}
|
|
972
|
-
|
|
989
|
+
if (syncState === SyncState.Syncing) {
|
|
990
|
+
// All collections will be synced, so clear any blocked ones
|
|
991
|
+
blockedCollections.clear();
|
|
992
|
+
logger.info('Doing app state sync');
|
|
993
|
+
await resyncAppState(ALL_WA_PATCH_NAMES, true);
|
|
994
|
+
// Sync is complete, go online and flush everything
|
|
995
|
+
syncState = SyncState.Online;
|
|
996
|
+
logger.info('App state sync complete, transitioning to Online state and flushing buffer');
|
|
997
|
+
ev.flush();
|
|
998
|
+
const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1;
|
|
999
|
+
ev.emit('creds.update', { accountSyncCounter });
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
973
1002
|
await Promise.all([
|
|
974
1003
|
(async () => {
|
|
975
1004
|
if (shouldProcessHistoryMsg) {
|
|
976
|
-
await doAppStateSync()
|
|
1005
|
+
await doAppStateSync();
|
|
977
1006
|
}
|
|
978
1007
|
})(),
|
|
979
|
-
|
|
980
|
-
|
|
1008
|
+
processMessage(msg, {
|
|
1009
|
+
signalRepository,
|
|
981
1010
|
shouldProcessHistoryMsg,
|
|
982
1011
|
placeholderResendCache,
|
|
983
1012
|
ev,
|
|
@@ -985,101 +1014,147 @@ const makeChatsSocket = (config) => {
|
|
|
985
1014
|
keyStore: authState.keys,
|
|
986
1015
|
logger,
|
|
987
1016
|
options: config.options,
|
|
988
|
-
getMessage
|
|
1017
|
+
getMessage
|
|
989
1018
|
})
|
|
990
|
-
])
|
|
991
|
-
|
|
992
|
-
if (msg.message?.protocolMessage?.appStateSyncKeyShare && syncState ===
|
|
993
|
-
|
|
994
|
-
|
|
1019
|
+
]);
|
|
1020
|
+
// If the app state key arrives and we are waiting to sync, trigger the sync now.
|
|
1021
|
+
if (msg.message?.protocolMessage?.appStateSyncKeyShare && syncState === SyncState.Syncing) {
|
|
1022
|
+
logger.info('App state sync key arrived, triggering app state sync');
|
|
1023
|
+
await doAppStateSync();
|
|
995
1024
|
}
|
|
996
|
-
})
|
|
997
|
-
|
|
998
|
-
ws.on('CB:
|
|
999
|
-
ws.on('CB:chatstate', handlePresenceUpdate)
|
|
1025
|
+
});
|
|
1026
|
+
ws.on('CB:presence', handlePresenceUpdate);
|
|
1027
|
+
ws.on('CB:chatstate', handlePresenceUpdate);
|
|
1000
1028
|
ws.on('CB:ib,,dirty', async (node) => {
|
|
1001
|
-
const { attrs } =
|
|
1002
|
-
const type = attrs.type
|
|
1003
|
-
|
|
1029
|
+
const { attrs } = getBinaryNodeChild(node, 'dirty');
|
|
1030
|
+
const type = attrs.type;
|
|
1004
1031
|
switch (type) {
|
|
1005
1032
|
case 'account_sync':
|
|
1006
1033
|
if (attrs.timestamp) {
|
|
1007
|
-
let { lastAccountSyncTimestamp } = authState.creds
|
|
1034
|
+
let { lastAccountSyncTimestamp } = authState.creds;
|
|
1008
1035
|
if (lastAccountSyncTimestamp) {
|
|
1009
|
-
await cleanDirtyBits('account_sync', lastAccountSyncTimestamp)
|
|
1036
|
+
await cleanDirtyBits('account_sync', lastAccountSyncTimestamp);
|
|
1010
1037
|
}
|
|
1011
|
-
lastAccountSyncTimestamp = +attrs.timestamp
|
|
1012
|
-
ev.emit('creds.update', { lastAccountSyncTimestamp })
|
|
1038
|
+
lastAccountSyncTimestamp = +attrs.timestamp;
|
|
1039
|
+
ev.emit('creds.update', { lastAccountSyncTimestamp });
|
|
1013
1040
|
}
|
|
1014
|
-
break
|
|
1041
|
+
break;
|
|
1015
1042
|
case 'groups':
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
break
|
|
1043
|
+
// handled in groups.ts
|
|
1044
|
+
break;
|
|
1019
1045
|
default:
|
|
1020
|
-
logger.info({ node }, 'received unknown sync')
|
|
1021
|
-
break
|
|
1046
|
+
logger.info({ node }, 'received unknown sync');
|
|
1047
|
+
break;
|
|
1022
1048
|
}
|
|
1023
|
-
})
|
|
1024
|
-
|
|
1049
|
+
});
|
|
1025
1050
|
ev.on('connection.update', ({ connection, receivedPendingNotifications }) => {
|
|
1051
|
+
if (connection === 'close') {
|
|
1052
|
+
blockedCollections.clear();
|
|
1053
|
+
clearTimeout(historySyncPausedTimeout);
|
|
1054
|
+
historySyncPausedTimeout = undefined;
|
|
1055
|
+
}
|
|
1026
1056
|
if (connection === 'open') {
|
|
1027
1057
|
if (fireInitQueries) {
|
|
1028
|
-
executeInitQueries()
|
|
1029
|
-
.catch(error => onUnexpectedError(error, 'init queries'))
|
|
1058
|
+
executeInitQueries().catch(error => onUnexpectedError(error, 'init queries'));
|
|
1030
1059
|
}
|
|
1031
|
-
sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable')
|
|
1032
|
-
.catch(error => onUnexpectedError(error, 'presence update requests'))
|
|
1060
|
+
sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable').catch(error => onUnexpectedError(error, 'presence update requests'));
|
|
1033
1061
|
}
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
return
|
|
1062
|
+
if (!receivedPendingNotifications || syncState !== SyncState.Connecting) {
|
|
1063
|
+
return;
|
|
1037
1064
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1065
|
+
historySyncStatus.initialBootstrapComplete = false;
|
|
1066
|
+
historySyncStatus.recentSyncComplete = false;
|
|
1067
|
+
clearTimeout(historySyncPausedTimeout);
|
|
1068
|
+
historySyncPausedTimeout = undefined;
|
|
1069
|
+
syncState = SyncState.AwaitingInitialSync;
|
|
1070
|
+
logger.info('Connection is now AwaitingInitialSync, buffering events');
|
|
1071
|
+
ev.buffer();
|
|
1072
|
+
const willSyncHistory = shouldSyncHistoryMessage(proto.Message.HistorySyncNotification.create({
|
|
1073
|
+
syncType: proto.HistorySync.HistorySyncType.RECENT
|
|
1074
|
+
}));
|
|
1047
1075
|
if (!willSyncHistory) {
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1076
|
+
logger.info('History sync is disabled by config, not waiting for notification. Transitioning to Online.');
|
|
1077
|
+
syncState = SyncState.Online;
|
|
1078
|
+
setTimeout(() => ev.flush(), 0);
|
|
1079
|
+
return;
|
|
1052
1080
|
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1081
|
+
// On reconnection (accountSyncCounter > 0), the server does not push
|
|
1082
|
+
// history sync notifications — the device already has its data.
|
|
1083
|
+
// Skip the 20s wait and go online immediately.
|
|
1084
|
+
if (authState.creds.accountSyncCounter > 0) {
|
|
1085
|
+
logger.info('Reconnection with existing sync data, skipping history sync wait. Transitioning to Online.');
|
|
1086
|
+
syncState = SyncState.Online;
|
|
1087
|
+
setTimeout(() => ev.flush(), 0);
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
logger.info('First connection, awaiting history sync notification with a 20s timeout.');
|
|
1056
1091
|
if (awaitingSyncTimeout) {
|
|
1057
|
-
|
|
1092
|
+
clearTimeout(awaitingSyncTimeout);
|
|
1058
1093
|
}
|
|
1059
|
-
|
|
1060
1094
|
awaitingSyncTimeout = setTimeout(() => {
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1095
|
+
if (syncState === SyncState.AwaitingInitialSync) {
|
|
1096
|
+
logger.warn('Timeout in AwaitingInitialSync, forcing state to Online and flushing buffer');
|
|
1097
|
+
syncState = SyncState.Online;
|
|
1098
|
+
ev.flush();
|
|
1099
|
+
// Increment so subsequent reconnections skip the 20s wait.
|
|
1100
|
+
// Late-arriving history is still processed via processMessage
|
|
1101
|
+
// regardless of the state machine phase.
|
|
1102
|
+
const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1;
|
|
1103
|
+
ev.emit('creds.update', { accountSyncCounter });
|
|
1104
|
+
}
|
|
1105
|
+
}, 20000);
|
|
1106
|
+
});
|
|
1107
|
+
// When an app state sync key arrives (myAppStateKeyId is set) and there are
|
|
1108
|
+
// collections blocked on a missing key, trigger a re-sync for just those collections.
|
|
1109
|
+
// This mirrors WA Web's Blocked → retry-on-key-arrival behavior.
|
|
1110
|
+
ev.on('creds.update', ({ myAppStateKeyId }) => {
|
|
1111
|
+
if (!myAppStateKeyId || blockedCollections.size === 0) {
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
// If we're in the middle of a full sync, doAppStateSync handles all collections
|
|
1115
|
+
if (syncState === SyncState.Syncing) {
|
|
1116
|
+
blockedCollections.clear();
|
|
1117
|
+
return;
|
|
1118
|
+
}
|
|
1119
|
+
const collections = [...blockedCollections];
|
|
1120
|
+
blockedCollections.clear();
|
|
1121
|
+
logger.info({ collections }, 'app state sync key arrived, re-syncing blocked collections');
|
|
1122
|
+
resyncAppState(collections, false).catch(error => onUnexpectedError(error, 'blocked collections resync'));
|
|
1123
|
+
});
|
|
1124
|
+
ev.on('lid-mapping.update', async ({ lid, pn }) => {
|
|
1125
|
+
try {
|
|
1126
|
+
await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }]);
|
|
1127
|
+
}
|
|
1128
|
+
catch (error) {
|
|
1129
|
+
logger.warn({ lid, pn, error }, 'Failed to store LID-PN mapping');
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
registerSocketEndHandler(() => {
|
|
1133
|
+
if (awaitingSyncTimeout) {
|
|
1134
|
+
clearTimeout(awaitingSyncTimeout);
|
|
1135
|
+
awaitingSyncTimeout = undefined;
|
|
1136
|
+
}
|
|
1137
|
+
if (!config.placeholderResendCache && placeholderResendCache.close) {
|
|
1138
|
+
placeholderResendCache.close();
|
|
1139
|
+
}
|
|
1140
|
+
syncState = SyncState.Connecting;
|
|
1141
|
+
privacySettings = undefined;
|
|
1142
|
+
});
|
|
1069
1143
|
return {
|
|
1070
|
-
...sock,
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1144
|
+
...sock,
|
|
1145
|
+
serverProps,
|
|
1146
|
+
createCallLink,
|
|
1147
|
+
getBotListV2,
|
|
1148
|
+
messageMutex,
|
|
1149
|
+
receiptMutex,
|
|
1150
|
+
appStatePatchMutex,
|
|
1151
|
+
notificationMutex,
|
|
1075
1152
|
fetchPrivacySettings,
|
|
1076
1153
|
upsertMessage,
|
|
1077
1154
|
appPatch,
|
|
1078
|
-
createCallLink,
|
|
1079
1155
|
sendPresenceUpdate,
|
|
1080
|
-
presenceSubscribe,
|
|
1081
|
-
|
|
1082
|
-
getLidUser,
|
|
1156
|
+
presenceSubscribe,
|
|
1157
|
+
profilePictureUrl,
|
|
1083
1158
|
fetchBlocklist,
|
|
1084
1159
|
fetchStatus,
|
|
1085
1160
|
fetchDisappearingDuration,
|
|
@@ -1088,8 +1163,9 @@ const makeChatsSocket = (config) => {
|
|
|
1088
1163
|
updateProfileStatus,
|
|
1089
1164
|
updateProfileName,
|
|
1090
1165
|
updateBlockStatus,
|
|
1166
|
+
updateDisableLinkPreviewsPrivacy,
|
|
1091
1167
|
updateCallPrivacy,
|
|
1092
|
-
updateMessagesPrivacy,
|
|
1168
|
+
updateMessagesPrivacy,
|
|
1093
1169
|
updateLastSeenPrivacy,
|
|
1094
1170
|
updateOnlinePrivacy,
|
|
1095
1171
|
updateProfilePicturePrivacy,
|
|
@@ -1097,22 +1173,21 @@ const makeChatsSocket = (config) => {
|
|
|
1097
1173
|
updateReadReceiptsPrivacy,
|
|
1098
1174
|
updateGroupsAddPrivacy,
|
|
1099
1175
|
updateDefaultDisappearingMode,
|
|
1100
|
-
updateDisableLinkPreviewsPrivacy,
|
|
1101
1176
|
getBusinessProfile,
|
|
1102
1177
|
resyncAppState,
|
|
1103
1178
|
chatModify,
|
|
1104
1179
|
cleanDirtyBits,
|
|
1180
|
+
addOrEditContact,
|
|
1181
|
+
removeContact,
|
|
1182
|
+
placeholderResendCache,
|
|
1105
1183
|
addLabel,
|
|
1106
1184
|
addChatLabel,
|
|
1107
1185
|
removeChatLabel,
|
|
1108
1186
|
addMessageLabel,
|
|
1109
1187
|
removeMessageLabel,
|
|
1110
|
-
|
|
1188
|
+
star,
|
|
1111
1189
|
addOrEditQuickReply,
|
|
1112
1190
|
removeQuickReply
|
|
1113
|
-
}
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
module.exports = {
|
|
1117
|
-
makeChatsSocket
|
|
1118
|
-
}
|
|
1191
|
+
};
|
|
1192
|
+
};
|
|
1193
|
+
//# sourceMappingURL=chats.js.map
|