alipclutch-baileys 8.3.0 → 8.4.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 (120) hide show
  1. package/LICENSE +3 -1
  2. package/README.md +10 -9
  3. package/WAProto/GenerateStatics.sh +4 -0
  4. package/WAProto/WAProto.proto +4775 -0
  5. package/WAProto/index.d.ts +55057 -0
  6. package/WAProto/index.js +56887 -17535
  7. package/WAProto/index.ts.ts +53473 -0
  8. package/lib/Defaults/baileys-version.json +2 -2
  9. package/lib/Defaults/index.d.ts +16 -7
  10. package/lib/Defaults/index.js +90 -119
  11. package/lib/Socket/Client/index.d.ts +2 -3
  12. package/lib/Socket/Client/index.js +2 -3
  13. package/lib/Socket/Client/types.d.ts +0 -1
  14. package/lib/Socket/Client/types.js +0 -1
  15. package/lib/Socket/Client/websocket.d.ts +0 -1
  16. package/lib/Socket/Client/websocket.js +0 -1
  17. package/lib/Socket/business.d.ts +59 -58
  18. package/lib/Socket/chats.d.ts +45 -230
  19. package/lib/Socket/chats.js +139 -238
  20. package/lib/Socket/groups.d.ts +41 -32
  21. package/lib/Socket/groups.js +38 -23
  22. package/lib/Socket/index.d.ts +63 -64
  23. package/lib/Socket/index.js +2 -3
  24. package/lib/Socket/messages-recv.js +9 -65
  25. package/lib/Socket/messages-send.d.ts +49 -47
  26. package/lib/Socket/messages-send.js +584 -395
  27. package/lib/Socket/newsletter.d.ts +39 -37
  28. package/lib/Socket/newsletter.js +88 -123
  29. package/lib/Socket/setup.js +433 -0
  30. package/lib/Socket/{dugong.d.ts → setup.ts} +17 -52
  31. package/lib/Socket/socket.d.ts +10 -10
  32. package/lib/Socket/socket.js +62 -38
  33. package/lib/Socket/usync.d.ts +3 -4
  34. package/lib/Socket/usync.js +0 -1
  35. package/lib/Store/index.d.ts +1 -2
  36. package/lib/Store/index.js +1 -3
  37. package/lib/Store/make-in-memory-store.d.ts +24 -24
  38. package/lib/Store/make-in-memory-store.js +26 -14
  39. package/lib/Store/make-ordered-dictionary.d.ts +1 -1
  40. package/lib/Store/make-ordered-dictionary.js +2 -2
  41. package/lib/Types/Auth.d.ts +0 -7
  42. package/lib/Types/Call.d.ts +1 -1
  43. package/lib/Types/Chat.d.ts +14 -7
  44. package/lib/Types/Contact.d.ts +5 -1
  45. package/lib/Types/Events.d.ts +44 -2
  46. package/lib/Types/GroupMetadata.d.ts +11 -2
  47. package/lib/Types/Label.js +1 -1
  48. package/lib/Types/LabelAssociation.js +1 -1
  49. package/lib/Types/Message.d.ts +148 -21
  50. package/lib/Types/Message.js +0 -2
  51. package/lib/Types/Newsletter.d.ts +73 -97
  52. package/lib/Types/Newsletter.js +18 -38
  53. package/lib/Types/Socket.d.ts +17 -9
  54. package/lib/Types/index.d.ts +8 -1
  55. package/lib/Types/index.js +2 -2
  56. package/lib/Utils/auth-utils.d.ts +3 -3
  57. package/lib/Utils/auth-utils.js +6 -13
  58. package/lib/Utils/business.js +2 -2
  59. package/lib/Utils/chat-utils.d.ts +15 -16
  60. package/lib/Utils/chat-utils.js +36 -35
  61. package/lib/Utils/crypto.d.ts +15 -16
  62. package/lib/Utils/crypto.js +71 -29
  63. package/lib/Utils/decode-wa-message.d.ts +22 -6
  64. package/lib/Utils/decode-wa-message.js +65 -56
  65. package/lib/Utils/event-buffer.d.ts +2 -2
  66. package/lib/Utils/event-buffer.js +11 -7
  67. package/lib/Utils/generics.d.ts +17 -20
  68. package/lib/Utils/generics.js +95 -75
  69. package/lib/Utils/history.d.ts +4 -0
  70. package/lib/Utils/history.js +4 -6
  71. package/lib/Utils/link-preview.d.ts +2 -2
  72. package/lib/Utils/link-preview.js +34 -1
  73. package/lib/Utils/logger.d.ts +10 -3
  74. package/lib/Utils/lt-hash.d.ts +2 -2
  75. package/lib/Utils/lt-hash.js +6 -6
  76. package/lib/Utils/make-mutex.d.ts +2 -2
  77. package/lib/Utils/messages-media.d.ts +28 -24
  78. package/lib/Utils/messages-media.js +272 -111
  79. package/lib/Utils/messages.d.ts +13 -10
  80. package/lib/Utils/messages.js +323 -50
  81. package/lib/Utils/noise-handler.d.ts +10 -12
  82. package/lib/Utils/noise-handler.js +18 -23
  83. package/lib/Utils/process-message.d.ts +5 -4
  84. package/lib/Utils/process-message.js +108 -25
  85. package/lib/Utils/signal.d.ts +2 -1
  86. package/lib/Utils/signal.js +26 -26
  87. package/lib/Utils/use-multi-file-auth-state.d.ts +0 -1
  88. package/lib/Utils/use-multi-file-auth-state.js +51 -6
  89. package/lib/Utils/validate-connection.d.ts +3 -4
  90. package/lib/Utils/validate-connection.js +90 -66
  91. package/lib/WABinary/constants.d.ts +24 -27
  92. package/lib/WABinary/constants.js +1276 -13
  93. package/lib/WABinary/decode.d.ts +3 -4
  94. package/lib/WABinary/decode.js +26 -13
  95. package/lib/WABinary/encode.d.ts +1 -2
  96. package/lib/WABinary/encode.js +137 -152
  97. package/lib/WABinary/generic-utils.d.ts +1 -4
  98. package/lib/WABinary/generic-utils.js +37 -125
  99. package/lib/WABinary/jid-utils.d.ts +11 -5
  100. package/lib/WABinary/jid-utils.js +28 -5
  101. package/lib/WABinary/jid-utils.js.bak +83 -0
  102. package/lib/WAM/BinaryInfo.d.ts +2 -11
  103. package/lib/WAM/encode.d.ts +1 -2
  104. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -1
  105. package/lib/index.d.ts +0 -1
  106. package/lib/index.js +27 -15
  107. package/package.json +18 -31
  108. package/engine-requirements.js +0 -10
  109. package/lib/Defaults/phonenumber-mcc.json +0 -223
  110. package/lib/Socket/Client/abstract-socket-client.d.ts +0 -17
  111. package/lib/Socket/Client/abstract-socket-client.js +0 -13
  112. package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
  113. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  114. package/lib/Socket/Client/web-socket-client.d.ts +0 -12
  115. package/lib/Socket/Client/web-socket-client.js +0 -62
  116. package/lib/Socket/dugong.js +0 -483
  117. package/lib/Socket/registration.d.ts +0 -267
  118. package/lib/Socket/registration.js +0 -166
  119. package/lib/Store/make-cache-manager-store.d.ts +0 -13
  120. package/lib/Store/make-cache-manager-store.js +0 -83
