@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
package/lib/Utils/messages.js
CHANGED
|
@@ -3,12 +3,14 @@ import { randomBytes } from 'crypto';
|
|
|
3
3
|
import { promises as fs } from 'fs';
|
|
4
4
|
import {} from 'stream';
|
|
5
5
|
import { proto } from '../../WAProto/index.js';
|
|
6
|
+
import { buildAdminInviteMessage, buildCallMessage, buildPaymentInviteMessage, buildStickerPackMessage } from '../addons/from-messages.js';
|
|
6
7
|
import { CALL_AUDIO_PREFIX, CALL_VIDEO_PREFIX, MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
|
|
7
8
|
import { WAMessageStatus, WAProto } from '../Types/index.js';
|
|
8
9
|
import { isJidGroup, isJidNewsletter, isJidStatusBroadcast, jidNormalizedUser } from '../WABinary/index.js';
|
|
9
10
|
import { sha256 } from './crypto.js';
|
|
10
11
|
import { generateMessageIDV2, getKeyAuthor, unixTimestampSeconds } from './generics.js';
|
|
11
12
|
import { downloadContentFromMessage, encryptedStream, generateThumbnail, getAudioDuration, getAudioWaveform, getRawMediaUploadData } from './messages-media.js';
|
|
13
|
+
import { shouldIncludeReportingToken } from './reporting-utils.js';
|
|
12
14
|
const MIMETYPE_MAP = {
|
|
13
15
|
image: 'image/jpeg',
|
|
14
16
|
video: 'video/mp4',
|
|
@@ -100,19 +102,22 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
100
102
|
logger?.info({ key: cacheableKey }, 'Preparing raw media for newsletter');
|
|
101
103
|
const { filePath, fileSha256, fileLength } = await getRawMediaUploadData(uploadData.media, options.mediaTypeOverride || mediaType, logger);
|
|
102
104
|
const fileSha256B64 = fileSha256.toString('base64');
|
|
103
|
-
const {
|
|
105
|
+
const { directPath, thumbnailDirectPath, thumbnailSha256 } = await options.upload(filePath, {
|
|
104
106
|
fileEncSha256B64: fileSha256B64,
|
|
105
107
|
mediaType: mediaType,
|
|
106
|
-
timeoutMs: options.mediaUploadTimeoutMs
|
|
108
|
+
timeoutMs: options.mediaUploadTimeoutMs,
|
|
109
|
+
newsletter: true
|
|
107
110
|
});
|
|
108
111
|
await fs.unlink(filePath);
|
|
109
112
|
const obj = WAProto.Message.fromObject({
|
|
110
113
|
// todo: add more support here
|
|
111
114
|
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
112
|
-
url
|
|
115
|
+
// url intentionally omitted — newsletters use directPath only
|
|
113
116
|
directPath,
|
|
114
117
|
fileSha256,
|
|
115
118
|
fileLength,
|
|
119
|
+
thumbnailDirectPath,
|
|
120
|
+
thumbnailSha256: thumbnailSha256 ? Buffer.from(thumbnailSha256, 'base64') : undefined,
|
|
116
121
|
...uploadData,
|
|
117
122
|
media: undefined
|
|
118
123
|
})
|
|
@@ -132,7 +137,7 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
132
137
|
}
|
|
133
138
|
const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
|
|
134
139
|
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && typeof uploadData['jpegThumbnail'] === 'undefined';
|
|
135
|
-
const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
|
|
140
|
+
const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true && typeof uploadData.waveform === 'undefined';
|
|
136
141
|
const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
|
|
137
142
|
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
|
|
138
143
|
const { mediaKey, encFilePath, originalFilePath, fileEncSha256, fileSha256, fileLength } = await encryptedStream(uploadData.media, options.mediaTypeOverride || mediaType, {
|
|
@@ -154,7 +159,7 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
154
159
|
(async () => {
|
|
155
160
|
try {
|
|
156
161
|
if (requiresThumbnailComputation) {
|
|
157
|
-
const { thumbnail, originalImageDimensions } = await generateThumbnail(originalFilePath, mediaType, options);
|
|
162
|
+
const { thumbnail, originalImageDimensions } = await generateThumbnail(originalFilePath, mediaType, { ...options, hdMode: !!message.hd });
|
|
158
163
|
uploadData.jpegThumbnail = thumbnail;
|
|
159
164
|
if (!uploadData.width && originalImageDimensions) {
|
|
160
165
|
uploadData.width = originalImageDimensions.width;
|
|
@@ -259,10 +264,20 @@ export const generateForwardMessageContent = (message, forceForward) => {
|
|
|
259
264
|
}
|
|
260
265
|
return content;
|
|
261
266
|
};
|
|
267
|
+
export const hasNonNullishProperty = (message, key) => {
|
|
268
|
+
return (typeof message === 'object' &&
|
|
269
|
+
message !== null &&
|
|
270
|
+
key in message &&
|
|
271
|
+
message[key] !== null &&
|
|
272
|
+
message[key] !== undefined);
|
|
273
|
+
};
|
|
274
|
+
function hasOptionalProperty(obj, key) {
|
|
275
|
+
return typeof obj === 'object' && obj !== null && key in obj && obj[key] !== null;
|
|
276
|
+
}
|
|
262
277
|
export const generateWAMessageContent = async (message, options) => {
|
|
263
278
|
var _a, _b;
|
|
264
279
|
let m = {};
|
|
265
|
-
if ('text'
|
|
280
|
+
if (hasNonNullishProperty(message, 'text')) {
|
|
266
281
|
const extContent = { text: message.text };
|
|
267
282
|
let urlInfo = message.linkPreview;
|
|
268
283
|
if (typeof urlInfo === 'undefined') {
|
|
@@ -293,7 +308,7 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
293
308
|
}
|
|
294
309
|
m.extendedTextMessage = extContent;
|
|
295
310
|
}
|
|
296
|
-
else if ('contacts'
|
|
311
|
+
else if (hasNonNullishProperty(message, 'contacts')) {
|
|
297
312
|
const contactLen = message.contacts.contacts.length;
|
|
298
313
|
if (!contactLen) {
|
|
299
314
|
throw new Boom('require atleast 1 contact', { statusCode: 400 });
|
|
@@ -305,25 +320,25 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
305
320
|
m.contactsArrayMessage = WAProto.Message.ContactsArrayMessage.create(message.contacts);
|
|
306
321
|
}
|
|
307
322
|
}
|
|
308
|
-
else if ('location'
|
|
323
|
+
else if (hasNonNullishProperty(message, 'location')) {
|
|
309
324
|
m.locationMessage = WAProto.Message.LocationMessage.create(message.location);
|
|
310
325
|
}
|
|
311
|
-
else if ('react'
|
|
326
|
+
else if (hasNonNullishProperty(message, 'react')) {
|
|
312
327
|
if (!message.react.senderTimestampMs) {
|
|
313
328
|
message.react.senderTimestampMs = Date.now();
|
|
314
329
|
}
|
|
315
330
|
m.reactionMessage = WAProto.Message.ReactionMessage.create(message.react);
|
|
316
331
|
}
|
|
317
|
-
else if ('delete'
|
|
332
|
+
else if (hasNonNullishProperty(message, 'delete')) {
|
|
318
333
|
m.protocolMessage = {
|
|
319
334
|
key: message.delete,
|
|
320
335
|
type: WAProto.Message.ProtocolMessage.Type.REVOKE
|
|
321
336
|
};
|
|
322
337
|
}
|
|
323
|
-
else if ('forward'
|
|
338
|
+
else if (hasNonNullishProperty(message, 'forward')) {
|
|
324
339
|
m = generateForwardMessageContent(message.forward, message.force);
|
|
325
340
|
}
|
|
326
|
-
else if ('disappearingMessagesInChat'
|
|
341
|
+
else if (hasNonNullishProperty(message, 'disappearingMessagesInChat')) {
|
|
327
342
|
const exp = typeof message.disappearingMessagesInChat === 'boolean'
|
|
328
343
|
? message.disappearingMessagesInChat
|
|
329
344
|
? WA_DEFAULT_EPHEMERAL
|
|
@@ -331,7 +346,7 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
331
346
|
: message.disappearingMessagesInChat;
|
|
332
347
|
m = prepareDisappearingMessageSettingContent(exp);
|
|
333
348
|
}
|
|
334
|
-
else if ('groupInvite'
|
|
349
|
+
else if (hasNonNullishProperty(message, 'groupInvite')) {
|
|
335
350
|
m.groupInviteMessage = {};
|
|
336
351
|
m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
|
|
337
352
|
m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
|
|
@@ -351,7 +366,7 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
351
366
|
}
|
|
352
367
|
}
|
|
353
368
|
}
|
|
354
|
-
else if ('pin'
|
|
369
|
+
else if (hasNonNullishProperty(message, 'pin')) {
|
|
355
370
|
m.pinInChatMessage = {};
|
|
356
371
|
m.messageContextInfo = {};
|
|
357
372
|
m.pinInChatMessage.key = message.pin;
|
|
@@ -359,7 +374,7 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
359
374
|
m.pinInChatMessage.senderTimestampMs = Date.now();
|
|
360
375
|
m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0;
|
|
361
376
|
}
|
|
362
|
-
else if ('buttonReply'
|
|
377
|
+
else if (hasNonNullishProperty(message, 'buttonReply')) {
|
|
363
378
|
switch (message.type) {
|
|
364
379
|
case 'template':
|
|
365
380
|
m.templateButtonReplyMessage = {
|
|
@@ -375,13 +390,36 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
375
390
|
type: proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT
|
|
376
391
|
};
|
|
377
392
|
break;
|
|
393
|
+
case 'list':
|
|
394
|
+
m.listResponseMessage = {
|
|
395
|
+
title: message.buttonReply.title,
|
|
396
|
+
description: message.buttonReply.description,
|
|
397
|
+
singleSelectReply: {
|
|
398
|
+
selectedRowId: message.buttonReply.rowId
|
|
399
|
+
},
|
|
400
|
+
listType: proto.Message.ListResponseMessage.ListType.SINGLE_SELECT
|
|
401
|
+
};
|
|
402
|
+
break;
|
|
403
|
+
case 'interactive':
|
|
404
|
+
m.interactiveResponseMessage = {
|
|
405
|
+
body: {
|
|
406
|
+
text: message.buttonReply.displayText,
|
|
407
|
+
format: proto.Message.InteractiveResponseMessage.Body.Format.EXTENSIONS_1
|
|
408
|
+
},
|
|
409
|
+
nativeFlowResponseMessage: {
|
|
410
|
+
name: message.buttonReply.nativeFlows?.name,
|
|
411
|
+
paramsJson: message.buttonReply.nativeFlows?.paramsJson,
|
|
412
|
+
version: message.buttonReply.nativeFlows?.version
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
break;
|
|
378
416
|
}
|
|
379
417
|
}
|
|
380
|
-
else if ('ptv'
|
|
418
|
+
else if (hasOptionalProperty(message, 'ptv') && message.ptv) {
|
|
381
419
|
const { videoMessage } = await prepareWAMessageMedia({ video: message.video }, options);
|
|
382
420
|
m.ptvMessage = videoMessage;
|
|
383
421
|
}
|
|
384
|
-
else if ('product'
|
|
422
|
+
else if (hasNonNullishProperty(message, 'product')) {
|
|
385
423
|
const { imageMessage } = await prepareWAMessageMedia({ image: message.product.productImage }, options);
|
|
386
424
|
m.productMessage = WAProto.Message.ProductMessage.create({
|
|
387
425
|
...message,
|
|
@@ -391,10 +429,10 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
391
429
|
}
|
|
392
430
|
});
|
|
393
431
|
}
|
|
394
|
-
else if ('listReply'
|
|
432
|
+
else if (hasNonNullishProperty(message, 'listReply')) {
|
|
395
433
|
m.listResponseMessage = { ...message.listReply };
|
|
396
434
|
}
|
|
397
|
-
else if ('event'
|
|
435
|
+
else if (hasNonNullishProperty(message, 'event')) {
|
|
398
436
|
m.eventMessage = {};
|
|
399
437
|
const startTime = Math.floor(message.event.startDate.getTime() / 1000);
|
|
400
438
|
if (message.event.call && options.getCallLink) {
|
|
@@ -414,7 +452,7 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
414
452
|
m.eventMessage.isScheduleCall = message.event.isScheduleCall ?? false;
|
|
415
453
|
m.eventMessage.location = message.event.location;
|
|
416
454
|
}
|
|
417
|
-
else if ('poll'
|
|
455
|
+
else if (hasNonNullishProperty(message, 'poll')) {
|
|
418
456
|
(_a = message.poll).selectableCount || (_a.selectableCount = 0);
|
|
419
457
|
(_b = message.poll).toAnnouncementGroup || (_b.toAnnouncementGroup = false);
|
|
420
458
|
if (!Array.isArray(message.poll.values)) {
|
|
@@ -425,10 +463,13 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
425
463
|
statusCode: 400
|
|
426
464
|
});
|
|
427
465
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
466
|
+
// messageSecret must NOT be set for newsletter polls —
|
|
467
|
+
// newsletters handle encryption differently and a secret causes send failures
|
|
468
|
+
if (!options.jid || !isJidNewsletter(options.jid)) {
|
|
469
|
+
const providedSecret = message.poll.messageSecret;
|
|
470
|
+
const messageSecret = providedSecret instanceof Uint8Array && providedSecret.length === 32 ? providedSecret : randomBytes(32);
|
|
471
|
+
m.messageContextInfo = { messageSecret };
|
|
472
|
+
}
|
|
432
473
|
const pollCreationMessage = {
|
|
433
474
|
name: message.poll.name,
|
|
434
475
|
selectableOptionsCount: message.poll.selectableCount,
|
|
@@ -449,15 +490,40 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
449
490
|
}
|
|
450
491
|
}
|
|
451
492
|
}
|
|
452
|
-
else if ('
|
|
493
|
+
else if ('adminInvite' in message && !!message.adminInvite) {
|
|
494
|
+
// addons/from-messages.ts → buildAdminInviteMessage
|
|
495
|
+
m.newsletterAdminInviteMessage = await buildAdminInviteMessage(message.adminInvite, message.contextInfo, options);
|
|
496
|
+
}
|
|
497
|
+
else if ('order' in message && !!message.order) {
|
|
498
|
+
// order → OrderMessage (from addons)
|
|
499
|
+
m.orderMessage = WAProto.Message.OrderMessage.fromObject(message.order);
|
|
500
|
+
}
|
|
501
|
+
else if ('keep' in message && !!message.keep) {
|
|
502
|
+
// keep → KeepInChatMessage (from addons)
|
|
503
|
+
const k = message.keep;
|
|
504
|
+
m.keepInChatMessage = {
|
|
505
|
+
key: k.key,
|
|
506
|
+
keepType: k.type ?? 1,
|
|
507
|
+
timestampMs: k.time ?? Date.now()
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
else if ('call' in message && !!message.call) {
|
|
511
|
+
// addons/from-messages.ts → buildCallMessage
|
|
512
|
+
m.scheduledCallCreationMessage = buildCallMessage(message.call);
|
|
513
|
+
}
|
|
514
|
+
else if ('paymentInvite' in message && !!message.paymentInvite) {
|
|
515
|
+
// addons/from-messages.ts → buildPaymentInviteMessage
|
|
516
|
+
m.paymentInviteMessage = buildPaymentInviteMessage(message.paymentInvite);
|
|
517
|
+
}
|
|
518
|
+
else if (hasNonNullishProperty(message, 'sharePhoneNumber')) {
|
|
453
519
|
m.protocolMessage = {
|
|
454
520
|
type: proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
|
|
455
521
|
};
|
|
456
522
|
}
|
|
457
|
-
else if ('requestPhoneNumber'
|
|
523
|
+
else if (hasNonNullishProperty(message, 'requestPhoneNumber')) {
|
|
458
524
|
m.requestPhoneNumberMessage = {};
|
|
459
525
|
}
|
|
460
|
-
else if ('limitSharing'
|
|
526
|
+
else if (hasNonNullishProperty(message, 'limitSharing')) {
|
|
461
527
|
m.protocolMessage = {
|
|
462
528
|
type: proto.Message.ProtocolMessage.Type.LIMIT_SHARING,
|
|
463
529
|
limitSharing: {
|
|
@@ -468,25 +534,381 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
468
534
|
}
|
|
469
535
|
};
|
|
470
536
|
}
|
|
537
|
+
else if ('productList' in message && !!message.productList) {
|
|
538
|
+
// productList handled below after this block — just skip media
|
|
539
|
+
}
|
|
540
|
+
else if ('album' in message && !!message.album) {
|
|
541
|
+
// album handled in sendMessage — just set albumMessage header
|
|
542
|
+
const albumOpts = message.album;
|
|
543
|
+
m.albumMessage = {
|
|
544
|
+
expectedImageCount: albumOpts.expectedImageCount,
|
|
545
|
+
expectedVideoCount: albumOpts.expectedVideoCount
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
else if ('stickerPack' in message && !!message.stickerPack) {
|
|
549
|
+
// addons/from-messages.ts → buildStickerPackMessage
|
|
550
|
+
m.stickerPackMessage = await buildStickerPackMessage(message.stickerPack, options);
|
|
551
|
+
}
|
|
471
552
|
else {
|
|
472
553
|
m = await prepareWAMessageMedia(message, options);
|
|
473
554
|
}
|
|
474
|
-
|
|
555
|
+
// ── productList → ListMessage with products ────────────────────────────────
|
|
556
|
+
if ('productList' in message && !!message.productList) {
|
|
557
|
+
const thumbnail = message.thumbnail
|
|
558
|
+
? await generateThumbnail(message.thumbnail, 'image', {})
|
|
559
|
+
: null;
|
|
560
|
+
const listMessage = {
|
|
561
|
+
title: message.title,
|
|
562
|
+
buttonText: message.buttonText,
|
|
563
|
+
footerText: message.footer,
|
|
564
|
+
description: message.text,
|
|
565
|
+
productListInfo: {
|
|
566
|
+
productSections: message.productList,
|
|
567
|
+
headerImage: {
|
|
568
|
+
productId: message.productList[0]?.products?.[0]?.productId,
|
|
569
|
+
jpegThumbnail: thumbnail?.thumbnail ?? null
|
|
570
|
+
},
|
|
571
|
+
businessOwnerJid: message.businessOwnerJid
|
|
572
|
+
},
|
|
573
|
+
listType: proto.Message.ListMessage.ListType.PRODUCT_LIST
|
|
574
|
+
};
|
|
575
|
+
listMessage.contextInfo = {
|
|
576
|
+
...(message.contextInfo || {}),
|
|
577
|
+
...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
|
|
578
|
+
...(message.mentionAll ? { nonJidMentions: 1 } : {})
|
|
579
|
+
};
|
|
580
|
+
m = { listMessage };
|
|
581
|
+
}
|
|
582
|
+
// ── sections → ListMessage (standalone if, runs independently like fork) ──
|
|
583
|
+
if ('sections' in message && !!message.sections) {
|
|
584
|
+
const listMessage = {
|
|
585
|
+
title: message.title,
|
|
586
|
+
buttonText: message.buttonText,
|
|
587
|
+
footerText: message.footer,
|
|
588
|
+
description: message.text,
|
|
589
|
+
sections: message.sections,
|
|
590
|
+
listType: proto.Message.ListMessage.ListType.SINGLE_SELECT
|
|
591
|
+
};
|
|
592
|
+
listMessage.contextInfo = {
|
|
593
|
+
...(message.contextInfo || {}),
|
|
594
|
+
...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
|
|
595
|
+
...(message.mentionAll ? { nonJidMentions: 1 } : {})
|
|
596
|
+
};
|
|
597
|
+
m = { listMessage };
|
|
598
|
+
}
|
|
599
|
+
// ── buttons → buttonsMessage ──────────────────────────────────────────────
|
|
600
|
+
else if ('buttons' in message && !!message.buttons) {
|
|
601
|
+
const buttonsMessage = {
|
|
602
|
+
buttons: message.buttons.map((b) => ({
|
|
603
|
+
...b,
|
|
604
|
+
type: proto.Message.ButtonsMessage.Button.Type.RESPONSE
|
|
605
|
+
}))
|
|
606
|
+
};
|
|
607
|
+
if ('text' in message) {
|
|
608
|
+
buttonsMessage.contentText = message.text;
|
|
609
|
+
buttonsMessage.headerType = proto.Message.ButtonsMessage.HeaderType.EMPTY;
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
if ('caption' in message) {
|
|
613
|
+
buttonsMessage.contentText = message.caption;
|
|
614
|
+
}
|
|
615
|
+
const mediaType = Object.keys(m)[0]?.replace('Message', '').toUpperCase();
|
|
616
|
+
if (mediaType && mediaType in proto.Message.ButtonsMessage.HeaderType) {
|
|
617
|
+
buttonsMessage.headerType =
|
|
618
|
+
proto.Message.ButtonsMessage.HeaderType[mediaType];
|
|
619
|
+
}
|
|
620
|
+
Object.assign(buttonsMessage, m);
|
|
621
|
+
}
|
|
622
|
+
if ('footer' in message && !!message.footer) {
|
|
623
|
+
buttonsMessage.footerText = message.footer;
|
|
624
|
+
}
|
|
625
|
+
if ('title' in message && !!message.title) {
|
|
626
|
+
buttonsMessage.text = message.title;
|
|
627
|
+
buttonsMessage.headerType = proto.Message.ButtonsMessage.HeaderType.TEXT;
|
|
628
|
+
}
|
|
629
|
+
buttonsMessage.contextInfo = {
|
|
630
|
+
...(message.contextInfo || {}),
|
|
631
|
+
...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
|
|
632
|
+
...(message.mentionAll ? { nonJidMentions: 1 } : {})
|
|
633
|
+
};
|
|
634
|
+
m = { buttonsMessage };
|
|
635
|
+
}
|
|
636
|
+
// ── templateButtons → TemplateMessage ─────────────────────────────────────
|
|
637
|
+
else if ('templateButtons' in message && !!message.templateButtons) {
|
|
638
|
+
const hydratedTemplate = {
|
|
639
|
+
hydratedButtons: message.templateButtons
|
|
640
|
+
};
|
|
641
|
+
if ('text' in message) {
|
|
642
|
+
hydratedTemplate.hydratedContentText = message.text;
|
|
643
|
+
}
|
|
644
|
+
else if ('caption' in message) {
|
|
645
|
+
hydratedTemplate.hydratedContentText = message.caption;
|
|
646
|
+
Object.assign(hydratedTemplate, m);
|
|
647
|
+
}
|
|
648
|
+
if ('footer' in message && !!message.footer) {
|
|
649
|
+
hydratedTemplate.hydratedFooterText = message.footer;
|
|
650
|
+
}
|
|
651
|
+
;
|
|
652
|
+
hydratedTemplate.contextInfo = {
|
|
653
|
+
...(message.contextInfo || {}),
|
|
654
|
+
...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
|
|
655
|
+
...(message.mentionAll ? { nonJidMentions: 1 } : {})
|
|
656
|
+
};
|
|
657
|
+
m = { templateMessage: { hydratedTemplate } };
|
|
658
|
+
}
|
|
659
|
+
// ── interactiveButtons → InteractiveMessage native flow (Android + iOS) ──
|
|
660
|
+
else if ('interactiveButtons' in message && !!message.interactiveButtons) {
|
|
661
|
+
const interactiveMessage = {
|
|
662
|
+
// FIX Bug 2: messageParamsJson: '' is required — without it iOS doesn't render buttons
|
|
663
|
+
nativeFlowMessage: { buttons: message.interactiveButtons, messageParamsJson: '' }
|
|
664
|
+
};
|
|
665
|
+
if ('text' in message) {
|
|
666
|
+
interactiveMessage.body = { text: message.text };
|
|
667
|
+
interactiveMessage.header = {
|
|
668
|
+
title: message.title,
|
|
669
|
+
subtitle: message.subtitle,
|
|
670
|
+
hasMediaAttachment: false
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
else if ('caption' in message) {
|
|
674
|
+
interactiveMessage.body = { text: message.caption ?? '' };
|
|
675
|
+
// FIX Bug 1: Object.assign(interactiveMessage, m) was mutating interactiveMessage
|
|
676
|
+
// AND spreading the whole corrupted object into header — completely broken.
|
|
677
|
+
// Correct fix: extract only the media fields from m and place them in header.
|
|
678
|
+
interactiveMessage.header = {
|
|
679
|
+
title: message.title,
|
|
680
|
+
subtitle: message.subtitle,
|
|
681
|
+
hasMediaAttachment: !!(m.imageMessage || m.videoMessage || m.documentMessage),
|
|
682
|
+
imageMessage: m.imageMessage ?? undefined,
|
|
683
|
+
videoMessage: m.videoMessage ?? undefined,
|
|
684
|
+
documentMessage: m.documentMessage ?? undefined
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
if ('footer' in message && !!message.footer) {
|
|
688
|
+
interactiveMessage.footer = { text: message.footer };
|
|
689
|
+
}
|
|
690
|
+
interactiveMessage.contextInfo = {
|
|
691
|
+
...(message.contextInfo || {}),
|
|
692
|
+
...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
|
|
693
|
+
...(message.mentionAll ? { nonJidMentions: 1 } : {})
|
|
694
|
+
};
|
|
695
|
+
m = { interactiveMessage };
|
|
696
|
+
}
|
|
697
|
+
// ── shop → InteractiveMessage (shopStorefrontMessage) ─────────────────────
|
|
698
|
+
else if ('shop' in message && !!message.shop) {
|
|
699
|
+
const interactiveMessage = {
|
|
700
|
+
shopStorefrontMessage: {
|
|
701
|
+
surface: message.shop.surface,
|
|
702
|
+
id: message.shop.id
|
|
703
|
+
}
|
|
704
|
+
};
|
|
705
|
+
if ('text' in message) {
|
|
706
|
+
interactiveMessage.body = { text: message.text };
|
|
707
|
+
interactiveMessage.header = {
|
|
708
|
+
title: message.title,
|
|
709
|
+
subtitle: message.subtitle,
|
|
710
|
+
hasMediaAttachment: false
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
else if ('caption' in message) {
|
|
714
|
+
interactiveMessage.body = { text: message.caption ?? '' };
|
|
715
|
+
// FIX Bug 1: same Object.assign corruption as interactiveButtons — fixed
|
|
716
|
+
interactiveMessage.header = {
|
|
717
|
+
title: message.title,
|
|
718
|
+
subtitle: message.subtitle,
|
|
719
|
+
hasMediaAttachment: !!(m.imageMessage || m.videoMessage || m.documentMessage),
|
|
720
|
+
imageMessage: m.imageMessage ?? undefined,
|
|
721
|
+
videoMessage: m.videoMessage ?? undefined,
|
|
722
|
+
documentMessage: m.documentMessage ?? undefined
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
if ('footer' in message && !!message.footer) {
|
|
726
|
+
interactiveMessage.footer = { text: message.footer };
|
|
727
|
+
}
|
|
728
|
+
interactiveMessage.contextInfo = {
|
|
729
|
+
...(message.contextInfo || {}),
|
|
730
|
+
...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
|
|
731
|
+
...(message.mentionAll ? { nonJidMentions: 1 } : {})
|
|
732
|
+
};
|
|
733
|
+
m = { interactiveMessage };
|
|
734
|
+
}
|
|
735
|
+
// ── collection → InteractiveMessage (collectionMessage) ───────────────────
|
|
736
|
+
else if ('collection' in message && !!message.collection) {
|
|
737
|
+
const interactiveMessage = {
|
|
738
|
+
collectionMessage: {
|
|
739
|
+
bizJid: message.collection.bizJid,
|
|
740
|
+
id: message.collection.id,
|
|
741
|
+
messageVersion: message.collection.version ?? message.collection.messageVersion
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
if ('text' in message) {
|
|
745
|
+
interactiveMessage.body = { text: message.text };
|
|
746
|
+
interactiveMessage.header = {
|
|
747
|
+
title: message.title,
|
|
748
|
+
subtitle: message.subtitle,
|
|
749
|
+
hasMediaAttachment: false
|
|
750
|
+
};
|
|
751
|
+
}
|
|
752
|
+
else if ('caption' in message) {
|
|
753
|
+
interactiveMessage.body = { text: message.caption ?? '' };
|
|
754
|
+
// FIX Bug 1: same Object.assign corruption — fixed
|
|
755
|
+
interactiveMessage.header = {
|
|
756
|
+
title: message.title,
|
|
757
|
+
subtitle: message.subtitle,
|
|
758
|
+
hasMediaAttachment: !!(m.imageMessage || m.videoMessage || m.documentMessage),
|
|
759
|
+
imageMessage: m.imageMessage ?? undefined,
|
|
760
|
+
videoMessage: m.videoMessage ?? undefined,
|
|
761
|
+
documentMessage: m.documentMessage ?? undefined
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
if ('footer' in message && !!message.footer) {
|
|
765
|
+
interactiveMessage.footer = { text: message.footer };
|
|
766
|
+
}
|
|
767
|
+
interactiveMessage.contextInfo = {
|
|
768
|
+
...(message.contextInfo || {}),
|
|
769
|
+
...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
|
|
770
|
+
...(message.mentionAll ? { nonJidMentions: 1 } : {})
|
|
771
|
+
};
|
|
772
|
+
m = { interactiveMessage };
|
|
773
|
+
}
|
|
774
|
+
// ── cards → InteractiveMessage (carouselMessage, wrapped in viewOnce) ──────
|
|
775
|
+
else if ('cards' in message && !!message.cards) {
|
|
776
|
+
const normalizeMedia = (media) => {
|
|
777
|
+
if (!media)
|
|
778
|
+
return undefined;
|
|
779
|
+
if (Buffer.isBuffer(media))
|
|
780
|
+
return media;
|
|
781
|
+
if (typeof media === 'string')
|
|
782
|
+
return { url: media };
|
|
783
|
+
return media;
|
|
784
|
+
};
|
|
785
|
+
const slides = await Promise.all(message.cards.map(async (slide) => {
|
|
786
|
+
const { image, video, document: doc, product, title, body, footer, buttons } = slide;
|
|
787
|
+
let header = {};
|
|
788
|
+
if (product) {
|
|
789
|
+
const { imageMessage } = await prepareWAMessageMedia({ image: normalizeMedia(product.productImage) }, options);
|
|
790
|
+
header.productMessage = { product: { ...product, productImage: imageMessage } };
|
|
791
|
+
}
|
|
792
|
+
else if (image) {
|
|
793
|
+
const prepared = await prepareWAMessageMedia({ image: normalizeMedia(image) }, options);
|
|
794
|
+
if (prepared.imageMessage)
|
|
795
|
+
prepared.imageMessage.viewOnce = true;
|
|
796
|
+
header = prepared;
|
|
797
|
+
}
|
|
798
|
+
else if (video) {
|
|
799
|
+
const prepared = await prepareWAMessageMedia({ video: normalizeMedia(video) }, options);
|
|
800
|
+
if (prepared.videoMessage) {
|
|
801
|
+
prepared.videoMessage.viewOnce = true;
|
|
802
|
+
prepared.videoMessage.gifPlayback = false;
|
|
803
|
+
}
|
|
804
|
+
header = prepared;
|
|
805
|
+
}
|
|
806
|
+
else if (doc) {
|
|
807
|
+
const prepared = await prepareWAMessageMedia({
|
|
808
|
+
document: normalizeMedia(doc),
|
|
809
|
+
mimetype: slide.mimetype || 'application/octet-stream',
|
|
810
|
+
fileName: slide.fileName
|
|
811
|
+
}, options);
|
|
812
|
+
header = prepared;
|
|
813
|
+
}
|
|
814
|
+
const headerProps = {
|
|
815
|
+
title,
|
|
816
|
+
hasMediaAttachment: !!(header.imageMessage ||
|
|
817
|
+
header.videoMessage ||
|
|
818
|
+
header.documentMessage ||
|
|
819
|
+
header.productMessage),
|
|
820
|
+
...header
|
|
821
|
+
};
|
|
822
|
+
return WAProto.Message.InteractiveMessage.create({
|
|
823
|
+
header: WAProto.Message.InteractiveMessage.Header.create(headerProps),
|
|
824
|
+
body: WAProto.Message.InteractiveMessage.Body.create({ text: body }),
|
|
825
|
+
footer: WAProto.Message.InteractiveMessage.Footer.create({ text: footer }),
|
|
826
|
+
nativeFlowMessage: WAProto.Message.InteractiveMessage.NativeFlowMessage.create({
|
|
827
|
+
buttons: buttons ?? []
|
|
828
|
+
})
|
|
829
|
+
});
|
|
830
|
+
}));
|
|
831
|
+
const interactiveMessage = {
|
|
832
|
+
carouselMessage: WAProto.Message.InteractiveMessage.CarouselMessage.create({ cards: slides })
|
|
833
|
+
};
|
|
834
|
+
if ('text' in message) {
|
|
835
|
+
interactiveMessage.body = WAProto.Message.InteractiveMessage.Body.create({
|
|
836
|
+
text: message.text ?? ''
|
|
837
|
+
});
|
|
838
|
+
interactiveMessage.header = WAProto.Message.InteractiveMessage.Header.create({
|
|
839
|
+
title: message.title,
|
|
840
|
+
subtitle: message.subtitle,
|
|
841
|
+
hasMediaAttachment: false
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
if ('footer' in message && !!message.footer) {
|
|
845
|
+
interactiveMessage.footer = WAProto.Message.InteractiveMessage.Footer.create({
|
|
846
|
+
text: message.footer ?? ''
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
interactiveMessage.contextInfo = {
|
|
850
|
+
...(message.contextInfo || {}),
|
|
851
|
+
...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
|
|
852
|
+
...(message.mentionAll ? { nonJidMentions: 1 } : {})
|
|
853
|
+
};
|
|
854
|
+
// Wrap in viewOnceMessage matching innovators pattern for correct WA rendering
|
|
855
|
+
m = { interactiveMessage };
|
|
856
|
+
}
|
|
857
|
+
if (hasOptionalProperty(message, 'viewOnce') && !!message.viewOnce) {
|
|
475
858
|
m = { viewOnceMessage: { message: m } };
|
|
476
859
|
}
|
|
477
|
-
|
|
860
|
+
// ── viewOnceExt → viewOnceMessageV2Extension ──────────────────────────────
|
|
861
|
+
if (hasOptionalProperty(message, 'viewOnceExt') && !!message.viewOnceExt) {
|
|
862
|
+
m = { viewOnceMessageV2Extension: { message: m } };
|
|
863
|
+
}
|
|
864
|
+
// ── groupStatus → groupStatusMessageV2 ────────────────────────────────────
|
|
865
|
+
if (hasOptionalProperty(message, 'groupStatus') && !!message.groupStatus) {
|
|
478
866
|
const messageType = Object.keys(m)[0];
|
|
867
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
479
868
|
const key = m[messageType];
|
|
480
|
-
if ('contextInfo' in key && !!key.contextInfo) {
|
|
481
|
-
key.contextInfo.
|
|
869
|
+
if (key && 'contextInfo' in key && !!key.contextInfo) {
|
|
870
|
+
key.contextInfo.isGroupStatus = message.groupStatus;
|
|
871
|
+
}
|
|
872
|
+
else if (key) {
|
|
873
|
+
key.contextInfo = { isGroupStatus: message.groupStatus };
|
|
874
|
+
}
|
|
875
|
+
m = { groupStatusMessageV2: { message: m } };
|
|
876
|
+
}
|
|
877
|
+
// ── interactiveAsTemplate → templateMessage.interactiveMessageTemplate ────
|
|
878
|
+
// FIX Bug 4: was `else if` — so it was silently skipped whenever groupStatus was set.
|
|
879
|
+
// Must be an independent `if` so both can apply independently.
|
|
880
|
+
if (hasOptionalProperty(message, 'interactiveAsTemplate') && !!message.interactiveAsTemplate) {
|
|
881
|
+
if (!m.interactiveMessage) {
|
|
882
|
+
throw new Boom('Invalid message type for template', { statusCode: 400 });
|
|
883
|
+
}
|
|
884
|
+
m = {
|
|
885
|
+
templateMessage: {
|
|
886
|
+
interactiveMessageTemplate: m.interactiveMessage,
|
|
887
|
+
templateId: message.id || `template-${Date.now()}`
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
if ((hasOptionalProperty(message, 'mentions') && message.mentions?.length) ||
|
|
892
|
+
(hasOptionalProperty(message, 'mentionAll') && message.mentionAll)) {
|
|
893
|
+
const messageType = Object.keys(m)[0];
|
|
894
|
+
const key = m[messageType];
|
|
895
|
+
if (key && 'contextInfo' in key) {
|
|
896
|
+
key.contextInfo = key.contextInfo || {};
|
|
897
|
+
if (message.mentions?.length) {
|
|
898
|
+
key.contextInfo.mentionedJid = message.mentions;
|
|
899
|
+
}
|
|
900
|
+
if (message.mentionAll) {
|
|
901
|
+
key.contextInfo.nonJidMentions = 1;
|
|
902
|
+
}
|
|
482
903
|
}
|
|
483
904
|
else if (key) {
|
|
484
905
|
key.contextInfo = {
|
|
485
|
-
mentionedJid: message.mentions
|
|
906
|
+
mentionedJid: message.mentions,
|
|
907
|
+
nonJidMentions: message.mentionAll ? 1 : 0
|
|
486
908
|
};
|
|
487
909
|
}
|
|
488
910
|
}
|
|
489
|
-
if ('edit'
|
|
911
|
+
if (hasOptionalProperty(message, 'edit')) {
|
|
490
912
|
m = {
|
|
491
913
|
protocolMessage: {
|
|
492
914
|
key: message.edit,
|
|
@@ -496,7 +918,7 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
496
918
|
}
|
|
497
919
|
};
|
|
498
920
|
}
|
|
499
|
-
if ('contextInfo'
|
|
921
|
+
if (hasOptionalProperty(message, 'contextInfo') && !!message.contextInfo) {
|
|
500
922
|
const messageType = Object.keys(m)[0];
|
|
501
923
|
const key = m[messageType];
|
|
502
924
|
if ('contextInfo' in key && !!key.contextInfo) {
|
|
@@ -506,6 +928,21 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
506
928
|
key.contextInfo = message.contextInfo;
|
|
507
929
|
}
|
|
508
930
|
}
|
|
931
|
+
if (hasOptionalProperty(message, 'albumParentKey') && !!message.albumParentKey) {
|
|
932
|
+
m.messageContextInfo = {
|
|
933
|
+
...m.messageContextInfo,
|
|
934
|
+
messageAssociation: {
|
|
935
|
+
associationType: WAProto.MessageAssociation.AssociationType.MEDIA_ALBUM,
|
|
936
|
+
parentMessageKey: message.albumParentKey
|
|
937
|
+
}
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
if (shouldIncludeReportingToken(m)) {
|
|
941
|
+
m.messageContextInfo = m.messageContextInfo || {};
|
|
942
|
+
if (!m.messageContextInfo.messageSecret) {
|
|
943
|
+
m.messageContextInfo.messageSecret = randomBytes(32);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
509
946
|
return WAProto.Message.create(m);
|
|
510
947
|
};
|
|
511
948
|
export const generateWAMessageFromContent = (jid, message, options) => {
|
|
@@ -614,7 +1051,10 @@ export const normalizeMessageContent = (content) => {
|
|
|
614
1051
|
message?.documentWithCaptionMessage ||
|
|
615
1052
|
message?.viewOnceMessageV2 ||
|
|
616
1053
|
message?.viewOnceMessageV2Extension ||
|
|
617
|
-
message?.editedMessage
|
|
1054
|
+
message?.editedMessage ||
|
|
1055
|
+
message?.associatedChildMessage ||
|
|
1056
|
+
message?.groupStatusMessage ||
|
|
1057
|
+
message?.groupStatusMessageV2);
|
|
618
1058
|
}
|
|
619
1059
|
};
|
|
620
1060
|
/**
|