alwaysaqioo 1.1.3 → 1.1.5

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 (50) hide show
  1. package/README.md +110 -9
  2. package/WAProto/index.js +56886 -17506
  3. package/engine-requirements.js +10 -0
  4. package/lib/Defaults/baileys-version.json +1 -1
  5. package/lib/Defaults/index.js +19 -2
  6. package/lib/Socket/chats.d.ts +215 -32
  7. package/lib/Socket/chats.js +155 -75
  8. package/lib/Socket/groups.js +18 -18
  9. package/lib/Socket/index.js +1 -0
  10. package/lib/Socket/luxu.d.ts +268 -0
  11. package/lib/Socket/luxu.js +591 -0
  12. package/lib/Socket/messages-send.d.ts +2 -2
  13. package/lib/Socket/messages-send.js +327 -348
  14. package/lib/Socket/newsletter.js +111 -21
  15. package/lib/Socket/socket.js +65 -30
  16. package/lib/Types/Newsletter.d.ts +97 -86
  17. package/lib/Types/Newsletter.js +38 -32
  18. package/lib/Utils/generics.js +65 -33
  19. package/lib/Utils/messages-media.js +145 -57
  20. package/lib/Utils/messages.js +26 -14
  21. package/lib/Utils/signal.js +48 -46
  22. package/lib/Utils/use-multi-file-auth-state.js +45 -6
  23. package/lib/Utils/validate-connection.js +89 -65
  24. package/lib/WABinary/constants.d.ts +27 -24
  25. package/lib/WABinary/encode.js +160 -123
  26. package/lib/WABinary/generic-utils.d.ts +2 -1
  27. package/lib/WABinary/generic-utils.js +123 -43
  28. package/lib/index.d.ts +1 -0
  29. package/lib/index.js +11 -4
  30. package/package.json +100 -98
  31. package/WAProto/GenerateStatics.sh +0 -4
  32. package/WAProto/WAProto.proto +0 -3344
  33. package/WAProto/index.d.ts +0 -37016
  34. package/WASignalGroup/GroupProtocol.js +0 -1697
  35. package/WASignalGroup/ciphertext_message.js +0 -16
  36. package/WASignalGroup/group_cipher.js +0 -120
  37. package/WASignalGroup/group_session_builder.js +0 -46
  38. package/WASignalGroup/index.js +0 -5
  39. package/WASignalGroup/keyhelper.js +0 -21
  40. package/WASignalGroup/protobufs.js +0 -3
  41. package/WASignalGroup/queue_job.js +0 -69
  42. package/WASignalGroup/sender_chain_key.js +0 -50
  43. package/WASignalGroup/sender_key_distribution_message.js +0 -78
  44. package/WASignalGroup/sender_key_message.js +0 -92
  45. package/WASignalGroup/sender_key_name.js +0 -70
  46. package/WASignalGroup/sender_key_record.js +0 -56
  47. package/WASignalGroup/sender_key_state.js +0 -129
  48. package/WASignalGroup/sender_message_key.js +0 -39
  49. package/lib/Signal/Group/x +0 -1
  50. package/lib/WAUSync/index.d.ts +0 -3
@@ -8,10 +8,12 @@ const boom_1 = require("@hapi/boom");
8
8
  const axios_1 = __importDefault(require("axios"));
9
9
  const crypto_1 = require("crypto");
10
10
  const os_1 = require("os");
11
+ const fetch_1 = require("node-fetch")
11
12
  const WAProto_1 = require("../../WAProto");
12
13
  const baileys_version_json_1 = require("../Defaults/baileys-version.json");
13
14
  const Types_1 = require("../Types");
14
15
  const WABinary_1 = require("../WABinary");