@@ -1,8 +1,6 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
- import { Logger } from 'pino';
4
1
  import { type Transform } from 'stream';
5
2
  import { proto } from '../../WAProto';
3
+ import { ILogger } from './logger';
6
4
  import { AnyMediaMessageContent, AnyMessageContent, MediaGenerationOptions, MessageContentGenerationOptions, MessageGenerationOptions, MessageGenerationOptionsFromContent, MessageUserReceipt, WAMessage, WAMessageContent, WAProto } from '../Types';
7
5
  import { MediaDownloadOptions } from './messages-media';
8
6
  /**
@@ -11,7 +9,7 @@ import { MediaDownloadOptions } from './messages-media';
11
9
  * @returns the URL, eg. https://google.com
12
10
  */
13
11
  export declare const extractUrlFromText: (text: string) => string | undefined;
14
- export declare const generateLinkPreviewIfRequired: (text: string, getUrlInfo: MessageGenerationOptions['getUrlInfo'], logger: MessageGenerationOptions['logger']) => Promise<import("../Types").WAUrlInfo | undefined>;
12
+ export declare const generateLinkPreviewIfRequired: (text: string, getUrlInfo: MessageGenerationOptions["getUrlInfo"], logger: MessageGenerationOptions["logger"]) => Promise<import("../Types").WAUrlInfo | undefined>;
15
13
  export declare const prepareWAMessageMedia: (message: AnyMediaMessageContent, options: MediaGenerationOptions) => Promise<proto.Message>;
16
14
  export declare const prepareDisappearingMessageSettingContent: (ephemeralExpiration?: number) => proto.Message;
17
15
  /**
@@ -40,13 +38,13 @@ export declare const extractMessageContent: (content: WAMessageContent | undefin
40
38
  /**
41
39
  * Returns the device predicted by message ID
42
40
  */
43
- export declare const getDevice: (id: string) => "android" | "unknown" | "web" | "ios" | "desktop";
41
+ export declare const getDevice: (id: string) => "web" | "unknown" | "android" | "ios" | "desktop";
44
42
  /** Upserts a receipt in the message */
45
- export declare const updateMessageWithReceipt: (msg: Pick<WAMessage, 'userReceipt'>, receipt: MessageUserReceipt) => void;
43
+ export declare const updateMessageWithReceipt: (msg: Pick<WAMessage, "userReceipt">, receipt: MessageUserReceipt) => void;
46
44
  /** Update the message with a new reaction */
47
- export declare const updateMessageWithReaction: (msg: Pick<WAMessage, 'reactions'>, reaction: proto.IReaction) => void;
45
+ export declare const updateMessageWithReaction: (msg: Pick<WAMessage, "reactions">, reaction: proto.IReaction) => void;
48
46
  /** Update the message with a new poll update */
49
- export declare const updateMessageWithPollUpdate: (msg: Pick<WAMessage, 'pollUpdates'>, update: proto.IPollUpdate) => void;
47
+ export declare const updateMessageWithPollUpdate: (msg: Pick<WAMessage, "pollUpdates">, update: proto.IPollUpdate) => void;
50
48
  type VoteAggregation = {
51
49
  name: string;
52
50
  voters: string[];
@@ -66,12 +64,17 @@ export declare const aggregateMessageKeysNotFromMe: (keys: proto.IMessageKey[])
66
64
  }[];
