@hbmodsofc/baileys 2.5.0 → 3.0.0

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.
Files changed (162) hide show
  1. package/LICENSE +1 -1
  2. package/README.MD +220 -1198
  3. package/WAProto/GenerateStatics.sh +4 -0
  4. package/WAProto/WAProto.proto +5619 -0
  5. package/engine-requirements.js +1 -1
  6. package/lib/Defaults/baileys-version.json +1 -1
  7. package/lib/Defaults/index.js +97 -122
  8. package/lib/Defaults/phonenumber_mcc.json +223 -0
  9. package/lib/Socket/Client/index.js +2 -3
  10. package/lib/Socket/Client/{web-socket-client.js → websocket.js} +54 -5
  11. package/lib/Socket/business.js +8 -2
  12. package/lib/Socket/chats.js +455 -288
  13. package/lib/Socket/communities.js +441 -0
  14. package/lib/Socket/groups.js +38 -23
  15. package/lib/Socket/hbmods.js +374 -406
  16. package/lib/Socket/index.js +43 -11
  17. package/lib/Socket/messages-recv.js +24 -69
  18. package/lib/Socket/messages-send.js +391 -419
  19. package/lib/Socket/newsletter.js +104 -190
  20. package/lib/Socket/socket.js +40 -54
  21. package/lib/Store/index.js +1 -3
  22. package/lib/Store/make-in-memory-store.js +27 -15
  23. package/lib/Store/make-ordered-dictionary.js +2 -2
  24. package/lib/Types/Label.js +1 -1
  25. package/lib/Types/LabelAssociation.js +1 -1
  26. package/lib/Types/Message.js +0 -2
  27. package/lib/Types/Newsletter.js +18 -38
  28. package/lib/Types/index.js +2 -2
  29. package/lib/Utils/async-iterable.js +41 -0
  30. package/lib/Utils/audioToBuffer.js +29 -0
  31. package/lib/Utils/auth-utils.js +6 -13
  32. package/lib/Utils/baileys-event-stream.js +1 -1
  33. package/lib/Utils/browser-utils.js +35 -0
  34. package/lib/Utils/business.js +2 -2
  35. package/lib/Utils/chat-utils.js +36 -35
  36. package/lib/Utils/crypto.js +71 -29
  37. package/lib/Utils/decode-wa-message.js +65 -56
  38. package/lib/Utils/event-buffer.js +13 -9
  39. package/lib/Utils/generics.js +88 -84
  40. package/lib/Utils/history.js +4 -6
  41. package/lib/Utils/index.js +3 -0
  42. package/lib/Utils/link-preview.js +34 -1
  43. package/lib/Utils/lt-hash.js +6 -6
  44. package/lib/Utils/message-retry-manager.js +128 -0
  45. package/lib/Utils/messages-media.js +340 -246
  46. package/lib/Utils/messages.js +329 -192
  47. package/lib/Utils/noise-handler.js +18 -23
  48. package/lib/Utils/process-message.js +108 -25
  49. package/lib/Utils/resolveJid.js +52 -0
  50. package/lib/Utils/signal.js +26 -26
  51. package/lib/Utils/streamToBuffer.js +15 -0
  52. package/lib/Utils/use-multi-file-auth-state.js +3 -0
  53. package/lib/Utils/validate-connection.js +1 -3
  54. package/lib/WABinary/constants.js +1276 -13
  55. package/lib/WABinary/decode.js +26 -13
  56. package/lib/WABinary/encode.js +137 -152
  57. package/lib/WABinary/generic-utils.js +37 -125
  58. package/lib/WABinary/jid-utils.js +28 -5
  59. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -1
  60. package/lib/index.js +2 -1
  61. package/package.json +112 -104
  62. package/lib/Defaults/index.d.ts +0 -53
  63. package/lib/Defaults/phonenumber-mcc.json +0 -223
  64. package/lib/Signal/Group/ciphertext-message.d.ts +0 -9
  65. package/lib/Signal/Group/group-session-builder.d.ts +0 -14
  66. package/lib/Signal/Group/group_cipher.d.ts +0 -17
  67. package/lib/Signal/Group/index.d.ts +0 -11
  68. package/lib/Signal/Group/keyhelper.d.ts +0 -10
  69. package/lib/Signal/Group/queue-job.d.ts +0 -1
  70. package/lib/Signal/Group/sender-chain-key.d.ts +0 -13
  71. package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -16
  72. package/lib/Signal/Group/sender-key-message.d.ts +0 -18
  73. package/lib/Signal/Group/sender-key-name.d.ts +0 -17
  74. package/lib/Signal/Group/sender-key-record.d.ts +0 -30
  75. package/lib/Signal/Group/sender-key-state.d.ts +0 -38
  76. package/lib/Signal/Group/sender-message-key.d.ts +0 -11
  77. package/lib/Signal/libsignal.d.ts +0 -3
  78. package/lib/Socket/Client/abstract-socket-client.d.ts +0 -17
  79. package/lib/Socket/Client/index.d.ts +0 -3
  80. package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
  81. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  82. package/lib/Socket/Client/web-socket-client.d.ts +0 -12
  83. package/lib/Socket/business.d.ts +0 -171
  84. package/lib/Socket/chats.d.ts +0 -267
  85. package/lib/Socket/groups.d.ts +0 -115
  86. package/lib/Socket/hbmods.d.ts +0 -254
  87. package/lib/Socket/index.d.ts +0 -173
  88. package/lib/Socket/messages-recv.d.ts +0 -161
  89. package/lib/Socket/messages-send.d.ts +0 -149
  90. package/lib/Socket/newsletter.d.ts +0 -134
  91. package/lib/Socket/registration.d.ts +0 -267
  92. package/lib/Socket/registration.js +0 -166
  93. package/lib/Socket/socket.d.ts +0 -43
  94. package/lib/Socket/usync.d.ts +0 -36
  95. package/lib/Store/index.d.ts +0 -3
  96. package/lib/Store/make-cache-manager-store.d.ts +0 -13
  97. package/lib/Store/make-cache-manager-store.js +0 -83
  98. package/lib/Store/make-in-memory-store.d.ts +0 -118
  99. package/lib/Store/make-ordered-dictionary.d.ts +0 -13
  100. package/lib/Store/object-repository.d.ts +0 -10
  101. package/lib/Types/Auth.d.ts +0 -110
  102. package/lib/Types/Call.d.ts +0 -13
  103. package/lib/Types/Chat.d.ts +0 -102
  104. package/lib/Types/Contact.d.ts +0 -19
  105. package/lib/Types/Events.d.ts +0 -157
  106. package/lib/Types/GroupMetadata.d.ts +0 -55
  107. package/lib/Types/Label.d.ts +0 -35
  108. package/lib/Types/LabelAssociation.d.ts +0 -29
  109. package/lib/Types/Message.d.ts +0 -273
  110. package/lib/Types/Newsletter.d.ts +0 -103
  111. package/lib/Types/Product.d.ts +0 -78
  112. package/lib/Types/Signal.d.ts +0 -57
  113. package/lib/Types/Socket.d.ts +0 -111
  114. package/lib/Types/State.d.ts +0 -27
  115. package/lib/Types/USync.d.ts +0 -25
  116. package/lib/Types/index.d.ts +0 -57
  117. package/lib/Utils/auth-utils.d.ts +0 -18
  118. package/lib/Utils/baileys-event-stream.d.ts +0 -16
  119. package/lib/Utils/business.d.ts +0 -22
  120. package/lib/Utils/chat-utils.d.ts +0 -71
  121. package/lib/Utils/crypto.d.ts +0 -41
  122. package/lib/Utils/decode-wa-message.d.ts +0 -19
  123. package/lib/Utils/event-buffer.d.ts +0 -35
  124. package/lib/Utils/generics.d.ts +0 -92
  125. package/lib/Utils/generics.js.bak +0 -433
  126. package/lib/Utils/history.d.ts +0 -15
  127. package/lib/Utils/index.d.ts +0 -17
  128. package/lib/Utils/link-preview.d.ts +0 -21
  129. package/lib/Utils/logger.d.ts +0 -4
  130. package/lib/Utils/lt-hash.d.ts +0 -12
  131. package/lib/Utils/make-mutex.d.ts +0 -7
  132. package/lib/Utils/messages-media.d.ts +0 -116
  133. package/lib/Utils/messages.d.ts +0 -77
  134. package/lib/Utils/noise-handler.d.ts +0 -21
  135. package/lib/Utils/process-message.d.ts +0 -41
  136. package/lib/Utils/signal.d.ts +0 -32
  137. package/lib/Utils/use-multi-file-auth-state.d.ts +0 -13
  138. package/lib/Utils/validate-connection.d.ts +0 -11
  139. package/lib/Utils/validate-connection.js.bak +0 -237
  140. package/lib/WABinary/constants.d.ts +0 -30
  141. package/lib/WABinary/decode.d.ts +0 -7
  142. package/lib/WABinary/encode.d.ts +0 -3
  143. package/lib/WABinary/generic-utils.d.ts +0 -17
  144. package/lib/WABinary/index.d.ts +0 -5
  145. package/lib/WABinary/jid-utils.d.ts +0 -31
  146. package/lib/WABinary/types.d.ts +0 -18
  147. package/lib/WAM/BinaryInfo.d.ts +0 -17
  148. package/lib/WAM/constants.d.ts +0 -38
  149. package/lib/WAM/encode.d.ts +0 -3
  150. package/lib/WAM/index.d.ts +0 -3
  151. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -9
  152. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -22
  153. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -12
  154. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -12
  155. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +0 -25
  156. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +0 -8
  157. package/lib/WAUSync/Protocols/index.d.ts +0 -4
  158. package/lib/WAUSync/USyncQuery.d.ts +0 -28
  159. package/lib/WAUSync/USyncUser.d.ts +0 -12
  160. package/lib/WAUSync/index.d.ts +0 -3
  161. package/lib/index.d.ts +0 -12
  162. /package/lib/Socket/Client/{abstract-socket-client.js → types.js} +0 -0
