cuki-bailx 1.2.5 → 1.2.6

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 (157) hide show
  1. package/LICENSE +21 -0
  2. package/WAProto/GenerateStatics.sh +4 -0
  3. package/WAProto/WAProto.proto +4775 -0
  4. package/WAProto/index.js +56886 -17506
  5. package/engine-requirements.js +1 -1
  6. package/lib/Defaults/index.js +98 -108
  7. package/lib/Defaults/vyzen-baileysx-version.json +3 -0
  8. package/lib/Signal/libsignal.js +2 -0
  9. package/lib/Socket/Client/index.js +2 -3
  10. package/lib/Socket/Client/{web-socket-client.js → websocket.js} +54 -5
  11. package/lib/Socket/chats.js +224 -173
  12. package/lib/Socket/groups.js +20 -5
  13. package/lib/Socket/index.js +2 -2
  14. package/lib/Socket/messages-recv.js +10 -66
  15. package/lib/Socket/messages-send.js +379 -312
  16. package/lib/Socket/newsletter.js +54 -40
  17. package/lib/Socket/socket.js +58 -32
  18. package/lib/Store/index.js +1 -3
  19. package/lib/Store/make-in-memory-store.js +27 -15
  20. package/lib/Store/make-ordered-dictionary.js +2 -2
  21. package/lib/Types/Label.js +1 -1
  22. package/lib/Types/LabelAssociation.js +1 -1
  23. package/lib/Types/Message.js +0 -2
  24. package/lib/Types/Newsletter.js +3 -17
  25. package/lib/Types/index.js +2 -2
  26. package/lib/Utils/auth-utils.js +6 -13
  27. package/lib/Utils/baileys-event-stream.js +1 -1
  28. package/lib/Utils/browser-utils.js +35 -0
  29. package/lib/Utils/business.js +2 -2
  30. package/lib/Utils/chat-utils.js +36 -35
  31. package/lib/Utils/crypto.js +71 -29
  32. package/lib/Utils/decode-wa-message.js +65 -56
  33. package/lib/Utils/event-buffer.js +13 -9
  34. package/lib/Utils/generics.js +107 -29
  35. package/lib/Utils/history.js +4 -6
  36. package/lib/Utils/index.js +2 -0
  37. package/lib/Utils/link-preview.js +34 -1
  38. package/lib/Utils/lt-hash.js +6 -6
  39. package/lib/Utils/message-retry-manager.js +128 -0
  40. package/lib/Utils/messages-media.js +263 -115
  41. package/lib/Utils/messages.js +500 -93
  42. package/lib/Utils/noise-handler.js +18 -23
  43. package/lib/Utils/process-message.js +108 -25
  44. package/lib/Utils/signal.js +37 -35
  45. package/lib/Utils/use-multi-file-auth-state.js +51 -6
  46. package/lib/Utils/validate-connection.js +90 -66
  47. package/lib/WABinary/constants.js +1276 -13
  48. package/lib/WABinary/decode.js +26 -13
  49. package/lib/WABinary/encode.js +39 -17
  50. package/lib/WABinary/generic-utils.js +2 -85
  51. package/lib/WABinary/jid-utils.js +28 -5
  52. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -1
  53. package/lib/index.js +18 -5
  54. package/package.json +109 -104
  55. package/lib/Defaults/baileys-version.json +0 -3
  56. package/lib/Defaults/index.d.ts +0 -53
  57. package/lib/Defaults/phonenumber-mcc.json +0 -223
  58. package/lib/Signal/Group/ciphertext-message.d.ts +0 -9
  59. package/lib/Signal/Group/group-session-builder.d.ts +0 -14
  60. package/lib/Signal/Group/group_cipher.d.ts +0 -17
  61. package/lib/Signal/Group/index.d.ts +0 -11
  62. package/lib/Signal/Group/keyhelper.d.ts +0 -10
  63. package/lib/Signal/Group/queue-job.d.ts +0 -1
  64. package/lib/Signal/Group/sender-chain-key.d.ts +0 -13
  65. package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -16
  66. package/lib/Signal/Group/sender-key-message.d.ts +0 -18
  67. package/lib/Signal/Group/sender-key-name.d.ts +0 -17
  68. package/lib/Signal/Group/sender-key-record.d.ts +0 -30
  69. package/lib/Signal/Group/sender-key-state.d.ts +0 -38
  70. package/lib/Signal/Group/sender-message-key.d.ts +0 -11
  71. package/lib/Signal/libsignal.d.ts +0 -3
  72. package/lib/Socket/Client/abstract-socket-client.d.ts +0 -17
  73. package/lib/Socket/Client/index.d.ts +0 -3
  74. package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
  75. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  76. package/lib/Socket/Client/web-socket-client.d.ts +0 -12
  77. package/lib/Socket/business.d.ts +0 -171
  78. package/lib/Socket/chats.d.ts +0 -80
  79. package/lib/Socket/dugong.d.ts +0 -219
  80. package/lib/Socket/dugong.js +0 -441
  81. package/lib/Socket/groups.d.ts +0 -115
  82. package/lib/Socket/index.d.ts +0 -173
  83. package/lib/Socket/messages-recv.d.ts +0 -161
  84. package/lib/Socket/messages-send.d.ts +0 -149
  85. package/lib/Socket/newsletter.d.ts +0 -134
  86. package/lib/Socket/registration.d.ts +0 -267
  87. package/lib/Socket/registration.js +0 -166
  88. package/lib/Socket/socket.d.ts +0 -43
  89. package/lib/Socket/socket.js.bak +0 -630
  90. package/lib/Socket/usync.d.ts +0 -36
  91. package/lib/Store/index.d.ts +0 -3
  92. package/lib/Store/make-cache-manager-store.d.ts +0 -13
  93. package/lib/Store/make-cache-manager-store.js +0 -83
  94. package/lib/Store/make-in-memory-store.d.ts +0 -118
  95. package/lib/Store/make-ordered-dictionary.d.ts +0 -13
  96. package/lib/Store/object-repository.d.ts +0 -10
  97. package/lib/Types/Auth.d.ts +0 -110
  98. package/lib/Types/Call.d.ts +0 -13
  99. package/lib/Types/Chat.d.ts +0 -102
  100. package/lib/Types/Contact.d.ts +0 -19
  101. package/lib/Types/Events.d.ts +0 -157
  102. package/lib/Types/GroupMetadata.d.ts +0 -55
  103. package/lib/Types/Label.d.ts +0 -35
  104. package/lib/Types/LabelAssociation.d.ts +0 -29
  105. package/lib/Types/Message.d.ts +0 -273
  106. package/lib/Types/Newsletter.d.ts +0 -92
  107. package/lib/Types/Product.d.ts +0 -78
  108. package/lib/Types/Signal.d.ts +0 -57
  109. package/lib/Types/Socket.d.ts +0 -111
  110. package/lib/Types/State.d.ts +0 -27
  111. package/lib/Types/USync.d.ts +0 -25
  112. package/lib/Types/index.d.ts +0 -57
  113. package/lib/Utils/auth-utils.d.ts +0 -18
  114. package/lib/Utils/baileys-event-stream.d.ts +0 -16
  115. package/lib/Utils/business.d.ts +0 -22
  116. package/lib/Utils/chat-utils.d.ts +0 -71
  117. package/lib/Utils/crypto.d.ts +0 -41
  118. package/lib/Utils/decode-wa-message.d.ts +0 -19
  119. package/lib/Utils/event-buffer.d.ts +0 -35
  120. package/lib/Utils/generics.d.ts +0 -92
  121. package/lib/Utils/history.d.ts +0 -15
  122. package/lib/Utils/index.d.ts +0 -17
  123. package/lib/Utils/link-preview.d.ts +0 -21
  124. package/lib/Utils/logger.d.ts +0 -4
  125. package/lib/Utils/lt-hash.d.ts +0 -12
  126. package/lib/Utils/make-mutex.d.ts +0 -7
  127. package/lib/Utils/messages-media.d.ts +0 -116
  128. package/lib/Utils/messages.d.ts +0 -77
  129. package/lib/Utils/noise-handler.d.ts +0 -21
  130. package/lib/Utils/process-message.d.ts +0 -41
  131. package/lib/Utils/signal.d.ts +0 -32
  132. package/lib/Utils/use-multi-file-auth-state.d.ts +0 -13
  133. package/lib/Utils/validate-connection.d.ts +0 -11
  134. package/lib/WABinary/constants.d.ts +0 -27
  135. package/lib/WABinary/decode.d.ts +0 -7
  136. package/lib/WABinary/encode.d.ts +0 -3
  137. package/lib/WABinary/generic-utils.d.ts +0 -16
  138. package/lib/WABinary/index.d.ts +0 -5
  139. package/lib/WABinary/jid-utils.d.ts +0 -31
  140. package/lib/WABinary/types.d.ts +0 -18
  141. package/lib/WAM/BinaryInfo.d.ts +0 -17
  142. package/lib/WAM/constants.d.ts +0 -38
  143. package/lib/WAM/encode.d.ts +0 -3
  144. package/lib/WAM/index.d.ts +0 -3
  145. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -9
  146. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -22
  147. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -12
  148. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -12
  149. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +0 -25
  150. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +0 -8
  151. package/lib/WAUSync/Protocols/index.d.ts +0 -4
  152. package/lib/WAUSync/USyncQuery.d.ts +0 -28
  153. package/lib/WAUSync/USyncUser.d.ts +0 -12
  154. package/lib/WAUSync/index.d.ts +0 -3
  155. package/lib/index.d.ts +0 -12
  156. package/lib/index.js.bak +0 -48
  157. /package/lib/Socket/Client/{abstract-socket-client.js → types.js} +0 -0
