@queenanya/baileys 6.8.6 → 6.9.1

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 (39) hide show
  1. package/lib/Defaults/index.d.ts +0 -1
  2. package/lib/Defaults/index.js +3 -4
  3. package/lib/Socket/business.d.ts +2 -1
  4. package/lib/Socket/chats.d.ts +1 -0
  5. package/lib/Socket/chats.js +7 -23
  6. package/lib/Socket/groups.d.ts +1 -0
  7. package/lib/Socket/groups.js +2 -1
  8. package/lib/Socket/index.d.ts +2 -1
  9. package/lib/Socket/messages-recv.d.ts +2 -1
  10. package/lib/Socket/messages-recv.js +8 -4
  11. package/lib/Socket/messages-send.d.ts +1 -0
  12. package/lib/Socket/registration.d.ts +2 -1
  13. package/lib/Socket/socket.d.ts +1 -0
  14. package/lib/Socket/socket.js +22 -4
  15. package/lib/Store/make-cache-manager-store.d.ts +1 -1
  16. package/lib/Store/make-in-memory-store.d.ts +3 -2
  17. package/lib/Store/make-in-memory-store.js +23 -5
  18. package/lib/Types/Auth.d.ts +1 -0
  19. package/lib/Types/GroupMetadata.d.ts +3 -1
  20. package/lib/Types/Message.d.ts +4 -0
  21. package/lib/Utils/auth-utils.js +1 -0
  22. package/lib/Utils/decode-wa-message.js +10 -5
  23. package/lib/Utils/generics.js +1 -1
  24. package/lib/Utils/link-preview.js +1 -1
  25. package/lib/Utils/messages.js +11 -9
  26. package/lib/Utils/process-message.js +2 -1
  27. package/lib/Utils/validate-connection.js +16 -2
  28. package/lib/WAM/BinaryInfo.d.ts +17 -0
  29. package/lib/WAM/BinaryInfo.js +13 -0
  30. package/lib/WAM/constants.d.ts +38 -0
  31. package/lib/WAM/constants.js +15350 -0
  32. package/lib/WAM/encode.d.ts +3 -0
  33. package/lib/WAM/encode.js +155 -0
  34. package/lib/WAM/index.d.ts +3 -0
  35. package/lib/WAM/index.js +19 -0
  36. package/lib/index.d.ts +1 -0
  37. package/lib/index.js +1 -0
  38. package/package.json +5 -4
  39. package/WASignalGroup/readme.md +0 -6
@@ -244,7 +244,6 @@ export declare const PROTOCOL_VERSION: number[];
244
244
  export declare const MOBILE_NOISE_HEADER: Buffer;
245
245
  /** from: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url */
246
246
  export declare const URL_REGEX: RegExp;
247
- export declare const URL_EXCLUDE_REGEX: RegExp;
248
247
  export declare const WA_CERT_DETAILS: {
249
248
  SERIAL: number;
250
249
  };
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DEFAULT_CACHE_TTLS = exports.INITIAL_PREKEY_COUNT = exports.MIN_PREKEY_COUNT = exports.MEDIA_KEYS = exports.MEDIA_HKDF_KEY_MAPPING = exports.MEDIA_PATH_MAP = exports.DEFAULT_CONNECTION_CONFIG = exports.PROCESSABLE_HISTORY_TYPES = exports.WA_CERT_DETAILS = exports.URL_EXCLUDE_REGEX = exports.URL_REGEX = exports.MOBILE_NOISE_HEADER = exports.PROTOCOL_VERSION = exports.NOISE_WA_HEADER = exports.KEY_BUNDLE_TYPE = exports.DICT_VERSION = exports.NOISE_MODE = exports.REGISTRATION_PUBLIC_KEY = exports.MOBILE_USERAGENT = exports.MOBILE_REGISTRATION_ENDPOINT = exports.MOBILE_TOKEN = exports.WA_DEFAULT_EPHEMERAL = exports.PHONE_CONNECTION_CB = exports.DEF_TAG_PREFIX = exports.DEF_CALLBACK_PREFIX = exports.MOBILE_PORT = exports.MOBILE_ENDPOINT = exports.DEFAULT_ORIGIN = exports.PHONENUMBER_MCC = exports.UNAUTHORIZED_CODES = void 0;
6
+ exports.DEFAULT_CACHE_TTLS = exports.INITIAL_PREKEY_COUNT = exports.MIN_PREKEY_COUNT = exports.MEDIA_KEYS = exports.MEDIA_HKDF_KEY_MAPPING = exports.MEDIA_PATH_MAP = exports.DEFAULT_CONNECTION_CONFIG = exports.PROCESSABLE_HISTORY_TYPES = exports.WA_CERT_DETAILS = exports.URL_REGEX = exports.MOBILE_NOISE_HEADER = exports.PROTOCOL_VERSION = exports.NOISE_WA_HEADER = exports.KEY_BUNDLE_TYPE = exports.DICT_VERSION = exports.NOISE_MODE = exports.REGISTRATION_PUBLIC_KEY = exports.MOBILE_USERAGENT = exports.MOBILE_REGISTRATION_ENDPOINT = exports.MOBILE_TOKEN = exports.WA_DEFAULT_EPHEMERAL = exports.PHONE_CONNECTION_CB = exports.DEF_TAG_PREFIX = exports.DEF_CALLBACK_PREFIX = exports.MOBILE_PORT = exports.MOBILE_ENDPOINT = exports.DEFAULT_ORIGIN = exports.PHONENUMBER_MCC = exports.UNAUTHORIZED_CODES = void 0;
7
7
  const crypto_1 = require("crypto");