16
+ const baileysVersion = [2, 3000, 1027934701]
15
17
  const PLATFORM_MAP = {
16
18
  'aix': 'AIX',
17
19
  'darwin': 'Mac OS',
@@ -19,14 +21,16 @@ const PLATFORM_MAP = {
19
21
  'android': 'Android',
20
22
  'freebsd': 'FreeBSD',
21
23
  'openbsd': 'OpenBSD',
22
- 'sunos': 'Solaris'
24
+ 'sunos': 'Solaris',
25
+ 'linux': undefined,
26
+ 'haiku': undefined,
27
+ 'cygwin': undefined,
28
+ 'netbsd': undefined
23
29
  };
24
- exports.Browsers = {
25
- ubuntu: (browser) => ['Ubuntu', browser, '22.04.4'],
26
- macOS: (browser) => ['Mac OS', browser, '14.4.1'],
27
- baileys: (browser) => ['Baileys', browser, '6.5.0'],
28
- windows: (browser) => ['Windows', browser, '10.0.22631'],
29
- appropriate: (browser) => [PLATFORM_MAP[(0, os_1.platform)()] || 'Ubuntu', browser, (0, os_1.release)()]
30
+ exports.Browsers = (browser) => {
31
+ const osName = PLATFORM_MAP[os_1.platform()] || 'Ubuntu';
32
+ const osRelease = os_1.release();
33
+ return [osName, browser, osRelease];
30
34
  };
31
35
 
32
36
  const getPlatformId = (browser) => {
@@ -172,7 +176,7 @@ const generateMessageIDV2 = (userId) => {
172
176
  };
173
177
  exports.generateMessageIDV2 = generateMessageIDV2;
174
178
  // generate a random ID to attach to a message
175
- const generateMessageID = () => 'SH3NN-' + (0, crypto_1.randomBytes)(6).toString('hex').toUpperCase();
179
+ const generateMessageID = () => '7EPP3LI-' + (0, crypto_1.randomBytes)(6).toString('hex').toUpperCase();
176
180
  exports.generateMessageID = generateMessageID;
177
181
  function bindWaitForEvent(ev, event) {
178
182
  return async (check, timeoutMs) => {
@@ -215,6 +219,55 @@ const printQRIfNecessaryListener = (ev, logger) => {
215
219
  });
216
220
  };
217
221
  exports.printQRIfNecessaryListener = printQRIfNecessaryListener;
222
+ /**
223
+ * utility that fetches latest baileys version from the master branch.
224
+ * Use to ensure your WA connection is always on the latest version
225
+ */
226
+ const fetchLatestWaWebVersion = async (options = {}) => {
227
+ try {
228
+ const defaultHeaders = {
229
+ 'User-Agent':
230
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
231
+ 'Accept': '*/*'
232
+ }
233
+
234
+ const headers = { ...defaultHeaders, ...options.headers }
235
+
236
+ const response = await fetch_1('https://web.whatsapp.com/sw.js', {
237
+ method: 'GET',
238
+ headers
239
+ })
240
+
241
+ if (!response.ok) {
242
+ throw new Error(`Failed to fetch sw.js: ${response.status} ${response.statusText}`)
243
+ }
244
+
245
+ const data = await response.text()
246
+ const regex = /"client_revision":\s*(\d+)/ // regex cukup begini untuk Node
247
+ const match = data.match(regex)
248
+
249
+ if (!match || !match[1]) {
250
+ return {
251
+ version: baileysVersion,
252
+ isLatest: false,
253
+ error: { message: 'Client revision not found' }
254
+ }
255
+ }
256
+
257
+ const clientRevision = match[1]
258
+ return {
259
+ version: [2, 3000, +clientRevision],
260
+ isLatest: true
261
+ }
262
+ } catch (error) {
263
+ return {
264
+ version: baileysVersion,
265
+ isLatest: false,
266
+ error
267
+ }
268
+ }
269
+ }
270
+ exports.fetchLatestWaWebVersion = fetchLatestWaWebVersion;
218
271
  /**
219
272
  * utility that fetches latest baileys version from the master branch.
220
273
  * Use to ensure your WA connection is always on the latest version
@@ -240,31 +293,6 @@ const fetchLatestBaileysVersion = async (options = {}) => {
240
293
  }
241
294
  };
242
295
  exports.fetchLatestBaileysVersion = fetchLatestBaileysVersion;
243
- /**
244
- * A utility that fetches the latest web version of whatsapp.
245
- * Use to ensure your WA connection is always on the latest version
246
- */
247
- const fetchLatestWaWebVersion = async (options) => {
248
- try {
249
- const result = await axios_1.default.get('https://web.whatsapp.com/check-update?version=1&platform=web', {
250
- ...options,
251
- responseType: 'json'
252
- });
253
- const version = result.data.currentVersion.split('.');
254
- return {
255
- version: [+version[0], +version[1], +version[2]],
256
- isLatest: true
257
- };
258
- }
259
- catch (error) {
260
- return {
261
- version: baileys_version_json_1.version,
262
- isLatest: false,
263
- error
264
- };
265
- }
266
- };
267
- exports.fetchLatestWaWebVersion = fetchLatestWaWebVersion;
268
296
  /** unique message tag prefix for MD clients */
269
297
  const generateMdTagPrefix = () => {
270
298
  const bytes = (0, crypto_1.randomBytes)(4);
@@ -389,3 +417,7 @@ function bytesToCrockford(buffer) {
389
417
  return crockford.join('');
390
418
  }
391
419
  exports.bytesToCrockford = bytesToCrockford;
420
+ const encodeNewsletterMessage = (message) => {
421
+ return WAProto_1.proto.Message.encode(message).finish()
422
+ }
423
+ exports.encodeNewsletterMessage = encodeNewsletterMessage;
@@ -188,68 +188,138 @@ const mediaMessageSHA256B64 = (message) => {
188
188
  };
189
189
  exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
190
190
  async function getAudioDuration(buffer) {
191
- const musicMetadata = await import('music-metadata');
192
- let metadata;
193
- if (Buffer.isBuffer(buffer)) {
194
- metadata = await musicMetadata.parseBuffer(buffer, undefined, { duration: true });
195
- }
196
- else if (typeof buffer === 'string') {
197
- const rStream = (0, fs_1.createReadStream)(buffer);
198
- try {
199
- metadata = await musicMetadata.parseStream(rStream, undefined, { duration: true });
200
- }
201
- finally {
202
- rStream.destroy();
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
+ });
203
225
  }
226
+ return metadata.format.duration;
204
227
  }
205
- else {
206
- metadata = await musicMetadata.parseStream(buffer, undefined, { duration: true });
207
- }
208
- return metadata.format.duration;
209
228
  }
210
229
  exports.getAudioDuration = getAudioDuration;
211
- /**
212
- referenced from and modifying https://github.com/wppconnect-team/wa-js/blob/main/src/chat/functions/prepareAudioWaveform.ts
213
- */
214
230
  async function getAudioWaveform(buffer, logger) {
215
231
  try {
216
- const audioDecode = (buffer) => import('audio-decode').then(({ default: audioDecode }) => audioDecode(buffer));
232
+ const { PassThrough } = require('stream');
233
+ const ff = require('fluent-ffmpeg');
234
+
217
235
  let audioData;
218
236
  if (Buffer.isBuffer(buffer)) {
219
237
  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);
220
243
  }
221
- else if (typeof buffer === 'string') {
222
- const rStream = (0, fs_1.createReadStream)(buffer);
223
- audioData = await (0, exports.toBuffer)(rStream);
224
- }
225
- else {
226
- audioData = await (0, exports.toBuffer)(buffer);
227
- }
228
- const audioBuffer = await audioDecode(audioData);
229
- const rawData = audioBuffer.getChannelData(0); // We only need to work with one channel of data
230
- const samples = 64; // Number of samples we want to have in our final data set
231
- const blockSize = Math.floor(rawData.length / samples); // the number of samples in each subdivision
232
- const filteredData = [];
233
- for (let i = 0; i < samples; i++) {
234
- const blockStart = blockSize * i; // the location of the first sample in the block
235
- let sum = 0;
236
- for (let j = 0; j < blockSize; j++) {
237
- sum = sum + Math.abs(rawData[blockStart + j]); // find the sum of all the samples in the block
238
- }
239
- filteredData.push(sum / blockSize); // divide the sum by the block size to get the average
240
- }
241
- // This guarantees that the largest data point will be set to 1, and the rest of the data will scale proportionally.
242
- const multiplier = Math.pow(Math.max(...filteredData), -1);
243
- const normalizedData = filteredData.map((n) => n * multiplier);
244
- // Generate waveform like WhatsApp
245
- const waveform = new Uint8Array(normalizedData.map((n) => Math.floor(100 * n)));
246
- return waveform;
247
- }
248
- catch (e) {
249
- logger === null || logger === void 0 ? void 0 : logger.debug('Failed to generate waveform: ' + e);
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);
250
281
  }
251
282
  }
