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