@rexxhayanasi/elaina-baileys 1.2.0 → 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/lib/Utils/index.js +0 -1
- package/lib/Utils/messages-media.js +48 -4
- package/lib/Utils/messages.js +77 -8
- package/package.json +1 -1
- package/lib/Utils/newslettermedia.js +0 -110
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);
|
|
@@ -76,7 +76,7 @@ const getImageProcessingLibrary = async () => {
|
|
|
76
76
|
if (sharp) {
|
|
77
77
|
return { sharp };
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
const jimp = (_jimp === null || _jimp === void 0 ? void 0 : _jimp.default) || _jimp;
|
|
80
80
|
if (jimp) {
|
|
81
81
|
return { jimp };
|
|
82
82
|
}
|
|
@@ -87,6 +87,53 @@ const hkdfInfoKey = (type) => {
|
|
|
87
87
|
return `WhatsApp ${hkdfInfo} Keys`;
|
|
88
88
|
};
|
|
89
89
|
exports.hkdfInfoKey = hkdfInfoKey;
|
|
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;
|
|
90
137
|
/** generates all the keys required to encrypt/decrypt & sign a media message */
|
|
91
138
|
async function getMediaKeys(buffer, mediaType) {
|
|
92
139
|
if (!buffer) {
|
|
@@ -874,6 +921,3 @@ const MEDIA_RETRY_STATUS_MAP = {
|
|
|
874
921
|
[WAProto_1.proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
|
|
875
922
|
[WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418,
|
|
876
923
|
};
|
|
877
|
-
function __importStar(arg0) {
|
|
878
|
-
throw new Error('Function not implemented.');
|
|
879
|
-
}
|
package/lib/Utils/messages.js
CHANGED
|
@@ -82,20 +82,20 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
82
82
|
media: message[mediaType]
|
|
83
83
|
};
|
|
84
84
|
delete uploadData[mediaType];
|
|
85
|
-
|
|
85
|
+
|
|
86
|
+
// Check cache
|
|
86
87
|
const cacheableKey = typeof uploadData.media === 'object' &&
|
|
87
88
|
('url' in uploadData.media) &&
|
|
88
89
|
!!uploadData.media.url &&
|
|
89
|
-
!!options.mediaCache && (
|
|
90
|
-
|
|
91
|
-
mediaType + ':' + uploadData.media.url.toString());
|
|
90
|
+
!!options.mediaCache && (mediaType + ':' + uploadData.media.url.toString());
|
|
91
|
+
|
|
92
92
|
if (mediaType === 'document' && !uploadData.fileName) {
|
|
93
93
|
uploadData.fileName = 'file';
|
|
94
94
|
}
|
|
95
95
|
if (!uploadData.mimetype) {
|
|
96
96
|
uploadData.mimetype = MIMETYPE_MAP[mediaType];
|
|
97
97
|
}
|
|
98
|
-
|
|
98
|
+
|
|
99
99
|
if (cacheableKey) {
|
|
100
100
|
const mediaBuff = options.mediaCache.get(cacheableKey);
|
|
101
101
|
if (mediaBuff) {
|
|
@@ -106,19 +106,85 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
106
106
|
return obj;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
// --- [MULAI] LOGIKA KHUSUS NEWSLETTER (WHISKEYSOCKETS ADAPTATION) ---
|
|
111
|
+
const isNewsletter = !!options.jid && (0, WABinary_1.isJidNewsletter)(options.jid);
|
|
112
|
+
|
|
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)(
|
|
118
|
+
uploadData.media,
|
|
119
|
+
options.mediaTypeOverride || mediaType,
|
|
120
|
+
logger
|
|
121
|
+
);
|
|
122
|
+
|
|
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
|
+
|
|
129
|
+
const { mediaUrl, directPath } = await options.upload(streamToUpload, {
|
|
130
|
+
fileEncSha256B64: fileSha256B64,
|
|
131
|
+
mediaType: mediaType,
|
|
132
|
+
timeoutMs: options.mediaUploadTimeoutMs
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Hapus file temp setelah upload selesai
|
|
136
|
+
await fs_1.promises.unlink(filePath);
|
|
137
|
+
|
|
138
|
+
// 3. Buat Objek Pesan
|
|
139
|
+
const obj = Types_1.WAProto.Message.fromObject({
|
|
140
|
+
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
141
|
+
url: mediaUrl,
|
|
142
|
+
directPath,
|
|
143
|
+
fileSha256,
|
|
144
|
+
fileLength,
|
|
145
|
+
...uploadData,
|
|
146
|
+
media: undefined
|
|
147
|
+
})
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// 4. Ubah tipe pesan jadi PTV jika flag aktif
|
|
151
|
+
if (uploadData.ptv) {
|
|
152
|
+
obj.ptvMessage = obj.videoMessage;
|
|
153
|
+
delete obj.videoMessage;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Handle sticker timestamp
|
|
157
|
+
if (obj.stickerMessage) {
|
|
158
|
+
obj.stickerMessage.stickerSentTs = Date.now();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (cacheableKey) {
|
|
162
|
+
logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
|
|
163
|
+
options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return obj;
|
|
167
|
+
}
|
|
168
|
+
// --- [SELESAI] LOGIKA NEWSLETTER ---
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
// --- LOGIKA LAMA (E2E / CHAT BIASA) ---
|
|
109
172
|
const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
|
|
110
173
|
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
|
|
111
174
|
(typeof uploadData['jpegThumbnail'] === 'undefined');
|
|
112
175
|
const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
|
|
113
176
|
const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
|
|
114
177
|
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
|
|
115
|
-
|
|
178
|
+
|
|
179
|
+
// Enkripsi standar
|
|
180
|
+
const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, } = await (0, messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
|
|
116
181
|
logger,
|
|
117
182
|
saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
|
|
118
183
|
opts: options.options
|
|
119
184
|
});
|
|
120
|
-
|
|
121
|
-
const fileEncSha256B64 = (
|
|
185
|
+
|
|
186
|
+
const fileEncSha256B64 = (fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256).toString('base64');
|
|
187
|
+
|
|
122
188
|
const [{ mediaUrl, directPath, handle }] = await Promise.all([
|
|
123
189
|
(async () => {
|
|
124
190
|
const result = await options.upload(encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs });
|
|
@@ -171,6 +237,7 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
171
237
|
}
|
|
172
238
|
}
|
|
173
239
|
});
|
|
240
|
+
|
|
174
241
|
const obj = Types_1.WAProto.Message.fromObject({
|
|
175
242
|
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
176
243
|
url: handle ? undefined : mediaUrl,
|
|
@@ -184,10 +251,12 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
184
251
|
media: undefined
|
|
185
252
|
})
|
|
186
253
|
});
|
|
254
|
+
|
|
187
255
|
if (uploadData.ptv) {
|
|
188
256
|
obj.ptvMessage = obj.videoMessage;
|
|
189
257
|
delete obj.videoMessage;
|
|
190
258
|
}
|
|
259
|
+
|
|
191
260
|
if (cacheableKey) {
|
|
192
261
|
logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
|
|
193
262
|
options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
|
package/package.json
CHANGED
|
@@ -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;
|