@queenanya/baileys 7.4.14 → 7.5.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 (110) hide show
  1. package/README.md +26 -26
  2. package/lib/Defaults/baileys-version.json +1 -1
  3. package/lib/Defaults/index.d.ts +1 -231
  4. package/lib/Defaults/index.js +11 -23
  5. package/lib/Socket/Client/index.d.ts +2 -3
  6. package/lib/Socket/Client/index.js +2 -3
  7. package/lib/Socket/Client/{web-socket-client.d.ts → websocket.d.ts} +1 -1
  8. package/lib/Socket/Client/{web-socket-client.js → websocket.js} +2 -2
  9. package/lib/Socket/business.d.ts +31 -28
  10. package/lib/Socket/chats.d.ts +17 -9
  11. package/lib/Socket/chats.js +115 -116
  12. package/lib/Socket/{registration.d.ts → communities.d.ts} +94 -145
  13. package/lib/Socket/communities.js +354 -0
  14. package/lib/Socket/groups.d.ts +23 -10
  15. package/lib/Socket/groups.js +12 -1
  16. package/lib/Socket/index.d.ts +69 -38
  17. package/lib/Socket/index.js +2 -2
  18. package/lib/Socket/messages-recv.d.ts +30 -28
  19. package/lib/Socket/messages-recv.js +291 -180
  20. package/lib/Socket/messages-send.d.ts +25 -19
  21. package/lib/Socket/messages-send.js +110 -76
  22. package/lib/Socket/newsletter.d.ts +19 -13
  23. package/lib/Socket/newsletter.js +67 -54
  24. package/lib/Socket/socket.d.ts +3 -1
  25. package/lib/Socket/socket.js +15 -17
  26. package/lib/Socket/usync.d.ts +38 -0
  27. package/lib/Socket/usync.js +70 -0
  28. package/lib/Store/make-cache-manager-store.d.ts +2 -1
  29. package/lib/Store/make-in-memory-store.js +13 -11
  30. package/lib/Store/make-ordered-dictionary.js +2 -2
  31. package/lib/Types/Auth.d.ts +1 -6
  32. package/lib/Types/Call.d.ts +1 -1
  33. package/lib/Types/Chat.d.ts +15 -7
  34. package/lib/Types/Contact.d.ts +6 -1
  35. package/lib/Types/Events.d.ts +44 -2
  36. package/lib/Types/GroupMetadata.d.ts +3 -1
  37. package/lib/Types/Label.d.ts +11 -0
  38. package/lib/Types/Message.d.ts +37 -30
  39. package/lib/Types/Newsletter.d.ts +0 -13
  40. package/lib/Types/Newsletter.js +1 -15
  41. package/lib/Types/Socket.d.ts +10 -3
  42. package/lib/Types/USync.d.ts +25 -0
  43. package/lib/Types/USync.js +2 -0
  44. package/lib/Types/index.d.ts +8 -0
  45. package/lib/Utils/auth-utils.js +1 -7
  46. package/lib/Utils/chat-utils.d.ts +5 -4
  47. package/lib/Utils/chat-utils.js +52 -20
  48. package/lib/Utils/crypto.d.ts +2 -1
  49. package/lib/Utils/crypto.js +4 -2
  50. package/lib/Utils/decode-wa-message.d.ts +1 -0
  51. package/lib/Utils/decode-wa-message.js +34 -14
  52. package/lib/Utils/event-buffer.js +14 -8
  53. package/lib/Utils/generics.d.ts +37 -13
  54. package/lib/Utils/generics.js +103 -18
  55. package/lib/Utils/history.d.ts +6 -2
  56. package/lib/Utils/history.js +3 -0
  57. package/lib/Utils/index.d.ts +1 -0
  58. package/lib/Utils/index.js +1 -0
  59. package/lib/Utils/link-preview.js +24 -1
  60. package/lib/Utils/logger.d.ts +1 -3
  61. package/lib/Utils/make-mutex.js +1 -0
  62. package/lib/Utils/messages-media.d.ts +3 -2
  63. package/lib/Utils/messages-media.js +17 -32
  64. package/lib/Utils/messages.d.ts +1 -0
  65. package/lib/Utils/messages.js +67 -72
  66. package/lib/Utils/noise-handler.d.ts +3 -3
  67. package/lib/Utils/noise-handler.js +7 -12
  68. package/lib/Utils/process-message.d.ts +3 -2
  69. package/lib/Utils/process-message.js +55 -21
  70. package/lib/Utils/signal.js +23 -16
  71. package/lib/Utils/use-multi-file-auth-state.js +17 -3
  72. package/lib/Utils/validate-connection.d.ts +0 -1
  73. package/lib/Utils/validate-connection.js +10 -44
  74. package/lib/WABinary/constants.js +5 -5
  75. package/lib/WABinary/decode.d.ts +3 -2
  76. package/lib/WABinary/decode.js +6 -4
  77. package/lib/WABinary/encode.d.ts +1 -2
  78. package/lib/WABinary/encode.js +8 -6
  79. package/lib/WABinary/generic-utils.d.ts +1 -0
  80. package/lib/WABinary/jid-utils.d.ts +3 -3
  81. package/lib/WABinary/jid-utils.js +5 -5
  82. package/lib/WAM/BinaryInfo.d.ts +3 -2
  83. package/lib/WAM/constants.d.ts +3 -2
  84. package/lib/WAM/encode.d.ts +1 -0
  85. package/lib/WAM/encode.js +2 -2
  86. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
  87. package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
  88. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
  89. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
  90. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  91. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
  92. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  93. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  94. package/lib/WAUSync/Protocols/index.d.ts +4 -0
  95. package/lib/WAUSync/Protocols/index.js +20 -0
  96. package/lib/WAUSync/USyncQuery.d.ts +26 -0
  97. package/lib/WAUSync/USyncQuery.js +79 -0
  98. package/lib/WAUSync/USyncUser.d.ts +10 -0
  99. package/lib/WAUSync/USyncUser.js +22 -0
  100. package/lib/WAUSync/index.d.ts +3 -0
  101. package/lib/WAUSync/index.js +19 -0
  102. package/lib/index.d.ts +1 -0
  103. package/lib/index.js +1 -0
  104. package/package.json +36 -34
  105. package/lib/Defaults/phonenumber-mcc.json +0 -223
  106. package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
  107. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  108. package/lib/Socket/registration.js +0 -166
  109. /package/lib/Socket/Client/{abstract-socket-client.d.ts → types.d.ts} +0 -0
  110. /package/lib/Socket/Client/{abstract-socket-client.js → types.js} +0 -0