@@ -1,13 +1,19 @@
1
- "use strict";
1
+ // BAILEYS BY VYZEN, MAU APA LU!?
2
+
3
+ "use strict";
2
4
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
5
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
6
  };
5
7
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.assertMediaContent = exports.downloadMediaMessage = exports.aggregateMessageKeysNotFromMe = exports.getAggregateVotesInPollMessage = exports.updateMessageWithPollUpdate = exports.updateMessageWithReaction = exports.updateMessageWithReceipt = exports.getDevice = exports.extractMessageContent = exports.normalizeMessageContent = exports.getContentType = exports.generateWAMessage = exports.generateWAMessageFromContent = exports.generateWAMessageContent = exports.generateForwardMessageContent = exports.prepareDisappearingMessageSettingContent = exports.prepareWAMessageMedia = exports.generateLinkPreviewIfRequired = exports.extractUrlFromText = void 0;
8
+ 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;
9
+ exports.getAggregateVotesInPollMessage = getAggregateVotesInPollMessage;
7
10
  const boom_1 = require("@hapi/boom");
8
11
  const axios_1 = __importDefault(require("axios"));
9
12
  const crypto_1 = require("crypto");
10
13
  const fs_1 = require("fs");
14
+ const child_process_1 = require("child_process");
15
+ const os_1 = require("os");
16
+ const path_1 = require("path");
11
17
  const WAProto_1 = require("../../WAProto");
12
18
  const Defaults_1 = require("../Defaults");
13
19
  const Types_1 = require("../Types");
@@ -45,7 +51,7 @@ const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
45
51
  const urlInfo = await getUrlInfo(url);
46
52
  return urlInfo;
47
53
  }
48
- catch (error) { // ignore if fails
54
+ catch (error) {
49
55
  logger === null || logger === void 0 ? void 0 : logger.warn({ trace: error.stack }, 'url generation failed');
50
56
  }
51
57
  }
@@ -78,47 +84,15 @@ const prepareWAMessageMedia = async (message, options) => {
78
84
  }
