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