@genuxofficial/baileys 1.0.0 → 3.0.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 (80) hide show
  1. package/README.md +5 -1
  2. package/WAProto/WAProto.proto +1385 -96
  3. package/WAProto/index.d.ts +19244 -2787
  4. package/WAProto/index.js +138202 -74217
  5. package/engine-requirements.js +10 -0
  6. package/lib/Defaults/baileys-version.json +1 -1
  7. package/lib/Defaults/index.js +1 -0
  8. package/lib/Socket/business.d.ts +47 -17
  9. package/lib/Socket/chats.d.ts +10 -9
  10. package/lib/Socket/chats.js +36 -16
  11. package/lib/Socket/groups.d.ts +12 -11
  12. package/lib/Socket/groups.js +16 -3
  13. package/lib/Socket/index.d.ts +52 -22
  14. package/lib/Socket/messages-recv.d.ts +46 -15
  15. package/lib/Socket/messages-recv.js +158 -23
  16. package/lib/Socket/messages-send.d.ts +39 -11
  17. package/lib/Socket/messages-send.js +188 -22
  18. package/lib/Socket/newsletter.d.ts +137 -0
  19. package/lib/Socket/newsletter.js +256 -0
  20. package/lib/Socket/socket.d.ts +4 -4
  21. package/lib/Socket/socket.js +25 -12
  22. package/lib/Socket/usync.d.ts +5 -5
  23. package/lib/Store/index.d.ts +1 -2
  24. package/lib/Store/index.js +1 -3
  25. package/lib/Store/make-in-memory-store.js +14 -5
  26. package/lib/Types/Chat.d.ts +6 -5
  27. package/lib/Types/Events.d.ts +27 -0
  28. package/lib/Types/GroupMetadata.d.ts +6 -0
  29. package/lib/Types/Label.d.ts +0 -11
  30. package/lib/Types/Message.d.ts +150 -12
  31. package/lib/Types/Message.js +0 -2
  32. package/lib/Types/Newsletter.d.ts +79 -0
  33. package/lib/Types/Newsletter.js +18 -0
  34. package/lib/Types/Socket.d.ts +8 -3
  35. package/lib/Types/index.d.ts +1 -0
  36. package/lib/Types/index.js +1 -0
  37. package/lib/Utils/auth-utils.d.ts +1 -1
  38. package/lib/Utils/auth-utils.js +3 -4
  39. package/lib/Utils/business.js +15 -3
  40. package/lib/Utils/chat-utils.js +0 -16
  41. package/lib/Utils/crypto.js +6 -4
  42. package/lib/Utils/decode-wa-message.d.ts +5 -3
  43. package/lib/Utils/decode-wa-message.js +158 -31
  44. package/lib/Utils/event-buffer.js +1 -3
  45. package/lib/Utils/generics.d.ts +3 -2
  46. package/lib/Utils/generics.js +16 -36
  47. package/lib/Utils/history.d.ts +2 -2
  48. package/lib/Utils/link-preview.d.ts +1 -1
  49. package/lib/Utils/link-preview.js +1 -24
  50. package/lib/Utils/make-mutex.js +0 -1
  51. package/lib/Utils/messages-media.d.ts +14 -5
  52. package/lib/Utils/messages-media.js +130 -69
  53. package/lib/Utils/messages.d.ts +1 -1
  54. package/lib/Utils/messages.js +309 -57
  55. package/lib/Utils/noise-handler.d.ts +1 -1
  56. package/lib/Utils/process-message.js +0 -1
  57. package/lib/Utils/use-multi-file-auth-state.js +44 -13
  58. package/lib/Utils/validate-connection.js +1 -3
  59. package/lib/WABinary/decode.js +3 -2
  60. package/lib/WABinary/encode.js +13 -5
  61. package/lib/WABinary/generic-utils.d.ts +3 -5
  62. package/lib/WABinary/generic-utils.js +34 -19
  63. package/lib/WABinary/jid-utils.d.ts +12 -3
  64. package/lib/WABinary/jid-utils.js +29 -4
  65. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +21 -12
  66. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +3 -3
  67. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +25 -0
  68. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +53 -0
  69. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +8 -0
  70. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -0
  71. package/lib/WAUSync/USyncQuery.d.ts +2 -0
  72. package/lib/WAUSync/USyncQuery.js +10 -0
  73. package/lib/WAUSync/USyncUser.d.ts +2 -0
  74. package/lib/WAUSync/USyncUser.js +4 -0
  75. package/lib/index.d.ts +2 -1
  76. package/lib/index.js +3 -1
  77. package/package.json +20 -12
  78. package/WAProto/GenerateStatics.sh +0 -4
  79. package/lib/Store/make-cache-manager-store.d.ts +0 -14
  80. package/lib/Store/make-cache-manager-store.js +0 -83