79
85
  const uploadData = {
80
86
  ...message,
81
- ...(message.annotations ? {
82
- annotations: message.annotations
83
- } : {
84
- annotations: [
85
- {
86
- polygonVertices: [
87
- {
88
- x: 60.71664810180664,
89
- y: -36.39784622192383
90
- },
91
- {
92
- x: -16.710189819335938,
93
- y: 49.263675689697266
94
- },
95
- {
96
- x: -56.585853576660156,
97
- y: 37.85963439941406
98
- },
99
- {
100
- x: 20.840980529785156,
101
- y: -47.80188751220703
102
- }
103
- ],
104
- newsletter: {
105
- newsletterJid: "120363297591152843@newsletter",
106
- serverMessageId: 0,
107
- newsletterName: "-",
108
- contentType: "UPDATE",
109
- }
110
- }
111
- ]
112
- }),
113
87
  media: message[mediaType]
114
88
  };
115
89
  delete uploadData[mediaType];
116
- // check if cacheable + generate cache key
90
+
117
91
  const cacheableKey = typeof uploadData.media === 'object' &&
118
92
  ('url' in uploadData.media) &&
119
93
  !!uploadData.media.url &&
120
94
  !!options.mediaCache && (
121
- // generate the key
95
+
122
96
  mediaType + ':' + uploadData.media.url.toString());