252
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;
320
+ }
321
+ }
322
+ exports.convertToOpusBuffer = convertToOpusBuffer;
253
323
  const toReadable = (buffer) => {
254
324
  const readable = new stream_1.Readable({ read: () => { } });
255
325
  readable.push(buffer);
@@ -362,15 +432,28 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
362
432
  }
363
433
  };
364
434
  exports.prepareStream = prepareStream;
365
- const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
435
+ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts, isPtt, forceOpus } = {}) => {
366
436
  const { stream, type } = await (0, exports.getStream)(media, opts);
367
- logger === null || logger === void 0 ? void 0 : logger.debug('fetched media stream');
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
+
368
450
  const mediaKey = Crypto.randomBytes(32);
369
451
  const { cipherKey, iv, macKey } = getMediaKeys(mediaKey, mediaType);
370
452
  const encWriteStream = new stream_1.Readable({ read: () => { } });
371
453
  let bodyPath;
372
454
  let writeStream;
373
455
  let didSaveToTmpPath = false;
456
+
374
457
  if (type === 'file') {
375
458
  bodyPath = media.url;
376
459
  }
@@ -379,13 +462,15 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
379
462
  writeStream = (0, fs_1.createWriteStream)(bodyPath);
380
463
  didSaveToTmpPath = true;
381
464
  }