8
8
  const WAProto_1 = require("../../WAProto");
9
9
  const libsignal_1 = require("../Signal/libsignal");
@@ -20,7 +20,7 @@ exports.DEF_CALLBACK_PREFIX = 'CB:';
20
20
  exports.DEF_TAG_PREFIX = 'TAG:';
21
21
  exports.PHONE_CONNECTION_CB = 'CB:Pong';
22
22
  exports.WA_DEFAULT_EPHEMERAL = 7 * 24 * 60 * 60;
23
- const WA_VERSION = '2.24.3.23';
23
+ const WA_VERSION = '2.24.6.77';
24
24
  const WA_VERSION_HASH = (0, crypto_1.createHash)('md5').update(WA_VERSION).digest('hex');
25
25
  exports.MOBILE_TOKEN = Buffer.from('0a1mLfGUIBVrMKF1RdvLI5lkRBvof6vn0fD2QRSM' + WA_VERSION_HASH);
26
26
  exports.MOBILE_REGISTRATION_ENDPOINT = 'https://v.whatsapp.net/v2';
@@ -37,7 +37,6 @@ exports.PROTOCOL_VERSION = [5, 2];
37
37
  exports.MOBILE_NOISE_HEADER = Buffer.concat([Buffer.from('WA'), Buffer.from(exports.PROTOCOL_VERSION)]);
38
38
  /** from: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url */
39
39
  exports.URL_REGEX = /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/;
40
- exports.URL_EXCLUDE_REGEX = /.*@.*/;
41
40
  exports.WA_CERT_DETAILS = {
42
41
  SERIAL: 0,
43
42
  };
@@ -49,7 +48,7 @@ exports.PROCESSABLE_HISTORY_TYPES = [
49
48
  ];
50
49
  exports.DEFAULT_CONNECTION_CONFIG = {
51
50
  version: baileys_version_json_1.version,
52
- browser: Utils_1.Browsers.windows('Firefox'),
51
+ browser: Utils_1.Browsers.ubuntu("Firefox"),
53
52
  waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat',
54
53
  connectTimeoutMs: 20000,
55
54
  keepAliveIntervalMs: 30000,
@@ -15,7 +15,7 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
15
15
  deleted: number;
16
16
  }>;
17
17
  productUpdate: (productId: string, update: ProductUpdate) => Promise<import("../Types").Product>;
18
- sendMessageAck: ({ tag, attrs }: BinaryNode) => Promise<void>;
18
+ sendMessageAck: ({ tag, attrs, content }: BinaryNode) => Promise<void>;
19
19
  sendRetryRequest: (node: BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
20
20
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
21
21
  getPrivacyTokens: (jids: string[]) => Promise<BinaryNode>;
@@ -132,4 +132,5 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
132
132
  uploadPreKeysToServerIfRequired: () => Promise<void>;
133
133
  requestPairingCode: (phoneNumber: string) => Promise<string>;
134
134
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
135
+ sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>;
135
136
  };
@@ -76,4 +76,5 @@ export declare const makeChatsSocket: (config: SocketConfig) => {
76
76
  uploadPreKeysToServerIfRequired: () => Promise<void>;
77
77
  requestPairingCode: (phoneNumber: string) => Promise<string>;
78
78
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
79
+ sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>;
79
80
  };
@@ -597,29 +597,9 @@ const makeChatsSocket = (config) => {
597
597
  }
598
598
  }
599
599
  };
600
- /** sending abt props may fix QR scan fail if server expects */
601
- const fetchAbt = async () => {
602
- const abtNode = await query({
603
- tag: 'iq',
604
- attrs: {
605
- to: WABinary_1.S_WHATSAPP_NET,
606
- xmlns: 'abt',
607
- type: 'get',
608
- },
609
- content: [
610
- { tag: 'props', attrs: { protocol: '1' } }
611
- ]
612
- });
613
- const propsNode = (0, WABinary_1.getBinaryNodeChild)(abtNode, 'props');
614
- let props = {};
615
- if (propsNode) {
616
- props = (0, WABinary_1.reduceBinaryNodeToDictionary)(propsNode, 'prop');
617
- }
618
- logger.debug('fetched abt');
619
- return props;
620
- };
621
600
  /** sending non-abt props may fix QR scan fail if server expects */
