@rexxhayanasi/elaina-baileys 1.2.0 → 1.2.1-rc.2

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.
@@ -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
- const jimp = (_jimp === null || _jimp === void 0 ? void 0 : _jimp.default) || _jimp;
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
- }
@@ -82,20 +82,20 @@ const prepareWAMessageMedia = async (message, options) => {
82
82
  media: message[mediaType]
83
83
  };
84
84
  delete uploadData[mediaType];
85
- // check if cacheable + generate cache key
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
- // generate the key
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
- // check for cache hit
98
+
99
99
  if (cacheableKey) {
100
100
  const mediaBuff = options.mediaCache.get(cacheableKey);
101
101
  if (mediaBuff) {
@@ -106,19 +106,96 @@ const prepareWAMessageMedia = async (message, options) => {
106
106
  return obj;
107
107
  }
108
108
  }
109
+
110
+ const isNewsletter = !!options.jid && (0, WABinary_1.isJidNewsletter)(options.jid);
111
+
112
+ if (isNewsletter) {
113
+ logger === null || logger === void 0 ? void 0 : logger.info({ key: cacheableKey }, 'Preparing raw media for newsletter');
114
+
115
+ const { filePath, fileSha256, fileLength } = await (0, messages_media_1.getRawMediaUploadData)(
116
+ uploadData.media,
117
+ options.mediaTypeOverride || mediaType,
118
+ logger
119
+ );
120
+
121
+ const fileSha256B64 = fileSha256.toString('base64');
122
+
123
+ try {
124
+ if (mediaType === 'video' || mediaType === 'image') {
125
+ const { thumbnail, originalImageDimensions } = await (0, messages_media_1.generateThumbnail)(filePath, mediaType, options);
126
+ uploadData.jpegThumbnail = thumbnail;
127
+
128
+ if (!uploadData.width && originalImageDimensions) {
129
+ uploadData.width = originalImageDimensions.width;
130
+ uploadData.height = originalImageDimensions.height;
131
+ }
132
+ }
133
+
134
+ if (mediaType === 'audio' || mediaType === 'video') {
135
+ if (typeof uploadData.seconds === 'undefined') {
136
+ uploadData.seconds = await (0, messages_media_1.getAudioDuration)(filePath);
137
+ }
138
+ }
139
+
140
+ if (mediaType === 'audio' && uploadData.ptt === true) {
141
+ uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(filePath, logger);
142
+ }
143
+ } catch (err) {
144
+ logger === null || logger === void 0 ? void 0 : logger.warn({ trace: err.stack }, 'Failed to generate metadata for newsletter media');
145
+ }
146
+
147
+ const streamToUpload = (0, fs_1.createReadStream)(filePath);
148
+
149
+ const { mediaUrl, directPath } = await options.upload(streamToUpload, {
150
+ fileEncSha256B64: fileSha256B64,
151
+ mediaType: mediaType,
152
+ timeoutMs: options.mediaUploadTimeoutMs
153
+ });
154
+
155
+ await fs_1.promises.unlink(filePath);
156
+
157
+ const obj = Types_1.WAProto.Message.fromObject({
158
+ [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
159
+ url: mediaUrl,
160
+ directPath,
161
+ fileSha256,
162
+ fileLength,
163
+ ...uploadData,
164
+ media: undefined
165
+ })
166
+ });
167
+
168
+ if (uploadData.ptv) {
169
+ obj.ptvMessage = obj.videoMessage;
170
+ delete obj.videoMessage;
171
+ }
172
+
173
+ if (obj.stickerMessage) {
174
+ obj.stickerMessage.stickerSentTs = Date.now();
175
+ }
176
+
177
+ if (cacheableKey) {
178
+ logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
179
+ options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
180
+ }
181
+
182
+ return obj;
183
+ }
109
184
  const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
110
185
  const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
111
186
  (typeof uploadData['jpegThumbnail'] === 'undefined');
112
187
  const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
113
188
  const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
114
189
  const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
115
- const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, } = await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
190
+
191
+ const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, } = await (0, messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
116
192
  logger,
117
193
  saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
118
194
  opts: options.options
119
195
  });
120
- // url safe Base64 encode the SHA256 hash of the body
121
- const fileEncSha256B64 = (options.newsletter ? fileSha256 : fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256).toString('base64');
196
+
197
+ const fileEncSha256B64 = (fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256).toString('base64');
198
+
122
199
  const [{ mediaUrl, directPath, handle }] = await Promise.all([
123
200
  (async () => {
124
201
  const result = await options.upload(encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs });
@@ -159,7 +236,7 @@ const prepareWAMessageMedia = async (message, options) => {
159
236
  if (!Buffer.isBuffer(encWriteStream)) {
160
237
  encWriteStream.destroy();
161
238
  }
162
- // remove tmp files
239
+
163
240
  if (didSaveToTmpPath && bodyPath) {
164
241
  try {
165
242
  await fs_1.promises.access(bodyPath);
@@ -171,6 +248,7 @@ const prepareWAMessageMedia = async (message, options) => {
171
248
  }
172
249
  }
173
250
  });
251
+
174
252
  const obj = Types_1.WAProto.Message.fromObject({
175
253
  [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
176
254
  url: handle ? undefined : mediaUrl,
@@ -184,10 +262,12 @@ const prepareWAMessageMedia = async (message, options) => {
184
262
  media: undefined
185
263
  })
186
264
  });
265
+
187
266
  if (uploadData.ptv) {
188
267
  obj.ptvMessage = obj.videoMessage;
189
268
  delete obj.videoMessage;
190
269
  }
270
+
191
271
  if (cacheableKey) {
192
272
  logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
193
273
  options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
@@ -221,7 +301,7 @@ const generateForwardMessageContent = (message, forceForward) => {
221
301
  if (!content) {
222
302
  throw new boom_1.Boom('no content in message', { statusCode: 400 });
223
303
  }
224
- // hacky copy
304
+
225
305
  content = (0, exports.normalizeMessageContent)(content);
226
306
  content = WAProto_1.proto.Message.decode(WAProto_1.proto.Message.encode(content).finish());
227
307
  let key = Object.keys(content)[0];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rexxhayanasi/elaina-baileys",
3
- "version": "1.2.0",
3
+ "version": "1.2.1-rc.2",
4
4
  "description": "Custom Baileys WhatsApp API",
5
5
  "keywords": [
6
6
  "baileys",
@@ -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;