123
97
  if (mediaType === 'document' && !uploadData.fileName) {
124
98
  uploadData.fileName = 'file';
@@ -126,7 +100,7 @@ const prepareWAMessageMedia = async (message, options) => {
126
100
  if (!uploadData.mimetype) {
127
101
  uploadData.mimetype = MIMETYPE_MAP[mediaType];
128
102
  }
129
- // check for cache hit
103
+
130
104
  if (cacheableKey) {
131
105
  const mediaBuff = options.mediaCache.get(cacheableKey);
132
106
  if (mediaBuff) {
@@ -142,13 +116,94 @@ const prepareWAMessageMedia = async (message, options) => {
142
116
  (typeof uploadData['jpegThumbnail'] === 'undefined');
143
117
  const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
144
118
  const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
119
+
120
+
121
+ if (requiresWaveformProcessing) {
122
+ let tmpInput;
123
+ let tmpOutput;
124
+ try {
125
+ let bufferToConvert = null;
126
+ let isMediaUrl = false;
127
+
128
+
129
+ if (Buffer.isBuffer(uploadData.media)) {
130
+ bufferToConvert = uploadData.media;
131
+ } else if (typeof uploadData.media === 'string') {
132
+ if (fs_1.existsSync(uploadData.media)) {
133
+ bufferToConvert = fs_1.readFileSync(uploadData.media);
134
+ } else if (uploadData.media.startsWith('http')) {
135
+ isMediaUrl = true;
136
+ }
137
+ } else if (typeof uploadData.media === 'object' && 'url' in uploadData.media && uploadData.media.url.startsWith('http')) {
138
+ isMediaUrl = true;
139
+ }
140
+
141
+
142
+ if (isMediaUrl) {
143
+ const mediaUrl = typeof uploadData.media === 'string' ? uploadData.media : uploadData.media.url;
144
+ const resp = await axios_1.default.get(mediaUrl, {
145
+ responseType: 'arraybuffer',
146
+
147
+ headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' }
148
+ });
149
+ if (resp.status === 200 && resp.data.length > 100) {
150
+ bufferToConvert = resp.data;
151
+ } else {
152
+ throw new boom_1.Boom(`Gagal mengunduh audio dari URL: Status ${resp.status} atau file terlalu kecil.`, { statusCode: 400 });
153
+ }
154
+ }
155
+
156
+ if (bufferToConvert) {
157
+ tmpInput = path_1.join(os_1.tmpdir(), `vyzen-raw-${(0, crypto_1.randomBytes)(4).toString('hex')}.tmp`);
158
+ tmpOutput = path_1.join(os_1.tmpdir(), `vyzen-fixed-${(0, crypto_1.randomBytes)(4).toString('hex')}.opus`);
159
+
160
+ fs_1.writeFileSync(tmpInput, bufferToConvert);
161
+
162
+ await new Promise((resolve, reject) => {
163
+
164
+ const cmd = `ffmpeg -y -i "${tmpInput}" -vn -c:a libopus -b:a 128k -ac 1 -ar 48000 -f opus -map_metadata -1 "${tmpOutput}"`;
165
+ (0, child_process_1.exec)(cmd, (error, stdout, stderr) => {
166
+ if (error) {
167
+ logger === null || logger === void 0 ? void 0 : logger.error(`FFMPEG PTT Fix Error: ${error.message} \n ${stderr}`);
168
+ reject(new Error(`FFmpeg failed: ${stderr.trim()}`));
169
+ }
170
+ else {
171
+ resolve();
172
+ }
173
+ });
174
+ });
175
+
176
+ if (fs_1.existsSync(tmpOutput) && fs_1.statSync(tmpOutput).size > 1000) {
177
+ const fixedBuffer = fs_1.readFileSync(tmpOutput);
178
+
179
+ uploadData.media = fixedBuffer;
180
+ uploadData.mimetype = 'audio/ogg; codecs=opus';
181
+ logger === null || logger === void 0 ? void 0 : logger.debug('Vyzen Auto-Fix: Audio converted to Whatsapp PTT standard successfully');
182
+ } else {
183
+ logger === null || logger === void 0 ? void 0 : logger.warn('Vyzen Auto-Fix: File hasil konversi terlalu kecil atau gagal dibuat, menggunakan media asli.');
184
+ }
185
+ }
186
+ } catch (err) {
187
+ logger === null || logger === void 0 ? void 0 : logger.warn({ err }, 'Vyzen Auto-Fix: Gagal memproses PTT, fallback ke data media asli.');
188
+ } finally {
189
+
190
+ if (tmpInput && fs_1.existsSync(tmpInput)) {
191
+ fs_1.unlinkSync(tmpInput);
192
+ }
193
+ if (tmpOutput && fs_1.existsSync(tmpOutput)) {
194
+ fs_1.unlinkSync(tmpOutput);
195
+ }
196
+ }
197
+ }
198
+
199
+
145
200
  const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
146
201
  const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, } = await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
147
202
  logger,
148
203
  saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
149
204
  opts: options.options
150
205
  });
151
- // url safe Base64 encode the SHA256 hash of the body
206
+
152
207
  const fileEncSha256B64 = (options.newsletter ? fileSha256 : fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256).toString('base64');
153
208
  const [{ mediaUrl, directPath, handle }] = await Promise.all([
154
209
  (async () => {
@@ -172,14 +227,86 @@ const prepareWAMessageMedia = async (message, options) => {
172
227
  uploadData.seconds = await (0, messages_media_1.getAudioDuration)(bodyPath);
173
228
  logger === null || logger === void 0 ? void 0 : logger.debug('computed audio duration');
174
229
  }
230
+
231
+
175
232
  if (requiresWaveformProcessing) {
176
- uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(bodyPath, logger);
177
- logger === null || logger === void 0 ? void 0 : logger.debug('processed waveform');
178
- }
179
- if (requiresWaveformProcessing) {
180
- uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(bodyPath, logger);
181
- logger === null || logger === void 0 ? void 0 : logger.debug('processed waveform');
233
+ let audioBuffer = null;
234
+ if (Buffer.isBuffer(uploadData.media)) {
235
+ audioBuffer = uploadData.media;
236
+ } else if (typeof uploadData.media === 'string') {
237
+ try {
238
+ audioBuffer = fs_1.readFileSync(uploadData.media);
239
+ } catch (e) {}
240
+ } else if (bodyPath) {
241
+ try {
242
+ audioBuffer = fs_1.readFileSync(bodyPath);
243
+ } catch (e) {}
244
+ }
245
+
246
+ if (audioBuffer) {
247
+ try {
248
+
249
+ const tmpPath = path_1.join(os_1.tmpdir(), `wa-wave-${(0, crypto_1.randomBytes)(4).toString('hex')}.tmp`);
250
+ fs_1.writeFileSync(tmpPath, audioBuffer);
251
+
252
+
253
+ const getPcm = () => new Promise((resolve, reject) => {
254
+
255
+ const cmd = `ffmpeg -i "${tmpPath}" -f s16le -ac 1 -ar 8000 pipe:1`;
256
+ (0, child_process_1.exec)(cmd, { encoding: 'buffer', maxBuffer: 20 * 1024 * 1024 }, (error, stdout) => {
257
+ if (error) reject(error);
258
+ else resolve(stdout);
259
+ });
260
+ });
261
+
262
+ const rawPcm = await getPcm();
263
+ try { fs_1.unlinkSync(tmpPath); } catch(e){}
264
+
265
+
266
+ const samples = new Int16Array(rawPcm.buffer, rawPcm.byteOffset, rawPcm.byteLength / 2);
267
+ const waveformLength = 64;
268
+ const newData = new Uint8Array(waveformLength);
269
+ const step = Math.floor(samples.length / waveformLength);
270
+
271
+ for (let i = 0; i < waveformLength; i++) {
272
+ let maxVal = 0;
273
+ const start = i * step;
274
+ const end = start + step;
275
+
276
+
277
+ for (let j = start; j < end; j++) {
278
+ const val = Math.abs(samples[j]);
279
+ if (val > maxVal) maxVal = val;
280
+ }
281
+
282
+
283
+ let ratio = maxVal / 32767;
284
+
285
+
286
+ ratio = Math.pow(ratio, 0.75);
287
+
288
+
289
+ let val = Math.floor(ratio * 100);
290
+ if (val > 100) val = 100;
291
+ newData[i] = val;
292
+ }
293
+
294
+ uploadData.waveform = newData;
295
+ logger === null || logger === void 0 ? void 0 : logger.debug('processed realistic audio waveform via ffmpeg');
296
+
297
+ } catch (err) {
298
+
299
+ logger === null || logger === void 0 ? void 0 : logger.warn({ err }, 'failed to generate realistic waveform, falling back to random');
300
+ const hash = (0, crypto_1.createHash)('sha256').update(audioBuffer).digest();
301
+ uploadData.waveform = new Uint8Array(64);
302
+ for (let i = 0; i < 64; i++) {
303
+ uploadData.waveform[i] = Math.floor((hash[i % hash.length] / 255) * 60);
304
+ }
305
+ }
306
+ }
182
307
  }
308
+
309
+
183
310
  if (requiresAudioBackground) {
184
311
  uploadData.backgroundArgb = await assertColor(options.backgroundColor);
185
312
  logger === null || logger === void 0 ? void 0 : logger.debug('computed backgroundColor audio status');
@@ -194,10 +321,16 @@ const prepareWAMessageMedia = async (message, options) => {
194
321
  if (!Buffer.isBuffer(encWriteStream)) {
195
322
  encWriteStream.destroy();
196
323
  }
197
- // remove tmp files
324
+
198
325
  if (didSaveToTmpPath && bodyPath) {
199
- await fs_1.promises.unlink(bodyPath);
200
- logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp files');
326
+ try {
327
+ await fs_1.promises.access(bodyPath);
328
+ await fs_1.promises.unlink(bodyPath);
329
+ logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp file');
330
+ }
331
+ catch (error) {
332
+ logger === null || logger === void 0 ? void 0 : logger.warn('failed to remove tmp file');
333
+ }
201
334
  }
202
335
  });
203
336
  const obj = Types_1.WAProto.Message.fromObject({
@@ -250,7 +383,7 @@ const generateForwardMessageContent = (message, forceForward) => {
250
383
  if (!content) {
251
384
  throw new boom_1.Boom('no content in message', { statusCode: 400 });
252
385
  }
253
- // hacky copy
386
+
254
387
  content = (0, exports.normalizeMessageContent)(content);
255
388
  content = WAProto_1.proto.Message.decode(WAProto_1.proto.Message.encode(content).finish());
256
389
  let key = Object.keys(content)[0];
@@ -271,8 +404,8 @@ const generateForwardMessageContent = (message, forceForward) => {
271
404
  };
272
405
  exports.generateForwardMessageContent = generateForwardMessageContent;
273
406
  const generateWAMessageContent = async (message, options) => {
274
- var _a;
275
- var _b;
407
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
408
+ var _p, _q;
276
409
  let m = {};
277
410
  if ('text' in message) {
278
411
  const extContent = { text: message.text };
@@ -281,7 +414,6 @@ const generateWAMessageContent = async (message, options) => {
281
414
  urlInfo = await (0, exports.generateLinkPreviewIfRequired)(message.text, options.getUrlInfo, options.logger);
282
415
  }
283
416
  if (urlInfo) {
284
- extContent.canonicalUrl = urlInfo['canonical-url'];
285
417
  extContent.matchedText = urlInfo['matched-text'];
286
418
  extContent.jpegThumbnail = urlInfo.jpegThumbnail;
287
419
  extContent.description = urlInfo.description;
@@ -342,6 +474,54 @@ const generateWAMessageContent = async (message, options) => {
342
474
  message.disappearingMessagesInChat;
343
475
  m = (0, exports.prepareDisappearingMessageSettingContent)(exp);
344
476
  }
477
+ else if ('groupInvite' in message) {
478
+ m.groupInviteMessage = {};
479
+ m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
480
+ m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
481
+ m.groupInviteMessage.caption = message.groupInvite.text;
482
+ m.groupInviteMessage.groupJid = message.groupInvite.jid;
483
+ m.groupInviteMessage.groupName = message.groupInvite.subject;
484
+
485
+
486
+ if (options.getProfilePicUrl) {
487
+ const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
488
+ if (pfpUrl) {
489
+ const resp = await axios_1.default.get(pfpUrl, { responseType: 'arraybuffer' });
490
+ if (resp.status === 200) {
491
+ m.groupInviteMessage.jpegThumbnail = resp.data;
492
+ }
493
+ }
494
+ }
495
+ }
496
+ else if ('pin' in message) {
497
+ m.pinInChatMessage = {};
498
+ m.messageContextInfo = {};
499
+ m.pinInChatMessage.key = message.pin;
500
+ m.pinInChatMessage.type = message.type;
501
+ m.pinInChatMessage.senderTimestampMs = Date.now();
502
+ m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0;
503
+ }
504
+ else if ('keep' in message) {
505
+ m.keepInChatMessage = {};
506
+ m.keepInChatMessage.key = message.keep;
507
+ m.keepInChatMessage.keepType = message.type;
508
+ m.keepInChatMessage.timestampMs = Date.now();
509
+ }
510
+ else if ('call' in message) {
511
+ m = {
512
+ scheduledCallCreationMessage: {
513
+ scheduledTimestampMs: (_a = message.call.time) !== null && _a !== void 0 ? _a : Date.now(),
514
+ callType: (_b = message.call.type) !== null && _b !== void 0 ? _b : 1,
515
+ title: message.call.title
516
+ }
517
+ };
518
+ }
519
+ else if ('paymentInvite' in message) {
520
+ m.paymentInviteMessage = {
521
+ serviceType: message.paymentInvite.type,
522
+ expiryTimestamp: message.paymentInvite.expiry
523
+ };
524
+ }
345
525
  else if ('buttonReply' in message) {
346
526
  switch (message.type) {
347
527
  case 'template':
@@ -360,6 +540,10 @@ const generateWAMessageContent = async (message, options) => {
360
540
  break;
361
541
  }
362
542
  }
543
+ else if ('ptv' in message && message.ptv) {
544
+ const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
545
+ m.ptvMessage = videoMessage;
546
+ }
363
547
  else if ('product' in message) {
364
548
  const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
365
549
  m.productMessage = Types_1.WAProto.Message.ProductMessage.fromObject({
@@ -370,11 +554,27 @@ const generateWAMessageContent = async (message, options) => {
370
554
  }
371
555
  });
372
556
  }
557
+ else if ('order' in message) {
558
+ m.orderMessage = Types_1.WAProto.Message.OrderMessage.fromObject({
559
+ orderId: message.order.id,
560
+ thumbnail: message.order.thumbnail,
561
+ itemCount: message.order.itemCount,
562
+ status: message.order.status,
563
+ surface: message.order.surface,
564
+ orderTitle: message.order.title,
565
+ message: message.order.text,
566
+ sellerJid: message.order.seller,
567
+ token: message.order.token,
568
+ totalAmount1000: message.order.amount,
569
+ totalCurrencyCode: message.order.currency
570
+ });
571
+ }
373
572
  else if ('listReply' in message) {
374
573
  m.listResponseMessage = { ...message.listReply };
375
574
  }
376
575
  else if ('poll' in message) {
377
- (_b = message.poll).selectableCount || (_b.selectableCount = 0);
576
+ (_p = message.poll).selectableCount || (_p.selectableCount = 0);
577
+ (_q = message.poll).toAnnouncementGroup || (_q.toAnnouncementGroup = false);
378
578
  if (!Array.isArray(message.poll.values)) {
379
579
  throw new boom_1.Boom('Invalid poll values', { statusCode: 400 });
380
580
  }
@@ -383,14 +583,75 @@ const generateWAMessageContent = async (message, options) => {
383
583
  throw new boom_1.Boom(`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`, { statusCode: 400 });
384
584
  }
385
585
  m.messageContextInfo = {
386
- // encKey
586
+
387
587
  messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32),
388
588
  };
389
- m.pollCreationMessage = {
589
+ const pollCreationMessage = {
390
590
  name: message.poll.name,
391
591
  selectableOptionsCount: message.poll.selectableCount,
392
592
  options: message.poll.values.map(optionName => ({ optionName })),
393
593
  };
594
+ if (message.poll.toAnnouncementGroup) {
595
+
596
+ m.pollCreationMessageV2 = pollCreationMessage;
597
+ }
598
+ else {
599
+ if (message.poll.selectableCount === 1) {
600
+
601
+ m.pollCreationMessageV3 = pollCreationMessage;
602
+ }
603
+ else {
604
+
605
+ m.pollCreationMessage = pollCreationMessage;
606
+ }
607
+ }
608
+ }
609
+ else if ('event' in message) {
610
+ m.messageContextInfo = {
611
+ messageSecret: message.event.messageSecret || (0, crypto_1.randomBytes)(32),
612
+ };
613
+ m.eventMessage = { ...message.event };
614
+ }
615
+ else if ('inviteAdmin' in message) {
616
+ m.newsletterAdminInviteMessage = {};
617
+ m.newsletterAdminInviteMessage.inviteExpiration = message.inviteAdmin.inviteExpiration;
618
+ m.newsletterAdminInviteMessage.caption = message.inviteAdmin.text;
619
+ m.newsletterAdminInviteMessage.newsletterJid = message.inviteAdmin.jid;
620
+ m.newsletterAdminInviteMessage.newsletterName = message.inviteAdmin.subject;
621
+ m.newsletterAdminInviteMessage.jpegThumbnail = message.inviteAdmin.thumbnail;
622
+ }
623
+ else if ('requestPayment' in message) {
624
+ const sticker = ((_c = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _c === void 0 ? void 0 : _c.sticker) ?
625
+ 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)
626
+ : null;
627
+ let notes = {};
628
+ if ((_e = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _e === void 0 ? void 0 : _e.sticker) {
629
+ notes = {
630
+ stickerMessage: {
631
+ ...sticker === null || sticker === void 0 ? void 0 : sticker.stickerMessage,
632
+ contextInfo: (_f = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _f === void 0 ? void 0 : _f.contextInfo
633
+ }
634
+ };
635
+ }
636
+ else if (message.requestPayment.note) {
637
+ notes = {
638
+ extendedTextMessage: {
639
+ text: message.requestPayment.note,
640
+ contextInfo: (_g = message === null || message === void 0 ? void 0 : message.requestPayment) === null || _g === void 0 ? void 0 : _g.contextInfo,
641
+ }
642
+ };
643
+ }
644
+ else {
645
+ throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
646
+ }
647
+ m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
648
+ expiryTimestamp: message.requestPayment.expiry,
649
+ amount1000: message.requestPayment.amount,
650
+ currencyCodeIso4217: message.requestPayment.currency,
651
+ requestFrom: message.requestPayment.from,
652
+ noteMessage: { ...notes },
653
+ background: (_h = message.requestPayment.background) !== null && _h !== void 0 ? _h : null,
654
+ });
394
655
  }
395
656
  else if ('sharePhoneNumber' in message) {
396
657
  m.protocolMessage = {
@@ -400,6 +661,14 @@ const generateWAMessageContent = async (message, options) => {
400
661
  else if ('requestPhoneNumber' in message) {
401
662
  m.requestPhoneNumberMessage = {};
402
663
  }
664
+ else if ('album' in message) {
665
+ const imageMessages = message.album.filter(item => 'image' in item);
666
+ const videoMessages = message.album.filter(item => 'video' in item);
667
+ m.albumMessage = WAProto_1.proto.Message.AlbumMessage.fromObject({
668
+ expectedImageCount: imageMessages.length,
669
+ expectedVideoCount: videoMessages.length,
670
+ });
671
+ }
403
672
  else {
404
673
  m = await (0, exports.prepareWAMessageMedia)(message, options);
405
674
  }
@@ -419,14 +688,24 @@ const generateWAMessageContent = async (message, options) => {
419
688
  buttonsMessage.headerType = ButtonType[type];
420
689
  Object.assign(buttonsMessage, m);
421
690
  }
691
+ if ('title' in message && !!message.title) {
692
+ buttonsMessage.text = message.title,
693
+ buttonsMessage.headerType = ButtonType.TEXT;
694
+ }
422
695
  if ('footer' in message && !!message.footer) {
423
696
  buttonsMessage.footerText = message.footer;
424
697
  }
698
+ if ('contextInfo' in message && !!message.contextInfo) {
699
+ buttonsMessage.contextInfo = message.contextInfo;
700
+ }
701
+ if ('mentions' in message && !!message.mentions) {
702
+ buttonsMessage.contextInfo = { mentionedJid: message.mentions };
703
+ }
425
704
  m = { buttonsMessage };
426
705
  }
427
706
  else if ('templateButtons' in message && !!message.templateButtons) {
428
707
  const msg = {
429
- hydratedButtons: message.templateButtons
708
+ hydratedButtons: message.hasOwnProperty("templateButtons") ? message.templateButtons : message.templateButtons
430
709
  };
431
710
  if ('text' in message) {
432
711
  msg.hydratedContentText = message.text;
@@ -458,10 +737,97 @@ const generateWAMessageContent = async (message, options) => {
458
737
  };
459
738
  m = { listMessage };
460
739
  }
740
+ else if ('interactiveButtons' in message && !!message.interactiveButtons) {
741
+ const interactiveMessage = {
742
+ nativeFlowMessage: Types_1.WAProto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
743
+ buttons: message.interactiveButtons,
744
+ })
745
+ };
746
+ if ('text' in message) {
747
+ interactiveMessage.body = {
748
+ text: message.text
749
+ };
750
+ }
751
+ else if ('caption' in message) {
752
+ interactiveMessage.body = {
753
+ text: message.caption
754
+ };
755
+ interactiveMessage.header = {
756
+ title: message.title,
757
+ subtitle: message.subtitle,
758
+ hasMediaAttachment: (_j = message === null || message === void 0 ? void 0 : message.media) !== null && _j !== void 0 ? _j : false,
759
+ };
760
+ Object.assign(interactiveMessage.header, m);
761
+ }
762
+ if ('footer' in message && !!message.footer) {
763
+ interactiveMessage.footer = {
764
+ text: message.footer
765
+ };
766
+ }
767
+ if ('title' in message && !!message.title) {
768
+ interactiveMessage.header = {
769
+ title: message.title,
770
+ subtitle: message.subtitle,
771
+ hasMediaAttachment: (_k = message === null || message === void 0 ? void 0 : message.media) !== null && _k !== void 0 ? _k : false,
772
+ };
773
+ Object.assign(interactiveMessage.header, m);
774
+ }
775
+ if ('contextInfo' in message && !!message.contextInfo) {
776
+ interactiveMessage.contextInfo = message.contextInfo;
777
+ }
778
+ if ('mentions' in message && !!message.mentions) {
779
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
780
+ }
781
+ m = { interactiveMessage };
782
+ }
783
+ else if ('shop' in message && !!message.shop) {
784
+ const interactiveMessage = {
785
+ shopStorefrontMessage: Types_1.WAProto.Message.InteractiveMessage.ShopMessage.fromObject({
786
+ surface: message.shop,
787
+ id: message.id
788
+ })
789
+ };
790
+ if ('text' in message) {
791
+ interactiveMessage.body = {
792
+ text: message.text
793
+ };
794
+ }
795
+ else if ('caption' in message) {
796
+ interactiveMessage.body = {
797
+ text: message.caption
798
+ };
799
+ interactiveMessage.header = {
800
+ title: message.title,
801
+ subtitle: message.subtitle,
802
+ hasMediaAttachment: (_l = message === null || message === void 0 ? void 0 : message.media) !== null && _l !== void 0 ? _l : false,
803
+ };
804
+ Object.assign(interactiveMessage.header, m);
805
+ }
806
+ if ('footer' in message && !!message.footer) {
807
+ interactiveMessage.footer = {
808
+ text: message.footer
809
+ };
810
+ }
811
+ if ('title' in message && !!message.title) {
812
+ interactiveMessage.header = {
813
+ title: message.title,
814
+ subtitle: message.subtitle,
815
+ hasMediaAttachment: (_m = message === null || message === void 0 ? void 0 : message.media) !== null && _m !== void 0 ? _m : false,
816
+ };
817
+ Object.assign(interactiveMessage.header, m);
818
+ }
819
+ if ('contextInfo' in message && !!message.contextInfo) {
820
+ interactiveMessage.contextInfo = message.contextInfo;
821
+ }
822
+ if ('mentions' in message && !!message.mentions) {
823
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
824
+ }
825
+ m = { interactiveMessage };
826
+ }
461
827
  if ('viewOnce' in message && !!message.viewOnce) {
462
828
  m = { viewOnceMessage: { message: m } };
463
829
  }
464
- if ('mentions' in message && ((_a = message.mentions) === null || _a === void 0 ? void 0 : _a.length)) {
830
+ if ('mentions' in message && ((_o = message.mentions) === null || _o === void 0 ? void 0 : _o.length)) {
465
831
  const [messageType] = Object.keys(m);
466
832
  m[messageType].contextInfo = m[messageType] || {};
467
833
  m[messageType].contextInfo.mentionedJid = message.mentions;
@@ -485,8 +851,8 @@ const generateWAMessageContent = async (message, options) => {
485
851
  };
486
852
  exports.generateWAMessageContent = generateWAMessageContent;
487
853
  const generateWAMessageFromContent = (jid, message, options) => {
488
- // set timestamp to now
489
- // if not specified
854
+
855
+
490
856
  if (!options.timestamp) {
491
857
  options.timestamp = new Date();
492
858
  }
@@ -494,36 +860,39 @@ const generateWAMessageFromContent = (jid, message, options) => {
494
860
  const key = (0, exports.getContentType)(innerMessage);
495
861
  const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp);
496
862
  const { quoted, userJid } = options;
497
- if (quoted && !(0, WABinary_1.isJidNewsLetter)(jid)) {
863
+
864
+ if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
498
865
  const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid);
499
866
  let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message);
500
867
  const msgType = (0, exports.getContentType)(quotedMsg);
501
- // strip any redundant properties
502
- quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
503
- const quotedContent = quotedMsg[msgType];
504
- if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
505
- delete quotedContent.contextInfo;
506
- }
507
- const contextInfo = innerMessage[key].contextInfo || {};
508
- contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
509
- contextInfo.stanzaId = quoted.key.id;
510
- contextInfo.quotedMessage = quotedMsg;
511
- // if a participant is quoted, then it must be a group
512
- // hence, remoteJid of group must also be entered
513
- if (jid !== quoted.key.remoteJid) {
514
- contextInfo.remoteJid = quoted.key.remoteJid;
515
- }
516
- innerMessage[key].contextInfo = contextInfo;
868
+
869
+ if (quotedMsg) {
870
+ quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
871
+ const quotedContent = quotedMsg[msgType];
872
+ if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
873
+ delete quotedContent.contextInfo;
874
+ }
875
+ const contextInfo = innerMessage[key].contextInfo || {};
876
+ contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
877
+ contextInfo.stanzaId = quoted.key.id;
878
+ contextInfo.quotedMessage = quotedMsg;
879
+
880
+
881
+ if (jid !== quoted.key.remoteJid) {
882
+ contextInfo.remoteJid = quoted.key.remoteJid;
883
+ }
884
+ innerMessage[key].contextInfo = contextInfo;
885
+ }
517
886
  }
518
887
  if (
519
- // if we want to send a disappearing message
888
+
520
889
  !!(options === null || options === void 0 ? void 0 : options.ephemeralExpiration) &&
521
- // and it's not a protocol message -- delete, toggle disappear message
890
+
522
891
  key !== 'protocolMessage' &&
523
- // already not converted to disappearing message
892
+
524
893
  key !== 'ephemeralMessage' &&
525
- // newsletter not accept disappearing messages
526
- !(0, WABinary_1.isJidNewsLetter)(jid)) {
894
+
895
+ !(0, WABinary_1.isJidNewsletter)(jid)) {
527
896
  innerMessage[key].contextInfo = {
528
897
  ...(innerMessage[key].contextInfo || {}),
529
898
  expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL,
@@ -535,7 +904,7 @@ const generateWAMessageFromContent = (jid, message, options) => {
535
904
  key: {
536
905
  remoteJid: jid,
537
906
  fromMe: true,
538
- id: (options === null || options === void 0 ? void 0 : options.messageId) || (0, generics_1.generateMessageID)(),
907
+ id: (options === null || options === void 0 ? void 0 : options.messageId) || (0, generics_1.generateMessageIDV2)(),
539
908
  },
540
909
  message: message,
541
910
  messageTimestamp: timestamp,
@@ -548,9 +917,9 @@ const generateWAMessageFromContent = (jid, message, options) => {
548
917
  exports.generateWAMessageFromContent = generateWAMessageFromContent;
549
918
  const generateWAMessage = async (jid, content, options) => {
550
919
  var _a;
551
- // ensure msg ID is with every log
920
+
552
921
  options.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) === null || _a === void 0 ? void 0 : _a.child({ msgId: options.messageId });
553
- return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsLetter)(jid), ...options }), options);
922
+ return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsletter)(jid), ...options }), options);
554
923
  };
555
924
  exports.generateWAMessage = generateWAMessage;
556
925
  /** Get the key to access the true type of content */
@@ -572,7 +941,7 @@ const normalizeMessageContent = (content) => {
572
941
  if (!content) {
573
942
  return undefined;
574
943
  }
575
- // set max iterations to prevent an infinite loop
944
+
576
945
  for (let i = 0; i < 5; i++) {
577
946
  const inner = getFutureProofMessage(content);
578
947
  if (!inner) {
@@ -587,7 +956,24 @@ const normalizeMessageContent = (content) => {
587
956
  || (message === null || message === void 0 ? void 0 : message.documentWithCaptionMessage)
588
957
  || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2)
589
958
  || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension)
590
- || (message === null || message === void 0 ? void 0 : message.editedMessage));
959
+ || (message === null || message === void 0 ? void 0 : message.editedMessage)
960
+ || (message === null || message === void 0 ? void 0 : message.groupMentionedMessage)
961
+ || (message === null || message === void 0 ? void 0 : message.botInvokeMessage)
962
+ || (message === null || message === void 0 ? void 0 : message.lottieStickerMessage)
963
+ || (message === null || message === void 0 ? void 0 : message.eventCoverImage)
964
+ || (message === null || message === void 0 ? void 0 : message.statusMentionMessage)
965
+ || (message === null || message === void 0 ? void 0 : message.pollCreationOptionImageMessage)
966
+ || (message === null || message === void 0 ? void 0 : message.associatedChildMessage)
967
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMentionMessage)
968
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV4)
969
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV5)
970
+ || (message === null || message === void 0 ? void 0 : message.statusAddYours)
971
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMessage)
972
+ || (message === null || message === void 0 ? void 0 : message.limitSharingMessage)
973
+ || (message === null || message === void 0 ? void 0 : message.botTaskMessage)
974
+ || (message === null || message === void 0 ? void 0 : message.questionMessage)
975
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMessageV2)
976
+ || (message === null || message === void 0 ? void 0 : message.botForwardedMessage));
591
977
  }
592
978
  };
593
979
  exports.normalizeMessageContent = normalizeMessageContent;
@@ -637,7 +1023,11 @@ exports.extractMessageContent = extractMessageContent;
637
1023
  /**
638
1024
  * Returns the device predicted by message ID
639
1025
  */
640
- const getDevice = (id) => /^3A.{18}$/.test(id) ? 'ios' : /^3E.{20}$/.test(id) ? 'web' : /^(.{21}|.{32})$/.test(id) ? 'android' : /^.{18}$/.test(id) ? 'desktop' : 'unknown';
1026
+ const getDevice = (id) => /^3A.{18}$/.test(id) ? 'ios' :
1027
+ /^3E.{20}$/.test(id) ? 'web' :
1028
+ /^(.{21}|.{32})$/.test(id) ? 'android' :
1029
+ /^(3F|.{18}$)/.test(id) ? 'desktop' :
1030
+ 'unknown';
641
1031
  exports.getDevice = getDevice;
642
1032
  /** Upserts a receipt in the message */
643
1033
  const updateMessageWithReceipt = (msg, receipt) => {
@@ -656,9 +1046,8 @@ const updateMessageWithReaction = (msg, reaction) => {
656
1046
  const authorID = (0, generics_1.getKeyAuthor)(reaction.key);
657
1047
  const reactions = (msg.reactions || [])
658
1048
  .filter(r => (0, generics_1.getKeyAuthor)(r.key) !== authorID);
659
- if (reaction.text) {
660
- reactions.push(reaction);
661
- }
1049
+ reaction.text = reaction.text || '';
1050
+ reactions.push(reaction);
662
1051
  msg.reactions = reactions;
663
1052
  };
664
1053
  exports.updateMessageWithReaction = updateMessageWithReaction;
@@ -711,7 +1100,6 @@ function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
711
1100
  }
712
1101
  return Object.values(voteHashMap);
713
1102
  }
