@d0v3riz/baileys 6.3.1 → 6.4.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 (51) hide show
  1. package/WAProto/WAProto.proto +58 -24
  2. package/WAProto/index.d.ts +649 -410
  3. package/WAProto/index.js +1632 -985
  4. package/lib/Defaults/baileys-version.json +1 -1
  5. package/lib/Defaults/index.js +1 -1
  6. package/lib/Socket/Client/abstract-socket-client.d.ts +1 -0
  7. package/lib/Socket/business.d.ts +4 -3
  8. package/lib/Socket/chats.d.ts +6 -5
  9. package/lib/Socket/groups.d.ts +3 -2
  10. package/lib/Socket/index.d.ts +9 -8
  11. package/lib/Socket/messages-recv.d.ts +5 -3
  12. package/lib/Socket/messages-recv.js +75 -2
  13. package/lib/Socket/messages-send.d.ts +3 -2
  14. package/lib/Socket/messages-send.js +13 -8
  15. package/lib/Socket/registration.d.ts +5 -4
  16. package/lib/Socket/socket.d.ts +4 -3
  17. package/lib/Socket/socket.js +69 -9
  18. package/lib/Store/make-in-memory-store.d.ts +2 -2
  19. package/lib/Types/Auth.d.ts +19 -17
  20. package/lib/Types/Call.d.ts +2 -2
  21. package/lib/Types/Chat.d.ts +13 -13
  22. package/lib/Types/Events.d.ts +3 -3
  23. package/lib/Types/GroupMetadata.d.ts +2 -2
  24. package/lib/Types/LabelAssociation.d.ts +2 -2
  25. package/lib/Types/Message.d.ts +57 -45
  26. package/lib/Types/Product.d.ts +14 -14
  27. package/lib/Types/Signal.d.ts +10 -10
  28. package/lib/Types/Socket.d.ts +5 -4
  29. package/lib/Types/State.d.ts +2 -2
  30. package/lib/Types/index.d.ts +5 -5
  31. package/lib/Utils/auth-utils.js +3 -1
  32. package/lib/Utils/chat-utils.d.ts +4 -4
  33. package/lib/Utils/crypto.d.ts +3 -0
  34. package/lib/Utils/crypto.js +15 -1
  35. package/lib/Utils/event-buffer.d.ts +2 -2
  36. package/lib/Utils/event-buffer.js +3 -3
  37. package/lib/Utils/generics.d.ts +7 -6
  38. package/lib/Utils/generics.js +25 -27
  39. package/lib/Utils/link-preview.d.ts +1 -1
  40. package/lib/Utils/link-preview.js +1 -24
  41. package/lib/Utils/make-mutex.d.ts +1 -1
  42. package/lib/Utils/messages-media.d.ts +9 -3
  43. package/lib/Utils/messages-media.js +54 -6
  44. package/lib/Utils/messages.d.ts +6 -5
  45. package/lib/Utils/messages.js +35 -1
  46. package/lib/Utils/process-message.d.ts +2 -2
  47. package/lib/Utils/validate-connection.js +1 -2
  48. package/lib/WABinary/jid-utils.d.ts +4 -4
  49. package/lib/WABinary/types.d.ts +4 -4
  50. package/lib/index.d.ts +1 -1
  51. package/package.json +6 -5
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { AxiosRequestConfig } from 'axios';
3
4
  import type { Agent } from 'https';
4
5
  import type { Logger } from 'pino';
@@ -7,9 +8,9 @@ import { proto } from '../../WAProto';
7
8
  import { AuthenticationState, SignalAuthState, TransactionCapabilityOptions } from './Auth';
8
9
  import { MediaConnInfo } from './Message';
9
10
  import { SignalRepository } from './Signal';
