@baileys-md/baileys 12.0.0 → 12.2.0

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