@blckrose/baileys 1.0.0 → 1.0.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.
@@ -1,4 +1,5 @@
1
1
  export * from './Auth.js';
2
+ export * from './MexUpdates.js';
2
3
  export * from './GroupMetadata.js';
3
4
  export * from './Chat.js';
4
5
  export * from './Contact.js';
@@ -0,0 +1,31 @@
1
+ import { Buffer } from 'buffer';
2
+ import fs from 'fs/promises';
3
+ import { Readable } from 'stream';
4
+ import { streamToBuffer } from './streamToBuffer.js';
5
+
6
+ /**
7
+ * Mengonversi berbagai input audio (Buffer, URL, path file, atau Readable stream) menjadi Buffer.
8
+ * @param {Buffer|string|Readable} audio Input audio.
9
+ * @returns {Promise<Buffer>} Buffer hasil konversi.
10
+ */
11
+ async function audioToBuffer(audio) {
12
+ if (Buffer.isBuffer(audio)) {
13
+ return audio;
14
+ }
15
+
16
+ if (typeof audio === 'string') {
17
+ if (/^https?:\/\//.test(audio)) {
18
+ const res = await fetch(audio); // native fetch bawaan Node 20
19
+ return Buffer.from(await res.arrayBuffer());
20
+ }
21
+ return fs.readFile(audio);
22
+ }
23
+
24
+ if (audio instanceof Readable) {
25
+ return streamToBuffer(audio);
26
+ }
27
+
28
+ throw new TypeError('Unsupported audio input type');
29
+ }
30
+
31
+ export { audioToBuffer };
@@ -0,0 +1,54 @@
1
+ import EventEmitter from 'events';
2
+ import { createReadStream } from 'fs';
3
+ import { writeFile } from 'fs/promises';
4
+ import { createInterface } from 'readline';
5
+ import { delay } from './generics.js';
6
+ import { makeMutex } from './make-mutex.js';
7
+
8
+ /**
9
+ * Captures events from a baileys event emitter & stores them in a file
10
+ * @param ev The event emitter to read events from
11
+ * @param filename File to save to
12
+ */
13
+ export const captureEventStream = (ev, filename) => {
14
+ const oldEmit = ev.emit;
15
+ // write mutex so data is appended in order
16
+ const writeMutex = makeMutex();
17
+ // monkey patch eventemitter to capture all events
18
+ ev.emit = function (...args) {
19
+ const content = JSON.stringify({ timestamp: Date.now(), event: args[0], data: args[1] }) + '\n';
20
+ const result = oldEmit.apply(ev, args);
21
+ writeMutex.mutex(async () => {
22
+ await writeFile(filename, content, { flag: 'a' });
23
+ });
24
+ return result;
25
+ };
26
+ };
27
+
28
+ /**
29
+ * Read event file and emit events from there
30
+ * @param filename filename containing event data
31
+ * @param delayIntervalMs delay between each event emit
32
+ */
33
+ export const readAndEmitEventStream = (filename, delayIntervalMs = 0) => {
34
+ const ev = new EventEmitter();
35
+ const fireEvents = async () => {
36
+ const fileStream = createReadStream(filename);
37
+ const rl = createInterface({
38
+ input: fileStream,
39
+ crlfDelay: Infinity
40
+ });
41
+ for await (const line of rl) {
42
+ if (line) {
43
+ const { event, data } = JSON.parse(line);
44
+ ev.emit(event, data);
45
+ delayIntervalMs && await delay(delayIntervalMs);
46
+ }
47
+ }
48
+ fileStream.close();
49
+ };
50
+ return {
51
+ ev,
52
+ task: fireEvents()
53
+ };
54
+ };
@@ -1,28 +1,41 @@
1
- import { platform, release } from 'os';
1
+ import { platform } from 'os';
2
2
  import { proto } from '../../WAProto/index.js';