@@ -30,6 +30,7 @@ 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;
33
34
  /**
34
35
  * Uses a regex to test whether the string contains a URL, and returns the URL if it does.
35
36
  * @param text eg. hello https://google.com
@@ -80,20 +81,17 @@ const prepareWAMessageMedia = async (message, options) => {
80
81
  media: message[mediaType]
81
82
  };
82
83
  delete uploadData[mediaType];
83
- // check if cacheable + generate cache key
84
84
  const cacheableKey = typeof uploadData.media === 'object' &&
85
- ('url' in uploadData.media) &&
85
+ 'url' in uploadData.media &&
86
86
  !!uploadData.media.url &&
87
- !!options.mediaCache && (
88
- // generate the key
89
- mediaType + ':' + uploadData.media.url.toString());
87
+ !!options.mediaCache &&
88
+ (mediaType + ':' + uploadData.media.url.toString());
90
89
  if (mediaType === 'document' && !uploadData.fileName) {
91
90
  uploadData.fileName = 'file';
92
91
  }
93
92
  if (!uploadData.mimetype) {
94
93
  uploadData.mimetype = MIMETYPE_MAP[mediaType];
95
94
  }
96
- // check for cache hit
97
95
  if (cacheableKey) {
98
96
  const mediaBuff = options.mediaCache.get(cacheableKey);
99
97
  if (mediaBuff) {
@@ -105,28 +103,26 @@ const prepareWAMessageMedia = async (message, options) => {
105
103
  }
106
104
  }
107
105
  const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
108
- const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
109
- (typeof uploadData['jpegThumbnail'] === 'undefined');
106
+ const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && typeof uploadData['jpegThumbnail'] === 'undefined';
110
107
  const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
111
108
  const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
112
109
  const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
113
- const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath } = await (0, messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
110
+ const { mediaKey, encFilePath, originalFilePath, fileEncSha256, fileSha256, fileLength } = await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
114
111
  logger,
115
112
  saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
116
113
  opts: options.options
117
114
  });
118
- // url safe Base64 encode the SHA256 hash of the body
119
- const fileEncSha256B64 = fileEncSha256.toString('base64');
120
- const [{ mediaUrl, directPath }] = await Promise.all([
115
+ const fileEncSha256B64 = (options.newsletter ? fileSha256 : fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256).toString('base64');
116
+ const [{ mediaUrl, directPath, handle }] = await Promise.all([
121
117
  (async () => {
122
- const result = await options.upload(encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs });
118
+ const result = await options.upload(encFilePath, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs });
123
119
  logger === null || logger === void 0 ? void 0 : logger.debug({ mediaType, cacheableKey }, 'uploaded media');
124
120
  return result;
125
121
  })(),
126
122
  (async () => {
127
123
  try {
128
124
  if (requiresThumbnailComputation) {
129
- const { thumbnail, originalImageDimensions } = await (0, messages_media_1.generateThumbnail)(bodyPath, mediaType, options);
125
+ const { thumbnail, originalImageDimensions } = await (0, messages_media_1.generateThumbnail)(originalFilePath, mediaType, options);
130
126
  uploadData.jpegThumbnail = thumbnail;
131
127
  if (!uploadData.width && originalImageDimensions) {
132
128
  uploadData.width = originalImageDimensions.width;
@@ -136,11 +132,11 @@ const prepareWAMessageMedia = async (message, options) => {
136
132
  logger === null || logger === void 0 ? void 0 : logger.debug('generated thumbnail');
137
133
  }
138
134
  if (requiresDurationComputation) {
139
- uploadData.seconds = await (0, messages_media_1.getAudioDuration)(bodyPath);
135
+ uploadData.seconds = await (0, messages_media_1.getAudioDuration)(originalFilePath);
140
136
  logger === null || logger === void 0 ? void 0 : logger.debug('computed audio duration');
141
137
  }
142
138
  if (requiresWaveformProcessing) {
143
- uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(bodyPath, logger);
139
+ uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(originalFilePath, logger);
144
140
  logger === null || logger === void 0 ? void 0 : logger.debug('processed waveform');
145
141
  }
146
142
  if (requiresAudioBackground) {
@@ -154,28 +150,26 @@ const prepareWAMessageMedia = async (message, options) => {
154
150
  })(),
155
151
  ])
156
152
  .finally(async () => {
157
- encWriteStream.destroy();
158
- // remove tmp files
159
- if (didSaveToTmpPath && bodyPath) {
160
- try {
161
- await fs_1.promises.access(bodyPath);
162
- await fs_1.promises.unlink(bodyPath);
163
- logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp file');
164
- }
165
- catch (error) {
166
- logger === null || logger === void 0 ? void 0 : logger.warn('failed to remove tmp file');
153
+ try {
154
+ await fs_1.promises.unlink(encFilePath);
155
+ if (originalFilePath) {
156
+ await fs_1.promises.unlink(originalFilePath);
167
157
  }
158
+ logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp files');
159
+ }
160
+ catch (error) {
161
+ logger === null || logger === void 0 ? void 0 : logger.warn('failed to remove tmp file');
168
162
  }
169
163
  });
170
164
  const obj = Types_1.WAProto.Message.fromObject({
171
165
  [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
172
- url: mediaUrl,
166
+ url: handle ? undefined : mediaUrl,
173
167
  directPath,
174
- mediaKey,
175
- fileEncSha256,
168
+ mediaKey: mediaKey,
169
+ fileEncSha256: fileEncSha256,
176
170
  fileSha256,
177
171
  fileLength,
178
- mediaKeyTimestamp: (0, generics_1.unixTimestampSeconds)(),
172
+ mediaKeyTimestamp: handle ? undefined : (0, generics_1.unixTimestampSeconds)(),
179
173
  ...uploadData,
180
174
  media: undefined
181
175
  })
@@ -238,8 +232,8 @@ const generateForwardMessageContent = (message, forceForward) => {
238
232
  };
239
233
  exports.generateForwardMessageContent = generateForwardMessageContent;
240
234
  const generateWAMessageContent = async (message, options) => {
241
- var _a;
242
- var _b, _c;
235
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
236
+ var _p, _q;
243
237
  let m = {};
244
238
  if ('text' in message) {
245
239
  const extContent = { text: message.text };
@@ -248,7 +242,6 @@ const generateWAMessageContent = async (message, options) => {
248
242
  urlInfo = await (0, exports.generateLinkPreviewIfRequired)(message.text, options.getUrlInfo, options.logger);
249
243
  }
250
244
  if (urlInfo) {
251
- extContent.canonicalUrl = urlInfo['canonical-url'];
252
245
  extContent.matchedText = urlInfo['matched-text'];
253
246
  extContent.jpegThumbnail = urlInfo.jpegThumbnail;
254
247
  extContent.description = urlInfo.description;
@@ -272,6 +265,10 @@ const generateWAMessageContent = async (message, options) => {
272
265
  extContent.font = options.font;
273
266
  }
274
267
  m.extendedTextMessage = extContent;
268
+ //WhatsApp always sends secretMessage along with the text message
269
+ m.messageContextInfo = {
270
+ messageSecret: (0, crypto_1.randomBytes)(32)
271
+ };
275
272
  }
276
273
  else if ('contacts' in message) {
277
274
  const contactLen = message.contacts.contacts.length;
@@ -336,6 +333,27 @@ const generateWAMessageContent = async (message, options) => {
336
333
  m.pinInChatMessage.senderTimestampMs = Date.now();
337
334
  m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0;
338
335
  }
336
+ else if ('keep' in message) {
337
+ m.keepInChatMessage = {};
338
+ m.keepInChatMessage.key = message.keep;
339
+ m.keepInChatMessage.keepType = message.type;
340
+ m.keepInChatMessage.timestampMs = Date.now();
341
+ }
342
+ else if ('call' in message) {
343
+ m = {
344
+ scheduledCallCreationMessage: {
345
+ scheduledTimestampMs: (_a = message.call.time) !== null && _a !== void 0 ? _a : Date.now(),
346
+ callType: (_b = message.call.type) !== null && _b !== void 0 ? _b : 1,
347
+ title: message.call.title
348
+ }
349
+ };
350
+ }
351
+ else if ('paymentInvite' in message) {
352
+ m.paymentInviteMessage = {
353
+ serviceType: message.paymentInvite.type,
354
+ expiryTimestamp: message.paymentInvite.expiry
355
+ };
356
+ }
339
357
  else if ('buttonReply' in message) {
340
358
  switch (message.type) {
341
359
  case 'template':
@@ -368,12 +386,27 @@ const generateWAMessageContent = async (message, options) => {
368
386
  }
369
387
  });
370
388
  }
389
+ else if ('order' in message) {
390
+ m.orderMessage = Types_1.WAProto.Message.OrderMessage.fromObject({
391
+ orderId: message.order.id,
392
+ thumbnail: message.order.thumbnail,
393
+ itemCount: message.order.itemCount,
394
+ status: message.order.status,
395
+ surface: message.order.surface,
396
+ orderTitle: message.order.title,
397
+ message: message.order.text,
398
+ sellerJid: message.order.seller,
399
+ token: message.order.token,
400
+ totalAmount1000: message.order.amount,
401
+ totalCurrencyCode: message.order.currency
402
+ });
403
+ }
371
404
  else if ('listReply' in message) {
372
405
  m.listResponseMessage = { ...message.listReply };
373
406
  }
374
407
  else if ('poll' in message) {
375
- (_b = message.poll).selectableCount || (_b.selectableCount = 0);
376
- (_c = message.poll).toAnnouncementGroup || (_c.toAnnouncementGroup = false);
408
+ (_p = message.poll).selectableCount || (_p.selectableCount = 0);
409
+ (_q = message.poll).toAnnouncementGroup || (_q.toAnnouncementGroup = false);
377
410
  if (!Array.isArray(message.poll.values)) {
378
411
  throw new boom_1.Boom('Invalid poll values', { statusCode: 400 });
379
412
  }
@@ -396,7 +429,7 @@ const generateWAMessageContent = async (message, options) => {
396
429
  }
397
430
  else {
398
431
  if (message.poll.selectableCount > 0) {
399
- //poll v3 is for single select polls
432
+ // poll v3 is for single select polls
400
433
  m.pollCreationMessageV3 = pollCreationMessage;
401
434
  }
402
435
  else {
@@ -405,6 +438,53 @@ const generateWAMessageContent = async (message, options) => {
405
438
  }
406
439
  }
407
440
  }
441
+ else if ('event' in message) {
442
+ m.messageContextInfo = {
443
+ messageSecret: message.event.messageSecret || (0, crypto_1.randomBytes)(32),
444
+ };
445
+ m.eventMessage = { ...message.event };
446
+ }
447
+ else if ('inviteAdmin' in message) {
448
+ m.newsletterAdminInviteMessage = {};
449
+ m.newsletterAdminInviteMessage.inviteExpiration = message.inviteAdmin.inviteExpiration;
450
+ m.newsletterAdminInviteMessage.caption = message.inviteAdmin.text;
451
+ m.newsletterAdminInviteMessage.newsletterJid = message.inviteAdmin.jid;
452
+ m.newsletterAdminInviteMessage.newsletterName = message.inviteAdmin.subject;
453
+ m.newsletterAdminInviteMessage.jpegThumbnail = message.inviteAdmin.thumbnail;
454
+ }
455
+ else if ('requestPayment' in message) {
456
+ const sticker = ((_c = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _c === void 0 ? void 0 : _c.sticker) ?
457
+ await (0, exports.prepareWAMessageMedia)({ sticker: (_d = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _d === void 0 ? void 0 : _d.sticker, ...options }, options)
458
+ : null;
459
+ let notes = {};
460
+ if ((_e = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _e === void 0 ? void 0 : _e.sticker) {
461
+ notes = {
462
+ stickerMessage: {
463
+ ...sticker === null || sticker === void 0 ? void 0 : sticker.stickerMessage,
464
+ contextInfo: (_f = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _f === void 0 ? void 0 : _f.contextInfo
465
+ }
466
+ };
467
+ }
468
+ else if (message.requestPayment.note) {
469
+ notes = {
470
+ extendedTextMessage: {
471
+ text: message.requestPayment.note,
472
+ contextInfo: (_g = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _g === void 0 ? void 0 : _g.contextInfo,
473
+ }
474
+ };
475
+ }
476
+ else {
477
+ throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
478
+ }
479
+ m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
480
+ expiryTimestamp: message.requestPayment.expiry,
481
+ amount1000: message.requestPayment.amount,
482
+ currencyCodeIso4217: message.requestPayment.currency,
483
+ requestFrom: message.requestPayment.from,
484
+ noteMessage: { ...notes },
485
+ background: (_h = message.requestPayment.background) !== null && _h !== void 0 ? _h : null,
486
+ });
487
+ }
408
488
  else if ('sharePhoneNumber' in message) {
409
489
  m.protocolMessage = {
410
490
  type: WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
@@ -416,10 +496,162 @@ const generateWAMessageContent = async (message, options) => {
416
496
  else {
417
497
  m = await (0, exports.prepareWAMessageMedia)(message, options);
418
498
  }
499
+ if ('buttons' in message && !!message.buttons) {
500
+ const buttonsMessage = {
501
+ buttons: message.buttons.map(b => ({ ...b, type: WAProto_1.proto.Message.ButtonsMessage.Button.Type.RESPONSE }))
502
+ };
503
+ if ('text' in message) {
504
+ buttonsMessage.contentText = message.text;
505
+ buttonsMessage.headerType = ButtonType.EMPTY;
506
+ }
507
+ else {
508
+ if ('caption' in message) {
509
+ buttonsMessage.contentText = message.caption;
510
+ }
511
+ const type = Object.keys(m)[0].replace('Message', '').toUpperCase();
512
+ buttonsMessage.headerType = ButtonType[type];
513
+ Object.assign(buttonsMessage, m);
514
+ }
515
+ if ('title' in message && !!message.title) {
516
+ buttonsMessage.text = message.title,
517
+ buttonsMessage.headerType = ButtonType.TEXT;
518
+ }
519
+ if ('footer' in message && !!message.footer) {
520
+ buttonsMessage.footerText = message.footer;
521
+ }
522
+ if ('contextInfo' in message && !!message.contextInfo) {
523
+ buttonsMessage.contextInfo = message.contextInfo;
524
+ }
525
+ if ('mentions' in message && !!message.mentions) {
526
+ buttonsMessage.contextInfo = { mentionedJid: message.mentions };
527
+ }
528
+ m = { buttonsMessage };
529
+ }
530
+ else if ('templateButtons' in message && !!message.templateButtons) {
531
+ const msg = {
532
+ hydratedButtons: message.hasOwnProperty("templateButtons") ? message.templateButtons : message.templateButtons
533
+ };
534
+ if ('text' in message) {
535
+ msg.hydratedContentText = message.text;
536
+ }
537
+ else {
538
+ if ('caption' in message) {
539
+ msg.hydratedContentText = message.caption;
540
+ }
541
+ Object.assign(msg, m);
542
+ }
543
+ if ('footer' in message && !!message.footer) {
544
+ msg.hydratedFooterText = message.footer;
545
+ }
546
+ m = {
547
+ templateMessage: {
548
+ fourRowTemplate: msg,
549
+ hydratedTemplate: msg
550
+ }
551
+ };
552
+ }
553
+ if ('sections' in message && !!message.sections) {
554
+ const listMessage = {
555
+ sections: message.sections,
556
+ buttonText: message.buttonText,
557
+ title: message.title,
558
+ footerText: message.footer,
559
+ description: message.text,
560
+ listType: message.hasOwnProperty('listType') ? message.listType : WAProto_1.proto.Message.ListMessage.ListType.PRODUCT_LIST
561
+ };
562
+ m = { listMessage };
563
+ }
564
+ if ('interactiveButtons' in message && !!message.interactiveButtons) {
565
+ const interactiveMessage = {
566
+ nativeFlowMessage: Types_1.WAProto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
567
+ buttons: message.interactiveButtons,
568
+ })
569
+ };
570
+ if ('text' in message) {
571
+ interactiveMessage.body = {
572
+ text: message.text
573
+ };
574
+ }
575
+ else if ('caption' in message) {
576
+ interactiveMessage.body = {
577
+ text: message.caption
578
+ };
579
+ interactiveMessage.header = {
580
+ title: message.title,
581
+ subtitle: message.subtitle,
582
+ hasMediaAttachment: (_j = message === null || message === void 0 ? void 0 : message.media) !== null && _j !== void 0 ? _j : false,
583
+ };
584
+ Object.assign(interactiveMessage.header, m);
585
+ }
586
+ if ('footer' in message && !!message.footer) {
587
+ interactiveMessage.footer = {
588
+ text: message.footer
589
+ };
590
+ }
591
+ if ('title' in message && !!message.title) {
592
+ interactiveMessage.header = {
593
+ title: message.title,
594
+ subtitle: message.subtitle,
595
+ hasMediaAttachment: (_k = message === null || message === void 0 ? void 0 : message.media) !== null && _k !== void 0 ? _k : false,
596
+ };
597
+ Object.assign(interactiveMessage.header, m);
598
+ }
599
+ if ('contextInfo' in message && !!message.contextInfo) {
600
+ interactiveMessage.contextInfo = message.contextInfo;
601
+ }
602
+ if ('mentions' in message && !!message.mentions) {
603
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
604
+ }
605
+ m = { interactiveMessage };
606
+ }
607
+ if ('shop' in message && !!message.shop) {
608
+ const interactiveMessage = {
609
+ shopStorefrontMessage: Types_1.WAProto.Message.InteractiveMessage.ShopMessage.fromObject({
610
+ surface: message.shop,
611
+ id: message.id
612
+ })
613
+ };
614
+ if ('text' in message) {
615
+ interactiveMessage.body = {
616
+ text: message.text
617
+ };
618
+ }
619
+ else if ('caption' in message) {
620
+ interactiveMessage.body = {
621
+ text: message.caption
622
+ };
623
+ interactiveMessage.header = {
624
+ title: message.title,
625
+ subtitle: message.subtitle,
626
+ hasMediaAttachment: (_l = message === null || message === void 0 ? void 0 : message.media) !== null && _l !== void 0 ? _l : false,
627
+ };
628
+ Object.assign(interactiveMessage.header, m);
629
+ }
630
+ if ('footer' in message && !!message.footer) {
631
+ interactiveMessage.footer = {
632
+ text: message.footer
633
+ };
634
+ }
635
+ if ('title' in message && !!message.title) {
636
+ interactiveMessage.header = {
637
+ title: message.title,
638
+ subtitle: message.subtitle,
639
+ hasMediaAttachment: (_m = message === null || message === void 0 ? void 0 : message.media) !== null && _m !== void 0 ? _m : false,
640
+ };
641
+ Object.assign(interactiveMessage.header, m);
642
+ }
643
+ if ('contextInfo' in message && !!message.contextInfo) {
644
+ interactiveMessage.contextInfo = message.contextInfo;
645
+ }
646
+ if ('mentions' in message && !!message.mentions) {
647
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
648
+ }
649
+ m = { interactiveMessage };
650
+ }
419
651
  if ('viewOnce' in message && !!message.viewOnce) {
420
652
  m = { viewOnceMessage: { message: m } };
421
653
  }
422
- if ('mentions' in message && ((_a = message.mentions) === null || _a === void 0 ? void 0 : _a.length)) {
654
+ if ('mentions' in message && ((_o = message.mentions) === null || _o === void 0 ? void 0 : _o.length)) {
423
655
  const [messageType] = Object.keys(m);
424
656
  m[messageType].contextInfo = m[messageType] || {};
425
657
  m[messageType].contextInfo.mentionedJid = message.mentions;
@@ -452,26 +684,29 @@ const generateWAMessageFromContent = (jid, message, options) => {
452
684
  const key = (0, exports.getContentType)(innerMessage);
453
685
  const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp);
454
686
  const { quoted, userJid } = options;
455
- if (quoted) {
687
+ // only set quoted if isn't a newsletter message
688
+ if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
456
689
  const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid);
457
690
  let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message);
458
691
  const msgType = (0, exports.getContentType)(quotedMsg);
459
692
  // strip any redundant properties
460
- quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
461
- const quotedContent = quotedMsg[msgType];
462
- if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
463
- delete quotedContent.contextInfo;
464
- }
465
- const contextInfo = innerMessage[key].contextInfo || {};
466
- contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
467
- contextInfo.stanzaId = quoted.key.id;
468
- contextInfo.quotedMessage = quotedMsg;
469
- // if a participant is quoted, then it must be a group
470
- // hence, remoteJid of group must also be entered
471
- if (jid !== quoted.key.remoteJid) {
472
- contextInfo.remoteJid = quoted.key.remoteJid;
473
- }
474
- innerMessage[key].contextInfo = contextInfo;
693
+ if (quotedMsg) {
694
+ quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
695
+ const quotedContent = quotedMsg[msgType];
696
+ if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
697
+ delete quotedContent.contextInfo;
698
+ }
699
+ const contextInfo = innerMessage[key].contextInfo || {};
700
+ contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
701
+ contextInfo.stanzaId = quoted.key.id;
702
+ contextInfo.quotedMessage = quotedMsg;
703
+ // if a participant is quoted, then it must be a group
704
+ // hence, remoteJid of group must also be entered
705
+ if (jid !== quoted.key.remoteJid) {
706
+ contextInfo.remoteJid = quoted.key.remoteJid;
707
+ }
708
+ innerMessage[key].contextInfo = contextInfo;
709
+ }
475
710
  }
476
711
  if (
477
712
  // if we want to send a disappearing message
@@ -479,7 +714,9 @@ const generateWAMessageFromContent = (jid, message, options) => {
479
714
  // and it's not a protocol message -- delete, toggle disappear message
480
715
  key !== 'protocolMessage' &&
481
716
  // already not converted to disappearing message
482
- key !== 'ephemeralMessage') {
717
+ key !== 'ephemeralMessage' &&
718
+ // newsletter not accept disappearing messages
719
+ !(0, WABinary_1.isJidNewsletter)(jid)) {
483
720
  innerMessage[key].contextInfo = {
484
721
  ...(innerMessage[key].contextInfo || {}),
485
722
  expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL,
@@ -491,7 +728,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
491
728
  key: {
492
729
  remoteJid: jid,
493
730
  fromMe: true,
494
- id: (options === null || options === void 0 ? void 0 : options.messageId) || (0, generics_1.generateMessageID)(),
731
+ id: (options === null || options === void 0 ? void 0 : options.messageId) || (0, generics_1.generateMessageIDV2)(),
495
732
  },
496
733
  message: message,
497
734
  messageTimestamp: timestamp,
@@ -506,7 +743,7 @@ const generateWAMessage = async (jid, content, options) => {
506
743
  var _a;
507
744
  // ensure msg ID is with every log
508
745
  options.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) === null || _a === void 0 ? void 0 : _a.child({ msgId: options.messageId });
509
- return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, options), options);
746
+ return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsletter)(jid), ...options }), options);
510
747
  };
511
748
  exports.generateWAMessage = generateWAMessage;
512
749
  /** Get the key to access the true type of content */
