@ubedsockets/baileys 1.6.6 → 1.6.7

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 (87) hide show
  1. package/WAProto/GenerateStatics.sh +4 -3
  2. package/WAProto/WAProto.proto +511 -1215
  3. package/WAProto/index.js +131318 -59331
  4. package/lib/Defaults/index.js +92 -76
  5. package/lib/Signal/Group/ciphertext-message.js +5 -2
  6. package/lib/Signal/Group/group-session-builder.js +41 -7
  7. package/lib/Signal/Group/group_cipher.js +51 -37
  8. package/lib/Signal/Group/index.js +57 -12
  9. package/lib/Signal/Group/keyhelper.js +44 -7
  10. package/lib/Signal/Group/sender-chain-key.js +15 -7
  11. package/lib/Signal/Group/sender-key-distribution-message.js +11 -8
  12. package/lib/Signal/Group/sender-key-message.js +12 -9
  13. package/lib/Signal/Group/sender-key-name.js +5 -2
  14. package/lib/Signal/Group/sender-key-record.js +21 -9
  15. package/lib/Signal/Group/sender-key-state.js +42 -27
  16. package/lib/Signal/Group/sender-message-key.js +7 -4
  17. package/lib/Signal/libsignal.js +90 -347
  18. package/lib/Socket/Client/index.js +18 -3
  19. package/lib/Socket/Client/types.js +6 -4
  20. package/lib/Socket/Client/websocket.js +78 -21
  21. package/lib/Socket/business.js +43 -162
  22. package/lib/Socket/chats.js +249 -571
  23. package/lib/Socket/groups.js +99 -114
  24. package/lib/Socket/index.js +9 -11
  25. package/lib/Socket/messages-recv.js +559 -1277
  26. package/lib/Socket/messages-send.js +669 -674
  27. package/lib/Socket/newsletter.js +286 -149
  28. package/lib/Socket/socket.js +235 -548
  29. package/lib/Types/Auth.js +2 -2
  30. package/lib/Types/Call.js +2 -2
  31. package/lib/Types/Chat.js +4 -8
  32. package/lib/Types/Contact.js +2 -2
  33. package/lib/Types/Events.js +2 -2
  34. package/lib/Types/GroupMetadata.js +2 -2
  35. package/lib/Types/Label.js +5 -3
  36. package/lib/Types/LabelAssociation.js +5 -3
  37. package/lib/Types/Message.js +7 -11
  38. package/lib/Types/Product.js +2 -2
  39. package/lib/Types/Signal.js +2 -2
  40. package/lib/Types/Socket.js +2 -3
  41. package/lib/Types/State.js +2 -56
  42. package/lib/Types/USync.js +2 -2
  43. package/lib/Types/index.js +31 -15
  44. package/lib/Utils/auth-utils.js +136 -239
  45. package/lib/Utils/business.js +69 -66
  46. package/lib/Utils/chat-utils.js +238 -380
  47. package/lib/Utils/crypto.js +127 -56
  48. package/lib/Utils/decode-wa-message.js +63 -173
  49. package/lib/Utils/event-buffer.js +70 -174
  50. package/lib/Utils/generics.js +207 -159
  51. package/lib/Utils/history.js +53 -93
  52. package/lib/Utils/index.js +33 -22
  53. package/lib/Utils/link-preview.js +58 -17
  54. package/lib/Utils/logger.js +7 -3
  55. package/lib/Utils/lt-hash.js +46 -3
  56. package/lib/Utils/make-mutex.js +34 -24
  57. package/lib/Utils/messages-media.js +744 -483
  58. package/lib/Utils/messages.js +621 -411
  59. package/lib/Utils/noise-handler.js +99 -149
  60. package/lib/Utils/process-message.js +150 -459
  61. package/lib/Utils/signal.js +73 -112
  62. package/lib/Utils/use-multi-file-auth-state.js +27 -23
  63. package/lib/Utils/validate-connection.js +104 -74
  64. package/lib/WABinary/constants.js +11 -9
  65. package/lib/WABinary/decode.js +52 -49
  66. package/lib/WABinary/encode.js +49 -19
  67. package/lib/WABinary/generic-utils.js +43 -46
  68. package/lib/WABinary/index.js +21 -6
  69. package/lib/WABinary/jid-utils.js +45 -72
  70. package/lib/WABinary/types.js +2 -2
  71. package/lib/WAM/BinaryInfo.js +5 -2
  72. package/lib/WAM/constants.js +11958 -19461
  73. package/lib/WAM/encode.js +22 -17
  74. package/lib/WAM/index.js +19 -4
  75. package/lib/WAUSync/Protocols/USyncContactProtocol.js +13 -33
  76. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +14 -11
  77. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +11 -8
  78. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +13 -9
  79. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +22 -20
  80. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +8 -13
  81. package/lib/WAUSync/Protocols/index.js +20 -6
  82. package/lib/WAUSync/USyncQuery.js +35 -44
  83. package/lib/WAUSync/USyncUser.js +5 -10
  84. package/lib/WAUSync/index.js +19 -4
  85. package/lib/index.js +70 -11
  86. package/package.json +60 -100
  87. package/engine-requirements.js +0 -10
