@queenanya/baileys 8.6.0-beta → 9.0.3
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/WAProto/GenerateStatics.sh +3 -0
- package/WAProto/WAProto.proto +4633 -0
- package/WAProto/fix-imports.js +29 -0
- package/WAProto/index.d.ts +2165 -45253
- package/WAProto/index.js +45236 -130529
- package/lib/Defaults/index.d.ts +14 -3
- package/lib/Defaults/index.d.ts.map +1 -0
- package/lib/Defaults/index.js +64 -55
- package/lib/Defaults/index.js.map +1 -0
- package/lib/Signal/Group/ciphertext-message.d.ts +1 -0
- package/lib/Signal/Group/ciphertext-message.d.ts.map +1 -0
- package/lib/Signal/Group/ciphertext-message.js +2 -5
- package/lib/Signal/Group/ciphertext-message.js.map +1 -0
- package/lib/Signal/Group/group-session-builder.d.ts +4 -3
- package/lib/Signal/Group/group-session-builder.d.ts.map +1 -0
- package/lib/Signal/Group/group-session-builder.js +7 -41
- package/lib/Signal/Group/group-session-builder.js.map +1 -0
- package/lib/Signal/Group/group_cipher.d.ts +4 -4
- package/lib/Signal/Group/group_cipher.d.ts.map +1 -0
- package/lib/Signal/Group/group_cipher.js +37 -51
- 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 -57
- package/lib/Signal/Group/index.js.map +1 -0
- package/lib/Signal/Group/keyhelper.d.ts +2 -1
- package/lib/Signal/Group/keyhelper.d.ts.map +1 -0
- package/lib/Signal/Group/keyhelper.js +7 -44
- package/lib/Signal/Group/keyhelper.js.map +1 -0
- package/lib/Signal/Group/sender-chain-key.d.ts +3 -2
- package/lib/Signal/Group/sender-chain-key.d.ts.map +1 -0
- package/lib/Signal/Group/sender-chain-key.js +7 -15
- package/lib/Signal/Group/sender-chain-key.js.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +2 -1
- package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +8 -11
- package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-message.d.ts +2 -1
- package/lib/Signal/Group/sender-key-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-message.js +9 -12
- package/lib/Signal/Group/sender-key-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-name.d.ts +1 -0
- package/lib/Signal/Group/sender-key-name.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-name.js +2 -5
- package/lib/Signal/Group/sender-key-name.js.map +1 -0
- package/lib/Signal/Group/sender-key-record.d.ts +3 -2
- package/lib/Signal/Group/sender-key-record.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-record.js +9 -21
- package/lib/Signal/Group/sender-key-record.js.map +1 -0
- package/lib/Signal/Group/sender-key-state.d.ts +7 -6
- package/lib/Signal/Group/sender-key-state.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-state.js +27 -42
- package/lib/Signal/Group/sender-key-state.js.map +1 -0
- package/lib/Signal/Group/sender-message-key.d.ts +1 -0
- package/lib/Signal/Group/sender-message-key.d.ts.map +1 -0
- package/lib/Signal/Group/sender-message-key.js +4 -7
- package/lib/Signal/Group/sender-message-key.js.map +1 -0
- package/lib/Signal/libsignal.d.ts +5 -3
- package/lib/Signal/libsignal.d.ts.map +1 -0
- package/lib/Signal/libsignal.js +258 -90
- package/lib/Signal/libsignal.js.map +1 -0
- package/lib/Signal/lid-mapping.d.ts +23 -0
- package/lib/Signal/lid-mapping.d.ts.map +1 -0
- package/lib/Signal/lid-mapping.js +171 -0
- 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 -18
- package/lib/Socket/Client/index.js.map +1 -0
- package/lib/Socket/Client/types.d.ts +2 -2
- package/lib/Socket/Client/types.d.ts.map +1 -0
- package/lib/Socket/Client/types.js +4 -6
- package/lib/Socket/Client/types.js.map +1 -0
- package/lib/Socket/Client/websocket.d.ts +2 -2
- package/lib/Socket/Client/websocket.d.ts.map +1 -0
- package/lib/Socket/Client/websocket.js +15 -37
- package/lib/Socket/Client/websocket.js.map +1 -0
- package/lib/Socket/business.d.ts +106 -94
- package/lib/Socket/business.d.ts.map +1 -0
- package/lib/Socket/business.js +159 -43
- package/lib/Socket/business.js.map +1 -0
- package/lib/Socket/chats.d.ts +39 -27
- package/lib/Socket/chats.d.ts.map +1 -0
- package/lib/Socket/chats.js +271 -261
- package/lib/Socket/chats.js.map +1 -0
- package/lib/Socket/communities.d.ts +111 -86
- package/lib/Socket/communities.d.ts.map +1 -0
- package/lib/Socket/communities.js +138 -70
- package/lib/Socket/communities.js.map +1 -0
- package/lib/Socket/groups.d.ts +53 -43
- package/lib/Socket/groups.d.ts.map +1 -0
- package/lib/Socket/groups.js +94 -99
- package/lib/Socket/groups.js.map +1 -0
- package/lib/Socket/index.d.ts +133 -108
- package/lib/Socket/index.d.ts.map +1 -0
- package/lib/Socket/index.js +17 -9
- package/lib/Socket/index.js.map +1 -0
- package/lib/Socket/messages-recv.d.ts +90 -82
- package/lib/Socket/messages-recv.d.ts.map +1 -0
- package/lib/Socket/messages-recv.js +635 -480
- package/lib/Socket/messages-recv.js.map +1 -0
- package/lib/Socket/messages-send.d.ts +90 -76
- package/lib/Socket/messages-send.d.ts.map +1 -0
- package/lib/Socket/messages-send.js +476 -402
- 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 +83 -73
- package/lib/Socket/newsletter.d.ts.map +1 -0
- package/lib/Socket/newsletter.js +181 -202
- package/lib/Socket/newsletter.js.map +1 -0
- package/lib/Socket/socket.d.ts +24 -16
- package/lib/Socket/socket.d.ts.map +1 -0
- package/lib/Socket/socket.js +402 -196
- package/lib/Socket/socket.js.map +1 -0
- package/lib/Types/Auth.d.ts +13 -5
- package/lib/Types/Auth.d.ts.map +1 -0
- package/lib/Types/Auth.js +2 -2
- 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 -0
- package/lib/Types/Bussines.js.map +1 -0
- package/lib/Types/Call.d.ts +1 -0
- package/lib/Types/Call.d.ts.map +1 -0
- package/lib/Types/Call.js +2 -2
- package/lib/Types/Call.js.map +1 -0
- package/lib/Types/Chat.d.ts +18 -9
- package/lib/Types/Chat.d.ts.map +1 -0
- package/lib/Types/Chat.js +8 -4
- package/lib/Types/Chat.js.map +1 -0
- package/lib/Types/Contact.d.ts +5 -4
- package/lib/Types/Contact.d.ts.map +1 -0
- package/lib/Types/Contact.js +2 -2
- package/lib/Types/Contact.js.map +1 -0
- package/lib/Types/Events.d.ts +36 -33
- package/lib/Types/Events.d.ts.map +1 -0
- package/lib/Types/Events.js +2 -2
- package/lib/Types/Events.js.map +1 -0
- package/lib/Types/GroupMetadata.d.ts +12 -11
- package/lib/Types/GroupMetadata.d.ts.map +1 -0
- package/lib/Types/GroupMetadata.js +2 -2
- package/lib/Types/GroupMetadata.js.map +1 -0
- package/lib/Types/Label.d.ts +12 -0
- package/lib/Types/Label.d.ts.map +1 -0
- package/lib/Types/Label.js +3 -5
- package/lib/Types/Label.js.map +1 -0
- package/lib/Types/LabelAssociation.d.ts +1 -0
- package/lib/Types/LabelAssociation.d.ts.map +1 -0
- package/lib/Types/LabelAssociation.js +3 -5
- package/lib/Types/LabelAssociation.js.map +1 -0
- package/lib/Types/Message.d.ts +51 -148
- package/lib/Types/Message.d.ts.map +1 -0
- package/lib/Types/Message.js +11 -7
- package/lib/Types/Message.js.map +1 -0
- package/lib/Types/Newsletter.d.ts +173 -71
- package/lib/Types/Newsletter.d.ts.map +1 -0
- package/lib/Types/Newsletter.js +54 -11
- package/lib/Types/Newsletter.js.map +1 -0
- package/lib/Types/Product.d.ts +2 -1
- package/lib/Types/Product.d.ts.map +1 -0
- package/lib/Types/Product.js +2 -2
- package/lib/Types/Product.js.map +1 -0
- package/lib/Types/Signal.d.ts +20 -1
- package/lib/Types/Signal.d.ts.map +1 -0
- package/lib/Types/Signal.js +2 -2
- package/lib/Types/Signal.js.map +1 -0
- package/lib/Types/Socket.d.ts +34 -20
- package/lib/Types/Socket.d.ts.map +1 -0
- package/lib/Types/Socket.js +3 -2
- package/lib/Types/Socket.js.map +1 -0
- package/lib/Types/State.d.ts +14 -2
- package/lib/Types/State.d.ts.map +1 -0
- package/lib/Types/State.js +13 -2
- package/lib/Types/State.js.map +1 -0
- package/lib/Types/USync.d.ts +3 -2
- package/lib/Types/USync.d.ts.map +1 -0
- package/lib/Types/USync.js +2 -2
- package/lib/Types/USync.js.map +1 -0
- package/lib/Types/index.d.ts +15 -14
- package/lib/Types/index.d.ts.map +1 -0
- package/lib/Types/index.js +15 -31
- package/lib/Types/index.js.map +1 -0
- package/lib/Utils/auth-utils.d.ts +5 -4
- package/lib/Utils/auth-utils.d.ts.map +1 -0
- package/lib/Utils/auth-utils.js +199 -141
- package/lib/Utils/auth-utils.js.map +1 -0
- package/lib/Utils/baileys-event-stream.d.ts +2 -1
- package/lib/Utils/baileys-event-stream.d.ts.map +1 -0
- package/lib/Utils/baileys-event-stream.js +15 -22
- package/lib/Utils/baileys-event-stream.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 +3 -2
- package/lib/Utils/business.d.ts.map +1 -0
- package/lib/Utils/business.js +66 -69
- package/lib/Utils/business.js.map +1 -0
- package/lib/Utils/chat-utils.d.ts +11 -11
- package/lib/Utils/chat-utils.d.ts.map +1 -0
- package/lib/Utils/chat-utils.js +203 -194
- package/lib/Utils/chat-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +8 -7
- package/lib/Utils/crypto.d.ts.map +1 -0
- package/lib/Utils/crypto.js +50 -101
- package/lib/Utils/crypto.js.map +1 -0
- package/lib/Utils/decode-wa-message.d.ts +18 -5
- package/lib/Utils/decode-wa-message.d.ts.map +1 -0
- package/lib/Utils/decode-wa-message.js +134 -62
- package/lib/Utils/decode-wa-message.js.map +1 -0
- package/lib/Utils/event-buffer.d.ts +6 -7
- package/lib/Utils/event-buffer.d.ts.map +1 -0
- package/lib/Utils/event-buffer.js +99 -69
- package/lib/Utils/event-buffer.js.map +1 -0
- package/lib/Utils/generics.d.ts +57 -68
- package/lib/Utils/generics.d.ts.map +1 -0
- package/lib/Utils/generics.js +179 -356
- package/lib/Utils/generics.js.map +1 -0
- package/lib/Utils/history.d.ts +10 -10
- package/lib/Utils/history.d.ts.map +1 -0
- package/lib/Utils/history.js +37 -50
- package/lib/Utils/history.js.map +1 -0
- package/lib/Utils/index.d.ts +21 -17
- package/lib/Utils/index.d.ts.map +1 -0
- package/lib/Utils/index.js +21 -33
- package/lib/Utils/index.js.map +1 -0
- package/lib/Utils/link-preview.d.ts +4 -4
- package/lib/Utils/link-preview.d.ts.map +1 -0
- package/lib/Utils/link-preview.js +15 -56
- package/lib/Utils/link-preview.js.map +1 -0
- package/lib/Utils/logger.d.ts +8 -6
- 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 +9 -8
- package/lib/Utils/lt-hash.d.ts.map +1 -0
- package/lib/Utils/lt-hash.js +23 -26
- package/lib/Utils/lt-hash.js.map +1 -0
- package/lib/Utils/make-mutex.d.ts +1 -0
- package/lib/Utils/make-mutex.d.ts.map +1 -0
- package/lib/Utils/make-mutex.js +7 -10
- package/lib/Utils/make-mutex.js.map +1 -0
- package/lib/Utils/message-retry-manager.d.ts +82 -0
- package/lib/Utils/message-retry-manager.d.ts.map +1 -0
- package/lib/Utils/message-retry-manager.js +149 -0
- package/lib/Utils/message-retry-manager.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +32 -38
- package/lib/Utils/messages-media.d.ts.map +1 -0
- package/lib/Utils/messages-media.js +283 -496
- package/lib/Utils/messages-media.js.map +1 -0
- package/lib/Utils/messages.d.ts +11 -10
- package/lib/Utils/messages.d.ts.map +1 -0
- package/lib/Utils/messages.js +309 -519
- package/lib/Utils/messages.js.map +1 -0
- package/lib/Utils/noise-handler.d.ts +5 -4
- package/lib/Utils/noise-handler.d.ts.map +1 -0
- package/lib/Utils/noise-handler.js +23 -26
- package/lib/Utils/noise-handler.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 +12 -12
- package/lib/Utils/process-message.d.ts.map +1 -0
- package/lib/Utils/process-message.js +196 -155
- package/lib/Utils/process-message.js.map +1 -0
- package/lib/Utils/signal.d.ts +7 -6
- package/lib/Utils/signal.d.ts.map +1 -0
- package/lib/Utils/signal.js +70 -64
- package/lib/Utils/signal.js.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts +2 -1
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +23 -27
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -0
- package/lib/Utils/use-single-file-auth-state.d.ts +3 -2
- package/lib/Utils/use-single-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-single-file-auth-state.js +63 -41
- package/lib/Utils/use-single-file-auth-state.js.map +1 -0
- package/lib/Utils/validate-connection.d.ts +4 -3
- package/lib/Utils/validate-connection.d.ts.map +1 -0
- package/lib/Utils/validate-connection.js +99 -77
- package/lib/Utils/validate-connection.js.map +1 -0
- package/lib/WABinary/constants.d.ts +1 -0
- package/lib/WABinary/constants.d.ts.map +1 -0
- package/lib/WABinary/constants.js +9 -11
- package/lib/WABinary/constants.js.map +1 -0
- package/lib/WABinary/decode.d.ts +2 -1
- package/lib/WABinary/decode.d.ts.map +1 -0
- package/lib/WABinary/decode.js +25 -52
- package/lib/WABinary/decode.js.map +1 -0
- package/lib/WABinary/encode.d.ts +2 -1
- package/lib/WABinary/encode.d.ts.map +1 -0
- package/lib/WABinary/encode.js +14 -48
- package/lib/WABinary/encode.js.map +1 -0
- package/lib/WABinary/generic-utils.d.ts +4 -3
- package/lib/WABinary/generic-utils.d.ts.map +1 -0
- package/lib/WABinary/generic-utils.js +31 -39
- 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 -21
- package/lib/WABinary/index.js.map +1 -0
- package/lib/WABinary/jid-utils.d.ts +23 -10
- package/lib/WABinary/jid-utils.d.ts.map +1 -0
- package/lib/WABinary/jid-utils.js +75 -60
- package/lib/WABinary/jid-utils.js.map +1 -0
- package/lib/WABinary/types.d.ts +2 -1
- package/lib/WABinary/types.d.ts.map +1 -0
- package/lib/WABinary/types.js +2 -2
- package/lib/WABinary/types.js.map +1 -0
- package/lib/WAM/BinaryInfo.d.ts +2 -1
- package/lib/WAM/BinaryInfo.d.ts.map +1 -0
- package/lib/WAM/BinaryInfo.js +2 -5
- package/lib/WAM/BinaryInfo.js.map +1 -0
- package/lib/WAM/constants.d.ts +5 -3
- package/lib/WAM/constants.d.ts.map +1 -0
- package/lib/WAM/constants.js +19071 -11568
- package/lib/WAM/constants.js.map +1 -0
- package/lib/WAM/encode.d.ts +2 -1
- package/lib/WAM/encode.d.ts.map +1 -0
- package/lib/WAM/encode.js +17 -22
- 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 -19
- package/lib/WAM/index.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +4 -3
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +8 -11
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +3 -2
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +11 -14
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +3 -2
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +8 -11
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +3 -2
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +9 -13
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +4 -3
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +20 -22
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +5 -3
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +13 -8
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/index.d.ts +5 -4
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/index.js +5 -20
- package/lib/WAUSync/Protocols/index.js.map +1 -0
- package/lib/WAUSync/USyncQuery.d.ts +5 -4
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
- package/lib/WAUSync/USyncQuery.js +40 -35
- package/lib/WAUSync/USyncQuery.js.map +1 -0
- package/lib/WAUSync/USyncUser.d.ts +6 -5
- package/lib/WAUSync/USyncUser.d.ts.map +1 -0
- package/lib/WAUSync/USyncUser.js +2 -5
- 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 -19
- package/lib/WAUSync/index.js.map +1 -0
- package/lib/index.d.ts +10 -12
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -34
- package/lib/index.js.map +1 -0
- package/package.json +55 -65
- package/CHANGELOG.md +0 -4
- package/README-anya.md +0 -459
- package/README-shizo.md +0 -445
- package/README-whiskey.md +0 -44
- package/lib/Defaults/baileys-version.json +0 -3
- package/lib/Signal/Group/queue-job.d.ts +0 -1
- package/lib/Signal/Group/queue-job.js +0 -57
- package/lib/Socket/usync.d.ts +0 -36
- package/lib/Socket/usync.js +0 -70
- package/lib/Store/index.d.ts +0 -2
- package/lib/Store/index.js +0 -8
- package/lib/Store/make-in-memory-store.d.ts +0 -118
- package/lib/Store/make-in-memory-store.js +0 -429
- package/lib/Store/make-ordered-dictionary.d.ts +0 -13
- package/lib/Store/make-ordered-dictionary.js +0 -81
- package/lib/Store/object-repository.d.ts +0 -10
- package/lib/Store/object-repository.js +0 -27
- package/lib/WAMedia/index.d.ts +0 -2
- package/lib/WAMedia/index.js +0 -18
- package/lib/WAMedia/media-messages.d.ts +0 -18
- package/lib/WAMedia/media-messages.js +0 -102
- package/lib/WAMedia/media-set.d.ts +0 -9
- package/lib/WAMedia/media-set.js +0 -312
|
@@ -1,39 +1,218 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const messages_send_1 = require("./messages-send");
|
|
18
|
-
const makeMessagesRecvSocket = (config) => {
|
|
19
|
-
const { logger, retryRequestDelayMs, maxMsgRetryCount, getMessage, shouldIgnoreJid } = config;
|
|
20
|
-
const sock = (0, messages_send_1.makeMessagesSocket)(config);
|
|
21
|
-
const { ev, authState, ws, processingMutex, signalRepository, query, upsertMessage, resyncAppState, groupMetadata, onUnexpectedError, assertSessions, sendNode, relayMessage, sendReceipt, uploadPreKeys, createParticipantNodes, getUSyncDevices, sendPeerDataOperationMessage, } = sock;
|
|
1
|
+
import NodeCache from '@cacheable/node-cache';
|
|
2
|
+
import { Boom } from '@hapi/boom';
|
|
3
|
+
import { randomBytes } from 'crypto';
|
|
4
|
+
import Long from 'long';
|
|
5
|
+
import { proto } from '../../WAProto/index.js';
|
|
6
|
+
import { DEFAULT_CACHE_TTLS, KEY_BUNDLE_TYPE, MIN_PREKEY_COUNT } from '../Defaults/index.js';
|
|
7
|
+
import { WAMessageStatus, WAMessageStubType } from '../Types/index.js';
|
|
8
|
+
import { aesDecryptCTR, aesEncryptGCM, cleanMessage, Curve, decodeMediaRetryNode, decodeMessageNode, decryptMessageNode, delay, derivePairingCodeKey, encodeBigEndian, encodeSignedDeviceIdentity, extractAddressingContext, getCallStatusFromNode, getHistoryMsg, getNextPreKeys, getStatusFromReceiptType, hkdf, MISSING_KEYS_ERROR_TEXT, NACK_REASONS, unixTimestampSeconds, xmppPreKey, xmppSignedPreKey } from '../Utils/index.js';
|
|
9
|
+
import { makeMutex } from '../Utils/make-mutex.js';
|
|
10
|
+
import { areJidsSameUser, binaryNodeToString, getAllBinaryNodeChildren, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildren, getBinaryNodeChildString, isJidGroup, isJidStatusBroadcast, isLidUser, isPnUser, jidDecode, jidNormalizedUser, S_WHATSAPP_NET } from '../WABinary/index.js';
|
|
11
|
+
import { extractGroupMetadata } from './groups.js';
|
|
12
|
+
import { makeMessagesSocket } from './messages-send.js';
|
|
13
|
+
export const makeMessagesRecvSocket = (config) => {
|
|
14
|
+
const { logger, retryRequestDelayMs, maxMsgRetryCount, getMessage, shouldIgnoreJid, enableAutoSessionRecreation } = config;
|
|
15
|
+
const sock = makeMessagesSocket(config);
|
|
16
|
+
const { ev, authState, ws, processingMutex, signalRepository, query, upsertMessage, resyncAppState, onUnexpectedError, assertSessions, sendNode, relayMessage, sendReceipt, uploadPreKeys, sendPeerDataOperationMessage, messageRetryManager } = sock;
|
|
22
17
|
/** this mutex ensures that each retryRequest will wait for the previous one to finish */
|
|
23
|
-
const retryMutex =
|
|
24
|
-
const msgRetryCache =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
18
|
+
const retryMutex = makeMutex();
|
|
19
|
+
const msgRetryCache = config.msgRetryCounterCache ||
|
|
20
|
+
new NodeCache({
|
|
21
|
+
stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
22
|
+
useClones: false
|
|
23
|
+
});
|
|
24
|
+
const callOfferCache = config.callOfferCache ||
|
|
25
|
+
new NodeCache({
|
|
26
|
+
stdTTL: DEFAULT_CACHE_TTLS.CALL_OFFER, // 5 mins
|
|
27
|
+
useClones: false
|
|
28
|
+
});
|
|
29
|
+
const placeholderResendCache = config.placeholderResendCache ||
|
|
30
|
+
new NodeCache({
|
|
31
|
+
stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
32
|
+
useClones: false
|
|
33
|
+
});
|
|
36
34
|
let sendActiveReceipts = false;
|
|
35
|
+
const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
|
|
36
|
+
if (!authState.creds.me?.id) {
|
|
37
|
+
throw new Boom('Not authenticated');
|
|
38
|
+
}
|
|
39
|
+
const pdoMessage = {
|
|
40
|
+
historySyncOnDemandRequest: {
|
|
41
|
+
chatJid: oldestMsgKey.remoteJid,
|
|
42
|
+
oldestMsgFromMe: oldestMsgKey.fromMe,
|
|
43
|
+
oldestMsgId: oldestMsgKey.id,
|
|
44
|
+
oldestMsgTimestampMs: oldestMsgTimestamp,
|
|
45
|
+
onDemandMsgCount: count
|
|
46
|
+
},
|
|
47
|
+
peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
|
|
48
|
+
};
|
|
49
|
+
return sendPeerDataOperationMessage(pdoMessage);
|
|
50
|
+
};
|
|
51
|
+
const requestPlaceholderResend = async (messageKey) => {
|
|
52
|
+
if (!authState.creds.me?.id) {
|
|
53
|
+
throw new Boom('Not authenticated');
|
|
54
|
+
}
|
|
55
|
+
if (placeholderResendCache.get(messageKey?.id)) {
|
|
56
|
+
logger.debug({ messageKey }, 'already requested resend');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
placeholderResendCache.set(messageKey?.id, true);
|
|
61
|
+
}
|
|
62
|
+
await delay(5000);
|
|
63
|
+
if (!placeholderResendCache.get(messageKey?.id)) {
|
|
64
|
+
logger.debug({ messageKey }, 'message received while resend requested');
|
|
65
|
+
return 'RESOLVED';
|
|
66
|
+
}
|
|
67
|
+
const pdoMessage = {
|
|
68
|
+
placeholderMessageResendRequest: [
|
|
69
|
+
{
|
|
70
|
+
messageKey
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
peerDataOperationRequestType: proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
|
|
74
|
+
};
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
if (placeholderResendCache.get(messageKey?.id)) {
|
|
77
|
+
logger.debug({ messageKey }, 'PDO message without response after 15 seconds. Phone possibly offline');
|
|
78
|
+
placeholderResendCache.del(messageKey?.id);
|
|
79
|
+
}
|
|
80
|
+
}, 15000);
|
|
81
|
+
return sendPeerDataOperationMessage(pdoMessage);
|
|
82
|
+
};
|
|
83
|
+
// Handles mex newsletter notifications
|
|
84
|
+
const handleMexNewsletterNotification = async (node) => {
|
|
85
|
+
const mexNode = getBinaryNodeChild(node, 'mex');
|
|
86
|
+
if (!mexNode?.content) {
|
|
87
|
+
logger.warn({ node }, 'Invalid mex newsletter notification');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
let data;
|
|
91
|
+
try {
|
|
92
|
+
data = JSON.parse(mexNode.content.toString());
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
logger.error({ err: error, node }, 'Failed to parse mex newsletter notification');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const operation = data?.operation;
|
|
99
|
+
const updates = data?.updates;
|
|
100
|
+
if (!updates || !operation) {
|
|
101
|
+
logger.warn({ data }, 'Invalid mex newsletter notification content');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
logger.info({ operation, updates }, 'got mex newsletter notification');
|
|
105
|
+
switch (operation) {
|
|
106
|
+
case 'NotificationNewsletterUpdate':
|
|
107
|
+
for (const update of updates) {
|
|
108
|
+
if (update.jid && update.settings && Object.keys(update.settings).length > 0) {
|
|
109
|
+
ev.emit('newsletter-settings.update', {
|
|
110
|
+
id: update.jid,
|
|
111
|
+
update: update.settings
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
case 'NotificationNewsletterAdminPromote':
|
|
117
|
+
for (const update of updates) {
|
|
118
|
+
if (update.jid && update.user) {
|
|
119
|
+
ev.emit('newsletter-participants.update', {
|
|
120
|
+
id: update.jid,
|
|
121
|
+
author: node.attrs.from,
|
|
122
|
+
user: update.user,
|
|
123
|
+
new_role: 'ADMIN',
|
|
124
|
+
action: 'promote'
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
break;
|
|
129
|
+
default:
|
|
130
|
+
logger.info({ operation, data }, 'Unhandled mex newsletter notification');
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
// Handles newsletter notifications
|
|
135
|
+
const handleNewsletterNotification = async (node) => {
|
|
136
|
+
const from = node.attrs.from;
|
|
137
|
+
const child = getAllBinaryNodeChildren(node)[0];
|
|
138
|
+
const author = node.attrs.participant;
|
|
139
|
+
logger.info({ from, child }, 'got newsletter notification');
|
|
140
|
+
switch (child.tag) {
|
|
141
|
+
case 'reaction':
|
|
142
|
+
const reactionUpdate = {
|
|
143
|
+
id: from,
|
|
144
|
+
server_id: child.attrs.message_id,
|
|
145
|
+
reaction: {
|
|
146
|
+
code: getBinaryNodeChildString(child, 'reaction'),
|
|
147
|
+
count: 1
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
ev.emit('newsletter.reaction', reactionUpdate);
|
|
151
|
+
break;
|
|
152
|
+
case 'view':
|
|
153
|
+
const viewUpdate = {
|
|
154
|
+
id: from,
|
|
155
|
+
server_id: child.attrs.message_id,
|
|
156
|
+
count: parseInt(child.content?.toString() || '0', 10)
|
|
157
|
+
};
|
|
158
|
+
ev.emit('newsletter.view', viewUpdate);
|
|
159
|
+
break;
|
|
160
|
+
case 'participant':
|
|
161
|
+
const participantUpdate = {
|
|
162
|
+
id: from,
|
|
163
|
+
author,
|
|
164
|
+
user: child.attrs.jid,
|
|
165
|
+
action: child.attrs.action,
|
|
166
|
+
new_role: child.attrs.role
|
|
167
|
+
};
|
|
168
|
+
ev.emit('newsletter-participants.update', participantUpdate);
|
|
169
|
+
break;
|
|
170
|
+
case 'update':
|
|
171
|
+
const settingsNode = getBinaryNodeChild(child, 'settings');
|
|
172
|
+
if (settingsNode) {
|
|
173
|
+
const update = {};
|
|
174
|
+
const nameNode = getBinaryNodeChild(settingsNode, 'name');
|
|
175
|
+
if (nameNode?.content)
|
|
176
|
+
update.name = nameNode.content.toString();
|
|
177
|
+
const descriptionNode = getBinaryNodeChild(settingsNode, 'description');
|
|
178
|
+
if (descriptionNode?.content)
|
|
179
|
+
update.description = descriptionNode.content.toString();
|
|
180
|
+
ev.emit('newsletter-settings.update', {
|
|
181
|
+
id: from,
|
|
182
|
+
update
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
case 'message':
|
|
187
|
+
const plaintextNode = getBinaryNodeChild(child, 'plaintext');
|
|
188
|
+
if (plaintextNode?.content) {
|
|
189
|
+
try {
|
|
190
|
+
const contentBuf = typeof plaintextNode.content === 'string'
|
|
191
|
+
? Buffer.from(plaintextNode.content, 'binary')
|
|
192
|
+
: Buffer.from(plaintextNode.content);
|
|
193
|
+
const messageProto = proto.Message.decode(contentBuf).toJSON();
|
|
194
|
+
const fullMessage = proto.WebMessageInfo.fromObject({
|
|
195
|
+
key: {
|
|
196
|
+
remoteJid: from,
|
|
197
|
+
id: child.attrs.message_id || child.attrs.server_id,
|
|
198
|
+
fromMe: false // TODO: is this really true though
|
|
199
|
+
},
|
|
200
|
+
message: messageProto,
|
|
201
|
+
messageTimestamp: +child.attrs.t
|
|
202
|
+
}).toJSON();
|
|
203
|
+
await upsertMessage(fullMessage, 'append');
|
|
204
|
+
logger.info('Processed plaintext newsletter message');
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
logger.error({ error }, 'Failed to decode plaintext newsletter message');
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
211
|
+
default:
|
|
212
|
+
logger.warn({ node }, 'Unknown newsletter notification');
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
37
216
|
const sendMessageAck = async ({ tag, attrs, content }, errorCode) => {
|
|
38
217
|
const stanza = {
|
|
39
218
|
tag: 'ack',
|
|
@@ -52,112 +231,113 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
52
231
|
if (!!attrs.recipient) {
|
|
53
232
|
stanza.attrs.recipient = attrs.recipient;
|
|
54
233
|
}
|
|
55
|
-
if (!!attrs.type &&
|
|
234
|
+
if (!!attrs.type &&
|
|
235
|
+
(tag !== 'message' || getBinaryNodeChild({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
|
|
56
236
|
stanza.attrs.type = attrs.type;
|
|
57
237
|
}
|
|
58
|
-
if (tag === 'message' &&
|
|
238
|
+
if (tag === 'message' && getBinaryNodeChild({ tag, attrs, content }, 'unavailable')) {
|
|
59
239
|
stanza.attrs.from = authState.creds.me.id;
|
|
60
240
|
}
|
|
61
241
|
logger.debug({ recv: { tag, attrs }, sent: stanza.attrs }, 'sent ack');
|
|
62
242
|
await sendNode(stanza);
|
|
63
243
|
};
|
|
64
|
-
const offerCall = async (toJid, isVideo = false) => {
|
|
65
|
-
const callId = (0, crypto_1.randomBytes)(16).toString('hex').toUpperCase().substring(0, 64);
|
|
66
|
-
const offerContent = [];
|
|
67
|
-
offerContent.push({ tag: 'audio', attrs: { enc: 'opus', rate: '16000' }, content: undefined });
|
|
68
|
-
offerContent.push({ tag: 'audio', attrs: { enc: 'opus', rate: '8000' }, content: undefined });
|
|
69
|
-
if (isVideo) {
|
|
70
|
-
offerContent.push({
|
|
71
|
-
tag: 'video',
|
|
72
|
-
attrs: {
|
|
73
|
-
orientation: '0',
|
|
74
|
-
'screen_width': '1920',
|
|
75
|
-
'screen_height': '1080',
|
|
76
|
-
'device_orientation': '0',
|
|
77
|
-
enc: 'vp8',
|
|
78
|
-
dec: 'vp8',
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
offerContent.push({ tag: 'net', attrs: { medium: '3' }, content: undefined });
|
|
83
|
-
offerContent.push({ tag: 'capability', attrs: { ver: '1' }, content: new Uint8Array([1, 4, 255, 131, 207, 4]) });
|
|
84
|
-
offerContent.push({ tag: 'encopt', attrs: { keygen: '2' }, content: undefined });
|
|
85
|
-
const encKey = (0, crypto_1.randomBytes)(32);
|
|
86
|
-
const devices = (await getUSyncDevices([toJid], true, false)).map(({ user, device }) => (0, WABinary_1.jidEncode)(user, 's.whatsapp.net', device));
|
|
87
|
-
await assertSessions(devices, true);
|
|
88
|
-
const { nodes: destinations, shouldIncludeDeviceIdentity } = await createParticipantNodes(devices, {
|
|
89
|
-
call: {
|
|
90
|
-
callKey: encKey
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
offerContent.push({ tag: 'destination', attrs: {}, content: destinations });
|
|
94
|
-
if (shouldIncludeDeviceIdentity) {
|
|
95
|
-
offerContent.push({
|
|
96
|
-
tag: 'device-identity',
|
|
97
|
-
attrs: {},
|
|
98
|
-
content: (0, Utils_1.encodeSignedDeviceIdentity)(authState.creds.account, true)
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
const stanza = ({
|
|
102
|
-
tag: 'call',
|
|
103
|
-
attrs: {
|
|
104
|
-
to: toJid,
|
|
105
|
-
},
|
|
106
|
-
content: [{
|
|
107
|
-
tag: 'offer',
|
|
108
|
-
attrs: {
|
|
109
|
-
'call-id': callId,
|
|
110
|
-
'call-creator': authState.creds.me.id,
|
|
111
|
-
},
|
|
112
|
-
content: offerContent,
|
|
113
|
-
}],
|
|
114
|
-
});
|
|
115
|
-
await query(stanza);
|
|
116
|
-
return {
|
|
117
|
-
callId,
|
|
118
|
-
toJid,
|
|
119
|
-
isVideo,
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
244
|
const rejectCall = async (callId, callFrom) => {
|
|
123
|
-
const stanza =
|
|
245
|
+
const stanza = {
|
|
124
246
|
tag: 'call',
|
|
125
247
|
attrs: {
|
|
126
248
|
from: authState.creds.me.id,
|
|
127
|
-
to: callFrom
|
|
249
|
+
to: callFrom
|
|
128
250
|
},
|
|
129
|
-
content: [
|
|
251
|
+
content: [
|
|
252
|
+
{
|
|
130
253
|
tag: 'reject',
|
|
131
254
|
attrs: {
|
|
132
255
|
'call-id': callId,
|
|
133
256
|
'call-creator': callFrom,
|
|
134
|
-
count: '0'
|
|
257
|
+
count: '0'
|
|
135
258
|
},
|
|
136
|
-
content: undefined
|
|
137
|
-
}
|
|
138
|
-
|
|
259
|
+
content: undefined
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
};
|
|
139
263
|
await query(stanza);
|
|
140
264
|
};
|
|
141
265
|
const sendRetryRequest = async (node, forceIncludeKeys = false) => {
|
|
142
|
-
const { fullMessage } =
|
|
266
|
+
const { fullMessage } = decodeMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '');
|
|
143
267
|
const { key: msgKey } = fullMessage;
|
|
144
268
|
const msgId = msgKey.id;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
269
|
+
if (messageRetryManager) {
|
|
270
|
+
// Check if we've exceeded max retries using the new system
|
|
271
|
+
if (messageRetryManager.hasExceededMaxRetries(msgId)) {
|
|
272
|
+
logger.debug({ msgId }, 'reached retry limit with new retry manager, clearing');
|
|
273
|
+
messageRetryManager.markRetryFailed(msgId);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
// Increment retry count using new system
|
|
277
|
+
const retryCount = messageRetryManager.incrementRetryCount(msgId);
|
|
278
|
+
// Use the new retry count for the rest of the logic
|
|
279
|
+
const key = `${msgId}:${msgKey?.participant}`;
|
|
280
|
+
msgRetryCache.set(key, retryCount);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
// Fallback to old system
|
|
284
|
+
const key = `${msgId}:${msgKey?.participant}`;
|
|
285
|
+
let retryCount = (await msgRetryCache.get(key)) || 0;
|
|
286
|
+
if (retryCount >= maxMsgRetryCount) {
|
|
287
|
+
logger.debug({ retryCount, msgId }, 'reached retry limit, clearing');
|
|
288
|
+
msgRetryCache.del(key);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
retryCount += 1;
|
|
292
|
+
await msgRetryCache.set(key, retryCount);
|
|
151
293
|
}
|
|
152
|
-
|
|
153
|
-
msgRetryCache.
|
|
294
|
+
const key = `${msgId}:${msgKey?.participant}`;
|
|
295
|
+
const retryCount = (await msgRetryCache.get(key)) || 1;
|
|
154
296
|
const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
297
|
+
const fromJid = node.attrs.from;
|
|
298
|
+
// Check if we should recreate the session
|
|
299
|
+
let shouldRecreateSession = false;
|
|
300
|
+
let recreateReason = '';
|
|
301
|
+
if (enableAutoSessionRecreation && messageRetryManager) {
|
|
302
|
+
try {
|
|
303
|
+
// Check if we have a session with this JID
|
|
304
|
+
const sessionId = signalRepository.jidToSignalProtocolAddress(fromJid);
|
|
305
|
+
const hasSession = await signalRepository.validateSession(fromJid);
|
|
306
|
+
const result = messageRetryManager.shouldRecreateSession(fromJid, retryCount, hasSession.exists);
|
|
307
|
+
shouldRecreateSession = result.recreate;
|
|
308
|
+
recreateReason = result.reason;
|
|
309
|
+
if (shouldRecreateSession) {
|
|
310
|
+
logger.debug({ fromJid, retryCount, reason: recreateReason }, 'recreating session for retry');
|
|
311
|
+
// Delete existing session to force recreation
|
|
312
|
+
await authState.keys.set({ session: { [sessionId]: null } });
|
|
313
|
+
forceIncludeKeys = true;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
logger.warn({ error, fromJid }, 'failed to check session recreation');
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (retryCount <= 2) {
|
|
321
|
+
// Use new retry manager for phone requests if available
|
|
322
|
+
if (messageRetryManager) {
|
|
323
|
+
// Schedule phone request with delay (like whatsmeow)
|
|
324
|
+
messageRetryManager.schedulePhoneRequest(msgId, async () => {
|
|
325
|
+
try {
|
|
326
|
+
const requestId = await requestPlaceholderResend(msgKey);
|
|
327
|
+
logger.debug(`sendRetryRequest: requested placeholder resend (${requestId}) for message ${msgId} (scheduled)`);
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
logger.warn({ error, msgId }, 'failed to send scheduled phone request');
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
// Fallback to immediate request
|
|
336
|
+
const msgId = await requestPlaceholderResend(msgKey);
|
|
337
|
+
logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId}`);
|
|
338
|
+
}
|
|
159
339
|
}
|
|
160
|
-
const deviceIdentity =
|
|
340
|
+
const deviceIdentity = encodeSignedDeviceIdentity(account, true);
|
|
161
341
|
await authState.keys.transaction(async () => {
|
|
162
342
|
const receipt = {
|
|
163
343
|
tag: 'receipt',
|
|
@@ -173,13 +353,15 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
173
353
|
count: retryCount.toString(),
|
|
174
354
|
id: node.attrs.id,
|
|
175
355
|
t: node.attrs.t,
|
|
176
|
-
v: '1'
|
|
356
|
+
v: '1',
|
|
357
|
+
// ADD ERROR FIELD
|
|
358
|
+
error: '0'
|
|
177
359
|
}
|
|
178
360
|
},
|
|
179
361
|
{
|
|
180
362
|
tag: 'registration',
|
|
181
363
|
attrs: {},
|
|
182
|
-
content:
|
|
364
|
+
content: encodeBigEndian(authState.creds.registrationId)
|
|
183
365
|
}
|
|
184
366
|
]
|
|
185
367
|
};
|
|
@@ -189,8 +371,8 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
189
371
|
if (node.attrs.participant) {
|
|
190
372
|
receipt.attrs.participant = node.attrs.participant;
|
|
191
373
|
}
|
|
192
|
-
if (retryCount > 1 || forceIncludeKeys) {
|
|
193
|
-
const { update, preKeys } = await
|
|
374
|
+
if (retryCount > 1 || forceIncludeKeys || shouldRecreateSession) {
|
|
375
|
+
const { update, preKeys } = await getNextPreKeys(authState, 1);
|
|
194
376
|
const [keyId] = Object.keys(preKeys);
|
|
195
377
|
const key = preKeys[+keyId];
|
|
196
378
|
const content = receipt.content;
|
|
@@ -198,10 +380,10 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
198
380
|
tag: 'keys',
|
|
199
381
|
attrs: {},
|
|
200
382
|
content: [
|
|
201
|
-
{ tag: 'type', attrs: {}, content: Buffer.from(
|
|
383
|
+
{ tag: 'type', attrs: {}, content: Buffer.from(KEY_BUNDLE_TYPE) },
|
|
202
384
|
{ tag: 'identity', attrs: {}, content: identityKey.public },
|
|
203
|
-
|
|
204
|
-
|
|
385
|
+
xmppPreKey(key, +keyId),
|
|
386
|
+
xmppSignedPreKey(signedPreKey),
|
|
205
387
|
{ tag: 'device-identity', attrs: {}, content: deviceIdentity }
|
|
206
388
|
]
|
|
207
389
|
});
|
|
@@ -209,21 +391,21 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
209
391
|
}
|
|
210
392
|
await sendNode(receipt);
|
|
211
393
|
logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt');
|
|
212
|
-
});
|
|
394
|
+
}, authState?.creds?.me?.id || 'sendRetryRequest');
|
|
213
395
|
};
|
|
214
396
|
const handleEncryptNotification = async (node) => {
|
|
215
397
|
const from = node.attrs.from;
|
|
216
|
-
if (from ===
|
|
217
|
-
const countChild =
|
|
398
|
+
if (from === S_WHATSAPP_NET) {
|
|
399
|
+
const countChild = getBinaryNodeChild(node, 'count');
|
|
218
400
|
const count = +countChild.attrs.value;
|
|
219
|
-
const shouldUploadMorePreKeys = count <
|
|
401
|
+
const shouldUploadMorePreKeys = count < MIN_PREKEY_COUNT;
|
|
220
402
|
logger.debug({ count, shouldUploadMorePreKeys }, 'recv pre-key count');
|
|
221
403
|
if (shouldUploadMorePreKeys) {
|
|
222
404
|
await uploadPreKeys();
|
|
223
405
|
}
|
|
224
406
|
}
|
|
225
407
|
else {
|
|
226
|
-
const identityNode =
|
|
408
|
+
const identityNode = getBinaryNodeChild(node, 'identity');
|
|
227
409
|
if (identityNode) {
|
|
228
410
|
logger.info({ jid: from }, 'identity changed');
|
|
229
411
|
// not handling right now
|
|
@@ -234,38 +416,46 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
234
416
|
}
|
|
235
417
|
}
|
|
236
418
|
};
|
|
237
|
-
const handleGroupNotification = (
|
|
238
|
-
|
|
239
|
-
const
|
|
240
|
-
|
|
419
|
+
const handleGroupNotification = (fullNode, child, msg) => {
|
|
420
|
+
// TODO: Support PN/LID (Here is only LID now)
|
|
421
|
+
const actingParticipantLid = fullNode.attrs.participant;
|
|
422
|
+
const actingParticipantPn = fullNode.attrs.participant_pn;
|
|
423
|
+
const affectedParticipantLid = getBinaryNodeChild(child, 'participant')?.attrs?.jid || actingParticipantLid;
|
|
424
|
+
const affectedParticipantPn = getBinaryNodeChild(child, 'participant')?.attrs?.phone_number || actingParticipantPn;
|
|
425
|
+
switch (child?.tag) {
|
|
241
426
|
case 'create':
|
|
242
|
-
const metadata =
|
|
243
|
-
msg.messageStubType =
|
|
427
|
+
const metadata = extractGroupMetadata(child);
|
|
428
|
+
msg.messageStubType = WAMessageStubType.GROUP_CREATE;
|
|
244
429
|
msg.messageStubParameters = [metadata.subject];
|
|
245
|
-
msg.key = { participant: metadata.owner };
|
|
246
|
-
ev.emit('chats.upsert', [
|
|
430
|
+
msg.key = { participant: metadata.owner, participantAlt: metadata.ownerPn };
|
|
431
|
+
ev.emit('chats.upsert', [
|
|
432
|
+
{
|
|
247
433
|
id: metadata.id,
|
|
248
434
|
name: metadata.subject,
|
|
249
|
-
conversationTimestamp: metadata.creation
|
|
250
|
-
}
|
|
251
|
-
|
|
435
|
+
conversationTimestamp: metadata.creation
|
|
436
|
+
}
|
|
437
|
+
]);
|
|
438
|
+
ev.emit('groups.upsert', [
|
|
439
|
+
{
|
|
252
440
|
...metadata,
|
|
253
|
-
author:
|
|
254
|
-
|
|
441
|
+
author: actingParticipantLid,
|
|
442
|
+
authorPn: actingParticipantPn
|
|
443
|
+
}
|
|
444
|
+
]);
|
|
255
445
|
break;
|
|
256
446
|
case 'ephemeral':
|
|
257
447
|
case 'not_ephemeral':
|
|
258
448
|
msg.message = {
|
|
259
449
|
protocolMessage: {
|
|
260
|
-
type:
|
|
450
|
+
type: proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
|
|
261
451
|
ephemeralExpiration: +(child.attrs.expiration || 0)
|
|
262
452
|
}
|
|
263
453
|
};
|
|
264
454
|
break;
|
|
265
455
|
case 'modify':
|
|
266
|
-
const oldNumber =
|
|
456
|
+
const oldNumber = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid);
|
|
267
457
|
msg.messageStubParameters = oldNumber || [];
|
|
268
|
-
msg.messageStubType =
|
|
458
|
+
msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER;
|
|
269
459
|
break;
|
|
270
460
|
case 'promote':
|
|
271
461
|
case 'demote':
|
|
@@ -273,121 +463,90 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
273
463
|
case 'add':
|
|
274
464
|
case 'leave':
|
|
275
465
|
const stubType = `GROUP_PARTICIPANT_${child.tag.toUpperCase()}`;
|
|
276
|
-
msg.messageStubType =
|
|
277
|
-
const participants =
|
|
466
|
+
msg.messageStubType = WAMessageStubType[stubType];
|
|
467
|
+
const participants = getBinaryNodeChildren(child, 'participant').map(({ attrs }) => {
|
|
468
|
+
// TODO: Store LID MAPPINGS
|
|
469
|
+
return {
|
|
470
|
+
id: attrs.jid,
|
|
471
|
+
phoneNumber: isLidUser(attrs.jid) && isPnUser(attrs.phone_number) ? attrs.phone_number : undefined,
|
|
472
|
+
lid: isPnUser(attrs.jid) && isLidUser(attrs.lid) ? attrs.lid : undefined,
|
|
473
|
+
admin: (attrs.type || null)
|
|
474
|
+
};
|
|
475
|
+
});
|
|
278
476
|
if (participants.length === 1 &&
|
|
279
477
|
// if recv. "remove" message and sender removed themselves
|
|
280
478
|
// mark as left
|
|
281
|
-
(
|
|
479
|
+
(areJidsSameUser(participants[0].id, actingParticipantLid) ||
|
|
480
|
+
areJidsSameUser(participants[0].id, actingParticipantPn)) &&
|
|
282
481
|
child.tag === 'remove') {
|
|
283
|
-
msg.messageStubType =
|
|
482
|
+
msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_LEAVE;
|
|
284
483
|
}
|
|
285
|
-
msg.messageStubParameters = participants;
|
|
484
|
+
msg.messageStubParameters = participants.map(a => JSON.stringify(a));
|
|
286
485
|
break;
|
|
287
486
|
case 'subject':
|
|
288
|
-
msg.messageStubType =
|
|
487
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_SUBJECT;
|
|
289
488
|
msg.messageStubParameters = [child.attrs.subject];
|
|
290
489
|
break;
|
|
291
490
|
case 'description':
|
|
292
|
-
const description =
|
|
293
|
-
msg.messageStubType =
|
|
491
|
+
const description = getBinaryNodeChild(child, 'body')?.content?.toString();
|
|
492
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_DESCRIPTION;
|
|
294
493
|
msg.messageStubParameters = description ? [description] : undefined;
|
|
295
494
|
break;
|
|
296
495
|
case 'announcement':
|
|
297
496
|
case 'not_announcement':
|
|
298
|
-
msg.messageStubType =
|
|
299
|
-
msg.messageStubParameters = [
|
|
497
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_ANNOUNCE;
|
|
498
|
+
msg.messageStubParameters = [child.tag === 'announcement' ? 'on' : 'off'];
|
|
300
499
|
break;
|
|
301
500
|
case 'locked':
|
|
302
501
|
case 'unlocked':
|
|
303
|
-
msg.messageStubType =
|
|
304
|
-
msg.messageStubParameters = [
|
|
502
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_RESTRICT;
|
|
503
|
+
msg.messageStubParameters = [child.tag === 'locked' ? 'on' : 'off'];
|
|
305
504
|
break;
|
|
306
505
|
case 'invite':
|
|
307
|
-
msg.messageStubType =
|
|
506
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_INVITE_LINK;
|
|
308
507
|
msg.messageStubParameters = [child.attrs.code];
|
|
309
508
|
break;
|
|
310
509
|
case 'member_add_mode':
|
|
311
510
|
const addMode = child.content;
|
|
312
511
|
if (addMode) {
|
|
313
|
-
msg.messageStubType =
|
|
512
|
+
msg.messageStubType = WAMessageStubType.GROUP_MEMBER_ADD_MODE;
|
|
314
513
|
msg.messageStubParameters = [addMode.toString()];
|
|
315
514
|
}
|
|
316
515
|
break;
|
|
317
516
|
case 'membership_approval_mode':
|
|
318
|
-
const approvalMode =
|
|
517
|
+
const approvalMode = getBinaryNodeChild(child, 'group_join');
|
|
319
518
|
if (approvalMode) {
|
|
320
|
-
msg.messageStubType =
|
|
519
|
+
msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE;
|
|
321
520
|
msg.messageStubParameters = [approvalMode.attrs.state];
|
|
322
521
|
}
|
|
323
522
|
break;
|
|
324
523
|
case 'created_membership_requests':
|
|
325
|
-
msg.messageStubType =
|
|
326
|
-
msg.messageStubParameters = [
|
|
524
|
+
msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
|
|
525
|
+
msg.messageStubParameters = [
|
|
526
|
+
JSON.stringify({ lid: affectedParticipantLid, pn: affectedParticipantPn }),
|
|
527
|
+
'created',
|
|
528
|
+
child.attrs.request_method
|
|
529
|
+
];
|
|
327
530
|
break;
|
|
328
531
|
case 'revoked_membership_requests':
|
|
329
|
-
const isDenied =
|
|
330
|
-
|
|
331
|
-
msg.
|
|
332
|
-
|
|
532
|
+
const isDenied = areJidsSameUser(affectedParticipantLid, actingParticipantLid);
|
|
533
|
+
// TODO: LIDMAPPING SUPPORT
|
|
534
|
+
msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD;
|
|
535
|
+
msg.messageStubParameters = [
|
|
536
|
+
JSON.stringify({ lid: affectedParticipantLid, pn: affectedParticipantPn }),
|
|
537
|
+
isDenied ? 'revoked' : 'rejected'
|
|
538
|
+
];
|
|
333
539
|
break;
|
|
334
|
-
default:
|
|
335
|
-
// console.log("BAILEYS-DEBUG:", JSON.stringify({ ...child, content: Buffer.isBuffer(child.content) ? child.content.toString() : child.content, participant }, null, 2))
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
const handleNewsletterNotification = (id, node) => {
|
|
339
|
-
const messages = (0, WABinary_1.getBinaryNodeChild)(node, 'messages');
|
|
340
|
-
const message = (0, WABinary_1.getBinaryNodeChild)(messages, 'message');
|
|
341
|
-
const serverId = message.attrs.server_id;
|
|
342
|
-
const reactionsList = (0, WABinary_1.getBinaryNodeChild)(message, 'reactions');
|
|
343
|
-
const viewsList = (0, WABinary_1.getBinaryNodeChildren)(message, 'views_count');
|
|
344
|
-
if (reactionsList) {
|
|
345
|
-
const reactions = (0, WABinary_1.getBinaryNodeChildren)(reactionsList, 'reaction');
|
|
346
|
-
if (reactions.length === 0) {
|
|
347
|
-
ev.emit('newsletter.reaction', { id, 'server_id': serverId, reaction: { removed: true } });
|
|
348
|
-
}
|
|
349
|
-
reactions.forEach(item => {
|
|
350
|
-
var _a, _b;
|
|
351
|
-
ev.emit('newsletter.reaction', { id, 'server_id': serverId, reaction: { code: (_a = item.attrs) === null || _a === void 0 ? void 0 : _a.code, count: +((_b = item.attrs) === null || _b === void 0 ? void 0 : _b.count) } });
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
if (viewsList.length) {
|
|
355
|
-
viewsList.forEach(item => {
|
|
356
|
-
ev.emit('newsletter.view', { id, 'server_id': serverId, count: +item.attrs.count });
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
};
|
|
360
|
-
const handleMexNewsletterNotification = (id, node) => {
|
|
361
|
-
var _a;
|
|
362
|
-
const operation = node === null || node === void 0 ? void 0 : node.attrs.op_name;
|
|
363
|
-
const content = JSON.parse((_a = node === null || node === void 0 ? void 0 : node.content) === null || _a === void 0 ? void 0 : _a.toString());
|
|
364
|
-
let contentPath;
|
|
365
|
-
if (operation === Types_1.MexOperations.PROMOTE || operation === Types_1.MexOperations.DEMOTE) {
|
|
366
|
-
let action;
|
|
367
|
-
if (operation === Types_1.MexOperations.PROMOTE) {
|
|
368
|
-
action = 'promote';
|
|
369
|
-
contentPath = content.data[Types_1.XWAPaths.PROMOTE];
|
|
370
|
-
}
|
|
371
|
-
if (operation === Types_1.MexOperations.DEMOTE) {
|
|
372
|
-
action = 'demote';
|
|
373
|
-
contentPath = content.data[Types_1.XWAPaths.DEMOTE];
|
|
374
|
-
}
|
|
375
|
-
ev.emit('newsletter-participants.update', { id, author: contentPath.actor.pn, user: contentPath.user.pn, new_role: contentPath.user_new_role, action });
|
|
376
|
-
}
|
|
377
|
-
if (operation === Types_1.MexOperations.UPDATE) {
|
|
378
|
-
contentPath = content.data[Types_1.XWAPaths.METADATA_UPDATE];
|
|
379
|
-
ev.emit('newsletter-settings.update', { id, update: contentPath.thread_metadata.settings });
|
|
380
540
|
}
|
|
381
541
|
};
|
|
382
542
|
const processNotification = async (node) => {
|
|
383
|
-
var _a, _b;
|
|
384
543
|
const result = {};
|
|
385
|
-
const [child] =
|
|
544
|
+
const [child] = getAllBinaryNodeChildren(node);
|
|
386
545
|
const nodeType = node.attrs.type;
|
|
387
|
-
const from =
|
|
546
|
+
const from = jidNormalizedUser(node.attrs.from);
|
|
388
547
|
switch (nodeType) {
|
|
389
548
|
case 'privacy_token':
|
|
390
|
-
const tokenList =
|
|
549
|
+
const tokenList = getBinaryNodeChildren(child, 'token');
|
|
391
550
|
for (const { attrs, content } of tokenList) {
|
|
392
551
|
const jid = attrs.jid;
|
|
393
552
|
ev.emit('chats.update', [
|
|
@@ -400,52 +559,57 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
400
559
|
}
|
|
401
560
|
break;
|
|
402
561
|
case 'newsletter':
|
|
403
|
-
handleNewsletterNotification(node
|
|
562
|
+
await handleNewsletterNotification(node);
|
|
404
563
|
break;
|
|
405
564
|
case 'mex':
|
|
406
|
-
handleMexNewsletterNotification(node
|
|
565
|
+
await handleMexNewsletterNotification(node);
|
|
407
566
|
break;
|
|
408
567
|
case 'w:gp2':
|
|
409
|
-
|
|
568
|
+
// TODO: HANDLE PARTICIPANT_PN
|
|
569
|
+
handleGroupNotification(node, child, result);
|
|
410
570
|
break;
|
|
411
571
|
case 'mediaretry':
|
|
412
|
-
const event =
|
|
572
|
+
const event = decodeMediaRetryNode(node);
|
|
413
573
|
ev.emit('messages.media-update', [event]);
|
|
414
574
|
break;
|
|
415
575
|
case 'encrypt':
|
|
416
576
|
await handleEncryptNotification(node);
|
|
417
577
|
break;
|
|
418
578
|
case 'devices':
|
|
419
|
-
const devices =
|
|
420
|
-
if (
|
|
421
|
-
|
|
422
|
-
|
|
579
|
+
const devices = getBinaryNodeChildren(child, 'device');
|
|
580
|
+
if (areJidsSameUser(child.attrs.jid, authState.creds.me.id) ||
|
|
581
|
+
areJidsSameUser(child.attrs.lid, authState.creds.me.lid)) {
|
|
582
|
+
const deviceData = devices.map(d => ({ id: d.attrs.jid, lid: d.attrs.lid }));
|
|
583
|
+
logger.info({ deviceData }, 'my own devices changed');
|
|
423
584
|
}
|
|
585
|
+
//TODO: drop a new event, add hashes
|
|
424
586
|
break;
|
|
425
587
|
case 'server_sync':
|
|
426
|
-
const update =
|
|
588
|
+
const update = getBinaryNodeChild(node, 'collection');
|
|
427
589
|
if (update) {
|
|
428
590
|
const name = update.attrs.name;
|
|
429
591
|
await resyncAppState([name], false);
|
|
430
592
|
}
|
|
431
593
|
break;
|
|
432
594
|
case 'picture':
|
|
433
|
-
const setPicture =
|
|
434
|
-
const delPicture =
|
|
435
|
-
ev.emit('contacts.update', [
|
|
436
|
-
|
|
595
|
+
const setPicture = getBinaryNodeChild(node, 'set');
|
|
596
|
+
const delPicture = getBinaryNodeChild(node, 'delete');
|
|
597
|
+
ev.emit('contacts.update', [
|
|
598
|
+
{
|
|
599
|
+
id: jidNormalizedUser(node?.attrs?.from) || (setPicture || delPicture)?.attrs?.hash || '',
|
|
437
600
|
imgUrl: setPicture ? 'changed' : 'removed'
|
|
438
|
-
}
|
|
439
|
-
|
|
601
|
+
}
|
|
602
|
+
]);
|
|
603
|
+
if (isJidGroup(from)) {
|
|
440
604
|
const node = setPicture || delPicture;
|
|
441
|
-
result.messageStubType =
|
|
605
|
+
result.messageStubType = WAMessageStubType.GROUP_CHANGE_ICON;
|
|
442
606
|
if (setPicture) {
|
|
443
607
|
result.messageStubParameters = [setPicture.attrs.id];
|
|
444
608
|
}
|
|
445
|
-
result.participant = node
|
|
609
|
+
result.participant = node?.attrs.author;
|
|
446
610
|
result.key = {
|
|
447
|
-
...result.key || {},
|
|
448
|
-
participant: setPicture
|
|
611
|
+
...(result.key || {}),
|
|
612
|
+
participant: setPicture?.attrs.author
|
|
449
613
|
};
|
|
450
614
|
}
|
|
451
615
|
break;
|
|
@@ -459,44 +623,48 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
459
623
|
...authState.creds.accountSettings,
|
|
460
624
|
defaultDisappearingMode: {
|
|
461
625
|
ephemeralExpiration: newDuration,
|
|
462
|
-
ephemeralSettingTimestamp: timestamp
|
|
463
|
-
}
|
|
626
|
+
ephemeralSettingTimestamp: timestamp
|
|
627
|
+
}
|
|
464
628
|
}
|
|
465
629
|
});
|
|
466
630
|
}
|
|
467
631
|
else if (child.tag === 'blocklist') {
|
|
468
|
-
const blocklists =
|
|
632
|
+
const blocklists = getBinaryNodeChildren(child, 'item');
|
|
469
633
|
for (const { attrs } of blocklists) {
|
|
470
634
|
const blocklist = [attrs.jid];
|
|
471
|
-
const type =
|
|
635
|
+
const type = attrs.action === 'block' ? 'add' : 'remove';
|
|
472
636
|
ev.emit('blocklist.update', { blocklist, type });
|
|
473
637
|
}
|
|
474
638
|
}
|
|
475
639
|
break;
|
|
476
640
|
case 'link_code_companion_reg':
|
|
477
|
-
const linkCodeCompanionReg =
|
|
478
|
-
const ref = toRequiredBuffer(
|
|
479
|
-
const primaryIdentityPublicKey = toRequiredBuffer(
|
|
480
|
-
const primaryEphemeralPublicKeyWrapped = toRequiredBuffer(
|
|
641
|
+
const linkCodeCompanionReg = getBinaryNodeChild(node, 'link_code_companion_reg');
|
|
642
|
+
const ref = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'link_code_pairing_ref'));
|
|
643
|
+
const primaryIdentityPublicKey = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'primary_identity_pub'));
|
|
644
|
+
const primaryEphemeralPublicKeyWrapped = toRequiredBuffer(getBinaryNodeChildBuffer(linkCodeCompanionReg, 'link_code_pairing_wrapped_primary_ephemeral_pub'));
|
|
481
645
|
const codePairingPublicKey = await decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped);
|
|
482
|
-
const companionSharedKey =
|
|
483
|
-
const random =
|
|
484
|
-
const linkCodeSalt =
|
|
485
|
-
const linkCodePairingExpanded = await
|
|
646
|
+
const companionSharedKey = Curve.sharedKey(authState.creds.pairingEphemeralKeyPair.private, codePairingPublicKey);
|
|
647
|
+
const random = randomBytes(32);
|
|
648
|
+
const linkCodeSalt = randomBytes(32);
|
|
649
|
+
const linkCodePairingExpanded = await hkdf(companionSharedKey, 32, {
|
|
486
650
|
salt: linkCodeSalt,
|
|
487
651
|
info: 'link_code_pairing_key_bundle_encryption_key'
|
|
488
652
|
});
|
|
489
|
-
const encryptPayload = Buffer.concat([
|
|
490
|
-
|
|
491
|
-
|
|
653
|
+
const encryptPayload = Buffer.concat([
|
|
654
|
+
Buffer.from(authState.creds.signedIdentityKey.public),
|
|
655
|
+
primaryIdentityPublicKey,
|
|
656
|
+
random
|
|
657
|
+
]);
|
|
658
|
+
const encryptIv = randomBytes(12);
|
|
659
|
+
const encrypted = aesEncryptGCM(encryptPayload, linkCodePairingExpanded, encryptIv, Buffer.alloc(0));
|
|
492
660
|
const encryptedPayload = Buffer.concat([linkCodeSalt, encryptIv, encrypted]);
|
|
493
|
-
const identitySharedKey =
|
|
661
|
+
const identitySharedKey = Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey);
|
|
494
662
|
const identityPayload = Buffer.concat([companionSharedKey, identitySharedKey, random]);
|
|
495
|
-
authState.creds.advSecretKey = (await
|
|
663
|
+
authState.creds.advSecretKey = (await hkdf(identityPayload, 32, { info: 'adv_secret' })).toString('base64');
|
|
496
664
|
await query({
|
|
497
665
|
tag: 'iq',
|
|
498
666
|
attrs: {
|
|
499
|
-
to:
|
|
667
|
+
to: S_WHATSAPP_NET,
|
|
500
668
|
type: 'set',
|
|
501
669
|
id: sock.generateMessageTag(),
|
|
502
670
|
xmlns: 'md'
|
|
@@ -506,7 +674,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
506
674
|
tag: 'link_code_companion_reg',
|
|
507
675
|
attrs: {
|
|
508
676
|
jid: authState.creds.me.id,
|
|
509
|
-
stage: 'companion_finish'
|
|
677
|
+
stage: 'companion_finish'
|
|
510
678
|
},
|
|
511
679
|
content: [
|
|
512
680
|
{
|
|
@@ -538,44 +706,90 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
538
706
|
async function decipherLinkPublicKey(data) {
|
|
539
707
|
const buffer = toRequiredBuffer(data);
|
|
540
708
|
const salt = buffer.slice(0, 32);
|
|
541
|
-
const secretKey = await
|
|
709
|
+
const secretKey = await derivePairingCodeKey(authState.creds.pairingCode, salt);
|
|
542
710
|
const iv = buffer.slice(32, 48);
|
|
543
711
|
const payload = buffer.slice(48, 80);
|
|
544
|
-
return
|
|
712
|
+
return aesDecryptCTR(payload, secretKey, iv);
|
|
545
713
|
}
|
|
546
714
|
function toRequiredBuffer(data) {
|
|
547
715
|
if (data === undefined) {
|
|
548
|
-
throw new
|
|
716
|
+
throw new Boom('Invalid buffer', { statusCode: 400 });
|
|
549
717
|
}
|
|
550
718
|
return data instanceof Buffer ? data : Buffer.from(data);
|
|
551
719
|
}
|
|
552
|
-
const willSendMessageAgain = (id, participant) => {
|
|
720
|
+
const willSendMessageAgain = async (id, participant) => {
|
|
553
721
|
const key = `${id}:${participant}`;
|
|
554
|
-
const retryCount = msgRetryCache.get(key) || 0;
|
|
722
|
+
const retryCount = (await msgRetryCache.get(key)) || 0;
|
|
555
723
|
return retryCount < maxMsgRetryCount;
|
|
556
724
|
};
|
|
557
|
-
const updateSendMessageAgainCount = (id, participant) => {
|
|
725
|
+
const updateSendMessageAgainCount = async (id, participant) => {
|
|
558
726
|
const key = `${id}:${participant}`;
|
|
559
|
-
const newValue = (msgRetryCache.get(key) || 0) + 1;
|
|
560
|
-
msgRetryCache.set(key, newValue);
|
|
727
|
+
const newValue = ((await msgRetryCache.get(key)) || 0) + 1;
|
|
728
|
+
await msgRetryCache.set(key, newValue);
|
|
561
729
|
};
|
|
562
730
|
const sendMessagesAgain = async (key, ids, retryNode) => {
|
|
563
|
-
var _a;
|
|
564
|
-
// todo: implement a cache to store the last 256 sent messages (copy whatsmeow)
|
|
565
|
-
const msgs = await Promise.all(ids.map(id => getMessage({ ...key, id })));
|
|
566
731
|
const remoteJid = key.remoteJid;
|
|
567
732
|
const participant = key.participant || remoteJid;
|
|
733
|
+
const retryCount = +retryNode.attrs.count || 1;
|
|
734
|
+
// Try to get messages from cache first, then fallback to getMessage
|
|
735
|
+
const msgs = [];
|
|
736
|
+
for (const id of ids) {
|
|
737
|
+
let msg;
|
|
738
|
+
// Try to get from retry cache first if enabled
|
|
739
|
+
if (messageRetryManager) {
|
|
740
|
+
const cachedMsg = messageRetryManager.getRecentMessage(remoteJid, id);
|
|
741
|
+
if (cachedMsg) {
|
|
742
|
+
msg = cachedMsg.message;
|
|
743
|
+
logger.debug({ jid: remoteJid, id }, 'found message in retry cache');
|
|
744
|
+
// Mark retry as successful since we found the message
|
|
745
|
+
messageRetryManager.markRetrySuccess(id);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
// Fallback to getMessage if not found in cache
|
|
749
|
+
if (!msg) {
|
|
750
|
+
msg = await getMessage({ ...key, id });
|
|
751
|
+
if (msg) {
|
|
752
|
+
logger.debug({ jid: remoteJid, id }, 'found message via getMessage');
|
|
753
|
+
// Also mark as successful if found via getMessage
|
|
754
|
+
if (messageRetryManager) {
|
|
755
|
+
messageRetryManager.markRetrySuccess(id);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
msgs.push(msg);
|
|
760
|
+
}
|
|
568
761
|
// if it's the primary jid sending the request
|
|
569
762
|
// just re-send the message to everyone
|
|
570
763
|
// prevents the first message decryption failure
|
|
571
|
-
const sendToAll = !
|
|
572
|
-
|
|
573
|
-
|
|
764
|
+
const sendToAll = !jidDecode(participant)?.device;
|
|
765
|
+
// Check if we should recreate session for this retry
|
|
766
|
+
let shouldRecreateSession = false;
|
|
767
|
+
let recreateReason = '';
|
|
768
|
+
if (enableAutoSessionRecreation && messageRetryManager) {
|
|
769
|
+
try {
|
|
770
|
+
const sessionId = signalRepository.jidToSignalProtocolAddress(participant);
|
|
771
|
+
const hasSession = await signalRepository.validateSession(participant);
|
|
772
|
+
const result = messageRetryManager.shouldRecreateSession(participant, retryCount, hasSession.exists);
|
|
773
|
+
shouldRecreateSession = result.recreate;
|
|
774
|
+
recreateReason = result.reason;
|
|
775
|
+
if (shouldRecreateSession) {
|
|
776
|
+
logger.debug({ participant, retryCount, reason: recreateReason }, 'recreating session for outgoing retry');
|
|
777
|
+
await authState.keys.set({ session: { [sessionId]: null } });
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
catch (error) {
|
|
781
|
+
logger.warn({ error, participant }, 'failed to check session recreation for outgoing retry');
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
await assertSessions([participant]);
|
|
785
|
+
if (isJidGroup(remoteJid)) {
|
|
574
786
|
await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } });
|
|
575
787
|
}
|
|
576
|
-
logger.debug({ participant, sendToAll }, 'forced new session for retry recp');
|
|
788
|
+
logger.debug({ participant, sendToAll, shouldRecreateSession, recreateReason }, 'forced new session for retry recp');
|
|
577
789
|
for (const [i, msg] of msgs.entries()) {
|
|
578
|
-
if (
|
|
790
|
+
if (!ids[i])
|
|
791
|
+
continue;
|
|
792
|
+
if (msg && (await willSendMessageAgain(ids[i], participant))) {
|
|
579
793
|
updateSendMessageAgainCount(ids[i], participant);
|
|
580
794
|
const msgRelayOpts = { messageId: ids[i] };
|
|
581
795
|
if (sendToAll) {
|
|
@@ -595,11 +809,10 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
595
809
|
}
|
|
596
810
|
};
|
|
597
811
|
const handleReceipt = async (node) => {
|
|
598
|
-
var _a, _b;
|
|
599
812
|
const { attrs, content } = node;
|
|
600
813
|
const isLid = attrs.from.includes('lid');
|
|
601
|
-
const isNodeFromMe =
|
|
602
|
-
const remoteJid = !isNodeFromMe ||
|
|
814
|
+
const isNodeFromMe = areJidsSameUser(attrs.participant || attrs.from, isLid ? authState.creds.me?.lid : authState.creds.me?.id);
|
|
815
|
+
const remoteJid = !isNodeFromMe || isJidGroup(attrs.from) ? attrs.from : attrs.recipient;
|
|
603
816
|
const fromMe = !attrs.recipient || ((attrs.type === 'retry' || attrs.type === 'sender') && isNodeFromMe);
|
|
604
817
|
const key = {
|
|
605
818
|
remoteJid,
|
|
@@ -607,33 +820,31 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
607
820
|
fromMe,
|
|
608
821
|
participant: attrs.participant
|
|
609
822
|
};
|
|
610
|
-
if (shouldIgnoreJid(remoteJid) && remoteJid !==
|
|
823
|
+
if (shouldIgnoreJid(remoteJid) && remoteJid !== S_WHATSAPP_NET) {
|
|
611
824
|
logger.debug({ remoteJid }, 'ignoring receipt from jid');
|
|
612
825
|
await sendMessageAck(node);
|
|
613
826
|
return;
|
|
614
827
|
}
|
|
615
828
|
const ids = [attrs.id];
|
|
616
829
|
if (Array.isArray(content)) {
|
|
617
|
-
const items =
|
|
830
|
+
const items = getBinaryNodeChildren(content[0], 'item');
|
|
618
831
|
ids.push(...items.map(i => i.attrs.id));
|
|
619
832
|
}
|
|
620
833
|
try {
|
|
621
834
|
await Promise.all([
|
|
622
835
|
processingMutex.mutex(async () => {
|
|
623
|
-
const status =
|
|
836
|
+
const status = getStatusFromReceiptType(attrs.type);
|
|
624
837
|
if (typeof status !== 'undefined' &&
|
|
625
|
-
(
|
|
626
838
|
// basically, we only want to know when a message from us has been delivered to/read by the other person
|
|
627
839
|
// or another device of ours has read some messages
|
|
628
|
-
status >=
|
|
629
|
-
|
|
630
|
-
if ((0, WABinary_1.isJidGroup)(remoteJid) || (0, WABinary_1.isJidStatusBroadcast)(remoteJid)) {
|
|
840
|
+
(status >= proto.WebMessageInfo.Status.SERVER_ACK || !isNodeFromMe)) {
|
|
841
|
+
if (isJidGroup(remoteJid) || isJidStatusBroadcast(remoteJid)) {
|
|
631
842
|
if (attrs.participant) {
|
|
632
|
-
const updateKey = status ===
|
|
843
|
+
const updateKey = status === proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
|
|
633
844
|
ev.emit('message-receipt.update', ids.map(id => ({
|
|
634
845
|
key: { ...key, id },
|
|
635
846
|
receipt: {
|
|
636
|
-
userJid:
|
|
847
|
+
userJid: jidNormalizedUser(attrs.participant),
|
|
637
848
|
[updateKey]: +attrs.t
|
|
638
849
|
}
|
|
639
850
|
})));
|
|
@@ -649,15 +860,16 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
649
860
|
if (attrs.type === 'retry') {
|
|
650
861
|
// correctly set who is asking for the retry
|
|
651
862
|
key.participant = key.participant || attrs.from;
|
|
652
|
-
const retryNode =
|
|
653
|
-
if (willSendMessageAgain(ids[0], key.participant)) {
|
|
863
|
+
const retryNode = getBinaryNodeChild(node, 'retry');
|
|
864
|
+
if (ids[0] && key.participant && (await willSendMessageAgain(ids[0], key.participant))) {
|
|
654
865
|
if (key.fromMe) {
|
|
655
866
|
try {
|
|
867
|
+
updateSendMessageAgainCount(ids[0], key.participant);
|
|
656
868
|
logger.debug({ attrs, key }, 'recv retry request');
|
|
657
869
|
await sendMessagesAgain(key, ids, retryNode);
|
|
658
870
|
}
|
|
659
871
|
catch (error) {
|
|
660
|
-
logger.error({ key, ids, trace: error.stack }, 'error in sending message again');
|
|
872
|
+
logger.error({ key, ids, trace: error instanceof Error ? error.stack : 'Unknown error' }, 'error in sending message again');
|
|
661
873
|
}
|
|
662
874
|
}
|
|
663
875
|
else {
|
|
@@ -677,7 +889,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
677
889
|
};
|
|
678
890
|
const handleNotification = async (node) => {
|
|
679
891
|
const remoteJid = node.attrs.from;
|
|
680
|
-
if (shouldIgnoreJid(remoteJid) && remoteJid !==
|
|
892
|
+
if (shouldIgnoreJid(remoteJid) && remoteJid !== S_WHATSAPP_NET) {
|
|
681
893
|
logger.debug({ remoteJid, id: node.attrs.id }, 'ignored notification');
|
|
682
894
|
await sendMessageAck(node);
|
|
683
895
|
return;
|
|
@@ -685,20 +897,22 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
685
897
|
try {
|
|
686
898
|
await Promise.all([
|
|
687
899
|
processingMutex.mutex(async () => {
|
|
688
|
-
var _a;
|
|
689
900
|
const msg = await processNotification(node);
|
|
690
901
|
if (msg) {
|
|
691
|
-
const fromMe =
|
|
902
|
+
const fromMe = areJidsSameUser(node.attrs.participant || remoteJid, authState.creds.me.id);
|
|
903
|
+
const { senderAlt: participantAlt, addressingMode } = extractAddressingContext(node);
|
|
692
904
|
msg.key = {
|
|
693
905
|
remoteJid,
|
|
694
906
|
fromMe,
|
|
695
907
|
participant: node.attrs.participant,
|
|
908
|
+
participantAlt,
|
|
909
|
+
addressingMode,
|
|
696
910
|
id: node.attrs.id,
|
|
697
911
|
...(msg.key || {})
|
|
698
912
|
};
|
|
699
|
-
|
|
913
|
+
msg.participant ?? (msg.participant = node.attrs.participant);
|
|
700
914
|
msg.messageTimestamp = +node.attrs.t;
|
|
701
|
-
const fullMsg =
|
|
915
|
+
const fullMsg = proto.WebMessageInfo.fromObject(msg);
|
|
702
916
|
await upsertMessage(fullMsg, 'append');
|
|
703
917
|
}
|
|
704
918
|
})
|
|
@@ -709,204 +923,152 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
709
923
|
}
|
|
710
924
|
};
|
|
711
925
|
const handleMessage = async (node) => {
|
|
712
|
-
|
|
713
|
-
if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !== '@s.whatsapp.net') {
|
|
926
|
+
if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !== S_WHATSAPP_NET) {
|
|
714
927
|
logger.debug({ key: node.attrs.key }, 'ignored message');
|
|
715
|
-
await sendMessageAck(node);
|
|
928
|
+
await sendMessageAck(node, NACK_REASONS.UnhandledError);
|
|
716
929
|
return;
|
|
717
930
|
}
|
|
718
|
-
const encNode =
|
|
931
|
+
const encNode = getBinaryNodeChild(node, 'enc');
|
|
719
932
|
// TODO: temporary fix for crashes and issues resulting of failed msmsg decryption
|
|
720
933
|
if (encNode && encNode.attrs.type === 'msmsg') {
|
|
721
934
|
logger.debug({ key: node.attrs.key }, 'ignored msmsg');
|
|
722
|
-
await sendMessageAck(node);
|
|
935
|
+
await sendMessageAck(node, NACK_REASONS.MissingMessageSecret);
|
|
723
936
|
return;
|
|
724
937
|
}
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
938
|
+
const { fullMessage: msg, category, author, decrypt } = decryptMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger);
|
|
939
|
+
const alt = msg.key.participantAlt || msg.key.remoteJidAlt;
|
|
940
|
+
// store new mappings we didn't have before
|
|
941
|
+
if (!!alt) {
|
|
942
|
+
const altServer = jidDecode(alt)?.server;
|
|
943
|
+
const primaryJid = msg.key.participant || msg.key.remoteJid;
|
|
944
|
+
if (altServer === 'lid') {
|
|
945
|
+
if (!(await signalRepository.lidMapping.getPNForLID(alt))) {
|
|
946
|
+
await signalRepository.lidMapping.storeLIDPNMappings([{ lid: alt, pn: primaryJid }]);
|
|
947
|
+
await signalRepository.migrateSession(primaryJid, alt);
|
|
948
|
+
}
|
|
732
949
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
if (placeholderResendCache.get(node.attrs.id)) {
|
|
737
|
-
placeholderResendCache.del(node.attrs.id);
|
|
950
|
+
else {
|
|
951
|
+
await signalRepository.lidMapping.storeLIDPNMappings([{ lid: primaryJid, pn: alt }]);
|
|
952
|
+
await signalRepository.migrateSession(alt, primaryJid);
|
|
738
953
|
}
|
|
739
954
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
955
|
+
if (msg.key?.remoteJid && msg.key?.id && messageRetryManager) {
|
|
956
|
+
messageRetryManager.addRecentMessage(msg.key.remoteJid, msg.key.id, msg.message);
|
|
957
|
+
logger.debug({
|
|
958
|
+
jid: msg.key.remoteJid,
|
|
959
|
+
id: msg.key.id
|
|
960
|
+
}, 'Added message to recent cache for retry receipts');
|
|
746
961
|
}
|
|
747
962
|
try {
|
|
748
|
-
await
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
963
|
+
await processingMutex.mutex(async () => {
|
|
964
|
+
await decrypt();
|
|
965
|
+
// message failed to decrypt
|
|
966
|
+
if (msg.messageStubType === proto.WebMessageInfo.StubType.CIPHERTEXT) {
|
|
967
|
+
if (msg?.messageStubParameters?.[0] === MISSING_KEYS_ERROR_TEXT) {
|
|
968
|
+
return sendMessageAck(node, NACK_REASONS.ParsingError);
|
|
969
|
+
}
|
|
970
|
+
const errorMessage = msg?.messageStubParameters?.[0] || '';
|
|
971
|
+
const isPreKeyError = errorMessage.includes('PreKey');
|
|
972
|
+
logger.debug(`[handleMessage] Attempting retry request for failed decryption`);
|
|
973
|
+
// Handle both pre-key and normal retries in single mutex
|
|
974
|
+
retryMutex.mutex(async () => {
|
|
975
|
+
try {
|
|
976
|
+
if (!ws.isOpen) {
|
|
977
|
+
logger.debug({ node }, 'Connection closed, skipping retry');
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
// Handle pre-key errors with upload and delay
|
|
981
|
+
if (isPreKeyError) {
|
|
982
|
+
logger.info({ error: errorMessage }, 'PreKey error detected, uploading and retrying');
|
|
983
|
+
try {
|
|
984
|
+
logger.debug('Uploading pre-keys for error recovery');
|
|
985
|
+
await uploadPreKeys(5);
|
|
986
|
+
logger.debug('Waiting for server to process new pre-keys');
|
|
987
|
+
await delay(1000);
|
|
761
988
|
}
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
if (retryRequestDelayMs) {
|
|
765
|
-
await (0, Utils_1.delay)(retryRequestDelayMs);
|
|
989
|
+
catch (uploadErr) {
|
|
990
|
+
logger.error({ uploadErr }, 'Pre-key upload failed, proceeding with retry anyway');
|
|
766
991
|
}
|
|
767
992
|
}
|
|
768
|
-
|
|
769
|
-
|
|
993
|
+
const encNode = getBinaryNodeChild(node, 'enc');
|
|
994
|
+
await sendRetryRequest(node, !encNode);
|
|
995
|
+
if (retryRequestDelayMs) {
|
|
996
|
+
await delay(retryRequestDelayMs);
|
|
770
997
|
}
|
|
771
|
-
});
|
|
772
|
-
}
|
|
773
|
-
else {
|
|
774
|
-
// no type in the receipt => message delivered
|
|
775
|
-
let type = undefined;
|
|
776
|
-
if ((_b = msg.key.participant) === null || _b === void 0 ? void 0 : _b.endsWith('@lid')) {
|
|
777
|
-
msg.key.participant = node.attrs.participant_pn || authState.creds.me.id;
|
|
778
998
|
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
const
|
|
784
|
-
|
|
999
|
+
catch (err) {
|
|
1000
|
+
logger.error({ err, isPreKeyError }, 'Failed to handle retry, attempting basic retry');
|
|
1001
|
+
// Still attempt retry even if pre-key upload failed
|
|
1002
|
+
try {
|
|
1003
|
+
const encNode = getBinaryNodeChild(node, 'enc');
|
|
1004
|
+
await sendRetryRequest(node, !encNode);
|
|
785
1005
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
msg.key.remoteJid = node.attrs.sender_pn || node.attrs.peer_recipient_pn;
|
|
789
|
-
}
|
|
790
|
-
let participant = msg.key.participant;
|
|
791
|
-
if (category === 'peer') { // special peer message
|
|
792
|
-
type = 'peer_msg';
|
|
793
|
-
}
|
|
794
|
-
else if (msg.key.fromMe) { // message was sent by us from a different device
|
|
795
|
-
type = 'sender';
|
|
796
|
-
// need to specially handle this case
|
|
797
|
-
if ((0, WABinary_1.isJidUser)(msg.key.remoteJid)) {
|
|
798
|
-
participant = author;
|
|
1006
|
+
catch (retryErr) {
|
|
1007
|
+
logger.error({ retryErr }, 'Failed to send retry after error handling');
|
|
799
1008
|
}
|
|
800
1009
|
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
1010
|
+
await sendMessageAck(node, NACK_REASONS.UnhandledError);
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
else {
|
|
1014
|
+
// no type in the receipt => message delivered
|
|
1015
|
+
let type = undefined;
|
|
1016
|
+
let participant = msg.key.participant;
|
|
1017
|
+
if (category === 'peer') {
|
|
1018
|
+
// special peer message
|
|
1019
|
+
type = 'peer_msg';
|
|
1020
|
+
}
|
|
1021
|
+
else if (msg.key.fromMe) {
|
|
1022
|
+
// message was sent by us from a different device
|
|
1023
|
+
type = 'sender';
|
|
1024
|
+
// need to specially handle this case
|
|
1025
|
+
if (isLidUser(msg.key.remoteJid) || isLidUser(msg.key.remoteJidAlt)) {
|
|
1026
|
+
participant = author; // TODO: investigate sending receipts to LIDs and not PNs
|
|
810
1027
|
}
|
|
811
1028
|
}
|
|
812
|
-
(
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
1029
|
+
else if (!sendActiveReceipts) {
|
|
1030
|
+
type = 'inactive';
|
|
1031
|
+
}
|
|
1032
|
+
await sendReceipt(msg.key.remoteJid, participant, [msg.key.id], type);
|
|
1033
|
+
// send ack for history message
|
|
1034
|
+
const isAnyHistoryMsg = getHistoryMsg(msg.message);
|
|
1035
|
+
if (isAnyHistoryMsg) {
|
|
1036
|
+
const jid = jidNormalizedUser(msg.key.remoteJid);
|
|
1037
|
+
await sendReceipt(jid, undefined, [msg.key.id], 'hist_sync');
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
cleanMessage(msg, authState.creds.me.id, authState.creds.me.lid);
|
|
1041
|
+
await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify');
|
|
1042
|
+
});
|
|
817
1043
|
}
|
|
818
1044
|
catch (error) {
|
|
819
|
-
logger.error({ error, node }, 'error in handling message');
|
|
1045
|
+
logger.error({ error, node: binaryNodeToString(node) }, 'error in handling message');
|
|
820
1046
|
}
|
|
821
1047
|
};
|
|
822
|
-
const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
|
|
823
|
-
var _a;
|
|
824
|
-
if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
825
|
-
throw new boom_1.Boom('Not authenticated');
|
|
826
|
-
}
|
|
827
|
-
const pdoMessage = {
|
|
828
|
-
historySyncOnDemandRequest: {
|
|
829
|
-
chatJid: oldestMsgKey.remoteJid,
|
|
830
|
-
oldestMsgFromMe: oldestMsgKey.fromMe,
|
|
831
|
-
oldestMsgId: oldestMsgKey.id,
|
|
832
|
-
oldestMsgTimestampMs: oldestMsgTimestamp,
|
|
833
|
-
onDemandMsgCount: count
|
|
834
|
-
},
|
|
835
|
-
peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
|
|
836
|
-
};
|
|
837
|
-
return sendPeerDataOperationMessage(pdoMessage);
|
|
838
|
-
};
|
|
839
|
-
const requestPlaceholderResend = async (messageKey) => {
|
|
840
|
-
var _a;
|
|
841
|
-
if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
842
|
-
throw new boom_1.Boom('Not authenticated');
|
|
843
|
-
}
|
|
844
|
-
if (placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
|
|
845
|
-
logger.debug({ messageKey }, 'already requested resend');
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
else {
|
|
849
|
-
placeholderResendCache.set(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id, true);
|
|
850
|
-
}
|
|
851
|
-
await (0, Utils_1.delay)(5000);
|
|
852
|
-
if (!placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
|
|
853
|
-
logger.debug({ messageKey }, 'message received while resend requested');
|
|
854
|
-
return 'RESOLVED';
|
|
855
|
-
}
|
|
856
|
-
const pdoMessage = {
|
|
857
|
-
placeholderMessageResendRequest: [{
|
|
858
|
-
messageKey
|
|
859
|
-
}],
|
|
860
|
-
peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
|
|
861
|
-
};
|
|
862
|
-
setTimeout(() => {
|
|
863
|
-
if (placeholderResendCache.get(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id)) {
|
|
864
|
-
logger.debug({ messageKey }, 'PDO message without response after 15 seconds. Phone possibly offline');
|
|
865
|
-
placeholderResendCache.del(messageKey === null || messageKey === void 0 ? void 0 : messageKey.id);
|
|
866
|
-
}
|
|
867
|
-
}, 15000);
|
|
868
|
-
return sendPeerDataOperationMessage(pdoMessage);
|
|
869
|
-
};
|
|
870
1048
|
const handleCall = async (node) => {
|
|
871
|
-
let status;
|
|
872
1049
|
const { attrs } = node;
|
|
873
|
-
const [infoChild] =
|
|
1050
|
+
const [infoChild] = getAllBinaryNodeChildren(node);
|
|
1051
|
+
const status = getCallStatusFromNode(infoChild);
|
|
874
1052
|
if (!infoChild) {
|
|
875
|
-
throw new
|
|
1053
|
+
throw new Boom('Missing call info in call node');
|
|
876
1054
|
}
|
|
877
1055
|
const callId = infoChild.attrs['call-id'];
|
|
878
1056
|
const from = infoChild.attrs.from || infoChild.attrs['call-creator'];
|
|
879
|
-
status = (0, Utils_1.getCallStatusFromNode)(infoChild);
|
|
880
|
-
if ((0, WABinary_1.isLidUser)(from) && infoChild.tag === 'relaylatency') {
|
|
881
|
-
const verify = callOfferCache.get(callId);
|
|
882
|
-
if (!verify) {
|
|
883
|
-
status = 'offer';
|
|
884
|
-
const callLid = {
|
|
885
|
-
chatId: attrs.from,
|
|
886
|
-
from,
|
|
887
|
-
id: callId,
|
|
888
|
-
date: new Date(+attrs.t * 1000),
|
|
889
|
-
offline: !!attrs.offline,
|
|
890
|
-
status
|
|
891
|
-
};
|
|
892
|
-
callOfferCache.set(callId, callLid);
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
1057
|
const call = {
|
|
896
1058
|
chatId: attrs.from,
|
|
897
1059
|
from,
|
|
898
1060
|
id: callId,
|
|
899
1061
|
date: new Date(+attrs.t * 1000),
|
|
900
1062
|
offline: !!attrs.offline,
|
|
901
|
-
status
|
|
1063
|
+
status
|
|
902
1064
|
};
|
|
903
1065
|
if (status === 'offer') {
|
|
904
|
-
call.isVideo = !!
|
|
1066
|
+
call.isVideo = !!getBinaryNodeChild(infoChild, 'video');
|
|
905
1067
|
call.isGroup = infoChild.attrs.type === 'group' || !!infoChild.attrs['group-jid'];
|
|
906
1068
|
call.groupJid = infoChild.attrs['group-jid'];
|
|
907
|
-
callOfferCache.set(call.id, call);
|
|
1069
|
+
await callOfferCache.set(call.id, call);
|
|
908
1070
|
}
|
|
909
|
-
const existingCall = callOfferCache.get(call.id);
|
|
1071
|
+
const existingCall = await callOfferCache.get(call.id);
|
|
910
1072
|
// use existing call info to populate this event
|
|
911
1073
|
if (existingCall) {
|
|
912
1074
|
call.isVideo = existingCall.isVideo;
|
|
@@ -914,34 +1076,26 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
914
1076
|
}
|
|
915
1077
|
// delete data once call has ended
|
|
916
1078
|
if (status === 'reject' || status === 'accept' || status === 'timeout' || status === 'terminate') {
|
|
917
|
-
callOfferCache.del(call.id);
|
|
1079
|
+
await callOfferCache.del(call.id);
|
|
918
1080
|
}
|
|
919
1081
|
ev.emit('call', [call]);
|
|
920
1082
|
await sendMessageAck(node);
|
|
921
1083
|
};
|
|
922
1084
|
const handleBadAck = async ({ attrs }) => {
|
|
923
|
-
const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id
|
|
924
|
-
//
|
|
925
|
-
//
|
|
926
|
-
//
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
if (msg) {
|
|
938
|
-
await relayMessage(key.remoteJid, msg, { messageId: key.id, useUserDevicesCache: false });
|
|
939
|
-
msgRetryCache.set(cacheKey, retryCount + 1);
|
|
940
|
-
}
|
|
941
|
-
else {
|
|
942
|
-
logger.warn({ attrs }, 'could not send message again, as it was not found');
|
|
943
|
-
}
|
|
944
|
-
}
|
|
1085
|
+
const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id };
|
|
1086
|
+
// WARNING: REFRAIN FROM ENABLING THIS FOR NOW. IT WILL CAUSE A LOOP
|
|
1087
|
+
// // current hypothesis is that if pash is sent in the ack
|
|
1088
|
+
// // it means -- the message hasn't reached all devices yet
|
|
1089
|
+
// // we'll retry sending the message here
|
|
1090
|
+
// if(attrs.phash) {
|
|
1091
|
+
// logger.info({ attrs }, 'received phash in ack, resending message...')
|
|
1092
|
+
// const msg = await getMessage(key)
|
|
1093
|
+
// if(msg) {
|
|
1094
|
+
// await relayMessage(key.remoteJid!, msg, { messageId: key.id!, useUserDevicesCache: false })
|
|
1095
|
+
// } else {
|
|
1096
|
+
// logger.warn({ attrs }, 'could not send message again, as it was not found')
|
|
1097
|
+
// }
|
|
1098
|
+
// }
|
|
945
1099
|
// error in acknowledgement,
|
|
946
1100
|
// device could not display the message
|
|
947
1101
|
if (attrs.error) {
|
|
@@ -950,10 +1104,8 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
950
1104
|
{
|
|
951
1105
|
key,
|
|
952
1106
|
update: {
|
|
953
|
-
status:
|
|
954
|
-
messageStubParameters: [
|
|
955
|
-
attrs.error
|
|
956
|
-
]
|
|
1107
|
+
status: WAMessageStatus.ERROR,
|
|
1108
|
+
messageStubParameters: [attrs.error]
|
|
957
1109
|
}
|
|
958
1110
|
}
|
|
959
1111
|
]);
|
|
@@ -966,8 +1118,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
966
1118
|
await execTask();
|
|
967
1119
|
ev.flush();
|
|
968
1120
|
function execTask() {
|
|
969
|
-
return exec(node, false)
|
|
970
|
-
.catch(err => onUnexpectedError(err, identifier));
|
|
1121
|
+
return exec(node, false).catch(err => onUnexpectedError(err, identifier));
|
|
971
1122
|
}
|
|
972
1123
|
};
|
|
973
1124
|
const makeOfflineNodeProcessor = () => {
|
|
@@ -1025,10 +1176,12 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1025
1176
|
processNode('notification', node, 'handling notification', handleNotification);
|
|
1026
1177
|
});
|
|
1027
1178
|
ws.on('CB:ack,class:message', (node) => {
|
|
1028
|
-
handleBadAck(node)
|
|
1029
|
-
.catch(error => onUnexpectedError(error, 'handling bad ack'));
|
|
1179
|
+
handleBadAck(node).catch(error => onUnexpectedError(error, 'handling bad ack'));
|
|
1030
1180
|
});
|
|
1031
1181
|
ev.on('call', ([call]) => {
|
|
1182
|
+
if (!call) {
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1032
1185
|
// missed call + group call notification message generation
|
|
1033
1186
|
if (call.status === 'timeout' || (call.status === 'offer' && call.isGroup)) {
|
|
1034
1187
|
const msg = {
|
|
@@ -1037,20 +1190,22 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1037
1190
|
id: call.id,
|
|
1038
1191
|
fromMe: false
|
|
1039
1192
|
},
|
|
1040
|
-
messageTimestamp:
|
|
1193
|
+
messageTimestamp: unixTimestampSeconds(call.date)
|
|
1041
1194
|
};
|
|
1042
1195
|
if (call.status === 'timeout') {
|
|
1043
1196
|
if (call.isGroup) {
|
|
1044
|
-
msg.messageStubType = call.isVideo
|
|
1197
|
+
msg.messageStubType = call.isVideo
|
|
1198
|
+
? WAMessageStubType.CALL_MISSED_GROUP_VIDEO
|
|
1199
|
+
: WAMessageStubType.CALL_MISSED_GROUP_VOICE;
|
|
1045
1200
|
}
|
|
1046
1201
|
else {
|
|
1047
|
-
msg.messageStubType = call.isVideo ?
|
|
1202
|
+
msg.messageStubType = call.isVideo ? WAMessageStubType.CALL_MISSED_VIDEO : WAMessageStubType.CALL_MISSED_VOICE;
|
|
1048
1203
|
}
|
|
1049
1204
|
}
|
|
1050
1205
|
else {
|
|
1051
1206
|
msg.message = { call: { callKey: Buffer.from(call.id) } };
|
|
1052
1207
|
}
|
|
1053
|
-
const protoMsg =
|
|
1208
|
+
const protoMsg = proto.WebMessageInfo.fromObject(msg);
|
|
1054
1209
|
upsertMessage(protoMsg, call.offline ? 'append' : 'notify');
|
|
1055
1210
|
}
|
|
1056
1211
|
});
|
|
@@ -1065,9 +1220,9 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1065
1220
|
sendMessageAck,
|
|
1066
1221
|
sendRetryRequest,
|
|
1067
1222
|
rejectCall,
|
|
1068
|
-
offerCall,
|
|
1069
1223
|
fetchMessageHistory,
|
|
1070
1224
|
requestPlaceholderResend,
|
|
1225
|
+
messageRetryManager
|
|
1071
1226
|
};
|
|
1072
1227
|
};
|
|
1073
|
-
|
|
1228
|
+
//# sourceMappingURL=messages-recv.js.map
|