67
65
  type DownloadMediaMessageContext = {
68
66
  reuploadRequest: (msg: WAMessage) => Promise<WAMessage>;
69
- logger: Logger;
67
+ logger: ILogger;
70
68
  };
71
69
  /**
72
70
  * Downloads the given message. Throws an error if it's not a media message
73
71
  */
74
- export declare const downloadMediaMessage: <Type extends "stream" | "buffer">(message: WAMessage, type: Type, options: MediaDownloadOptions, ctx?: DownloadMediaMessageContext) => Promise<Type extends "buffer" ? Buffer : Transform>;
72
+ export declare const downloadMediaMessage: <Type extends "buffer" | "stream">(message: WAMessage, type: Type, options: MediaDownloadOptions, ctx?: DownloadMediaMessageContext) => Promise<Type extends "buffer" ? Buffer<ArrayBufferLike> : Transform>;
75
73
  /** Checks whether the given message is a media message; if it is returns the inner content */
76
74
  export declare const assertMediaContent: (content: proto.IMessage | null | undefined) => proto.Message.IVideoMessage | proto.Message.IImageMessage | proto.Message.IAudioMessage | proto.Message.IDocumentMessage | proto.Message.IStickerMessage;
75
+ export declare const toJid: (id: string) => string;
76
+ export declare const getSenderLid: (msg: WAMessage) => {
77
+ jid: string;
78
+ lid: string;
79
+ };
77
80
  export {};
@@ -1,9 +1,10 @@
1
- "use strict";
1
+ "use strict";
2
2
  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.assertMediaContent = exports.downloadMediaMessage = exports.aggregateMessageKeysNotFromMe = exports.getAggregateVotesInPollMessage = exports.updateMessageWithPollUpdate = exports.updateMessageWithReaction = exports.updateMessageWithReceipt = exports.getDevice = exports.extractMessageContent = exports.normalizeMessageContent = exports.getContentType = exports.generateWAMessage = exports.generateWAMessageFromContent = exports.generateWAMessageContent = exports.generateForwardMessageContent = exports.prepareDisappearingMessageSettingContent = exports.prepareWAMessageMedia = exports.generateLinkPreviewIfRequired = exports.extractUrlFromText = void 0;
6
+ exports.assertMediaContent = exports.downloadMediaMessage = exports.aggregateMessageKeysNotFromMe = exports.updateMessageWithPollUpdate = exports.updateMessageWithReaction = exports.updateMessageWithReceipt = exports.getDevice = exports.extractMessageContent = exports.normalizeMessageContent = exports.getContentType = exports.generateWAMessage = exports.generateWAMessageFromContent = exports.generateWAMessageContent = exports.generateForwardMessageContent = exports.prepareDisappearingMessageSettingContent = exports.prepareWAMessageMedia = exports.generateLinkPreviewIfRequired = exports.extractUrlFromText = void 0;
7
+ exports.getAggregateVotesInPollMessage = getAggregateVotesInPollMessage;
7
8
  const boom_1 = require("@hapi/boom");
8
9
  const axios_1 = __importDefault(require("axios"));
9
10
  const crypto_1 = require("crypto");
@@ -74,11 +75,8 @@ const prepareWAMessageMedia = async (message, options) => {
74
75
  }
75
76
  }
76
77
  if (!mediaType) {
77
- throw new boom_1.Boom('Invalid media type', {
78
- statusCode: 400
79
- });
78
+ throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
80
79
  }
