@gqb333/based 2.7.82 → 2.7.83
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/lib/Utils/messages.js +183 -1451
- package/package.json +1 -1
package/lib/Utils/messages.js
CHANGED
|
@@ -16,6 +16,7 @@ const WABinary_1 = require("../WABinary");
|
|
|
16
16
|
const crypto_2 = require("./crypto");
|
|
17
17
|
const generics_1 = require("./generics");
|
|
18
18
|
const messages_media_1 = require("./messages-media");
|
|
19
|
+
|
|
19
20
|
const MIMETYPE_MAP = {
|
|
20
21
|
image: 'image/jpeg',
|
|
21
22
|
video: 'video/mp4',
|
|
@@ -24,6 +25,7 @@ const MIMETYPE_MAP = {
|
|
|
24
25
|
sticker: 'image/webp',
|
|
25
26
|
'product-catalog-image': 'image/jpeg',
|
|
26
27
|
};
|
|
28
|
+
|
|
27
29
|
const MessageTypeProto = {
|
|
28
30
|
'image': Types_1.WAProto.Message.ImageMessage,
|
|
29
31
|
'video': Types_1.WAProto.Message.VideoMessage,
|
|
@@ -31,14 +33,16 @@ const MessageTypeProto = {
|
|
|
31
33
|
'sticker': Types_1.WAProto.Message.StickerMessage,
|
|
32
34
|
'document': Types_1.WAProto.Message.DocumentMessage,
|
|
33
35
|
};
|
|
36
|
+
|
|
34
37
|
const ButtonType = WAProto_1.proto.Message.ButtonsMessage.HeaderType;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
|
|
39
|
+
const mediaCache = new Map();
|
|
40
|
+
const CACHE_MAX_SIZE = 100;
|
|
41
|
+
const CACHE_TTL = 3600000;
|
|
42
|
+
|
|
40
43
|
const extractUrlFromText = (text) => { var _a; return (_a = text.match(Defaults_1.URL_REGEX)) === null || _a === void 0 ? void 0 : _a[0]; };
|
|
41
44
|
exports.extractUrlFromText = extractUrlFromText;
|
|
45
|
+
|
|
42
46
|
const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
|
|
43
47
|
const url = (0, exports.extractUrlFromText)(text);
|
|
44
48
|
if (!!getUrlInfo && url) {
|
|
@@ -46,12 +50,13 @@ const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
|
|
|
46
50
|
const urlInfo = await getUrlInfo(url);
|
|
47
51
|
return urlInfo;
|
|
48
52
|
}
|
|
49
|
-
catch (error) {
|
|
53
|
+
catch (error) {
|
|
50
54
|
logger === null || logger === void 0 ? void 0 : logger.warn({ trace: error.stack }, 'url generation failed');
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
};
|
|
54
58
|
exports.generateLinkPreviewIfRequired = generateLinkPreviewIfRequired;
|
|
59
|
+
|
|
55
60
|
const assertColor = async (color) => {
|
|
56
61
|
let assertedColor;
|
|
57
62
|
if (typeof color === 'number') {
|
|
@@ -67,61 +72,88 @@ const assertColor = async (color) => {
|
|
|
67
72
|
return assertedColor;
|
|
68
73
|
}
|
|
69
74
|
};
|
|
75
|
+
|
|
76
|
+
const cleanMediaCache = () => {
|
|
77
|
+
if (mediaCache.size > CACHE_MAX_SIZE) {
|
|
78
|
+
const entriesToDelete = mediaCache.size - CACHE_MAX_SIZE;
|
|
79
|
+
const keys = Array.from(mediaCache.keys()).slice(0, entriesToDelete);
|
|
80
|
+
keys.forEach(key => mediaCache.delete(key));
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
70
84
|
const prepareWAMessageMedia = async (message, options) => {
|
|
71
85
|
const logger = options.logger;
|
|
72
86
|
let mediaType;
|
|
87
|
+
|
|
73
88
|
for (const key of Defaults_1.MEDIA_KEYS) {
|
|
74
89
|
if (key in message) {
|
|
75
90
|
mediaType = key;
|
|
91
|
+
break;
|
|
76
92
|
}
|
|
77
93
|
}
|
|
94
|
+
|
|
78
95
|
if (!mediaType) {
|
|
79
96
|
throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
|
|
80
97
|
}
|
|
98
|
+
|
|
81
99
|
const uploadData = {
|
|
82
100
|
...message,
|
|
83
101
|
media: message[mediaType]
|
|
84
102
|
};
|
|
85
103
|
delete uploadData[mediaType];
|
|
86
|
-
|
|
104
|
+
|
|
87
105
|
const cacheableKey = typeof uploadData.media === 'object' &&
|
|
88
106
|
('url' in uploadData.media) &&
|
|
89
107
|
!!uploadData.media.url &&
|
|
90
108
|
!!options.mediaCache && (
|
|
91
|
-
|
|
92
|
-
|
|
109
|
+
mediaType + ':' + uploadData.media.url.toString());
|
|
110
|
+
|
|
93
111
|
if (mediaType === 'document' && !uploadData.fileName) {
|
|
94
112
|
uploadData.fileName = 'file';
|
|
95
113
|
}
|
|
114
|
+
|
|
96
115
|
if (!uploadData.mimetype) {
|
|
97
116
|
uploadData.mimetype = MIMETYPE_MAP[mediaType];
|
|
98
117
|
}
|
|
99
|
-
|
|
118
|
+
|
|
100
119
|
if (cacheableKey) {
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
103
|
-
logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, '
|
|
104
|
-
const obj = Types_1.WAProto.Message.decode(
|
|
120
|
+
const cached = mediaCache.get(cacheableKey);
|
|
121
|
+
if (cached && (Date.now() - cached.timestamp < CACHE_TTL)) {
|
|
122
|
+
logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'media cache hit');
|
|
123
|
+
const obj = Types_1.WAProto.Message.decode(cached.data);
|
|
105
124
|
const key = `${mediaType}Message`;
|
|
106
125
|
Object.assign(obj[key], { ...uploadData, media: undefined });
|
|
107
126
|
return obj;
|
|
108
127
|
}
|
|
109
128
|
}
|
|
129
|
+
|
|
110
130
|
const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
|
|
111
131
|
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
|
|
112
132
|
(typeof uploadData['jpegThumbnail'] === 'undefined');
|
|
113
133
|
const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
|
|
114
134
|
const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
|
|
115
135
|
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
136
|
+
|
|
137
|
+
const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath } =
|
|
138
|
+
await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(
|
|
139
|
+
uploadData.media,
|
|
140
|
+
options.mediaTypeOverride || mediaType,
|
|
141
|
+
{
|
|
142
|
+
logger,
|
|
143
|
+
saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
|
|
144
|
+
opts: options.options
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
|
|
121
148
|
const fileEncSha256B64 = (options.newsletter ? fileSha256 : fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256).toString('base64');
|
|
149
|
+
|
|
122
150
|
const [{ mediaUrl, directPath, handle }] = await Promise.all([
|
|
123
151
|
(async () => {
|
|
124
|
-
const result = await options.upload(encWriteStream, {
|
|
152
|
+
const result = await options.upload(encWriteStream, {
|
|
153
|
+
fileEncSha256B64,
|
|
154
|
+
mediaType,
|
|
155
|
+
timeoutMs: options.mediaUploadTimeoutMs || 60000
|
|
156
|
+
});
|
|
125
157
|
logger === null || logger === void 0 ? void 0 : logger.debug({ mediaType, cacheableKey }, 'uploaded media');
|
|
126
158
|
return result;
|
|
127
159
|
})(),
|
|
@@ -154,160 +186,60 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
154
186
|
logger === null || logger === void 0 ? void 0 : logger.warn({ trace: error.stack }, 'failed to obtain extra info');
|
|
155
187
|
}
|
|
156
188
|
})(),
|
|
157
|
-
])
|
|
158
|
-
.finally(async () => {
|
|
189
|
+
]).finally(async () => {
|
|
159
190
|
if (!Buffer.isBuffer(encWriteStream)) {
|
|
160
191
|
encWriteStream.destroy();
|
|
161
192
|
}
|
|
162
|
-
// remove tmp files
|
|
163
193
|
if (didSaveToTmpPath && bodyPath) {
|
|
164
194
|
try {
|
|
165
195
|
await fs_1.promises.access(bodyPath);
|
|
166
196
|
await fs_1.promises.unlink(bodyPath);
|
|
167
|
-
logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp file');
|
|
168
|
-
}
|
|
169
|
-
catch (error) {
|
|
170
|
-
logger === null || logger === void 0 ? void 0 : logger.warn('failed to remove tmp file');
|
|
171
197
|
}
|
|
198
|
+
catch { }
|
|
172
199
|
}
|
|
173
200
|
});
|
|
201
|
+
|
|
202
|
+
const message = MessageTypeProto[mediaType].fromObject({
|
|
203
|
+
url: mediaUrl,
|
|
204
|
+
directPath,
|
|
205
|
+
mediaKey,
|
|
206
|
+
fileEncSha256: options.newsletter ? fileSha256 : fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256,
|
|
207
|
+
fileSha256: fileSha256,
|
|
208
|
+
fileLength: fileLength,
|
|
209
|
+
mediaKeyTimestamp: (0, generics_1.unixTimestampSeconds)(),
|
|
210
|
+
handle,
|
|
211
|
+
...uploadData,
|
|
212
|
+
media: undefined
|
|
213
|
+
});
|
|
214
|
+
|
|
174
215
|
const obj = Types_1.WAProto.Message.fromObject({
|
|
175
|
-
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject(
|
|
176
|
-
url: handle ? undefined : mediaUrl,
|
|
177
|
-
directPath,
|
|
178
|
-
mediaKey: mediaKey,
|
|
179
|
-
fileEncSha256: fileEncSha256,
|
|
180
|
-
fileSha256,
|
|
181
|
-
fileLength,
|
|
182
|
-
mediaKeyTimestamp: handle ? undefined : (0, generics_1.unixTimestampSeconds)(),
|
|
183
|
-
...uploadData,
|
|
184
|
-
media: undefined
|
|
185
|
-
})
|
|
216
|
+
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject(message)
|
|
186
217
|
});
|
|
187
|
-
|
|
188
|
-
obj.ptvMessage = obj.videoMessage;
|
|
189
|
-
delete obj.videoMessage;
|
|
190
|
-
}
|
|
218
|
+
|
|
191
219
|
if (cacheableKey) {
|
|
192
|
-
|
|
193
|
-
|
|
220
|
+
const encoded = Types_1.WAProto.Message.encode(obj).finish();
|
|
221
|
+
mediaCache.set(cacheableKey, {
|
|
222
|
+
data: encoded,
|
|
223
|
+
timestamp: Date.now()
|
|
224
|
+
});
|
|
225
|
+
cleanMediaCache();
|
|
194
226
|
}
|
|
227
|
+
|
|
195
228
|
return obj;
|
|
196
229
|
};
|
|
197
230
|
exports.prepareWAMessageMedia = prepareWAMessageMedia;
|
|
198
|
-
const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
|
|
199
|
-
ephemeralExpiration = ephemeralExpiration || 0;
|
|
200
|
-
const content = {
|
|
201
|
-
ephemeralMessage: {
|
|
202
|
-
message: {
|
|
203
|
-
protocolMessage: {
|
|
204
|
-
type: Types_1.WAProto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
|
|
205
|
-
ephemeralExpiration
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
return Types_1.WAProto.Message.fromObject(content);
|
|
211
|
-
};
|
|
212
|
-
exports.prepareDisappearingMessageSettingContent = prepareDisappearingMessageSettingContent;
|
|
213
|
-
/**
|
|
214
|
-
* Generate forwarded message content like WA does
|
|
215
|
-
* @param message the message to forward
|
|
216
|
-
* @param options.forceForward will show the message as forwarded even if it is from you
|
|
217
|
-
*/
|
|
218
|
-
const generateForwardMessageContent = (message, forceForward) => {
|
|
219
|
-
var _a;
|
|
220
|
-
let content = message.message;
|
|
221
|
-
if (!content) {
|
|
222
|
-
throw new boom_1.Boom('no content in message', { statusCode: 400 });
|
|
223
|
-
}
|
|
224
|
-
// hacky copy
|
|
225
|
-
content = (0, exports.normalizeMessageContent)(content);
|
|
226
|
-
content = WAProto_1.proto.Message.decode(WAProto_1.proto.Message.encode(content).finish());
|
|
227
|
-
let key = Object.keys(content)[0];
|
|
228
|
-
let score = ((_a = content[key].contextInfo) === null || _a === void 0 ? void 0 : _a.forwardingScore) || 0;
|
|
229
|
-
score += message.key.fromMe && !forceForward ? 0 : 1;
|
|
230
|
-
if (key === 'conversation') {
|
|
231
|
-
content.extendedTextMessage = { text: content[key] };
|
|
232
|
-
delete content.conversation;
|
|
233
|
-
key = 'extendedTextMessage';
|
|
234
|
-
}
|
|
235
|
-
if (score > 0) {
|
|
236
|
-
content[key].contextInfo = { forwardingScore: score, isForwarded: true };
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
content[key].contextInfo = {};
|
|
240
|
-
}
|
|
241
|
-
return content;
|
|
242
|
-
};
|
|
243
|
-
exports.generateForwardMessageContent = generateForwardMessageContent;
|
|
244
|
-
const generateWAMessageContent = async (message, options) => {
|
|
245
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
246
|
-
var _p, _q;
|
|
247
|
-
|
|
248
|
-
// Cross-platform externalAdReply thumbnail handling
|
|
249
|
-
const fixupExternalAdReplyThumb = async (externalAdReply) => {
|
|
250
|
-
const thumbUrl = externalAdReply.originalImageUrl || externalAdReply.thumbnailUrl;
|
|
251
|
-
const currentThumb = externalAdReply.thumbnail;
|
|
252
|
-
const currentThumbLen = currentThumb && typeof currentThumb.length === 'number' ? currentThumb.length : 0;
|
|
253
|
-
if (thumbUrl && (!currentThumb || currentThumbLen < 2000)) {
|
|
254
|
-
try {
|
|
255
|
-
const stream = await (0, messages_media_1.getHttpStream)(thumbUrl, {
|
|
256
|
-
timeout: 8000,
|
|
257
|
-
headers: {
|
|
258
|
-
'User-Agent': 'WhatsApp/2.23.20.15 iOS/16.0 Device/iPhone'
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
|
-
const { buffer } = await (0, messages_media_1.extractImageThumb)(stream, 512, 80);
|
|
262
|
-
externalAdReply.thumbnail = buffer;
|
|
263
|
-
}
|
|
264
|
-
catch (error) {
|
|
265
|
-
options.logger?.warn('Failed to generate externalAdReply thumbnail for cross-platform compatibility:', error.message);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
if (externalAdReply.renderLargerThumbnail === undefined) {
|
|
269
|
-
externalAdReply.renderLargerThumbnail = true;
|
|
270
|
-
}
|
|
271
|
-
return externalAdReply;
|
|
272
|
-
};
|
|
273
|
-
if (message.contextInfo?.externalAdReply) {
|
|
274
|
-
message.contextInfo.externalAdReply = await fixupExternalAdReplyThumb(message.contextInfo.externalAdReply);
|
|
275
|
-
}
|
|
276
|
-
if (message.externalAdReply) {
|
|
277
|
-
message.externalAdReply = await fixupExternalAdReplyThumb(message.externalAdReply);
|
|
278
|
-
}
|
|
279
231
|
|
|
232
|
+
const generateWAMessageContent = async (message, options) => {
|
|
280
233
|
let m = {};
|
|
234
|
+
|
|
281
235
|
if ('text' in message) {
|
|
282
|
-
const extContent =
|
|
283
|
-
|
|
284
|
-
if (
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
extContent.matchedText = urlInfo['matched-text'];
|
|
289
|
-
extContent.jpegThumbnail = urlInfo.jpegThumbnail;
|
|
290
|
-
extContent.description = urlInfo.description;
|
|
291
|
-
extContent.title = urlInfo.title;
|
|
292
|
-
extContent.previewType = 0;
|
|
293
|
-
const img = urlInfo.highQualityThumbnail;
|
|
294
|
-
if (img) {
|
|
295
|
-
extContent.thumbnailDirectPath = img.directPath;
|
|
296
|
-
extContent.mediaKey = img.mediaKey;
|
|
297
|
-
extContent.mediaKeyTimestamp = img.mediaKeyTimestamp;
|
|
298
|
-
extContent.thumbnailWidth = img.width;
|
|
299
|
-
extContent.thumbnailHeight = img.height;
|
|
300
|
-
extContent.thumbnailSha256 = img.fileSha256;
|
|
301
|
-
extContent.thumbnailEncSha256 = img.fileEncSha256;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
if (options.backgroundColor) {
|
|
305
|
-
extContent.backgroundArgb = await assertColor(options.backgroundColor);
|
|
306
|
-
}
|
|
307
|
-
if (options.font) {
|
|
308
|
-
extContent.font = options.font;
|
|
236
|
+
const extContent = await (0, exports.generateLinkPreviewIfRequired)(message.text, options.getUrlInfo, options.logger);
|
|
237
|
+
m.extendedTextMessage = { text: message.text };
|
|
238
|
+
if (extContent) {
|
|
239
|
+
m.extendedTextMessage.contextInfo = {
|
|
240
|
+
externalAdReply: extContent
|
|
241
|
+
};
|
|
309
242
|
}
|
|
310
|
-
m.extendedTextMessage = extContent;
|
|
311
243
|
}
|
|
312
244
|
else if ('contacts' in message) {
|
|
313
245
|
const contactLen = message.contacts.contacts.length;
|
|
@@ -324,13 +256,7 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
324
256
|
else if ('location' in message) {
|
|
325
257
|
m.locationMessage = Types_1.WAProto.Message.LocationMessage.fromObject(message.location);
|
|
326
258
|
}
|
|
327
|
-
else if ('liveLocation' in message) {
|
|
328
|
-
m.liveLocationMessage = Types_1.WAProto.Message.LiveLocationMessage.fromObject(message.liveLocation);
|
|
329
|
-
}
|
|
330
259
|
else if ('react' in message) {
|
|
331
|
-
if (!message.react.senderTimestampMs) {
|
|
332
|
-
message.react.senderTimestampMs = Date.now();
|
|
333
|
-
}
|
|
334
260
|
m.reactionMessage = Types_1.WAProto.Message.ReactionMessage.fromObject(message.react);
|
|
335
261
|
}
|
|
336
262
|
else if ('delete' in message) {
|
|
@@ -339,948 +265,66 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
339
265
|
type: Types_1.WAProto.Message.ProtocolMessage.Type.REVOKE
|
|
340
266
|
};
|
|
341
267
|
}
|
|
342
|
-
else if ('forward' in message) {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const exp = typeof message.disappearingMessagesInChat === 'boolean' ?
|
|
347
|
-
(message.disappearingMessagesInChat ? Defaults_1.WA_DEFAULT_EPHEMERAL : 0) :
|
|
348
|
-
message.disappearingMessagesInChat;
|
|
349
|
-
m = (0, exports.prepareDisappearingMessageSettingContent)(exp);
|
|
350
|
-
}
|
|
351
|
-
else if ('groupInvite' in message) {
|
|
352
|
-
m.groupInviteMessage = {};
|
|
353
|
-
m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
|
|
354
|
-
m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
|
|
355
|
-
m.groupInviteMessage.caption = message.groupInvite.text;
|
|
356
|
-
m.groupInviteMessage.groupJid = message.groupInvite.jid;
|
|
357
|
-
m.groupInviteMessage.groupName = message.groupInvite.subject;
|
|
358
|
-
|
|
359
|
-
// Get group metadata to obtain disappearing mode and other group info
|
|
360
|
-
if (options.groupMetadata) {
|
|
361
|
-
try {
|
|
362
|
-
const groupMetadata = await options.groupMetadata(message.groupInvite.jid);
|
|
363
|
-
if (groupMetadata) {
|
|
364
|
-
// Add disappearing mode info if available
|
|
365
|
-
if (groupMetadata.ephemeralDuration !== undefined) {
|
|
366
|
-
m.groupInviteMessage.ephemeralDuration = groupMetadata.ephemeralDuration;
|
|
367
|
-
}
|
|
368
|
-
// Add group subject from metadata if not provided in message
|
|
369
|
-
if (!m.groupInviteMessage.groupName && groupMetadata.subject) {
|
|
370
|
-
m.groupInviteMessage.groupName = groupMetadata.subject;
|
|
371
|
-
}
|
|
372
|
-
// Add group participant count
|
|
373
|
-
if (groupMetadata.participants) {
|
|
374
|
-
m.groupInviteMessage.groupSize = groupMetadata.participants.length;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
} catch (error) {
|
|
378
|
-
options.logger?.debug({ error, jid: message.groupInvite.jid }, 'Failed to fetch group metadata for invite');
|
|
379
|
-
}
|
|
268
|
+
else if ('forward' in message || 'copy' in message) {
|
|
269
|
+
const content = (0, exports.normalizeMessageContent)(message.forward || message.copy);
|
|
270
|
+
if (!content) {
|
|
271
|
+
throw new boom_1.Boom('no content present in forwarded/copied message', { statusCode: 400 });
|
|
380
272
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
if (options.cache && options.cache.get) {
|
|
388
|
-
const cachedPfp = options.cache.get(cacheKey);
|
|
389
|
-
if (cachedPfp) {
|
|
390
|
-
m.groupInviteMessage.jpegThumbnail = cachedPfp;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
// Fetch if not in cache
|
|
395
|
-
if (!m.groupInviteMessage.jpegThumbnail) {
|
|
396
|
-
try {
|
|
397
|
-
const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
|
|
398
|
-
if (pfpUrl) {
|
|
399
|
-
const resp = await axios_1.default.get(pfpUrl, {
|
|
400
|
-
responseType: 'arraybuffer',
|
|
401
|
-
timeout: 5000,
|
|
402
|
-
headers: {
|
|
403
|
-
'User-Agent': 'WhatsApp/2.23.20.15 iOS/16.0 Device/iPhone'
|
|
404
|
-
}
|
|
405
|
-
});
|
|
406
|
-
if (resp.status === 200) {
|
|
407
|
-
m.groupInviteMessage.jpegThumbnail = resp.data;
|
|
408
|
-
|
|
409
|
-
// Cache the result if cache is available
|
|
410
|
-
if (options.cache && options.cache.set) {
|
|
411
|
-
options.cache.set(cacheKey, resp.data, 3600); // Cache for 1 hour
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
} catch (error) {
|
|
416
|
-
options.logger?.debug({ error, jid: message.groupInvite.jid }, 'Failed to fetch group profile picture');
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
else if ('pin' in message) {
|
|
422
|
-
const pinData = typeof message.pin === 'object' ? message.pin : { key: message.pin };
|
|
423
|
-
// Map type: 1 = PIN_FOR_ALL, 2 = UNPIN_FOR_ALL
|
|
424
|
-
const pinType = pinData.type !== undefined ? pinData.type : (message.type !== undefined ? message.type : WAProto_1.proto.Message.PinInChatMessage.Type.PIN_FOR_ALL);
|
|
425
|
-
m.pinInChatMessage = {
|
|
426
|
-
key: pinData.key,
|
|
427
|
-
type: pinType,
|
|
428
|
-
senderTimestampMs: Date.now()
|
|
429
|
-
};
|
|
430
|
-
// Add messageContextInfo only for PIN (type 1), not for UNPIN (type 2)
|
|
431
|
-
if (pinType === WAProto_1.proto.Message.PinInChatMessage.Type.PIN_FOR_ALL) {
|
|
432
|
-
m.messageContextInfo = {
|
|
433
|
-
messageAddOnDurationInSecs: pinData.time || message.time || 86400, // Default 24 hours
|
|
434
|
-
messageAddOnExpiryType: WAProto_1.proto.MessageContextInfo.MessageAddonExpiryType.STATIC
|
|
273
|
+
let key = Object.keys(content)[0];
|
|
274
|
+
let score = content[key].contextInfo?.forwardingScore || 0;
|
|
275
|
+
score += message.force ? 0 : 1;
|
|
276
|
+
if (key === 'conversation') {
|
|
277
|
+
m.extendedTextMessage = {
|
|
278
|
+
text: content[key]
|
|
435
279
|
};
|
|
436
|
-
|
|
437
|
-
}
|
|
438
|
-
else if ('keep' in message) {
|
|
439
|
-
m.keepInChatMessage = {};
|
|
440
|
-
m.keepInChatMessage.key = message.keep;
|
|
441
|
-
m.keepInChatMessage.keepType = message.type;
|
|
442
|
-
m.keepInChatMessage.timestampMs = Date.now();
|
|
443
|
-
}
|
|
444
|
-
else if ('call' in message) {
|
|
445
|
-
const call = message.call;
|
|
446
|
-
if (call && typeof call === 'object' && (
|
|
447
|
-
'callKey' in call
|
|
448
|
-
|| 'conversionSource' in call
|
|
449
|
-
|| 'conversionData' in call
|
|
450
|
-
|| 'conversionDelaySeconds' in call
|
|
451
|
-
|| 'ctwaSignals' in call
|
|
452
|
-
|| 'ctwaPayload' in call
|
|
453
|
-
|| 'nativeFlowCallButtonPayload' in call
|
|
454
|
-
|| 'deeplinkPayload' in call
|
|
455
|
-
)) {
|
|
456
|
-
m.call = WAProto_1.proto.Message.Call.fromObject(call);
|
|
280
|
+
key = 'extendedTextMessage';
|
|
457
281
|
}
|
|
458
282
|
else {
|
|
459
|
-
m = {
|
|
460
|
-
scheduledCallCreationMessage: {
|
|
461
|
-
scheduledTimestampMs: (_a = call === null || call === void 0 ? void 0 : call.time) !== null && _a !== void 0 ? _a : Date.now(),
|
|
462
|
-
callType: (_b = call === null || call === void 0 ? void 0 : call.type) !== null && _b !== void 0 ? _b : 1,
|
|
463
|
-
title: call === null || call === void 0 ? void 0 : call.title
|
|
464
|
-
}
|
|
465
|
-
};
|
|
283
|
+
m = { [key]: content[key] };
|
|
466
284
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
m.paymentInviteMessage = {
|
|
470
|
-
serviceType: message.paymentInvite.type,
|
|
471
|
-
expiryTimestamp: message.paymentInvite.expiry
|
|
472
|
-
};
|
|
473
|
-
}
|
|
474
|
-
else if ('buttonReply' in message) {
|
|
475
|
-
switch (message.type) {
|
|
476
|
-
case 'template':
|
|
477
|
-
m.templateButtonReplyMessage = {
|
|
478
|
-
selectedDisplayText: message.buttonReply.displayText,
|
|
479
|
-
selectedId: message.buttonReply.id,
|
|
480
|
-
selectedIndex: message.buttonReply.index,
|
|
481
|
-
selectedCarouselCardIndex: message.buttonReply.carouselCardIndex
|
|
482
|
-
};
|
|
483
|
-
break;
|
|
484
|
-
case 'plain':
|
|
485
|
-
m.buttonsResponseMessage = {
|
|
486
|
-
selectedButtonId: message.buttonReply.id,
|
|
487
|
-
selectedDisplayText: message.buttonReply.displayText,
|
|
488
|
-
type: WAProto_1.proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT,
|
|
489
|
-
};
|
|
490
|
-
break;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
else if ('ptv' in message && message.ptv) {
|
|
494
|
-
const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
|
|
495
|
-
m.ptvMessage = videoMessage;
|
|
496
|
-
}
|
|
497
|
-
else if ('product' in message) {
|
|
498
|
-
const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
|
|
499
|
-
m.productMessage = Types_1.WAProto.Message.ProductMessage.fromObject({
|
|
500
|
-
...message,
|
|
501
|
-
product: {
|
|
502
|
-
...message.product,
|
|
503
|
-
productImage: imageMessage,
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
else if ('order' in message) {
|
|
508
|
-
m.orderMessage = Types_1.WAProto.Message.OrderMessage.fromObject({
|
|
509
|
-
orderId: message.order.id,
|
|
510
|
-
thumbnail: message.order.thumbnail,
|
|
511
|
-
itemCount: message.order.itemCount,
|
|
512
|
-
status: message.order.status,
|
|
513
|
-
surface: message.order.surface,
|
|
514
|
-
orderTitle: message.order.title,
|
|
515
|
-
message: message.order.text,
|
|
516
|
-
sellerJid: message.order.seller,
|
|
517
|
-
token: message.order.token,
|
|
518
|
-
totalAmount1000: message.order.amount,
|
|
519
|
-
totalCurrencyCode: message.order.currency
|
|
520
|
-
});
|
|
521
|
-
}
|
|
522
|
-
else if ('listReply' in message) {
|
|
523
|
-
m.listResponseMessage = { ...message.listReply };
|
|
524
|
-
}
|
|
525
|
-
else if ('poll' in message) {
|
|
526
|
-
(_p = message.poll).selectableCount || (_p.selectableCount = 0);
|
|
527
|
-
(_q = message.poll).toAnnouncementGroup || (_q.toAnnouncementGroup = false);
|
|
528
|
-
if (!Array.isArray(message.poll.values)) {
|
|
529
|
-
throw new boom_1.Boom('Invalid poll values', { statusCode: 400 });
|
|
530
|
-
}
|
|
531
|
-
if (message.poll.selectableCount < 0
|
|
532
|
-
|| message.poll.selectableCount > message.poll.values.length) {
|
|
533
|
-
throw new boom_1.Boom(`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`, { statusCode: 400 });
|
|
534
|
-
}
|
|
535
|
-
m.messageContextInfo = {
|
|
536
|
-
// encKey
|
|
537
|
-
messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32),
|
|
538
|
-
};
|
|
539
|
-
const pollCreationMessage = {
|
|
540
|
-
name: message.poll.name,
|
|
541
|
-
selectableOptionsCount: message.poll.selectableCount,
|
|
542
|
-
options: message.poll.values.map(optionName => ({ optionName })),
|
|
543
|
-
};
|
|
544
|
-
if (message.poll.toAnnouncementGroup) {
|
|
545
|
-
// poll v2 is for community announcement groups (single select and multiple)
|
|
546
|
-
m.pollCreationMessageV2 = pollCreationMessage;
|
|
285
|
+
if (score > 0) {
|
|
286
|
+
m[key].contextInfo = { ...(m[key].contextInfo || {}), forwardingScore: score, isForwarded: true };
|
|
547
287
|
}
|
|
548
288
|
else {
|
|
549
|
-
|
|
550
|
-
// poll v3 is for single select polls
|
|
551
|
-
m.pollCreationMessageV3 = pollCreationMessage;
|
|
552
|
-
}
|
|
553
|
-
else {
|
|
554
|
-
// poll for multiple choice polls
|
|
555
|
-
m.pollCreationMessage = pollCreationMessage;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
else if ('pollResultSnapshotV3' in message && !!message.pollResultSnapshotV3) {
|
|
560
|
-
m.pollResultSnapshotMessageV3 = {
|
|
561
|
-
pollCreationMessageKey: message.pollResultSnapshotV3.pollCreationMessageKey,
|
|
562
|
-
pollResult: message.pollResultSnapshotV3.pollResult,
|
|
563
|
-
selectedOptions: message.pollResultSnapshotV3.selectedOptions,
|
|
564
|
-
contextInfo: message.pollResultSnapshotV3.contextInfo,
|
|
565
|
-
pollType: message.pollResultSnapshotV3.pollType
|
|
566
|
-
};
|
|
567
|
-
}
|
|
568
|
-
else if ('pollV4' in message) {
|
|
569
|
-
const pollCreationMessage = {
|
|
570
|
-
name: message.pollV4.name,
|
|
571
|
-
selectableOptionsCount: message.pollV4.selectableCount,
|
|
572
|
-
options: message.pollV4.values.map(optionName => ({ optionName })),
|
|
573
|
-
pollType: message.pollV4.pollType
|
|
574
|
-
};
|
|
575
|
-
m.pollCreationMessageV4 = pollCreationMessage;
|
|
576
|
-
}
|
|
577
|
-
else if ('pollV5' in message) {
|
|
578
|
-
const pollCreationMessage = {
|
|
579
|
-
name: message.pollV5.name,
|
|
580
|
-
selectableOptionsCount: message.pollV5.selectableCount,
|
|
581
|
-
options: message.pollV5.values.map(optionName => ({ optionName })),
|
|
582
|
-
pollType: message.pollV5.pollType
|
|
583
|
-
};
|
|
584
|
-
m.pollCreationMessageV5 = pollCreationMessage;
|
|
585
|
-
}
|
|
586
|
-
else if ('event' in message) {
|
|
587
|
-
m.messageContextInfo = {
|
|
588
|
-
messageSecret: message.event.messageSecret || (0, crypto_1.randomBytes)(32),
|
|
589
|
-
};
|
|
590
|
-
m.eventMessage = { ...message.event };
|
|
591
|
-
}
|
|
592
|
-
else if ('comment' in message) {
|
|
593
|
-
m.commentMessage = {
|
|
594
|
-
message: message.comment.message,
|
|
595
|
-
targetMessageKey: message.comment.targetMessageKey
|
|
596
|
-
};
|
|
597
|
-
}
|
|
598
|
-
else if ('question' in message) {
|
|
599
|
-
m.questionMessage = {
|
|
600
|
-
text: message.question.text,
|
|
601
|
-
contextInfo: message.question.contextInfo
|
|
602
|
-
};
|
|
603
|
-
}
|
|
604
|
-
else if ('questionResponse' in message) {
|
|
605
|
-
m.questionResponseMessage = {
|
|
606
|
-
key: message.questionResponse.key,
|
|
607
|
-
text: message.questionResponse.text
|
|
608
|
-
};
|
|
609
|
-
}
|
|
610
|
-
else if ('statusQuestionAnswer' in message) {
|
|
611
|
-
m.statusQuestionAnswerMessage = {
|
|
612
|
-
key: message.statusQuestionAnswer.key,
|
|
613
|
-
text: message.statusQuestionAnswer.text
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
else if ('statusQuoted' in message) {
|
|
617
|
-
m.statusQuotedMessage = {
|
|
618
|
-
type: message.statusQuoted.type,
|
|
619
|
-
text: message.statusQuoted.text,
|
|
620
|
-
thumbnail: message.statusQuoted.thumbnail,
|
|
621
|
-
originalStatusId: message.statusQuoted.originalStatusId
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
else if ('statusStickerInteraction' in message) {
|
|
625
|
-
m.statusStickerInteractionMessage = {
|
|
626
|
-
key: message.statusStickerInteraction.key,
|
|
627
|
-
stickerKey: message.statusStickerInteraction.stickerKey,
|
|
628
|
-
type: message.statusStickerInteraction.type
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
else if ('richResponse' in message) {
|
|
632
|
-
m.richResponseMessage = WAProto_1.proto.AIRichResponseMessage.fromObject({
|
|
633
|
-
messageType: message.richResponse.messageType !== undefined ? message.richResponse.messageType : 1, // AI_RICH_RESPONSE_TYPE_STANDARD
|
|
634
|
-
submessages: message.richResponse.submessages || [],
|
|
635
|
-
unifiedResponse: message.richResponse.unifiedResponse,
|
|
636
|
-
contextInfo: message.richResponse.contextInfo
|
|
637
|
-
});
|
|
638
|
-
}
|
|
639
|
-
else if ('eventResponse' in message && !!message.eventResponse) {
|
|
640
|
-
m.eventResponseMessage = {
|
|
641
|
-
response: message.eventResponse.response, // GOING = 1, NOT_GOING = 2, MAYBE = 3
|
|
642
|
-
timestampMs: message.eventResponse.timestampMs || Date.now(),
|
|
643
|
-
extraGuestCount: message.eventResponse.extraGuestCount
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
else if ('statusMention' in message && !!message.statusMention) {
|
|
647
|
-
m.statusMentionMessage = {
|
|
648
|
-
quotedStatus: message.statusMention.quotedStatus
|
|
649
|
-
};
|
|
650
|
-
}
|
|
651
|
-
else if ('groupStatus' in message && !!message.groupStatus) {
|
|
652
|
-
m.groupStatusMessage = message.groupStatus.message;
|
|
653
|
-
}
|
|
654
|
-
else if ('botTask' in message && !!message.botTask) {
|
|
655
|
-
m.botTaskMessage = message.botTask.message;
|
|
656
|
-
}
|
|
657
|
-
else if ('limitSharing' in message && !!message.limitSharing) {
|
|
658
|
-
m.limitSharingMessage = message.limitSharing.message;
|
|
659
|
-
}
|
|
660
|
-
else if ('statusAddYours' in message && !!message.statusAddYours) {
|
|
661
|
-
m.statusAddYours = message.statusAddYours.message;
|
|
662
|
-
}
|
|
663
|
-
else if ('botForwarded' in message && !!message.botForwarded) {
|
|
664
|
-
m.botForwardedMessage = message.botForwarded.message;
|
|
665
|
-
}
|
|
666
|
-
else if ('eventCoverImage' in message && !!message.eventCoverImage) {
|
|
667
|
-
m.eventCoverImage = message.eventCoverImage.message;
|
|
668
|
-
}
|
|
669
|
-
else if ('stickerPack' in message && !!message.stickerPack) {
|
|
670
|
-
const pack = message.stickerPack;
|
|
671
|
-
const stickerPackMessage = {
|
|
672
|
-
name: pack.name,
|
|
673
|
-
publisher: pack.publisher,
|
|
674
|
-
packDescription: pack.description,
|
|
675
|
-
stickerPackId: pack.stickerPackId || (0, crypto_1.randomBytes)(16).toString('hex'),
|
|
676
|
-
stickerPackOrigin: pack.origin || 2 // USER_CREATED = 2
|
|
677
|
-
};
|
|
678
|
-
// Process cover if provided
|
|
679
|
-
if (pack.cover) {
|
|
680
|
-
const coverMedia = await (0, exports.prepareWAMessageMedia)({ image: pack.cover }, options);
|
|
681
|
-
stickerPackMessage.thumbnailDirectPath = coverMedia.imageMessage.directPath;
|
|
682
|
-
stickerPackMessage.thumbnailSha256 = coverMedia.imageMessage.thumbnailSha256;
|
|
683
|
-
stickerPackMessage.thumbnailEncSha256 = coverMedia.imageMessage.thumbnailEncSha256;
|
|
684
|
-
stickerPackMessage.thumbnailHeight = coverMedia.imageMessage.height;
|
|
685
|
-
stickerPackMessage.thumbnailWidth = coverMedia.imageMessage.width;
|
|
686
|
-
}
|
|
687
|
-
// Process stickers
|
|
688
|
-
if (pack.stickers && pack.stickers.length > 0) {
|
|
689
|
-
const processedStickers = await Promise.all(pack.stickers.map(async (sticker) => {
|
|
690
|
-
const stickerMedia = await (0, exports.prepareWAMessageMedia)({ sticker: sticker.sticker }, options);
|
|
691
|
-
return {
|
|
692
|
-
fileName: sticker.fileName || `sticker_${Date.now()}.webp`,
|
|
693
|
-
isAnimated: sticker.isAnimated || false,
|
|
694
|
-
emojis: sticker.emojis || [],
|
|
695
|
-
accessibilityLabel: sticker.accessibilityLabel,
|
|
696
|
-
isLottie: sticker.isLottie || false,
|
|
697
|
-
mimetype: sticker.mimetype || stickerMedia.stickerMessage.mimetype
|
|
698
|
-
};
|
|
699
|
-
}));
|
|
700
|
-
stickerPackMessage.stickers = processedStickers;
|
|
701
|
-
stickerPackMessage.stickerPackSize = processedStickers.length;
|
|
702
|
-
}
|
|
703
|
-
if (pack.caption) {
|
|
704
|
-
stickerPackMessage.caption = pack.caption;
|
|
289
|
+
m[key].contextInfo = m[key].contextInfo || {};
|
|
705
290
|
}
|
|
706
|
-
m.stickerPackMessage = stickerPackMessage;
|
|
707
|
-
}
|
|
708
|
-
else if ('interactiveResponse' in message && !!message.interactiveResponse) {
|
|
709
|
-
const response = message.interactiveResponse;
|
|
710
|
-
const interactiveResponseMessage = {
|
|
711
|
-
body: {
|
|
712
|
-
text: response.body?.text || '',
|
|
713
|
-
format: response.body?.format || 0 // DEFAULT = 0
|
|
714
|
-
}
|
|
715
|
-
};
|
|
716
|
-
if (response.nativeFlowResponse) {
|
|
717
|
-
interactiveResponseMessage.nativeFlowResponseMessage = {
|
|
718
|
-
name: response.nativeFlowResponse.name,
|
|
719
|
-
paramsJson: response.nativeFlowResponse.paramsJson,
|
|
720
|
-
version: response.nativeFlowResponse.version || 1
|
|
721
|
-
};
|
|
722
|
-
}
|
|
723
|
-
if (response.contextInfo) {
|
|
724
|
-
interactiveResponseMessage.contextInfo = response.contextInfo;
|
|
725
|
-
}
|
|
726
|
-
m.interactiveResponseMessage = interactiveResponseMessage;
|
|
727
|
-
}
|
|
728
|
-
else if ('bCall' in message && !!message.bCall) {
|
|
729
|
-
m.bcallMessage = {
|
|
730
|
-
sessionId: message.bCall.sessionId,
|
|
731
|
-
mediaType: message.bCall.mediaType || 0, // UNKNOWN = 0, AUDIO = 1, VIDEO = 2
|
|
732
|
-
masterKey: message.bCall.masterKey,
|
|
733
|
-
caption: message.bCall.caption
|
|
734
|
-
};
|
|
735
|
-
}
|
|
736
|
-
else if ('callLog' in message && !!message.callLog) {
|
|
737
|
-
m.callLogMesssage = {
|
|
738
|
-
isVideo: message.callLog.isVideo || false,
|
|
739
|
-
callOutcome: message.callLog.callOutcome || 0, // CONNECTED = 0
|
|
740
|
-
durationSecs: message.callLog.durationSecs,
|
|
741
|
-
callType: message.callLog.callType || 0, // REGULAR = 0
|
|
742
|
-
participants: message.callLog.participants || []
|
|
743
|
-
};
|
|
744
|
-
}
|
|
745
|
-
else if ('encComment' in message && !!message.encComment) {
|
|
746
|
-
m.encCommentMessage = {
|
|
747
|
-
targetMessageKey: message.encComment.targetMessageKey,
|
|
748
|
-
encPayload: message.encComment.encPayload,
|
|
749
|
-
encIv: message.encComment.encIv
|
|
750
|
-
};
|
|
751
|
-
}
|
|
752
|
-
else if ('encEventResponse' in message && !!message.encEventResponse) {
|
|
753
|
-
m.encEventResponseMessage = {
|
|
754
|
-
eventCreationMessageKey: message.encEventResponse.eventCreationMessageKey,
|
|
755
|
-
encPayload: message.encEventResponse.encPayload,
|
|
756
|
-
encIv: message.encEventResponse.encIv
|
|
757
|
-
};
|
|
758
|
-
}
|
|
759
|
-
else if ('messageHistoryBundle' in message && !!message.messageHistoryBundle) {
|
|
760
|
-
const bundle = message.messageHistoryBundle;
|
|
761
|
-
const bundleMedia = bundle.media ? await (0, exports.prepareWAMessageMedia)({ document: bundle.media }, options) : null;
|
|
762
|
-
m.messageHistoryBundle = {
|
|
763
|
-
mimetype: bundle.mimetype || 'application/octet-stream',
|
|
764
|
-
fileSha256: bundleMedia?.documentMessage?.fileSha256,
|
|
765
|
-
mediaKey: bundleMedia?.documentMessage?.mediaKey,
|
|
766
|
-
fileEncSha256: bundleMedia?.documentMessage?.fileEncSha256,
|
|
767
|
-
directPath: bundleMedia?.documentMessage?.directPath,
|
|
768
|
-
mediaKeyTimestamp: bundleMedia?.documentMessage?.mediaKeyTimestamp,
|
|
769
|
-
contextInfo: bundle.contextInfo,
|
|
770
|
-
messageHistoryMetadata: bundle.messageHistoryMetadata
|
|
771
|
-
};
|
|
772
|
-
}
|
|
773
|
-
else if ('messageHistoryNotice' in message && !!message.messageHistoryNotice) {
|
|
774
|
-
m.messageHistoryNotice = {
|
|
775
|
-
contextInfo: message.messageHistoryNotice.contextInfo,
|
|
776
|
-
messageHistoryMetadata: message.messageHistoryNotice.messageHistoryMetadata
|
|
777
|
-
};
|
|
778
|
-
}
|
|
779
|
-
else if ('inviteFollower' in message && !!message.inviteFollower) {
|
|
780
|
-
m.newsletterFollowerInviteMessageV2 = {
|
|
781
|
-
newsletterJid: message.inviteFollower.newsletterJid,
|
|
782
|
-
newsletterName: message.inviteFollower.newsletterName,
|
|
783
|
-
jpegThumbnail: message.inviteFollower.thumbnail,
|
|
784
|
-
caption: message.inviteFollower.caption,
|
|
785
|
-
contextInfo: message.inviteFollower.contextInfo
|
|
786
|
-
};
|
|
787
|
-
}
|
|
788
|
-
else if ('placeholder' in message && !!message.placeholder) {
|
|
789
|
-
m.placeholderMessage = {
|
|
790
|
-
type: message.placeholder.type || 0 // MASK_LINKED_DEVICES = 0
|
|
791
|
-
};
|
|
792
291
|
}
|
|
793
|
-
else if ('
|
|
794
|
-
m
|
|
795
|
-
targetMessageKey: message.secretEncrypted.targetMessageKey,
|
|
796
|
-
encPayload: message.secretEncrypted.encPayload,
|
|
797
|
-
encIv: message.secretEncrypted.encIv,
|
|
798
|
-
secretEncType: message.secretEncrypted.secretEncType || 0 // UNKNOWN = 0, EVENT_EDIT = 1, MESSAGE_EDIT = 2
|
|
799
|
-
};
|
|
800
|
-
}
|
|
801
|
-
else if ('statusNotification' in message && !!message.statusNotification) {
|
|
802
|
-
m.statusNotificationMessage = {
|
|
803
|
-
responseMessageKey: message.statusNotification.responseMessageKey,
|
|
804
|
-
originalMessageKey: message.statusNotification.originalMessageKey,
|
|
805
|
-
type: message.statusNotification.type || 0 // UNKNOWN = 0, STATUS_ADD_YOURS = 1, STATUS_RESHARE = 2, STATUS_QUESTION_ANSWER_RESHARE = 3
|
|
806
|
-
};
|
|
292
|
+
else if ('listMessage' in message) {
|
|
293
|
+
m = { listMessage: Types_1.WAProto.Message.ListMessage.fromObject(message.listMessage) };
|
|
807
294
|
}
|
|
808
|
-
else if ('
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
rmrSource: message.stickerSyncRMR.rmrSource,
|
|
812
|
-
requestTimestamp: message.stickerSyncRMR.requestTimestamp || Date.now()
|
|
813
|
-
};
|
|
814
|
-
}
|
|
815
|
-
else if ('inviteAdmin' in message) {
|
|
816
|
-
m.newsletterAdminInviteMessage = {};
|
|
817
|
-
m.newsletterAdminInviteMessage.inviteExpiration = message.inviteAdmin.inviteExpiration;
|
|
818
|
-
m.newsletterAdminInviteMessage.caption = message.inviteAdmin.text;
|
|
819
|
-
m.newsletterAdminInviteMessage.newsletterJid = message.inviteAdmin.jid;
|
|
820
|
-
m.newsletterAdminInviteMessage.newsletterName = message.inviteAdmin.subject;
|
|
821
|
-
m.newsletterAdminInviteMessage.jpegThumbnail = message.inviteAdmin.thumbnail;
|
|
822
|
-
}
|
|
823
|
-
else if ('requestPayment' in message) {
|
|
824
|
-
const reqPayment = message.requestPayment;
|
|
825
|
-
const sticker = reqPayment.sticker ?
|
|
826
|
-
await (0, exports.prepareWAMessageMedia)({ sticker: reqPayment.sticker }, options)
|
|
827
|
-
: null;
|
|
828
|
-
let notes = {};
|
|
829
|
-
if (reqPayment.sticker) {
|
|
830
|
-
notes = {
|
|
831
|
-
stickerMessage: {
|
|
832
|
-
...sticker.stickerMessage,
|
|
833
|
-
contextInfo: reqPayment.contextInfo
|
|
834
|
-
}
|
|
835
|
-
};
|
|
836
|
-
}
|
|
837
|
-
else if (reqPayment.note) {
|
|
838
|
-
notes = {
|
|
839
|
-
extendedTextMessage: {
|
|
840
|
-
text: reqPayment.note,
|
|
841
|
-
contextInfo: reqPayment.contextInfo,
|
|
842
|
-
}
|
|
843
|
-
};
|
|
844
|
-
}
|
|
845
|
-
else {
|
|
846
|
-
throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
|
|
847
|
-
}
|
|
848
|
-
m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
|
|
849
|
-
expiryTimestamp: reqPayment.expiryTimestamp || reqPayment.expiry,
|
|
850
|
-
amount1000: reqPayment.amount1000 || reqPayment.amount,
|
|
851
|
-
currencyCodeIso4217: reqPayment.currencyCodeIso4217 || reqPayment.currency,
|
|
852
|
-
requestFrom: reqPayment.requestFrom || reqPayment.from,
|
|
853
|
-
noteMessage: { ...notes },
|
|
854
|
-
background: reqPayment.background,
|
|
855
|
-
// Aggiungi altri parametri se disponibili
|
|
856
|
-
...reqPayment
|
|
857
|
-
});
|
|
858
|
-
|
|
859
|
-
// Pix adaptation for Brazilian payments
|
|
860
|
-
if (reqPayment.currencyCodeIso4217 === 'BRL' && reqPayment.pixKey) {
|
|
861
|
-
// Embed Pix key in note for dynamic requests
|
|
862
|
-
if (!m.requestPaymentMessage.noteMessage.extendedTextMessage) {
|
|
863
|
-
m.requestPaymentMessage.noteMessage = { extendedTextMessage: { text: '' } };
|
|
864
|
-
}
|
|
865
|
-
m.requestPaymentMessage.noteMessage.extendedTextMessage.text += `\nPix Key: ${reqPayment.pixKey}`;
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
else if ('sharePhoneNumber' in message) {
|
|
295
|
+
else if ('disappearingMessagesInChat' in message) {
|
|
296
|
+
const exp = typeof message.disappearingMessagesInChat === 'boolean' && message.disappearingMessagesInChat ?
|
|
297
|
+
Defaults_1.WA_DEFAULT_EPHEMERAL : 0;
|
|
869
298
|
m.protocolMessage = {
|
|
870
|
-
|
|
299
|
+
ephemeralExpiration: exp,
|
|
300
|
+
type: Types_1.WAProto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
|
|
301
|
+
ephemeralSettingTimestamp: (0, generics_1.unixTimestampSeconds)()
|
|
871
302
|
};
|
|
872
303
|
}
|
|
873
|
-
else if ('
|
|
874
|
-
m.
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
m.newsletterMessage = Types_1.WAProto.Message.NewsletterMessage.fromObject(message.newsletterMessage);
|
|
878
|
-
}
|
|
879
|
-
else if ('externalAdReply' in message) {
|
|
880
|
-
// Handle sendNyanCat functionality - external ad reply
|
|
881
|
-
const extAdReply = message.externalAdReply;
|
|
882
|
-
m.extendedTextMessage = {
|
|
883
|
-
text: message.text || '',
|
|
884
|
-
contextInfo: {
|
|
885
|
-
externalAdReply: {
|
|
886
|
-
title: extAdReply.title,
|
|
887
|
-
body: extAdReply.body,
|
|
888
|
-
mediaType: extAdReply.mediaType || 1,
|
|
889
|
-
thumbnailUrl: extAdReply.thumbnailUrl,
|
|
890
|
-
thumbnail: extAdReply.thumbnail,
|
|
891
|
-
sourceUrl: extAdReply.sourceUrl,
|
|
892
|
-
showAdAttribution: extAdReply.showAdAttribution || false,
|
|
893
|
-
renderLargerThumbnail: extAdReply.renderLargerThumbnail !== false
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
};
|
|
897
|
-
}
|
|
898
|
-
else if ('sendPayment' in message && !!message.sendPayment) {
|
|
899
|
-
const payment = message.sendPayment;
|
|
900
|
-
m.sendPaymentMessage = {
|
|
901
|
-
requestMessageKey: payment.requestMessageKey,
|
|
902
|
-
noteMessage: payment.noteMessage,
|
|
903
|
-
background: payment.background,
|
|
904
|
-
transactionData: payment.transactionData
|
|
905
|
-
};
|
|
906
|
-
}
|
|
907
|
-
else if ('declinePayment' in message && !!message.declinePayment) {
|
|
908
|
-
m.declinePaymentRequestMessage = {
|
|
909
|
-
key: message.declinePayment.key
|
|
910
|
-
};
|
|
911
|
-
}
|
|
912
|
-
else if ('cancelPayment' in message && !!message.cancelPayment) {
|
|
913
|
-
m.cancelPaymentRequestMessage = {
|
|
914
|
-
key: message.cancelPayment.key
|
|
915
|
-
};
|
|
916
|
-
}
|
|
917
|
-
else if ('scheduledCallEdit' in message && !!message.scheduledCallEdit) {
|
|
918
|
-
m.scheduledCallEditMessage = {
|
|
919
|
-
key: message.scheduledCallEdit.key,
|
|
920
|
-
editType: message.scheduledCallEdit.editType || 0 // UNKNOWN = 0, CANCEL = 1
|
|
921
|
-
};
|
|
922
|
-
}
|
|
923
|
-
else if ('pollResultSnapshot' in message && !!message.pollResultSnapshot) {
|
|
924
|
-
m.pollResultSnapshotMessage = {
|
|
925
|
-
name: message.pollResultSnapshot.name,
|
|
926
|
-
pollVotes: message.pollResultSnapshot.pollVotes || [],
|
|
927
|
-
contextInfo: message.pollResultSnapshot.contextInfo,
|
|
928
|
-
pollType: message.pollResultSnapshot.pollType || 0 // POLL = 0, QUIZ = 1
|
|
929
|
-
};
|
|
930
|
-
}
|
|
931
|
-
else if ('pollUpdate' in message && !!message.pollUpdate) {
|
|
932
|
-
m.pollUpdateMessage = {
|
|
933
|
-
pollCreationMessageKey: message.pollUpdate.pollCreationMessageKey,
|
|
934
|
-
vote: message.pollUpdate.vote,
|
|
935
|
-
metadata: message.pollUpdate.metadata,
|
|
936
|
-
senderTimestampMs: message.pollUpdate.senderTimestampMs || Date.now()
|
|
937
|
-
};
|
|
938
|
-
}
|
|
939
|
-
else if ('deviceSent' in message && !!message.deviceSent) {
|
|
940
|
-
const deviceSent = message.deviceSent;
|
|
941
|
-
const innerMessage = await (0, exports.generateWAMessageContent)(deviceSent.message, options);
|
|
942
|
-
m.deviceSentMessage = {
|
|
943
|
-
destinationJid: deviceSent.destinationJid,
|
|
944
|
-
message: innerMessage,
|
|
945
|
-
phash: deviceSent.phash
|
|
946
|
-
};
|
|
947
|
-
}
|
|
948
|
-
else if ('chat' in message && !!message.chat) {
|
|
949
|
-
m.chat = {
|
|
950
|
-
displayName: message.chat.displayName,
|
|
951
|
-
id: message.chat.id
|
|
952
|
-
};
|
|
953
|
-
}
|
|
954
|
-
else if ('payment' in message) {
|
|
955
|
-
// Handle sendPayment functionality
|
|
956
|
-
m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
|
|
957
|
-
currencyCodeIso4217: message.payment.currency || 'EUR',
|
|
958
|
-
amount1000: message.payment.amount1000 || message.payment.amount * 1000,
|
|
959
|
-
requestFrom: message.payment.requestFrom || message.payment.from,
|
|
960
|
-
noteMessage: {
|
|
961
|
-
extendedTextMessage: {
|
|
962
|
-
text: message.payment.text || message.payment.note || '',
|
|
963
|
-
contextInfo: message.payment.contextInfo
|
|
964
|
-
}
|
|
965
|
-
},
|
|
966
|
-
expiryTimestamp: message.payment.expiryTimestamp || message.payment.expiry,
|
|
967
|
-
background: message.payment.background
|
|
968
|
-
});
|
|
969
|
-
}
|
|
970
|
-
else if ('comment' in message) {
|
|
971
|
-
m.commentMessage = {
|
|
972
|
-
message: message.comment.message,
|
|
973
|
-
targetMessageKey: message.comment.targetMessageKey
|
|
974
|
-
};
|
|
975
|
-
}
|
|
976
|
-
else if ('question' in message) {
|
|
977
|
-
m.questionMessage = {
|
|
978
|
-
text: message.question.text,
|
|
979
|
-
contextInfo: message.question.contextInfo
|
|
980
|
-
};
|
|
981
|
-
}
|
|
982
|
-
else if ('questionResponse' in message) {
|
|
983
|
-
m.questionResponseMessage = {
|
|
984
|
-
key: message.questionResponse.key,
|
|
985
|
-
text: message.questionResponse.text
|
|
986
|
-
};
|
|
987
|
-
}
|
|
988
|
-
else if ('statusQuestionAnswer' in message) {
|
|
989
|
-
m.statusQuestionAnswerMessage = {
|
|
990
|
-
key: message.statusQuestionAnswer.key,
|
|
991
|
-
text: message.statusQuestionAnswer.text
|
|
304
|
+
else if ('buttonReply' in message) {
|
|
305
|
+
m.templateButtonReplyMessage = {
|
|
306
|
+
selectedId: message.buttonReply.id,
|
|
307
|
+
selectedDisplayText: message.buttonReply.displayText
|
|
992
308
|
};
|
|
993
309
|
}
|
|
994
|
-
else if ('
|
|
995
|
-
m.
|
|
996
|
-
type: message.statusQuoted.type,
|
|
997
|
-
text: message.statusQuoted.text,
|
|
998
|
-
thumbnail: message.statusQuoted.thumbnail,
|
|
999
|
-
jid: message.statusQuoted.jid,
|
|
1000
|
-
originalStatusId: message.statusQuoted.originalStatusId
|
|
1001
|
-
};
|
|
310
|
+
else if ('listReply' in message) {
|
|
311
|
+
m.listResponseMessage = Types_1.WAProto.Message.ListResponseMessage.fromObject(message.listReply);
|
|
1002
312
|
}
|
|
1003
|
-
else if ('
|
|
1004
|
-
m.
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
};
|
|
313
|
+
else if ('poll' in message) {
|
|
314
|
+
m.pollCreationMessage = Types_1.WAProto.Message.PollCreationMessage.fromObject(message.poll);
|
|
315
|
+
if (!m.pollCreationMessage.selectableOptionsCount) {
|
|
316
|
+
m.pollCreationMessage.selectableOptionsCount = 0;
|
|
317
|
+
}
|
|
1009
318
|
}
|
|
1010
|
-
else if ('
|
|
1011
|
-
|
|
1012
|
-
const videoMessages = message.album.filter(item => 'video' in item);
|
|
1013
|
-
m.albumMessage = WAProto_1.proto.Message.AlbumMessage.fromObject({
|
|
1014
|
-
expectedImageCount: imageMessages.length,
|
|
1015
|
-
expectedVideoCount: videoMessages.length,
|
|
1016
|
-
});
|
|
319
|
+
else if ('pollUpdate' in message) {
|
|
320
|
+
m.pollUpdateMessage = Types_1.WAProto.Message.PollUpdateMessage.fromObject(message.pollUpdate);
|
|
1017
321
|
}
|
|
1018
322
|
else {
|
|
1019
323
|
m = await (0, exports.prepareWAMessageMedia)(message, options);
|
|
1020
324
|
}
|
|
1021
|
-
|
|
1022
|
-
const buttonsMessage = {
|
|
1023
|
-
buttons: message.buttons.map(b => ({ ...b, type: WAProto_1.proto.Message.ButtonsMessage.Button.Type.RESPONSE }))
|
|
1024
|
-
};
|
|
1025
|
-
if ('text' in message) {
|
|
1026
|
-
buttonsMessage.contentText = message.text;
|
|
1027
|
-
buttonsMessage.headerType = ButtonType.EMPTY;
|
|
1028
|
-
}
|
|
1029
|
-
else {
|
|
1030
|
-
if ('caption' in message) {
|
|
1031
|
-
buttonsMessage.contentText = message.caption;
|
|
1032
|
-
}
|
|
1033
|
-
const type = Object.keys(m)[0].replace('Message', '').toUpperCase();
|
|
1034
|
-
buttonsMessage.headerType = ButtonType[type];
|
|
1035
|
-
Object.assign(buttonsMessage, m);
|
|
1036
|
-
}
|
|
1037
|
-
if ('title' in message && !!message.title) {
|
|
1038
|
-
buttonsMessage.text = message.title,
|
|
1039
|
-
buttonsMessage.headerType = ButtonType.TEXT;
|
|
1040
|
-
}
|
|
1041
|
-
if ('footer' in message && !!message.footer) {
|
|
1042
|
-
buttonsMessage.footerText = message.footer;
|
|
1043
|
-
}
|
|
1044
|
-
if ('contextInfo' in message && !!message.contextInfo) {
|
|
1045
|
-
buttonsMessage.contextInfo = message.contextInfo;
|
|
1046
|
-
}
|
|
1047
|
-
if ('mentions' in message && !!message.mentions) {
|
|
1048
|
-
buttonsMessage.contextInfo = { mentionedJid: message.mentions };
|
|
1049
|
-
}
|
|
1050
|
-
m = { buttonsMessage };
|
|
1051
|
-
}
|
|
1052
|
-
else if ('templateButtons' in message && !!message.templateButtons) {
|
|
1053
|
-
const templateMsg = {
|
|
1054
|
-
hydratedButtons: message.templateButtons
|
|
1055
|
-
};
|
|
1056
|
-
if ('text' in message) {
|
|
1057
|
-
templateMsg.hydratedContentText = message.text;
|
|
1058
|
-
}
|
|
1059
|
-
else if ('caption' in message) {
|
|
1060
|
-
templateMsg.hydratedContentText = message.caption;
|
|
1061
|
-
}
|
|
1062
|
-
if ('footer' in message && !!message.footer) {
|
|
1063
|
-
templateMsg.hydratedFooterText = message.footer;
|
|
1064
|
-
}
|
|
1065
|
-
// Add media to template if present
|
|
1066
|
-
if (m && Object.keys(m).length > 0) {
|
|
1067
|
-
Object.assign(templateMsg, m);
|
|
1068
|
-
}
|
|
1069
|
-
m = {
|
|
1070
|
-
templateMessage: {
|
|
1071
|
-
fourRowTemplate: templateMsg,
|
|
1072
|
-
hydratedTemplate: templateMsg
|
|
1073
|
-
}
|
|
1074
|
-
};
|
|
1075
|
-
}
|
|
1076
|
-
if ('sections' in message && !!message.sections) {
|
|
1077
|
-
const listMessage = {
|
|
1078
|
-
sections: message.sections,
|
|
1079
|
-
buttonText: message.buttonText,
|
|
1080
|
-
title: message.title,
|
|
1081
|
-
footerText: message.footer,
|
|
1082
|
-
description: message.text,
|
|
1083
|
-
listType: WAProto_1.proto.Message.ListMessage.ListType.SINGLE_SELECT
|
|
1084
|
-
};
|
|
1085
|
-
m = { listMessage };
|
|
1086
|
-
}
|
|
1087
|
-
if ('interactiveButtons' in message && !!message.interactiveButtons) {
|
|
1088
|
-
const interactiveMessage = {
|
|
1089
|
-
nativeFlowMessage: Types_1.WAProto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
|
|
1090
|
-
buttons: message.interactiveButtons,
|
|
1091
|
-
messageVersion: 1,
|
|
1092
|
-
})
|
|
1093
|
-
};
|
|
1094
|
-
if ('text' in message) {
|
|
1095
|
-
interactiveMessage.body = {
|
|
1096
|
-
text: message.text
|
|
1097
|
-
};
|
|
1098
|
-
}
|
|
1099
|
-
else if ('caption' in message) {
|
|
1100
|
-
interactiveMessage.body = {
|
|
1101
|
-
text: message.caption
|
|
1102
|
-
};
|
|
1103
|
-
interactiveMessage.header = {
|
|
1104
|
-
title: message.title,
|
|
1105
|
-
subtitle: message.subtitle,
|
|
1106
|
-
hasMediaAttachment: !!(message === null || message === void 0 ? void 0 : message.media),
|
|
1107
|
-
};
|
|
1108
|
-
Object.assign(interactiveMessage.header, m);
|
|
1109
|
-
}
|
|
1110
|
-
if ('footer' in message && !!message.footer) {
|
|
1111
|
-
if (typeof message.footer === 'string') {
|
|
1112
|
-
interactiveMessage.footer = {
|
|
1113
|
-
text: message.footer
|
|
1114
|
-
};
|
|
1115
|
-
} else if (typeof message.footer === 'object' && message.footer.text) {
|
|
1116
|
-
interactiveMessage.footer = {
|
|
1117
|
-
text: message.footer.text,
|
|
1118
|
-
hasMediaAttachment: !!message.footer.audio
|
|
1119
|
-
};
|
|
1120
|
-
if (message.footer.audio) {
|
|
1121
|
-
const audioMedia = await (0, exports.prepareWAMessageMedia)({ audio: message.footer.audio }, options);
|
|
1122
|
-
interactiveMessage.footer.audioMessage = audioMedia.audioMessage;
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
if ('title' in message && !!message.title) {
|
|
1127
|
-
const headerData = {
|
|
1128
|
-
title: message.title,
|
|
1129
|
-
subtitle: message.subtitle,
|
|
1130
|
-
hasMediaAttachment: !!message.media,
|
|
1131
|
-
};
|
|
1132
|
-
|
|
1133
|
-
// Process media attachments for interactive buttons
|
|
1134
|
-
if (message.media) {
|
|
1135
|
-
if (message.media.image) {
|
|
1136
|
-
const mediaMessage = await (0, exports.prepareWAMessageMedia)({ image: message.media.image }, options);
|
|
1137
|
-
if (mediaMessage.imageMessage) {
|
|
1138
|
-
headerData.imageMessage = mediaMessage.imageMessage;
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
else if (message.media.video) {
|
|
1142
|
-
const mediaMessage = await (0, exports.prepareWAMessageMedia)({ video: message.media.video }, options);
|
|
1143
|
-
if (mediaMessage.videoMessage) {
|
|
1144
|
-
headerData.videoMessage = mediaMessage.videoMessage;
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
else if (message.media.document) {
|
|
1148
|
-
const mediaMessage = await (0, exports.prepareWAMessageMedia)({ document: message.media.document }, options);
|
|
1149
|
-
if (mediaMessage.documentMessage) {
|
|
1150
|
-
headerData.documentMessage = mediaMessage.documentMessage;
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
interactiveMessage.header = headerData;
|
|
1156
|
-
// Support for ProductMessage in header
|
|
1157
|
-
if (message.headerProduct) {
|
|
1158
|
-
const productMedia = await (0, exports.prepareWAMessageMedia)({ image: message.headerProduct.productImage }, options);
|
|
1159
|
-
interactiveMessage.header.productMessage = {
|
|
1160
|
-
product: {
|
|
1161
|
-
...message.headerProduct,
|
|
1162
|
-
productImage: productMedia.imageMessage
|
|
1163
|
-
}
|
|
1164
|
-
};
|
|
1165
|
-
interactiveMessage.header.hasMediaAttachment = true;
|
|
1166
|
-
} else {
|
|
1167
|
-
Object.assign(interactiveMessage.header, m);
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
if ('contextInfo' in message && !!message.contextInfo) {
|
|
1171
|
-
interactiveMessage.contextInfo = message.contextInfo;
|
|
1172
|
-
}
|
|
1173
|
-
if ('mentions' in message && !!message.mentions) {
|
|
1174
|
-
interactiveMessage.contextInfo = { mentionedJid: message.mentions };
|
|
1175
|
-
}
|
|
1176
|
-
m = { interactiveMessage };
|
|
1177
|
-
}
|
|
1178
|
-
if ('shop' in message && !!message.shop) {
|
|
1179
|
-
const interactiveMessage = {
|
|
1180
|
-
shopStorefrontMessage: Types_1.WAProto.Message.InteractiveMessage.ShopMessage.fromObject({
|
|
1181
|
-
surface: message.shop,
|
|
1182
|
-
id: message.id
|
|
1183
|
-
})
|
|
1184
|
-
};
|
|
1185
|
-
if ('text' in message) {
|
|
1186
|
-
interactiveMessage.body = {
|
|
1187
|
-
text: message.text
|
|
1188
|
-
};
|
|
1189
|
-
}
|
|
1190
|
-
else if ('caption' in message) {
|
|
1191
|
-
interactiveMessage.body = {
|
|
1192
|
-
text: message.caption
|
|
1193
|
-
};
|
|
1194
|
-
interactiveMessage.header = {
|
|
1195
|
-
title: message.title,
|
|
1196
|
-
subtitle: message.subtitle,
|
|
1197
|
-
hasMediaAttachment: !!(message === null || message === void 0 ? void 0 : message.media),
|
|
1198
|
-
};
|
|
1199
|
-
Object.assign(interactiveMessage.header, m);
|
|
1200
|
-
}
|
|
1201
|
-
if ('footer' in message && !!message.footer) {
|
|
1202
|
-
interactiveMessage.footer = {
|
|
1203
|
-
text: message.footer
|
|
1204
|
-
};
|
|
1205
|
-
}
|
|
1206
|
-
if ('title' in message && !!message.title) {
|
|
1207
|
-
interactiveMessage.header = {
|
|
1208
|
-
title: message.title,
|
|
1209
|
-
subtitle: message.subtitle,
|
|
1210
|
-
hasMediaAttachment: !!(message === null || message === void 0 ? void 0 : message.media),
|
|
1211
|
-
};
|
|
1212
|
-
Object.assign(interactiveMessage.header, m);
|
|
1213
|
-
}
|
|
1214
|
-
if ('contextInfo' in message && !!message.contextInfo) {
|
|
1215
|
-
interactiveMessage.contextInfo = message.contextInfo;
|
|
1216
|
-
}
|
|
1217
|
-
if ('mentions' in message && !!message.mentions) {
|
|
1218
|
-
interactiveMessage.contextInfo = { mentionedJid: message.mentions };
|
|
1219
|
-
}
|
|
1220
|
-
m = { interactiveMessage };
|
|
1221
|
-
}
|
|
1222
|
-
else if ('collection' in message && !!message.collection) {
|
|
1223
|
-
const interactiveMessage = {
|
|
1224
|
-
collectionMessage: Types_1.WAProto.Message.InteractiveMessage.CollectionMessage.fromObject({
|
|
1225
|
-
bizJid: message.collection.bizJid,
|
|
1226
|
-
id: message.collection.id,
|
|
1227
|
-
messageVersion: message.collection.messageVersion || 1
|
|
1228
|
-
})
|
|
1229
|
-
};
|
|
1230
|
-
if ('text' in message) {
|
|
1231
|
-
interactiveMessage.body = {
|
|
1232
|
-
text: message.text
|
|
1233
|
-
};
|
|
1234
|
-
}
|
|
1235
|
-
if ('footer' in message && !!message.footer) {
|
|
1236
|
-
interactiveMessage.footer = {
|
|
1237
|
-
text: message.footer
|
|
1238
|
-
};
|
|
1239
|
-
}
|
|
1240
|
-
if ('title' in message && !!message.title) {
|
|
1241
|
-
interactiveMessage.header = {
|
|
1242
|
-
title: message.title,
|
|
1243
|
-
subtitle: message.subtitle,
|
|
1244
|
-
hasMediaAttachment: false
|
|
1245
|
-
};
|
|
1246
|
-
}
|
|
1247
|
-
if ('contextInfo' in message && !!message.contextInfo) {
|
|
1248
|
-
interactiveMessage.contextInfo = message.contextInfo;
|
|
1249
|
-
}
|
|
1250
|
-
m = { interactiveMessage };
|
|
1251
|
-
}
|
|
1252
|
-
else if ('invoice' in message && !!message.invoice) {
|
|
1253
|
-
const invoiceData = message.invoice;
|
|
1254
|
-
const invoiceMessage = {
|
|
1255
|
-
note: invoiceData.note,
|
|
1256
|
-
token: invoiceData.token,
|
|
1257
|
-
attachmentType: invoiceData.attachmentType || 0 // IMAGE = 0, PDF = 1
|
|
1258
|
-
};
|
|
1259
|
-
if (invoiceData.attachment) {
|
|
1260
|
-
const attachmentMedia = await (0, exports.prepareWAMessageMedia)({
|
|
1261
|
-
[invoiceData.attachmentType === 1 ? 'document' : 'image']: invoiceData.attachment
|
|
1262
|
-
}, options);
|
|
1263
|
-
if (invoiceData.attachmentType === 1) {
|
|
1264
|
-
invoiceMessage.attachmentMimetype = attachmentMedia.documentMessage.mimetype;
|
|
1265
|
-
invoiceMessage.attachmentMediaKey = attachmentMedia.documentMessage.mediaKey;
|
|
1266
|
-
invoiceMessage.attachmentMediaKeyTimestamp = attachmentMedia.documentMessage.mediaKeyTimestamp;
|
|
1267
|
-
invoiceMessage.attachmentFileSha256 = attachmentMedia.documentMessage.fileSha256;
|
|
1268
|
-
invoiceMessage.attachmentFileEncSha256 = attachmentMedia.documentMessage.fileEncSha256;
|
|
1269
|
-
invoiceMessage.attachmentDirectPath = attachmentMedia.documentMessage.directPath;
|
|
1270
|
-
} else {
|
|
1271
|
-
invoiceMessage.attachmentMimetype = attachmentMedia.imageMessage.mimetype;
|
|
1272
|
-
invoiceMessage.attachmentMediaKey = attachmentMedia.imageMessage.mediaKey;
|
|
1273
|
-
invoiceMessage.attachmentMediaKeyTimestamp = attachmentMedia.imageMessage.mediaKeyTimestamp;
|
|
1274
|
-
invoiceMessage.attachmentFileSha256 = attachmentMedia.imageMessage.fileSha256;
|
|
1275
|
-
invoiceMessage.attachmentFileEncSha256 = attachmentMedia.imageMessage.fileEncSha256;
|
|
1276
|
-
invoiceMessage.attachmentDirectPath = attachmentMedia.imageMessage.directPath;
|
|
1277
|
-
invoiceMessage.attachmentJpegThumbnail = attachmentMedia.imageMessage.jpegThumbnail;
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
|
-
m = { invoiceMessage };
|
|
1281
|
-
}
|
|
325
|
+
|
|
1282
326
|
if ('cards' in message && !!message.cards && message.cards.length > 0) {
|
|
1283
|
-
const carouselCardType = message.carouselCardType || 1;
|
|
327
|
+
const carouselCardType = message.carouselCardType || 1;
|
|
1284
328
|
const carouselCards = await Promise.all(message.cards.map(async (card) => {
|
|
1285
329
|
const cardMessage = {
|
|
1286
330
|
header: {
|
|
@@ -1289,26 +333,23 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
1289
333
|
}
|
|
1290
334
|
};
|
|
1291
335
|
|
|
1292
|
-
// Add body as separate field if present
|
|
1293
336
|
if (card.body) {
|
|
1294
|
-
cardMessage.body = {
|
|
1295
|
-
text: card.body
|
|
1296
|
-
};
|
|
337
|
+
cardMessage.body = { text: card.body };
|
|
1297
338
|
}
|
|
1298
|
-
|
|
339
|
+
|
|
1299
340
|
if (card.image) {
|
|
1300
|
-
const mediaMessage = await prepareWAMessageMedia({ image: card.image }, options);
|
|
341
|
+
const mediaMessage = await (0, exports.prepareWAMessageMedia)({ image: card.image }, options);
|
|
1301
342
|
if (mediaMessage.imageMessage) {
|
|
1302
343
|
cardMessage.header.imageMessage = mediaMessage.imageMessage;
|
|
1303
344
|
}
|
|
1304
345
|
}
|
|
1305
346
|
else if (card.video) {
|
|
1306
|
-
const mediaMessage = await prepareWAMessageMedia({ video: card.video }, options);
|
|
347
|
+
const mediaMessage = await (0, exports.prepareWAMessageMedia)({ video: card.video }, options);
|
|
1307
348
|
if (mediaMessage.videoMessage) {
|
|
1308
349
|
cardMessage.header.videoMessage = mediaMessage.videoMessage;
|
|
1309
350
|
}
|
|
1310
351
|
}
|
|
1311
|
-
|
|
352
|
+
|
|
1312
353
|
if (card.buttons && card.buttons.length > 0) {
|
|
1313
354
|
cardMessage.nativeFlowMessage = {
|
|
1314
355
|
buttons: card.buttons.map(button => ({
|
|
@@ -1318,14 +359,14 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
1318
359
|
messageVersion: 1,
|
|
1319
360
|
};
|
|
1320
361
|
}
|
|
1321
|
-
|
|
362
|
+
|
|
1322
363
|
if (card.footer) {
|
|
1323
|
-
cardMessage.footer = {
|
|
1324
|
-
text: card.footer
|
|
1325
|
-
};
|
|
364
|
+
cardMessage.footer = { text: card.footer };
|
|
1326
365
|
}
|
|
366
|
+
|
|
1327
367
|
return cardMessage;
|
|
1328
368
|
}));
|
|
369
|
+
|
|
1329
370
|
const interactiveMessage = {
|
|
1330
371
|
carouselMessage: Types_1.WAProto.Message.InteractiveMessage.CarouselMessage.fromObject({
|
|
1331
372
|
cards: carouselCards,
|
|
@@ -1333,15 +374,12 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
1333
374
|
carouselCardType: carouselCardType
|
|
1334
375
|
})
|
|
1335
376
|
};
|
|
377
|
+
|
|
1336
378
|
if ('text' in message) {
|
|
1337
|
-
interactiveMessage.body = {
|
|
1338
|
-
text: message.text
|
|
1339
|
-
};
|
|
379
|
+
interactiveMessage.body = { text: message.text };
|
|
1340
380
|
}
|
|
1341
381
|
if ('footer' in message && !!message.footer) {
|
|
1342
|
-
interactiveMessage.footer = {
|
|
1343
|
-
text: message.footer
|
|
1344
|
-
};
|
|
382
|
+
interactiveMessage.footer = { text: message.footer };
|
|
1345
383
|
}
|
|
1346
384
|
if ('title' in message && !!message.title) {
|
|
1347
385
|
interactiveMessage.header = {
|
|
@@ -1356,20 +394,25 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
1356
394
|
if ('mentions' in message && !!message.mentions) {
|
|
1357
395
|
interactiveMessage.contextInfo = { mentionedJid: message.mentions };
|
|
1358
396
|
}
|
|
397
|
+
|
|
1359
398
|
m = { interactiveMessage };
|
|
1360
399
|
}
|
|
1361
|
-
|
|
1362
|
-
// This improves client compatibility (avoids "update WhatsApp" / invisible messages on some clients).
|
|
400
|
+
|
|
1363
401
|
const shouldWrapInteractive = !!(m === null || m === void 0 ? void 0 : m.interactiveMessage);
|
|
1364
|
-
const hasViewOnceAlready = !!(m === null || m === void 0 ? void 0 : m.viewOnceMessage) ||
|
|
402
|
+
const hasViewOnceAlready = !!(m === null || m === void 0 ? void 0 : m.viewOnceMessage) ||
|
|
403
|
+
!!(m === null || m === void 0 ? void 0 : m.viewOnceMessageV2) ||
|
|
404
|
+
!!(m === null || m === void 0 ? void 0 : m.viewOnceMessageV2Extension);
|
|
405
|
+
|
|
1365
406
|
if ((('viewOnce' in message && !!message.viewOnce) || shouldWrapInteractive) && !hasViewOnceAlready) {
|
|
1366
407
|
m = { viewOnceMessageV2: { message: m } };
|
|
1367
408
|
}
|
|
1368
|
-
|
|
409
|
+
|
|
410
|
+
if ('mentions' in message && (message.mentions?.length)) {
|
|
1369
411
|
const [messageType] = Object.keys(m);
|
|
1370
|
-
m[messageType].contextInfo = m[messageType] || {};
|
|
412
|
+
m[messageType].contextInfo = m[messageType].contextInfo || {};
|
|
1371
413
|
m[messageType].contextInfo.mentionedJid = message.mentions;
|
|
1372
414
|
}
|
|
415
|
+
|
|
1373
416
|
if ('edit' in message) {
|
|
1374
417
|
m = {
|
|
1375
418
|
protocolMessage: {
|
|
@@ -1380,6 +423,7 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
1380
423
|
}
|
|
1381
424
|
};
|
|
1382
425
|
}
|
|
426
|
+
|
|
1383
427
|
if ('contextInfo' in message && !!message.contextInfo) {
|
|
1384
428
|
const [messageType] = Object.keys(m);
|
|
1385
429
|
m[messageType] = m[messageType] || {};
|
|
@@ -1388,406 +432,94 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
1388
432
|
...message.contextInfo
|
|
1389
433
|
};
|
|
1390
434
|
}
|
|
435
|
+
|
|
1391
436
|
return Types_1.WAProto.Message.fromObject(m);
|
|
1392
437
|
};
|
|
1393
438
|
exports.generateWAMessageContent = generateWAMessageContent;
|
|
439
|
+
|
|
1394
440
|
const generateWAMessageFromContent = (jid, message, options) => {
|
|
1395
|
-
// set timestamp to now
|
|
1396
|
-
// if not specified
|
|
1397
441
|
if (!options.timestamp) {
|
|
1398
442
|
options.timestamp = new Date();
|
|
1399
443
|
}
|
|
444
|
+
|
|
1400
445
|
const innerMessage = (0, exports.normalizeMessageContent)(message);
|
|
1401
446
|
const key = (0, exports.getContentType)(innerMessage);
|
|
1402
447
|
const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp);
|
|
1403
448
|
const { quoted, userJid } = options;
|
|
1404
|
-
|
|
449
|
+
|
|
1405
450
|
if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
|
|
1406
451
|
const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid);
|
|
1407
452
|
let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message);
|
|
1408
453
|
const msgType = (0, exports.getContentType)(quotedMsg);
|
|
1409
|
-
|
|
454
|
+
|
|
1410
455
|
if (quotedMsg) {
|
|
1411
456
|
quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
|
|
1412
457
|
const quotedContent = quotedMsg[msgType];
|
|
1413
458
|
if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
|
|
1414
459
|
delete quotedContent.contextInfo;
|
|
1415
460
|
}
|
|
461
|
+
|
|
1416
462
|
const contextInfo = innerMessage[key].contextInfo || {};
|
|
1417
463
|
contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
|
|
1418
464
|
contextInfo.stanzaId = quoted.key.id;
|
|
1419
465
|
contextInfo.quotedMessage = quotedMsg;
|
|
1420
|
-
|
|
1421
|
-
// hence, remoteJid of group must also be entered
|
|
466
|
+
|
|
1422
467
|
if (jid !== quoted.key.remoteJid) {
|
|
1423
468
|
contextInfo.remoteJid = quoted.key.remoteJid;
|
|
1424
469
|
}
|
|
470
|
+
|
|
1425
471
|
innerMessage[key].contextInfo = contextInfo;
|
|
1426
472
|
}
|
|
1427
473
|
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
!!(options === null || options === void 0 ? void 0 : options.ephemeralExpiration) &&
|
|
1431
|
-
// and it's not a protocol message -- delete, toggle disappear message
|
|
474
|
+
|
|
475
|
+
if (!!(options === null || options === void 0 ? void 0 : options.ephemeralExpiration) &&
|
|
1432
476
|
key !== 'protocolMessage' &&
|
|
1433
|
-
// already not converted to disappearing message
|
|
1434
477
|
key !== 'ephemeralMessage' &&
|
|
1435
|
-
// newsletter not accept disappearing messages
|
|
1436
478
|
!(0, WABinary_1.isJidNewsletter)(jid)) {
|
|
1437
479
|
innerMessage[key].contextInfo = {
|
|
1438
480
|
...(innerMessage[key].contextInfo || {}),
|
|
1439
481
|
expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL,
|
|
1440
|
-
//ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString()
|
|
1441
482
|
};
|
|
1442
483
|
}
|
|
1443
|
-
|
|
1444
|
-
const
|
|
484
|
+
|
|
485
|
+
const msg = {
|
|
1445
486
|
key: {
|
|
1446
487
|
remoteJid: jid,
|
|
1447
488
|
fromMe: true,
|
|
1448
|
-
id:
|
|
489
|
+
id: options.messageId || (0, generics_1.generateMessageID)(),
|
|
1449
490
|
},
|
|
1450
|
-
message:
|
|
491
|
+
message: innerMessage,
|
|
1451
492
|
messageTimestamp: timestamp,
|
|
1452
493
|
messageStubParameters: [],
|
|
1453
|
-
participant: (0, WABinary_1.isJidGroup)(jid)
|
|
494
|
+
participant: (0, WABinary_1.isJidGroup)(jid) ? userJid : undefined,
|
|
1454
495
|
status: Types_1.WAMessageStatus.PENDING
|
|
1455
496
|
};
|
|
1456
|
-
|
|
497
|
+
|
|
498
|
+
return WAProto_1.proto.WebMessageInfo.fromObject(msg);
|
|
1457
499
|
};
|
|
1458
500
|
exports.generateWAMessageFromContent = generateWAMessageFromContent;
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
exports.generateWAMessage = generateWAMessage;
|
|
1466
|
-
/** Get the key to access the true type of content */
|
|
1467
|
-
const getContentType = (content) => {
|
|
1468
|
-
if (content) {
|
|
1469
|
-
const keys = Object.keys(content);
|
|
1470
|
-
const key = keys.find(k => (k === 'conversation' || k.includes('Message')) && k !== 'senderKeyDistributionMessage');
|
|
1471
|
-
return key;
|
|
1472
|
-
}
|
|
1473
|
-
};
|
|
1474
|
-
exports.getContentType = getContentType;
|
|
1475
|
-
/**
|
|
1476
|
-
* Normalizes ephemeral, view once messages to regular message content
|
|
1477
|
-
* Eg. image messages in ephemeral messages, in view once messages etc.
|
|
1478
|
-
* @param content
|
|
1479
|
-
* @returns
|
|
1480
|
-
*/
|
|
1481
|
-
const normalizeMessageContent = (content) => {
|
|
1482
|
-
if (!content) {
|
|
1483
|
-
return undefined;
|
|
1484
|
-
}
|
|
1485
|
-
// set max iterations to prevent an infinite loop
|
|
1486
|
-
for (let i = 0; i < 5; i++) {
|
|
1487
|
-
const inner = getFutureProofMessage(content);
|
|
1488
|
-
if (!inner) {
|
|
1489
|
-
break;
|
|
1490
|
-
}
|
|
1491
|
-
content = inner.message;
|
|
1492
|
-
}
|
|
1493
|
-
return content;
|
|
1494
|
-
function getFutureProofMessage(message) {
|
|
1495
|
-
return ((message === null || message === void 0 ? void 0 : message.ephemeralMessage)
|
|
1496
|
-
|| (message === null || message === void 0 ? void 0 : message.viewOnceMessage)
|
|
1497
|
-
|| (message === null || message === void 0 ? void 0 : message.documentWithCaptionMessage)
|
|
1498
|
-
|| (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2)
|
|
1499
|
-
|| (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension)
|
|
1500
|
-
|| (message === null || message === void 0 ? void 0 : message.editedMessage)
|
|
1501
|
-
|| (message === null || message === void 0 ? void 0 : message.groupMentionedMessage)
|
|
1502
|
-
|| (message === null || message === void 0 ? void 0 : message.botInvokeMessage)
|
|
1503
|
-
|| (message === null || message === void 0 ? void 0 : message.lottieStickerMessage)
|
|
1504
|
-
|| (message === null || message === void 0 ? void 0 : message.eventCoverImage)
|
|
1505
|
-
|| (message === null || message === void 0 ? void 0 : message.statusMentionMessage)
|
|
1506
|
-
|| (message === null || message === void 0 ? void 0 : message.pollCreationOptionImageMessage)
|
|
1507
|
-
|| (message === null || message === void 0 ? void 0 : message.associatedChildMessage)
|
|
1508
|
-
|| (message === null || message === void 0 ? void 0 : message.groupStatusMentionMessage)
|
|
1509
|
-
|| (message === null || message === void 0 ? void 0 : message.pollCreationMessageV4)
|
|
1510
|
-
|| (message === null || message === void 0 ? void 0 : message.pollCreationMessageV5)
|
|
1511
|
-
|| (message === null || message === void 0 ? void 0 : message.statusAddYours)
|
|
1512
|
-
|| (message === null || message === void 0 ? void 0 : message.groupStatusMessage)
|
|
1513
|
-
|| (message === null || message === void 0 ? void 0 : message.limitSharingMessage)
|
|
1514
|
-
|| (message === null || message === void 0 ? void 0 : message.botTaskMessage)
|
|
1515
|
-
|| (message === null || message === void 0 ? void 0 : message.questionMessage)
|
|
1516
|
-
|| (message === null || message === void 0 ? void 0 : message.groupStatusMessageV2)
|
|
1517
|
-
|| (message === null || message === void 0 ? void 0 : message.botForwardedMessage));
|
|
1518
|
-
}
|
|
1519
|
-
};
|
|
1520
|
-
exports.normalizeMessageContent = normalizeMessageContent;
|
|
1521
|
-
/**
|
|
1522
|
-
* Extract the true message content from a message
|
|
1523
|
-
* Eg. extracts the inner message from a disappearing message/view once message
|
|
1524
|
-
*/
|
|
1525
|
-
const extractMessageContent = (content) => {
|
|
1526
|
-
var _a, _b, _c, _d, _e, _f;
|
|
1527
|
-
const extractFromTemplateMessage = (msg) => {
|
|
1528
|
-
if (msg.imageMessage) {
|
|
1529
|
-
return { imageMessage: msg.imageMessage };
|
|
1530
|
-
}
|
|
1531
|
-
else if (msg.documentMessage) {
|
|
1532
|
-
return { documentMessage: msg.documentMessage };
|
|
1533
|
-
}
|
|
1534
|
-
else if (msg.videoMessage) {
|
|
1535
|
-
return { videoMessage: msg.videoMessage };
|
|
1536
|
-
}
|
|
1537
|
-
else if (msg.locationMessage) {
|
|
1538
|
-
return { locationMessage: msg.locationMessage };
|
|
1539
|
-
}
|
|
1540
|
-
else {
|
|
1541
|
-
return {
|
|
1542
|
-
conversation: 'contentText' in msg
|
|
1543
|
-
? msg.contentText
|
|
1544
|
-
: ('hydratedContentText' in msg ? msg.hydratedContentText : '')
|
|
1545
|
-
};
|
|
1546
|
-
}
|
|
1547
|
-
};
|
|
1548
|
-
content = (0, exports.normalizeMessageContent)(content);
|
|
1549
|
-
if (content === null || content === void 0 ? void 0 : content.buttonsMessage) {
|
|
1550
|
-
return extractFromTemplateMessage(content.buttonsMessage);
|
|
1551
|
-
}
|
|
1552
|
-
if ((_a = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _a === void 0 ? void 0 : _a.hydratedFourRowTemplate) {
|
|
1553
|
-
return extractFromTemplateMessage((_b = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _b === void 0 ? void 0 : _b.hydratedFourRowTemplate);
|
|
1554
|
-
}
|
|
1555
|
-
if ((_c = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _c === void 0 ? void 0 : _c.hydratedTemplate) {
|
|
1556
|
-
return extractFromTemplateMessage((_d = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _d === void 0 ? void 0 : _d.hydratedTemplate);
|
|
1557
|
-
}
|
|
1558
|
-
if ((_e = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _e === void 0 ? void 0 : _e.fourRowTemplate) {
|
|
1559
|
-
return extractFromTemplateMessage((_f = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _f === void 0 ? void 0 : _f.fourRowTemplate);
|
|
1560
|
-
}
|
|
1561
|
-
return content;
|
|
1562
|
-
};
|
|
1563
|
-
exports.extractMessageContent = extractMessageContent;
|
|
1564
|
-
/**
|
|
1565
|
-
* Returns the device predicted by message ID
|
|
1566
|
-
*/
|
|
1567
|
-
const getDevice = (id) => /^3A.{18}$/.test(id) ? 'ios' :
|
|
1568
|
-
/^3E.{20}$/.test(id) ? 'web' :
|
|
1569
|
-
/^(.{21}|.{32})$/.test(id) ? 'android' :
|
|
1570
|
-
/^(3F|.{18}$)/.test(id) ? 'desktop' :
|
|
1571
|
-
'unknown';
|
|
1572
|
-
exports.getDevice = getDevice;
|
|
1573
|
-
/** Upserts a receipt in the message */
|
|
1574
|
-
const updateMessageWithReceipt = (msg, receipt) => {
|
|
1575
|
-
msg.userReceipt = msg.userReceipt || [];
|
|
1576
|
-
const recp = msg.userReceipt.find(m => m.userJid === receipt.userJid);
|
|
1577
|
-
if (recp) {
|
|
1578
|
-
Object.assign(recp, receipt);
|
|
1579
|
-
}
|
|
1580
|
-
else {
|
|
1581
|
-
msg.userReceipt.push(receipt);
|
|
1582
|
-
}
|
|
1583
|
-
};
|
|
1584
|
-
exports.updateMessageWithReceipt = updateMessageWithReceipt;
|
|
1585
|
-
/** Update the message with a new reaction */
|
|
1586
|
-
const updateMessageWithReaction = (msg, reaction) => {
|
|
1587
|
-
const authorID = (0, generics_1.getKeyAuthor)(reaction.key);
|
|
1588
|
-
const reactions = (msg.reactions || [])
|
|
1589
|
-
.filter(r => (0, generics_1.getKeyAuthor)(r.key) !== authorID);
|
|
1590
|
-
reaction.text = reaction.text || '';
|
|
1591
|
-
reactions.push(reaction);
|
|
1592
|
-
msg.reactions = reactions;
|
|
1593
|
-
};
|
|
1594
|
-
exports.updateMessageWithReaction = updateMessageWithReaction;
|
|
1595
|
-
/** Update the message with a new poll update */
|
|
1596
|
-
const updateMessageWithPollUpdate = (msg, update) => {
|
|
1597
|
-
var _a, _b;
|
|
1598
|
-
const authorID = (0, generics_1.getKeyAuthor)(update.pollUpdateMessageKey);
|
|
1599
|
-
const reactions = (msg.pollUpdates || [])
|
|
1600
|
-
.filter(r => (0, generics_1.getKeyAuthor)(r.pollUpdateMessageKey) !== authorID);
|
|
1601
|
-
if ((_b = (_a = update.vote) === null || _a === void 0 ? void 0 : _a.selectedOptions) === null || _b === void 0 ? void 0 : _b.length) {
|
|
1602
|
-
reactions.push(update);
|
|
1603
|
-
}
|
|
1604
|
-
msg.pollUpdates = reactions;
|
|
1605
|
-
};
|
|
1606
|
-
exports.updateMessageWithPollUpdate = updateMessageWithPollUpdate;
|
|
1607
|
-
/**
|
|
1608
|
-
* Aggregates all poll updates in a poll.
|
|
1609
|
-
* @param msg the poll creation message
|
|
1610
|
-
* @param meId your jid
|
|
1611
|
-
* @returns A list of options & their voters
|
|
1612
|
-
*/
|
|
1613
|
-
function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
|
|
1614
|
-
var _a, _b, _c;
|
|
1615
|
-
const opts = ((_a = message === null || message === void 0 ? void 0 : message.pollCreationMessage) === null || _a === void 0 ? void 0 : _a.options) || ((_b = message === null || message === void 0 ? void 0 : message.pollCreationMessageV2) === null || _b === void 0 ? void 0 : _b.options) || ((_c = message === null || message === void 0 ? void 0 : message.pollCreationMessageV3) === null || _c === void 0 ? void 0 : _c.options) || [];
|
|
1616
|
-
const voteHashMap = opts.reduce((acc, opt) => {
|
|
1617
|
-
const hash = (0, crypto_2.sha256)(Buffer.from(opt.optionName || '')).toString();
|
|
1618
|
-
acc[hash] = {
|
|
1619
|
-
name: opt.optionName || '',
|
|
1620
|
-
voters: []
|
|
1621
|
-
};
|
|
1622
|
-
return acc;
|
|
1623
|
-
}, {});
|
|
1624
|
-
for (const update of pollUpdates || []) {
|
|
501
|
+
|
|
502
|
+
async function getAggregateVotesInPollMessage({ message, pollUpdates }) {
|
|
503
|
+
const votes = {};
|
|
504
|
+
const voters = {};
|
|
505
|
+
|
|
506
|
+
for (const update of pollUpdates) {
|
|
1625
507
|
const { vote } = update;
|
|
1626
|
-
if (!vote)
|
|
1627
|
-
continue;
|
|
1628
|
-
}
|
|
1629
|
-
for (const option of vote.selectedOptions || []) {
|
|
1630
|
-
const hash = option.toString();
|
|
1631
|
-
let data = voteHashMap[hash];
|
|
1632
|
-
if (!data) {
|
|
1633
|
-
voteHashMap[hash] = {
|
|
1634
|
-
name: 'Unknown',
|
|
1635
|
-
voters: []
|
|
1636
|
-
};
|
|
1637
|
-
data = voteHashMap[hash];
|
|
1638
|
-
}
|
|
1639
|
-
voteHashMap[hash].voters.push((0, generics_1.getKeyAuthor)(update.pollUpdateMessageKey, meId));
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
return Object.values(voteHashMap);
|
|
1643
|
-
}
|
|
1644
|
-
/** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
|
|
1645
|
-
const aggregateMessageKeysNotFromMe = (keys) => {
|
|
1646
|
-
const keyMap = {};
|
|
1647
|
-
for (const { remoteJid, id, participant, fromMe } of keys) {
|
|
1648
|
-
if (!fromMe) {
|
|
1649
|
-
const uqKey = `${remoteJid}:${participant || ''}`;
|
|
1650
|
-
if (!keyMap[uqKey]) {
|
|
1651
|
-
keyMap[uqKey] = {
|
|
1652
|
-
jid: remoteJid,
|
|
1653
|
-
participant: participant,
|
|
1654
|
-
messageIds: []
|
|
1655
|
-
};
|
|
1656
|
-
}
|
|
1657
|
-
keyMap[uqKey].messageIds.push(id);
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
return Object.values(keyMap);
|
|
1661
|
-
};
|
|
1662
|
-
exports.aggregateMessageKeysNotFromMe = aggregateMessageKeysNotFromMe;
|
|
1663
|
-
const REUPLOAD_REQUIRED_STATUS = [410, 404];
|
|
1664
|
-
/**
|
|
1665
|
-
* Downloads the given message. Throws an error if it's not a media message
|
|
1666
|
-
*/
|
|
1667
|
-
const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
1668
|
-
const result = await downloadMsg()
|
|
1669
|
-
.catch(async (error) => {
|
|
1670
|
-
var _a;
|
|
1671
|
-
if (ctx) {
|
|
1672
|
-
if (axios_1.default.isAxiosError(error)) {
|
|
1673
|
-
// check if the message requires a reupload
|
|
1674
|
-
if (REUPLOAD_REQUIRED_STATUS.includes((_a = error.response) === null || _a === void 0 ? void 0 : _a.status)) {
|
|
1675
|
-
ctx.logger.info({ key: message.key }, 'sending reupload media request...');
|
|
1676
|
-
// request reupload
|
|
1677
|
-
message = await ctx.reuploadRequest(message);
|
|
1678
|
-
const result = await downloadMsg();
|
|
1679
|
-
return result;
|
|
1680
|
-
}
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
throw error;
|
|
1684
|
-
});
|
|
1685
|
-
return result;
|
|
1686
|
-
async function downloadMsg() {
|
|
1687
|
-
const mContent = (0, exports.extractMessageContent)(message.message);
|
|
1688
|
-
if (!mContent) {
|
|
1689
|
-
throw new boom_1.Boom('No message present', { statusCode: 400, data: message });
|
|
1690
|
-
}
|
|
1691
|
-
const contentType = (0, exports.getContentType)(mContent);
|
|
1692
|
-
let mediaType = contentType === null || contentType === void 0 ? void 0 : contentType.replace('Message', '');
|
|
1693
|
-
const media = mContent[contentType];
|
|
1694
|
-
if (!media || typeof media !== 'object' || (!('url' in media) && !('thumbnailDirectPath' in media))) {
|
|
1695
|
-
throw new boom_1.Boom(`"${contentType}" message is not a media message`);
|
|
1696
|
-
}
|
|
1697
|
-
let download;
|
|
1698
|
-
if ('thumbnailDirectPath' in media && !('url' in media)) {
|
|
1699
|
-
download = {
|
|
1700
|
-
directPath: media.thumbnailDirectPath,
|
|
1701
|
-
mediaKey: media.mediaKey
|
|
1702
|
-
};
|
|
1703
|
-
mediaType = 'thumbnail-link';
|
|
1704
|
-
}
|
|
1705
|
-
else {
|
|
1706
|
-
download = media;
|
|
1707
|
-
}
|
|
1708
|
-
const stream = await (0, messages_media_1.downloadContentFromMessage)(download, mediaType, options);
|
|
1709
|
-
if (type === 'buffer') {
|
|
1710
|
-
const bufferArray = [];
|
|
1711
|
-
for await (const chunk of stream) {
|
|
1712
|
-
bufferArray.push(chunk);
|
|
1713
|
-
}
|
|
1714
|
-
return Buffer.concat(bufferArray);
|
|
1715
|
-
}
|
|
1716
|
-
return stream;
|
|
1717
|
-
}
|
|
1718
|
-
};
|
|
1719
|
-
exports.downloadMediaMessage = downloadMediaMessage;
|
|
1720
|
-
/** Checks whether the given message is a media message; if it is returns the inner content */
|
|
1721
|
-
const assertMediaContent = (content) => {
|
|
1722
|
-
content = (0, exports.extractMessageContent)(content);
|
|
1723
|
-
const mediaContent = (content === null || content === void 0 ? void 0 : content.documentMessage)
|
|
1724
|
-
|| (content === null || content === void 0 ? void 0 : content.imageMessage)
|
|
1725
|
-
|| (content === null || content === void 0 ? void 0 : content.videoMessage)
|
|
1726
|
-
|| (content === null || content === void 0 ? void 0 : content.audioMessage)
|
|
1727
|
-
|| (content === null || content === void 0 ? void 0 : content.stickerMessage);
|
|
1728
|
-
if (!mediaContent) {
|
|
1729
|
-
throw new boom_1.Boom('given message is not a media message', { statusCode: 400, data: content });
|
|
1730
|
-
}
|
|
1731
|
-
return mediaContent;
|
|
1732
|
-
};
|
|
1733
|
-
exports.assertMediaContent = assertMediaContent;
|
|
1734
|
-
const cache_manager_1 = require("./cache-manager");
|
|
1735
|
-
const performance_config_1 = require("./performance-config");
|
|
1736
|
-
/**
|
|
1737
|
-
* Get cache statistics for monitoring performance
|
|
1738
|
-
*/
|
|
1739
|
-
const getCacheStats = () => {
|
|
1740
|
-
try {
|
|
1741
|
-
const cacheManager = cache_manager_1.default;
|
|
1742
|
-
const config = performance_config_1.getPerformanceConfig();
|
|
508
|
+
if (!vote) continue;
|
|
1743
509
|
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
return {
|
|
1755
|
-
lidCache: {
|
|
1756
|
-
size: lidStats?.keys || 0,
|
|
1757
|
-
maxSize: lidStats?.max || config.cache.lidCache.maxSize || 0,
|
|
1758
|
-
ttl: config.cache.lidCache.ttl
|
|
1759
|
-
},
|
|
1760
|
-
jidCache: {
|
|
1761
|
-
size: jidStats?.keys || 0,
|
|
1762
|
-
maxSize: jidStats?.max || config.cache.jidCache.maxSize || 0,
|
|
1763
|
-
ttl: config.cache.jidCache.ttl
|
|
510
|
+
const selectedOptions = vote.selectedOptions || [];
|
|
511
|
+
for (const option of selectedOptions) {
|
|
512
|
+
if (!votes[option]) {
|
|
513
|
+
votes[option] = [];
|
|
514
|
+
voters[option] = new Set();
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
if (!voters[option].has(update.voter)) {
|
|
518
|
+
votes[option].push(update.voter);
|
|
519
|
+
voters[option].add(update.voter);
|
|
1764
520
|
}
|
|
1765
|
-
};
|
|
1766
|
-
} catch (error) {
|
|
1767
|
-
const config = performance_config_1.getPerformanceConfig();
|
|
1768
|
-
return {
|
|
1769
|
-
lidCache: { size: 0, maxSize: 0, ttl: config.cache.lidCache.ttl },
|
|
1770
|
-
jidCache: { size: 0, maxSize: 0, ttl: config.cache.jidCache.ttl }
|
|
1771
|
-
};
|
|
1772
|
-
}
|
|
1773
|
-
};
|
|
1774
|
-
exports.getCacheStats = getCacheStats;
|
|
1775
|
-
/**
|
|
1776
|
-
* Clear all caches (useful for testing or memory management)
|
|
1777
|
-
*/
|
|
1778
|
-
const clearCache = () => {
|
|
1779
|
-
try {
|
|
1780
|
-
const cacheManager = cache_manager_1.default;
|
|
1781
|
-
if (cacheManager && cacheManager.caches) {
|
|
1782
|
-
Object.keys(cacheManager.caches).forEach(cacheName => {
|
|
1783
|
-
const cache = cacheManager.caches[cacheName];
|
|
1784
|
-
if (cache && typeof cache.flushAll === 'function') {
|
|
1785
|
-
cache.flushAll();
|
|
1786
|
-
}
|
|
1787
|
-
});
|
|
1788
521
|
}
|
|
1789
|
-
} catch (error) {
|
|
1790
|
-
// Silently fail if cache manager is not available
|
|
1791
522
|
}
|
|
1792
|
-
|
|
1793
|
-
|
|
523
|
+
|
|
524
|
+
return votes;
|
|
525
|
+
}
|