@@ -543,7 +780,22 @@ const normalizeMessageContent = (content) => {
543
780
  || (message === null || message === void 0 ? void 0 : message.documentWithCaptionMessage)
544
781
  || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2)
545
782
  || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension)
546
- || (message === null || message === void 0 ? void 0 : message.editedMessage));
783
+ || (message === null || message === void 0 ? void 0 : message.editedMessage)
784
+ || (message === null || message === void 0 ? void 0 : message.groupMentionedMessage)
785
+ || (message === null || message === void 0 ? void 0 : message.botInvokeMessage)
786
+ || (message === null || message === void 0 ? void 0 : message.lottieStickerMessage)
787
+ || (message === null || message === void 0 ? void 0 : message.eventCoverImage)
788
+ || (message === null || message === void 0 ? void 0 : message.statusMentionMessage)
789
+ || (message === null || message === void 0 ? void 0 : message.pollCreationOptionImageMessage)
790
+ || (message === null || message === void 0 ? void 0 : message.associatedChildMessage)
791
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMentionMessage)
792
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV4)
793
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV5)
794
+ || (message === null || message === void 0 ? void 0 : message.statusAddYours)
795
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMessage)
796
+ || (message === null || message === void 0 ? void 0 : message.limitSharingMessage)
797
+ || (message === null || message === void 0 ? void 0 : message.botTaskMessage)
798
+ || (message === null || message === void 0 ? void 0 : message.questionMessage));
547
799
  }
