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