@systemzero/baileys 1.0.0
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/WAProto/GenerateStatics.sh +3 -0
- package/WAProto/WAProto.proto +5479 -0
- package/WAProto/fix-imports.js +29 -0
- package/WAProto/index.d.ts +14017 -0
- package/WAProto/index.js +97650 -0
- package/engine-requirements.js +10 -0
- package/lib/Defaults/index.d.ts +62 -0
- package/lib/Defaults/index.d.ts.map +1 -0
- package/lib/Defaults/index.js +115 -0
- 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/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 +342 -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 +171 -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 +50 -0
- package/lib/Socket/Client/websocket.js.map +1 -0
- package/lib/Socket/business.d.ts +190 -0
- package/lib/Socket/business.d.ts.map +1 -0
- package/lib/Socket/business.js +376 -0
- package/lib/Socket/business.js.map +1 -0
- package/lib/Socket/chats.d.ts +100 -0
- package/lib/Socket/chats.d.ts.map +1 -0
- package/lib/Socket/chats.js +964 -0
- package/lib/Socket/chats.js.map +1 -0
- package/lib/Socket/communities.d.ts +246 -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 +139 -0
- package/lib/Socket/groups.d.ts.map +1 -0
- package/lib/Socket/groups.js +327 -0
- package/lib/Socket/groups.js.map +1 -0
- package/lib/Socket/hzxx.d.ts +255 -0
- package/lib/Socket/hzxx.js +478 -0
- package/lib/Socket/index.d.ts +233 -0
- package/lib/Socket/index.d.ts.map +1 -0
- package/lib/Socket/index.js +18 -0
- package/lib/Socket/index.js.map +1 -0
- package/lib/Socket/messages-recv.d.ts +175 -0
- package/lib/Socket/messages-recv.d.ts.map +1 -0
- package/lib/Socket/messages-recv.js +1273 -0
- package/lib/Socket/messages-recv.js.map +1 -0
- package/lib/Socket/messages-send.d.ts +171 -0
- package/lib/Socket/messages-send.d.ts.map +1 -0
- package/lib/Socket/messages-send.js +1152 -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 +149 -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/normalize.js +290 -0
- package/lib/Socket/socket.d.ts +53 -0
- package/lib/Socket/socket.d.ts.map +1 -0
- package/lib/Socket/socket.js +882 -0
- package/lib/Socket/socket.js.map +1 -0
- package/lib/Types/Auth.d.ts +115 -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 +14 -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 +123 -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 +24 -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 +202 -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 +67 -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 +305 -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/Newsletter.d.ts +135 -0
- package/lib/Types/Newsletter.d.ts.map +1 -0
- package/lib/Types/Newsletter.js +31 -0
- package/lib/Types/Newsletter.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 +76 -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 +133 -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 +39 -0
- package/lib/Types/State.d.ts.map +1 -0
- package/lib/Types/State.js +13 -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 +65 -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 +19 -0
- package/lib/Utils/auth-utils.d.ts.map +1 -0
- package/lib/Utils/auth-utils.js +257 -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 +28 -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 +70 -0
- package/lib/Utils/chat-utils.d.ts.map +1 -0
- package/lib/Utils/chat-utils.js +763 -0
- package/lib/Utils/chat-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +41 -0
- package/lib/Utils/crypto.d.ts.map +1 -0
- package/lib/Utils/crypto.js +142 -0
- package/lib/Utils/crypto.js.map +1 -0
- package/lib/Utils/decode-wa-message.d.ts +48 -0
- package/lib/Utils/decode-wa-message.d.ts.map +1 -0
- package/lib/Utils/decode-wa-message.js +283 -0
- package/lib/Utils/decode-wa-message.js.map +1 -0
- package/lib/Utils/event-buffer.d.ts +34 -0
- package/lib/Utils/event-buffer.d.ts.map +1 -0
- package/lib/Utils/event-buffer.js +548 -0
- package/lib/Utils/event-buffer.js.map +1 -0
- package/lib/Utils/generics.d.ts +90 -0
- package/lib/Utils/generics.d.ts.map +1 -0
- package/lib/Utils/generics.js +381 -0
- package/lib/Utils/generics.js.map +1 -0
- package/lib/Utils/history.d.ts +19 -0
- package/lib/Utils/history.d.ts.map +1 -0
- package/lib/Utils/history.js +90 -0
- package/lib/Utils/history.js.map +1 -0
- package/lib/Utils/index.d.ts +19 -0
- package/lib/Utils/index.d.ts.map +1 -0
- package/lib/Utils/index.js +19 -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 +13 -0
- package/lib/Utils/lt-hash.d.ts.map +1 -0
- package/lib/Utils/lt-hash.js +48 -0
- package/lib/Utils/lt-hash.js.map +1 -0
- package/lib/Utils/make-mutex.d.ts +8 -0
- package/lib/Utils/make-mutex.d.ts.map +1 -0
- package/lib/Utils/make-mutex.js +40 -0
- 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 +172 -0
- package/lib/Utils/message-retry-manager.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +114 -0
- package/lib/Utils/messages-media.d.ts.map +1 -0
- package/lib/Utils/messages-media.js +663 -0
- package/lib/Utils/messages-media.js.map +1 -0
- package/lib/Utils/messages.d.ts +89 -0
- package/lib/Utils/messages.d.ts.map +1 -0
- package/lib/Utils/messages.js +877 -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 +147 -0
- 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 +60 -0
- package/lib/Utils/process-message.d.ts.map +1 -0
- package/lib/Utils/process-message.js +485 -0
- package/lib/Utils/process-message.js.map +1 -0
- package/lib/Utils/signal.d.ts +34 -0
- package/lib/Utils/signal.d.ts.map +1 -0
- package/lib/Utils/signal.js +159 -0
- package/lib/Utils/signal.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 +200 -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 +238 -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 +216 -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 +102 -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 +29 -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/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 -0
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/index.js +5 -0
- package/lib/WAUSync/Protocols/index.js.map +1 -0
- package/lib/WAUSync/USyncQuery.d.ts +29 -0
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
- package/lib/WAUSync/USyncQuery.js +94 -0
- package/lib/WAUSync/USyncQuery.js.map +1 -0
- package/lib/WAUSync/USyncUser.d.ts +13 -0
- package/lib/WAUSync/USyncUser.d.ts.map +1 -0
- package/lib/WAUSync/USyncUser.js +23 -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 +12 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -0
- package/package.json +106 -0
|
@@ -0,0 +1,1152 @@
|
|
|
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, generateWAMessageFromContent, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils/index.js';
|
|
6
|
+
import * as Utils from '../Utils/index.js';
|
|
7
|
+
import { getUrlInfo } from '../Utils/link-preview.js';
|
|
8
|
+
import { makeKeyedMutex } from '../Utils/make-mutex.js';
|
|
9
|
+
import { areJidsSameUser, getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isJidGroup, isLidUser, isPnUser, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET } from '../WABinary/index.js';
|
|
10
|
+
import { USyncQuery, USyncUser } from '../WAUSync/index.js';
|
|
11
|
+
import { makeNewsletterSocket } from './newsletter.js';
|
|
12
|
+
import Hzxx from './hzxx.js';
|
|
13
|
+
import { randomBytes } from 'crypto';
|
|
14
|
+
import normalizeSystem from './normalize.js';
|
|
15
|
+
const META_AI_BOT_JID = '867051314767696@bot';
|
|
16
|
+
const META_AI_BOT_NAME = 'Meta AI';
|
|
17
|
+
const META_AI_CREATOR_NAME = 'Meta';
|
|
18
|
+
const FORWARD_ORIGIN_META_AI = 4;
|
|
19
|
+
const BOT_ENTRY_1ON1 = 29;
|
|
20
|
+
const BOT_ENTRY_GROUP = 30;
|
|
21
|
+
const KEYWORD_HIGHLIGHT = 1;
|
|
22
|
+
const STRING_HIGHLIGHT = 3;
|
|
23
|
+
const NUMBER_HIGHLIGHT = 4;
|
|
24
|
+
const CODE_TOKEN_REGEX = /\b(?:async|await|break|case|catch|class|const|continue|default|delete|do|else|export|false|finally|for|from|function|if|import|in|instanceof|let|new|null|of|return|static|super|switch|this|throw|true|try|typeof|undefined|var|void|while|with|yield)\b|\b\d+(?:\.\d+)?\b|(["'`])(?:\\.|(?!\1)[\s\S])*\1/g;
|
|
25
|
+
|
|
26
|
+
function _randomId(prefix = 'systemzr') {
|
|
27
|
+
return `${prefix}-${Date.now()}-${randomBytes(6).toString('hex')}`; }
|
|
28
|
+
|
|
29
|
+
function _getHighlightType(token) {
|
|
30
|
+
if (/^["'`]/.test(token)) return STRING_HIGHLIGHT;
|
|
31
|
+
if (/^\d/.test(token)) return NUMBER_HIGHLIGHT;
|
|
32
|
+
return KEYWORD_HIGHLIGHT; }
|
|
33
|
+
|
|
34
|
+
function _buildCodeBlocks(codeText) {
|
|
35
|
+
const text = String(codeText || '');
|
|
36
|
+
const blocks = [];
|
|
37
|
+
let lastIndex = 0;
|
|
38
|
+
for (const match of text.matchAll(CODE_TOKEN_REGEX)) {
|
|
39
|
+
const token = match[0];
|
|
40
|
+
const index = match.index ?? 0;
|
|
41
|
+
|
|
42
|
+
if (index > lastIndex) blocks.push({ codeContent: text.slice(lastIndex, index) });
|
|
43
|
+
blocks.push({ highlightType: _getHighlightType(token), codeContent: token });
|
|
44
|
+
lastIndex = index + token.length;
|
|
45
|
+
}
|
|
46
|
+
if (lastIndex < text.length) blocks.push({ codeContent: text.slice(lastIndex) });
|
|
47
|
+
return blocks.length ? blocks : [{ codeContent: text }];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function _encodeUnified(value) {
|
|
51
|
+
return Buffer.from(JSON.stringify(value)).toString('base64');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function _metaAiContext(remoteJid) {
|
|
55
|
+
return {
|
|
56
|
+
isForwarded: true,
|
|
57
|
+
forwardingScore: 1,
|
|
58
|
+
forwardOrigin: FORWARD_ORIGIN_META_AI,
|
|
59
|
+
forwardedAiBotMessageInfo: {
|
|
60
|
+
botName: META_AI_BOT_NAME,
|
|
61
|
+
botJid: META_AI_BOT_JID,
|
|
62
|
+
creatorName: META_AI_CREATOR_NAME,
|
|
63
|
+
},
|
|
64
|
+
botMessageSharingInfo: {
|
|
65
|
+
botEntryPointOrigin: String(remoteJid || '').endsWith('@g.us') ? BOT_ENTRY_GROUP : BOT_ENTRY_1ON1,
|
|
66
|
+
forwardScore: 1,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function _buildBotMetadata(extraCapabilities = []) {
|
|
72
|
+
return {
|
|
73
|
+
modelMetadata: { modelType: 'LLAMA_PROD', premiumModelStatus: 'AVAILABLE' },
|
|
74
|
+
botAgeCollectionMetadata: {},
|
|
75
|
+
botResponseId: _randomId('systemzr-bot'),
|
|
76
|
+
verificationMetadata: { proofs: [] },
|
|
77
|
+
botInfrastructureDiagnostics: {},
|
|
78
|
+
capabilityMetadata: {
|
|
79
|
+
capabilities: [
|
|
80
|
+
'RICH_RESPONSE_STRUCTURED_RESPONSE',
|
|
81
|
+
'RICH_RESPONSE_UNIFIED_RESPONSE',
|
|
82
|
+
'RICH_RESPONSE_UNIFIED_TEXT_COMPONENT',
|
|
83
|
+
'SESSION_TRANSPARENCY_SYSTEM_MESSAGE',
|
|
84
|
+
...extraCapabilities,
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function _buildUnifiedSection(submessage) {
|
|
91
|
+
if (submessage.messageType === 2) {
|
|
92
|
+
return {
|
|
93
|
+
view_model: {
|
|
94
|
+
primitive: { text: submessage.messageText, __typename: 'GenAIMarkdownTextUXPrimitive' },
|
|
95
|
+
__typename: 'GenAISingleLayoutViewModel',
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
if (submessage.messageType === 4) {
|
|
100
|
+
return {
|
|
101
|
+
view_model: {
|
|
102
|
+
primitive: {
|
|
103
|
+
rows: submessage.tableMetadata.rows.map(row => ({
|
|
104
|
+
is_header: !!row.isHeading,
|
|
105
|
+
cells: row.items.map(value => String(value ?? ''))
|
|
106
|
+
})),
|
|
107
|
+
__typename: 'GenATableUXPrimitive'
|
|
108
|
+
},
|
|
109
|
+
__typename: 'GenAISingleLayoutViewModel'
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
if (submessage.messageType === 5) {
|
|
114
|
+
return {
|
|
115
|
+
view_model: {
|
|
116
|
+
primitive: {
|
|
117
|
+
language: submessage.codeMetadata.codeLanguage,
|
|
118
|
+
code_blocks: submessage.codeMetadata.codeBlocks.map((b) => ({
|
|
119
|
+
content: String(b.codeContent || ''),
|
|
120
|
+
type: (() => {
|
|
121
|
+
switch (b.highlightType) {
|
|
122
|
+
case KEYWORD_HIGHLIGHT: return 'KEYWORD';
|
|
123
|
+
case STRING_HIGHLIGHT: return 'STR';
|
|
124
|
+
case NUMBER_HIGHLIGHT: return 'NUMBER';
|
|
125
|
+
default: return 'DEFAULT';
|
|
126
|
+
}
|
|
127
|
+
})(),
|
|
128
|
+
})),
|
|
129
|
+
__typename: 'GenAICodeUXPrimitive',
|
|
130
|
+
},
|
|
131
|
+
__typename: 'GenAISingleLayoutViewModel',
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function _buildRichResponse(submessages, remoteJid) {
|
|
139
|
+
const base = {
|
|
140
|
+
messageType: 1,
|
|
141
|
+
submessages,
|
|
142
|
+
unifiedResponse: {
|
|
143
|
+
data: _encodeUnified({
|
|
144
|
+
response_id: _randomId('systemzr'),
|
|
145
|
+
sections: submessages.map(_buildUnifiedSection).filter(Boolean),
|
|
146
|
+
}),
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
return { ...base, contextInfo: _metaAiContext(remoteJid) };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function makeText(text) { return { messageType: 2, messageText: String(text || '') }; }
|
|
153
|
+
function makeCode(language, codeText) { return { messageType: 5, codeMetadata: { codeLanguage: language || 'text', codeBlocks: _buildCodeBlocks(codeText) } }; }
|
|
154
|
+
function makeList(items = []) { return { messageType: 2, messageText: items.map((i) => `- ${i}`).join('\n') }; }
|
|
155
|
+
function makeTable(rows = []) {
|
|
156
|
+
return {
|
|
157
|
+
messageType: 4,
|
|
158
|
+
tableMetadata: {
|
|
159
|
+
rows: rows.map((items, index) => ({
|
|
160
|
+
items: items.map(value => String(value ?? '')),
|
|
161
|
+
isHeading: index === 0
|
|
162
|
+
}))
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const getButtonArgs = (message) => {
|
|
168
|
+
const nativeFlow = message.interactiveMessage?.nativeFlowMessage;
|
|
169
|
+
const stickerPack = message.interactiveMessage?.stickerPackMessage;
|
|
170
|
+
const firstButtonName = nativeFlow?.buttons?.[0]?.name;
|
|
171
|
+
const nativeFlowSpecials = [
|
|
172
|
+
'mpm', 'cta_catalog', 'send_location',
|
|
173
|
+
'call_permission_request', 'wa_payment_transaction_details',
|
|
174
|
+
'automated_greeting_message_view_catalog'
|
|
175
|
+
];
|
|
176
|
+
if (nativeFlow && (firstButtonName === 'review_and_pay' || firstButtonName === 'payment_info')) {
|
|
177
|
+
return {
|
|
178
|
+
tag: 'biz',
|
|
179
|
+
attrs: { native_flow_name: firstButtonName === 'review_and_pay' ? 'order_details' : firstButtonName }
|
|
180
|
+
};
|
|
181
|
+
} else if (stickerPack) {
|
|
182
|
+
return {
|
|
183
|
+
tag: 'biz',
|
|
184
|
+
attrs: { actual_actors: '2', host_storage: '2', privacy_mode_ts: unixTimestampSeconds().toString() },
|
|
185
|
+
content: [{
|
|
186
|
+
tag: 'interactive',
|
|
187
|
+
attrs: { type: 'sticker_pack', v: '1' },
|
|
188
|
+
content: [{ tag: 'sticker_pack', attrs: { id: stickerPack.stickerPackId } }]
|
|
189
|
+
}]
|
|
190
|
+
};
|
|
191
|
+
} else if (nativeFlow && nativeFlowSpecials.includes(firstButtonName)) {
|
|
192
|
+
return {
|
|
193
|
+
tag: 'biz',
|
|
194
|
+
attrs: { actual_actors: '2', host_storage: '2', privacy_mode_ts: unixTimestampSeconds().toString() },
|
|
195
|
+
content: [{
|
|
196
|
+
tag: 'interactive', attrs: { type: 'native_flow', v: '1' },
|
|
197
|
+
content: [{ tag: 'native_flow', attrs: { v: '2', name: firstButtonName } }]
|
|
198
|
+
}, { tag: 'quality_control', attrs: { source_type: 'third_party' } }]
|
|
199
|
+
};
|
|
200
|
+
} else if (nativeFlow || message.buttonsMessage) {
|
|
201
|
+
return {
|
|
202
|
+
tag: 'biz',
|
|
203
|
+
attrs: { actual_actors: '2', host_storage: '2', privacy_mode_ts: unixTimestampSeconds().toString() },
|
|
204
|
+
content: [{
|
|
205
|
+
tag: 'interactive', attrs: { type: 'native_flow', v: '1' },
|
|
206
|
+
content: [{ tag: 'native_flow', attrs: { v: '9', name: 'mixed' } }]
|
|
207
|
+
}, { tag: 'quality_control', attrs: { source_type: 'third_party' } }]
|
|
208
|
+
};
|
|
209
|
+
} else if (message.listMessage) {
|
|
210
|
+
return {
|
|
211
|
+
tag: 'biz',
|
|
212
|
+
attrs: { actual_actors: '2', host_storage: '2', privacy_mode_ts: unixTimestampSeconds().toString() },
|
|
213
|
+
content: [{ tag: 'list', attrs: { v: '2', type: 'product_list' } }, { tag: 'quality_control', attrs: { source_type: 'third_party' } }]
|
|
214
|
+
};
|
|
215
|
+
} else {
|
|
216
|
+
return { tag: 'biz', attrs: { actual_actors: '2', host_storage: '2', privacy_mode_ts: unixTimestampSeconds().toString() } };
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
const getButtonType = (message) => {
|
|
221
|
+
if (message.listMessage) return 'list';
|
|
222
|
+
else if (message.buttonsMessage) return 'buttons';
|
|
223
|
+
else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'review_and_pay') return 'review_and_pay';
|
|
224
|
+
else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'review_order') return 'review_order';
|
|
225
|
+
else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_info') return 'payment_info';
|
|
226
|
+
else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_status') return 'payment_status';
|
|
227
|
+
else if (message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_method') return 'payment_method';
|
|
228
|
+
else if (message.interactiveMessage && message.interactiveMessage?.nativeFlowMessage) return 'interactive';
|
|
229
|
+
else if (message.interactiveMessage?.nativeFlowMessage) return 'native_flow';
|
|
230
|
+
else if (message.interactiveMessage?.stickerPackMessage) return 'sticker_pack';
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export const makeMessagesSocket = (config) => {
|
|
234
|
+
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: httpRequestOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache, maxMsgRetryCount } = config;
|
|
235
|
+
const sock = makeNewsletterSocket(config);
|
|
236
|
+
const { ev, authState, processingMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral } = sock;
|
|
237
|
+
normalizeSystem.bindSocket(sock, config.store);
|
|
238
|
+
const userDevicesCache = config.userDevicesCache ||
|
|
239
|
+
new NodeCache({
|
|
240
|
+
stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES,
|
|
241
|
+
useClones: false
|
|
242
|
+
});
|
|
243
|
+
const peerSessionsCache = new NodeCache({
|
|
244
|
+
stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES,
|
|
245
|
+
useClones: false
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
const messageRetryManager = enableRecentMessageCache ? new MessageRetryManager(logger, maxMsgRetryCount) : null;
|
|
249
|
+
const encryptionMutex = makeKeyedMutex();
|
|
250
|
+
let mediaConn;
|
|
251
|
+
|
|
252
|
+
const refreshMediaConn = async (forceGet = false) => {
|
|
253
|
+
const media = await mediaConn;
|
|
254
|
+
if (!media || forceGet || new Date().getTime() - media.fetchDate.getTime() > media.ttl * 1000) {
|
|
255
|
+
mediaConn = (async () => {
|
|
256
|
+
const result = await query({
|
|
257
|
+
tag: 'iq',
|
|
258
|
+
attrs: {
|
|
259
|
+
type: 'set',
|
|
260
|
+
xmlns: 'w:m',
|
|
261
|
+
to: S_WHATSAPP_NET
|
|
262
|
+
},
|
|
263
|
+
content: [{ tag: 'media_conn', attrs: {} }]
|
|
264
|
+
});
|
|
265
|
+
const mediaConnNode = getBinaryNodeChild(result, 'media_conn');
|
|
266
|
+
const node = {
|
|
267
|
+
hosts: getBinaryNodeChildren(mediaConnNode, 'host').map(({ attrs }) => ({
|
|
268
|
+
hostname: attrs.hostname,
|
|
269
|
+
maxContentLengthBytes: +attrs.maxContentLengthBytes
|
|
270
|
+
})),
|
|
271
|
+
auth: mediaConnNode.attrs.auth,
|
|
272
|
+
ttl: +mediaConnNode.attrs.ttl,
|
|
273
|
+
fetchDate: new Date()
|
|
274
|
+
};
|
|
275
|
+
logger.debug('fetched media conn');
|
|
276
|
+
return node;
|
|
277
|
+
})();
|
|
278
|
+
}
|
|
279
|
+
return mediaConn;
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
const sendReceipt = async (jid, participant, messageIds, type) => {
|
|
283
|
+
if (!messageIds || messageIds.length === 0) {
|
|
284
|
+
throw new Boom('missing ids in receipt');
|
|
285
|
+
}
|
|
286
|
+
const node = { tag: 'receipt', attrs: { id: messageIds[0] } };
|
|
287
|
+
const isReadReceipt = type === 'read' || type === 'read-self';
|
|
288
|
+
if (isReadReceipt) {
|
|
289
|
+
node.attrs.t = unixTimestampSeconds().toString();
|
|
290
|
+
}
|
|
291
|
+
if (type === 'sender' && (isPnUser(jid) || isLidUser(jid))) {
|
|
292
|
+
node.attrs.recipient = jid;
|
|
293
|
+
node.attrs.to = participant;
|
|
294
|
+
} else {
|
|
295
|
+
node.attrs.to = jid;
|
|
296
|
+
if (participant) {
|
|
297
|
+
node.attrs.participant = participant;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (type) node.attrs.type = type;
|
|
301
|
+
|
|
302
|
+
const remainingMessageIds = messageIds.slice(1);
|
|
303
|
+
if (remainingMessageIds.length) {
|
|
304
|
+
node.content = [{
|
|
305
|
+
tag: 'list', attrs: {},
|
|
306
|
+
content: remainingMessageIds.map(id => ({ tag: 'item', attrs: { id } }))
|
|
307
|
+
}];
|
|
308
|
+
}
|
|
309
|
+
logger.debug({ attrs: node.attrs, messageIds }, 'sending receipt for messages');
|
|
310
|
+
await sendNode(node);
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
const sendReceipts = async (keys, type) => {
|
|
314
|
+
const recps = aggregateMessageKeysNotFromMe(keys);
|
|
315
|
+
for (const { jid, participant, messageIds } of recps) {
|
|
316
|
+
await sendReceipt(jid, participant, messageIds, type);
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const readMessages = async (keys) => {
|
|
321
|
+
const privacySettings = await fetchPrivacySettings();
|
|
322
|
+
const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self';
|
|
323
|
+
await sendReceipts(keys, readType);
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
const getUSyncDevices = async (jids, useCache, ignoreZeroDevices) => {
|
|
327
|
+
const deviceResults = [];
|
|
328
|
+
if (!useCache) logger.debug('not using cache for devices');
|
|
329
|
+
const toFetch = [];
|
|
330
|
+
const jidsWithUser = jids
|
|
331
|
+
.map(jid => {
|
|
332
|
+
const decoded = jidDecode(jid);
|
|
333
|
+
const user = decoded?.user;
|
|
334
|
+
const device = decoded?.device;
|
|
335
|
+
const isExplicitDevice = typeof device === 'number' && device >= 0;
|
|
336
|
+
if (isExplicitDevice && user) {
|
|
337
|
+
deviceResults.push({ user, device, jid });
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
jid = jidNormalizedUser(jid);
|
|
341
|
+
return { jid, user };
|
|
342
|
+
}).filter(jid => jid !== null);
|
|
343
|
+
|
|
344
|
+
let mgetDevices;
|
|
345
|
+
if (useCache && userDevicesCache.mget) {
|
|
346
|
+
const usersToFetch = jidsWithUser.map(j => j?.user).filter(Boolean);
|
|
347
|
+
mgetDevices = await userDevicesCache.mget(usersToFetch);
|
|
348
|
+
}
|
|
349
|
+
for (const { jid, user } of jidsWithUser) {
|
|
350
|
+
if (useCache) {
|
|
351
|
+
const devices = mgetDevices?.[user] || (userDevicesCache.mget ? undefined : (await userDevicesCache.get(user)));
|
|
352
|
+
if (devices) {
|
|
353
|
+
const devicesWithJid = devices.map(d => ({ ...d, jid: jidEncode(d.user, d.server, d.device) }));
|
|
354
|
+
deviceResults.push(...devicesWithJid);
|
|
355
|
+
logger.trace({ user }, 'using cache for devices');
|
|
356
|
+
} else {
|
|
357
|
+
toFetch.push(jid);
|
|
358
|
+
}
|
|
359
|
+
} else {
|
|
360
|
+
toFetch.push(jid);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (!toFetch.length) return deviceResults;
|
|
364
|
+
|
|
365
|
+
const requestedLidUsers = new Set();
|
|
366
|
+
for (const jid of toFetch) {
|
|
367
|
+
if (isLidUser(jid) || isHostedLidUser(jid)) {
|
|
368
|
+
const user = jidDecode(jid)?.user;
|
|
369
|
+
if (user) requestedLidUsers.add(user);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const query = new USyncQuery().withContext('message').withDeviceProtocol().withLIDProtocol();
|
|
374
|
+
for (const jid of toFetch) query.withUser(new USyncUser().withId(jid));
|
|
375
|
+
|
|
376
|
+
const result = await sock.executeUSyncQuery(query);
|
|
377
|
+
if (result) {
|
|
378
|
+
const lidResults = result.list.filter(a => !!a.lid);
|
|
379
|
+
if (lidResults.length > 0) {
|
|
380
|
+
logger.trace('Storing LID maps from device call');
|
|
381
|
+
await signalRepository.lidMapping.storeLIDPNMappings(lidResults.map(a => ({ lid: a.lid, pn: a.id })));
|
|
382
|
+
try {
|
|
383
|
+
const lids = lidResults.map(a => a.lid);
|
|
384
|
+
if (lids.length) await assertSessions(lids, true);
|
|
385
|
+
} catch (e) {
|
|
386
|
+
logger.warn({ e, count: lidResults.length }, 'failed to assert sessions for newly mapped LIDs');
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
const extracted = extractDeviceJids(result?.list, authState.creds.me.id, authState.creds.me.lid, ignoreZeroDevices);
|
|
390
|
+
const deviceMap = {};
|
|
391
|
+
for (const item of extracted) {
|
|
392
|
+
deviceMap[item.user] = deviceMap[item.user] || [];
|
|
393
|
+
deviceMap[item.user]?.push(item);
|
|
394
|
+
}
|
|
395
|
+
for (const [user, userDevices] of Object.entries(deviceMap)) {
|
|
396
|
+
const isLidUser = requestedLidUsers.has(user);
|
|
397
|
+
for (const item of userDevices) {
|
|
398
|
+
const finalJid = isLidUser ? jidEncode(user, item.server, item.device) : jidEncode(item.user, item.server, item.device);
|
|
399
|
+
deviceResults.push({ ...item, jid: finalJid });
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (userDevicesCache.mset) {
|
|
403
|
+
await userDevicesCache.mset(Object.entries(deviceMap).map(([key, value]) => ({ key, value })));
|
|
404
|
+
} else {
|
|
405
|
+
for (const key in deviceMap) {
|
|
406
|
+
if (deviceMap[key]) await userDevicesCache.set(key, deviceMap[key]);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
const userDeviceUpdates = {};
|
|
410
|
+
for (const [userId, devices] of Object.entries(deviceMap)) {
|
|
411
|
+
if (devices && devices.length > 0) {
|
|
412
|
+
userDeviceUpdates[userId] = devices.map(d => d.device?.toString() || '0');
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (Object.keys(userDeviceUpdates).length > 0) {
|
|
416
|
+
try {
|
|
417
|
+
await authState.keys.set({ 'device-list': userDeviceUpdates });
|
|
418
|
+
} catch (error) {
|
|
419
|
+
logger.warn({ error }, 'failed to store user device lists');
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return deviceResults;
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
const assertSessions = async (jids, force) => {
|
|
427
|
+
let didFetchNewSession = false;
|
|
428
|
+
const uniqueJids = [...new Set(jids)];
|
|
429
|
+
const jidsRequiringFetch = [];
|
|
430
|
+
logger.debug({ jids }, 'assertSessions call with jids');
|
|
431
|
+
for (const jid of uniqueJids) {
|
|
432
|
+
const signalId = signalRepository.jidToSignalProtocolAddress(jid);
|
|
433
|
+
const cachedSession = peerSessionsCache.get(signalId);
|
|
434
|
+
if (cachedSession !== undefined) {
|
|
435
|
+
if (cachedSession && !force) continue;
|
|
436
|
+
} else {
|
|
437
|
+
const sessionValidation = await signalRepository.validateSession(jid);
|
|
438
|
+
const hasSession = sessionValidation.exists;
|
|
439
|
+
peerSessionsCache.set(signalId, hasSession);
|
|
440
|
+
if (hasSession && !force) continue;
|
|
441
|
+
}
|
|
442
|
+
jidsRequiringFetch.push(jid);
|
|
443
|
+
}
|
|
444
|
+
if (jidsRequiringFetch.length) {
|
|
445
|
+
const wireJids = [
|
|
446
|
+
...jidsRequiringFetch.filter(jid => !!isLidUser(jid) || !!isHostedLidUser(jid)),
|
|
447
|
+
...((await signalRepository.lidMapping.getLIDsForPNs(jidsRequiringFetch.filter(jid => !!isPnUser(jid) || !!isHostedPnUser(jid)))) || []).map(a => a.lid)
|
|
448
|
+
];
|
|
449
|
+
const result = await query({
|
|
450
|
+
tag: 'iq',
|
|
451
|
+
attrs: { xmlns: 'encrypt', type: 'get', to: S_WHATSAPP_NET },
|
|
452
|
+
content: [{
|
|
453
|
+
tag: 'key', attrs: {},
|
|
454
|
+
content: wireJids.map(jid => {
|
|
455
|
+
const attrs = { jid };
|
|
456
|
+
if (force) attrs.reason = 'identity';
|
|
457
|
+
return { tag: 'user', attrs };
|
|
458
|
+
})
|
|
459
|
+
}]
|
|
460
|
+
});
|
|
461
|
+
await parseAndInjectE2ESessions(result, signalRepository);
|
|
462
|
+
didFetchNewSession = true;
|
|
463
|
+
for (const wireJid of wireJids) {
|
|
464
|
+
const signalId = signalRepository.jidToSignalProtocolAddress(wireJid);
|
|
465
|
+
peerSessionsCache.set(signalId, true);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return didFetchNewSession;
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
const sendPeerDataOperationMessage = async (pdoMessage) => {
|
|
472
|
+
if (!authState.creds.me?.id) throw new Boom('Not authenticated');
|
|
473
|
+
const protocolMessage = {
|
|
474
|
+
protocolMessage: {
|
|
475
|
+
peerDataOperationRequestMessage: pdoMessage,
|
|
476
|
+
type: proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
const meJid = jidNormalizedUser(authState.creds.me.id);
|
|
480
|
+
const msgId = await relayMessage(meJid, protocolMessage, {
|
|
481
|
+
additionalAttributes: { category: 'peer', push_priority: 'high_force' },
|
|
482
|
+
additionalNodes: [{ tag: 'meta', attrs: { appdata: 'default' } }]
|
|
483
|
+
});
|
|
484
|
+
return msgId;
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
const createParticipantNodes = async (recipientJids, message, extraAttrs, dsmMessage) => {
|
|
488
|
+
if (!recipientJids.length) return { nodes: [], shouldIncludeDeviceIdentity: false };
|
|
489
|
+
const patched = await patchMessageBeforeSending(message, recipientJids);
|
|
490
|
+
const patchedMessages = Array.isArray(patched) ? patched : recipientJids.map(jid => ({ recipientJid: jid, message: patched }));
|
|
491
|
+
let shouldIncludeDeviceIdentity = false;
|
|
492
|
+
const meId = authState.creds.me.id;
|
|
493
|
+
const meLid = authState.creds.me?.lid;
|
|
494
|
+
const meLidUser = meLid ? jidDecode(meLid)?.user : null;
|
|
495
|
+
|
|
496
|
+
const encryptionPromises = patchedMessages.map(async ({ recipientJid: jid, message: patchedMessage }) => {
|
|
497
|
+
if (!jid) return null;
|
|
498
|
+
let msgToEncrypt = patchedMessage;
|
|
499
|
+
if (dsmMessage) {
|
|
500
|
+
const { user: targetUser } = jidDecode(jid);
|
|
501
|
+
const { user: ownPnUser } = jidDecode(meId);
|
|
502
|
+
const ownLidUser = meLidUser;
|
|
503
|
+
const isOwnUser = targetUser === ownPnUser || (ownLidUser && targetUser === ownLidUser);
|
|
504
|
+
const isExactSenderDevice = jid === meId || (meLid && jid === meLid);
|
|
505
|
+
if (isOwnUser && !isExactSenderDevice) msgToEncrypt = dsmMessage;
|
|
506
|
+
}
|
|
507
|
+
const bytes = encodeWAMessage(msgToEncrypt);
|
|
508
|
+
const mutexKey = jid;
|
|
509
|
+
const node = await encryptionMutex.mutex(mutexKey, async () => {
|
|
510
|
+
const { type, ciphertext } = await signalRepository.encryptMessage({ jid, data: bytes });
|
|
511
|
+
if (type === 'pkmsg') shouldIncludeDeviceIdentity = true;
|
|
512
|
+
return {
|
|
513
|
+
tag: 'to', attrs: { jid },
|
|
514
|
+
content: [{ tag: 'enc', attrs: { v: '2', type, ...(extraAttrs || {}) }, content: ciphertext }]
|
|
515
|
+
};
|
|
516
|
+
});
|
|
517
|
+
return node;
|
|
518
|
+
});
|
|
519
|
+
const nodes = (await Promise.all(encryptionPromises)).filter(node => node !== null);
|
|
520
|
+
return { nodes, shouldIncludeDeviceIdentity };
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList, AI = true }) => {
|
|
524
|
+
const meId = authState.creds.me.id;
|
|
525
|
+
const meLid = authState.creds.me?.lid;
|
|
526
|
+
const isRetryResend = Boolean(participant?.jid);
|
|
527
|
+
let shouldIncludeDeviceIdentity = isRetryResend;
|
|
528
|
+
const statusJid = 'status@broadcast';
|
|
529
|
+
const { user, server } = jidDecode(jid);
|
|
530
|
+
const isGroup = server === 'g.us';
|
|
531
|
+
const isStatus = jid === statusJid;
|
|
532
|
+
const isLid = server === 'lid';
|
|
533
|
+
const isNewsletter = server === 'newsletter';
|
|
534
|
+
const isGroupOrStatus = isGroup || isStatus;
|
|
535
|
+
const finalJid = jid;
|
|
536
|
+
msgId = msgId || generateMessageIDV2(meId);
|
|
537
|
+
useUserDevicesCache = useUserDevicesCache !== false;
|
|
538
|
+
useCachedGroupMetadata = useCachedGroupMetadata !== false && !isStatus;
|
|
539
|
+
const participants = [];
|
|
540
|
+
const destinationJid = !isStatus ? finalJid : statusJid;
|
|
541
|
+
const binaryNodeContent = [];
|
|
542
|
+
const devices = [];
|
|
543
|
+
const meMsg = { deviceSentMessage: { destinationJid, message }, messageContextInfo: message.messageContextInfo };
|
|
544
|
+
const extraAttrs = {};
|
|
545
|
+
|
|
546
|
+
if (participant) {
|
|
547
|
+
if (!isGroup && !isStatus) additionalAttributes = { ...additionalAttributes, device_fanout: 'false' };
|
|
548
|
+
const { user, device } = jidDecode(participant.jid);
|
|
549
|
+
devices.push({ user, device, jid: participant.jid });
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
await authState.keys.transaction(async () => {
|
|
553
|
+
const mediaType = getMediaType(message);
|
|
554
|
+
if (mediaType) extraAttrs['mediatype'] = mediaType;
|
|
555
|
+
if (isNewsletter) {
|
|
556
|
+
const patched = patchMessageBeforeSending ? await patchMessageBeforeSending(message, []) : message;
|
|
557
|
+
const bytes = encodeNewsletterMessage(patched);
|
|
558
|
+
binaryNodeContent.push({ tag: 'plaintext', attrs: {}, content: bytes });
|
|
559
|
+
const stanza = {
|
|
560
|
+
tag: 'message',
|
|
561
|
+
attrs: { to: jid, id: msgId, type: getMessageType(message), ...(additionalAttributes || {}) },
|
|
562
|
+
content: binaryNodeContent
|
|
563
|
+
};
|
|
564
|
+
await sendNode(stanza);
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
if (normalizeMessageContent(message)?.pinInChatMessage) {
|
|
568
|
+
extraAttrs['decrypt-fail'] = 'hide';
|
|
569
|
+
}
|
|
570
|
+
if (isGroupOrStatus && !isRetryResend) {
|
|
571
|
+
const [groupData, senderKeyMap] = await Promise.all([
|
|
572
|
+
(async () => {
|
|
573
|
+
let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined;
|
|
574
|
+
if (!groupData && !isStatus) groupData = await groupMetadata(jid);
|
|
575
|
+
return groupData;
|
|
576
|
+
})(),
|
|
577
|
+
(async () => {
|
|
578
|
+
if (!participant && !isStatus) {
|
|
579
|
+
const result = await authState.keys.get('sender-key-memory', [jid]);
|
|
580
|
+
return result[jid] || {};
|
|
581
|
+
}
|
|
582
|
+
return {};
|
|
583
|
+
})()
|
|
584
|
+
]);
|
|
585
|
+
const participantsList = groupData ? groupData.participants.map(p => p.id) : [];
|
|
586
|
+
if (groupData?.ephemeralDuration && groupData.ephemeralDuration > 0) {
|
|
587
|
+
additionalAttributes = { ...additionalAttributes, expiration: groupData.ephemeralDuration.toString() };
|
|
588
|
+
}
|
|
589
|
+
if (isStatus && statusJidList) participantsList.push(...statusJidList);
|
|
590
|
+
const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false);
|
|
591
|
+
devices.push(...additionalDevices);
|
|
592
|
+
if (isGroup) {
|
|
593
|
+
additionalAttributes = { ...additionalAttributes, addressing_mode: groupData?.addressingMode || 'lid' };
|
|
594
|
+
}
|
|
595
|
+
const patched = await patchMessageBeforeSending(message);
|
|
596
|
+
if (Array.isArray(patched)) throw new Boom('Per-jid patching is not supported in groups');
|
|
597
|
+
const bytes = encodeWAMessage(patched);
|
|
598
|
+
const groupAddressingMode = additionalAttributes?.['addressing_mode'] || groupData?.addressingMode || 'lid';
|
|
599
|
+
const groupSenderIdentity = groupAddressingMode === 'lid' && meLid ? meLid : meId;
|
|
600
|
+
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({
|
|
601
|
+
group: destinationJid, data: bytes, meId: groupSenderIdentity
|
|
602
|
+
});
|
|
603
|
+
const senderKeyRecipients = [];
|
|
604
|
+
for (const device of devices) {
|
|
605
|
+
const deviceJid = device.jid;
|
|
606
|
+
const hasKey = !!senderKeyMap[deviceJid];
|
|
607
|
+
if ((!hasKey || !!participant) && !isHostedLidUser(deviceJid) && !isHostedPnUser(deviceJid) && device.device !== 99) {
|
|
608
|
+
senderKeyRecipients.push(deviceJid);
|
|
609
|
+
senderKeyMap[deviceJid] = true;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
if (senderKeyRecipients.length) {
|
|
613
|
+
const senderKeyMsg = {
|
|
614
|
+
senderKeyDistributionMessage: { axolotlSenderKeyDistributionMessage: senderKeyDistributionMessage, groupId: destinationJid }
|
|
615
|
+
};
|
|
616
|
+
await assertSessions(senderKeyRecipients);
|
|
617
|
+
const result = await createParticipantNodes(senderKeyRecipients, senderKeyMsg, extraAttrs);
|
|
618
|
+
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity;
|
|
619
|
+
participants.push(...result.nodes);
|
|
620
|
+
}
|
|
621
|
+
binaryNodeContent.push({ tag: 'enc', attrs: { v: '2', type: 'skmsg', ...extraAttrs }, content: ciphertext });
|
|
622
|
+
await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } });
|
|
623
|
+
} else {
|
|
624
|
+
let ownId = meId;
|
|
625
|
+
if (isLid && meLid) ownId = meLid;
|
|
626
|
+
const { user: ownUser } = jidDecode(ownId);
|
|
627
|
+
if (!isRetryResend) {
|
|
628
|
+
const targetUserServer = isLid ? 'lid' : 's.whatsapp.net';
|
|
629
|
+
devices.push({ user, device: 0, jid: jidEncode(user, targetUserServer, 0) });
|
|
630
|
+
if (user !== ownUser) {
|
|
631
|
+
const ownUserServer = isLid ? 'lid' : 's.whatsapp.net';
|
|
632
|
+
const ownUserForAddressing = isLid && meLid ? jidDecode(meLid).user : jidDecode(meId).user;
|
|
633
|
+
devices.push({ user: ownUserForAddressing, device: 0, jid: jidEncode(ownUserForAddressing, ownUserServer, 0) });
|
|
634
|
+
}
|
|
635
|
+
if (additionalAttributes?.['category'] !== 'peer') {
|
|
636
|
+
devices.length = 0;
|
|
637
|
+
const senderIdentity = isLid && meLid ? jidEncode(jidDecode(meLid)?.user, 'lid', undefined) : jidEncode(jidDecode(meId)?.user, 's.whatsapp.net', undefined);
|
|
638
|
+
const sessionDevices = await getUSyncDevices([senderIdentity, jid], true, false);
|
|
639
|
+
devices.push(...sessionDevices);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
const allRecipients = [];
|
|
643
|
+
const meRecipients = [];
|
|
644
|
+
const otherRecipients = [];
|
|
645
|
+
const { user: mePnUser } = jidDecode(meId);
|
|
646
|
+
const { user: meLidUser } = meLid ? jidDecode(meLid) : { user: null };
|
|
647
|
+
for (const { user, jid } of devices) {
|
|
648
|
+
const isExactSenderDevice = jid === meId || (meLid && jid === meLid);
|
|
649
|
+
if (isExactSenderDevice) continue;
|
|
650
|
+
const isMe = user === mePnUser || user === meLidUser;
|
|
651
|
+
if (isMe) meRecipients.push(jid);
|
|
652
|
+
else otherRecipients.push(jid);
|
|
653
|
+
allRecipients.push(jid);
|
|
654
|
+
}
|
|
655
|
+
await assertSessions(allRecipients);
|
|
656
|
+
const [{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 }, { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }] = await Promise.all([
|
|
657
|
+
createParticipantNodes(meRecipients, meMsg || message, extraAttrs),
|
|
658
|
+
createParticipantNodes(otherRecipients, message, extraAttrs, meMsg)
|
|
659
|
+
]);
|
|
660
|
+
participants.push(...meNodes);
|
|
661
|
+
participants.push(...otherNodes);
|
|
662
|
+
if (meRecipients.length > 0 || otherRecipients.length > 0) {
|
|
663
|
+
extraAttrs['phash'] = generateParticipantHashV2([...meRecipients, ...otherRecipients]);
|
|
664
|
+
}
|
|
665
|
+
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2;
|
|
666
|
+
}
|
|
667
|
+
if (isRetryResend) {
|
|
668
|
+
const isParticipantLid = isLidUser(participant.jid);
|
|
669
|
+
const isMe = areJidsSameUser(participant.jid, isParticipantLid ? meLid : meId);
|
|
670
|
+
const encodedMessageToSend = isMe ? encodeWAMessage({ deviceSentMessage: { destinationJid, message } }) : encodeWAMessage(message);
|
|
671
|
+
const { type, ciphertext: encryptedContent } = await signalRepository.encryptMessage({ data: encodedMessageToSend, jid: participant.jid });
|
|
672
|
+
binaryNodeContent.push({ tag: 'enc', attrs: { v: '2', type, count: participant.count.toString() }, content: encryptedContent });
|
|
673
|
+
}
|
|
674
|
+
if (participants.length) {
|
|
675
|
+
if (additionalAttributes?.['category'] === 'peer') {
|
|
676
|
+
const peerNode = participants[0]?.content?.[0];
|
|
677
|
+
if (peerNode) binaryNodeContent.push(peerNode);
|
|
678
|
+
} else {
|
|
679
|
+
binaryNodeContent.push({ tag: 'participants', attrs: {}, content: participants });
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
const stanza = {
|
|
683
|
+
tag: 'message',
|
|
684
|
+
attrs: { id: msgId, to: destinationJid, type: getMessageType(message), ...(additionalAttributes || {}) },
|
|
685
|
+
content: binaryNodeContent
|
|
686
|
+
};
|
|
687
|
+
if (participant) {
|
|
688
|
+
if (isJidGroup(destinationJid)) {
|
|
689
|
+
stanza.attrs.to = destinationJid;
|
|
690
|
+
stanza.attrs.participant = participant.jid;
|
|
691
|
+
} else if (areJidsSameUser(participant.jid, meId)) {
|
|
692
|
+
stanza.attrs.to = participant.jid;
|
|
693
|
+
stanza.attrs.recipient = destinationJid;
|
|
694
|
+
} else {
|
|
695
|
+
stanza.attrs.to = participant.jid;
|
|
696
|
+
}
|
|
697
|
+
} else {
|
|
698
|
+
stanza.attrs.to = destinationJid;
|
|
699
|
+
}
|
|
700
|
+
if (shouldIncludeDeviceIdentity) {
|
|
701
|
+
stanza.content.push({ tag: 'device-identity', attrs: {}, content: encodeSignedDeviceIdentity(authState.creds.account, true) });
|
|
702
|
+
}
|
|
703
|
+
const contactTcTokenData = !isGroup && !isRetryResend && !isStatus ? await authState.keys.get('tctoken', [destinationJid]) : {};
|
|
704
|
+
const tcTokenBuffer = contactTcTokenData[destinationJid]?.token;
|
|
705
|
+
if (tcTokenBuffer) {
|
|
706
|
+
stanza.content.push({ tag: 'tctoken', attrs: {}, content: tcTokenBuffer });
|
|
707
|
+
}
|
|
708
|
+
const messages = normalizeMessageContent(message) || message;
|
|
709
|
+
const buttonType = getButtonType(messages);
|
|
710
|
+
let didPushAdditional = false;
|
|
711
|
+
const isChatPrivate = !isJidGroup(destinationJid) && destinationJid !== 'status@broadcast' && !destinationJid.includes('newsletter');
|
|
712
|
+
|
|
713
|
+
if (AI && isChatPrivate) {
|
|
714
|
+
const botNode = { tag: 'bot', attrs: { biz_bot: '1' } };
|
|
715
|
+
const filteredBizBot = additionalNodes?.find(n => n.tag === 'bot');
|
|
716
|
+
if (filteredBizBot) {
|
|
717
|
+
stanza.content.push(...additionalNodes);
|
|
718
|
+
didPushAdditional = true;
|
|
719
|
+
} else {
|
|
720
|
+
stanza.content.push(botNode);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
if (!destinationJid.includes('newsletter') && buttonType && destinationJid !== 'status@broadcast') {
|
|
724
|
+
const contentArgs = getButtonArgs(messages);
|
|
725
|
+
const filteredNode = additionalNodes?.find(n => n.tag === contentArgs?.tag);
|
|
726
|
+
if (filteredNode) {
|
|
727
|
+
didPushAdditional = true;
|
|
728
|
+
stanza.content.push(...additionalNodes);
|
|
729
|
+
} else if (contentArgs) {
|
|
730
|
+
if (Array.isArray(contentArgs)) stanza.content.push(...contentArgs);
|
|
731
|
+
else stanza.content.push(contentArgs);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
if (!didPushAdditional && additionalNodes && additionalNodes.length > 0) {
|
|
735
|
+
stanza.content.push(...additionalNodes);
|
|
736
|
+
}
|
|
737
|
+
await sendNode(stanza);
|
|
738
|
+
if (messageRetryManager && !participant) {
|
|
739
|
+
messageRetryManager.addRecentMessage(destinationJid, msgId, message);
|
|
740
|
+
}
|
|
741
|
+
}, meId);
|
|
742
|
+
return msgId;
|
|
743
|
+
};
|
|
744
|
+
|
|
745
|
+
const sendRich = async (remoteJid, parts = [], quoted = null, extraCapabilities = []) => {
|
|
746
|
+
const rich = _buildRichResponse(parts, remoteJid);
|
|
747
|
+
const payload = proto.Message.fromObject({
|
|
748
|
+
botForwardedMessage: { message: { richResponseMessage: rich } },
|
|
749
|
+
messageContextInfo: { messageSecret: randomBytes(32), botMetadata: _buildBotMetadata(['RICH_RESPONSE_CODE', ...extraCapabilities]) }
|
|
750
|
+
});
|
|
751
|
+
const options = quoted ? { quoted: JSON.parse(JSON.stringify(quoted)) } : {};
|
|
752
|
+
const waMsg = generateWAMessageFromContent(remoteJid, payload, options);
|
|
753
|
+
return relayMessage(remoteJid, waMsg.message, { messageId: waMsg.key.id });
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
const getMessageType = (message) => {
|
|
757
|
+
if (message.pollCreationMessage || message.pollCreationMessageV2 || message.pollCreationMessageV3) return 'poll';
|
|
758
|
+
if (message.eventMessage) return 'event';
|
|
759
|
+
if (getMediaType(message) !== '') return 'media';
|
|
760
|
+
return 'text';
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
const getMediaType = (message) => {
|
|
764
|
+
if (message.imageMessage) return 'image';
|
|
765
|
+
else if (message.videoMessage) return message.videoMessage.gifPlayback ? 'gif' : 'video';
|
|
766
|
+
else if (message.audioMessage) return message.audioMessage.ptt ? 'ptt' : 'audio';
|
|
767
|
+
else if (message.contactMessage) return 'vcard';
|
|
768
|
+
else if (message.documentMessage) return 'document';
|
|
769
|
+
else if (message.contactsArrayMessage) return 'contact_array';
|
|
770
|
+
else if (message.liveLocationMessage) return 'livelocation';
|
|
771
|
+
else if (message.stickerMessage) return 'sticker';
|
|
772
|
+
else if (message.listMessage) return 'list';
|
|
773
|
+
else if (message.listResponseMessage) return 'list_response';
|
|
774
|
+
else if (message.buttonsResponseMessage) return 'buttons_response';
|
|
775
|
+
else if (message.orderMessage) return 'order';
|
|
776
|
+
else if (message.productMessage) return 'product';
|
|
777
|
+
else if (message.interactiveResponseMessage) return 'native_flow_response';
|
|
778
|
+
else if (message.groupInviteMessage) return 'url';
|
|
779
|
+
return '';
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
const getPrivacyTokens = async (jids) => {
|
|
783
|
+
const t = unixTimestampSeconds().toString();
|
|
784
|
+
const result = await query({
|
|
785
|
+
tag: 'iq',
|
|
786
|
+
attrs: { to: S_WHATSAPP_NET, type: 'set', xmlns: 'privacy' },
|
|
787
|
+
content: [{ tag: 'tokens', attrs: {}, content: jids.map(jid => ({ tag: 'token', attrs: { jid: jidNormalizedUser(jid), t, type: 'trusted_contact' } })) }]
|
|
788
|
+
});
|
|
789
|
+
return result;
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
const waUploadToServer = getWAUploadToServer(config, refreshMediaConn);
|
|
793
|
+
const waitForMsgMediaUpdate = bindWaitForEvent(ev, 'messages.media-update');
|
|
794
|
+
const hzxx = new Hzxx(Utils, waUploadToServer, relayMessage);
|
|
795
|
+
|
|
796
|
+
const sendRichReels = async (jid, title, headerText, query, reels, options = {}) => {
|
|
797
|
+
const unified = {
|
|
798
|
+
response_id: `reels-${Date.now()}`,
|
|
799
|
+
sections: [
|
|
800
|
+
{ view_model: { primitive: { text: title, __typename: "GenAIMarkdownTextUXPrimitive" }, __typename: "GenAISingleLayoutViewModel" } },
|
|
801
|
+
{
|
|
802
|
+
view_model: {
|
|
803
|
+
primitives: reels.map(reel => ({
|
|
804
|
+
reels_url: reel.videoUrl,
|
|
805
|
+
thumbnail_url: reel.thumbnailUrl,
|
|
806
|
+
creator: reel.author,
|
|
807
|
+
avatar_url: reel.profileIconUrl,
|
|
808
|
+
reels_title: reel.title,
|
|
809
|
+
likes_count: reel.likes || 0,
|
|
810
|
+
shares_count: 0,
|
|
811
|
+
view_count: 0,
|
|
812
|
+
reel_source: reel.source || "WEB",
|
|
813
|
+
is_verified: true,
|
|
814
|
+
__typename: "GenAIReelPrimitive"
|
|
815
|
+
})),
|
|
816
|
+
__typename: "GenAIHScrollLayoutViewModel"
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
]
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
const rawMessage = {
|
|
823
|
+
botForwardedMessage: {
|
|
824
|
+
message: {
|
|
825
|
+
richResponseMessage: {
|
|
826
|
+
messageType: 1,
|
|
827
|
+
submessages: [
|
|
828
|
+
{ messageType: 2, messageText: headerText },
|
|
829
|
+
{
|
|
830
|
+
messageType: 9,
|
|
831
|
+
contentItemsMetadata: {
|
|
832
|
+
contentType: 1,
|
|
833
|
+
itemsMetadata: reels.map(r => ({ reelItem: { title: r.title, profileIconUrl: r.profileIconUrl, thumbnailUrl: r.thumbnailUrl, videoUrl: r.videoUrl } }))
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
],
|
|
837
|
+
unifiedResponse: { data: Buffer.from(JSON.stringify(unified)).toString("base64") },
|
|
838
|
+
contextInfo: options.quoted ? {
|
|
839
|
+
isForwarded: true,
|
|
840
|
+
forwardingScore: 1,
|
|
841
|
+
forwardOrigin: 4,
|
|
842
|
+
forwardedAiBotMessageInfo: { botName: "Meta AI", botJid: "867051314767696@bot", creatorName: "Meta" },
|
|
843
|
+
botMessageSharingInfo: { botEntryPointOrigin: String(jid).endsWith('@g.us') ? 30 : 29, forwardScore: 1 },
|
|
844
|
+
stanzaId: options.quoted.key.id,
|
|
845
|
+
participant: options.quoted.sender || options.quoted.key?.participant,
|
|
846
|
+
quotedMessage: options.quoted.message
|
|
847
|
+
} : {}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
},
|
|
851
|
+
messageContextInfo: {
|
|
852
|
+
messageSecret: randomBytes(32),
|
|
853
|
+
botMetadata: {
|
|
854
|
+
modelMetadata: { modelType: "LLAMA_PROD", premiumModelStatus: "AVAILABLE" },
|
|
855
|
+
botResponseId: `reels-${Date.now()}`,
|
|
856
|
+
richResponseSourcesMetadata: {
|
|
857
|
+
sources: reels.map((r, i) => ({
|
|
858
|
+
provider: r.source || "WEB",
|
|
859
|
+
thumbnailCDNURL: r.thumbnailUrl,
|
|
860
|
+
sourceProviderURL: r.videoUrl,
|
|
861
|
+
sourceQuery: query,
|
|
862
|
+
faviconCDNURL: r.profileIconUrl,
|
|
863
|
+
citationNumber: i + 1,
|
|
864
|
+
sourceTitle: r.title
|
|
865
|
+
}))
|
|
866
|
+
},
|
|
867
|
+
capabilityMetadata: { capabilities: ["RICH_RESPONSE_STRUCTURED_RESPONSE", "RICH_RESPONSE_UNIFIED_RESPONSE", "RICH_RESPONSE_UNIFIED_TEXT_COMPONENT", "RICH_RESPONSE_REELS", "SESSION_TRANSPARENCY_SYSTEM_MESSAGE"] }
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
|
|
872
|
+
const msgId = generateMessageIDV2(sock.user?.id);
|
|
873
|
+
return await relayMessage(jid, rawMessage, { messageId: msgId });
|
|
874
|
+
};
|
|
875
|
+
|
|
876
|
+
return {
|
|
877
|
+
...sock,
|
|
878
|
+
getPrivacyTokens,
|
|
879
|
+
assertSessions,
|
|
880
|
+
relayMessage,
|
|
881
|
+
sendReceipt,
|
|
882
|
+
sendReceipts,
|
|
883
|
+
readMessages,
|
|
884
|
+
refreshMediaConn,
|
|
885
|
+
waUploadToServer,
|
|
886
|
+
fetchPrivacySettings,
|
|
887
|
+
sendPeerDataOperationMessage,
|
|
888
|
+
createParticipantNodes,
|
|
889
|
+
getUSyncDevices,
|
|
890
|
+
messageRetryManager,
|
|
891
|
+
hzxx,
|
|
892
|
+
sendRich,
|
|
893
|
+
makeText,
|
|
894
|
+
makeCode,
|
|
895
|
+
makeList,
|
|
896
|
+
makeTable,
|
|
897
|
+
sendRichReels,
|
|
898
|
+
normalizeSystem,
|
|
899
|
+
sendRichText: async (remoteJid, text, quoted = null) => sendRich(remoteJid, [makeText(text)], quoted),
|
|
900
|
+
sendRichCode: async (remoteJid, title, language, code, quoted = null) => {
|
|
901
|
+
const parts = [];
|
|
902
|
+
if (title) parts.push(makeText(title));
|
|
903
|
+
parts.push(makeCode(language, code));
|
|
904
|
+
return sendRich(remoteJid, parts, quoted, ['RICH_RESPONSE_CODE']);
|
|
905
|
+
},
|
|
906
|
+
sendRichList: async (remoteJid, title, items = [], quoted = null) => {
|
|
907
|
+
const parts = [];
|
|
908
|
+
if (title) parts.push(makeText(title));
|
|
909
|
+
parts.push(makeList(items));
|
|
910
|
+
return sendRich(remoteJid, parts, quoted);
|
|
911
|
+
},
|
|
912
|
+
sendRichTable: async (remoteJid, title, rows = [], footer = '', quoted = null) => {
|
|
913
|
+
const parts = [];
|
|
914
|
+
if (title) parts.push(makeText(title));
|
|
915
|
+
parts.push(makeTable(rows));
|
|
916
|
+
if (footer) parts.push(makeText(footer));
|
|
917
|
+
return sendRich(remoteJid, parts, quoted, ['RICH_RESPONSE_TABLE']);
|
|
918
|
+
},
|
|
919
|
+
sendRichFull: async (remoteJid, { title, language, code, items, table, footer } = {}, quoted = null) => {
|
|
920
|
+
const parts = [];
|
|
921
|
+
const caps = [];
|
|
922
|
+
if (title) parts.push(makeText(title));
|
|
923
|
+
if (code) { parts.push(makeCode(language || 'text', code)); caps.push('RICH_RESPONSE_CODE'); }
|
|
924
|
+
if (items?.length) parts.push(makeList(items));
|
|
925
|
+
if (table?.length) { parts.push(makeTable(table)); caps.push('RICH_RESPONSE_TABLE'); }
|
|
926
|
+
if (footer) parts.push(makeText(footer));
|
|
927
|
+
return sendRich(remoteJid, parts, quoted, caps);
|
|
928
|
+
},
|
|
929
|
+
updateMediaMessage: async (message) => {
|
|
930
|
+
const content = assertMediaContent(message.message);
|
|
931
|
+
const mediaKey = content.mediaKey;
|
|
932
|
+
const meId = authState.creds.me.id;
|
|
933
|
+
const node = await encryptMediaRetryRequest(message.key, mediaKey, meId);
|
|
934
|
+
let error = undefined;
|
|
935
|
+
await Promise.all([
|
|
936
|
+
sendNode(node),
|
|
937
|
+
waitForMsgMediaUpdate(async (update) => {
|
|
938
|
+
const result = update.find(c => c.key.id === message.key.id);
|
|
939
|
+
if (result) {
|
|
940
|
+
if (result.error) {
|
|
941
|
+
error = result.error;
|
|
942
|
+
} else {
|
|
943
|
+
try {
|
|
944
|
+
const media = await decryptMediaRetryData(result.media, mediaKey, result.key.id);
|
|
945
|
+
if (media.result !== proto.MediaRetryNotification.ResultType.SUCCESS) {
|
|
946
|
+
const resultStr = proto.MediaRetryNotification.ResultType[media.result];
|
|
947
|
+
throw new Boom(`Media re-upload failed by device (${resultStr})`, {
|
|
948
|
+
data: media,
|
|
949
|
+
statusCode: getStatusCodeForMediaRetry(media.result) || 404
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
content.directPath = media.directPath;
|
|
953
|
+
content.url = getUrlFromDirectPath(content.directPath);
|
|
954
|
+
logger.debug({ directPath: media.directPath, key: result.key }, 'media update successful');
|
|
955
|
+
} catch (err) {
|
|
956
|
+
error = err;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
return true;
|
|
960
|
+
}
|
|
961
|
+
})
|
|
962
|
+
]);
|
|
963
|
+
if (error) throw error;
|
|
964
|
+
ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]);
|
|
965
|
+
return message;
|
|
966
|
+
},
|
|
967
|
+
|
|
968
|
+
sendMessage: async (jid, content, options = {}) => {
|
|
969
|
+
// Smart Router Roteamento Nativo LID / JID
|
|
970
|
+
const cleanTarget = normalizeSystem.cleanId(jid);
|
|
971
|
+
const mappedLid = normalizeSystem.jidLidMemoryCache.get(cleanTarget);
|
|
972
|
+
if (mappedLid) {
|
|
973
|
+
const signalId = signalRepository.jidToSignalProtocolAddress(mappedLid);
|
|
974
|
+
const hasLidSession = peerSessionsCache.get(signalId) || (await signalRepository.validateSession(mappedLid)).exists;
|
|
975
|
+
if (cleanTarget.includes('@s.whatsapp.net') && hasLidSession) {
|
|
976
|
+
jid = mappedLid;
|
|
977
|
+
} else if (cleanTarget.includes('@lid') && !hasLidSession) {
|
|
978
|
+
const mappedPn = normalizeSystem.jidLidMemoryCache.get(cleanTarget);
|
|
979
|
+
if (mappedPn) jid = mappedPn;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
const userJid = authState.creds.me.id;
|
|
984
|
+
const { filter = false, quoted } = options;
|
|
985
|
+
const getParticipantAttr = () => filter ? { participant: { jid } } : {};
|
|
986
|
+
if (content && content.interactiveButtons) {
|
|
987
|
+
const formattedButtons = content.interactiveButtons.map(btn => {
|
|
988
|
+
if (btn.name === 'payment_info' || btn.name === 'review_and_pay') {
|
|
989
|
+
try {
|
|
990
|
+
const params = JSON.parse(btn.buttonParamsJson);
|
|
991
|
+
params.currency = params.currency || 'BRL';
|
|
992
|
+
params.total_amount = params.total_amount || { value: 0, offset: 100 };
|
|
993
|
+
params.reference_id = params.reference_id || randomBytes(4).toString('hex').toUpperCase();
|
|
994
|
+
params.type = params.type || 'physical-goods';
|
|
995
|
+
if (!params.order) {
|
|
996
|
+
params.order = {
|
|
997
|
+
status: 'pending',
|
|
998
|
+
subtotal: params.total_amount,
|
|
999
|
+
order_type: 'ORDER',
|
|
1000
|
+
items: [{
|
|
1001
|
+
name: 'Fatura via Pix',
|
|
1002
|
+
amount: params.total_amount,
|
|
1003
|
+
quantity: 1,
|
|
1004
|
+
sale_amount: params.total_amount
|
|
1005
|
+
}]
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
btn.buttonParamsJson = JSON.stringify(params);
|
|
1010
|
+
} catch (e) {
|
|
1011
|
+
logger.error({ err: e }, "[System Baileys] Erro ao processar JSON de Pagamento Nativo");
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
return btn;
|
|
1015
|
+
});
|
|
1016
|
+
|
|
1017
|
+
const rawMessage = {
|
|
1018
|
+
messageContextInfo: { messageSecret: randomBytes(32) },
|
|
1019
|
+
interactiveMessage: {
|
|
1020
|
+
nativeFlowMessage: { buttons: formattedButtons },
|
|
1021
|
+
contextInfo: options.quoted ? {
|
|
1022
|
+
stanzaId: options.quoted.key.id,
|
|
1023
|
+
participant: options.quoted.sender || options.quoted.key?.participant,
|
|
1024
|
+
quotedMessage: options.quoted.message
|
|
1025
|
+
} : {}
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
|
|
1029
|
+
if (content.text) {
|
|
1030
|
+
rawMessage.interactiveMessage.body = { text: content.text };
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
const msgId = generateMessageIDV2(sock.user?.id);
|
|
1034
|
+
return await relayMessage(jid, rawMessage, { messageId: msgId, ...getParticipantAttr() });
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
if (typeof hzxx.buildMessageContent === 'function') {
|
|
1038
|
+
content = await hzxx.buildMessageContent(content);
|
|
1039
|
+
}
|
|
1040
|
+
const messageType = hzxx.detectType(content);
|
|
1041
|
+
|
|
1042
|
+
if (messageType) {
|
|
1043
|
+
switch(messageType) {
|
|
1044
|
+
case 'PAYMENT':
|
|
1045
|
+
const paymentContent = await hzxx.handlePayment(content, quoted);
|
|
1046
|
+
return await relayMessage(jid, paymentContent, { messageId: generateMessageIDV2(), ...getParticipantAttr() });
|
|
1047
|
+
case 'PRODUCT':
|
|
1048
|
+
const productContent = await hzxx.handleProduct(content, jid, quoted);
|
|
1049
|
+
const productMsg = generateWAMessageFromContent(jid, productContent, { ...options, quoted });
|
|
1050
|
+
return await relayMessage(jid, productMsg.message, { messageId: productMsg.key.id, ...getParticipantAttr() });
|
|
1051
|
+
case 'INTERACTIVE':
|
|
1052
|
+
const interactiveContent = await hzxx.handleInteractive(content, jid, quoted);
|
|
1053
|
+
const interactiveMsg = generateWAMessageFromContent(jid, interactiveContent, { ...options, quoted });
|
|
1054
|
+
|
|
1055
|
+
if (!interactiveMsg.message.messageContextInfo) {
|
|
1056
|
+
interactiveMsg.message.messageContextInfo = {};
|
|
1057
|
+
}
|
|
1058
|
+
interactiveMsg.message.messageContextInfo.deviceListMetadata = {};
|
|
1059
|
+
interactiveMsg.message.messageContextInfo.deviceListMetadataVersion = 2;
|
|
1060
|
+
|
|
1061
|
+
return await relayMessage(jid, interactiveMsg.message, { messageId: interactiveMsg.key.id, ...getParticipantAttr() });
|
|
1062
|
+
case 'ALBUM':
|
|
1063
|
+
return await hzxx.handleAlbum(content, jid, quoted);
|
|
1064
|
+
case 'EVENT':
|
|
1065
|
+
return await hzxx.handleEvent(content, jid, quoted);
|
|
1066
|
+
case 'POLL_RESULT':
|
|
1067
|
+
return await hzxx.handlePollResult(content, jid, quoted);
|
|
1068
|
+
case 'GROUP_STORY':
|
|
1069
|
+
return await hzxx.handleGroupStory(content, jid, quoted);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
if (typeof content === 'object' &&
|
|
1073
|
+
'disappearingMessagesInChat' in content &&
|
|
1074
|
+
typeof content['disappearingMessagesInChat'] !== 'undefined' &&
|
|
1075
|
+
isJidGroup(jid)) {
|
|
1076
|
+
const { disappearingMessagesInChat } = content;
|
|
1077
|
+
const value = typeof disappearingMessagesInChat === 'boolean'
|
|
1078
|
+
? disappearingMessagesInChat
|
|
1079
|
+
? WA_DEFAULT_EPHEMERAL
|
|
1080
|
+
: 0
|
|
1081
|
+
: disappearingMessagesInChat;
|
|
1082
|
+
await groupToggleEphemeral(jid, value);
|
|
1083
|
+
}
|
|
1084
|
+
else {
|
|
1085
|
+
const fullMsg = await generateWAMessage(jid, content, {
|
|
1086
|
+
logger,
|
|
1087
|
+
userJid,
|
|
1088
|
+
getUrlInfo: text => getUrlInfo(text, {
|
|
1089
|
+
thumbnailWidth: linkPreviewImageThumbnailWidth,
|
|
1090
|
+
fetchOpts: {
|
|
1091
|
+
timeout: 3000,
|
|
1092
|
+
...(httpRequestOptions || {})
|
|
1093
|
+
},
|
|
1094
|
+
logger,
|
|
1095
|
+
uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
|
|
1096
|
+
}),
|
|
1097
|
+
getProfilePicUrl: sock.profilePictureUrl,
|
|
1098
|
+
getCallLink: sock.createCallLink,
|
|
1099
|
+
upload: waUploadToServer,
|
|
1100
|
+
mediaCache: config.mediaCache,
|
|
1101
|
+
options: config.options,
|
|
1102
|
+
messageId: generateMessageIDV2(sock.user?.id),
|
|
1103
|
+
...options
|
|
1104
|
+
});
|
|
1105
|
+
const isEventMsg = 'event' in content && !!content.event;
|
|
1106
|
+
const isDeleteMsg = 'delete' in content && !!content.delete;
|
|
1107
|
+
const isEditMsg = 'edit' in content && !!content.edit;
|
|
1108
|
+
const isPinMsg = 'pin' in content && !!content.pin;
|
|
1109
|
+
const isPollMessage = 'poll' in content && !!content.poll;
|
|
1110
|
+
|
|
1111
|
+
const isAiMsg = 'ai' in content && !!content.ai;
|
|
1112
|
+
|
|
1113
|
+
const additionalAttributes = {};
|
|
1114
|
+
const additionalNodes = [];
|
|
1115
|
+
if (isDeleteMsg) {
|
|
1116
|
+
if (isJidGroup(content.delete?.remoteJid) && !content.delete?.fromMe) {
|
|
1117
|
+
additionalAttributes.edit = '8';
|
|
1118
|
+
} else {
|
|
1119
|
+
additionalAttributes.edit = '7';
|
|
1120
|
+
}
|
|
1121
|
+
} else if (isEditMsg) {
|
|
1122
|
+
additionalAttributes.edit = '1';
|
|
1123
|
+
} else if (isPinMsg) {
|
|
1124
|
+
additionalAttributes.edit = '2';
|
|
1125
|
+
} else if (isPollMessage) {
|
|
1126
|
+
additionalNodes.push({ tag: 'meta', attrs: { polltype: 'creation' } });
|
|
1127
|
+
} else if (isEventMsg) {
|
|
1128
|
+
additionalNodes.push({ tag: 'meta', attrs: { event_type: 'creation' } });
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
if (isAiMsg) {
|
|
1132
|
+
additionalNodes.push({ tag: 'bot', attrs: { biz_bot: '1' } });
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
await relayMessage(jid, fullMsg.message, {
|
|
1136
|
+
messageId: fullMsg.key.id,
|
|
1137
|
+
useCachedGroupMetadata: options.useCachedGroupMetadata,
|
|
1138
|
+
additionalAttributes,
|
|
1139
|
+
statusJidList: options.statusJidList,
|
|
1140
|
+
additionalNodes
|
|
1141
|
+
});
|
|
1142
|
+
if (config.emitOwnEvents) {
|
|
1143
|
+
process.nextTick(async () => {
|
|
1144
|
+
await processingMutex.mutex(() => upsertMessage(fullMsg, 'append'));
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
return fullMsg;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
};
|
|
1151
|
+
};
|
|
1152
|
+
//# sourceMappingURL=messages-send.js.map
|