548
800
  };
549
801
  exports.normalizeMessageContent = normalizeMessageContent;
@@ -1,9 +1,9 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
+ import { ILogger } from './logger';
3
4
  import { proto } from '../../WAProto';
4
5
  import { KeyPair } from '../Types';
5
6
  import { BinaryNode } from '../WABinary';
6
- import { ILogger } from './logger';
7
7
  export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }: {
8
8
  keyPair: KeyPair;
9
9
  NOISE_HEADER: Uint8Array;
@@ -201,7 +201,6 @@ const processMessage = async (message, { shouldProcessHistoryMsg, placeholderRes
201
201
  const { peerDataOperationResult } = response;
202
202
  for (const result of peerDataOperationResult) {
203
203
  const { placeholderMessageResendResponse: retryResponse } = result;
204
- //eslint-disable-next-line max-depth
205
204
  if (retryResponse) {
206
205
  const webMessageInfo = WAProto_1.proto.WebMessageInfo.decode(retryResponse.webMessageInfoBytes);
207
206
  // wait till another upsert event is available, don't want it to be part of the PDO response message
@@ -1,10 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.useMultiFileAuthState = void 0;
7
- const async_lock_1 = __importDefault(require("async-lock"));
4
+ const async_mutex_1 = require("async-mutex");
8
5
  const promises_1 = require("fs/promises");
9
6
  const path_1 = require("path");
10
7
  const WAProto_1 = require("../../WAProto");
@@ -13,9 +10,17 @@ const generics_1 = require("./generics");
13
10
  // We need to lock files due to the fact that we are using async functions to read and write files
14
11
  // https://github.com/WhiskeySockets/Baileys/issues/794
15
12
  // https://github.com/nodejs/node/issues/26338
16
- // Default pending is 1000, set it to infinity
17
- // https://github.com/rogierschouten/async-lock/issues/63
18
- const fileLock = new async_lock_1.default({ maxPending: Infinity });
13
+ // Use a Map to store mutexes for each file path
14
+ const fileLocks = new Map();
15
+ // Get or create a mutex for a specific file path
16
+ const getFileLock = (path) => {
17
+ let mutex = fileLocks.get(path);
18
+ if (!mutex) {
19
+ mutex = new async_mutex_1.Mutex();
20
+ fileLocks.set(path, mutex);
21
+ }
22
+ return mutex;
23
+ };
19
24
  /**
20
25
  * stores the full authentication state in a single folder.
21
26
  * Far more efficient than singlefileauthstate
@@ -25,15 +30,31 @@ const fileLock = new async_lock_1.default({ maxPending: Infinity });
25
30
  * */
26
31
  const useMultiFileAuthState = async (folder) => {
27
32
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
- const writeData = (data, file) => {
33
+ const writeData = async (data, file) => {
29
34
  const filePath = (0, path_1.join)(folder, fixFileName(file));
30
- return fileLock.acquire(filePath, () => (0, promises_1.writeFile)((0, path_1.join)(filePath), JSON.stringify(data, generics_1.BufferJSON.replacer)));
35
+ const mutex = getFileLock(filePath);
36
+ return mutex.acquire().then(async (release) => {
37
+ try {
38
+ await (0, promises_1.writeFile)(filePath, JSON.stringify(data, generics_1.BufferJSON.replacer));
39
+ }
40
+ finally {
41
+ release();
42
+ }
43
+ });
31
44
  };
32
45
  const readData = async (file) => {
33
46
  try {
34
47
  const filePath = (0, path_1.join)(folder, fixFileName(file));
35
- const data = await fileLock.acquire(filePath, () => (0, promises_1.readFile)(filePath, { encoding: 'utf-8' }));
36
- return JSON.parse(data, generics_1.BufferJSON.reviver);
48
+ const mutex = getFileLock(filePath);
49
+ return await mutex.acquire().then(async (release) => {
50
+ try {
51
+ const data = await (0, promises_1.readFile)(filePath, { encoding: 'utf-8' });
52
+ return JSON.parse(data, generics_1.BufferJSON.reviver);
53
+ }
54
+ finally {
55
+ release();
56
+ }
57
+ });
37
58
  }
38
59
  catch (error) {
39
60
  return null;
@@ -42,7 +63,17 @@ const useMultiFileAuthState = async (folder) => {
42
63
  const removeData = async (file) => {
43
64
  try {
44
65
  const filePath = (0, path_1.join)(folder, fixFileName(file));
45
- await fileLock.acquire(filePath, () => (0, promises_1.unlink)(filePath));
66
+ const mutex = getFileLock(filePath);
67
+ return mutex.acquire().then(async (release) => {
68
+ try {
69
+ await (0, promises_1.unlink)(filePath);
70
+ }
71
+ catch (_a) {
72
+ }
73
+ finally {
74
+ release();
75
+ }
76
+ });
46
77
  }
47
78
  catch (_a) {
48
79
  }
@@ -86,7 +117,7 @@ const useMultiFileAuthState = async (folder) => {
86
117
  }
87
118
  }
88
119
  },
89
- saveCreds: () => {
120
+ saveCreds: async () => {
90
121
  return writeData(creds, 'creds.json');
91
122
  }
92
123
  };
@@ -22,9 +22,7 @@ const getUserAgent = (config) => {
22
22
  device: 'Desktop',
23
23
  osBuildNumber: '0.1',
24
24
  localeLanguageIso6391: 'en',
25
- mnc: '000',
26
- mcc: '000',
27
- localeCountryIso31661Alpha2: config.countryCode,
25
+ localeCountryIso31661Alpha2: config.countryCode
28
26
  };
29
27
  };
30
28
  const PLATFORM_MAP = {