@@ -22,9 +22,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
25
28
  Object.defineProperty(exports, "__esModule", { value: true });
26
29
  exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.extensionForMediaMessage = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.prepareStream = exports.getHttpStream = exports.generateThumbnail = exports.getStream = exports.toBuffer = exports.toReadable = exports.getAudioWaveform = exports.getAudioDuration = exports.mediaMessageSHA256B64 = exports.changeprofileFull = exports.generatePP = exports.generateProfilePictureFP = exports.generateProfilePictureFull = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.getMediaKeys = exports.hkdfInfoKey = void 0;
27
30
  const boom_1 = require("@hapi/boom");
31
+ const axios_1 = __importDefault(require("axios"));
28
32
  const child_process_1 = require("child_process");
29
33
  const Crypto = __importStar(require("crypto"));
30
34
  const events_1 = require("events");
@@ -41,13 +45,11 @@ const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
41
45
  const getImageProcessingLibrary = async () => {
42
46
  const [_jimp, sharp] = await Promise.all([
43
47
  (async () => {
44
- const jimp = await (import('jimp')
45
- .catch(() => { }));
48
+ const jimp = await (Promise.resolve().then(() => __importStar(require('jimp'))).catch(() => { }));
46
49
  return jimp;
47
50
  })(),
48
51
  (async () => {
49
- const sharp = await (import('sharp')
50
- .catch(() => { }));
52
+ const sharp = await (Promise.resolve().then(() => __importStar(require('sharp'))).catch(() => { }));
51
53
  return sharp;
52
54
  })()
53
55
  ]);
@@ -258,7 +260,7 @@ const mediaMessageSHA256B64 = (message) => {
258
260
  };
259
261
  exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
260
262
  async function getAudioDuration(buffer) {
261
- const musicMetadata = await import('music-metadata');
263
+ const musicMetadata = await Promise.resolve().then(() => __importStar(require('music-metadata')));
262
264
  let metadata;
263
265
  if (Buffer.isBuffer(buffer)) {
264
266
  metadata = await musicMetadata.parseBuffer(buffer, undefined, { duration: true });
@@ -283,7 +285,7 @@ exports.getAudioDuration = getAudioDuration;
283
285
  */
284
286
  async function getAudioWaveform(buffer, logger) {
285
287
  try {
286
- const audioDecode = (buffer) => import('audio-decode').then(({ default: audioDecode }) => audioDecode(buffer));
288
+ const audioDecode = (buffer) => Promise.resolve().then(() => __importStar(require('audio-decode'))).then(({ default: audioDecode }) => audioDecode(buffer));
287
289
  let audioData;
288
290
  if (Buffer.isBuffer(buffer)) {
289
291
  audioData = buffer;
@@ -383,8 +385,7 @@ async function generateThumbnail(file, mediaType, options) {
383
385
  }
384
386
  exports.generateThumbnail = generateThumbnail;
385
387
  const getHttpStream = async (url, options = {}) => {
386
- const { default: axios } = await import('axios');
387
- const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' });
388
+ const fetched = await axios_1.default.get(url.toString(), { ...options, responseType: 'stream' });
388
389
  return fetched.data;
389
390
  };
390
391
  exports.getHttpStream = getHttpStream;
@@ -442,7 +443,7 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
442
443
  let writeStream;
443
444
  let didSaveToTmpPath = false;
444
445
  if (type === 'file') {
445
- bodyPath = media.url;
446
+ bodyPath = media.url.toString();
446
447
  }
447
448
  else if (saveOriginalFileIfRequired) {
448
449
  bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageID)());
@@ -465,10 +466,8 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
465
466
  });
466
467
  }
467
468
  sha256Plain = sha256Plain.update(data);
468
- if (writeStream) {
469
- if (!writeStream.write(data)) {
470
- await (0, events_1.once)(writeStream, 'drain');
471
- }
469
+ if (writeStream && !writeStream.write(data)) {
470
+ await (0, events_1.once)(writeStream, 'drain');
472
471
  }
473
472
  onChunk(aes.update(data));
474
473
  }
@@ -639,33 +638,23 @@ exports.extensionForMediaMessage = extensionForMediaMessage;
639
638
  const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
640
639
  return async (stream, { mediaType, fileEncSha256B64, newsletter, timeoutMs }) => {
641
640
  var _a, _b;
642
- const { default: axios } = await import('axios');
643
641
  // send a query JSON to obtain the url & auth token to upload our media
644
642
  let uploadInfo = await refreshMediaConn(false);
645
643
  let urls;
646
644
  const hosts = [...customUploadHosts, ...uploadInfo.hosts];
647
- const chunks = [];
648
- if (!Buffer.isBuffer(stream)) {
649
- for await (const chunk of stream) {
650
- chunks.push(chunk);
651
- }
652
- }
653
- const reqBody = Buffer.isBuffer(stream) ? stream : Buffer.concat(chunks);
654
645
  fileEncSha256B64 = (0, exports.encodeBase64EncodedStringForUpload)(fileEncSha256B64);
655
646
  let media = Defaults_1.MEDIA_PATH_MAP[mediaType];
656
647
  if (newsletter) {
657
648
  media = media === null || media === void 0 ? void 0 : media.replace('/mms/', '/newsletter/newsletter-');
658
649
  }
659
- for (const { hostname, maxContentLengthBytes } of hosts) {
650
+ for (const { hostname } of hosts) {
660
651
  logger.debug(`uploading to "${hostname}"`);
661
652
  const auth = encodeURIComponent(uploadInfo.auth); // the auth token
662
- const url = `https://${hostname}${media}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
653
+ const url = `https://${hostname}${Defaults_1.MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
654
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
663
655
  let result;
664
656
  try {
665
- if (maxContentLengthBytes && reqBody.length > maxContentLengthBytes) {
666
- throw new boom_1.Boom(`Body too large for "${hostname}"`, { statusCode: 413 });
667
- }
668
- const body = await axios.post(url, reqBody, {
657
+ const body = await axios_1.default.post(url, stream, {
669
658
  ...options,
670
659
  headers: {
671
660
  ...options.headers || {},
@@ -693,7 +682,7 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
693
682
  }
694
683
  }
695
684
  catch (error) {
696
- if (axios.isAxiosError(error)) {
685
+ if (axios_1.default.isAxiosError(error)) {
697
686
  result = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data;
698
687
  }
699
688
  const isLast = hostname === ((_b = hosts[uploadInfo.hosts.length - 1]) === null || _b === void 0 ? void 0 : _b.hostname);
@@ -795,7 +784,3 @@ const MEDIA_RETRY_STATUS_MAP = {
795
784
  [WAProto_1.proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
796
785
  [WAProto_1.proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418,
797
786
  };
798
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
799
- function __importStar(arg0) {
800
- throw new Error('Function not implemented.');
801
- }
@@ -1,5 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
+ /// <reference types="node" />
3
4
  import { Logger } from 'pino';
4
5
  import { type Transform } from 'stream';
5
6
  import { proto } from '../../WAProto';
@@ -30,7 +30,6 @@ const MessageTypeProto = {
30
30
  'sticker': Types_1.WAProto.Message.StickerMessage,
31
31
  'document': Types_1.WAProto.Message.DocumentMessage,
32
32
  };
33
- const ButtonType = WAProto_1.proto.Message.ButtonsMessage.HeaderType;
34
33
  /**
35
34
  * Uses a regex to test whether the string contains a URL, and returns the URL if it does.
36
35
  * @param text eg. hello https://google.com
@@ -240,7 +239,7 @@ const generateForwardMessageContent = (message, forceForward) => {
240
239
  exports.generateForwardMessageContent = generateForwardMessageContent;
241
240
  const generateWAMessageContent = async (message, options) => {
242
241
  var _a;
243
- var _b;
242
+ var _b, _c;
244
243
  let m = {};
245
244
  if ('text' in message) {
246
245
  const extContent = { text: message.text };
@@ -310,6 +309,41 @@ const generateWAMessageContent = async (message, options) => {
310
309
  message.disappearingMessagesInChat;
311
310
  m = (0, exports.prepareDisappearingMessageSettingContent)(exp);
312
311
  }
312
+ else if ('groupInvite' in message) {
313
+ m.groupInviteMessage = {};
314
+ m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
315
+ m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
316
+ m.groupInviteMessage.caption = message.groupInvite.text;
317
+ m.groupInviteMessage.groupJid = message.groupInvite.jid;
318
+ m.groupInviteMessage.groupName = message.groupInvite.subject;
319
+ //TODO: use built-in interface and get disappearing mode info etc.
320
+ //TODO: cache / use store!?
321
+ if (options.getProfilePicUrl) {
322
+ const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
323
+ if (pfpUrl) {
324
+ const resp = await axios_1.default.get(pfpUrl, { responseType: 'arraybuffer' });
325
+ if (resp.status === 200) {
326
+ m.groupInviteMessage.jpegThumbnail = resp.data;
327
+ }
328
+ }
329
+ }
330
+ }
331
+ else if ('pin' in message) {
332
+ m.pinInChatMessage = {};
333
+ m.messageContextInfo = {};
334
+ m.pinInChatMessage.key = message.pin;
335
+ m.pinInChatMessage.type = 1;
336
+ m.pinInChatMessage.senderTimestampMs = Date.now();
337
+ m.messageContextInfo.messageAddOnDurationInSecs = message.time || 86400;
338
+ }
339
+ else if ('unpin' in message) {
340
+ m.pinInChatMessage = {};
341
+ m.messageContextInfo = {};
342
+ m.pinInChatMessage.key = message.unpin;
343
+ m.pinInChatMessage.type = 2;
344
+ m.pinInChatMessage.senderTimestampMs = Date.now();
345
+ m.messageContextInfo.messageAddOnDurationInSecs = 0;
346
+ }
313
347
  else if ('buttonReply' in message) {
314
348
  switch (message.type) {
315
349
  case 'template':
@@ -328,6 +362,10 @@ const generateWAMessageContent = async (message, options) => {
328
362
  break;
329
363
  }
330
364
  }
365
+ else if ('ptv' in message && message.ptv) {
366
+ const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
367
+ m.ptvMessage = videoMessage;
368
+ }
331
369
  else if ('product' in message) {
332
370
  const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
333
371
  m.productMessage = Types_1.WAProto.Message.ProductMessage.fromObject({
@@ -343,6 +381,7 @@ const generateWAMessageContent = async (message, options) => {
343
381
  }
344
382
  else if ('poll' in message) {
345
383
  (_b = message.poll).selectableCount || (_b.selectableCount = 0);
384
+ (_c = message.poll).toAnnouncementGroup || (_c.toAnnouncementGroup = false);
346
385
  if (!Array.isArray(message.poll.values)) {
347
386
  throw new boom_1.Boom('Invalid poll values', { statusCode: 400 });
348
387
  }
@@ -354,11 +393,25 @@ const generateWAMessageContent = async (message, options) => {
354
393
  // encKey
355
394
  messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32),
356
395
  };
357
- m.pollCreationMessage = {
396
+ const pollCreationMessage = {
358
397
  name: message.poll.name,
359
398
  selectableOptionsCount: message.poll.selectableCount,
360
399
  options: message.poll.values.map(optionName => ({ optionName })),
361
400
  };
401
+ if (message.poll.toAnnouncementGroup) {
402
+ // poll v2 is for community announcement groups (single select and multiple)
403
+ m.pollCreationMessageV2 = pollCreationMessage;
404
+ }
405
+ else {
406
+ if (message.poll.selectableCount > 0) {
407
+ //poll v3 is for single select polls
408
+ m.pollCreationMessageV3 = pollCreationMessage;
409
+ }
410
+ else {
411
+ // poll v3 for multiple choice polls
412
+ m.pollCreationMessage = pollCreationMessage;
413
+ }
414
+ }
362
415
  }
363
416
  else if ('sharePhoneNumber' in message) {
364
417
  m.protocolMessage = {
@@ -371,61 +424,6 @@ const generateWAMessageContent = async (message, options) => {
371
424
  else {
372
425
  m = await (0, exports.prepareWAMessageMedia)(message, options);
373
426
  }
374
- if ('buttons' in message && !!message.buttons) {
375
- const buttonsMessage = {
376
- buttons: message.buttons.map(b => ({ ...b, type: WAProto_1.proto.Message.ButtonsMessage.Button.Type.RESPONSE }))
377
- };
378
- if ('text' in message) {
379
- buttonsMessage.contentText = message.text;
380
- buttonsMessage.headerType = ButtonType.EMPTY;
381
- }
382
- else {
383
- if ('caption' in message) {
384
- buttonsMessage.contentText = message.caption;
385
- }
386
- const type = Object.keys(m)[0].replace('Message', '').toUpperCase();
387
- buttonsMessage.headerType = ButtonType[type];
388
- Object.assign(buttonsMessage, m);
389
- }
390
- if ('footer' in message && !!message.footer) {
391
- buttonsMessage.footerText = message.footer;
392
- }
393
- m = { buttonsMessage };
394
- }
395
- else if ('templateButtons' in message && !!message.templateButtons) {
396
- const msg = {
397
- hydratedButtons: message.templateButtons
398
- };
399
- if ('text' in message) {
400
- msg.hydratedContentText = message.text;
401
- }
402
- else {
403
- if ('caption' in message) {
404
- msg.hydratedContentText = message.caption;
405
- }
406
- Object.assign(msg, m);
407
- }
408
- if ('footer' in message && !!message.footer) {
409
- msg.hydratedFooterText = message.footer;
410
- }
411
- m = {
412
- templateMessage: {
413
- fourRowTemplate: msg,
414
- hydratedTemplate: msg
415
- }
416
- };
417
- }
418
- if ('sections' in message && !!message.sections) {
419
- const listMessage = {
420
- sections: message.sections,
421
- buttonText: message.buttonText,
422
- title: message.title,
423
- footerText: message.footer,
424
- description: message.text,
425
- listType: WAProto_1.proto.Message.ListMessage.ListType.SINGLE_SELECT
426
- };
427
- m = { listMessage };
428
- }
429
427
  if ('viewOnce' in message && !!message.viewOnce) {
430
428
  m = { viewOnceMessage: { message: m } };
431
429
  }
@@ -462,7 +460,8 @@ const generateWAMessageFromContent = (jid, message, options) => {
462
460
  const key = (0, exports.getContentType)(innerMessage);
463
461
  const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp);
464
462
  const { quoted, userJid } = options;
465
- if (quoted && !(0, WABinary_1.isJidNewsLetter)(jid)) {
463
+ // only set quoted if isn't a newsletter message
464
+ if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
466
465
  const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid);
467
466
  let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message);
468
467
  const msgType = (0, exports.getContentType)(quotedMsg);
@@ -491,7 +490,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
491
490
  // already not converted to disappearing message
492
491
  key !== 'ephemeralMessage' &&
493
492
  // newsletter not accept disappearing messages
494
- !(0, WABinary_1.isJidNewsLetter)(jid)) {
493
+ !(0, WABinary_1.isJidNewsletter)(jid)) {
495
494
  innerMessage[key].contextInfo = {
496
495
  ...(innerMessage[key].contextInfo || {}),
497
496
  expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL,
@@ -518,7 +517,7 @@ const generateWAMessage = async (jid, content, options) => {
518
517
  var _a;
519
518
  // ensure msg ID is with every log
520
519
  options.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) === null || _a === void 0 ? void 0 : _a.child({ msgId: options.messageId });
521
- return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsLetter)(jid), ...options }), options);
520
+ return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsletter)(jid), ...options }), options);
522
521
  };
523
522
  exports.generateWAMessage = generateWAMessage;
524
523
  /** Get the key to access the true type of content */
@@ -707,17 +706,13 @@ const downloadMediaMessage = async (message, type, options, ctx) => {
707
706
  const result = await downloadMsg()
708
707
  .catch(async (error) => {
709
708
  var _a;
710
- if (ctx) {
711
- if (axios_1.default.isAxiosError(error)) {
712
- // check if the message requires a reupload
713
- if (REUPLOAD_REQUIRED_STATUS.includes((_a = error.response) === null || _a === void 0 ? void 0 : _a.status)) {
714
- ctx.logger.info({ key: message.key }, 'sending reupload media request...');
715
- // request reupload
716
- message = await ctx.reuploadRequest(message);
717
- const result = await downloadMsg();
718
- return result;
719
- }
720
- }
709
+ if (ctx && axios_1.default.isAxiosError(error) && // check if the message requires a reupload
710
+ REUPLOAD_REQUIRED_STATUS.includes((_a = error.response) === null || _a === void 0 ? void 0 : _a.status)) {
711
+ ctx.logger.info({ key: message.key }, 'sending reupload media request...');
712
+ // request reupload
713
+ message = await ctx.reuploadRequest(message);
714
+ const result = await downloadMsg();
715
+ return result;
721
716
  }
722
717
  throw error;
723
718
  });
@@ -1,12 +1,12 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { Logger } from 'pino';
3
4
  import { proto } from '../../WAProto';
4
5
  import { KeyPair } from '../Types';
5
6
  import { BinaryNode } from '../WABinary';
6
- export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, mobile, logger, routingInfo }: {
7
+ export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }: {
7
8
  keyPair: KeyPair;
8
9
  NOISE_HEADER: Uint8Array;
9
- mobile: boolean;
10
10
  logger: Logger;
11
11
  routingInfo?: Buffer | undefined;
12
12
  }) => {
@@ -17,5 +17,5 @@ export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public
17
17
  finishInit: () => void;
18
18
  processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => Buffer;
19
19
  encodeFrame: (data: Buffer | Uint8Array) => Buffer;
20
- decodeFrame: (newData: Buffer | Uint8Array, onFrame: (buff: Uint8Array | BinaryNode) => void) => void;
20
+ decodeFrame: (newData: Buffer | Uint8Array, onFrame: (buff: Uint8Array | BinaryNode) => void) => Promise<void>;
21
21
  };
@@ -11,7 +11,7 @@ const generateIV = (counter) => {
11
11
  new DataView(iv).setUint32(8, counter);
12
12
  return new Uint8Array(iv);
13
13
  };
14
- const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, mobile, logger, routingInfo }) => {
14
+ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }) => {
15
15
  logger = logger.child({ class: 'ns' });
16
16
  const authenticate = (data) => {
17
17
  if (!isFinished) {
@@ -83,15 +83,10 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
83
83
  const decStaticContent = decrypt(serverHello.static);
84
84
  mixIntoKey(crypto_1.Curve.sharedKey(privateKey, decStaticContent));
85
85
  const certDecoded = decrypt(serverHello.payload);
86
- if (mobile) {
87
- WAProto_1.proto.CertChain.NoiseCertificate.decode(certDecoded);
88
- }
89
- else {
90
- const { intermediate: certIntermediate } = WAProto_1.proto.CertChain.decode(certDecoded);
91
- const { issuerSerial } = WAProto_1.proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details);
92
- if (issuerSerial !== Defaults_1.WA_CERT_DETAILS.SERIAL) {
93
- throw new boom_1.Boom('certification match failed', { statusCode: 400 });
94
- }
86
+ const { intermediate: certIntermediate } = WAProto_1.proto.CertChain.decode(certDecoded);
87
+ const { issuerSerial } = WAProto_1.proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details);
88
+ if (issuerSerial !== Defaults_1.WA_CERT_DETAILS.SERIAL) {
89
+ throw new boom_1.Boom('certification match failed', { statusCode: 400 });
95
90
  }
96
91
  const keyEnc = encrypt(noiseKey.public);
97
92
  mixIntoKey(crypto_1.Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
@@ -125,7 +120,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
125
120
  frame.set(data, introSize + 3);
126
121
  return frame;
127
122
  },
128
- decodeFrame: (newData, onFrame) => {
123
+ decodeFrame: async (newData, onFrame) => {
129
124
  var _a;
130
125
  // the binary protocol uses its own framing mechanism
131
126
  // on top of the WS frames
@@ -143,7 +138,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
143
138
  inBytes = inBytes.slice(size + 3);
144
139
  if (isFinished) {
145
140
  const result = decrypt(frame);
146
- frame = (0, WABinary_1.decodeBinaryNode)(result);
141
+ frame = await (0, WABinary_1.decodeBinaryNode)(result);
147
142
  }
148
143
  logger.trace({ msg: (_a = frame === null || frame === void 0 ? void 0 : frame.attrs) === null || _a === void 0 ? void 0 : _a.id }, 'recv frame');
149
144
  onFrame(frame);
@@ -1,9 +1,10 @@
1
1
  import { AxiosRequestConfig } from 'axios';
2
2
  import type { Logger } from 'pino';
3
3
  import { proto } from '../../WAProto';
4
- import { AuthenticationCreds, BaileysEventEmitter, SignalKeyStoreWithTransaction, SocketConfig } from '../Types';
4
+ import { AuthenticationCreds, BaileysEventEmitter, CacheStore, SignalKeyStoreWithTransaction, SocketConfig } from '../Types';
5
5
  type ProcessMessageContext = {
6
6
  shouldProcessHistoryMsg: boolean;
7
+ placeholderResendCache?: CacheStore;
7
8
  creds: AuthenticationCreds;
8
9
  keyStore: SignalKeyStoreWithTransaction;
9
10
  ev: BaileysEventEmitter;
@@ -37,5 +38,5 @@ type PollContext = {
37
38
  * @returns list of SHA256 options
38
39
  */
39
40
  export declare function decryptPollVote({ encPayload, encIv }: proto.Message.IPollEncValue, { pollCreatorJid, pollMsgId, pollEncKey, voterJid, }: PollContext): proto.Message.PollVoteMessage;
40
- declare const processMessage: (message: proto.IWebMessageInfo, { shouldProcessHistoryMsg, ev, creds, keyStore, logger, options, getMessage }: ProcessMessageContext) => Promise<void>;
41
+ declare const processMessage: (message: proto.IWebMessageInfo, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, keyStore, logger, options, getMessage }: ProcessMessageContext) => Promise<void>;
41
42
  export default processMessage;
@@ -102,8 +102,8 @@ function decryptPollVote({ encPayload, encIv }, { pollCreatorJid, pollMsgId, pol
102
102
  }
103
103
  }
104
104
  exports.decryptPollVote = decryptPollVote;
105
- const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, keyStore, logger, options, getMessage }) => {
106
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
105
+ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, keyStore, logger, options, getMessage }) => {
106
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
107
107
  const meId = creds.me.id;
108
108
  const { accountSettings } = creds;
109
109
  const chat = { id: (0, WABinary_1.jidNormalizedUser)((0, exports.getChatId)(message.key)) };
@@ -137,14 +137,22 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
137
137
  isLatest,
138
138
  }, 'got history notification');
139
139
  if (process) {
140
- ev.emit('creds.update', {
141
- processedHistoryMessages: [
142
- ...(creds.processedHistoryMessages || []),
143
- { key: message.key, messageTimestamp: message.messageTimestamp }
144
- ]
145
- });
140
+ if (histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND) {
141
+ ev.emit('creds.update', {
142
+ processedHistoryMessages: [
143
+ ...(creds.processedHistoryMessages || []),
144
+ { key: message.key, messageTimestamp: message.messageTimestamp }
145
+ ]
146
+ });
147
+ }
146
148
  const data = await (0, history_1.downloadAndProcessHistorySyncNotification)(histNotification, options);
147
- ev.emit('messaging-history.set', { ...data, isLatest });
149
+ ev.emit('messaging-history.set', {
150
+ ...data,
151
+ isLatest: histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND
152
+ ? isLatest
153
+ : undefined,
154
+ peerDataRequestSessionId: histNotification.peerDataRequestSessionId
155
+ });
148
156
  }
149
157
  break;
150
158
  case WAProto_1.proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE:
@@ -187,14 +195,22 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
187
195
  case WAProto_1.proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE:
188
196
  const response = protocolMsg.peerDataOperationRequestResponseMessage;
189
197
  if (response) {
198
+ placeholderResendCache === null || placeholderResendCache === void 0 ? void 0 : placeholderResendCache.del(response.stanzaId);
199
+ // TODO: IMPLEMENT HISTORY SYNC ETC (sticker uploads etc.).
190
200
  const { peerDataOperationResult } = response;
191
201
  for (const result of peerDataOperationResult) {
192
202
  const { placeholderMessageResendResponse: retryResponse } = result;
203
+ //eslint-disable-next-line max-depth
193
204
  if (retryResponse) {
194
205
  const webMessageInfo = WAProto_1.proto.WebMessageInfo.decode(retryResponse.webMessageInfoBytes);
195
- ev.emit('messages.update', [
196
- { key: webMessageInfo.key, update: { message: webMessageInfo.message } }
197
- ]);
206
+ // wait till another upsert event is available, don't want it to be part of the PDO response message
207
+ setTimeout(() => {
208
+ ev.emit('messages.upsert', {
209
+ messages: [webMessageInfo],
210
+ type: 'notify',
211
+ requestId: response.stanzaId
212
+ });
213
+ }, 500);
198
214
  }
199
215
  }
200
216
  }
@@ -208,11 +224,11 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
208
224
  };
209
225
  ev.emit('messages.reaction', [{
210
226
  reaction,
211
- key: content.reactionMessage.key,
227
+ key: (_d = content.reactionMessage) === null || _d === void 0 ? void 0 : _d.key,
212
228
  }]);
213
229
  }
214
230
  else if (message.messageStubType) {
215
- const jid = message.key.remoteJid;
231
+ const jid = (_e = message.key) === null || _e === void 0 ? void 0 : _e.remoteJid;
216
232
  //let actor = whatsappID (message.participant)
217
233
  let participants;
218
234
  const emitParticipantsUpdate = (action) => (ev.emit('group-participants.update', { id: jid, author: message.participant, participants, action }));
@@ -220,8 +236,15 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
220
236
  var _a;
221
237
  ev.emit('groups.update', [{ id: jid, ...update, author: (_a = message.participant) !== null && _a !== void 0 ? _a : undefined }]);
222
238
  };
239
+ const emitGroupRequestJoin = (participant, action, method) => {
240
+ ev.emit('group.join-request', { id: jid, author: message.participant, participant, action, method: method });
241
+ };
223
242
  const participantsIncludesMe = () => participants.find(jid => (0, WABinary_1.areJidsSameUser)(meId, jid));
224
243
  switch (message.messageStubType) {
244
+ case Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER:
245
+ participants = message.messageStubParameters || [];
246
+ emitParticipantsUpdate('modify');
247
+ break;
225
248
  case Types_1.WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
226
249
  case Types_1.WAMessageStubType.GROUP_PARTICIPANT_REMOVE:
227
250
  participants = message.messageStubParameters || [];
@@ -249,30 +272,41 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
249
272
  emitParticipantsUpdate('promote');
250
273
  break;
251
274
  case Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE:
252
- const announceValue = (_d = message.messageStubParameters) === null || _d === void 0 ? void 0 : _d[0];
275
+ const announceValue = (_f = message.messageStubParameters) === null || _f === void 0 ? void 0 : _f[0];
253
276
  emitGroupUpdate({ announce: announceValue === 'true' || announceValue === 'on' });
254
277
  break;
255
278
  case Types_1.WAMessageStubType.GROUP_CHANGE_RESTRICT:
256
- const restrictValue = (_e = message.messageStubParameters) === null || _e === void 0 ? void 0 : _e[0];
279
+ const restrictValue = (_g = message.messageStubParameters) === null || _g === void 0 ? void 0 : _g[0];
257
280
  emitGroupUpdate({ restrict: restrictValue === 'true' || restrictValue === 'on' });
258
281
  break;
259
282
  case Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT:
260
- const name = (_f = message.messageStubParameters) === null || _f === void 0 ? void 0 : _f[0];
283
+ const name = (_h = message.messageStubParameters) === null || _h === void 0 ? void 0 : _h[0];
261
284
  chat.name = name;
262
285
  emitGroupUpdate({ subject: name });
263
286
  break;
287
+ case Types_1.WAMessageStubType.GROUP_CHANGE_DESCRIPTION:
288
+ const description = (_j = message.messageStubParameters) === null || _j === void 0 ? void 0 : _j[0];
289
+ chat.description = description;
290
+ emitGroupUpdate({ desc: description });
291
+ break;
264
292
  case Types_1.WAMessageStubType.GROUP_CHANGE_INVITE_LINK:
265
- const code = (_g = message.messageStubParameters) === null || _g === void 0 ? void 0 : _g[0];
293
+ const code = (_k = message.messageStubParameters) === null || _k === void 0 ? void 0 : _k[0];
266
294
  emitGroupUpdate({ inviteCode: code });
267
295
  break;
268
296
  case Types_1.WAMessageStubType.GROUP_MEMBER_ADD_MODE:
269
- const memberAddValue = (_h = message.messageStubParameters) === null || _h === void 0 ? void 0 : _h[0];
297
+ const memberAddValue = (_l = message.messageStubParameters) === null || _l === void 0 ? void 0 : _l[0];
270
298
  emitGroupUpdate({ memberAddMode: memberAddValue === 'all_member_add' });
271
299
  break;
272
300
  case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE:
273
- const approvalMode = (_j = message.messageStubParameters) === null || _j === void 0 ? void 0 : _j[0];
301
+ const approvalMode = (_m = message.messageStubParameters) === null || _m === void 0 ? void 0 : _m[0];
274
302
  emitGroupUpdate({ joinApprovalMode: approvalMode === 'on' });
275
303
  break;
304
+ case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD:
305
+ const participant = (_o = message.messageStubParameters) === null || _o === void 0 ? void 0 : _o[0];
306
+ const action = (_p = message.messageStubParameters) === null || _p === void 0 ? void 0 : _p[1];
307
+ const method = (_q = message.messageStubParameters) === null || _q === void 0 ? void 0 : _q[2];
308
+ emitGroupRequestJoin(participant, action, method);
309
+ break;
276
310
  }
277
311
  }
278
312
  else if (content === null || content === void 0 ? void 0 : content.pollUpdateMessage) {
@@ -283,7 +317,7 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
283
317
  const meIdNormalised = (0, WABinary_1.jidNormalizedUser)(meId);
284
318
  const pollCreatorJid = (0, generics_1.getKeyAuthor)(creationMsgKey, meIdNormalised);
285
319
  const voterJid = (0, generics_1.getKeyAuthor)(message.key, meIdNormalised);
286
- const pollEncKey = (_k = pollMsg.messageContextInfo) === null || _k === void 0 ? void 0 : _k.messageSecret;
320
+ const pollEncKey = (_r = pollMsg.messageContextInfo) === null || _r === void 0 ? void 0 : _r.messageSecret;
287
321
  try {
288
322
  const voteMsg = decryptPollVote(content.pollUpdateMessage.vote, {
289
323
  pollEncKey,