@awangxcode/qiro-baileys 0.0.0-stage → 7.0.0-rc16
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 -0
- package/QIRO-BAILEYS-RC16.md +25 -0
- package/README.md +1337 -2
- package/THIRD_PARTY_NOTICES.md +15 -0
- package/WAProto/GenerateStatics.sh +3 -0
- package/WAProto/WAProto.proto +5479 -0
- package/WAProto/fix-imports.js +85 -0
- package/WAProto/index.d.ts +14017 -0
- package/WAProto/index.js +97691 -0
- package/engine-requirements.js +10 -0
- package/lib/Defaults/index.d.ts +75 -0
- package/lib/Defaults/index.d.ts.map +1 -0
- package/lib/Defaults/index.js +129 -0
- package/lib/Defaults/index.js.map +1 -0
- package/lib/MessageBuilder/index.d.ts +206 -0
- package/lib/MessageBuilder/index.d.ts.map +1 -0
- package/lib/MessageBuilder/index.js +673 -0
- package/lib/MessageBuilder/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/Group/sender-message-key.js +26 -0
- package/lib/Signal/Group/sender-message-key.js.map +1 -0
- package/lib/Signal/libsignal.d.ts +5 -0
- package/lib/Signal/libsignal.d.ts.map +1 -0
- package/lib/Signal/libsignal.js +431 -0
- 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 +277 -0
- package/lib/Signal/lid-mapping.js.map +1 -0
- package/lib/Socket/Client/index.d.ts +3 -0
- package/lib/Socket/Client/index.d.ts.map +1 -0
- package/lib/Socket/Client/index.js +3 -0
- package/lib/Socket/Client/index.js.map +1 -0
- package/lib/Socket/Client/types.d.ts +16 -0
- package/lib/Socket/Client/types.d.ts.map +1 -0
- package/lib/Socket/Client/types.js +11 -0
- package/lib/Socket/Client/types.js.map +1 -0
- package/lib/Socket/Client/websocket.d.ts +13 -0
- package/lib/Socket/Client/websocket.d.ts.map +1 -0
- package/lib/Socket/Client/websocket.js +54 -0
- package/lib/Socket/Client/websocket.js.map +1 -0
- package/lib/Socket/business.d.ts +217 -0
- package/lib/Socket/business.d.ts.map +1 -0
- package/lib/Socket/business.js +379 -0
- package/lib/Socket/business.js.map +1 -0
- package/lib/Socket/chats.d.ts +125 -0
- package/lib/Socket/chats.d.ts.map +1 -0
- package/lib/Socket/chats.js +1198 -0
- package/lib/Socket/chats.js.map +1 -0
- package/lib/Socket/communities.d.ts +273 -0
- package/lib/Socket/communities.d.ts.map +1 -0
- package/lib/Socket/communities.js +431 -0
- package/lib/Socket/communities.js.map +1 -0
- package/lib/Socket/groups.d.ts +161 -0
- package/lib/Socket/groups.d.ts.map +1 -0
- package/lib/Socket/groups.js +347 -0
- package/lib/Socket/groups.js.map +1 -0
- package/lib/Socket/index.d.ts +260 -0
- package/lib/Socket/index.d.ts.map +1 -0
- package/lib/Socket/index.js +12 -0
- package/lib/Socket/index.js.map +1 -0
- package/lib/Socket/messages-recv.d.ts +203 -0
- package/lib/Socket/messages-recv.d.ts.map +1 -0
- package/lib/Socket/messages-recv.js +1772 -0
- package/lib/Socket/messages-recv.js.map +1 -0
- package/lib/Socket/messages-send.d.ts +199 -0
- package/lib/Socket/messages-send.d.ts.map +1 -0
- package/lib/Socket/messages-send.js +1145 -0
- package/lib/Socket/messages-send.js.map +1 -0
- package/lib/Socket/mex.d.ts +3 -0
- package/lib/Socket/mex.d.ts.map +1 -0
- package/lib/Socket/mex.js +42 -0
- package/lib/Socket/mex.js.map +1 -0
- package/lib/Socket/newsletter.d.ts +170 -0
- package/lib/Socket/newsletter.d.ts.map +1 -0
- package/lib/Socket/newsletter.js +181 -0
- package/lib/Socket/newsletter.js.map +1 -0
- package/lib/Socket/socket.d.ts +59 -0
- package/lib/Socket/socket.d.ts.map +1 -0
- package/lib/Socket/socket.js +1010 -0
- package/lib/Socket/socket.js.map +1 -0
- package/lib/Types/Auth.d.ts +117 -0
- package/lib/Types/Auth.d.ts.map +1 -0
- package/lib/Types/Auth.js +2 -0
- 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 +15 -0
- package/lib/Types/Call.d.ts.map +1 -0
- package/lib/Types/Call.js +2 -0
- package/lib/Types/Call.js.map +1 -0
- package/lib/Types/Chat.d.ts +124 -0
- package/lib/Types/Chat.d.ts.map +1 -0
- package/lib/Types/Chat.js +8 -0
- package/lib/Types/Chat.js.map +1 -0
- package/lib/Types/Contact.d.ts +26 -0
- package/lib/Types/Contact.d.ts.map +1 -0
- package/lib/Types/Contact.js +2 -0
- package/lib/Types/Contact.js.map +1 -0
- package/lib/Types/Events.d.ts +256 -0
- package/lib/Types/Events.d.ts.map +1 -0
- package/lib/Types/Events.js +2 -0
- package/lib/Types/Events.js.map +1 -0
- package/lib/Types/GroupMetadata.d.ts +71 -0
- package/lib/Types/GroupMetadata.d.ts.map +1 -0
- package/lib/Types/GroupMetadata.js +2 -0
- package/lib/Types/GroupMetadata.js.map +1 -0
- package/lib/Types/Label.d.ts +47 -0
- package/lib/Types/Label.d.ts.map +1 -0
- package/lib/Types/Label.js +25 -0
- package/lib/Types/Label.js.map +1 -0
- package/lib/Types/LabelAssociation.d.ts +30 -0
- package/lib/Types/LabelAssociation.d.ts.map +1 -0
- package/lib/Types/LabelAssociation.js +7 -0
- package/lib/Types/LabelAssociation.js.map +1 -0
- package/lib/Types/Message.d.ts +320 -0
- package/lib/Types/Message.d.ts.map +1 -0
- package/lib/Types/Message.js +11 -0
- package/lib/Types/Message.js.map +1 -0
- package/lib/Types/Mex.d.ts +141 -0
- package/lib/Types/Mex.d.ts.map +1 -0
- package/lib/Types/Mex.js +37 -0
- package/lib/Types/Mex.js.map +1 -0
- package/lib/Types/Product.d.ts +79 -0
- package/lib/Types/Product.d.ts.map +1 -0
- package/lib/Types/Product.js +2 -0
- package/lib/Types/Product.js.map +1 -0
- package/lib/Types/Signal.d.ts +87 -0
- package/lib/Types/Signal.d.ts.map +1 -0
- package/lib/Types/Signal.js +2 -0
- package/lib/Types/Signal.js.map +1 -0
- package/lib/Types/Socket.d.ts +136 -0
- package/lib/Types/Socket.d.ts.map +1 -0
- package/lib/Types/Socket.js +3 -0
- package/lib/Types/Socket.js.map +1 -0
- package/lib/Types/State.d.ts +97 -0
- package/lib/Types/State.d.ts.map +1 -0
- package/lib/Types/State.js +56 -0
- package/lib/Types/State.js.map +1 -0
- package/lib/Types/USync.d.ts +26 -0
- package/lib/Types/USync.d.ts.map +1 -0
- package/lib/Types/USync.js +2 -0
- package/lib/Types/USync.js.map +1 -0
- package/lib/Types/index.d.ts +66 -0
- package/lib/Types/index.d.ts.map +1 -0
- package/lib/Types/index.js +26 -0
- package/lib/Types/index.js.map +1 -0
- package/lib/Utils/auth-utils.d.ts +24 -0
- package/lib/Utils/auth-utils.d.ts.map +1 -0
- package/lib/Utils/auth-utils.js +302 -0
- package/lib/Utils/auth-utils.js.map +1 -0
- package/lib/Utils/browser-utils.d.ts +4 -0
- package/lib/Utils/browser-utils.d.ts.map +1 -0
- package/lib/Utils/browser-utils.js +29 -0
- package/lib/Utils/browser-utils.js.map +1 -0
- package/lib/Utils/business.d.ts +23 -0
- package/lib/Utils/business.d.ts.map +1 -0
- package/lib/Utils/business.js +231 -0
- package/lib/Utils/business.js.map +1 -0
- package/lib/Utils/chat-utils.d.ts +100 -0
- package/lib/Utils/chat-utils.d.ts.map +1 -0
- package/lib/Utils/chat-utils.js +872 -0
- package/lib/Utils/chat-utils.js.map +1 -0
- package/lib/Utils/companion-reg-client-utils.d.ts +50 -0
- package/lib/Utils/companion-reg-client-utils.d.ts.map +1 -0
- package/lib/Utils/companion-reg-client-utils.js +90 -0
- package/lib/Utils/companion-reg-client-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +37 -0
- package/lib/Utils/crypto.d.ts.map +1 -0
- package/lib/Utils/crypto.js +118 -0
- package/lib/Utils/crypto.js.map +1 -0
- package/lib/Utils/decode-wa-message.d.ts +66 -0
- package/lib/Utils/decode-wa-message.d.ts.map +1 -0
- package/lib/Utils/decode-wa-message.js +317 -0
- package/lib/Utils/decode-wa-message.js.map +1 -0
- package/lib/Utils/event-buffer.d.ts +36 -0
- package/lib/Utils/event-buffer.d.ts.map +1 -0
- package/lib/Utils/event-buffer.js +622 -0
- package/lib/Utils/event-buffer.js.map +1 -0
- package/lib/Utils/generics.d.ts +92 -0
- package/lib/Utils/generics.d.ts.map +1 -0
- package/lib/Utils/generics.js +393 -0
- package/lib/Utils/generics.js.map +1 -0
- package/lib/Utils/history.d.ts +24 -0
- package/lib/Utils/history.d.ts.map +1 -0
- package/lib/Utils/history.js +134 -0
- package/lib/Utils/history.js.map +1 -0
- package/lib/Utils/identity-change-handler.d.ts +44 -0
- package/lib/Utils/identity-change-handler.d.ts.map +1 -0
- package/lib/Utils/identity-change-handler.js +50 -0
- package/lib/Utils/identity-change-handler.js.map +1 -0
- package/lib/Utils/index.d.ts +22 -0
- package/lib/Utils/index.d.ts.map +1 -0
- package/lib/Utils/index.js +22 -0
- package/lib/Utils/index.js.map +1 -0
- package/lib/Utils/link-preview.d.ts +21 -0
- package/lib/Utils/link-preview.d.ts.map +1 -0
- package/lib/Utils/link-preview.js +85 -0
- package/lib/Utils/link-preview.js.map +1 -0
- package/lib/Utils/logger.d.ts +12 -0
- package/lib/Utils/logger.d.ts.map +1 -0
- package/lib/Utils/logger.js +3 -0
- package/lib/Utils/logger.js.map +1 -0
- package/lib/Utils/lt-hash.d.ts +8 -0
- package/lib/Utils/lt-hash.d.ts.map +1 -0
- package/lib/Utils/lt-hash.js +8 -0
- package/lib/Utils/lt-hash.js.map +1 -0
- package/lib/Utils/make-mutex.d.ts +9 -0
- package/lib/Utils/make-mutex.d.ts.map +1 -0
- package/lib/Utils/make-mutex.js +33 -0
- package/lib/Utils/make-mutex.js.map +1 -0
- package/lib/Utils/message-retry-manager.d.ts +115 -0
- package/lib/Utils/message-retry-manager.d.ts.map +1 -0
- package/lib/Utils/message-retry-manager.js +265 -0
- package/lib/Utils/message-retry-manager.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +133 -0
- package/lib/Utils/messages-media.d.ts.map +1 -0
- package/lib/Utils/messages-media.js +788 -0
- package/lib/Utils/messages-media.js.map +1 -0
- package/lib/Utils/messages.d.ts +91 -0
- package/lib/Utils/messages.d.ts.map +1 -0
- package/lib/Utils/messages.js +893 -0
- package/lib/Utils/messages.js.map +1 -0
- package/lib/Utils/noise-handler.d.ts +20 -0
- package/lib/Utils/noise-handler.d.ts.map +1 -0
- package/lib/Utils/noise-handler.js +201 -0
- package/lib/Utils/noise-handler.js.map +1 -0
- package/lib/Utils/offline-node-processor.d.ts +17 -0
- package/lib/Utils/offline-node-processor.d.ts.map +1 -0
- package/lib/Utils/offline-node-processor.js +40 -0
- package/lib/Utils/offline-node-processor.js.map +1 -0
- package/lib/Utils/pre-key-manager.d.ts +28 -0
- package/lib/Utils/pre-key-manager.d.ts.map +1 -0
- package/lib/Utils/pre-key-manager.js +106 -0
- package/lib/Utils/pre-key-manager.js.map +1 -0
- package/lib/Utils/process-message.d.ts +60 -0
- package/lib/Utils/process-message.d.ts.map +1 -0
- package/lib/Utils/process-message.js +630 -0
- package/lib/Utils/process-message.js.map +1 -0
- package/lib/Utils/reporting-utils.d.ts +11 -0
- package/lib/Utils/reporting-utils.d.ts.map +1 -0
- package/lib/Utils/reporting-utils.js +258 -0
- package/lib/Utils/reporting-utils.js.map +1 -0
- package/lib/Utils/signal.d.ts +47 -0
- package/lib/Utils/signal.d.ts.map +1 -0
- package/lib/Utils/signal.js +201 -0
- package/lib/Utils/signal.js.map +1 -0
- package/lib/Utils/stanza-ack.d.ts +11 -0
- package/lib/Utils/stanza-ack.d.ts.map +1 -0
- package/lib/Utils/stanza-ack.js +38 -0
- package/lib/Utils/stanza-ack.js.map +1 -0
- package/lib/Utils/sync-action-utils.d.ts +19 -0
- package/lib/Utils/sync-action-utils.d.ts.map +1 -0
- package/lib/Utils/sync-action-utils.js +49 -0
- package/lib/Utils/sync-action-utils.js.map +1 -0
- package/lib/Utils/tc-token-utils.d.ts +37 -0
- package/lib/Utils/tc-token-utils.d.ts.map +1 -0
- package/lib/Utils/tc-token-utils.js +164 -0
- package/lib/Utils/tc-token-utils.js.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts +13 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +121 -0
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -0
- package/lib/Utils/validate-connection.d.ts +11 -0
- package/lib/Utils/validate-connection.d.ts.map +1 -0
- package/lib/Utils/validate-connection.js +210 -0
- package/lib/Utils/validate-connection.js.map +1 -0
- package/lib/WABinary/constants.d.ts +28 -0
- package/lib/WABinary/constants.d.ts.map +1 -0
- package/lib/WABinary/constants.js +1301 -0
- package/lib/WABinary/constants.js.map +1 -0
- package/lib/WABinary/decode.d.ts +7 -0
- package/lib/WABinary/decode.d.ts.map +1 -0
- package/lib/WABinary/decode.js +262 -0
- package/lib/WABinary/decode.js.map +1 -0
- package/lib/WABinary/encode.d.ts +3 -0
- package/lib/WABinary/encode.d.ts.map +1 -0
- package/lib/WABinary/encode.js +220 -0
- package/lib/WABinary/encode.js.map +1 -0
- package/lib/WABinary/generic-utils.d.ts +15 -0
- package/lib/WABinary/generic-utils.d.ts.map +1 -0
- package/lib/WABinary/generic-utils.js +113 -0
- package/lib/WABinary/generic-utils.js.map +1 -0
- package/lib/WABinary/index.d.ts +6 -0
- package/lib/WABinary/index.d.ts.map +1 -0
- package/lib/WABinary/index.js +6 -0
- package/lib/WABinary/index.js.map +1 -0
- package/lib/WABinary/jid-utils.d.ts +48 -0
- package/lib/WABinary/jid-utils.d.ts.map +1 -0
- package/lib/WABinary/jid-utils.js +96 -0
- package/lib/WABinary/jid-utils.js.map +1 -0
- package/lib/WABinary/types.d.ts +19 -0
- package/lib/WABinary/types.d.ts.map +1 -0
- package/lib/WABinary/types.js +2 -0
- package/lib/WABinary/types.js.map +1 -0
- package/lib/WAM/BinaryInfo.d.ts +9 -0
- package/lib/WAM/BinaryInfo.d.ts.map +1 -0
- package/lib/WAM/BinaryInfo.js +10 -0
- package/lib/WAM/BinaryInfo.js.map +1 -0
- package/lib/WAM/constants.d.ts +40 -0
- package/lib/WAM/constants.d.ts.map +1 -0
- package/lib/WAM/constants.js +22853 -0
- package/lib/WAM/constants.js.map +1 -0
- package/lib/WAM/encode.d.ts +3 -0
- package/lib/WAM/encode.d.ts.map +1 -0
- package/lib/WAM/encode.js +150 -0
- package/lib/WAM/encode.js.map +1 -0
- package/lib/WAM/index.d.ts +4 -0
- package/lib/WAM/index.d.ts.map +1 -0
- package/lib/WAM/index.js +4 -0
- package/lib/WAM/index.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +52 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +23 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +54 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +13 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +13 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +38 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +26 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +51 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/index.d.ts +6 -0
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/index.js +6 -0
- package/lib/WAUSync/Protocols/index.js.map +1 -0
- package/lib/WAUSync/USyncQuery.d.ts +30 -0
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
- package/lib/WAUSync/USyncQuery.js +98 -0
- package/lib/WAUSync/USyncQuery.js.map +1 -0
- package/lib/WAUSync/USyncUser.d.ts +17 -0
- package/lib/WAUSync/USyncUser.d.ts.map +1 -0
- package/lib/WAUSync/USyncUser.js +31 -0
- package/lib/WAUSync/USyncUser.js.map +1 -0
- package/lib/WAUSync/index.d.ts +4 -0
- package/lib/WAUSync/index.d.ts.map +1 -0
- package/lib/WAUSync/index.js +4 -0
- package/lib/WAUSync/index.js.map +1 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +12 -0
- package/lib/index.js.map +1 -0
- package/package.json +137 -4
|
@@ -0,0 +1,673 @@
|
|
|
1
|
+
import { generateMessageID } from '../Utils/generics.js';
|
|
2
|
+
import { proto } from '../../WAProto/index.js';
|
|
3
|
+
const COMMON_NATIVE_FLOW_BUTTONS = new Set([
|
|
4
|
+
'quick_reply',
|
|
5
|
+
'cta_url',
|
|
6
|
+
'cta_call',
|
|
7
|
+
'cta_copy',
|
|
8
|
+
'cta_catalog',
|
|
9
|
+
'catalog_message',
|
|
10
|
+
'galaxy_message',
|
|
11
|
+
'order_status',
|
|
12
|
+
'payment_reminder',
|
|
13
|
+
'booking_confirmation',
|
|
14
|
+
'payment_request',
|
|
15
|
+
'api_signup',
|
|
16
|
+
'inapp_signup',
|
|
17
|
+
'cta_app',
|
|
18
|
+
'form_message'
|
|
19
|
+
]);
|
|
20
|
+
const ANDROID_ONLY_NATIVE_FLOW_BUTTONS = new Set([
|
|
21
|
+
'single_select',
|
|
22
|
+
'send_location',
|
|
23
|
+
'address_message',
|
|
24
|
+
'cta_reminder',
|
|
25
|
+
'cta_cancel_reminder'
|
|
26
|
+
]);
|
|
27
|
+
const isQuickReply = (button) => button.name === 'quick_reply';
|
|
28
|
+
/** Runtime guard for values supplied by JavaScript callers or untyped input. */
|
|
29
|
+
const isPlainRecord = (value) => {
|
|
30
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
31
|
+
return false;
|
|
32
|
+
const prototype = Object.getPrototypeOf(value);
|
|
33
|
+
return prototype === Object.prototype || prototype === null;
|
|
34
|
+
};
|
|
35
|
+
const hasTextParam = (button, name) => {
|
|
36
|
+
const value = button.params[name];
|
|
37
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
38
|
+
};
|
|
39
|
+
const validateButtonParams = (button, index) => {
|
|
40
|
+
const errors = [];
|
|
41
|
+
const requiredByType = {
|
|
42
|
+
quick_reply: ['display_text', 'id'],
|
|
43
|
+
cta_url: ['display_text', 'url'],
|
|
44
|
+
cta_call: ['display_text', 'phone_number'],
|
|
45
|
+
cta_copy: ['display_text', 'copy_code'],
|
|
46
|
+
cta_catalog: ['display_text'],
|
|
47
|
+
catalog_message: ['display_text'],
|
|
48
|
+
single_select: ['title', 'sections']
|
|
49
|
+
};
|
|
50
|
+
for (const key of requiredByType[button.name] ?? []) {
|
|
51
|
+
if (key === 'sections') {
|
|
52
|
+
const sections = button.params.sections;
|
|
53
|
+
if (!Array.isArray(sections) || sections.length === 0) {
|
|
54
|
+
errors.push(`Button ${index + 1} (${button.name}) must include a non-empty sections array`);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
sections.forEach((section, sectionIndex) => {
|
|
58
|
+
if (!isPlainRecord(section)) {
|
|
59
|
+
errors.push('Button ' + (index + 1) + ' section ' + (sectionIndex + 1) + ' must be an object');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (typeof section.title !== 'string' || !section.title.trim()) {
|
|
63
|
+
errors.push('Button ' + (index + 1) + ' section ' + (sectionIndex + 1) + ' needs a title');
|
|
64
|
+
}
|
|
65
|
+
const rows = section.rows;
|
|
66
|
+
if (!Array.isArray(rows) || rows.length === 0) {
|
|
67
|
+
errors.push('Button ' + (index + 1) + ' section ' + (sectionIndex + 1) + ' must contain at least one row');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
rows.forEach((row, rowIndex) => {
|
|
71
|
+
if (!isPlainRecord(row)) {
|
|
72
|
+
errors.push('Button ' + (index + 1) + ' section ' + (sectionIndex + 1) + ' row ' + (rowIndex + 1) + ' must be an object');
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (typeof row.title !== 'string' || !row.title.trim()) {
|
|
76
|
+
errors.push('Button ' + (index + 1) + ' section ' + (sectionIndex + 1) + ' row ' + (rowIndex + 1) + ' needs a title');
|
|
77
|
+
}
|
|
78
|
+
if (typeof row.id !== 'string' || !row.id.trim()) {
|
|
79
|
+
errors.push('Button ' + (index + 1) + ' section ' + (sectionIndex + 1) + ' row ' + (rowIndex + 1) + ' needs an id');
|
|
80
|
+
}
|
|
81
|
+
for (const field of ['header', 'description']) {
|
|
82
|
+
if (row[field] !== undefined && typeof row[field] !== 'string') {
|
|
83
|
+
errors.push('Button ' + (index + 1) + ' section ' + (sectionIndex + 1) + ' row ' + (rowIndex + 1) + ' ' + field + ' must be a string');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else if (!hasTextParam(button, key)) {
|
|
91
|
+
errors.push(`Button ${index + 1} (${button.name}) requires a non-empty ${key}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (button.name === 'cta_url' && hasTextParam(button, 'url')) {
|
|
95
|
+
try {
|
|
96
|
+
const url = new URL(button.params.url);
|
|
97
|
+
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password) {
|
|
98
|
+
errors.push(`Button ${index + 1} has an unsafe URL; use http(s) without embedded credentials`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
errors.push(`Button ${index + 1} has an invalid URL`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (button.name === 'cta_call' && hasTextParam(button, 'phone_number')) {
|
|
106
|
+
if (!/^\+?[1-9]\d{6,14}$/.test(button.params.phone_number)) {
|
|
107
|
+
errors.push(`Button ${index + 1} phone_number must be an international number with 7–15 digits`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return errors;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Validate native-flow button combinations against the currently documented WA Web/iOS
|
|
114
|
+
* constraints. This is a client-compatibility check, not a guarantee that WhatsApp will
|
|
115
|
+
* render a server-side or account-gated feature.
|
|
116
|
+
*/
|
|
117
|
+
export const checkNativeFlowButtons = (buttons, platform = 'web', options = {}) => {
|
|
118
|
+
const errors = [];
|
|
119
|
+
if (!Array.isArray(buttons)) {
|
|
120
|
+
return { ok: false, platform, maxButtons: 0, errors: ['buttons must be an array'] };
|
|
121
|
+
}
|
|
122
|
+
if (!['web', 'ios', 'android'].includes(platform)) {
|
|
123
|
+
errors.push('platform must be one of: web, ios, android');
|
|
124
|
+
}
|
|
125
|
+
const first = buttons[0];
|
|
126
|
+
const firstIsQuickReply = isPlainRecord(first) && first.name === 'quick_reply';
|
|
127
|
+
const maxButtons = firstIsQuickReply ? 10 : 3;
|
|
128
|
+
const allowExperimental = isPlainRecord(options) && options.allowExperimentalNativeFlowTypes === true;
|
|
129
|
+
if (!buttons.length)
|
|
130
|
+
errors.push('At least one native-flow button is required');
|
|
131
|
+
if (buttons.length > maxButtons) {
|
|
132
|
+
errors.push((firstIsQuickReply ? 'quick_reply' : 'non-quick-reply') + ' messages support at most ' + maxButtons + ' buttons');
|
|
133
|
+
}
|
|
134
|
+
for (const [index, input] of buttons.entries()) {
|
|
135
|
+
if (!isPlainRecord(input)) {
|
|
136
|
+
errors.push('Button ' + (index + 1) + ' must be an object');
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const name = input.name;
|
|
140
|
+
if (typeof name !== 'string' || !name.trim()) {
|
|
141
|
+
errors.push('Button ' + (index + 1) + ' has an empty or invalid name');
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const params = input.params;
|
|
145
|
+
if (!isPlainRecord(params)) {
|
|
146
|
+
errors.push('Button ' + (index + 1) + ' (' + name + ') params must be a plain object');
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const button = { name, params };
|
|
150
|
+
const known = COMMON_NATIVE_FLOW_BUTTONS.has(button.name) || ANDROID_ONLY_NATIVE_FLOW_BUTTONS.has(button.name);
|
|
151
|
+
if (!known && !allowExperimental) {
|
|
152
|
+
errors.push('Button ' + (index + 1) + ' uses an unknown native-flow type: ' + button.name);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (known)
|
|
156
|
+
errors.push(...validateButtonParams(button, index));
|
|
157
|
+
if (platform !== 'android' && ANDROID_ONLY_NATIVE_FLOW_BUTTONS.has(button.name)) {
|
|
158
|
+
errors.push(button.name + ' is documented as Android-only and is not portable to ' + platform);
|
|
159
|
+
}
|
|
160
|
+
if (index > 0 && firstIsQuickReply !== isQuickReply(button)) {
|
|
161
|
+
errors.push('quick_reply buttons cannot be mixed with other native-flow button types');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return { ok: errors.length === 0, platform, maxButtons, errors };
|
|
165
|
+
};
|
|
166
|
+
export const isWebSupportedNativeFlowButton = (name) => COMMON_NATIVE_FLOW_BUTTONS.has(name);
|
|
167
|
+
const createNativeFlowMetadataNode = () => ({
|
|
168
|
+
tag: 'biz',
|
|
169
|
+
attrs: {
|
|
170
|
+
actual_actors: '2',
|
|
171
|
+
host_storage: '2',
|
|
172
|
+
privacy_mode_ts: String(Date.now())
|
|
173
|
+
},
|
|
174
|
+
content: [
|
|
175
|
+
{
|
|
176
|
+
tag: 'interactive',
|
|
177
|
+
attrs: { type: 'native_flow', v: '1' },
|
|
178
|
+
content: [{ tag: 'native_flow', attrs: { v: '9', name: 'mixed' } }]
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
});
|
|
182
|
+
const ensureText = (value, field) => {
|
|
183
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
184
|
+
throw new TypeError(field + ' must be a non-empty string');
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const serializeButton = (button) => {
|
|
188
|
+
let buttonParamsJson;
|
|
189
|
+
try {
|
|
190
|
+
buttonParamsJson = JSON.stringify(button.params);
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
throw new TypeError('Button ' + button.name + ' params must be JSON-serializable');
|
|
194
|
+
}
|
|
195
|
+
if (typeof buttonParamsJson !== 'string') {
|
|
196
|
+
throw new TypeError('Button ' + button.name + ' params must be JSON-serializable');
|
|
197
|
+
}
|
|
198
|
+
return { name: button.name, buttonParamsJson };
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Native-flow button builder integrated into Qiro Baileys. It intentionally builds only
|
|
202
|
+
* protocol payloads that are represented by the bundled WAProto types; it does not try
|
|
203
|
+
* to bypass device or server-side feature gates.
|
|
204
|
+
*/
|
|
205
|
+
export class Button {
|
|
206
|
+
constructor(socket) {
|
|
207
|
+
this.titleText = '';
|
|
208
|
+
this.subtitleText = '';
|
|
209
|
+
this.body = '';
|
|
210
|
+
this.footerText = '';
|
|
211
|
+
this.buttons = [];
|
|
212
|
+
this.socket = socket;
|
|
213
|
+
}
|
|
214
|
+
setTitle(value) {
|
|
215
|
+
this.titleText = value;
|
|
216
|
+
return this;
|
|
217
|
+
}
|
|
218
|
+
title(value) {
|
|
219
|
+
return this.setTitle(value);
|
|
220
|
+
}
|
|
221
|
+
/** Fluent alias compatible with common MessageBuilder APIs. */
|
|
222
|
+
header(value) {
|
|
223
|
+
return this.setTitle(value);
|
|
224
|
+
}
|
|
225
|
+
setSubtitle(value) {
|
|
226
|
+
this.subtitleText = value;
|
|
227
|
+
return this;
|
|
228
|
+
}
|
|
229
|
+
subtitle(value) {
|
|
230
|
+
return this.setSubtitle(value);
|
|
231
|
+
}
|
|
232
|
+
setBody(value) {
|
|
233
|
+
this.body = value;
|
|
234
|
+
return this;
|
|
235
|
+
}
|
|
236
|
+
/** Fluent alias compatible with common MessageBuilder APIs. */
|
|
237
|
+
text(value) {
|
|
238
|
+
return this.setBody(value);
|
|
239
|
+
}
|
|
240
|
+
setFooter(value) {
|
|
241
|
+
this.footerText = value;
|
|
242
|
+
return this;
|
|
243
|
+
}
|
|
244
|
+
footer(value) {
|
|
245
|
+
return this.setFooter(value);
|
|
246
|
+
}
|
|
247
|
+
/** Set an already-prepared protobuf header; media upload is intentionally not hidden here. */
|
|
248
|
+
setHeader(value) {
|
|
249
|
+
this.headerPayload = structuredClone(value);
|
|
250
|
+
return this;
|
|
251
|
+
}
|
|
252
|
+
addReply(displayText, id) {
|
|
253
|
+
ensureText(displayText, 'displayText');
|
|
254
|
+
ensureText(id, 'id');
|
|
255
|
+
this.buttons.push({ name: 'quick_reply', params: { display_text: displayText, id } });
|
|
256
|
+
return this;
|
|
257
|
+
}
|
|
258
|
+
/** Fluent alias for addReply(). */
|
|
259
|
+
button(displayText, id) {
|
|
260
|
+
return this.addReply(displayText, id);
|
|
261
|
+
}
|
|
262
|
+
addUrl(displayText, url) {
|
|
263
|
+
ensureText(displayText, 'displayText');
|
|
264
|
+
let parsed;
|
|
265
|
+
try {
|
|
266
|
+
parsed = new URL(url);
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
throw new TypeError('Button URL must be an absolute URL using http or https');
|
|
270
|
+
}
|
|
271
|
+
if ((parsed.protocol !== 'https:' && parsed.protocol !== 'http:') ||
|
|
272
|
+
parsed.username.length > 0 ||
|
|
273
|
+
parsed.password.length > 0) {
|
|
274
|
+
throw new TypeError('Button URL must use http or https and must not include embedded credentials');
|
|
275
|
+
}
|
|
276
|
+
const safeUrl = parsed.toString();
|
|
277
|
+
this.buttons.push({
|
|
278
|
+
name: 'cta_url',
|
|
279
|
+
params: { display_text: displayText, url: safeUrl, merchant_url: safeUrl }
|
|
280
|
+
});
|
|
281
|
+
return this;
|
|
282
|
+
}
|
|
283
|
+
addCopy(displayText, copyCode) {
|
|
284
|
+
ensureText(displayText, 'displayText');
|
|
285
|
+
ensureText(copyCode, 'copyCode');
|
|
286
|
+
this.buttons.push({ name: 'cta_copy', params: { display_text: displayText, copy_code: copyCode } });
|
|
287
|
+
return this;
|
|
288
|
+
}
|
|
289
|
+
addCall(displayText, phoneNumber) {
|
|
290
|
+
ensureText(displayText, 'displayText');
|
|
291
|
+
if (!/^\+?[1-9]\d{6,14}$/.test(phoneNumber)) {
|
|
292
|
+
throw new TypeError('phoneNumber must be an international number with 7–15 digits');
|
|
293
|
+
}
|
|
294
|
+
this.buttons.push({ name: 'cta_call', params: { display_text: displayText, phone_number: phoneNumber } });
|
|
295
|
+
return this;
|
|
296
|
+
}
|
|
297
|
+
/** Escape hatch for documented native-flow types not covered by a convenience method. */
|
|
298
|
+
addNativeButton(name, params) {
|
|
299
|
+
ensureText(name, 'name');
|
|
300
|
+
if (!isPlainRecord(params)) {
|
|
301
|
+
throw new TypeError('params must be a plain object');
|
|
302
|
+
}
|
|
303
|
+
this.buttons.push({ name, params: structuredClone(params) });
|
|
304
|
+
return this;
|
|
305
|
+
}
|
|
306
|
+
addSelection(title) {
|
|
307
|
+
ensureText(title, 'title');
|
|
308
|
+
this.selection = { title, sections: [] };
|
|
309
|
+
this.currentSection = undefined;
|
|
310
|
+
return this;
|
|
311
|
+
}
|
|
312
|
+
makeSection(title) {
|
|
313
|
+
ensureText(title, 'title');
|
|
314
|
+
if (!this.selection)
|
|
315
|
+
throw new Error('Call addSelection(title) before makeSection(title)');
|
|
316
|
+
const section = { title, rows: [] };
|
|
317
|
+
this.selection.sections.push(section);
|
|
318
|
+
this.currentSection = section;
|
|
319
|
+
return this;
|
|
320
|
+
}
|
|
321
|
+
makeRow(header, title, description, id) {
|
|
322
|
+
if (!this.selection || !this.currentSection)
|
|
323
|
+
throw new Error('Call addSelection() and makeSection() before makeRow()');
|
|
324
|
+
ensureText(title, 'title');
|
|
325
|
+
ensureText(id, 'id');
|
|
326
|
+
this.currentSection.rows.push({ header: header || undefined, title, description: description || undefined, id });
|
|
327
|
+
return this;
|
|
328
|
+
}
|
|
329
|
+
getButtonInputs() {
|
|
330
|
+
const result = [...this.buttons];
|
|
331
|
+
if (this.selection) {
|
|
332
|
+
if (!this.selection.sections.length || this.selection.sections.some(section => !section.rows.length)) {
|
|
333
|
+
throw new TypeError('single_select needs at least one non-empty section');
|
|
334
|
+
}
|
|
335
|
+
result.push({
|
|
336
|
+
name: 'single_select',
|
|
337
|
+
params: { title: this.selection.title, sections: this.selection.sections }
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
return result;
|
|
341
|
+
}
|
|
342
|
+
build(options = {}) {
|
|
343
|
+
ensureText(this.body, 'body');
|
|
344
|
+
const buttons = this.getButtonInputs();
|
|
345
|
+
const validation = checkNativeFlowButtons(buttons, options.platform ?? 'web', {
|
|
346
|
+
allowExperimentalNativeFlowTypes: options.allowExperimentalNativeFlowTypes
|
|
347
|
+
});
|
|
348
|
+
if (!validation.ok)
|
|
349
|
+
throw new TypeError(`Invalid native-flow buttons: ${validation.errors.join('; ')}`);
|
|
350
|
+
const header = this.headerPayload ??
|
|
351
|
+
(this.titleText || this.subtitleText
|
|
352
|
+
? { title: this.titleText || undefined, subtitle: this.subtitleText || undefined }
|
|
353
|
+
: undefined);
|
|
354
|
+
return {
|
|
355
|
+
interactiveMessage: {
|
|
356
|
+
header,
|
|
357
|
+
body: { text: this.body },
|
|
358
|
+
footer: this.footerText ? { text: this.footerText } : undefined,
|
|
359
|
+
nativeFlowMessage: {
|
|
360
|
+
messageVersion: 1,
|
|
361
|
+
buttons: buttons.map(serializeButton)
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
toCard(options = {}) {
|
|
367
|
+
const message = this.build(options).interactiveMessage;
|
|
368
|
+
if (!message)
|
|
369
|
+
throw new Error('Failed to construct interactive card');
|
|
370
|
+
if (!message.header?.imageMessage && !message.header?.videoMessage) {
|
|
371
|
+
throw new TypeError('Carousel cards require a prepared imageMessage or videoMessage in the header');
|
|
372
|
+
}
|
|
373
|
+
return message;
|
|
374
|
+
}
|
|
375
|
+
async send(jid, options = {}) {
|
|
376
|
+
return this.socket.relayMessage(jid, this.build(options), {
|
|
377
|
+
messageId: options.messageId ?? generateMessageID(),
|
|
378
|
+
additionalNodes: [createNativeFlowMetadataNode()]
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/** ButtonV2 exposes a compact quick-reply API over the same validated native-flow format. */
|
|
383
|
+
export class ButtonV2 extends Button {
|
|
384
|
+
addButton(displayText, id) {
|
|
385
|
+
return this.addReply(displayText, id);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Carousel builder for already-prepared protobuf cards. Each card must include image or
|
|
390
|
+
* video media metadata; use the normal media preparation utilities before adding it.
|
|
391
|
+
*/
|
|
392
|
+
export class Carousel {
|
|
393
|
+
constructor(socket) {
|
|
394
|
+
this.body = '';
|
|
395
|
+
this.footerText = '';
|
|
396
|
+
this.cards = [];
|
|
397
|
+
this.socket = socket;
|
|
398
|
+
}
|
|
399
|
+
setBody(value) {
|
|
400
|
+
this.body = value;
|
|
401
|
+
return this;
|
|
402
|
+
}
|
|
403
|
+
text(value) {
|
|
404
|
+
return this.setBody(value);
|
|
405
|
+
}
|
|
406
|
+
setFooter(value) {
|
|
407
|
+
this.footerText = value;
|
|
408
|
+
return this;
|
|
409
|
+
}
|
|
410
|
+
footer(value) {
|
|
411
|
+
return this.setFooter(value);
|
|
412
|
+
}
|
|
413
|
+
addCard(card) {
|
|
414
|
+
const items = Array.isArray(card) ? card : [card];
|
|
415
|
+
const preparedCards = [];
|
|
416
|
+
// Validate the full batch before mutating state, so an invalid later card does not
|
|
417
|
+
// leave a partially-added carousel behind.
|
|
418
|
+
for (const item of items) {
|
|
419
|
+
if (!item || typeof item !== 'object') {
|
|
420
|
+
throw new TypeError('Every carousel card must be an interactive-message object');
|
|
421
|
+
}
|
|
422
|
+
if (!item.header?.imageMessage && !item.header?.videoMessage) {
|
|
423
|
+
throw new TypeError('Every carousel card must have a prepared imageMessage or videoMessage in its header');
|
|
424
|
+
}
|
|
425
|
+
if (typeof item.body?.text !== 'string' || !item.body.text.trim()) {
|
|
426
|
+
throw new TypeError('Every carousel card must have non-empty body text');
|
|
427
|
+
}
|
|
428
|
+
preparedCards.push(structuredClone(item));
|
|
429
|
+
}
|
|
430
|
+
this.cards.push(...preparedCards);
|
|
431
|
+
return this;
|
|
432
|
+
}
|
|
433
|
+
build() {
|
|
434
|
+
ensureText(this.body, 'body');
|
|
435
|
+
if (this.cards.length < 2)
|
|
436
|
+
throw new TypeError('Carousel needs at least two cards');
|
|
437
|
+
return {
|
|
438
|
+
interactiveMessage: {
|
|
439
|
+
body: { text: this.body },
|
|
440
|
+
footer: this.footerText ? { text: this.footerText } : undefined,
|
|
441
|
+
carouselMessage: {
|
|
442
|
+
messageVersion: 1,
|
|
443
|
+
carouselCardType: proto.Message.InteractiveMessage.CarouselMessage.CarouselCardType.HSCROLL_CARDS,
|
|
444
|
+
cards: this.cards
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
async send(jid, options = {}) {
|
|
450
|
+
return this.socket.relayMessage(jid, this.build(), {
|
|
451
|
+
messageId: options.messageId ?? generateMessageID(),
|
|
452
|
+
additionalNodes: [createNativeFlowMetadataNode()]
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
const parseHttpUrl = (value, field) => {
|
|
457
|
+
let parsed;
|
|
458
|
+
try {
|
|
459
|
+
parsed = new URL(value);
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
throw new TypeError(`${field} must be a valid absolute URL`);
|
|
463
|
+
}
|
|
464
|
+
if (!['http:', 'https:'].includes(parsed.protocol) || parsed.username || parsed.password) {
|
|
465
|
+
throw new TypeError(`${field} must use http(s) and must not include embedded credentials`);
|
|
466
|
+
}
|
|
467
|
+
return parsed;
|
|
468
|
+
};
|
|
469
|
+
/**
|
|
470
|
+
* Experimental builder for the AIRichResponse protobuf types already bundled in WAProto.
|
|
471
|
+
* This creates a validly-shaped payload only; WhatsApp may gate or change how these
|
|
472
|
+
* internal/experimental message types are rendered on different clients.
|
|
473
|
+
*/
|
|
474
|
+
export class AIRich {
|
|
475
|
+
constructor(socket) {
|
|
476
|
+
this.submessages = [];
|
|
477
|
+
this.sources = [];
|
|
478
|
+
this.socket = socket;
|
|
479
|
+
}
|
|
480
|
+
text(value) {
|
|
481
|
+
return this.addText(value);
|
|
482
|
+
}
|
|
483
|
+
addText(value) {
|
|
484
|
+
ensureText(value, 'text');
|
|
485
|
+
this.submessages.push({
|
|
486
|
+
messageType: proto.AIRichResponseSubMessageType.AI_RICH_RESPONSE_TEXT,
|
|
487
|
+
messageText: value
|
|
488
|
+
});
|
|
489
|
+
return this;
|
|
490
|
+
}
|
|
491
|
+
addCode(language, code) {
|
|
492
|
+
ensureText(language, 'language');
|
|
493
|
+
ensureText(code, 'code');
|
|
494
|
+
this.submessages.push({
|
|
495
|
+
messageType: proto.AIRichResponseSubMessageType.AI_RICH_RESPONSE_CODE,
|
|
496
|
+
codeMetadata: {
|
|
497
|
+
codeLanguage: language.trim(),
|
|
498
|
+
codeBlocks: [
|
|
499
|
+
{
|
|
500
|
+
highlightType: proto.AIRichResponseCodeMetadata.AIRichResponseCodeHighlightType.AI_RICH_RESPONSE_CODE_HIGHLIGHT_DEFAULT,
|
|
501
|
+
codeContent: code
|
|
502
|
+
}
|
|
503
|
+
]
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
return this;
|
|
507
|
+
}
|
|
508
|
+
addTable(rows, title) {
|
|
509
|
+
if (!Array.isArray(rows) || rows.length === 0)
|
|
510
|
+
throw new TypeError('rows must contain at least one row');
|
|
511
|
+
if (!rows.every(row => Array.isArray(row) && row.length > 0)) {
|
|
512
|
+
throw new TypeError('each table row must contain at least one cell');
|
|
513
|
+
}
|
|
514
|
+
const width = rows[0].length;
|
|
515
|
+
if (!rows.every(row => row.length === width))
|
|
516
|
+
throw new TypeError('all table rows must have the same number of cells');
|
|
517
|
+
this.submessages.push({
|
|
518
|
+
messageType: proto.AIRichResponseSubMessageType.AI_RICH_RESPONSE_TABLE,
|
|
519
|
+
tableMetadata: {
|
|
520
|
+
title,
|
|
521
|
+
rows: rows.map((items, index) => ({ items: items.map(String), isHeading: index === 0 }))
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
return this;
|
|
525
|
+
}
|
|
526
|
+
addLatex(expression, options = {}) {
|
|
527
|
+
ensureText(expression, 'expression');
|
|
528
|
+
const renderedImageUrl = options.renderedImageUrl;
|
|
529
|
+
if (renderedImageUrl)
|
|
530
|
+
parseHttpUrl(renderedImageUrl, 'renderedImageUrl');
|
|
531
|
+
for (const [name, value] of Object.entries({ width: options.width, height: options.height })) {
|
|
532
|
+
if (value !== undefined && (!Number.isFinite(value) || value <= 0)) {
|
|
533
|
+
throw new TypeError(`${name} must be a positive finite number`);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
this.submessages.push({
|
|
537
|
+
messageType: proto.AIRichResponseSubMessageType.AI_RICH_RESPONSE_LATEX,
|
|
538
|
+
latexMetadata: {
|
|
539
|
+
text: expression,
|
|
540
|
+
expressions: [
|
|
541
|
+
{
|
|
542
|
+
latexExpression: expression,
|
|
543
|
+
url: renderedImageUrl,
|
|
544
|
+
width: options.width,
|
|
545
|
+
height: options.height
|
|
546
|
+
}
|
|
547
|
+
]
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
return this;
|
|
551
|
+
}
|
|
552
|
+
addInlineImage(url, altText = '', alignment = proto.AIRichResponseInlineImageMetadata.AIRichResponseImageAlignment.AI_RICH_RESPONSE_IMAGE_LAYOUT_CENTER_ALIGNED, tapLinkUrl) {
|
|
553
|
+
const imageUrl = parseHttpUrl(url, 'url').toString();
|
|
554
|
+
if (tapLinkUrl)
|
|
555
|
+
parseHttpUrl(tapLinkUrl, 'tapLinkUrl');
|
|
556
|
+
this.submessages.push({
|
|
557
|
+
messageType: proto.AIRichResponseSubMessageType.AI_RICH_RESPONSE_INLINE_IMAGE,
|
|
558
|
+
imageMetadata: {
|
|
559
|
+
imageUrl: { imagePreviewUrl: imageUrl, imageHighResUrl: imageUrl, sourceUrl: imageUrl },
|
|
560
|
+
imageText: altText || undefined,
|
|
561
|
+
alignment,
|
|
562
|
+
tapLinkUrl
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
return this;
|
|
566
|
+
}
|
|
567
|
+
addMap(centerLatitude, centerLongitude, annotations) {
|
|
568
|
+
const validCoordinate = (latitude, longitude) => Number.isFinite(latitude) && Number.isFinite(longitude) && Math.abs(latitude) <= 90 && Math.abs(longitude) <= 180;
|
|
569
|
+
if (!validCoordinate(centerLatitude, centerLongitude))
|
|
570
|
+
throw new TypeError('map center coordinates are invalid');
|
|
571
|
+
if (!Array.isArray(annotations))
|
|
572
|
+
throw new TypeError('annotations must be an array');
|
|
573
|
+
annotations.forEach((annotation, index) => {
|
|
574
|
+
if (!isPlainRecord(annotation)) {
|
|
575
|
+
throw new TypeError('map annotation ' + (index + 1) + ' must be an object');
|
|
576
|
+
}
|
|
577
|
+
if (!validCoordinate(annotation.latitude, annotation.longitude)) {
|
|
578
|
+
throw new TypeError('map annotation ' + (index + 1) + ' has invalid coordinates');
|
|
579
|
+
}
|
|
580
|
+
for (const field of ['title', 'body']) {
|
|
581
|
+
if (annotation[field] !== undefined && typeof annotation[field] !== 'string') {
|
|
582
|
+
throw new TypeError('map annotation ' + (index + 1) + ' ' + field + ' must be a string');
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
this.submessages.push({
|
|
587
|
+
messageType: proto.AIRichResponseSubMessageType.AI_RICH_RESPONSE_MAP,
|
|
588
|
+
mapMetadata: {
|
|
589
|
+
centerLatitude,
|
|
590
|
+
centerLongitude,
|
|
591
|
+
annotations: annotations.map((item, index) => ({
|
|
592
|
+
annotationNumber: index + 1,
|
|
593
|
+
latitude: item.latitude,
|
|
594
|
+
longitude: item.longitude,
|
|
595
|
+
title: item.title,
|
|
596
|
+
body: item.body
|
|
597
|
+
}))
|
|
598
|
+
}
|
|
599
|
+
});
|
|
600
|
+
return this;
|
|
601
|
+
}
|
|
602
|
+
addSource(source) {
|
|
603
|
+
ensureText(source.title, 'source.title');
|
|
604
|
+
const url = parseHttpUrl(source.url, 'source.url').toString();
|
|
605
|
+
if (source.thumbnailUrl)
|
|
606
|
+
parseHttpUrl(source.thumbnailUrl, 'source.thumbnailUrl');
|
|
607
|
+
if (source.faviconUrl)
|
|
608
|
+
parseHttpUrl(source.faviconUrl, 'source.faviconUrl');
|
|
609
|
+
this.sources.push({
|
|
610
|
+
provider: source.provider,
|
|
611
|
+
sourceTitle: source.title,
|
|
612
|
+
sourceProviderUrl: url,
|
|
613
|
+
sourceQuery: source.query,
|
|
614
|
+
thumbnailCdnUrl: source.thumbnailUrl,
|
|
615
|
+
faviconCdnUrl: source.faviconUrl,
|
|
616
|
+
citationNumber: this.sources.length + 1
|
|
617
|
+
});
|
|
618
|
+
return this;
|
|
619
|
+
}
|
|
620
|
+
/** Add a WAProto submessage directly for advanced, version-aware use cases. */
|
|
621
|
+
addSubmessage(submessage) {
|
|
622
|
+
if (!submessage || typeof submessage !== 'object' || submessage.messageType === undefined) {
|
|
623
|
+
throw new TypeError('submessage must be an object with a messageType');
|
|
624
|
+
}
|
|
625
|
+
this.submessages.push(structuredClone(submessage));
|
|
626
|
+
return this;
|
|
627
|
+
}
|
|
628
|
+
build() {
|
|
629
|
+
if (this.submessages.length === 0)
|
|
630
|
+
throw new TypeError('AIRich requires at least one submessage');
|
|
631
|
+
const message = {
|
|
632
|
+
richResponseMessage: {
|
|
633
|
+
messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
|
|
634
|
+
submessages: structuredClone(this.submessages)
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
if (this.sources.length) {
|
|
638
|
+
message.messageContextInfo = {
|
|
639
|
+
botMetadata: {
|
|
640
|
+
richResponseSourcesMetadata: { sources: structuredClone(this.sources) }
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
return message;
|
|
645
|
+
}
|
|
646
|
+
async send(jid, options = {}) {
|
|
647
|
+
if (!this.socket)
|
|
648
|
+
throw new Error('AIRich.send() requires a socket; construct with new AIRich(sock)');
|
|
649
|
+
return this.socket.relayMessage(jid, this.build(), { messageId: options.messageId ?? generateMessageID() });
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
/** Small, deterministic utilities; unlike remote auto-update helpers, these never fetch or execute code. */
|
|
653
|
+
export const Toolkit = Object.freeze({
|
|
654
|
+
checkNativeFlowButtons,
|
|
655
|
+
isWebSupportedNativeFlowButton,
|
|
656
|
+
validateHttpUrl: (url) => parseHttpUrl(url, 'url').toString(),
|
|
657
|
+
textMessage: (text) => {
|
|
658
|
+
ensureText(text, 'text');
|
|
659
|
+
return { conversation: text };
|
|
660
|
+
},
|
|
661
|
+
cloneMessage: (message) => structuredClone(message)
|
|
662
|
+
});
|
|
663
|
+
export const MessageBuilder = {
|
|
664
|
+
Button,
|
|
665
|
+
ButtonV2,
|
|
666
|
+
Carousel,
|
|
667
|
+
AIRich,
|
|
668
|
+
Toolkit,
|
|
669
|
+
checkNativeFlowButtons,
|
|
670
|
+
isWebSupportedNativeFlowButton
|
|
671
|
+
};
|
|
672
|
+
export const MB = MessageBuilder;
|
|
673
|
+
//# sourceMappingURL=index.js.map
|