@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,115 +1,93 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const makeMessagesSocket = (config) => {
|
|
23
|
-
const { logger, maxMsgRetryCount, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: axiosOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache } = config
|
|
24
|
-
const baron = newsletter_1.makeNewsletterSocket(config)
|
|
25
|
-
const { ev, authState, processingMutex, signalRepository, upsertMessage, createCallLink, query, fetchPrivacySettings, sendNode, groupQuery, groupMetadata, groupToggleEphemeral, newsletterWMexQuery, executeUSyncQuery } = baron
|
|
26
|
-
|
|
27
|
-
const userDevicesCache = config.userDevicesCache || new node_cache_1.default({
|
|
28
|
-
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.USER_DEVICES,
|
|
1
|
+
import NodeCache from '@cacheable/node-cache';
|
|
2
|
+
import { Boom } from '@hapi/boom';
|
|
3
|
+
import { proto } from '../../WAProto/index.js';
|
|
4
|
+
import { DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
|
|
5
|
+
import { aggregateMessageKeysNotFromMe, assertMediaContent, bindWaitForEvent, decryptMediaRetryData, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateParticipantHashV2, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils/index.js';
|
|
6
|
+
import { getUrlInfo } from '../Utils/link-preview.js';
|
|
7
|
+
import { makeKeyedMutex } from '../Utils/make-mutex.js';
|
|
8
|
+
import { areJidsSameUser, getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isJidGroup, isLidUser, isPnUser, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET } from '../WABinary/index.js';
|
|
9
|
+
import { USyncQuery, USyncUser } from '../WAUSync/index.js';
|
|
10
|
+
import { makeNewsletterSocket } from './newsletter.js';
|
|
11
|
+
export const makeMessagesSocket = (config) => {
|
|
12
|
+
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: httpRequestOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache, maxMsgRetryCount } = config;
|
|
13
|
+
const sock = makeNewsletterSocket(config);
|
|
14
|
+
const { ev, authState, processingMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral } = sock;
|
|
15
|
+
const userDevicesCache = config.userDevicesCache ||
|
|
16
|
+
new NodeCache({
|
|
17
|
+
stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
|
|
18
|
+
useClones: false
|
|
19
|
+
});
|
|
20
|
+
const peerSessionsCache = new NodeCache({
|
|
21
|
+
stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES,
|
|
29
22
|
useClones: false
|
|
30
|
-
})
|
|
31
|
-
|
|
23
|
+
});
|
|
32
24
|
// Initialize message retry manager if enabled
|
|
33
|
-
const messageRetryManager = enableRecentMessageCache ? new
|
|
34
|
-
|
|
25
|
+
const messageRetryManager = enableRecentMessageCache ? new MessageRetryManager(logger, maxMsgRetryCount) : null;
|
|
35
26
|
// Prevent race conditions in Signal session encryption by user
|
|
36
|
-
const encryptionMutex =
|
|
37
|
-
|
|
38
|
-
let mediaConn
|
|
39
|
-
|
|
27
|
+
const encryptionMutex = makeKeyedMutex();
|
|
28
|
+
let mediaConn;
|
|
40
29
|
const refreshMediaConn = async (forceGet = false) => {
|
|
41
|
-
const media = await mediaConn
|
|
42
|
-
|
|
43
|
-
if (!media || forceGet || (new Date().getTime() - media.fetchDate.getTime()) > media.ttl * 1000) {
|
|
30
|
+
const media = await mediaConn;
|
|
31
|
+
if (!media || forceGet || new Date().getTime() - media.fetchDate.getTime() > media.ttl * 1000) {
|
|
44
32
|
mediaConn = (async () => {
|
|
45
|
-
|
|
46
33
|
const result = await query({
|
|
47
34
|
tag: 'iq',
|
|
48
35
|
attrs: {
|
|
49
36
|
type: 'set',
|
|
50
37
|
xmlns: 'w:m',
|
|
51
|
-
to:
|
|
38
|
+
to: S_WHATSAPP_NET
|
|
52
39
|
},
|
|
53
40
|
content: [{ tag: 'media_conn', attrs: {} }]
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
41
|
+
});
|
|
42
|
+
const mediaConnNode = getBinaryNodeChild(result, 'media_conn');
|
|
43
|
+
// TODO: explore full length of data that whatsapp provides
|
|
58
44
|
const node = {
|
|
59
|
-
hosts:
|
|
45
|
+
hosts: getBinaryNodeChildren(mediaConnNode, 'host').map(({ attrs }) => ({
|
|
60
46
|
hostname: attrs.hostname,
|
|
61
|
-
maxContentLengthBytes: +attrs.maxContentLengthBytes
|
|
47
|
+
maxContentLengthBytes: +attrs.maxContentLengthBytes
|
|
62
48
|
})),
|
|
63
49
|
auth: mediaConnNode.attrs.auth,
|
|
64
50
|
ttl: +mediaConnNode.attrs.ttl,
|
|
65
51
|
fetchDate: new Date()
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return node
|
|
71
|
-
})()
|
|
52
|
+
};
|
|
53
|
+
logger.debug('fetched media conn');
|
|
54
|
+
return node;
|
|
55
|
+
})();
|
|
72
56
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|
|
57
|
+
return mediaConn;
|
|
58
|
+
};
|
|
77
59
|
/**
|
|
78
60
|
* generic send receipt function
|
|
79
61
|
* used for receipts of phone call, read, delivery etc.
|
|
80
62
|
* */
|
|
81
63
|
const sendReceipt = async (jid, participant, messageIds, type) => {
|
|
64
|
+
if (!messageIds || messageIds.length === 0) {
|
|
65
|
+
throw new Boom('missing ids in receipt');
|
|
66
|
+
}
|
|
82
67
|
const node = {
|
|
83
68
|
tag: 'receipt',
|
|
84
69
|
attrs: {
|
|
85
|
-
id: messageIds[0]
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const isReadReceipt = type === 'read' || type === 'read-self'
|
|
90
|
-
|
|
70
|
+
id: messageIds[0]
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const isReadReceipt = type === 'read' || type === 'read-self';
|
|
91
74
|
if (isReadReceipt) {
|
|
92
|
-
node.attrs.t =
|
|
75
|
+
node.attrs.t = unixTimestampSeconds().toString();
|
|
93
76
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
node.attrs.
|
|
97
|
-
node.attrs.to = participant
|
|
77
|
+
if (type === 'sender' && (isPnUser(jid) || isLidUser(jid))) {
|
|
78
|
+
node.attrs.recipient = jid;
|
|
79
|
+
node.attrs.to = participant;
|
|
98
80
|
}
|
|
99
|
-
|
|
100
81
|
else {
|
|
101
|
-
node.attrs.to = jid
|
|
82
|
+
node.attrs.to = jid;
|
|
102
83
|
if (participant) {
|
|
103
|
-
node.attrs.participant = participant
|
|
84
|
+
node.attrs.participant = participant;
|
|
104
85
|
}
|
|
105
86
|
}
|
|
106
|
-
|
|
107
87
|
if (type) {
|
|
108
|
-
node.attrs.type =
|
|
88
|
+
node.attrs.type = type;
|
|
109
89
|
}
|
|
110
|
-
|
|
111
|
-
const remainingMessageIds = messageIds.slice(1)
|
|
112
|
-
|
|
90
|
+
const remainingMessageIds = messageIds.slice(1);
|
|
113
91
|
if (remainingMessageIds.length) {
|
|
114
92
|
node.content = [
|
|
115
93
|
{
|
|
@@ -120,573 +98,277 @@ const makeMessagesSocket = (config) => {
|
|
|
120
98
|
attrs: { id }
|
|
121
99
|
}))
|
|
122
100
|
}
|
|
123
|
-
]
|
|
101
|
+
];
|
|
124
102
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
await sendNode(node)
|
|
129
|
-
}
|
|
130
|
-
|
|
103
|
+
logger.debug({ attrs: node.attrs, messageIds }, 'sending receipt for messages');
|
|
104
|
+
await sendNode(node);
|
|
105
|
+
};
|
|
131
106
|
/** Correctly bulk send receipts to multiple chats, participants */
|
|
132
107
|
const sendReceipts = async (keys, type) => {
|
|
133
|
-
const recps =
|
|
134
|
-
|
|
108
|
+
const recps = aggregateMessageKeysNotFromMe(keys);
|
|
135
109
|
for (const { jid, participant, messageIds } of recps) {
|
|
136
|
-
await sendReceipt(jid, participant, messageIds, type)
|
|
110
|
+
await sendReceipt(jid, participant, messageIds, type);
|
|
137
111
|
}
|
|
138
|
-
}
|
|
139
|
-
|
|
112
|
+
};
|
|
140
113
|
/** Bulk read messages. Keys can be from different chats & participants */
|
|
141
114
|
const readMessages = async (keys) => {
|
|
142
|
-
const privacySettings = await fetchPrivacySettings()
|
|
143
|
-
|
|
115
|
+
const privacySettings = await fetchPrivacySettings();
|
|
144
116
|
// based on privacy settings, we have to change the read type
|
|
145
|
-
const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self'
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Deduplicate JIDs when both LID and PN versions exist for same user
|
|
152
|
-
* Prefers LID over PN to maintain single encryption layer
|
|
153
|
-
*/
|
|
154
|
-
const deduplicateLidPnJids = (jids) => {
|
|
155
|
-
const lidUsers = new Set()
|
|
156
|
-
const filteredJids = []
|
|
157
|
-
|
|
158
|
-
// Collect all LID users
|
|
159
|
-
for (const jid of jids) {
|
|
160
|
-
if (WABinary_1.isLidUser(jid)) {
|
|
161
|
-
const user = WABinary_1.jidDecode(jid)?.user
|
|
162
|
-
if (user)
|
|
163
|
-
lidUsers.add(user)
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Filter out PN versions when LID exists
|
|
168
|
-
for (const jid of jids) {
|
|
169
|
-
if (WABinary_1.isJidUser(jid)) {
|
|
170
|
-
const user = WABinary_1.jidDecode(jid)?.user
|
|
171
|
-
if (user && lidUsers.has(user)) {
|
|
172
|
-
logger.debug({ jid }, 'Skipping PN - LID version exists')
|
|
173
|
-
continue
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
filteredJids.push(jid)
|
|
177
|
-
}
|
|
178
|
-
return filteredJids
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/** Fetch image for groups, user, and newsletter **/
|
|
182
|
-
const profilePictureUrl = async (jid) => {
|
|
183
|
-
if (WABinary_1.isJidNewsletter(jid)) {
|
|
184
|
-
|
|
185
|
-
let node = await newsletterWMexQuery(undefined, Types_1.QueryIds.METADATA, {
|
|
186
|
-
input: {
|
|
187
|
-
key: jid,
|
|
188
|
-
type: 'JID',
|
|
189
|
-
view_role: 'GUEST'
|
|
190
|
-
},
|
|
191
|
-
fetch_viewer_metadata: true,
|
|
192
|
-
fetch_full_image: true,
|
|
193
|
-
fetch_creation_time: true
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
let result = WABinary_1.getBinaryNodeChild(node, 'result')?.content?.toString()
|
|
197
|
-
|
|
198
|
-
let metadata = JSON.parse(result).data[Types_1.XWAPaths.NEWSLETTER]
|
|
199
|
-
|
|
200
|
-
return Utils_1.getUrlFromDirectPath(metadata.thread_metadata.picture?.direct_path || '')
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
else {
|
|
205
|
-
const result = await query({
|
|
206
|
-
tag: 'iq',
|
|
207
|
-
attrs: {
|
|
208
|
-
target: WABinary_1.jidNormalizedUser(jid),
|
|
209
|
-
to: WABinary_1.S_WHATSAPP_NET,
|
|
210
|
-
type: 'get',
|
|
211
|
-
xmlns: 'w:profile:picture'
|
|
212
|
-
},
|
|
213
|
-
content: [{
|
|
214
|
-
tag: 'picture',
|
|
215
|
-
attrs: {
|
|
216
|
-
type: 'image',
|
|
217
|
-
query: 'url'
|
|
218
|
-
}
|
|
219
|
-
}]
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
const child = WABinary_1.getBinaryNodeChild(result, 'picture')
|
|
223
|
-
|
|
224
|
-
return child?.attrs?.url || null
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
117
|
+
const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self';
|
|
118
|
+
await sendReceipts(keys, readType);
|
|
119
|
+
};
|
|
228
120
|
/** Fetch all the devices we've to send a message to */
|
|
229
121
|
const getUSyncDevices = async (jids, useCache, ignoreZeroDevices) => {
|
|
230
|
-
const deviceResults = []
|
|
231
|
-
|
|
122
|
+
const deviceResults = [];
|
|
232
123
|
if (!useCache) {
|
|
233
|
-
logger.debug('not using cache for devices')
|
|
124
|
+
logger.debug('not using cache for devices');
|
|
234
125
|
}
|
|
235
|
-
|
|
236
|
-
const toFetch = []
|
|
237
|
-
|
|
238
|
-
jids = deduplicateLidPnJids(Array.from(new Set(jids)))
|
|
126
|
+
const toFetch = [];
|
|
239
127
|
const jidsWithUser = jids
|
|
240
128
|
.map(jid => {
|
|
241
|
-
const decoded =
|
|
242
|
-
const user = decoded?.user
|
|
243
|
-
const device = decoded?.device
|
|
244
|
-
const isExplicitDevice = typeof device === 'number' && device >= 0
|
|
245
|
-
|
|
129
|
+
const decoded = jidDecode(jid);
|
|
130
|
+
const user = decoded?.user;
|
|
131
|
+
const device = decoded?.device;
|
|
132
|
+
const isExplicitDevice = typeof device === 'number' && device >= 0;
|
|
246
133
|
if (isExplicitDevice && user) {
|
|
247
134
|
deviceResults.push({
|
|
248
135
|
user,
|
|
249
136
|
device,
|
|
250
|
-
|
|
137
|
+
jid
|
|
251
138
|
});
|
|
252
|
-
return null
|
|
139
|
+
return null;
|
|
253
140
|
}
|
|
254
|
-
|
|
255
|
-
jid
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
let mgetDevices
|
|
261
|
-
|
|
141
|
+
jid = jidNormalizedUser(jid);
|
|
142
|
+
return { jid, user };
|
|
143
|
+
})
|
|
144
|
+
.filter(jid => jid !== null);
|
|
145
|
+
let mgetDevices;
|
|
262
146
|
if (useCache && userDevicesCache.mget) {
|
|
263
|
-
const usersToFetch = jidsWithUser.map(j => j?.user).filter(Boolean)
|
|
264
|
-
mgetDevices = await userDevicesCache.mget(usersToFetch)
|
|
147
|
+
const usersToFetch = jidsWithUser.map(j => j?.user).filter(Boolean);
|
|
148
|
+
mgetDevices = await userDevicesCache.mget(usersToFetch);
|
|
265
149
|
}
|
|
266
|
-
|
|
267
150
|
for (const { jid, user } of jidsWithUser) {
|
|
268
151
|
if (useCache) {
|
|
269
152
|
const devices = mgetDevices?.[user] ||
|
|
270
|
-
(userDevicesCache.mget ? undefined : (await userDevicesCache.get(user)))
|
|
271
|
-
|
|
153
|
+
(userDevicesCache.mget ? undefined : (await userDevicesCache.get(user)));
|
|
272
154
|
if (devices) {
|
|
273
|
-
const
|
|
274
|
-
const devicesWithWire = devices.map(d => ({
|
|
155
|
+
const devicesWithJid = devices.map(d => ({
|
|
275
156
|
...d,
|
|
276
|
-
|
|
277
|
-
}))
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
logger.trace({ user }, 'using cache for devices')
|
|
157
|
+
jid: jidEncode(d.user, d.server, d.device)
|
|
158
|
+
}));
|
|
159
|
+
deviceResults.push(...devicesWithJid);
|
|
160
|
+
logger.trace({ user }, 'using cache for devices');
|
|
281
161
|
}
|
|
282
162
|
else {
|
|
283
|
-
toFetch.push(jid)
|
|
163
|
+
toFetch.push(jid);
|
|
284
164
|
}
|
|
285
165
|
}
|
|
286
166
|
else {
|
|
287
|
-
toFetch.push(jid)
|
|
167
|
+
toFetch.push(jid);
|
|
288
168
|
}
|
|
289
169
|
}
|
|
290
|
-
|
|
291
170
|
if (!toFetch.length) {
|
|
292
|
-
return deviceResults
|
|
171
|
+
return deviceResults;
|
|
293
172
|
}
|
|
294
|
-
|
|
295
|
-
const requestedLidUsers = new Set()
|
|
173
|
+
const requestedLidUsers = new Set();
|
|
296
174
|
for (const jid of toFetch) {
|
|
297
|
-
if (
|
|
298
|
-
const user =
|
|
175
|
+
if (isLidUser(jid) || isHostedLidUser(jid)) {
|
|
176
|
+
const user = jidDecode(jid)?.user;
|
|
299
177
|
if (user)
|
|
300
|
-
requestedLidUsers.add(user)
|
|
178
|
+
requestedLidUsers.add(user);
|
|
301
179
|
}
|
|
302
180
|
}
|
|
303
|
-
|
|
304
|
-
const query = new WAUSync_1.USyncQuery().withContext('message').withDeviceProtocol()
|
|
181
|
+
const query = new USyncQuery().withContext('message').withDeviceProtocol().withLIDProtocol();
|
|
305
182
|
for (const jid of toFetch) {
|
|
306
|
-
query.withUser(new
|
|
183
|
+
query.withUser(new USyncUser().withId(jid)); // todo: investigate - the idea here is that <user> should have an inline lid field with the lid being the pn equivalent
|
|
307
184
|
}
|
|
308
|
-
|
|
309
|
-
const result = await executeUSyncQuery(query)
|
|
310
|
-
|
|
185
|
+
const result = await sock.executeUSyncQuery(query);
|
|
311
186
|
if (result) {
|
|
312
|
-
|
|
313
|
-
const
|
|
314
|
-
|
|
187
|
+
// TODO: LID MAP this stuff (lid protocol will now return lid with devices)
|
|
188
|
+
const lidResults = result.list.filter(a => !!a.lid);
|
|
189
|
+
if (lidResults.length > 0) {
|
|
190
|
+
logger.trace('Storing LID maps from device call');
|
|
191
|
+
await signalRepository.lidMapping.storeLIDPNMappings(lidResults.map(a => ({ lid: a.lid, pn: a.id })));
|
|
192
|
+
}
|
|
193
|
+
const extracted = extractDeviceJids(result?.list, authState.creds.me.id, authState.creds.me.lid, ignoreZeroDevices);
|
|
194
|
+
const deviceMap = {};
|
|
315
195
|
for (const item of extracted) {
|
|
316
|
-
deviceMap[item.user] = deviceMap[item.user] || []
|
|
317
|
-
deviceMap[item.user]?.push(item)
|
|
196
|
+
deviceMap[item.user] = deviceMap[item.user] || [];
|
|
197
|
+
deviceMap[item.user]?.push(item);
|
|
318
198
|
}
|
|
319
|
-
|
|
320
199
|
// Process each user's devices as a group for bulk LID migration
|
|
321
200
|
for (const [user, userDevices] of Object.entries(deviceMap)) {
|
|
322
|
-
const isLidUser = requestedLidUsers.has(user)
|
|
323
|
-
|
|
201
|
+
const isLidUser = requestedLidUsers.has(user);
|
|
324
202
|
// Process all devices for this user
|
|
325
203
|
for (const item of userDevices) {
|
|
326
|
-
const
|
|
327
|
-
?
|
|
328
|
-
:
|
|
204
|
+
const finalJid = isLidUser
|
|
205
|
+
? jidEncode(user, item.server, item.device)
|
|
206
|
+
: jidEncode(item.user, item.server, item.device);
|
|
329
207
|
deviceResults.push({
|
|
330
208
|
...item,
|
|
331
|
-
|
|
209
|
+
jid: finalJid
|
|
332
210
|
});
|
|
333
|
-
|
|
334
211
|
logger.debug({
|
|
335
212
|
user: item.user,
|
|
336
213
|
device: item.device,
|
|
337
|
-
|
|
214
|
+
finalJid,
|
|
338
215
|
usedLid: isLidUser
|
|
339
|
-
}, 'Processed device with LID priority')
|
|
216
|
+
}, 'Processed device with LID priority');
|
|
340
217
|
}
|
|
341
218
|
}
|
|
342
|
-
|
|
343
219
|
if (userDevicesCache.mset) {
|
|
344
220
|
// if the cache supports mset, we can set all devices in one go
|
|
345
|
-
await userDevicesCache.mset(Object.entries(deviceMap).map(([key, value]) => ({ key, value })))
|
|
221
|
+
await userDevicesCache.mset(Object.entries(deviceMap).map(([key, value]) => ({ key, value })));
|
|
346
222
|
}
|
|
347
|
-
|
|
348
223
|
else {
|
|
349
224
|
for (const key in deviceMap) {
|
|
350
225
|
if (deviceMap[key])
|
|
351
|
-
await userDevicesCache.set(key, deviceMap[key])
|
|
226
|
+
await userDevicesCache.set(key, deviceMap[key]);
|
|
352
227
|
}
|
|
353
228
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
const assertSessions = async (jids, force) => {
|
|
360
|
-
let didFetchNewSession = false
|
|
361
|
-
const jidsRequiringFetch = []
|
|
362
|
-
|
|
363
|
-
// Apply same deduplication as in getUSyncDevices
|
|
364
|
-
jids = deduplicateLidPnJids(jids)
|
|
365
|
-
|
|
366
|
-
if (force) {
|
|
367
|
-
// Check which sessions are missing (with LID migration check)
|
|
368
|
-
const addrs = jids.map(jid => signalRepository.jidToSignalProtocolAddress(jid))
|
|
369
|
-
const sessions = await authState.keys.get('session', addrs)
|
|
370
|
-
|
|
371
|
-
const checkJidSession = (jid) => {
|
|
372
|
-
const signalId = signalRepository.jidToSignalProtocolAddress(jid)
|
|
373
|
-
const hasSession = !!sessions[signalId]
|
|
374
|
-
|
|
375
|
-
// Add to fetch list if no session exists
|
|
376
|
-
// Session type selection (LID vs PN) is handled in encryptMessage
|
|
377
|
-
if (!hasSession) {
|
|
378
|
-
if (jid.includes('@lid')) {
|
|
379
|
-
logger.debug({ jid }, 'No LID session found, will create new LID session')
|
|
380
|
-
}
|
|
381
|
-
jidsRequiringFetch.push(jid)
|
|
229
|
+
const userDeviceUpdates = {};
|
|
230
|
+
for (const [userId, devices] of Object.entries(deviceMap)) {
|
|
231
|
+
if (devices && devices.length > 0) {
|
|
232
|
+
userDeviceUpdates[userId] = devices.map(d => d.device?.toString() || '0');
|
|
382
233
|
}
|
|
383
234
|
}
|
|
384
|
-
|
|
385
|
-
// Process all JIDs
|
|
386
|
-
for (const jid of jids) {
|
|
387
|
-
checkJidSession(jid)
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
else {
|
|
391
|
-
const addrs = jids.map(jid => signalRepository.jidToSignalProtocolAddress(jid))
|
|
392
|
-
const sessions = await authState.keys.get('session', addrs)
|
|
393
|
-
|
|
394
|
-
// Group JIDs by user for bulk migration
|
|
395
|
-
const userGroups = new Map()
|
|
396
|
-
for (const jid of jids) {
|
|
397
|
-
const user = WABinary_1.jidNormalizedUser(jid)
|
|
398
|
-
if (!userGroups.has(user)) {
|
|
399
|
-
userGroups.set(user, [])
|
|
400
|
-
}
|
|
401
|
-
userGroups.get(user).push(jid)
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// Helper to check LID mapping for a user
|
|
405
|
-
const checkUserLidMapping = async (user, userJids) => {
|
|
406
|
-
if (!userJids.some(jid => WABinary_1.isJidUser(jid))) {
|
|
407
|
-
return { shouldMigrate: false, lidForPN: undefined }
|
|
408
|
-
}
|
|
409
|
-
|
|
235
|
+
if (Object.keys(userDeviceUpdates).length > 0) {
|
|
410
236
|
try {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
const mapping = await signalRepository.lidMapping.getLIDForPN(pnJid)
|
|
414
|
-
|
|
415
|
-
if (mapping?.includes('@lid')) {
|
|
416
|
-
logger.debug({ user, lidForPN: mapping, deviceCount: userJids.length }, 'User has LID mapping - preparing bulk migration')
|
|
417
|
-
return { shouldMigrate: true, lidForPN: mapping }
|
|
418
|
-
}
|
|
237
|
+
await authState.keys.set({ 'device-list': userDeviceUpdates });
|
|
238
|
+
logger.debug({ userCount: Object.keys(userDeviceUpdates).length }, 'stored user device lists for bulk migration');
|
|
419
239
|
}
|
|
420
240
|
catch (error) {
|
|
421
|
-
logger.
|
|
241
|
+
logger.warn({ error }, 'failed to store user device lists');
|
|
422
242
|
}
|
|
423
|
-
|
|
424
|
-
return { shouldMigrate: false, lidForPN: undefined }
|
|
425
243
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
lidMapping: lidForPN,
|
|
442
|
-
migrated: migrationResult.migrated,
|
|
443
|
-
skipped: migrationResult.skipped,
|
|
444
|
-
total: migrationResult.total
|
|
445
|
-
}, 'Completed bulk migration for user devices');
|
|
446
|
-
}
|
|
447
|
-
else {
|
|
448
|
-
logger.debug({
|
|
449
|
-
user,
|
|
450
|
-
lidMapping: lidForPN,
|
|
451
|
-
skipped: migrationResult.skipped,
|
|
452
|
-
total: migrationResult.total
|
|
453
|
-
}, 'All user device sessions already migrated');
|
|
454
|
-
}
|
|
244
|
+
}
|
|
245
|
+
return deviceResults;
|
|
246
|
+
};
|
|
247
|
+
const assertSessions = async (jids) => {
|
|
248
|
+
let didFetchNewSession = false;
|
|
249
|
+
const uniqueJids = [...new Set(jids)]; // Deduplicate JIDs
|
|
250
|
+
const jidsRequiringFetch = [];
|
|
251
|
+
logger.debug({ jids }, 'assertSessions call with jids');
|
|
252
|
+
// Check peerSessionsCache and validate sessions using libsignal loadSession
|
|
253
|
+
for (const jid of uniqueJids) {
|
|
254
|
+
const signalId = signalRepository.jidToSignalProtocolAddress(jid);
|
|
255
|
+
const cachedSession = peerSessionsCache.get(signalId);
|
|
256
|
+
if (cachedSession !== undefined) {
|
|
257
|
+
if (cachedSession) {
|
|
258
|
+
continue; // Session exists in cache
|
|
455
259
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
const
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
// Determine correct JID to fetch (LID if mapping exists, otherwise original)
|
|
464
|
-
if (jid.includes('@s.whatsapp.net') && shouldMigrateUser && lidForPN) {
|
|
465
|
-
const decoded = WABinary_1.jidDecode(jid)
|
|
466
|
-
const lidDeviceJid = decoded.device !== undefined ? `${WABinary_1.jidDecode(lidForPN).user}:${decoded.device}@lid` : lidForPN
|
|
467
|
-
|
|
468
|
-
jidsRequiringFetch.push(lidDeviceJid)
|
|
469
|
-
logger.debug({ pnJid: jid, lidJid: lidDeviceJid }, 'Adding LID JID to fetch list (conversion)')
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
else {
|
|
473
|
-
jidsRequiringFetch.push(jid)
|
|
474
|
-
logger.debug({ jid }, 'Adding JID to fetch list')
|
|
475
|
-
}
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
const sessionValidation = await signalRepository.validateSession(jid);
|
|
263
|
+
const hasSession = sessionValidation.exists;
|
|
264
|
+
peerSessionsCache.set(signalId, hasSession);
|
|
265
|
+
if (hasSession) {
|
|
266
|
+
continue;
|
|
476
267
|
}
|
|
477
|
-
|
|
478
|
-
userJids.forEach(addMissingSessionsToFetchList)
|
|
479
268
|
}
|
|
269
|
+
jidsRequiringFetch.push(jid);
|
|
480
270
|
}
|
|
481
|
-
|
|
482
271
|
if (jidsRequiringFetch.length) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
for (const jid of jidsRequiringFetch) {
|
|
490
|
-
const user = WABinary_1.jidDecode(jid)?.user
|
|
491
|
-
|
|
492
|
-
if (user) {
|
|
493
|
-
if (WABinary_1.isLidUser(jid)) {
|
|
494
|
-
lidUsersBeingFetched.add(user)
|
|
495
|
-
}
|
|
496
|
-
else if (WABinary_1.isJidUser(jid)) {
|
|
497
|
-
pnUsersBeingFetched.add(user)
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
// Find overlaps
|
|
503
|
-
const overlapping = Array.from(pnUsersBeingFetched).filter(user => lidUsersBeingFetched.has(user))
|
|
504
|
-
if (overlapping.length > 0) {
|
|
505
|
-
logger.warn({
|
|
506
|
-
overlapping,
|
|
507
|
-
lidUsersBeingFetched: Array.from(lidUsersBeingFetched),
|
|
508
|
-
pnUsersBeingFetched: Array.from(pnUsersBeingFetched)
|
|
509
|
-
}, 'Fetching both LID and PN sessions for same users')
|
|
510
|
-
}
|
|
511
|
-
|
|
272
|
+
// LID if mapped, otherwise original
|
|
273
|
+
const wireJids = [
|
|
274
|
+
...jidsRequiringFetch.filter(jid => !!isLidUser(jid) || !!isHostedLidUser(jid)),
|
|
275
|
+
...((await signalRepository.lidMapping.getLIDsForPNs(jidsRequiringFetch.filter(jid => !!isPnUser(jid) || !!isHostedPnUser(jid)))) || []).map(a => a.lid)
|
|
276
|
+
];
|
|
277
|
+
logger.debug({ jidsRequiringFetch, wireJids }, 'fetching sessions');
|
|
512
278
|
const result = await query({
|
|
513
279
|
tag: 'iq',
|
|
514
280
|
attrs: {
|
|
515
281
|
xmlns: 'encrypt',
|
|
516
282
|
type: 'get',
|
|
517
|
-
to:
|
|
283
|
+
to: S_WHATSAPP_NET
|
|
518
284
|
},
|
|
519
285
|
content: [
|
|
520
286
|
{
|
|
521
287
|
tag: 'key',
|
|
522
288
|
attrs: {},
|
|
523
|
-
content:
|
|
289
|
+
content: wireJids.map(jid => ({
|
|
524
290
|
tag: 'user',
|
|
525
291
|
attrs: { jid }
|
|
526
292
|
}))
|
|
527
293
|
}
|
|
528
294
|
]
|
|
529
|
-
})
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
295
|
+
});
|
|
296
|
+
await parseAndInjectE2ESessions(result, signalRepository);
|
|
297
|
+
didFetchNewSession = true;
|
|
298
|
+
// Cache fetched sessions using wire JIDs
|
|
299
|
+
for (const wireJid of wireJids) {
|
|
300
|
+
const signalId = signalRepository.jidToSignalProtocolAddress(wireJid);
|
|
301
|
+
peerSessionsCache.set(signalId, true);
|
|
302
|
+
}
|
|
533
303
|
}
|
|
534
|
-
return didFetchNewSession
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
/** Send Peer Operation */
|
|
304
|
+
return didFetchNewSession;
|
|
305
|
+
};
|
|
538
306
|
const sendPeerDataOperationMessage = async (pdoMessage) => {
|
|
539
307
|
//TODO: for later, abstract the logic to send a Peer Message instead of just PDO - useful for App State Key Resync with phone
|
|
540
308
|
if (!authState.creds.me?.id) {
|
|
541
|
-
throw new
|
|
309
|
+
throw new Boom('Not authenticated');
|
|
542
310
|
}
|
|
543
|
-
|
|
544
311
|
const protocolMessage = {
|
|
545
312
|
protocolMessage: {
|
|
546
313
|
peerDataOperationRequestMessage: pdoMessage,
|
|
547
|
-
type:
|
|
314
|
+
type: proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE
|
|
548
315
|
}
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
const meJid = WABinary_1.jidNormalizedUser(authState.creds.me.id)
|
|
552
|
-
|
|
316
|
+
};
|
|
317
|
+
const meJid = jidNormalizedUser(authState.creds.me.id);
|
|
553
318
|
const msgId = await relayMessage(meJid, protocolMessage, {
|
|
554
319
|
additionalAttributes: {
|
|
555
320
|
category: 'peer',
|
|
556
|
-
|
|
557
|
-
push_priority: 'high_force',
|
|
321
|
+
push_priority: 'high_force'
|
|
558
322
|
},
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
const createParticipantNodes = async (jids, message, extraAttrs, dsmMessage) => {
|
|
565
|
-
let patched = await patchMessageBeforeSending(message, jids)
|
|
566
|
-
|
|
567
|
-
if (!Array.isArray(patched)) {
|
|
568
|
-
patched = jids ? jids.map(jid => ({ recipientJid: jid, ...patched })) : [patched]
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
let shouldIncludeDeviceIdentity = false
|
|
572
|
-
|
|
573
|
-
const meId = authState.creds.me.id
|
|
574
|
-
const meLid = authState.creds.me?.lid
|
|
575
|
-
const meLidUser = meLid ? WABinary_1.jidDecode(meLid)?.user : null
|
|
576
|
-
const devicesByUser = new Map()
|
|
577
|
-
|
|
578
|
-
for (const patchedMessageWithJid of patched) {
|
|
579
|
-
const { recipientJid: wireJid, ...patchedMessage } = patchedMessageWithJid
|
|
580
|
-
if (!wireJid)
|
|
581
|
-
continue
|
|
582
|
-
|
|
583
|
-
// Extract user from JID for grouping
|
|
584
|
-
const decoded = WABinary_1.jidDecode(wireJid)
|
|
585
|
-
const user = decoded?.user
|
|
586
|
-
|
|
587
|
-
if (!user)
|
|
588
|
-
continue
|
|
589
|
-
|
|
590
|
-
if (!devicesByUser.has(user)) {
|
|
591
|
-
devicesByUser.set(user, []);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
devicesByUser.get(user).push({ recipientJid: wireJid, patchedMessage })
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
// Process each user's devices sequentially, but different users in parallel
|
|
598
|
-
const userEncryptionPromises = Array.from(devicesByUser.entries()).map(([user, userDevices]) => encryptionMutex.mutex(user, async () => {
|
|
599
|
-
logger.debug({ user, deviceCount: userDevices.length }, 'Acquiring encryption lock for user devices');
|
|
600
|
-
const userNodes = []
|
|
601
|
-
|
|
602
|
-
// Helper to get encryption JID with LID migration
|
|
603
|
-
const getEncryptionJid = async (wireJid) => {
|
|
604
|
-
if (!WABinary_1.isJidUser(wireJid))
|
|
605
|
-
return wireJid
|
|
606
|
-
|
|
607
|
-
try {
|
|
608
|
-
const lidForPN = await signalRepository.lidMapping.getLIDForPN(wireJid)
|
|
609
|
-
|
|
610
|
-
if (!lidForPN?.includes('@lid'))
|
|
611
|
-
return wireJid
|
|
612
|
-
|
|
613
|
-
// Preserve device ID from original wire JID
|
|
614
|
-
const wireDecoded = WABinary_1.jidDecode(wireJid)
|
|
615
|
-
const deviceId = wireDecoded?.device || 0
|
|
616
|
-
const lidDecoded = WABinary_1.jidDecode(lidForPN)
|
|
617
|
-
const lidWithDevice = WABinary_1.jidEncode(lidDecoded?.user, 'lid', deviceId)
|
|
618
|
-
|
|
619
|
-
// Migrate session to LID for unified encryption layer
|
|
620
|
-
try {
|
|
621
|
-
const migrationResult = await signalRepository.migrateSession([wireJid], lidWithDevice)
|
|
622
|
-
const recipientUser = WABinary_1.jidNormalizedUser(wireJid)
|
|
623
|
-
const ownPnUser = WABinary_1.jidNormalizedUser(meId)
|
|
624
|
-
const isOwnDevice = recipientUser === ownPnUser
|
|
625
|
-
logger.info({ wireJid, lidWithDevice, isOwnDevice }, 'Migrated to LID encryption')
|
|
626
|
-
|
|
627
|
-
// Delete PN session after successful migration
|
|
628
|
-
try {
|
|
629
|
-
if (migrationResult.migrated) {
|
|
630
|
-
await signalRepository.deleteSession([wireJid])
|
|
631
|
-
logger.debug({ deletedPNSession: wireJid }, 'Deleted PN session')
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
catch (deleteError) {
|
|
635
|
-
logger.warn({ wireJid, error: deleteError }, 'Failed to delete PN session')
|
|
636
|
-
}
|
|
637
|
-
return lidWithDevice
|
|
638
|
-
}
|
|
639
|
-
catch (migrationError) {
|
|
640
|
-
logger.warn({ wireJid, error: migrationError }, 'Failed to migrate session')
|
|
641
|
-
return wireJid
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
catch (error) {
|
|
645
|
-
logger.debug({ wireJid, error }, 'Failed to check LID mapping')
|
|
646
|
-
return wireJid
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
// Encrypt to this user's devices sequentially to prevent session corruption
|
|
651
|
-
for (const { recipientJid: wireJid, patchedMessage } of userDevices) {
|
|
652
|
-
// DSM logic: Use DSM for own other devices (following whatsmeow implementation)
|
|
653
|
-
let messageToEncrypt = patchedMessage
|
|
654
|
-
|
|
655
|
-
if (dsmMessage) {
|
|
656
|
-
const { user: targetUser } = WABinary_1.jidDecode(wireJid)
|
|
657
|
-
const { user: ownPnUser } = WABinary_1.jidDecode(meId)
|
|
658
|
-
const ownLidUser = meLidUser
|
|
659
|
-
|
|
660
|
-
// Check if this is our device (same user, different device)
|
|
661
|
-
const isOwnUser = targetUser === ownPnUser || (ownLidUser && targetUser === ownLidUser)
|
|
662
|
-
|
|
663
|
-
// Exclude exact sender device (whatsmeow: if jid == ownJID || jid == ownLID { continue })
|
|
664
|
-
const isExactSenderDevice = wireJid === meId || (authState.creds.me?.lid && wireJid === authState.creds.me.lid)
|
|
665
|
-
|
|
666
|
-
if (isOwnUser && !isExactSenderDevice) {
|
|
667
|
-
messageToEncrypt = dsmMessage
|
|
668
|
-
logger.debug({ wireJid, targetUser }, 'Using DSM for own device')
|
|
669
|
-
}
|
|
323
|
+
additionalNodes: [
|
|
324
|
+
{
|
|
325
|
+
tag: 'meta',
|
|
326
|
+
attrs: { appdata: 'default' }
|
|
670
327
|
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
328
|
+
]
|
|
329
|
+
});
|
|
330
|
+
return msgId;
|
|
331
|
+
};
|
|
332
|
+
const createParticipantNodes = async (recipientJids, message, extraAttrs, dsmMessage) => {
|
|
333
|
+
if (!recipientJids.length) {
|
|
334
|
+
return { nodes: [], shouldIncludeDeviceIdentity: false };
|
|
335
|
+
}
|
|
336
|
+
const patched = await patchMessageBeforeSending(message, recipientJids);
|
|
337
|
+
const patchedMessages = Array.isArray(patched)
|
|
338
|
+
? patched
|
|
339
|
+
: recipientJids.map(jid => ({ recipientJid: jid, message: patched }));
|
|
340
|
+
let shouldIncludeDeviceIdentity = false;
|
|
341
|
+
const meId = authState.creds.me.id;
|
|
342
|
+
const meLid = authState.creds.me?.lid;
|
|
343
|
+
const meLidUser = meLid ? jidDecode(meLid)?.user : null;
|
|
344
|
+
const encryptionPromises = patchedMessages.map(async ({ recipientJid: jid, message: patchedMessage }) => {
|
|
345
|
+
if (!jid)
|
|
346
|
+
return null;
|
|
347
|
+
let msgToEncrypt = patchedMessage;
|
|
348
|
+
if (dsmMessage) {
|
|
349
|
+
const { user: targetUser } = jidDecode(jid);
|
|
350
|
+
const { user: ownPnUser } = jidDecode(meId);
|
|
351
|
+
const ownLidUser = meLidUser;
|
|
352
|
+
const isOwnUser = targetUser === ownPnUser || (ownLidUser && targetUser === ownLidUser);
|
|
353
|
+
const isExactSenderDevice = jid === meId || (meLid && jid === meLid);
|
|
354
|
+
if (isOwnUser && !isExactSenderDevice) {
|
|
355
|
+
msgToEncrypt = dsmMessage;
|
|
356
|
+
logger.debug({ jid, targetUser }, 'Using DSM for own device');
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
const bytes = encodeWAMessage(msgToEncrypt);
|
|
360
|
+
const mutexKey = jid;
|
|
361
|
+
const node = await encryptionMutex.mutex(mutexKey, async () => {
|
|
678
362
|
const { type, ciphertext } = await signalRepository.encryptMessage({
|
|
679
|
-
jid
|
|
363
|
+
jid,
|
|
680
364
|
data: bytes
|
|
681
|
-
})
|
|
682
|
-
|
|
365
|
+
});
|
|
683
366
|
if (type === 'pkmsg') {
|
|
684
|
-
shouldIncludeDeviceIdentity = true
|
|
367
|
+
shouldIncludeDeviceIdentity = true;
|
|
685
368
|
}
|
|
686
|
-
|
|
687
|
-
const node = {
|
|
369
|
+
return {
|
|
688
370
|
tag: 'to',
|
|
689
|
-
attrs: { jid
|
|
371
|
+
attrs: { jid },
|
|
690
372
|
content: [
|
|
691
373
|
{
|
|
692
374
|
tag: 'enc',
|
|
@@ -698,711 +380,405 @@ const makeMessagesSocket = (config) => {
|
|
|
698
380
|
content: ciphertext
|
|
699
381
|
}
|
|
700
382
|
]
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
const
|
|
710
|
-
const
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
const
|
|
716
|
-
const
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
const
|
|
724
|
-
const
|
|
725
|
-
const
|
|
726
|
-
const
|
|
727
|
-
const isStatus = jid === statusJid
|
|
728
|
-
const isLid = server === 'lid'
|
|
729
|
-
|
|
730
|
-
// Keep user's original JID choice for envelope addressing
|
|
731
|
-
const finalJid = jid
|
|
732
|
-
|
|
733
|
-
// ADDRESSING CONSISTENCY: Match own identity to conversation context
|
|
734
|
-
let ownId = meId
|
|
735
|
-
|
|
736
|
-
if (isLid && meLid) {
|
|
737
|
-
ownId = meLid
|
|
738
|
-
logger.debug({ to: jid, ownId }, 'Using LID identity for @lid conversation')
|
|
739
|
-
}
|
|
740
|
-
else {
|
|
741
|
-
logger.debug({ to: jid, ownId }, 'Using PN identity for @s.whatsapp.net conversation')
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
msgId = msgId || Utils_1.generateMessageID(authState.creds.me.id)
|
|
745
|
-
useUserDevicesCache = useUserDevicesCache !== false
|
|
746
|
-
useCachedGroupMetadata = useCachedGroupMetadata !== false && !isStatus
|
|
747
|
-
|
|
748
|
-
const participants = []
|
|
749
|
-
const destinationJid = !isStatus ? finalJid : statusJid
|
|
750
|
-
const binaryNodeContent = []
|
|
751
|
-
const devices = []
|
|
752
|
-
|
|
383
|
+
};
|
|
384
|
+
});
|
|
385
|
+
return node;
|
|
386
|
+
});
|
|
387
|
+
const nodes = (await Promise.all(encryptionPromises)).filter(node => node !== null);
|
|
388
|
+
return { nodes, shouldIncludeDeviceIdentity };
|
|
389
|
+
};
|
|
390
|
+
const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList }) => {
|
|
391
|
+
const meId = authState.creds.me.id;
|
|
392
|
+
const meLid = authState.creds.me?.lid;
|
|
393
|
+
const isRetryResend = Boolean(participant?.jid);
|
|
394
|
+
let shouldIncludeDeviceIdentity = isRetryResend;
|
|
395
|
+
const statusJid = 'status@broadcast';
|
|
396
|
+
const { user, server } = jidDecode(jid);
|
|
397
|
+
const isGroup = server === 'g.us';
|
|
398
|
+
const isStatus = jid === statusJid;
|
|
399
|
+
const isLid = server === 'lid';
|
|
400
|
+
const isNewsletter = server === 'newsletter';
|
|
401
|
+
const finalJid = jid;
|
|
402
|
+
msgId = msgId || generateMessageIDV2(meId);
|
|
403
|
+
useUserDevicesCache = useUserDevicesCache !== false;
|
|
404
|
+
useCachedGroupMetadata = useCachedGroupMetadata !== false && !isStatus;
|
|
405
|
+
const participants = [];
|
|
406
|
+
const destinationJid = !isStatus ? finalJid : statusJid;
|
|
407
|
+
const binaryNodeContent = [];
|
|
408
|
+
const devices = [];
|
|
753
409
|
const meMsg = {
|
|
754
410
|
deviceSentMessage: {
|
|
755
411
|
destinationJid,
|
|
756
412
|
message
|
|
757
|
-
},
|
|
758
|
-
messageContextInfo: message.messageContextInfo
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
const extraAttrs = {}
|
|
762
|
-
|
|
763
|
-
const regexGroupOld = /^(\d{1,15})-(\d+)@g\.us$/
|
|
764
|
-
|
|
765
|
-
const messages = Utils_1.normalizeMessageContent(message)
|
|
766
|
-
|
|
767
|
-
const buttonType = getButtonType(messages)
|
|
768
|
-
const pollMessage = messages.pollCreationMessage || messages.pollCreationMessageV2 || messages.pollCreationMessageV3
|
|
769
|
-
|
|
770
|
-
|
|
413
|
+
},
|
|
414
|
+
messageContextInfo: message.messageContextInfo
|
|
415
|
+
};
|
|
416
|
+
const extraAttrs = {};
|
|
771
417
|
if (participant) {
|
|
772
|
-
// when the retry request is not for a group
|
|
773
|
-
// only send to the specific device that asked for a retry
|
|
774
|
-
// otherwise the message is sent out to every device that should be a recipient
|
|
775
418
|
if (!isGroup && !isStatus) {
|
|
776
|
-
additionalAttributes = { ...additionalAttributes,
|
|
419
|
+
additionalAttributes = { ...additionalAttributes, device_fanout: 'false' };
|
|
777
420
|
}
|
|
778
|
-
|
|
779
|
-
const { user, device } = WABinary_1.jidDecode(participant.jid)
|
|
780
|
-
|
|
421
|
+
const { user, device } = jidDecode(participant.jid);
|
|
781
422
|
devices.push({
|
|
782
423
|
user,
|
|
783
424
|
device,
|
|
784
|
-
|
|
785
|
-
})
|
|
425
|
+
jid: participant.jid
|
|
426
|
+
});
|
|
786
427
|
}
|
|
787
|
-
|
|
788
428
|
await authState.keys.transaction(async () => {
|
|
789
|
-
const mediaType = getMediaType(message)
|
|
790
|
-
|
|
429
|
+
const mediaType = getMediaType(message);
|
|
791
430
|
if (mediaType) {
|
|
792
|
-
extraAttrs['mediatype'] = mediaType
|
|
431
|
+
extraAttrs['mediatype'] = mediaType;
|
|
432
|
+
}
|
|
433
|
+
if (isNewsletter) {
|
|
434
|
+
const patched = patchMessageBeforeSending ? await patchMessageBeforeSending(message, []) : message;
|
|
435
|
+
const bytes = encodeNewsletterMessage(patched);
|
|
436
|
+
binaryNodeContent.push({
|
|
437
|
+
tag: 'plaintext',
|
|
438
|
+
attrs: {},
|
|
439
|
+
content: bytes
|
|
440
|
+
});
|
|
441
|
+
const stanza = {
|
|
442
|
+
tag: 'message',
|
|
443
|
+
attrs: {
|
|
444
|
+
to: jid,
|
|
445
|
+
id: msgId,
|
|
446
|
+
type: getMessageType(message),
|
|
447
|
+
...(additionalAttributes || {})
|
|
448
|
+
},
|
|
449
|
+
content: binaryNodeContent
|
|
450
|
+
};
|
|
451
|
+
logger.debug({ msgId }, `sending newsletter message to ${jid}`);
|
|
452
|
+
await sendNode(stanza);
|
|
453
|
+
return;
|
|
793
454
|
}
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
extraAttrs['decrypt-fail'] = 'hide'
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
if (messages.interactiveResponseMessage?.nativeFlowResponseMessage) {
|
|
800
|
-
extraAttrs['native_flow_name'] = messages.interactiveResponseMessage.nativeFlowResponseMessage?.name || 'menu_options'
|
|
455
|
+
if (normalizeMessageContent(message)?.pinInChatMessage) {
|
|
456
|
+
extraAttrs['decrypt-fail'] = 'hide'; // todo: expand for reactions and other types
|
|
801
457
|
}
|
|
802
|
-
|
|
803
458
|
if (isGroup || isStatus) {
|
|
804
459
|
const [groupData, senderKeyMap] = await Promise.all([
|
|
805
460
|
(async () => {
|
|
806
|
-
let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined
|
|
807
|
-
|
|
461
|
+
let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined; // todo: should we rely on the cache specially if the cache is outdated and the metadata has new fields?
|
|
808
462
|
if (groupData && Array.isArray(groupData?.participants)) {
|
|
809
|
-
logger.trace({ jid, participants: groupData.participants.length }, 'using cached group metadata')
|
|
463
|
+
logger.trace({ jid, participants: groupData.participants.length }, 'using cached group metadata');
|
|
810
464
|
}
|
|
811
|
-
|
|
812
465
|
else if (!isStatus) {
|
|
813
|
-
groupData = await groupMetadata(jid)
|
|
466
|
+
groupData = await groupMetadata(jid); // TODO: start storing group participant list + addr mode in Signal & stop relying on this
|
|
814
467
|
}
|
|
815
|
-
|
|
816
|
-
return groupData
|
|
468
|
+
return groupData;
|
|
817
469
|
})(),
|
|
818
|
-
|
|
819
470
|
(async () => {
|
|
820
471
|
if (!participant && !isStatus) {
|
|
821
|
-
|
|
822
|
-
|
|
472
|
+
// what if sender memory is less accurate than the cached metadata
|
|
473
|
+
// on participant change in group, we should do sender memory manipulation
|
|
474
|
+
const result = await authState.keys.get('sender-key-memory', [jid]); // TODO: check out what if the sender key memory doesn't include the LID stuff now?
|
|
475
|
+
return result[jid] || {};
|
|
823
476
|
}
|
|
824
|
-
|
|
825
|
-
return {}
|
|
826
|
-
|
|
477
|
+
return {};
|
|
827
478
|
})()
|
|
828
|
-
])
|
|
829
|
-
|
|
479
|
+
]);
|
|
830
480
|
if (!participant) {
|
|
831
|
-
const participantsList =
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
481
|
+
const participantsList = [];
|
|
482
|
+
if (isStatus) {
|
|
483
|
+
if (statusJidList?.length)
|
|
484
|
+
participantsList.push(...statusJidList);
|
|
835
485
|
}
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
486
|
+
else {
|
|
487
|
+
// default to LID based groups
|
|
488
|
+
let groupAddressingMode = 'lid';
|
|
489
|
+
if (groupData) {
|
|
490
|
+
participantsList.push(...groupData.participants.map(p => p.id));
|
|
491
|
+
groupAddressingMode = groupData?.addressingMode || groupAddressingMode;
|
|
492
|
+
}
|
|
493
|
+
// default to lid addressing mode in a group
|
|
839
494
|
additionalAttributes = {
|
|
840
495
|
...additionalAttributes,
|
|
841
496
|
addressing_mode: groupAddressingMode
|
|
842
|
-
}
|
|
497
|
+
};
|
|
843
498
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
const
|
|
854
|
-
|
|
855
|
-
|
|
499
|
+
const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false);
|
|
500
|
+
devices.push(...additionalDevices);
|
|
501
|
+
}
|
|
502
|
+
if (groupData?.ephemeralDuration && groupData.ephemeralDuration > 0) {
|
|
503
|
+
additionalAttributes = {
|
|
504
|
+
...additionalAttributes,
|
|
505
|
+
expiration: groupData.ephemeralDuration.toString()
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
const patched = await patchMessageBeforeSending(message);
|
|
509
|
+
if (Array.isArray(patched)) {
|
|
510
|
+
throw new Boom('Per-jid patching is not supported in groups');
|
|
511
|
+
}
|
|
512
|
+
const bytes = encodeWAMessage(patched);
|
|
513
|
+
const groupAddressingMode = additionalAttributes?.['addressing_mode'] || groupData?.addressingMode || 'lid';
|
|
514
|
+
const groupSenderIdentity = groupAddressingMode === 'lid' && meLid ? meLid : meId;
|
|
856
515
|
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({
|
|
857
516
|
group: destinationJid,
|
|
858
517
|
data: bytes,
|
|
859
518
|
meId: groupSenderIdentity
|
|
860
|
-
})
|
|
861
|
-
|
|
862
|
-
const senderKeyJids = []
|
|
863
|
-
|
|
864
|
-
// ensure a connection is established with every device
|
|
519
|
+
});
|
|
520
|
+
const senderKeyRecipients = [];
|
|
865
521
|
for (const device of devices) {
|
|
866
|
-
|
|
867
|
-
const
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
522
|
+
const deviceJid = device.jid;
|
|
523
|
+
const hasKey = !!senderKeyMap[deviceJid];
|
|
524
|
+
if ((!hasKey || !!participant) &&
|
|
525
|
+
!isHostedLidUser(deviceJid) &&
|
|
526
|
+
!isHostedPnUser(deviceJid) &&
|
|
527
|
+
device.device !== 99) {
|
|
528
|
+
//todo: revamp all this logic
|
|
529
|
+
// the goal is to follow with what I said above for each group, and instead of a true false map of ids, we can set an array full of those the app has already sent pkmsgs
|
|
530
|
+
senderKeyRecipients.push(deviceJid);
|
|
531
|
+
senderKeyMap[deviceJid] = true;
|
|
873
532
|
}
|
|
874
533
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
// if there are, we re-send the senderkey
|
|
878
|
-
if (senderKeyJids.length) {
|
|
879
|
-
logger.debug({ senderKeyJids }, 'sending new sender key')
|
|
534
|
+
if (senderKeyRecipients.length) {
|
|
535
|
+
logger.debug({ senderKeyJids: senderKeyRecipients }, 'sending new sender key');
|
|
880
536
|
const senderKeyMsg = {
|
|
881
537
|
senderKeyDistributionMessage: {
|
|
882
538
|
axolotlSenderKeyDistributionMessage: senderKeyDistributionMessage,
|
|
883
539
|
groupId: destinationJid
|
|
884
540
|
}
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
await assertSessions(
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
// Message edit
|
|
907
|
-
if (message.protocolMessage?.editedMessage) {
|
|
908
|
-
msgId = message.protocolMessage.key?.id
|
|
909
|
-
message = message.protocolMessage.editedMessage
|
|
541
|
+
};
|
|
542
|
+
const senderKeySessionTargets = senderKeyRecipients;
|
|
543
|
+
await assertSessions(senderKeySessionTargets);
|
|
544
|
+
const result = await createParticipantNodes(senderKeyRecipients, senderKeyMsg, extraAttrs);
|
|
545
|
+
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity;
|
|
546
|
+
participants.push(...result.nodes);
|
|
547
|
+
}
|
|
548
|
+
if (isRetryResend) {
|
|
549
|
+
const { type, ciphertext: encryptedContent } = await signalRepository.encryptMessage({
|
|
550
|
+
data: bytes,
|
|
551
|
+
jid: participant?.jid
|
|
552
|
+
});
|
|
553
|
+
binaryNodeContent.push({
|
|
554
|
+
tag: 'enc',
|
|
555
|
+
attrs: {
|
|
556
|
+
v: '2',
|
|
557
|
+
type,
|
|
558
|
+
count: participant.count.toString()
|
|
559
|
+
},
|
|
560
|
+
content: encryptedContent
|
|
561
|
+
});
|
|
910
562
|
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
563
|
+
else {
|
|
564
|
+
binaryNodeContent.push({
|
|
565
|
+
tag: 'enc',
|
|
566
|
+
attrs: { v: '2', type: 'skmsg', ...extraAttrs },
|
|
567
|
+
content: ciphertext
|
|
568
|
+
});
|
|
569
|
+
await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } });
|
|
916
570
|
}
|
|
917
|
-
|
|
918
|
-
const patched = await patchMessageBeforeSending(message, [])
|
|
919
|
-
const bytes = Utils_1.encodeNewsletterMessage(patched)
|
|
920
|
-
|
|
921
|
-
binaryNodeContent.push({
|
|
922
|
-
tag: 'plaintext',
|
|
923
|
-
attrs: extraAttrs,
|
|
924
|
-
content: bytes
|
|
925
|
-
})
|
|
926
571
|
}
|
|
927
|
-
|
|
928
572
|
else {
|
|
929
|
-
|
|
930
|
-
|
|
573
|
+
// ADDRESSING CONSISTENCY: Match own identity to conversation context
|
|
574
|
+
// TODO: investigate if this is true
|
|
575
|
+
let ownId = meId;
|
|
576
|
+
if (isLid && meLid) {
|
|
577
|
+
ownId = meLid;
|
|
578
|
+
logger.debug({ to: jid, ownId }, 'Using LID identity for @lid conversation');
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
logger.debug({ to: jid, ownId }, 'Using PN identity for @s.whatsapp.net conversation');
|
|
582
|
+
}
|
|
583
|
+
const { user: ownUser } = jidDecode(ownId);
|
|
931
584
|
if (!participant) {
|
|
932
|
-
const targetUserServer = isLid ? 'lid' : 's.whatsapp.net'
|
|
585
|
+
const targetUserServer = isLid ? 'lid' : 's.whatsapp.net';
|
|
933
586
|
devices.push({
|
|
934
587
|
user,
|
|
935
588
|
device: 0,
|
|
936
|
-
|
|
937
|
-
})
|
|
938
|
-
|
|
939
|
-
// Own user matches conversation addressing mode
|
|
589
|
+
jid: jidEncode(user, targetUserServer, 0) // rajeh, todo: this entire logic is convoluted and weird.
|
|
590
|
+
});
|
|
940
591
|
if (user !== ownUser) {
|
|
941
592
|
const ownUserServer = isLid ? 'lid' : 's.whatsapp.net';
|
|
942
|
-
const ownUserForAddressing = isLid && meLid ?
|
|
593
|
+
const ownUserForAddressing = isLid && meLid ? jidDecode(meLid).user : jidDecode(meId).user;
|
|
943
594
|
devices.push({
|
|
944
595
|
user: ownUserForAddressing,
|
|
945
596
|
device: 0,
|
|
946
|
-
|
|
947
|
-
})
|
|
597
|
+
jid: jidEncode(ownUserForAddressing, ownUserServer, 0)
|
|
598
|
+
});
|
|
948
599
|
}
|
|
949
|
-
|
|
950
600
|
if (additionalAttributes?.['category'] !== 'peer') {
|
|
951
601
|
// Clear placeholders and enumerate actual devices
|
|
952
|
-
devices.length = 0
|
|
953
|
-
|
|
602
|
+
devices.length = 0;
|
|
954
603
|
// Use conversation-appropriate sender identity
|
|
955
604
|
const senderIdentity = isLid && meLid
|
|
956
|
-
?
|
|
957
|
-
:
|
|
958
|
-
|
|
605
|
+
? jidEncode(jidDecode(meLid)?.user, 'lid', undefined)
|
|
606
|
+
: jidEncode(jidDecode(meId)?.user, 's.whatsapp.net', undefined);
|
|
959
607
|
// Enumerate devices for sender and target with consistent addressing
|
|
960
|
-
const sessionDevices = await getUSyncDevices([senderIdentity, jid],
|
|
961
|
-
devices.push(...sessionDevices)
|
|
608
|
+
const sessionDevices = await getUSyncDevices([senderIdentity, jid], true, false);
|
|
609
|
+
devices.push(...sessionDevices);
|
|
962
610
|
logger.debug({
|
|
963
611
|
deviceCount: devices.length,
|
|
964
|
-
devices: devices.map(d => `${d.user}:${d.device}@${
|
|
965
|
-
}, 'Device enumeration complete with unified addressing')
|
|
612
|
+
devices: devices.map(d => `${d.user}:${d.device}@${jidDecode(d.jid)?.server}`)
|
|
613
|
+
}, 'Device enumeration complete with unified addressing');
|
|
966
614
|
}
|
|
967
615
|
}
|
|
968
|
-
|
|
969
|
-
const
|
|
970
|
-
const
|
|
971
|
-
const
|
|
972
|
-
|
|
973
|
-
const { user
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
for (const { user, wireJid, device } of devices) {
|
|
977
|
-
const isExactSenderDevice = wireJid === meId || (meLid && wireJid === meLid)
|
|
616
|
+
const allRecipients = [];
|
|
617
|
+
const meRecipients = [];
|
|
618
|
+
const otherRecipients = [];
|
|
619
|
+
const { user: mePnUser } = jidDecode(meId);
|
|
620
|
+
const { user: meLidUser } = meLid ? jidDecode(meLid) : { user: null };
|
|
621
|
+
for (const { user, jid } of devices) {
|
|
622
|
+
const isExactSenderDevice = jid === meId || (meLid && jid === meLid);
|
|
978
623
|
if (isExactSenderDevice) {
|
|
979
|
-
logger.debug({
|
|
980
|
-
continue
|
|
624
|
+
logger.debug({ jid, meId, meLid }, 'Skipping exact sender device (whatsmeow pattern)');
|
|
625
|
+
continue;
|
|
981
626
|
}
|
|
982
|
-
|
|
983
627
|
// Check if this is our device (could match either PN or LID user)
|
|
984
|
-
const isMe = user === mePnUser ||
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
// allJids.push(jid)
|
|
996
|
-
// }
|
|
997
|
-
|
|
998
|
-
let tatar = false;
|
|
999
|
-
|
|
1000
|
-
if (!isMe) {
|
|
1001
|
-
if (isSecret === 1 && device !== undefined) {
|
|
1002
|
-
tatar = true;
|
|
1003
|
-
} else if (isSecret === 2 && device === undefined) {
|
|
1004
|
-
tatar = true;
|
|
1005
|
-
} else if (isSecret === 5 && device === undefined) {
|
|
1006
|
-
tatar = true
|
|
1007
|
-
} else if (isSecret === 6 && device !== undefined) {
|
|
1008
|
-
tatar = true
|
|
1009
|
-
}
|
|
1010
|
-
} else {
|
|
1011
|
-
if (isSecret === 3 && device !== undefined) {
|
|
1012
|
-
tatar = true;
|
|
1013
|
-
} else if (isSecret === 4 && device === undefined) {
|
|
1014
|
-
tatar = true;
|
|
1015
|
-
} else if (isSecret === 5) {
|
|
1016
|
-
tatar = true
|
|
1017
|
-
} else if (isSecret === 6) {
|
|
1018
|
-
tatar = true
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
if (!tatar) {
|
|
1023
|
-
// const jid = (0, WABinary_1.jidEncode)(
|
|
1024
|
-
// isMe && isLid
|
|
1025
|
-
// ? (authState.creds?.me?.lid.split(':')[0]) || user
|
|
1026
|
-
// : user,
|
|
1027
|
-
// isLid ? 'lid' : 's.whatsapp.net',
|
|
1028
|
-
// device
|
|
1029
|
-
// );
|
|
1030
|
-
|
|
1031
|
-
if (isMe) {
|
|
1032
|
-
meJids.push(jid);
|
|
1033
|
-
} else {
|
|
1034
|
-
otherJids.push(jid);
|
|
1035
|
-
}
|
|
1036
|
-
allJids.push(jid);
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
// await assertSessions([...otherJids, ...meJids], false)
|
|
1040
|
-
await assertSessions(allJids, false)
|
|
628
|
+
const isMe = user === mePnUser || user === meLidUser;
|
|
629
|
+
if (isMe) {
|
|
630
|
+
meRecipients.push(jid);
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
otherRecipients.push(jid);
|
|
634
|
+
}
|
|
635
|
+
allRecipients.push(jid);
|
|
636
|
+
}
|
|
637
|
+
await assertSessions(allRecipients);
|
|
1041
638
|
const [{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 }, { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }] = await Promise.all([
|
|
1042
639
|
// For own devices: use DSM if available (1:1 chats only)
|
|
1043
|
-
createParticipantNodes(
|
|
1044
|
-
createParticipantNodes(
|
|
1045
|
-
])
|
|
1046
|
-
|
|
1047
|
-
participants.push(...
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
if (meJids.length > 0 || otherJids.length > 0) {
|
|
1052
|
-
extraAttrs['phash'] = Utils_1.generateParticipantHashV2([...meJids, ...otherJids])
|
|
640
|
+
createParticipantNodes(meRecipients, meMsg || message, extraAttrs),
|
|
641
|
+
createParticipantNodes(otherRecipients, message, extraAttrs, meMsg)
|
|
642
|
+
]);
|
|
643
|
+
participants.push(...meNodes);
|
|
644
|
+
participants.push(...otherNodes);
|
|
645
|
+
if (meRecipients.length > 0 || otherRecipients.length > 0) {
|
|
646
|
+
extraAttrs['phash'] = generateParticipantHashV2([...meRecipients, ...otherRecipients]);
|
|
1053
647
|
}
|
|
1054
|
-
|
|
1055
|
-
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2
|
|
648
|
+
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2;
|
|
1056
649
|
}
|
|
1057
|
-
|
|
1058
650
|
if (participants.length) {
|
|
1059
651
|
if (additionalAttributes?.['category'] === 'peer') {
|
|
1060
|
-
const peerNode = participants[0]?.content?.[0]
|
|
1061
|
-
|
|
652
|
+
const peerNode = participants[0]?.content?.[0];
|
|
1062
653
|
if (peerNode) {
|
|
1063
|
-
binaryNodeContent.push(peerNode) // push only enc
|
|
654
|
+
binaryNodeContent.push(peerNode); // push only enc
|
|
1064
655
|
}
|
|
1065
656
|
}
|
|
1066
|
-
|
|
1067
657
|
else {
|
|
1068
658
|
binaryNodeContent.push({
|
|
1069
659
|
tag: 'participants',
|
|
1070
660
|
attrs: {},
|
|
1071
661
|
content: participants
|
|
1072
|
-
})
|
|
662
|
+
});
|
|
1073
663
|
}
|
|
1074
664
|
}
|
|
1075
|
-
|
|
1076
665
|
const stanza = {
|
|
1077
666
|
tag: 'message',
|
|
1078
667
|
attrs: {
|
|
668
|
+
id: msgId,
|
|
1079
669
|
to: destinationJid,
|
|
1080
|
-
|
|
1081
|
-
type: getTypeMessage(message),
|
|
670
|
+
type: getMessageType(message),
|
|
1082
671
|
...(additionalAttributes || {})
|
|
1083
672
|
},
|
|
1084
673
|
content: binaryNodeContent
|
|
1085
|
-
}
|
|
1086
|
-
|
|
674
|
+
};
|
|
1087
675
|
// if the participant to send to is explicitly specified (generally retry recp)
|
|
1088
676
|
// ensure the message is only sent to that person
|
|
1089
677
|
// if a retry receipt is sent to everyone -- it'll fail decryption for everyone else who received the msg
|
|
1090
678
|
if (participant) {
|
|
1091
|
-
if (
|
|
1092
|
-
stanza.attrs.to = destinationJid
|
|
1093
|
-
stanza.attrs.participant = participant.jid
|
|
679
|
+
if (isJidGroup(destinationJid)) {
|
|
680
|
+
stanza.attrs.to = destinationJid;
|
|
681
|
+
stanza.attrs.participant = participant.jid;
|
|
1094
682
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
stanza.attrs.
|
|
1098
|
-
stanza.attrs.recipient = destinationJid
|
|
683
|
+
else if (areJidsSameUser(participant.jid, meId)) {
|
|
684
|
+
stanza.attrs.to = participant.jid;
|
|
685
|
+
stanza.attrs.recipient = destinationJid;
|
|
1099
686
|
}
|
|
1100
|
-
|
|
1101
687
|
else {
|
|
1102
|
-
stanza.attrs.to = participant.jid
|
|
688
|
+
stanza.attrs.to = participant.jid;
|
|
1103
689
|
}
|
|
1104
690
|
}
|
|
1105
|
-
|
|
1106
691
|
else {
|
|
1107
|
-
stanza.attrs.to = destinationJid
|
|
692
|
+
stanza.attrs.to = destinationJid;
|
|
1108
693
|
}
|
|
1109
|
-
|
|
1110
694
|
if (shouldIncludeDeviceIdentity) {
|
|
695
|
+
;
|
|
1111
696
|
stanza.content.push({
|
|
1112
697
|
tag: 'device-identity',
|
|
1113
698
|
attrs: {},
|
|
1114
|
-
content:
|
|
1115
|
-
})
|
|
1116
|
-
|
|
1117
|
-
logger.debug({ jid }, 'adding device identity')
|
|
1118
|
-
}
|
|
1119
|
-
|
|
1120
|
-
if (isGroup && regexGroupOld.test(jid) && !message.reactionMessage) {
|
|
1121
|
-
stanza.content.push({
|
|
1122
|
-
tag: 'multicast',
|
|
1123
|
-
attrs: {}
|
|
1124
|
-
})
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
if (pollMessage || messages.eventMessage) {
|
|
1128
|
-
stanza.content.push({
|
|
1129
|
-
tag: 'meta',
|
|
1130
|
-
attrs: messages.eventMessage ? {
|
|
1131
|
-
event_type: 'creation'
|
|
1132
|
-
} : isNewsletter ? {
|
|
1133
|
-
polltype: 'creation',
|
|
1134
|
-
contenttype: pollMessage?.pollContentType === 2 ? 'image' : 'text'
|
|
1135
|
-
} : {
|
|
1136
|
-
polltype: 'creation'
|
|
1137
|
-
}
|
|
1138
|
-
})
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
if (!isNewsletter && buttonType) {
|
|
1142
|
-
const buttonsNode = getButtonArgs(messages)
|
|
1143
|
-
const filteredButtons = WABinary_1.getBinaryFilteredButtons(additionalNodes ? additionalNodes : [])
|
|
1144
|
-
|
|
1145
|
-
if (filteredButtons) {
|
|
1146
|
-
stanza.content.push(...additionalNodes)
|
|
1147
|
-
didPushAdditional = true
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
else {
|
|
1151
|
-
stanza.content.push(buttonsNode)
|
|
1152
|
-
}
|
|
699
|
+
content: encodeSignedDeviceIdentity(authState.creds.account, true)
|
|
700
|
+
});
|
|
701
|
+
logger.debug({ jid }, 'adding device identity');
|
|
1153
702
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
tag: 'bot',
|
|
1158
|
-
attrs: {
|
|
1159
|
-
biz_bot: '1'
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
const filteredBizBot = WABinary_1.getBinaryFilteredBizBot(additionalNodes ? additionalNodes : [])
|
|
1164
|
-
|
|
1165
|
-
if (filteredBizBot) {
|
|
1166
|
-
stanza.content.push(...additionalNodes)
|
|
1167
|
-
didPushAdditional = true
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
else {
|
|
1171
|
-
stanza.content.push(botNode)
|
|
1172
|
-
}
|
|
703
|
+
if (additionalNodes && additionalNodes.length > 0) {
|
|
704
|
+
;
|
|
705
|
+
stanza.content.push(...additionalNodes);
|
|
1173
706
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
stanza.content.push(...additionalNodes)
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
logger.debug({ msgId }, `sending message to ${participants.length} devices`)
|
|
1180
|
-
|
|
1181
|
-
await sendNode(stanza)
|
|
1182
|
-
|
|
707
|
+
logger.debug({ msgId }, `sending message to ${participants.length} devices`);
|
|
708
|
+
await sendNode(stanza);
|
|
1183
709
|
// Add message to retry cache if enabled
|
|
1184
710
|
if (messageRetryManager && !participant) {
|
|
1185
|
-
messageRetryManager.addRecentMessage(destinationJid, msgId, message)
|
|
711
|
+
messageRetryManager.addRecentMessage(destinationJid, msgId, message);
|
|
1186
712
|
}
|
|
1187
|
-
}, meId)
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
const getTypeMessage = (msg) => {
|
|
1193
|
-
const message = Utils_1.normalizeMessageContent(msg)
|
|
713
|
+
}, meId);
|
|
714
|
+
return msgId;
|
|
715
|
+
};
|
|
716
|
+
const getMessageType = (message) => {
|
|
1194
717
|
if (message.pollCreationMessage || message.pollCreationMessageV2 || message.pollCreationMessageV3) {
|
|
1195
|
-
return 'poll'
|
|
1196
|
-
}
|
|
1197
|
-
else if (message.reactionMessage) {
|
|
1198
|
-
return 'reaction'
|
|
1199
|
-
}
|
|
1200
|
-
else if (message.eventMessage) {
|
|
1201
|
-
return 'event'
|
|
1202
|
-
}
|
|
1203
|
-
else if (getMediaType(message)) {
|
|
1204
|
-
return 'media'
|
|
1205
|
-
}
|
|
1206
|
-
else {
|
|
1207
|
-
return 'text'
|
|
718
|
+
return 'poll';
|
|
1208
719
|
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
const getMediaType = (message) => {
|
|
1212
|
-
if (message.imageMessage) {
|
|
1213
|
-
return 'image'
|
|
720
|
+
if (message.eventMessage) {
|
|
721
|
+
return 'event';
|
|
1214
722
|
}
|
|
1215
|
-
|
|
1216
|
-
return
|
|
723
|
+
if (getMediaType(message) !== '') {
|
|
724
|
+
return 'media';
|
|
725
|
+
}
|
|
726
|
+
return 'text';
|
|
727
|
+
};
|
|
728
|
+
const getMediaType = (message) => {
|
|
729
|
+
if (message.imageMessage) {
|
|
730
|
+
return 'image';
|
|
1217
731
|
}
|
|
1218
732
|
else if (message.videoMessage) {
|
|
1219
|
-
return message.videoMessage.gifPlayback ? 'gif' : 'video'
|
|
733
|
+
return message.videoMessage.gifPlayback ? 'gif' : 'video';
|
|
1220
734
|
}
|
|
1221
735
|
else if (message.audioMessage) {
|
|
1222
|
-
return message.audioMessage.ptt ? 'ptt' : 'audio'
|
|
1223
|
-
}
|
|
1224
|
-
else if (message.ptvMessage) {
|
|
1225
|
-
return 'ptv'
|
|
1226
|
-
}
|
|
1227
|
-
else if (message.albumMessage) {
|
|
1228
|
-
return 'collection'
|
|
736
|
+
return message.audioMessage.ptt ? 'ptt' : 'audio';
|
|
1229
737
|
}
|
|
1230
738
|
else if (message.contactMessage) {
|
|
1231
|
-
return 'vcard'
|
|
739
|
+
return 'vcard';
|
|
1232
740
|
}
|
|
1233
741
|
else if (message.documentMessage) {
|
|
1234
|
-
return 'document'
|
|
1235
|
-
}
|
|
1236
|
-
else if (message.stickerPackMessage) {
|
|
1237
|
-
return 'sticker_pack'
|
|
742
|
+
return 'document';
|
|
1238
743
|
}
|
|
1239
744
|
else if (message.contactsArrayMessage) {
|
|
1240
|
-
return 'contact_array'
|
|
1241
|
-
}
|
|
1242
|
-
else if (message.locationMessage) {
|
|
1243
|
-
return 'location'
|
|
745
|
+
return 'contact_array';
|
|
1244
746
|
}
|
|
1245
747
|
else if (message.liveLocationMessage) {
|
|
1246
|
-
return 'livelocation'
|
|
748
|
+
return 'livelocation';
|
|
749
|
+
}
|
|
750
|
+
else if (message.stickerMessage) {
|
|
751
|
+
return 'sticker';
|
|
1247
752
|
}
|
|
1248
753
|
else if (message.listMessage) {
|
|
1249
|
-
return 'list'
|
|
754
|
+
return 'list';
|
|
1250
755
|
}
|
|
1251
756
|
else if (message.listResponseMessage) {
|
|
1252
|
-
return 'list_response'
|
|
757
|
+
return 'list_response';
|
|
1253
758
|
}
|
|
1254
759
|
else if (message.buttonsResponseMessage) {
|
|
1255
|
-
return 'buttons_response'
|
|
760
|
+
return 'buttons_response';
|
|
1256
761
|
}
|
|
1257
762
|
else if (message.orderMessage) {
|
|
1258
|
-
return 'order'
|
|
763
|
+
return 'order';
|
|
1259
764
|
}
|
|
1260
765
|
else if (message.productMessage) {
|
|
1261
|
-
return 'product'
|
|
766
|
+
return 'product';
|
|
1262
767
|
}
|
|
1263
768
|
else if (message.interactiveResponseMessage) {
|
|
1264
|
-
return 'native_flow_response'
|
|
1265
|
-
}
|
|
1266
|
-
else if (/https:\/\/wa\.me\/c\/\d+/.test(message.extendedTextMessage?.text)) {
|
|
1267
|
-
return 'cataloglink'
|
|
1268
|
-
}
|
|
1269
|
-
else if (/https:\/\/wa\.me\/p\/\d+\/\d+/.test(message.extendedTextMessage?.text)) {
|
|
1270
|
-
return 'productlink'
|
|
1271
|
-
}
|
|
1272
|
-
else if (message.extendedTextMessage?.matchedText || message.groupInviteMessage) {
|
|
1273
|
-
return 'url'
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
|
-
const getButtonType = (message) => {
|
|
1278
|
-
if (message.listMessage) {
|
|
1279
|
-
return 'list'
|
|
1280
|
-
}
|
|
1281
|
-
else if (message.buttonsMessage) {
|
|
1282
|
-
return 'buttons'
|
|
1283
|
-
}
|
|
1284
|
-
else if(message.interactiveMessage?.nativeFlowMessage) {
|
|
1285
|
-
return 'native_flow'
|
|
769
|
+
return 'native_flow_response';
|
|
1286
770
|
}
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
const getButtonArgs = (message) => {
|
|
1290
|
-
const nativeFlow = message.interactiveMessage?.nativeFlowMessage
|
|
1291
|
-
const firstButtonName = nativeFlow?.buttons?.[0]?.name
|
|
1292
|
-
const nativeFlowSpecials = [
|
|
1293
|
-
'mpm', 'cta_catalog', 'send_location',
|
|
1294
|
-
'call_permission_request', 'wa_payment_transaction_details',
|
|
1295
|
-
'automated_greeting_message_view_catalog'
|
|
1296
|
-
]
|
|
1297
|
-
|
|
1298
|
-
if (nativeFlow && (firstButtonName === 'review_and_pay' || firstButtonName === 'payment_info')) {
|
|
1299
|
-
return {
|
|
1300
|
-
tag: 'biz',
|
|
1301
|
-
attrs: {
|
|
1302
|
-
native_flow_name: firstButtonName === 'review_and_pay' ? 'order_details' : firstButtonName
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
} else if (nativeFlow && nativeFlowSpecials.includes(firstButtonName)) {
|
|
1306
|
-
// Only works for WhatsApp Original, not WhatsApp Business
|
|
1307
|
-
return {
|
|
1308
|
-
tag: 'biz',
|
|
1309
|
-
attrs: {
|
|
1310
|
-
actual_actors: '2',
|
|
1311
|
-
host_storage: '2',
|
|
1312
|
-
privacy_mode_ts: Utils_1.unixTimestampSeconds().toString()
|
|
1313
|
-
},
|
|
1314
|
-
content: [{
|
|
1315
|
-
tag: 'interactive',
|
|
1316
|
-
attrs: {
|
|
1317
|
-
type: 'native_flow',
|
|
1318
|
-
v: '1'
|
|
1319
|
-
},
|
|
1320
|
-
content: [{
|
|
1321
|
-
tag: 'native_flow',
|
|
1322
|
-
attrs: {
|
|
1323
|
-
v: '2',
|
|
1324
|
-
name: firstButtonName
|
|
1325
|
-
}
|
|
1326
|
-
}]
|
|
1327
|
-
},
|
|
1328
|
-
{
|
|
1329
|
-
tag: 'quality_control',
|
|
1330
|
-
attrs: {
|
|
1331
|
-
source_type: 'third_party'
|
|
1332
|
-
}
|
|
1333
|
-
}]
|
|
1334
|
-
}
|
|
1335
|
-
} else if (nativeFlow || message.buttonsMessage) {
|
|
1336
|
-
// It works for whatsapp original and whatsapp business
|
|
1337
|
-
return {
|
|
1338
|
-
tag: 'biz',
|
|
1339
|
-
attrs: {
|
|
1340
|
-
actual_actors: '2',
|
|
1341
|
-
host_storage: '2',
|
|
1342
|
-
privacy_mode_ts: Utils_1.unixTimestampSeconds().toString()
|
|
1343
|
-
},
|
|
1344
|
-
content: [{
|
|
1345
|
-
tag: 'interactive',
|
|
1346
|
-
attrs: {
|
|
1347
|
-
type: 'native_flow',
|
|
1348
|
-
v: '1'
|
|
1349
|
-
},
|
|
1350
|
-
content: [{
|
|
1351
|
-
tag: 'native_flow',
|
|
1352
|
-
attrs: {
|
|
1353
|
-
v: '9',
|
|
1354
|
-
name: 'mixed'
|
|
1355
|
-
}
|
|
1356
|
-
}]
|
|
1357
|
-
},
|
|
1358
|
-
{
|
|
1359
|
-
tag: 'quality_control',
|
|
1360
|
-
attrs: {
|
|
1361
|
-
source_type: 'third_party'
|
|
1362
|
-
}
|
|
1363
|
-
}]
|
|
1364
|
-
}
|
|
1365
|
-
} else if (message.listMessage) {
|
|
1366
|
-
return {
|
|
1367
|
-
tag: 'biz',
|
|
1368
|
-
attrs: {
|
|
1369
|
-
actual_actors: '2',
|
|
1370
|
-
host_storage: '2',
|
|
1371
|
-
privacy_mode_ts: Utils_1.unixTimestampSeconds().toString()
|
|
1372
|
-
},
|
|
1373
|
-
content: [{
|
|
1374
|
-
tag: 'list',
|
|
1375
|
-
attrs: {
|
|
1376
|
-
v: '2',
|
|
1377
|
-
type: 'product_list'
|
|
1378
|
-
}
|
|
1379
|
-
},
|
|
1380
|
-
{
|
|
1381
|
-
tag: 'quality_control',
|
|
1382
|
-
attrs: {
|
|
1383
|
-
source_type: 'third_party'
|
|
1384
|
-
}
|
|
1385
|
-
}]
|
|
1386
|
-
}
|
|
1387
|
-
} else {
|
|
1388
|
-
return {
|
|
1389
|
-
tag: 'biz',
|
|
1390
|
-
attrs: {
|
|
1391
|
-
actual_actors: '2',
|
|
1392
|
-
host_storage: '2',
|
|
1393
|
-
privacy_mode_ts: Utils_1.unixTimestampSeconds().toString()
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
771
|
+
else if (message.groupInviteMessage) {
|
|
772
|
+
return 'url';
|
|
1396
773
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
774
|
+
return '';
|
|
775
|
+
};
|
|
1399
776
|
const getPrivacyTokens = async (jids) => {
|
|
1400
|
-
const t =
|
|
1401
|
-
|
|
777
|
+
const t = unixTimestampSeconds().toString();
|
|
1402
778
|
const result = await query({
|
|
1403
779
|
tag: 'iq',
|
|
1404
780
|
attrs: {
|
|
1405
|
-
to:
|
|
781
|
+
to: S_WHATSAPP_NET,
|
|
1406
782
|
type: 'set',
|
|
1407
783
|
xmlns: 'privacy'
|
|
1408
784
|
},
|
|
@@ -1413,373 +789,165 @@ await assertSessions(allJids, false)
|
|
|
1413
789
|
content: jids.map(jid => ({
|
|
1414
790
|
tag: 'token',
|
|
1415
791
|
attrs: {
|
|
1416
|
-
jid:
|
|
792
|
+
jid: jidNormalizedUser(jid),
|
|
1417
793
|
t,
|
|
1418
794
|
type: 'trusted_contact'
|
|
1419
795
|
}
|
|
1420
796
|
}))
|
|
1421
797
|
}
|
|
1422
798
|
]
|
|
1423
|
-
})
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
const getEphemeralGroup = (jid) => {
|
|
1429
|
-
if (!WABinary_1.isJidGroup(jid)) throw new TypeError("Jid should originate from a group!")
|
|
1430
|
-
|
|
1431
|
-
return groupQuery(jid, 'get', [{
|
|
1432
|
-
tag: 'query',
|
|
1433
|
-
attrs: {
|
|
1434
|
-
request: 'interactive'
|
|
1435
|
-
}
|
|
1436
|
-
}])
|
|
1437
|
-
.then((groups) => WABinary_1.getBinaryNodeChild(groups, 'group'))
|
|
1438
|
-
.then((metadata) => WABinary_1.getBinaryNodeChild(metadata, 'ephemeral')?.attrs?.expiration || 0)
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
|
-
const waUploadToServer = Utils_1.getWAUploadToServer(config, refreshMediaConn)
|
|
1442
|
-
|
|
1443
|
-
const waitForMsgMediaUpdate = Utils_1.bindWaitForEvent(ev, 'messages.media-update')
|
|
1444
|
-
|
|
799
|
+
});
|
|
800
|
+
return result;
|
|
801
|
+
};
|
|
802
|
+
const waUploadToServer = getWAUploadToServer(config, refreshMediaConn);
|
|
803
|
+
const waitForMsgMediaUpdate = bindWaitForEvent(ev, 'messages.media-update');
|
|
1445
804
|
return {
|
|
1446
|
-
...
|
|
805
|
+
...sock,
|
|
1447
806
|
getPrivacyTokens,
|
|
1448
807
|
assertSessions,
|
|
1449
808
|
relayMessage,
|
|
1450
809
|
sendReceipt,
|
|
1451
810
|
sendReceipts,
|
|
1452
811
|
readMessages,
|
|
1453
|
-
profilePictureUrl,
|
|
1454
|
-
getUSyncDevices,
|
|
1455
812
|
refreshMediaConn,
|
|
1456
813
|
waUploadToServer,
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
814
|
+
fetchPrivacySettings,
|
|
815
|
+
sendPeerDataOperationMessage,
|
|
816
|
+
createParticipantNodes,
|
|
817
|
+
getUSyncDevices,
|
|
818
|
+
messageRetryManager,
|
|
1462
819
|
updateMediaMessage: async (message) => {
|
|
1463
|
-
const content =
|
|
1464
|
-
const mediaKey = content.mediaKey
|
|
1465
|
-
const meId = authState.creds.me.id
|
|
1466
|
-
const node = await
|
|
1467
|
-
let error = undefined
|
|
1468
|
-
|
|
820
|
+
const content = assertMediaContent(message.message);
|
|
821
|
+
const mediaKey = content.mediaKey;
|
|
822
|
+
const meId = authState.creds.me.id;
|
|
823
|
+
const node = await encryptMediaRetryRequest(message.key, mediaKey, meId);
|
|
824
|
+
let error = undefined;
|
|
1469
825
|
await Promise.all([
|
|
1470
826
|
sendNode(node),
|
|
1471
827
|
waitForMsgMediaUpdate(async (update) => {
|
|
1472
|
-
const result = update.find(c => c.key.id === message.key.id)
|
|
828
|
+
const result = update.find(c => c.key.id === message.key.id);
|
|
1473
829
|
if (result) {
|
|
1474
830
|
if (result.error) {
|
|
1475
|
-
error = result.error
|
|
831
|
+
error = result.error;
|
|
1476
832
|
}
|
|
1477
|
-
|
|
1478
833
|
else {
|
|
1479
834
|
try {
|
|
1480
|
-
const media = await
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
835
|
+
const media = await decryptMediaRetryData(result.media, mediaKey, result.key.id);
|
|
836
|
+
if (media.result !== proto.MediaRetryNotification.ResultType.SUCCESS) {
|
|
837
|
+
const resultStr = proto.MediaRetryNotification.ResultType[media.result];
|
|
838
|
+
throw new Boom(`Media re-upload failed by device (${resultStr})`, {
|
|
839
|
+
data: media,
|
|
840
|
+
statusCode: getStatusCodeForMediaRetry(media.result) || 404
|
|
841
|
+
});
|
|
1486
842
|
}
|
|
1487
|
-
|
|
1488
|
-
content.
|
|
1489
|
-
|
|
1490
|
-
content.url = Utils_1.getUrlFromDirectPath(content.directPath)
|
|
1491
|
-
|
|
1492
|
-
logger.debug({ directPath: media.directPath, key: result.key }, 'media update successful')
|
|
843
|
+
content.directPath = media.directPath;
|
|
844
|
+
content.url = getUrlFromDirectPath(content.directPath);
|
|
845
|
+
logger.debug({ directPath: media.directPath, key: result.key }, 'media update successful');
|
|
1493
846
|
}
|
|
1494
|
-
|
|
1495
847
|
catch (err) {
|
|
1496
|
-
error = err
|
|
848
|
+
error = err;
|
|
1497
849
|
}
|
|
1498
850
|
}
|
|
1499
|
-
|
|
1500
|
-
return true
|
|
851
|
+
return true;
|
|
1501
852
|
}
|
|
1502
853
|
})
|
|
1503
|
-
])
|
|
1504
|
-
|
|
854
|
+
]);
|
|
1505
855
|
if (error) {
|
|
1506
|
-
throw error
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
|
-
ev.emit('messages.update', [
|
|
1510
|
-
{ key: message.key, update: { message: message.message } }
|
|
1511
|
-
])
|
|
1512
|
-
|
|
1513
|
-
return message
|
|
1514
|
-
},
|
|
1515
|
-
sendStatusMentions: async (content, jids = []) => {
|
|
1516
|
-
const userJid = WABinary_1.jidNormalizedUser(authState.creds.me.id)
|
|
1517
|
-
let allUsers = new Set()
|
|
1518
|
-
allUsers.add(userJid)
|
|
1519
|
-
|
|
1520
|
-
for (const id of jids) {
|
|
1521
|
-
const isGroup = WABinary_1.isJidGroup(id)
|
|
1522
|
-
const isPrivate = WABinary_1.isJidUser(id)
|
|
1523
|
-
|
|
1524
|
-
if (isGroup) {
|
|
1525
|
-
try {
|
|
1526
|
-
const metadata = await cachedGroupMetadata(id) || await groupMetadata(id)
|
|
1527
|
-
const participants = metadata.participants.map(p => WABinary_1.jidNormalizedUser(p.id))
|
|
1528
|
-
participants.forEach(jid => allUsers.add(jid))
|
|
1529
|
-
} catch (error) {
|
|
1530
|
-
logger.error(`Error getting metadata for group ${id}: ${error}`)
|
|
1531
|
-
}
|
|
1532
|
-
} else if (isPrivate) {
|
|
1533
|
-
allUsers.add(WABinary_1.jidNormalizedUser(id))
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
|
|
1537
|
-
const uniqueUsers = Array.from(allUsers)
|
|
1538
|
-
const getRandomHexColor = () => "#" + Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0")
|
|
1539
|
-
|
|
1540
|
-
const isMedia = content.image || content.video || content.audio
|
|
1541
|
-
const isAudio = !!content.audio
|
|
1542
|
-
|
|
1543
|
-
const messageContent = { ...content }
|
|
1544
|
-
|
|
1545
|
-
if (isMedia && !isAudio) {
|
|
1546
|
-
if (messageContent.text) {
|
|
1547
|
-
messageContent.caption = messageContent.text
|
|
1548
|
-
|
|
1549
|
-
delete messageContent.text
|
|
856
|
+
throw error;
|
|
1550
857
|
}
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
delete messageContent.font
|
|
1554
|
-
delete messageContent.backgroundColor
|
|
1555
|
-
delete messageContent.textColor
|
|
1556
|
-
}
|
|
1557
|
-
|
|
1558
|
-
if (isAudio) {
|
|
1559
|
-
delete messageContent.text
|
|
1560
|
-
delete messageContent.caption
|
|
1561
|
-
delete messageContent.font
|
|
1562
|
-
delete messageContent.textColor
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
|
-
const font = !isMedia ? (content.font || Math.floor(Math.random() * 9)) : undefined
|
|
1566
|
-
const textColor = !isMedia ? (content.textColor || getRandomHexColor()) : undefined
|
|
1567
|
-
const backgroundColor = (!isMedia || isAudio) ? (content.backgroundColor || getRandomHexColor()) : undefined
|
|
1568
|
-
const ptt = isAudio ? (typeof content.ptt === 'boolean' ? content.ptt : true) : undefined
|
|
1569
|
-
|
|
1570
|
-
let msg
|
|
1571
|
-
let mediaHandle
|
|
1572
|
-
try {
|
|
1573
|
-
msg = await Utils_1.generateWAMessage(WABinary_1.STORIES_JID, messageContent, {
|
|
1574
|
-
logger,
|
|
1575
|
-
userJid,
|
|
1576
|
-
getUrlInfo: text => link_preview_1.getUrlInfo(text, {
|
|
1577
|
-
thumbnailWidth: linkPreviewImageThumbnailWidth,
|
|
1578
|
-
fetchOpts: { timeout: 3000, ...axiosOptions || {} },
|
|
1579
|
-
logger,
|
|
1580
|
-
uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
|
|
1581
|
-
}),
|
|
1582
|
-
upload: async (encFilePath, opts) => {
|
|
1583
|
-
const up = await waUploadToServer(encFilePath, { ...opts })
|
|
1584
|
-
mediaHandle = up.handle
|
|
1585
|
-
return up
|
|
1586
|
-
},
|
|
1587
|
-
mediaCache: config.mediaCache,
|
|
1588
|
-
options: config.options,
|
|
1589
|
-
font,
|
|
1590
|
-
textColor,
|
|
1591
|
-
backgroundColor,
|
|
1592
|
-
ptt
|
|
1593
|
-
})
|
|
1594
|
-
} catch (error) {
|
|
1595
|
-
logger.error(`Error generating message: ${error}`)
|
|
1596
|
-
throw error
|
|
1597
|
-
}
|
|
1598
|
-
|
|
1599
|
-
await relayMessage(WABinary_1.STORIES_JID, msg.message, {
|
|
1600
|
-
messageId: msg.key.id,
|
|
1601
|
-
statusJidList: uniqueUsers,
|
|
1602
|
-
additionalNodes: [
|
|
1603
|
-
{
|
|
1604
|
-
tag: 'meta',
|
|
1605
|
-
attrs: {},
|
|
1606
|
-
content: [
|
|
1607
|
-
{
|
|
1608
|
-
tag: 'mentioned_users',
|
|
1609
|
-
attrs: {},
|
|
1610
|
-
content: jids.map(jid => ({
|
|
1611
|
-
tag: 'to',
|
|
1612
|
-
attrs: { jid: WABinary_1.jidNormalizedUser(jid) }
|
|
1613
|
-
}))
|
|
1614
|
-
}]
|
|
1615
|
-
}]
|
|
1616
|
-
})
|
|
1617
|
-
|
|
1618
|
-
for (const id of jids) {
|
|
1619
|
-
try {
|
|
1620
|
-
const normalizedId = WABinary_1.jidNormalizedUser(id)
|
|
1621
|
-
const isPrivate = WABinary_1.isJidUser(normalizedId)
|
|
1622
|
-
const type = isPrivate ? 'statusMentionMessage' : 'groupStatusMentionMessage'
|
|
1623
|
-
|
|
1624
|
-
const protocolMessage = {
|
|
1625
|
-
[type]: {
|
|
1626
|
-
message: {
|
|
1627
|
-
protocolMessage: {
|
|
1628
|
-
key: msg.key,
|
|
1629
|
-
type: 25
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
},
|
|
1633
|
-
messageContextInfo: {
|
|
1634
|
-
messageSecret: crypto_1.randomBytes(32)
|
|
1635
|
-
}
|
|
1636
|
-
}
|
|
1637
|
-
|
|
1638
|
-
const statusMsg = await Utils_1.generateWAMessageFromContent(normalizedId,
|
|
1639
|
-
protocolMessage,
|
|
1640
|
-
{}
|
|
1641
|
-
)
|
|
1642
|
-
|
|
1643
|
-
await relayMessage(
|
|
1644
|
-
normalizedId,
|
|
1645
|
-
statusMsg.message,
|
|
1646
|
-
{
|
|
1647
|
-
additionalNodes: [{
|
|
1648
|
-
tag: 'meta',
|
|
1649
|
-
attrs: isPrivate ?
|
|
1650
|
-
{ is_status_mention: 'true' } :
|
|
1651
|
-
{ is_group_status_mention: 'true' }
|
|
1652
|
-
}]
|
|
1653
|
-
}
|
|
1654
|
-
)
|
|
1655
|
-
|
|
1656
|
-
await Utils_1.delay(2000)
|
|
1657
|
-
} catch (error) {
|
|
1658
|
-
logger.error(`Error sending to ${id}: ${error}`)
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
return msg
|
|
858
|
+
ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]);
|
|
859
|
+
return message;
|
|
1663
860
|
},
|
|
1664
861
|
sendMessage: async (jid, content, options = {}) => {
|
|
1665
|
-
const userJid = authState.creds.me.id
|
|
1666
|
-
const additionalAttributes = {}
|
|
1667
|
-
|
|
1668
|
-
if (!options.ephemeralExpiration) {
|
|
1669
|
-
if (WABinary_1.isJidGroup(jid)) {
|
|
1670
|
-
const expiration = await getEphemeralGroup(jid)
|
|
1671
|
-
options.ephemeralExpiration = expiration
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
|
|
862
|
+
const userJid = authState.creds.me.id;
|
|
1675
863
|
if (typeof content === 'object' &&
|
|
1676
864
|
'disappearingMessagesInChat' in content &&
|
|
1677
865
|
typeof content['disappearingMessagesInChat'] !== 'undefined' &&
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
const
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
disappearingMessagesInChat
|
|
1685
|
-
|
|
1686
|
-
await groupToggleEphemeral(jid, value)
|
|
866
|
+
isJidGroup(jid)) {
|
|
867
|
+
const { disappearingMessagesInChat } = content;
|
|
868
|
+
const value = typeof disappearingMessagesInChat === 'boolean'
|
|
869
|
+
? disappearingMessagesInChat
|
|
870
|
+
? WA_DEFAULT_EPHEMERAL
|
|
871
|
+
: 0
|
|
872
|
+
: disappearingMessagesInChat;
|
|
873
|
+
await groupToggleEphemeral(jid, value);
|
|
1687
874
|
}
|
|
1688
|
-
|
|
1689
|
-
else if (typeof content === 'object' && 'album' in content && content.album) {
|
|
1690
|
-
const albumMsg = await Utils_1.prepareAlbumMessageContent(jid, content.album, {
|
|
1691
|
-
baron: {
|
|
1692
|
-
relayMessage,
|
|
1693
|
-
waUploadToServer
|
|
1694
|
-
},
|
|
1695
|
-
userJid: userJid,
|
|
1696
|
-
...options
|
|
1697
|
-
})
|
|
1698
|
-
|
|
1699
|
-
for (const media of albumMsg) {
|
|
1700
|
-
await Utils_1.delay(options.delay || 500)
|
|
1701
|
-
await relayMessage(jid, media.message, { messageId: media.key.id, useCachedGroupMetadata: options.useCachedGroupMetadata, additionalAttributes, statusJidList: options.statusJidList, additionalNodes: options.additionalNodes, AI: options.ai })
|
|
1702
|
-
}
|
|
1703
|
-
|
|
1704
|
-
return albumMsg
|
|
1705
|
-
}
|
|
1706
|
-
|
|
1707
875
|
else {
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
const fullMsg = await Utils_1.generateWAMessage(jid, content, {
|
|
876
|
+
const fullMsg = await generateWAMessage(jid, content, {
|
|
1711
877
|
logger,
|
|
1712
878
|
userJid,
|
|
1713
|
-
getUrlInfo: text =>
|
|
879
|
+
getUrlInfo: text => getUrlInfo(text, {
|
|
1714
880
|
thumbnailWidth: linkPreviewImageThumbnailWidth,
|
|
1715
881
|
fetchOpts: {
|
|
1716
882
|
timeout: 3000,
|
|
1717
|
-
...
|
|
883
|
+
...(httpRequestOptions || {})
|
|
1718
884
|
},
|
|
1719
885
|
logger,
|
|
1720
|
-
uploadImage: generateHighQualityLinkPreview
|
|
1721
|
-
? waUploadToServer
|
|
1722
|
-
: undefined
|
|
886
|
+
uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
|
|
1723
887
|
}),
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
mediaHandle = up.handle
|
|
1729
|
-
return up
|
|
1730
|
-
},
|
|
888
|
+
//TODO: CACHE
|
|
889
|
+
getProfilePicUrl: sock.profilePictureUrl,
|
|
890
|
+
getCallLink: sock.createCallLink,
|
|
891
|
+
upload: waUploadToServer,
|
|
1731
892
|
mediaCache: config.mediaCache,
|
|
1732
893
|
options: config.options,
|
|
1733
|
-
messageId:
|
|
1734
|
-
...options
|
|
1735
|
-
})
|
|
1736
|
-
|
|
1737
|
-
const
|
|
1738
|
-
const
|
|
1739
|
-
const
|
|
1740
|
-
const
|
|
1741
|
-
|
|
1742
|
-
|
|
894
|
+
messageId: generateMessageIDV2(sock.user?.id),
|
|
895
|
+
...options
|
|
896
|
+
});
|
|
897
|
+
const isEventMsg = 'event' in content && !!content.event;
|
|
898
|
+
const isDeleteMsg = 'delete' in content && !!content.delete;
|
|
899
|
+
const isEditMsg = 'edit' in content && !!content.edit;
|
|
900
|
+
const isPinMsg = 'pin' in content && !!content.pin;
|
|
901
|
+
const isPollMessage = 'poll' in content && !!content.poll;
|
|
902
|
+
const additionalAttributes = {};
|
|
903
|
+
const additionalNodes = [];
|
|
904
|
+
// required for delete
|
|
905
|
+
if (isDeleteMsg) {
|
|
1743
906
|
// if the chat is a group, and I am not the author, then delete the message as an admin
|
|
1744
|
-
if (
|
|
1745
|
-
additionalAttributes.edit = '8'
|
|
907
|
+
if (isJidGroup(content.delete?.remoteJid) && !content.delete?.fromMe) {
|
|
908
|
+
additionalAttributes.edit = '8';
|
|
1746
909
|
}
|
|
1747
|
-
|
|
1748
910
|
else {
|
|
1749
|
-
additionalAttributes.edit = '7'
|
|
911
|
+
additionalAttributes.edit = '7';
|
|
1750
912
|
}
|
|
1751
913
|
}
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
additionalAttributes.edit = WABinary_1.isJidNewsletter(jid) ? '3' : '1'
|
|
914
|
+
else if (isEditMsg) {
|
|
915
|
+
additionalAttributes.edit = '1';
|
|
1755
916
|
}
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
additionalAttributes.edit = '2'
|
|
1759
|
-
}
|
|
1760
|
-
|
|
1761
|
-
if (mediaHandle) {
|
|
1762
|
-
additionalAttributes['media_id'] = mediaHandle
|
|
917
|
+
else if (isPinMsg) {
|
|
918
|
+
additionalAttributes.edit = '2';
|
|
1763
919
|
}
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
920
|
+
else if (isPollMessage) {
|
|
921
|
+
additionalNodes.push({
|
|
922
|
+
tag: 'meta',
|
|
923
|
+
attrs: {
|
|
924
|
+
polltype: 'creation'
|
|
925
|
+
}
|
|
926
|
+
});
|
|
1767
927
|
}
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
928
|
+
else if (isEventMsg) {
|
|
929
|
+
additionalNodes.push({
|
|
930
|
+
tag: 'meta',
|
|
931
|
+
attrs: {
|
|
932
|
+
event_type: 'creation'
|
|
933
|
+
}
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
await relayMessage(jid, fullMsg.message, {
|
|
937
|
+
messageId: fullMsg.key.id,
|
|
938
|
+
useCachedGroupMetadata: options.useCachedGroupMetadata,
|
|
939
|
+
additionalAttributes,
|
|
940
|
+
statusJidList: options.statusJidList,
|
|
941
|
+
additionalNodes
|
|
942
|
+
});
|
|
1771
943
|
if (config.emitOwnEvents) {
|
|
1772
944
|
process.nextTick(() => {
|
|
1773
|
-
processingMutex.mutex(() =>
|
|
1774
|
-
})
|
|
945
|
+
processingMutex.mutex(() => upsertMessage(fullMsg, 'append'));
|
|
946
|
+
});
|
|
1775
947
|
}
|
|
1776
|
-
|
|
1777
|
-
return fullMsg
|
|
948
|
+
return fullMsg;
|
|
1778
949
|
}
|
|
1779
950
|
}
|
|
1780
|
-
}
|
|
1781
|
-
}
|
|
1782
|
-
|
|
1783
|
-
module.exports = {
|
|
1784
|
-
makeMessagesSocket
|
|
1785
|
-
}
|
|
951
|
+
};
|
|
952
|
+
};
|
|
953
|
+
//# sourceMappingURL=messages-send.js.map
|