@neelegirl/baileys 1.5.3 → 1.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +195 -195
- package/WAProto/GenerateStatics.sh +3 -0
- package/WAProto/WAProto.proto +478 -1153
- package/WAProto/fix-imports.js +29 -0
- package/WAProto/index.d.ts +2645 -51971
- package/WAProto/index.js +48649 -154035
- package/engine-requirements.js +10 -0
- package/lib/Defaults/index.d.ts +62 -78
- package/lib/Defaults/index.d.ts.map +1 -0
- package/lib/Defaults/index.js +115 -149
- package/lib/Defaults/index.js.map +1 -0
- package/lib/Signal/Group/ciphertext-message.d.ts +10 -0
- package/lib/Signal/Group/ciphertext-message.d.ts.map +1 -0
- package/lib/Signal/Group/ciphertext-message.js +12 -0
- package/lib/Signal/Group/ciphertext-message.js.map +1 -0
- package/lib/Signal/{WASignalGroup → 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 +30 -0
- package/lib/Signal/Group/group-session-builder.js.map +1 -0
- package/lib/Signal/Group/group_cipher.d.ts +17 -0
- package/lib/Signal/Group/group_cipher.d.ts.map +1 -0
- package/lib/Signal/{WASignalGroup → Group}/group_cipher.js +41 -70
- package/lib/Signal/Group/group_cipher.js.map +1 -0
- package/lib/Signal/Group/index.d.ts +12 -0
- package/lib/Signal/Group/index.d.ts.map +1 -0
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/index.js.map +1 -0
- package/lib/Signal/Group/keyhelper.d.ts +11 -0
- package/lib/Signal/Group/keyhelper.d.ts.map +1 -0
- package/lib/Signal/Group/keyhelper.js +18 -0
- package/lib/Signal/Group/keyhelper.js.map +1 -0
- package/lib/Signal/Group/sender-chain-key.d.ts +14 -0
- package/lib/Signal/Group/sender-chain-key.d.ts.map +1 -0
- package/lib/Signal/Group/sender-chain-key.js +26 -0
- package/lib/Signal/Group/sender-chain-key.js.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +17 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
- package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-message.d.ts +19 -0
- package/lib/Signal/Group/sender-key-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-message.js +66 -0
- package/lib/Signal/Group/sender-key-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-name.d.ts +18 -0
- package/lib/Signal/Group/sender-key-name.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-name.js +48 -0
- package/lib/Signal/Group/sender-key-name.js.map +1 -0
- package/lib/Signal/Group/sender-key-record.d.ts +31 -0
- package/lib/Signal/Group/sender-key-record.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-record.js +41 -0
- package/lib/Signal/Group/sender-key-record.js.map +1 -0
- package/lib/Signal/Group/sender-key-state.d.ts +39 -0
- package/lib/Signal/Group/sender-key-state.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-state.js +84 -0
- package/lib/Signal/Group/sender-key-state.js.map +1 -0
- package/lib/Signal/Group/sender-message-key.d.ts +12 -0
- package/lib/Signal/Group/sender-message-key.d.ts.map +1 -0
- package/lib/Signal/{WASignalGroup/sender_message_key.js → Group/sender-message-key.js} +26 -39
- 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 +342 -391
- 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 +171 -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 +24 -36
- package/lib/Socket/Client/websocket.js.map +1 -0
- package/lib/Socket/business.d.ts +178 -177
- package/lib/Socket/business.d.ts.map +1 -0
- package/lib/Socket/business.js +81 -120
- package/lib/Socket/business.js.map +1 -0
- package/lib/Socket/chats.d.ts +93 -92
- package/lib/Socket/chats.d.ts.map +1 -0
- package/lib/Socket/chats.js +462 -618
- package/lib/Socket/chats.js.map +1 -0
- package/lib/Socket/communities.d.ts +244 -223
- package/lib/Socket/communities.d.ts.map +1 -0
- package/lib/Socket/communities.js +431 -433
- package/lib/Socket/communities.js.map +1 -0
- package/lib/Socket/groups.d.ts +118 -110
- package/lib/Socket/groups.d.ts.map +1 -0
- package/lib/Socket/groups.js +148 -181
- package/lib/Socket/groups.js.map +1 -0
- package/lib/Socket/index.d.ts +222 -182
- package/lib/Socket/index.d.ts.map +1 -0
- package/lib/Socket/index.js +12 -18
- package/lib/Socket/index.js.map +1 -0
- package/lib/Socket/messages-recv.d.ts +165 -166
- package/lib/Socket/messages-recv.d.ts.map +1 -0
- package/lib/Socket/messages-recv.js +753 -1031
- package/lib/Socket/messages-recv.js.map +1 -0
- package/lib/Socket/messages-send.d.ts +161 -157
- package/lib/Socket/messages-send.d.ts.map +1 -0
- package/lib/Socket/messages-send.js +564 -1396
- package/lib/Socket/messages-send.js.map +1 -0
- package/lib/Socket/mex.d.ts +3 -2
- package/lib/Socket/mex.d.ts.map +1 -0
- package/lib/Socket/mex.js +42 -47
- package/lib/Socket/mex.js.map +1 -0
- package/lib/Socket/newsletter.d.ts +139 -137
- package/lib/Socket/newsletter.d.ts.map +1 -0
- package/lib/Socket/newsletter.js +181 -295
- package/lib/Socket/newsletter.js.map +1 -0
- package/lib/Socket/socket.d.ts +42 -36
- package/lib/Socket/socket.d.ts.map +1 -0
- package/lib/Socket/socket.js +487 -557
- package/lib/Socket/socket.js.map +1 -0
- package/lib/Types/Auth.d.ts +87 -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 +13 -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 +77 -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 +10 -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 +151 -175
- 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 +49 -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 +231 -412
- package/lib/Types/Message.d.ts.map +1 -0
- package/lib/Types/Message.js +11 -19
- package/lib/Types/Message.js.map +1 -0
- package/lib/Types/Newsletter.d.ts +130 -104
- package/lib/Types/Newsletter.d.ts.map +1 -0
- package/lib/Types/Newsletter.js +31 -40
- package/lib/Types/Newsletter.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/Signal.d.ts +60 -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 +73 -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 +17 -19
- package/lib/Types/State.d.ts.map +1 -0
- package/lib/Types/State.js +13 -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 +19 -21
- package/lib/Utils/auth-utils.d.ts.map +1 -0
- package/lib/Utils/auth-utils.js +257 -528
- package/lib/Utils/auth-utils.js.map +1 -0
- package/lib/Utils/baileys-event-stream.d.ts +17 -18
- package/lib/Utils/baileys-event-stream.d.ts.map +1 -0
- package/lib/Utils/baileys-event-stream.js +56 -70
- 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 +23 -29
- package/lib/Utils/business.d.ts.map +1 -0
- package/lib/Utils/business.js +231 -255
- package/lib/Utils/business.js.map +1 -0
- package/lib/Utils/chat-utils.d.ts +70 -82
- package/lib/Utils/chat-utils.d.ts.map +1 -0
- package/lib/Utils/chat-utils.js +763 -809
- package/lib/Utils/chat-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +41 -56
- package/lib/Utils/crypto.d.ts.map +1 -0
- package/lib/Utils/crypto.js +142 -189
- package/lib/Utils/crypto.js.map +1 -0
- package/lib/Utils/decode-wa-message.d.ts +48 -53
- package/lib/Utils/decode-wa-message.d.ts.map +1 -0
- package/lib/Utils/decode-wa-message.js +279 -323
- package/lib/Utils/decode-wa-message.js.map +1 -0
- package/lib/Utils/event-buffer.d.ts +34 -39
- package/lib/Utils/event-buffer.d.ts.map +1 -0
- package/lib/Utils/event-buffer.js +548 -595
- package/lib/Utils/event-buffer.js.map +1 -0
- package/lib/Utils/generics.d.ts +90 -131
- package/lib/Utils/generics.d.ts.map +1 -0
- package/lib/Utils/generics.js +381 -630
- package/lib/Utils/generics.js.map +1 -0
- package/lib/Utils/history.d.ts +19 -23
- package/lib/Utils/history.d.ts.map +1 -0
- package/lib/Utils/history.js +84 -104
- package/lib/Utils/history.js.map +1 -0
- package/lib/Utils/index.d.ts +20 -20
- package/lib/Utils/index.d.ts.map +1 -0
- package/lib/Utils/index.js +19 -40
- package/lib/Utils/index.js.map +1 -0
- package/lib/Utils/link-preview.d.ts +21 -23
- package/lib/Utils/link-preview.d.ts.map +1 -0
- package/lib/Utils/link-preview.js +85 -120
- package/lib/Utils/link-preview.js.map +1 -0
- package/lib/Utils/logger.d.ts +12 -13
- 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 +13 -14
- package/lib/Utils/lt-hash.d.ts.map +1 -0
- package/lib/Utils/lt-hash.js +48 -58
- package/lib/Utils/lt-hash.js.map +1 -0
- package/lib/Utils/make-mutex.d.ts +8 -9
- package/lib/Utils/make-mutex.d.ts.map +1 -0
- package/lib/Utils/make-mutex.js +40 -49
- package/lib/Utils/make-mutex.js.map +1 -0
- package/lib/Utils/message-retry-manager.d.ts +82 -88
- package/lib/Utils/message-retry-manager.d.ts.map +1 -0
- package/lib/Utils/message-retry-manager.js +149 -160
- package/lib/Utils/message-retry-manager.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +114 -135
- package/lib/Utils/messages-media.d.ts.map +1 -0
- package/lib/Utils/messages-media.js +663 -869
- package/lib/Utils/messages-media.js.map +1 -0
- package/lib/Utils/messages.d.ts +76 -105
- package/lib/Utils/messages.d.ts.map +1 -0
- package/lib/Utils/messages.js +820 -1745
- package/lib/Utils/messages.js.map +1 -0
- package/lib/Utils/noise-handler.d.ts +20 -21
- package/lib/Utils/noise-handler.d.ts.map +1 -0
- package/lib/Utils/noise-handler.js +147 -165
- 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 +42 -49
- package/lib/Utils/process-message.d.ts.map +1 -0
- package/lib/Utils/process-message.js +413 -427
- package/lib/Utils/process-message.js.map +1 -0
- package/lib/Utils/signal.d.ts +34 -42
- package/lib/Utils/signal.d.ts.map +1 -0
- package/lib/Utils/signal.js +159 -166
- package/lib/Utils/signal.js.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts +13 -18
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +121 -238
- package/lib/Utils/use-multi-file-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 +195 -220
- package/lib/Utils/validate-connection.js.map +1 -0
- package/lib/WABinary/constants.d.ts +28 -30
- package/lib/WABinary/constants.d.ts.map +1 -0
- package/lib/WABinary/constants.js +1301 -1316
- 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 +238 -288
- 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 +216 -265
- package/lib/WABinary/encode.js.map +1 -0
- package/lib/WABinary/generic-utils.d.ts +15 -28
- package/lib/WABinary/generic-utils.d.ts.map +1 -0
- package/lib/WABinary/generic-utils.js +102 -142
- 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 +48 -58
- package/lib/WABinary/jid-utils.d.ts.map +1 -0
- package/lib/WABinary/jid-utils.js +96 -104
- package/lib/WABinary/jid-utils.js.map +1 -0
- package/lib/WABinary/types.d.ts +19 -22
- 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 +9 -16
- package/lib/WAM/BinaryInfo.d.ts.map +1 -0
- package/lib/WAM/BinaryInfo.js +10 -17
- package/lib/WAM/BinaryInfo.js.map +1 -0
- package/lib/WAM/constants.d.ts +40 -47
- package/lib/WAM/constants.d.ts.map +1 -0
- package/lib/WAM/constants.js +22853 -15371
- 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 +150 -164
- 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 +12 -19
- 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/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 +5 -6
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/index.js +5 -26
- package/lib/WAUSync/Protocols/index.js.map +1 -0
- package/lib/WAUSync/USyncQuery.d.ts +26 -28
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
- package/lib/WAUSync/USyncQuery.js +64 -62
- package/lib/WAUSync/USyncQuery.js.map +1 -0
- package/lib/WAUSync/USyncUser.d.ts +11 -10
- package/lib/WAUSync/USyncUser.d.ts.map +1 -0
- package/lib/WAUSync/USyncUser.js +12 -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 +12 -13
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -33
- package/lib/index.js.map +1 -0
- package/package.json +99 -96
- package/lib/Defaults/baileys-version.json +0 -3
- package/lib/Defaults/phonenumber-mcc.json +0 -223
- package/lib/Signal/WASignalGroup/GroupProtocol.js +0 -1909
- package/lib/Signal/WASignalGroup/ciphertext-message.d.ts +0 -9
- package/lib/Signal/WASignalGroup/ciphertext-message.js +0 -19
- package/lib/Signal/WASignalGroup/ciphertext_message.js +0 -16
- package/lib/Signal/WASignalGroup/generate-proto.sh +0 -1
- package/lib/Signal/WASignalGroup/group-session-builder.js +0 -72
- package/lib/Signal/WASignalGroup/group.proto +0 -42
- package/lib/Signal/WASignalGroup/group_cipher.d.ts +0 -19
- package/lib/Signal/WASignalGroup/group_session_builder.js +0 -46
- package/lib/Signal/WASignalGroup/index.d.ts +0 -11
- package/lib/Signal/WASignalGroup/index.js +0 -61
- package/lib/Signal/WASignalGroup/keyhelper.d.ts +0 -16
- package/lib/Signal/WASignalGroup/keyhelper.js +0 -66
- package/lib/Signal/WASignalGroup/protobufs.js +0 -3
- package/lib/Signal/WASignalGroup/queue_job.js +0 -69
- package/lib/Signal/WASignalGroup/readme.md +0 -6
- package/lib/Signal/WASignalGroup/sender-chain-key.d.ts +0 -14
- package/lib/Signal/WASignalGroup/sender-chain-key.js +0 -47
- package/lib/Signal/WASignalGroup/sender-key-distribution-message.d.ts +0 -17
- package/lib/Signal/WASignalGroup/sender-key-distribution-message.js +0 -71
- package/lib/Signal/WASignalGroup/sender-key-message.d.ts +0 -19
- package/lib/Signal/WASignalGroup/sender-key-message.js +0 -73
- package/lib/Signal/WASignalGroup/sender-key-name.d.ts +0 -19
- package/lib/Signal/WASignalGroup/sender-key-name.js +0 -59
- package/lib/Signal/WASignalGroup/sender-key-record.d.ts +0 -32
- package/lib/Signal/WASignalGroup/sender-key-record.js +0 -58
- package/lib/Signal/WASignalGroup/sender-key-state.d.ts +0 -44
- package/lib/Signal/WASignalGroup/sender-key-state.js +0 -147
- package/lib/Signal/WASignalGroup/sender-message-key.d.ts +0 -11
- package/lib/Signal/WASignalGroup/sender-message-key.js +0 -33
- package/lib/Signal/WASignalGroup/sender_chain_key.js +0 -50
- package/lib/Signal/WASignalGroup/sender_key_distribution_message.js +0 -78
- package/lib/Signal/WASignalGroup/sender_key_message.js +0 -92
- package/lib/Signal/WASignalGroup/sender_key_name.js +0 -70
- package/lib/Signal/WASignalGroup/sender_key_record.js +0 -56
- package/lib/Signal/WASignalGroup/sender_key_state.js +0 -129
- package/lib/Socket/Client/abstract-socket-client.d.ts +0 -15
- package/lib/Socket/Client/abstract-socket-client.js +0 -13
- package/lib/Socket/Client/mobile-socket-client.d.ts +0 -12
- package/lib/Socket/Client/mobile-socket-client.js +0 -65
- package/lib/Socket/usync.d.ts +0 -37
- package/lib/Socket/usync.js +0 -83
- package/lib/Store/index.d.ts +0 -4
- package/lib/Store/index.js +0 -24
- package/lib/Store/make-cache-manager-store.d.ts +0 -14
- package/lib/Store/make-cache-manager-store.js +0 -90
- package/lib/Store/make-in-memory-store.d.ts +0 -123
- package/lib/Store/make-in-memory-store.js +0 -429
- package/lib/Store/make-ordered-dictionary.d.ts +0 -12
- package/lib/Store/make-ordered-dictionary.js +0 -86
- package/lib/Store/object-repository.d.ts +0 -10
- package/lib/Store/object-repository.js +0 -31
- package/lib/Types/Bussiness.d.ts +0 -28
- package/lib/Types/MexUpdates.d.ts +0 -9
- package/lib/Types/MexUpdates.js +0 -18
- package/lib/Utils/use-mongo-file-auth-state.d.ts +0 -6
- package/lib/Utils/use-mongo-file-auth-state.js +0 -84
- package/lib/Utils/use-single-file-auth-state.d.ts +0 -13
- package/lib/Utils/use-single-file-auth-state.js +0 -80
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.d.ts +0 -28
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +0 -69
- package/lib/WAUSync/Protocols/USyncLIDProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/USyncLIDProtocol.js +0 -38
|
@@ -1,48 +1,218 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const groups_1 = require("./groups")
|
|
18
|
-
const make_mutex_1 = require("../Utils/make-mutex")
|
|
19
|
-
const messages_send_1 = require("./messages-send")
|
|
20
|
-
|
|
21
|
-
const makeMessagesRecvSocket = (config) => {
|
|
22
|
-
const { logger, retryRequestDelayMs, maxMsgRetryCount, getMessage, shouldIgnoreJid, enableAutoSessionRecreation } = config
|
|
23
|
-
const baron = messages_send_1.makeMessagesSocket(config)
|
|
24
|
-
const { ev, authState, ws, processingMutex, signalRepository, query, upsertMessage, resyncAppState, onUnexpectedError, assertSessions, sendNode, relayMessage, sendReceipt, uploadPreKeys, groupMetadata, getUSyncDevices, createParticipantNodes, messageRetryManager, sendPeerDataOperationMessage } = baron
|
|
25
|
-
|
|
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;
|
|
26
17
|
/** this mutex ensures that each retryRequest will wait for the previous one to finish */
|
|
27
|
-
const retryMutex =
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
+
});
|
|
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
|
+
};
|
|
46
216
|
const sendMessageAck = async ({ tag, attrs, content }, errorCode) => {
|
|
47
217
|
const stanza = {
|
|
48
218
|
tag: 'ack',
|
|
@@ -51,201 +221,123 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
51
221
|
to: attrs.from,
|
|
52
222
|
class: tag
|
|
53
223
|
}
|
|
54
|
-
}
|
|
55
|
-
|
|
224
|
+
};
|
|
56
225
|
if (!!errorCode) {
|
|
57
|
-
stanza.attrs.error = errorCode.toString()
|
|
226
|
+
stanza.attrs.error = errorCode.toString();
|
|
58
227
|
}
|
|
59
|
-
|
|
60
228
|
if (!!attrs.participant) {
|
|
61
|
-
stanza.attrs.participant = attrs.participant
|
|
229
|
+
stanza.attrs.participant = attrs.participant;
|
|
62
230
|
}
|
|
63
|
-
|
|
64
231
|
if (!!attrs.recipient) {
|
|
65
|
-
stanza.attrs.recipient = attrs.recipient
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (!!attrs.type && (tag !== 'message' || WABinary_1.getBinaryNodeChild({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
|
|
69
|
-
stanza.attrs.type = attrs.type
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (tag === 'message' && WABinary_1.getBinaryNodeChild({ tag, attrs, content }, 'unavailable')) {
|
|
73
|
-
stanza.attrs.from = authState.creds.me.id
|
|
232
|
+
stanza.attrs.recipient = attrs.recipient;
|
|
74
233
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const offerCall = async (toJid, isVideo = false) => {
|
|
81
|
-
const callId = crypto_1.randomBytes(16).toString('hex').toUpperCase().substring(0, 64)
|
|
82
|
-
const offerContent = []
|
|
83
|
-
offerContent.push({ tag: 'audio', attrs: { enc: 'opus', rate: '16000' }, content: undefined })
|
|
84
|
-
offerContent.push({ tag: 'audio', attrs: { enc: 'opus', rate: '8000' }, content: undefined })
|
|
85
|
-
|
|
86
|
-
if (isVideo) {
|
|
87
|
-
offerContent.push({
|
|
88
|
-
tag: 'video',
|
|
89
|
-
attrs: { enc: 'vp8', dec: 'vp8', orientation: '0', 'screen_width': '1920', 'screen_height': '1080', 'device_orientation': '0' },
|
|
90
|
-
content: undefined
|
|
91
|
-
})
|
|
234
|
+
if (!!attrs.type &&
|
|
235
|
+
(tag !== 'message' || getBinaryNodeChild({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
|
|
236
|
+
stanza.attrs.type = attrs.type;
|
|
92
237
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
offerContent.push({ tag: 'encopt', attrs: { keygen: '2' }, content: undefined })
|
|
96
|
-
|
|
97
|
-
const encKey = crypto_1.randomBytes(32)
|
|
98
|
-
const devices = (await getUSyncDevices([toJid], true, false)).map(({ user, device }) => WABinary_1.jidEncode(user, 's.whatsapp.net', device))
|
|
99
|
-
await assertSessions(devices, true)
|
|
100
|
-
|
|
101
|
-
const { nodes: destinations, shouldIncludeDeviceIdentity } = await createParticipantNodes(devices, {
|
|
102
|
-
call: {
|
|
103
|
-
callKey: new Uint8Array(encKey)
|
|
104
|
-
}
|
|
105
|
-
}, { count: '0' })
|
|
106
|
-
offerContent.push({ tag: 'destination', attrs: {}, content: destinations })
|
|
107
|
-
|
|
108
|
-
if (shouldIncludeDeviceIdentity) {
|
|
109
|
-
offerContent.push({
|
|
110
|
-
tag: 'device-identity',
|
|
111
|
-
attrs: {},
|
|
112
|
-
content: Utils_1.encodeSignedDeviceIdentity(authState.creds.account, true)
|
|
113
|
-
})
|
|
238
|
+
if (tag === 'message' && getBinaryNodeChild({ tag, attrs, content }, 'unavailable')) {
|
|
239
|
+
stanza.attrs.from = authState.creds.me.id;
|
|
114
240
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
attrs: {
|
|
119
|
-
id: Utils_1.generateMessageID(),
|
|
120
|
-
to: toJid,
|
|
121
|
-
},
|
|
122
|
-
content: [{
|
|
123
|
-
tag: 'offer',
|
|
124
|
-
attrs: {
|
|
125
|
-
'call-id': callId,
|
|
126
|
-
'call-creator': authState.creds.me.id,
|
|
127
|
-
},
|
|
128
|
-
content: offerContent,
|
|
129
|
-
}],
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
await query(stanza)
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
id: callId,
|
|
136
|
-
to: toJid
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
241
|
+
logger.debug({ recv: { tag, attrs }, sent: stanza.attrs }, 'sent ack');
|
|
242
|
+
await sendNode(stanza);
|
|
243
|
+
};
|
|
140
244
|
const rejectCall = async (callId, callFrom) => {
|
|
141
|
-
const stanza =
|
|
245
|
+
const stanza = {
|
|
142
246
|
tag: 'call',
|
|
143
247
|
attrs: {
|
|
144
248
|
from: authState.creds.me.id,
|
|
145
|
-
to: callFrom
|
|
249
|
+
to: callFrom
|
|
146
250
|
},
|
|
147
|
-
content: [
|
|
251
|
+
content: [
|
|
252
|
+
{
|
|
148
253
|
tag: 'reject',
|
|
149
254
|
attrs: {
|
|
150
255
|
'call-id': callId,
|
|
151
256
|
'call-creator': callFrom,
|
|
152
|
-
count: '0'
|
|
257
|
+
count: '0'
|
|
153
258
|
},
|
|
154
|
-
content: undefined
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
await query(stanza)
|
|
159
|
-
}
|
|
160
|
-
|
|
259
|
+
content: undefined
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
};
|
|
263
|
+
await query(stanza);
|
|
264
|
+
};
|
|
161
265
|
const sendRetryRequest = async (node, forceIncludeKeys = false) => {
|
|
162
|
-
const { fullMessage } =
|
|
163
|
-
const { key: msgKey } = fullMessage
|
|
164
|
-
const msgId = msgKey.id
|
|
165
|
-
|
|
266
|
+
const { fullMessage } = decodeMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '');
|
|
267
|
+
const { key: msgKey } = fullMessage;
|
|
268
|
+
const msgId = msgKey.id;
|
|
166
269
|
if (messageRetryManager) {
|
|
167
270
|
// Check if we've exceeded max retries using the new system
|
|
168
271
|
if (messageRetryManager.hasExceededMaxRetries(msgId)) {
|
|
169
|
-
logger.debug({ msgId }, 'reached retry limit with new retry manager, clearing')
|
|
170
|
-
messageRetryManager.markRetryFailed(msgId)
|
|
171
|
-
return
|
|
272
|
+
logger.debug({ msgId }, 'reached retry limit with new retry manager, clearing');
|
|
273
|
+
messageRetryManager.markRetryFailed(msgId);
|
|
274
|
+
return;
|
|
172
275
|
}
|
|
173
|
-
|
|
174
276
|
// Increment retry count using new system
|
|
175
|
-
const retryCount = messageRetryManager.incrementRetryCount(msgId)
|
|
176
|
-
|
|
277
|
+
const retryCount = messageRetryManager.incrementRetryCount(msgId);
|
|
177
278
|
// Use the new retry count for the rest of the logic
|
|
178
|
-
const key = `${msgId}:${msgKey?.participant}
|
|
179
|
-
msgRetryCache.set(key, retryCount)
|
|
279
|
+
const key = `${msgId}:${msgKey?.participant}`;
|
|
280
|
+
msgRetryCache.set(key, retryCount);
|
|
180
281
|
}
|
|
181
282
|
else {
|
|
182
283
|
// Fallback to old system
|
|
183
|
-
const key = `${msgId}:${msgKey?.participant}
|
|
184
|
-
let retryCount = (await msgRetryCache.get(key)) || 0
|
|
185
|
-
|
|
284
|
+
const key = `${msgId}:${msgKey?.participant}`;
|
|
285
|
+
let retryCount = (await msgRetryCache.get(key)) || 0;
|
|
186
286
|
if (retryCount >= maxMsgRetryCount) {
|
|
187
|
-
logger.debug({ retryCount, msgId }, 'reached retry limit, clearing')
|
|
188
|
-
msgRetryCache.del(key)
|
|
189
|
-
return
|
|
287
|
+
logger.debug({ retryCount, msgId }, 'reached retry limit, clearing');
|
|
288
|
+
msgRetryCache.del(key);
|
|
289
|
+
return;
|
|
190
290
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
await msgRetryCache.set(key, retryCount)
|
|
291
|
+
retryCount += 1;
|
|
292
|
+
await msgRetryCache.set(key, retryCount);
|
|
194
293
|
}
|
|
195
|
-
|
|
196
|
-
const
|
|
197
|
-
const
|
|
198
|
-
const
|
|
199
|
-
const fromJid = node.attrs.from
|
|
200
|
-
|
|
294
|
+
const key = `${msgId}:${msgKey?.participant}`;
|
|
295
|
+
const retryCount = (await msgRetryCache.get(key)) || 1;
|
|
296
|
+
const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds;
|
|
297
|
+
const fromJid = node.attrs.from;
|
|
201
298
|
// Check if we should recreate the session
|
|
202
|
-
let shouldRecreateSession = false
|
|
203
|
-
let recreateReason = ''
|
|
204
|
-
|
|
299
|
+
let shouldRecreateSession = false;
|
|
300
|
+
let recreateReason = '';
|
|
205
301
|
if (enableAutoSessionRecreation && messageRetryManager) {
|
|
206
302
|
try {
|
|
207
303
|
// Check if we have a session with this JID
|
|
208
|
-
const sessionId = signalRepository.jidToSignalProtocolAddress(fromJid)
|
|
209
|
-
const hasSession = await signalRepository.validateSession(fromJid)
|
|
210
|
-
const result = messageRetryManager.shouldRecreateSession(fromJid, retryCount, hasSession.exists)
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
recreateReason = result.reason
|
|
214
|
-
|
|
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;
|
|
215
309
|
if (shouldRecreateSession) {
|
|
216
|
-
logger.
|
|
310
|
+
logger.debug({ fromJid, retryCount, reason: recreateReason }, 'recreating session for retry');
|
|
217
311
|
// Delete existing session to force recreation
|
|
218
|
-
await authState.keys.set({ session: { [sessionId]: null } })
|
|
219
|
-
forceIncludeKeys = true
|
|
312
|
+
await authState.keys.set({ session: { [sessionId]: null } });
|
|
313
|
+
forceIncludeKeys = true;
|
|
220
314
|
}
|
|
221
315
|
}
|
|
222
316
|
catch (error) {
|
|
223
|
-
logger.warn({ error, fromJid }, 'failed to check session recreation')
|
|
317
|
+
logger.warn({ error, fromJid }, 'failed to check session recreation');
|
|
224
318
|
}
|
|
225
319
|
}
|
|
226
|
-
|
|
227
320
|
if (retryCount <= 2) {
|
|
228
321
|
// Use new retry manager for phone requests if available
|
|
229
322
|
if (messageRetryManager) {
|
|
230
323
|
// Schedule phone request with delay (like whatsmeow)
|
|
231
324
|
messageRetryManager.schedulePhoneRequest(msgId, async () => {
|
|
232
325
|
try {
|
|
233
|
-
const
|
|
234
|
-
logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId} (scheduled)`)
|
|
326
|
+
const requestId = await requestPlaceholderResend(msgKey);
|
|
327
|
+
logger.debug(`sendRetryRequest: requested placeholder resend (${requestId}) for message ${msgId} (scheduled)`);
|
|
235
328
|
}
|
|
236
329
|
catch (error) {
|
|
237
330
|
logger.warn({ error, msgId }, 'failed to send scheduled phone request');
|
|
238
331
|
}
|
|
239
|
-
})
|
|
332
|
+
});
|
|
240
333
|
}
|
|
241
334
|
else {
|
|
242
335
|
// Fallback to immediate request
|
|
243
|
-
const msgId = await requestPlaceholderResend(msgKey)
|
|
244
|
-
logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId}`)
|
|
336
|
+
const msgId = await requestPlaceholderResend(msgKey);
|
|
337
|
+
logger.debug(`sendRetryRequest: requested placeholder resend for message ${msgId}`);
|
|
245
338
|
}
|
|
246
339
|
}
|
|
247
|
-
|
|
248
|
-
const deviceIdentity = Utils_1.encodeSignedDeviceIdentity(account, true)
|
|
340
|
+
const deviceIdentity = encodeSignedDeviceIdentity(account, true);
|
|
249
341
|
await authState.keys.transaction(async () => {
|
|
250
342
|
const receipt = {
|
|
251
343
|
tag: 'receipt',
|
|
@@ -261,447 +353,320 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
261
353
|
count: retryCount.toString(),
|
|
262
354
|
id: node.attrs.id,
|
|
263
355
|
t: node.attrs.t,
|
|
264
|
-
v: '1'
|
|
356
|
+
v: '1',
|
|
357
|
+
// ADD ERROR FIELD
|
|
358
|
+
error: '0'
|
|
265
359
|
}
|
|
266
360
|
},
|
|
267
361
|
{
|
|
268
362
|
tag: 'registration',
|
|
269
363
|
attrs: {},
|
|
270
|
-
content:
|
|
364
|
+
content: encodeBigEndian(authState.creds.registrationId)
|
|
271
365
|
}
|
|
272
366
|
]
|
|
273
|
-
}
|
|
274
|
-
|
|
367
|
+
};
|
|
275
368
|
if (node.attrs.recipient) {
|
|
276
|
-
receipt.attrs.recipient = node.attrs.recipient
|
|
369
|
+
receipt.attrs.recipient = node.attrs.recipient;
|
|
277
370
|
}
|
|
278
|
-
|
|
279
371
|
if (node.attrs.participant) {
|
|
280
|
-
receipt.attrs.participant = node.attrs.participant
|
|
372
|
+
receipt.attrs.participant = node.attrs.participant;
|
|
281
373
|
}
|
|
282
|
-
|
|
283
374
|
if (retryCount > 1 || forceIncludeKeys || shouldRecreateSession) {
|
|
284
|
-
const { update, preKeys } = await
|
|
285
|
-
const [keyId] = Object.keys(preKeys)
|
|
286
|
-
const key = preKeys[+keyId]
|
|
287
|
-
const content = receipt.content
|
|
288
|
-
|
|
375
|
+
const { update, preKeys } = await getNextPreKeys(authState, 1);
|
|
376
|
+
const [keyId] = Object.keys(preKeys);
|
|
377
|
+
const key = preKeys[+keyId];
|
|
378
|
+
const content = receipt.content;
|
|
289
379
|
content.push({
|
|
290
380
|
tag: 'keys',
|
|
291
381
|
attrs: {},
|
|
292
382
|
content: [
|
|
293
|
-
{ tag: 'type', attrs: {}, content: Buffer.from(
|
|
383
|
+
{ tag: 'type', attrs: {}, content: Buffer.from(KEY_BUNDLE_TYPE) },
|
|
294
384
|
{ tag: 'identity', attrs: {}, content: identityKey.public },
|
|
295
|
-
|
|
296
|
-
|
|
385
|
+
xmppPreKey(key, +keyId),
|
|
386
|
+
xmppSignedPreKey(signedPreKey),
|
|
297
387
|
{ tag: 'device-identity', attrs: {}, content: deviceIdentity }
|
|
298
388
|
]
|
|
299
389
|
});
|
|
300
|
-
ev.emit('creds.update', update)
|
|
390
|
+
ev.emit('creds.update', update);
|
|
301
391
|
}
|
|
302
|
-
await sendNode(receipt)
|
|
303
|
-
logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt')
|
|
304
|
-
}, authState?.creds?.me?.id || 'sendRetryRequest')
|
|
305
|
-
}
|
|
306
|
-
|
|
392
|
+
await sendNode(receipt);
|
|
393
|
+
logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt');
|
|
394
|
+
}, authState?.creds?.me?.id || 'sendRetryRequest');
|
|
395
|
+
};
|
|
307
396
|
const handleEncryptNotification = async (node) => {
|
|
308
|
-
const from = node.attrs.from
|
|
309
|
-
if (from ===
|
|
310
|
-
const countChild =
|
|
311
|
-
const count = +countChild.attrs.value
|
|
312
|
-
const shouldUploadMorePreKeys = count <
|
|
313
|
-
logger.debug({ count, shouldUploadMorePreKeys }, 'recv pre-key count')
|
|
314
|
-
|
|
397
|
+
const from = node.attrs.from;
|
|
398
|
+
if (from === S_WHATSAPP_NET) {
|
|
399
|
+
const countChild = getBinaryNodeChild(node, 'count');
|
|
400
|
+
const count = +countChild.attrs.value;
|
|
401
|
+
const shouldUploadMorePreKeys = count < MIN_PREKEY_COUNT;
|
|
402
|
+
logger.debug({ count, shouldUploadMorePreKeys }, 'recv pre-key count');
|
|
315
403
|
if (shouldUploadMorePreKeys) {
|
|
316
|
-
await uploadPreKeys()
|
|
404
|
+
await uploadPreKeys();
|
|
317
405
|
}
|
|
318
406
|
}
|
|
319
|
-
|
|
320
407
|
else {
|
|
321
|
-
const identityNode =
|
|
408
|
+
const identityNode = getBinaryNodeChild(node, 'identity');
|
|
322
409
|
if (identityNode) {
|
|
323
|
-
logger.info({ jid: from }, 'identity changed')
|
|
410
|
+
logger.info({ jid: from }, 'identity changed');
|
|
324
411
|
// not handling right now
|
|
325
412
|
// signal will override new identity anyway
|
|
326
413
|
}
|
|
327
|
-
|
|
328
414
|
else {
|
|
329
|
-
logger.info({ node }, 'unknown encrypt notification')
|
|
415
|
+
logger.info({ node }, 'unknown encrypt notification');
|
|
330
416
|
}
|
|
331
417
|
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
418
|
+
};
|
|
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) {
|
|
339
426
|
case 'create':
|
|
340
|
-
const metadata =
|
|
341
|
-
msg.messageStubType =
|
|
342
|
-
msg.messageStubParameters = [metadata.subject]
|
|
343
|
-
msg.key = { participant: metadata.owner }
|
|
344
|
-
ev.emit('chats.upsert', [
|
|
427
|
+
const metadata = extractGroupMetadata(child);
|
|
428
|
+
msg.messageStubType = WAMessageStubType.GROUP_CREATE;
|
|
429
|
+
msg.messageStubParameters = [metadata.subject];
|
|
430
|
+
msg.key = { participant: metadata.owner, participantAlt: metadata.ownerPn };
|
|
431
|
+
ev.emit('chats.upsert', [
|
|
432
|
+
{
|
|
345
433
|
id: metadata.id,
|
|
346
434
|
name: metadata.subject,
|
|
347
|
-
conversationTimestamp: metadata.creation
|
|
348
|
-
}
|
|
349
|
-
|
|
435
|
+
conversationTimestamp: metadata.creation
|
|
436
|
+
}
|
|
437
|
+
]);
|
|
438
|
+
ev.emit('groups.upsert', [
|
|
439
|
+
{
|
|
350
440
|
...metadata,
|
|
351
|
-
author:
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
msg.messageStubParameters = [participantJid, 'delete']
|
|
357
|
-
break
|
|
441
|
+
author: actingParticipantLid,
|
|
442
|
+
authorPn: actingParticipantPn
|
|
443
|
+
}
|
|
444
|
+
]);
|
|
445
|
+
break;
|
|
358
446
|
case 'ephemeral':
|
|
359
447
|
case 'not_ephemeral':
|
|
360
448
|
msg.message = {
|
|
361
449
|
protocolMessage: {
|
|
362
|
-
type:
|
|
450
|
+
type: proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
|
|
363
451
|
ephemeralExpiration: +(child.attrs.expiration || 0)
|
|
364
452
|
}
|
|
365
|
-
}
|
|
366
|
-
break
|
|
453
|
+
};
|
|
454
|
+
break;
|
|
367
455
|
case 'modify':
|
|
368
|
-
const oldNumber =
|
|
369
|
-
msg.messageStubParameters = oldNumber || []
|
|
370
|
-
msg.messageStubType =
|
|
371
|
-
break
|
|
456
|
+
const oldNumber = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid);
|
|
457
|
+
msg.messageStubParameters = oldNumber || [];
|
|
458
|
+
msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER;
|
|
459
|
+
break;
|
|
372
460
|
case 'promote':
|
|
373
461
|
case 'demote':
|
|
374
462
|
case 'remove':
|
|
375
463
|
case 'add':
|
|
376
464
|
case 'leave':
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
465
|
+
const stubType = `GROUP_PARTICIPANT_${child.tag.toUpperCase()}`;
|
|
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
|
+
});
|
|
383
476
|
if (participants.length === 1 &&
|
|
384
477
|
// if recv. "remove" message and sender removed themselves
|
|
385
478
|
// mark as left
|
|
386
|
-
|
|
479
|
+
(areJidsSameUser(participants[0].id, actingParticipantLid) ||
|
|
480
|
+
areJidsSameUser(participants[0].id, actingParticipantPn)) &&
|
|
387
481
|
child.tag === 'remove') {
|
|
388
|
-
msg.messageStubType =
|
|
482
|
+
msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_LEAVE;
|
|
389
483
|
}
|
|
390
|
-
msg.messageStubParameters = participants
|
|
391
|
-
break
|
|
484
|
+
msg.messageStubParameters = participants.map(a => JSON.stringify(a));
|
|
485
|
+
break;
|
|
392
486
|
case 'subject':
|
|
393
|
-
msg.messageStubType =
|
|
394
|
-
msg.messageStubParameters = [
|
|
395
|
-
break
|
|
487
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_SUBJECT;
|
|
488
|
+
msg.messageStubParameters = [child.attrs.subject];
|
|
489
|
+
break;
|
|
396
490
|
case 'description':
|
|
397
|
-
const description =
|
|
398
|
-
msg.messageStubType =
|
|
399
|
-
msg.messageStubParameters = description ? [description] : undefined
|
|
400
|
-
break
|
|
491
|
+
const description = getBinaryNodeChild(child, 'body')?.content?.toString();
|
|
492
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_DESCRIPTION;
|
|
493
|
+
msg.messageStubParameters = description ? [description] : undefined;
|
|
494
|
+
break;
|
|
401
495
|
case 'announcement':
|
|
402
496
|
case 'not_announcement':
|
|
403
|
-
msg.messageStubType =
|
|
404
|
-
msg.messageStubParameters = [
|
|
405
|
-
break
|
|
497
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_ANNOUNCE;
|
|
498
|
+
msg.messageStubParameters = [child.tag === 'announcement' ? 'on' : 'off'];
|
|
499
|
+
break;
|
|
406
500
|
case 'locked':
|
|
407
501
|
case 'unlocked':
|
|
408
|
-
msg.messageStubType =
|
|
409
|
-
msg.messageStubParameters = [
|
|
410
|
-
break
|
|
502
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_RESTRICT;
|
|
503
|
+
msg.messageStubParameters = [child.tag === 'locked' ? 'on' : 'off'];
|
|
504
|
+
break;
|
|
411
505
|
case 'invite':
|
|
412
|
-
msg.messageStubType =
|
|
413
|
-
msg.messageStubParameters = [child.attrs.code]
|
|
414
|
-
break
|
|
506
|
+
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_INVITE_LINK;
|
|
507
|
+
msg.messageStubParameters = [child.attrs.code];
|
|
508
|
+
break;
|
|
415
509
|
case 'member_add_mode':
|
|
416
|
-
const addMode = child.content
|
|
510
|
+
const addMode = child.content;
|
|
417
511
|
if (addMode) {
|
|
418
|
-
msg.messageStubType =
|
|
419
|
-
msg.messageStubParameters = [addMode.toString()]
|
|
512
|
+
msg.messageStubType = WAMessageStubType.GROUP_MEMBER_ADD_MODE;
|
|
513
|
+
msg.messageStubParameters = [addMode.toString()];
|
|
420
514
|
}
|
|
421
|
-
break
|
|
515
|
+
break;
|
|
422
516
|
case 'membership_approval_mode':
|
|
423
|
-
const approvalMode =
|
|
517
|
+
const approvalMode = getBinaryNodeChild(child, 'group_join');
|
|
424
518
|
if (approvalMode) {
|
|
425
|
-
msg.messageStubType =
|
|
426
|
-
msg.messageStubParameters = [approvalMode.attrs.state]
|
|
519
|
+
msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE;
|
|
520
|
+
msg.messageStubParameters = [approvalMode.attrs.state];
|
|
427
521
|
}
|
|
428
|
-
break
|
|
522
|
+
break;
|
|
429
523
|
case 'created_membership_requests':
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
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
|
+
];
|
|
530
|
+
break;
|
|
435
531
|
case 'revoked_membership_requests':
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
msg.
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
parent_group: Types_1.WAMessageStubType[`COMMUNITY_${child.tag.toUpperCase()}_PARENT_GROUP`],
|
|
447
|
-
sibling_group: Types_1.WAMessageStubType[`COMMUNITY_${child.tag.toUpperCase()}_SIBLING_GROUP`],
|
|
448
|
-
sub_group: Types_1.WAMessageStubType[`COMMUNITY_${child.tag.toUpperCase()}_SUB_GROUP`]
|
|
449
|
-
}
|
|
450
|
-
const groups = WABinary_1.getBinaryNodeChildren(child, 'group')
|
|
451
|
-
.map(g => g.attrs?.jid || g.attrs?.subject || '')
|
|
452
|
-
.filter(x => x)
|
|
453
|
-
msg.messageStubType = stubMap?.[type] || Types_1.WAMessageStubType[`COMMUNITY_${child.tag.toUpperCase()}_PARENT_GROUP`]
|
|
454
|
-
msg.messageStubParameters = [participantJid, child.tag, groups]
|
|
455
|
-
break
|
|
456
|
-
case 'linked_group_promote':
|
|
457
|
-
case 'linked_group_demote':
|
|
458
|
-
const stubtype = `COMMUNITY_PARTICIPANT_${child.tag.split('_')[2].toUpperCase()}`
|
|
459
|
-
const participantS = mode === 'lid' ? WABinary_1.getBinaryNodeChildren(child, 'participant').map(p => p.attrs.phone_number) : WABinary_1.getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid)
|
|
460
|
-
msg.messageStubType = Types_1.WAMessageStubType[stubtype]
|
|
461
|
-
msg.messageStubParameters = participantS
|
|
462
|
-
break
|
|
463
|
-
case 'created_sub_group_suggestion':
|
|
464
|
-
msg.messageStubType = Types_1.WAMessageStubType.SUGGESTED_SUBGROUP_ANNOUNCE
|
|
465
|
-
msg.messageStubParameters = [participantJid, 'add']
|
|
466
|
-
break
|
|
467
|
-
case 'revoked_sub_group_suggestions':
|
|
468
|
-
const res = WABinary_1.getBinaryNodeChildren(child, 'sub_group_suggestions')
|
|
469
|
-
const reason = res.attrs?.reason
|
|
470
|
-
if (reason === 'approved') msg.messageStubType = Types_1.WAMessageStubType.GROUP_CREATE
|
|
471
|
-
else msg.messageStubType = Types_1.WAMessageStubType.GENERIC_NOTIFICATION
|
|
472
|
-
msg.messageStubParameters = [participantJid, reason]
|
|
473
|
-
break
|
|
474
|
-
default:
|
|
475
|
-
logger.warn(child.tag, 'Unhandled group node')
|
|
476
|
-
break
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
const handleNewsletterNotification = (id, node) => {
|
|
481
|
-
const messages = WABinary_1.getBinaryNodeChild(node, 'messages')
|
|
482
|
-
const message = WABinary_1.getBinaryNodeChild(node, 'message')
|
|
483
|
-
const serverId = node.attrs.server_id
|
|
484
|
-
|
|
485
|
-
const reactionsList = WABinary_1.getBinaryNodeChild(node, 'reactions')
|
|
486
|
-
const viewsList = WABinary_1.getBinaryNodeChild(node, 'views_count')
|
|
487
|
-
|
|
488
|
-
if (reactionsList) {
|
|
489
|
-
const reactions = WABinary_1.getBinaryNodeChild(reactionsList, 'reaction')
|
|
490
|
-
|
|
491
|
-
if (reactions.length === 0) {
|
|
492
|
-
ev.emit('newsletter.reaction', {
|
|
493
|
-
id,
|
|
494
|
-
newsletter_server_id: serverId,
|
|
495
|
-
reaction: {
|
|
496
|
-
removed: true
|
|
497
|
-
}
|
|
498
|
-
})
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
reactions.forEach(item => {
|
|
502
|
-
ev.emit('newsletter.reaction', {
|
|
503
|
-
id,
|
|
504
|
-
newsletter_server_id: serverId,
|
|
505
|
-
reaction: {
|
|
506
|
-
code: item.attrs?.code,
|
|
507
|
-
count: +item.attrs.count
|
|
508
|
-
}
|
|
509
|
-
})
|
|
510
|
-
})
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
if (viewsList.length) {
|
|
514
|
-
viewsList.forEach(item => {
|
|
515
|
-
ev.emit('newsletter.view', {
|
|
516
|
-
id,
|
|
517
|
-
newsletter_server_id: serverId,
|
|
518
|
-
count: +item.attrs.count
|
|
519
|
-
})
|
|
520
|
-
})
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
const handleMexNotification = (id, node) => {
|
|
525
|
-
const operation = node?.attrs?.op_name
|
|
526
|
-
const content = JSON.parse(node?.content)
|
|
527
|
-
|
|
528
|
-
let contentPath
|
|
529
|
-
let action
|
|
530
|
-
|
|
531
|
-
if (operation === Types_1.MexOperations.UPDATE) {
|
|
532
|
-
contentPath = content.data[Types_1.XWAPaths.METADATA_UPDATE]
|
|
533
|
-
|
|
534
|
-
ev.emit('newsletter-settings.update', {
|
|
535
|
-
id,
|
|
536
|
-
update: contentPath.thread_metadata.settings
|
|
537
|
-
})
|
|
538
|
-
} else if (operation === Types_1.MexUpdatesOperations.GROUP_LIMIT_SHARING) {
|
|
539
|
-
contentPath = content.data[Types_1.XWAPathsMexUpdates.GROUP_SHARING_CHANGE]
|
|
540
|
-
|
|
541
|
-
ev.emit('limit-sharing.update', {
|
|
542
|
-
id,
|
|
543
|
-
author: contentPath.updated_by?.pn ? contentPath.updated_by.pn : contentPath.updated_by.id,
|
|
544
|
-
action: `${contentPath.properties.limit_sharing.limit_sharing_enabled ? 'on' : 'off'}`,
|
|
545
|
-
trigger: contentPath.properties.limit_sharing.limit_sharing_trigger,
|
|
546
|
-
update_time: contentPath.update_time
|
|
547
|
-
})
|
|
548
|
-
} else if (operation === Types_1.MexUpdatesOperations.OWNER_COMMUNITY) {
|
|
549
|
-
contentPath = content.data[Types_1.XWAPathsMexUpdates.COMMUNITY_OWNER_CHANGE]
|
|
550
|
-
|
|
551
|
-
ev.emit('community-owner.update', {
|
|
552
|
-
id,
|
|
553
|
-
author: contentPath.updated_by?.pn ? contentPath.updated_by.pn : contentPath.updated_by.id,
|
|
554
|
-
user: contentPath.role_updates[0].user?.pn ? contentPath.role_updates[0].user.pn : contentPath.role_updates[0].user.jid,
|
|
555
|
-
new_role: contentPath.role_updates[0].new_role,
|
|
556
|
-
update_time: contentPath.update_time
|
|
557
|
-
})
|
|
558
|
-
} else {
|
|
559
|
-
|
|
560
|
-
if (operation === Types_1.MexOperations.PROMOTE) {
|
|
561
|
-
action = 'promote'
|
|
562
|
-
contentPath = content.data[Types_1.XWAPaths.PROMOTE]
|
|
563
|
-
} else {
|
|
564
|
-
action = 'demote'
|
|
565
|
-
contentPath = content.data[Types_1.XWAPaths.DEMOTE]
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
ev.emit('newsletter-participants.update', {
|
|
569
|
-
id,
|
|
570
|
-
author: contentPath.actor.pn,
|
|
571
|
-
user: contentPath.user.pn,
|
|
572
|
-
new_role: contentPath.user_new_role,
|
|
573
|
-
action
|
|
574
|
-
})
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
|
|
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
|
+
];
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
};
|
|
578
542
|
const processNotification = async (node) => {
|
|
579
|
-
const result = {}
|
|
580
|
-
const [child] =
|
|
581
|
-
const nodeType = node.attrs.type
|
|
582
|
-
const from =
|
|
583
|
-
|
|
543
|
+
const result = {};
|
|
544
|
+
const [child] = getAllBinaryNodeChildren(node);
|
|
545
|
+
const nodeType = node.attrs.type;
|
|
546
|
+
const from = jidNormalizedUser(node.attrs.from);
|
|
584
547
|
switch (nodeType) {
|
|
585
548
|
case 'privacy_token':
|
|
586
|
-
const tokenList =
|
|
549
|
+
const tokenList = getBinaryNodeChildren(child, 'token');
|
|
587
550
|
for (const { attrs, content } of tokenList) {
|
|
588
|
-
const jid = attrs.jid
|
|
551
|
+
const jid = attrs.jid;
|
|
589
552
|
ev.emit('chats.update', [
|
|
590
553
|
{
|
|
591
554
|
id: jid,
|
|
592
555
|
tcToken: content
|
|
593
556
|
}
|
|
594
|
-
])
|
|
595
|
-
logger.debug({ jid }, 'got privacy token update')
|
|
557
|
+
]);
|
|
558
|
+
logger.debug({ jid }, 'got privacy token update');
|
|
596
559
|
}
|
|
597
|
-
break
|
|
598
|
-
case 'w:gp2':
|
|
599
|
-
const mode = node.attrs.addressing_mode
|
|
600
|
-
handleGroupNotification(mode === 'lid' ? node.attrs.participant_pn : node.attrs.participant, child, result, mode)
|
|
601
|
-
break
|
|
560
|
+
break;
|
|
602
561
|
case 'newsletter':
|
|
603
|
-
handleNewsletterNotification(node
|
|
604
|
-
break
|
|
562
|
+
await handleNewsletterNotification(node);
|
|
563
|
+
break;
|
|
605
564
|
case 'mex':
|
|
606
|
-
|
|
607
|
-
break
|
|
565
|
+
await handleMexNewsletterNotification(node);
|
|
566
|
+
break;
|
|
567
|
+
case 'w:gp2':
|
|
568
|
+
// TODO: HANDLE PARTICIPANT_PN
|
|
569
|
+
handleGroupNotification(node, child, result);
|
|
570
|
+
break;
|
|
608
571
|
case 'mediaretry':
|
|
609
|
-
const event =
|
|
610
|
-
ev.emit('messages.media-update', [event])
|
|
611
|
-
break
|
|
572
|
+
const event = decodeMediaRetryNode(node);
|
|
573
|
+
ev.emit('messages.media-update', [event]);
|
|
574
|
+
break;
|
|
612
575
|
case 'encrypt':
|
|
613
|
-
await handleEncryptNotification(node)
|
|
614
|
-
break
|
|
576
|
+
await handleEncryptNotification(node);
|
|
577
|
+
break;
|
|
615
578
|
case 'devices':
|
|
616
|
-
const devices =
|
|
617
|
-
if (
|
|
618
|
-
|
|
619
|
-
const deviceData = devices.map(d => ({ id: d.attrs.jid, lid: d.attrs.lid }))
|
|
620
|
-
logger.info({ deviceData }, 'my own devices changed')
|
|
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');
|
|
621
584
|
}
|
|
622
585
|
//TODO: drop a new event, add hashes
|
|
623
|
-
break
|
|
586
|
+
break;
|
|
624
587
|
case 'server_sync':
|
|
625
|
-
const update =
|
|
588
|
+
const update = getBinaryNodeChild(node, 'collection');
|
|
626
589
|
if (update) {
|
|
627
|
-
const name = update.attrs.name
|
|
628
|
-
await resyncAppState([name], false)
|
|
590
|
+
const name = update.attrs.name;
|
|
591
|
+
await resyncAppState([name], false);
|
|
629
592
|
}
|
|
630
|
-
break
|
|
593
|
+
break;
|
|
631
594
|
case 'picture':
|
|
632
|
-
const setPicture =
|
|
633
|
-
const delPicture =
|
|
634
|
-
ev.emit('contacts.update', [
|
|
635
|
-
|
|
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 || '',
|
|
636
600
|
imgUrl: setPicture ? 'changed' : 'removed'
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
601
|
+
}
|
|
602
|
+
]);
|
|
603
|
+
if (isJidGroup(from)) {
|
|
604
|
+
const node = setPicture || delPicture;
|
|
605
|
+
result.messageStubType = WAMessageStubType.GROUP_CHANGE_ICON;
|
|
641
606
|
if (setPicture) {
|
|
642
|
-
result.messageStubParameters = [setPicture.attrs.id]
|
|
607
|
+
result.messageStubParameters = [setPicture.attrs.id];
|
|
643
608
|
}
|
|
644
|
-
result.participant = node?.attrs
|
|
609
|
+
result.participant = node?.attrs.author;
|
|
645
610
|
result.key = {
|
|
646
|
-
...result.key || {},
|
|
647
|
-
participant: setPicture?.attrs
|
|
648
|
-
}
|
|
611
|
+
...(result.key || {}),
|
|
612
|
+
participant: setPicture?.attrs.author
|
|
613
|
+
};
|
|
649
614
|
}
|
|
650
|
-
break
|
|
615
|
+
break;
|
|
651
616
|
case 'account_sync':
|
|
652
617
|
if (child.tag === 'disappearing_mode') {
|
|
653
|
-
const newDuration = +child.attrs.duration
|
|
654
|
-
const timestamp = +child.attrs.t
|
|
655
|
-
logger.info({ newDuration }, 'updated account disappearing mode')
|
|
618
|
+
const newDuration = +child.attrs.duration;
|
|
619
|
+
const timestamp = +child.attrs.t;
|
|
620
|
+
logger.info({ newDuration }, 'updated account disappearing mode');
|
|
656
621
|
ev.emit('creds.update', {
|
|
657
622
|
accountSettings: {
|
|
658
623
|
...authState.creds.accountSettings,
|
|
659
624
|
defaultDisappearingMode: {
|
|
660
625
|
ephemeralExpiration: newDuration,
|
|
661
|
-
ephemeralSettingTimestamp: timestamp
|
|
662
|
-
}
|
|
626
|
+
ephemeralSettingTimestamp: timestamp
|
|
627
|
+
}
|
|
663
628
|
}
|
|
664
|
-
})
|
|
629
|
+
});
|
|
665
630
|
}
|
|
666
631
|
else if (child.tag === 'blocklist') {
|
|
667
|
-
const blocklists =
|
|
632
|
+
const blocklists = getBinaryNodeChildren(child, 'item');
|
|
668
633
|
for (const { attrs } of blocklists) {
|
|
669
|
-
const blocklist = [attrs.jid]
|
|
670
|
-
const type =
|
|
671
|
-
ev.emit('blocklist.update', { blocklist, type })
|
|
634
|
+
const blocklist = [attrs.jid];
|
|
635
|
+
const type = attrs.action === 'block' ? 'add' : 'remove';
|
|
636
|
+
ev.emit('blocklist.update', { blocklist, type });
|
|
672
637
|
}
|
|
673
638
|
}
|
|
674
|
-
break
|
|
639
|
+
break;
|
|
675
640
|
case 'link_code_companion_reg':
|
|
676
|
-
const linkCodeCompanionReg =
|
|
677
|
-
const ref = toRequiredBuffer(
|
|
678
|
-
const primaryIdentityPublicKey = toRequiredBuffer(
|
|
679
|
-
const primaryEphemeralPublicKeyWrapped = toRequiredBuffer(
|
|
680
|
-
const codePairingPublicKey = await decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped)
|
|
681
|
-
const companionSharedKey =
|
|
682
|
-
const random =
|
|
683
|
-
const linkCodeSalt =
|
|
684
|
-
|
|
685
|
-
const linkCodePairingExpanded = await Utils_1.hkdf(companionSharedKey, 32, {
|
|
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'));
|
|
645
|
+
const codePairingPublicKey = await decipherLinkPublicKey(primaryEphemeralPublicKeyWrapped);
|
|
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, {
|
|
686
650
|
salt: linkCodeSalt,
|
|
687
651
|
info: 'link_code_pairing_key_bundle_encryption_key'
|
|
688
|
-
})
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
const
|
|
695
|
-
const
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
652
|
+
});
|
|
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));
|
|
660
|
+
const encryptedPayload = Buffer.concat([linkCodeSalt, encryptIv, encrypted]);
|
|
661
|
+
const identitySharedKey = Curve.sharedKey(authState.creds.signedIdentityKey.private, primaryIdentityPublicKey);
|
|
662
|
+
const identityPayload = Buffer.concat([companionSharedKey, identitySharedKey, random]);
|
|
663
|
+
authState.creds.advSecretKey = (await hkdf(identityPayload, 32, { info: 'adv_secret' })).toString('base64');
|
|
699
664
|
await query({
|
|
700
665
|
tag: 'iq',
|
|
701
666
|
attrs: {
|
|
702
|
-
to:
|
|
667
|
+
to: S_WHATSAPP_NET,
|
|
703
668
|
type: 'set',
|
|
704
|
-
id:
|
|
669
|
+
id: sock.generateMessageTag(),
|
|
705
670
|
xmlns: 'md'
|
|
706
671
|
},
|
|
707
672
|
content: [
|
|
@@ -709,7 +674,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
709
674
|
tag: 'link_code_companion_reg',
|
|
710
675
|
attrs: {
|
|
711
676
|
jid: authState.creds.me.id,
|
|
712
|
-
stage: 'companion_finish'
|
|
677
|
+
stage: 'companion_finish'
|
|
713
678
|
},
|
|
714
679
|
content: [
|
|
715
680
|
{
|
|
@@ -730,576 +695,394 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
730
695
|
]
|
|
731
696
|
}
|
|
732
697
|
]
|
|
733
|
-
})
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
ev.emit('creds.update', authState.creds)
|
|
698
|
+
});
|
|
699
|
+
authState.creds.registered = true;
|
|
700
|
+
ev.emit('creds.update', authState.creds);
|
|
737
701
|
}
|
|
738
|
-
|
|
739
702
|
if (Object.keys(result).length) {
|
|
740
|
-
return result
|
|
703
|
+
return result;
|
|
741
704
|
}
|
|
742
|
-
}
|
|
743
|
-
|
|
705
|
+
};
|
|
744
706
|
async function decipherLinkPublicKey(data) {
|
|
745
|
-
const buffer = toRequiredBuffer(data)
|
|
746
|
-
const salt = buffer.slice(0, 32)
|
|
747
|
-
const secretKey = await
|
|
748
|
-
const iv = buffer.slice(32, 48)
|
|
749
|
-
const payload = buffer.slice(48, 80)
|
|
750
|
-
return
|
|
707
|
+
const buffer = toRequiredBuffer(data);
|
|
708
|
+
const salt = buffer.slice(0, 32);
|
|
709
|
+
const secretKey = await derivePairingCodeKey(authState.creds.pairingCode, salt);
|
|
710
|
+
const iv = buffer.slice(32, 48);
|
|
711
|
+
const payload = buffer.slice(48, 80);
|
|
712
|
+
return aesDecryptCTR(payload, secretKey, iv);
|
|
751
713
|
}
|
|
752
|
-
|
|
753
714
|
function toRequiredBuffer(data) {
|
|
754
715
|
if (data === undefined) {
|
|
755
|
-
throw new
|
|
716
|
+
throw new Boom('Invalid buffer', { statusCode: 400 });
|
|
756
717
|
}
|
|
757
|
-
return data instanceof Buffer ? data : Buffer.from(data)
|
|
718
|
+
return data instanceof Buffer ? data : Buffer.from(data);
|
|
758
719
|
}
|
|
759
|
-
|
|
760
720
|
const willSendMessageAgain = async (id, participant) => {
|
|
761
|
-
const key = `${id}:${participant}
|
|
762
|
-
const retryCount = (await msgRetryCache.get(key)) || 0
|
|
763
|
-
return retryCount < maxMsgRetryCount
|
|
764
|
-
}
|
|
765
|
-
|
|
721
|
+
const key = `${id}:${participant}`;
|
|
722
|
+
const retryCount = (await msgRetryCache.get(key)) || 0;
|
|
723
|
+
return retryCount < maxMsgRetryCount;
|
|
724
|
+
};
|
|
766
725
|
const updateSendMessageAgainCount = async (id, participant) => {
|
|
767
|
-
const key = `${id}:${participant}
|
|
768
|
-
const newValue = ((await msgRetryCache.get(key)) || 0) + 1
|
|
769
|
-
await msgRetryCache.set(key, newValue)
|
|
770
|
-
}
|
|
771
|
-
|
|
726
|
+
const key = `${id}:${participant}`;
|
|
727
|
+
const newValue = ((await msgRetryCache.get(key)) || 0) + 1;
|
|
728
|
+
await msgRetryCache.set(key, newValue);
|
|
729
|
+
};
|
|
772
730
|
const sendMessagesAgain = async (key, ids, retryNode) => {
|
|
773
|
-
const remoteJid = key.remoteJid
|
|
774
|
-
const participant = key.participant || remoteJid
|
|
775
|
-
const retryCount = +retryNode.attrs.count || 1
|
|
776
|
-
|
|
731
|
+
const remoteJid = key.remoteJid;
|
|
732
|
+
const participant = key.participant || remoteJid;
|
|
733
|
+
const retryCount = +retryNode.attrs.count || 1;
|
|
777
734
|
// Try to get messages from cache first, then fallback to getMessage
|
|
778
|
-
const msgs = []
|
|
779
|
-
|
|
735
|
+
const msgs = [];
|
|
780
736
|
for (const id of ids) {
|
|
781
|
-
let msg
|
|
782
|
-
|
|
737
|
+
let msg;
|
|
783
738
|
// Try to get from retry cache first if enabled
|
|
784
739
|
if (messageRetryManager) {
|
|
785
|
-
const cachedMsg = messageRetryManager.getRecentMessage(remoteJid, id)
|
|
740
|
+
const cachedMsg = messageRetryManager.getRecentMessage(remoteJid, id);
|
|
786
741
|
if (cachedMsg) {
|
|
787
|
-
msg = cachedMsg.message
|
|
788
|
-
logger.debug({ jid: remoteJid, id }, 'found message in retry cache')
|
|
789
|
-
|
|
742
|
+
msg = cachedMsg.message;
|
|
743
|
+
logger.debug({ jid: remoteJid, id }, 'found message in retry cache');
|
|
790
744
|
// Mark retry as successful since we found the message
|
|
791
|
-
messageRetryManager.markRetrySuccess(id)
|
|
745
|
+
messageRetryManager.markRetrySuccess(id);
|
|
792
746
|
}
|
|
793
747
|
}
|
|
794
|
-
|
|
795
748
|
// Fallback to getMessage if not found in cache
|
|
796
749
|
if (!msg) {
|
|
797
|
-
msg = await getMessage({ ...key, id })
|
|
750
|
+
msg = await getMessage({ ...key, id });
|
|
798
751
|
if (msg) {
|
|
799
|
-
logger.debug({ jid: remoteJid, id }, 'found message via getMessage')
|
|
800
|
-
|
|
752
|
+
logger.debug({ jid: remoteJid, id }, 'found message via getMessage');
|
|
801
753
|
// Also mark as successful if found via getMessage
|
|
802
754
|
if (messageRetryManager) {
|
|
803
755
|
messageRetryManager.markRetrySuccess(id);
|
|
804
756
|
}
|
|
805
757
|
}
|
|
806
758
|
}
|
|
807
|
-
msgs.push(msg)
|
|
759
|
+
msgs.push(msg);
|
|
808
760
|
}
|
|
809
|
-
|
|
810
761
|
// if it's the primary jid sending the request
|
|
811
762
|
// just re-send the message to everyone
|
|
812
763
|
// prevents the first message decryption failure
|
|
813
|
-
const sendToAll = !
|
|
814
|
-
|
|
764
|
+
const sendToAll = !jidDecode(participant)?.device;
|
|
815
765
|
// Check if we should recreate session for this retry
|
|
816
|
-
let shouldRecreateSession = false
|
|
817
|
-
let recreateReason = ''
|
|
818
|
-
|
|
766
|
+
let shouldRecreateSession = false;
|
|
767
|
+
let recreateReason = '';
|
|
819
768
|
if (enableAutoSessionRecreation && messageRetryManager) {
|
|
820
769
|
try {
|
|
821
|
-
const sessionId = signalRepository.jidToSignalProtocolAddress(participant)
|
|
822
|
-
const hasSession = await signalRepository.validateSession(participant)
|
|
823
|
-
const result = messageRetryManager.shouldRecreateSession(participant, retryCount, hasSession.exists)
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
recreateReason = result.reason
|
|
827
|
-
|
|
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;
|
|
828
775
|
if (shouldRecreateSession) {
|
|
829
|
-
logger.
|
|
776
|
+
logger.debug({ participant, retryCount, reason: recreateReason }, 'recreating session for outgoing retry');
|
|
830
777
|
await authState.keys.set({ session: { [sessionId]: null } });
|
|
831
778
|
}
|
|
832
779
|
}
|
|
833
780
|
catch (error) {
|
|
834
|
-
logger.warn({ error, participant }, 'failed to check session recreation for outgoing retry')
|
|
781
|
+
logger.warn({ error, participant }, 'failed to check session recreation for outgoing retry');
|
|
835
782
|
}
|
|
836
783
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
if (WABinary_1.isJidGroup(remoteJid)) {
|
|
784
|
+
await assertSessions([participant]);
|
|
785
|
+
if (isJidGroup(remoteJid)) {
|
|
841
786
|
await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } });
|
|
842
787
|
}
|
|
843
|
-
logger.debug({ participant, sendToAll, shouldRecreateSession, recreateReason }, 'forced new session for retry recp')
|
|
844
|
-
|
|
788
|
+
logger.debug({ participant, sendToAll, shouldRecreateSession, recreateReason }, 'forced new session for retry recp');
|
|
845
789
|
for (const [i, msg] of msgs.entries()) {
|
|
846
790
|
if (!ids[i])
|
|
847
|
-
continue
|
|
848
|
-
|
|
791
|
+
continue;
|
|
849
792
|
if (msg && (await willSendMessageAgain(ids[i], participant))) {
|
|
850
|
-
updateSendMessageAgainCount(ids[i], participant)
|
|
851
|
-
const msgRelayOpts = { messageId: ids[i] }
|
|
852
|
-
|
|
793
|
+
updateSendMessageAgainCount(ids[i], participant);
|
|
794
|
+
const msgRelayOpts = { messageId: ids[i] };
|
|
853
795
|
if (sendToAll) {
|
|
854
|
-
msgRelayOpts.useUserDevicesCache = false
|
|
796
|
+
msgRelayOpts.useUserDevicesCache = false;
|
|
855
797
|
}
|
|
856
798
|
else {
|
|
857
799
|
msgRelayOpts.participant = {
|
|
858
800
|
jid: participant,
|
|
859
801
|
count: +retryNode.attrs.count
|
|
860
|
-
}
|
|
802
|
+
};
|
|
861
803
|
}
|
|
862
|
-
await relayMessage(key.remoteJid, msg, msgRelayOpts)
|
|
804
|
+
await relayMessage(key.remoteJid, msg, msgRelayOpts);
|
|
863
805
|
}
|
|
864
806
|
else {
|
|
865
|
-
logger.debug({ jid: key.remoteJid, id: ids[i] }, 'recv retry request, but message not available')
|
|
807
|
+
logger.debug({ jid: key.remoteJid, id: ids[i] }, 'recv retry request, but message not available');
|
|
866
808
|
}
|
|
867
809
|
}
|
|
868
|
-
}
|
|
869
|
-
|
|
810
|
+
};
|
|
870
811
|
const handleReceipt = async (node) => {
|
|
871
|
-
const { attrs, content } = node
|
|
872
|
-
const isLid = attrs.from.includes('lid')
|
|
873
|
-
const isNodeFromMe =
|
|
874
|
-
const remoteJid = !isNodeFromMe ||
|
|
875
|
-
const fromMe = !attrs.recipient || ((attrs.type === 'retry' || attrs.type === 'sender') && isNodeFromMe)
|
|
876
|
-
|
|
812
|
+
const { attrs, content } = node;
|
|
813
|
+
const isLid = attrs.from.includes('lid');
|
|
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;
|
|
816
|
+
const fromMe = !attrs.recipient || ((attrs.type === 'retry' || attrs.type === 'sender') && isNodeFromMe);
|
|
877
817
|
const key = {
|
|
878
818
|
remoteJid,
|
|
879
819
|
id: '',
|
|
880
820
|
fromMe,
|
|
881
821
|
participant: attrs.participant
|
|
822
|
+
};
|
|
823
|
+
if (shouldIgnoreJid(remoteJid) && remoteJid !== S_WHATSAPP_NET) {
|
|
824
|
+
logger.debug({ remoteJid }, 'ignoring receipt from jid');
|
|
825
|
+
await sendMessageAck(node);
|
|
826
|
+
return;
|
|
882
827
|
}
|
|
883
|
-
|
|
884
|
-
if (shouldIgnoreJid(remoteJid) && remoteJid !== '@s.whatsapp.net') {
|
|
885
|
-
logger.debug({ remoteJid }, 'ignoring receipt from jid')
|
|
886
|
-
await sendMessageAck(node)
|
|
887
|
-
return
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
const ids = [attrs.id]
|
|
828
|
+
const ids = [attrs.id];
|
|
891
829
|
if (Array.isArray(content)) {
|
|
892
|
-
const items =
|
|
893
|
-
ids.push(...items.map(i => i.attrs.id))
|
|
830
|
+
const items = getBinaryNodeChildren(content[0], 'item');
|
|
831
|
+
ids.push(...items.map(i => i.attrs.id));
|
|
894
832
|
}
|
|
895
|
-
|
|
896
833
|
try {
|
|
897
834
|
await Promise.all([
|
|
898
835
|
processingMutex.mutex(async () => {
|
|
899
|
-
const status =
|
|
900
|
-
|
|
901
|
-
if (typeof status !== 'undefined' && (
|
|
836
|
+
const status = getStatusFromReceiptType(attrs.type);
|
|
837
|
+
if (typeof status !== 'undefined' &&
|
|
902
838
|
// basically, we only want to know when a message from us has been delivered to/read by the other person
|
|
903
839
|
// or another device of ours has read some messages
|
|
904
|
-
status >=
|
|
905
|
-
|
|
906
|
-
if (WABinary_1.isJidGroup(remoteJid) || WABinary_1.isJidStatusBroadcast(remoteJid)) {
|
|
840
|
+
(status >= proto.WebMessageInfo.Status.SERVER_ACK || !isNodeFromMe)) {
|
|
841
|
+
if (isJidGroup(remoteJid) || isJidStatusBroadcast(remoteJid)) {
|
|
907
842
|
if (attrs.participant) {
|
|
908
|
-
const updateKey = status ===
|
|
843
|
+
const updateKey = status === proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp';
|
|
909
844
|
ev.emit('message-receipt.update', ids.map(id => ({
|
|
910
845
|
key: { ...key, id },
|
|
911
846
|
receipt: {
|
|
912
|
-
userJid:
|
|
847
|
+
userJid: jidNormalizedUser(attrs.participant),
|
|
913
848
|
[updateKey]: +attrs.t
|
|
914
849
|
}
|
|
915
|
-
})))
|
|
850
|
+
})));
|
|
916
851
|
}
|
|
917
852
|
}
|
|
918
|
-
|
|
919
853
|
else {
|
|
920
854
|
ev.emit('messages.update', ids.map(id => ({
|
|
921
855
|
key: { ...key, id },
|
|
922
856
|
update: { status }
|
|
923
|
-
})))
|
|
857
|
+
})));
|
|
924
858
|
}
|
|
925
859
|
}
|
|
926
|
-
|
|
927
860
|
if (attrs.type === 'retry') {
|
|
928
861
|
// correctly set who is asking for the retry
|
|
929
|
-
key.participant = key.participant || attrs.from
|
|
930
|
-
const retryNode =
|
|
931
|
-
|
|
862
|
+
key.participant = key.participant || attrs.from;
|
|
863
|
+
const retryNode = getBinaryNodeChild(node, 'retry');
|
|
932
864
|
if (ids[0] && key.participant && (await willSendMessageAgain(ids[0], key.participant))) {
|
|
933
865
|
if (key.fromMe) {
|
|
934
866
|
try {
|
|
935
|
-
updateSendMessageAgainCount(ids[0], key.participant)
|
|
936
|
-
logger.debug({ attrs, key }, 'recv retry request')
|
|
937
|
-
await sendMessagesAgain(key, ids, retryNode)
|
|
867
|
+
updateSendMessageAgainCount(ids[0], key.participant);
|
|
868
|
+
logger.debug({ attrs, key }, 'recv retry request');
|
|
869
|
+
await sendMessagesAgain(key, ids, retryNode);
|
|
938
870
|
}
|
|
939
|
-
|
|
940
871
|
catch (error) {
|
|
941
|
-
logger.error({ key, ids, trace: error instanceof Error ? error.stack : 'Unknown error' }, 'error in sending message again')
|
|
872
|
+
logger.error({ key, ids, trace: error instanceof Error ? error.stack : 'Unknown error' }, 'error in sending message again');
|
|
942
873
|
}
|
|
943
874
|
}
|
|
944
|
-
|
|
945
875
|
else {
|
|
946
|
-
logger.info({ attrs, key }, 'recv retry for not fromMe message')
|
|
876
|
+
logger.info({ attrs, key }, 'recv retry for not fromMe message');
|
|
947
877
|
}
|
|
948
878
|
}
|
|
949
|
-
|
|
950
879
|
else {
|
|
951
|
-
logger.info({ attrs, key }, 'will not send message again, as sent too many times')
|
|
880
|
+
logger.info({ attrs, key }, 'will not send message again, as sent too many times');
|
|
952
881
|
}
|
|
953
882
|
}
|
|
954
883
|
})
|
|
955
|
-
])
|
|
884
|
+
]);
|
|
956
885
|
}
|
|
957
886
|
finally {
|
|
958
|
-
await sendMessageAck(node)
|
|
887
|
+
await sendMessageAck(node);
|
|
959
888
|
}
|
|
960
|
-
}
|
|
961
|
-
|
|
889
|
+
};
|
|
962
890
|
const handleNotification = async (node) => {
|
|
963
|
-
const remoteJid = node.attrs.from
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
return
|
|
891
|
+
const remoteJid = node.attrs.from;
|
|
892
|
+
if (shouldIgnoreJid(remoteJid) && remoteJid !== S_WHATSAPP_NET) {
|
|
893
|
+
logger.debug({ remoteJid, id: node.attrs.id }, 'ignored notification');
|
|
894
|
+
await sendMessageAck(node);
|
|
895
|
+
return;
|
|
969
896
|
}
|
|
970
|
-
|
|
971
897
|
try {
|
|
972
898
|
await Promise.all([
|
|
973
899
|
processingMutex.mutex(async () => {
|
|
974
|
-
const msg = await processNotification(node)
|
|
975
|
-
|
|
900
|
+
const msg = await processNotification(node);
|
|
976
901
|
if (msg) {
|
|
977
|
-
const fromMe =
|
|
902
|
+
const fromMe = areJidsSameUser(node.attrs.participant || remoteJid, authState.creds.me.id);
|
|
903
|
+
const { senderAlt: participantAlt, addressingMode } = extractAddressingContext(node);
|
|
978
904
|
msg.key = {
|
|
979
905
|
remoteJid,
|
|
980
906
|
fromMe,
|
|
981
907
|
participant: node.attrs.participant,
|
|
908
|
+
participantAlt,
|
|
909
|
+
addressingMode,
|
|
982
910
|
id: node.attrs.id,
|
|
983
911
|
...(msg.key || {})
|
|
984
|
-
}
|
|
985
|
-
msg.participant
|
|
986
|
-
msg.messageTimestamp = +node.attrs.t
|
|
987
|
-
const fullMsg =
|
|
988
|
-
await upsertMessage(fullMsg, 'append')
|
|
912
|
+
};
|
|
913
|
+
msg.participant ?? (msg.participant = node.attrs.participant);
|
|
914
|
+
msg.messageTimestamp = +node.attrs.t;
|
|
915
|
+
const fullMsg = proto.WebMessageInfo.fromObject(msg);
|
|
916
|
+
await upsertMessage(fullMsg, 'append');
|
|
989
917
|
}
|
|
990
918
|
})
|
|
991
|
-
])
|
|
919
|
+
]);
|
|
992
920
|
}
|
|
993
921
|
finally {
|
|
994
|
-
await sendMessageAck(node)
|
|
922
|
+
await sendMessageAck(node);
|
|
995
923
|
}
|
|
996
|
-
}
|
|
997
|
-
|
|
924
|
+
};
|
|
998
925
|
const handleMessage = async (node) => {
|
|
999
|
-
if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !==
|
|
1000
|
-
logger.debug({ key: node.attrs.key }, 'ignored message')
|
|
1001
|
-
await sendMessageAck(node)
|
|
1002
|
-
return
|
|
926
|
+
if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !== S_WHATSAPP_NET) {
|
|
927
|
+
logger.debug({ key: node.attrs.key }, 'ignored message');
|
|
928
|
+
await sendMessageAck(node, NACK_REASONS.UnhandledError);
|
|
929
|
+
return;
|
|
1003
930
|
}
|
|
1004
|
-
|
|
1005
|
-
let response
|
|
1006
|
-
const groupJid = node.attrs.from;
|
|
1007
|
-
const communityJid = linkedParentMap[groupJid];
|
|
1008
|
-
const encNode = WABinary_1.getBinaryNodeChild(node, 'enc')
|
|
1009
|
-
|
|
931
|
+
const encNode = getBinaryNodeChild(node, 'enc');
|
|
1010
932
|
// TODO: temporary fix for crashes and issues resulting of failed msmsg decryption
|
|
1011
933
|
if (encNode && encNode.attrs.type === 'msmsg') {
|
|
1012
|
-
logger.debug({ key: node.attrs.key }, 'ignored msmsg')
|
|
1013
|
-
await sendMessageAck(node,
|
|
1014
|
-
return
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
if (WABinary_1.getBinaryNodeChild(node, 'unavailable') && !encNode) {
|
|
1018
|
-
await sendMessageAck(node)
|
|
1019
|
-
const { key } = Utils_1.decodeMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '').fullMessage
|
|
1020
|
-
response = await requestPlaceholderResend(key);
|
|
1021
|
-
if (response === 'RESOLVED') {
|
|
1022
|
-
return
|
|
1023
|
-
}
|
|
1024
|
-
logger.debug('received unavailable message, acked and requested resend from phone');
|
|
934
|
+
logger.debug({ key: node.attrs.key }, 'ignored msmsg');
|
|
935
|
+
await sendMessageAck(node, NACK_REASONS.MissingMessageSecret);
|
|
936
|
+
return;
|
|
1025
937
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
await placeholderResendCache.del(node.attrs.id)
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
const { fullMessage: msg, category, author, decrypt } = Utils_1.decryptMessageNode(node, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, logger)
|
|
1033
|
-
|
|
1034
|
-
if (response && msg?.messageStubParameters?.[0] === Utils_1.NO_MESSAGE_FOUND_ERROR_TEXT) {
|
|
1035
|
-
msg.messageStubParameters = [Utils_1.NO_MESSAGE_FOUND_ERROR_TEXT, response]
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
if (msg.message?.protocolMessage?.type === WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER &&
|
|
1039
|
-
node.attrs.sender_pn) {
|
|
1040
|
-
const lid = WABinary_1.jidNormalizedUser(node.attrs.from), pn = WABinary_1.jidNormalizedUser(node.attrs.sender_pn)
|
|
1041
|
-
ev.emit('lid-mapping.update', { lid, pn })
|
|
1042
|
-
await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }])
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
const alt = msg.key.participantAlt || msg.key.remoteJidAlt
|
|
1046
|
-
|
|
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;
|
|
1047
940
|
// store new mappings we didn't have before
|
|
1048
941
|
if (!!alt) {
|
|
1049
|
-
const altServer =
|
|
1050
|
-
|
|
942
|
+
const altServer = jidDecode(alt)?.server;
|
|
943
|
+
const primaryJid = msg.key.participant || msg.key.remoteJid;
|
|
1051
944
|
if (altServer === 'lid') {
|
|
1052
|
-
if (
|
|
1053
|
-
await signalRepository.lidMapping.storeLIDPNMappings([
|
|
1054
|
-
|
|
1055
|
-
])
|
|
945
|
+
if (!(await signalRepository.lidMapping.getPNForLID(alt))) {
|
|
946
|
+
await signalRepository.lidMapping.storeLIDPNMappings([{ lid: alt, pn: primaryJid }]);
|
|
947
|
+
await signalRepository.migrateSession(primaryJid, alt);
|
|
1056
948
|
}
|
|
1057
949
|
}
|
|
1058
950
|
else {
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
{ lid: msg.key.participant || msg.key.remoteJid, pn: alt }
|
|
1062
|
-
])
|
|
1063
|
-
}
|
|
951
|
+
await signalRepository.lidMapping.storeLIDPNMappings([{ lid: primaryJid, pn: alt }]);
|
|
952
|
+
await signalRepository.migrateSession(alt, primaryJid);
|
|
1064
953
|
}
|
|
1065
954
|
}
|
|
1066
|
-
|
|
1067
955
|
if (msg.key?.remoteJid && msg.key?.id && messageRetryManager) {
|
|
1068
|
-
messageRetryManager.addRecentMessage(msg.key.remoteJid, msg.key.id, msg.message)
|
|
956
|
+
messageRetryManager.addRecentMessage(msg.key.remoteJid, msg.key.id, msg.message);
|
|
1069
957
|
logger.debug({
|
|
1070
958
|
jid: msg.key.remoteJid,
|
|
1071
959
|
id: msg.key.id
|
|
1072
|
-
}, 'Added message to recent cache for retry receipts')
|
|
960
|
+
}, 'Added message to recent cache for retry receipts');
|
|
1073
961
|
}
|
|
1074
|
-
|
|
1075
962
|
try {
|
|
1076
|
-
await
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
if (msg
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
if (!ws.isOpen) {
|
|
1093
|
-
logger.debug({ node }, 'Connection closed, skipping retry')
|
|
1094
|
-
return
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
if (WABinary_1.getBinaryNodeChild(node, 'unavailable')) {
|
|
1098
|
-
logger.debug('Message unavailable, skipping retry')
|
|
1099
|
-
return
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
// Handle pre-key errors with upload and delay
|
|
1103
|
-
if (isPreKeyError) {
|
|
1104
|
-
logger.info({ error: errorMessage }, 'PreKey error detected, uploading and retrying')
|
|
1105
|
-
try {
|
|
1106
|
-
logger.debug('Uploading pre-keys for error recovery')
|
|
1107
|
-
await uploadPreKeys(5)
|
|
1108
|
-
logger.debug('Waiting for server to process new pre-keys')
|
|
1109
|
-
await Utils_1.delay(1000)
|
|
1110
|
-
}
|
|
1111
|
-
catch (uploadErr) {
|
|
1112
|
-
logger.error({ uploadErr }, 'Pre-key upload failed, proceeding with retry anyway')
|
|
1113
|
-
}
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
const encNode = WABinary_1.getBinaryNodeChild(node, 'enc')
|
|
1117
|
-
await sendRetryRequest(node, !encNode)
|
|
1118
|
-
if (retryRequestDelayMs) {
|
|
1119
|
-
await Utils_1.delay(retryRequestDelayMs)
|
|
1120
|
-
}
|
|
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;
|
|
1121
979
|
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
980
|
+
// Handle pre-key errors with upload and delay
|
|
981
|
+
if (isPreKeyError) {
|
|
982
|
+
logger.info({ error: errorMessage }, 'PreKey error detected, uploading and retrying');
|
|
1125
983
|
try {
|
|
1126
|
-
|
|
1127
|
-
await
|
|
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);
|
|
1128
988
|
}
|
|
1129
|
-
catch (
|
|
1130
|
-
logger.error({
|
|
989
|
+
catch (uploadErr) {
|
|
990
|
+
logger.error({ uploadErr }, 'Pre-key upload failed, proceeding with retry anyway');
|
|
1131
991
|
}
|
|
1132
992
|
}
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
// no type in the receipt => message delivered
|
|
1138
|
-
let type = undefined
|
|
1139
|
-
|
|
1140
|
-
let participant = msg.key.participant
|
|
1141
|
-
if (communityJid) {
|
|
1142
|
-
msg.communityJid = communityJid;
|
|
1143
|
-
}
|
|
1144
|
-
if (category === 'peer') {
|
|
1145
|
-
// special peer message
|
|
1146
|
-
type = 'peer_msg'
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
else if (msg.key.fromMe) {
|
|
1150
|
-
// message was sent by us from a different device
|
|
1151
|
-
type = 'sender'
|
|
1152
|
-
|
|
1153
|
-
// need to specially handle this case
|
|
1154
|
-
if (WABinary_1.isLidUser(msg.key.remoteJid) || WABinary_1.isLidUser(msg.key.remoteJidAlt)) {
|
|
1155
|
-
participant = author // TODO: investigate sending receipts to LIDs and not PNs
|
|
993
|
+
const encNode = getBinaryNodeChild(node, 'enc');
|
|
994
|
+
await sendRetryRequest(node, !encNode);
|
|
995
|
+
if (retryRequestDelayMs) {
|
|
996
|
+
await delay(retryRequestDelayMs);
|
|
1156
997
|
}
|
|
1157
998
|
}
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
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);
|
|
1005
|
+
}
|
|
1006
|
+
catch (retryErr) {
|
|
1007
|
+
logger.error({ retryErr }, 'Failed to send retry after error handling');
|
|
1008
|
+
}
|
|
1161
1009
|
}
|
|
1162
|
-
await
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
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
|
|
1169
1027
|
}
|
|
1170
1028
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
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
|
+
});
|
|
1176
1043
|
}
|
|
1177
|
-
|
|
1178
1044
|
catch (error) {
|
|
1179
|
-
logger.error({ error, node }, 'error in handling message')
|
|
1045
|
+
logger.error({ error, node: binaryNodeToString(node) }, 'error in handling message');
|
|
1180
1046
|
}
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
|
|
1184
|
-
if (!authState.creds.me?.id) {
|
|
1185
|
-
throw new boom_1.Boom('Not authenticated')
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1188
|
-
const pdoMessage = {
|
|
1189
|
-
historySyncOnDemandRequest: {
|
|
1190
|
-
chatJid: oldestMsgKey.remoteJid,
|
|
1191
|
-
oldestMsgFromMe: oldestMsgKey.fromMe,
|
|
1192
|
-
oldestMsgId: oldestMsgKey.id,
|
|
1193
|
-
oldestMsgTimestampMs: oldestMsgTimestamp,
|
|
1194
|
-
onDemandMsgCount: count
|
|
1195
|
-
},
|
|
1196
|
-
peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.HISTORY_SYNC_ON_DEMAND
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
return sendPeerDataOperationMessage(pdoMessage)
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
const requestPlaceholderResend = async (messageKey) => {
|
|
1203
|
-
if (!authState.creds.me?.id) {
|
|
1204
|
-
throw new boom_1.Boom('Not authenticated')
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
if (placeholderResendCache.get(messageKey?.id)) {
|
|
1208
|
-
logger.debug({ messageKey }, 'already requested resend')
|
|
1209
|
-
return
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1212
|
-
else {
|
|
1213
|
-
placeholderResendCache.set(messageKey?.id, true)
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
await Utils_1.delay(5000)
|
|
1217
|
-
|
|
1218
|
-
if (!placeholderResendCache.get(messageKey?.id)) {
|
|
1219
|
-
logger.debug({ messageKey }, 'message received while resend requested')
|
|
1220
|
-
return 'RESOLVED'
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
const pdoMessage = {
|
|
1224
|
-
placeholderMessageResendRequest: [{
|
|
1225
|
-
messageKey
|
|
1226
|
-
}],
|
|
1227
|
-
peerDataOperationRequestType: WAProto_1.proto.Message.PeerDataOperationRequestType.PLACEHOLDER_MESSAGE_RESEND
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1230
|
-
setTimeout(() => {
|
|
1231
|
-
if (placeholderResendCache.get(messageKey?.id)) {
|
|
1232
|
-
logger.debug({ messageKey }, 'PDO message without response after 15 seconds. Phone possibly offline')
|
|
1233
|
-
placeholderResendCache.del(messageKey?.id)
|
|
1234
|
-
}
|
|
1235
|
-
}, 15000)
|
|
1236
|
-
|
|
1237
|
-
return sendPeerDataOperationMessage(pdoMessage)
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1047
|
+
};
|
|
1240
1048
|
const handleCall = async (node) => {
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
const
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
if (WABinary_1.isLidUser(from) && infoChild.tag === 'relaylatency') {
|
|
1250
|
-
const verify = await callOfferCache.get(callId)
|
|
1251
|
-
|
|
1252
|
-
if (!verify) {
|
|
1253
|
-
status = 'offer'
|
|
1254
|
-
|
|
1255
|
-
const callLid = {
|
|
1256
|
-
chatId: attrs.from,
|
|
1257
|
-
from,
|
|
1258
|
-
id: callId,
|
|
1259
|
-
date: new Date(+attrs.t * 1000),
|
|
1260
|
-
offline: !!attrs.offline,
|
|
1261
|
-
status
|
|
1262
|
-
}
|
|
1263
|
-
await callOfferCache.set(callId, callLid)
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1049
|
+
const { attrs } = node;
|
|
1050
|
+
const [infoChild] = getAllBinaryNodeChildren(node);
|
|
1051
|
+
const status = getCallStatusFromNode(infoChild);
|
|
1052
|
+
if (!infoChild) {
|
|
1053
|
+
throw new Boom('Missing call info in call node');
|
|
1054
|
+
}
|
|
1055
|
+
const callId = infoChild.attrs['call-id'];
|
|
1056
|
+
const from = infoChild.attrs.from || infoChild.attrs['call-creator'];
|
|
1267
1057
|
const call = {
|
|
1268
1058
|
chatId: attrs.from,
|
|
1269
1059
|
from,
|
|
1270
1060
|
id: callId,
|
|
1271
1061
|
date: new Date(+attrs.t * 1000),
|
|
1272
1062
|
offline: !!attrs.offline,
|
|
1273
|
-
status
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1063
|
+
status
|
|
1064
|
+
};
|
|
1276
1065
|
if (status === 'offer') {
|
|
1277
|
-
call.isVideo = !!
|
|
1278
|
-
call.isGroup = infoChild.attrs.type === 'group' || !!infoChild.attrs['group-jid']
|
|
1279
|
-
call.groupJid = infoChild.attrs['group-jid']
|
|
1280
|
-
await callOfferCache.set(call.id, call)
|
|
1066
|
+
call.isVideo = !!getBinaryNodeChild(infoChild, 'video');
|
|
1067
|
+
call.isGroup = infoChild.attrs.type === 'group' || !!infoChild.attrs['group-jid'];
|
|
1068
|
+
call.groupJid = infoChild.attrs['group-jid'];
|
|
1069
|
+
await callOfferCache.set(call.id, call);
|
|
1281
1070
|
}
|
|
1282
|
-
|
|
1283
|
-
const existingCall = await callOfferCache.get(call.id)
|
|
1284
|
-
|
|
1071
|
+
const existingCall = await callOfferCache.get(call.id);
|
|
1285
1072
|
// use existing call info to populate this event
|
|
1286
1073
|
if (existingCall) {
|
|
1287
|
-
call.isVideo = existingCall.isVideo
|
|
1288
|
-
call.isGroup = existingCall.isGroup
|
|
1074
|
+
call.isVideo = existingCall.isVideo;
|
|
1075
|
+
call.isGroup = existingCall.isGroup;
|
|
1289
1076
|
}
|
|
1290
|
-
|
|
1291
1077
|
// delete data once call has ended
|
|
1292
1078
|
if (status === 'reject' || status === 'accept' || status === 'timeout' || status === 'terminate') {
|
|
1293
|
-
await callOfferCache.del(call.id)
|
|
1079
|
+
await callOfferCache.del(call.id);
|
|
1294
1080
|
}
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
await sendMessageAck(node)
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1081
|
+
ev.emit('call', [call]);
|
|
1082
|
+
await sendMessageAck(node);
|
|
1083
|
+
};
|
|
1301
1084
|
const handleBadAck = async ({ attrs }) => {
|
|
1302
|
-
const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id
|
|
1085
|
+
const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id };
|
|
1303
1086
|
// WARNING: REFRAIN FROM ENABLING THIS FOR NOW. IT WILL CAUSE A LOOP
|
|
1304
1087
|
// // current hypothesis is that if pash is sent in the ack
|
|
1305
1088
|
// // it means -- the message hasn't reached all devices yet
|
|
@@ -1316,140 +1099,89 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
1316
1099
|
// error in acknowledgement,
|
|
1317
1100
|
// device could not display the message
|
|
1318
1101
|
if (attrs.error) {
|
|
1319
|
-
logger.warn({ attrs }, 'received error in ack')
|
|
1102
|
+
logger.warn({ attrs }, 'received error in ack');
|
|
1320
1103
|
ev.emit('messages.update', [
|
|
1321
1104
|
{
|
|
1322
1105
|
key,
|
|
1323
1106
|
update: {
|
|
1324
|
-
status:
|
|
1325
|
-
messageStubParameters: [
|
|
1326
|
-
attrs.error
|
|
1327
|
-
]
|
|
1107
|
+
status: WAMessageStatus.ERROR,
|
|
1108
|
+
messageStubParameters: [attrs.error]
|
|
1328
1109
|
}
|
|
1329
1110
|
}
|
|
1330
|
-
])
|
|
1111
|
+
]);
|
|
1331
1112
|
}
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1113
|
+
};
|
|
1334
1114
|
/// processes a node with the given function
|
|
1335
1115
|
/// and adds the task to the existing buffer if we're buffering events
|
|
1336
1116
|
const processNodeWithBuffer = async (node, identifier, exec) => {
|
|
1337
|
-
ev.buffer()
|
|
1338
|
-
await execTask()
|
|
1339
|
-
ev.flush()
|
|
1117
|
+
ev.buffer();
|
|
1118
|
+
await execTask();
|
|
1119
|
+
ev.flush();
|
|
1340
1120
|
function execTask() {
|
|
1341
|
-
return exec(node, false)
|
|
1342
|
-
.catch(err => onUnexpectedError(err, identifier))
|
|
1121
|
+
return exec(node, false).catch(err => onUnexpectedError(err, identifier));
|
|
1343
1122
|
}
|
|
1344
|
-
}
|
|
1345
|
-
|
|
1123
|
+
};
|
|
1346
1124
|
const makeOfflineNodeProcessor = () => {
|
|
1347
1125
|
const nodeProcessorMap = new Map([
|
|
1348
1126
|
['message', handleMessage],
|
|
1349
1127
|
['call', handleCall],
|
|
1350
1128
|
['receipt', handleReceipt],
|
|
1351
1129
|
['notification', handleNotification]
|
|
1352
|
-
])
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
let isProcessing = false
|
|
1356
|
-
|
|
1130
|
+
]);
|
|
1131
|
+
const nodes = [];
|
|
1132
|
+
let isProcessing = false;
|
|
1357
1133
|
const enqueue = (type, node) => {
|
|
1358
|
-
nodes.push({ type, node })
|
|
1359
|
-
|
|
1134
|
+
nodes.push({ type, node });
|
|
1360
1135
|
if (isProcessing) {
|
|
1361
|
-
return
|
|
1136
|
+
return;
|
|
1362
1137
|
}
|
|
1363
|
-
|
|
1364
|
-
isProcessing = true
|
|
1365
|
-
|
|
1138
|
+
isProcessing = true;
|
|
1366
1139
|
const promise = async () => {
|
|
1367
1140
|
while (nodes.length && ws.isOpen) {
|
|
1368
|
-
const { type, node } = nodes.shift()
|
|
1369
|
-
const nodeProcessor = nodeProcessorMap.get(type)
|
|
1141
|
+
const { type, node } = nodes.shift();
|
|
1142
|
+
const nodeProcessor = nodeProcessorMap.get(type);
|
|
1370
1143
|
if (!nodeProcessor) {
|
|
1371
|
-
onUnexpectedError(new Error(`unknown offline node type: ${type}`), 'processing offline node')
|
|
1372
|
-
continue
|
|
1144
|
+
onUnexpectedError(new Error(`unknown offline node type: ${type}`), 'processing offline node');
|
|
1145
|
+
continue;
|
|
1373
1146
|
}
|
|
1374
|
-
await nodeProcessor(node)
|
|
1147
|
+
await nodeProcessor(node);
|
|
1375
1148
|
}
|
|
1376
|
-
isProcessing = false
|
|
1377
|
-
}
|
|
1378
|
-
promise().catch(error => onUnexpectedError(error, 'processing offline nodes'))
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
const offlineNodeProcessor = makeOfflineNodeProcessor()
|
|
1385
|
-
|
|
1149
|
+
isProcessing = false;
|
|
1150
|
+
};
|
|
1151
|
+
promise().catch(error => onUnexpectedError(error, 'processing offline nodes'));
|
|
1152
|
+
};
|
|
1153
|
+
return { enqueue };
|
|
1154
|
+
};
|
|
1155
|
+
const offlineNodeProcessor = makeOfflineNodeProcessor();
|
|
1386
1156
|
const processNode = (type, node, identifier, exec) => {
|
|
1387
|
-
const isOffline = !!node.attrs.offline
|
|
1388
|
-
|
|
1157
|
+
const isOffline = !!node.attrs.offline;
|
|
1389
1158
|
if (isOffline) {
|
|
1390
|
-
offlineNodeProcessor.enqueue(type, node)
|
|
1159
|
+
offlineNodeProcessor.enqueue(type, node);
|
|
1391
1160
|
}
|
|
1392
|
-
|
|
1393
1161
|
else {
|
|
1394
|
-
processNodeWithBuffer(node, identifier, exec)
|
|
1162
|
+
processNodeWithBuffer(node, identifier, exec);
|
|
1395
1163
|
}
|
|
1396
|
-
}
|
|
1397
|
-
let latestNodeInMemory = null;
|
|
1398
|
-
const nodelogger = (node) => {
|
|
1399
|
-
if (!node) return null;
|
|
1400
|
-
latestNodeInMemory = node
|
|
1401
|
-
return latestNodeInMemory;
|
|
1402
|
-
};
|
|
1403
|
-
const setNodeLoggerListener = () => {
|
|
1404
|
-
return latestNodeInMemory;
|
|
1405
|
-
};
|
|
1164
|
+
};
|
|
1406
1165
|
// recv a message
|
|
1407
1166
|
ws.on('CB:message', (node) => {
|
|
1408
|
-
processNode('message', node, 'processing message', handleMessage)
|
|
1409
|
-
|
|
1410
|
-
})
|
|
1167
|
+
processNode('message', node, 'processing message', handleMessage);
|
|
1168
|
+
});
|
|
1411
1169
|
ws.on('CB:call', async (node) => {
|
|
1412
|
-
processNode('call', node, 'handling call', handleCall)
|
|
1413
|
-
})
|
|
1170
|
+
processNode('call', node, 'handling call', handleCall);
|
|
1171
|
+
});
|
|
1414
1172
|
ws.on('CB:receipt', node => {
|
|
1415
|
-
processNode('receipt', node, 'handling receipt', handleReceipt)
|
|
1416
|
-
|
|
1417
|
-
})
|
|
1173
|
+
processNode('receipt', node, 'handling receipt', handleReceipt);
|
|
1174
|
+
});
|
|
1418
1175
|
ws.on('CB:notification', async (node) => {
|
|
1419
|
-
processNode('notification', node, 'handling notification', handleNotification)
|
|
1420
|
-
|
|
1421
|
-
})
|
|
1176
|
+
processNode('notification', node, 'handling notification', handleNotification);
|
|
1177
|
+
});
|
|
1422
1178
|
ws.on('CB:ack,class:message', (node) => {
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
.catch(error => onUnexpectedError(error, 'handling bad ack'))
|
|
1426
|
-
})
|
|
1427
|
-
|
|
1428
|
-
const linkedParentMap = {};
|
|
1429
|
-
ws.on("CB:iq", (node) => {
|
|
1430
|
-
if (node && node.tag === "iq" && node.attrs.type === "result") {
|
|
1431
|
-
const groups = node.content;
|
|
1432
|
-
|
|
1433
|
-
if (Array.isArray(groups)) {
|
|
1434
|
-
for (const group of groups) {
|
|
1435
|
-
const groupId = group.attrs.id + "@g.us";
|
|
1436
|
-
|
|
1437
|
-
if (group && Array.isArray(group.content)) {
|
|
1438
|
-
for (const item of group.content) {
|
|
1439
|
-
if (
|
|
1440
|
-
item.tag === "linked_parent" &&
|
|
1441
|
-
item.attrs &&
|
|
1442
|
-
item.attrs.jid
|
|
1443
|
-
) {
|
|
1444
|
-
linkedParentMap[groupId] = item.attrs.jid;
|
|
1445
|
-
}
|
|
1446
|
-
}
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
});
|
|
1179
|
+
handleBadAck(node).catch(error => onUnexpectedError(error, 'handling bad ack'));
|
|
1180
|
+
});
|
|
1452
1181
|
ev.on('call', ([call]) => {
|
|
1182
|
+
if (!call) {
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1453
1185
|
// missed call + group call notification message generation
|
|
1454
1186
|
if (call.status === 'timeout' || (call.status === 'offer' && call.isGroup)) {
|
|
1455
1187
|
const msg = {
|
|
@@ -1458,49 +1190,39 @@ ws.on("CB:iq", (node) => {
|
|
|
1458
1190
|
id: call.id,
|
|
1459
1191
|
fromMe: false
|
|
1460
1192
|
},
|
|
1461
|
-
messageTimestamp:
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1193
|
+
messageTimestamp: unixTimestampSeconds(call.date)
|
|
1194
|
+
};
|
|
1464
1195
|
if (call.status === 'timeout') {
|
|
1465
1196
|
if (call.isGroup) {
|
|
1466
|
-
msg.messageStubType = call.isVideo
|
|
1197
|
+
msg.messageStubType = call.isVideo
|
|
1198
|
+
? WAMessageStubType.CALL_MISSED_GROUP_VIDEO
|
|
1199
|
+
: WAMessageStubType.CALL_MISSED_GROUP_VOICE;
|
|
1467
1200
|
}
|
|
1468
|
-
|
|
1469
1201
|
else {
|
|
1470
|
-
msg.messageStubType = call.isVideo ?
|
|
1202
|
+
msg.messageStubType = call.isVideo ? WAMessageStubType.CALL_MISSED_VIDEO : WAMessageStubType.CALL_MISSED_VOICE;
|
|
1471
1203
|
}
|
|
1472
1204
|
}
|
|
1473
|
-
|
|
1474
1205
|
else {
|
|
1475
|
-
msg.message = { call: { callKey: Buffer.from(call.id) } }
|
|
1206
|
+
msg.message = { call: { callKey: Buffer.from(call.id) } };
|
|
1476
1207
|
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
upsertMessage(protoMsg, call.offline ? 'append' : 'notify')
|
|
1208
|
+
const protoMsg = proto.WebMessageInfo.fromObject(msg);
|
|
1209
|
+
upsertMessage(protoMsg, call.offline ? 'append' : 'notify');
|
|
1480
1210
|
}
|
|
1481
|
-
})
|
|
1482
|
-
|
|
1211
|
+
});
|
|
1483
1212
|
ev.on('connection.update', ({ isOnline }) => {
|
|
1484
1213
|
if (typeof isOnline !== 'undefined') {
|
|
1485
|
-
sendActiveReceipts = isOnline
|
|
1486
|
-
logger.trace(`sendActiveReceipts set to "${sendActiveReceipts}"`)
|
|
1214
|
+
sendActiveReceipts = isOnline;
|
|
1215
|
+
logger.trace(`sendActiveReceipts set to "${sendActiveReceipts}"`);
|
|
1487
1216
|
}
|
|
1488
|
-
})
|
|
1489
|
-
|
|
1217
|
+
});
|
|
1490
1218
|
return {
|
|
1491
|
-
...
|
|
1219
|
+
...sock,
|
|
1492
1220
|
sendMessageAck,
|
|
1493
1221
|
sendRetryRequest,
|
|
1494
|
-
offerCall,
|
|
1495
1222
|
rejectCall,
|
|
1496
|
-
nodelogger,
|
|
1497
|
-
setNodeLoggerListener,
|
|
1498
1223
|
fetchMessageHistory,
|
|
1499
1224
|
requestPlaceholderResend,
|
|
1500
1225
|
messageRetryManager
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1503
|
-
|
|
1504
|
-
module.exports = {
|
|
1505
|
-
makeMessagesRecvSocket
|
|
1506
|
-
}
|
|
1226
|
+
};
|
|
1227
|
+
};
|
|
1228
|
+
//# sourceMappingURL=messages-recv.js.map
|