714
- exports.getAggregateVotesInPollMessage = getAggregateVotesInPollMessage;
715
1103
  /** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
716
1104
  const aggregateMessageKeysNotFromMe = (keys) => {
717
1105
  const keyMap = {};
@@ -741,10 +1129,10 @@ const downloadMediaMessage = async (message, type, options, ctx) => {
741
1129
  var _a;
742
1130
  if (ctx) {
743
1131
  if (axios_1.default.isAxiosError(error)) {
744
- // check if the message requires a reupload
1132
+
745
1133
  if (REUPLOAD_REQUIRED_STATUS.includes((_a = error.response) === null || _a === void 0 ? void 0 : _a.status)) {
746
1134
  ctx.logger.info({ key: message.key }, 'sending reupload media request...');
747
- // request reupload
1135
+
748
1136
  message = await ctx.reuploadRequest(message);
749
1137
  const result = await downloadMsg();
750
1138
  return result;
@@ -802,3 +1190,22 @@ const assertMediaContent = (content) => {
802
1190
  return mediaContent;
803
1191
  };
804
1192
  exports.assertMediaContent = assertMediaContent;
1193
+
1194
+ const toJid = (id) => {
1195
+ if (!id)
1196
+ return '';
1197
+ if (id.endsWith('@lid'))
1198
+ return id.replace('@lid', '@s.whatsapp.net');
1199
+ if (id.includes('@'))
1200
+ return id;
1201
+ return `${id}@s.whatsapp.net`;
1202
+ };
1203
+ exports.toJid = toJid;
1204
+ const getSenderLid = (message) => {
1205
+ const sender = message.key.participant || message.key.remoteJid;
1206
+ const user = (0, WABinary_1.jidDecode)(sender)?.user || '';
1207
+ const lid = (0, WABinary_1.jidEncode)(user, 'lid');
1208
+ console.log('sender lid:', lid);
1209
+ return { jid: sender, lid };
1210
+ };
1211
+ exports.getSenderLid = getSenderLid;