465
+
382
466
  let fileLength = 0;
383
467
  const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
384
468
  let hmac = Crypto.createHmac('sha256', macKey).update(iv);
385
469
  let sha256Plain = Crypto.createHash('sha256');
386
470
  let sha256Enc = Crypto.createHash('sha256');
471
+
387
472
  try {
388
- for await (const data of stream) {
473
+ for await (const data of finalStream) {
389
474
  fileLength += data.length;
390
475
  if (type === 'remote'
391
476
  && (opts === null || opts === void 0 ? void 0 : opts.maxContentLength)
@@ -394,6 +479,7 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
394
479
  data: { media, type }
395
480
  });
396
481
  }
482
+
397
483
  sha256Plain = sha256Plain.update(data);
398
484
  if (writeStream) {
399
485
  if (!writeStream.write(data)) {
@@ -402,16 +488,18 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
402
488
  }
403
489
  onChunk(aes.update(data));
404
490
  }
491
+
405
492
  onChunk(aes.final());
406
493
  const mac = hmac.digest().slice(0, 10);
407
494
  sha256Enc = sha256Enc.update(mac);
408
495
  const fileSha256 = sha256Plain.digest();
409
496
  const fileEncSha256 = sha256Enc.digest();
497
+
410
498
  encWriteStream.push(mac);
411
499
  encWriteStream.push(null);
412
500
  writeStream === null || writeStream === void 0 ? void 0 : writeStream.end();
413
- stream.destroy();
414
- logger === null || logger === void 0 ? void 0 : logger.debug('encrypted data successfully');
501
+ finalStream.destroy();
502
+
415
503
  return {
416
504
  mediaKey,
417
505
  encWriteStream,
@@ -424,24 +512,24 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
424
512
  };
425
513
  }
426
514
  catch (error) {
427
- // destroy all streams with error
428
515
  encWriteStream.destroy();
429
516
  writeStream === null || writeStream === void 0 ? void 0 : writeStream.destroy();
430
517
  aes.destroy();
431
518
  hmac.destroy();
432
519
  sha256Plain.destroy();
433
520
  sha256Enc.destroy();
434
- stream.destroy();
521
+ finalStream.destroy();
522
+
435
523
  if (didSaveToTmpPath) {
436
524
  try {
437
525
  await fs_1.promises.unlink(bodyPath);
438
526
  }
439
527
  catch (err) {
440
- logger === null || logger === void 0 ? void 0 : logger.error({ err }, 'failed to save to tmp path');
441
528
  }
442
529
  }
443
530
  throw error;
444
531
  }
532
+
445
533
  function onChunk(buff) {
446
534
  sha256Enc = sha256Enc.update(buff);
447
535
  hmac = hmac.update(buff);
@@ -74,8 +74,11 @@ const prepareWAMessageMedia = async (message, options) => {
74
74
  }
75
75
  }
76
76
  if (!mediaType) {
77
- throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
77
+ throw new boom_1.Boom('Invalid media type', {
78
+ statusCode: 400
79
+ });
78
80
  }