622
601
  const fetchProps = async () => {
602
+ var _a, _b;
623
603
  const resultNode = await query({
624
604
  tag: 'iq',
625
605
  attrs: {
@@ -628,12 +608,17 @@ const makeChatsSocket = (config) => {
628
608
  type: 'get',
629
609
  },
630
610
  content: [
631
- { tag: 'props', attrs: {} }
611
+ { tag: 'props', attrs: {
612
+ protocol: '2',
613
+ hash: ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.lastPropHash) || ""
614
+ } }
632
615
  ]
633
616
  });
634
617
  const propsNode = (0, WABinary_1.getBinaryNodeChild)(resultNode, 'props');
635
618
  let props = {};
636
619
  if (propsNode) {
620
+ authState.creds.lastPropHash = (_b = propsNode === null || propsNode === void 0 ? void 0 : propsNode.attrs) === null || _b === void 0 ? void 0 : _b.hash;
621
+ ev.emit('creds.update', authState.creds);
637
622
  props = (0, WABinary_1.reduceBinaryNodeToDictionary)(propsNode, 'prop');
638
623
  }
639
624
  logger.debug('fetched props');
@@ -707,7 +692,6 @@ const makeChatsSocket = (config) => {
707
692
  * */
708
693
  const executeInitQueries = async () => {
709
694
  await Promise.all([
710
- fetchAbt(),
711
695
  fetchProps(),
712
696
  fetchBlocklist(),
713
697
  fetchPrivacySettings(),
@@ -109,5 +109,6 @@ export declare const makeGroupsSocket: (config: SocketConfig) => {
109
109
  uploadPreKeysToServerIfRequired: () => Promise<void>;
110
110
  requestPairingCode: (phoneNumber: string) => Promise<string>;
111
111
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
112
+ sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>;
112
113
  };
113
114
  export declare const extractGroupMetadata: (result: BinaryNode) => GroupMetadata;
@@ -261,7 +261,7 @@ const makeGroupsSocket = (config) => {
261
261
  };
262
262
  exports.makeGroupsSocket = makeGroupsSocket;
263
263
  const extractGroupMetadata = (result) => {
264
- var _a;
264
+ var _a, _b;
265
265
  const group = (0, WABinary_1.getBinaryNodeChild)(result, 'group');
266
266
  const descChild = (0, WABinary_1.getBinaryNodeChild)(group, 'description');
267
267
  let desc;
@@ -283,6 +283,7 @@ const extractGroupMetadata = (result) => {
283
283
  owner: group.attrs.creator ? (0, WABinary_1.jidNormalizedUser)(group.attrs.creator) : undefined,
284
284
  desc,
285
285
  descId,
286
+ linkedParent: ((_b = (0, WABinary_1.getBinaryNodeChild)(group, 'linked_parent')) === null || _b === void 0 ? void 0 : _b.attrs.jid) || undefined,
286
287
  restrict: !!(0, WABinary_1.getBinaryNodeChild)(group, 'locked'),
287
288
  announce: !!(0, WABinary_1.getBinaryNodeChild)(group, 'announcement'),
288
289
  isCommunity: !!(0, WABinary_1.getBinaryNodeChild)(group, 'parent'),
@@ -16,7 +16,7 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
16
16
  deleted: number;
17
17
  }>;
18
18
  productUpdate: (productId: string, update: import("../Types").ProductUpdate) => Promise<import("../Types").Product>;
19
- sendMessageAck: ({ tag, attrs }: import("../index").BinaryNode) => Promise<void>;
19
+ sendMessageAck: ({ tag, attrs, content }: import("../index").BinaryNode) => Promise<void>;
20
20
  sendRetryRequest: (node: import("../index").BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
21
21
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
22
22
  getPrivacyTokens: (jids: string[]) => Promise<import("../index").BinaryNode>;
@@ -133,5 +133,6 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
133
133
  uploadPreKeysToServerIfRequired: () => Promise<void>;
134
134
  requestPairingCode: (phoneNumber: string) => Promise<string>;
135
135
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
136
+ sendWAMBuffer: (wamBuffer: Buffer) => Promise<import("../index").BinaryNode>;
136
137
  };
137
138
  export default makeWASocket;
@@ -4,7 +4,7 @@ import { proto } from '../../WAProto';
4
4
  import { MessageReceiptType, MessageRelayOptions, SocketConfig } from '../Types';
5
5
  import { BinaryNode } from '../WABinary';
6
6
  export declare const makeMessagesRecvSocket: (config: SocketConfig) => {
7
- sendMessageAck: ({ tag, attrs }: BinaryNode) => Promise<void>;
7
+ sendMessageAck: ({ tag, attrs, content }: BinaryNode) => Promise<void>;
8
8
  sendRetryRequest: (node: BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
9
9
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
10
10
  getPrivacyTokens: (jids: string[]) => Promise<BinaryNode>;
@@ -121,4 +121,5 @@ export declare const makeMessagesRecvSocket: (config: SocketConfig) => {
121
121
  uploadPreKeysToServerIfRequired: () => Promise<void>;
122
122
  requestPairingCode: (phoneNumber: string) => Promise<string>;
123
123
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
124
+ sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>;
124
125
  };
@@ -31,7 +31,7 @@ const makeMessagesRecvSocket = (config) => {
31
31
  useClones: false
32
32
  });
33
33
  let sendActiveReceipts = false;
34
- const sendMessageAck = async ({ tag, attrs }) => {
34
+ const sendMessageAck = async ({ tag, attrs, content }) => {
35
35
  const stanza = {
36
36
  tag: 'ack',
37
37
  attrs: {
@@ -46,9 +46,12 @@ const makeMessagesRecvSocket = (config) => {
46
46
  if (!!attrs.recipient) {
47
47
  stanza.attrs.recipient = attrs.recipient;
48
48
  }
49
- if (tag !== 'message' && attrs.type) {
49
+ if (!!attrs.type && (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable'))) {
50
50
  stanza.attrs.type = attrs.type;
51
51
  }
52
+ if (tag === 'message' && (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable')) {
53
+ stanza.attrs.from = authState.creds.me.id;
54
+ }
52
55
  logger.debug({ recv: { tag, attrs }, sent: stanza.attrs }, 'sent ack');
53
56
  await sendNode(stanza);
54
57
  };
@@ -237,6 +240,7 @@ const makeMessagesRecvSocket = (config) => {
237
240
  }
238
241
  };
239
242
  const processNotification = async (node) => {
243
+ var _a, _b, _c;
240
244
  const result = {};
241
245
  const [child] = (0, WABinary_1.getAllBinaryNodeChildren)(node);
242
246
  const nodeType = node.attrs.type;
@@ -283,8 +287,8 @@ const makeMessagesRecvSocket = (config) => {
283
287
  const setPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'set');
284
288
  const delPicture = (0, WABinary_1.getBinaryNodeChild)(node, 'delete');
285
289
  ev.emit('contacts.update', [{
286
- id: from,
287
- imgUrl: setPicture ? 'changed' : null
290
+ id: (0, WABinary_1.jidNormalizedUser)((_a = node === null || node === void 0 ? void 0 : node.attrs) === null || _a === void 0 ? void 0 : _a.jid) || ((_c = (_b = (setPicture || delPicture)) === null || _b === void 0 ? void 0 : _b.attrs) === null || _c === void 0 ? void 0 : _c.hash) || '',
291
+ imgUrl: setPicture ? 'changed' : 'removed'
288
292
  }]);
289
293
  if ((0, WABinary_1.isJidGroup)(from)) {
290
294
  const node = setPicture || delPicture;
@@ -116,4 +116,5 @@ export declare const makeMessagesSocket: (config: SocketConfig) => {
116
116
  uploadPreKeysToServerIfRequired: () => Promise<void>;
117
117
  requestPairingCode: (phoneNumber: string) => Promise<string>;
118
118
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
119
+ sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>;
119
120
  };
@@ -17,7 +17,7 @@ export declare const makeRegistrationSocket: (config: SocketConfig) => {
17
17
  deleted: number;
18
18
  }>;
19
19
  productUpdate: (productId: string, update: import("../Types").ProductUpdate) => Promise<import("../Types").Product>;
20
- sendMessageAck: ({ tag, attrs }: import("../WABinary").BinaryNode) => Promise<void>;
20
+ sendMessageAck: ({ tag, attrs, content }: import("../WABinary").BinaryNode) => Promise<void>;
21
21
  sendRetryRequest: (node: import("../WABinary").BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
22
22
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
23
23
  getPrivacyTokens: (jids: string[]) => Promise<import("../WABinary").BinaryNode>;
@@ -137,6 +137,7 @@ export declare const makeRegistrationSocket: (config: SocketConfig) => {
137
137
  uploadPreKeysToServerIfRequired: () => Promise<void>;
138
138
  requestPairingCode: (phoneNumber: string) => Promise<string>;
139
139
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
140
+ sendWAMBuffer: (wamBuffer: Buffer) => Promise<import("../WABinary").BinaryNode>;
140
141
  };
141
142
  export interface RegistrationData {
142
143
  registrationId: number;
@@ -38,5 +38,6 @@ export declare const makeSocket: (config: SocketConfig) => {
38
38
  requestPairingCode: (phoneNumber: string) => Promise<string>;
39
39
  /** Waits for the connection to WA to reach a state */
40
40
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number | undefined) => Promise<void>;
41
+ sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>;
41
42
  };
42
43
  export type Socket = ReturnType<typeof makeSocket>;
@@ -67,7 +67,7 @@ const makeSocket = (config) => {
67
67
  /** send a binary node */
68
68
  const sendNode = (frame) => {
69
69
  if (logger.level === 'trace') {
70
- logger.trace((0, WABinary_1.binaryNodeToString)(frame), 'xml send');
70
+ logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'xml send' });
71
71
  }
72
72
  const buff = (0, WABinary_1.encodeBinaryNode)(frame);
73
73
  return sendRawMessage(buff);
@@ -208,7 +208,7 @@ const makeSocket = (config) => {
208
208
  await uploadPreKeys();
209
209
  }
210
210
  };
211
- const onMessageRecieved = (data) => {
211
+ const onMessageReceived = (data) => {
212
212
  noise.decodeFrame(data, frame => {
213
213
  var _a;
214
214
  // reset ping timeout
@@ -219,7 +219,7 @@ const makeSocket = (config) => {
219
219
  if (!(frame instanceof Uint8Array)) {
220
220
  const msgId = frame.attrs.id;
221
221
  if (logger.level === 'trace') {
222
- logger.trace((0, WABinary_1.binaryNodeToString)(frame), 'recv xml');
222
+ logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'recv xml' });
223
223
  }
224
224
  /* Check if this is a response to a message we sent */
225
225
  anyTriggered = ws.emit(`${Defaults_1.DEF_TAG_PREFIX}${msgId}`, frame) || anyTriggered;
@@ -423,7 +423,24 @@ const makeSocket = (config) => {
423
423
  const ciphered = (0, Utils_1.aesEncryptCTR)(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
424
424
  return Buffer.concat([salt, randomIv, ciphered]);
425
425
  }
426
- ws.on('message', onMessageRecieved);
426
+ const sendWAMBuffer = (wamBuffer) => {
427
+ return query({
428
+ tag: 'iq',
429
+ attrs: {
430
+ to: WABinary_1.S_WHATSAPP_NET,
431
+ id: generateMessageTag(),
432
+ xmlns: 'w:stats'
433
+ },
434
+ content: [
435
+ {
436
+ tag: 'add',
437
+ attrs: {},
438
+ content: wamBuffer
439
+ }
440
+ ]
441
+ });
442
+ };
443
+ ws.on('message', onMessageReceived);
427
444
  ws.on('open', async () => {
428
445
  try {
429
446
  await validateConnection();
@@ -574,6 +591,7 @@ const makeSocket = (config) => {
574
591
  requestPairingCode,
575
592
  /** Waits for the connection to WA to reach a state */
576
593
  waitForConnectionUpdate: (0, Utils_1.bindWaitForConnectionUpdate)(ev),
594
+ sendWAMBuffer,
577
595
  };
578
596
  };
579
597
  exports.makeSocket = makeSocket;
@@ -1,5 +1,5 @@
1
1
  import { AuthenticationCreds } from '../Types';
2
- declare const makeCacheManagerAuthState: (store: Store, sessionKey: string) => Promise<{
2
+ declare const makeCacheManagerAuthState: (store: Storage, sessionKey: string) => Promise<{
3
3
  clearState: () => Promise<void>;
4
4
  saveCreds: () => Promise<void>;
5
5
  state: {
@@ -17,9 +17,10 @@ export declare const waLabelAssociationKey: Comparable<LabelAssociation, string>
17
17
  export type BaileysInMemoryStoreConfig = {
18
18
  chatKey?: Comparable<Chat, string>;
19
19
  labelAssociationKey?: Comparable<LabelAssociation, string>;
20
- logger?: Logger;
20
+ logger: Logger;
21
+ socket?: WASocket;
21
22
  };
22
- declare const _default: ({ logger: _logger, chatKey, labelAssociationKey }: BaileysInMemoryStoreConfig) => {
23
+ declare const _default: ({ logger, chatKey, labelAssociationKey, socket }: BaileysInMemoryStoreConfig) => {
23
24
  chats: KeyedDB<Chat, string>;
24
25
  contacts: {
25
26
  [_: string]: Contact;
@@ -60,11 +60,11 @@ const predefinedLabels = Object.freeze({
60
60
  deleted: false
61
61
  }
62
62
  });
63
- exports.default = ({ logger: _logger, chatKey, labelAssociationKey }) => {
63
+ exports.default = ({ logger, chatKey, labelAssociationKey, socket }) => {
64
64
  // const logger = _logger || DEFAULT_CONNECTION_CONFIG.logger.child({ stream: 'in-mem-store' })
65
65
  chatKey = chatKey || (0, exports.waChatKey)(true);
66
66
  labelAssociationKey = labelAssociationKey || exports.waLabelAssociationKey;
67
- const logger = _logger || Defaults_1.DEFAULT_CONNECTION_CONFIG.logger.child({ stream: 'in-mem-store' });
67
+ logger = logger || Defaults_1.DEFAULT_CONNECTION_CONFIG.logger.child({ stream: 'in-mem-store' });
68
68
  const KeyedDB = require('@adiwajshing/keyed-db').default;
69
69
  const chats = new KeyedDB(chatKey, c => c.id);
70
70
  const messages = {};
@@ -129,14 +129,32 @@ exports.default = ({ logger: _logger, chatKey, labelAssociationKey }) => {
129
129
  ev.on('contacts.upsert', contacts => {
130
130
  contactsUpsert(contacts);
131
131
  });
132
- ev.on('contacts.update', updates => {
132
+ ev.on('contacts.update', async (updates) => {
133
+ var _a;
133
134
  for (const update of updates) {
135
+ let contact;
134
136
  if (contacts[update.id]) {
135
- Object.assign(contacts[update.id], update);
137
+ contact = contacts[update.id];
138
+ }
139
+ else {
140
+ const contactHashes = await Promise.all(Object.keys(contacts).map(async (contactId) => {
141
+ const { user } = (0, WABinary_1.jidDecode)(contactId);
142
+ return [contactId, (await (0, Utils_1.md5)(Buffer.from(user + 'WA_ADD_NOTIF', 'utf8'))).toString('base64').slice(0, 3)];
143
+ }));
144
+ contact = contacts[((_a = contactHashes.find(([, b]) => b === update.id)) === null || _a === void 0 ? void 0 : _a[0]) || '']; // find contact by attrs.hash, when user is not saved as a contact
145
+ }
146
+ if (contact) {
147
+ if (update.imgUrl === 'changed') {
148
+ contact.imgUrl = socket ? await (socket === null || socket === void 0 ? void 0 : socket.profilePictureUrl(contact.id)) : undefined;
149
+ }
150
+ else if (update.imgUrl === 'removed') {
151
+ delete contact.imgUrl;
152
+ }
136
153
  }
137
154
  else {
138
- logger.debug({ update }, 'got update for non-existant contact');
155
+ return logger.debug({ update }, 'got update for non-existant contact');
139
156
  }
157
+ Object.assign(contacts[contact.id], contact);
140
158
  }
141
159
  });
142
160
  ev.on('chats.upsert', newChats => {
@@ -64,6 +64,7 @@ export type AuthenticationCreds = SignalCreds & {
64
64
  backupToken: Buffer;
65
65
  registration: RegistrationOptions;
66
66
  pairingCode: string | undefined;
67
+ lastPropHash: string | undefined;
67
68
  };
68
69
  export type SignalDataTypeMap = {
69
70
  'pre-key': KeyPair;
@@ -17,6 +17,8 @@ export interface GroupMetadata {
17
17
  desc?: string;
18
18
  descOwner?: string;
19
19
  descId?: string;
20
+ /** if this group is part of a community, it returns the jid of the community to which it belongs */
21
+ linkedParent?: string;
20
22
  /** is set when the group only allows admins to change group settings */
21
23
  restrict?: boolean;
22
24
  /** is set when the group only allows admins to write messages */
@@ -34,7 +36,7 @@ export interface GroupMetadata {
34
36
  participants: GroupParticipant[];
35
37
  ephemeralDuration?: number;
36
38
  inviteCode?: string;
37
- /** the person who added you */
39
+ /** the person who added you to group or changed some setting in group */
38
40
  author?: string;
39
41
  }
40
42
  export interface WAGroupCreateResponse {
@@ -110,6 +110,8 @@ export type AnyMediaMessageContent = (({
110
110
  caption?: string;
111
111
  gifPlayback?: boolean;
112
112
  jpegThumbnail?: string;
113
+ /** if set to true, will send as a `video note` */
114
+ ptv?: boolean;
113
115
  } & Mentionable & Contextable & Buttonable & Templatable & WithDimensions) | {
114
116
  audio: WAMediaUpload;
115
117
  /** if set to true, will send as a `voice note` */
@@ -206,6 +208,8 @@ export type MiscMessageGenerationOptions = MinimalRelayOptions & {
206
208
  backgroundColor?: string;
207
209
  /** font type for status */
208
210
  font?: number;
211
+ /** if it is broadcast */
212
+ broadcast?: boolean;
209
213
  };
210
214
  export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & {
211
215
  userJid: string;
@@ -199,6 +199,7 @@ const initAuthCreds = () => {
199
199
  backupToken: (0, crypto_1.randomBytes)(20),
200
200
  registration: {},
201
201
  pairingCode: undefined,
202
+ lastPropHash: undefined,
202
203
  };
203
204
  };
204
205
  exports.initAuthCreds = initAuthCreds;
@@ -144,10 +144,15 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
144
144
  let msg = WAProto_1.proto.Message.decode((0, generics_1.unpadRandomMax16)(msgBuffer));
145
145
  msg = ((_a = msg.deviceSentMessage) === null || _a === void 0 ? void 0 : _a.message) || msg;
146
146
  if (msg.senderKeyDistributionMessage) {
147
- await repository.processSenderKeyDistributionMessage({
148
- authorJid: author,
149
- item: msg.senderKeyDistributionMessage
150
- });
147
+ try {
148
+ await repository.processSenderKeyDistributionMessage({
149
+ authorJid: author,
150
+ item: msg.senderKeyDistributionMessage
151
+ });
152
+ }
153
+ catch (err) {
154
+ logger.error({ key: fullMessage.key, err }, 'failed to decrypt message');
155
+ }
151
156
  }
152
157
  if (fullMessage.message) {
153
158
  Object.assign(fullMessage.message, msg);
@@ -166,7 +171,7 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
166
171
  // if nothing was found to decrypt
167
172
  if (!decryptables) {
168
173
  fullMessage.messageStubType = WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT;
169
- fullMessage.messageStubParameters = [NO_MESSAGE_FOUND_ERROR_TEXT];
174
+ fullMessage.messageStubParameters = [NO_MESSAGE_FOUND_ERROR_TEXT, JSON.stringify(stanza, generics_1.BufferJSON.replacer)];
170
175
  }
171
176
  }
172
177
  };
@@ -21,7 +21,7 @@ const PLATFORM_MAP = {
21
21
  exports.Browsers = {
22
22
  ubuntu: browser => ['Ubuntu', browser, '20.0.04'],
23
23
  macOS: browser => ['Mac OS', browser, '10.15.7'],
24
- baileys: browser => ['Windows', browser, '10.0.22621'],
24
+ baileys: browser => ['Ubuntu', browser, '20.0.04'],
25
25
  windows: browser => ['Windows', browser, '10.0.22621'],
26
26
  /** The appropriate browser based on your OS & release */
27
27
  appropriate: browser => [PLATFORM_MAP[(0, os_1.platform)()] || 'Ubuntu', browser, (0, os_1.release)()]
@@ -32,7 +32,7 @@ const getUrlInfo = async (text, opts = {
32
32
  }
33
33
  const info = await getLinkPreview(previewLink, {
34
34
  ...opts.fetchOpts,
35
- followRedirects: 'manual',
35
+ followRedirects: 'follow',
36
36
  handleRedirects: (baseURL, forwardedURL) => {
37
37
  const urlObj = new URL(baseURL);
38
38
  const forwardedURLObj = new URL(forwardedURL);
@@ -36,10 +36,7 @@ const ButtonType = WAProto_1.proto.Message.ButtonsMessage.HeaderType;
36
36
  * @param text eg. hello https://google.com
37
37
  * @returns the URL, eg. https://google.com
38
38
  */
39
- const extractUrlFromText = (text) => {
40
- var _a;
41
- return (!Defaults_1.URL_EXCLUDE_REGEX.test(text) ? (_a = text.match(Defaults_1.URL_REGEX)) === null || _a === void 0 ? void 0 : _a[0] : undefined);
42
- };
39
+ const extractUrlFromText = (text) => { var _a; return (_a = text.match(Defaults_1.URL_REGEX)) === null || _a === void 0 ? void 0 : _a[0]; };
43
40
  exports.extractUrlFromText = extractUrlFromText;
44
41
  const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
45
42
  const url = (0, exports.extractUrlFromText)(text);
@@ -182,6 +179,10 @@ const prepareWAMessageMedia = async (message, options) => {
182
179
  media: undefined
183
180
  })
184
181
  });
182
+ if (uploadData.ptv) {
183
+ obj.ptvMessage = obj.videoMessage;
184
+ delete obj.videoMessage;
185
+ }
185
186
  if (cacheableKey) {
186
187
  logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
187
188
  options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
@@ -455,7 +456,8 @@ const generateWAMessageFromContent = (jid, message, options) => {
455
456
  if (!options.timestamp) {
456
457
  options.timestamp = new Date();
457
458
  }
458
- const key = Object.keys(message)[0];
459
+ const innerMessage = (0, exports.normalizeMessageContent)(message);
460
+ const key = (0, exports.getContentType)(innerMessage);
459
461
  const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp);
460
462
  const { quoted, userJid } = options;
461
463
  if (quoted) {
@@ -468,7 +470,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
468
470
  if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
469
471
  delete quotedContent.contextInfo;
470
472
  }
471
- const contextInfo = message[key].contextInfo || {};
473
+ const contextInfo = innerMessage[key].contextInfo || {};
472
474
  contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
473
475
  contextInfo.stanzaId = quoted.key.id;
474
476
  contextInfo.quotedMessage = quotedMsg;
@@ -477,7 +479,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
477
479
  if (jid !== quoted.key.remoteJid) {
478
480
  contextInfo.remoteJid = quoted.key.remoteJid;
479
481
  }
480
- message[key].contextInfo = contextInfo;
482
+ innerMessage[key].contextInfo = contextInfo;
481
483
  }
482
484
  if (
483
485
  // if we want to send a disappearing message
@@ -486,8 +488,8 @@ const generateWAMessageFromContent = (jid, message, options) => {
486
488
  key !== 'protocolMessage' &&
487
489
  // already not converted to disappearing message
488
490
  key !== 'ephemeralMessage') {
489
- message[key].contextInfo = {
490
- ...(message[key].contextInfo || {}),
491
+ innerMessage[key].contextInfo = {
492
+ ...(innerMessage[key].contextInfo || {}),
491
493
  expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL,
492
494
  //ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString()
493
495
  };
@@ -217,7 +217,8 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
217
217
  let participants;
218
218
  const emitParticipantsUpdate = (action) => (ev.emit('group-participants.update', { id: jid, author: message.participant, participants, action }));
219
219
  const emitGroupUpdate = (update) => {
220
- ev.emit('groups.update', [{ id: jid, ...update }]);
220
+ var _a;
221
+ ev.emit('groups.update', [{ id: jid, ...update, author: (_a = message.participant) !== null && _a !== void 0 ? _a : undefined }]);
221
222
  };
222
223
  const participantsIncludesMe = () => participants.find(jid => (0, WABinary_1.areJidsSameUser)(meId, jid));
223
224
  switch (message.messageStubType) {
@@ -12,10 +12,10 @@ const signal_1 = require("./signal");
12
12
  const getUserAgent = (config) => {
13
13
  var _a, _b;
14
14
  const osVersion = config.mobile ? '15.3.1' : '0.1';
15
- const version = config.mobile ? [2, 24, 3] : config.version;
15
+ const version = config.mobile ? [2, 24, 6] : config.version;
16
16
  const device = config.mobile ? 'iPhone_7' : 'Desktop';
17
17
  const manufacturer = config.mobile ? 'Apple' : '';
18
- const platform = config.mobile ? WAProto_1.proto.ClientPayload.UserAgent.Platform.IOS : WAProto_1.proto.ClientPayload.UserAgent.Platform.MACOS;
18
+ const platform = config.mobile ? WAProto_1.proto.ClientPayload.UserAgent.Platform.IOS : WAProto_1.proto.ClientPayload.UserAgent.Platform.WEB;
19
19
  const phoneId = config.mobile ? { phoneId: config.auth.creds.phoneId } : {};
20
20
  return {
21
21
  appVersion: {
@@ -36,12 +36,26 @@ const getUserAgent = (config) => {
36
36
  ...phoneId
37
37
  };
38
38
  };
39
+ const PLATFORM_MAP = {
40
+ 'Mac OS': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
41
+ 'Windows': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN32
42
+ };
43
+ const getWebInfo = (config) => {
44
+ let webSubPlatform = WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER;
45
+ if (config.syncFullHistory && PLATFORM_MAP[config.browser[0]]) {
46
+ webSubPlatform = PLATFORM_MAP[config.browser[0]];
47
+ }
48
+ return { webSubPlatform };
49
+ };
39
50
  const getClientPayload = (config) => {
40
51
  const payload = {
41
52
  connectType: WAProto_1.proto.ClientPayload.ConnectType.WIFI_UNKNOWN,
42
53
  connectReason: WAProto_1.proto.ClientPayload.ConnectReason.USER_ACTIVATED,
43
54
  userAgent: getUserAgent(config),
44
55
  };
56
+ if (!config.mobile) {
57
+ payload.webInfo = getWebInfo(config);
58
+ }
45
59
  return payload;
46
60
  };
47
61
  const generateMobileNode = (config) => {
@@ -0,0 +1,17 @@
1
+ /// <reference types="node" />
2
+ export declare class BinaryInfo {
3
+ protocolVersion: number;
4
+ sequence: number;
5
+ events: {
6
+ [x: string]: {
7
+ props: {
8
+ [x: string]: any;
9
+ };
10
+ globals: {
11
+ [x: string]: any;
12
+ };
13
+ };
14
+ }[];
15
+ buffer: Buffer[];
16
+ constructor(options?: Partial<BinaryInfo>);
17
+ }