81
-
82
80
  const uploadData = {
83
81
  ...message,
84
82
  ...(message.annotations ? {
@@ -116,20 +114,20 @@ const prepareWAMessageMedia = async (message, options) => {
116
114
  media: message[mediaType]
117
115
  };
118
116
  delete uploadData[mediaType];
117
+ // check if cacheable + generate cache key
119
118
  const cacheableKey = typeof uploadData.media === 'object' &&
120
119
  ('url' in uploadData.media) &&
121
120
  !!uploadData.media.url &&
122
121
  !!options.mediaCache && (
122
+ // generate the key
123
123
  mediaType + ':' + uploadData.media.url.toString());
124
-
125
124
  if (mediaType === 'document' && !uploadData.fileName) {
126
125
  uploadData.fileName = 'file';
127
126
  }
128
-
129
127
  if (!uploadData.mimetype) {
130
128
  uploadData.mimetype = MIMETYPE_MAP[mediaType];
131
129
  }
132
-
130
+ // check for cache hit
133
131
  if (cacheableKey) {
134
132
  const mediaBuff = options.mediaCache.get(cacheableKey);
135
133
  if (mediaBuff) {
@@ -140,8 +138,7 @@ const prepareWAMessageMedia = async (message, options) => {
140
138
  return obj;
141
139
  }
142
140
  }
143
-
144
- const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
141
+ const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
145
142
  const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
146
143
  (typeof uploadData['jpegThumbnail'] === 'undefined');
147
144
  const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
@@ -202,13 +199,18 @@ const prepareWAMessageMedia = async (message, options) => {
202
199
  if (!Buffer.isBuffer(encWriteStream)) {
203
200
  encWriteStream.destroy();
204
201
  }
205
-
202
+ // remove tmp files
206
203
  if (didSaveToTmpPath && bodyPath) {
207
- await fs_1.promises.unlink(bodyPath);
208
- logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp files');
204
+ try {
205
+ await fs_1.promises.access(bodyPath);
206
+ await fs_1.promises.unlink(bodyPath);
207
+ logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp file');
208
+ }
209
+ catch (error) {
210
+ logger === null || logger === void 0 ? void 0 : logger.warn('failed to remove tmp file');
211
+ }
209
212
  }
210
213
  });
211
-
212
214
  const obj = Types_1.WAProto.Message.fromObject({
213
215
  [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
214
216
  url: handle ? undefined : mediaUrl,
@@ -222,17 +224,14 @@ const prepareWAMessageMedia = async (message, options) => {
222
224
  media: undefined
223
225
  })
224
226
  });
225
-
226
227
  if (uploadData.ptv) {
227
228
  obj.ptvMessage = obj.videoMessage;
228
229
  delete obj.videoMessage;
229
230
  }
230
-
231
231
  if (cacheableKey) {
232
232
  logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
233
233
  options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
234
234
  }
235
-
236
235
  return obj;
237
236
  };
238
237
  exports.prepareWAMessageMedia = prepareWAMessageMedia;
@@ -283,8 +282,8 @@ const generateForwardMessageContent = (message, forceForward) => {
283
282
  };
284
283
  exports.generateForwardMessageContent = generateForwardMessageContent;
285
284
  const generateWAMessageContent = async (message, options) => {
286
- var _a;
287
- var _b;
285
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
286
+ var _p, _q;
288
287
  let m = {};
289
288
  if ('text' in message) {
290
289
  const extContent = { text: message.text };
@@ -293,7 +292,6 @@ const generateWAMessageContent = async (message, options) => {
293
292
  urlInfo = await (0, exports.generateLinkPreviewIfRequired)(message.text, options.getUrlInfo, options.logger);
294
293
  }
295
294
  if (urlInfo) {
296
- extContent.canonicalUrl = urlInfo['canonical-url'];
297
295
  extContent.matchedText = urlInfo['matched-text'];
298
296
  extContent.jpegThumbnail = urlInfo.jpegThumbnail;
299
297
  extContent.description = urlInfo.description;
@@ -354,6 +352,54 @@ const generateWAMessageContent = async (message, options) => {
354
352
  message.disappearingMessagesInChat;
355
353
  m = (0, exports.prepareDisappearingMessageSettingContent)(exp);
356
354
  }
355
+ else if ('groupInvite' in message) {
356
+ m.groupInviteMessage = {};
357
+ m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
358
+ m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
359
+ m.groupInviteMessage.caption = message.groupInvite.text;
360
+ m.groupInviteMessage.groupJid = message.groupInvite.jid;
361
+ m.groupInviteMessage.groupName = message.groupInvite.subject;
362
+ //TODO: use built-in interface and get disappearing mode info etc.
363
+ //TODO: cache / use store!?
364
+ if (options.getProfilePicUrl) {
365
+ const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
366
+ if (pfpUrl) {
367
+ const resp = await axios_1.default.get(pfpUrl, { responseType: 'arraybuffer' });
368
+ if (resp.status === 200) {
369
+ m.groupInviteMessage.jpegThumbnail = resp.data;
370
+ }
371
+ }
372
+ }
373
+ }
374
+ else if ('pin' in message) {
375
+ m.pinInChatMessage = {};
376
+ m.messageContextInfo = {};
377
+ m.pinInChatMessage.key = message.pin;
378
+ m.pinInChatMessage.type = message.type;
379
+ m.pinInChatMessage.senderTimestampMs = Date.now();
380
+ m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0;
381
+ }
382
+ else if ('keep' in message) {
383
+ m.keepInChatMessage = {};
384
+ m.keepInChatMessage.key = message.keep;
385
+ m.keepInChatMessage.keepType = message.type;
386
+ m.keepInChatMessage.timestampMs = Date.now();
387
+ }
388
+ else if ('call' in message) {
389
+ m = {
390
+ scheduledCallCreationMessage: {
391
+ scheduledTimestampMs: (_a = message.call.time) !== null && _a !== void 0 ? _a : Date.now(),
392
+ callType: (_b = message.call.type) !== null && _b !== void 0 ? _b : 1,
393
+ title: message.call.title
394
+ }
395
+ };
396
+ }
397
+ else if ('paymentInvite' in message) {
398
+ m.paymentInviteMessage = {
399
+ serviceType: message.paymentInvite.type,
400
+ expiryTimestamp: message.paymentInvite.expiry
401
+ };
402
+ }
357
403
  else if ('buttonReply' in message) {
358
404
  switch (message.type) {
359
405
  case 'template':
@@ -372,6 +418,10 @@ const generateWAMessageContent = async (message, options) => {
372
418
  break;
373
419
  }
374
420
  }
421
+ else if ('ptv' in message && message.ptv) {
422
+ const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
423
+ m.ptvMessage = videoMessage;
424
+ }
375
425
  else if ('product' in message) {
376
426
  const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
377
427
  m.productMessage = Types_1.WAProto.Message.ProductMessage.fromObject({
@@ -382,11 +432,27 @@ const generateWAMessageContent = async (message, options) => {
382
432
  }
383
433
  });
384
434
  }
435
+ else if ('order' in message) {
436
+ m.orderMessage = Types_1.WAProto.Message.OrderMessage.fromObject({
437
+ orderId: message.order.id,
438
+ thumbnail: message.order.thumbnail,
439
+ itemCount: message.order.itemCount,
440
+ status: message.order.status,
441
+ surface: message.order.surface,
442
+ orderTitle: message.order.title,
443
+ message: message.order.text,
444
+ sellerJid: message.order.seller,
445
+ token: message.order.token,
446
+ totalAmount1000: message.order.amount,
447
+ totalCurrencyCode: message.order.currency
448
+ });
449
+ }
385
450
  else if ('listReply' in message) {
386
451
  m.listResponseMessage = { ...message.listReply };
387
452
  }
388
453
  else if ('poll' in message) {
389
- (_b = message.poll).selectableCount || (_b.selectableCount = 0);
454
+ (_p = message.poll).selectableCount || (_p.selectableCount = 0);
455
+ (_q = message.poll).toAnnouncementGroup || (_q.toAnnouncementGroup = false);
390
456
  if (!Array.isArray(message.poll.values)) {
391
457
  throw new boom_1.Boom('Invalid poll values', { statusCode: 400 });
392
458
  }
@@ -398,11 +464,72 @@ const generateWAMessageContent = async (message, options) => {
398
464
  // encKey
399
465
  messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32),
400
466
  };
401
- m.pollCreationMessage = {
467
+ const pollCreationMessage = {
402
468
  name: message.poll.name,
403
469
  selectableOptionsCount: message.poll.selectableCount,
404
470
  options: message.poll.values.map(optionName => ({ optionName })),
405
471
  };
472
+ if (message.poll.toAnnouncementGroup) {
473
+ // poll v2 is for community announcement groups (single select and multiple)
474
+ m.pollCreationMessageV2 = pollCreationMessage;
475
+ }
476
+ else {
477
+ if (message.poll.selectableCount === 1) {
478
+ // poll v3 is for single select polls
479
+ m.pollCreationMessageV3 = pollCreationMessage;
480
+ }
481
+ else {
482
+ // poll for multiple choice polls
483
+ m.pollCreationMessage = pollCreationMessage;
484
+ }
485
+ }
486
+ }
487
+ else if ('event' in message) {
488
+ m.messageContextInfo = {
489
+ messageSecret: message.event.messageSecret || (0, crypto_1.randomBytes)(32),
490
+ };
491
+ m.eventMessage = { ...message.event };
492
+ }
493
+ else if ('inviteAdmin' in message) {
494
+ m.newsletterAdminInviteMessage = {};
495
+ m.newsletterAdminInviteMessage.inviteExpiration = message.inviteAdmin.inviteExpiration;
496
+ m.newsletterAdminInviteMessage.caption = message.inviteAdmin.text;
497
+ m.newsletterAdminInviteMessage.newsletterJid = message.inviteAdmin.jid;
498
+ m.newsletterAdminInviteMessage.newsletterName = message.inviteAdmin.subject;
499
+ m.newsletterAdminInviteMessage.jpegThumbnail = message.inviteAdmin.thumbnail;
500
+ }
501
+ else if ('requestPayment' in message) {
502
+ const sticker = ((_c = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _c === void 0 ? void 0 : _c.sticker) ?
503
+ 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)
504
+ : null;
505
+ let notes = {};
506
+ if ((_e = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _e === void 0 ? void 0 : _e.sticker) {
507
+ notes = {
508
+ stickerMessage: {
509
+ ...sticker === null || sticker === void 0 ? void 0 : sticker.stickerMessage,
510
+ contextInfo: (_f = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _f === void 0 ? void 0 : _f.contextInfo
511
+ }
512
+ };
513
+ }
514
+ else if (message.requestPayment.note) {
515
+ notes = {
516
+ extendedTextMessage: {
517
+ text: message.requestPayment.note,
518
+ contextInfo: (_g = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _g === void 0 ? void 0 : _g.contextInfo,
519
+ }
520
+ };
521
+ }
522
+ else {
523
+ throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
524
+ }
525
+ m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
526
+ expiryTimestamp: message.requestPayment.expiry,
527
+ amount1000: message.requestPayment.amount,
528
+ currencyCodeIso4217: message.requestPayment.currency,
529
+ requestFrom: message.requestPayment.from,
530
+ noteMessage: { ...notes },
531
+ background: (_h = message.requestPayment.background) !== null && _h !== void 0 ? _h : null,
532
+ });
406
533
  }
407
534
  else if ('sharePhoneNumber' in message) {
408
535
  m.protocolMessage = {
@@ -412,6 +539,14 @@ const generateWAMessageContent = async (message, options) => {
412
539
  else if ('requestPhoneNumber' in message) {
413
540
  m.requestPhoneNumberMessage = {};
414
541
  }
542
+ else if ('album' in message) {
543
+ const imageMessages = message.album.filter(item => 'image' in item);
544
+ const videoMessages = message.album.filter(item => 'video' in item);
545
+ m.albumMessage = WAProto_1.proto.Message.AlbumMessage.fromObject({
546
+ expectedImageCount: imageMessages.length,
547
+ expectedVideoCount: videoMessages.length,
548
+ });
549
+ }
415
550
  else {
416
551
  m = await (0, exports.prepareWAMessageMedia)(message, options);
417
552
  }
@@ -431,14 +566,24 @@ const generateWAMessageContent = async (message, options) => {
431
566
  buttonsMessage.headerType = ButtonType[type];
432
567
  Object.assign(buttonsMessage, m);
433
568
  }
569
+ if ('title' in message && !!message.title) {
570
+ buttonsMessage.text = message.title,
571
+ buttonsMessage.headerType = ButtonType.TEXT;
572
+ }
434
573
  if ('footer' in message && !!message.footer) {
435
574
  buttonsMessage.footerText = message.footer;
436
575
  }
576
+ if ('contextInfo' in message && !!message.contextInfo) {
577
+ buttonsMessage.contextInfo = message.contextInfo;
578
+ }
579
+ if ('mentions' in message && !!message.mentions) {
580
+ buttonsMessage.contextInfo = { mentionedJid: message.mentions };
581
+ }
437
582
  m = { buttonsMessage };
438
583
  }
439
584
  else if ('templateButtons' in message && !!message.templateButtons) {
440
585
  const msg = {
441
- hydratedButtons: message.templateButtons
586
+ hydratedButtons: message.hasOwnProperty("templateButtons") ? message.templateButtons : message.templateButtons
442
587
  };
443
588
  if ('text' in message) {
444
589
  msg.hydratedContentText = message.text;
@@ -470,10 +615,97 @@ const generateWAMessageContent = async (message, options) => {
470
615
  };
471
616
  m = { listMessage };
472
617
  }
618
+ if ('interactiveButtons' in message && !!message.interactiveButtons) {
619
+ const interactiveMessage = {
620
+ nativeFlowMessage: Types_1.WAProto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
621
+ buttons: message.interactiveButtons,
622
+ })
623
+ };
624
+ if ('text' in message) {
625
+ interactiveMessage.body = {
626
+ text: message.text
627
+ };
628
+ }
629
+ else if ('caption' in message) {
630
+ interactiveMessage.body = {
631
+ text: message.caption
632
+ };
633
+ interactiveMessage.header = {
634
+ title: message.title,
635
+ subtitle: message.subtitle,
636
+ hasMediaAttachment: (_j = message === null || message === void 0 ? void 0 : message.media) !== null && _j !== void 0 ? _j : false,
637
+ };
638
+ Object.assign(interactiveMessage.header, m);
639
+ }
640
+ if ('footer' in message && !!message.footer) {
641
+ interactiveMessage.footer = {
642
+ text: message.footer
643
+ };
644
+ }
645
+ if ('title' in message && !!message.title) {
646
+ interactiveMessage.header = {
647
+ title: message.title,
648
+ subtitle: message.subtitle,
649
+ hasMediaAttachment: (_k = message === null || message === void 0 ? void 0 : message.media) !== null && _k !== void 0 ? _k : false,
650
+ };
651
+ Object.assign(interactiveMessage.header, m);
652
+ }
653
+ if ('contextInfo' in message && !!message.contextInfo) {
654
+ interactiveMessage.contextInfo = message.contextInfo;
655
+ }
656
+ if ('mentions' in message && !!message.mentions) {
657
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
658
+ }
659
+ m = { interactiveMessage };
660
+ }
661
+ if ('shop' in message && !!message.shop) {
662
+ const interactiveMessage = {
663
+ shopStorefrontMessage: Types_1.WAProto.Message.InteractiveMessage.ShopMessage.fromObject({
664
+ surface: message.shop,
665
+ id: message.id
666
+ })
667
+ };
668
+ if ('text' in message) {
669
+ interactiveMessage.body = {
670
+ text: message.text
671
+ };
672
+ }
673
+ else if ('caption' in message) {
674
+ interactiveMessage.body = {
675
+ text: message.caption
676
+ };
677
+ interactiveMessage.header = {
678
+ title: message.title,
679
+ subtitle: message.subtitle,
680
+ hasMediaAttachment: (_l = message === null || message === void 0 ? void 0 : message.media) !== null && _l !== void 0 ? _l : false,
681
+ };
682
+ Object.assign(interactiveMessage.header, m);
683
+ }
684
+ if ('footer' in message && !!message.footer) {
685
+ interactiveMessage.footer = {
686
+ text: message.footer
687
+ };
688
+ }
689
+ if ('title' in message && !!message.title) {
690
+ interactiveMessage.header = {
691
+ title: message.title,
692
+ subtitle: message.subtitle,
693
+ hasMediaAttachment: (_m = message === null || message === void 0 ? void 0 : message.media) !== null && _m !== void 0 ? _m : false,
694
+ };
695
+ Object.assign(interactiveMessage.header, m);
696
+ }
697
+ if ('contextInfo' in message && !!message.contextInfo) {
698
+ interactiveMessage.contextInfo = message.contextInfo;
699
+ }
700
+ if ('mentions' in message && !!message.mentions) {
701
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
702
+ }
703
+ m = { interactiveMessage };
704
+ }
473
705
  if ('viewOnce' in message && !!message.viewOnce) {
474
706
  m = { viewOnceMessage: { message: m } };
475
707
  }
476
- if ('mentions' in message && ((_a = message.mentions) === null || _a === void 0 ? void 0 : _a.length)) {
708
+ if ('mentions' in message && ((_o = message.mentions) === null || _o === void 0 ? void 0 : _o.length)) {
477
709
  const [messageType] = Object.keys(m);
478
710
  m[messageType].contextInfo = m[messageType] || {};
479
711
  m[messageType].contextInfo.mentionedJid = message.mentions;
@@ -506,26 +738,29 @@ const generateWAMessageFromContent = (jid, message, options) => {
506
738
  const key = (0, exports.getContentType)(innerMessage);
507
739
  const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp);
508
740
  const { quoted, userJid } = options;
509
- if (quoted && !(0, WABinary_1.isJidNewsLetter)(jid)) {
741
+ // only set quoted if isn't a newsletter message
742
+ if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
510
743
  const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid);
511
744
  let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message);
512
745
  const msgType = (0, exports.getContentType)(quotedMsg);
513
746
  // strip any redundant properties
514
- quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
515
- const quotedContent = quotedMsg[msgType];
516
- if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
517
- delete quotedContent.contextInfo;
518
- }
519
- const contextInfo = innerMessage[key].contextInfo || {};
520
- contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
521
- contextInfo.stanzaId = quoted.key.id;
522
- contextInfo.quotedMessage = quotedMsg;
523
- // if a participant is quoted, then it must be a group
524
- // hence, remoteJid of group must also be entered
525
- if (jid !== quoted.key.remoteJid) {
526
- contextInfo.remoteJid = quoted.key.remoteJid;
527
- }
528
- innerMessage[key].contextInfo = contextInfo;
747
+ if (quotedMsg) {
748
+ quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
749
+ const quotedContent = quotedMsg[msgType];
750
+ if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
751
+ delete quotedContent.contextInfo;
752
+ }
753
+ const contextInfo = innerMessage[key].contextInfo || {};
754
+ contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
755
+ contextInfo.stanzaId = quoted.key.id;
756
+ contextInfo.quotedMessage = quotedMsg;
757
+ // if a participant is quoted, then it must be a group
758
+ // hence, remoteJid of group must also be entered
759
+ if (jid !== quoted.key.remoteJid) {
760
+ contextInfo.remoteJid = quoted.key.remoteJid;
761
+ }
762
+ innerMessage[key].contextInfo = contextInfo;
763
+ }
529
764
  }
530
765
  if (
531
766
  // if we want to send a disappearing message
@@ -535,7 +770,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
535
770
  // already not converted to disappearing message
536
771
  key !== 'ephemeralMessage' &&
537
772
  // newsletter not accept disappearing messages
538
- !(0, WABinary_1.isJidNewsLetter)(jid)) {
773
+ !(0, WABinary_1.isJidNewsletter)(jid)) {
539
774
  innerMessage[key].contextInfo = {
540
775
  ...(innerMessage[key].contextInfo || {}),
541
776
  expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL,
@@ -547,7 +782,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
547
782
  key: {
548
783
  remoteJid: jid,
549
784
  fromMe: true,
550
- id: (options === null || options === void 0 ? void 0 : options.messageId) || (0, generics_1.generateMessageID)(),
785
+ id: (options === null || options === void 0 ? void 0 : options.messageId) || (0, generics_1.generateMessageIDV2)(),
551
786
  },
552
787
  message: message,
553
788
  messageTimestamp: timestamp,
@@ -562,7 +797,7 @@ const generateWAMessage = async (jid, content, options) => {
562
797
  var _a;
563
798
  // ensure msg ID is with every log
564
799
  options.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) === null || _a === void 0 ? void 0 : _a.child({ msgId: options.messageId });
565
- return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsLetter)(jid), ...options }), options);
800
+ return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsletter)(jid), ...options }), options);
566
801
  };
