@rexxhayanasi/elaina-baileys 1.1.8 → 1.2.0-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/lib/Signal/Group/keyhelper.js +32 -20
- package/lib/Socket/index.js +9 -35
- package/lib/Utils/async-iterable.js +41 -0
- package/lib/Utils/messages-media.js +60 -6
- package/lib/Utils/messages.js +51 -33
- package/lib/index.js +0 -1
- package/package.json +2 -3
- package/lib/Auth/index.js +0 -8
- package/lib/Auth/sqlite.js +0 -57
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Signal Group Key Helper
|
|
4
|
+
* Helper functions to generate sender keys and signing keys safely.
|
|
5
|
+
*/
|
|
2
6
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
7
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
8
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
9
9
|
}) : (function(o, m, k, k2) {
|
|
10
10
|
if (k2 === undefined) k2 = k;
|
|
11
11
|
o[k2] = m[k];
|
|
12
12
|
}));
|
|
13
|
+
|
|
13
14
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
15
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
16
|
}) : function(o, v) {
|
|
16
17
|
o["default"] = v;
|
|
17
18
|
});
|
|
19
|
+
|
|
18
20
|
var __importStar = (this && this.__importStar) || (function () {
|
|
19
21
|
var ownKeys = function(o) {
|
|
20
22
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
@@ -32,45 +34,55 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
34
|
return result;
|
|
33
35
|
};
|
|
34
36
|
})();
|
|
37
|
+
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
exports.generateSenderKey = generateSenderKey;
|
|
37
40
|
exports.generateSenderKeyId = generateSenderKeyId;
|
|
38
41
|
exports.generateSenderSigningKey = generateSenderSigningKey;
|
|
42
|
+
|
|
39
43
|
const nodeCrypto = __importStar(require("crypto"));
|
|
40
|
-
const curve_1 = require("libsignal/src/curve");
|
|
44
|
+
const curve_1 = require("libsignal/src/curve");
|
|
41
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Generates a random 32-byte Sender Key.
|
|
48
|
+
* @returns {Buffer} The generated key.
|
|
49
|
+
*/
|
|
42
50
|
function generateSenderKey() {
|
|
43
51
|
const key = nodeCrypto.randomBytes(32);
|
|
44
|
-
if (
|
|
45
|
-
throw new Error("Failed to generate valid
|
|
52
|
+
if (key.length !== 32) {
|
|
53
|
+
throw new Error("Failed to generate a valid 32-byte Sender Key");
|
|
46
54
|
}
|
|
47
55
|
return key;
|
|
48
56
|
}
|
|
49
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Generates a random Sender Key ID.
|
|
60
|
+
* @returns {number} The generated Key ID.
|
|
61
|
+
*/
|
|
50
62
|
function generateSenderKeyId() {
|
|
51
63
|
const id = nodeCrypto.randomInt(2147483647);
|
|
52
|
-
if (typeof id !== 'number') {
|
|
53
|
-
throw new Error("Failed to generate
|
|
64
|
+
if (!id || typeof id !== 'number') {
|
|
65
|
+
throw new Error("Failed to generate Sender Key ID");
|
|
54
66
|
}
|
|
55
67
|
return id;
|
|
56
68
|
}
|
|
57
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Generates a Sender Signing Key Pair.
|
|
72
|
+
* Uses libsignal's curve implementation.
|
|
73
|
+
* @param {Object} [key] Optional existing key pair.
|
|
74
|
+
* @returns {Object} The key pair (public/private).
|
|
75
|
+
*/
|
|
58
76
|
function generateSenderSigningKey(key) {
|
|
59
77
|
if (!key) {
|
|
60
78
|
key = (0, curve_1.generateKeyPair)();
|
|
61
79
|
}
|
|
80
|
+
|
|
62
81
|
if (!key || !key.pubKey || !key.privKey) {
|
|
63
|
-
throw new Error("Invalid
|
|
82
|
+
throw new Error("Invalid KeyPair generated from Curve");
|
|
64
83
|
}
|
|
65
|
-
const publicBuf = Buffer.from(key.pubKey);
|
|
66
|
-
const privateBuf = Buffer.from(key.privKey);
|
|
67
|
-
|
|
68
|
-
if (publicBuf.length !== 32 || privateBuf.length !== 32) {
|
|
69
|
-
throw new Error("Invalid signing key length");
|
|
70
|
-
}
|
|
71
|
-
|
|
72
84
|
return {
|
|
73
|
-
public:
|
|
74
|
-
private:
|
|
85
|
+
public: key.pubKey,
|
|
86
|
+
private: key.privKey
|
|
75
87
|
};
|
|
76
88
|
}
|
package/lib/Socket/index.js
CHANGED
|
@@ -1,36 +1,10 @@
|
|
|
1
|
-
"use strict"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
let __ACTIVE_SOCKET__ = null
|
|
9
|
-
|
|
10
|
-
const makeWASocket = (config) => {
|
|
11
|
-
try {
|
|
12
|
-
if (__ACTIVE_SOCKET__) {
|
|
13
|
-
try {
|
|
14
|
-
__ACTIVE_SOCKET__.ev?.removeAllListeners?.()
|
|
15
|
-
__ACTIVE_SOCKET__.ws?.removeAllListeners?.()
|
|
16
|
-
__ACTIVE_SOCKET__.ws?.terminate?.()
|
|
17
|
-
__ACTIVE_SOCKET__.ws?.close?.()
|
|
18
|
-
} catch {}
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
__ACTIVE_SOCKET__ = null
|
|
22
|
-
} catch {}
|
|
23
|
-
}
|
|
24
|
-
} catch {}
|
|
25
|
-
|
|
26
|
-
const sock = makeBusinessSocket({
|
|
27
|
-
...DEFAULT_CONNECTION_CONFIG,
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Defaults_1 = require("../Defaults");
|
|
4
|
+
const business_1 = require("./business");
|
|
5
|
+
// export the last socket layer
|
|
6
|
+
const makeWASocket = (config) => ((0, business_1.makeBusinessSocket)({
|
|
7
|
+
...Defaults_1.DEFAULT_CONNECTION_CONFIG,
|
|
28
8
|
...config
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
__ACTIVE_SOCKET__ = sock
|
|
32
|
-
|
|
33
|
-
return sock
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
exports.default = makeWASocket
|
|
9
|
+
}));
|
|
10
|
+
exports.default = makeWASocket;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toAsyncIterable = void 0;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Helper by @rexxhayanasi to convert various media inputs into an Async Iterable
|
|
7
|
+
* Compatible with Baileys buffer/stream handling
|
|
8
|
+
*/
|
|
9
|
+
function toAsyncIterable(input) {
|
|
10
|
+
if (!input) {
|
|
11
|
+
throw new Error("Invalid media stream (undefined/null)");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (input[Symbol.asyncIterator]) {
|
|
15
|
+
return input;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
if (Buffer.isBuffer(input)) {
|
|
20
|
+
return (async function* () {
|
|
21
|
+
yield input;
|
|
22
|
+
})();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (typeof input === "string") {
|
|
26
|
+
const fs = require("fs");
|
|
27
|
+
return fs.createReadStream(input);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (typeof input.on === "function") {
|
|
31
|
+
return (async function* () {
|
|
32
|
+
for await (const chunk of input) {
|
|
33
|
+
yield chunk;
|
|
34
|
+
}
|
|
35
|
+
})();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
throw new Error("Unsupported media stream type");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
exports.toAsyncIterable = toAsyncIterable;
|
|
@@ -61,6 +61,8 @@ 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
|
+
|
|
64
66
|
const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
|
|
65
67
|
const getImageProcessingLibrary = async () => {
|
|
66
68
|
const [_jimp, sharp] = await Promise.all([
|
|
@@ -82,14 +84,26 @@ const getImageProcessingLibrary = async () => {
|
|
|
82
84
|
}
|
|
83
85
|
throw new boom_1.Boom('No image processing library available');
|
|
84
86
|
};
|
|
87
|
+
|
|
85
88
|
const hkdfInfoKey = (type) => {
|
|
86
|
-
if (type === 'ptv') return 'WhatsApp Video Keys';
|
|
87
89
|
if (type === 'sticker-pack') return 'WhatsApp Image Keys';
|
|
90
|
+
if (type === 'ptv') return 'WhatsApp Video Keys';
|
|
91
|
+
|
|
92
|
+
// Support Newsletter keys explicitly or fallback
|
|
93
|
+
if (type === 'newsletter-image') return 'WhatsApp Image Keys';
|
|
94
|
+
if (type === 'newsletter-video') return 'WhatsApp Video Keys';
|
|
88
95
|
|
|
89
96
|
const hkdfInfo = Defaults_1.MEDIA_HKDF_KEY_MAPPING[type];
|
|
97
|
+
|
|
98
|
+
// Fallback if type not found to prevent undefined key error
|
|
99
|
+
if (!hkdfInfo) {
|
|
100
|
+
return 'WhatsApp Image Keys';
|
|
101
|
+
}
|
|
102
|
+
|
|
90
103
|
return `WhatsApp ${hkdfInfo} Keys`;
|
|
91
104
|
};
|
|
92
105
|
exports.hkdfInfoKey = hkdfInfoKey;
|
|
106
|
+
|
|
93
107
|
/** generates all the keys required to encrypt/decrypt & sign a media message */
|
|
94
108
|
async function getMediaKeys(buffer, mediaType) {
|
|
95
109
|
if (!buffer) {
|
|
@@ -106,6 +120,7 @@ async function getMediaKeys(buffer, mediaType) {
|
|
|
106
120
|
macKey: expandedMediaKey.slice(48, 80),
|
|
107
121
|
};
|
|
108
122
|
}
|
|
123
|
+
|
|
109
124
|
async function uploadFile(buffer, logger) {
|
|
110
125
|
const { fromBuffer } = await Promise.resolve().then(() => __importStar(require('file-type')));
|
|
111
126
|
const fileType = await fromBuffer(buffer);
|
|
@@ -210,6 +225,7 @@ async function uploadFile(buffer, logger) {
|
|
|
210
225
|
}
|
|
211
226
|
throw new Error("All upload services failed.");
|
|
212
227
|
}
|
|
228
|
+
|
|
213
229
|
async function vid2jpg(videoUrl) {
|
|
214
230
|
try {
|
|
215
231
|
const { data } = await axios_1.default.get(`https://ezgif.com/video-to-jpg?url=${encodeURIComponent(videoUrl)}`);
|
|
@@ -246,6 +262,7 @@ async function vid2jpg(videoUrl) {
|
|
|
246
262
|
throw new Error("Failed to convert video to JPG: " + error.message);
|
|
247
263
|
}
|
|
248
264
|
}
|
|
265
|
+
|
|
249
266
|
/**
|
|
250
267
|
* Extracts video thumbnail using FFmpeg
|
|
251
268
|
*/
|
|
@@ -276,6 +293,7 @@ const extractVideoThumb = async (videoPath, time = '00:00:00', size = { width: 2
|
|
|
276
293
|
});
|
|
277
294
|
};
|
|
278
295
|
exports.extractVideoThumb = extractVideoThumb;
|
|
296
|
+
|
|
279
297
|
const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
280
298
|
var _a, _b;
|
|
281
299
|
if (bufferOrFilePath instanceof stream_1.Readable) {
|
|
@@ -318,11 +336,13 @@ const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
|
318
336
|
}
|
|
319
337
|
};
|
|
320
338
|
exports.extractImageThumb = extractImageThumb;
|
|
339
|
+
|
|
321
340
|
const encodeBase64EncodedStringForUpload = (b64) => (encodeURIComponent(b64
|
|
322
341
|
.replace(/\+/g, '-')
|
|
323
342
|
.replace(/\//g, '_')
|
|
324
343
|
.replace(/\=+$/, '')));
|
|
325
344
|
exports.encodeBase64EncodedStringForUpload = encodeBase64EncodedStringForUpload;
|
|
345
|
+
|
|
326
346
|
const generateProfilePicture = async (mediaUpload) => {
|
|
327
347
|
let bufferOrFilePath;
|
|
328
348
|
let img;
|
|
@@ -345,12 +365,14 @@ const generateProfilePicture = async (mediaUpload) => {
|
|
|
345
365
|
};
|
|
346
366
|
};
|
|
347
367
|
exports.generateProfilePicture = generateProfilePicture;
|
|
368
|
+
|
|
348
369
|
/** gets the SHA256 of the given media message */
|
|
349
370
|
const mediaMessageSHA256B64 = (message) => {
|
|
350
371
|
const media = Object.values(message)[0];
|
|
351
372
|
return (media === null || media === void 0 ? void 0 : media.fileSha256) && Buffer.from(media.fileSha256).toString('base64');
|
|
352
373
|
};
|
|
353
374
|
exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
|
|
375
|
+
|
|
354
376
|
async function getAudioDuration(buffer) {
|
|
355
377
|
const musicMetadata = await Promise.resolve().then(() => __importStar(require('music-metadata')));
|
|
356
378
|
let metadata;
|
|
@@ -368,6 +390,7 @@ async function getAudioDuration(buffer) {
|
|
|
368
390
|
}
|
|
369
391
|
return metadata.format.duration;
|
|
370
392
|
}
|
|
393
|
+
|
|
371
394
|
async function getAudioWaveform(buffer, logger) {
|
|
372
395
|
try {
|
|
373
396
|
const { default: decoder } = await eval('import(\'audio-decode\')');
|
|
@@ -404,6 +427,7 @@ async function getAudioWaveform(buffer, logger) {
|
|
|
404
427
|
logger === null || logger === void 0 ? void 0 : logger.debug('Failed to generate waveform: ' + e);
|
|
405
428
|
}
|
|
406
429
|
}
|
|
430
|
+
|
|
407
431
|
const toReadable = (buffer) => {
|
|
408
432
|
const readable = new stream_1.Readable({ read: () => { } });
|
|
409
433
|
readable.push(buffer);
|
|
@@ -411,6 +435,7 @@ const toReadable = (buffer) => {
|
|
|
411
435
|
return readable;
|
|
412
436
|
};
|
|
413
437
|
exports.toReadable = toReadable;
|
|
438
|
+
|
|
414
439
|
const toBuffer = async (stream) => {
|
|
415
440
|
const chunks = [];
|
|
416
441
|
for await (const chunk of stream) {
|
|
@@ -420,6 +445,7 @@ const toBuffer = async (stream) => {
|
|
|
420
445
|
return Buffer.concat(chunks);
|
|
421
446
|
};
|
|
422
447
|
exports.toBuffer = toBuffer;
|
|
448
|
+
|
|
423
449
|
const getStream = async (item, opts) => {
|
|
424
450
|
if (Buffer.isBuffer(item)) {
|
|
425
451
|
return { stream: (0, exports.toReadable)(item), type: 'buffer' };
|
|
@@ -433,6 +459,7 @@ const getStream = async (item, opts) => {
|
|
|
433
459
|
return { stream: (0, fs_1.createReadStream)(item.url), type: 'file' };
|
|
434
460
|
};
|
|
435
461
|
exports.getStream = getStream;
|
|
462
|
+
|
|
436
463
|
/** generates a thumbnail for a given media, if required */
|
|
437
464
|
async function generateThumbnail(file, mediaType, options) {
|
|
438
465
|
var _a;
|
|
@@ -481,11 +508,13 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
481
508
|
originalImageDimensions
|
|
482
509
|
};
|
|
483
510
|
}
|
|
511
|
+
|
|
484
512
|
const getHttpStream = async (url, options = {}) => {
|
|
485
513
|
const fetched = await axios_1.default.get(url.toString(), { ...options, responseType: 'stream' });
|
|
486
514
|
return fetched.data;
|
|
487
515
|
};
|
|
488
516
|
exports.getHttpStream = getHttpStream;
|
|
517
|
+
|
|
489
518
|
const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
|
|
490
519
|
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
491
520
|
logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
|
|
@@ -529,6 +558,7 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
|
|
|
529
558
|
}
|
|
530
559
|
};
|
|
531
560
|
exports.prepareStream = prepareStream;
|
|
561
|
+
|
|
532
562
|
const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
|
|
533
563
|
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
534
564
|
logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
|
|
@@ -615,6 +645,7 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
615
645
|
}
|
|
616
646
|
};
|
|
617
647
|
exports.encryptedStream = encryptedStream;
|
|
648
|
+
|
|
618
649
|
const DEF_HOST = 'mmg.whatsapp.net';
|
|
619
650
|
const AES_CHUNK_SIZE = 16;
|
|
620
651
|
const toSmallestChunkSize = (num) => {
|
|
@@ -622,6 +653,7 @@ const toSmallestChunkSize = (num) => {
|
|
|
622
653
|
};
|
|
623
654
|
const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
|
|
624
655
|
exports.getUrlFromDirectPath = getUrlFromDirectPath;
|
|
656
|
+
|
|
625
657
|
const downloadContentFromMessage = async ({ mediaKey, directPath, url }, type, opts = {}) => {
|
|
626
658
|
const isValidMediaUrl = url === null || url === void 0 ? void 0 : url.startsWith('https://mmg.whatsapp.net/');
|
|
627
659
|
const downloadUrl = isValidMediaUrl ? url : (0, exports.getUrlFromDirectPath)(directPath);
|
|
@@ -632,6 +664,7 @@ const downloadContentFromMessage = async ({ mediaKey, directPath, url }, type, o
|
|
|
632
664
|
return (0, exports.downloadEncryptedContent)(downloadUrl, keys, opts);
|
|
633
665
|
};
|
|
634
666
|
exports.downloadContentFromMessage = downloadContentFromMessage;
|
|
667
|
+
|
|
635
668
|
const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startByte, endByte, options } = {}) => {
|
|
636
669
|
let bytesFetched = 0;
|
|
637
670
|
let startChunk = 0;
|
|
@@ -712,6 +745,7 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
|
|
|
712
745
|
return fetched.pipe(output, { end: true });
|
|
713
746
|
};
|
|
714
747
|
exports.downloadEncryptedContent = downloadEncryptedContent;
|
|
748
|
+
|
|
715
749
|
function extensionForMediaMessage(message) {
|
|
716
750
|
const getExtension = (mimetype) => mimetype.split(';')[0].split('/')[1];
|
|
717
751
|
const type = Object.keys(message)[0];
|
|
@@ -727,6 +761,7 @@ function extensionForMediaMessage(message) {
|
|
|
727
761
|
}
|
|
728
762
|
return extension;
|
|
729
763
|
}
|
|
764
|
+
|
|
730
765
|
const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
731
766
|
return async (stream, { mediaType, fileEncSha256B64, newsletter, timeoutMs }) => {
|
|
732
767
|
var _a, _b;
|
|
@@ -734,6 +769,16 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
734
769
|
let urls;
|
|
735
770
|
const hosts = [...customUploadHosts, ...uploadInfo.hosts];
|
|
736
771
|
const chunks = [];
|
|
772
|
+
|
|
773
|
+
// --- MODIFIKASI: Panggil via objek toAsyncIterable_1 ---
|
|
774
|
+
try {
|
|
775
|
+
// Kita akses properti .toAsyncIterable karena diimpor sebagai objek
|
|
776
|
+
stream = toAsyncIterable_1.toAsyncIterable(stream);
|
|
777
|
+
} catch (error) {
|
|
778
|
+
throw new boom_1.Boom(error.message, { statusCode: 400 });
|
|
779
|
+
}
|
|
780
|
+
// --------------------------------------------------------
|
|
781
|
+
|
|
737
782
|
if (!Buffer.isBuffer(stream)) {
|
|
738
783
|
for await (const chunk of stream) {
|
|
739
784
|
chunks.push(chunk);
|
|
@@ -741,13 +786,20 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
741
786
|
}
|
|
742
787
|
const reqBody = Buffer.isBuffer(stream) ? stream : Buffer.concat(chunks);
|
|
743
788
|
fileEncSha256B64 = (0, exports.encodeBase64EncodedStringForUpload)(fileEncSha256B64);
|
|
789
|
+
|
|
744
790
|
let media = Defaults_1.MEDIA_PATH_MAP[mediaType];
|
|
745
791
|
if (mediaType === 'sticker-pack') {
|
|
746
792
|
media = '/mms/image';
|
|
747
793
|
}
|
|
794
|
+
|
|
748
795
|
if (newsletter) {
|
|
749
|
-
|
|
796
|
+
if (media) {
|
|
797
|
+
media = media.replace('/mms/', '/newsletter/newsletter-');
|
|
798
|
+
} else {
|
|
799
|
+
media = '/newsletter/newsletter-image';
|
|
800
|
+
}
|
|
750
801
|
}
|
|
802
|
+
|
|
751
803
|
for (const { hostname, maxContentLengthBytes } of hosts) {
|
|
752
804
|
logger.debug(`uploading to "${hostname}"`);
|
|
753
805
|
const auth = encodeURIComponent(uploadInfo.auth);
|
|
@@ -798,7 +850,8 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
798
850
|
return urls;
|
|
799
851
|
};
|
|
800
852
|
};
|
|
801
|
-
exports.getWAUploadToServer = getWAUploadToServer;
|
|
853
|
+
exports.getWAUploadToServer = getWAUploadToServer;
|
|
854
|
+
|
|
802
855
|
const getMediaRetryKey = (mediaKey) => {
|
|
803
856
|
return (0, crypto_1.hkdf)(mediaKey, 32, { info: 'WhatsApp Media Retry Notification' });
|
|
804
857
|
};
|
|
@@ -837,6 +890,7 @@ const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
|
|
|
837
890
|
return req;
|
|
838
891
|
};
|
|
839
892
|
exports.encryptMediaRetryRequest = encryptMediaRetryRequest;
|
|
893
|
+
|
|
840
894
|
const decodeMediaRetryNode = (node) => {
|
|
841
895
|
const rmrNode = (0, WABinary_1.getBinaryNodeChild)(node, 'rmr');
|
|
842
896
|
const event = {
|
|
@@ -866,20 +920,20 @@ const decodeMediaRetryNode = (node) => {
|
|
|
866
920
|
return event;
|
|
867
921
|
};
|
|
868
922
|
exports.decodeMediaRetryNode = decodeMediaRetryNode;
|
|
923
|
+
|
|
869
924
|
const decryptMediaRetryData = async ({ ciphertext, iv }, mediaKey, msgId) => {
|
|
870
925
|
const retryKey = await getMediaRetryKey(mediaKey);
|
|
871
926
|
const plaintext = (0, crypto_1.aesDecryptGCM)(ciphertext, retryKey, iv, Buffer.from(msgId));
|
|
872
927
|
return WAProto_1.proto.MediaRetryNotification.decode(plaintext);
|
|
873
928
|
};
|
|
874
929
|
exports.decryptMediaRetryData = decryptMediaRetryData;
|
|
930
|
+
|
|
875
931
|
const getStatusCodeForMediaRetry = (code) => MEDIA_RETRY_STATUS_MAP[code];
|
|
876
932
|
exports.getStatusCodeForMediaRetry = getStatusCodeForMediaRetry;
|
|
933
|
+
|
|
877
934
|
const MEDIA_RETRY_STATUS_MAP = {
|
|
878
935
|
[WAProto_1.proto.MediaRetryNotification.ResultType.SUCCESS]: 200,
|
|
879
936
|
[WAProto_1.proto.MediaRetryNotification.ResultType.DECRYPTION_ERROR]: 412,
|
|
880
937
|
[WAProto_1.proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
|
|
881
938
|
[WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418,
|
|
882
939
|
};
|
|
883
|
-
function __importStar(arg0) {
|
|
884
|
-
throw new Error('Function not implemented.');
|
|
885
|
-
}
|
package/lib/Utils/messages.js
CHANGED
|
@@ -42,6 +42,9 @@ const MIMETYPE_MAP = {
|
|
|
42
42
|
sticker: 'image/webp',
|
|
43
43
|
'product-catalog-image': 'image/jpeg',
|
|
44
44
|
'sticker-pack': 'application/x-zip-compressed'
|
|
45
|
+
"ptv": "video/mp4",
|
|
46
|
+
"newsletter-image": "image/jpeg",
|
|
47
|
+
"newsletter-video": "video/mp4"
|
|
45
48
|
};
|
|
46
49
|
const MessageTypeProto = {
|
|
47
50
|
'image': Types_1.WAProto.Message.ImageMessage,
|
|
@@ -85,36 +88,51 @@ const assertColor = async (color) => {
|
|
|
85
88
|
return assertedColor;
|
|
86
89
|
}
|
|
87
90
|
};
|
|
88
|
-
const prepareWAMessageMedia = async (message, options) => {
|
|
91
|
+
const prepareWAMessageMedia = async (message, options) => {
|
|
89
92
|
const logger = options.logger;
|
|
90
93
|
let mediaType;
|
|
94
|
+
|
|
91
95
|
for (const key of Defaults_1.MEDIA_KEYS) {
|
|
92
96
|
if (key in message) {
|
|
93
97
|
mediaType = key;
|
|
94
98
|
}
|
|
95
99
|
}
|
|
100
|
+
|
|
101
|
+
if (!mediaType && 'ptv' in message) {
|
|
102
|
+
mediaType = 'ptv';
|
|
103
|
+
}
|
|
104
|
+
|
|
96
105
|
if (!mediaType) {
|
|
97
106
|
throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
|
|
98
107
|
}
|
|
108
|
+
|
|
109
|
+
let isPtv = false;
|
|
110
|
+
if (mediaType === 'ptv') {
|
|
111
|
+
isPtv = true;
|
|
112
|
+
mediaType = 'video';
|
|
113
|
+
}
|
|
114
|
+
|
|
99
115
|
const uploadData = {
|
|
100
116
|
...message,
|
|
101
|
-
media: message[mediaType]
|
|
117
|
+
media: message[mediaType] || message['ptv']
|
|
102
118
|
};
|
|
119
|
+
|
|
103
120
|
delete uploadData[mediaType];
|
|
104
|
-
|
|
121
|
+
delete uploadData['ptv'];
|
|
122
|
+
|
|
105
123
|
const cacheableKey = typeof uploadData.media === 'object' &&
|
|
106
124
|
('url' in uploadData.media) &&
|
|
107
125
|
!!uploadData.media.url &&
|
|
108
126
|
!!options.mediaCache && (
|
|
109
127
|
mediaType + ':' + uploadData.media.url.toString());
|
|
110
|
-
|
|
128
|
+
|
|
111
129
|
if (mediaType === 'document' && !uploadData.fileName) {
|
|
112
130
|
uploadData.fileName = 'file';
|
|
113
131
|
}
|
|
114
132
|
if (!uploadData.mimetype) {
|
|
115
133
|
uploadData.mimetype = MIMETYPE_MAP[mediaType];
|
|
116
134
|
}
|
|
117
|
-
|
|
135
|
+
|
|
118
136
|
if (cacheableKey) {
|
|
119
137
|
const mediaBuff = options.mediaCache.get(cacheableKey);
|
|
120
138
|
if (mediaBuff) {
|
|
@@ -126,23 +144,24 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
126
144
|
}
|
|
127
145
|
}
|
|
128
146
|
|
|
129
|
-
const isNewsletter = (0, WABinary_1.isJidNewsletter)(options.jid);
|
|
147
|
+
const isNewsletter = options.newsletter || (options.jid && (0, WABinary_1.isJidNewsletter)(options.jid));
|
|
130
148
|
|
|
131
149
|
if (isNewsletter) {
|
|
132
150
|
logger === null || logger === void 0 ? void 0 : logger.debug({ key: cacheableKey }, 'Preparing raw media for newsletter');
|
|
133
|
-
|
|
151
|
+
|
|
134
152
|
const { bodyPath, fileSha256, fileLength, didSaveToTmpPath } = await (0, messages_media_1.prepareStream)(
|
|
135
|
-
uploadData.media,
|
|
136
|
-
options.mediaTypeOverride || mediaType,
|
|
153
|
+
uploadData.media,
|
|
154
|
+
options.mediaTypeOverride || mediaType,
|
|
137
155
|
{ logger, opts: options.options }
|
|
138
156
|
);
|
|
139
157
|
|
|
140
158
|
const fileEncSha256B64 = fileSha256.toString('base64');
|
|
141
|
-
|
|
142
|
-
const { mediaUrl, directPath } = await options.upload(bodyPath, {
|
|
143
|
-
fileEncSha256B64,
|
|
144
|
-
mediaType,
|
|
145
|
-
timeoutMs: options.mediaUploadTimeoutMs
|
|
159
|
+
|
|
160
|
+
const { mediaUrl, directPath } = await options.upload(bodyPath, {
|
|
161
|
+
fileEncSha256B64,
|
|
162
|
+
mediaType,
|
|
163
|
+
timeoutMs: options.mediaUploadTimeoutMs,
|
|
164
|
+
newsletter: true
|
|
146
165
|
});
|
|
147
166
|
|
|
148
167
|
if (didSaveToTmpPath && bodyPath) {
|
|
@@ -164,7 +183,7 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
164
183
|
})
|
|
165
184
|
});
|
|
166
185
|
|
|
167
|
-
if (
|
|
186
|
+
if (isPtv) {
|
|
168
187
|
obj.ptvMessage = obj.videoMessage;
|
|
169
188
|
delete obj.videoMessage;
|
|
170
189
|
}
|
|
@@ -187,18 +206,23 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
187
206
|
const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
|
|
188
207
|
const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
|
|
189
208
|
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
|
|
190
|
-
|
|
209
|
+
|
|
191
210
|
const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, } = await (0, messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
|
|
192
211
|
logger,
|
|
193
212
|
saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
|
|
194
213
|
opts: options.options
|
|
195
214
|
});
|
|
196
|
-
|
|
215
|
+
|
|
197
216
|
const fileEncSha256B64 = (fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256).toString('base64');
|
|
198
|
-
|
|
217
|
+
|
|
199
218
|
const [{ mediaUrl, directPath, handle }] = await Promise.all([
|
|
200
219
|
(async () => {
|
|
201
|
-
const result = await options.upload(encWriteStream, {
|
|
220
|
+
const result = await options.upload(encWriteStream, {
|
|
221
|
+
fileEncSha256B64,
|
|
222
|
+
mediaType,
|
|
223
|
+
timeoutMs: options.mediaUploadTimeoutMs,
|
|
224
|
+
newsletter: false
|
|
225
|
+
});
|
|
202
226
|
logger === null || logger === void 0 ? void 0 : logger.debug({ mediaType, cacheableKey }, 'uploaded media');
|
|
203
227
|
return result;
|
|
204
228
|
})(),
|
|
@@ -210,21 +234,16 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
210
234
|
if (!uploadData.width && originalImageDimensions) {
|
|
211
235
|
uploadData.width = originalImageDimensions.width;
|
|
212
236
|
uploadData.height = originalImageDimensions.height;
|
|
213
|
-
logger === null || logger === void 0 ? void 0 : logger.debug('set dimensions');
|
|
214
237
|
}
|
|
215
|
-
logger === null || logger === void 0 ? void 0 : logger.debug('generated thumbnail');
|
|
216
238
|
}
|
|
217
239
|
if (requiresDurationComputation) {
|
|
218
240
|
uploadData.seconds = await (0, messages_media_1.getAudioDuration)(bodyPath);
|
|
219
|
-
logger === null || logger === void 0 ? void 0 : logger.debug('computed audio duration');
|
|
220
241
|
}
|
|
221
242
|
if (requiresWaveformProcessing) {
|
|
222
243
|
uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(bodyPath, logger);
|
|
223
|
-
logger === null || logger === void 0 ? void 0 : logger.debug('processed waveform');
|
|
224
244
|
}
|
|
225
245
|
if (requiresAudioBackground) {
|
|
226
246
|
uploadData.backgroundArgb = await assertColor(options.backgroundColor);
|
|
227
|
-
logger === null || logger === void 0 ? void 0 : logger.debug('computed backgroundColor audio status');
|
|
228
247
|
}
|
|
229
248
|
}
|
|
230
249
|
catch (error) {
|
|
@@ -262,19 +281,19 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
262
281
|
})
|
|
263
282
|
});
|
|
264
283
|
|
|
265
|
-
|
|
266
|
-
if (uploadData.ptv) {
|
|
284
|
+
if (isPtv) {
|
|
267
285
|
obj.ptvMessage = obj.videoMessage;
|
|
268
286
|
delete obj.videoMessage;
|
|
269
287
|
}
|
|
270
288
|
|
|
271
289
|
if (cacheableKey) {
|
|
272
|
-
logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
|
|
273
290
|
options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
|
|
274
291
|
}
|
|
275
292
|
return obj;
|
|
276
293
|
};
|
|
277
294
|
exports.prepareWAMessageMedia = prepareWAMessageMedia;
|
|
295
|
+
|
|
296
|
+
|
|
278
297
|
const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
|
|
279
298
|
ephemeralExpiration = ephemeralExpiration || 0;
|
|
280
299
|
const content = {
|
|
@@ -458,12 +477,11 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
458
477
|
break;
|
|
459
478
|
}
|
|
460
479
|
}
|
|
461
|
-
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
ptv: true
|
|
480
|
+
else if ('ptv' in message && message.ptv) {
|
|
481
|
+
const generated = await (0, exports.prepareWAMessageMedia)({
|
|
482
|
+
ptv: message.ptv
|
|
465
483
|
}, options);
|
|
466
|
-
m.ptvMessage = ptvMessage;
|
|
484
|
+
m.ptvMessage = generated.ptvMessage || generated.videoMessage;
|
|
467
485
|
}
|
|
468
486
|
else if ('product' in message) {
|
|
469
487
|
const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
|
|
@@ -1286,4 +1304,4 @@ const prepareStickerPackMessage = async (stickerPack, options) => {
|
|
|
1286
1304
|
|
|
1287
1305
|
return { stickerPackMessage };
|
|
1288
1306
|
};
|
|
1289
|
-
exports.prepareStickerPackMessage = prepareStickerPackMessage;
|
|
1307
|
+
exports.prepareStickerPackMessage = prepareStickerPackMessage;
|
package/lib/index.js
CHANGED
|
@@ -55,6 +55,5 @@ __exportStar(require("./WABinary"), exports);
|
|
|
55
55
|
__exportStar(require("./WAM"), exports);
|
|
56
56
|
__exportStar(require("./WAUSync"), exports);
|
|
57
57
|
__exportStar(require("./Api"), exports);
|
|
58
|
-
__exportStar(require("./Auth"), exports);
|
|
59
58
|
|
|
60
59
|
exports.default = Socket_1.default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rexxhayanasi/elaina-baileys",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.0-rc.1",
|
|
4
4
|
"description": "Custom Baileys WhatsApp API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"baileys",
|
|
@@ -89,8 +89,7 @@
|
|
|
89
89
|
"jimp": "^0.22.10",
|
|
90
90
|
"link-preview-js": "^3.0.0",
|
|
91
91
|
"qrcode-terminal": "^0.12.0",
|
|
92
|
-
"sharp": "^0.34.1"
|
|
93
|
-
"better-sqlite3": "^12.5.0"
|
|
92
|
+
"sharp": "^0.34.1"
|
|
94
93
|
},
|
|
95
94
|
"peerDependenciesMeta": {
|
|
96
95
|
"jimp": {
|
package/lib/Auth/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.useSQLiteAuth = void 0;
|
|
7
|
-
const sqlite_1 = __importDefault(require("./sqlite"));
|
|
8
|
-
exports.useSQLiteAuth = sqlite_1.default;
|
package/lib/Auth/sqlite.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.useSQLiteAuth = void 0;
|
|
5
|
-
|
|
6
|
-
const BetterSqlite = require("better-sqlite3");
|
|
7
|
-
const { BufferJSON } = require("../index");
|
|
8
|
-
const { initAuthCreds } = require("../Utils");
|
|
9
|
-
|
|
10
|
-
const db = new BetterSqlite("./session.db");
|
|
11
|
-
|
|
12
|
-
db.exec(`
|
|
13
|
-
CREATE TABLE IF NOT EXISTS auth (
|
|
14
|
-
id TEXT PRIMARY KEY,
|
|
15
|
-
data TEXT
|
|
16
|
-
)
|
|
17
|
-
`);
|
|
18
|
-
|
|
19
|
-
const useSQLiteAuth = () => {
|
|
20
|
-
const readData = (id) => {
|
|
21
|
-
const row = db.prepare("SELECT data FROM auth WHERE id=?").get(id);
|
|
22
|
-
return row ? JSON.parse(row.data, BufferJSON.reviver) : null;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const writeData = (id, data) => {
|
|
26
|
-
db.prepare("INSERT OR REPLACE INTO auth VALUES (?, ?)")
|
|
27
|
-
.run(id, JSON.stringify(data, BufferJSON.replacer));
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const state = {
|
|
31
|
-
creds: readData("creds") || initAuthCreds(),
|
|
32
|
-
keys: {
|
|
33
|
-
get(type, ids) {
|
|
34
|
-
const data = {};
|
|
35
|
-
for (const id of ids) {
|
|
36
|
-
const value = readData(`${type}-${id}`);
|
|
37
|
-
if (value) data[id] = value;
|
|
38
|
-
}
|
|
39
|
-
return data;
|
|
40
|
-
},
|
|
41
|
-
set(data) {
|
|
42
|
-
for (const type in data) {
|
|
43
|
-
for (const id in data[type]) {
|
|
44
|
-
writeData(`${type}-${id}`, data[type][id]);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const saveCreds = () => writeData("creds", state.creds);
|
|
52
|
-
|
|
53
|
-
return { state, saveCreds };
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
exports.useSQLiteAuth = useSQLiteAuth;
|
|
57
|
-
exports.default = useSQLiteAuth;
|