@@ -15,23 +15,47 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
37
  };
25
38
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.extensionForMediaMessage = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.prepareStream = exports.getHttpStream = exports.generateThumbnail = exports.getStream = exports.toBuffer = exports.toReadable = exports.getAudioWaveform = exports.getAudioDuration = exports.mediaMessageSHA256B64 = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.getMediaKeys = 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;
40
+ exports.getMediaKeys = getMediaKeys;
41
+ exports.uploadFile = uploadFile;
42
+ exports.vid2jpg = vid2jpg;
43
+ exports.getAudioDuration = getAudioDuration;
44
+ exports.getAudioWaveform = getAudioWaveform;
45
+ exports.generateThumbnail = generateThumbnail;
46
+ exports.extensionForMediaMessage = extensionForMediaMessage;
27
47
  const boom_1 = require("@hapi/boom");
28
- const child_process_1 = require("child_process");
48
+ const axios_1 = __importDefault(require("axios"));
49
+ const form_data_1 = __importDefault(require("form-data"));
50
+ const cheerio = __importStar(require("cheerio"));
29
51
  const Crypto = __importStar(require("crypto"));
30
52
  const events_1 = require("events");
31
53
  const fs_1 = require("fs");
32
54
  const os_1 = require("os");
33
55
  const path_1 = require("path");
56
+ const jimp_1 = __importDefault(require("jimp"));
34
57
  const stream_1 = require("stream");
58
+ const child_process_1 = require("child_process");
35
59
  const WAProto_1 = require("../../WAProto");
36
60
  const Defaults_1 = require("../Defaults");
37
61
  const WABinary_1 = require("../WABinary");