567
802
  exports.generateWAMessage = generateWAMessage;
568
803
  /** Get the key to access the true type of content */
@@ -599,7 +834,24 @@ const normalizeMessageContent = (content) => {
599
834
  || (message === null || message === void 0 ? void 0 : message.documentWithCaptionMessage)
600
835
  || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2)
601
836
  || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension)
602
- || (message === null || message === void 0 ? void 0 : message.editedMessage));
837
+ || (message === null || message === void 0 ? void 0 : message.editedMessage)
838
+ || (message === null || message === void 0 ? void 0 : message.groupMentionedMessage)
839
+ || (message === null || message === void 0 ? void 0 : message.botInvokeMessage)
840
+ || (message === null || message === void 0 ? void 0 : message.lottieStickerMessage)
841
+ || (message === null || message === void 0 ? void 0 : message.eventCoverImage)
842
+ || (message === null || message === void 0 ? void 0 : message.statusMentionMessage)
843
+ || (message === null || message === void 0 ? void 0 : message.pollCreationOptionImageMessage)
844
+ || (message === null || message === void 0 ? void 0 : message.associatedChildMessage)
845
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMentionMessage)
846
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV4)
847
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV5)
848
+ || (message === null || message === void 0 ? void 0 : message.statusAddYours)
849
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMessage)
850
+ || (message === null || message === void 0 ? void 0 : message.limitSharingMessage)
851
+ || (message === null || message === void 0 ? void 0 : message.botTaskMessage)
852
+ || (message === null || message === void 0 ? void 0 : message.questionMessage)
853
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMessageV2)
854
+ || (message === null || message === void 0 ? void 0 : message.botForwardedMessage));
603
855
  }
