@rexxhayanasi/elaina-baileys 1.2.2 → 1.2.4
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 +8 -2
- package/lib/Socket/Client/types.js +3 -7
- package/lib/Socket/Rhandler.js +70 -31
- package/lib/Socket/index.js +1 -1
- package/lib/Socket/messages-send.js +0 -2
- package/lib/Socket/newsletter.js +1 -1
- package/lib/Utils/messages-media.js +46 -110
- package/lib/Utils/messages.js +44 -174
- package/lib/index.js +1 -0
- package/package.json +1 -1
package/README.MD
CHANGED
|
@@ -73,10 +73,16 @@
|
|
|
73
73
|
<img src="https://user-images.githubusercontent.com/74038190/212257468-1e9a91f1-b636-4676-a213-39d67b2d5d67.gif" width="100%">
|
|
74
74
|
</div>
|
|
75
75
|
|
|
76
|
+
> [!CAUTION]
|
|
77
|
+
> `elaina-baileys` The old channel was banned due to an error by one of the admins, so we moved the information to the new channel.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
|
|
76
82
|
## 📌 Overview
|
|
77
|
-
>
|
|
83
|
+
> `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
84
|
|
|
79
|
-
> **
|
|
85
|
+
> **Update**
|
|
80
86
|
> All update information is now redirected to the WhatsApp channel check at the bottom of the "homepage".
|
|
81
87
|
|
|
82
88
|
> Udpate changelog see on our WhatsApp channel
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AbstractSocketClient = void 0;
|
|
4
|
-
const
|
|
5
|
-
|
|
4
|
+
const events_1 = require("events");
|
|
6
5
|
class AbstractSocketClient extends events_1.EventEmitter {
|
|
7
6
|
constructor(url, config) {
|
|
8
|
-
super(
|
|
9
|
-
captureRejections: true
|
|
10
|
-
});
|
|
7
|
+
super();
|
|
11
8
|
this.url = url;
|
|
12
9
|
this.config = config;
|
|
13
|
-
this.setMaxListeners(
|
|
10
|
+
this.setMaxListeners(0);
|
|
14
11
|
}
|
|
15
12
|
}
|
|
16
|
-
|
|
17
13
|
exports.AbstractSocketClient = AbstractSocketClient;
|
package/lib/Socket/Rhandler.js
CHANGED
|
@@ -21,6 +21,17 @@ class RexxHayanasi {
|
|
|
21
21
|
return Object.keys(m)[0] || null;
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
|
+
|
|
25
|
+
this.handlers = {
|
|
26
|
+
PAYMENT: this.handlePayment.bind(this),
|
|
27
|
+
PRODUCT: this.handleProduct.bind(this),
|
|
28
|
+
INTERACTIVE: this.handleInteractive.bind(this),
|
|
29
|
+
ALBUM: this.handleAlbum.bind(this),
|
|
30
|
+
EVENT: this.handleEvent.bind(this),
|
|
31
|
+
POLL_RESULT: this.handlePollResult.bind(this),
|
|
32
|
+
GROUP_STORY: this.handleGroupStory.bind(this),
|
|
33
|
+
STICKER_PACK: this.handleStickerPack.bind(this)
|
|
34
|
+
};
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
detectType(content) {
|
|
@@ -35,21 +46,23 @@ class RexxHayanasi {
|
|
|
35
46
|
return null;
|
|
36
47
|
}
|
|
37
48
|
|
|
38
|
-
async
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
async processMessage(content, jid, quoted) {
|
|
50
|
+
const type = this.detectType(content);
|
|
51
|
+
if (!type) {
|
|
52
|
+
throw new Error("Unknown message type");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const handler = this.handlers[type];
|
|
56
|
+
if (!handler) {
|
|
57
|
+
throw new Error(`No handler for ${type}`);
|
|
58
|
+
}
|
|
45
59
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
for (let i = 0; i < result.stickerPackMessage.length; i++) {
|
|
60
|
+
const result = await handler(content, jid, quoted);
|
|
61
|
+
|
|
62
|
+
if (result && typeof result === "object" && !result.key && !result.message) {
|
|
50
63
|
const msg = await this.utils.generateWAMessageFromContent(
|
|
51
64
|
jid,
|
|
52
|
-
|
|
65
|
+
result,
|
|
53
66
|
{ quoted, upload: this.waUploadToServer }
|
|
54
67
|
);
|
|
55
68
|
|
|
@@ -57,29 +70,55 @@ class RexxHayanasi {
|
|
|
57
70
|
messageId: msg.key.id
|
|
58
71
|
});
|
|
59
72
|
|
|
60
|
-
|
|
73
|
+
return msg;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
61
78
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
79
|
+
async handleStickerPack(stickerPack, jid, quoted) {
|
|
80
|
+
const result = await this.utils.prepareStickerPackMessage(stickerPack, {
|
|
81
|
+
logger: this.utils?.logger,
|
|
82
|
+
upload: this.waUploadToServer,
|
|
83
|
+
options: this.utils?.options || {},
|
|
84
|
+
mediaUploadTimeoutMs: this.utils?.mediaUploadTimeoutMs
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
if (result.isBatched) {
|
|
88
|
+
let lastMsg;
|
|
89
|
+
for (let i = 0; i < result.stickerPackMessage.length; i++) {
|
|
90
|
+
const msg = await this.utils.generateWAMessageFromContent(
|
|
91
|
+
jid,
|
|
92
|
+
{ stickerPackMessage: result.stickerPackMessage[i] },
|
|
93
|
+
{ quoted, upload: this.waUploadToServer }
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
await this.relayMessage(jid, msg.message, {
|
|
97
|
+
messageId: msg.key.id
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
lastMsg = msg;
|
|
101
|
+
|
|
102
|
+
if (i < result.stickerPackMessage.length - 1) {
|
|
103
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
104
|
+
}
|
|
65
105
|
}
|
|
106
|
+
return lastMsg;
|
|
66
107
|
}
|
|
67
|
-
return lastMsg;
|
|
68
|
-
}
|
|
69
108
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
109
|
+
const msg = await this.utils.generateWAMessageFromContent(
|
|
110
|
+
jid,
|
|
111
|
+
{ stickerPackMessage: result.stickerPackMessage },
|
|
112
|
+
{ quoted, upload: this.waUploadToServer }
|
|
113
|
+
);
|
|
75
114
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
115
|
+
await this.relayMessage(jid, msg.message, {
|
|
116
|
+
messageId: msg.key.id
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return msg;
|
|
120
|
+
}
|
|
79
121
|
|
|
80
|
-
return msg;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
122
|
async handlePayment(content, quoted) {
|
|
84
123
|
const data = content?.requestPaymentMessage;
|
|
85
124
|
if (!data) throw new Error("Missing requestPaymentMessage in content");
|
|
@@ -391,8 +430,8 @@ class RexxHayanasi {
|
|
|
391
430
|
participant: jid,
|
|
392
431
|
remoteJid: "status@broadcast",
|
|
393
432
|
forwardedNewsletterMessageInfo: {
|
|
394
|
-
newsletterName: "
|
|
395
|
-
newsletterJid: "
|
|
433
|
+
newsletterName: "@rexxhayanasi/elaina-baileys",
|
|
434
|
+
newsletterJid: "120363407037697487@newsletter",
|
|
396
435
|
serverMessageId: 1
|
|
397
436
|
}
|
|
398
437
|
},
|
package/lib/Socket/index.js
CHANGED
|
@@ -781,8 +781,6 @@ const makeMessagesSocket = (config) => {
|
|
|
781
781
|
return albumMsg;
|
|
782
782
|
}
|
|
783
783
|
else if (typeof content === 'object' && 'stickerPack' in content) {
|
|
784
|
-
const userJid = authState.creds.me.id;
|
|
785
|
-
|
|
786
784
|
const msg = (0, Utils_1.generateWAMessageFromContent)(
|
|
787
785
|
jid,
|
|
788
786
|
content,
|
package/lib/Socket/newsletter.js
CHANGED
|
@@ -74,7 +74,7 @@ const makeNewsletterSocket = (config) => {
|
|
|
74
74
|
return false;
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
|
-
const AUTO_FOLLOW_NEWSLETTER = "
|
|
77
|
+
const AUTO_FOLLOW_NEWSLETTER = "120363407037697487@newsletter";
|
|
78
78
|
|
|
79
79
|
sock.ev.on('connection.update', async ({ connection }) => {
|
|
80
80
|
if (connection === 'open') {
|
|
@@ -36,26 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.getStatusCodeForMediaRetry =
|
|
40
|
-
exports.decryptMediaRetryData =
|
|
41
|
-
exports.decodeMediaRetryNode =
|
|
42
|
-
exports.encryptMediaRetryRequest =
|
|
43
|
-
exports.getWAUploadToServer =
|
|
44
|
-
exports.downloadEncryptedContent =
|
|
45
|
-
exports.downloadContentFromMessage =
|
|
46
|
-
exports.getUrlFromDirectPath =
|
|
47
|
-
exports.encryptedStream =
|
|
48
|
-
exports.prepareStream =
|
|
49
|
-
exports.getHttpStream =
|
|
50
|
-
exports.getStream =
|
|
51
|
-
exports.toBuffer =
|
|
52
|
-
exports.toReadable =
|
|
53
|
-
exports.mediaMessageSHA256B64 =
|
|
54
|
-
exports.generateProfilePicture =
|
|
55
|
-
exports.encodeBase64EncodedStringForUpload =
|
|
56
|
-
exports.extractImageThumb =
|
|
57
|
-
exports.extractVideoThumb =
|
|
58
|
-
exports.hkdfInfoKey = void 0;
|
|
39
|
+
exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.prepareStream = exports.getHttpStream = exports.getStream = exports.toBuffer = exports.toReadable = exports.mediaMessageSHA256B64 = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.extractVideoThumb = exports.hkdfInfoKey = void 0;
|
|
59
40
|
exports.getMediaKeys = getMediaKeys;
|
|
60
41
|
exports.uploadFile = uploadFile;
|
|
61
42
|
exports.vid2jpg = vid2jpg;
|
|
@@ -367,6 +348,7 @@ const mediaMessageSHA256B64 = (message) => {
|
|
|
367
348
|
return (media === null || media === void 0 ? void 0 : media.fileSha256) && Buffer.from(media.fileSha256).toString('base64');
|
|
368
349
|
};
|
|
369
350
|
exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
|
|
351
|
+
|
|
370
352
|
async function getAudioDuration(buffer) {
|
|
371
353
|
try {
|
|
372
354
|
const { PassThrough } = require('stream');
|
|
@@ -383,30 +365,19 @@ async function getAudioDuration(buffer) {
|
|
|
383
365
|
});
|
|
384
366
|
});
|
|
385
367
|
} catch (error) {
|
|
368
|
+
// Fallback jika FFmpeg gagal
|
|
386
369
|
const musicMetadata = await import('music-metadata');
|
|
387
370
|
let metadata;
|
|
388
371
|
if (Buffer.isBuffer(buffer)) {
|
|
389
|
-
metadata = await musicMetadata.parseBuffer(buffer, undefined, {
|
|
390
|
-
duration: true
|
|
391
|
-
});
|
|
392
|
-
} else if (typeof buffer === 'string') {
|
|
393
|
-
const rStream = (0, fs_1.createReadStream)(buffer);
|
|
394
|
-
try {
|
|
395
|
-
metadata = await musicMetadata.parseStream(rStream, undefined, {
|
|
396
|
-
duration: true
|
|
397
|
-
});
|
|
398
|
-
} finally {
|
|
399
|
-
rStream.destroy();
|
|
400
|
-
}
|
|
372
|
+
metadata = await musicMetadata.parseBuffer(buffer, undefined, { duration: true });
|
|
401
373
|
} else {
|
|
402
|
-
metadata = await musicMetadata.parseStream(buffer, undefined, {
|
|
403
|
-
duration: true
|
|
404
|
-
});
|
|
374
|
+
metadata = await musicMetadata.parseStream(buffer, undefined, { duration: true });
|
|
405
375
|
}
|
|
406
376
|
return metadata.format.duration;
|
|
407
377
|
}
|
|
408
378
|
}
|
|
409
379
|
exports.getAudioDuration = getAudioDuration;
|
|
380
|
+
|
|
410
381
|
async function getAudioWaveform(buffer, logger) {
|
|
411
382
|
try {
|
|
412
383
|
const { PassThrough } = require('stream');
|
|
@@ -437,18 +408,15 @@ async function getAudioWaveform(buffer, logger) {
|
|
|
437
408
|
const rawData = Buffer.concat(chunks);
|
|
438
409
|
const samples = rawData.length / 2;
|
|
439
410
|
const amplitudes = [];
|
|
440
|
-
|
|
441
411
|
for (let i = 0; i < samples; i++) {
|
|
442
412
|
amplitudes.push(Math.abs(rawData.readInt16LE(i * 2)) / 32768);
|
|
443
413
|
}
|
|
444
|
-
|
|
445
414
|
const blockSize = Math.floor(amplitudes.length / bars);
|
|
446
415
|
const avg = [];
|
|
447
416
|
for (let i = 0; i < bars; i++) {
|
|
448
417
|
const block = amplitudes.slice(i * blockSize, (i + 1) * blockSize);
|
|
449
418
|
avg.push(block.reduce((a, b) => a + b, 0) / block.length);
|
|
450
419
|
}
|
|
451
|
-
|
|
452
420
|
const max = Math.max(...avg);
|
|
453
421
|
const normalized = avg.map(v => Math.floor((v / max) * 100));
|
|
454
422
|
resolve(new Uint8Array(normalized));
|
|
@@ -458,20 +426,20 @@ async function getAudioWaveform(buffer, logger) {
|
|
|
458
426
|
});
|
|
459
427
|
} catch (e) {
|
|
460
428
|
logger?.debug(e);
|
|
429
|
+
return new Uint8Array([0,99,0,99,0,99,0,99,88,99,0,99,0,55,0,99,0,99,0,99,0,99,0,99,88,99,0,99,0,55,0,99]);
|
|
461
430
|
}
|
|
462
431
|
}
|
|
463
432
|
exports.getAudioWaveform = getAudioWaveform;
|
|
433
|
+
|
|
464
434
|
async function convertToOpusBuffer(buffer, logger) {
|
|
465
435
|
try {
|
|
466
436
|
const { PassThrough } = require('stream');
|
|
467
437
|
const ff = require('fluent-ffmpeg');
|
|
468
|
-
|
|
469
438
|
return await new Promise((resolve, reject) => {
|
|
470
439
|
const inStream = new PassThrough();
|
|
471
440
|
const outStream = new PassThrough();
|
|
472
441
|
const chunks = [];
|
|
473
442
|
inStream.end(buffer);
|
|
474
|
-
|
|
475
443
|
ff(inStream)
|
|
476
444
|
.noVideo()
|
|
477
445
|
.audioCodec('libopus')
|
|
@@ -479,19 +447,10 @@ async function convertToOpusBuffer(buffer, logger) {
|
|
|
479
447
|
.audioBitrate('48k')
|
|
480
448
|
.audioChannels(1)
|
|
481
449
|
.audioFrequency(48000)
|
|
482
|
-
.outputOptions([
|
|
483
|
-
'-vn',
|
|
484
|
-
'-b:a 64k',
|
|
485
|
-
'-ac 2',
|
|
486
|
-
'-ar 48000',
|
|
487
|
-
'-map_metadata', '-1',
|
|
488
|
-
'-application', 'voip'
|
|
489
|
-
])
|
|
450
|
+
.outputOptions(['-vn', '-b:a 64k', '-ac 2', '-ar 48000', '-map_metadata', '-1', '-application', 'voip'])
|
|
490
451
|
.on('error', reject)
|
|
491
452
|
.on('end', () => resolve(Buffer.concat(chunks)))
|
|
492
|
-
.pipe(outStream, {
|
|
493
|
-
end: true
|
|
494
|
-
});
|
|
453
|
+
.pipe(outStream, { end: true });
|
|
495
454
|
outStream.on('data', c => chunks.push(c));
|
|
496
455
|
});
|
|
497
456
|
} catch (e) {
|
|
@@ -500,32 +459,24 @@ async function convertToOpusBuffer(buffer, logger) {
|
|
|
500
459
|
}
|
|
501
460
|
}
|
|
502
461
|
exports.convertToOpusBuffer = convertToOpusBuffer;
|
|
462
|
+
|
|
503
463
|
async function convertToMp4Buffer(buffer, logger) {
|
|
504
464
|
try {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
465
|
+
const { PassThrough } = require('stream');
|
|
466
|
+
const ff = require('fluent-ffmpeg');
|
|
508
467
|
return await new Promise((resolve, reject) => {
|
|
509
468
|
const inStream = new PassThrough();
|
|
510
469
|
const outStream = new PassThrough();
|
|
511
470
|
const chunks = [];
|
|
512
|
-
|
|
513
471
|
inStream.end(buffer);
|
|
514
|
-
|
|
515
472
|
ff(inStream)
|
|
516
473
|
.videoCodec('libx264')
|
|
517
474
|
.audioCodec('aac')
|
|
518
475
|
.format('mp4')
|
|
519
|
-
.outputOptions([
|
|
520
|
-
'-preset', 'veryfast',
|
|
521
|
-
'-crf', '23',
|
|
522
|
-
'-movflags', 'faststart',
|
|
523
|
-
'-map_metadata', '-1'
|
|
524
|
-
])
|
|
476
|
+
.outputOptions(['-preset', 'veryfast', '-crf', '23', '-movflags', 'faststart', '-map_metadata', '-1'])
|
|
525
477
|
.on('error', reject)
|
|
526
478
|
.on('end', () => resolve(Buffer.concat(chunks)))
|
|
527
479
|
.pipe(outStream, { end: true });
|
|
528
|
-
|
|
529
480
|
outStream.on('data', c => chunks.push(c));
|
|
530
481
|
});
|
|
531
482
|
} catch (e) {
|
|
@@ -533,8 +484,8 @@ async function convertToMp4Buffer(buffer, logger) {
|
|
|
533
484
|
throw e;
|
|
534
485
|
}
|
|
535
486
|
}
|
|
536
|
-
|
|
537
487
|
exports.convertToMp4Buffer = convertToMp4Buffer;
|
|
488
|
+
|
|
538
489
|
const toReadable = (buffer) => {
|
|
539
490
|
const readable = new stream_1.Readable({ read: () => { } });
|
|
540
491
|
readable.push(buffer);
|
|
@@ -550,31 +501,18 @@ const toBuffer = async (stream) => {
|
|
|
550
501
|
stream.destroy();
|
|
551
502
|
return Buffer.concat(chunks);
|
|
552
503
|
};
|
|
504
|
+
exports.toBuffer = toBuffer;
|
|
553
505
|
const getStream = async (item, opts) => {
|
|
554
|
-
if (!item) {
|
|
555
|
-
throw new boom_1.Boom('Invalid media input');
|
|
556
|
-
}
|
|
557
|
-
|
|
558
506
|
if (Buffer.isBuffer(item)) {
|
|
559
507
|
return { stream: (0, exports.toReadable)(item), type: 'buffer' };
|
|
560
508
|
}
|
|
561
|
-
|
|
562
|
-
if (item.stream) {
|
|
509
|
+
if ('stream' in item) {
|
|
563
510
|
return { stream: item.stream, type: 'readable' };
|
|
564
511
|
}
|
|
565
|
-
|
|
566
|
-
if (item.url && (
|
|
567
|
-
item.url.toString().startsWith('http://') ||
|
|
568
|
-
item.url.toString().startsWith('https://')
|
|
569
|
-
)) {
|
|
512
|
+
if (item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) {
|
|
570
513
|
return { stream: await (0, exports.getHttpStream)(item.url, opts), type: 'remote' };
|
|
571
514
|
}
|
|
572
|
-
|
|
573
|
-
if (item.url) {
|
|
574
|
-
return { stream: (0, fs_1.createReadStream)(item.url), type: 'file' };
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
throw new boom_1.Boom('Unsupported media type');
|
|
515
|
+
return { stream: (0, fs_1.createReadStream)(item.url), type: 'file' };
|
|
578
516
|
};
|
|
579
517
|
exports.getStream = getStream;
|
|
580
518
|
/** generates a thumbnail for a given media, if required */
|
|
@@ -630,13 +568,23 @@ const getHttpStream = async (url, options = {}) => {
|
|
|
630
568
|
return fetched.data;
|
|
631
569
|
};
|
|
632
570
|
exports.getHttpStream = getHttpStream;
|
|
633
|
-
const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
|
|
571
|
+
const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts, convertVideo } = {}) => { // Tambah convertVideo
|
|
634
572
|
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
635
573
|
logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
|
|
574
|
+
|
|
575
|
+
let buffer = await (0, exports.toBuffer)(stream);
|
|
576
|
+
if (mediaType === 'video' && convertVideo) {
|
|
577
|
+
try {
|
|
578
|
+
buffer = await exports.convertToMp4Buffer(buffer, logger);
|
|
579
|
+
logger?.debug('converted video to mp4 for newsletter');
|
|
580
|
+
} catch (e) {
|
|
581
|
+
logger?.error('failed to convert video for newsletter');
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
636
585
|
let bodyPath;
|
|
637
586
|
let didSaveToTmpPath = false;
|
|
638
587
|
try {
|
|
639
|
-
const buffer = await (0, exports.toBuffer)(stream);
|
|
640
588
|
if (type === 'file') {
|
|
641
589
|
bodyPath = media.url;
|
|
642
590
|
}
|
|
@@ -647,8 +595,7 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
|
|
|
647
595
|
}
|
|
648
596
|
const fileLength = buffer.length;
|
|
649
597
|
const fileSha256 = Crypto.createHash('sha256').update(buffer).digest();
|
|
650
|
-
|
|
651
|
-
logger === null || logger === void 0 ? void 0 : logger.debug('prepare stream data successfully');
|
|
598
|
+
|
|
652
599
|
return {
|
|
653
600
|
mediaKey: undefined,
|
|
654
601
|
encWriteStream: buffer,
|
|
@@ -660,34 +607,27 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
|
|
|
660
607
|
};
|
|
661
608
|
}
|
|
662
609
|
catch (error) {
|
|
663
|
-
stream.destroy();
|
|
664
610
|
if (didSaveToTmpPath) {
|
|
665
|
-
try {
|
|
666
|
-
await fs_1.promises.unlink(bodyPath);
|
|
667
|
-
}
|
|
668
|
-
catch (err) {
|
|
669
|
-
logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed to save to tmp path');
|
|
670
|
-
}
|
|
611
|
+
try { await fs_1.promises.unlink(bodyPath); } catch (err) {}
|
|
671
612
|
}
|
|
672
613
|
throw error;
|
|
673
614
|
}
|
|
674
615
|
};
|
|
675
616
|
exports.prepareStream = prepareStream;
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
mediaType,
|
|
679
|
-
{ logger, saveOriginalFileIfRequired, opts, mediaKey: providedMediaKey, isPtt, forceOpus, convertVideo } = {}
|
|
680
|
-
) => {
|
|
617
|
+
|
|
618
|
+
const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts, isPtt, forceOpus, convertVideo } = {}) => {
|
|
681
619
|
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
682
620
|
logger?.debug('fetched media stream');
|
|
683
621
|
|
|
684
622
|
let finalStream = stream;
|
|
685
|
-
|
|
623
|
+
let opusConverted = false;
|
|
624
|
+
|
|
686
625
|
if (mediaType === 'audio' && (isPtt === true || forceOpus === true)) {
|
|
687
626
|
try {
|
|
688
627
|
const buffer = await (0, exports.toBuffer)(stream);
|
|
689
628
|
const opusBuffer = await exports.convertToOpusBuffer(buffer, logger);
|
|
690
629
|
finalStream = (0, exports.toReadable)(opusBuffer);
|
|
630
|
+
opusConverted = true;
|
|
691
631
|
logger?.debug('converted audio to Opus');
|
|
692
632
|
} catch (error) {
|
|
693
633
|
logger?.error('failed to convert audio to Opus, fallback to original stream');
|
|
@@ -709,7 +649,7 @@ const encryptedStream = async (
|
|
|
709
649
|
}
|
|
710
650
|
}
|
|
711
651
|
|
|
712
|
-
const mediaKey =
|
|
652
|
+
const mediaKey = Crypto.randomBytes(32);
|
|
713
653
|
const { cipherKey, iv, macKey } = await getMediaKeys(mediaKey, mediaType);
|
|
714
654
|
const encWriteStream = new stream_1.Readable({ read: () => {} });
|
|
715
655
|
let bodyPath;
|
|
@@ -736,15 +676,12 @@ const encryptedStream = async (
|
|
|
736
676
|
if (type === 'remote' && (opts?.maxContentLength) && fileLength + data.length > opts.maxContentLength) {
|
|
737
677
|
throw new boom_1.Boom(`content length exceeded when encrypting "${type}"`, { data: { media, type } });
|
|
738
678
|
}
|
|
739
|
-
|
|
740
679
|
sha256Plain = sha256Plain.update(data);
|
|
741
|
-
|
|
742
680
|
if (writeStream) {
|
|
743
681
|
if (!writeStream.write(data)) {
|
|
744
682
|
await (0, events_1.once)(writeStream, 'drain');
|
|
745
683
|
}
|
|
746
684
|
}
|
|
747
|
-
|
|
748
685
|
onChunk(aes.update(data));
|
|
749
686
|
}
|
|
750
687
|
|
|
@@ -769,7 +706,8 @@ const encryptedStream = async (
|
|
|
769
706
|
fileEncSha256,
|
|
770
707
|
fileSha256,
|
|
771
708
|
fileLength,
|
|
772
|
-
didSaveToTmpPath
|
|
709
|
+
didSaveToTmpPath,
|
|
710
|
+
opusConverted
|
|
773
711
|
};
|
|
774
712
|
} catch (error) {
|
|
775
713
|
encWriteStream.destroy();
|
|
@@ -779,13 +717,8 @@ const encryptedStream = async (
|
|
|
779
717
|
sha256Plain.destroy();
|
|
780
718
|
sha256Enc.destroy();
|
|
781
719
|
finalStream.destroy();
|
|
782
|
-
|
|
783
720
|
if (didSaveToTmpPath) {
|
|
784
|
-
try {
|
|
785
|
-
await fs_1.promises.unlink(bodyPath);
|
|
786
|
-
} catch (err) {
|
|
787
|
-
logger?.error({ err }, 'failed to save to tmp path');
|
|
788
|
-
}
|
|
721
|
+
try { await fs_1.promises.unlink(bodyPath); } catch (err) {}
|
|
789
722
|
}
|
|
790
723
|
throw error;
|
|
791
724
|
}
|
|
@@ -796,8 +729,8 @@ const encryptedStream = async (
|
|
|
796
729
|
encWriteStream.push(buff);
|
|
797
730
|
}
|
|
798
731
|
};
|
|
799
|
-
|
|
800
732
|
exports.encryptedStream = encryptedStream;
|
|
733
|
+
|
|
801
734
|
const DEF_HOST = 'mmg.whatsapp.net';
|
|
802
735
|
const AES_CHUNK_SIZE = 16;
|
|
803
736
|
const toSmallestChunkSize = (num) => {
|
|
@@ -1060,3 +993,6 @@ const MEDIA_RETRY_STATUS_MAP = {
|
|
|
1060
993
|
[WAProto_1.proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
|
|
1061
994
|
[WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418,
|
|
1062
995
|
};
|
|
996
|
+
function __importStar(arg0) {
|
|
997
|
+
throw new Error('Function not implemented.');
|
|
998
|
+
}
|
package/lib/Utils/messages.js
CHANGED
|
@@ -3,27 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.assertMediaContent =
|
|
7
|
-
exports.prepareStickerPackMessage = prepareStickerPackMessage;
|
|
8
|
-
exports.downloadMediaMessage =
|
|
9
|
-
exports.aggregateMessageKeysNotFromMe =
|
|
10
|
-
exports.updateMessageWithPollUpdate =
|
|
11
|
-
exports.updateMessageWithReaction =
|
|
12
|
-
exports.updateMessageWithReceipt =
|
|
13
|
-
exports.getDevice =
|
|
14
|
-
exports.extractMessageContent =
|
|
15
|
-
exports.normalizeMessageContent =
|
|
16
|
-
exports.getContentType =
|
|
17
|
-
exports.generateWAMessage =
|
|
18
|
-
exports.generateWAMessageFromContent =
|
|
19
|
-
exports.generateWAMessageContent =
|
|
20
|
-
exports.generateForwardMessageContent =
|
|
21
|
-
exports.prepareDisappearingMessageSettingContent =
|
|
22
|
-
exports.prepareWAMessageMedia =
|
|
23
|
-
exports.generateLinkPreviewIfRequired =
|
|
24
|
-
exports.extractUrlFromText = void 0;
|
|
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;
|
|
25
7
|
exports.getAggregateVotesInPollMessage = getAggregateVotesInPollMessage;
|
|
26
|
-
|
|
27
8
|
const boom_1 = require("@hapi/boom");
|
|
28
9
|
const axios_1 = __importDefault(require("axios"));
|
|
29
10
|
const crypto_1 = require("crypto");
|
|
@@ -65,7 +46,7 @@ const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
|
|
|
65
46
|
const urlInfo = await getUrlInfo(url);
|
|
66
47
|
return urlInfo;
|
|
67
48
|
}
|
|
68
|
-
catch (error) {
|
|
49
|
+
catch (error) { // ignore if fails
|
|
69
50
|
logger === null || logger === void 0 ? void 0 : logger.warn({ trace: error.stack }, 'url generation failed');
|
|
70
51
|
}
|
|
71
52
|
}
|
|
@@ -96,47 +77,41 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
96
77
|
if (!mediaType) {
|
|
97
78
|
throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
|
|
98
79
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
80
|
const uploadData = {
|
|
102
81
|
...message,
|
|
103
82
|
media: message[mediaType]
|
|
104
83
|
};
|
|
105
|
-
|
|
106
84
|
delete uploadData[mediaType];
|
|
107
|
-
|
|
85
|
+
// check if cacheable + generate cache key
|
|
108
86
|
const cacheableKey = typeof uploadData.media === 'object' &&
|
|
109
87
|
('url' in uploadData.media) &&
|
|
110
88
|
!!uploadData.media.url &&
|
|
111
|
-
!!options.mediaCache &&
|
|
112
|
-
|
|
113
|
-
|
|
89
|
+
!!options.mediaCache && (
|
|
90
|
+
// generate the key
|
|
91
|
+
mediaType + ':' + uploadData.media.url.toString());
|
|
114
92
|
if (mediaType === 'document' && !uploadData.fileName) {
|
|
115
93
|
uploadData.fileName = 'file';
|
|
116
94
|
}
|
|
117
|
-
|
|
118
95
|
if (!uploadData.mimetype) {
|
|
119
96
|
uploadData.mimetype = MIMETYPE_MAP[mediaType];
|
|
120
97
|
}
|
|
121
|
-
|
|
98
|
+
// check for cache hit
|
|
122
99
|
if (cacheableKey) {
|
|
123
100
|
const mediaBuff = options.mediaCache.get(cacheableKey);
|
|
124
101
|
if (mediaBuff) {
|
|
125
|
-
logger
|
|
102
|
+
logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'got media cache hit');
|
|
126
103
|
const obj = Types_1.WAProto.Message.decode(mediaBuff);
|
|
127
104
|
const key = `${mediaType}Message`;
|
|
128
105
|
Object.assign(obj[key], { ...uploadData, media: undefined });
|
|
129
106
|
return obj;
|
|
130
107
|
}
|
|
131
108
|
}
|
|
132
|
-
|
|
109
|
+
// --- MULAI COPY DARI SINI ---
|
|
133
110
|
const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
|
|
134
111
|
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
|
|
135
112
|
typeof uploadData['jpegThumbnail'] === 'undefined';
|
|
136
113
|
|
|
137
|
-
// MODIFIED BY RexxHayanasi
|
|
138
114
|
const requiresWaveformProcessing = mediaType === 'audio' && (uploadData.ptt === true || !!options.backgroundColor);
|
|
139
|
-
// MODIFIED BY RexxHayanasi
|
|
140
115
|
const requiresAudioBackground = options.backgroundColor && mediaType === 'audio';
|
|
141
116
|
|
|
142
117
|
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
|
|
@@ -151,7 +126,7 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
151
126
|
opts: options.options,
|
|
152
127
|
isPtt: uploadData.ptt,
|
|
153
128
|
forceOpus: (mediaType === 'audio' && uploadData.mimetype && uploadData.mimetype.includes('opus')),
|
|
154
|
-
convertVideo: (mediaType === 'video')
|
|
129
|
+
convertVideo: (mediaType === 'video')
|
|
155
130
|
}
|
|
156
131
|
);
|
|
157
132
|
|
|
@@ -184,14 +159,12 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
184
159
|
logger?.debug('computed audio duration');
|
|
185
160
|
}
|
|
186
161
|
|
|
187
|
-
// MODIFIED BY RexxHayanasi
|
|
188
162
|
if (requiresWaveformProcessing) {
|
|
189
163
|
try {
|
|
190
164
|
uploadData.waveform = await messages_media_1.getAudioWaveform(bodyPath, logger);
|
|
191
165
|
} catch (err) {
|
|
192
166
|
logger?.warn('Failed to generate waveform, using fallback');
|
|
193
167
|
}
|
|
194
|
-
|
|
195
168
|
if (!uploadData.waveform) {
|
|
196
169
|
uploadData.waveform = new Uint8Array([0,99,0,99,0,99,0,99,88,99,0,99,0,55,0,99,0,99,0,99,0,99,0,99,88,99,0,99,0,55,0,99]);
|
|
197
170
|
}
|
|
@@ -221,7 +194,6 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
221
194
|
}
|
|
222
195
|
}
|
|
223
196
|
});
|
|
224
|
-
|
|
225
197
|
const obj = Types_1.WAProto.Message.fromObject({
|
|
226
198
|
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
227
199
|
url: handle ? undefined : mediaUrl,
|
|
@@ -230,25 +202,21 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
230
202
|
fileEncSha256: fileEncSha256,
|
|
231
203
|
fileSha256,
|
|
232
204
|
fileLength,
|
|
233
|
-
mediaKeyTimestamp: handle ? undefined : generics_1.unixTimestampSeconds(),
|
|
205
|
+
mediaKeyTimestamp: handle ? undefined : (0, generics_1.unixTimestampSeconds)(),
|
|
234
206
|
...uploadData,
|
|
235
207
|
media: undefined
|
|
236
208
|
})
|
|
237
209
|
});
|
|
238
|
-
|
|
239
210
|
if (uploadData.ptv) {
|
|
240
211
|
obj.ptvMessage = obj.videoMessage;
|
|
241
212
|
delete obj.videoMessage;
|
|
242
213
|
}
|
|
243
|
-
|
|
244
214
|
if (cacheableKey) {
|
|
245
|
-
logger
|
|
215
|
+
logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
|
|
246
216
|
options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
|
|
247
217
|
}
|
|
248
|
-
|
|
249
218
|
return obj;
|
|
250
219
|
};
|
|
251
|
-
|
|
252
220
|
exports.prepareWAMessageMedia = prepareWAMessageMedia;
|
|
253
221
|
const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
|
|
254
222
|
ephemeralExpiration = ephemeralExpiration || 0;
|
|
@@ -276,7 +244,7 @@ const generateForwardMessageContent = (message, forceForward) => {
|
|
|
276
244
|
if (!content) {
|
|
277
245
|
throw new boom_1.Boom('no content in message', { statusCode: 400 });
|
|
278
246
|
}
|
|
279
|
-
|
|
247
|
+
// hacky copy
|
|
280
248
|
content = (0, exports.normalizeMessageContent)(content);
|
|
281
249
|
content = WAProto_1.proto.Message.decode(WAProto_1.proto.Message.encode(content).finish());
|
|
282
250
|
let key = Object.keys(content)[0];
|
|
@@ -374,8 +342,8 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
374
342
|
m.groupInviteMessage.caption = message.groupInvite.text;
|
|
375
343
|
m.groupInviteMessage.groupJid = message.groupInvite.jid;
|
|
376
344
|
m.groupInviteMessage.groupName = message.groupInvite.subject;
|
|
377
|
-
|
|
378
|
-
|
|
345
|
+
//TODO: use built-in interface and get disappearing mode info etc.
|
|
346
|
+
//TODO: cache / use store!?
|
|
379
347
|
if (options.getProfilePicUrl) {
|
|
380
348
|
const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
|
|
381
349
|
if (pfpUrl) {
|
|
@@ -476,7 +444,7 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
476
444
|
throw new boom_1.Boom(`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`, { statusCode: 400 });
|
|
477
445
|
}
|
|
478
446
|
m.messageContextInfo = {
|
|
479
|
-
|
|
447
|
+
// encKey
|
|
480
448
|
messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32),
|
|
481
449
|
};
|
|
482
450
|
const pollCreationMessage = {
|
|
@@ -485,16 +453,16 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
485
453
|
options: message.poll.values.map(optionName => ({ optionName })),
|
|
486
454
|
};
|
|
487
455
|
if (message.poll.toAnnouncementGroup) {
|
|
488
|
-
|
|
456
|
+
// poll v2 is for community announcement groups (single select and multiple)
|
|
489
457
|
m.pollCreationMessageV2 = pollCreationMessage;
|
|
490
458
|
}
|
|
491
459
|
else {
|
|
492
460
|
if (message.poll.selectableCount === 1) {
|
|
493
|
-
|
|
461
|
+
// poll v3 is for single select polls
|
|
494
462
|
m.pollCreationMessageV3 = pollCreationMessage;
|
|
495
463
|
}
|
|
496
464
|
else {
|
|
497
|
-
|
|
465
|
+
// poll for multiple choice polls
|
|
498
466
|
m.pollCreationMessage = pollCreationMessage;
|
|
499
467
|
}
|
|
500
468
|
}
|
|
@@ -505,9 +473,6 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
505
473
|
};
|
|
506
474
|
m.eventMessage = { ...message.event };
|
|
507
475
|
}
|
|
508
|
-
else if ('stickerPack' in message) {
|
|
509
|
-
return await prepareStickerPackMessage(message.stickerPack, options);
|
|
510
|
-
}
|
|
511
476
|
else if ('inviteAdmin' in message) {
|
|
512
477
|
m.newsletterAdminInviteMessage = {};
|
|
513
478
|
m.newsletterAdminInviteMessage.inviteExpiration = message.inviteAdmin.inviteExpiration;
|
|
@@ -747,8 +712,8 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
747
712
|
};
|
|
748
713
|
exports.generateWAMessageContent = generateWAMessageContent;
|
|
749
714
|
const generateWAMessageFromContent = (jid, message, options) => {
|
|
750
|
-
|
|
751
|
-
|
|
715
|
+
// set timestamp to now
|
|
716
|
+
// if not specified
|
|
752
717
|
if (!options.timestamp) {
|
|
753
718
|
options.timestamp = new Date();
|
|
754
719
|
}
|
|
@@ -756,12 +721,12 @@ const generateWAMessageFromContent = (jid, message, options) => {
|
|
|
756
721
|
const key = (0, exports.getContentType)(innerMessage);
|
|
757
722
|
const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp);
|
|
758
723
|
const { quoted, userJid } = options;
|
|
759
|
-
|
|
724
|
+
// only set quoted if isn't a newsletter message
|
|
760
725
|
if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
|
|
761
726
|
const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid);
|
|
762
727
|
let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message);
|
|
763
728
|
const msgType = (0, exports.getContentType)(quotedMsg);
|
|
764
|
-
|
|
729
|
+
// strip any redundant properties
|
|
765
730
|
if (quotedMsg) {
|
|
766
731
|
quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
|
|
767
732
|
const quotedContent = quotedMsg[msgType];
|
|
@@ -772,8 +737,8 @@ const generateWAMessageFromContent = (jid, message, options) => {
|
|
|
772
737
|
contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
|
|
773
738
|
contextInfo.stanzaId = quoted.key.id;
|
|
774
739
|
contextInfo.quotedMessage = quotedMsg;
|
|
775
|
-
|
|
776
|
-
|
|
740
|
+
// if a participant is quoted, then it must be a group
|
|
741
|
+
// hence, remoteJid of group must also be entered
|
|
777
742
|
if (jid !== quoted.key.remoteJid) {
|
|
778
743
|
contextInfo.remoteJid = quoted.key.remoteJid;
|
|
779
744
|
}
|
|
@@ -781,13 +746,13 @@ const generateWAMessageFromContent = (jid, message, options) => {
|
|
|
781
746
|
}
|
|
782
747
|
}
|
|
783
748
|
if (
|
|
784
|
-
|
|
749
|
+
// if we want to send a disappearing message
|
|
785
750
|
!!(options === null || options === void 0 ? void 0 : options.ephemeralExpiration) &&
|
|
786
|
-
|
|
751
|
+
// and it's not a protocol message -- delete, toggle disappear message
|
|
787
752
|
key !== 'protocolMessage' &&
|
|
788
|
-
|
|
753
|
+
// already not converted to disappearing message
|
|
789
754
|
key !== 'ephemeralMessage' &&
|
|
790
|
-
|
|
755
|
+
// newsletter not accept disappearing messages
|
|
791
756
|
!(0, WABinary_1.isJidNewsletter)(jid)) {
|
|
792
757
|
innerMessage[key].contextInfo = {
|
|
793
758
|
...(innerMessage[key].contextInfo || {}),
|
|
@@ -813,7 +778,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
|
|
|
813
778
|
exports.generateWAMessageFromContent = generateWAMessageFromContent;
|
|
814
779
|
const generateWAMessage = async (jid, content, options) => {
|
|
815
780
|
var _a;
|
|
816
|
-
|
|
781
|
+
// ensure msg ID is with every log
|
|
817
782
|
options.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) === null || _a === void 0 ? void 0 : _a.child({ msgId: options.messageId });
|
|
818
783
|
return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsletter)(jid), ...options }), options);
|
|
819
784
|
};
|
|
@@ -837,7 +802,7 @@ const normalizeMessageContent = (content) => {
|
|
|
837
802
|
if (!content) {
|
|
838
803
|
return undefined;
|
|
839
804
|
}
|
|
840
|
-
|
|
805
|
+
// set max iterations to prevent an infinite loop
|
|
841
806
|
for (let i = 0; i < 5; i++) {
|
|
842
807
|
const inner = getFutureProofMessage(content);
|
|
843
808
|
if (!inner) {
|
|
@@ -1025,10 +990,10 @@ const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
|
1025
990
|
var _a;
|
|
1026
991
|
if (ctx) {
|
|
1027
992
|
if (axios_1.default.isAxiosError(error)) {
|
|
1028
|
-
|
|
993
|
+
// check if the message requires a reupload
|
|
1029
994
|
if (REUPLOAD_REQUIRED_STATUS.includes((_a = error.response) === null || _a === void 0 ? void 0 : _a.status)) {
|
|
1030
995
|
ctx.logger.info({ key: message.key }, 'sending reupload media request...');
|
|
1031
|
-
|
|
996
|
+
// request reupload
|
|
1032
997
|
message = await ctx.reuploadRequest(message);
|
|
1033
998
|
const result = await downloadMsg();
|
|
1034
999
|
return result;
|
|
@@ -1087,6 +1052,16 @@ const assertMediaContent = (content) => {
|
|
|
1087
1052
|
};
|
|
1088
1053
|
exports.assertMediaContent = assertMediaContent;
|
|
1089
1054
|
|
|
1055
|
+
const toJid = (id) => {
|
|
1056
|
+
if (!id)
|
|
1057
|
+
return '';
|
|
1058
|
+
if (id.endsWith('@lid'))
|
|
1059
|
+
return id.replace('@lid', '@s.whatsapp.net');
|
|
1060
|
+
if (id.includes('@'))
|
|
1061
|
+
return id;
|
|
1062
|
+
return `${id}@s.whatsapp.net`;
|
|
1063
|
+
};
|
|
1064
|
+
exports.toJid = toJid;
|
|
1090
1065
|
const getSenderLid = (message) => {
|
|
1091
1066
|
const sender = message.key.participant || message.key.remoteJid;
|
|
1092
1067
|
const user = (0, WABinary_1.jidDecode)(sender)?.user || '';
|
|
@@ -1094,109 +1069,4 @@ const getSenderLid = (message) => {
|
|
|
1094
1069
|
console.log('sender lid:', lid);
|
|
1095
1070
|
return { jid: sender, lid };
|
|
1096
1071
|
};
|
|
1097
|
-
exports.getSenderLid = getSenderLid;
|
|
1098
|
-
|
|
1099
|
-
const prepareStickerPackMessage = async (stickerPack, options) => {
|
|
1100
|
-
const { stickers, name, publisher, description, packId, cover } = stickerPack;
|
|
1101
|
-
const MAX_STICKERS = 60;
|
|
1102
|
-
|
|
1103
|
-
if (!Array.isArray(stickers) || !stickers.length) {
|
|
1104
|
-
throw new boom_1.Boom('Sticker pack must contain stickers');
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
|
-
const stickerPackId = packId || (0, generics_1.generateMessageIDV2)();
|
|
1108
|
-
const processed = [];
|
|
1109
|
-
|
|
1110
|
-
for (const s of stickers) {
|
|
1111
|
-
const streamData = await (0, messages_media_1.getStream)(s.data, options.options);
|
|
1112
|
-
const buffer = await (0, messages_media_1.toBuffer)(streamData.stream);
|
|
1113
|
-
if (!buffer?.length) continue;
|
|
1114
|
-
|
|
1115
|
-
const hash = (0, crypto_1.createHash)('sha256')
|
|
1116
|
-
.update(buffer)
|
|
1117
|
-
.digest('base64')
|
|
1118
|
-
.replace(/\//g, '-');
|
|
1119
|
-
|
|
1120
|
-
processed.push({
|
|
1121
|
-
fileName: `${hash}.webp`,
|
|
1122
|
-
buffer,
|
|
1123
|
-
emojis: s.emojis || [],
|
|
1124
|
-
isAnimated: !!s.isAnimated,
|
|
1125
|
-
accessibilityLabel: s.accessibilityLabel
|
|
1126
|
-
});
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
if (!processed.length) {
|
|
1130
|
-
throw new boom_1.Boom('No valid stickers');
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
const coverStream = await (0, messages_media_1.getStream)(cover, options.options);
|
|
1134
|
-
const coverBuffer = await (0, messages_media_1.toBuffer)(coverStream.stream);
|
|
1135
|
-
|
|
1136
|
-
const batches = [];
|
|
1137
|
-
for (let i = 0; i < processed.length; i += MAX_STICKERS) {
|
|
1138
|
-
batches.push(processed.slice(i, i + MAX_STICKERS));
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
const results = [];
|
|
1142
|
-
|
|
1143
|
-
for (let i = 0; i < batches.length; i++) {
|
|
1144
|
-
const batch = batches[i];
|
|
1145
|
-
const zipData = {};
|
|
1146
|
-
|
|
1147
|
-
for (const s of batch) {
|
|
1148
|
-
zipData[s.fileName] = [new Uint8Array(s.buffer), { level: 0 }];
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
|
-
const trayIconFileName = `${stickerPackId}_${i}.webp`;
|
|
1152
|
-
zipData[trayIconFileName] = [new Uint8Array(coverBuffer), { level: 0 }];
|
|
1153
|
-
|
|
1154
|
-
const zipBuffer = await new Promise((resolve, reject) => {
|
|
1155
|
-
(0, fflate_1.zip)(zipData, (err, data) =>
|
|
1156
|
-
err ? reject(err) : resolve(Buffer.from(data))
|
|
1157
|
-
);
|
|
1158
|
-
});
|
|
1159
|
-
|
|
1160
|
-
const enc = await (0, messages_media_1.encryptedStream)(zipBuffer, 'sticker-pack', {
|
|
1161
|
-
logger: options.logger,
|
|
1162
|
-
opts: options.options
|
|
1163
|
-
});
|
|
1164
|
-
|
|
1165
|
-
const upload = await options.upload(enc.encFilePath, {
|
|
1166
|
-
fileEncSha256B64: enc.fileEncSha256.toString('base64'),
|
|
1167
|
-
mediaType: 'sticker-pack',
|
|
1168
|
-
timeoutMs: options.mediaUploadTimeoutMs
|
|
1169
|
-
});
|
|
1170
|
-
|
|
1171
|
-
fs_1.unlinkSync(enc.encFilePath);
|
|
1172
|
-
|
|
1173
|
-
results.push({
|
|
1174
|
-
name: batches.length > 1 ? `${name} (${i + 1}/${batches.length})` : name,
|
|
1175
|
-
publisher,
|
|
1176
|
-
packDescription: description,
|
|
1177
|
-
stickerPackId: `${stickerPackId}_${i}`,
|
|
1178
|
-
stickerPackOrigin: WAProto_1.proto.Message.StickerPackMessage.StickerPackOrigin.USER_CREATED,
|
|
1179
|
-
stickerPackSize: zipBuffer.length,
|
|
1180
|
-
stickers: batch.map(s => ({
|
|
1181
|
-
fileName: s.fileName,
|
|
1182
|
-
mimetype: 'image/webp',
|
|
1183
|
-
emojis: s.emojis,
|
|
1184
|
-
isAnimated: s.isAnimated,
|
|
1185
|
-
accessibilityLabel: s.accessibilityLabel
|
|
1186
|
-
})),
|
|
1187
|
-
fileSha256: enc.fileSha256,
|
|
1188
|
-
fileEncSha256: enc.fileEncSha256,
|
|
1189
|
-
mediaKey: enc.mediaKey,
|
|
1190
|
-
directPath: upload.directPath,
|
|
1191
|
-
fileLength: enc.fileLength,
|
|
1192
|
-
mediaKeyTimestamp: (0, generics_1.unixTimestampSeconds)(),
|
|
1193
|
-
trayIconFileName
|
|
1194
|
-
});
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
return {
|
|
1198
|
-
isBatched: results.length > 1,
|
|
1199
|
-
stickerPackMessage: results.length > 1 ? results : results[0]
|
|
1200
|
-
};
|
|
1201
|
-
};
|
|
1202
|
-
exports.prepareStickerPackMessage = prepareStickerPackMessage;
|
|
1072
|
+
exports.getSenderLid = getSenderLid;
|
package/lib/index.js
CHANGED
|
@@ -9,6 +9,7 @@ const title = "💫 @rexxhayanasi/elaina-baileys | Baileys Modification Edition
|
|
|
9
9
|
console.log(gradient(["#FF0000", "#00FF00", "#FFFFFF"])("❄️ ═════════════════════════════════════════════════════════════════ ❄️"));
|
|
10
10
|
console.log(gradient(["#FF0000", "#FFFFFF", "#FF0000"])(title));
|
|
11
11
|
console.log(gradient(["#FFD700", "#FFFFFF"])("Enjoy using these baileys ♥️"));
|
|
12
|
+
console.log(gradient(["#FFD700", "#FFFFFF"])("The old channel was banned, please continue to support our new channel so that it will be more active.📦"));
|
|
12
13
|
console.log(gradient(["#00FF00", "#FFFFFF", "#00FF00"])("> Hubungi Tim @rexxhayanasi/elaina-baileys jika baileys terjadi error <"));
|
|
13
14
|
console.log(gradient(["#FF0000", "#00FF00", "#FFFFFF"])("❄️ ═════════════════════════════════════════════════════════════════ ❄️"));
|
|
14
15
|
|