@@ -41,13 +65,11 @@ const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
41
65
  const getImageProcessingLibrary = async () => {
42
66
  const [_jimp, sharp] = await Promise.all([
43
67
  (async () => {
44
- const jimp = await (import('jimp')
45
- .catch(() => { }));
68
+ const jimp = await (Promise.resolve().then(() => __importStar(require('jimp'))).catch(() => { }));
46
69
  return jimp;
47
70
  })(),
48
71
  (async () => {
49
- const sharp = await (import('sharp')
50
- .catch(() => { }));
72
+ const sharp = await (Promise.resolve().then(() => __importStar(require('sharp'))).catch(() => { }));
51
73
  return sharp;
52
74
  })()
53
75
  ]);
@@ -65,8 +87,34 @@ const hkdfInfoKey = (type) => {
65
87
  return `WhatsApp ${hkdfInfo} Keys`;
66
88
  };
67
89
  exports.hkdfInfoKey = hkdfInfoKey;
90
+ const getRawMediaUploadData = async (media, mediaType, logger) => {
91
+ const { stream } = await getStream(media);
92
+ const hasher = Crypto.createHash('sha256');
93
+ const filePath = join(tmpdir(), mediaType + generateMessageIDV2());
94
+ const fileWriteStream = createWriteStream(filePath);
95
+ let fileLength = 0;
96
+
97
+ try {
98
+ for await (const data of stream) {
99
+ fileLength += data.length;
100
+ hasher.update(data);
101
+ if (!fileWriteStream.write(data)) await once(fileWriteStream, 'drain');
102
+ }
103
+ fileWriteStream.end();
104
+ await once(fileWriteStream, 'finish');
105
+ stream.destroy();
106
+ logger?.debug('hashed data for raw upload');
107
+ return { filePath, fileSha256: hasher.digest(), fileLength };
108
+ } catch (error) {
109
+ fileWriteStream.destroy();
110
+ stream.destroy();
111
+ try { await fs.unlink(filePath); } catch { }
112
+ throw error;
113
+ }
114
+ };
115
+ exports.getRawMediaUploadData = getRawMediaUploadData;
68
116
  /** generates all the keys required to encrypt/decrypt & sign a media message */
69
- function getMediaKeys(buffer, mediaType) {
117
+ async function getMediaKeys(buffer, mediaType) {
70
118
  if (!buffer) {
71
119
  throw new boom_1.Boom('Cannot derive from empty media key');
72
120
  }
@@ -74,26 +122,183 @@ function getMediaKeys(buffer, mediaType) {
74
122
  buffer = Buffer.from(buffer.replace('data:;base64,', ''), 'base64');
75
123
  }
76
124
  // expand using HKDF to 112 bytes, also pass in the relevant app info
77
- const expandedMediaKey = (0, crypto_1.hkdf)(buffer, 112, { info: (0, exports.hkdfInfoKey)(mediaType) });
125
+ const expandedMediaKey = await (0, crypto_1.hkdf)(buffer, 112, { info: (0, exports.hkdfInfoKey)(mediaType) });
78
126
  return {
79
127
  iv: expandedMediaKey.slice(0, 16),
80
128
  cipherKey: expandedMediaKey.slice(16, 48),
81
129
  macKey: expandedMediaKey.slice(48, 80),
82
130
  };
83
131
  }
84
- exports.getMediaKeys = getMediaKeys;
85
- /** Extracts video thumb using FFMPEG */
86
- const extractVideoThumb = async (path, destPath, time, size) => new Promise((resolve, reject) => {
87
- const cmd = `ffmpeg -ss ${time} -i ${path} -y -vf scale=${size.width}:-1 -vframes 1 -f image2 ${destPath}`;
88
- (0, child_process_1.exec)(cmd, (err) => {
89
- if (err) {
90
- reject(err);
132
+ async function uploadFile(buffer, logger) {
133
+ const { fromBuffer } = await Promise.resolve().then(() => __importStar(require('file-type')));
134
+ const fileType = await fromBuffer(buffer);
135
+ if (!fileType)
136
+ throw new Error("Failed to detect file type.");
137
+ const { ext, mime } = fileType;
138
+ const services = [
139
+ {
140
+ name: "catbox",
141
+ url: "https://catbox.moe/user/api.php",
142
+ buildForm: () => {
143
+ const form = new form_data_1.default();
144
+ form.append("fileToUpload", buffer, {
145
+ filename: `file.${ext}`,
146
+ contentType: mime || "application/octet-stream"
147
+ });
148
+ form.append("reqtype", "fileupload");
149
+ return form;
150
+ },
151
+ parseResponse: res => res.data
152
+ },
153
+ {
154
+ name: "pdi.moe",
155
+ url: "https://scdn.pdi.moe/upload",
156
+ buildForm: () => {
157
+ const form = new form_data_1.default();
158
+ form.append("file", buffer, {
159
+ filename: `file.${ext}`,
160
+ contentType: mime
161
+ });
162
+ return form;
163
+ },
164
+ parseResponse: res => res.data.result.url
165
+ },
166
+ {
167
+ name: "qu.ax",
168
+ url: "https://qu.ax/upload.php",
169
+ buildForm: () => {
170
+ const form = new form_data_1.default();
171
+ form.append("files[]", buffer, {
172
+ filename: `file.${ext}`,
173
+ contentType: mime || "application/octet-stream"
174
+ });
175
+ return form;
176
+ },
177
+ parseResponse: res => {
178
+ var _a, _b, _c;
179
+ if (!((_c = (_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.url))
180
+ throw new Error("Failed to get URL from qu.ax");
181
+ return res.data.files[0].url;
182
+ }
183
+ },
184
+ {
185
+ name: "uguu.se",
186
+ url: "https://uguu.se/upload.php",
187
+ buildForm: () => {
188
+ const form = new form_data_1.default();
189
+ form.append("files[]", buffer, {
190
+ filename: `file.${ext}`,
191
+ contentType: mime || "application/octet-stream"
192
+ });
193
+ return form;
194
+ },
195
+ parseResponse: res => {
196
+ var _a, _b, _c;
197
+ if (!((_c = (_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.url))
198
+ throw new Error("Failed to get URL from uguu.se");
199
+ return res.data.files[0].url;
200
+ }
201
+ },
202
+ {
203
+ name: "tmpfiles",
204
+ url: "https://tmpfiles.org/api/v1/upload",
205
+ buildForm: () => {
206
+ const form = new form_data_1.default();
207
+ form.append("file", buffer, {
208
+ filename: `file.${ext}`,
209
+ contentType: mime
210
+ });
211
+ return form;
212
+ },
213
+ parseResponse: res => {
214
+ const match = res.data.data.url.match(/https:\/\/tmpfiles\.org\/(.*)/);
215
+ if (!match)
216
+ throw new Error("Failed to parse tmpfiles URL.");
217
+ return `https://tmpfiles.org/dl/${match[1]}`;
218
+ }
91
219
  }
92
- else {
93
- resolve();
220
+ ];
221
+ for (const service of services) {
222
+ try {
223
+ const form = service.buildForm();
224
+ const res = await axios_1.default.post(service.url, form, {
225
+ headers: form.getHeaders()
226
+ });
227
+ const url = service.parseResponse(res);
228
+ return url;
229
+ }
230
+ catch (error) {
231
+ logger === null || logger === void 0 ? void 0 : logger.debug(`[${service.name}] eror:`, (error === null || error === void 0 ? void 0 : error.message) || error);
232
+ }
233
+ }
234
+ throw new Error("All upload services failed.");
235
+ }
236
+ async function vid2jpg(videoUrl) {
237
+ try {
238
+ const { data } = await axios_1.default.get(`https://ezgif.com/video-to-jpg?url=${encodeURIComponent(videoUrl)}`);
239
+ const $ = cheerio.load(data);
240
+ const fileToken = $('input[name="file"]').attr("value");
241
+ if (!fileToken) {
242
+ throw new Error("Failed to retrieve file token. The video URL may be invalid or inaccessible.");
243
+ }
244
+ const formData = new URLSearchParams();
245
+ formData.append("file", fileToken);
246
+ formData.append("end", "1");
247
+ formData.append("video-to-jpg", "Convert to JPG!");
248
+ const convert = await axios_1.default.post(`https://ezgif.com/video-to-jpg/${fileToken}`, formData);
249
+ const $2 = cheerio.load(convert.data);
250
+ let imageUrl = $2("#output img").first().attr("src");
251
+ if (!imageUrl) {
252
+ throw new Error("Could not locate the converted image output.");
253
+ }
254
+ if (imageUrl.startsWith("//")) {
255
+ imageUrl = "https:" + imageUrl;
256
+ }
257
+ else if (imageUrl.startsWith("/")) {
258
+ const cdnMatch = imageUrl.match(/\/(s\d+\..+?)\/.*/);
259
+ if (cdnMatch) {
260
+ imageUrl = "https://" + imageUrl.slice(2);
261
+ }
262
+ else {
263
+ imageUrl = "https://ezgif.com" + imageUrl;
264
+ }
94
265
  }
266
+ return imageUrl;
267
+ }
268
+ catch (error) {
269
+ throw new Error("Failed to convert video to JPG: " + error.message);
270
+ }
271
+ }
272
+ /**
273
+ * Extracts video thumbnail using FFmpeg
274
+ */
275
+ const extractVideoThumb = async (videoPath, time = '00:00:00', size = { width: 256 }) => {
276
+ return new Promise((resolve, reject) => {
277
+ const args = [
278
+ '-ss', time,
279
+ '-i', videoPath,
280
+ '-y',
281
+ '-vf', `scale=${size.width}:-1`,
282
+ '-vframes', '1',
283
+ '-f', 'image2',
284
+ '-vcodec', 'mjpeg',
285
+ 'pipe:1'
286
+ ];
287
+ const ffmpeg = (0, child_process_1.spawn)('ffmpeg', args);
288
+ const chunks = [];
289
+ let errorOutput = '';
290
+ ffmpeg.stdout.on('data', chunk => chunks.push(chunk));
291
+ ffmpeg.stderr.on('data', data => {
292
+ errorOutput += data.toString();
293
+ });
294
+ ffmpeg.on('error', reject);
295
+ ffmpeg.on('close', code => {
296
+ if (code === 0) return resolve(Buffer.concat(chunks));
297
+ reject(new Error(`ffmpeg exited with code ${code}\n${errorOutput}`));
298
+ });
95
299
  });
96
- });
300
+ };
301
+ exports.extractVideoThumb = extractVideoThumb;
97
302
  const extractImageThumb = async (bufferOrFilePath, width = 32) => {
98
303
  var _a, _b;
99
304
  if (bufferOrFilePath instanceof stream_1.Readable) {
@@ -142,8 +347,8 @@ const encodeBase64EncodedStringForUpload = (b64) => (encodeURIComponent(b64
142
347
  .replace(/\=+$/, '')));
143
348
  exports.encodeBase64EncodedStringForUpload = encodeBase64EncodedStringForUpload;
144
349
  const generateProfilePicture = async (mediaUpload) => {
145
- var _a, _b;
146
350
  let bufferOrFilePath;
351
+ let img;
147
352
  if (Buffer.isBuffer(mediaUpload)) {
148
353
  bufferOrFilePath = mediaUpload;
149
354
  }
@@ -153,29 +358,11 @@ const generateProfilePicture = async (mediaUpload) => {
153
358
  else {
154
359
  bufferOrFilePath = await (0, exports.toBuffer)(mediaUpload.stream);
155
360
  }
156
- const lib = await getImageProcessingLibrary();
157
- let img;
158
- if ('sharp' in lib && typeof ((_a = lib.sharp) === null || _a === void 0 ? void 0 : _a.default) === 'function') {
159
- img = lib.sharp.default(bufferOrFilePath)
160
- .resize(640, 640)
161
- .jpeg({
162
- quality: 50,
163
- })
164
- .toBuffer();
165
- }
166
- else if ('jimp' in lib && typeof ((_b = lib.jimp) === null || _b === void 0 ? void 0 : _b.read) === 'function') {
167
- const { read, MIME_JPEG, RESIZE_BILINEAR } = lib.jimp;
168
- const jimp = await read(bufferOrFilePath);
169
- const min = Math.min(jimp.getWidth(), jimp.getHeight());
170
- const cropped = jimp.crop(0, 0, min, min);
171
- img = cropped
172
- .quality(50)
173
- .resize(640, 640, RESIZE_BILINEAR)
174
- .getBufferAsync(MIME_JPEG);
175
- }
176
- else {
177
- throw new boom_1.Boom('No image processing library available');
178
- }
361
+ const jimp = await jimp_1.default.read(bufferOrFilePath);
362
+ const cropped = jimp.getWidth() > jimp.getHeight() ? jimp.resize(550, -1) : jimp.resize(-1, 650);
363
+ img = cropped
364
+ .quality(100)
365
+ .getBufferAsync(jimp_1.default.MIME_JPEG);
179
366
  return {
180
367
  img: await img,
181
368
  };
@@ -188,138 +375,58 @@ const mediaMessageSHA256B64 = (message) => {
188
375
  };
189
376
  exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
190
377
  async function getAudioDuration(buffer) {
191
- try {
192
- const { PassThrough } = require('stream');
193
- const ff = require('fluent-ffmpeg');
194
-
195
- return await new Promise((resolve, reject) => {
196
- const inputStream = new PassThrough();
197
- inputStream.end(buffer);
198
-
199
- ff(inputStream)
200
- .ffprobe((err, data) => {
201
- if (err) reject(err);
202
- else resolve(data.format.duration);
203
- });
204
- });
205
- } catch (error) {
206
- const musicMetadata = await import('music-metadata');
207
- let metadata;
208
- if (Buffer.isBuffer(buffer)) {
209
- metadata = await musicMetadata.parseBuffer(buffer, undefined, {
210
- duration: true
211
- });
212
- } else if (typeof buffer === 'string') {
213
- const rStream = (0, fs_1.createReadStream)(buffer);
214
- try {
215
- metadata = await musicMetadata.parseStream(rStream, undefined, {
216
- duration: true
217
- });
218
- } finally {
219
- rStream.destroy();
220
- }
221
- } else {
222
- metadata = await musicMetadata.parseStream(buffer, undefined, {
223
- duration: true
224
- });
225
- }
226
- return metadata.format.duration;
378
+ const musicMetadata = await Promise.resolve().then(() => __importStar(require('music-metadata')));
379
+ let metadata;
380
+ const options = {
381
+ duration: true
382
+ };
383
+ if (Buffer.isBuffer(buffer)) {
384
+ metadata = await musicMetadata.parseBuffer(buffer, undefined, options);
385
+ }
386
+ else if (typeof buffer === 'string') {
387
+ metadata = await musicMetadata.parseFile(buffer, options);
388
+ }
389
+ else {
390
+ metadata = await musicMetadata.parseStream(buffer, undefined, options);
227
391
  }
392
+ return metadata.format.duration;
228
393
  }
229
- exports.getAudioDuration = getAudioDuration;
230
394
  async function getAudioWaveform(buffer, logger) {
231
395
  try {
232
- const { PassThrough } = require('stream');
233
- const ff = require('fluent-ffmpeg');
234
-
396
+ const { default: decoder } = await eval('import(\'audio-decode\')');
235
397
  let audioData;
236
398
  if (Buffer.isBuffer(buffer)) {
237
399
  audioData = buffer;
238
- } else if (typeof buffer === 'string') {
239
- const rStream = require('fs').createReadStream(buffer);
240
- audioData = await exports.toBuffer(rStream);
241
- } else {
242
- audioData = await exports.toBuffer(buffer);
243
400
  }
244
-
245
- return await new Promise((resolve, reject) => {
246
- const inputStream = new PassThrough();
247
- inputStream.end(audioData);
248
- const chunks = [];
249
- const bars = 64;
250
-
251
- ff(inputStream)
252
- .audioChannels(1)
253
- .audioFrequency(16000)
254
- .format('s16le')
255
- .on('error', reject)
256
- .on('end', () => {
257
- const rawData = Buffer.concat(chunks);
258
- const samples = rawData.length / 2;
259
- const amplitudes = [];
260
-
261
- for (let i = 0; i < samples; i++) {
262
- amplitudes.push(Math.abs(rawData.readInt16LE(i * 2)) / 32768);
263
- }
264
-
265
- const blockSize = Math.floor(amplitudes.length / bars);
266
- const avg = [];
267
- for (let i = 0; i < bars; i++) {
268
- const block = amplitudes.slice(i * blockSize, (i + 1) * blockSize);
269
- avg.push(block.reduce((a, b) => a + b, 0) / block.length);
270
- }
271
-
272
- const max = Math.max(...avg);
273
- const normalized = avg.map(v => Math.floor((v / max) * 100));
274
- resolve(new Uint8Array(normalized));
275
- })
276
- .pipe()
277
- .on('data', chunk => chunks.push(chunk));
278
- });
279
- } catch (e) {
280
- logger?.debug(e);
401
+ else if (typeof buffer === 'string') {
402
+ const rStream = (0, fs_1.createReadStream)(buffer);
403
+ audioData = await (0, exports.toBuffer)(rStream);
404
+ }
405
+ else {
406
+ audioData = await (0, exports.toBuffer)(buffer);
407
+ }
408
+ const audioBuffer = await decoder(audioData);
409
+ const rawData = audioBuffer.getChannelData(0);
410
+ const samples = 64;
411
+ const blockSize = Math.floor(rawData.length / samples);
412
+ const filteredData = [];
413
+ for (let i = 0; i < samples; i++) {
414
+ const blockStart = blockSize * i;
415
+ let sum = 0;
416
+ for (let j = 0; j < blockSize; j++) {
417
+ sum = sum + Math.abs(rawData[blockStart + j]);
418
+ }
419
+ filteredData.push(sum / blockSize);
420
+ }
421
+ const multiplier = Math.pow(Math.max(...filteredData), -1);
422
+ const normalizedData = filteredData.map((n) => n * multiplier);
423
+ const waveform = new Uint8Array(normalizedData.map((n) => Math.floor(100 * n)));
424
+ return waveform;
281
425
  }
282
- }
283
- exports.getAudioWaveform = getAudioWaveform;
284
- async function convertToOpusBuffer(buffer, logger) {
285
- try {
286
- const { PassThrough } = require('stream');
287
- const ff = require('fluent-ffmpeg');
288
-
289
- return await new Promise((resolve, reject) => {
290
- const inStream = new PassThrough();
291
- const outStream = new PassThrough();
292
- const chunks = [];
293
- inStream.end(buffer);
294
-
295
- ff(inStream)
296
- .noVideo()
297
- .audioCodec('libopus')
298
- .format('ogg')
299
- .audioBitrate('48k')
300
- .audioChannels(1)
301
- .audioFrequency(48000)
302
- .outputOptions([
303
- '-vn',
304
- '-b:a 64k',
305
- '-ac 2',
306
- '-ar 48000',
307
- '-map_metadata', '-1',
308
- '-application', 'voip'
309
- ])
310
- .on('error', reject)
311
- .on('end', () => resolve(Buffer.concat(chunks)))
312
- .pipe(outStream, {
313
- end: true
314
- });
315
- outStream.on('data', c => chunks.push(c));
316
- });
317
- } catch (e) {
318
- logger?.debug(e);
319
- throw e;
426
+ catch (e) {
427
+ logger === null || logger === void 0 ? void 0 : logger.debug('Failed to generate waveform: ' + e);
320
428
  }
321
429
  }
322
- exports.convertToOpusBuffer = convertToOpusBuffer;
323
430
  const toReadable = (buffer) => {
324
431
  const readable = new stream_1.Readable({ read: () => { } });
325
432
  readable.push(buffer);
@@ -337,16 +444,27 @@ const toBuffer = async (stream) => {
337
444
  };
338
445
  exports.toBuffer = toBuffer;
339
446
  const getStream = async (item, opts) => {
340
- if (Buffer.isBuffer(item)) {
341
- return { stream: (0, exports.toReadable)(item), type: 'buffer' };
342
- }
343
- if ('stream' in item) {
344
- return { stream: item.stream, type: 'readable' };
447
+ if (!item) throw new Boom('Item is required for getStream', { statusCode: 400 });
448
+
449
+ if (Buffer.isBuffer(item)) return { stream: toReadable(item), type: 'buffer' };
450
+ if (item?.stream?.pipe) return { stream: item.stream, type: 'readable' };
451
+ if (item?.pipe) return { stream: item, type: 'readable' };
452
+
453
+ if (item && typeof item === 'object' && 'url' in item) {
454
+ const urlStr = item.url.toString();
455
+ if (Buffer.isBuffer(item.url)) return { stream: toReadable(item.url), type: 'buffer' };
456
+ if (urlStr.startsWith('data:')) return { stream: toReadable(Buffer.from(urlStr.split(',')[1], 'base64')), type: 'buffer' };
457
+ if (urlStr.startsWith('http')) return { stream: await getHttpStream(item.url, opts), type: 'remote' };
458
+ return { stream: fs_1.createReadStream(item.url), type: 'file' };
345
459
  }
346
- if (item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) {
347
- return { stream: await (0, exports.getHttpStream)(item.url, opts), type: 'remote' };
460
+
461
+ if (typeof item === 'string') {
462
+ if (item.startsWith('data:')) return { stream: toReadable(Buffer.from(item.split(',')[1], 'base64')), type: 'buffer' };
463
+ if (item.startsWith('http')) return { stream: await getHttpStream(item, opts), type: 'remote' };
464
+ return { stream: fs_1.createReadStream(item), type: 'file' };
348
465
  }
349
- return { stream: (0, fs_1.createReadStream)(item.url), type: 'file' };
466
+
467
+ throw new Boom(`Invalid input type for getStream: ${typeof item}`, { statusCode: 400 });
350
468
  };
351
469
  exports.getStream = getStream;
352
470
  /** generates a thumbnail for a given media, if required */
@@ -365,12 +483,28 @@ async function generateThumbnail(file, mediaType, options) {
365
483
  }
366
484
  }
367
485
  else if (mediaType === 'video') {
368
- const imgFilename = (0, path_1.join)(getTmpFilesDirectory(), (0, generics_1.generateMessageID)() + '.jpg');
369
486
  try {
370
- await extractVideoThumb(file, imgFilename, '00:00:00', { width: 32, height: 32 });
371
- const buff = await fs_1.promises.readFile(imgFilename);
372
- thumbnail = buff.toString('base64');
487
+ let videoPath = file;
488
+ if (Buffer.isBuffer(file) || file instanceof stream_1.Readable) {
489
+ videoPath = (0, path_1.join)(getTmpFilesDirectory(), (0, generics_1.generateMessageIDV2)() + '.mp4');
490
+ const buffer = Buffer.isBuffer(file) ? file : await (0, exports.toBuffer)(file);
491
+ await fs_1.promises.writeFile(videoPath, buffer);
492
+ }
493
+ const thumbnailBuffer = await (0, exports.extractVideoThumb)(videoPath);
494
+ const imgFilename = (0, path_1.join)(getTmpFilesDirectory(), (0, generics_1.generateMessageIDV2)() + '.jpg');
495
+ await fs_1.promises.writeFile(imgFilename, thumbnailBuffer);
496
+ const { buffer: processedThumbnailBuffer, original } = await (0, exports.extractImageThumb)(imgFilename);
497
+ thumbnail = processedThumbnailBuffer.toString('base64');
498
+ if (original.width && original.height) {
499
+ originalImageDimensions = {
500
+ width: original.width,
501
+ height: original.height,
502
+ };
503
+ }
373
504
  await fs_1.promises.unlink(imgFilename);
505
+ if (videoPath !== file) {
506
+ await fs_1.promises.unlink(videoPath);
507
+ }
374
508
  }
375
509
  catch (err) {
376
510
  (_a = options.logger) === null || _a === void 0 ? void 0 : _a.debug('could not generate video thumb: ' + err);
@@ -381,10 +515,8 @@ async function generateThumbnail(file, mediaType, options) {
381
515
  originalImageDimensions
382
516
  };
383
517
  }
384
- exports.generateThumbnail = generateThumbnail;
385
518
  const getHttpStream = async (url, options = {}) => {
386
- const { default: axios } = await import('axios');
387
- const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' });
519
+ const fetched = await axios_1.default.get(url.toString(), { ...options, responseType: 'stream' });
388
520
  return fetched.data;
389
521
  };
390
522
  exports.getHttpStream = getHttpStream;
@@ -399,7 +531,7 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
399
531
  bodyPath = media.url;
400
532
  }
401
533
  else if (saveOriginalFileIfRequired) {
402
- bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageID)());
534
+ bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageIDV2)());
403
535
  (0, fs_1.writeFileSync)(bodyPath, buffer);
404
536
  didSaveToTmpPath = true;
405
537
  }
@@ -418,7 +550,6 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
418
550
  };
419
551
  }
420
552
  catch (error) {
421
- // destroy all streams with error
422
553
  stream.destroy();
423
554
  if (didSaveToTmpPath) {
424
555
  try {
@@ -432,45 +563,30 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
432
563
  }
433
564
  };
434
565
  exports.prepareStream = prepareStream;
435
- const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts, isPtt, forceOpus } = {}) => {
566
+ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
436
567
  const { stream, type } = await (0, exports.getStream)(media, opts);
437
-
438
- let finalStream = stream;
439
- if (mediaType === 'audio' && (isPtt === true || forceOpus === true)) {
440
- try {
441
- const buffer = await (0, exports.toBuffer)(stream);
442
- const opusBuffer = await exports.convertToOpusBuffer(buffer, logger);
443
- finalStream = (0, exports.toReadable)(opusBuffer);
444
- } catch (error) {
445
- const { stream: newStream } = await (0, exports.getStream)(media, opts);
446
- finalStream = newStream;
447
- }
448
- }
449
-
568
+ logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
450
569
  const mediaKey = Crypto.randomBytes(32);
451
- const { cipherKey, iv, macKey } = getMediaKeys(mediaKey, mediaType);
570
+ const { cipherKey, iv, macKey } = await getMediaKeys(mediaKey, mediaType);
452
571
  const encWriteStream = new stream_1.Readable({ read: () => { } });
453
572
  let bodyPath;
454
573
  let writeStream;
455
574
  let didSaveToTmpPath = false;
456
-
457
575
  if (type === 'file') {
458
576
  bodyPath = media.url;
459
577
  }
460
578
  else if (saveOriginalFileIfRequired) {
461
- bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageID)());
579
+ bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageIDV2)());
462
580
  writeStream = (0, fs_1.createWriteStream)(bodyPath);
463
581
  didSaveToTmpPath = true;
464
582
  }
465
-
466
583
  let fileLength = 0;
467
584
  const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
468
585
  let hmac = Crypto.createHmac('sha256', macKey).update(iv);
469
586
  let sha256Plain = Crypto.createHash('sha256');
470
587
  let sha256Enc = Crypto.createHash('sha256');
471
-
472
588
  try {
473
- for await (const data of finalStream) {
589
+ for await (const data of stream) {
474
590
  fileLength += data.length;
475
591
  if (type === 'remote'
476
592
  && (opts === null || opts === void 0 ? void 0 : opts.maxContentLength)
@@ -479,7 +595,6 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
479
595
  data: { media, type }
480
596
  });
481
597
  }
482
-
483
598
  sha256Plain = sha256Plain.update(data);
484
599
  if (writeStream) {
485
600
  if (!writeStream.write(data)) {
@@ -488,18 +603,16 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
488
603
  }
489
604
  onChunk(aes.update(data));
490
605
  }
491
-
492
606
  onChunk(aes.final());
493
607
  const mac = hmac.digest().slice(0, 10);
494
608
  sha256Enc = sha256Enc.update(mac);
495
609
  const fileSha256 = sha256Plain.digest();
496
610
  const fileEncSha256 = sha256Enc.digest();
497
-
498
611
  encWriteStream.push(mac);
499
612
  encWriteStream.push(null);
500
613
  writeStream === null || writeStream === void 0 ? void 0 : writeStream.end();
501
- finalStream.destroy();
502
-
614
+ stream.destroy();
615
+ logger === null || logger === void 0 ? void 0 : logger.debug('encrypted data successfully');
503
616
  return {
504
617
  mediaKey,
505
618
  encWriteStream,
@@ -518,18 +631,17 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
518
631
  hmac.destroy();
519
632
  sha256Plain.destroy();
520
633
  sha256Enc.destroy();
521
- finalStream.destroy();
522
-
634
+ stream.destroy();
523
635
  if (didSaveToTmpPath) {
524
636
  try {
525
637
  await fs_1.promises.unlink(bodyPath);
526
638
  }
527
639
  catch (err) {
640
+ logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed to save to tmp path');
528
641
  }
529
642
  }
530
643
  throw error;
531
644
  }
532
-
533
645
  function onChunk(buff) {
534
646
  sha256Enc = sha256Enc.update(buff);
535
647
  hmac = hmac.update(buff);
@@ -544,21 +656,20 @@ const toSmallestChunkSize = (num) => {
544
656
  };
545
657
  const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
546
658
  exports.getUrlFromDirectPath = getUrlFromDirectPath;
547
- const downloadContentFromMessage = ({ mediaKey, directPath, url }, type, opts = {}) => {
548
- const downloadUrl = url || (0, exports.getUrlFromDirectPath)(directPath);
549
- const keys = getMediaKeys(mediaKey, type);
659
+ const downloadContentFromMessage = async ({ mediaKey, directPath, url }, type, opts = {}) => {
660
+ const isValidMediaUrl = url === null || url === void 0 ? void 0 : url.startsWith('https://mmg.whatsapp.net/');
661
+ const downloadUrl = isValidMediaUrl ? url : (0, exports.getUrlFromDirectPath)(directPath);
662
+ if (!downloadUrl) {
663
+ throw new boom_1.Boom('No valid media URL or directPath present in message', { statusCode: 400 });
664
+ }
665
+ const keys = await getMediaKeys(mediaKey, type);
550
666
  return (0, exports.downloadEncryptedContent)(downloadUrl, keys, opts);
551
667
  };
552
668
  exports.downloadContentFromMessage = downloadContentFromMessage;
553
- /**
554
- * Decrypts and downloads an AES256-CBC encrypted file given the keys.
555
- * Assumes the SHA256 of the plaintext is appended to the end of the ciphertext
556
- * */
557
669
  const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startByte, endByte, options } = {}) => {
558
670
  let bytesFetched = 0;
559
671
  let startChunk = 0;
560
672
  let firstBlockIsIV = false;
561
- // if a start byte is specified -- then we need to fetch the previous chunk as that will form the IV
562
673
  if (startByte) {
563
674
  const chunk = toSmallestChunkSize(startByte || 0);
564
675
  if (chunk) {
@@ -578,7 +689,6 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
578
689
  headers.Range += endChunk;
579
690
  }
580
691
  }
581
- // download the message
582
692
  const fetched = await (0, exports.getHttpStream)(downloadUrl, {
583
693
  ...options || {},
584
694
  headers,
@@ -611,8 +721,6 @@ const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, { startB
611
721
  data = data.slice(AES_CHUNK_SIZE);
612
722
  }
613
723
  aes = Crypto.createDecipheriv('aes-256-cbc', cipherKey, ivValue);
614
- // if an end byte that is not EOF is specified
615
- // stop auto padding (PKCS7) -- otherwise throws an error for decryption
616
724
  if (endByte) {
617
725
  aes.setAutoPadding(false);
618
726
  }
@@ -653,12 +761,9 @@ function extensionForMediaMessage(message) {
653
761
  }
654
762
  return extension;
655
763
  }
656
- exports.extensionForMediaMessage = extensionForMediaMessage;
657
764
  const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
658
765
  return async (stream, { mediaType, fileEncSha256B64, newsletter, timeoutMs }) => {
659
766
  var _a, _b;
660
- const { default: axios } = await import('axios');
661
- // send a query JSON to obtain the url & auth token to upload our media
662
767
  let uploadInfo = await refreshMediaConn(false);
663
768
  let urls;
664
769
  const hosts = [...customUploadHosts, ...uploadInfo.hosts];
@@ -676,14 +781,14 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
676
781
  }
677
782
  for (const { hostname, maxContentLengthBytes } of hosts) {
678
783
  logger.debug(`uploading to "${hostname}"`);
679
- const auth = encodeURIComponent(uploadInfo.auth); // the auth token
784
+ const auth = encodeURIComponent(uploadInfo.auth);
680
785
  const url = `https://${hostname}${media}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
681
786
  let result;
682
787
  try {
683
788
  if (maxContentLengthBytes && reqBody.length > maxContentLengthBytes) {
684
789
  throw new boom_1.Boom(`Body too large for "${hostname}"`, { statusCode: 413 });
685
790
  }
686
- const body = await axios.post(url, reqBody, {
791
+ const body = await axios_1.default.post(url, reqBody, {
687
792
  ...options,
688
793
  headers: {
689
794
  ...options.headers || {},
@@ -711,7 +816,7 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
711
816
  }
712
817
  }
713
818
  catch (error) {
714
- if (axios.isAxiosError(error)) {
819
+ if (axios_1.default.isAxiosError(error)) {
715
820
  result = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data;
716
821
  }
717
822
  const isLast = hostname === ((_b = hosts[uploadInfo.hosts.length - 1]) === null || _b === void 0 ? void 0 : _b.hostname);
@@ -728,14 +833,11 @@ exports.getWAUploadToServer = getWAUploadToServer;
728
833
  const getMediaRetryKey = (mediaKey) => {
729
834
  return (0, crypto_1.hkdf)(mediaKey, 32, { info: 'WhatsApp Media Retry Notification' });
730
835
  };
731
- /**
732
- * Generate a binary node that will request the phone to re-upload the media & return the newly uploaded URL
733
- */
734
- const encryptMediaRetryRequest = (key, mediaKey, meId) => {
836
+ const encryptMediaRetryRequest = async (key, mediaKey, meId) => {
735
837
  const recp = { stanzaId: key.id };
736
838
  const recpBuffer = WAProto_1.proto.ServerErrorReceipt.encode(recp).finish();
737
839
  const iv = Crypto.randomBytes(12);
738
- const retryKey = getMediaRetryKey(mediaKey);
840
+ const retryKey = await getMediaRetryKey(mediaKey);
739
841
  const ciphertext = (0, crypto_1.aesEncryptGCM)(recpBuffer, retryKey, iv, Buffer.from(key.id));
740
842
  const req = {
741
843
  tag: 'receipt',
@@ -745,9 +847,6 @@ const encryptMediaRetryRequest = (key, mediaKey, meId) => {
745
847
  type: 'server-error'
746
848
  },
747
849
  content: [
748
- // this encrypt node is actually pretty useless
749
- // the media is returned even without this node
750
- // keeping it here to maintain parity with WA Web
751
850
  {
752
851
  tag: 'encrypt',
753
852
  attrs: {},
@@ -761,7 +860,6 @@ const encryptMediaRetryRequest = (key, mediaKey, meId) => {
761
860
  attrs: {
762
861
  jid: key.remoteJid,
763
862
  'from_me': (!!key.fromMe).toString(),
764
- // @ts-ignore
765
863
  participant: key.participant || undefined
766
864
  }
767
865
  }
@@ -799,8 +897,8 @@ const decodeMediaRetryNode = (node) => {
799
897
  return event;
800
898
  };
801
899
  exports.decodeMediaRetryNode = decodeMediaRetryNode;
802
- const decryptMediaRetryData = ({ ciphertext, iv }, mediaKey, msgId) => {
803
- const retryKey = getMediaRetryKey(mediaKey);
900
+ const decryptMediaRetryData = async ({ ciphertext, iv }, mediaKey, msgId) => {
901
+ const retryKey = await getMediaRetryKey(mediaKey);
804
902
  const plaintext = (0, crypto_1.aesDecryptGCM)(ciphertext, retryKey, iv, Buffer.from(msgId));
805
903
  return WAProto_1.proto.MediaRetryNotification.decode(plaintext);
806
904
  };
@@ -813,7 +911,3 @@ const MEDIA_RETRY_STATUS_MAP = {
813
911
  [WAProto_1.proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
814
912
  [WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418,
815
913
  };
816
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
817
- function __importStar(arg0) {
818
- throw new Error('Function not implemented.');
819
- }