10
- export declare type WAVersion = [number, number, number];
11
- export declare type WABrowserDescription = [string, string, string];
12
- export declare type CacheStore = {
11
+ export type WAVersion = [number, number, number];
12
+ export type WABrowserDescription = [string, string, string];
13
+ export type CacheStore = {
13
14
  /** get a cached key and change the stats */
14
15
  get<T>(key: string): T | undefined;
15
16
  /** set a key in the cache */
@@ -19,7 +20,7 @@ export declare type CacheStore = {
19
20
  /** flush all data */
20
21
  flushAll(): void;
21
22
  };
22
- export declare type SocketConfig = {
23
+ export type SocketConfig = {
23
24
  /** the WS url to connect to WA */
24
25
  waWebSocketUrl: string | URL;
25
26
  /** Fails the connection if the socket times out in this interval */
@@ -1,6 +1,6 @@
1
1
  import { Contact } from './Contact';
2
- export declare type WAConnectionState = 'open' | 'connecting' | 'close';
3
- export declare type ConnectionState = {
2
+ export type WAConnectionState = 'open' | 'connecting' | 'close';
3
+ export type ConnectionState = {
4
4
  /** connection is now open, connecting or closed */
5
5
  connection: WAConnectionState;
6
6
  /** the error that caused the connection to close */
@@ -11,7 +11,7 @@ export * from './Call';
11
11
  export * from './Signal';
12
12
  import { AuthenticationState } from './Auth';
13
13
  import { SocketConfig } from './Socket';
14
- export declare type UserFacingSocketConfig = Partial<SocketConfig> & {
14
+ export type UserFacingSocketConfig = Partial<SocketConfig> & {
15
15
  auth: AuthenticationState;
16
16
  };
17
17
  export declare enum DisconnectReason {
@@ -24,18 +24,18 @@ export declare enum DisconnectReason {
24
24
  restartRequired = 515,
25
25
  multideviceMismatch = 411
26
26
  }
27
- export declare type WAInitResponse = {
27
+ export type WAInitResponse = {
28
28
  ref: string;
29
29
  ttl: number;
30
30
  status: 200;
31
31
  };
32
- export declare type WABusinessHoursConfig = {
32
+ export type WABusinessHoursConfig = {
33
33
  day_of_week: string;
34
34
  mode: string;
35
35
  open_time?: number;
36
36
  close_time?: number;
37
37
  };
38
- export declare type WABusinessProfile = {
38
+ export type WABusinessProfile = {
39
39
  description: string;
40
40
  email: string | undefined;
41
41
  business_hours: {
@@ -48,7 +48,7 @@ export declare type WABusinessProfile = {
48
48
  wid?: string;
49
49
  address?: string;
50
50
  };
51
- export declare type CurveKeyPair = {
51
+ export type CurveKeyPair = {
52
52
  private: Uint8Array;
53
53
  public: Uint8Array;
54
54
  };
@@ -179,6 +179,7 @@ const initAuthCreds = () => {
179
179
  const identityKey = crypto_2.Curve.generateKeyPair();
180
180
  return {
181
181
  noiseKey: crypto_2.Curve.generateKeyPair(),
182
+ pairingEphemeralKeyPair: crypto_2.Curve.generateKeyPair(),
182
183
  signedIdentityKey: identityKey,
183
184
  signedPreKey: (0, crypto_2.signedKeyPair)(identityKey, 1),
184
185
  registrationId: (0, generics_1.generateRegistrationId)(),
@@ -196,7 +197,8 @@ const initAuthCreds = () => {
196
197
  identityId: (0, crypto_1.randomBytes)(20),
197
198
  registered: false,
198
199
  backupToken: (0, crypto_1.randomBytes)(20),
199
- registration: {}
200
+ registration: {},
201
+ pairingCode: undefined,
200
202
  };
201
203
  };
202
204
  exports.initAuthCreds = initAuthCreds;
@@ -4,8 +4,8 @@ import type { Logger } from 'pino';
4
4
  import { proto } from '../../WAProto';
5
5
  import { BaileysEventEmitter, ChatModification, ChatMutation, Contact, InitialAppStateSyncOptions, LTHashState, WAPatchCreate, WAPatchName } from '../Types';
6
6
  import { BinaryNode } from '../WABinary';
7
- declare type FetchAppStateSyncKey = (keyId: string) => Promise<proto.Message.IAppStateSyncKeyData | null | undefined>;
8
- export declare type ChatMutationMap = {
7
+ type FetchAppStateSyncKey = (keyId: string) => Promise<proto.Message.IAppStateSyncKeyData | null | undefined>;
8
+ export type ChatMutationMap = {
9
9
  [index: string]: ChatMutation;
10
10
  };
11
11
  export declare const newLTHashState: () => LTHashState;
@@ -62,10 +62,10 @@ export declare const decodeSyncdSnapshot: (name: WAPatchName, snapshot: proto.IS
62
62
  state: LTHashState;
63
63
  mutationMap: ChatMutationMap;
64
64
  }>;
65
- export declare const decodePatches: (name: WAPatchName, syncds: proto.ISyncdPatch[], initial: LTHashState, getAppStateSyncKey: FetchAppStateSyncKey, options: AxiosRequestConfig<any>, minimumVersionNumber?: number | undefined, logger?: Logger<import("pino").LoggerOptions> | undefined, validateMacs?: boolean) => Promise<{
65
+ export declare const decodePatches: (name: WAPatchName, syncds: proto.ISyncdPatch[], initial: LTHashState, getAppStateSyncKey: FetchAppStateSyncKey, options: AxiosRequestConfig<any>, minimumVersionNumber?: number, logger?: Logger, validateMacs?: boolean) => Promise<{
66
66
  state: LTHashState;
67
67
  mutationMap: ChatMutationMap;
68
68
  }>;
69
69
  export declare const chatModificationToAppPatch: (mod: ChatModification, jid: string) => WAPatchCreate;
70
- export declare const processSyncAction: (syncAction: ChatMutation, ev: BaileysEventEmitter, me: Contact, initialSyncOpts?: InitialAppStateSyncOptions | undefined, logger?: Logger<import("pino").LoggerOptions> | undefined) => void;
70
+ export declare const processSyncAction: (syncAction: ChatMutation, ev: BaileysEventEmitter, me: Contact, initialSyncOpts?: InitialAppStateSyncOptions, logger?: Logger) => void;
71
71
  export {};
@@ -23,6 +23,8 @@ export declare function aesEncryptGCM(plaintext: Uint8Array, key: Uint8Array, iv
23
23
  * where the auth tag is suffixed to the ciphertext
24
24
  * */
25
25
  export declare function aesDecryptGCM(ciphertext: Uint8Array, key: Uint8Array, iv: Uint8Array, additionalData: Uint8Array): Buffer;
26
+ export declare function aesEncryptCTR(plaintext: Uint8Array, key: Uint8Array, iv: Uint8Array): Buffer;
27
+ export declare function aesDecryptCTR(ciphertext: Uint8Array, key: Uint8Array, iv: Uint8Array): Buffer;
26
28
  /** decrypt AES 256 CBC; where the IV is prefixed to the buffer */
27
29
  export declare function aesDecrypt(buffer: Buffer, key: Buffer): Buffer;
28
30
  /** decrypt AES 256 CBC */
@@ -36,3 +38,4 @@ export declare function hkdf(buffer: Uint8Array | Buffer, expandedLength: number
36
38
  salt?: Buffer;
37
39
  info?: string;
38
40
  }): Buffer;
41
+ export declare function derivePairingCodeKey(pairingCode: string, salt: Buffer): Buffer;
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.hkdf = exports.md5 = exports.sha256 = exports.hmacSign = exports.aesEncrypWithIV = exports.aesEncrypt = exports.aesDecryptWithIV = exports.aesDecrypt = exports.aesDecryptGCM = exports.aesEncryptGCM = exports.signedKeyPair = exports.Curve = exports.generateSignalPubKey = void 0;
29
+ exports.derivePairingCodeKey = exports.hkdf = exports.md5 = exports.sha256 = exports.hmacSign = exports.aesEncrypWithIV = exports.aesEncrypt = exports.aesDecryptWithIV = exports.aesDecrypt = exports.aesDecryptCTR = exports.aesEncryptCTR = exports.aesDecryptGCM = exports.aesEncryptGCM = exports.signedKeyPair = exports.Curve = exports.generateSignalPubKey = void 0;
30
30
  const crypto_1 = require("crypto");
31
31
  const futoin_hkdf_1 = __importDefault(require("futoin-hkdf"));
32
32
  const libsignal = __importStar(require("libsignal"));
@@ -93,6 +93,16 @@ function aesDecryptGCM(ciphertext, key, iv, additionalData) {
93
93
  return Buffer.concat([decipher.update(enc), decipher.final()]);
94
94
  }
95
95
  exports.aesDecryptGCM = aesDecryptGCM;
96
+ function aesEncryptCTR(plaintext, key, iv) {
97
+ const cipher = (0, crypto_1.createCipheriv)('aes-256-ctr', key, iv);
98
+ return Buffer.concat([cipher.update(plaintext), cipher.final()]);
99
+ }
100
+ exports.aesEncryptCTR = aesEncryptCTR;
101
+ function aesDecryptCTR(ciphertext, key, iv) {
102
+ const decipher = (0, crypto_1.createDecipheriv)('aes-256-ctr', key, iv);
103
+ return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
104
+ }
105
+ exports.aesDecryptCTR = aesDecryptCTR;
96
106
  /** decrypt AES 256 CBC; where the IV is prefixed to the buffer */
97
107
  function aesDecrypt(buffer, key) {
98
108
  return aesDecryptWithIV(buffer.slice(16, buffer.length), key, buffer.slice(0, 16));
@@ -135,3 +145,7 @@ function hkdf(buffer, expandedLength, info) {
135
145
  return (0, futoin_hkdf_1.default)(!Buffer.isBuffer(buffer) ? Buffer.from(buffer) : buffer, expandedLength, info);
136
146
  }
137
147
  exports.hkdf = hkdf;
148
+ function derivePairingCodeKey(pairingCode, salt) {
149
+ return (0, crypto_1.pbkdf2Sync)(pairingCode, salt, 2 << 16, 32, 'sha256');
150
+ }
151
+ exports.derivePairingCodeKey = derivePairingCodeKey;
@@ -7,8 +7,8 @@ import { BaileysEventEmitter, BaileysEventMap } from '../Types';
7
7
  * this can make processing events extremely efficient -- since everything
8
8
  * can be done in a single transaction
9
9
  */
10
- declare type BaileysEventData = Partial<BaileysEventMap>;
11
- declare type BaileysBufferableEventEmitter = BaileysEventEmitter & {
10
+ type BaileysEventData = Partial<BaileysEventMap>;
11
+ type BaileysBufferableEventEmitter = BaileysEventEmitter & {
12
12
  /** Use to process events in a batch */
13
13
  process(handler: (events: BaileysEventData) => void | Promise<void>): (() => void);
14
14
  /**
@@ -156,7 +156,7 @@ function append(data, historyCache, event, eventData, logger) {
156
156
  for (const contact of eventData.contacts) {
157
157
  const existingContact = data.historySets.contacts[contact.id];
158
158
  if (existingContact) {
159
- Object.assign(existingContact, (0, generics_1.trimUndefineds)(contact));
159
+ Object.assign(existingContact, (0, generics_1.trimUndefined)(contact));
160
160
  }
161
161
  else {
162
162
  const historyContactId = `c:${contact.id}`;
@@ -256,14 +256,14 @@ function append(data, historyCache, event, eventData, logger) {
256
256
  }
257
257
  }
258
258
  if (upsert) {
259
- upsert = Object.assign(upsert, (0, generics_1.trimUndefineds)(contact));
259
+ upsert = Object.assign(upsert, (0, generics_1.trimUndefined)(contact));
260
260
  }
261
261
  else {
262
262
  upsert = contact;
263
263
  data.contactUpserts[contact.id] = upsert;
264
264
  }
265
265
  if (data.contactUpdates[contact.id]) {
266
- upsert = Object.assign(data.contactUpdates[contact.id], (0, generics_1.trimUndefineds)(contact));
266
+ upsert = Object.assign(data.contactUpdates[contact.id], (0, generics_1.trimUndefined)(contact));
267
267
  delete data.contactUpdates[contact.id];
268
268
  }
269
269
  }
@@ -24,9 +24,9 @@ export declare const encodeBigEndian: (e: number, t?: number) => Uint8Array;
24
24
  export declare const toNumber: (t: Long | number | null | undefined) => number;
25
25
  /** unix timestamp of a date in seconds */
26
26
  export declare const unixTimestampSeconds: (date?: Date) => number;
27
- export declare type DebouncedTimeout = ReturnType<typeof debouncedTimeout>;
28
- export declare const debouncedTimeout: (intervalMs?: number, task?: (() => void) | undefined) => {
29
- start: (newIntervalMs?: number | undefined, newTask?: (() => void) | undefined) => void;
27
+ export type DebouncedTimeout = ReturnType<typeof debouncedTimeout>;
28
+ export declare const debouncedTimeout: (intervalMs?: number, task?: () => void) => {
29
+ start: (newIntervalMs?: number, newTask?: () => void) => void;
30
30
  cancel: () => void;
31
31
  setTask: (newTask: () => void) => () => void;
32
32
  setInterval: (newInterval: number) => number;
@@ -38,8 +38,8 @@ export declare const delayCancellable: (ms: number) => {
38
38
  };
39
39
  export declare function promiseTimeout<T>(ms: number | undefined, promise: (resolve: (v: T) => void, reject: (error: any) => void) => void): Promise<T>;
40
40
  export declare const generateMessageID: () => string;
41
- export declare function bindWaitForEvent<T extends keyof BaileysEventMap>(ev: BaileysEventEmitter, event: T): (check: (u: BaileysEventMap[T]) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
42
- export declare const bindWaitForConnectionUpdate: (ev: BaileysEventEmitter) => (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
41
+ export declare function bindWaitForEvent<T extends keyof BaileysEventMap>(ev: BaileysEventEmitter, event: T): (check: (u: BaileysEventMap[T]) => boolean | undefined, timeoutMs?: number) => Promise<void>;
42
+ export declare const bindWaitForConnectionUpdate: (ev: BaileysEventEmitter) => (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number) => Promise<void>;
43
43
  export declare const printQRIfNecessaryListener: (ev: BaileysEventEmitter, logger: Logger) => void;
44
44
  /**
45
45
  * utility that fetches latest baileys version from the master branch.
@@ -89,4 +89,5 @@ export declare const getCodeFromWSError: (error: Error) => number;
89
89
  * @param platform AuthenticationCreds.platform
90
90
  */
91
91
  export declare const isWABusinessPlatform: (platform: string) => boolean;
92
- export declare function trimUndefineds(obj: any): any;
92
+ export declare function trimUndefined(obj: any): any;
93
+ export declare function bytesToCrockford(buffer: Buffer): string;
@@ -1,32 +1,9 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
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;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.trimUndefineds = exports.isWABusinessPlatform = exports.getCodeFromWSError = exports.getCallStatusFromNode = exports.getErrorCodeFromStreamError = exports.getStatusFromReceiptType = exports.generateMdTagPrefix = exports.fetchLatestWaWebVersion = exports.fetchLatestBaileysVersion = exports.printQRIfNecessaryListener = exports.bindWaitForConnectionUpdate = exports.bindWaitForEvent = exports.generateMessageID = exports.promiseTimeout = exports.delayCancellable = exports.delay = exports.debouncedTimeout = exports.unixTimestampSeconds = exports.toNumber = exports.encodeBigEndian = exports.generateRegistrationId = exports.encodeWAMessage = exports.unpadRandomMax16 = exports.writeRandomPadMax16 = exports.getKeyAuthor = exports.BufferJSON = exports.Browsers = void 0;
6
+ exports.bytesToCrockford = exports.trimUndefined = exports.isWABusinessPlatform = exports.getCodeFromWSError = exports.getCallStatusFromNode = exports.getErrorCodeFromStreamError = exports.getStatusFromReceiptType = exports.generateMdTagPrefix = exports.fetchLatestWaWebVersion = exports.fetchLatestBaileysVersion = exports.printQRIfNecessaryListener = exports.bindWaitForConnectionUpdate = exports.bindWaitForEvent = exports.generateMessageID = exports.promiseTimeout = exports.delayCancellable = exports.delay = exports.debouncedTimeout = exports.unixTimestampSeconds = exports.toNumber = exports.encodeBigEndian = exports.generateRegistrationId = exports.encodeWAMessage = exports.unpadRandomMax16 = exports.writeRandomPadMax16 = exports.getKeyAuthor = exports.BufferJSON = exports.Browsers = void 0;
30
7
  const boom_1 = require("@hapi/boom");
31
8
  const axios_1 = __importDefault(require("axios"));
32
9
  const crypto_1 = require("crypto");
@@ -203,7 +180,9 @@ exports.bindWaitForConnectionUpdate = bindWaitForConnectionUpdate;
203
180
  const printQRIfNecessaryListener = (ev, logger) => {
204
181
  ev.on('connection.update', async ({ qr }) => {
205
182
  if (qr) {
206
- const QR = await Promise.resolve().then(() => __importStar(require('qrcode-terminal'))).catch(() => {
183
+ const QR = await import('qrcode-terminal')
184
+ .then(m => m.default || m)
185
+ .catch(() => {
207
186
  logger.error('QR code terminal not added as dependency');
208
187
  });
209
188
  QR === null || QR === void 0 ? void 0 : QR.generate(qr, { small: true });
@@ -357,7 +336,7 @@ const isWABusinessPlatform = (platform) => {
357
336
  return platform === 'smbi' || platform === 'smba';
358
337
  };
359
338
  exports.isWABusinessPlatform = isWABusinessPlatform;
360
- function trimUndefineds(obj) {
339
+ function trimUndefined(obj) {
361
340
  for (const key in obj) {
362
341
  if (typeof obj[key] === 'undefined') {
363
342
  delete obj[key];
@@ -365,4 +344,23 @@ function trimUndefineds(obj) {
365
344
  }
366
345
  return obj;
367
346
  }
368
- exports.trimUndefineds = trimUndefineds;
347
+ exports.trimUndefined = trimUndefined;
348
+ const CROCKFORD_CHARACTERS = '123456789ABCDEFGHJKLMNPQRSTVWXYZ';
349
+ function bytesToCrockford(buffer) {
350
+ let value = 0;
351
+ let bitCount = 0;
352
+ const crockford = [];
353
+ for (let i = 0; i < buffer.length; i++) {
354
+ value = (value << 8) | (buffer[i] & 0xff);
355
+ bitCount += 8;
356
+ while (bitCount >= 5) {
357
+ crockford.push(CROCKFORD_CHARACTERS.charAt((value >>> (bitCount - 5)) & 31));
358
+ bitCount -= 5;
359
+ }
360
+ }
361
+ if (bitCount > 0) {
362
+ crockford.push(CROCKFORD_CHARACTERS.charAt((value << (5 - bitCount)) & 31));
363
+ }
364
+ return crockford.join('');
365
+ }
366
+ exports.bytesToCrockford = bytesToCrockford;
@@ -1,7 +1,7 @@
1
1
  import { AxiosRequestConfig } from 'axios';
2
2
  import { Logger } from 'pino';
3
3
  import { WAMediaUploadFunction, WAUrlInfo } from '../Types';
4
- export declare type URLGenerationOptions = {
4
+ export type URLGenerationOptions = {
5
5
  thumbnailWidth: number;
6
6
  fetchOpts: {
7
7
  /** Timeout in ms */
@@ -1,27 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
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;
24
- };
25
2
  Object.defineProperty(exports, "__esModule", { value: true });
26
3
  exports.getUrlInfo = void 0;
27
4
  const messages_1 = require("./messages");
@@ -48,7 +25,7 @@ const getUrlInfo = async (text, opts = {
48
25
  // retries
49
26
  const retries = 0;
50
27
  const maxRetry = 5;
51
- const { getLinkPreview } = await Promise.resolve().then(() => __importStar(require('link-preview-js')));
28
+ const { getLinkPreview } = await import('link-preview-js');
52
29
  let previewLink = text;
53
30
  if (!text.startsWith('https://') && !text.startsWith('http://')) {
54
31
  previewLink = 'https://' + previewLink;
@@ -1,7 +1,7 @@
1
1
  export declare const makeMutex: () => {
2
2
  mutex<T>(code: () => T | Promise<T>): Promise<T>;
3
3
  };
4
- export declare type Mutex = ReturnType<typeof makeMutex>;
4
+ export type Mutex = ReturnType<typeof makeMutex>;
5
5
  export declare const makeKeyedMutex: () => {
6
6
  mutex<T>(key: string, task: () => T | Promise<T>): Promise<T>;
7
7
  };
@@ -1,4 +1,6 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
2
4
  import { Boom } from '@hapi/boom';
3
5
  import { AxiosRequestConfig } from 'axios';
4
6
  import type { Logger } from 'pino';
@@ -24,9 +26,13 @@ export declare const generateProfilePicture: (mediaUpload: WAMediaUpload) => Pro
24
26
  /** gets the SHA256 of the given media message */
25
27
  export declare const mediaMessageSHA256B64: (message: WAMessageContent) => string | null | undefined;
26
28
  export declare function getAudioDuration(buffer: Buffer | string | Readable): Promise<number | undefined>;
29
+ /**
30
+ referenced from and modifying https://github.com/wppconnect-team/wa-js/blob/main/src/chat/functions/prepareAudioWaveform.ts
31
+ */
32
+ export declare function getAudioWaveform(buffer: Buffer | string | Readable, logger?: Logger): Promise<Uint8Array | undefined>;
27
33
  export declare const toReadable: (buffer: Buffer) => Readable;
28
34
  export declare const toBuffer: (stream: Readable) => Promise<Buffer>;
29
- export declare const getStream: (item: WAMediaUpload, opts?: AxiosRequestConfig<any> | undefined) => Promise<{
35
+ export declare const getStream: (item: WAMediaUpload, opts?: AxiosRequestConfig) => Promise<{
30
36
  readonly stream: Readable;
31
37
  readonly type: "buffer";
32
38
  } | {
@@ -52,7 +58,7 @@ export declare function generateThumbnail(file: string, mediaType: 'video' | 'im
52
58
  export declare const getHttpStream: (url: string | URL, options?: AxiosRequestConfig & {
53
59
  isStream?: true;
54
60
  }) => Promise<Readable>;
55
- declare type EncryptedStreamOptions = {
61
+ type EncryptedStreamOptions = {
56
62
  saveOriginalFileIfRequired?: boolean;
57
63
  logger?: Logger;
58
64
  opts?: AxiosRequestConfig;
@@ -67,7 +73,7 @@ export declare const encryptedStream: (media: WAMediaUpload, mediaType: MediaTyp
67
73
  fileLength: number;
68
74
  didSaveToTmpPath: boolean;
69
75
  }>;
70
- export declare type MediaDownloadOptions = {
76
+ export type MediaDownloadOptions = {
71
77
  startByte?: number;
72
78
  endByte?: number;
73
79
  options?: AxiosRequestConfig<any>;
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  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.getHttpStream = exports.generateThumbnail = exports.getStream = exports.toBuffer = exports.toReadable = exports.getAudioDuration = exports.mediaMessageSHA256B64 = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.getMediaKeys = exports.hkdfInfoKey = void 0;
26
+ exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.extensionForMediaMessage = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = 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;
27
27
  const boom_1 = require("@hapi/boom");
28
28
  const child_process_1 = require("child_process");
29
29
  const Crypto = __importStar(require("crypto"));
@@ -41,11 +41,13 @@ const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
41
41
  const getImageProcessingLibrary = async () => {
42
42
  const [_jimp, sharp] = await Promise.all([
43
43
  (async () => {
44
- const jimp = await (Promise.resolve().then(() => __importStar(require('jimp'))).catch(() => { }));
44
+ const jimp = await (import('jimp')
45
+ .catch(() => { }));
45
46
  return jimp;
46
47
  })(),
47
48
  (async () => {
48
- const sharp = await (Promise.resolve().then(() => __importStar(require('sharp'))).catch(() => { }));
49
+ const sharp = await (import('sharp')
50
+ .catch(() => { }));
49
51
  return sharp;
50
52
  })()
51
53
  ]);
@@ -186,7 +188,7 @@ const mediaMessageSHA256B64 = (message) => {
186
188
  };
187
189
  exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
188
190
  async function getAudioDuration(buffer) {
189
- const musicMetadata = await Promise.resolve().then(() => __importStar(require('music-metadata')));
191
+ const musicMetadata = await import('music-metadata');
190
192
  let metadata;
191
193
  if (Buffer.isBuffer(buffer)) {
192
194
  metadata = await musicMetadata.parseBuffer(buffer, undefined, { duration: true });
@@ -206,6 +208,48 @@ async function getAudioDuration(buffer) {
206
208
  return metadata.format.duration;
207
209
  }
208
210
  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
+ async function getAudioWaveform(buffer, logger) {
215
+ try {
216
+ const audioDecode = (...args) => import('audio-decode').then(({ default: audioDecode }) => audioDecode(...args));
217
+ let audioData;
218
+ if (Buffer.isBuffer(buffer)) {
219
+ audioData = buffer;
220
+ }
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);
250
+ }
251
+ }
252
+ exports.getAudioWaveform = getAudioWaveform;
209
253
  const toReadable = (buffer) => {
210
254
  const readable = new stream_1.Readable({ read: () => { } });
211
255
  readable.push(buffer);
@@ -269,7 +313,7 @@ async function generateThumbnail(file, mediaType, options) {
269
313
  }
270
314
  exports.generateThumbnail = generateThumbnail;
271
315
  const getHttpStream = async (url, options = {}) => {
272
- const { default: axios } = await Promise.resolve().then(() => __importStar(require('axios')));
316
+ const { default: axios } = await import('axios');
273
317
  const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' });
274
318
  return fetched.data;
275
319
  };
@@ -481,7 +525,7 @@ exports.extensionForMediaMessage = extensionForMediaMessage;
481
525
  const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
482
526
  return async (stream, { mediaType, fileEncSha256B64, timeoutMs }) => {
483
527
  var _a, _b;
484
- const { default: axios } = await Promise.resolve().then(() => __importStar(require('axios')));
528
+ const { default: axios } = await import('axios');
485
529
  // send a query JSON to obtain the url & auth token to upload our media
486
530
  let uploadInfo = await refreshMediaConn(false);
487
531
  let urls;
@@ -630,3 +674,7 @@ const MEDIA_RETRY_STATUS_MAP = {
630
674
  [WAProto_1.proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
631
675
  [WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418,
632
676
  };
677
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
678
+ function __importStar(arg0) {
679
+ throw new Error('Function not implemented.');
680
+ }
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { Logger } from 'pino';
3
4
  import { proto } from '../../WAProto';
4
5
  import { AnyMediaMessageContent, AnyMessageContent, MediaGenerationOptions, MessageContentGenerationOptions, MessageGenerationOptions, MessageGenerationOptionsFromContent, MessageUserReceipt, WAMessage, WAMessageContent, WAProto } from '../Types';
@@ -11,13 +12,13 @@ import { MediaDownloadOptions } from './messages-media';
11
12
  export declare const extractUrlFromText: (text: string) => string | undefined;
12
13
  export declare const generateLinkPreviewIfRequired: (text: string, getUrlInfo: MessageGenerationOptions['getUrlInfo'], logger: MessageGenerationOptions['logger']) => Promise<import("../Types").WAUrlInfo | undefined>;
13
14
  export declare const prepareWAMessageMedia: (message: AnyMediaMessageContent, options: MediaGenerationOptions) => Promise<proto.Message>;
14
- export declare const prepareDisappearingMessageSettingContent: (ephemeralExpiration?: number | undefined) => proto.Message;
15
+ export declare const prepareDisappearingMessageSettingContent: (ephemeralExpiration?: number) => proto.Message;
15
16
  /**
16
17
  * Generate forwarded message content like WA does
17
18
  * @param message the message to forward
18
19
  * @param options.forceForward will show the message as forwarded even if it is from you
19
20
  */
20
- export declare const generateForwardMessageContent: (message: WAMessage, forceForward?: boolean | undefined) => proto.IMessage;
21
+ export declare const generateForwardMessageContent: (message: WAMessage, forceForward?: boolean) => proto.IMessage;
21
22
  export declare const generateWAMessageContent: (message: AnyMessageContent, options: MessageContentGenerationOptions) => Promise<proto.Message>;
22
23
  export declare const generateWAMessageFromContent: (jid: string, message: WAMessageContent, options: MessageGenerationOptionsFromContent) => proto.WebMessageInfo;
23
24
  export declare const generateWAMessage: (jid: string, content: AnyMessageContent, options: MessageGenerationOptions) => Promise<proto.WebMessageInfo>;
@@ -45,7 +46,7 @@ export declare const updateMessageWithReceipt: (msg: Pick<WAMessage, 'userReceip
45
46
  export declare const updateMessageWithReaction: (msg: Pick<WAMessage, 'reactions'>, reaction: proto.IReaction) => void;
46
47
  /** Update the message with a new poll update */
47
48
  export declare const updateMessageWithPollUpdate: (msg: Pick<WAMessage, 'pollUpdates'>, update: proto.IPollUpdate) => void;
48
- declare type VoteAggregation = {
49
+ type VoteAggregation = {
49
50
  name: string;
50
51
  voters: string[];
51
52
  };
@@ -62,14 +63,14 @@ export declare const aggregateMessageKeysNotFromMe: (keys: proto.IMessageKey[])
62
63
  participant: string | undefined;
63
64
  messageIds: string[];
64
65
  }[];
65
- declare type DownloadMediaMessageContext = {
66
+ type DownloadMediaMessageContext = {
66
67
  reuploadRequest: (msg: WAMessage) => Promise<WAMessage>;
67
68
  logger: Logger;
68
69
  };
69
70
  /**
70
71
  * Downloads the given message. Throws an error if it's not a media message
71
72
  */
72
- export declare const downloadMediaMessage: (message: WAMessage, type: 'buffer' | 'stream', options: MediaDownloadOptions, ctx?: DownloadMediaMessageContext | undefined) => Promise<Buffer | import("stream").Transform>;
73
+ export declare const downloadMediaMessage: (message: WAMessage, type: 'buffer' | 'stream', options: MediaDownloadOptions, ctx?: DownloadMediaMessageContext) => Promise<Buffer | import("stream").Transform>;
73
74
  /** Checks whether the given message is a media message; if it is returns the inner content */
74
75
  export declare const assertMediaContent: (content: proto.IMessage | null | undefined) => proto.Message.IVideoMessage | proto.Message.IImageMessage | proto.Message.IAudioMessage | proto.Message.IDocumentMessage | proto.Message.IStickerMessage;
75
76
  export {};
@@ -54,6 +54,20 @@ const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
54
54
  }
55
55
  };
56
56
  exports.generateLinkPreviewIfRequired = generateLinkPreviewIfRequired;
57
+ const assertColor = async (color) => {
58
+ let assertedColor;
59
+ if (typeof color === 'number') {
60
+ assertedColor = color > 0 ? color : 0xffffffff + Number(color) + 1;
61
+ }
62
+ else {
63
+ let hex = color.trim().replace('#', '');
64
+ if (hex.length <= 6) {
65
+ hex = 'FF' + hex.padStart(6, '0');
66
+ }
67
+ assertedColor = parseInt(hex, 16);
68
+ return assertedColor;
69
+ }
70
+ };
57
71
  const prepareWAMessageMedia = async (message, options) => {
58
72
  const logger = options.logger;
59
73
  let mediaType;
@@ -97,6 +111,8 @@ const prepareWAMessageMedia = async (message, options) => {
97
111
  const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
98
112
  const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
99
113
  (typeof uploadData['jpegThumbnail'] === 'undefined');
114
+ const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === 'true' || true;
115
+ const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === 'true' || true;
100
116
  const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
101
117
  const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath } = await (0, messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
102
118
  logger,
@@ -127,6 +143,18 @@ const prepareWAMessageMedia = async (message, options) => {
127
143
  uploadData.seconds = await (0, messages_media_1.getAudioDuration)(bodyPath);
128
144
  logger === null || logger === void 0 ? void 0 : logger.debug('computed audio duration');
129
145
  }
146
+ if (requiresWaveformProcessing) {
147
+ uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(bodyPath, logger);
148
+ logger === null || logger === void 0 ? void 0 : logger.debug('processed waveform');
149
+ }
150
+ if (requiresWaveformProcessing) {
151
+ uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(bodyPath, logger);
152
+ logger === null || logger === void 0 ? void 0 : logger.debug('processed waveform');
153
+ }
154
+ if (requiresAudioBackground) {
155
+ uploadData.backgroundArgb = await assertColor(options.backgroundColor);
156
+ logger === null || logger === void 0 ? void 0 : logger.debug('computed backgroundColor audio status');
157
+ }
130
158
  }
131
159
  catch (error) {
132
160
  logger === null || logger === void 0 ? void 0 : logger.warn({ trace: error.stack }, 'failed to obtain extra info');
@@ -235,6 +263,12 @@ const generateWAMessageContent = async (message, options) => {
235
263
  extContent.thumbnailEncSha256 = img.fileEncSha256;
236
264
  }
237
265
  }
266
+ if (options.backgroundColor) {
267
+ extContent.backgroundArgb = await assertColor(options.backgroundColor);
268
+ }
269
+ if (options.font) {
270
+ extContent.font = options.font;
271
+ }
238
272
  m.extendedTextMessage = extContent;
239
273
  }
240
274
  else if ('contacts' in message) {
@@ -466,7 +500,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
466
500
  message: message,
467
501
  messageTimestamp: timestamp,
468
502
  messageStubParameters: [],
469
- participant: (0, WABinary_1.isJidGroup)(jid) ? userJid : undefined,
503
+ participant: (0, WABinary_1.isJidGroup)(jid) || (0, WABinary_1.isJidStatusBroadcast)(jid) ? userJid : undefined,
470
504
  status: Types_1.WAMessageStatus.PENDING
471
505
  };
472
506
  return Types_1.WAProto.WebMessageInfo.fromObject(messageJSON);