@baileys-md/baileys 10.1.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +1303 -2
- package/WAProto/GenerateStatics.sh +3 -0
- package/WAProto/WAProto.proto +4633 -0
- package/WAProto/fix-imports.js +29 -0
- package/WAProto/index.js +13516 -4182
- package/lib/Defaults/baileys-version.js +1 -0
- package/lib/Defaults/index.js +51 -72
- package/lib/Signal/Group/ciphertext-message.js +12 -0
- package/lib/Signal/Group/group-session-builder.js +30 -0
- package/lib/Signal/Group/group_cipher.js +94 -0
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/keyhelper.js +19 -0
- package/lib/Signal/Group/queue-job.js +54 -0
- package/lib/Signal/Group/sender-chain-key.js +32 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
- package/lib/Signal/Group/sender-key-message.js +67 -0
- package/lib/Signal/Group/sender-key-name.js +48 -0
- package/lib/Signal/Group/sender-key-record.js +50 -0
- package/lib/Signal/Group/sender-key-state.js +96 -0
- package/{WASignalGroup/sender_message_key.js → lib/Signal/Group/sender-message-key.js} +4 -16
- package/lib/Signal/libsignal.js +41 -61
- package/lib/Socket/Client/index.js +3 -19
- package/lib/Socket/Client/types.js +11 -0
- package/lib/Socket/Client/websocket.js +50 -0
- package/lib/Socket/business.js +37 -42
- package/lib/Socket/chats.js +194 -187
- package/lib/Socket/communities.js +351 -0
- package/lib/Socket/groups.js +87 -90
- package/lib/Socket/index.js +7 -8
- package/lib/Socket/messages-recv.js +360 -335
- package/lib/Socket/messages-send.js +156 -279
- package/lib/Socket/mex.js +42 -0
- package/lib/Socket/newsletter.js +144 -213
- package/lib/Socket/socket.js +128 -161
- package/lib/Socket/usync.js +19 -26
- package/lib/Types/Auth.js +2 -2
- package/lib/Types/Call.js +2 -2
- package/lib/Types/Chat.js +8 -4
- package/lib/Types/Contact.js +2 -2
- package/lib/Types/Events.js +2 -2
- package/lib/Types/GroupMetadata.js +2 -2
- package/lib/Types/Label.js +3 -5
- package/lib/Types/LabelAssociation.js +3 -5
- package/lib/Types/Message.js +7 -7
- package/lib/Types/Newsletter.js +30 -17
- package/lib/Types/Product.js +2 -2
- package/lib/Types/Signal.js +2 -2
- package/lib/Types/Socket.js +3 -2
- package/lib/Types/State.js +2 -2
- package/lib/Types/USync.js +2 -2
- package/lib/Types/index.js +15 -31
- package/lib/Utils/auth-utils.js +31 -47
- package/lib/Utils/baileys-event-stream.js +15 -22
- package/lib/Utils/business.js +66 -69
- package/lib/Utils/chat-utils.js +200 -195
- package/lib/Utils/crypto.js +70 -85
- package/lib/Utils/decode-wa-message.js +47 -51
- package/lib/Utils/event-buffer.js +36 -46
- package/lib/Utils/generics.js +116 -188
- package/lib/Utils/history.js +37 -46
- package/lib/Utils/index.js +19 -33
- package/lib/Utils/link-preview.js +14 -55
- package/lib/Utils/logger.js +3 -7
- package/lib/Utils/lt-hash.js +23 -26
- package/lib/{Store → Utils}/make-in-memory-store.js +19 -27
- package/lib/Utils/make-mutex.js +7 -10
- package/lib/{Store → Utils}/make-ordered-dictionary.js +1 -3
- package/lib/Utils/messages-media.js +236 -368
- package/lib/Utils/messages.js +278 -510
- package/lib/Utils/noise-handler.js +22 -31
- package/lib/{Store → Utils}/object-repository.js +1 -4
- package/lib/Utils/process-message.js +144 -148
- package/lib/Utils/signal.js +71 -64
- package/lib/Utils/use-multi-file-auth-state.js +112 -84
- package/lib/Utils/validate-connection.js +72 -115
- package/lib/WABinary/constants.js +1281 -20
- package/lib/WABinary/decode.js +15 -52
- package/lib/WABinary/encode.js +14 -48
- package/lib/WABinary/generic-utils.js +31 -39
- package/lib/WABinary/index.js +6 -21
- package/lib/WABinary/jid-utils.js +23 -40
- package/lib/WABinary/types.js +2 -2
- package/lib/WAM/BinaryInfo.js +2 -5
- package/lib/WAM/constants.js +2257 -2366
- package/lib/WAM/encode.js +17 -21
- package/lib/WAM/index.js +4 -19
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +8 -11
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +11 -14
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +9 -12
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +9 -13
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +20 -22
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +3 -6
- package/lib/WAUSync/Protocols/index.js +5 -20
- package/lib/WAUSync/USyncQuery.js +34 -32
- package/lib/WAUSync/USyncUser.js +2 -5
- package/lib/WAUSync/index.js +4 -19
- package/lib/index.js +11 -33
- package/package.json +25 -54
- package/WASignalGroup/GroupProtocol.js +0 -1697
- package/WASignalGroup/ciphertext_message.js +0 -16
- package/WASignalGroup/group_cipher.js +0 -120
- package/WASignalGroup/group_session_builder.js +0 -46
- package/WASignalGroup/index.js +0 -5
- package/WASignalGroup/keyhelper.js +0 -21
- package/WASignalGroup/protobufs.js +0 -3
- package/WASignalGroup/queue_job.js +0 -69
- package/WASignalGroup/sender_chain_key.js +0 -50
- package/WASignalGroup/sender_key_distribution_message.js +0 -78
- package/WASignalGroup/sender_key_message.js +0 -92
- package/WASignalGroup/sender_key_name.js +0 -70
- package/WASignalGroup/sender_key_record.js +0 -56
- package/WASignalGroup/sender_key_state.js +0 -129
- package/lib/Defaults/baileys-version.json +0 -3
- package/lib/Defaults/phonenumber-mcc.json +0 -223
- package/lib/Socket/Client/abstract-socket-client.js +0 -13
- package/lib/Socket/Client/mobile-socket-client.js +0 -65
- package/lib/Socket/Client/web-socket-client.js +0 -62
- package/lib/Socket/registration.js +0 -166
- package/lib/Store/index.js +0 -8
- package/lib/Store/make-cache-manager-store.js +0 -83
- package/lib/Store/make-mongo-store.js +0 -567
package/lib/Utils/messages.js
CHANGED
|
@@ -1,57 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const Defaults_1 = require("../Defaults");
|
|
14
|
-
const Types_1 = require("../Types");
|
|
15
|
-
const WABinary_1 = require("../WABinary");
|
|
16
|
-
const crypto_2 = require("./crypto");
|
|
17
|
-
const generics_1 = require("./generics");
|
|
18
|
-
const messages_media_1 = require("./messages-media");
|
|
1
|
+
import { Boom } from '@hapi/boom';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { randomBytes } from 'crypto';
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
import {} from 'stream';
|
|
6
|
+
import { proto } from '../../WAProto/index.js';
|
|
7
|
+
import { MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
|
|
8
|
+
import { WAMessageStatus, WAProto } from '../Types/index.js';
|
|
9
|
+
import { isJidGroup, isJidNewsletter, isJidStatusBroadcast, jidNormalizedUser } from '../WABinary/index.js';
|
|
10
|
+
import { sha256 } from './crypto.js';
|
|
11
|
+
import { generateMessageIDV2, getKeyAuthor, unixTimestampSeconds } from './generics.js';
|
|
12
|
+
import { downloadContentFromMessage, encryptedStream, generateThumbnail, getAudioDuration, getAudioWaveform, getRawMediaUploadData } from './messages-media.js';
|
|
19
13
|
const MIMETYPE_MAP = {
|
|
20
14
|
image: 'image/jpeg',
|
|
21
15
|
video: 'video/mp4',
|
|
22
16
|
document: 'application/pdf',
|
|
23
17
|
audio: 'audio/ogg; codecs=opus',
|
|
24
18
|
sticker: 'image/webp',
|
|
25
|
-
'product-catalog-image': 'image/jpeg'
|
|
19
|
+
'product-catalog-image': 'image/jpeg'
|
|
26
20
|
};
|
|
27
21
|
const MessageTypeProto = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
image: WAProto.Message.ImageMessage,
|
|
23
|
+
video: WAProto.Message.VideoMessage,
|
|
24
|
+
audio: WAProto.Message.AudioMessage,
|
|
25
|
+
sticker: WAProto.Message.StickerMessage,
|
|
26
|
+
document: WAProto.Message.DocumentMessage
|
|
33
27
|
};
|
|
34
|
-
const ButtonType = WAProto_1.proto.Message.ButtonsMessage.HeaderType;
|
|
35
28
|
/**
|
|
36
29
|
* Uses a regex to test whether the string contains a URL, and returns the URL if it does.
|
|
37
30
|
* @param text eg. hello https://google.com
|
|
38
31
|
* @returns the URL, eg. https://google.com
|
|
39
32
|
*/
|
|
40
|
-
const extractUrlFromText = (text) =>
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
const url = (0, exports.extractUrlFromText)(text);
|
|
33
|
+
export const extractUrlFromText = (text) => text.match(URL_REGEX)?.[0];
|
|
34
|
+
export const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
|
|
35
|
+
const url = extractUrlFromText(text);
|
|
44
36
|
if (!!getUrlInfo && url) {
|
|
45
37
|
try {
|
|
46
38
|
const urlInfo = await getUrlInfo(url);
|
|
47
39
|
return urlInfo;
|
|
48
40
|
}
|
|
49
|
-
catch (error) {
|
|
50
|
-
|
|
41
|
+
catch (error) {
|
|
42
|
+
// ignore if fails
|
|
43
|
+
logger?.warn({ trace: error.stack }, 'url generation failed');
|
|
51
44
|
}
|
|
52
45
|
}
|
|
53
46
|
};
|
|
54
|
-
exports.generateLinkPreviewIfRequired = generateLinkPreviewIfRequired;
|
|
55
47
|
const assertColor = async (color) => {
|
|
56
48
|
let assertedColor;
|
|
57
49
|
if (typeof color === 'number') {
|
|
@@ -66,16 +58,16 @@ const assertColor = async (color) => {
|
|
|
66
58
|
return assertedColor;
|
|
67
59
|
}
|
|
68
60
|
};
|
|
69
|
-
const prepareWAMessageMedia = async (message, options) => {
|
|
61
|
+
export const prepareWAMessageMedia = async (message, options) => {
|
|
70
62
|
const logger = options.logger;
|
|
71
63
|
let mediaType;
|
|
72
|
-
for (const key of
|
|
64
|
+
for (const key of MEDIA_KEYS) {
|
|
73
65
|
if (key in message) {
|
|
74
66
|
mediaType = key;
|
|
75
67
|
}
|
|
76
68
|
}
|
|
77
69
|
if (!mediaType) {
|
|
78
|
-
throw new
|
|
70
|
+
throw new Boom('Invalid media type', { statusCode: 400 });
|
|
79
71
|
}
|
|
80
72
|
const uploadData = {
|
|
81
73
|
...message,
|
|
@@ -84,102 +76,129 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
84
76
|
delete uploadData[mediaType];
|
|
85
77
|
// check if cacheable + generate cache key
|
|
86
78
|
const cacheableKey = typeof uploadData.media === 'object' &&
|
|
87
|
-
|
|
79
|
+
'url' in uploadData.media &&
|
|
88
80
|
!!uploadData.media.url &&
|
|
89
|
-
!!options.mediaCache &&
|
|
90
|
-
|
|
91
|
-
mediaType + ':' + uploadData.media.url.toString());
|
|
81
|
+
!!options.mediaCache &&
|
|
82
|
+
mediaType + ':' + uploadData.media.url.toString();
|
|
92
83
|
if (mediaType === 'document' && !uploadData.fileName) {
|
|
93
84
|
uploadData.fileName = 'file';
|
|
94
85
|
}
|
|
95
86
|
if (!uploadData.mimetype) {
|
|
96
87
|
uploadData.mimetype = MIMETYPE_MAP[mediaType];
|
|
97
88
|
}
|
|
98
|
-
// check for cache hit
|
|
99
89
|
if (cacheableKey) {
|
|
100
90
|
const mediaBuff = options.mediaCache.get(cacheableKey);
|
|
101
91
|
if (mediaBuff) {
|
|
102
|
-
logger
|
|
103
|
-
const obj =
|
|
92
|
+
logger?.debug({ cacheableKey }, 'got media cache hit');
|
|
93
|
+
const obj = WAProto.Message.decode(mediaBuff);
|
|
104
94
|
const key = `${mediaType}Message`;
|
|
105
95
|
Object.assign(obj[key], { ...uploadData, media: undefined });
|
|
106
96
|
return obj;
|
|
107
97
|
}
|
|
108
98
|
}
|
|
99
|
+
const isNewsletter = !!options.jid && isJidNewsletter(options.jid);
|
|
100
|
+
if (isNewsletter) {
|
|
101
|
+
logger?.info({ key: cacheableKey }, 'Preparing raw media for newsletter');
|
|
102
|
+
const { filePath, fileSha256, fileLength } = await getRawMediaUploadData(uploadData.media, options.mediaTypeOverride || mediaType, logger);
|
|
103
|
+
const fileSha256B64 = fileSha256.toString('base64');
|
|
104
|
+
const { mediaUrl, directPath } = await options.upload(filePath, {
|
|
105
|
+
fileEncSha256B64: fileSha256B64,
|
|
106
|
+
mediaType: mediaType,
|
|
107
|
+
timeoutMs: options.mediaUploadTimeoutMs
|
|
108
|
+
});
|
|
109
|
+
await fs.unlink(filePath);
|
|
110
|
+
const obj = WAProto.Message.fromObject({
|
|
111
|
+
// todo: add more support here
|
|
112
|
+
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
113
|
+
url: mediaUrl,
|
|
114
|
+
directPath,
|
|
115
|
+
fileSha256,
|
|
116
|
+
fileLength,
|
|
117
|
+
...uploadData,
|
|
118
|
+
media: undefined
|
|
119
|
+
})
|
|
120
|
+
});
|
|
121
|
+
if (uploadData.ptv) {
|
|
122
|
+
obj.ptvMessage = obj.videoMessage;
|
|
123
|
+
delete obj.videoMessage;
|
|
124
|
+
}
|
|
125
|
+
if (cacheableKey) {
|
|
126
|
+
logger?.debug({ cacheableKey }, 'set cache');
|
|
127
|
+
options.mediaCache.set(cacheableKey, WAProto.Message.encode(obj).finish());
|
|
128
|
+
}
|
|
129
|
+
return obj;
|
|
130
|
+
}
|
|
109
131
|
const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
|
|
110
|
-
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
|
|
111
|
-
(typeof uploadData['jpegThumbnail'] === 'undefined');
|
|
132
|
+
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && typeof uploadData['jpegThumbnail'] === 'undefined';
|
|
112
133
|
const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
|
|
113
134
|
const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
|
|
114
135
|
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
|
|
115
|
-
const { mediaKey,
|
|
136
|
+
const { mediaKey, encFilePath, originalFilePath, fileEncSha256, fileSha256, fileLength } = await encryptedStream(uploadData.media, options.mediaTypeOverride || mediaType, {
|
|
116
137
|
logger,
|
|
117
138
|
saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
|
|
118
139
|
opts: options.options
|
|
119
140
|
});
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
const [{ mediaUrl, directPath, handle }] = await Promise.all([
|
|
141
|
+
const fileEncSha256B64 = fileEncSha256.toString('base64');
|
|
142
|
+
const [{ mediaUrl, directPath }] = await Promise.all([
|
|
123
143
|
(async () => {
|
|
124
|
-
const result = await options.upload(
|
|
125
|
-
|
|
144
|
+
const result = await options.upload(encFilePath, {
|
|
145
|
+
fileEncSha256B64,
|
|
146
|
+
mediaType,
|
|
147
|
+
timeoutMs: options.mediaUploadTimeoutMs
|
|
148
|
+
});
|
|
149
|
+
logger?.debug({ mediaType, cacheableKey }, 'uploaded media');
|
|
126
150
|
return result;
|
|
127
151
|
})(),
|
|
128
152
|
(async () => {
|
|
129
153
|
try {
|
|
130
154
|
if (requiresThumbnailComputation) {
|
|
131
|
-
const { thumbnail, originalImageDimensions } = await
|
|
155
|
+
const { thumbnail, originalImageDimensions } = await generateThumbnail(originalFilePath, mediaType, options);
|
|
132
156
|
uploadData.jpegThumbnail = thumbnail;
|
|
133
157
|
if (!uploadData.width && originalImageDimensions) {
|
|
134
158
|
uploadData.width = originalImageDimensions.width;
|
|
135
159
|
uploadData.height = originalImageDimensions.height;
|
|
136
|
-
logger
|
|
160
|
+
logger?.debug('set dimensions');
|
|
137
161
|
}
|
|
138
|
-
logger
|
|
162
|
+
logger?.debug('generated thumbnail');
|
|
139
163
|
}
|
|
140
164
|
if (requiresDurationComputation) {
|
|
141
|
-
uploadData.seconds = await
|
|
142
|
-
logger
|
|
165
|
+
uploadData.seconds = await getAudioDuration(originalFilePath);
|
|
166
|
+
logger?.debug('computed audio duration');
|
|
143
167
|
}
|
|
144
168
|
if (requiresWaveformProcessing) {
|
|
145
|
-
uploadData.waveform = await
|
|
146
|
-
logger
|
|
169
|
+
uploadData.waveform = await getAudioWaveform(originalFilePath, logger);
|
|
170
|
+
logger?.debug('processed waveform');
|
|
147
171
|
}
|
|
148
172
|
if (requiresAudioBackground) {
|
|
149
173
|
uploadData.backgroundArgb = await assertColor(options.backgroundColor);
|
|
150
|
-
logger
|
|
174
|
+
logger?.debug('computed backgroundColor audio status');
|
|
151
175
|
}
|
|
152
176
|
}
|
|
153
177
|
catch (error) {
|
|
154
|
-
logger
|
|
155
|
-
}
|
|
156
|
-
})(),
|
|
157
|
-
])
|
|
158
|
-
.finally(async () => {
|
|
159
|
-
if (!Buffer.isBuffer(encWriteStream)) {
|
|
160
|
-
encWriteStream.destroy();
|
|
161
|
-
}
|
|
162
|
-
// remove tmp files
|
|
163
|
-
if (didSaveToTmpPath && bodyPath) {
|
|
164
|
-
try {
|
|
165
|
-
await fs_1.promises.access(bodyPath);
|
|
166
|
-
await fs_1.promises.unlink(bodyPath);
|
|
167
|
-
logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp file');
|
|
178
|
+
logger?.warn({ trace: error.stack }, 'failed to obtain extra info');
|
|
168
179
|
}
|
|
169
|
-
|
|
170
|
-
|
|
180
|
+
})()
|
|
181
|
+
]).finally(async () => {
|
|
182
|
+
try {
|
|
183
|
+
await fs.unlink(encFilePath);
|
|
184
|
+
if (originalFilePath) {
|
|
185
|
+
await fs.unlink(originalFilePath);
|
|
171
186
|
}
|
|
187
|
+
logger?.debug('removed tmp files');
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
logger?.warn('failed to remove tmp file');
|
|
172
191
|
}
|
|
173
192
|
});
|
|
174
|
-
const obj =
|
|
193
|
+
const obj = WAProto.Message.fromObject({
|
|
175
194
|
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
176
|
-
url:
|
|
195
|
+
url: mediaUrl,
|
|
177
196
|
directPath,
|
|
178
|
-
mediaKey
|
|
179
|
-
fileEncSha256
|
|
197
|
+
mediaKey,
|
|
198
|
+
fileEncSha256,
|
|
180
199
|
fileSha256,
|
|
181
200
|
fileLength,
|
|
182
|
-
mediaKeyTimestamp:
|
|
201
|
+
mediaKeyTimestamp: unixTimestampSeconds(),
|
|
183
202
|
...uploadData,
|
|
184
203
|
media: undefined
|
|
185
204
|
})
|
|
@@ -189,67 +208,63 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
189
208
|
delete obj.videoMessage;
|
|
190
209
|
}
|
|
191
210
|
if (cacheableKey) {
|
|
192
|
-
logger
|
|
193
|
-
options.mediaCache.set(cacheableKey,
|
|
211
|
+
logger?.debug({ cacheableKey }, 'set cache');
|
|
212
|
+
options.mediaCache.set(cacheableKey, WAProto.Message.encode(obj).finish());
|
|
194
213
|
}
|
|
195
214
|
return obj;
|
|
196
215
|
};
|
|
197
|
-
|
|
198
|
-
const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
|
|
216
|
+
export const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
|
|
199
217
|
ephemeralExpiration = ephemeralExpiration || 0;
|
|
200
218
|
const content = {
|
|
201
219
|
ephemeralMessage: {
|
|
202
220
|
message: {
|
|
203
221
|
protocolMessage: {
|
|
204
|
-
type:
|
|
222
|
+
type: WAProto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
|
|
205
223
|
ephemeralExpiration
|
|
206
224
|
}
|
|
207
225
|
}
|
|
208
226
|
}
|
|
209
227
|
};
|
|
210
|
-
return
|
|
228
|
+
return WAProto.Message.fromObject(content);
|
|
211
229
|
};
|
|
212
|
-
exports.prepareDisappearingMessageSettingContent = prepareDisappearingMessageSettingContent;
|
|
213
230
|
/**
|
|
214
231
|
* Generate forwarded message content like WA does
|
|
215
232
|
* @param message the message to forward
|
|
216
233
|
* @param options.forceForward will show the message as forwarded even if it is from you
|
|
217
234
|
*/
|
|
218
|
-
const generateForwardMessageContent = (message, forceForward) => {
|
|
219
|
-
var _a;
|
|
235
|
+
export const generateForwardMessageContent = (message, forceForward) => {
|
|
220
236
|
let content = message.message;
|
|
221
237
|
if (!content) {
|
|
222
|
-
throw new
|
|
238
|
+
throw new Boom('no content in message', { statusCode: 400 });
|
|
223
239
|
}
|
|
224
240
|
// hacky copy
|
|
225
|
-
content =
|
|
226
|
-
content =
|
|
241
|
+
content = normalizeMessageContent(content);
|
|
242
|
+
content = proto.Message.decode(proto.Message.encode(content).finish());
|
|
227
243
|
let key = Object.keys(content)[0];
|
|
228
|
-
let score =
|
|
244
|
+
let score = content?.[key]?.contextInfo?.forwardingScore || 0;
|
|
229
245
|
score += message.key.fromMe && !forceForward ? 0 : 1;
|
|
230
246
|
if (key === 'conversation') {
|
|
231
247
|
content.extendedTextMessage = { text: content[key] };
|
|
232
248
|
delete content.conversation;
|
|
233
249
|
key = 'extendedTextMessage';
|
|
234
250
|
}
|
|
251
|
+
const key_ = content?.[key];
|
|
235
252
|
if (score > 0) {
|
|
236
|
-
|
|
253
|
+
key_.contextInfo = { forwardingScore: score, isForwarded: true };
|
|
237
254
|
}
|
|
238
255
|
else {
|
|
239
|
-
|
|
256
|
+
key_.contextInfo = {};
|
|
240
257
|
}
|
|
241
258
|
return content;
|
|
242
259
|
};
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
246
|
-
var _p, _q;
|
|
260
|
+
export const generateWAMessageContent = async (message, options) => {
|
|
261
|
+
var _a, _b;
|
|
247
262
|
let m = {};
|
|
248
263
|
if ('text' in message) {
|
|
249
264
|
const extContent = { text: message.text };
|
|
250
265
|
let urlInfo = message.linkPreview;
|
|
251
266
|
if (typeof urlInfo === 'undefined') {
|
|
252
|
-
urlInfo = await
|
|
267
|
+
urlInfo = await generateLinkPreviewIfRequired(message.text, options.getUrlInfo, options.logger);
|
|
253
268
|
}
|
|
254
269
|
if (urlInfo) {
|
|
255
270
|
extContent.matchedText = urlInfo['matched-text'];
|
|
@@ -279,38 +294,40 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
279
294
|
else if ('contacts' in message) {
|
|
280
295
|
const contactLen = message.contacts.contacts.length;
|
|
281
296
|
if (!contactLen) {
|
|
282
|
-
throw new
|
|
297
|
+
throw new Boom('require atleast 1 contact', { statusCode: 400 });
|
|
283
298
|
}
|
|
284
299
|
if (contactLen === 1) {
|
|
285
|
-
m.contactMessage =
|
|
300
|
+
m.contactMessage = WAProto.Message.ContactMessage.fromObject(message.contacts.contacts[0]);
|
|
286
301
|
}
|
|
287
302
|
else {
|
|
288
|
-
m.contactsArrayMessage =
|
|
303
|
+
m.contactsArrayMessage = WAProto.Message.ContactsArrayMessage.fromObject(message.contacts);
|
|
289
304
|
}
|
|
290
305
|
}
|
|
291
306
|
else if ('location' in message) {
|
|
292
|
-
m.locationMessage =
|
|
307
|
+
m.locationMessage = WAProto.Message.LocationMessage.fromObject(message.location);
|
|
293
308
|
}
|
|
294
309
|
else if ('react' in message) {
|
|
295
310
|
if (!message.react.senderTimestampMs) {
|
|
296
311
|
message.react.senderTimestampMs = Date.now();
|
|
297
312
|
}
|
|
298
|
-
m.reactionMessage =
|
|
313
|
+
m.reactionMessage = WAProto.Message.ReactionMessage.fromObject(message.react);
|
|
299
314
|
}
|
|
300
315
|
else if ('delete' in message) {
|
|
301
316
|
m.protocolMessage = {
|
|
302
317
|
key: message.delete,
|
|
303
|
-
type:
|
|
318
|
+
type: WAProto.Message.ProtocolMessage.Type.REVOKE
|
|
304
319
|
};
|
|
305
320
|
}
|
|
306
321
|
else if ('forward' in message) {
|
|
307
|
-
m =
|
|
322
|
+
m = generateForwardMessageContent(message.forward, message.force);
|
|
308
323
|
}
|
|
309
324
|
else if ('disappearingMessagesInChat' in message) {
|
|
310
|
-
const exp = typeof message.disappearingMessagesInChat === 'boolean'
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
325
|
+
const exp = typeof message.disappearingMessagesInChat === 'boolean'
|
|
326
|
+
? message.disappearingMessagesInChat
|
|
327
|
+
? WA_DEFAULT_EPHEMERAL
|
|
328
|
+
: 0
|
|
329
|
+
: message.disappearingMessagesInChat;
|
|
330
|
+
m = prepareDisappearingMessageSettingContent(exp);
|
|
314
331
|
}
|
|
315
332
|
else if ('groupInvite' in message) {
|
|
316
333
|
m.groupInviteMessage = {};
|
|
@@ -324,7 +341,7 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
324
341
|
if (options.getProfilePicUrl) {
|
|
325
342
|
const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
|
|
326
343
|
if (pfpUrl) {
|
|
327
|
-
const resp = await
|
|
344
|
+
const resp = await axios.get(pfpUrl, { responseType: 'arraybuffer' });
|
|
328
345
|
if (resp.status === 200) {
|
|
329
346
|
m.groupInviteMessage.jpegThumbnail = resp.data;
|
|
330
347
|
}
|
|
@@ -339,328 +356,101 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
339
356
|
m.pinInChatMessage.senderTimestampMs = Date.now();
|
|
340
357
|
m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0;
|
|
341
358
|
}
|
|
342
|
-
else if ('keep' in message) {
|
|
343
|
-
m.keepInChatMessage = {};
|
|
344
|
-
m.keepInChatMessage.key = message.keep;
|
|
345
|
-
m.keepInChatMessage.keepType = message.type;
|
|
346
|
-
m.keepInChatMessage.timestampMs = Date.now();
|
|
347
|
-
}
|
|
348
|
-
else if ('call' in message) {
|
|
349
|
-
m = {
|
|
350
|
-
scheduledCallCreationMessage: {
|
|
351
|
-
scheduledTimestampMs: (_a = message.call.time) !== null && _a !== void 0 ? _a : Date.now(),
|
|
352
|
-
callType: (_b = message.call.type) !== null && _b !== void 0 ? _b : 1,
|
|
353
|
-
title: message.call.title
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
else if ('paymentInvite' in message) {
|
|
358
|
-
m.paymentInviteMessage = {
|
|
359
|
-
serviceType: message.paymentInvite.type,
|
|
360
|
-
expiryTimestamp: message.paymentInvite.expiry
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
359
|
else if ('buttonReply' in message) {
|
|
364
360
|
switch (message.type) {
|
|
365
361
|
case 'template':
|
|
366
362
|
m.templateButtonReplyMessage = {
|
|
367
363
|
selectedDisplayText: message.buttonReply.displayText,
|
|
368
364
|
selectedId: message.buttonReply.id,
|
|
369
|
-
selectedIndex: message.buttonReply.index
|
|
365
|
+
selectedIndex: message.buttonReply.index
|
|
370
366
|
};
|
|
371
367
|
break;
|
|
372
368
|
case 'plain':
|
|
373
369
|
m.buttonsResponseMessage = {
|
|
374
370
|
selectedButtonId: message.buttonReply.id,
|
|
375
371
|
selectedDisplayText: message.buttonReply.displayText,
|
|
376
|
-
type:
|
|
372
|
+
type: proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT
|
|
377
373
|
};
|
|
378
374
|
break;
|
|
379
375
|
}
|
|
380
376
|
}
|
|
381
377
|
else if ('ptv' in message && message.ptv) {
|
|
382
|
-
const { videoMessage } = await
|
|
378
|
+
const { videoMessage } = await prepareWAMessageMedia({ video: message.video }, options);
|
|
383
379
|
m.ptvMessage = videoMessage;
|
|
384
380
|
}
|
|
385
381
|
else if ('product' in message) {
|
|
386
|
-
const { imageMessage } = await
|
|
387
|
-
m.productMessage =
|
|
382
|
+
const { imageMessage } = await prepareWAMessageMedia({ image: message.product.productImage }, options);
|
|
383
|
+
m.productMessage = WAProto.Message.ProductMessage.fromObject({
|
|
388
384
|
...message,
|
|
389
385
|
product: {
|
|
390
386
|
...message.product,
|
|
391
|
-
productImage: imageMessage
|
|
387
|
+
productImage: imageMessage
|
|
392
388
|
}
|
|
393
389
|
});
|
|
394
390
|
}
|
|
395
|
-
else if ('order' in message) {
|
|
396
|
-
m.orderMessage = Types_1.WAProto.Message.OrderMessage.fromObject({
|
|
397
|
-
orderId: message.order.id,
|
|
398
|
-
thumbnail: message.order.thumbnail,
|
|
399
|
-
itemCount: message.order.itemCount,
|
|
400
|
-
status: message.order.status,
|
|
401
|
-
surface: message.order.surface,
|
|
402
|
-
orderTitle: message.order.title,
|
|
403
|
-
message: message.order.text,
|
|
404
|
-
sellerJid: message.order.seller,
|
|
405
|
-
token: message.order.token,
|
|
406
|
-
totalAmount1000: message.order.amount,
|
|
407
|
-
totalCurrencyCode: message.order.currency
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
391
|
else if ('listReply' in message) {
|
|
411
392
|
m.listResponseMessage = { ...message.listReply };
|
|
412
393
|
}
|
|
413
394
|
else if ('poll' in message) {
|
|
414
|
-
(
|
|
415
|
-
(
|
|
395
|
+
(_a = message.poll).selectableCount || (_a.selectableCount = 0);
|
|
396
|
+
(_b = message.poll).toAnnouncementGroup || (_b.toAnnouncementGroup = false);
|
|
416
397
|
if (!Array.isArray(message.poll.values)) {
|
|
417
|
-
throw new
|
|
398
|
+
throw new Boom('Invalid poll values', { statusCode: 400 });
|
|
418
399
|
}
|
|
419
|
-
if (message.poll.selectableCount < 0
|
|
420
|
-
|
|
421
|
-
|
|
400
|
+
if (message.poll.selectableCount < 0 || message.poll.selectableCount > message.poll.values.length) {
|
|
401
|
+
throw new Boom(`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`, {
|
|
402
|
+
statusCode: 400
|
|
403
|
+
});
|
|
422
404
|
}
|
|
423
405
|
m.messageContextInfo = {
|
|
424
406
|
// encKey
|
|
425
|
-
messageSecret: message.poll.messageSecret ||
|
|
407
|
+
messageSecret: message.poll.messageSecret || randomBytes(32)
|
|
426
408
|
};
|
|
427
409
|
const pollCreationMessage = {
|
|
428
410
|
name: message.poll.name,
|
|
429
411
|
selectableOptionsCount: message.poll.selectableCount,
|
|
430
|
-
options: message.poll.values.map(optionName => ({ optionName }))
|
|
412
|
+
options: message.poll.values.map(optionName => ({ optionName }))
|
|
431
413
|
};
|
|
432
414
|
if (message.poll.toAnnouncementGroup) {
|
|
433
415
|
// poll v2 is for community announcement groups (single select and multiple)
|
|
434
416
|
m.pollCreationMessageV2 = pollCreationMessage;
|
|
435
417
|
}
|
|
436
418
|
else {
|
|
437
|
-
if (message.poll.selectableCount
|
|
438
|
-
//
|
|
419
|
+
if (message.poll.selectableCount === 1) {
|
|
420
|
+
//poll v3 is for single select polls
|
|
439
421
|
m.pollCreationMessageV3 = pollCreationMessage;
|
|
440
422
|
}
|
|
441
423
|
else {
|
|
442
|
-
// poll
|
|
424
|
+
// poll for multiple choice polls
|
|
443
425
|
m.pollCreationMessage = pollCreationMessage;
|
|
444
426
|
}
|
|
445
427
|
}
|
|
446
428
|
}
|
|
447
|
-
else if ('event' in message) {
|
|
448
|
-
m.messageContextInfo = {
|
|
449
|
-
messageSecret: message.event.messageSecret || (0, crypto_1.randomBytes)(32),
|
|
450
|
-
};
|
|
451
|
-
m.eventMessage = { ...message.event };
|
|
452
|
-
}
|
|
453
|
-
else if ('inviteAdmin' in message) {
|
|
454
|
-
m.newsletterAdminInviteMessage = {};
|
|
455
|
-
m.newsletterAdminInviteMessage.inviteExpiration = message.inviteAdmin.inviteExpiration;
|
|
456
|
-
m.newsletterAdminInviteMessage.caption = message.inviteAdmin.text;
|
|
457
|
-
m.newsletterAdminInviteMessage.newsletterJid = message.inviteAdmin.jid;
|
|
458
|
-
m.newsletterAdminInviteMessage.newsletterName = message.inviteAdmin.subject;
|
|
459
|
-
m.newsletterAdminInviteMessage.jpegThumbnail = message.inviteAdmin.thumbnail;
|
|
460
|
-
}
|
|
461
|
-
else if ('requestPayment' in message) {
|
|
462
|
-
const sticker = ((_c = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _c === void 0 ? void 0 : _c.sticker) ?
|
|
463
|
-
await (0, exports.prepareWAMessageMedia)({ sticker: (_d = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _d === void 0 ? void 0 : _d.sticker, ...options }, options)
|
|
464
|
-
: null;
|
|
465
|
-
let notes = {};
|
|
466
|
-
if ((_e = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _e === void 0 ? void 0 : _e.sticker) {
|
|
467
|
-
notes = {
|
|
468
|
-
stickerMessage: {
|
|
469
|
-
...sticker === null || sticker === void 0 ? void 0 : sticker.stickerMessage,
|
|
470
|
-
contextInfo: (_f = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _f === void 0 ? void 0 : _f.contextInfo
|
|
471
|
-
}
|
|
472
|
-
};
|
|
473
|
-
}
|
|
474
|
-
else if (message.requestPayment.note) {
|
|
475
|
-
notes = {
|
|
476
|
-
extendedTextMessage: {
|
|
477
|
-
text: message.requestPayment.note,
|
|
478
|
-
contextInfo: (_g = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _g === void 0 ? void 0 : _g.contextInfo,
|
|
479
|
-
}
|
|
480
|
-
};
|
|
481
|
-
}
|
|
482
|
-
else {
|
|
483
|
-
throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
|
|
484
|
-
}
|
|
485
|
-
m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
|
|
486
|
-
expiryTimestamp: message.requestPayment.expiry,
|
|
487
|
-
amount1000: message.requestPayment.amount,
|
|
488
|
-
currencyCodeIso4217: message.requestPayment.currency,
|
|
489
|
-
requestFrom: message.requestPayment.from,
|
|
490
|
-
noteMessage: { ...notes },
|
|
491
|
-
background: (_h = message.requestPayment.background) !== null && _h !== void 0 ? _h : null,
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
429
|
else if ('sharePhoneNumber' in message) {
|
|
495
430
|
m.protocolMessage = {
|
|
496
|
-
type:
|
|
431
|
+
type: proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
|
|
497
432
|
};
|
|
498
433
|
}
|
|
499
434
|
else if ('requestPhoneNumber' in message) {
|
|
500
435
|
m.requestPhoneNumberMessage = {};
|
|
501
436
|
}
|
|
502
437
|
else {
|
|
503
|
-
m = await
|
|
504
|
-
}
|
|
505
|
-
if ('buttons' in message && !!message.buttons) {
|
|
506
|
-
const buttonsMessage = {
|
|
507
|
-
buttons: message.buttons.map(b => ({ ...b, type: WAProto_1.proto.Message.ButtonsMessage.Button.Type.RESPONSE }))
|
|
508
|
-
};
|
|
509
|
-
if ('text' in message) {
|
|
510
|
-
buttonsMessage.contentText = message.text;
|
|
511
|
-
buttonsMessage.headerType = ButtonType.EMPTY;
|
|
512
|
-
}
|
|
513
|
-
else {
|
|
514
|
-
if ('caption' in message) {
|
|
515
|
-
buttonsMessage.contentText = message.caption;
|
|
516
|
-
}
|
|
517
|
-
const type = Object.keys(m)[0].replace('Message', '').toUpperCase();
|
|
518
|
-
buttonsMessage.headerType = ButtonType[type];
|
|
519
|
-
Object.assign(buttonsMessage, m);
|
|
520
|
-
}
|
|
521
|
-
if ('title' in message && !!message.title) {
|
|
522
|
-
buttonsMessage.text = message.title,
|
|
523
|
-
buttonsMessage.headerType = ButtonType.TEXT;
|
|
524
|
-
}
|
|
525
|
-
if ('footer' in message && !!message.footer) {
|
|
526
|
-
buttonsMessage.footerText = message.footer;
|
|
527
|
-
}
|
|
528
|
-
if ('contextInfo' in message && !!message.contextInfo) {
|
|
529
|
-
buttonsMessage.contextInfo = message.contextInfo;
|
|
530
|
-
}
|
|
531
|
-
if ('mentions' in message && !!message.mentions) {
|
|
532
|
-
buttonsMessage.contextInfo = { mentionedJid: message.mentions };
|
|
533
|
-
}
|
|
534
|
-
m = { buttonsMessage };
|
|
438
|
+
m = await prepareWAMessageMedia(message, options);
|
|
535
439
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
hydratedButtons: message.hasOwnProperty("templateButtons") ? message.templateButtons : message.templateButtons
|
|
539
|
-
};
|
|
540
|
-
if ('text' in message) {
|
|
541
|
-
msg.hydratedContentText = message.text;
|
|
542
|
-
}
|
|
543
|
-
else {
|
|
544
|
-
if ('caption' in message) {
|
|
545
|
-
msg.hydratedContentText = message.caption;
|
|
546
|
-
}
|
|
547
|
-
Object.assign(msg, m);
|
|
548
|
-
}
|
|
549
|
-
if ('footer' in message && !!message.footer) {
|
|
550
|
-
msg.hydratedFooterText = message.footer;
|
|
551
|
-
}
|
|
552
|
-
m = {
|
|
553
|
-
templateMessage: {
|
|
554
|
-
fourRowTemplate: msg,
|
|
555
|
-
hydratedTemplate: msg
|
|
556
|
-
}
|
|
557
|
-
};
|
|
558
|
-
}
|
|
559
|
-
if ('sections' in message && !!message.sections) {
|
|
560
|
-
const listMessage = {
|
|
561
|
-
sections: message.sections,
|
|
562
|
-
buttonText: message.buttonText,
|
|
563
|
-
title: message.title,
|
|
564
|
-
footerText: message.footer,
|
|
565
|
-
description: message.text,
|
|
566
|
-
listType: message.hasOwnProperty('listType') ? message.listType : WAProto_1.proto.Message.ListMessage.ListType.PRODUCT_LIST
|
|
567
|
-
};
|
|
568
|
-
m = { listMessage };
|
|
440
|
+
if ('viewOnce' in message && !!message.viewOnce) {
|
|
441
|
+
m = { viewOnceMessage: { message: m } };
|
|
569
442
|
}
|
|
570
|
-
if ('
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
};
|
|
576
|
-
if ('text' in message) {
|
|
577
|
-
interactiveMessage.body = {
|
|
578
|
-
text: message.text
|
|
579
|
-
};
|
|
580
|
-
}
|
|
581
|
-
else if ('caption' in message) {
|
|
582
|
-
interactiveMessage.body = {
|
|
583
|
-
text: message.caption
|
|
584
|
-
};
|
|
585
|
-
interactiveMessage.header = {
|
|
586
|
-
title: message.title,
|
|
587
|
-
subtitle: message.subtitle,
|
|
588
|
-
hasMediaAttachment: (_j = message === null || message === void 0 ? void 0 : message.media) !== null && _j !== void 0 ? _j : false,
|
|
589
|
-
};
|
|
590
|
-
Object.assign(interactiveMessage.header, m);
|
|
591
|
-
}
|
|
592
|
-
if ('footer' in message && !!message.footer) {
|
|
593
|
-
interactiveMessage.footer = {
|
|
594
|
-
text: message.footer
|
|
595
|
-
};
|
|
443
|
+
if ('mentions' in message && message.mentions?.length) {
|
|
444
|
+
const messageType = Object.keys(m)[0];
|
|
445
|
+
const key = m[messageType];
|
|
446
|
+
if ('contextInfo' in key && !!key.contextInfo) {
|
|
447
|
+
key.contextInfo.mentionedJid = message.mentions;
|
|
596
448
|
}
|
|
597
|
-
if (
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
subtitle: message.subtitle,
|
|
601
|
-
hasMediaAttachment: (_k = message === null || message === void 0 ? void 0 : message.media) !== null && _k !== void 0 ? _k : false,
|
|
449
|
+
else if (key) {
|
|
450
|
+
key.contextInfo = {
|
|
451
|
+
mentionedJid: message.mentions
|
|
602
452
|
};
|
|
603
|
-
Object.assign(interactiveMessage.header, m);
|
|
604
453
|
}
|
|
605
|
-
if ('contextInfo' in message && !!message.contextInfo) {
|
|
606
|
-
interactiveMessage.contextInfo = message.contextInfo;
|
|
607
|
-
}
|
|
608
|
-
if ('mentions' in message && !!message.mentions) {
|
|
609
|
-
interactiveMessage.contextInfo = { mentionedJid: message.mentions };
|
|
610
|
-
}
|
|
611
|
-
m = { interactiveMessage };
|
|
612
|
-
}
|
|
613
|
-
if ('shop' in message && !!message.shop) {
|
|
614
|
-
const interactiveMessage = {
|
|
615
|
-
shopStorefrontMessage: Types_1.WAProto.Message.InteractiveMessage.ShopMessage.fromObject({
|
|
616
|
-
surface: message.shop,
|
|
617
|
-
id: message.id
|
|
618
|
-
})
|
|
619
|
-
};
|
|
620
|
-
if ('text' in message) {
|
|
621
|
-
interactiveMessage.body = {
|
|
622
|
-
text: message.text
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
else if ('caption' in message) {
|
|
626
|
-
interactiveMessage.body = {
|
|
627
|
-
text: message.caption
|
|
628
|
-
};
|
|
629
|
-
interactiveMessage.header = {
|
|
630
|
-
title: message.title,
|
|
631
|
-
subtitle: message.subtitle,
|
|
632
|
-
hasMediaAttachment: (_l = message === null || message === void 0 ? void 0 : message.media) !== null && _l !== void 0 ? _l : false,
|
|
633
|
-
};
|
|
634
|
-
Object.assign(interactiveMessage.header, m);
|
|
635
|
-
}
|
|
636
|
-
if ('footer' in message && !!message.footer) {
|
|
637
|
-
interactiveMessage.footer = {
|
|
638
|
-
text: message.footer
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
if ('title' in message && !!message.title) {
|
|
642
|
-
interactiveMessage.header = {
|
|
643
|
-
title: message.title,
|
|
644
|
-
subtitle: message.subtitle,
|
|
645
|
-
hasMediaAttachment: (_m = message === null || message === void 0 ? void 0 : message.media) !== null && _m !== void 0 ? _m : false,
|
|
646
|
-
};
|
|
647
|
-
Object.assign(interactiveMessage.header, m);
|
|
648
|
-
}
|
|
649
|
-
if ('contextInfo' in message && !!message.contextInfo) {
|
|
650
|
-
interactiveMessage.contextInfo = message.contextInfo;
|
|
651
|
-
}
|
|
652
|
-
if ('mentions' in message && !!message.mentions) {
|
|
653
|
-
interactiveMessage.contextInfo = { mentionedJid: message.mentions };
|
|
654
|
-
}
|
|
655
|
-
m = { interactiveMessage };
|
|
656
|
-
}
|
|
657
|
-
if ('viewOnce' in message && !!message.viewOnce) {
|
|
658
|
-
m = { viewOnceMessage: { message: m } };
|
|
659
|
-
}
|
|
660
|
-
if ('mentions' in message && ((_o = message.mentions) === null || _o === void 0 ? void 0 : _o.length)) {
|
|
661
|
-
const [messageType] = Object.keys(m);
|
|
662
|
-
m[messageType].contextInfo = m[messageType] || {};
|
|
663
|
-
m[messageType].contextInfo.mentionedJid = message.mentions;
|
|
664
454
|
}
|
|
665
455
|
if ('edit' in message) {
|
|
666
456
|
m = {
|
|
@@ -668,106 +458,110 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
668
458
|
key: message.edit,
|
|
669
459
|
editedMessage: m,
|
|
670
460
|
timestampMs: Date.now(),
|
|
671
|
-
type:
|
|
461
|
+
type: WAProto.Message.ProtocolMessage.Type.MESSAGE_EDIT
|
|
672
462
|
}
|
|
673
463
|
};
|
|
674
464
|
}
|
|
675
465
|
if ('contextInfo' in message && !!message.contextInfo) {
|
|
676
|
-
const
|
|
677
|
-
|
|
678
|
-
|
|
466
|
+
const messageType = Object.keys(m)[0];
|
|
467
|
+
const key = m[messageType];
|
|
468
|
+
if ('contextInfo' in key && !!key.contextInfo) {
|
|
469
|
+
key.contextInfo = { ...key.contextInfo, ...message.contextInfo };
|
|
470
|
+
}
|
|
471
|
+
else if (key) {
|
|
472
|
+
key.contextInfo = message.contextInfo;
|
|
473
|
+
}
|
|
679
474
|
}
|
|
680
|
-
return
|
|
475
|
+
return WAProto.Message.fromObject(m);
|
|
681
476
|
};
|
|
682
|
-
|
|
683
|
-
const generateWAMessageFromContent = (jid, message, options) => {
|
|
477
|
+
export const generateWAMessageFromContent = (jid, message, options) => {
|
|
684
478
|
// set timestamp to now
|
|
685
479
|
// if not specified
|
|
686
480
|
if (!options.timestamp) {
|
|
687
481
|
options.timestamp = new Date();
|
|
688
482
|
}
|
|
689
|
-
const innerMessage =
|
|
690
|
-
const key =
|
|
691
|
-
const timestamp =
|
|
483
|
+
const innerMessage = normalizeMessageContent(message);
|
|
484
|
+
const key = getContentType(innerMessage);
|
|
485
|
+
const timestamp = unixTimestampSeconds(options.timestamp);
|
|
692
486
|
const { quoted, userJid } = options;
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
487
|
+
if (quoted && !isJidNewsletter(jid)) {
|
|
488
|
+
const participant = quoted.key.fromMe
|
|
489
|
+
? userJid
|
|
490
|
+
: quoted.participant || quoted.key.participant || quoted.key.remoteJid;
|
|
491
|
+
let quotedMsg = normalizeMessageContent(quoted.message);
|
|
492
|
+
const msgType = getContentType(quotedMsg);
|
|
698
493
|
// strip any redundant properties
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
494
|
+
quotedMsg = proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
|
|
495
|
+
const quotedContent = quotedMsg[msgType];
|
|
496
|
+
if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
|
|
497
|
+
delete quotedContent.contextInfo;
|
|
498
|
+
}
|
|
499
|
+
const contextInfo = ('contextInfo' in innerMessage[key] && innerMessage[key]?.contextInfo) || {};
|
|
500
|
+
contextInfo.participant = jidNormalizedUser(participant);
|
|
501
|
+
contextInfo.stanzaId = quoted.key.id;
|
|
502
|
+
contextInfo.quotedMessage = quotedMsg;
|
|
503
|
+
// if a participant is quoted, then it must be a group
|
|
504
|
+
// hence, remoteJid of group must also be entered
|
|
505
|
+
if (jid !== quoted.key.remoteJid) {
|
|
506
|
+
contextInfo.remoteJid = quoted.key.remoteJid;
|
|
507
|
+
}
|
|
508
|
+
if (contextInfo && innerMessage[key]) {
|
|
509
|
+
/* @ts-ignore */
|
|
714
510
|
innerMessage[key].contextInfo = contextInfo;
|
|
715
511
|
}
|
|
716
512
|
}
|
|
717
513
|
if (
|
|
718
514
|
// if we want to send a disappearing message
|
|
719
|
-
!!
|
|
515
|
+
!!options?.ephemeralExpiration &&
|
|
720
516
|
// and it's not a protocol message -- delete, toggle disappear message
|
|
721
517
|
key !== 'protocolMessage' &&
|
|
722
518
|
// already not converted to disappearing message
|
|
723
519
|
key !== 'ephemeralMessage' &&
|
|
724
|
-
//
|
|
725
|
-
!
|
|
520
|
+
// newsletters don't support ephemeral messages
|
|
521
|
+
!isJidNewsletter(jid)) {
|
|
522
|
+
/* @ts-ignore */
|
|
726
523
|
innerMessage[key].contextInfo = {
|
|
727
524
|
...(innerMessage[key].contextInfo || {}),
|
|
728
|
-
expiration: options.ephemeralExpiration ||
|
|
525
|
+
expiration: options.ephemeralExpiration || WA_DEFAULT_EPHEMERAL
|
|
729
526
|
//ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString()
|
|
730
527
|
};
|
|
731
528
|
}
|
|
732
|
-
message =
|
|
529
|
+
message = WAProto.Message.fromObject(message);
|
|
733
530
|
const messageJSON = {
|
|
734
531
|
key: {
|
|
735
532
|
remoteJid: jid,
|
|
736
533
|
fromMe: true,
|
|
737
|
-
id:
|
|
534
|
+
id: options?.messageId || generateMessageIDV2()
|
|
738
535
|
},
|
|
739
536
|
message: message,
|
|
740
537
|
messageTimestamp: timestamp,
|
|
741
538
|
messageStubParameters: [],
|
|
742
|
-
participant:
|
|
743
|
-
status:
|
|
539
|
+
participant: isJidGroup(jid) || isJidStatusBroadcast(jid) ? userJid : undefined,
|
|
540
|
+
status: WAMessageStatus.PENDING
|
|
744
541
|
};
|
|
745
|
-
return
|
|
542
|
+
return WAProto.WebMessageInfo.fromObject(messageJSON);
|
|
746
543
|
};
|
|
747
|
-
|
|
748
|
-
const generateWAMessage = async (jid, content, options) => {
|
|
749
|
-
var _a;
|
|
544
|
+
export const generateWAMessage = async (jid, content, options) => {
|
|
750
545
|
// ensure msg ID is with every log
|
|
751
|
-
options.logger =
|
|
752
|
-
|
|
546
|
+
options.logger = options?.logger?.child({ msgId: options.messageId });
|
|
547
|
+
// Pass jid in the options to generateWAMessageContent
|
|
548
|
+
return generateWAMessageFromContent(jid, await generateWAMessageContent(content, { ...options, jid }), options);
|
|
753
549
|
};
|
|
754
|
-
exports.generateWAMessage = generateWAMessage;
|
|
755
550
|
/** Get the key to access the true type of content */
|
|
756
|
-
const getContentType = (content) => {
|
|
551
|
+
export const getContentType = (content) => {
|
|
757
552
|
if (content) {
|
|
758
553
|
const keys = Object.keys(content);
|
|
759
554
|
const key = keys.find(k => (k === 'conversation' || k.includes('Message')) && k !== 'senderKeyDistributionMessage');
|
|
760
555
|
return key;
|
|
761
556
|
}
|
|
762
557
|
};
|
|
763
|
-
exports.getContentType = getContentType;
|
|
764
558
|
/**
|
|
765
559
|
* Normalizes ephemeral, view once messages to regular message content
|
|
766
560
|
* Eg. image messages in ephemeral messages, in view once messages etc.
|
|
767
561
|
* @param content
|
|
768
562
|
* @returns
|
|
769
563
|
*/
|
|
770
|
-
const normalizeMessageContent = (content) => {
|
|
564
|
+
export const normalizeMessageContent = (content) => {
|
|
771
565
|
if (!content) {
|
|
772
566
|
return undefined;
|
|
773
567
|
}
|
|
@@ -781,33 +575,19 @@ const normalizeMessageContent = (content) => {
|
|
|
781
575
|
}
|
|
782
576
|
return content;
|
|
783
577
|
function getFutureProofMessage(message) {
|
|
784
|
-
return (
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|| (message === null || message === void 0 ? void 0 : message.groupMentionedMessage)
|
|
791
|
-
|| (message === null || message === void 0 ? void 0 : message.botInvokeMessage)
|
|
792
|
-
|| (message === null || message === void 0 ? void 0 : message.lottieStickerMessage)
|
|
793
|
-
|| (message === null || message === void 0 ? void 0 : message.eventCoverImage)
|
|
794
|
-
|| (message === null || message === void 0 ? void 0 : message.statusMentionMessage)
|
|
795
|
-
|| (message === null || message === void 0 ? void 0 : message.pollCreationOptionImageMessage)
|
|
796
|
-
|| (message === null || message === void 0 ? void 0 : message.associatedChildMessage)
|
|
797
|
-
|| (message === null || message === void 0 ? void 0 : message.groupStatusMentionMessage)
|
|
798
|
-
|| (message === null || message === void 0 ? void 0 : message.pollCreationMessageV4)
|
|
799
|
-
|| (message === null || message === void 0 ? void 0 : message.pollCreationMessageV5)
|
|
800
|
-
|| (message === null || message === void 0 ? void 0 : message.statusAddYours)
|
|
801
|
-
|| (message === null || message === void 0 ? void 0 : message.groupStatusMessage));
|
|
578
|
+
return (message?.ephemeralMessage ||
|
|
579
|
+
message?.viewOnceMessage ||
|
|
580
|
+
message?.documentWithCaptionMessage ||
|
|
581
|
+
message?.viewOnceMessageV2 ||
|
|
582
|
+
message?.viewOnceMessageV2Extension ||
|
|
583
|
+
message?.editedMessage);
|
|
802
584
|
}
|
|
803
585
|
};
|
|
804
|
-
exports.normalizeMessageContent = normalizeMessageContent;
|
|
805
586
|
/**
|
|
806
587
|
* Extract the true message content from a message
|
|
807
588
|
* Eg. extracts the inner message from a disappearing message/view once message
|
|
808
589
|
*/
|
|
809
|
-
const extractMessageContent = (content) => {
|
|
810
|
-
var _a, _b, _c, _d, _e, _f;
|
|
590
|
+
export const extractMessageContent = (content) => {
|
|
811
591
|
const extractFromTemplateMessage = (msg) => {
|
|
812
592
|
if (msg.imageMessage) {
|
|
813
593
|
return { imageMessage: msg.imageMessage };
|
|
@@ -823,39 +603,39 @@ const extractMessageContent = (content) => {
|
|
|
823
603
|
}
|
|
824
604
|
else {
|
|
825
605
|
return {
|
|
826
|
-
conversation: 'contentText' in msg
|
|
827
|
-
? msg.contentText
|
|
828
|
-
: ('hydratedContentText' in msg ? msg.hydratedContentText : '')
|
|
606
|
+
conversation: 'contentText' in msg ? msg.contentText : 'hydratedContentText' in msg ? msg.hydratedContentText : ''
|
|
829
607
|
};
|
|
830
608
|
}
|
|
831
609
|
};
|
|
832
|
-
content =
|
|
833
|
-
if (content
|
|
610
|
+
content = normalizeMessageContent(content);
|
|
611
|
+
if (content?.buttonsMessage) {
|
|
834
612
|
return extractFromTemplateMessage(content.buttonsMessage);
|
|
835
613
|
}
|
|
836
|
-
if (
|
|
837
|
-
return extractFromTemplateMessage(
|
|
614
|
+
if (content?.templateMessage?.hydratedFourRowTemplate) {
|
|
615
|
+
return extractFromTemplateMessage(content?.templateMessage?.hydratedFourRowTemplate);
|
|
838
616
|
}
|
|
839
|
-
if (
|
|
840
|
-
return extractFromTemplateMessage(
|
|
617
|
+
if (content?.templateMessage?.hydratedTemplate) {
|
|
618
|
+
return extractFromTemplateMessage(content?.templateMessage?.hydratedTemplate);
|
|
841
619
|
}
|
|
842
|
-
if (
|
|
843
|
-
return extractFromTemplateMessage(
|
|
620
|
+
if (content?.templateMessage?.fourRowTemplate) {
|
|
621
|
+
return extractFromTemplateMessage(content?.templateMessage?.fourRowTemplate);
|
|
844
622
|
}
|
|
845
623
|
return content;
|
|
846
624
|
};
|
|
847
|
-
exports.extractMessageContent = extractMessageContent;
|
|
848
625
|
/**
|
|
849
626
|
* Returns the device predicted by message ID
|
|
850
627
|
*/
|
|
851
|
-
const getDevice = (id) => /^3A.{18}$/.test(id)
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
628
|
+
export const getDevice = (id) => /^3A.{18}$/.test(id)
|
|
629
|
+
? 'ios'
|
|
630
|
+
: /^3E.{20}$/.test(id)
|
|
631
|
+
? 'web'
|
|
632
|
+
: /^(.{21}|.{32})$/.test(id)
|
|
633
|
+
? 'android'
|
|
634
|
+
: /^(3F|.{18}$)/.test(id)
|
|
635
|
+
? 'desktop'
|
|
636
|
+
: 'unknown';
|
|
857
637
|
/** Upserts a receipt in the message */
|
|
858
|
-
const updateMessageWithReceipt = (msg, receipt) => {
|
|
638
|
+
export const updateMessageWithReceipt = (msg, receipt) => {
|
|
859
639
|
msg.userReceipt = msg.userReceipt || [];
|
|
860
640
|
const recp = msg.userReceipt.find(m => m.userJid === receipt.userJid);
|
|
861
641
|
if (recp) {
|
|
@@ -865,41 +645,36 @@ const updateMessageWithReceipt = (msg, receipt) => {
|
|
|
865
645
|
msg.userReceipt.push(receipt);
|
|
866
646
|
}
|
|
867
647
|
};
|
|
868
|
-
exports.updateMessageWithReceipt = updateMessageWithReceipt;
|
|
869
648
|
/** Update the message with a new reaction */
|
|
870
|
-
const updateMessageWithReaction = (msg, reaction) => {
|
|
871
|
-
const authorID =
|
|
872
|
-
const reactions = (msg.reactions || [])
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
reactions.push(reaction);
|
|
876
|
-
}
|
|
649
|
+
export const updateMessageWithReaction = (msg, reaction) => {
|
|
650
|
+
const authorID = getKeyAuthor(reaction.key);
|
|
651
|
+
const reactions = (msg.reactions || []).filter(r => getKeyAuthor(r.key) !== authorID);
|
|
652
|
+
reaction.text = reaction.text || '';
|
|
653
|
+
reactions.push(reaction);
|
|
877
654
|
msg.reactions = reactions;
|
|
878
655
|
};
|
|
879
|
-
exports.updateMessageWithReaction = updateMessageWithReaction;
|
|
880
656
|
/** Update the message with a new poll update */
|
|
881
|
-
const updateMessageWithPollUpdate = (msg, update) => {
|
|
882
|
-
|
|
883
|
-
const
|
|
884
|
-
|
|
885
|
-
.filter(r => (0, generics_1.getKeyAuthor)(r.pollUpdateMessageKey) !== authorID);
|
|
886
|
-
if ((_b = (_a = update.vote) === null || _a === void 0 ? void 0 : _a.selectedOptions) === null || _b === void 0 ? void 0 : _b.length) {
|
|
657
|
+
export const updateMessageWithPollUpdate = (msg, update) => {
|
|
658
|
+
const authorID = getKeyAuthor(update.pollUpdateMessageKey);
|
|
659
|
+
const reactions = (msg.pollUpdates || []).filter(r => getKeyAuthor(r.pollUpdateMessageKey) !== authorID);
|
|
660
|
+
if (update.vote?.selectedOptions?.length) {
|
|
887
661
|
reactions.push(update);
|
|
888
662
|
}
|
|
889
663
|
msg.pollUpdates = reactions;
|
|
890
664
|
};
|
|
891
|
-
exports.updateMessageWithPollUpdate = updateMessageWithPollUpdate;
|
|
892
665
|
/**
|
|
893
666
|
* Aggregates all poll updates in a poll.
|
|
894
667
|
* @param msg the poll creation message
|
|
895
668
|
* @param meId your jid
|
|
896
669
|
* @returns A list of options & their voters
|
|
897
670
|
*/
|
|
898
|
-
function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
|
|
899
|
-
|
|
900
|
-
|
|
671
|
+
export function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
|
|
672
|
+
const opts = message?.pollCreationMessage?.options ||
|
|
673
|
+
message?.pollCreationMessageV2?.options ||
|
|
674
|
+
message?.pollCreationMessageV3?.options ||
|
|
675
|
+
[];
|
|
901
676
|
const voteHashMap = opts.reduce((acc, opt) => {
|
|
902
|
-
const hash =
|
|
677
|
+
const hash = sha256(Buffer.from(opt.optionName || '')).toString();
|
|
903
678
|
acc[hash] = {
|
|
904
679
|
name: opt.optionName || '',
|
|
905
680
|
voters: []
|
|
@@ -921,13 +696,13 @@ function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
|
|
|
921
696
|
};
|
|
922
697
|
data = voteHashMap[hash];
|
|
923
698
|
}
|
|
924
|
-
voteHashMap[hash].voters.push(
|
|
699
|
+
voteHashMap[hash].voters.push(getKeyAuthor(update.pollUpdateMessageKey, meId));
|
|
925
700
|
}
|
|
926
701
|
}
|
|
927
702
|
return Object.values(voteHashMap);
|
|
928
703
|
}
|
|
929
704
|
/** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
|
|
930
|
-
const aggregateMessageKeysNotFromMe = (keys) => {
|
|
705
|
+
export const aggregateMessageKeysNotFromMe = (keys) => {
|
|
931
706
|
const keyMap = {};
|
|
932
707
|
for (const { remoteJid, id, participant, fromMe } of keys) {
|
|
933
708
|
if (!fromMe) {
|
|
@@ -944,40 +719,34 @@ const aggregateMessageKeysNotFromMe = (keys) => {
|
|
|
944
719
|
}
|
|
945
720
|
return Object.values(keyMap);
|
|
946
721
|
};
|
|
947
|
-
exports.aggregateMessageKeysNotFromMe = aggregateMessageKeysNotFromMe;
|
|
948
722
|
const REUPLOAD_REQUIRED_STATUS = [410, 404];
|
|
949
723
|
/**
|
|
950
724
|
* Downloads the given message. Throws an error if it's not a media message
|
|
951
725
|
*/
|
|
952
|
-
const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
953
|
-
const result = await downloadMsg()
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
message = await ctx.reuploadRequest(message);
|
|
963
|
-
const result = await downloadMsg();
|
|
964
|
-
return result;
|
|
965
|
-
}
|
|
966
|
-
}
|
|
726
|
+
export const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
727
|
+
const result = await downloadMsg().catch(async (error) => {
|
|
728
|
+
if (ctx &&
|
|
729
|
+
axios.isAxiosError(error) && // check if the message requires a reupload
|
|
730
|
+
REUPLOAD_REQUIRED_STATUS.includes(error.response?.status)) {
|
|
731
|
+
ctx.logger.info({ key: message.key }, 'sending reupload media request...');
|
|
732
|
+
// request reupload
|
|
733
|
+
message = await ctx.reuploadRequest(message);
|
|
734
|
+
const result = await downloadMsg();
|
|
735
|
+
return result;
|
|
967
736
|
}
|
|
968
737
|
throw error;
|
|
969
738
|
});
|
|
970
739
|
return result;
|
|
971
740
|
async function downloadMsg() {
|
|
972
|
-
const mContent =
|
|
741
|
+
const mContent = extractMessageContent(message.message);
|
|
973
742
|
if (!mContent) {
|
|
974
|
-
throw new
|
|
743
|
+
throw new Boom('No message present', { statusCode: 400, data: message });
|
|
975
744
|
}
|
|
976
|
-
const contentType =
|
|
977
|
-
let mediaType = contentType
|
|
745
|
+
const contentType = getContentType(mContent);
|
|
746
|
+
let mediaType = contentType?.replace('Message', '');
|
|
978
747
|
const media = mContent[contentType];
|
|
979
748
|
if (!media || typeof media !== 'object' || (!('url' in media) && !('thumbnailDirectPath' in media))) {
|
|
980
|
-
throw new
|
|
749
|
+
throw new Boom(`"${contentType}" message is not a media message`);
|
|
981
750
|
}
|
|
982
751
|
let download;
|
|
983
752
|
if ('thumbnailDirectPath' in media && !('url' in media)) {
|
|
@@ -990,7 +759,7 @@ const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
|
990
759
|
else {
|
|
991
760
|
download = media;
|
|
992
761
|
}
|
|
993
|
-
const stream = await
|
|
762
|
+
const stream = await downloadContentFromMessage(download, mediaType, options);
|
|
994
763
|
if (type === 'buffer') {
|
|
995
764
|
const bufferArray = [];
|
|
996
765
|
for await (const chunk of stream) {
|
|
@@ -1001,18 +770,17 @@ const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
|
1001
770
|
return stream;
|
|
1002
771
|
}
|
|
1003
772
|
};
|
|
1004
|
-
exports.downloadMediaMessage = downloadMediaMessage;
|
|
1005
773
|
/** Checks whether the given message is a media message; if it is returns the inner content */
|
|
1006
|
-
const assertMediaContent = (content) => {
|
|
1007
|
-
content =
|
|
1008
|
-
const mediaContent =
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
774
|
+
export const assertMediaContent = (content) => {
|
|
775
|
+
content = extractMessageContent(content);
|
|
776
|
+
const mediaContent = content?.documentMessage ||
|
|
777
|
+
content?.imageMessage ||
|
|
778
|
+
content?.videoMessage ||
|
|
779
|
+
content?.audioMessage ||
|
|
780
|
+
content?.stickerMessage;
|
|
1013
781
|
if (!mediaContent) {
|
|
1014
|
-
throw new
|
|
782
|
+
throw new Boom('given message is not a media message', { statusCode: 400, data: content });
|
|
1015
783
|
}
|
|
1016
784
|
return mediaContent;
|
|
1017
785
|
};
|
|
1018
|
-
|
|
786
|
+
//# sourceMappingURL=messages.js.map
|