604
856
  };
605
857
  exports.normalizeMessageContent = normalizeMessageContent;
@@ -649,7 +901,11 @@ exports.extractMessageContent = extractMessageContent;
649
901
  /**
650
902
  * Returns the device predicted by message ID
651
903
  */
652
- const getDevice = (id) => /^3A.{18}$/.test(id) ? 'ios' : /^3E.{20}$/.test(id) ? 'web' : /^(.{21}|.{32})$/.test(id) ? 'android' : /^.{18}$/.test(id) ? 'desktop' : 'unknown';
904
+ const getDevice = (id) => /^3A.{18}$/.test(id) ? 'ios' :
905
+ /^3E.{20}$/.test(id) ? 'web' :
906
+ /^(.{21}|.{32})$/.test(id) ? 'android' :
907
+ /^(3F|.{18}$)/.test(id) ? 'desktop' :
908
+ 'unknown';
653
909
  exports.getDevice = getDevice;
654
910
  /** Upserts a receipt in the message */
655
911
  const updateMessageWithReceipt = (msg, receipt) => {
@@ -668,9 +924,8 @@ const updateMessageWithReaction = (msg, reaction) => {
668
924
  const authorID = (0, generics_1.getKeyAuthor)(reaction.key);
669
925
  const reactions = (msg.reactions || [])
670
926
  .filter(r => (0, generics_1.getKeyAuthor)(r.key) !== authorID);
671
- if (reaction.text) {
672
- reactions.push(reaction);
673
- }
927
+ reaction.text = reaction.text || '';
928
+ reactions.push(reaction);
674
929
  msg.reactions = reactions;
675
930
  };
676
931
  exports.updateMessageWithReaction = updateMessageWithReaction;
@@ -723,7 +978,6 @@ function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
723
978
  }