@@ -1,49 +1,75 @@
1
- import { Boom } from '@hapi/boom';
2
- import { randomBytes } from 'crypto';
3
- import { promises as fs } from 'fs';
4
- import {} from 'stream';
5
- import { proto } from '../../WAProto/index.js';
6
- import { CALL_AUDIO_PREFIX, CALL_VIDEO_PREFIX, MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
7
- import { WAMessageStatus, WAProto } from '../Types/index.js';
8
- import { isJidGroup, isJidNewsletter, isJidStatusBroadcast, jidNormalizedUser } from '../WABinary/index.js';
9
- import { sha256 } from './crypto.js';
10
- import { generateMessageIDV2, getKeyAuthor, unixTimestampSeconds } from './generics.js';
11
- import { downloadContentFromMessage, encryptedStream, generateThumbnail, getAudioDuration, getAudioWaveform, getRawMediaUploadData } from './messages-media.js';
12
- import { shouldIncludeReportingToken } from './reporting-utils.js';
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.assertMediaContent =
7
+ exports.downloadMediaMessage =
8
+ exports.aggregateMessageKeysNotFromMe =
9
+ exports.updateMessageWithPollUpdate =
10
+ exports.updateMessageWithReaction =
11
+ exports.updateMessageWithReceipt =
12
+ exports.getDevice =
13
+ exports.extractMessageContent =
14
+ exports.normalizeMessageContent =
15
+ exports.getContentType =
16
+ exports.generateWAMessage =
17
+ exports.generateWAMessageFromContent =
18
+ exports.generateWAMessageContent =
19
+ exports.generateForwardMessageContent =
20
+ exports.prepareDisappearingMessageSettingContent =
21
+ exports.prepareWAMessageMedia =
22
+ exports.generateLinkPreviewIfRequired =
23
+ exports.extractUrlFromText = void 0;
24
+ exports.getAggregateVotesInPollMessage = getAggregateVotesInPollMessage;
25
+
26
+ const boom_1 = require("@hapi/boom");
27
+ const axios_1 = __importDefault(require("axios"));
28
+ const crypto_1 = require("crypto");
29
+ const fs_1 = require("fs");
30
+ const WAProto_1 = require("../../WAProto");
31
+ const Defaults_1 = require("../Defaults");
32
+ const Types_1 = require("../Types");
33
+ const WABinary_1 = require("../WABinary");
34
+ const crypto_2 = require("./crypto");
35
+ const generics_1 = require("./generics");
36
+ const messages_media_1 = require("./messages-media");
13
37
  const MIMETYPE_MAP = {
14
38
  image: 'image/jpeg',
15
39
  video: 'video/mp4',
16
40
  document: 'application/pdf',
17
41
  audio: 'audio/ogg; codecs=opus',
18
42
  sticker: 'image/webp',
19
- 'product-catalog-image': 'image/jpeg'
43
+ 'product-catalog-image': 'image/jpeg',
20
44
  };
21
45
  const MessageTypeProto = {
22
- image: WAProto.Message.ImageMessage,
23
- video: WAProto.Message.VideoMessage,
24
- audio: WAProto.Message.AudioMessage,
25
- sticker: WAProto.Message.StickerMessage,
26
- document: WAProto.Message.DocumentMessage
46
+ 'image': Types_1.WAProto.Message.ImageMessage,
47
+ 'video': Types_1.WAProto.Message.VideoMessage,
48
+ 'audio': Types_1.WAProto.Message.AudioMessage,
49
+ 'sticker': Types_1.WAProto.Message.StickerMessage,
50
+ 'document': Types_1.WAProto.Message.DocumentMessage,
27
51
  };
52
+ const ButtonType = WAProto_1.proto.Message.ButtonsMessage.HeaderType;
28
53
  /**
29
54
  * Uses a regex to test whether the string contains a URL, and returns the URL if it does.
30
55
  * @param text eg. hello https://google.com
31
56
  * @returns the URL, eg. https://google.com
32
57
  */
33
- export const extractUrlFromText = (text) => text.match(URL_REGEX)?.[0];
34
- export const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
35
- const url = extractUrlFromText(text);
58
+ const extractUrlFromText = (text) => { var _a; return (_a = text.match(Defaults_1.URL_REGEX)) === null || _a === void 0 ? void 0 : _a[0]; };
59
+ exports.extractUrlFromText = extractUrlFromText;
60
+ const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
61
+ const url = (0, exports.extractUrlFromText)(text);
36
62
  if (!!getUrlInfo && url) {
37
63
  try {
38
64
  const urlInfo = await getUrlInfo(url);
39
65
  return urlInfo;
40
66
  }
41
- catch (error) {
42
- // ignore if fails
43
- logger?.warn({ trace: error.stack }, 'url generation failed');
67
+ catch (error) {
68
+ logger === null || logger === void 0 ? void 0 : logger.warn({ trace: error.stack }, 'url generation failed');
44
69
  }
45
70
  }
46
71
  };
72
+ exports.generateLinkPreviewIfRequired = generateLinkPreviewIfRequired;
47
73
  const assertColor = async (color) => {
48
74
  let assertedColor;
49
75
  if (typeof color === 'number') {
@@ -58,104 +84,92 @@ const assertColor = async (color) => {
58
84
  return assertedColor;
59
85
  }
60
86
  };
61
- export const prepareWAMessageMedia = async (message, options) => {
87
+ const prepareWAMessageMedia = async (message, options) => {
62
88
  const logger = options.logger;
63
89
  let mediaType;
64
- for (const key of MEDIA_KEYS) {
90
+ for (const key of Defaults_1.MEDIA_KEYS) {
65
91
  if (key in message) {
66
92
  mediaType = key;
67
93
  }
68
94
  }
69
95
  if (!mediaType) {
70
- throw new Boom('Invalid media type', { statusCode: 400 });
96
+ throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
71
97
  }
98
+
99
+
72
100
  const uploadData = {
73
101
  ...message,
74
102
  media: message[mediaType]
75
103
  };
104
+
76
105
  delete uploadData[mediaType];
77
- // check if cacheable + generate cache key
106
+
78
107
  const cacheableKey = typeof uploadData.media === 'object' &&
79
- 'url' in uploadData.media &&
108
+ ('url' in uploadData.media) &&
80
109
  !!uploadData.media.url &&
81
110
  !!options.mediaCache &&
82
111
  mediaType + ':' + uploadData.media.url.toString();
112
+
83
113
  if (mediaType === 'document' && !uploadData.fileName) {
84
114
  uploadData.fileName = 'file';
85
115
  }
116
+
86
117
  if (!uploadData.mimetype) {
87
118
  uploadData.mimetype = MIMETYPE_MAP[mediaType];
88
119
  }
120
+
89
121
  if (cacheableKey) {
90
- const mediaBuff = await options.mediaCache.get(cacheableKey);
122
+ const mediaBuff = options.mediaCache.get(cacheableKey);
91
123
  if (mediaBuff) {
92
124
  logger?.debug({ cacheableKey }, 'got media cache hit');
93
- const obj = proto.Message.decode(mediaBuff);
125
+ const obj = Types_1.WAProto.Message.decode(mediaBuff);
94
126
  const key = `${mediaType}Message`;
95
127
  Object.assign(obj[key], { ...uploadData, media: undefined });
96
128
  return obj;
97
129
  }
98
130
  }
99
- const isNewsletter = !!options.jid && isJidNewsletter(options.jid);
100
- if (isNewsletter) {
101
- logger?.info({ key: cacheableKey }, 'Preparing raw media for newsletter');
102
- const { filePath, fileSha256, fileLength } = await getRawMediaUploadData(uploadData.media, options.mediaTypeOverride || mediaType, logger);
103
- const fileSha256B64 = fileSha256.toString('base64');
104
- const { mediaUrl, directPath } = await options.upload(filePath, {
105
- fileEncSha256B64: fileSha256B64,
106
- mediaType: mediaType,
107
- timeoutMs: options.mediaUploadTimeoutMs
108
- });
109
- await fs.unlink(filePath);
110
- const obj = WAProto.Message.fromObject({
111
- // todo: add more support here
112
- [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
113
- url: mediaUrl,
114
- directPath,
115
- fileSha256,
116
- fileLength,
117
- ...uploadData,
118
- media: undefined
119
- })
120
- });
121
- if (uploadData.ptv) {
122
- obj.ptvMessage = obj.videoMessage;
123
- delete obj.videoMessage;
124
- }
125
- if (obj.stickerMessage) {
126
- obj.stickerMessage.stickerSentTs = Date.now();
127
- }
128
- if (cacheableKey) {
129
- logger?.debug({ cacheableKey }, 'set cache');
130
- await options.mediaCache.set(cacheableKey, WAProto.Message.encode(obj).finish());
131
- }
132
- return obj;
133
- }
131
+
134
132
  const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
135
- const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && typeof uploadData['jpegThumbnail'] === 'undefined';
136
- const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true && typeof uploadData.waveform === 'undefined';
137
- const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
133
+ const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
134
+ typeof uploadData['jpegThumbnail'] === 'undefined';
135
+
136
+ // MODIFIED BY VYZEN
137
+ const requiresWaveformProcessing = mediaType === 'audio' && (uploadData.ptt === true || !!options.backgroundColor);
138
+ // MODIFIED BY VYZEN
139
+ const requiresAudioBackground = options.backgroundColor && mediaType === 'audio';
140
+
138
141
  const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
139
- const { mediaKey, encFilePath, originalFilePath, fileEncSha256, fileSha256, fileLength } = await encryptedStream(uploadData.media, options.mediaTypeOverride || mediaType, {
140
- logger,
141
- saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
142
- opts: options.options
143
- });
144
- const fileEncSha256B64 = fileEncSha256.toString('base64');
145
- const [{ mediaUrl, directPath }] = await Promise.all([
142
+
143
+ const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, opusConverted } =
144
+ await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(
145
+ uploadData.media,
146
+ options.mediaTypeOverride || mediaType,
147
+ {
148
+ logger,
149
+ saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
150
+ opts: options.options,
151
+ isPtt: uploadData.ptt,
152
+ forceOpus: (mediaType === 'audio' && uploadData.mimetype && uploadData.mimetype.includes('opus')),
153
+ convertVideo: (mediaType === 'video')
154
+ }
155
+ );
156
+
157
+ if (mediaType === 'audio' && opusConverted) {
158
+ uploadData.mimetype = 'audio/ogg; codecs=opus';
159
+ }
160
+
161
+ const fileEncSha256B64 = (options.newsletter ? fileSha256 : fileEncSha256 ?? fileSha256).toString('base64');
162
+
163
+ const [{ mediaUrl, directPath, handle }] = await Promise.all([
146
164
  (async () => {
147
- const result = await options.upload(encFilePath, {
148
- fileEncSha256B64,
149
- mediaType,
150
- timeoutMs: options.mediaUploadTimeoutMs
151
- });
165
+ const result = await options.upload(encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs });
152
166
  logger?.debug({ mediaType, cacheableKey }, 'uploaded media');
153
167
  return result;
154
168
  })(),
155
169
  (async () => {
156
170
  try {
157
171
  if (requiresThumbnailComputation) {
158
- const { thumbnail, originalImageDimensions } = await generateThumbnail(originalFilePath, mediaType, options);
172
+ const { thumbnail, originalImageDimensions } = await messages_media_1.generateThumbnail(bodyPath, mediaType, options);
159
173
  uploadData.jpegThumbnail = thumbnail;
160
174
  if (!uploadData.width && originalImageDimensions) {
161
175
  uploadData.width = originalImageDimensions.width;
@@ -165,119 +179,131 @@ export const prepareWAMessageMedia = async (message, options) => {
165
179
  logger?.debug('generated thumbnail');
166
180
  }
167
181
  if (requiresDurationComputation) {
168
- uploadData.seconds = await getAudioDuration(originalFilePath);
182
+ uploadData.seconds = await messages_media_1.getAudioDuration(bodyPath);
169
183
  logger?.debug('computed audio duration');
170
184
  }
185
+
186
+ // MODIFIED BY VYZEN
171
187
  if (requiresWaveformProcessing) {
172
- uploadData.waveform = await getAudioWaveform(originalFilePath, logger);
188
+ try {
189
+ uploadData.waveform = await messages_media_1.getAudioWaveform(bodyPath, logger);
190
+ } catch (err) {
191
+ logger?.warn('Failed to generate waveform, using fallback');
192
+ }
193
+
194
+ if (!uploadData.waveform) {
195
+ uploadData.waveform = new Uint8Array([0,99,0,99,0,99,0,99,88,99,0,99,0,55,0,99,0,99,0,99,0,99,0,99,88,99,0,99,0,55,0,99]);
196
+ }
173
197
  logger?.debug('processed waveform');
174
198
  }
199
+
175
200
  if (requiresAudioBackground) {
176
201
  uploadData.backgroundArgb = await assertColor(options.backgroundColor);
177
202
  logger?.debug('computed backgroundColor audio status');
178
203
  }
179
- }
180
- catch (error) {
204
+ } catch (error) {
181
205
  logger?.warn({ trace: error.stack }, 'failed to obtain extra info');
182
206
  }
183
- })()
184
- ]).finally(async () => {
185
- try {
186
- await fs.unlink(encFilePath);
187
- if (originalFilePath) {
188
- await fs.unlink(originalFilePath);
207
+ })(),
208
+ ])
209
+ .finally(async () => {
210
+ if (!Buffer.isBuffer(encWriteStream)) {
211
+ encWriteStream.destroy();
189
212
  }
190
- logger?.debug('removed tmp files');
191
- }
192
- catch (error) {
193
- logger?.warn('failed to remove tmp file');
194
- }
195
- });
196
- const obj = WAProto.Message.fromObject({
213
+ if (didSaveToTmpPath && bodyPath) {
214
+ try {
215
+ await fs_1.promises.access(bodyPath);
216
+ await fs_1.promises.unlink(bodyPath);
217
+ logger?.debug('removed tmp file');
218
+ } catch (error) {
219
+ logger?.warn('failed to remove tmp file');
220
+ }
221
+ }
222
+ });
223
+
224
+ const obj = Types_1.WAProto.Message.fromObject({
197
225
  [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
198
- url: mediaUrl,
226
+ url: handle ? undefined : mediaUrl,
199
227
  directPath,
200
- mediaKey,
201
- fileEncSha256,
228
+ mediaKey: mediaKey,
229
+ fileEncSha256: fileEncSha256,
202
230
  fileSha256,
203
231
  fileLength,
204
- mediaKeyTimestamp: unixTimestampSeconds(),
232
+ mediaKeyTimestamp: handle ? undefined : generics_1.unixTimestampSeconds(),
205
233
  ...uploadData,
206
234
  media: undefined
207
235
  })
208
236
  });
237
+
209
238
  if (uploadData.ptv) {
210
239
  obj.ptvMessage = obj.videoMessage;
211
240
  delete obj.videoMessage;
212
241
  }
242
+
213
243
  if (cacheableKey) {
214
244
  logger?.debug({ cacheableKey }, 'set cache');
215
- await options.mediaCache.set(cacheableKey, WAProto.Message.encode(obj).finish());
245
+ options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
216
246
  }
247
+
217
248
  return obj;
218
249
  };
219
- export const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
250
+
251
+ exports.prepareWAMessageMedia = prepareWAMessageMedia;
252
+ const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
220
253
  ephemeralExpiration = ephemeralExpiration || 0;
221
254
  const content = {
222
255
  ephemeralMessage: {
223
256
  message: {
224
257
  protocolMessage: {
225
- type: WAProto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
258
+ type: Types_1.WAProto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
226
259
  ephemeralExpiration
227
260
  }
228
261
  }
229
262
  }
230
263
  };
231
- return WAProto.Message.fromObject(content);
264
+ return Types_1.WAProto.Message.fromObject(content);
232
265
  };
266
+ exports.prepareDisappearingMessageSettingContent = prepareDisappearingMessageSettingContent;
233
267
  /**
234
268
  * Generate forwarded message content like WA does
235
269
  * @param message the message to forward
236
270
  * @param options.forceForward will show the message as forwarded even if it is from you
237
271
  */
238
- export const generateForwardMessageContent = (message, forceForward) => {
272
+ const generateForwardMessageContent = (message, forceForward) => {
273
+ var _a;
239
274
  let content = message.message;
240
275
  if (!content) {
241
- throw new Boom('no content in message', { statusCode: 400 });
276
+ throw new boom_1.Boom('no content in message', { statusCode: 400 });
242
277
  }
243
- // hacky copy
244
- content = normalizeMessageContent(content);
245
- content = proto.Message.decode(proto.Message.encode(content).finish());
278
+
279
+ content = (0, exports.normalizeMessageContent)(content);
280
+ content = WAProto_1.proto.Message.decode(WAProto_1.proto.Message.encode(content).finish());
246
281
  let key = Object.keys(content)[0];
247
- let score = content?.[key]?.contextInfo?.forwardingScore || 0;
282
+ let score = ((_a = content[key].contextInfo) === null || _a === void 0 ? void 0 : _a.forwardingScore) || 0;
248
283
  score += message.key.fromMe && !forceForward ? 0 : 1;
249
284
  if (key === 'conversation') {
250
285
  content.extendedTextMessage = { text: content[key] };
251
286
  delete content.conversation;
252
287
  key = 'extendedTextMessage';
253
288
  }
254
- const key_ = content?.[key];
255
289
  if (score > 0) {
256
- key_.contextInfo = { forwardingScore: score, isForwarded: true };
290
+ content[key].contextInfo = { forwardingScore: score, isForwarded: true };
257
291
  }
258
292
  else {
259
- key_.contextInfo = {};
293
+ content[key].contextInfo = {};
260
294
  }
261
295
  return content;
262
296
  };
263
- export const hasNonNullishProperty = (message, key) => {
264
- return (typeof message === 'object' &&
265
- message !== null &&
266
- key in message &&
267
- message[key] !== null &&
268
- message[key] !== undefined);
269
- };
270
- function hasOptionalProperty(obj, key) {
271
- return typeof obj === 'object' && obj !== null && key in obj && obj[key] !== null;
272
- }
273
- export const generateWAMessageContent = async (message, options) => {
274
- var _a, _b;
297
+ exports.generateForwardMessageContent = generateForwardMessageContent;
298
+ const generateWAMessageContent = async (message, options) => {
299
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
300
+ var _p, _q;
275
301
  let m = {};
276
- if (hasNonNullishProperty(message, 'text')) {
302
+ if ('text' in message) {
277
303
  const extContent = { text: message.text };
278
304
  let urlInfo = message.linkPreview;
279
305
  if (typeof urlInfo === 'undefined') {
280
- urlInfo = await generateLinkPreviewIfRequired(message.text, options.getUrlInfo, options.logger);
306
+ urlInfo = await (0, exports.generateLinkPreviewIfRequired)(message.text, options.getUrlInfo, options.logger);
281
307
  }
282
308
  if (urlInfo) {
283
309
  extContent.matchedText = urlInfo['matched-text'];
@@ -304,65 +330,62 @@ export const generateWAMessageContent = async (message, options) => {
304
330
  }
305
331
  m.extendedTextMessage = extContent;
306
332
  }
307
- else if (hasNonNullishProperty(message, 'contacts')) {
333
+ else if ('contacts' in message) {
308
334
  const contactLen = message.contacts.contacts.length;
309
335
  if (!contactLen) {
310
- throw new Boom('require atleast 1 contact', { statusCode: 400 });
336
+ throw new boom_1.Boom('require atleast 1 contact', { statusCode: 400 });
311
337
  }
312
338
  if (contactLen === 1) {
313
- m.contactMessage = WAProto.Message.ContactMessage.create(message.contacts.contacts[0]);
339
+ m.contactMessage = Types_1.WAProto.Message.ContactMessage.fromObject(message.contacts.contacts[0]);
314
340
  }
315
341
  else {
316
- m.contactsArrayMessage = WAProto.Message.ContactsArrayMessage.create(message.contacts);
342
+ m.contactsArrayMessage = Types_1.WAProto.Message.ContactsArrayMessage.fromObject(message.contacts);
317
343
  }
318
344
  }
319
- else if (hasNonNullishProperty(message, 'location')) {
320
- m.locationMessage = WAProto.Message.LocationMessage.create(message.location);
345
+ else if ('location' in message) {
346
+ m.locationMessage = Types_1.WAProto.Message.LocationMessage.fromObject(message.location);
321
347
  }
322
- else if (hasNonNullishProperty(message, 'react')) {
348
+ else if ('react' in message) {
323
349
  if (!message.react.senderTimestampMs) {
324
350
  message.react.senderTimestampMs = Date.now();
325
351
  }
326
- m.reactionMessage = WAProto.Message.ReactionMessage.create(message.react);
352
+ m.reactionMessage = Types_1.WAProto.Message.ReactionMessage.fromObject(message.react);
327
353
  }
328
- else if (hasNonNullishProperty(message, 'delete')) {
354
+ else if ('delete' in message) {
329
355
  m.protocolMessage = {
330
356
  key: message.delete,
331
- type: WAProto.Message.ProtocolMessage.Type.REVOKE
357
+ type: Types_1.WAProto.Message.ProtocolMessage.Type.REVOKE
332
358
  };
333
359
  }
334
- else if (hasNonNullishProperty(message, 'forward')) {
335
- m = generateForwardMessageContent(message.forward, message.force);
360
+ else if ('forward' in message) {
361
+ m = (0, exports.generateForwardMessageContent)(message.forward, message.force);
336
362
  }
337
- else if (hasNonNullishProperty(message, 'disappearingMessagesInChat')) {
338
- const exp = typeof message.disappearingMessagesInChat === 'boolean'
339
- ? message.disappearingMessagesInChat
340
- ? WA_DEFAULT_EPHEMERAL
341
- : 0
342
- : message.disappearingMessagesInChat;
343
- m = prepareDisappearingMessageSettingContent(exp);
363
+ else if ('disappearingMessagesInChat' in message) {
364
+ const exp = typeof message.disappearingMessagesInChat === 'boolean' ?
365
+ (message.disappearingMessagesInChat ? Defaults_1.WA_DEFAULT_EPHEMERAL : 0) :
366
+ message.disappearingMessagesInChat;
367
+ m = (0, exports.prepareDisappearingMessageSettingContent)(exp);
344
368
  }
345
- else if (hasNonNullishProperty(message, 'groupInvite')) {
369
+ else if ('groupInvite' in message) {
346
370
  m.groupInviteMessage = {};
347
371
  m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
348
372
  m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
349
373
  m.groupInviteMessage.caption = message.groupInvite.text;
350
374
  m.groupInviteMessage.groupJid = message.groupInvite.jid;
351
375
  m.groupInviteMessage.groupName = message.groupInvite.subject;
352
- //TODO: use built-in interface and get disappearing mode info etc.
353
- //TODO: cache / use store!?
376
+
377
+
354
378
  if (options.getProfilePicUrl) {
355
379
  const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
356
380
  if (pfpUrl) {
357
- const resp = await fetch(pfpUrl, { method: 'GET', dispatcher: options?.options?.dispatcher });
358
- if (resp.ok) {
359
- const buf = Buffer.from(await resp.arrayBuffer());
360
- m.groupInviteMessage.jpegThumbnail = buf;
381
+ const resp = await axios_1.default.get(pfpUrl, { responseType: 'arraybuffer' });
382
+ if (resp.status === 200) {
383
+ m.groupInviteMessage.jpegThumbnail = resp.data;
361
384
  }
362
385
  }
363
386
  }
364
387
  }
365
- else if (hasNonNullishProperty(message, 'pin')) {
388
+ else if ('pin' in message) {
366
389
  m.pinInChatMessage = {};
367
390
  m.messageContextInfo = {};
368
391
  m.pinInChatMessage.key = message.pin;
@@ -370,276 +393,447 @@ export const generateWAMessageContent = async (message, options) => {
370
393
  m.pinInChatMessage.senderTimestampMs = Date.now();
371
394
  m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0;
372
395
  }
373
- else if (hasNonNullishProperty(message, 'buttonReply')) {
396
+ else if ('keep' in message) {
397
+ m.keepInChatMessage = {};
398
+ m.keepInChatMessage.key = message.keep;
399
+ m.keepInChatMessage.keepType = message.type;
400
+ m.keepInChatMessage.timestampMs = Date.now();
401
+ }
402
+ else if ('call' in message) {
403
+ m = {
404
+ scheduledCallCreationMessage: {
405
+ scheduledTimestampMs: (_a = message.call.time) !== null && _a !== void 0 ? _a : Date.now(),
406
+ callType: (_b = message.call.type) !== null && _b !== void 0 ? _b : 1,
407
+ title: message.call.title
408
+ }
409
+ };
410
+ }
411
+ else if ('paymentInvite' in message) {
412
+ m.paymentInviteMessage = {
413
+ serviceType: message.paymentInvite.type,
414
+ expiryTimestamp: message.paymentInvite.expiry
415
+ };
416
+ }
417
+ else if ('buttonReply' in message) {
374
418
  switch (message.type) {
375
419
  case 'template':
376
420
  m.templateButtonReplyMessage = {
377
421
  selectedDisplayText: message.buttonReply.displayText,
378
422
  selectedId: message.buttonReply.id,
379
- selectedIndex: message.buttonReply.index
423
+ selectedIndex: message.buttonReply.index,
380
424
  };
381
425
  break;
382
426
  case 'plain':
383
427
  m.buttonsResponseMessage = {
384
428
  selectedButtonId: message.buttonReply.id,
385
429
  selectedDisplayText: message.buttonReply.displayText,
386
- type: proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT
430
+ type: WAProto_1.proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT,
387
431
  };
388
432
  break;
389
433
  }
390
434
  }
391
- else if (hasOptionalProperty(message, 'ptv') && message.ptv) {
392
- const { videoMessage } = await prepareWAMessageMedia({ video: message.video }, options);
435
+ else if ('ptv' in message && message.ptv) {
436
+ const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
393
437
  m.ptvMessage = videoMessage;
394
438
  }
395
- else if (hasNonNullishProperty(message, 'product')) {
396
- const { imageMessage } = await prepareWAMessageMedia({ image: message.product.productImage }, options);
397
- m.productMessage = WAProto.Message.ProductMessage.create({
439
+ else if ('product' in message) {
440
+ const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
441
+ m.productMessage = Types_1.WAProto.Message.ProductMessage.fromObject({
398
442
  ...message,
399
443
  product: {
400
444
  ...message.product,
401
- productImage: imageMessage
445
+ productImage: imageMessage,
402
446
  }
403
447
  });
404
448
  }
405
- else if (hasNonNullishProperty(message, 'listReply')) {
449
+ else if ('order' in message) {
450
+ m.orderMessage = Types_1.WAProto.Message.OrderMessage.fromObject({
451
+ orderId: message.order.id,
452
+ thumbnail: message.order.thumbnail,
453
+ itemCount: message.order.itemCount,
454
+ status: message.order.status,
455
+ surface: message.order.surface,
456
+ orderTitle: message.order.title,
457
+ message: message.order.text,
458
+ sellerJid: message.order.seller,
459
+ token: message.order.token,
460
+ totalAmount1000: message.order.amount,
461
+ totalCurrencyCode: message.order.currency
462
+ });
463
+ }
464
+ else if ('listReply' in message) {
406
465
  m.listResponseMessage = { ...message.listReply };
407
466
  }
408
- else if (hasNonNullishProperty(message, 'event')) {
409
- m.eventMessage = {};
410
- const startTime = Math.floor(message.event.startDate.getTime() / 1000);
411
- if (message.event.call && options.getCallLink) {
412
- const token = await options.getCallLink(message.event.call, { startTime });
413
- m.eventMessage.joinLink = (message.event.call === 'audio' ? CALL_AUDIO_PREFIX : CALL_VIDEO_PREFIX) + token;
414
- }
415
- m.messageContextInfo = {
416
- // encKey
417
- messageSecret: message.event.messageSecret || randomBytes(32)
418
- };
419
- m.eventMessage.name = message.event.name;
420
- m.eventMessage.description = message.event.description;
421
- m.eventMessage.startTime = startTime;
422
- m.eventMessage.endTime = message.event.endDate ? message.event.endDate.getTime() / 1000 : undefined;
423
- m.eventMessage.isCanceled = message.event.isCancelled ?? false;
424
- m.eventMessage.extraGuestsAllowed = message.event.extraGuestsAllowed;
425
- m.eventMessage.isScheduleCall = message.event.isScheduleCall ?? false;
426
- m.eventMessage.location = message.event.location;
427
- }
428
- else if (hasNonNullishProperty(message, 'poll')) {
429
- (_a = message.poll).selectableCount || (_a.selectableCount = 0);
430
- (_b = message.poll).toAnnouncementGroup || (_b.toAnnouncementGroup = false);
467
+ else if ('poll' in message) {
468
+ (_p = message.poll).selectableCount || (_p.selectableCount = 0);
469
+ (_q = message.poll).toAnnouncementGroup || (_q.toAnnouncementGroup = false);
431
470
  if (!Array.isArray(message.poll.values)) {
432
- throw new Boom('Invalid poll values', { statusCode: 400 });
471
+ throw new boom_1.Boom('Invalid poll values', { statusCode: 400 });
433
472
  }
434
- if (message.poll.selectableCount < 0 || message.poll.selectableCount > message.poll.values.length) {
435
- throw new Boom(`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`, {
436
- statusCode: 400
437
- });
473
+ if (message.poll.selectableCount < 0
474
+ || message.poll.selectableCount > message.poll.values.length) {
475
+ throw new boom_1.Boom(`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`, { statusCode: 400 });
438
476
  }
439
477
  m.messageContextInfo = {
440
- // encKey
441
- messageSecret: message.poll.messageSecret || randomBytes(32)
478
+
479
+ messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32),
442
480
  };
443
481
  const pollCreationMessage = {
444
482
  name: message.poll.name,
445
483
  selectableOptionsCount: message.poll.selectableCount,
446
- options: message.poll.values.map(optionName => ({ optionName }))
484
+ options: message.poll.values.map(optionName => ({ optionName })),
447
485
  };
448
486
  if (message.poll.toAnnouncementGroup) {
449
- // poll v2 is for community announcement groups (single select and multiple)
487
+
450
488
  m.pollCreationMessageV2 = pollCreationMessage;
451
489
  }
452
490
  else {
453
491
  if (message.poll.selectableCount === 1) {
454
- //poll v3 is for single select polls
492
+
455
493
  m.pollCreationMessageV3 = pollCreationMessage;
456
494
  }
457
495
  else {
458
- // poll for multiple choice polls
496
+
459
497
  m.pollCreationMessage = pollCreationMessage;
460
498
  }
461
499
  }
462
500
  }
463
- else if (hasNonNullishProperty(message, 'album')) {
464
- m.albumMessage = {
465
- expectedImageCount: message.album.expectedImageCount,
466
- expectedVideoCount: message.album.expectedVideoCount
501
+ else if ('event' in message) {
502
+ m.messageContextInfo = {
503
+ messageSecret: message.event.messageSecret || (0, crypto_1.randomBytes)(32),
467
504
  };
505
+ m.eventMessage = { ...message.event };
468
506
  }
469
- else if (hasNonNullishProperty(message, 'sharePhoneNumber')) {
507
+ else if ('inviteAdmin' in message) {
508
+ m.newsletterAdminInviteMessage = {};
509
+ m.newsletterAdminInviteMessage.inviteExpiration = message.inviteAdmin.inviteExpiration;
510
+ m.newsletterAdminInviteMessage.caption = message.inviteAdmin.text;
511
+ m.newsletterAdminInviteMessage.newsletterJid = message.inviteAdmin.jid;
512
+ m.newsletterAdminInviteMessage.newsletterName = message.inviteAdmin.subject;
513
+ m.newsletterAdminInviteMessage.jpegThumbnail = message.inviteAdmin.thumbnail;
514
+ }
515
+ else if ('requestPayment' in message) {
516
+ const sticker = ((_c = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _c === void 0 ? void 0 : _c.sticker) ?
517
+ 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)
518
+ : null;
519
+ let notes = {};
520
+ if ((_e = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _e === void 0 ? void 0 : _e.sticker) {
521
+ notes = {
522
+ stickerMessage: {
523
+ ...sticker === null || sticker === void 0 ? void 0 : sticker.stickerMessage,
524
+ contextInfo: (_f = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _f === void 0 ? void 0 : _f.contextInfo
525
+ }
526
+ };
527
+ }
528
+ else if (message.requestPayment.note) {
529
+ notes = {
530
+ extendedTextMessage: {
531
+ text: message.requestPayment.note,
532
+ contextInfo: (_g = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _g === void 0 ? void 0 : _g.contextInfo,
533
+ }
534
+ };
535
+ }
536
+ else {
537
+ throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
538
+ }
539
+ m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
540
+ expiryTimestamp: message.requestPayment.expiry,
541
+ amount1000: message.requestPayment.amount,
542
+ currencyCodeIso4217: message.requestPayment.currency,
543
+ requestFrom: message.requestPayment.from,
544
+ noteMessage: { ...notes },
545
+ background: (_h = message.requestPayment.background) !== null && _h !== void 0 ? _h : null,
546
+ });
547
+ }
548
+ else if ('sharePhoneNumber' in message) {
470
549
  m.protocolMessage = {
471
- type: proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
550
+ type: WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
472
551
  };
473
552
  }
474
- else if (hasNonNullishProperty(message, 'requestPhoneNumber')) {
553
+ else if ('requestPhoneNumber' in message) {
475
554
  m.requestPhoneNumberMessage = {};
476
555
  }
477
- else if (hasNonNullishProperty(message, 'limitSharing')) {
478
- m.protocolMessage = {
479
- type: proto.Message.ProtocolMessage.Type.LIMIT_SHARING,
480
- limitSharing: {
481
- sharingLimited: message.limitSharing === true,
482
- trigger: 1,
483
- limitSharingSettingTimestamp: Date.now(),
484
- initiatedByMe: true
485
- }
486
- };
556
+ else if ('album' in message) {
557
+ const imageMessages = message.album.filter(item => 'image' in item);
558
+ const videoMessages = message.album.filter(item => 'video' in item);
559
+ m.albumMessage = WAProto_1.proto.Message.AlbumMessage.fromObject({
560
+ expectedImageCount: imageMessages.length,
561
+ expectedVideoCount: videoMessages.length,
562
+ });
487
563
  }
488
564
  else {
489
- m = await prepareWAMessageMedia(message, options);
565
+ m = await (0, exports.prepareWAMessageMedia)(message, options);
490
566
  }
491
- if (hasOptionalProperty(message, 'viewOnce') && !!message.viewOnce) {
492
- m = { viewOnceMessage: { message: m } };
567
+ if ('buttons' in message && !!message.buttons) {
568
+ const buttonsMessage = {
569
+ buttons: message.buttons.map(b => ({ ...b, type: WAProto_1.proto.Message.ButtonsMessage.Button.Type.RESPONSE }))
570
+ };
571
+ if ('text' in message) {
572
+ buttonsMessage.contentText = message.text;
573
+ buttonsMessage.headerType = ButtonType.EMPTY;
574
+ }
575
+ else {
576
+ if ('caption' in message) {
577
+ buttonsMessage.contentText = message.caption;
578
+ }
579
+ const type = Object.keys(m)[0].replace('Message', '').toUpperCase();
580
+ buttonsMessage.headerType = ButtonType[type];
581
+ Object.assign(buttonsMessage, m);
582
+ }
583
+ if ('title' in message && !!message.title) {
584
+ buttonsMessage.text = message.title,
585
+ buttonsMessage.headerType = ButtonType.TEXT;
586
+ }
587
+ if ('footer' in message && !!message.footer) {
588
+ buttonsMessage.footerText = message.footer;
589
+ }
590
+ if ('contextInfo' in message && !!message.contextInfo) {
591
+ buttonsMessage.contextInfo = message.contextInfo;
592
+ }
593
+ if ('mentions' in message && !!message.mentions) {
594
+ buttonsMessage.contextInfo = { mentionedJid: message.mentions };
595
+ }
596
+ m = { buttonsMessage };
493
597
  }
494
- if ((hasOptionalProperty(message, 'mentions') && message.mentions?.length) ||
495
- (hasOptionalProperty(message, 'mentionAll') && message.mentionAll)) {
496
- const messageType = Object.keys(m)[0];
497
- const key = m[messageType];
498
- if (key && 'contextInfo' in key) {
499
- key.contextInfo = key.contextInfo || {};
500
- if (message.mentions?.length) {
501
- key.contextInfo.mentionedJid = message.mentions;
598
+ else if ('templateButtons' in message && !!message.templateButtons) {
599
+ const msg = {
600
+ hydratedButtons: message.hasOwnProperty("templateButtons") ? message.templateButtons : message.templateButtons
601
+ };
602
+ if ('text' in message) {
603
+ msg.hydratedContentText = message.text;
604
+ }
605
+ else {
606
+ if ('caption' in message) {
607
+ msg.hydratedContentText = message.caption;
502
608
  }
503
- if (message.mentionAll) {
504
- key.contextInfo.nonJidMentions = 1;
609
+ Object.assign(msg, m);
610
+ }
611
+ if ('footer' in message && !!message.footer) {
612
+ msg.hydratedFooterText = message.footer;
613
+ }
614
+ m = {
615
+ templateMessage: {
616
+ fourRowTemplate: msg,
617
+ hydratedTemplate: msg
505
618
  }
619
+ };
620
+ }
621
+ if ('sections' in message && !!message.sections) {
622
+ const listMessage = {
623
+ sections: message.sections,
624
+ buttonText: message.buttonText,
625
+ title: message.title,
626
+ footerText: message.footer,
627
+ description: message.text,
628
+ listType: WAProto_1.proto.Message.ListMessage.ListType.SINGLE_SELECT
629
+ };
630
+ m = { listMessage };
631
+ }
632
+ if ('interactiveButtons' in message && !!message.interactiveButtons) {
633
+ const interactiveMessage = {
634
+ nativeFlowMessage: Types_1.WAProto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
635
+ buttons: message.interactiveButtons,
636
+ })
637
+ };
638
+ if ('text' in message) {
639
+ interactiveMessage.body = {
640
+ text: message.text
641
+ };
642
+ }
643
+ else if ('caption' in message) {
644
+ interactiveMessage.body = {
645
+ text: message.caption
646
+ };
647
+ interactiveMessage.header = {
648
+ title: message.title,
649
+ subtitle: message.subtitle,
650
+ hasMediaAttachment: (_j = message === null || message === void 0 ? void 0 : message.media) !== null && _j !== void 0 ? _j : false,
651
+ };
652
+ Object.assign(interactiveMessage.header, m);
653
+ }
654
+ if ('footer' in message && !!message.footer) {
655
+ interactiveMessage.footer = {
656
+ text: message.footer
657
+ };
658
+ }
659
+ if ('title' in message && !!message.title) {
660
+ interactiveMessage.header = {
661
+ title: message.title,
662
+ subtitle: message.subtitle,
663
+ hasMediaAttachment: (_k = message === null || message === void 0 ? void 0 : message.media) !== null && _k !== void 0 ? _k : false,
664
+ };
665
+ Object.assign(interactiveMessage.header, m);
666
+ }
667
+ if ('contextInfo' in message && !!message.contextInfo) {
668
+ interactiveMessage.contextInfo = message.contextInfo;
669
+ }
670
+ if ('mentions' in message && !!message.mentions) {
671
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
672
+ }
673
+ m = { interactiveMessage };
674
+ }
675
+ if ('shop' in message && !!message.shop) {
676
+ const interactiveMessage = {
677
+ shopStorefrontMessage: Types_1.WAProto.Message.InteractiveMessage.ShopMessage.fromObject({
678
+ surface: message.shop,
679
+ id: message.id
680
+ })
681
+ };
682
+ if ('text' in message) {
683
+ interactiveMessage.body = {
684
+ text: message.text
685
+ };
686
+ }
687
+ else if ('caption' in message) {
688
+ interactiveMessage.body = {
689
+ text: message.caption
690
+ };
691
+ interactiveMessage.header = {
692
+ title: message.title,
693
+ subtitle: message.subtitle,
694
+ hasMediaAttachment: (_l = message === null || message === void 0 ? void 0 : message.media) !== null && _l !== void 0 ? _l : false,
695
+ };
696
+ Object.assign(interactiveMessage.header, m);
697
+ }
698
+ if ('footer' in message && !!message.footer) {
699
+ interactiveMessage.footer = {
700
+ text: message.footer
701
+ };
506
702
  }
507
- else if (key) {
508
- key.contextInfo = {
509
- mentionedJid: message.mentions,
510
- nonJidMentions: message.mentionAll ? 1 : 0
703
+ if ('title' in message && !!message.title) {
704
+ interactiveMessage.header = {
705
+ title: message.title,
706
+ subtitle: message.subtitle,
707
+ hasMediaAttachment: (_m = message === null || message === void 0 ? void 0 : message.media) !== null && _m !== void 0 ? _m : false,
511
708
  };
709
+ Object.assign(interactiveMessage.header, m);
710
+ }
711
+ if ('contextInfo' in message && !!message.contextInfo) {
712
+ interactiveMessage.contextInfo = message.contextInfo;
512
713
  }
714
+ if ('mentions' in message && !!message.mentions) {
715
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
716
+ }
717
+ m = { interactiveMessage };
718
+ }
719
+ if ('viewOnce' in message && !!message.viewOnce) {
720
+ m = { viewOnceMessage: { message: m } };
721
+ }
722
+ if ('mentions' in message && ((_o = message.mentions) === null || _o === void 0 ? void 0 : _o.length)) {
723
+ const [messageType] = Object.keys(m);
724
+ m[messageType].contextInfo = m[messageType] || {};
725
+ m[messageType].contextInfo.mentionedJid = message.mentions;
513
726
  }
514
- if (hasOptionalProperty(message, 'edit')) {
727
+ if ('edit' in message) {
515
728
  m = {
516
729
  protocolMessage: {
517
730
  key: message.edit,
518
731
  editedMessage: m,
519
732
  timestampMs: Date.now(),
520
- type: WAProto.Message.ProtocolMessage.Type.MESSAGE_EDIT
521
- }
522
- };
523
- }
524
- if (hasOptionalProperty(message, 'contextInfo') && !!message.contextInfo) {
525
- const messageType = Object.keys(m)[0];
526
- const key = m[messageType];
527
- if ('contextInfo' in key && !!key.contextInfo) {
528
- key.contextInfo = { ...key.contextInfo, ...message.contextInfo };
529
- }
530
- else if (key) {
531
- key.contextInfo = message.contextInfo;
532
- }
533
- }
534
- if (hasOptionalProperty(message, 'albumParentKey') && !!message.albumParentKey) {
535
- m.messageContextInfo = {
536
- ...m.messageContextInfo,
537
- messageAssociation: {
538
- associationType: WAProto.MessageAssociation.AssociationType.MEDIA_ALBUM,
539
- parentMessageKey: message.albumParentKey
733
+ type: Types_1.WAProto.Message.ProtocolMessage.Type.MESSAGE_EDIT
540
734
  }
541
735
  };
542
736
  }
543
- if (shouldIncludeReportingToken(m)) {
544
- m.messageContextInfo = m.messageContextInfo || {};
545
- if (!m.messageContextInfo.messageSecret) {
546
- m.messageContextInfo.messageSecret = randomBytes(32);
547
- }
737
+ if ('contextInfo' in message && !!message.contextInfo) {
738
+ const [messageType] = Object.keys(m);
739
+ m[messageType] = m[messageType] || {};
740
+ m[messageType].contextInfo = message.contextInfo;
548
741
  }
549
- return WAProto.Message.create(m);
742
+ return Types_1.WAProto.Message.fromObject(m);
550
743
  };
551
- export const generateWAMessageFromContent = (jid, message, options) => {
552
- // set timestamp to now
553
- // if not specified
744
+ exports.generateWAMessageContent = generateWAMessageContent;
745
+ const generateWAMessageFromContent = (jid, message, options) => {
746
+
747
+
554
748
  if (!options.timestamp) {
555
749
  options.timestamp = new Date();
556
750
  }
557
- const innerMessage = normalizeMessageContent(message);
558
- const key = getContentType(innerMessage);
559
- const timestamp = unixTimestampSeconds(options.timestamp);
751
+ const innerMessage = (0, exports.normalizeMessageContent)(message);
752
+ const key = (0, exports.getContentType)(innerMessage);
753
+ const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp);
560
754
  const { quoted, userJid } = options;
561
- if (quoted && !isJidNewsletter(jid)) {
562
- const participant = quoted.key.fromMe
563
- ? userJid // TODO: Add support for LIDs
564
- : quoted.participant || quoted.key.participant || quoted.key.remoteJid;
565
- let quotedMsg = normalizeMessageContent(quoted.message);
566
- const msgType = getContentType(quotedMsg);
567
- // strip any redundant properties
568
- quotedMsg = proto.Message.create({ [msgType]: quotedMsg[msgType] });
569
- const quotedContent = quotedMsg[msgType];
570
- if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
571
- delete quotedContent.contextInfo;
572
- }
573
- const contextInfo = ('contextInfo' in innerMessage[key] && innerMessage[key]?.contextInfo) || {};
574
- contextInfo.participant = jidNormalizedUser(participant);
575
- contextInfo.stanzaId = quoted.key.id;
576
- contextInfo.quotedMessage = quotedMsg;
577
- // if a participant is quoted, then it must be a group
578
- // hence, remoteJid of group must also be entered
579
- if (jid !== quoted.key.remoteJid) {
580
- contextInfo.remoteJid = quoted.key.remoteJid;
581
- }
582
- if (contextInfo && innerMessage[key]) {
583
- /* @ts-ignore */
755
+
756
+ if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
757
+ const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid);
758
+ let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message);
759
+ const msgType = (0, exports.getContentType)(quotedMsg);
760
+
761
+ if (quotedMsg) {
762
+ quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
763
+ const quotedContent = quotedMsg[msgType];
764
+ if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
765
+ delete quotedContent.contextInfo;
766
+ }
767
+ const contextInfo = innerMessage[key].contextInfo || {};
768
+ contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
769
+ contextInfo.stanzaId = quoted.key.id;
770
+ contextInfo.quotedMessage = quotedMsg;
771
+
772
+
773
+ if (jid !== quoted.key.remoteJid) {
774
+ contextInfo.remoteJid = quoted.key.remoteJid;
775
+ }
584
776
  innerMessage[key].contextInfo = contextInfo;
585
777
  }
586
778
  }
587
779
  if (
588
- // if we want to send a disappearing message
589
- !!options?.ephemeralExpiration &&
590
- // and it's not a protocol message -- delete, toggle disappear message
780
+
781
+ !!(options === null || options === void 0 ? void 0 : options.ephemeralExpiration) &&
782
+
591
783
  key !== 'protocolMessage' &&
592
- // already not converted to disappearing message
784
+
593
785
  key !== 'ephemeralMessage' &&
594
- // newsletters don't support ephemeral messages
595
- !isJidNewsletter(jid)) {
596
- /* @ts-ignore */
786
+
787
+ !(0, WABinary_1.isJidNewsletter)(jid)) {
597
788
  innerMessage[key].contextInfo = {
598
789
  ...(innerMessage[key].contextInfo || {}),
599
- expiration: options.ephemeralExpiration || WA_DEFAULT_EPHEMERAL
790
+ expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL,
600
791
  //ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString()
601
792
  };
602
793
  }
603
- message = WAProto.Message.create(message);
794
+ message = Types_1.WAProto.Message.fromObject(message);
604
795
  const messageJSON = {
605
796
  key: {
606
797
  remoteJid: jid,
607
798
  fromMe: true,
608
- id: options?.messageId || generateMessageIDV2()
799
+ id: (options === null || options === void 0 ? void 0 : options.messageId) || (0, generics_1.generateMessageIDV2)(),
609
800
  },
610
801
  message: message,
611
802
  messageTimestamp: timestamp,
612
803
  messageStubParameters: [],
613
- participant: isJidGroup(jid) || isJidStatusBroadcast(jid) ? userJid : undefined, // TODO: Add support for LIDs
614
- status: WAMessageStatus.PENDING
804
+ participant: (0, WABinary_1.isJidGroup)(jid) || (0, WABinary_1.isJidStatusBroadcast)(jid) ? userJid : undefined,
805
+ status: Types_1.WAMessageStatus.PENDING
615
806
  };
616
- return WAProto.WebMessageInfo.fromObject(messageJSON);
807
+ return Types_1.WAProto.WebMessageInfo.fromObject(messageJSON);
617
808
  };
618
- export const generateWAMessage = async (jid, content, options) => {
619
- // ensure msg ID is with every log
620
- options.logger = options?.logger?.child({ msgId: options.messageId });
621
- // Pass jid in the options to generateWAMessageContent
622
- return generateWAMessageFromContent(jid, await generateWAMessageContent(content, { ...options, jid }), options);
809
+ exports.generateWAMessageFromContent = generateWAMessageFromContent;
810
+ const generateWAMessage = async (jid, content, options) => {
811
+ var _a;
812
+
813
+ options.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) === null || _a === void 0 ? void 0 : _a.child({ msgId: options.messageId });
814
+ return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsletter)(jid), ...options }), options);
623
815
  };
816
+ exports.generateWAMessage = generateWAMessage;
624
817
  /** Get the key to access the true type of content */
625
- export const getContentType = (content) => {
818
+ const getContentType = (content) => {
626
819
  if (content) {
627
820
  const keys = Object.keys(content);
628
821
  const key = keys.find(k => (k === 'conversation' || k.includes('Message')) && k !== 'senderKeyDistributionMessage');
629
822
  return key;
630
823
  }
631
824
  };
825
+ exports.getContentType = getContentType;
632
826
  /**
633
827
  * Normalizes ephemeral, view once messages to regular message content
634
828
  * Eg. image messages in ephemeral messages, in view once messages etc.
635
829
  * @param content
636
830
  * @returns
637
831
  */
638
- export const normalizeMessageContent = (content) => {
832
+ const normalizeMessageContent = (content) => {
639
833
  if (!content) {
640
834
  return undefined;
641
835
  }
642
- // set max iterations to prevent an infinite loop
836
+
643
837
  for (let i = 0; i < 5; i++) {
644
838
  const inner = getFutureProofMessage(content);
645
839
  if (!inner) {
@@ -649,22 +843,38 @@ export const normalizeMessageContent = (content) => {
649
843
  }
650
844
  return content;
651
845
  function getFutureProofMessage(message) {
652
- return (message?.ephemeralMessage ||
653
- message?.viewOnceMessage ||
654
- message?.documentWithCaptionMessage ||
655
- message?.viewOnceMessageV2 ||
656
- message?.viewOnceMessageV2Extension ||
657
- message?.editedMessage ||
658
- message?.associatedChildMessage ||
659
- message?.groupStatusMessage ||
660
- message?.groupStatusMessageV2);
846
+ return ((message === null || message === void 0 ? void 0 : message.ephemeralMessage)
847
+ || (message === null || message === void 0 ? void 0 : message.viewOnceMessage)
848
+ || (message === null || message === void 0 ? void 0 : message.documentWithCaptionMessage)
849
+ || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2)
850
+ || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension)
851
+ || (message === null || message === void 0 ? void 0 : message.editedMessage)
852
+ || (message === null || message === void 0 ? void 0 : message.groupMentionedMessage)
853
+ || (message === null || message === void 0 ? void 0 : message.botInvokeMessage)
854
+ || (message === null || message === void 0 ? void 0 : message.lottieStickerMessage)
855
+ || (message === null || message === void 0 ? void 0 : message.eventCoverImage)
856
+ || (message === null || message === void 0 ? void 0 : message.statusMentionMessage)
857
+ || (message === null || message === void 0 ? void 0 : message.pollCreationOptionImageMessage)
858
+ || (message === null || message === void 0 ? void 0 : message.associatedChildMessage)
859
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMentionMessage)
860
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV4)
861
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV5)
862
+ || (message === null || message === void 0 ? void 0 : message.statusAddYours)
863
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMessage)
864
+ || (message === null || message === void 0 ? void 0 : message.limitSharingMessage)
865
+ || (message === null || message === void 0 ? void 0 : message.botTaskMessage)
866
+ || (message === null || message === void 0 ? void 0 : message.questionMessage)
867
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMessageV2)
868
+ || (message === null || message === void 0 ? void 0 : message.botForwardedMessage));
661
869
  }
662
870
  };
871
+ exports.normalizeMessageContent = normalizeMessageContent;
663
872
  /**
664
873
  * Extract the true message content from a message
665
874
  * Eg. extracts the inner message from a disappearing message/view once message
666
875
  */
667
- export const extractMessageContent = (content) => {
876
+ const extractMessageContent = (content) => {
877
+ var _a, _b, _c, _d, _e, _f;
668
878
  const extractFromTemplateMessage = (msg) => {
669
879
  if (msg.imageMessage) {
670
880
  return { imageMessage: msg.imageMessage };
@@ -680,39 +890,39 @@ export const extractMessageContent = (content) => {
680
890
  }
681
891
  else {
682
892
  return {
683
- conversation: 'contentText' in msg ? msg.contentText : 'hydratedContentText' in msg ? msg.hydratedContentText : ''
893
+ conversation: 'contentText' in msg
894
+ ? msg.contentText
895
+ : ('hydratedContentText' in msg ? msg.hydratedContentText : '')
684
896
  };
685
897
  }
686
898
  };
687
- content = normalizeMessageContent(content);
688
- if (content?.buttonsMessage) {
899
+ content = (0, exports.normalizeMessageContent)(content);
900
+ if (content === null || content === void 0 ? void 0 : content.buttonsMessage) {
689
901
  return extractFromTemplateMessage(content.buttonsMessage);
690
902
  }
691
- if (content?.templateMessage?.hydratedFourRowTemplate) {
692
- return extractFromTemplateMessage(content?.templateMessage?.hydratedFourRowTemplate);
903
+ if ((_a = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _a === void 0 ? void 0 : _a.hydratedFourRowTemplate) {
904
+ return extractFromTemplateMessage((_b = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _b === void 0 ? void 0 : _b.hydratedFourRowTemplate);
693
905
  }
694
- if (content?.templateMessage?.hydratedTemplate) {
695
- return extractFromTemplateMessage(content?.templateMessage?.hydratedTemplate);
906
+ if ((_c = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _c === void 0 ? void 0 : _c.hydratedTemplate) {
907
+ return extractFromTemplateMessage((_d = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _d === void 0 ? void 0 : _d.hydratedTemplate);
696
908
  }
697
- if (content?.templateMessage?.fourRowTemplate) {
698
- return extractFromTemplateMessage(content?.templateMessage?.fourRowTemplate);
909
+ if ((_e = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _e === void 0 ? void 0 : _e.fourRowTemplate) {
910
+ return extractFromTemplateMessage((_f = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _f === void 0 ? void 0 : _f.fourRowTemplate);
699
911
  }
700
912
  return content;
701
913
  };
914
+ exports.extractMessageContent = extractMessageContent;
702
915
  /**
703
916
  * Returns the device predicted by message ID
704
917
  */
705
- export const getDevice = (id) => /^3A.{18}$/.test(id)
706
- ? 'ios'
707
- : /^3E.{20}$/.test(id)
708
- ? 'web'
709
- : /^(.{21}|.{32})$/.test(id)
710
- ? 'android'
711
- : /^(3F|.{18}$)/.test(id)
712
- ? 'desktop'
713
- : 'unknown';
918
+ const getDevice = (id) => /^3A.{18}$/.test(id) ? 'ios' :
919
+ /^3E.{20}$/.test(id) ? 'web' :
920
+ /^(.{21}|.{32})$/.test(id) ? 'android' :
921
+ /^(3F|.{18}$)/.test(id) ? 'desktop' :
922
+ 'unknown';
923
+ exports.getDevice = getDevice;
714
924
  /** Upserts a receipt in the message */
715
- export const updateMessageWithReceipt = (msg, receipt) => {
925
+ const updateMessageWithReceipt = (msg, receipt) => {
716
926
  msg.userReceipt = msg.userReceipt || [];
717
927
  const recp = msg.userReceipt.find(m => m.userJid === receipt.userJid);
718
928
  if (recp) {
@@ -722,43 +932,40 @@ export const updateMessageWithReceipt = (msg, receipt) => {
722
932
  msg.userReceipt.push(receipt);
723
933
  }
724
934
  };
935
+ exports.updateMessageWithReceipt = updateMessageWithReceipt;
725
936
  /** Update the message with a new reaction */
726
- export const updateMessageWithReaction = (msg, reaction) => {
727
- const authorID = getKeyAuthor(reaction.key);
728
- const reactions = (msg.reactions || []).filter(r => getKeyAuthor(r.key) !== authorID);
937
+ const updateMessageWithReaction = (msg, reaction) => {
938
+ const authorID = (0, generics_1.getKeyAuthor)(reaction.key);
939
+ const reactions = (msg.reactions || [])
940
+ .filter(r => (0, generics_1.getKeyAuthor)(r.key) !== authorID);
729
941
  reaction.text = reaction.text || '';
730
942
  reactions.push(reaction);
731
943
  msg.reactions = reactions;
732
944
  };
945
+ exports.updateMessageWithReaction = updateMessageWithReaction;
733
946
  /** Update the message with a new poll update */
734
- export const updateMessageWithPollUpdate = (msg, update) => {
735
- const authorID = getKeyAuthor(update.pollUpdateMessageKey);
736
- const reactions = (msg.pollUpdates || []).filter(r => getKeyAuthor(r.pollUpdateMessageKey) !== authorID);
737
- if (update.vote?.selectedOptions?.length) {
947
+ const updateMessageWithPollUpdate = (msg, update) => {
948
+ var _a, _b;
949
+ const authorID = (0, generics_1.getKeyAuthor)(update.pollUpdateMessageKey);
950
+ const reactions = (msg.pollUpdates || [])
951
+ .filter(r => (0, generics_1.getKeyAuthor)(r.pollUpdateMessageKey) !== authorID);
952
+ if ((_b = (_a = update.vote) === null || _a === void 0 ? void 0 : _a.selectedOptions) === null || _b === void 0 ? void 0 : _b.length) {
738
953
  reactions.push(update);
739
954
  }
740
955
  msg.pollUpdates = reactions;
741
956
  };
742
- /** Update the message with a new event response */
743
- export const updateMessageWithEventResponse = (msg, update) => {
744
- const authorID = getKeyAuthor(update.eventResponseMessageKey);
745
- const responses = (msg.eventResponses || []).filter(r => getKeyAuthor(r.eventResponseMessageKey) !== authorID);
746
- responses.push(update);
747
- msg.eventResponses = responses;
748
- };
957
+ exports.updateMessageWithPollUpdate = updateMessageWithPollUpdate;
749
958
  /**
750
959
  * Aggregates all poll updates in a poll.
751
960
  * @param msg the poll creation message
752
961
  * @param meId your jid
753
962
  * @returns A list of options & their voters
754
963
  */
755
- export function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
756
- const opts = message?.pollCreationMessage?.options ||
757
- message?.pollCreationMessageV2?.options ||
758
- message?.pollCreationMessageV3?.options ||
759
- [];
964
+ function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
965
+ var _a, _b, _c;
966
+ const opts = ((_a = message === null || message === void 0 ? void 0 : message.pollCreationMessage) === null || _a === void 0 ? void 0 : _a.options) || ((_b = message === null || message === void 0 ? void 0 : message.pollCreationMessageV2) === null || _b === void 0 ? void 0 : _b.options) || ((_c = message === null || message === void 0 ? void 0 : message.pollCreationMessageV3) === null || _c === void 0 ? void 0 : _c.options) || [];
760
967
  const voteHashMap = opts.reduce((acc, opt) => {
761
- const hash = sha256(Buffer.from(opt.optionName || '')).toString();
968
+ const hash = (0, crypto_2.sha256)(Buffer.from(opt.optionName || '')).toString();
762
969
  acc[hash] = {
763
970
  name: opt.optionName || '',
764
971
  voters: []
@@ -780,36 +987,13 @@ export function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
780
987
  };
781
988
  data = voteHashMap[hash];
782
989
  }
783
- voteHashMap[hash].voters.push(getKeyAuthor(update.pollUpdateMessageKey, meId));
990
+ voteHashMap[hash].voters.push((0, generics_1.getKeyAuthor)(update.pollUpdateMessageKey, meId));
784
991
  }
785
992
  }
786
993
  return Object.values(voteHashMap);
787
994
  }
788
- /**
789
- * Aggregates all event responses in an event message.
790
- * @param msg the event creation message
791
- * @param meId your jid
792
- * @returns A list of response types & their responders
793
- */
794
- export function getAggregateResponsesInEventMessage({ eventResponses }, meId) {
795
- const responseTypes = ['GOING', 'NOT_GOING', 'MAYBE'];
796
- const responseMap = {};
797
- for (const type of responseTypes) {
798
- responseMap[type] = {
799
- response: type,
800
- responders: []
801
- };
802
- }
803
- for (const update of eventResponses || []) {
804
- const responseType = update.eventResponse || 'UNKNOWN';
805
- if (responseType !== 'UNKNOWN' && responseMap[responseType]) {
806
- responseMap[responseType].responders.push(getKeyAuthor(update.eventResponseMessageKey, meId));
807
- }
808
- }
809
- return Object.values(responseMap);
810
- }
811
995
  /** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
812
- export const aggregateMessageKeysNotFromMe = (keys) => {
996
+ const aggregateMessageKeysNotFromMe = (keys) => {
813
997
  const keyMap = {};
814
998
  for (const { remoteJid, id, participant, fromMe } of keys) {
815
999
  if (!fromMe) {
@@ -826,34 +1010,40 @@ export const aggregateMessageKeysNotFromMe = (keys) => {
826
1010
  }
827
1011
  return Object.values(keyMap);
828
1012
  };
1013
+ exports.aggregateMessageKeysNotFromMe = aggregateMessageKeysNotFromMe;
829
1014
  const REUPLOAD_REQUIRED_STATUS = [410, 404];
830
1015
  /**
831
1016
  * Downloads the given message. Throws an error if it's not a media message
832
1017
  */
833
- export const downloadMediaMessage = async (message, type, options, ctx) => {
834
- const result = await downloadMsg().catch(async (error) => {
835
- if (ctx &&
836
- typeof error?.status === 'number' && // treat errors with status as HTTP failures requiring reupload
837
- REUPLOAD_REQUIRED_STATUS.includes(error.status)) {
838
- ctx.logger.info({ key: message.key }, 'sending reupload media request...');
839
- // request reupload
840
- message = await ctx.reuploadRequest(message);
841
- const result = await downloadMsg();
842
- return result;
1018
+ const downloadMediaMessage = async (message, type, options, ctx) => {
1019
+ const result = await downloadMsg()
1020
+ .catch(async (error) => {
1021
+ var _a;
1022
+ if (ctx) {
1023
+ if (axios_1.default.isAxiosError(error)) {
1024
+
1025
+ if (REUPLOAD_REQUIRED_STATUS.includes((_a = error.response) === null || _a === void 0 ? void 0 : _a.status)) {
1026
+ ctx.logger.info({ key: message.key }, 'sending reupload media request...');
1027
+
1028
+ message = await ctx.reuploadRequest(message);
1029
+ const result = await downloadMsg();
1030
+ return result;
1031
+ }
1032
+ }
843
1033
  }
844
1034
  throw error;
845
1035
  });
846
1036
  return result;
847
1037
  async function downloadMsg() {
848
- const mContent = extractMessageContent(message.message);
1038
+ const mContent = (0, exports.extractMessageContent)(message.message);
849
1039
  if (!mContent) {
850
- throw new Boom('No message present', { statusCode: 400, data: message });
1040
+ throw new boom_1.Boom('No message present', { statusCode: 400, data: message });
851
1041
  }
852
- const contentType = getContentType(mContent);
853
- let mediaType = contentType?.replace('Message', '');
1042
+ const contentType = (0, exports.getContentType)(mContent);
1043
+ let mediaType = contentType === null || contentType === void 0 ? void 0 : contentType.replace('Message', '');
854
1044
  const media = mContent[contentType];
855
1045
  if (!media || typeof media !== 'object' || (!('url' in media) && !('thumbnailDirectPath' in media))) {
856
- throw new Boom(`"${contentType}" message is not a media message`);
1046
+ throw new boom_1.Boom(`"${contentType}" message is not a media message`);
857
1047
  }
858
1048
  let download;
859
1049
  if ('thumbnailDirectPath' in media && !('url' in media)) {
@@ -866,7 +1056,7 @@ export const downloadMediaMessage = async (message, type, options, ctx) => {
866
1056
  else {
867
1057
  download = media;
868
1058
  }
869
- const stream = await downloadContentFromMessage(download, mediaType, options);
1059
+ const stream = await (0, messages_media_1.downloadContentFromMessage)(download, mediaType, options);
870
1060
  if (type === 'buffer') {
871
1061
  const bufferArray = [];
872
1062
  for await (const chunk of stream) {
@@ -877,17 +1067,37 @@ export const downloadMediaMessage = async (message, type, options, ctx) => {
877
1067
  return stream;
878
1068
  }
879
1069
  };
1070
+ exports.downloadMediaMessage = downloadMediaMessage;
880
1071
  /** Checks whether the given message is a media message; if it is returns the inner content */
881
- export const assertMediaContent = (content) => {
882
- content = extractMessageContent(content);
883
- const mediaContent = content?.documentMessage ||
884
- content?.imageMessage ||
885
- content?.videoMessage ||
886
- content?.audioMessage ||
887
- content?.stickerMessage;
1072
+ const assertMediaContent = (content) => {
1073
+ content = (0, exports.extractMessageContent)(content);
1074
+ const mediaContent = (content === null || content === void 0 ? void 0 : content.documentMessage)
1075
+ || (content === null || content === void 0 ? void 0 : content.imageMessage)
1076
+ || (content === null || content === void 0 ? void 0 : content.videoMessage)
1077
+ || (content === null || content === void 0 ? void 0 : content.audioMessage)
1078
+ || (content === null || content === void 0 ? void 0 : content.stickerMessage);
888
1079
  if (!mediaContent) {
889
- throw new Boom('given message is not a media message', { statusCode: 400, data: content });
1080
+ throw new boom_1.Boom('given message is not a media message', { statusCode: 400, data: content });
890
1081
  }
891
1082
  return mediaContent;
892
1083
  };
893
- //# sourceMappingURL=messages.js.map
1084
+ exports.assertMediaContent = assertMediaContent;
1085
+
1086
+ const toJid = (id) => {
1087
+ if (!id)
1088
+ return '';
1089
+ if (id.endsWith('@lid'))
1090
+ return id.replace('@lid', '@s.whatsapp.net');
1091
+ if (id.includes('@'))
1092
+ return id;
1093
+ return `${id}@s.whatsapp.net`;
1094
+ };
1095
+ exports.toJid = toJid;
1096
+ const getSenderLid = (message) => {
1097
+ const sender = message.key.participant || message.key.remoteJid;
1098
+ const user = (0, WABinary_1.jidDecode)(sender)?.user || '';
1099
+ const lid = (0, WABinary_1.jidEncode)(user, 'lid');
1100
+ console.log('sender lid:', lid);
1101
+ return { jid: sender, lid };
1102
+ };
1103
+ exports.getSenderLid = getSenderLid;