@neelegirl/baileys 1.5.2 → 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/README.md +26 -18
- package/WAProto/GenerateStatics.sh +3 -0
- package/WAProto/WAProto.proto +291 -665
- package/WAProto/fix-imports.js +29 -0
- package/WAProto/index.d.ts +2297 -48040
- package/WAProto/index.js +45500 -140101
- package/engine-requirements.js +10 -0
- package/lib/Defaults/index.d.ts +58 -64
- package/lib/Defaults/index.d.ts.map +1 -0
- package/lib/Defaults/index.js +74 -96
- 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/Group/group-session-builder.d.ts +15 -0
- 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/Group/group_cipher.js +82 -0
- 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} +3 -16
- package/lib/Signal/Group/sender-message-key.js.map +1 -0
- package/lib/Signal/libsignal.d.ts +5 -4
- package/lib/Signal/libsignal.d.ts.map +1 -0
- package/lib/Signal/libsignal.js +292 -112
- package/lib/Signal/libsignal.js.map +1 -0
- package/lib/Signal/lid-mapping.d.ts +23 -0
- package/lib/Signal/lid-mapping.d.ts.map +1 -0
- package/lib/Signal/lid-mapping.js +171 -0
- package/lib/Signal/lid-mapping.js.map +1 -0
- package/lib/Socket/Client/index.d.ts +3 -2
- package/lib/Socket/Client/index.d.ts.map +1 -0
- package/lib/Socket/Client/index.js +3 -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 +179 -71
- package/lib/Socket/business.js.map +1 -0
- package/lib/Socket/chats.d.ts +93 -93
- package/lib/Socket/chats.d.ts.map +1 -0
- package/lib/Socket/chats.js +474 -625
- package/lib/Socket/chats.js.map +1 -0
- package/lib/Socket/communities.d.ts +83 -62
- package/lib/Socket/communities.d.ts.map +1 -0
- package/lib/Socket/communities.js +412 -414
- package/lib/Socket/communities.js.map +1 -0
- package/lib/Socket/groups.d.ts +118 -112
- package/lib/Socket/groups.d.ts.map +1 -0
- package/lib/Socket/groups.js +146 -171
- 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 -17
- package/lib/Socket/index.js.map +1 -0
- package/lib/Socket/messages-recv.d.ts +165 -169
- package/lib/Socket/messages-recv.d.ts.map +1 -0
- package/lib/Socket/messages-recv.js +1185 -1721
- package/lib/Socket/messages-recv.js.map +1 -0
- package/lib/Socket/messages-send.d.ts +161 -159
- package/lib/Socket/messages-send.d.ts.map +1 -0
- package/lib/Socket/messages-send.js +650 -991
- package/lib/Socket/messages-send.js.map +1 -0
- package/lib/Socket/mex.d.ts +1 -0
- package/lib/Socket/mex.d.ts.map +1 -0
- package/lib/Socket/mex.js +4 -9
- package/lib/Socket/mex.js.map +1 -0
- package/lib/Socket/newsletter.d.ts +139 -139
- package/lib/Socket/newsletter.d.ts.map +1 -0
- package/lib/Socket/newsletter.js +153 -258
- 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 +623 -507
- package/lib/Socket/socket.js.map +1 -0
- package/lib/Types/Auth.d.ts +87 -96
- 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 -0
- 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 +79 -94
- 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 +13 -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 +152 -179
- 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 +234 -404
- package/lib/Types/Message.d.ts.map +1 -0
- package/lib/Types/Message.js +11 -13
- 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 +63 -55
- 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 +78 -65
- 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 -61
- package/lib/Types/index.d.ts.map +1 -0
- package/lib/Types/index.js +26 -48
- package/lib/Types/index.js.map +1 -0
- package/lib/Utils/auth-utils.d.ts +8 -10
- package/lib/Utils/auth-utils.d.ts.map +1 -0
- package/lib/Utils/auth-utils.js +206 -154
- package/lib/Utils/auth-utils.js.map +1 -0
- package/lib/Utils/baileys-event-stream.d.ts +6 -7
- package/lib/Utils/baileys-event-stream.d.ts.map +1 -0
- package/lib/Utils/baileys-event-stream.js +29 -43
- 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 +14 -20
- package/lib/Utils/business.d.ts.map +1 -0
- package/lib/Utils/business.js +110 -134
- package/lib/Utils/business.js.map +1 -0
- package/lib/Utils/chat-utils.d.ts +57 -69
- package/lib/Utils/chat-utils.d.ts.map +1 -0
- package/lib/Utils/chat-utils.js +362 -380
- package/lib/Utils/chat-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +30 -45
- package/lib/Utils/crypto.d.ts.map +1 -0
- package/lib/Utils/crypto.js +141 -178
- package/lib/Utils/crypto.js.map +1 -0
- package/lib/Utils/decode-wa-message.d.ts +42 -35
- package/lib/Utils/decode-wa-message.d.ts.map +1 -0
- package/lib/Utils/decode-wa-message.js +176 -150
- package/lib/Utils/decode-wa-message.js.map +1 -0
- package/lib/Utils/event-buffer.d.ts +12 -17
- package/lib/Utils/event-buffer.d.ts.map +1 -0
- package/lib/Utils/event-buffer.js +269 -286
- package/lib/Utils/event-buffer.js.map +1 -0
- package/lib/Utils/generics.d.ts +60 -99
- package/lib/Utils/generics.d.ts.map +1 -0
- package/lib/Utils/generics.js +244 -487
- package/lib/Utils/generics.js.map +1 -0
- package/lib/Utils/history.d.ts +18 -22
- package/lib/Utils/history.d.ts.map +1 -0
- package/lib/Utils/history.js +54 -80
- package/lib/Utils/history.js.map +1 -0
- package/lib/Utils/index.d.ts +20 -19
- package/lib/Utils/index.d.ts.map +1 -0
- package/lib/Utils/index.js +19 -39
- package/lib/Utils/index.js.map +1 -0
- package/lib/Utils/link-preview.d.ts +12 -14
- package/lib/Utils/link-preview.d.ts.map +1 -0
- package/lib/Utils/link-preview.js +40 -75
- package/lib/Utils/link-preview.js.map +1 -0
- package/lib/Utils/logger.d.ts +10 -11
- package/lib/Utils/logger.d.ts.map +1 -0
- package/lib/Utils/logger.js +3 -7
- package/lib/Utils/logger.js.map +1 -0
- package/lib/Utils/lt-hash.d.ts +12 -13
- package/lib/Utils/lt-hash.d.ts.map +1 -0
- package/lib/Utils/lt-hash.js +27 -37
- package/lib/Utils/lt-hash.js.map +1 -0
- package/lib/Utils/make-mutex.d.ts +6 -7
- package/lib/Utils/make-mutex.d.ts.map +1 -0
- package/lib/Utils/make-mutex.js +20 -29
- package/lib/Utils/make-mutex.js.map +1 -0
- package/lib/Utils/message-retry-manager.d.ts +82 -0
- package/lib/Utils/message-retry-manager.d.ts.map +1 -0
- package/lib/Utils/message-retry-manager.js +149 -0
- package/lib/Utils/message-retry-manager.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +87 -102
- package/lib/Utils/messages-media.d.ts.map +1 -0
- package/lib/Utils/messages-media.js +427 -570
- package/lib/Utils/messages-media.js.map +1 -0
- package/lib/Utils/messages.d.ts +37 -64
- package/lib/Utils/messages.d.ts.map +1 -0
- package/lib/Utils/messages.js +511 -1270
- package/lib/Utils/messages.js.map +1 -0
- package/lib/Utils/noise-handler.d.ts +18 -18
- package/lib/Utils/noise-handler.d.ts.map +1 -0
- package/lib/Utils/noise-handler.js +101 -109
- 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 +25 -32
- package/lib/Utils/process-message.d.ts.map +1 -0
- package/lib/Utils/process-message.js +266 -281
- package/lib/Utils/process-message.js.map +1 -0
- package/lib/Utils/signal.d.ts +24 -32
- package/lib/Utils/signal.d.ts.map +1 -0
- package/lib/Utils/signal.js +98 -105
- package/lib/Utils/signal.js.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts +5 -10
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +69 -186
- 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 +124 -116
- package/lib/Utils/validate-connection.js.map +1 -0
- package/lib/WABinary/constants.d.ts +25 -27
- package/lib/WABinary/constants.d.ts.map +1 -0
- package/lib/WABinary/constants.js +1277 -1292
- 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 +139 -189
- package/lib/WABinary/decode.js.map +1 -0
- package/lib/WABinary/encode.d.ts +3 -3
- package/lib/WABinary/encode.d.ts.map +1 -0
- package/lib/WABinary/encode.js +105 -154
- package/lib/WABinary/encode.js.map +1 -0
- package/lib/WABinary/generic-utils.d.ts +14 -27
- package/lib/WABinary/generic-utils.d.ts.map +1 -0
- package/lib/WABinary/generic-utils.js +62 -102
- package/lib/WABinary/generic-utils.js.map +1 -0
- package/lib/WABinary/index.d.ts +6 -5
- package/lib/WABinary/index.d.ts.map +1 -0
- package/lib/WABinary/index.js +6 -25
- package/lib/WABinary/index.js.map +1 -0
- package/lib/WABinary/jid-utils.d.ts +41 -46
- package/lib/WABinary/jid-utils.d.ts.map +1 -0
- package/lib/WABinary/jid-utils.js +84 -80
- package/lib/WABinary/jid-utils.js.map +1 -0
- package/lib/WABinary/types.d.ts +10 -13
- package/lib/WABinary/types.d.ts.map +1 -0
- package/lib/WABinary/types.js +2 -3
- package/lib/WABinary/types.js.map +1 -0
- package/lib/WAM/BinaryInfo.d.ts +8 -15
- package/lib/WAM/BinaryInfo.d.ts.map +1 -0
- package/lib/WAM/BinaryInfo.js +7 -14
- package/lib/WAM/BinaryInfo.js.map +1 -0
- package/lib/WAM/constants.d.ts +30 -37
- package/lib/WAM/constants.d.ts.map +1 -0
- package/lib/WAM/constants.js +19193 -11711
- package/lib/WAM/constants.js.map +1 -0
- package/lib/WAM/encode.d.ts +3 -3
- package/lib/WAM/encode.d.ts.map +1 -0
- package/lib/WAM/encode.js +95 -110
- 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 +10 -11
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -33
- package/lib/index.js.map +1 -0
- package/package.json +48 -43
- 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.js +0 -16
- package/lib/Signal/WASignalGroup/generate-proto.sh +0 -1
- package/lib/Signal/WASignalGroup/group.proto +0 -42
- package/lib/Signal/WASignalGroup/group_cipher.js +0 -120
- package/lib/Signal/WASignalGroup/group_session_builder.js +0 -46
- package/lib/Signal/WASignalGroup/index.js +0 -6
- package/lib/Signal/WASignalGroup/keyhelper.js +0 -21
- 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.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/registration.d.ts +0 -266
- package/lib/Socket/registration.js +0 -166
- 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/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 -9
- package/lib/WAUSync/Protocols/USyncLIDProtocol.js +0 -30
|
@@ -1,108 +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
|
-
|
|
21
|
-
|
|
22
|
-
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: axiosOptions, patchMessageBeforeSending, cachedGroupMetadata, } = config
|
|
23
|
-
const baron = newsletter_1.makeNewsletterSocket(config)
|
|
24
|
-
const { ev, authState, processingMutex, signalRepository, upsertMessage, createCallLink, query, fetchPrivacySettings, sendNode, groupQuery, groupMetadata, groupToggleEphemeral, newsletterWMexQuery, executeUSyncQuery } = baron
|
|
25
|
-
|
|
26
|
-
const userDevicesCache = config.userDevicesCache || new node_cache_1.default({
|
|
27
|
-
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,
|
|
28
22
|
useClones: false
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
});
|
|
24
|
+
// Initialize message retry manager if enabled
|
|
25
|
+
const messageRetryManager = enableRecentMessageCache ? new MessageRetryManager(logger, maxMsgRetryCount) : null;
|
|
26
|
+
// Prevent race conditions in Signal session encryption by user
|
|
27
|
+
const encryptionMutex = makeKeyedMutex();
|
|
28
|
+
let mediaConn;
|
|
33
29
|
const refreshMediaConn = async (forceGet = false) => {
|
|
34
|
-
const media = await mediaConn
|
|
35
|
-
|
|
36
|
-
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) {
|
|
37
32
|
mediaConn = (async () => {
|
|
38
|
-
|
|
39
33
|
const result = await query({
|
|
40
34
|
tag: 'iq',
|
|
41
35
|
attrs: {
|
|
42
36
|
type: 'set',
|
|
43
37
|
xmlns: 'w:m',
|
|
44
|
-
to:
|
|
38
|
+
to: S_WHATSAPP_NET
|
|
45
39
|
},
|
|
46
40
|
content: [{ tag: 'media_conn', attrs: {} }]
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
41
|
+
});
|
|
42
|
+
const mediaConnNode = getBinaryNodeChild(result, 'media_conn');
|
|
43
|
+
// TODO: explore full length of data that whatsapp provides
|
|
51
44
|
const node = {
|
|
52
|
-
hosts:
|
|
45
|
+
hosts: getBinaryNodeChildren(mediaConnNode, 'host').map(({ attrs }) => ({
|
|
53
46
|
hostname: attrs.hostname,
|
|
54
|
-
maxContentLengthBytes: +attrs.maxContentLengthBytes
|
|
47
|
+
maxContentLengthBytes: +attrs.maxContentLengthBytes
|
|
55
48
|
})),
|
|
56
49
|
auth: mediaConnNode.attrs.auth,
|
|
57
50
|
ttl: +mediaConnNode.attrs.ttl,
|
|
58
51
|
fetchDate: new Date()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return node
|
|
64
|
-
})()
|
|
52
|
+
};
|
|
53
|
+
logger.debug('fetched media conn');
|
|
54
|
+
return node;
|
|
55
|
+
})();
|
|
65
56
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
|
|
57
|
+
return mediaConn;
|
|
58
|
+
};
|
|
70
59
|
/**
|
|
71
60
|
* generic send receipt function
|
|
72
61
|
* used for receipts of phone call, read, delivery etc.
|
|
73
62
|
* */
|
|
74
63
|
const sendReceipt = async (jid, participant, messageIds, type) => {
|
|
64
|
+
if (!messageIds || messageIds.length === 0) {
|
|
65
|
+
throw new Boom('missing ids in receipt');
|
|
66
|
+
}
|
|
75
67
|
const node = {
|
|
76
68
|
tag: 'receipt',
|
|
77
69
|
attrs: {
|
|
78
|
-
id: messageIds[0]
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const isReadReceipt = type === 'read' || type === 'read-self'
|
|
83
|
-
|
|
70
|
+
id: messageIds[0]
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const isReadReceipt = type === 'read' || type === 'read-self';
|
|
84
74
|
if (isReadReceipt) {
|
|
85
|
-
node.attrs.t =
|
|
75
|
+
node.attrs.t = unixTimestampSeconds().toString();
|
|
86
76
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
node.attrs.
|
|
90
|
-
node.attrs.to = participant
|
|
77
|
+
if (type === 'sender' && (isPnUser(jid) || isLidUser(jid))) {
|
|
78
|
+
node.attrs.recipient = jid;
|
|
79
|
+
node.attrs.to = participant;
|
|
91
80
|
}
|
|
92
|
-
|
|
93
81
|
else {
|
|
94
|
-
node.attrs.to = jid
|
|
82
|
+
node.attrs.to = jid;
|
|
95
83
|
if (participant) {
|
|
96
|
-
node.attrs.participant = participant
|
|
84
|
+
node.attrs.participant = participant;
|
|
97
85
|
}
|
|
98
86
|
}
|
|
99
|
-
|
|
100
87
|
if (type) {
|
|
101
|
-
node.attrs.type =
|
|
88
|
+
node.attrs.type = type;
|
|
102
89
|
}
|
|
103
|
-
|
|
104
|
-
const remainingMessageIds = messageIds.slice(1)
|
|
105
|
-
|
|
90
|
+
const remainingMessageIds = messageIds.slice(1);
|
|
106
91
|
if (remainingMessageIds.length) {
|
|
107
92
|
node.content = [
|
|
108
93
|
{
|
|
@@ -113,806 +98,687 @@ const makeMessagesSocket = (config) => {
|
|
|
113
98
|
attrs: { id }
|
|
114
99
|
}))
|
|
115
100
|
}
|
|
116
|
-
]
|
|
101
|
+
];
|
|
117
102
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
await sendNode(node)
|
|
122
|
-
}
|
|
123
|
-
|
|
103
|
+
logger.debug({ attrs: node.attrs, messageIds }, 'sending receipt for messages');
|
|
104
|
+
await sendNode(node);
|
|
105
|
+
};
|
|
124
106
|
/** Correctly bulk send receipts to multiple chats, participants */
|
|
125
107
|
const sendReceipts = async (keys, type) => {
|
|
126
|
-
const recps =
|
|
127
|
-
|
|
108
|
+
const recps = aggregateMessageKeysNotFromMe(keys);
|
|
128
109
|
for (const { jid, participant, messageIds } of recps) {
|
|
129
|
-
await sendReceipt(jid, participant, messageIds, type)
|
|
110
|
+
await sendReceipt(jid, participant, messageIds, type);
|
|
130
111
|
}
|
|
131
|
-
}
|
|
132
|
-
|
|
112
|
+
};
|
|
133
113
|
/** Bulk read messages. Keys can be from different chats & participants */
|
|
134
114
|
const readMessages = async (keys) => {
|
|
135
|
-
const privacySettings = await fetchPrivacySettings()
|
|
136
|
-
|
|
115
|
+
const privacySettings = await fetchPrivacySettings();
|
|
137
116
|
// based on privacy settings, we have to change the read type
|
|
138
|
-
const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self'
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/** Fetch image for groups, user, and newsletter **/
|
|
144
|
-
const profilePictureUrl = async (jid) => {
|
|
145
|
-
if (WABinary_1.isJidNewsletter(jid)) {
|
|
146
|
-
|
|
147
|
-
let node = await newsletterWMexQuery(undefined, Types_1.QueryIds.METADATA, {
|
|
148
|
-
input: {
|
|
149
|
-
key: jid,
|
|
150
|
-
type: 'JID',
|
|
151
|
-
view_role: 'GUEST'
|
|
152
|
-
},
|
|
153
|
-
fetch_viewer_metadata: true,
|
|
154
|
-
fetch_full_image: true,
|
|
155
|
-
fetch_creation_time: true
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
let result = WABinary_1.getBinaryNodeChild(node, 'result')?.content?.toString()
|
|
159
|
-
|
|
160
|
-
let metadata = JSON.parse(result).data[Types_1.XWAPaths.NEWSLETTER]
|
|
161
|
-
|
|
162
|
-
return Utils_1.getUrlFromDirectPath(metadata.thread_metadata.picture?.direct_path || '')
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
else {
|
|
167
|
-
const result = await query({
|
|
168
|
-
tag: 'iq',
|
|
169
|
-
attrs: {
|
|
170
|
-
target: WABinary_1.jidNormalizedUser(jid),
|
|
171
|
-
to: WABinary_1.S_WHATSAPP_NET,
|
|
172
|
-
type: 'get',
|
|
173
|
-
xmlns: 'w:profile:picture'
|
|
174
|
-
},
|
|
175
|
-
content: [{
|
|
176
|
-
tag: 'picture',
|
|
177
|
-
attrs: {
|
|
178
|
-
type: 'image',
|
|
179
|
-
query: 'url'
|
|
180
|
-
}
|
|
181
|
-
}]
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
const child = WABinary_1.getBinaryNodeChild(result, 'picture')
|
|
185
|
-
|
|
186
|
-
return child?.attrs?.url || null
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
117
|
+
const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self';
|
|
118
|
+
await sendReceipts(keys, readType);
|
|
119
|
+
};
|
|
190
120
|
/** Fetch all the devices we've to send a message to */
|
|
191
121
|
const getUSyncDevices = async (jids, useCache, ignoreZeroDevices) => {
|
|
192
|
-
const deviceResults = []
|
|
193
|
-
|
|
122
|
+
const deviceResults = [];
|
|
194
123
|
if (!useCache) {
|
|
195
|
-
logger.debug('not using cache for devices')
|
|
124
|
+
logger.debug('not using cache for devices');
|
|
125
|
+
}
|
|
126
|
+
const toFetch = [];
|
|
127
|
+
const jidsWithUser = jids
|
|
128
|
+
.map(jid => {
|
|
129
|
+
const decoded = jidDecode(jid);
|
|
130
|
+
const user = decoded?.user;
|
|
131
|
+
const device = decoded?.device;
|
|
132
|
+
const isExplicitDevice = typeof device === 'number' && device >= 0;
|
|
133
|
+
if (isExplicitDevice && user) {
|
|
134
|
+
deviceResults.push({
|
|
135
|
+
user,
|
|
136
|
+
device,
|
|
137
|
+
jid
|
|
138
|
+
});
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
jid = jidNormalizedUser(jid);
|
|
142
|
+
return { jid, user };
|
|
143
|
+
})
|
|
144
|
+
.filter(jid => jid !== null);
|
|
145
|
+
let mgetDevices;
|
|
146
|
+
if (useCache && userDevicesCache.mget) {
|
|
147
|
+
const usersToFetch = jidsWithUser.map(j => j?.user).filter(Boolean);
|
|
148
|
+
mgetDevices = await userDevicesCache.mget(usersToFetch);
|
|
196
149
|
}
|
|
197
|
-
|
|
198
|
-
const toFetch = []
|
|
199
|
-
|
|
200
|
-
jids = Array.from(new Set(jids))
|
|
201
|
-
|
|
202
|
-
for (let jid of jids) {
|
|
203
|
-
const user = WABinary_1.jidDecode(jid)?.user
|
|
204
|
-
|
|
205
|
-
jid = WABinary_1.jidNormalizedUser(jid)
|
|
206
|
-
|
|
150
|
+
for (const { jid, user } of jidsWithUser) {
|
|
207
151
|
if (useCache) {
|
|
208
|
-
const devices =
|
|
209
|
-
|
|
152
|
+
const devices = mgetDevices?.[user] ||
|
|
153
|
+
(userDevicesCache.mget ? undefined : (await userDevicesCache.get(user)));
|
|
210
154
|
if (devices) {
|
|
211
|
-
|
|
212
|
-
|
|
155
|
+
const devicesWithJid = devices.map(d => ({
|
|
156
|
+
...d,
|
|
157
|
+
jid: jidEncode(d.user, d.server, d.device)
|
|
158
|
+
}));
|
|
159
|
+
deviceResults.push(...devicesWithJid);
|
|
160
|
+
logger.trace({ user }, 'using cache for devices');
|
|
213
161
|
}
|
|
214
|
-
|
|
215
162
|
else {
|
|
216
|
-
toFetch.push(jid)
|
|
163
|
+
toFetch.push(jid);
|
|
217
164
|
}
|
|
218
165
|
}
|
|
219
|
-
|
|
220
166
|
else {
|
|
221
|
-
toFetch.push(jid)
|
|
167
|
+
toFetch.push(jid);
|
|
222
168
|
}
|
|
223
169
|
}
|
|
224
|
-
|
|
225
170
|
if (!toFetch.length) {
|
|
226
|
-
return deviceResults
|
|
171
|
+
return deviceResults;
|
|
227
172
|
}
|
|
228
|
-
|
|
229
|
-
const query = new WAUSync_1.USyncQuery()
|
|
230
|
-
.withContext('message')
|
|
231
|
-
.withDeviceProtocol()
|
|
232
|
-
|
|
173
|
+
const requestedLidUsers = new Set();
|
|
233
174
|
for (const jid of toFetch) {
|
|
234
|
-
|
|
175
|
+
if (isLidUser(jid) || isHostedLidUser(jid)) {
|
|
176
|
+
const user = jidDecode(jid)?.user;
|
|
177
|
+
if (user)
|
|
178
|
+
requestedLidUsers.add(user);
|
|
179
|
+
}
|
|
235
180
|
}
|
|
236
|
-
|
|
237
|
-
const
|
|
238
|
-
|
|
181
|
+
const query = new USyncQuery().withContext('message').withDeviceProtocol().withLIDProtocol();
|
|
182
|
+
for (const jid of toFetch) {
|
|
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
|
|
184
|
+
}
|
|
185
|
+
const result = await sock.executeUSyncQuery(query);
|
|
239
186
|
if (result) {
|
|
240
|
-
|
|
241
|
-
const
|
|
242
|
-
|
|
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 = {};
|
|
243
195
|
for (const item of extracted) {
|
|
244
|
-
deviceMap[item.user] = deviceMap[item.user] || []
|
|
245
|
-
deviceMap[item.user]
|
|
246
|
-
|
|
196
|
+
deviceMap[item.user] = deviceMap[item.user] || [];
|
|
197
|
+
deviceMap[item.user]?.push(item);
|
|
198
|
+
}
|
|
199
|
+
// Process each user's devices as a group for bulk LID migration
|
|
200
|
+
for (const [user, userDevices] of Object.entries(deviceMap)) {
|
|
201
|
+
const isLidUser = requestedLidUsers.has(user);
|
|
202
|
+
// Process all devices for this user
|
|
203
|
+
for (const item of userDevices) {
|
|
204
|
+
const finalJid = isLidUser
|
|
205
|
+
? jidEncode(user, item.server, item.device)
|
|
206
|
+
: jidEncode(item.user, item.server, item.device);
|
|
207
|
+
deviceResults.push({
|
|
208
|
+
...item,
|
|
209
|
+
jid: finalJid
|
|
210
|
+
});
|
|
211
|
+
logger.debug({
|
|
212
|
+
user: item.user,
|
|
213
|
+
device: item.device,
|
|
214
|
+
finalJid,
|
|
215
|
+
usedLid: isLidUser
|
|
216
|
+
}, 'Processed device with LID priority');
|
|
217
|
+
}
|
|
247
218
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
userDevicesCache.
|
|
219
|
+
if (userDevicesCache.mset) {
|
|
220
|
+
// if the cache supports mset, we can set all devices in one go
|
|
221
|
+
await userDevicesCache.mset(Object.entries(deviceMap).map(([key, value]) => ({ key, value })));
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
for (const key in deviceMap) {
|
|
225
|
+
if (deviceMap[key])
|
|
226
|
+
await userDevicesCache.set(key, deviceMap[key]);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
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');
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (Object.keys(userDeviceUpdates).length > 0) {
|
|
236
|
+
try {
|
|
237
|
+
await authState.keys.set({ 'device-list': userDeviceUpdates });
|
|
238
|
+
logger.debug({ userCount: Object.keys(userDeviceUpdates).length }, 'stored user device lists for bulk migration');
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
logger.warn({ error }, 'failed to store user device lists');
|
|
242
|
+
}
|
|
251
243
|
}
|
|
252
244
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
const addrs = jids.map(jid => (signalRepository.jidToSignalProtocolAddress(jid)))
|
|
268
|
-
|
|
269
|
-
const sessions = await authState.keys.get('session', addrs)
|
|
270
|
-
|
|
271
|
-
for (const jid of jids) {
|
|
272
|
-
const signalId = signalRepository
|
|
273
|
-
.jidToSignalProtocolAddress(jid)
|
|
274
|
-
|
|
275
|
-
if (!sessions[signalId]) {
|
|
276
|
-
jidsRequiringFetch.push(jid)
|
|
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
|
|
277
259
|
}
|
|
278
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;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
jidsRequiringFetch.push(jid);
|
|
279
270
|
}
|
|
280
|
-
|
|
281
271
|
if (jidsRequiringFetch.length) {
|
|
282
|
-
|
|
283
|
-
|
|
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');
|
|
284
278
|
const result = await query({
|
|
285
279
|
tag: 'iq',
|
|
286
280
|
attrs: {
|
|
287
281
|
xmlns: 'encrypt',
|
|
288
282
|
type: 'get',
|
|
289
|
-
to:
|
|
283
|
+
to: S_WHATSAPP_NET
|
|
290
284
|
},
|
|
291
285
|
content: [
|
|
292
286
|
{
|
|
293
287
|
tag: 'key',
|
|
294
288
|
attrs: {},
|
|
295
|
-
content:
|
|
289
|
+
content: wireJids.map(jid => ({
|
|
296
290
|
tag: 'user',
|
|
297
|
-
attrs: { jid }
|
|
291
|
+
attrs: { jid }
|
|
298
292
|
}))
|
|
299
293
|
}
|
|
300
294
|
]
|
|
301
|
-
})
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
|
+
}
|
|
306
303
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/** Send Peer Operation */
|
|
304
|
+
return didFetchNewSession;
|
|
305
|
+
};
|
|
312
306
|
const sendPeerDataOperationMessage = async (pdoMessage) => {
|
|
313
307
|
//TODO: for later, abstract the logic to send a Peer Message instead of just PDO - useful for App State Key Resync with phone
|
|
314
308
|
if (!authState.creds.me?.id) {
|
|
315
|
-
throw new
|
|
309
|
+
throw new Boom('Not authenticated');
|
|
316
310
|
}
|
|
317
|
-
|
|
318
311
|
const protocolMessage = {
|
|
319
312
|
protocolMessage: {
|
|
320
313
|
peerDataOperationRequestMessage: pdoMessage,
|
|
321
|
-
type:
|
|
314
|
+
type: proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE
|
|
322
315
|
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
const meJid = WABinary_1.jidNormalizedUser(authState.creds.me.id)
|
|
326
|
-
|
|
316
|
+
};
|
|
317
|
+
const meJid = jidNormalizedUser(authState.creds.me.id);
|
|
327
318
|
const msgId = await relayMessage(meJid, protocolMessage, {
|
|
328
319
|
additionalAttributes: {
|
|
329
320
|
category: 'peer',
|
|
330
|
-
|
|
331
|
-
push_priority: 'high_force',
|
|
321
|
+
push_priority: 'high_force'
|
|
332
322
|
},
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
323
|
+
additionalNodes: [
|
|
324
|
+
{
|
|
325
|
+
tag: 'meta',
|
|
326
|
+
attrs: { appdata: 'default' }
|
|
327
|
+
}
|
|
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
|
+
}
|
|
363
358
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
const
|
|
397
|
-
|
|
359
|
+
const bytes = encodeWAMessage(msgToEncrypt);
|
|
360
|
+
const mutexKey = jid;
|
|
361
|
+
const node = await encryptionMutex.mutex(mutexKey, async () => {
|
|
362
|
+
const { type, ciphertext } = await signalRepository.encryptMessage({
|
|
363
|
+
jid,
|
|
364
|
+
data: bytes
|
|
365
|
+
});
|
|
366
|
+
if (type === 'pkmsg') {
|
|
367
|
+
shouldIncludeDeviceIdentity = true;
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
tag: 'to',
|
|
371
|
+
attrs: { jid },
|
|
372
|
+
content: [
|
|
373
|
+
{
|
|
374
|
+
tag: 'enc',
|
|
375
|
+
attrs: {
|
|
376
|
+
v: '2',
|
|
377
|
+
type,
|
|
378
|
+
...(extraAttrs || {})
|
|
379
|
+
},
|
|
380
|
+
content: ciphertext
|
|
381
|
+
}
|
|
382
|
+
]
|
|
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 = [];
|
|
398
409
|
const meMsg = {
|
|
399
410
|
deviceSentMessage: {
|
|
400
411
|
destinationJid,
|
|
401
412
|
message
|
|
402
|
-
},
|
|
403
|
-
messageContextInfo: message.messageContextInfo
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
const extraAttrs = {}
|
|
407
|
-
|
|
408
|
-
const regexGroupOld = /^(\d{1,15})-(\d+)@g\.us$/
|
|
409
|
-
|
|
410
|
-
const messages = Utils_1.normalizeMessageContent(message)
|
|
411
|
-
|
|
412
|
-
const buttonType = getButtonType(messages)
|
|
413
|
-
const pollMessage = messages.pollCreationMessage || messages.pollCreationMessageV2 || messages.pollCreationMessageV3
|
|
414
|
-
|
|
415
|
-
|
|
413
|
+
},
|
|
414
|
+
messageContextInfo: message.messageContextInfo
|
|
415
|
+
};
|
|
416
|
+
const extraAttrs = {};
|
|
416
417
|
if (participant) {
|
|
417
|
-
// when the retry request is not for a group
|
|
418
|
-
// only send to the specific device that asked for a retry
|
|
419
|
-
// otherwise the message is sent out to every device that should be a recipient
|
|
420
418
|
if (!isGroup && !isStatus) {
|
|
421
|
-
additionalAttributes = { ...additionalAttributes,
|
|
419
|
+
additionalAttributes = { ...additionalAttributes, device_fanout: 'false' };
|
|
422
420
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
421
|
+
const { user, device } = jidDecode(participant.jid);
|
|
422
|
+
devices.push({
|
|
423
|
+
user,
|
|
424
|
+
device,
|
|
425
|
+
jid: participant.jid
|
|
426
|
+
});
|
|
427
427
|
}
|
|
428
|
-
|
|
429
428
|
await authState.keys.transaction(async () => {
|
|
430
|
-
const mediaType = getMediaType(message)
|
|
431
|
-
|
|
429
|
+
const mediaType = getMediaType(message);
|
|
432
430
|
if (mediaType) {
|
|
433
|
-
extraAttrs['mediatype'] = mediaType
|
|
431
|
+
extraAttrs['mediatype'] = mediaType;
|
|
434
432
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
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;
|
|
454
|
+
}
|
|
455
|
+
if (normalizeMessageContent(message)?.pinInChatMessage) {
|
|
456
|
+
extraAttrs['decrypt-fail'] = 'hide'; // todo: expand for reactions and other types
|
|
442
457
|
}
|
|
443
|
-
|
|
444
458
|
if (isGroup || isStatus) {
|
|
445
459
|
const [groupData, senderKeyMap] = await Promise.all([
|
|
446
460
|
(async () => {
|
|
447
|
-
let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined
|
|
448
|
-
|
|
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?
|
|
449
462
|
if (groupData && Array.isArray(groupData?.participants)) {
|
|
450
|
-
logger.trace({ jid, participants: groupData.participants.length }, 'using cached group metadata')
|
|
463
|
+
logger.trace({ jid, participants: groupData.participants.length }, 'using cached group metadata');
|
|
451
464
|
}
|
|
452
|
-
|
|
453
465
|
else if (!isStatus) {
|
|
454
|
-
groupData = await groupMetadata(jid)
|
|
466
|
+
groupData = await groupMetadata(jid); // TODO: start storing group participant list + addr mode in Signal & stop relying on this
|
|
455
467
|
}
|
|
456
|
-
|
|
457
|
-
return groupData
|
|
468
|
+
return groupData;
|
|
458
469
|
})(),
|
|
459
|
-
|
|
460
470
|
(async () => {
|
|
461
471
|
if (!participant && !isStatus) {
|
|
462
|
-
|
|
463
|
-
|
|
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] || {};
|
|
464
476
|
}
|
|
465
|
-
|
|
466
|
-
return {}
|
|
467
|
-
|
|
477
|
+
return {};
|
|
468
478
|
})()
|
|
469
|
-
])
|
|
470
|
-
|
|
479
|
+
]);
|
|
471
480
|
if (!participant) {
|
|
472
|
-
const participantsList =
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
481
|
+
const participantsList = [];
|
|
482
|
+
if (isStatus) {
|
|
483
|
+
if (statusJidList?.length)
|
|
484
|
+
participantsList.push(...statusJidList);
|
|
476
485
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
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;
|
|
482
492
|
}
|
|
493
|
+
// default to lid addressing mode in a group
|
|
494
|
+
additionalAttributes = {
|
|
495
|
+
...additionalAttributes,
|
|
496
|
+
addressing_mode: groupAddressingMode
|
|
497
|
+
};
|
|
483
498
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
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
|
+
};
|
|
487
507
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
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;
|
|
492
515
|
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({
|
|
493
516
|
group: destinationJid,
|
|
494
517
|
data: bytes,
|
|
495
|
-
meId
|
|
496
|
-
})
|
|
497
|
-
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
//
|
|
506
|
-
|
|
518
|
+
meId: groupSenderIdentity
|
|
519
|
+
});
|
|
520
|
+
const senderKeyRecipients = [];
|
|
521
|
+
for (const device of devices) {
|
|
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;
|
|
507
532
|
}
|
|
508
533
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
// if there are, we re-send the senderkey
|
|
512
|
-
if (senderKeyJids.length) {
|
|
513
|
-
logger.debug({ senderKeyJids }, 'sending new sender key')
|
|
534
|
+
if (senderKeyRecipients.length) {
|
|
535
|
+
logger.debug({ senderKeyJids: senderKeyRecipients }, 'sending new sender key');
|
|
514
536
|
const senderKeyMsg = {
|
|
515
537
|
senderKeyDistributionMessage: {
|
|
516
538
|
axolotlSenderKeyDistributionMessage: senderKeyDistributionMessage,
|
|
517
539
|
groupId: destinationJid
|
|
518
540
|
}
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
await assertSessions(
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity
|
|
526
|
-
|
|
527
|
-
participants.push(...result.nodes)
|
|
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);
|
|
528
547
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
message = message.protocolMessage.editedMessage
|
|
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
|
+
});
|
|
544
562
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
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 } });
|
|
550
570
|
}
|
|
551
|
-
|
|
552
|
-
const patched = await patchMessageBeforeSending(message, [])
|
|
553
|
-
const bytes = Utils_1.encodeNewsletterMessage(patched)
|
|
554
|
-
|
|
555
|
-
binaryNodeContent.push({
|
|
556
|
-
tag: 'plaintext',
|
|
557
|
-
attrs: extraAttrs ? extraAttrs : {},
|
|
558
|
-
content: bytes
|
|
559
|
-
})
|
|
560
571
|
}
|
|
561
|
-
|
|
562
572
|
else {
|
|
563
|
-
|
|
564
|
-
|
|
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);
|
|
565
584
|
if (!participant) {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
585
|
+
const targetUserServer = isLid ? 'lid' : 's.whatsapp.net';
|
|
586
|
+
devices.push({
|
|
587
|
+
user,
|
|
588
|
+
device: 0,
|
|
589
|
+
jid: jidEncode(user, targetUserServer, 0) // rajeh, todo: this entire logic is convoluted and weird.
|
|
590
|
+
});
|
|
591
|
+
if (user !== ownUser) {
|
|
592
|
+
const ownUserServer = isLid ? 'lid' : 's.whatsapp.net';
|
|
593
|
+
const ownUserForAddressing = isLid && meLid ? jidDecode(meLid).user : jidDecode(meId).user;
|
|
594
|
+
devices.push({
|
|
595
|
+
user: ownUserForAddressing,
|
|
596
|
+
device: 0,
|
|
597
|
+
jid: jidEncode(ownUserForAddressing, ownUserServer, 0)
|
|
598
|
+
});
|
|
569
599
|
}
|
|
570
|
-
|
|
571
600
|
if (additionalAttributes?.['category'] !== 'peer') {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
601
|
+
// Clear placeholders and enumerate actual devices
|
|
602
|
+
devices.length = 0;
|
|
603
|
+
// Use conversation-appropriate sender identity
|
|
604
|
+
const senderIdentity = isLid && meLid
|
|
605
|
+
? jidEncode(jidDecode(meLid)?.user, 'lid', undefined)
|
|
606
|
+
: jidEncode(jidDecode(meId)?.user, 's.whatsapp.net', undefined);
|
|
607
|
+
// Enumerate devices for sender and target with consistent addressing
|
|
608
|
+
const sessionDevices = await getUSyncDevices([senderIdentity, jid], true, false);
|
|
609
|
+
devices.push(...sessionDevices);
|
|
610
|
+
logger.debug({
|
|
611
|
+
deviceCount: devices.length,
|
|
612
|
+
devices: devices.map(d => `${d.user}:${d.device}@${jidDecode(d.jid)?.server}`)
|
|
613
|
+
}, 'Device enumeration complete with unified addressing');
|
|
575
614
|
}
|
|
576
615
|
}
|
|
577
|
-
|
|
578
|
-
const
|
|
579
|
-
const
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
for (const { user,
|
|
583
|
-
const
|
|
584
|
-
|
|
585
|
-
|
|
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);
|
|
623
|
+
if (isExactSenderDevice) {
|
|
624
|
+
logger.debug({ jid, meId, meLid }, 'Skipping exact sender device (whatsmeow pattern)');
|
|
625
|
+
continue;
|
|
626
|
+
}
|
|
627
|
+
// Check if this is our device (could match either PN or LID user)
|
|
628
|
+
const isMe = user === mePnUser || user === meLidUser;
|
|
586
629
|
if (isMe) {
|
|
587
|
-
|
|
630
|
+
meRecipients.push(jid);
|
|
588
631
|
}
|
|
589
|
-
|
|
590
632
|
else {
|
|
591
|
-
|
|
633
|
+
otherRecipients.push(jid);
|
|
592
634
|
}
|
|
593
|
-
|
|
594
|
-
allJids.push(jid)
|
|
635
|
+
allRecipients.push(jid);
|
|
595
636
|
}
|
|
596
|
-
|
|
597
|
-
await assertSessions(allJids, false)
|
|
598
|
-
|
|
637
|
+
await assertSessions(allRecipients);
|
|
599
638
|
const [{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 }, { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }] = await Promise.all([
|
|
600
|
-
|
|
601
|
-
createParticipantNodes(
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
participants.push(...meNodes)
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
639
|
+
// For own devices: use DSM if available (1:1 chats only)
|
|
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]);
|
|
647
|
+
}
|
|
648
|
+
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2;
|
|
609
649
|
}
|
|
610
|
-
|
|
611
650
|
if (participants.length) {
|
|
612
651
|
if (additionalAttributes?.['category'] === 'peer') {
|
|
613
|
-
const peerNode = participants[0]?.content?.[0]
|
|
614
|
-
|
|
652
|
+
const peerNode = participants[0]?.content?.[0];
|
|
615
653
|
if (peerNode) {
|
|
616
|
-
binaryNodeContent.push(peerNode) // push only enc
|
|
654
|
+
binaryNodeContent.push(peerNode); // push only enc
|
|
617
655
|
}
|
|
618
656
|
}
|
|
619
|
-
|
|
620
657
|
else {
|
|
621
658
|
binaryNodeContent.push({
|
|
622
659
|
tag: 'participants',
|
|
623
660
|
attrs: {},
|
|
624
661
|
content: participants
|
|
625
|
-
})
|
|
662
|
+
});
|
|
626
663
|
}
|
|
627
664
|
}
|
|
628
|
-
|
|
629
665
|
const stanza = {
|
|
630
666
|
tag: 'message',
|
|
631
667
|
attrs: {
|
|
632
668
|
id: msgId,
|
|
633
|
-
|
|
669
|
+
to: destinationJid,
|
|
670
|
+
type: getMessageType(message),
|
|
634
671
|
...(additionalAttributes || {})
|
|
635
672
|
},
|
|
636
673
|
content: binaryNodeContent
|
|
637
|
-
}
|
|
638
|
-
|
|
674
|
+
};
|
|
639
675
|
// if the participant to send to is explicitly specified (generally retry recp)
|
|
640
676
|
// ensure the message is only sent to that person
|
|
641
677
|
// if a retry receipt is sent to everyone -- it'll fail decryption for everyone else who received the msg
|
|
642
678
|
if (participant) {
|
|
643
|
-
if (
|
|
644
|
-
stanza.attrs.to = destinationJid
|
|
645
|
-
stanza.attrs.participant = participant.jid
|
|
679
|
+
if (isJidGroup(destinationJid)) {
|
|
680
|
+
stanza.attrs.to = destinationJid;
|
|
681
|
+
stanza.attrs.participant = participant.jid;
|
|
646
682
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
stanza.attrs.
|
|
650
|
-
stanza.attrs.recipient = destinationJid
|
|
683
|
+
else if (areJidsSameUser(participant.jid, meId)) {
|
|
684
|
+
stanza.attrs.to = participant.jid;
|
|
685
|
+
stanza.attrs.recipient = destinationJid;
|
|
651
686
|
}
|
|
652
|
-
|
|
653
687
|
else {
|
|
654
|
-
stanza.attrs.to = participant.jid
|
|
688
|
+
stanza.attrs.to = participant.jid;
|
|
655
689
|
}
|
|
656
690
|
}
|
|
657
|
-
|
|
658
691
|
else {
|
|
659
|
-
stanza.attrs.to = destinationJid
|
|
692
|
+
stanza.attrs.to = destinationJid;
|
|
660
693
|
}
|
|
661
|
-
|
|
662
694
|
if (shouldIncludeDeviceIdentity) {
|
|
695
|
+
;
|
|
663
696
|
stanza.content.push({
|
|
664
697
|
tag: 'device-identity',
|
|
665
698
|
attrs: {},
|
|
666
|
-
content:
|
|
667
|
-
})
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
} : isNewsletter ? {
|
|
685
|
-
polltype: 'creation',
|
|
686
|
-
contenttype: pollMessage?.pollContentType === 2 ? 'image' : 'text'
|
|
687
|
-
} : {
|
|
688
|
-
polltype: 'creation'
|
|
689
|
-
}
|
|
690
|
-
})
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
if (!isNewsletter && buttonType) {
|
|
694
|
-
const buttonsNode = getButtonArgs(messages)
|
|
695
|
-
const filteredButtons = WABinary_1.getBinaryFilteredButtons(additionalNodes ? additionalNodes : [])
|
|
696
|
-
|
|
697
|
-
if (filteredButtons) {
|
|
698
|
-
stanza.content.push(...additionalNodes)
|
|
699
|
-
didPushAdditional = true
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
else {
|
|
703
|
-
stanza.content.push(buttonsNode)
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
if (AI && isPrivate) {
|
|
708
|
-
const botNode = {
|
|
709
|
-
tag: 'bot',
|
|
710
|
-
attrs: {
|
|
711
|
-
biz_bot: '1'
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
const filteredBizBot = WABinary_1.getBinaryFilteredBizBot(additionalNodes ? additionalNodes : [])
|
|
716
|
-
|
|
717
|
-
if (filteredBizBot) {
|
|
718
|
-
stanza.content.push(...additionalNodes)
|
|
719
|
-
didPushAdditional = true
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
else {
|
|
723
|
-
stanza.content.push(botNode)
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
if (!didPushAdditional && additionalNodes && additionalNodes.length > 0) {
|
|
728
|
-
stanza.content.push(...additionalNodes)
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
logger.debug({ msgId }, `sending message to ${participants.length} devices`)
|
|
732
|
-
|
|
733
|
-
await sendNode(stanza)
|
|
734
|
-
})
|
|
735
|
-
|
|
736
|
-
return msgId
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
const getTypeMessage = (msg) => {
|
|
740
|
-
const message = Utils_1.normalizeMessageContent(msg)
|
|
699
|
+
content: encodeSignedDeviceIdentity(authState.creds.account, true)
|
|
700
|
+
});
|
|
701
|
+
logger.debug({ jid }, 'adding device identity');
|
|
702
|
+
}
|
|
703
|
+
if (additionalNodes && additionalNodes.length > 0) {
|
|
704
|
+
;
|
|
705
|
+
stanza.content.push(...additionalNodes);
|
|
706
|
+
}
|
|
707
|
+
logger.debug({ msgId }, `sending message to ${participants.length} devices`);
|
|
708
|
+
await sendNode(stanza);
|
|
709
|
+
// Add message to retry cache if enabled
|
|
710
|
+
if (messageRetryManager && !participant) {
|
|
711
|
+
messageRetryManager.addRecentMessage(destinationJid, msgId, message);
|
|
712
|
+
}
|
|
713
|
+
}, meId);
|
|
714
|
+
return msgId;
|
|
715
|
+
};
|
|
716
|
+
const getMessageType = (message) => {
|
|
741
717
|
if (message.pollCreationMessage || message.pollCreationMessageV2 || message.pollCreationMessageV3) {
|
|
742
|
-
return 'poll'
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
return '
|
|
746
|
-
}
|
|
747
|
-
else if (message.eventMessage) {
|
|
748
|
-
return 'event'
|
|
749
|
-
}
|
|
750
|
-
else if (getMediaType(message)) {
|
|
751
|
-
return 'media'
|
|
752
|
-
}
|
|
753
|
-
else {
|
|
754
|
-
return 'text'
|
|
718
|
+
return 'poll';
|
|
719
|
+
}
|
|
720
|
+
if (message.eventMessage) {
|
|
721
|
+
return 'event';
|
|
755
722
|
}
|
|
756
|
-
|
|
757
|
-
|
|
723
|
+
if (getMediaType(message) !== '') {
|
|
724
|
+
return 'media';
|
|
725
|
+
}
|
|
726
|
+
return 'text';
|
|
727
|
+
};
|
|
758
728
|
const getMediaType = (message) => {
|
|
759
729
|
if (message.imageMessage) {
|
|
760
|
-
return 'image'
|
|
761
|
-
}
|
|
762
|
-
else if (message.stickerMessage) {
|
|
763
|
-
return message.stickerMessage.isLottie ? '1p_sticker' : message.stickerMessage.isAvatar ? 'avatar_sticker' : 'sticker'
|
|
730
|
+
return 'image';
|
|
764
731
|
}
|
|
765
732
|
else if (message.videoMessage) {
|
|
766
|
-
return message.videoMessage.gifPlayback ? 'gif' : 'video'
|
|
733
|
+
return message.videoMessage.gifPlayback ? 'gif' : 'video';
|
|
767
734
|
}
|
|
768
735
|
else if (message.audioMessage) {
|
|
769
|
-
return message.audioMessage.ptt ? 'ptt' : 'audio'
|
|
770
|
-
}
|
|
771
|
-
else if (message.ptvMessage) {
|
|
772
|
-
return 'ptv'
|
|
736
|
+
return message.audioMessage.ptt ? 'ptt' : 'audio';
|
|
773
737
|
}
|
|
774
738
|
else if (message.contactMessage) {
|
|
775
|
-
return 'vcard'
|
|
739
|
+
return 'vcard';
|
|
776
740
|
}
|
|
777
741
|
else if (message.documentMessage) {
|
|
778
|
-
return 'document'
|
|
779
|
-
}
|
|
780
|
-
else if (message.stickerPackMessage) {
|
|
781
|
-
return 'sticker_pack'
|
|
742
|
+
return 'document';
|
|
782
743
|
}
|
|
783
744
|
else if (message.contactsArrayMessage) {
|
|
784
|
-
return 'contact_array'
|
|
785
|
-
}
|
|
786
|
-
else if (message.locationMessage) {
|
|
787
|
-
return 'location'
|
|
745
|
+
return 'contact_array';
|
|
788
746
|
}
|
|
789
747
|
else if (message.liveLocationMessage) {
|
|
790
|
-
return 'livelocation'
|
|
748
|
+
return 'livelocation';
|
|
749
|
+
}
|
|
750
|
+
else if (message.stickerMessage) {
|
|
751
|
+
return 'sticker';
|
|
791
752
|
}
|
|
792
753
|
else if (message.listMessage) {
|
|
793
|
-
return 'list'
|
|
754
|
+
return 'list';
|
|
794
755
|
}
|
|
795
756
|
else if (message.listResponseMessage) {
|
|
796
|
-
return 'list_response'
|
|
757
|
+
return 'list_response';
|
|
797
758
|
}
|
|
798
759
|
else if (message.buttonsResponseMessage) {
|
|
799
|
-
return 'buttons_response'
|
|
760
|
+
return 'buttons_response';
|
|
800
761
|
}
|
|
801
762
|
else if (message.orderMessage) {
|
|
802
|
-
return 'order'
|
|
763
|
+
return 'order';
|
|
803
764
|
}
|
|
804
765
|
else if (message.productMessage) {
|
|
805
|
-
return 'product'
|
|
766
|
+
return 'product';
|
|
806
767
|
}
|
|
807
768
|
else if (message.interactiveResponseMessage) {
|
|
808
|
-
return 'native_flow_response'
|
|
809
|
-
}
|
|
810
|
-
else if (/https:\/\/wa\.me\/c\/\d+/.test(message.extendedTextMessage?.text)) {
|
|
811
|
-
return 'cataloglink'
|
|
812
|
-
}
|
|
813
|
-
else if (/https:\/\/wa\.me\/p\/\d+\/\d+/.test(message.extendedTextMessage?.text)) {
|
|
814
|
-
return 'productlink'
|
|
815
|
-
}
|
|
816
|
-
else if (message.extendedTextMessage?.matchedText || message.groupInviteMessage) {
|
|
817
|
-
return 'url'
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
const getButtonType = (message) => {
|
|
822
|
-
if (message.listMessage) {
|
|
823
|
-
return 'list'
|
|
824
|
-
}
|
|
825
|
-
else if (message.buttonsMessage) {
|
|
826
|
-
return 'buttons'
|
|
769
|
+
return 'native_flow_response';
|
|
827
770
|
}
|
|
828
|
-
else if(message.
|
|
829
|
-
return '
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
const getButtonArgs = (message) => {
|
|
834
|
-
const nativeFlow = message.interactiveMessage?.nativeFlowMessage
|
|
835
|
-
const firstButtonName = nativeFlow?.buttons?.[0]?.name
|
|
836
|
-
const nativeFlowSpecials = [
|
|
837
|
-
'mpm', 'cta_catalog', 'send_location',
|
|
838
|
-
'call_permission_request', 'wa_payment_transaction_details',
|
|
839
|
-
'automated_greeting_message_view_catalog'
|
|
840
|
-
]
|
|
841
|
-
|
|
842
|
-
if (nativeFlow && (firstButtonName === 'review_and_pay' || firstButtonName === 'payment_info')) {
|
|
843
|
-
return {
|
|
844
|
-
tag: 'biz',
|
|
845
|
-
attrs: {
|
|
846
|
-
native_flow_name: firstButtonName === 'review_and_pay' ? 'order_details' : firstButtonName
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
} else if (nativeFlow && nativeFlowSpecials.includes(firstButtonName)) {
|
|
850
|
-
// Only works for WhatsApp Original, not WhatsApp Business
|
|
851
|
-
return {
|
|
852
|
-
tag: 'biz',
|
|
853
|
-
attrs: {},
|
|
854
|
-
content: [{
|
|
855
|
-
tag: 'interactive',
|
|
856
|
-
attrs: {
|
|
857
|
-
type: 'native_flow',
|
|
858
|
-
v: '1'
|
|
859
|
-
},
|
|
860
|
-
content: [{
|
|
861
|
-
tag: 'native_flow',
|
|
862
|
-
attrs: {
|
|
863
|
-
v: '2',
|
|
864
|
-
name: firstButtonName
|
|
865
|
-
}
|
|
866
|
-
}]
|
|
867
|
-
}]
|
|
868
|
-
}
|
|
869
|
-
} else if (nativeFlow || message.buttonsMessage) {
|
|
870
|
-
// It works for whatsapp original and whatsapp business
|
|
871
|
-
return {
|
|
872
|
-
tag: 'biz',
|
|
873
|
-
attrs: {},
|
|
874
|
-
content: [{
|
|
875
|
-
tag: 'interactive',
|
|
876
|
-
attrs: {
|
|
877
|
-
type: 'native_flow',
|
|
878
|
-
v: '1'
|
|
879
|
-
},
|
|
880
|
-
content: [{
|
|
881
|
-
tag: 'native_flow',
|
|
882
|
-
attrs: {
|
|
883
|
-
v: '9',
|
|
884
|
-
name: 'mixed'
|
|
885
|
-
}
|
|
886
|
-
}]
|
|
887
|
-
}]
|
|
888
|
-
}
|
|
889
|
-
} else if (message.listMessage) {
|
|
890
|
-
return {
|
|
891
|
-
tag: 'biz',
|
|
892
|
-
attrs: {},
|
|
893
|
-
content: [{
|
|
894
|
-
tag: 'list',
|
|
895
|
-
attrs: {
|
|
896
|
-
v: '2',
|
|
897
|
-
type: 'product_list'
|
|
898
|
-
}
|
|
899
|
-
}]
|
|
900
|
-
}
|
|
901
|
-
} else {
|
|
902
|
-
return {
|
|
903
|
-
tag: 'biz',
|
|
904
|
-
attrs: {}
|
|
905
|
-
}
|
|
771
|
+
else if (message.groupInviteMessage) {
|
|
772
|
+
return 'url';
|
|
906
773
|
}
|
|
907
|
-
|
|
908
|
-
|
|
774
|
+
return '';
|
|
775
|
+
};
|
|
909
776
|
const getPrivacyTokens = async (jids) => {
|
|
910
|
-
const t =
|
|
911
|
-
|
|
777
|
+
const t = unixTimestampSeconds().toString();
|
|
912
778
|
const result = await query({
|
|
913
779
|
tag: 'iq',
|
|
914
780
|
attrs: {
|
|
915
|
-
to:
|
|
781
|
+
to: S_WHATSAPP_NET,
|
|
916
782
|
type: 'set',
|
|
917
783
|
xmlns: 'privacy'
|
|
918
784
|
},
|
|
@@ -923,372 +789,165 @@ const makeMessagesSocket = (config) => {
|
|
|
923
789
|
content: jids.map(jid => ({
|
|
924
790
|
tag: 'token',
|
|
925
791
|
attrs: {
|
|
926
|
-
jid:
|
|
792
|
+
jid: jidNormalizedUser(jid),
|
|
927
793
|
t,
|
|
928
794
|
type: 'trusted_contact'
|
|
929
795
|
}
|
|
930
796
|
}))
|
|
931
797
|
}
|
|
932
798
|
]
|
|
933
|
-
})
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
const getEphemeralGroup = (jid) => {
|
|
939
|
-
if (!WABinary_1.isJidGroup(jid)) throw new TypeError("Jid should originate from a group!")
|
|
940
|
-
|
|
941
|
-
return groupQuery(jid, 'get', [{
|
|
942
|
-
tag: 'query',
|
|
943
|
-
attrs: {
|
|
944
|
-
request: 'interactive'
|
|
945
|
-
}
|
|
946
|
-
}])
|
|
947
|
-
.then((groups) => WABinary_1.getBinaryNodeChild(groups, 'group'))
|
|
948
|
-
.then((metadata) => WABinary_1.getBinaryNodeChild(metadata, 'ephemeral')?.attrs?.expiration || 0)
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
const waUploadToServer = Utils_1.getWAUploadToServer(config, refreshMediaConn)
|
|
952
|
-
|
|
953
|
-
const waitForMsgMediaUpdate = Utils_1.bindWaitForEvent(ev, 'messages.media-update')
|
|
954
|
-
|
|
799
|
+
});
|
|
800
|
+
return result;
|
|
801
|
+
};
|
|
802
|
+
const waUploadToServer = getWAUploadToServer(config, refreshMediaConn);
|
|
803
|
+
const waitForMsgMediaUpdate = bindWaitForEvent(ev, 'messages.media-update');
|
|
955
804
|
return {
|
|
956
|
-
...
|
|
805
|
+
...sock,
|
|
957
806
|
getPrivacyTokens,
|
|
958
807
|
assertSessions,
|
|
959
808
|
relayMessage,
|
|
960
809
|
sendReceipt,
|
|
961
810
|
sendReceipts,
|
|
962
811
|
readMessages,
|
|
963
|
-
profilePictureUrl,
|
|
964
|
-
getUSyncDevices,
|
|
965
812
|
refreshMediaConn,
|
|
966
813
|
waUploadToServer,
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
createParticipantNodes,
|
|
970
|
-
|
|
814
|
+
fetchPrivacySettings,
|
|
815
|
+
sendPeerDataOperationMessage,
|
|
816
|
+
createParticipantNodes,
|
|
817
|
+
getUSyncDevices,
|
|
818
|
+
messageRetryManager,
|
|
971
819
|
updateMediaMessage: async (message) => {
|
|
972
|
-
const content =
|
|
973
|
-
const mediaKey = content.mediaKey
|
|
974
|
-
const meId = authState.creds.me.id
|
|
975
|
-
const node = await
|
|
976
|
-
let error = undefined
|
|
977
|
-
|
|
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;
|
|
978
825
|
await Promise.all([
|
|
979
826
|
sendNode(node),
|
|
980
827
|
waitForMsgMediaUpdate(async (update) => {
|
|
981
|
-
const result = update.find(c => c.key.id === message.key.id)
|
|
828
|
+
const result = update.find(c => c.key.id === message.key.id);
|
|
982
829
|
if (result) {
|
|
983
830
|
if (result.error) {
|
|
984
|
-
error = result.error
|
|
831
|
+
error = result.error;
|
|
985
832
|
}
|
|
986
|
-
|
|
987
833
|
else {
|
|
988
834
|
try {
|
|
989
|
-
const media = await
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
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
|
+
});
|
|
995
842
|
}
|
|
996
|
-
|
|
997
|
-
content.
|
|
998
|
-
|
|
999
|
-
content.url = Utils_1.getUrlFromDirectPath(content.directPath)
|
|
1000
|
-
|
|
1001
|
-
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');
|
|
1002
846
|
}
|
|
1003
|
-
|
|
1004
847
|
catch (err) {
|
|
1005
|
-
error = err
|
|
848
|
+
error = err;
|
|
1006
849
|
}
|
|
1007
850
|
}
|
|
1008
|
-
|
|
1009
|
-
return true
|
|
851
|
+
return true;
|
|
1010
852
|
}
|
|
1011
853
|
})
|
|
1012
|
-
])
|
|
1013
|
-
|
|
854
|
+
]);
|
|
1014
855
|
if (error) {
|
|
1015
|
-
throw error
|
|
856
|
+
throw error;
|
|
1016
857
|
}
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
{ key: message.key, update: { message: message.message } }
|
|
1020
|
-
])
|
|
1021
|
-
|
|
1022
|
-
return message
|
|
1023
|
-
},
|
|
1024
|
-
sendStatusMentions: async (content, jids = []) => {
|
|
1025
|
-
const userJid = WABinary_1.jidNormalizedUser(authState.creds.me.id)
|
|
1026
|
-
let allUsers = new Set()
|
|
1027
|
-
allUsers.add(userJid)
|
|
1028
|
-
|
|
1029
|
-
for (const id of jids) {
|
|
1030
|
-
const isGroup = WABinary_1.isJidGroup(id)
|
|
1031
|
-
const isPrivate = WABinary_1.isJidUser(id)
|
|
1032
|
-
|
|
1033
|
-
if (isGroup) {
|
|
1034
|
-
try {
|
|
1035
|
-
const metadata = await cachedGroupMetadata(id) || await groupMetadata(id)
|
|
1036
|
-
const participants = metadata.participants.map(p => WABinary_1.jidNormalizedUser(p.id))
|
|
1037
|
-
participants.forEach(jid => allUsers.add(jid))
|
|
1038
|
-
} catch (error) {
|
|
1039
|
-
logger.error(`Error getting metadata for group ${id}: ${error}`)
|
|
1040
|
-
}
|
|
1041
|
-
} else if (isPrivate) {
|
|
1042
|
-
allUsers.add(WABinary_1.jidNormalizedUser(id))
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
const uniqueUsers = Array.from(allUsers)
|
|
1047
|
-
const getRandomHexColor = () => "#" + Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0")
|
|
1048
|
-
|
|
1049
|
-
const isMedia = content.image || content.video || content.audio
|
|
1050
|
-
const isAudio = !!content.audio
|
|
1051
|
-
|
|
1052
|
-
const messageContent = { ...content }
|
|
1053
|
-
|
|
1054
|
-
if (isMedia && !isAudio) {
|
|
1055
|
-
if (messageContent.text) {
|
|
1056
|
-
messageContent.caption = messageContent.text
|
|
1057
|
-
|
|
1058
|
-
delete messageContent.text
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
delete messageContent.ptt
|
|
1062
|
-
delete messageContent.font
|
|
1063
|
-
delete messageContent.backgroundColor
|
|
1064
|
-
delete messageContent.textColor
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
|
-
if (isAudio) {
|
|
1068
|
-
delete messageContent.text
|
|
1069
|
-
delete messageContent.caption
|
|
1070
|
-
delete messageContent.font
|
|
1071
|
-
delete messageContent.textColor
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
const font = !isMedia ? (content.font || Math.floor(Math.random() * 9)) : undefined
|
|
1075
|
-
const textColor = !isMedia ? (content.textColor || getRandomHexColor()) : undefined
|
|
1076
|
-
const backgroundColor = (!isMedia || isAudio) ? (content.backgroundColor || getRandomHexColor()) : undefined
|
|
1077
|
-
const ptt = isAudio ? (typeof content.ptt === 'boolean' ? content.ptt : true) : undefined
|
|
1078
|
-
|
|
1079
|
-
let msg
|
|
1080
|
-
let mediaHandle
|
|
1081
|
-
try {
|
|
1082
|
-
msg = await Utils_1.generateWAMessage(WABinary_1.STORIES_JID, messageContent, {
|
|
1083
|
-
logger,
|
|
1084
|
-
userJid,
|
|
1085
|
-
getUrlInfo: text => link_preview_1.getUrlInfo(text, {
|
|
1086
|
-
thumbnailWidth: linkPreviewImageThumbnailWidth,
|
|
1087
|
-
fetchOpts: { timeout: 3000, ...axiosOptions || {} },
|
|
1088
|
-
logger,
|
|
1089
|
-
uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
|
|
1090
|
-
}),
|
|
1091
|
-
upload: async (encFilePath, opts) => {
|
|
1092
|
-
const up = await waUploadToServer(encFilePath, { ...opts })
|
|
1093
|
-
mediaHandle = up.handle
|
|
1094
|
-
return up
|
|
1095
|
-
},
|
|
1096
|
-
mediaCache: config.mediaCache,
|
|
1097
|
-
options: config.options,
|
|
1098
|
-
font,
|
|
1099
|
-
textColor,
|
|
1100
|
-
backgroundColor,
|
|
1101
|
-
ptt
|
|
1102
|
-
})
|
|
1103
|
-
} catch (error) {
|
|
1104
|
-
logger.error(`Error generating message: ${error}`)
|
|
1105
|
-
throw error
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
await relayMessage(WABinary_1.STORIES_JID, msg.message, {
|
|
1109
|
-
messageId: msg.key.id,
|
|
1110
|
-
statusJidList: uniqueUsers,
|
|
1111
|
-
additionalNodes: [
|
|
1112
|
-
{
|
|
1113
|
-
tag: 'meta',
|
|
1114
|
-
attrs: {},
|
|
1115
|
-
content: [
|
|
1116
|
-
{
|
|
1117
|
-
tag: 'mentioned_users',
|
|
1118
|
-
attrs: {},
|
|
1119
|
-
content: jids.map(jid => ({
|
|
1120
|
-
tag: 'to',
|
|
1121
|
-
attrs: { jid: WABinary_1.jidNormalizedUser(jid) }
|
|
1122
|
-
}))
|
|
1123
|
-
}]
|
|
1124
|
-
}]
|
|
1125
|
-
})
|
|
1126
|
-
|
|
1127
|
-
for (const id of jids) {
|
|
1128
|
-
try {
|
|
1129
|
-
const normalizedId = WABinary_1.jidNormalizedUser(id)
|
|
1130
|
-
const isPrivate = WABinary_1.isJidUser(normalizedId)
|
|
1131
|
-
const type = isPrivate ? 'statusMentionMessage' : 'groupStatusMentionMessage'
|
|
1132
|
-
|
|
1133
|
-
const protocolMessage = {
|
|
1134
|
-
[type]: {
|
|
1135
|
-
message: {
|
|
1136
|
-
protocolMessage: {
|
|
1137
|
-
key: msg.key,
|
|
1138
|
-
type: 25
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
},
|
|
1142
|
-
messageContextInfo: {
|
|
1143
|
-
messageSecret: crypto_1.randomBytes(32)
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
const statusMsg = await Utils_1.generateWAMessageFromContent(normalizedId,
|
|
1148
|
-
protocolMessage,
|
|
1149
|
-
{}
|
|
1150
|
-
)
|
|
1151
|
-
|
|
1152
|
-
await relayMessage(
|
|
1153
|
-
normalizedId,
|
|
1154
|
-
statusMsg.message,
|
|
1155
|
-
{
|
|
1156
|
-
additionalNodes: [{
|
|
1157
|
-
tag: 'meta',
|
|
1158
|
-
attrs: isPrivate ?
|
|
1159
|
-
{ is_status_mention: 'true' } :
|
|
1160
|
-
{ is_group_status_mention: 'true' }
|
|
1161
|
-
}]
|
|
1162
|
-
}
|
|
1163
|
-
)
|
|
1164
|
-
|
|
1165
|
-
await Utils_1.delay(2000)
|
|
1166
|
-
} catch (error) {
|
|
1167
|
-
logger.error(`Error sending to ${id}: ${error}`)
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
return msg
|
|
858
|
+
ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]);
|
|
859
|
+
return message;
|
|
1172
860
|
},
|
|
1173
861
|
sendMessage: async (jid, content, options = {}) => {
|
|
1174
|
-
const userJid = authState.creds.me.id
|
|
1175
|
-
const additionalAttributes = {}
|
|
1176
|
-
|
|
1177
|
-
if (!options.ephemeralExpiration) {
|
|
1178
|
-
if (WABinary_1.isJidGroup(jid)) {
|
|
1179
|
-
const expiration = await getEphemeralGroup(jid)
|
|
1180
|
-
options.ephemeralExpiration = expiration
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
|
|
862
|
+
const userJid = authState.creds.me.id;
|
|
1184
863
|
if (typeof content === 'object' &&
|
|
1185
864
|
'disappearingMessagesInChat' in content &&
|
|
1186
865
|
typeof content['disappearingMessagesInChat'] !== 'undefined' &&
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
const
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
disappearingMessagesInChat
|
|
1194
|
-
|
|
1195
|
-
await groupToggleEphemeral(jid, value)
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
else if (typeof content === 'object' && 'album' in content && content.album) {
|
|
1199
|
-
const albumMsg = await Utils_1.prepareAlbumMessageContent(jid, content.album, {
|
|
1200
|
-
baron: {
|
|
1201
|
-
relayMessage,
|
|
1202
|
-
waUploadToServer
|
|
1203
|
-
},
|
|
1204
|
-
userJid: userJid,
|
|
1205
|
-
...options
|
|
1206
|
-
})
|
|
1207
|
-
|
|
1208
|
-
for (const media of albumMsg) {
|
|
1209
|
-
await Utils_1.delay(options.delay || 500)
|
|
1210
|
-
await relayMessage(jid, media.message, { messageId: media.key.id, useCachedGroupMetadata: options.useCachedGroupMetadata, additionalAttributes, statusJidList: options.statusJidList, additionalNodes: options.additionalNodes, AI: options.ai })
|
|
1211
|
-
}
|
|
1212
|
-
|
|
1213
|
-
return albumMsg
|
|
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);
|
|
1214
874
|
}
|
|
1215
|
-
|
|
1216
875
|
else {
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
const fullMsg = await Utils_1.generateWAMessage(jid, content, {
|
|
876
|
+
const fullMsg = await generateWAMessage(jid, content, {
|
|
1220
877
|
logger,
|
|
1221
878
|
userJid,
|
|
1222
|
-
getUrlInfo: text =>
|
|
879
|
+
getUrlInfo: text => getUrlInfo(text, {
|
|
1223
880
|
thumbnailWidth: linkPreviewImageThumbnailWidth,
|
|
1224
881
|
fetchOpts: {
|
|
1225
882
|
timeout: 3000,
|
|
1226
|
-
...
|
|
883
|
+
...(httpRequestOptions || {})
|
|
1227
884
|
},
|
|
1228
885
|
logger,
|
|
1229
|
-
uploadImage: generateHighQualityLinkPreview
|
|
1230
|
-
? waUploadToServer
|
|
1231
|
-
: undefined
|
|
886
|
+
uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
|
|
1232
887
|
}),
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
mediaHandle = up.handle
|
|
1238
|
-
return up
|
|
1239
|
-
},
|
|
888
|
+
//TODO: CACHE
|
|
889
|
+
getProfilePicUrl: sock.profilePictureUrl,
|
|
890
|
+
getCallLink: sock.createCallLink,
|
|
891
|
+
upload: waUploadToServer,
|
|
1240
892
|
mediaCache: config.mediaCache,
|
|
1241
893
|
options: config.options,
|
|
1242
|
-
messageId:
|
|
1243
|
-
...options
|
|
1244
|
-
})
|
|
1245
|
-
|
|
1246
|
-
const
|
|
1247
|
-
const
|
|
1248
|
-
const
|
|
1249
|
-
const
|
|
1250
|
-
|
|
1251
|
-
|
|
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) {
|
|
1252
906
|
// if the chat is a group, and I am not the author, then delete the message as an admin
|
|
1253
|
-
if (
|
|
1254
|
-
additionalAttributes.edit = '8'
|
|
907
|
+
if (isJidGroup(content.delete?.remoteJid) && !content.delete?.fromMe) {
|
|
908
|
+
additionalAttributes.edit = '8';
|
|
1255
909
|
}
|
|
1256
|
-
|
|
1257
910
|
else {
|
|
1258
|
-
additionalAttributes.edit = '7'
|
|
911
|
+
additionalAttributes.edit = '7';
|
|
1259
912
|
}
|
|
1260
913
|
}
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
additionalAttributes.edit = WABinary_1.isJidNewsletter(jid) ? '3' : '1'
|
|
914
|
+
else if (isEditMsg) {
|
|
915
|
+
additionalAttributes.edit = '1';
|
|
1264
916
|
}
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
additionalAttributes.edit = '2'
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
if (mediaHandle) {
|
|
1271
|
-
additionalAttributes['media_id'] = mediaHandle
|
|
917
|
+
else if (isPinMsg) {
|
|
918
|
+
additionalAttributes.edit = '2';
|
|
1272
919
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
920
|
+
else if (isPollMessage) {
|
|
921
|
+
additionalNodes.push({
|
|
922
|
+
tag: 'meta',
|
|
923
|
+
attrs: {
|
|
924
|
+
polltype: 'creation'
|
|
925
|
+
}
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
else if (isEventMsg) {
|
|
929
|
+
additionalNodes.push({
|
|
930
|
+
tag: 'meta',
|
|
931
|
+
attrs: {
|
|
932
|
+
event_type: 'creation'
|
|
933
|
+
}
|
|
934
|
+
});
|
|
1276
935
|
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
936
|
+
await relayMessage(jid, fullMsg.message, {
|
|
937
|
+
messageId: fullMsg.key.id,
|
|
938
|
+
useCachedGroupMetadata: options.useCachedGroupMetadata,
|
|
939
|
+
additionalAttributes,
|
|
940
|
+
statusJidList: options.statusJidList,
|
|
941
|
+
additionalNodes
|
|
942
|
+
});
|
|
1280
943
|
if (config.emitOwnEvents) {
|
|
1281
944
|
process.nextTick(() => {
|
|
1282
|
-
processingMutex.mutex(() =>
|
|
1283
|
-
})
|
|
945
|
+
processingMutex.mutex(() => upsertMessage(fullMsg, 'append'));
|
|
946
|
+
});
|
|
1284
947
|
}
|
|
1285
|
-
|
|
1286
|
-
return fullMsg
|
|
948
|
+
return fullMsg;
|
|
1287
949
|
}
|
|
1288
950
|
}
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
module.exports = {
|
|
1293
|
-
makeMessagesSocket
|
|
1294
|
-
}
|
|
951
|
+
};
|
|
952
|
+
};
|
|
953
|
+
//# sourceMappingURL=messages-send.js.map
|