724
979
  return Object.values(voteHashMap);
725
980
  }
726
- exports.getAggregateVotesInPollMessage = getAggregateVotesInPollMessage;
727
981
  /** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
728
982
  const aggregateMessageKeysNotFromMe = (keys) => {
729
983
  const keyMap = {};
@@ -814,3 +1068,22 @@ const assertMediaContent = (content) => {
814
1068
  return mediaContent;
815
1069
  };
816
1070
  exports.assertMediaContent = assertMediaContent;
1071
+
1072
+ const toJid = (id) => {
1073
+ if (!id)
1074
+ return '';
1075
+ if (id.endsWith('@lid'))
1076
+ return id.replace('@lid', '@s.whatsapp.net');
1077
+ if (id.includes('@'))
1078
+ return id;
1079
+ return `${id}@s.whatsapp.net`;
1080
+ };
1081
+ exports.toJid = toJid;
1082
+ const getSenderLid = (message) => {
1083
+ const sender = message.key.participant || message.key.remoteJid;
1084
+ const user = (0, WABinary_1.jidDecode)(sender)?.user || '';
1085
+ const lid = (0, WABinary_1.jidEncode)(user, 'lid');
1086
+ console.log('sender lid:', lid);
1087
+ return { jid: sender, lid };
1088
+ };
1089
+ exports.getSenderLid = getSenderLid;
@@ -1,21 +1,19 @@
1
- /// <reference types="node" />
2
- import { Logger } from 'pino';
1
+ import { ILogger } from './logger';
3
2
  import { proto } from '../../WAProto';
4
3
  import { KeyPair } from '../Types';
5
4
  import { BinaryNode } from '../WABinary';
6
- export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, mobile, logger, routingInfo }: {
5
+ export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }: {
7
6
  keyPair: KeyPair;
8
7
  NOISE_HEADER: Uint8Array;
9
- mobile: boolean;
10
- logger: Logger;
8
+ logger: ILogger;
11
9
  routingInfo?: Buffer | undefined;
12
10
  }) => {
13
- encrypt: (plaintext: Uint8Array) => Buffer;
14
- decrypt: (ciphertext: Uint8Array) => Buffer;
11
+ encrypt: (plaintext: Uint8Array) => Buffer<ArrayBuffer>;
12
+ decrypt: (ciphertext: Uint8Array) => Buffer<ArrayBuffer>;
15
13
  authenticate: (data: Uint8Array) => void;
16
- mixIntoKey: (data: Uint8Array) => void;
17
- finishInit: () => void;
18
- processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => Buffer;
19
- encodeFrame: (data: Buffer | Uint8Array) => Buffer;
20
- decodeFrame: (newData: Buffer | Uint8Array, onFrame: (buff: Uint8Array | BinaryNode) => void) => void;
14
+ mixIntoKey: (data: Uint8Array) => Promise<void>;
15
+ finishInit: () => Promise<void>;
16
+ processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => Promise<Buffer<ArrayBuffer>>;
17
+ encodeFrame: (data: Buffer | Uint8Array) => Buffer<ArrayBuffer>;
18
+ decodeFrame: (newData: Buffer | Uint8Array, onFrame: (buff: Uint8Array | BinaryNode) => void) => Promise<void>;
21
19
  };