@rexxhayanasi/elaina-baileys 1.2.0-rc.9 → 1.2.1-rc.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/README.MD +3 -1
- package/lib/Utils/index.js +0 -1
- package/lib/Utils/messages-media.js +49 -58
- package/lib/Utils/messages.js +55 -261
- package/package.json +2 -2
- package/lib/Utils/newslettermedia.js +0 -110
package/README.MD
CHANGED
|
@@ -77,7 +77,9 @@
|
|
|
77
77
|
> ❄️ `elaina-baileys` is a refined version of the Baileys library with cleaner API usage, exclusive features like album messaging, newsletter controls, and full-size profile uploads — tailored for modern WhatsApp automation needs.
|
|
78
78
|
|
|
79
79
|
> **Christmas Update** 🎁
|
|
80
|
-
> All update information is now redirected to the WhatsApp channel check at the bottom of the "homepage"
|
|
80
|
+
> All update information is now redirected to the WhatsApp channel check at the bottom of the "homepage".
|
|
81
|
+
|
|
82
|
+
> Udpate changelog see on our WhatsApp channel
|
|
81
83
|
|
|
82
84
|
---
|
|
83
85
|
|
package/lib/Utils/index.js
CHANGED
|
@@ -34,4 +34,3 @@ __exportStar(require("./process-message"), exports);
|
|
|
34
34
|
__exportStar(require("./message-retry-manager"), exports);
|
|
35
35
|
__exportStar(require("./browser-utils"), exports);
|
|
36
36
|
__exportStar(require("./resolveJid"), exports);
|
|
37
|
-
__exportStar(require("./newslettermedia"), exports);
|
|
@@ -61,8 +61,6 @@ const Defaults_1 = require("../Defaults");
|
|
|
61
61
|
const WABinary_1 = require("../WABinary");
|
|
62
62
|
const crypto_1 = require("./crypto");
|
|
63
63
|
const generics_1 = require("./generics");
|
|
64
|
-
const toAsyncIterable_1 = require("./async-iterable");
|
|
65
|
-
|
|
66
64
|
const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
|
|
67
65
|
const getImageProcessingLibrary = async () => {
|
|
68
66
|
const [_jimp, sharp] = await Promise.all([
|
|
@@ -78,27 +76,64 @@ const getImageProcessingLibrary = async () => {
|
|
|
78
76
|
if (sharp) {
|
|
79
77
|
return { sharp };
|
|
80
78
|
}
|
|
81
|
-
|
|
79
|
+
const jimp = (_jimp === null || _jimp === void 0 ? void 0 : _jimp.default) || _jimp;
|
|
82
80
|
if (jimp) {
|
|
83
81
|
return { jimp };
|
|
84
82
|
}
|
|
85
83
|
throw new boom_1.Boom('No image processing library available');
|
|
86
84
|
};
|
|
87
|
-
|
|
88
85
|
const hkdfInfoKey = (type) => {
|
|
89
|
-
if (type === 'sticker-pack') return 'WhatsApp Image Keys';
|
|
90
|
-
if (type === 'ptv') return 'WhatsApp Video Keys';
|
|
91
|
-
if (type === 'newsletter-image') return 'WhatsApp Image Keys';
|
|
92
|
-
if (type === 'newsletter-video') return 'WhatsApp Video Keys';
|
|
93
|
-
|
|
94
86
|
const hkdfInfo = Defaults_1.MEDIA_HKDF_KEY_MAPPING[type];
|
|
95
|
-
if (!hkdfInfo) {
|
|
96
|
-
return 'WhatsApp Image Keys';
|
|
97
|
-
}
|
|
98
87
|
return `WhatsApp ${hkdfInfo} Keys`;
|
|
99
88
|
};
|
|
100
89
|
exports.hkdfInfoKey = hkdfInfoKey;
|
|
101
90
|
|
|
91
|
+
const getRawMediaUploadData = async (media, mediaType, logger) => {
|
|
92
|
+
|
|
93
|
+
const { stream } = await exports.getStream(media);
|
|
94
|
+
logger === null || logger === void 0 ? void 0 : logger.debug('got stream for raw upload');
|
|
95
|
+
const hasher = Crypto.createHash('sha256');
|
|
96
|
+
|
|
97
|
+
// Generate file temp
|
|
98
|
+
const filePath = (0, path_1.join)((0, os_1.tmpdir)(), mediaType + (0, generics_1.generateMessageIDV2)());
|
|
99
|
+
const fileWriteStream = (0, fs_1.createWriteStream)(filePath);
|
|
100
|
+
|
|
101
|
+
let fileLength = 0;
|
|
102
|
+
try {
|
|
103
|
+
for await (const data of stream) {
|
|
104
|
+
fileLength += data.length;
|
|
105
|
+
hasher.update(data);
|
|
106
|
+
// Handle backpressure
|
|
107
|
+
if (!fileWriteStream.write(data)) {
|
|
108
|
+
await (0, events_1.once)(fileWriteStream, 'drain');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
fileWriteStream.end();
|
|
112
|
+
await (0, events_1.once)(fileWriteStream, 'finish');
|
|
113
|
+
stream.destroy();
|
|
114
|
+
|
|
115
|
+
const fileSha256 = hasher.digest();
|
|
116
|
+
logger === null || logger === void 0 ? void 0 : logger.debug('hashed data for raw upload');
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
filePath: filePath,
|
|
120
|
+
fileSha256,
|
|
121
|
+
fileLength
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
fileWriteStream.destroy();
|
|
126
|
+
stream.destroy();
|
|
127
|
+
try {
|
|
128
|
+
await fs_1.promises.unlink(filePath);
|
|
129
|
+
}
|
|
130
|
+
catch (_a) {
|
|
131
|
+
// ignore
|
|
132
|
+
}
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
exports.getRawMediaUploadData = getRawMediaUploadData;
|
|
102
137
|
/** generates all the keys required to encrypt/decrypt & sign a media message */
|
|
103
138
|
async function getMediaKeys(buffer, mediaType) {
|
|
104
139
|
if (!buffer) {
|
|
@@ -115,7 +150,6 @@ async function getMediaKeys(buffer, mediaType) {
|
|
|
115
150
|
macKey: expandedMediaKey.slice(48, 80),
|
|
116
151
|
};
|
|
117
152
|
}
|
|
118
|
-
|
|
119
153
|
async function uploadFile(buffer, logger) {
|
|
120
154
|
const { fromBuffer } = await Promise.resolve().then(() => __importStar(require('file-type')));
|
|
121
155
|
const fileType = await fromBuffer(buffer);
|
|
@@ -220,7 +254,6 @@ async function uploadFile(buffer, logger) {
|
|
|
220
254
|
}
|
|
221
255
|
throw new Error("All upload services failed.");
|
|
222
256
|
}
|
|
223
|
-
|
|
224
257
|
async function vid2jpg(videoUrl) {
|
|
225
258
|
try {
|
|
226
259
|
const { data } = await axios_1.default.get(`https://ezgif.com/video-to-jpg?url=${encodeURIComponent(videoUrl)}`);
|
|
@@ -257,7 +290,6 @@ async function vid2jpg(videoUrl) {
|
|
|
257
290
|
throw new Error("Failed to convert video to JPG: " + error.message);
|
|
258
291
|
}
|
|
259
292
|
}
|
|
260
|
-
|
|
261
293
|
/**
|
|
262
294
|
* Extracts video thumbnail using FFmpeg
|
|
263
295
|
*/
|
|
@@ -288,7 +320,6 @@ const extractVideoThumb = async (videoPath, time = '00:00:00', size = { width: 2
|
|
|
288
320
|
});
|
|
289
321
|
};
|
|
290
322
|
exports.extractVideoThumb = extractVideoThumb;
|
|
291
|
-
|
|
292
323
|
const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
293
324
|
var _a, _b;
|
|
294
325
|
if (bufferOrFilePath instanceof stream_1.Readable) {
|
|
@@ -331,13 +362,11 @@ const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
|
331
362
|
}
|
|
332
363
|
};
|
|
333
364
|
exports.extractImageThumb = extractImageThumb;
|
|
334
|
-
|
|
335
365
|
const encodeBase64EncodedStringForUpload = (b64) => (encodeURIComponent(b64
|
|
336
366
|
.replace(/\+/g, '-')
|
|
337
367
|
.replace(/\//g, '_')
|
|
338
368
|
.replace(/\=+$/, '')));
|
|
339
369
|
exports.encodeBase64EncodedStringForUpload = encodeBase64EncodedStringForUpload;
|
|
340
|
-
|
|
341
370
|
const generateProfilePicture = async (mediaUpload) => {
|
|
342
371
|
let bufferOrFilePath;
|
|
343
372
|
let img;
|
|
@@ -360,14 +389,12 @@ const generateProfilePicture = async (mediaUpload) => {
|
|
|
360
389
|
};
|
|
361
390
|
};
|
|
362
391
|
exports.generateProfilePicture = generateProfilePicture;
|
|
363
|
-
|
|
364
392
|
/** gets the SHA256 of the given media message */
|
|
365
393
|
const mediaMessageSHA256B64 = (message) => {
|
|
366
394
|
const media = Object.values(message)[0];
|
|
367
395
|
return (media === null || media === void 0 ? void 0 : media.fileSha256) && Buffer.from(media.fileSha256).toString('base64');
|
|
368
396
|
};
|
|
369
397
|
exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
|
|
370
|
-
|
|
371
398
|
async function getAudioDuration(buffer) {
|
|
372
399
|
const musicMetadata = await Promise.resolve().then(() => __importStar(require('music-metadata')));
|
|
373
400
|
let metadata;
|
|
@@ -385,7 +412,6 @@ async function getAudioDuration(buffer) {
|
|
|
385
412
|
}
|
|
386
413
|
return metadata.format.duration;
|
|
387
414
|
}
|
|
388
|
-
|
|
389
415
|
async function getAudioWaveform(buffer, logger) {
|
|
390
416
|
try {
|
|
391
417
|
const { default: decoder } = await eval('import(\'audio-decode\')');
|
|
@@ -422,7 +448,6 @@ async function getAudioWaveform(buffer, logger) {
|
|
|
422
448
|
logger === null || logger === void 0 ? void 0 : logger.debug('Failed to generate waveform: ' + e);
|
|
423
449
|
}
|
|
424
450
|
}
|
|
425
|
-
|
|
426
451
|
const toReadable = (buffer) => {
|
|
427
452
|
const readable = new stream_1.Readable({ read: () => { } });
|
|
428
453
|
readable.push(buffer);
|
|
@@ -430,7 +455,6 @@ const toReadable = (buffer) => {
|
|
|
430
455
|
return readable;
|
|
431
456
|
};
|
|
432
457
|
exports.toReadable = toReadable;
|
|
433
|
-
|
|
434
458
|
const toBuffer = async (stream) => {
|
|
435
459
|
const chunks = [];
|
|
436
460
|
for await (const chunk of stream) {
|
|
@@ -440,7 +464,6 @@ const toBuffer = async (stream) => {
|
|
|
440
464
|
return Buffer.concat(chunks);
|
|
441
465
|
};
|
|
442
466
|
exports.toBuffer = toBuffer;
|
|
443
|
-
|
|
444
467
|
const getStream = async (item, opts) => {
|
|
445
468
|
if (Buffer.isBuffer(item)) {
|
|
446
469
|
return { stream: (0, exports.toReadable)(item), type: 'buffer' };
|
|
@@ -454,7 +477,6 @@ const getStream = async (item, opts) => {
|
|
|
454
477
|
return { stream: (0, fs_1.createReadStream)(item.url), type: 'file' };
|
|
455
478
|
};
|
|
456
479
|
exports.getStream = getStream;
|
|
457
|
-
|
|
458
480
|
/** generates a thumbnail for a given media, if required */
|
|
459
481
|
async function generateThumbnail(file, mediaType, options) {
|
|
460
482
|
var _a;
|
|
@@ -503,13 +525,11 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
503
525
|
originalImageDimensions
|
|
504
526
|
};
|
|
505
527
|
}
|
|
506
|
-
|
|
507
528
|
const getHttpStream = async (url, options = {}) => {
|
|
508
529
|
const fetched = await axios_1.default.get(url.toString(), { ...options, responseType: 'stream' });
|
|
509
530
|
return fetched.data;
|
|
510
531
|
};
|
|
511
532
|
exports.getHttpStream = getHttpStream;
|
|
512
|
-
|
|
513
533
|
const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
|
|
514
534
|
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
515
535
|
logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
|
|
@@ -553,7 +573,6 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
|
|
|
553
573
|
}
|
|
554
574
|
};
|
|
555
575
|
exports.prepareStream = prepareStream;
|
|
556
|
-
|
|
557
576
|
const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
|
|
558
577
|
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
559
578
|
logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
|
|
@@ -640,7 +659,6 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
640
659
|
}
|
|
641
660
|
};
|
|
642
661
|
exports.encryptedStream = encryptedStream;
|
|
643
|
-
|
|
644
662
|
const DEF_HOST = 'mmg.whatsapp.net';
|
|
645
663
|
const AES_CHUNK_SIZE = 16;
|
|
646
664
|
const toSmallestChunkSize = (num) => {
|
|
@@ -648,7 +666,6 @@ const toSmallestChunkSize = (num) => {
|
|
|
648
666
|
};
|
|
649
667
|
const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
|
|
650
668
|
exports.getUrlFromDirectPath = getUrlFromDirectPath;
|
|
651
|
-
|
|
652
669
|
const downloadContentFromMessage = async ({ mediaKey, directPath, url }, type, opts = {}) => {
|
|
653
670
|
const isValidMediaUrl = url === null || url === void 0 ? void 0 : url.startsWith('https://mmg.whatsapp.net/');
|
|
654
671
|
const downloadUrl = isValidMediaUrl ? url : (0, exports.getUrlFromDirectPath)(directPath);
|
|
@@ -659,7 +676,6 @@ const downloadContentFromMessage = async ({ mediaKey, directPath, url }, type, o
|
|
|
659
676
|
return (0, exports.downloadEncryptedContent)(downloadUrl, keys, opts);
|
|
660
677
|
};
|
|
661
678
|
exports.downloadContentFromMessage = downloadContentFromMessage;
|
|
662
|
-
|
|
663
679
|
const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startByte, endByte, options } = {}) => {
|
|
664
680
|
let bytesFetched = 0;
|
|
665
681
|
let startChunk = 0;
|
|
@@ -740,7 +756,6 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
740
756
|
return fetched.pipe(output, { end: true });
|
|
741
757
|
};
|
|
742
758
|
exports.downloadEncryptedContent = downloadEncryptedContent;
|
|
743
|
-
|
|
744
759
|
function extensionForMediaMessage(message) {
|
|
745
760
|
const getExtension = (mimetype) => mimetype.split(';')[0].split('/')[1];
|
|
746
761
|
const type = Object.keys(message)[0];
|
|
@@ -756,7 +771,6 @@ function extensionForMediaMessage(message) {
|
|
|
756
771
|
}
|
|
757
772
|
return extension;
|
|
758
773
|
}
|
|
759
|
-
|
|
760
774
|
const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
761
775
|
return async (stream, { mediaType, fileEncSha256B64, newsletter, timeoutMs }) => {
|
|
762
776
|
var _a, _b;
|
|
@@ -764,14 +778,6 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
764
778
|
let urls;
|
|
765
779
|
const hosts = [...customUploadHosts, ...uploadInfo.hosts];
|
|
766
780
|
const chunks = [];
|
|
767
|
-
|
|
768
|
-
try {
|
|
769
|
-
stream = toAsyncIterable_1.toAsyncIterable(stream);
|
|
770
|
-
} catch (error) {
|
|
771
|
-
throw new boom_1.Boom(error.message, { statusCode: 400 });
|
|
772
|
-
}
|
|
773
|
-
// --------------------------------------------------------
|
|
774
|
-
|
|
775
781
|
if (!Buffer.isBuffer(stream)) {
|
|
776
782
|
for await (const chunk of stream) {
|
|
777
783
|
chunks.push(chunk);
|
|
@@ -779,20 +785,10 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
779
785
|
}
|
|
780
786
|
const reqBody = Buffer.isBuffer(stream) ? stream : Buffer.concat(chunks);
|
|
781
787
|
fileEncSha256B64 = (0, exports.encodeBase64EncodedStringForUpload)(fileEncSha256B64);
|
|
782
|
-
|
|
783
788
|
let media = Defaults_1.MEDIA_PATH_MAP[mediaType];
|
|
784
|
-
if (mediaType === 'sticker-pack') {
|
|
785
|
-
media = '/mms/image';
|
|
786
|
-
}
|
|
787
|
-
|
|
788
789
|
if (newsletter) {
|
|
789
|
-
|
|
790
|
-
media = media.replace('/mms/', '/newsletter/newsletter-');
|
|
791
|
-
} else {
|
|
792
|
-
media = '/newsletter/newsletter-image';
|
|
793
|
-
}
|
|
790
|
+
media = media === null || media === void 0 ? void 0 : media.replace('/mms/', '/newsletter/newsletter-');
|
|
794
791
|
}
|
|
795
|
-
|
|
796
792
|
for (const { hostname, maxContentLengthBytes } of hosts) {
|
|
797
793
|
logger.debug(`uploading to "${hostname}"`);
|
|
798
794
|
const auth = encodeURIComponent(uploadInfo.auth);
|
|
@@ -843,8 +839,7 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
843
839
|
return urls;
|
|
844
840
|
};
|
|
845
841
|
};
|
|
846
|
-
exports.getWAUploadToServer = getWAUploadToServer;
|
|
847
|
-
|
|
842
|
+
exports.getWAUploadToServer = getWAUploadToServer;
|
|
848
843
|
const getMediaRetryKey = (mediaKey) => {
|
|
849
844
|
return (0, crypto_1.hkdf)(mediaKey, 32, { info: 'WhatsApp Media Retry Notification' });
|
|
850
845
|
};
|
|
@@ -883,7 +878,6 @@ const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
|
|
|
883
878
|
return req;
|
|
884
879
|
};
|
|
885
880
|
exports.encryptMediaRetryRequest = encryptMediaRetryRequest;
|
|
886
|
-
|
|
887
881
|
const decodeMediaRetryNode = (node) => {
|
|
888
882
|
const rmrNode = (0, WABinary_1.getBinaryNodeChild)(node, 'rmr');
|
|
889
883
|
const event = {
|
|
@@ -913,17 +907,14 @@ const decodeMediaRetryNode = (node) => {
|
|
|
913
907
|
return event;
|
|
914
908
|
};
|
|
915
909
|
exports.decodeMediaRetryNode = decodeMediaRetryNode;
|
|
916
|
-
|
|
917
910
|
const decryptMediaRetryData = async ({ ciphertext, iv }, mediaKey, msgId) => {
|
|
918
911
|
const retryKey = await getMediaRetryKey(mediaKey);
|
|
919
912
|
const plaintext = (0, crypto_1.aesDecryptGCM)(ciphertext, retryKey, iv, Buffer.from(msgId));
|
|
920
913
|
return WAProto_1.proto.MediaRetryNotification.decode(plaintext);
|
|
921
914
|
};
|
|
922
915
|
exports.decryptMediaRetryData = decryptMediaRetryData;
|
|
923
|
-
|
|
924
916
|
const getStatusCodeForMediaRetry = (code) => MEDIA_RETRY_STATUS_MAP[code];
|
|
925
917
|
exports.getStatusCodeForMediaRetry = getStatusCodeForMediaRetry;
|
|
926
|
-
|
|
927
918
|
const MEDIA_RETRY_STATUS_MAP = {
|
|
928
919
|
[WAProto_1.proto.MediaRetryNotification.ResultType.SUCCESS]: 200,
|
|
929
920
|
[WAProto_1.proto.MediaRetryNotification.ResultType.DECRYPTION_ERROR]: 412,
|
package/lib/Utils/messages.js
CHANGED
|
@@ -2,29 +2,11 @@
|
|
|
2
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true })
|
|
6
|
-
|
|
7
|
-
const lib = {};
|
|
8
|
-
try {
|
|
9
|
-
lib.sharp = require('sharp');
|
|
10
|
-
} catch {}
|
|
11
|
-
try {
|
|
12
|
-
lib.jimp = require('jimp');
|
|
13
|
-
} catch {}
|
|
14
|
-
return lib;
|
|
15
|
-
};
|
|
16
|
-
const isWebPBuffer = (buffer) => {
|
|
17
|
-
return buffer.length >= 12 && buffer.toString('ascii', 8, 12) === 'WEBP';
|
|
18
|
-
};
|
|
19
|
-
const isAnimatedWebP = (buffer) => {
|
|
20
|
-
if (!isWebPBuffer(buffer)) return false;
|
|
21
|
-
return buffer.includes(Buffer.from("ANIM"));
|
|
22
|
-
};
|
|
23
|
-
exports.prepareStickerPackMessage = exports.assertMediaContent = exports.downloadMediaMessage = exports.aggregateMessageKeysNotFromMe = exports.updateMessageWithPollUpdate = exports.updateMessageWithReaction = exports.updateMessageWithReceipt = exports.getDevice = exports.extractMessageContent = exports.normalizeMessageContent = exports.getContentType = exports.generateWAMessage = exports.generateWAMessageFromContent = exports.generateWAMessageContent = exports.generateForwardMessageContent = exports.prepareDisappearingMessageSettingContent = exports.prepareWAMessageMedia = exports.generateLinkPreviewIfRequired = exports.extractUrlFromText = void 0;
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.assertMediaContent = exports.downloadMediaMessage = exports.aggregateMessageKeysNotFromMe = exports.updateMessageWithPollUpdate = exports.updateMessageWithReaction = exports.updateMessageWithReceipt = exports.getDevice = exports.extractMessageContent = exports.normalizeMessageContent = exports.getContentType = exports.generateWAMessage = exports.generateWAMessageFromContent = exports.generateWAMessageContent = exports.generateForwardMessageContent = exports.prepareDisappearingMessageSettingContent = exports.prepareWAMessageMedia = exports.generateLinkPreviewIfRequired = exports.extractUrlFromText = void 0;
|
|
24
7
|
exports.getAggregateVotesInPollMessage = getAggregateVotesInPollMessage;
|
|
25
8
|
const boom_1 = require("@hapi/boom");
|
|
26
9
|
const axios_1 = __importDefault(require("axios"));
|
|
27
|
-
const fflate_1 = require("fflate");
|
|
28
10
|
const crypto_1 = require("crypto");
|
|
29
11
|
const fs_1 = require("fs");
|
|
30
12
|
const WAProto_1 = require("../../WAProto");
|
|
@@ -41,10 +23,6 @@ const MIMETYPE_MAP = {
|
|
|
41
23
|
audio: 'audio/ogg; codecs=opus',
|
|
42
24
|
sticker: 'image/webp',
|
|
43
25
|
'product-catalog-image': 'image/jpeg',
|
|
44
|
-
'sticker-pack': 'application/x-zip-compressed',
|
|
45
|
-
"ptv": "video/mp4",
|
|
46
|
-
"newsletter-image": "image/jpeg",
|
|
47
|
-
"newsletter-video": "video/mp4"
|
|
48
26
|
};
|
|
49
27
|
const MessageTypeProto = {
|
|
50
28
|
'image': Types_1.WAProto.Message.ImageMessage,
|
|
@@ -88,53 +66,36 @@ const assertColor = async (color) => {
|
|
|
88
66
|
return assertedColor;
|
|
89
67
|
}
|
|
90
68
|
};
|
|
91
|
-
|
|
69
|
+
const prepareWAMessageMedia = async (message, options) => {
|
|
92
70
|
const logger = options.logger;
|
|
93
71
|
let mediaType;
|
|
94
|
-
|
|
95
72
|
for (const key of Defaults_1.MEDIA_KEYS) {
|
|
96
73
|
if (key in message) {
|
|
97
74
|
mediaType = key;
|
|
98
75
|
}
|
|
99
76
|
}
|
|
100
|
-
|
|
101
|
-
if (!mediaType && 'ptv' in message) {
|
|
102
|
-
mediaType = 'ptv';
|
|
103
|
-
}
|
|
104
|
-
|
|
105
77
|
if (!mediaType) {
|
|
106
78
|
throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
|
|
107
79
|
}
|
|
108
|
-
|
|
109
|
-
let isPtv = false;
|
|
110
|
-
if (mediaType === 'ptv') {
|
|
111
|
-
isPtv = true;
|
|
112
|
-
mediaType = 'video';
|
|
113
|
-
}
|
|
114
|
-
|
|
115
80
|
const uploadData = {
|
|
116
81
|
...message,
|
|
117
|
-
media: message[mediaType]
|
|
82
|
+
media: message[mediaType]
|
|
118
83
|
};
|
|
119
|
-
|
|
120
|
-
if (!(mediaType === 'audio' && uploadData.ptt)) {
|
|
121
84
|
delete uploadData[mediaType];
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
85
|
+
|
|
86
|
+
// Check cache
|
|
125
87
|
const cacheableKey = typeof uploadData.media === 'object' &&
|
|
126
88
|
('url' in uploadData.media) &&
|
|
127
89
|
!!uploadData.media.url &&
|
|
128
|
-
!!options.mediaCache && (
|
|
129
|
-
|
|
130
|
-
|
|
90
|
+
!!options.mediaCache && (mediaType + ':' + uploadData.media.url.toString());
|
|
91
|
+
|
|
131
92
|
if (mediaType === 'document' && !uploadData.fileName) {
|
|
132
93
|
uploadData.fileName = 'file';
|
|
133
94
|
}
|
|
134
95
|
if (!uploadData.mimetype) {
|
|
135
96
|
uploadData.mimetype = MIMETYPE_MAP[mediaType];
|
|
136
97
|
}
|
|
137
|
-
|
|
98
|
+
|
|
138
99
|
if (cacheableKey) {
|
|
139
100
|
const mediaBuff = options.mediaCache.get(cacheableKey);
|
|
140
101
|
if (mediaBuff) {
|
|
@@ -146,35 +107,35 @@ const assertColor = async (color) => {
|
|
|
146
107
|
}
|
|
147
108
|
}
|
|
148
109
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
logger === null || logger === void 0 ? void 0 : logger.debug({ key: cacheableKey }, 'Preparing raw media for newsletter');
|
|
152
|
-
|
|
110
|
+
// --- [MULAI] LOGIKA KHUSUS NEWSLETTER (WHISKEYSOCKETS ADAPTATION) ---
|
|
111
|
+
const isNewsletter = !!options.jid && (0, WABinary_1.isJidNewsletter)(options.jid);
|
|
153
112
|
|
|
154
|
-
|
|
113
|
+
if (isNewsletter) {
|
|
114
|
+
logger === null || logger === void 0 ? void 0 : logger.info({ key: cacheableKey }, 'Preparing raw media for newsletter');
|
|
115
|
+
|
|
116
|
+
// 1. Dapatkan file mentah (RAW) menggunakan fungsi yang baru kita buat di messages-media.js
|
|
117
|
+
const { filePath, fileSha256, fileLength } = await (0, messages_media_1.getRawMediaUploadData)(
|
|
155
118
|
uploadData.media,
|
|
156
119
|
options.mediaTypeOverride || mediaType,
|
|
157
|
-
|
|
120
|
+
logger
|
|
158
121
|
);
|
|
159
122
|
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
123
|
+
const fileSha256B64 = fileSha256.toString('base64');
|
|
124
|
+
|
|
125
|
+
// 2. Upload Stream Mentah
|
|
126
|
+
// Kita buat ReadStream dari filePath agar kompatibel dengan sistem upload Baileys v6
|
|
127
|
+
const streamToUpload = (0, fs_1.createReadStream)(filePath);
|
|
128
|
+
|
|
163
129
|
const { mediaUrl, directPath } = await options.upload(streamToUpload, {
|
|
164
|
-
fileEncSha256B64,
|
|
165
|
-
mediaType,
|
|
166
|
-
timeoutMs: options.mediaUploadTimeoutMs
|
|
167
|
-
newsletter: true
|
|
130
|
+
fileEncSha256B64: fileSha256B64,
|
|
131
|
+
mediaType: mediaType,
|
|
132
|
+
timeoutMs: options.mediaUploadTimeoutMs
|
|
168
133
|
});
|
|
169
134
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
await fs_1.promises.unlink(bodyPath);
|
|
173
|
-
} catch (error) {
|
|
174
|
-
logger === null || logger === void 0 ? void 0 : logger.warn('failed to remove tmp file');
|
|
175
|
-
}
|
|
176
|
-
}
|
|
135
|
+
// Hapus file temp setelah upload selesai
|
|
136
|
+
await fs_1.promises.unlink(filePath);
|
|
177
137
|
|
|
138
|
+
// 3. Buat Objek Pesan
|
|
178
139
|
const obj = Types_1.WAProto.Message.fromObject({
|
|
179
140
|
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
180
141
|
url: mediaUrl,
|
|
@@ -186,15 +147,13 @@ const assertColor = async (color) => {
|
|
|
186
147
|
})
|
|
187
148
|
});
|
|
188
149
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (isPtv) {
|
|
150
|
+
// 4. Ubah tipe pesan jadi PTV jika flag aktif
|
|
151
|
+
if (uploadData.ptv) {
|
|
194
152
|
obj.ptvMessage = obj.videoMessage;
|
|
195
153
|
delete obj.videoMessage;
|
|
196
154
|
}
|
|
197
155
|
|
|
156
|
+
// Handle sticker timestamp
|
|
198
157
|
if (obj.stickerMessage) {
|
|
199
158
|
obj.stickerMessage.stickerSentTs = Date.now();
|
|
200
159
|
}
|
|
@@ -206,30 +165,29 @@ const assertColor = async (color) => {
|
|
|
206
165
|
|
|
207
166
|
return obj;
|
|
208
167
|
}
|
|
168
|
+
// --- [SELESAI] LOGIKA NEWSLETTER ---
|
|
169
|
+
|
|
209
170
|
|
|
171
|
+
// --- LOGIKA LAMA (E2E / CHAT BIASA) ---
|
|
210
172
|
const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
|
|
211
173
|
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
|
|
212
174
|
(typeof uploadData['jpegThumbnail'] === 'undefined');
|
|
213
175
|
const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
|
|
214
176
|
const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
|
|
215
177
|
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
|
|
216
|
-
|
|
178
|
+
|
|
179
|
+
// Enkripsi standar
|
|
217
180
|
const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, } = await (0, messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
|
|
218
181
|
logger,
|
|
219
182
|
saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
|
|
220
183
|
opts: options.options
|
|
221
184
|
});
|
|
222
|
-
|
|
185
|
+
|
|
223
186
|
const fileEncSha256B64 = (fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256).toString('base64');
|
|
224
|
-
|
|
187
|
+
|
|
225
188
|
const [{ mediaUrl, directPath, handle }] = await Promise.all([
|
|
226
189
|
(async () => {
|
|
227
|
-
const result = await options.upload(encWriteStream, {
|
|
228
|
-
fileEncSha256B64,
|
|
229
|
-
mediaType,
|
|
230
|
-
timeoutMs: options.mediaUploadTimeoutMs,
|
|
231
|
-
newsletter: false
|
|
232
|
-
});
|
|
190
|
+
const result = await options.upload(encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs });
|
|
233
191
|
logger === null || logger === void 0 ? void 0 : logger.debug({ mediaType, cacheableKey }, 'uploaded media');
|
|
234
192
|
return result;
|
|
235
193
|
})(),
|
|
@@ -241,16 +199,21 @@ const assertColor = async (color) => {
|
|
|
241
199
|
if (!uploadData.width && originalImageDimensions) {
|
|
242
200
|
uploadData.width = originalImageDimensions.width;
|
|
243
201
|
uploadData.height = originalImageDimensions.height;
|
|
202
|
+
logger === null || logger === void 0 ? void 0 : logger.debug('set dimensions');
|
|
244
203
|
}
|
|
204
|
+
logger === null || logger === void 0 ? void 0 : logger.debug('generated thumbnail');
|
|
245
205
|
}
|
|
246
206
|
if (requiresDurationComputation) {
|
|
247
207
|
uploadData.seconds = await (0, messages_media_1.getAudioDuration)(bodyPath);
|
|
208
|
+
logger === null || logger === void 0 ? void 0 : logger.debug('computed audio duration');
|
|
248
209
|
}
|
|
249
210
|
if (requiresWaveformProcessing) {
|
|
250
211
|
uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(bodyPath, logger);
|
|
212
|
+
logger === null || logger === void 0 ? void 0 : logger.debug('processed waveform');
|
|
251
213
|
}
|
|
252
214
|
if (requiresAudioBackground) {
|
|
253
215
|
uploadData.backgroundArgb = await assertColor(options.backgroundColor);
|
|
216
|
+
logger === null || logger === void 0 ? void 0 : logger.debug('computed backgroundColor audio status');
|
|
254
217
|
}
|
|
255
218
|
}
|
|
256
219
|
catch (error) {
|
|
@@ -258,10 +221,11 @@ const assertColor = async (color) => {
|
|
|
258
221
|
}
|
|
259
222
|
})(),
|
|
260
223
|
])
|
|
261
|
-
|
|
224
|
+
.finally(async () => {
|
|
262
225
|
if (!Buffer.isBuffer(encWriteStream)) {
|
|
263
226
|
encWriteStream.destroy();
|
|
264
227
|
}
|
|
228
|
+
// remove tmp files
|
|
265
229
|
if (didSaveToTmpPath && bodyPath) {
|
|
266
230
|
try {
|
|
267
231
|
await fs_1.promises.access(bodyPath);
|
|
@@ -273,7 +237,7 @@ const assertColor = async (color) => {
|
|
|
273
237
|
}
|
|
274
238
|
}
|
|
275
239
|
});
|
|
276
|
-
|
|
240
|
+
|
|
277
241
|
const obj = Types_1.WAProto.Message.fromObject({
|
|
278
242
|
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
279
243
|
url: handle ? undefined : mediaUrl,
|
|
@@ -287,20 +251,19 @@ const assertColor = async (color) => {
|
|
|
287
251
|
media: undefined
|
|
288
252
|
})
|
|
289
253
|
});
|
|
290
|
-
|
|
291
|
-
if (
|
|
254
|
+
|
|
255
|
+
if (uploadData.ptv) {
|
|
292
256
|
obj.ptvMessage = obj.videoMessage;
|
|
293
257
|
delete obj.videoMessage;
|
|
294
258
|
}
|
|
295
|
-
|
|
259
|
+
|
|
296
260
|
if (cacheableKey) {
|
|
261
|
+
logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
|
|
297
262
|
options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
|
|
298
263
|
}
|
|
299
264
|
return obj;
|
|
300
265
|
};
|
|
301
266
|
exports.prepareWAMessageMedia = prepareWAMessageMedia;
|
|
302
|
-
|
|
303
|
-
|
|
304
267
|
const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
|
|
305
268
|
ephemeralExpiration = ephemeralExpiration || 0;
|
|
306
269
|
const content = {
|
|
@@ -484,11 +447,9 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
484
447
|
break;
|
|
485
448
|
}
|
|
486
449
|
}
|
|
487
|
-
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
}, options);
|
|
491
|
-
m.ptvMessage = generated.ptvMessage || generated.videoMessage;
|
|
450
|
+
else if ('ptv' in message && message.ptv) {
|
|
451
|
+
const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
|
|
452
|
+
m.ptvMessage = videoMessage;
|
|
492
453
|
}
|
|
493
454
|
else if ('product' in message) {
|
|
494
455
|
const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
|
|
@@ -1145,170 +1106,3 @@ const getSenderLid = (message) => {
|
|
|
1145
1106
|
return { jid: sender, lid };
|
|
1146
1107
|
};
|
|
1147
1108
|
exports.getSenderLid = getSenderLid;
|
|
1148
|
-
|
|
1149
|
-
/**
|
|
1150
|
-
STICKER PACK FUNCTION RECODE BY
|
|
1151
|
-
@RexxHayanasi < Maintainer @rexxhayanasi/elaina-baileys >
|
|
1152
|
-
**/
|
|
1153
|
-
|
|
1154
|
-
const prepareStickerPackMessage = async (stickerPack, options) => {
|
|
1155
|
-
const { stickers, name, publisher, packId, description } = stickerPack;
|
|
1156
|
-
|
|
1157
|
-
if (stickers.length > 60) {
|
|
1158
|
-
throw new boom_1.Boom('Sticker pack exceeds the maximum limit of 60 stickers', { statusCode: 400 });
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
if (stickers.length === 0) {
|
|
1162
|
-
throw new boom_1.Boom('Sticker pack must contain at least one sticker', { statusCode: 400 });
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
const stickerPackIdValue = packId || (0, generics_1.generateMessageIDV2)();
|
|
1166
|
-
const lib = await getImageProcessingLibrary();
|
|
1167
|
-
const stickerData = {};
|
|
1168
|
-
|
|
1169
|
-
const stickerPromises = stickers.map(async (s, i) => {
|
|
1170
|
-
const { stream } = await (0, messages_media_1.getStream)(s.data);
|
|
1171
|
-
const buffer = await (0, generics_1.toBuffer)(stream);
|
|
1172
|
-
|
|
1173
|
-
let webpBuffer;
|
|
1174
|
-
let isAnimated = false;
|
|
1175
|
-
const isWebP = isWebPBuffer(buffer);
|
|
1176
|
-
|
|
1177
|
-
if (isWebP) {
|
|
1178
|
-
webpBuffer = buffer;
|
|
1179
|
-
isAnimated = isAnimatedWebP(buffer);
|
|
1180
|
-
} else if (lib.sharp) {
|
|
1181
|
-
webpBuffer = await lib.sharp(buffer).webp().toBuffer();
|
|
1182
|
-
isAnimated = false;
|
|
1183
|
-
} else {
|
|
1184
|
-
throw new boom_1.Boom(
|
|
1185
|
-
'No image processing library (sharp) available for converting sticker to WebP. Either install sharp or provide stickers in WebP format.'
|
|
1186
|
-
);
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
if (webpBuffer.length > 1024 * 1024) {
|
|
1190
|
-
throw new boom_1.Boom(`Sticker at index ${i} exceeds the 1MB size limit`, { statusCode: 400 });
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
const hash = (0, crypto_2.sha256)(webpBuffer).toString('base64').replace(/\//g, '-');
|
|
1194
|
-
const fileName = `${hash}.webp`;
|
|
1195
|
-
|
|
1196
|
-
stickerData[fileName] = [new Uint8Array(webpBuffer), { level: 0 }];
|
|
1197
|
-
|
|
1198
|
-
return {
|
|
1199
|
-
fileName,
|
|
1200
|
-
mimetype: 'image/webp',
|
|
1201
|
-
isAnimated,
|
|
1202
|
-
emojis: s.emojis || [],
|
|
1203
|
-
accessibilityLabel: s.accessibilityLabel
|
|
1204
|
-
};
|
|
1205
|
-
});
|
|
1206
|
-
|
|
1207
|
-
const stickerMetadata = await Promise.all(stickerPromises);
|
|
1208
|
-
|
|
1209
|
-
const trayIconFileName = `${stickerPackIdValue}.webp`;
|
|
1210
|
-
const { stream: coverStream } = await (0, messages_media_1.getStream)(stickerPack.cover);
|
|
1211
|
-
const coverBuffer = await (0, generics_1.toBuffer)(coverStream);
|
|
1212
|
-
|
|
1213
|
-
let coverWebpBuffer;
|
|
1214
|
-
const isCoverWebP = isWebPBuffer(coverBuffer);
|
|
1215
|
-
|
|
1216
|
-
if (isCoverWebP) {
|
|
1217
|
-
coverWebpBuffer = coverBuffer;
|
|
1218
|
-
} else if (lib.sharp) {
|
|
1219
|
-
coverWebpBuffer = await lib.sharp(coverBuffer).webp().toBuffer();
|
|
1220
|
-
} else {
|
|
1221
|
-
throw new boom_1.Boom(
|
|
1222
|
-
'No image processing library (sharp) available for converting cover to WebP. Either install sharp or provide cover in WebP format.'
|
|
1223
|
-
);
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
|
-
stickerData[trayIconFileName] = [new Uint8Array(coverWebpBuffer), { level: 0 }];
|
|
1227
|
-
|
|
1228
|
-
const zipBuffer = await new Promise((resolve, reject) => {
|
|
1229
|
-
(0, fflate_1.zip)(stickerData, (err, data) => {
|
|
1230
|
-
if (err) {
|
|
1231
|
-
reject(err);
|
|
1232
|
-
} else {
|
|
1233
|
-
resolve(Buffer.from(data));
|
|
1234
|
-
}
|
|
1235
|
-
});
|
|
1236
|
-
});
|
|
1237
|
-
|
|
1238
|
-
const stickerPackSize = zipBuffer.length;
|
|
1239
|
-
|
|
1240
|
-
const stickerPackUpload = await (0, messages_media_1.encryptedStream)(zipBuffer, 'sticker-pack', {
|
|
1241
|
-
logger: options.logger,
|
|
1242
|
-
opts: options.options
|
|
1243
|
-
});
|
|
1244
|
-
|
|
1245
|
-
const stickerPackUploadResult = await options.upload(stickerPackUpload.encFilePath, {
|
|
1246
|
-
fileEncSha256B64: stickerPackUpload.fileEncSha256.toString('base64'),
|
|
1247
|
-
mediaType: 'sticker-pack',
|
|
1248
|
-
timeoutMs: options.mediaUploadTimeoutMs
|
|
1249
|
-
});
|
|
1250
|
-
|
|
1251
|
-
await fs_1.promises.unlink(stickerPackUpload.encFilePath);
|
|
1252
|
-
|
|
1253
|
-
const stickerPackMessage = {
|
|
1254
|
-
name: name,
|
|
1255
|
-
publisher: publisher,
|
|
1256
|
-
stickerPackId: stickerPackIdValue,
|
|
1257
|
-
packDescription: description,
|
|
1258
|
-
stickerPackOrigin: WAProto_1.proto.Message.StickerPackMessage.StickerPackOrigin.USER_CREATED,
|
|
1259
|
-
stickerPackSize: stickerPackSize,
|
|
1260
|
-
stickers: stickerMetadata,
|
|
1261
|
-
fileSha256: stickerPackUpload.fileSha256,
|
|
1262
|
-
fileEncSha256: stickerPackUpload.fileEncSha256,
|
|
1263
|
-
mediaKey: stickerPackUpload.mediaKey,
|
|
1264
|
-
directPath: stickerPackUploadResult.directPath,
|
|
1265
|
-
fileLength: stickerPackUpload.fileLength,
|
|
1266
|
-
mediaKeyTimestamp: (0, generics_1.unixTimestampSeconds)(),
|
|
1267
|
-
trayIconFileName: trayIconFileName
|
|
1268
|
-
};
|
|
1269
|
-
|
|
1270
|
-
try {
|
|
1271
|
-
let thumbnailBuffer;
|
|
1272
|
-
if (lib.sharp) {
|
|
1273
|
-
thumbnailBuffer = await lib.sharp(coverBuffer).resize(252, 252).jpeg().toBuffer();
|
|
1274
|
-
} else if (lib.jimp) {
|
|
1275
|
-
const jimpImage = await lib.jimp.read(coverBuffer);
|
|
1276
|
-
thumbnailBuffer = await jimpImage.resize(252, 252).getBufferAsync(lib.jimp.MIME_JPEG);
|
|
1277
|
-
} else {
|
|
1278
|
-
throw new Error('No image processing library available for thumbnail generation');
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
if (!thumbnailBuffer || thumbnailBuffer.length === 0) {
|
|
1282
|
-
throw new Error('Failed to generate thumbnail buffer');
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
const thumbUpload = await (0, messages_media_1.encryptedStream)(thumbnailBuffer, 'thumbnail-sticker-pack', {
|
|
1286
|
-
logger: options.logger,
|
|
1287
|
-
opts: options.options,
|
|
1288
|
-
mediaKey: stickerPackUpload.mediaKey
|
|
1289
|
-
});
|
|
1290
|
-
|
|
1291
|
-
const thumbUploadResult = await options.upload(thumbUpload.encFilePath, {
|
|
1292
|
-
fileEncSha256B64: thumbUpload.fileEncSha256.toString('base64'),
|
|
1293
|
-
mediaType: 'thumbnail-sticker-pack',
|
|
1294
|
-
timeoutMs: options.mediaUploadTimeoutMs
|
|
1295
|
-
});
|
|
1296
|
-
|
|
1297
|
-
await fs_1.promises.unlink(thumbUpload.encFilePath);
|
|
1298
|
-
|
|
1299
|
-
Object.assign(stickerPackMessage, {
|
|
1300
|
-
thumbnailDirectPath: thumbUploadResult.directPath,
|
|
1301
|
-
thumbnailSha256: thumbUpload.fileSha256,
|
|
1302
|
-
thumbnailEncSha256: thumbUpload.fileEncSha256,
|
|
1303
|
-
thumbnailHeight: 252,
|
|
1304
|
-
thumbnailWidth: 252,
|
|
1305
|
-
imageDataHash: (0, crypto_2.sha256)(thumbnailBuffer).toString('base64')
|
|
1306
|
-
});
|
|
1307
|
-
|
|
1308
|
-
} catch (e) {
|
|
1309
|
-
options.logger === null || options.logger === void 0 ? void 0 : options.logger.warn(`Thumbnail generation failed: ${e}`);
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
|
-
return { stickerPackMessage };
|
|
1313
|
-
};
|
|
1314
|
-
exports.prepareStickerPackMessage = prepareStickerPackMessage;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rexxhayanasi/elaina-baileys",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1-rc.1",
|
|
4
4
|
"description": "Custom Baileys WhatsApp API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"baileys",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"homepage": "https://whatsapp.com/channel/0029Vb70uHbD8SE2w5Q9M107",
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"publishConfig": {
|
|
21
|
-
"tag": "
|
|
21
|
+
"tag": "latest"
|
|
22
22
|
},
|
|
23
23
|
"author": "RexxHayanasi",
|
|
24
24
|
"main": "lib/index.js",
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.getWAUploadToServerNewsletter = exports.prepareWAMessageMediaNewsletter = exports.getRawMediaUploadDataNewsletter = void 0;
|
|
5
|
-
|
|
6
|
-
const crypto_1 = require("crypto");
|
|
7
|
-
const boom_1 = require("@hapi/boom");
|
|
8
|
-
const WAProto_1 = require("../../WAProto");
|
|
9
|
-
const axios_1 = require("axios");
|
|
10
|
-
const Defaults_1 = require("../Defaults");
|
|
11
|
-
|
|
12
|
-
function getRawMediaUploadDataNewsletter(buffer) {
|
|
13
|
-
if (!Buffer.isBuffer(buffer)) {
|
|
14
|
-
throw new boom_1.Boom("Newsletter media must be Buffer");
|
|
15
|
-
}
|
|
16
|
-
const fileSha256 = (0, crypto_1.createHash)("sha256").update(buffer).digest();
|
|
17
|
-
return {
|
|
18
|
-
buffer,
|
|
19
|
-
fileSha256,
|
|
20
|
-
fileLength: buffer.length
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
exports.getRawMediaUploadDataNewsletter = getRawMediaUploadDataNewsletter;
|
|
24
|
-
|
|
25
|
-
function getWAUploadToServerNewsletter({ customUploadHosts = [], fetchAgent, logger, options = {} }, refreshMediaConn) {
|
|
26
|
-
return async (buffer, { mediaType, fileEncSha256B64 }) => {
|
|
27
|
-
if (!Buffer.isBuffer(buffer)) {
|
|
28
|
-
throw new boom_1.Boom("Upload expects Buffer");
|
|
29
|
-
}
|
|
30
|
-
let uploadInfo = await refreshMediaConn(false);
|
|
31
|
-
const hosts = [...customUploadHosts, ...uploadInfo.hosts];
|
|
32
|
-
let urls;
|
|
33
|
-
for (const { hostname, maxContentLengthBytes } of hosts) {
|
|
34
|
-
const auth = encodeURIComponent(uploadInfo.auth);
|
|
35
|
-
let mediaPath = Defaults_1.MEDIA_PATH_MAP[mediaType];
|
|
36
|
-
if (!mediaPath) {
|
|
37
|
-
mediaPath = "/newsletter/newsletter-image";
|
|
38
|
-
} else {
|
|
39
|
-
mediaPath = mediaPath.replace("/mms/", "/newsletter/newsletter-");
|
|
40
|
-
}
|
|
41
|
-
const url = `https://${hostname}${mediaPath}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
|
|
42
|
-
try {
|
|
43
|
-
if (maxContentLengthBytes && buffer.length > maxContentLengthBytes) {
|
|
44
|
-
throw new boom_1.Boom("Body too large", { statusCode: 413 });
|
|
45
|
-
}
|
|
46
|
-
const res = await axios_1.default.post(url, buffer, {
|
|
47
|
-
...options,
|
|
48
|
-
headers: {
|
|
49
|
-
"Content-Type": "application/octet-stream",
|
|
50
|
-
Origin: Defaults_1.DEFAULT_ORIGIN,
|
|
51
|
-
...(options.headers || {})
|
|
52
|
-
},
|
|
53
|
-
httpsAgent: fetchAgent,
|
|
54
|
-
responseType: "json",
|
|
55
|
-
maxBodyLength: Infinity,
|
|
56
|
-
maxContentLength: Infinity
|
|
57
|
-
});
|
|
58
|
-
const result = res.data;
|
|
59
|
-
if (result?.url || result?.direct_path) {
|
|
60
|
-
urls = {
|
|
61
|
-
mediaUrl: result.url,
|
|
62
|
-
directPath: result.direct_path
|
|
63
|
-
};
|
|
64
|
-
break;
|
|
65
|
-
}
|
|
66
|
-
uploadInfo = await refreshMediaConn(true);
|
|
67
|
-
} catch (err) {
|
|
68
|
-
logger?.warn?.({ err }, `Newsletter upload failed on ${hostname}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
if (!urls) {
|
|
72
|
-
throw new boom_1.Boom("Newsletter media upload failed", { statusCode: 500 });
|
|
73
|
-
}
|
|
74
|
-
return urls;
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
exports.getWAUploadToServerNewsletter = getWAUploadToServerNewsletter;
|
|
78
|
-
|
|
79
|
-
async function prepareWAMessageMediaNewsletter(message, options) {
|
|
80
|
-
if (!options || typeof options.upload !== "function") {
|
|
81
|
-
throw new boom_1.Boom("upload function is required");
|
|
82
|
-
}
|
|
83
|
-
const mediaType = Object.keys(message || {})[0];
|
|
84
|
-
if (!mediaType) {
|
|
85
|
-
throw new boom_1.Boom("Invalid newsletter media");
|
|
86
|
-
}
|
|
87
|
-
const buffer = message[mediaType];
|
|
88
|
-
if (!Buffer.isBuffer(buffer)) {
|
|
89
|
-
throw new boom_1.Boom("Newsletter media must be Buffer");
|
|
90
|
-
}
|
|
91
|
-
const uploadData = getRawMediaUploadDataNewsletter(buffer);
|
|
92
|
-
const uploaded = await options.upload(buffer, {
|
|
93
|
-
mediaType,
|
|
94
|
-
fileEncSha256B64: uploadData.fileSha256.toString("base64"),
|
|
95
|
-
newsletter: true
|
|
96
|
-
});
|
|
97
|
-
const proto = {};
|
|
98
|
-
proto[`${mediaType}Message`] = {
|
|
99
|
-
url: uploaded.mediaUrl,
|
|
100
|
-
directPath: uploaded.directPath,
|
|
101
|
-
fileSha256: uploadData.fileSha256,
|
|
102
|
-
fileLength: uploadData.fileLength,
|
|
103
|
-
mimetype: options.mimetype
|
|
104
|
-
};
|
|
105
|
-
if (mediaType === "video") {
|
|
106
|
-
proto.videoMessage.ptv = true;
|
|
107
|
-
}
|
|
108
|
-
return WAProto_1.WAProto.Message.fromObject(proto);
|
|
109
|
-
}
|
|
110
|
-
exports.prepareWAMessageMediaNewsletter = prepareWAMessageMediaNewsletter;
|