@queenanya/baileys 9.2.1 → 9.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +349 -1171
- package/WAProto/fix-imports.js +74 -18
- package/WAProto/index.js +201 -160
- package/engine-requirements.js +7 -7
- package/lib/Defaults/index.d.ts +19 -0
- package/lib/Defaults/index.d.ts.map +1 -1
- package/lib/Defaults/index.js +32 -6
- package/lib/Defaults/index.js.map +1 -1
- package/lib/Signal/libsignal.d.ts.map +1 -1
- package/lib/Signal/libsignal.js +61 -2
- package/lib/Signal/libsignal.js.map +1 -1
- package/lib/Signal/lid-mapping.d.ts +5 -9
- package/lib/Signal/lid-mapping.d.ts.map +1 -1
- package/lib/Signal/lid-mapping.js +170 -70
- package/lib/Signal/lid-mapping.js.map +1 -1
- package/lib/Socket/Client/websocket.d.ts +1 -1
- package/lib/Socket/Client/websocket.d.ts.map +1 -1
- package/lib/Socket/Client/websocket.js +5 -1
- package/lib/Socket/Client/websocket.js.map +1 -1
- package/lib/Socket/business.d.ts +125 -5
- package/lib/Socket/business.d.ts.map +1 -1
- package/lib/Socket/business.js +11 -8
- package/lib/Socket/business.js.map +1 -1
- package/lib/Socket/chats.d.ts +22 -3
- package/lib/Socket/chats.d.ts.map +1 -1
- package/lib/Socket/chats.js +277 -58
- package/lib/Socket/chats.js.map +1 -1
- package/lib/Socket/communities.d.ts +125 -5
- package/lib/Socket/communities.d.ts.map +1 -1
- package/lib/Socket/groups.d.ts +19 -3
- package/lib/Socket/groups.d.ts.map +1 -1
- package/lib/Socket/groups.js +7 -1
- package/lib/Socket/groups.js.map +1 -1
- package/lib/Socket/index.d.ts +125 -5
- package/lib/Socket/index.d.ts.map +1 -1
- package/lib/Socket/index.js +0 -6
- package/lib/Socket/index.js.map +1 -1
- package/lib/Socket/messages-recv.d.ts +126 -6
- package/lib/Socket/messages-recv.d.ts.map +1 -1
- package/lib/Socket/messages-recv.js +771 -177
- package/lib/Socket/messages-recv.js.map +1 -1
- package/lib/Socket/messages-send.d.ts +129 -7
- package/lib/Socket/messages-send.d.ts.map +1 -1
- package/lib/Socket/messages-send.js +430 -119
- package/lib/Socket/messages-send.js.map +1 -1
- package/lib/Socket/newsletter.d.ts +20 -5
- package/lib/Socket/newsletter.d.ts.map +1 -1
- package/lib/Socket/newsletter.js +2 -47
- package/lib/Socket/newsletter.js.map +1 -1
- package/lib/Socket/socket.d.ts +3 -1
- package/lib/Socket/socket.d.ts.map +1 -1
- package/lib/Socket/socket.js +151 -29
- package/lib/Socket/socket.js.map +1 -1
- package/lib/Types/Auth.d.ts +2 -0
- package/lib/Types/Auth.d.ts.map +1 -1
- package/lib/Types/Call.d.ts +10 -1
- package/lib/Types/Call.d.ts.map +1 -1
- package/lib/Types/Contact.d.ts +2 -0
- package/lib/Types/Contact.d.ts.map +1 -1
- package/lib/Types/Events.d.ts +60 -6
- package/lib/Types/Events.d.ts.map +1 -1
- package/lib/Types/GroupMetadata.d.ts +4 -0
- package/lib/Types/GroupMetadata.d.ts.map +1 -1
- package/lib/Types/Message.d.ts +530 -16
- package/lib/Types/Message.d.ts.map +1 -1
- package/lib/Types/Message.js.map +1 -1
- package/lib/Types/Newsletter.d.ts +32 -45
- package/lib/Types/Newsletter.d.ts.map +1 -1
- package/lib/Types/Newsletter.js +25 -23
- package/lib/Types/Newsletter.js.map +1 -1
- package/lib/Types/State.d.ts +54 -0
- package/lib/Types/State.d.ts.map +1 -1
- package/lib/Types/State.js +42 -0
- package/lib/Types/State.js.map +1 -1
- package/lib/Types/index.d.ts +9 -0
- package/lib/Types/index.d.ts.map +1 -1
- package/lib/Types/index.js.map +1 -1
- package/lib/Utils/auth-utils.d.ts.map +1 -1
- package/lib/Utils/auth-utils.js +53 -20
- package/lib/Utils/auth-utils.js.map +1 -1
- package/lib/Utils/browser-utils.d.ts +13 -0
- package/lib/Utils/browser-utils.d.ts.map +1 -1
- package/lib/Utils/browser-utils.js +90 -10
- package/lib/Utils/browser-utils.js.map +1 -1
- package/lib/Utils/chat-utils.d.ts +30 -0
- package/lib/Utils/chat-utils.d.ts.map +1 -1
- package/lib/Utils/chat-utils.js +134 -59
- package/lib/Utils/chat-utils.js.map +1 -1
- package/lib/Utils/companion-reg-client-utils.d.ts +17 -0
- package/lib/Utils/companion-reg-client-utils.d.ts.map +1 -0
- package/lib/Utils/companion-reg-client-utils.js +34 -0
- package/lib/Utils/companion-reg-client-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +4 -8
- package/lib/Utils/crypto.d.ts.map +1 -1
- package/lib/Utils/crypto.js +2 -26
- package/lib/Utils/crypto.js.map +1 -1
- package/lib/Utils/decode-wa-message.d.ts +12 -0
- package/lib/Utils/decode-wa-message.d.ts.map +1 -1
- package/lib/Utils/decode-wa-message.js +16 -0
- package/lib/Utils/decode-wa-message.js.map +1 -1
- package/lib/Utils/event-buffer.d.ts.map +1 -1
- package/lib/Utils/event-buffer.js +43 -8
- package/lib/Utils/event-buffer.js.map +1 -1
- package/lib/Utils/generics.d.ts +3 -1
- package/lib/Utils/generics.d.ts.map +1 -1
- package/lib/Utils/generics.js +17 -4
- package/lib/Utils/generics.js.map +1 -1
- package/lib/Utils/history.d.ts +8 -3
- package/lib/Utils/history.d.ts.map +1 -1
- package/lib/Utils/history.js +60 -16
- package/lib/Utils/history.js.map +1 -1
- 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 +6 -0
- package/lib/Utils/index.d.ts.map +1 -1
- package/lib/Utils/index.js +6 -0
- package/lib/Utils/index.js.map +1 -1
- package/lib/Utils/interactive-message.d.ts +201 -0
- package/lib/Utils/interactive-message.d.ts.map +1 -0
- package/lib/Utils/interactive-message.js +256 -0
- package/lib/Utils/interactive-message.js.map +1 -0
- package/lib/Utils/lt-hash.d.ts +7 -12
- package/lib/Utils/lt-hash.d.ts.map +1 -1
- package/lib/Utils/lt-hash.js +2 -42
- package/lib/Utils/lt-hash.js.map +1 -1
- package/lib/Utils/make-mutex.d.ts +1 -0
- package/lib/Utils/make-mutex.d.ts.map +1 -1
- package/lib/Utils/make-mutex.js +20 -27
- package/lib/Utils/make-mutex.js.map +1 -1
- package/lib/Utils/message-composer.d.ts +5 -0
- package/lib/Utils/message-composer.d.ts.map +1 -0
- package/lib/Utils/message-composer.js +5 -0
- package/lib/Utils/message-composer.js.map +1 -0
- package/lib/Utils/message-retry-manager.d.ts +30 -2
- package/lib/Utils/message-retry-manager.d.ts.map +1 -1
- package/lib/Utils/message-retry-manager.js +58 -5
- package/lib/Utils/message-retry-manager.js.map +1 -1
- package/lib/Utils/messages-media.d.ts +35 -5
- package/lib/Utils/messages-media.d.ts.map +1 -1
- package/lib/Utils/messages-media.js +171 -51
- package/lib/Utils/messages-media.js.map +1 -1
- package/lib/Utils/messages.d.ts +2 -0
- package/lib/Utils/messages.d.ts.map +1 -1
- package/lib/Utils/messages.js +475 -35
- package/lib/Utils/messages.js.map +1 -1
- package/lib/Utils/noise-handler.d.ts +4 -4
- package/lib/Utils/noise-handler.d.ts.map +1 -1
- package/lib/Utils/noise-handler.js +139 -85
- package/lib/Utils/noise-handler.js.map +1 -1
- 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/process-message.d.ts.map +1 -1
- package/lib/Utils/process-message.js +115 -16
- package/lib/Utils/process-message.js.map +1 -1
- 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/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 +163 -0
- package/lib/Utils/tc-token-utils.js.map +1 -0
- package/lib/Utils/use-mongo-file-auth-state.d.ts +16 -0
- package/lib/Utils/use-mongo-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-mongo-file-auth-state.js +60 -0
- package/lib/Utils/use-mongo-file-auth-state.js.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +1 -1
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -1
- package/lib/Utils/use-single-file-auth-state.d.ts.map +1 -1
- package/lib/Utils/use-single-file-auth-state.js.map +1 -1
- package/lib/Utils/validate-connection.d.ts.map +1 -1
- package/lib/Utils/validate-connection.js +11 -1
- package/lib/Utils/validate-connection.js.map +1 -1
- package/lib/WABinary/decode.d.ts.map +1 -1
- package/lib/WABinary/decode.js +24 -0
- package/lib/WABinary/decode.js.map +1 -1
- package/lib/WABinary/encode.js +5 -1
- package/lib/WABinary/encode.js.map +1 -1
- package/lib/WABinary/generic-utils.d.ts +10 -1
- package/lib/WABinary/generic-utils.d.ts.map +1 -1
- package/lib/WABinary/generic-utils.js +42 -8
- package/lib/WABinary/generic-utils.js.map +1 -1
- package/lib/WABinary/jid-utils.js.map +1 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +26 -3
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -1
- 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/index.d.ts +1 -0
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/index.js +1 -0
- package/lib/WAUSync/Protocols/index.js.map +1 -1
- package/lib/WAUSync/USyncQuery.d.ts +1 -0
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -1
- package/lib/WAUSync/USyncQuery.js +6 -2
- package/lib/WAUSync/USyncQuery.js.map +1 -1
- package/lib/WAUSync/USyncUser.d.ts +4 -0
- package/lib/WAUSync/USyncUser.d.ts.map +1 -1
- package/lib/WAUSync/USyncUser.js +8 -0
- package/lib/WAUSync/USyncUser.js.map +1 -1
- package/lib/addons/anti-delete.d.ts +72 -0
- package/lib/addons/anti-delete.d.ts.map +1 -0
- package/lib/addons/anti-delete.js +165 -0
- package/lib/addons/anti-delete.js.map +1 -0
- package/lib/addons/auto-reply.d.ts +67 -0
- package/lib/addons/auto-reply.d.ts.map +1 -0
- package/lib/addons/auto-reply.js +145 -0
- package/lib/addons/auto-reply.js.map +1 -0
- package/lib/addons/browser-presets.d.ts +16 -0
- package/lib/addons/browser-presets.d.ts.map +1 -0
- package/lib/addons/browser-presets.js +24 -0
- package/lib/addons/browser-presets.js.map +1 -0
- package/lib/addons/button-sender.d.ts +260 -0
- package/lib/addons/button-sender.d.ts.map +1 -0
- package/lib/addons/button-sender.js +771 -0
- package/lib/addons/button-sender.js.map +1 -0
- package/lib/addons/call-handler.d.ts +79 -0
- package/lib/addons/call-handler.d.ts.map +1 -0
- package/lib/addons/call-handler.js +342 -0
- package/lib/addons/call-handler.js.map +1 -0
- package/lib/addons/from-chats.d.ts +30 -0
- package/lib/addons/from-chats.d.ts.map +1 -0
- package/lib/addons/from-chats.js +38 -0
- package/lib/addons/from-chats.js.map +1 -0
- package/lib/addons/from-messages-recv.d.ts +59 -0
- package/lib/addons/from-messages-recv.d.ts.map +1 -0
- package/lib/addons/from-messages-recv.js +326 -0
- package/lib/addons/from-messages-recv.js.map +1 -0
- package/lib/addons/from-messages-send.d.ts +50 -0
- package/lib/addons/from-messages-send.d.ts.map +1 -0
- package/lib/addons/from-messages-send.js +148 -0
- package/lib/addons/from-messages-send.js.map +1 -0
- package/lib/addons/from-messages.d.ts +52 -0
- package/lib/addons/from-messages.d.ts.map +1 -0
- package/lib/addons/from-messages.js +304 -0
- package/lib/addons/from-messages.js.map +1 -0
- package/lib/addons/index.d.ts +67 -0
- package/lib/addons/index.d.ts.map +1 -0
- package/lib/addons/index.js +86 -0
- package/lib/addons/index.js.map +1 -0
- package/lib/addons/interactive-message.d.ts +201 -0
- package/lib/addons/interactive-message.d.ts.map +1 -0
- package/lib/addons/interactive-message.js +256 -0
- package/lib/addons/interactive-message.js.map +1 -0
- package/lib/addons/jid-plot.d.ts +49 -0
- package/lib/addons/jid-plot.d.ts.map +1 -0
- package/lib/addons/jid-plot.js +84 -0
- package/lib/addons/jid-plot.js.map +1 -0
- package/lib/addons/jid-plotting.d.ts +54 -0
- package/lib/addons/jid-plotting.d.ts.map +1 -0
- package/lib/addons/jid-plotting.js +150 -0
- package/lib/addons/jid-plotting.js.map +1 -0
- package/lib/addons/lid-support.d.ts +41 -0
- package/lib/addons/lid-support.d.ts.map +1 -0
- package/lib/addons/lid-support.js +42 -0
- package/lib/addons/lid-support.js.map +1 -0
- package/lib/addons/message-composer.d.ts +142 -0
- package/lib/addons/message-composer.d.ts.map +1 -0
- package/lib/addons/message-composer.js +377 -0
- package/lib/addons/message-composer.js.map +1 -0
- package/lib/addons/message-scheduler.d.ts +77 -0
- package/lib/addons/message-scheduler.d.ts.map +1 -0
- package/lib/addons/message-scheduler.js +108 -0
- package/lib/addons/message-scheduler.js.map +1 -0
- package/lib/addons/message-search.d.ts +51 -0
- package/lib/addons/message-search.d.ts.map +1 -0
- package/lib/addons/message-search.js +171 -0
- package/lib/addons/message-search.js.map +1 -0
- package/lib/addons/message-utils.d.ts +88 -0
- package/lib/addons/message-utils.d.ts.map +1 -0
- package/lib/addons/message-utils.js +292 -0
- package/lib/addons/message-utils.js.map +1 -0
- package/lib/addons/outgoing-calls.d.ts +64 -0
- package/lib/addons/outgoing-calls.d.ts.map +1 -0
- package/lib/addons/outgoing-calls.js +139 -0
- package/lib/addons/outgoing-calls.js.map +1 -0
- package/lib/addons/pairing-fix.d.ts +31 -0
- package/lib/addons/pairing-fix.d.ts.map +1 -0
- package/lib/addons/pairing-fix.js +74 -0
- package/lib/addons/pairing-fix.js.map +1 -0
- package/lib/addons/past-participants.d.ts +42 -0
- package/lib/addons/past-participants.d.ts.map +1 -0
- package/lib/addons/past-participants.js +41 -0
- package/lib/addons/past-participants.js.map +1 -0
- package/lib/addons/rich-response.d.ts +111 -0
- package/lib/addons/rich-response.d.ts.map +1 -0
- package/lib/addons/rich-response.js +152 -0
- package/lib/addons/rich-response.js.map +1 -0
- package/lib/addons/scheduling.d.ts +41 -0
- package/lib/addons/scheduling.d.ts.map +1 -0
- package/lib/addons/scheduling.js +110 -0
- package/lib/addons/scheduling.js.map +1 -0
- package/lib/addons/status-posting.d.ts +177 -0
- package/lib/addons/status-posting.d.ts.map +1 -0
- package/lib/addons/status-posting.js +240 -0
- package/lib/addons/status-posting.js.map +1 -0
- package/lib/addons/stickerpack.d.ts +37 -0
- package/lib/addons/stickerpack.d.ts.map +1 -0
- package/lib/addons/stickerpack.js +39 -0
- package/lib/addons/stickerpack.js.map +1 -0
- package/lib/addons/templates.d.ts +72 -0
- package/lib/addons/templates.d.ts.map +1 -0
- package/lib/addons/templates.js +145 -0
- package/lib/addons/templates.js.map +1 -0
- package/lib/addons/vcard.d.ts +59 -0
- package/lib/addons/vcard.d.ts.map +1 -0
- package/lib/addons/vcard.js +88 -0
- package/lib/addons/vcard.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/package.json +6 -3
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
import NodeCache from '@cacheable/node-cache';
|
|
2
2
|
import { Boom } from '@hapi/boom';
|
|
3
|
+
import { randomBytes } from 'crypto';
|
|
3
4
|
import { proto } from '../../WAProto/index.js';
|
|
5
|
+
import { execSendStatusMentions } from '../addons/from-messages-send.js';
|
|
6
|
+
import { extractUnifiedResponse, generateCodeBlockContent, generateLatexContent, generateLatexImageContent, generateLatexInlineImageContent, generateListContent, generateRichMessageContent, generateTableContent, generateUnifiedResponseContent } from '../addons/message-composer.js';
|
|
7
|
+
import { getButtonArgs, getButtonType, getMediaType, getMessageType } from '../addons/message-utils.js';
|
|
4
8
|
import { DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
|
|
5
|
-
import { aggregateMessageKeysNotFromMe, assertMediaContent, bindWaitForEvent, decryptMediaRetryData, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateParticipantHashV2, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils/index.js';
|
|
9
|
+
import { aggregateMessageKeysNotFromMe, assertMediaContent, bindWaitForEvent, decryptMediaRetryData, delay, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateParticipantHashV2, generateWAMessage, generateWAMessageFromContent, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils/index.js';
|
|
6
10
|
import { getUrlInfo } from '../Utils/link-preview.js';
|
|
7
11
|
import { makeKeyedMutex } from '../Utils/make-mutex.js';
|
|
8
|
-
import {
|
|
12
|
+
import { getMessageReportingToken, shouldIncludeReportingToken } from '../Utils/reporting-utils.js';
|
|
13
|
+
import { buildMergedTcTokenIndexWrite, isTcTokenExpired, resolveIssuanceJid, resolveTcTokenJid, shouldSendNewTcToken, storeTcTokensFromIqResult } from '../Utils/tc-token-utils.js';
|
|
14
|
+
import { areJidsSameUser, getBinaryFilteredBizBot, getBinaryFilteredButtons, getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isJidBot, isJidGroup, isJidMetaAI, isJidNewsletter, isLidUser, isPnUser, jidDecode, jidEncode, jidNormalizedUser, PSA_WID, S_WHATSAPP_NET } from '../WABinary/index.js';
|
|
9
15
|
import { USyncQuery, USyncUser } from '../WAUSync/index.js';
|
|
10
16
|
import { makeNewsletterSocket } from './newsletter.js';
|
|
11
17
|
export const makeMessagesSocket = (config) => {
|
|
12
18
|
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: httpRequestOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache, maxMsgRetryCount } = config;
|
|
13
19
|
const sock = makeNewsletterSocket(config);
|
|
14
|
-
const { ev, authState,
|
|
20
|
+
const { ev, authState, messageMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral } = sock;
|
|
21
|
+
const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping);
|
|
22
|
+
/**
|
|
23
|
+
* Set of tctoken storage JIDs with a fire-and-forget `issuePrivacyTokens` IQ in flight.
|
|
24
|
+
* Prevents duplicate IQs from rapid back-to-back sends before `senderTimestamp` persists.
|
|
25
|
+
*/
|
|
26
|
+
const inFlightTcTokenIssuance = new Set();
|
|
15
27
|
const userDevicesCache = config.userDevicesCache ||
|
|
16
28
|
new NodeCache({
|
|
17
29
|
stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
|
|
@@ -254,6 +266,34 @@ export const makeMessagesSocket = (config) => {
|
|
|
254
266
|
}
|
|
255
267
|
return deviceResults;
|
|
256
268
|
};
|
|
269
|
+
/**
|
|
270
|
+
* Update Member Label
|
|
271
|
+
*/
|
|
272
|
+
const updateMemberLabel = (jid, memberLabel) => {
|
|
273
|
+
if (!isJidGroup(jid)) {
|
|
274
|
+
throw new Error('Jid must a group jid!');
|
|
275
|
+
}
|
|
276
|
+
return relayMessage(jid, {
|
|
277
|
+
protocolMessage: {
|
|
278
|
+
type: proto.Message.ProtocolMessage.Type.GROUP_MEMBER_LABEL_CHANGE,
|
|
279
|
+
memberLabel: {
|
|
280
|
+
label: memberLabel?.slice(0, 30),
|
|
281
|
+
labelTimestamp: unixTimestampSeconds()
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}, {
|
|
285
|
+
additionalNodes: [
|
|
286
|
+
{
|
|
287
|
+
tag: 'meta',
|
|
288
|
+
attrs: {
|
|
289
|
+
tag_reason: 'user_update',
|
|
290
|
+
appdata: 'member_tag'
|
|
291
|
+
},
|
|
292
|
+
content: undefined
|
|
293
|
+
}
|
|
294
|
+
]
|
|
295
|
+
});
|
|
296
|
+
};
|
|
257
297
|
const assertSessions = async (jids, force) => {
|
|
258
298
|
let didFetchNewSession = false;
|
|
259
299
|
const uniqueJids = [...new Set(jids)]; // Deduplicate JIDs
|
|
@@ -354,59 +394,63 @@ export const makeMessagesSocket = (config) => {
|
|
|
354
394
|
const meLid = authState.creds.me?.lid;
|
|
355
395
|
const meLidUser = meLid ? jidDecode(meLid)?.user : null;
|
|
356
396
|
const encryptionPromises = patchedMessages.map(async ({ recipientJid: jid, message: patchedMessage }) => {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
const
|
|
375
|
-
jid,
|
|
376
|
-
|
|
397
|
+
try {
|
|
398
|
+
if (!jid)
|
|
399
|
+
return null;
|
|
400
|
+
let msgToEncrypt = patchedMessage;
|
|
401
|
+
if (dsmMessage) {
|
|
402
|
+
const { user: targetUser } = jidDecode(jid);
|
|
403
|
+
const { user: ownPnUser } = jidDecode(meId);
|
|
404
|
+
const ownLidUser = meLidUser;
|
|
405
|
+
const isOwnUser = targetUser === ownPnUser || (ownLidUser && targetUser === ownLidUser);
|
|
406
|
+
const isExactSenderDevice = jid === meId || (meLid && jid === meLid);
|
|
407
|
+
if (isOwnUser && !isExactSenderDevice) {
|
|
408
|
+
msgToEncrypt = dsmMessage;
|
|
409
|
+
logger.debug({ jid, targetUser }, 'Using DSM for own device');
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
const bytes = encodeWAMessage(msgToEncrypt);
|
|
413
|
+
const mutexKey = jid;
|
|
414
|
+
const node = await encryptionMutex.mutex(mutexKey, async () => {
|
|
415
|
+
const { type, ciphertext } = await signalRepository.encryptMessage({ jid, data: bytes });
|
|
416
|
+
if (type === 'pkmsg') {
|
|
417
|
+
shouldIncludeDeviceIdentity = true;
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
tag: 'to',
|
|
421
|
+
attrs: { jid },
|
|
422
|
+
content: [
|
|
423
|
+
{
|
|
424
|
+
tag: 'enc',
|
|
425
|
+
attrs: { v: '2', type, ...(extraAttrs || {}) },
|
|
426
|
+
content: ciphertext
|
|
427
|
+
}
|
|
428
|
+
]
|
|
429
|
+
};
|
|
377
430
|
});
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
content: [
|
|
385
|
-
{
|
|
386
|
-
tag: 'enc',
|
|
387
|
-
attrs: {
|
|
388
|
-
v: '2',
|
|
389
|
-
type,
|
|
390
|
-
...(extraAttrs || {})
|
|
391
|
-
},
|
|
392
|
-
content: ciphertext
|
|
393
|
-
}
|
|
394
|
-
]
|
|
395
|
-
};
|
|
396
|
-
});
|
|
397
|
-
return node;
|
|
431
|
+
return node;
|
|
432
|
+
}
|
|
433
|
+
catch (err) {
|
|
434
|
+
logger.error({ jid, err }, 'Failed to encrypt for recipient');
|
|
435
|
+
return null;
|
|
436
|
+
}
|
|
398
437
|
});
|
|
399
438
|
const nodes = (await Promise.all(encryptionPromises)).filter(node => node !== null);
|
|
439
|
+
if (recipientJids.length > 0 && nodes.length === 0) {
|
|
440
|
+
throw new Boom('All encryptions failed', { statusCode: 500 });
|
|
441
|
+
}
|
|
400
442
|
return { nodes, shouldIncludeDeviceIdentity };
|
|
401
443
|
};
|
|
402
|
-
const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList }) => {
|
|
444
|
+
const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList, AI = false }) => {
|
|
403
445
|
const meId = authState.creds.me.id;
|
|
404
446
|
const meLid = authState.creds.me?.lid;
|
|
405
447
|
const isRetryResend = Boolean(participant?.jid);
|
|
406
448
|
let shouldIncludeDeviceIdentity = isRetryResend;
|
|
449
|
+
let didPushAdditional = false;
|
|
407
450
|
const statusJid = 'status@broadcast';
|
|
408
451
|
const { user, server } = jidDecode(jid);
|
|
409
452
|
const isGroup = server === 'g.us';
|
|
453
|
+
const isPrivate = server === 's.whatsapp.net';
|
|
410
454
|
const isStatus = jid === statusJid;
|
|
411
455
|
const isLid = server === 'lid';
|
|
412
456
|
const isNewsletter = server === 'newsletter';
|
|
@@ -419,6 +463,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
419
463
|
const destinationJid = !isStatus ? finalJid : statusJid;
|
|
420
464
|
const binaryNodeContent = [];
|
|
421
465
|
const devices = [];
|
|
466
|
+
let reportingMessage;
|
|
422
467
|
const meMsg = {
|
|
423
468
|
deviceSentMessage: {
|
|
424
469
|
destinationJid,
|
|
@@ -427,6 +472,10 @@ export const makeMessagesSocket = (config) => {
|
|
|
427
472
|
messageContextInfo: message.messageContextInfo
|
|
428
473
|
};
|
|
429
474
|
const extraAttrs = {};
|
|
475
|
+
// normalizeMessageContent BEFORE transaction — exact addons pattern
|
|
476
|
+
const messages = normalizeMessageContent(message) || message;
|
|
477
|
+
const buttonType = getButtonType(messages);
|
|
478
|
+
const pollMessage = messages.pollCreationMessage || messages.pollCreationMessageV2 || messages.pollCreationMessageV3;
|
|
430
479
|
if (participant) {
|
|
431
480
|
if (!isGroup && !isStatus) {
|
|
432
481
|
additionalAttributes = { ...additionalAttributes, device_fanout: 'false' };
|
|
@@ -439,7 +488,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
439
488
|
});
|
|
440
489
|
}
|
|
441
490
|
await authState.keys.transaction(async () => {
|
|
442
|
-
const mediaType = getMediaType(
|
|
491
|
+
const mediaType = getMediaType(messages);
|
|
443
492
|
if (mediaType) {
|
|
444
493
|
extraAttrs['mediatype'] = mediaType;
|
|
445
494
|
}
|
|
@@ -448,7 +497,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
448
497
|
const bytes = encodeNewsletterMessage(patched);
|
|
449
498
|
binaryNodeContent.push({
|
|
450
499
|
tag: 'plaintext',
|
|
451
|
-
attrs: {},
|
|
500
|
+
attrs: mediaType ? { mediatype: mediaType } : {},
|
|
452
501
|
content: bytes
|
|
453
502
|
});
|
|
454
503
|
const stanza = {
|
|
@@ -465,7 +514,10 @@ export const makeMessagesSocket = (config) => {
|
|
|
465
514
|
await sendNode(stanza);
|
|
466
515
|
return;
|
|
467
516
|
}
|
|
468
|
-
if (
|
|
517
|
+
if (messages.pinInChatMessage ||
|
|
518
|
+
messages.keepInChatMessage ||
|
|
519
|
+
messages.reactionMessage ||
|
|
520
|
+
messages.protocolMessage?.editedMessage) {
|
|
469
521
|
extraAttrs['decrypt-fail'] = 'hide'; // todo: expand for reactions and other types
|
|
470
522
|
}
|
|
471
523
|
if (isGroupOrStatus && !isRetryResend) {
|
|
@@ -513,6 +565,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
513
565
|
throw new Boom('Per-jid patching is not supported in groups');
|
|
514
566
|
}
|
|
515
567
|
const bytes = encodeWAMessage(patched);
|
|
568
|
+
reportingMessage = patched;
|
|
516
569
|
const groupAddressingMode = additionalAttributes?.['addressing_mode'] || groupData?.addressingMode || 'lid';
|
|
517
570
|
const groupSenderIdentity = groupAddressingMode === 'lid' && meLid ? meLid : meId;
|
|
518
571
|
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({
|
|
@@ -567,6 +620,12 @@ export const makeMessagesSocket = (config) => {
|
|
|
567
620
|
logger.debug({ to: jid, ownId }, 'Using PN identity for @s.whatsapp.net conversation');
|
|
568
621
|
}
|
|
569
622
|
const { user: ownUser } = jidDecode(ownId);
|
|
623
|
+
if (!participant) {
|
|
624
|
+
const patchedForReporting = await patchMessageBeforeSending(message, [jid]);
|
|
625
|
+
reportingMessage = Array.isArray(patchedForReporting)
|
|
626
|
+
? patchedForReporting.find(item => item.recipientJid === jid) || patchedForReporting[0]
|
|
627
|
+
: patchedForReporting;
|
|
628
|
+
}
|
|
570
629
|
if (!isRetryResend) {
|
|
571
630
|
const targetUserServer = isLid ? 'lid' : 's.whatsapp.net';
|
|
572
631
|
devices.push({
|
|
@@ -711,9 +770,52 @@ export const makeMessagesSocket = (config) => {
|
|
|
711
770
|
});
|
|
712
771
|
logger.debug({ jid }, 'adding device identity');
|
|
713
772
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
773
|
+
if (!isNewsletter &&
|
|
774
|
+
!isRetryResend &&
|
|
775
|
+
reportingMessage?.messageContextInfo?.messageSecret &&
|
|
776
|
+
shouldIncludeReportingToken(reportingMessage)) {
|
|
777
|
+
try {
|
|
778
|
+
const encoded = encodeWAMessage(reportingMessage);
|
|
779
|
+
const reportingKey = {
|
|
780
|
+
id: msgId,
|
|
781
|
+
fromMe: true,
|
|
782
|
+
remoteJid: destinationJid,
|
|
783
|
+
participant: participant?.jid
|
|
784
|
+
};
|
|
785
|
+
const reportingNode = await getMessageReportingToken(encoded, reportingMessage, reportingKey);
|
|
786
|
+
if (reportingNode) {
|
|
787
|
+
;
|
|
788
|
+
stanza.content.push(reportingNode);
|
|
789
|
+
logger.trace({ jid }, 'added reporting token to message');
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
catch (error) {
|
|
793
|
+
logger.warn({ jid, trace: error?.stack }, 'failed to attach reporting token');
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
// WA Web never attaches tctoken to peer (AppStateSync) messages — server rejects with 479
|
|
797
|
+
const isPeerMessage = additionalAttributes?.['category'] === 'peer';
|
|
798
|
+
const is1on1Send = !isGroup && !isRetryResend && !isStatus && !isNewsletter && !isPeerMessage;
|
|
799
|
+
// Resolve destination to LID for tctoken storage — matches Signal session key pattern
|
|
800
|
+
const tcTokenJid = is1on1Send ? await resolveTcTokenJid(destinationJid, getLIDForPN) : destinationJid;
|
|
801
|
+
const contactTcTokenData = is1on1Send ? await authState.keys.get('tctoken', [tcTokenJid]) : {};
|
|
802
|
+
const existingTokenEntry = contactTcTokenData[tcTokenJid];
|
|
803
|
+
let tcTokenBuffer = existingTokenEntry?.token;
|
|
804
|
+
// Treat expired tokens the same as missing — clear from cache
|
|
805
|
+
if (tcTokenBuffer?.length && isTcTokenExpired(existingTokenEntry?.timestamp)) {
|
|
806
|
+
logger.debug({ jid: destinationJid, timestamp: existingTokenEntry?.timestamp }, 'tctoken expired, clearing');
|
|
807
|
+
tcTokenBuffer = undefined;
|
|
808
|
+
const cleared = existingTokenEntry?.senderTimestamp !== undefined
|
|
809
|
+
? { token: Buffer.alloc(0), senderTimestamp: existingTokenEntry.senderTimestamp }
|
|
810
|
+
: null;
|
|
811
|
+
try {
|
|
812
|
+
await authState.keys.set({ tctoken: { [tcTokenJid]: cleared } });
|
|
813
|
+
}
|
|
814
|
+
catch (err) {
|
|
815
|
+
logger.debug({ jid: destinationJid, err: err?.message }, 'failed to persist tctoken expiry cleanup');
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
if (tcTokenBuffer?.length && sock.serverProps.privacyTokenOn1to1) {
|
|
717
819
|
;
|
|
718
820
|
stanza.content.push({
|
|
719
821
|
tag: 'tctoken',
|
|
@@ -721,12 +823,116 @@ export const makeMessagesSocket = (config) => {
|
|
|
721
823
|
content: tcTokenBuffer
|
|
722
824
|
});
|
|
723
825
|
}
|
|
724
|
-
|
|
826
|
+
// Inject poll/event meta node directly in relayMessage
|
|
827
|
+
// (mirrors innovators — handles direct relayMessage calls, not just sendMessage)
|
|
828
|
+
if (pollMessage || messages.eventMessage) {
|
|
829
|
+
const hasPollMeta = (additionalNodes ?? []).some((n) => n.tag === 'meta' && ('polltype' in n.attrs || 'event_type' in n.attrs));
|
|
830
|
+
if (!hasPollMeta) {
|
|
831
|
+
const metaAttrs = messages.eventMessage
|
|
832
|
+
? { event_type: 'creation' }
|
|
833
|
+
: isNewsletter
|
|
834
|
+
? {
|
|
835
|
+
polltype: 'creation',
|
|
836
|
+
contenttype: pollMessage?.pollContentType === 2 ? 'image' : 'text'
|
|
837
|
+
}
|
|
838
|
+
: { polltype: 'creation' };
|
|
839
|
+
stanza.content.push({ tag: 'meta', attrs: metaAttrs });
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
// Inject <biz> node for button messages
|
|
843
|
+
// Works for: WhatsApp Messenger + WhatsApp Business, Android + iOS
|
|
844
|
+
if (!isJidNewsletter(destinationJid) && buttonType) {
|
|
845
|
+
const buttonsNode = getButtonArgs(messages);
|
|
846
|
+
const filteredButtons = getBinaryFilteredButtons(additionalNodes ? additionalNodes : []);
|
|
847
|
+
if (filteredButtons) {
|
|
848
|
+
;
|
|
849
|
+
stanza.content.push(...additionalNodes);
|
|
850
|
+
didPushAdditional = true;
|
|
851
|
+
}
|
|
852
|
+
else {
|
|
853
|
+
;
|
|
854
|
+
stanza.content.push(buttonsNode);
|
|
855
|
+
}
|
|
856
|
+
// bot node: required for buttons to be interactive in private chats
|
|
857
|
+
// (independent of AI flag — matches innovators + button-helper behaviour)
|
|
858
|
+
if (isPrivate) {
|
|
859
|
+
const botNode = { tag: 'bot', attrs: { biz_bot: '1' } };
|
|
860
|
+
const filteredBizBot = getBinaryFilteredBizBot(additionalNodes ? additionalNodes : []);
|
|
861
|
+
if (filteredBizBot) {
|
|
862
|
+
if (!didPushAdditional) {
|
|
863
|
+
;
|
|
864
|
+
stanza.content.push(...additionalNodes);
|
|
865
|
+
didPushAdditional = true;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
else {
|
|
869
|
+
;
|
|
870
|
+
stanza.content.push(botNode);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
// AI icon feature — adds bot node for non-button messages with AI flag
|
|
875
|
+
if (AI && isPrivate && !buttonType) {
|
|
876
|
+
const botNode = { tag: 'bot', attrs: { biz_bot: '1' } };
|
|
877
|
+
const filteredBizBot = getBinaryFilteredBizBot(additionalNodes ? additionalNodes : []);
|
|
878
|
+
if (filteredBizBot) {
|
|
879
|
+
;
|
|
880
|
+
stanza.content.push(...additionalNodes);
|
|
881
|
+
didPushAdditional = true;
|
|
882
|
+
}
|
|
883
|
+
else {
|
|
884
|
+
;
|
|
885
|
+
stanza.content.push(botNode);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
if (!didPushAdditional && additionalNodes && additionalNodes.length > 0) {
|
|
725
889
|
;
|
|
726
890
|
stanza.content.push(...additionalNodes);
|
|
727
891
|
}
|
|
728
892
|
logger.debug({ msgId }, `sending message to ${participants.length} devices`);
|
|
729
893
|
await sendNode(stanza);
|
|
894
|
+
// Fire-and-forget: issue our token to the contact AFTER message send.
|
|
895
|
+
// WA Web skips protocol messages and PSA/bot contacts
|
|
896
|
+
const isProtocolMsg = !!normalizeMessageContent(message)?.protocolMessage;
|
|
897
|
+
const isBotOrPSA = destinationJid === PSA_WID || isJidBot(destinationJid) || isJidMetaAI(destinationJid);
|
|
898
|
+
if (is1on1Send &&
|
|
899
|
+
!isProtocolMsg &&
|
|
900
|
+
!isBotOrPSA &&
|
|
901
|
+
shouldSendNewTcToken(existingTokenEntry?.senderTimestamp) &&
|
|
902
|
+
!inFlightTcTokenIssuance.has(tcTokenJid)) {
|
|
903
|
+
inFlightTcTokenIssuance.add(tcTokenJid);
|
|
904
|
+
const issueTimestamp = unixTimestampSeconds();
|
|
905
|
+
const getPNForLID = signalRepository.lidMapping.getPNForLID.bind(signalRepository.lidMapping);
|
|
906
|
+
resolveIssuanceJid(destinationJid, sock.serverProps.lidTrustedTokenIssueToLid, getLIDForPN, getPNForLID)
|
|
907
|
+
.then(issueJid => issuePrivacyTokens([issueJid], issueTimestamp))
|
|
908
|
+
.then(async (result) => {
|
|
909
|
+
await storeTcTokensFromIqResult({
|
|
910
|
+
result,
|
|
911
|
+
fallbackJid: tcTokenJid,
|
|
912
|
+
keys: authState.keys,
|
|
913
|
+
getLIDForPN
|
|
914
|
+
});
|
|
915
|
+
const currentData = await authState.keys.get('tctoken', [tcTokenJid]);
|
|
916
|
+
const currentEntry = currentData[tcTokenJid];
|
|
917
|
+
const indexWrite = await buildMergedTcTokenIndexWrite(authState.keys, [tcTokenJid]);
|
|
918
|
+
await authState.keys.set({
|
|
919
|
+
tctoken: {
|
|
920
|
+
[tcTokenJid]: {
|
|
921
|
+
token: Buffer.alloc(0),
|
|
922
|
+
...currentEntry,
|
|
923
|
+
senderTimestamp: issueTimestamp
|
|
924
|
+
},
|
|
925
|
+
...indexWrite
|
|
926
|
+
}
|
|
927
|
+
});
|
|
928
|
+
})
|
|
929
|
+
.catch(err => {
|
|
930
|
+
logger.debug({ jid: destinationJid, err: err?.message }, 'fire-and-forget tctoken issuance failed');
|
|
931
|
+
})
|
|
932
|
+
.finally(() => {
|
|
933
|
+
inFlightTcTokenIssuance.delete(tcTokenJid);
|
|
934
|
+
});
|
|
935
|
+
}
|
|
730
936
|
// Add message to retry cache if enabled
|
|
731
937
|
if (messageRetryManager && !participant) {
|
|
732
938
|
messageRetryManager.addRecentMessage(destinationJid, msgId, message);
|
|
@@ -734,66 +940,6 @@ export const makeMessagesSocket = (config) => {
|
|
|
734
940
|
}, meId);
|
|
735
941
|
return msgId;
|
|
736
942
|
};
|
|
737
|
-
const getMessageType = (message) => {
|
|
738
|
-
if (message.pollCreationMessage || message.pollCreationMessageV2 || message.pollCreationMessageV3) {
|
|
739
|
-
return 'poll';
|
|
740
|
-
}
|
|
741
|
-
if (message.eventMessage) {
|
|
742
|
-
return 'event';
|
|
743
|
-
}
|
|
744
|
-
if (getMediaType(message) !== '') {
|
|
745
|
-
return 'media';
|
|
746
|
-
}
|
|
747
|
-
return 'text';
|
|
748
|
-
};
|
|
749
|
-
const getMediaType = (message) => {
|
|
750
|
-
if (message.imageMessage) {
|
|
751
|
-
return 'image';
|
|
752
|
-
}
|
|
753
|
-
else if (message.videoMessage) {
|
|
754
|
-
return message.videoMessage.gifPlayback ? 'gif' : 'video';
|
|
755
|
-
}
|
|
756
|
-
else if (message.audioMessage) {
|
|
757
|
-
return message.audioMessage.ptt ? 'ptt' : 'audio';
|
|
758
|
-
}
|
|
759
|
-
else if (message.contactMessage) {
|
|
760
|
-
return 'vcard';
|
|
761
|
-
}
|
|
762
|
-
else if (message.documentMessage) {
|
|
763
|
-
return 'document';
|
|
764
|
-
}
|
|
765
|
-
else if (message.contactsArrayMessage) {
|
|
766
|
-
return 'contact_array';
|
|
767
|
-
}
|
|
768
|
-
else if (message.liveLocationMessage) {
|
|
769
|
-
return 'livelocation';
|
|
770
|
-
}
|
|
771
|
-
else if (message.stickerMessage) {
|
|
772
|
-
return 'sticker';
|
|
773
|
-
}
|
|
774
|
-
else if (message.listMessage) {
|
|
775
|
-
return 'list';
|
|
776
|
-
}
|
|
777
|
-
else if (message.listResponseMessage) {
|
|
778
|
-
return 'list_response';
|
|
779
|
-
}
|
|
780
|
-
else if (message.buttonsResponseMessage) {
|
|
781
|
-
return 'buttons_response';
|
|
782
|
-
}
|
|
783
|
-
else if (message.orderMessage) {
|
|
784
|
-
return 'order';
|
|
785
|
-
}
|
|
786
|
-
else if (message.productMessage) {
|
|
787
|
-
return 'product';
|
|
788
|
-
}
|
|
789
|
-
else if (message.interactiveResponseMessage) {
|
|
790
|
-
return 'native_flow_response';
|
|
791
|
-
}
|
|
792
|
-
else if (message.groupInviteMessage) {
|
|
793
|
-
return 'url';
|
|
794
|
-
}
|
|
795
|
-
return '';
|
|
796
|
-
};
|
|
797
943
|
const getPrivacyTokens = async (jids) => {
|
|
798
944
|
const t = unixTimestampSeconds().toString();
|
|
799
945
|
const result = await query({
|
|
@@ -820,11 +966,38 @@ export const makeMessagesSocket = (config) => {
|
|
|
820
966
|
});
|
|
821
967
|
return result;
|
|
822
968
|
};
|
|
969
|
+
const issuePrivacyTokens = async (jids, timestamp) => {
|
|
970
|
+
const t = (timestamp ?? unixTimestampSeconds()).toString();
|
|
971
|
+
const result = await query({
|
|
972
|
+
tag: 'iq',
|
|
973
|
+
attrs: {
|
|
974
|
+
to: S_WHATSAPP_NET,
|
|
975
|
+
type: 'set',
|
|
976
|
+
xmlns: 'privacy'
|
|
977
|
+
},
|
|
978
|
+
content: [
|
|
979
|
+
{
|
|
980
|
+
tag: 'tokens',
|
|
981
|
+
attrs: {},
|
|
982
|
+
content: jids.map(jid => ({
|
|
983
|
+
tag: 'token',
|
|
984
|
+
attrs: {
|
|
985
|
+
jid: jidNormalizedUser(jid),
|
|
986
|
+
t,
|
|
987
|
+
type: 'trusted_contact'
|
|
988
|
+
}
|
|
989
|
+
}))
|
|
990
|
+
}
|
|
991
|
+
]
|
|
992
|
+
});
|
|
993
|
+
return result;
|
|
994
|
+
};
|
|
823
995
|
const waUploadToServer = getWAUploadToServer(config, refreshMediaConn);
|
|
824
996
|
const waitForMsgMediaUpdate = bindWaitForEvent(ev, 'messages.media-update');
|
|
825
997
|
return {
|
|
826
998
|
...sock,
|
|
827
999
|
getPrivacyTokens,
|
|
1000
|
+
issuePrivacyTokens,
|
|
828
1001
|
assertSessions,
|
|
829
1002
|
relayMessage,
|
|
830
1003
|
sendReceipt,
|
|
@@ -837,11 +1010,12 @@ export const makeMessagesSocket = (config) => {
|
|
|
837
1010
|
createParticipantNodes,
|
|
838
1011
|
getUSyncDevices,
|
|
839
1012
|
messageRetryManager,
|
|
1013
|
+
updateMemberLabel,
|
|
840
1014
|
updateMediaMessage: async (message) => {
|
|
841
1015
|
const content = assertMediaContent(message.message);
|
|
842
1016
|
const mediaKey = content.mediaKey;
|
|
843
1017
|
const meId = authState.creds.me.id;
|
|
844
|
-
const node =
|
|
1018
|
+
const node = encryptMediaRetryRequest(message.key, mediaKey, meId);
|
|
845
1019
|
let error = undefined;
|
|
846
1020
|
await Promise.all([
|
|
847
1021
|
sendNode(node),
|
|
@@ -853,7 +1027,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
853
1027
|
}
|
|
854
1028
|
else {
|
|
855
1029
|
try {
|
|
856
|
-
const media =
|
|
1030
|
+
const media = decryptMediaRetryData(result.media, mediaKey, result.key.id);
|
|
857
1031
|
if (media.result !== proto.MediaRetryNotification.ResultType.SUCCESS) {
|
|
858
1032
|
const resultStr = proto.MediaRetryNotification.ResultType[media.result];
|
|
859
1033
|
throw new Boom(`Media re-upload failed by device (${resultStr})`, {
|
|
@@ -893,6 +1067,48 @@ export const makeMessagesSocket = (config) => {
|
|
|
893
1067
|
: disappearingMessagesInChat;
|
|
894
1068
|
await groupToggleEphemeral(jid, value);
|
|
895
1069
|
}
|
|
1070
|
+
else if (typeof content === 'object' && 'album' in content && content.album) {
|
|
1071
|
+
// Album message — matches addons prepareAlbumMessageContent
|
|
1072
|
+
const albumItems = content.album;
|
|
1073
|
+
const albumMsg = generateWAMessageFromContent(jid, {
|
|
1074
|
+
albumMessage: {
|
|
1075
|
+
expectedImageCount: albumItems.filter((i) => 'image' in i).length,
|
|
1076
|
+
expectedVideoCount: albumItems.filter((i) => 'video' in i).length
|
|
1077
|
+
}
|
|
1078
|
+
}, { userJid, ...options });
|
|
1079
|
+
await relayMessage(jid, albumMsg.message, { messageId: albumMsg.key.id });
|
|
1080
|
+
const mediaMsgs = [];
|
|
1081
|
+
for (const item of albumItems) {
|
|
1082
|
+
const mediaContent = 'image' in item ? { image: item.image, ...item } : { video: item.video, ...item };
|
|
1083
|
+
const mediaMsg = await generateWAMessage(jid, mediaContent, {
|
|
1084
|
+
logger,
|
|
1085
|
+
userJid,
|
|
1086
|
+
upload: async (encFilePath, opts) => {
|
|
1087
|
+
const up = await waUploadToServer(encFilePath, { ...opts, newsletter: isJidNewsletter(jid) });
|
|
1088
|
+
return up;
|
|
1089
|
+
},
|
|
1090
|
+
...options
|
|
1091
|
+
});
|
|
1092
|
+
if (mediaMsg.message) {
|
|
1093
|
+
mediaMsg.message.messageContextInfo = {
|
|
1094
|
+
messageSecret: randomBytes(32),
|
|
1095
|
+
messageAssociation: {
|
|
1096
|
+
associationType: 1,
|
|
1097
|
+
parentMessageKey: albumMsg.key
|
|
1098
|
+
}
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
mediaMsgs.push(mediaMsg);
|
|
1102
|
+
await delay(options.delay || 500);
|
|
1103
|
+
await relayMessage(jid, mediaMsg.message, {
|
|
1104
|
+
messageId: mediaMsg.key.id,
|
|
1105
|
+
useCachedGroupMetadata: options.useCachedGroupMetadata,
|
|
1106
|
+
statusJidList: options.statusJidList,
|
|
1107
|
+
AI: options.ai
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
1110
|
+
return mediaMsgs[0];
|
|
1111
|
+
}
|
|
896
1112
|
else {
|
|
897
1113
|
const fullMsg = await generateWAMessage(jid, content, {
|
|
898
1114
|
logger,
|
|
@@ -912,7 +1128,11 @@ export const makeMessagesSocket = (config) => {
|
|
|
912
1128
|
upload: waUploadToServer,
|
|
913
1129
|
mediaCache: config.mediaCache,
|
|
914
1130
|
options: config.options,
|
|
915
|
-
messageId:
|
|
1131
|
+
messageId: (('groupStatus' in content && content.groupStatus) ||
|
|
1132
|
+
('cards' in content && content?.cards)) &&
|
|
1133
|
+
!options.messageId
|
|
1134
|
+
? `4NY4W3B${randomBytes(16).toString('hex').toUpperCase()}`
|
|
1135
|
+
: generateMessageIDV2(sock.user?.id),
|
|
916
1136
|
...options
|
|
917
1137
|
});
|
|
918
1138
|
const isEventMsg = 'event' in content && !!content.event;
|
|
@@ -939,11 +1159,16 @@ export const makeMessagesSocket = (config) => {
|
|
|
939
1159
|
additionalAttributes.edit = '2';
|
|
940
1160
|
}
|
|
941
1161
|
else if (isPollMessage) {
|
|
1162
|
+
// Newsletter polls need a contenttype attr ('image' or 'text')
|
|
1163
|
+
// matching innovators behaviour for cross-client compatibility
|
|
1164
|
+
const pollAttrs = { polltype: 'creation' };
|
|
1165
|
+
if (isJidNewsletter(jid)) {
|
|
1166
|
+
const pollContent = content.poll;
|
|
1167
|
+
pollAttrs.contenttype = pollContent?.pollContentType === 2 ? 'image' : 'text';
|
|
1168
|
+
}
|
|
942
1169
|
additionalNodes.push({
|
|
943
1170
|
tag: 'meta',
|
|
944
|
-
attrs:
|
|
945
|
-
polltype: 'creation'
|
|
946
|
-
}
|
|
1171
|
+
attrs: pollAttrs
|
|
947
1172
|
});
|
|
948
1173
|
}
|
|
949
1174
|
else if (isEventMsg) {
|
|
@@ -959,15 +1184,101 @@ export const makeMessagesSocket = (config) => {
|
|
|
959
1184
|
useCachedGroupMetadata: options.useCachedGroupMetadata,
|
|
960
1185
|
additionalAttributes,
|
|
961
1186
|
statusJidList: options.statusJidList,
|
|
962
|
-
additionalNodes
|
|
1187
|
+
additionalNodes,
|
|
1188
|
+
AI: options.ai
|
|
963
1189
|
});
|
|
964
1190
|
if (config.emitOwnEvents) {
|
|
965
1191
|
process.nextTick(async () => {
|
|
966
|
-
await
|
|
1192
|
+
await messageMutex.mutex(() => upsertMessage(fullMsg, 'append'));
|
|
967
1193
|
});
|
|
968
1194
|
}
|
|
969
1195
|
return fullMsg;
|
|
970
1196
|
}
|
|
1197
|
+
},
|
|
1198
|
+
// Logic lives in addons/from-messages-send.ts → execSendStatusMentions
|
|
1199
|
+
sendStatusMentions: async (content, jids = []) => {
|
|
1200
|
+
return execSendStatusMentions(content, jids, {
|
|
1201
|
+
meId: authState.creds.me.id,
|
|
1202
|
+
logger,
|
|
1203
|
+
groupMetadata: sock.groupMetadata,
|
|
1204
|
+
cachedGroupMetadata: config.cachedGroupMetadata,
|
|
1205
|
+
relayMessage,
|
|
1206
|
+
waUploadToServer,
|
|
1207
|
+
getUrlInfo,
|
|
1208
|
+
config,
|
|
1209
|
+
linkPreviewImageThumbnailWidth,
|
|
1210
|
+
generateHighQualityLinkPreview,
|
|
1211
|
+
httpRequestOptions
|
|
1212
|
+
});
|
|
1213
|
+
},
|
|
1214
|
+
/**
|
|
1215
|
+
* Send a rich table via botForwardedMessage → richResponseMessage.
|
|
1216
|
+
*/
|
|
1217
|
+
sendTable: async (jid, title, headers, rows, quoted, options = {}) => {
|
|
1218
|
+
const { message, messageId } = generateTableContent(title, headers, rows, quoted, options);
|
|
1219
|
+
await relayMessage(jid, message, { messageId });
|
|
1220
|
+
return { message, messageId };
|
|
1221
|
+
},
|
|
1222
|
+
/**
|
|
1223
|
+
* Send a rich list (single-column table).
|
|
1224
|
+
*/
|
|
1225
|
+
sendList: async (jid, title, items, quoted, options = {}) => {
|
|
1226
|
+
const { message, messageId } = generateListContent(title, items, quoted, options);
|
|
1227
|
+
await relayMessage(jid, message, { messageId });
|
|
1228
|
+
return { message, messageId };
|
|
1229
|
+
},
|
|
1230
|
+
/**
|
|
1231
|
+
* Send a syntax-highlighted code block.
|
|
1232
|
+
*/
|
|
1233
|
+
sendCodeBlock: async (jid, code, quoted, options = {}) => {
|
|
1234
|
+
const { message, messageId } = generateCodeBlockContent(code, quoted, options);
|
|
1235
|
+
await relayMessage(jid, message, { messageId });
|
|
1236
|
+
return { message, messageId };
|
|
1237
|
+
},
|
|
1238
|
+
/**
|
|
1239
|
+
* Send a LaTeX expression as text (no image rendering).
|
|
1240
|
+
*/
|
|
1241
|
+
sendLatex: async (jid, quoted, options) => {
|
|
1242
|
+
const { message, messageId } = generateLatexContent(quoted, options);
|
|
1243
|
+
await relayMessage(jid, message, { messageId });
|
|
1244
|
+
return { message, messageId };
|
|
1245
|
+
},
|
|
1246
|
+
/**
|
|
1247
|
+
* Render LaTeX to PNG images, upload, and send.
|
|
1248
|
+
*/
|
|
1249
|
+
sendLatexImage: async (jid, quoted, options, renderLatexToPng, uploadFn) => {
|
|
1250
|
+
const { message, messageId } = await generateLatexImageContent(quoted, options, uploadFn, renderLatexToPng);
|
|
1251
|
+
await relayMessage(jid, message, { messageId });
|
|
1252
|
+
return { message, messageId };
|
|
1253
|
+
},
|
|
1254
|
+
/**
|
|
1255
|
+
* Render LaTeX to PNG inline image blocks, upload, and send.
|
|
1256
|
+
*/
|
|
1257
|
+
sendLatexInlineImage: async (jid, quoted, options, renderLatexToPng, uploadFn) => {
|
|
1258
|
+
const { message, messageId } = await generateLatexInlineImageContent(quoted, options, uploadFn, renderLatexToPng);
|
|
1259
|
+
await relayMessage(jid, message, { messageId });
|
|
1260
|
+
return { message, messageId };
|
|
1261
|
+
},
|
|
1262
|
+
/**
|
|
1263
|
+
* Send a fully custom rich message from a raw submessages array.
|
|
1264
|
+
*/
|
|
1265
|
+
sendRichMessage: async (jid, submessages, quoted) => {
|
|
1266
|
+
const { message, messageId } = generateRichMessageContent(submessages, quoted);
|
|
1267
|
+
await relayMessage(jid, message, { messageId });
|
|
1268
|
+
return { message, messageId };
|
|
1269
|
+
},
|
|
1270
|
+
/**
|
|
1271
|
+
* Capture the unifiedResponse payload from an incoming Meta AI message.
|
|
1272
|
+
* Returns null if the message is not a rich response.
|
|
1273
|
+
*/
|
|
1274
|
+
extractUnifiedResponse,
|
|
1275
|
+
/**
|
|
1276
|
+
* Re-send a captured unifiedResponse to a new JID.
|
|
1277
|
+
*/
|
|
1278
|
+
sendUnifiedResponse: async (jid, quoted, captured) => {
|
|
1279
|
+
const { message, messageId } = generateUnifiedResponseContent(quoted, captured);
|
|
1280
|
+
await relayMessage(jid, message, { messageId });
|
|
1281
|
+
return { message, messageId };
|
|
971
1282
|
}
|
|
972
1283
|
};
|
|
973
1284
|
};
|