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