3
- const PLATFORM_MAP = {
4
- aix: 'AIX',
5
- darwin: 'Mac OS',
6
- win32: 'Windows',
7
- android: 'Android',
8
- freebsd: 'FreeBSD',
9
- openbsd: 'OpenBSD',
10
- sunos: 'Solaris',
11
- linux: undefined,
12
- haiku: undefined,
13
- cygwin: undefined,
14
- netbsd: undefined
3
+ export const PLATFORM_MAP = {
4
+ 'aix':'AIX','darwin':'Mac OS','win32':'Windows','android':'Android',
5
+ 'freebsd':'FreeBSD','openbsd':'OpenBSD','sunos':'Solaris','linux':'Linux',
6
+ 'ubuntu':'Ubuntu','ios':'iOS','baileys':'Baileys','chromeos':'Chrome OS',
7
+ 'tizen':'Tizen','watchos':'watchOS','wearos':'Wear OS','harmonyos':'HarmonyOS',
8
+ 'kaios':'KaiOS','smarttv':'Smart TV','raspberrypi':'Raspberry Pi OS',
9
+ 'symbian':'Symbian','blackberry':'Blackberry OS','windowsphone':'Windows Phone'
10
+ };
11
+ export const PLATFORM_VERSIONS = {
12
+ 'ubuntu':'22.04.4','darwin':'18.5','win32':'10.0.22631','android':'14.0.0',
13
+ 'freebsd':'13.2','openbsd':'7.3','sunos':'11','linux':'6.5','ios':'18.2',
14
+ 'baileys':'6.5.0','chromeos':'117.0.5938.132','tizen':'6.5','watchos':'10.1',
15
+ 'wearos':'4.1','harmonyos':'4.0.0','kaios':'3.1','smarttv':'23.3.1',
16
+ 'raspberrypi':'11 (Bullseye)','symbian':'3','blackberry':'10.3.3','windowsphone':'8.1'
15
17
  };
16
18
  export const Browsers = {
17
- ubuntu: browser => ['Ubuntu', browser, '22.04.4'],
18
- macOS: browser => ['Mac OS', browser, '14.4.1'],
19
- baileys: browser => ['Baileys', browser, '6.5.0'],
20
- windows: browser => ['Windows', browser, '10.0.22631'],
21
- /** The appropriate browser based on your OS & release */
22
- appropriate: browser => [PLATFORM_MAP[platform()] || 'Ubuntu', browser, release()]
19
+ ubuntu: (browser) => [PLATFORM_MAP['ubuntu'], browser, PLATFORM_VERSIONS['ubuntu']],
20
+ macOS: (browser) => [PLATFORM_MAP['darwin'], browser, PLATFORM_VERSIONS['darwin']],
21
+ windows: (browser) => [PLATFORM_MAP['win32'], browser, PLATFORM_VERSIONS['win32']],
22
+ linux: (browser) => [PLATFORM_MAP['linux'], browser, PLATFORM_VERSIONS['linux']],
23
+ solaris: (browser) => [PLATFORM_MAP['sunos'], browser, PLATFORM_VERSIONS['sunos']],
24
+ baileys: (browser) => [PLATFORM_MAP['baileys'], browser, PLATFORM_VERSIONS['baileys']],
25
+ android: (browser) => [PLATFORM_MAP['android'], browser, PLATFORM_VERSIONS['android']],
26
+ iOS: (browser) => [PLATFORM_MAP['ios'], browser, PLATFORM_VERSIONS['ios']],
27
+ kaiOS: (browser) => [PLATFORM_MAP['kaios'], browser, PLATFORM_VERSIONS['kaios']],
28
+ chromeOS: (browser) => [PLATFORM_MAP['chromeos'], browser, PLATFORM_VERSIONS['chromeos']],
29
+ appropriate: (browser) => {
30
+ const p = platform();
31
+ return [PLATFORM_MAP[p] || 'Unknown OS', browser, PLATFORM_VERSIONS[p] || 'latest'];
32
+ },
33
+ custom: (p, browser, version) => {
34
+ return [PLATFORM_MAP[p.toLowerCase()] || p, browser, version || PLATFORM_VERSIONS[p] || 'latest'];
35
+ }
23
36
  };
24
37
  export const getPlatformId = (browser) => {
25
38
  const platformType = proto.DeviceProps.PlatformType[browser.toUpperCase()];
26
- return platformType ? platformType.toString() : '1'; //chrome
39
+ return platformType ? platformType.toString() : '1';
27
40
  };
28
41
  //# sourceMappingURL=browser-utils.js.map
@@ -1,5 +1,6 @@
1
1
  import { Boom } from '@hapi/boom';
2
2
  import { createHash, randomBytes } from 'crypto';
3
+ import axios from 'axios';
3
4
  import { proto } from '../../WAProto/index.js';
4
5
  const baileysVersion = [2, 3000, 1033105955];
5
6
  import { DisconnectReason } from '../Types/index.js';
@@ -381,4 +382,30 @@ export function bytesToCrockford(buffer) {
381
382
  export function encodeNewsletterMessage(message) {
382
383
  return proto.Message.encode(message).finish();
383
384
  }
385
+
386
+ export const COMPANION_PLATFORM_MAP = {
387
+ 'Chrome': '49', 'Edge': '50', 'Firefox': '51', 'Opera': '53', 'Safari': '54',
388
+ 'Brave': '1.79.112', 'Vivaldi': '6.2.3105.58', 'Tor': '12.5.3',
389
+ 'Yandex': '23.7.1', 'Falkon': '22.08.3', 'Epiphany': '44.2'
390
+ };
391
+ // Browsers, PLATFORM_MAP, PLATFORM_VERSIONS, getPlatformId moved to browser-utils.js
392
+ export const printQRIfNecessaryListener = (ev, logger) => {
393
+ ev.on('connection.update', async ({ qr }) => {
394
+ if (qr) {
395
+ const QR = await import('qrcode-terminal').then(m => m.default || m).catch(() => {
396
+ logger.error('QR code terminal not added as dependency');
397
+ });
398
+ QR?.generate(qr, { small: true });
399
+ }
400
+ });
401
+ };
402
+ export const toUnicodeEscape = (text) =>
403
+ text.split('').map(c => '\\u' + c.charCodeAt(0).toString(16).padStart(4, '0')).join('');
404
+ export const fromUnicodeEscape = (escapedText) =>
405
+ escapedText.replace(/\\u[\dA-Fa-f]{4}/g, m => String.fromCharCode(parseInt(m.slice(2), 16)));
406
+ export const asciiEncode = (text) => text.split('').map(c => c.charCodeAt(0));
407
+ export const asciiDecode = (...codes) => {
408
+ const arr = Array.isArray(codes[0]) ? codes[0] : codes;
409
+ return arr.map(c => String.fromCharCode(c)).join('');
410
+ };
384
411
  //# sourceMappingURL=generics.js.map
@@ -1,4 +1,6 @@
1
1
  export * from './generics.js';
2
+ export * from './audioToBuffer.js';
3
+ export * from './streamToBuffer.js';
2
4
  export * from './decode-wa-message.js';
3
5
  export * from './messages.js';
4
6
  export * from './messages-media.js';
@@ -11,6 +13,9 @@ export * from './chat-utils.js';
11
13
  export * from './lt-hash.js';
12
14
  export * from './auth-utils.js';
13
15
  export * from './use-multi-file-auth-state.js';
16
+ export * from './use-single-file-auth-state.js';
17
+ export * from './use-mongo-file-auth-state.js';
18
+ export * from './baileys-event-stream.js';
14
19
  export * from './link-preview.js';
15
20
  export * from './event-buffer.js';
16
21
  export * from './process-message.js';
@@ -1,7 +1,9 @@
1
+ import { spawn } from 'child_process';
2
+ import { once } from 'events';
3
+ import { unlink as unlinkFs } from 'fs/promises';
1
4
  import { Boom } from '@hapi/boom';
2
5
  import { exec } from 'child_process';
3
6
  import * as Crypto from 'crypto';
4
- import { once } from 'events';
5
7
  import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs';
6
8
  import { tmpdir } from 'os';
7
9
  import { join } from 'path';
@@ -771,4 +773,45 @@ const MEDIA_RETRY_STATUS_MAP = {
771
773
  [proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
772
774
  [proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418
773
775
  };
776
+
777
+ export const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
778
+ const { stream, type } = await getStream(media, opts);
779
+ logger?.debug('fetched media stream');
780
+ const encFilePath = join(tmpdir(), mediaType + generateMessageID() + '-plain');
781
+ const encFileWriteStream = createWriteStream(encFilePath);
782
+ let originalFilePath;
783
+ let originalFileStream;
784
+ if (type === 'file') {
785
+ originalFilePath = media.url.toString();
786
+ } else if (saveOriginalFileIfRequired) {
787
+ originalFilePath = join(tmpdir(), mediaType + generateMessageID() + '-original');
788
+ originalFileStream = createWriteStream(originalFilePath);
789
+ }
790
+ let fileLength = 0;
791
+ const hashCtx = createHashCrypto('sha256');
792
+ try {
793
+ for await (const data of stream) {
794
+ fileLength += data.length;
795
+ hashCtx.update(data);
796
+ encFileWriteStream.write(data);
797
+ if (originalFileStream && !originalFileStream.write(data)) {
798
+ await once(originalFileStream, 'drain');
799
+ }
800
+ }
801
+ const fileSha256 = hashCtx.digest();
802
+ encFileWriteStream.end();
803
+ originalFileStream?.end?.call(originalFileStream);
804
+ stream.destroy();
805
+ logger?.debug('prepared plain stream successfully');
806
+ return { mediaKey: undefined, originalFilePath, encFilePath, mac: undefined, fileEncSha256: undefined, fileSha256, fileLength };
807
+ } catch (error) {
808
+ encFileWriteStream.destroy();
809
+ originalFileStream?.destroy?.call(originalFileStream);
810
+ stream.destroy();
811
+ try {
812
+ await unlinkFs(encFilePath);
813
+ } catch (err) { logger?.error({ err }, 'failed deleting tmp files'); }
814
+ throw error;
815
+ }
816
+ };
774
817
  //# sourceMappingURL=messages-media.js.map