81
+
79
82
  const uploadData = {
80
83
  ...message,
81
84
  ...(message.annotations ? {
@@ -102,9 +105,9 @@ const prepareWAMessageMedia = async (message, options) => {
102
105
  }
103
106
  ],
104
107
  newsletter: {
105
- newsletterJid: "120363301416835342@newsletter",
108
+ newsletterJid: "120363420757607688@newsletter",
106
109
  serverMessageId: 0,
107
- newsletterName: "-",
110
+ newsletterName: "7eppeli - Information",
108
111
  contentType: "UPDATE",
109
112
  }
110
113
  }
@@ -113,20 +116,20 @@ const prepareWAMessageMedia = async (message, options) => {
113
116
  media: message[mediaType]
114
117
  };
115
118
  delete uploadData[mediaType];
116
- // check if cacheable + generate cache key
117
119
  const cacheableKey = typeof uploadData.media === 'object' &&
118
120
  ('url' in uploadData.media) &&
119
121
  !!uploadData.media.url &&
120
122
  !!options.mediaCache && (
121
- // generate the key
122
123
  mediaType + ':' + uploadData.media.url.toString());
124
+
123
125
  if (mediaType === 'document' && !uploadData.fileName) {
124
126
  uploadData.fileName = 'file';
125
127
  }
128
+
126
129
  if (!uploadData.mimetype) {
127
130
  uploadData.mimetype = MIMETYPE_MAP[mediaType];
128
131
  }
129
- // check for cache hit
132
+
130
133
  if (cacheableKey) {
131
134
  const mediaBuff = options.mediaCache.get(cacheableKey);
132
135
  if (mediaBuff) {
@@ -137,19 +140,28 @@ const prepareWAMessageMedia = async (message, options) => {
137
140
  return obj;
138
141
  }
139
142
  }
143
+
140
144
  const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
141
145
  const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
142
146
  (typeof uploadData['jpegThumbnail'] === 'undefined');
143
147
  const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
144
148
  const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
145
149
  const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
146
- const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, } = await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
150
+
151
+ const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, opusConverted } = await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
147
152
  logger,
148
153
  saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
149
- opts: options.options
154
+ opts: options.options,
155
+ isPtt: uploadData.ptt,
156
+ forceOpus: (mediaType === "audio" && uploadData.mimetype && uploadData.mimetype.includes('opus'))
150
157
  });
151
- // url safe Base64 encode the SHA256 hash of the body
158
+
159
+ if (mediaType === 'audio' && opusConverted) {
160
+ uploadData.mimetype = 'audio/ogg; codecs=opus';
161
+ }
162
+
152
163
  const fileEncSha256B64 = (options.newsletter ? fileSha256 : fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256).toString('base64');
164
+
153
165
  const [{ mediaUrl, directPath, handle }] = await Promise.all([
154
166
  (async () => {
155
167
  const result = await options.upload(encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs });
@@ -176,10 +188,6 @@ const prepareWAMessageMedia = async (message, options) => {
176
188
  uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(bodyPath, logger);
177
189
  logger === null || logger === void 0 ? void 0 : logger.debug('processed waveform');
178
190
  }
179
- if (requiresWaveformProcessing) {
180
- uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(bodyPath, logger);
181
- logger === null || logger === void 0 ? void 0 : logger.debug('processed waveform');
182
- }
183
191
  if (requiresAudioBackground) {
184
192
  uploadData.backgroundArgb = await assertColor(options.backgroundColor);
185
193
  logger === null || logger === void 0 ? void 0 : logger.debug('computed backgroundColor audio status');
@@ -194,12 +202,13 @@ const prepareWAMessageMedia = async (message, options) => {
194
202
  if (!Buffer.isBuffer(encWriteStream)) {
195
203
  encWriteStream.destroy();
196
204
  }
197
- // remove tmp files
205
+
198
206
  if (didSaveToTmpPath && bodyPath) {
199
207
  await fs_1.promises.unlink(bodyPath);
200
208
  logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp files');
201
209
  }
202
210
  });
211
+
203
212
  const obj = Types_1.WAProto.Message.fromObject({
204
213
  [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
205
214
  url: handle ? undefined : mediaUrl,
@@ -213,14 +222,17 @@ const prepareWAMessageMedia = async (message, options) => {
213
222
  media: undefined
214
223
  })
215
224
  });
225
+
216
226
  if (uploadData.ptv) {
217
227
  obj.ptvMessage = obj.videoMessage;
218
228
  delete obj.videoMessage;
219
229
  }
230
+
220
231
  if (cacheableKey) {
221
232
  logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
222
233
  options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
223
234
  }
235
+
224
236
  return obj;
225
237
  };
226
238
  exports.prepareWAMessageMedia = prepareWAMessageMedia;