@gqb333/based 2.7.71

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 (201) hide show
  1. package/LICENSE +58 -0
  2. package/README.MD +611 -0
  3. package/WAProto/GenerateStatics.sh +4 -0
  4. package/WAProto/WAProto.proto +5604 -0
  5. package/WAProto/index.d.ts +63156 -0
  6. package/WAProto/index.js +195638 -0
  7. package/WAProto/p.html +1 -0
  8. package/engine-requirements.js +10 -0
  9. package/lib/Defaults/baileys-version.json +3 -0
  10. package/lib/Defaults/index.d.ts +53 -0
  11. package/lib/Defaults/index.js +108 -0
  12. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  13. package/lib/Signal/Group/ciphertext-message.js +15 -0
  14. package/lib/Signal/Group/group-session-builder.d.ts +14 -0
  15. package/lib/Signal/Group/group-session-builder.js +64 -0
  16. package/lib/Signal/Group/group_cipher.d.ts +17 -0
  17. package/lib/Signal/Group/group_cipher.js +96 -0
  18. package/lib/Signal/Group/index.d.ts +11 -0
  19. package/lib/Signal/Group/index.js +57 -0
  20. package/lib/Signal/Group/keyhelper.d.ts +10 -0
  21. package/lib/Signal/Group/keyhelper.js +55 -0
  22. package/lib/Signal/Group/queue-job.d.ts +1 -0
  23. package/lib/Signal/Group/queue-job.js +57 -0
  24. package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
  25. package/lib/Signal/Group/sender-chain-key.js +34 -0
  26. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
  27. package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
  28. package/lib/Signal/Group/sender-key-message.d.ts +18 -0
  29. package/lib/Signal/Group/sender-key-message.js +69 -0
  30. package/lib/Signal/Group/sender-key-name.d.ts +17 -0
  31. package/lib/Signal/Group/sender-key-name.js +51 -0
  32. package/lib/Signal/Group/sender-key-record.d.ts +30 -0
  33. package/lib/Signal/Group/sender-key-record.js +53 -0
  34. package/lib/Signal/Group/sender-key-state.d.ts +38 -0
  35. package/lib/Signal/Group/sender-key-state.js +99 -0
  36. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  37. package/lib/Signal/Group/sender-message-key.js +29 -0
  38. package/lib/Signal/libsignal.d.ts +3 -0
  39. package/lib/Signal/libsignal.js +174 -0
  40. package/lib/Socket/Client/index.d.ts +2 -0
  41. package/lib/Socket/Client/index.js +18 -0
  42. package/lib/Socket/Client/types.d.ts +16 -0
  43. package/lib/Socket/Client/types.js +13 -0
  44. package/lib/Socket/Client/websocket.d.ts +13 -0
  45. package/lib/Socket/Client/websocket.js +111 -0
  46. package/lib/Socket/business.d.ts +172 -0
  47. package/lib/Socket/business.js +260 -0
  48. package/lib/Socket/chats.d.ts +85 -0
  49. package/lib/Socket/chats.js +1094 -0
  50. package/lib/Socket/groups.d.ts +124 -0
  51. package/lib/Socket/groups.js +423 -0
  52. package/lib/Socket/index.d.ts +172 -0
  53. package/lib/Socket/index.js +32 -0
  54. package/lib/Socket/messages-interactive.js +259 -0
  55. package/lib/Socket/messages-recv.d.ts +161 -0
  56. package/lib/Socket/messages-recv.js +1474 -0
  57. package/lib/Socket/messages-send.d.ts +151 -0
  58. package/lib/Socket/messages-send.js +1085 -0
  59. package/lib/Socket/newsletter.d.ts +136 -0
  60. package/lib/Socket/newsletter.js +250 -0
  61. package/lib/Socket/socket.d.ts +43 -0
  62. package/lib/Socket/socket.js +1241 -0
  63. package/lib/Socket/usync.d.ts +36 -0
  64. package/lib/Socket/usync.js +123 -0
  65. package/lib/Store/index.d.ts +2 -0
  66. package/lib/Store/index.js +8 -0
  67. package/lib/Store/make-in-memory-store.d.ts +118 -0
  68. package/lib/Store/make-in-memory-store.js +452 -0
  69. package/lib/Store/make-ordered-dictionary.d.ts +13 -0
  70. package/lib/Store/make-ordered-dictionary.js +81 -0
  71. package/lib/Store/object-repository.d.ts +10 -0
  72. package/lib/Store/object-repository.js +27 -0
  73. package/lib/Types/Auth.d.ts +114 -0
  74. package/lib/Types/Auth.js +2 -0
  75. package/lib/Types/Call.d.ts +13 -0
  76. package/lib/Types/Call.js +2 -0
  77. package/lib/Types/Chat.d.ts +109 -0
  78. package/lib/Types/Chat.js +4 -0
  79. package/lib/Types/Contact.d.ts +29 -0
  80. package/lib/Types/Contact.js +2 -0
  81. package/lib/Types/Events.d.ts +199 -0
  82. package/lib/Types/Events.js +2 -0
  83. package/lib/Types/GroupMetadata.d.ts +64 -0
  84. package/lib/Types/GroupMetadata.js +2 -0
  85. package/lib/Types/Label.d.ts +35 -0
  86. package/lib/Types/Label.js +27 -0
  87. package/lib/Types/LabelAssociation.d.ts +29 -0
  88. package/lib/Types/LabelAssociation.js +9 -0
  89. package/lib/Types/Message.d.ts +740 -0
  90. package/lib/Types/Message.js +7 -0
  91. package/lib/Types/Newsletter.d.ts +22 -0
  92. package/lib/Types/Newsletter.js +18 -0
  93. package/lib/Types/Product.d.ts +78 -0
  94. package/lib/Types/Product.js +2 -0
  95. package/lib/Types/Signal.d.ts +63 -0
  96. package/lib/Types/Signal.js +2 -0
  97. package/lib/Types/Socket.d.ts +134 -0
  98. package/lib/Types/Socket.js +2 -0
  99. package/lib/Types/State.d.ts +27 -0
  100. package/lib/Types/State.js +2 -0
  101. package/lib/Types/USync.d.ts +25 -0
  102. package/lib/Types/USync.js +2 -0
  103. package/lib/Types/index.d.ts +65 -0
  104. package/lib/Types/index.js +43 -0
  105. package/lib/Utils/auth-utils.d.ts +18 -0
  106. package/lib/Utils/auth-utils.js +209 -0
  107. package/lib/Utils/baileys-event-stream.d.ts +16 -0
  108. package/lib/Utils/baileys-event-stream.js +63 -0
  109. package/lib/Utils/business.d.ts +22 -0
  110. package/lib/Utils/business.js +234 -0
  111. package/lib/Utils/cache-manager.d.ts +16 -0
  112. package/lib/Utils/cache-manager.js +114 -0
  113. package/lib/Utils/chat-utils.d.ts +70 -0
  114. package/lib/Utils/chat-utils.js +734 -0
  115. package/lib/Utils/crypto.d.ts +40 -0
  116. package/lib/Utils/crypto.js +193 -0
  117. package/lib/Utils/decode-wa-message.d.ts +35 -0
  118. package/lib/Utils/decode-wa-message.js +207 -0
  119. package/lib/Utils/event-buffer.d.ts +35 -0
  120. package/lib/Utils/event-buffer.js +619 -0
  121. package/lib/Utils/generics.d.ts +89 -0
  122. package/lib/Utils/generics.js +440 -0
  123. package/lib/Utils/history.d.ts +19 -0
  124. package/lib/Utils/history.js +94 -0
  125. package/lib/Utils/index.d.ts +22 -0
  126. package/lib/Utils/index.js +38 -0
  127. package/lib/Utils/jid-validation.d.ts +2 -0
  128. package/lib/Utils/jid-validation.js +186 -0
  129. package/lib/Utils/link-preview.d.ts +21 -0
  130. package/lib/Utils/link-preview.js +152 -0
  131. package/lib/Utils/logger.d.ts +11 -0
  132. package/lib/Utils/logger.js +59 -0
  133. package/lib/Utils/lt-hash.d.ts +12 -0
  134. package/lib/Utils/lt-hash.js +51 -0
  135. package/lib/Utils/make-mutex.d.ts +7 -0
  136. package/lib/Utils/make-mutex.js +43 -0
  137. package/lib/Utils/messages-media.d.ts +120 -0
  138. package/lib/Utils/messages-media.js +848 -0
  139. package/lib/Utils/messages.d.ts +131 -0
  140. package/lib/Utils/messages.js +1793 -0
  141. package/lib/Utils/newsletter-utils.d.ts +2 -0
  142. package/lib/Utils/newsletter-utils.js +48 -0
  143. package/lib/Utils/noise-handler.d.ts +19 -0
  144. package/lib/Utils/noise-handler.js +150 -0
  145. package/lib/Utils/performance-config.d.ts +70 -0
  146. package/lib/Utils/performance-config.js +183 -0
  147. package/lib/Utils/process-message.d.ts +42 -0
  148. package/lib/Utils/process-message.js +498 -0
  149. package/lib/Utils/rate-limiter.js +90 -0
  150. package/lib/Utils/retry.js +66 -0
  151. package/lib/Utils/signal.d.ts +33 -0
  152. package/lib/Utils/signal.js +153 -0
  153. package/lib/Utils/use-multi-file-auth-state.d.ts +12 -0
  154. package/lib/Utils/use-multi-file-auth-state.js +129 -0
  155. package/lib/Utils/validate-connection.d.ts +10 -0
  156. package/lib/Utils/validate-connection.js +233 -0
  157. package/lib/WABinary/constants.d.ts +27 -0
  158. package/lib/WABinary/constants.js +1303 -0
  159. package/lib/WABinary/decode.d.ts +6 -0
  160. package/lib/WABinary/decode.js +279 -0
  161. package/lib/WABinary/encode.d.ts +2 -0
  162. package/lib/WABinary/encode.js +264 -0
  163. package/lib/WABinary/generic-utils.d.ts +14 -0
  164. package/lib/WABinary/generic-utils.js +114 -0
  165. package/lib/WABinary/index.d.ts +5 -0
  166. package/lib/WABinary/index.js +21 -0
  167. package/lib/WABinary/jid-utils.d.ts +38 -0
  168. package/lib/WABinary/jid-utils.js +485 -0
  169. package/lib/WABinary/types.d.ts +18 -0
  170. package/lib/WABinary/types.js +2 -0
  171. package/lib/WAM/BinaryInfo.d.ts +8 -0
  172. package/lib/WAM/BinaryInfo.js +13 -0
  173. package/lib/WAM/constants.d.ts +38 -0
  174. package/lib/WAM/constants.js +15350 -0
  175. package/lib/WAM/encode.d.ts +2 -0
  176. package/lib/WAM/encode.js +155 -0
  177. package/lib/WAM/index.d.ts +3 -0
  178. package/lib/WAM/index.js +19 -0
  179. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
  180. package/lib/WAUSync/Protocols/USyncContactProtocol.js +102 -0
  181. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
  182. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +110 -0
  183. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  184. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
  185. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  186. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  187. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +25 -0
  188. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +53 -0
  189. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +8 -0
  190. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -0
  191. package/lib/WAUSync/Protocols/index.d.ts +4 -0
  192. package/lib/WAUSync/Protocols/index.js +20 -0
  193. package/lib/WAUSync/USyncQuery.d.ts +28 -0
  194. package/lib/WAUSync/USyncQuery.js +147 -0
  195. package/lib/WAUSync/USyncUser.d.ts +12 -0
  196. package/lib/WAUSync/USyncUser.js +26 -0
  197. package/lib/WAUSync/index.d.ts +3 -0
  198. package/lib/WAUSync/index.js +19 -0
  199. package/lib/index.d.ts +17 -0
  200. package/lib/index.js +53 -0
  201. package/package.json +104 -0
@@ -0,0 +1,1793 @@
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.clearCache = exports.getCacheStats = 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");
19
+ const MIMETYPE_MAP = {
20
+ image: 'image/jpeg',
21
+ video: 'video/mp4',
22
+ document: 'application/pdf',
23
+ audio: 'audio/ogg; codecs=opus',
24
+ sticker: 'image/webp',
25
+ 'product-catalog-image': 'image/jpeg',
26
+ };
27
+ 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,
33
+ };
34
+ const ButtonType = WAProto_1.proto.Message.ButtonsMessage.HeaderType;
35
+ /**
36
+ * Uses a regex to test whether the string contains a URL, and returns the URL if it does.
37
+ * @param text eg. hello https://google.com
38
+ * @returns the URL, eg. https://google.com
39
+ */
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);
44
+ if (!!getUrlInfo && url) {
45
+ try {
46
+ const urlInfo = await getUrlInfo(url);
47
+ return urlInfo;
48
+ }
49
+ catch (error) { // ignore if fails
50
+ logger === null || logger === void 0 ? void 0 : logger.warn({ trace: error.stack }, 'url generation failed');
51
+ }
52
+ }
53
+ };
54
+ exports.generateLinkPreviewIfRequired = generateLinkPreviewIfRequired;
55
+ const assertColor = async (color) => {
56
+ let assertedColor;
57
+ if (typeof color === 'number') {
58
+ assertedColor = color > 0 ? color : 0xffffffff + Number(color) + 1;
59
+ return assertedColor;
60
+ }
61
+ else {
62
+ let hex = color.trim().replace('#', '');
63
+ if (hex.length <= 6) {
64
+ hex = 'FF' + hex.padStart(6, '0');
65
+ }
66
+ assertedColor = parseInt(hex, 16);
67
+ return assertedColor;
68
+ }
69
+ };
70
+ const prepareWAMessageMedia = async (message, options) => {
71
+ const logger = options.logger;
72
+ let mediaType;
73
+ for (const key of Defaults_1.MEDIA_KEYS) {
74
+ if (key in message) {
75
+ mediaType = key;
76
+ }
77
+ }
78
+ if (!mediaType) {
79
+ throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
80
+ }
81
+ const uploadData = {
82
+ ...message,
83
+ media: message[mediaType]
84
+ };
85
+ delete uploadData[mediaType];
86
+ // check if cacheable + generate cache key
87
+ const cacheableKey = typeof uploadData.media === 'object' &&
88
+ ('url' in uploadData.media) &&
89
+ !!uploadData.media.url &&
90
+ !!options.mediaCache && (
91
+ // generate the key
92
+ mediaType + ':' + uploadData.media.url.toString());
93
+ if (mediaType === 'document' && !uploadData.fileName) {
94
+ uploadData.fileName = 'file';
95
+ }
96
+ if (!uploadData.mimetype) {
97
+ uploadData.mimetype = MIMETYPE_MAP[mediaType];
98
+ }
99
+ // check for cache hit
100
+ if (cacheableKey) {
101
+ const mediaBuff = options.mediaCache.get(cacheableKey);
102
+ if (mediaBuff) {
103
+ logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'got media cache hit');
104
+ const obj = Types_1.WAProto.Message.decode(mediaBuff);
105
+ const key = `${mediaType}Message`;
106
+ Object.assign(obj[key], { ...uploadData, media: undefined });
107
+ return obj;
108
+ }
109
+ }
110
+ const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
111
+ const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') &&
112
+ (typeof uploadData['jpegThumbnail'] === 'undefined');
113
+ const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
114
+ const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
115
+ const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
116
+ const { mediaKey, encWriteStream, bodyPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, } = await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
117
+ logger,
118
+ saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
119
+ opts: options.options
120
+ });
121
+ const fileEncSha256B64 = (options.newsletter ? fileSha256 : fileEncSha256 !== null && fileEncSha256 !== void 0 ? fileEncSha256 : fileSha256).toString('base64');
122
+ const [{ mediaUrl, directPath, handle }] = await Promise.all([
123
+ (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');
126
+ return result;
127
+ })(),
128
+ (async () => {
129
+ try {
130
+ if (requiresThumbnailComputation) {
131
+ const { thumbnail, originalImageDimensions } = await (0, messages_media_1.generateThumbnail)(bodyPath, mediaType, options);
132
+ uploadData.jpegThumbnail = thumbnail;
133
+ if (!uploadData.width && originalImageDimensions) {
134
+ uploadData.width = originalImageDimensions.width;
135
+ uploadData.height = originalImageDimensions.height;
136
+ logger === null || logger === void 0 ? void 0 : logger.debug('set dimensions');
137
+ }
138
+ logger === null || logger === void 0 ? void 0 : logger.debug('generated thumbnail');
139
+ }
140
+ 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');
143
+ }
144
+ 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');
147
+ }
148
+ if (requiresAudioBackground) {
149
+ uploadData.backgroundArgb = await assertColor(options.backgroundColor);
150
+ logger === null || logger === void 0 ? void 0 : logger.debug('computed backgroundColor audio status');
151
+ }
152
+ }
153
+ 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');
168
+ }
169
+ catch (error) {
170
+ logger === null || logger === void 0 ? void 0 : logger.warn('failed to remove tmp file');
171
+ }
172
+ }
173
+ });
174
+ const obj = Types_1.WAProto.Message.fromObject({
175
+ [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
176
+ url: handle ? undefined : mediaUrl,
177
+ directPath,
178
+ mediaKey: mediaKey,
179
+ fileEncSha256: fileEncSha256,
180
+ fileSha256,
181
+ fileLength,
182
+ mediaKeyTimestamp: handle ? undefined : (0, generics_1.unixTimestampSeconds)(),
183
+ ...uploadData,
184
+ media: undefined
185
+ })
186
+ });
187
+ if (uploadData.ptv) {
188
+ obj.ptvMessage = obj.videoMessage;
189
+ delete obj.videoMessage;
190
+ }
191
+ 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());
194
+ }
195
+ return obj;
196
+ };
197
+ exports.prepareWAMessageMedia = prepareWAMessageMedia;
198
+ const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
199
+ ephemeralExpiration = ephemeralExpiration || 0;
200
+ const content = {
201
+ ephemeralMessage: {
202
+ message: {
203
+ protocolMessage: {
204
+ type: Types_1.WAProto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
205
+ ephemeralExpiration
206
+ }
207
+ }
208
+ }
209
+ };
210
+ return Types_1.WAProto.Message.fromObject(content);
211
+ };
212
+ exports.prepareDisappearingMessageSettingContent = prepareDisappearingMessageSettingContent;
213
+ /**
214
+ * Generate forwarded message content like WA does
215
+ * @param message the message to forward
216
+ * @param options.forceForward will show the message as forwarded even if it is from you
217
+ */
218
+ const generateForwardMessageContent = (message, forceForward) => {
219
+ var _a;
220
+ let content = message.message;
221
+ if (!content) {
222
+ throw new boom_1.Boom('no content in message', { statusCode: 400 });
223
+ }
224
+ // hacky copy
225
+ content = (0, exports.normalizeMessageContent)(content);
226
+ content = WAProto_1.proto.Message.decode(WAProto_1.proto.Message.encode(content).finish());
227
+ let key = Object.keys(content)[0];
228
+ let score = ((_a = content[key].contextInfo) === null || _a === void 0 ? void 0 : _a.forwardingScore) || 0;
229
+ score += message.key.fromMe && !forceForward ? 0 : 1;
230
+ if (key === 'conversation') {
231
+ content.extendedTextMessage = { text: content[key] };
232
+ delete content.conversation;
233
+ key = 'extendedTextMessage';
234
+ }
235
+ if (score > 0) {
236
+ content[key].contextInfo = { forwardingScore: score, isForwarded: true };
237
+ }
238
+ else {
239
+ content[key].contextInfo = {};
240
+ }
241
+ return content;
242
+ };
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;
247
+
248
+ // Cross-platform externalAdReply thumbnail handling
249
+ const fixupExternalAdReplyThumb = async (externalAdReply) => {
250
+ const thumbUrl = externalAdReply.originalImageUrl || externalAdReply.thumbnailUrl;
251
+ const currentThumb = externalAdReply.thumbnail;
252
+ const currentThumbLen = currentThumb && typeof currentThumb.length === 'number' ? currentThumb.length : 0;
253
+ if (thumbUrl && (!currentThumb || currentThumbLen < 2000)) {
254
+ try {
255
+ const stream = await (0, messages_media_1.getHttpStream)(thumbUrl, {
256
+ timeout: 8000,
257
+ headers: {
258
+ 'User-Agent': 'WhatsApp/2.23.20.15 iOS/16.0 Device/iPhone'
259
+ }
260
+ });
261
+ const { buffer } = await (0, messages_media_1.extractImageThumb)(stream, 512, 80);
262
+ externalAdReply.thumbnail = buffer;
263
+ }
264
+ catch (error) {
265
+ options.logger?.warn('Failed to generate externalAdReply thumbnail for cross-platform compatibility:', error.message);
266
+ }
267
+ }
268
+ if (externalAdReply.renderLargerThumbnail === undefined) {
269
+ externalAdReply.renderLargerThumbnail = true;
270
+ }
271
+ return externalAdReply;
272
+ };
273
+ if (message.contextInfo?.externalAdReply) {
274
+ message.contextInfo.externalAdReply = await fixupExternalAdReplyThumb(message.contextInfo.externalAdReply);
275
+ }
276
+ if (message.externalAdReply) {
277
+ message.externalAdReply = await fixupExternalAdReplyThumb(message.externalAdReply);
278
+ }
279
+
280
+ let m = {};
281
+ if ('text' in message) {
282
+ const extContent = { text: message.text };
283
+ let urlInfo = message.linkPreview;
284
+ if (urlInfo === true) {
285
+ urlInfo = await (0, exports.generateLinkPreviewIfRequired)(message.text, options.getUrlInfo, options.logger);
286
+ }
287
+ if (urlInfo && typeof urlInfo === 'object') {
288
+ extContent.matchedText = urlInfo['matched-text'];
289
+ extContent.jpegThumbnail = urlInfo.jpegThumbnail;
290
+ extContent.description = urlInfo.description;
291
+ extContent.title = urlInfo.title;
292
+ extContent.previewType = 0;
293
+ const img = urlInfo.highQualityThumbnail;
294
+ if (img) {
295
+ extContent.thumbnailDirectPath = img.directPath;
296
+ extContent.mediaKey = img.mediaKey;
297
+ extContent.mediaKeyTimestamp = img.mediaKeyTimestamp;
298
+ extContent.thumbnailWidth = img.width;
299
+ extContent.thumbnailHeight = img.height;
300
+ extContent.thumbnailSha256 = img.fileSha256;
301
+ extContent.thumbnailEncSha256 = img.fileEncSha256;
302
+ }
303
+ }
304
+ if (options.backgroundColor) {
305
+ extContent.backgroundArgb = await assertColor(options.backgroundColor);
306
+ }
307
+ if (options.font) {
308
+ extContent.font = options.font;
309
+ }
310
+ m.extendedTextMessage = extContent;
311
+ }
312
+ else if ('contacts' in message) {
313
+ const contactLen = message.contacts.contacts.length;
314
+ if (!contactLen) {
315
+ throw new boom_1.Boom('require atleast 1 contact', { statusCode: 400 });
316
+ }
317
+ if (contactLen === 1) {
318
+ m.contactMessage = Types_1.WAProto.Message.ContactMessage.fromObject(message.contacts.contacts[0]);
319
+ }
320
+ else {
321
+ m.contactsArrayMessage = Types_1.WAProto.Message.ContactsArrayMessage.fromObject(message.contacts);
322
+ }
323
+ }
324
+ else if ('location' in message) {
325
+ m.locationMessage = Types_1.WAProto.Message.LocationMessage.fromObject(message.location);
326
+ }
327
+ else if ('liveLocation' in message) {
328
+ m.liveLocationMessage = Types_1.WAProto.Message.LiveLocationMessage.fromObject(message.liveLocation);
329
+ }
330
+ else if ('react' in message) {
331
+ if (!message.react.senderTimestampMs) {
332
+ message.react.senderTimestampMs = Date.now();
333
+ }
334
+ m.reactionMessage = Types_1.WAProto.Message.ReactionMessage.fromObject(message.react);
335
+ }
336
+ else if ('delete' in message) {
337
+ m.protocolMessage = {
338
+ key: message.delete,
339
+ type: Types_1.WAProto.Message.ProtocolMessage.Type.REVOKE
340
+ };
341
+ }
342
+ else if ('forward' in message) {
343
+ m = (0, exports.generateForwardMessageContent)(message.forward, message.force);
344
+ }
345
+ else if ('disappearingMessagesInChat' in message) {
346
+ const exp = typeof message.disappearingMessagesInChat === 'boolean' ?
347
+ (message.disappearingMessagesInChat ? Defaults_1.WA_DEFAULT_EPHEMERAL : 0) :
348
+ message.disappearingMessagesInChat;
349
+ m = (0, exports.prepareDisappearingMessageSettingContent)(exp);
350
+ }
351
+ else if ('groupInvite' in message) {
352
+ m.groupInviteMessage = {};
353
+ m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
354
+ m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
355
+ m.groupInviteMessage.caption = message.groupInvite.text;
356
+ m.groupInviteMessage.groupJid = message.groupInvite.jid;
357
+ m.groupInviteMessage.groupName = message.groupInvite.subject;
358
+
359
+ // Get group metadata to obtain disappearing mode and other group info
360
+ if (options.groupMetadata) {
361
+ try {
362
+ const groupMetadata = await options.groupMetadata(message.groupInvite.jid);
363
+ if (groupMetadata) {
364
+ // Add disappearing mode info if available
365
+ if (groupMetadata.ephemeralDuration !== undefined) {
366
+ m.groupInviteMessage.ephemeralDuration = groupMetadata.ephemeralDuration;
367
+ }
368
+ // Add group subject from metadata if not provided in message
369
+ if (!m.groupInviteMessage.groupName && groupMetadata.subject) {
370
+ m.groupInviteMessage.groupName = groupMetadata.subject;
371
+ }
372
+ // Add group participant count
373
+ if (groupMetadata.participants) {
374
+ m.groupInviteMessage.groupSize = groupMetadata.participants.length;
375
+ }
376
+ }
377
+ } catch (error) {
378
+ options.logger?.debug({ error, jid: message.groupInvite.jid }, 'Failed to fetch group metadata for invite');
379
+ }
380
+ }
381
+
382
+ // Handle profile picture with caching
383
+ if (options.getProfilePicUrl) {
384
+ const cacheKey = `group_pfp:${message.groupInvite.jid}`;
385
+
386
+ // Check cache first if available
387
+ if (options.cache && options.cache.get) {
388
+ const cachedPfp = options.cache.get(cacheKey);
389
+ if (cachedPfp) {
390
+ m.groupInviteMessage.jpegThumbnail = cachedPfp;
391
+ }
392
+ }
393
+
394
+ // Fetch if not in cache
395
+ if (!m.groupInviteMessage.jpegThumbnail) {
396
+ try {
397
+ const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
398
+ if (pfpUrl) {
399
+ const resp = await axios_1.default.get(pfpUrl, {
400
+ responseType: 'arraybuffer',
401
+ timeout: 5000,
402
+ headers: {
403
+ 'User-Agent': 'WhatsApp/2.23.20.15 iOS/16.0 Device/iPhone'
404
+ }
405
+ });
406
+ if (resp.status === 200) {
407
+ m.groupInviteMessage.jpegThumbnail = resp.data;
408
+
409
+ // Cache the result if cache is available
410
+ if (options.cache && options.cache.set) {
411
+ options.cache.set(cacheKey, resp.data, 3600); // Cache for 1 hour
412
+ }
413
+ }
414
+ }
415
+ } catch (error) {
416
+ options.logger?.debug({ error, jid: message.groupInvite.jid }, 'Failed to fetch group profile picture');
417
+ }
418
+ }
419
+ }
420
+ }
421
+ else if ('pin' in message) {
422
+ const pinData = typeof message.pin === 'object' ? message.pin : { key: message.pin };
423
+ // Map type: 1 = PIN_FOR_ALL, 2 = UNPIN_FOR_ALL
424
+ const pinType = pinData.type !== undefined ? pinData.type : (message.type !== undefined ? message.type : WAProto_1.proto.Message.PinInChatMessage.Type.PIN_FOR_ALL);
425
+ m.pinInChatMessage = {
426
+ key: pinData.key,
427
+ type: pinType,
428
+ senderTimestampMs: Date.now()
429
+ };
430
+ // Add messageContextInfo only for PIN (type 1), not for UNPIN (type 2)
431
+ if (pinType === WAProto_1.proto.Message.PinInChatMessage.Type.PIN_FOR_ALL) {
432
+ m.messageContextInfo = {
433
+ messageAddOnDurationInSecs: pinData.time || message.time || 86400, // Default 24 hours
434
+ messageAddOnExpiryType: WAProto_1.proto.MessageContextInfo.MessageAddonExpiryType.STATIC
435
+ };
436
+ }
437
+ }
438
+ else if ('keep' in message) {
439
+ m.keepInChatMessage = {};
440
+ m.keepInChatMessage.key = message.keep;
441
+ m.keepInChatMessage.keepType = message.type;
442
+ m.keepInChatMessage.timestampMs = Date.now();
443
+ }
444
+ else if ('call' in message) {
445
+ const call = message.call;
446
+ if (call && typeof call === 'object' && (
447
+ 'callKey' in call
448
+ || 'conversionSource' in call
449
+ || 'conversionData' in call
450
+ || 'conversionDelaySeconds' in call
451
+ || 'ctwaSignals' in call
452
+ || 'ctwaPayload' in call
453
+ || 'nativeFlowCallButtonPayload' in call
454
+ || 'deeplinkPayload' in call
455
+ )) {
456
+ m.call = WAProto_1.proto.Message.Call.fromObject(call);
457
+ }
458
+ else {
459
+ m = {
460
+ scheduledCallCreationMessage: {
461
+ scheduledTimestampMs: (_a = call === null || call === void 0 ? void 0 : call.time) !== null && _a !== void 0 ? _a : Date.now(),
462
+ callType: (_b = call === null || call === void 0 ? void 0 : call.type) !== null && _b !== void 0 ? _b : 1,
463
+ title: call === null || call === void 0 ? void 0 : call.title
464
+ }
465
+ };
466
+ }
467
+ }
468
+ else if ('paymentInvite' in message) {
469
+ m.paymentInviteMessage = {
470
+ serviceType: message.paymentInvite.type,
471
+ expiryTimestamp: message.paymentInvite.expiry
472
+ };
473
+ }
474
+ else if ('buttonReply' in message) {
475
+ switch (message.type) {
476
+ case 'template':
477
+ m.templateButtonReplyMessage = {
478
+ selectedDisplayText: message.buttonReply.displayText,
479
+ selectedId: message.buttonReply.id,
480
+ selectedIndex: message.buttonReply.index,
481
+ selectedCarouselCardIndex: message.buttonReply.carouselCardIndex
482
+ };
483
+ break;
484
+ case 'plain':
485
+ m.buttonsResponseMessage = {
486
+ selectedButtonId: message.buttonReply.id,
487
+ selectedDisplayText: message.buttonReply.displayText,
488
+ type: WAProto_1.proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT,
489
+ };
490
+ break;
491
+ }
492
+ }
493
+ else if ('ptv' in message && message.ptv) {
494
+ const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
495
+ m.ptvMessage = videoMessage;
496
+ }
497
+ else if ('product' in message) {
498
+ const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
499
+ m.productMessage = Types_1.WAProto.Message.ProductMessage.fromObject({
500
+ ...message,
501
+ product: {
502
+ ...message.product,
503
+ productImage: imageMessage,
504
+ }
505
+ });
506
+ }
507
+ else if ('order' in message) {
508
+ m.orderMessage = Types_1.WAProto.Message.OrderMessage.fromObject({
509
+ orderId: message.order.id,
510
+ thumbnail: message.order.thumbnail,
511
+ itemCount: message.order.itemCount,
512
+ status: message.order.status,
513
+ surface: message.order.surface,
514
+ orderTitle: message.order.title,
515
+ message: message.order.text,
516
+ sellerJid: message.order.seller,
517
+ token: message.order.token,
518
+ totalAmount1000: message.order.amount,
519
+ totalCurrencyCode: message.order.currency
520
+ });
521
+ }
522
+ else if ('listReply' in message) {
523
+ m.listResponseMessage = { ...message.listReply };
524
+ }
525
+ else if ('poll' in message) {
526
+ (_p = message.poll).selectableCount || (_p.selectableCount = 0);
527
+ (_q = message.poll).toAnnouncementGroup || (_q.toAnnouncementGroup = false);
528
+ if (!Array.isArray(message.poll.values)) {
529
+ throw new boom_1.Boom('Invalid poll values', { statusCode: 400 });
530
+ }
531
+ if (message.poll.selectableCount < 0
532
+ || message.poll.selectableCount > message.poll.values.length) {
533
+ throw new boom_1.Boom(`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`, { statusCode: 400 });
534
+ }
535
+ m.messageContextInfo = {
536
+ // encKey
537
+ messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32),
538
+ };
539
+ const pollCreationMessage = {
540
+ name: message.poll.name,
541
+ selectableOptionsCount: message.poll.selectableCount,
542
+ options: message.poll.values.map(optionName => ({ optionName })),
543
+ };
544
+ if (message.poll.toAnnouncementGroup) {
545
+ // poll v2 is for community announcement groups (single select and multiple)
546
+ m.pollCreationMessageV2 = pollCreationMessage;
547
+ }
548
+ else {
549
+ if (message.poll.selectableCount === 1) {
550
+ // poll v3 is for single select polls
551
+ m.pollCreationMessageV3 = pollCreationMessage;
552
+ }
553
+ else {
554
+ // poll for multiple choice polls
555
+ m.pollCreationMessage = pollCreationMessage;
556
+ }
557
+ }
558
+ }
559
+ else if ('pollResultSnapshotV3' in message && !!message.pollResultSnapshotV3) {
560
+ m.pollResultSnapshotMessageV3 = {
561
+ pollCreationMessageKey: message.pollResultSnapshotV3.pollCreationMessageKey,
562
+ pollResult: message.pollResultSnapshotV3.pollResult,
563
+ selectedOptions: message.pollResultSnapshotV3.selectedOptions,
564
+ contextInfo: message.pollResultSnapshotV3.contextInfo,
565
+ pollType: message.pollResultSnapshotV3.pollType
566
+ };
567
+ }
568
+ else if ('pollV4' in message) {
569
+ const pollCreationMessage = {
570
+ name: message.pollV4.name,
571
+ selectableOptionsCount: message.pollV4.selectableCount,
572
+ options: message.pollV4.values.map(optionName => ({ optionName })),
573
+ pollType: message.pollV4.pollType
574
+ };
575
+ m.pollCreationMessageV4 = pollCreationMessage;
576
+ }
577
+ else if ('pollV5' in message) {
578
+ const pollCreationMessage = {
579
+ name: message.pollV5.name,
580
+ selectableOptionsCount: message.pollV5.selectableCount,
581
+ options: message.pollV5.values.map(optionName => ({ optionName })),
582
+ pollType: message.pollV5.pollType
583
+ };
584
+ m.pollCreationMessageV5 = pollCreationMessage;
585
+ }
586
+ else if ('event' in message) {
587
+ m.messageContextInfo = {
588
+ messageSecret: message.event.messageSecret || (0, crypto_1.randomBytes)(32),
589
+ };
590
+ m.eventMessage = { ...message.event };
591
+ }
592
+ else if ('comment' in message) {
593
+ m.commentMessage = {
594
+ message: message.comment.message,
595
+ targetMessageKey: message.comment.targetMessageKey
596
+ };
597
+ }
598
+ else if ('question' in message) {
599
+ m.questionMessage = {
600
+ text: message.question.text,
601
+ contextInfo: message.question.contextInfo
602
+ };
603
+ }
604
+ else if ('questionResponse' in message) {
605
+ m.questionResponseMessage = {
606
+ key: message.questionResponse.key,
607
+ text: message.questionResponse.text
608
+ };
609
+ }
610
+ else if ('statusQuestionAnswer' in message) {
611
+ m.statusQuestionAnswerMessage = {
612
+ key: message.statusQuestionAnswer.key,
613
+ text: message.statusQuestionAnswer.text
614
+ };
615
+ }
616
+ else if ('statusQuoted' in message) {
617
+ m.statusQuotedMessage = {
618
+ type: message.statusQuoted.type,
619
+ text: message.statusQuoted.text,
620
+ thumbnail: message.statusQuoted.thumbnail,
621
+ originalStatusId: message.statusQuoted.originalStatusId
622
+ };
623
+ }
624
+ else if ('statusStickerInteraction' in message) {
625
+ m.statusStickerInteractionMessage = {
626
+ key: message.statusStickerInteraction.key,
627
+ stickerKey: message.statusStickerInteraction.stickerKey,
628
+ type: message.statusStickerInteraction.type
629
+ };
630
+ }
631
+ else if ('richResponse' in message) {
632
+ m.richResponseMessage = WAProto_1.proto.AIRichResponseMessage.fromObject({
633
+ messageType: message.richResponse.messageType !== undefined ? message.richResponse.messageType : 1, // AI_RICH_RESPONSE_TYPE_STANDARD
634
+ submessages: message.richResponse.submessages || [],
635
+ unifiedResponse: message.richResponse.unifiedResponse,
636
+ contextInfo: message.richResponse.contextInfo
637
+ });
638
+ }
639
+ else if ('eventResponse' in message && !!message.eventResponse) {
640
+ m.eventResponseMessage = {
641
+ response: message.eventResponse.response, // GOING = 1, NOT_GOING = 2, MAYBE = 3
642
+ timestampMs: message.eventResponse.timestampMs || Date.now(),
643
+ extraGuestCount: message.eventResponse.extraGuestCount
644
+ };
645
+ }
646
+ else if ('statusMention' in message && !!message.statusMention) {
647
+ m.statusMentionMessage = {
648
+ quotedStatus: message.statusMention.quotedStatus
649
+ };
650
+ }
651
+ else if ('groupStatus' in message && !!message.groupStatus) {
652
+ m.groupStatusMessage = message.groupStatus.message;
653
+ }
654
+ else if ('botTask' in message && !!message.botTask) {
655
+ m.botTaskMessage = message.botTask.message;
656
+ }
657
+ else if ('limitSharing' in message && !!message.limitSharing) {
658
+ m.limitSharingMessage = message.limitSharing.message;
659
+ }
660
+ else if ('statusAddYours' in message && !!message.statusAddYours) {
661
+ m.statusAddYours = message.statusAddYours.message;
662
+ }
663
+ else if ('botForwarded' in message && !!message.botForwarded) {
664
+ m.botForwardedMessage = message.botForwarded.message;
665
+ }
666
+ else if ('eventCoverImage' in message && !!message.eventCoverImage) {
667
+ m.eventCoverImage = message.eventCoverImage.message;
668
+ }
669
+ else if ('stickerPack' in message && !!message.stickerPack) {
670
+ const pack = message.stickerPack;
671
+ const stickerPackMessage = {
672
+ name: pack.name,
673
+ publisher: pack.publisher,
674
+ packDescription: pack.description,
675
+ stickerPackId: pack.stickerPackId || (0, crypto_1.randomBytes)(16).toString('hex'),
676
+ stickerPackOrigin: pack.origin || 2 // USER_CREATED = 2
677
+ };
678
+ // Process cover if provided
679
+ if (pack.cover) {
680
+ const coverMedia = await (0, exports.prepareWAMessageMedia)({ image: pack.cover }, options);
681
+ stickerPackMessage.thumbnailDirectPath = coverMedia.imageMessage.directPath;
682
+ stickerPackMessage.thumbnailSha256 = coverMedia.imageMessage.thumbnailSha256;
683
+ stickerPackMessage.thumbnailEncSha256 = coverMedia.imageMessage.thumbnailEncSha256;
684
+ stickerPackMessage.thumbnailHeight = coverMedia.imageMessage.height;
685
+ stickerPackMessage.thumbnailWidth = coverMedia.imageMessage.width;
686
+ }
687
+ // Process stickers
688
+ if (pack.stickers && pack.stickers.length > 0) {
689
+ const processedStickers = await Promise.all(pack.stickers.map(async (sticker) => {
690
+ const stickerMedia = await (0, exports.prepareWAMessageMedia)({ sticker: sticker.sticker }, options);
691
+ return {
692
+ fileName: sticker.fileName || `sticker_${Date.now()}.webp`,
693
+ isAnimated: sticker.isAnimated || false,
694
+ emojis: sticker.emojis || [],
695
+ accessibilityLabel: sticker.accessibilityLabel,
696
+ isLottie: sticker.isLottie || false,
697
+ mimetype: sticker.mimetype || stickerMedia.stickerMessage.mimetype
698
+ };
699
+ }));
700
+ stickerPackMessage.stickers = processedStickers;
701
+ stickerPackMessage.stickerPackSize = processedStickers.length;
702
+ }
703
+ if (pack.caption) {
704
+ stickerPackMessage.caption = pack.caption;
705
+ }
706
+ m.stickerPackMessage = stickerPackMessage;
707
+ }
708
+ else if ('interactiveResponse' in message && !!message.interactiveResponse) {
709
+ const response = message.interactiveResponse;
710
+ const interactiveResponseMessage = {
711
+ body: {
712
+ text: response.body?.text || '',
713
+ format: response.body?.format || 0 // DEFAULT = 0
714
+ }
715
+ };
716
+ if (response.nativeFlowResponse) {
717
+ interactiveResponseMessage.nativeFlowResponseMessage = {
718
+ name: response.nativeFlowResponse.name,
719
+ paramsJson: response.nativeFlowResponse.paramsJson,
720
+ version: response.nativeFlowResponse.version || 1
721
+ };
722
+ }
723
+ if (response.contextInfo) {
724
+ interactiveResponseMessage.contextInfo = response.contextInfo;
725
+ }
726
+ m.interactiveResponseMessage = interactiveResponseMessage;
727
+ }
728
+ else if ('bCall' in message && !!message.bCall) {
729
+ m.bcallMessage = {
730
+ sessionId: message.bCall.sessionId,
731
+ mediaType: message.bCall.mediaType || 0, // UNKNOWN = 0, AUDIO = 1, VIDEO = 2
732
+ masterKey: message.bCall.masterKey,
733
+ caption: message.bCall.caption
734
+ };
735
+ }
736
+ else if ('callLog' in message && !!message.callLog) {
737
+ m.callLogMesssage = {
738
+ isVideo: message.callLog.isVideo || false,
739
+ callOutcome: message.callLog.callOutcome || 0, // CONNECTED = 0
740
+ durationSecs: message.callLog.durationSecs,
741
+ callType: message.callLog.callType || 0, // REGULAR = 0
742
+ participants: message.callLog.participants || []
743
+ };
744
+ }
745
+ else if ('encComment' in message && !!message.encComment) {
746
+ m.encCommentMessage = {
747
+ targetMessageKey: message.encComment.targetMessageKey,
748
+ encPayload: message.encComment.encPayload,
749
+ encIv: message.encComment.encIv
750
+ };
751
+ }
752
+ else if ('encEventResponse' in message && !!message.encEventResponse) {
753
+ m.encEventResponseMessage = {
754
+ eventCreationMessageKey: message.encEventResponse.eventCreationMessageKey,
755
+ encPayload: message.encEventResponse.encPayload,
756
+ encIv: message.encEventResponse.encIv
757
+ };
758
+ }
759
+ else if ('messageHistoryBundle' in message && !!message.messageHistoryBundle) {
760
+ const bundle = message.messageHistoryBundle;
761
+ const bundleMedia = bundle.media ? await (0, exports.prepareWAMessageMedia)({ document: bundle.media }, options) : null;
762
+ m.messageHistoryBundle = {
763
+ mimetype: bundle.mimetype || 'application/octet-stream',
764
+ fileSha256: bundleMedia?.documentMessage?.fileSha256,
765
+ mediaKey: bundleMedia?.documentMessage?.mediaKey,
766
+ fileEncSha256: bundleMedia?.documentMessage?.fileEncSha256,
767
+ directPath: bundleMedia?.documentMessage?.directPath,
768
+ mediaKeyTimestamp: bundleMedia?.documentMessage?.mediaKeyTimestamp,
769
+ contextInfo: bundle.contextInfo,
770
+ messageHistoryMetadata: bundle.messageHistoryMetadata
771
+ };
772
+ }
773
+ else if ('messageHistoryNotice' in message && !!message.messageHistoryNotice) {
774
+ m.messageHistoryNotice = {
775
+ contextInfo: message.messageHistoryNotice.contextInfo,
776
+ messageHistoryMetadata: message.messageHistoryNotice.messageHistoryMetadata
777
+ };
778
+ }
779
+ else if ('inviteFollower' in message && !!message.inviteFollower) {
780
+ m.newsletterFollowerInviteMessageV2 = {
781
+ newsletterJid: message.inviteFollower.newsletterJid,
782
+ newsletterName: message.inviteFollower.newsletterName,
783
+ jpegThumbnail: message.inviteFollower.thumbnail,
784
+ caption: message.inviteFollower.caption,
785
+ contextInfo: message.inviteFollower.contextInfo
786
+ };
787
+ }
788
+ else if ('placeholder' in message && !!message.placeholder) {
789
+ m.placeholderMessage = {
790
+ type: message.placeholder.type || 0 // MASK_LINKED_DEVICES = 0
791
+ };
792
+ }
793
+ else if ('secretEncrypted' in message && !!message.secretEncrypted) {
794
+ m.secretEncryptedMessage = {
795
+ targetMessageKey: message.secretEncrypted.targetMessageKey,
796
+ encPayload: message.secretEncrypted.encPayload,
797
+ encIv: message.secretEncrypted.encIv,
798
+ secretEncType: message.secretEncrypted.secretEncType || 0 // UNKNOWN = 0, EVENT_EDIT = 1, MESSAGE_EDIT = 2
799
+ };
800
+ }
801
+ else if ('statusNotification' in message && !!message.statusNotification) {
802
+ m.statusNotificationMessage = {
803
+ responseMessageKey: message.statusNotification.responseMessageKey,
804
+ originalMessageKey: message.statusNotification.originalMessageKey,
805
+ type: message.statusNotification.type || 0 // UNKNOWN = 0, STATUS_ADD_YOURS = 1, STATUS_RESHARE = 2, STATUS_QUESTION_ANSWER_RESHARE = 3
806
+ };
807
+ }
808
+ else if ('stickerSyncRMR' in message && !!message.stickerSyncRMR) {
809
+ m.stickerSyncRmrMessage = {
810
+ filehash: message.stickerSyncRMR.filehash || [],
811
+ rmrSource: message.stickerSyncRMR.rmrSource,
812
+ requestTimestamp: message.stickerSyncRMR.requestTimestamp || Date.now()
813
+ };
814
+ }
815
+ else if ('inviteAdmin' in message) {
816
+ m.newsletterAdminInviteMessage = {};
817
+ m.newsletterAdminInviteMessage.inviteExpiration = message.inviteAdmin.inviteExpiration;
818
+ m.newsletterAdminInviteMessage.caption = message.inviteAdmin.text;
819
+ m.newsletterAdminInviteMessage.newsletterJid = message.inviteAdmin.jid;
820
+ m.newsletterAdminInviteMessage.newsletterName = message.inviteAdmin.subject;
821
+ m.newsletterAdminInviteMessage.jpegThumbnail = message.inviteAdmin.thumbnail;
822
+ }
823
+ else if ('requestPayment' in message) {
824
+ const reqPayment = message.requestPayment;
825
+ const sticker = reqPayment.sticker ?
826
+ await (0, exports.prepareWAMessageMedia)({ sticker: reqPayment.sticker }, options)
827
+ : null;
828
+ let notes = {};
829
+ if (reqPayment.sticker) {
830
+ notes = {
831
+ stickerMessage: {
832
+ ...sticker.stickerMessage,
833
+ contextInfo: reqPayment.contextInfo
834
+ }
835
+ };
836
+ }
837
+ else if (reqPayment.note) {
838
+ notes = {
839
+ extendedTextMessage: {
840
+ text: reqPayment.note,
841
+ contextInfo: reqPayment.contextInfo,
842
+ }
843
+ };
844
+ }
845
+ else {
846
+ throw new boom_1.Boom('Invalid media type', { statusCode: 400 });
847
+ }
848
+ m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
849
+ expiryTimestamp: reqPayment.expiryTimestamp || reqPayment.expiry,
850
+ amount1000: reqPayment.amount1000 || reqPayment.amount,
851
+ currencyCodeIso4217: reqPayment.currencyCodeIso4217 || reqPayment.currency,
852
+ requestFrom: reqPayment.requestFrom || reqPayment.from,
853
+ noteMessage: { ...notes },
854
+ background: reqPayment.background,
855
+ // Aggiungi altri parametri se disponibili
856
+ ...reqPayment
857
+ });
858
+
859
+ // Pix adaptation for Brazilian payments
860
+ if (reqPayment.currencyCodeIso4217 === 'BRL' && reqPayment.pixKey) {
861
+ // Embed Pix key in note for dynamic requests
862
+ if (!m.requestPaymentMessage.noteMessage.extendedTextMessage) {
863
+ m.requestPaymentMessage.noteMessage = { extendedTextMessage: { text: '' } };
864
+ }
865
+ m.requestPaymentMessage.noteMessage.extendedTextMessage.text += `\nPix Key: ${reqPayment.pixKey}`;
866
+ }
867
+ }
868
+ else if ('sharePhoneNumber' in message) {
869
+ m.protocolMessage = {
870
+ type: WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
871
+ };
872
+ }
873
+ else if ('requestPhoneNumber' in message) {
874
+ m.requestPhoneNumberMessage = {};
875
+ }
876
+ else if ('newsletterMessage' in message) {
877
+ m.newsletterMessage = Types_1.WAProto.Message.NewsletterMessage.fromObject(message.newsletterMessage);
878
+ }
879
+ else if ('externalAdReply' in message) {
880
+ // Handle sendNyanCat functionality - external ad reply
881
+ const extAdReply = message.externalAdReply;
882
+ m.extendedTextMessage = {
883
+ text: message.text || '',
884
+ contextInfo: {
885
+ externalAdReply: {
886
+ title: extAdReply.title,
887
+ body: extAdReply.body,
888
+ mediaType: extAdReply.mediaType || 1,
889
+ thumbnailUrl: extAdReply.thumbnailUrl,
890
+ thumbnail: extAdReply.thumbnail,
891
+ sourceUrl: extAdReply.sourceUrl,
892
+ showAdAttribution: extAdReply.showAdAttribution || false,
893
+ renderLargerThumbnail: extAdReply.renderLargerThumbnail !== false
894
+ }
895
+ }
896
+ };
897
+ }
898
+ else if ('sendPayment' in message && !!message.sendPayment) {
899
+ const payment = message.sendPayment;
900
+ m.sendPaymentMessage = {
901
+ requestMessageKey: payment.requestMessageKey,
902
+ noteMessage: payment.noteMessage,
903
+ background: payment.background,
904
+ transactionData: payment.transactionData
905
+ };
906
+ }
907
+ else if ('declinePayment' in message && !!message.declinePayment) {
908
+ m.declinePaymentRequestMessage = {
909
+ key: message.declinePayment.key
910
+ };
911
+ }
912
+ else if ('cancelPayment' in message && !!message.cancelPayment) {
913
+ m.cancelPaymentRequestMessage = {
914
+ key: message.cancelPayment.key
915
+ };
916
+ }
917
+ else if ('scheduledCallEdit' in message && !!message.scheduledCallEdit) {
918
+ m.scheduledCallEditMessage = {
919
+ key: message.scheduledCallEdit.key,
920
+ editType: message.scheduledCallEdit.editType || 0 // UNKNOWN = 0, CANCEL = 1
921
+ };
922
+ }
923
+ else if ('pollResultSnapshot' in message && !!message.pollResultSnapshot) {
924
+ m.pollResultSnapshotMessage = {
925
+ name: message.pollResultSnapshot.name,
926
+ pollVotes: message.pollResultSnapshot.pollVotes || [],
927
+ contextInfo: message.pollResultSnapshot.contextInfo,
928
+ pollType: message.pollResultSnapshot.pollType || 0 // POLL = 0, QUIZ = 1
929
+ };
930
+ }
931
+ else if ('pollUpdate' in message && !!message.pollUpdate) {
932
+ m.pollUpdateMessage = {
933
+ pollCreationMessageKey: message.pollUpdate.pollCreationMessageKey,
934
+ vote: message.pollUpdate.vote,
935
+ metadata: message.pollUpdate.metadata,
936
+ senderTimestampMs: message.pollUpdate.senderTimestampMs || Date.now()
937
+ };
938
+ }
939
+ else if ('deviceSent' in message && !!message.deviceSent) {
940
+ const deviceSent = message.deviceSent;
941
+ const innerMessage = await (0, exports.generateWAMessageContent)(deviceSent.message, options);
942
+ m.deviceSentMessage = {
943
+ destinationJid: deviceSent.destinationJid,
944
+ message: innerMessage,
945
+ phash: deviceSent.phash
946
+ };
947
+ }
948
+ else if ('chat' in message && !!message.chat) {
949
+ m.chat = {
950
+ displayName: message.chat.displayName,
951
+ id: message.chat.id
952
+ };
953
+ }
954
+ else if ('payment' in message) {
955
+ // Handle sendPayment functionality
956
+ m.requestPaymentMessage = Types_1.WAProto.Message.RequestPaymentMessage.fromObject({
957
+ currencyCodeIso4217: message.payment.currency || 'EUR',
958
+ amount1000: message.payment.amount1000 || message.payment.amount * 1000,
959
+ requestFrom: message.payment.requestFrom || message.payment.from,
960
+ noteMessage: {
961
+ extendedTextMessage: {
962
+ text: message.payment.text || message.payment.note || '',
963
+ contextInfo: message.payment.contextInfo
964
+ }
965
+ },
966
+ expiryTimestamp: message.payment.expiryTimestamp || message.payment.expiry,
967
+ background: message.payment.background
968
+ });
969
+ }
970
+ else if ('comment' in message) {
971
+ m.commentMessage = {
972
+ message: message.comment.message,
973
+ targetMessageKey: message.comment.targetMessageKey
974
+ };
975
+ }
976
+ else if ('question' in message) {
977
+ m.questionMessage = {
978
+ text: message.question.text,
979
+ contextInfo: message.question.contextInfo
980
+ };
981
+ }
982
+ else if ('questionResponse' in message) {
983
+ m.questionResponseMessage = {
984
+ key: message.questionResponse.key,
985
+ text: message.questionResponse.text
986
+ };
987
+ }
988
+ else if ('statusQuestionAnswer' in message) {
989
+ m.statusQuestionAnswerMessage = {
990
+ key: message.statusQuestionAnswer.key,
991
+ text: message.statusQuestionAnswer.text
992
+ };
993
+ }
994
+ else if ('statusQuoted' in message) {
995
+ m.statusQuotedMessage = {
996
+ type: message.statusQuoted.type,
997
+ text: message.statusQuoted.text,
998
+ thumbnail: message.statusQuoted.thumbnail,
999
+ jid: message.statusQuoted.jid,
1000
+ originalStatusId: message.statusQuoted.originalStatusId
1001
+ };
1002
+ }
1003
+ else if ('statusStickerInteraction' in message) {
1004
+ m.statusStickerInteractionMessage = {
1005
+ key: message.statusStickerInteraction.key,
1006
+ stickerKey: message.statusStickerInteraction.stickerKey,
1007
+ type: message.statusStickerInteraction.type
1008
+ };
1009
+ }
1010
+ else if ('album' in message) {
1011
+ const imageMessages = message.album.filter(item => 'image' in item);
1012
+ const videoMessages = message.album.filter(item => 'video' in item);
1013
+ m.albumMessage = WAProto_1.proto.Message.AlbumMessage.fromObject({
1014
+ expectedImageCount: imageMessages.length,
1015
+ expectedVideoCount: videoMessages.length,
1016
+ });
1017
+ }
1018
+ else {
1019
+ m = await (0, exports.prepareWAMessageMedia)(message, options);
1020
+ }
1021
+ if ('buttons' in message && !!message.buttons) {
1022
+ const buttonsMessage = {
1023
+ buttons: message.buttons.map(b => ({ ...b, type: WAProto_1.proto.Message.ButtonsMessage.Button.Type.RESPONSE }))
1024
+ };
1025
+ if ('text' in message) {
1026
+ buttonsMessage.contentText = message.text;
1027
+ buttonsMessage.headerType = ButtonType.EMPTY;
1028
+ }
1029
+ else {
1030
+ if ('caption' in message) {
1031
+ buttonsMessage.contentText = message.caption;
1032
+ }
1033
+ const type = Object.keys(m)[0].replace('Message', '').toUpperCase();
1034
+ buttonsMessage.headerType = ButtonType[type];
1035
+ Object.assign(buttonsMessage, m);
1036
+ }
1037
+ if ('title' in message && !!message.title) {
1038
+ buttonsMessage.text = message.title,
1039
+ buttonsMessage.headerType = ButtonType.TEXT;
1040
+ }
1041
+ if ('footer' in message && !!message.footer) {
1042
+ buttonsMessage.footerText = message.footer;
1043
+ }
1044
+ if ('contextInfo' in message && !!message.contextInfo) {
1045
+ buttonsMessage.contextInfo = message.contextInfo;
1046
+ }
1047
+ if ('mentions' in message && !!message.mentions) {
1048
+ buttonsMessage.contextInfo = { mentionedJid: message.mentions };
1049
+ }
1050
+ m = { buttonsMessage };
1051
+ }
1052
+ else if ('templateButtons' in message && !!message.templateButtons) {
1053
+ const templateMsg = {
1054
+ hydratedButtons: message.templateButtons
1055
+ };
1056
+ if ('text' in message) {
1057
+ templateMsg.hydratedContentText = message.text;
1058
+ }
1059
+ else if ('caption' in message) {
1060
+ templateMsg.hydratedContentText = message.caption;
1061
+ }
1062
+ if ('footer' in message && !!message.footer) {
1063
+ templateMsg.hydratedFooterText = message.footer;
1064
+ }
1065
+ // Add media to template if present
1066
+ if (m && Object.keys(m).length > 0) {
1067
+ Object.assign(templateMsg, m);
1068
+ }
1069
+ m = {
1070
+ templateMessage: {
1071
+ fourRowTemplate: templateMsg,
1072
+ hydratedTemplate: templateMsg
1073
+ }
1074
+ };
1075
+ }
1076
+ if ('sections' in message && !!message.sections) {
1077
+ const listMessage = {
1078
+ sections: message.sections,
1079
+ buttonText: message.buttonText,
1080
+ title: message.title,
1081
+ footerText: message.footer,
1082
+ description: message.text,
1083
+ listType: WAProto_1.proto.Message.ListMessage.ListType.SINGLE_SELECT
1084
+ };
1085
+ m = { listMessage };
1086
+ }
1087
+ if ('interactiveButtons' in message && !!message.interactiveButtons) {
1088
+ const interactiveMessage = {
1089
+ nativeFlowMessage: Types_1.WAProto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
1090
+ buttons: message.interactiveButtons,
1091
+ messageVersion: 1,
1092
+ })
1093
+ };
1094
+ if ('text' in message) {
1095
+ interactiveMessage.body = {
1096
+ text: message.text
1097
+ };
1098
+ }
1099
+ else if ('caption' in message) {
1100
+ interactiveMessage.body = {
1101
+ text: message.caption
1102
+ };
1103
+ interactiveMessage.header = {
1104
+ title: message.title,
1105
+ subtitle: message.subtitle,
1106
+ hasMediaAttachment: !!(message === null || message === void 0 ? void 0 : message.media),
1107
+ };
1108
+ Object.assign(interactiveMessage.header, m);
1109
+ }
1110
+ if ('footer' in message && !!message.footer) {
1111
+ if (typeof message.footer === 'string') {
1112
+ interactiveMessage.footer = {
1113
+ text: message.footer
1114
+ };
1115
+ } else if (typeof message.footer === 'object' && message.footer.text) {
1116
+ interactiveMessage.footer = {
1117
+ text: message.footer.text,
1118
+ hasMediaAttachment: !!message.footer.audio
1119
+ };
1120
+ if (message.footer.audio) {
1121
+ const audioMedia = await (0, exports.prepareWAMessageMedia)({ audio: message.footer.audio }, options);
1122
+ interactiveMessage.footer.audioMessage = audioMedia.audioMessage;
1123
+ }
1124
+ }
1125
+ }
1126
+ if ('title' in message && !!message.title) {
1127
+ const headerData = {
1128
+ title: message.title,
1129
+ subtitle: message.subtitle,
1130
+ hasMediaAttachment: !!message.media,
1131
+ };
1132
+
1133
+ // Process media attachments for interactive buttons
1134
+ if (message.media) {
1135
+ if (message.media.image) {
1136
+ const mediaMessage = await (0, exports.prepareWAMessageMedia)({ image: message.media.image }, options);
1137
+ if (mediaMessage.imageMessage) {
1138
+ headerData.imageMessage = mediaMessage.imageMessage;
1139
+ }
1140
+ }
1141
+ else if (message.media.video) {
1142
+ const mediaMessage = await (0, exports.prepareWAMessageMedia)({ video: message.media.video }, options);
1143
+ if (mediaMessage.videoMessage) {
1144
+ headerData.videoMessage = mediaMessage.videoMessage;
1145
+ }
1146
+ }
1147
+ else if (message.media.document) {
1148
+ const mediaMessage = await (0, exports.prepareWAMessageMedia)({ document: message.media.document }, options);
1149
+ if (mediaMessage.documentMessage) {
1150
+ headerData.documentMessage = mediaMessage.documentMessage;
1151
+ }
1152
+ }
1153
+ }
1154
+
1155
+ interactiveMessage.header = headerData;
1156
+ // Support for ProductMessage in header
1157
+ if (message.headerProduct) {
1158
+ const productMedia = await (0, exports.prepareWAMessageMedia)({ image: message.headerProduct.productImage }, options);
1159
+ interactiveMessage.header.productMessage = {
1160
+ product: {
1161
+ ...message.headerProduct,
1162
+ productImage: productMedia.imageMessage
1163
+ }
1164
+ };
1165
+ interactiveMessage.header.hasMediaAttachment = true;
1166
+ } else {
1167
+ Object.assign(interactiveMessage.header, m);
1168
+ }
1169
+ }
1170
+ if ('contextInfo' in message && !!message.contextInfo) {
1171
+ interactiveMessage.contextInfo = message.contextInfo;
1172
+ }
1173
+ if ('mentions' in message && !!message.mentions) {
1174
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
1175
+ }
1176
+ m = { interactiveMessage };
1177
+ }
1178
+ if ('shop' in message && !!message.shop) {
1179
+ const interactiveMessage = {
1180
+ shopStorefrontMessage: Types_1.WAProto.Message.InteractiveMessage.ShopMessage.fromObject({
1181
+ surface: message.shop,
1182
+ id: message.id
1183
+ })
1184
+ };
1185
+ if ('text' in message) {
1186
+ interactiveMessage.body = {
1187
+ text: message.text
1188
+ };
1189
+ }
1190
+ else if ('caption' in message) {
1191
+ interactiveMessage.body = {
1192
+ text: message.caption
1193
+ };
1194
+ interactiveMessage.header = {
1195
+ title: message.title,
1196
+ subtitle: message.subtitle,
1197
+ hasMediaAttachment: !!(message === null || message === void 0 ? void 0 : message.media),
1198
+ };
1199
+ Object.assign(interactiveMessage.header, m);
1200
+ }
1201
+ if ('footer' in message && !!message.footer) {
1202
+ interactiveMessage.footer = {
1203
+ text: message.footer
1204
+ };
1205
+ }
1206
+ if ('title' in message && !!message.title) {
1207
+ interactiveMessage.header = {
1208
+ title: message.title,
1209
+ subtitle: message.subtitle,
1210
+ hasMediaAttachment: !!(message === null || message === void 0 ? void 0 : message.media),
1211
+ };
1212
+ Object.assign(interactiveMessage.header, m);
1213
+ }
1214
+ if ('contextInfo' in message && !!message.contextInfo) {
1215
+ interactiveMessage.contextInfo = message.contextInfo;
1216
+ }
1217
+ if ('mentions' in message && !!message.mentions) {
1218
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
1219
+ }
1220
+ m = { interactiveMessage };
1221
+ }
1222
+ else if ('collection' in message && !!message.collection) {
1223
+ const interactiveMessage = {
1224
+ collectionMessage: Types_1.WAProto.Message.InteractiveMessage.CollectionMessage.fromObject({
1225
+ bizJid: message.collection.bizJid,
1226
+ id: message.collection.id,
1227
+ messageVersion: message.collection.messageVersion || 1
1228
+ })
1229
+ };
1230
+ if ('text' in message) {
1231
+ interactiveMessage.body = {
1232
+ text: message.text
1233
+ };
1234
+ }
1235
+ if ('footer' in message && !!message.footer) {
1236
+ interactiveMessage.footer = {
1237
+ text: message.footer
1238
+ };
1239
+ }
1240
+ if ('title' in message && !!message.title) {
1241
+ interactiveMessage.header = {
1242
+ title: message.title,
1243
+ subtitle: message.subtitle,
1244
+ hasMediaAttachment: false
1245
+ };
1246
+ }
1247
+ if ('contextInfo' in message && !!message.contextInfo) {
1248
+ interactiveMessage.contextInfo = message.contextInfo;
1249
+ }
1250
+ m = { interactiveMessage };
1251
+ }
1252
+ else if ('invoice' in message && !!message.invoice) {
1253
+ const invoiceData = message.invoice;
1254
+ const invoiceMessage = {
1255
+ note: invoiceData.note,
1256
+ token: invoiceData.token,
1257
+ attachmentType: invoiceData.attachmentType || 0 // IMAGE = 0, PDF = 1
1258
+ };
1259
+ if (invoiceData.attachment) {
1260
+ const attachmentMedia = await (0, exports.prepareWAMessageMedia)({
1261
+ [invoiceData.attachmentType === 1 ? 'document' : 'image']: invoiceData.attachment
1262
+ }, options);
1263
+ if (invoiceData.attachmentType === 1) {
1264
+ invoiceMessage.attachmentMimetype = attachmentMedia.documentMessage.mimetype;
1265
+ invoiceMessage.attachmentMediaKey = attachmentMedia.documentMessage.mediaKey;
1266
+ invoiceMessage.attachmentMediaKeyTimestamp = attachmentMedia.documentMessage.mediaKeyTimestamp;
1267
+ invoiceMessage.attachmentFileSha256 = attachmentMedia.documentMessage.fileSha256;
1268
+ invoiceMessage.attachmentFileEncSha256 = attachmentMedia.documentMessage.fileEncSha256;
1269
+ invoiceMessage.attachmentDirectPath = attachmentMedia.documentMessage.directPath;
1270
+ } else {
1271
+ invoiceMessage.attachmentMimetype = attachmentMedia.imageMessage.mimetype;
1272
+ invoiceMessage.attachmentMediaKey = attachmentMedia.imageMessage.mediaKey;
1273
+ invoiceMessage.attachmentMediaKeyTimestamp = attachmentMedia.imageMessage.mediaKeyTimestamp;
1274
+ invoiceMessage.attachmentFileSha256 = attachmentMedia.imageMessage.fileSha256;
1275
+ invoiceMessage.attachmentFileEncSha256 = attachmentMedia.imageMessage.fileEncSha256;
1276
+ invoiceMessage.attachmentDirectPath = attachmentMedia.imageMessage.directPath;
1277
+ invoiceMessage.attachmentJpegThumbnail = attachmentMedia.imageMessage.jpegThumbnail;
1278
+ }
1279
+ }
1280
+ m = { invoiceMessage };
1281
+ }
1282
+ if ('cards' in message && !!message.cards && message.cards.length > 0) {
1283
+ const carouselCardType = message.carouselCardType || 1; // HSCROLL_CARDS = 1, ALBUM_IMAGE = 2
1284
+ const carouselCards = await Promise.all(message.cards.map(async (card) => {
1285
+ const cardMessage = {
1286
+ header: {
1287
+ title: card.title || '',
1288
+ hasMediaAttachment: !!(card.image || card.video)
1289
+ }
1290
+ };
1291
+
1292
+ // Add body as separate field if present
1293
+ if (card.body) {
1294
+ cardMessage.body = {
1295
+ text: card.body
1296
+ };
1297
+ }
1298
+ // Handle media attachments
1299
+ if (card.image) {
1300
+ const mediaMessage = await prepareWAMessageMedia({ image: card.image }, options);
1301
+ if (mediaMessage.imageMessage) {
1302
+ cardMessage.header.imageMessage = mediaMessage.imageMessage;
1303
+ }
1304
+ }
1305
+ else if (card.video) {
1306
+ const mediaMessage = await prepareWAMessageMedia({ video: card.video }, options);
1307
+ if (mediaMessage.videoMessage) {
1308
+ cardMessage.header.videoMessage = mediaMessage.videoMessage;
1309
+ }
1310
+ }
1311
+ // Handle buttons
1312
+ if (card.buttons && card.buttons.length > 0) {
1313
+ cardMessage.nativeFlowMessage = {
1314
+ buttons: card.buttons.map(button => ({
1315
+ name: button.name,
1316
+ buttonParamsJson: button.buttonParamsJson
1317
+ })),
1318
+ messageVersion: 1,
1319
+ };
1320
+ }
1321
+ // Add footer if present
1322
+ if (card.footer) {
1323
+ cardMessage.footer = {
1324
+ text: card.footer
1325
+ };
1326
+ }
1327
+ return cardMessage;
1328
+ }));
1329
+ const interactiveMessage = {
1330
+ carouselMessage: Types_1.WAProto.Message.InteractiveMessage.CarouselMessage.fromObject({
1331
+ cards: carouselCards,
1332
+ messageVersion: 1,
1333
+ carouselCardType: carouselCardType
1334
+ })
1335
+ };
1336
+ if ('text' in message) {
1337
+ interactiveMessage.body = {
1338
+ text: message.text
1339
+ };
1340
+ }
1341
+ if ('footer' in message && !!message.footer) {
1342
+ interactiveMessage.footer = {
1343
+ text: message.footer
1344
+ };
1345
+ }
1346
+ if ('title' in message && !!message.title) {
1347
+ interactiveMessage.header = {
1348
+ title: message.title,
1349
+ subtitle: message.subtitle,
1350
+ hasMediaAttachment: false
1351
+ };
1352
+ }
1353
+ if ('contextInfo' in message && !!message.contextInfo) {
1354
+ interactiveMessage.contextInfo = message.contextInfo;
1355
+ }
1356
+ if ('mentions' in message && !!message.mentions) {
1357
+ interactiveMessage.contextInfo = { mentionedJid: message.mentions };
1358
+ }
1359
+ m = { interactiveMessage };
1360
+ }
1361
+ // Interactive messages are commonly sent wrapped in a view-once container on MD.
1362
+ // This improves client compatibility (avoids "update WhatsApp" / invisible messages on some clients).
1363
+ const shouldWrapInteractive = !!(m === null || m === void 0 ? void 0 : m.interactiveMessage);
1364
+ const hasViewOnceAlready = !!(m === null || m === void 0 ? void 0 : m.viewOnceMessage) || !!(m === null || m === void 0 ? void 0 : m.viewOnceMessageV2) || !!(m === null || m === void 0 ? void 0 : m.viewOnceMessageV2Extension);
1365
+ if ((('viewOnce' in message && !!message.viewOnce) || shouldWrapInteractive) && !hasViewOnceAlready) {
1366
+ m = { viewOnceMessageV2: { message: m } };
1367
+ }
1368
+ if ('mentions' in message && ((_o = message.mentions) === null || _o === void 0 ? void 0 : _o.length)) {
1369
+ const [messageType] = Object.keys(m);
1370
+ m[messageType].contextInfo = m[messageType] || {};
1371
+ m[messageType].contextInfo.mentionedJid = message.mentions;
1372
+ }
1373
+ if ('edit' in message) {
1374
+ m = {
1375
+ protocolMessage: {
1376
+ key: message.edit,
1377
+ editedMessage: m,
1378
+ timestampMs: Date.now(),
1379
+ type: Types_1.WAProto.Message.ProtocolMessage.Type.MESSAGE_EDIT
1380
+ }
1381
+ };
1382
+ }
1383
+ if ('contextInfo' in message && !!message.contextInfo) {
1384
+ const [messageType] = Object.keys(m);
1385
+ m[messageType] = m[messageType] || {};
1386
+ m[messageType].contextInfo = {
1387
+ ...m[messageType].contextInfo,
1388
+ ...message.contextInfo
1389
+ };
1390
+ }
1391
+ return Types_1.WAProto.Message.fromObject(m);
1392
+ };
1393
+ exports.generateWAMessageContent = generateWAMessageContent;
1394
+ const generateWAMessageFromContent = (jid, message, options) => {
1395
+ // set timestamp to now
1396
+ // if not specified
1397
+ if (!options.timestamp) {
1398
+ options.timestamp = new Date();
1399
+ }
1400
+ const innerMessage = (0, exports.normalizeMessageContent)(message);
1401
+ const key = (0, exports.getContentType)(innerMessage);
1402
+ const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp);
1403
+ const { quoted, userJid } = options;
1404
+ // only set quoted if isn't a newsletter message
1405
+ if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
1406
+ const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid);
1407
+ let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message);
1408
+ const msgType = (0, exports.getContentType)(quotedMsg);
1409
+ // strip any redundant properties
1410
+ if (quotedMsg) {
1411
+ quotedMsg = WAProto_1.proto.Message.fromObject({ [msgType]: quotedMsg[msgType] });
1412
+ const quotedContent = quotedMsg[msgType];
1413
+ if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
1414
+ delete quotedContent.contextInfo;
1415
+ }
1416
+ const contextInfo = innerMessage[key].contextInfo || {};
1417
+ contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant);
1418
+ contextInfo.stanzaId = quoted.key.id;
1419
+ contextInfo.quotedMessage = quotedMsg;
1420
+ // if a participant is quoted, then it must be a group
1421
+ // hence, remoteJid of group must also be entered
1422
+ if (jid !== quoted.key.remoteJid) {
1423
+ contextInfo.remoteJid = quoted.key.remoteJid;
1424
+ }
1425
+ innerMessage[key].contextInfo = contextInfo;
1426
+ }
1427
+ }
1428
+ if (
1429
+ // if we want to send a disappearing message
1430
+ !!(options === null || options === void 0 ? void 0 : options.ephemeralExpiration) &&
1431
+ // and it's not a protocol message -- delete, toggle disappear message
1432
+ key !== 'protocolMessage' &&
1433
+ // already not converted to disappearing message
1434
+ key !== 'ephemeralMessage' &&
1435
+ // newsletter not accept disappearing messages
1436
+ !(0, WABinary_1.isJidNewsletter)(jid)) {
1437
+ innerMessage[key].contextInfo = {
1438
+ ...(innerMessage[key].contextInfo || {}),
1439
+ expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL,
1440
+ //ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString()
1441
+ };
1442
+ }
1443
+ message = Types_1.WAProto.Message.fromObject(message);
1444
+ const messageJSON = {
1445
+ key: {
1446
+ remoteJid: jid,
1447
+ fromMe: true,
1448
+ id: (options === null || options === void 0 ? void 0 : options.messageId) || (0, generics_1.generateMessageIDV2)(),
1449
+ },
1450
+ message: message,
1451
+ messageTimestamp: timestamp,
1452
+ messageStubParameters: [],
1453
+ participant: (0, WABinary_1.isJidGroup)(jid) || (0, WABinary_1.isJidStatusBroadcast)(jid) ? userJid : undefined,
1454
+ status: Types_1.WAMessageStatus.PENDING
1455
+ };
1456
+ return Types_1.WAProto.WebMessageInfo.fromObject(messageJSON);
1457
+ };
1458
+ exports.generateWAMessageFromContent = generateWAMessageFromContent;
1459
+ const generateWAMessage = async (jid, content, options) => {
1460
+ var _a;
1461
+ // ensure msg ID is with every log
1462
+ options.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) === null || _a === void 0 ? void 0 : _a.child({ msgId: options.messageId });
1463
+ return (0, exports.generateWAMessageFromContent)(jid, await (0, exports.generateWAMessageContent)(content, { newsletter: (0, WABinary_1.isJidNewsletter)(jid), ...options }), options);
1464
+ };
1465
+ exports.generateWAMessage = generateWAMessage;
1466
+ /** Get the key to access the true type of content */
1467
+ const getContentType = (content) => {
1468
+ if (content) {
1469
+ const keys = Object.keys(content);
1470
+ const key = keys.find(k => (k === 'conversation' || k.includes('Message')) && k !== 'senderKeyDistributionMessage');
1471
+ return key;
1472
+ }
1473
+ };
1474
+ exports.getContentType = getContentType;
1475
+ /**
1476
+ * Normalizes ephemeral, view once messages to regular message content
1477
+ * Eg. image messages in ephemeral messages, in view once messages etc.
1478
+ * @param content
1479
+ * @returns
1480
+ */
1481
+ const normalizeMessageContent = (content) => {
1482
+ if (!content) {
1483
+ return undefined;
1484
+ }
1485
+ // set max iterations to prevent an infinite loop
1486
+ for (let i = 0; i < 5; i++) {
1487
+ const inner = getFutureProofMessage(content);
1488
+ if (!inner) {
1489
+ break;
1490
+ }
1491
+ content = inner.message;
1492
+ }
1493
+ return content;
1494
+ function getFutureProofMessage(message) {
1495
+ return ((message === null || message === void 0 ? void 0 : message.ephemeralMessage)
1496
+ || (message === null || message === void 0 ? void 0 : message.viewOnceMessage)
1497
+ || (message === null || message === void 0 ? void 0 : message.documentWithCaptionMessage)
1498
+ || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2)
1499
+ || (message === null || message === void 0 ? void 0 : message.viewOnceMessageV2Extension)
1500
+ || (message === null || message === void 0 ? void 0 : message.editedMessage)
1501
+ || (message === null || message === void 0 ? void 0 : message.groupMentionedMessage)
1502
+ || (message === null || message === void 0 ? void 0 : message.botInvokeMessage)
1503
+ || (message === null || message === void 0 ? void 0 : message.lottieStickerMessage)
1504
+ || (message === null || message === void 0 ? void 0 : message.eventCoverImage)
1505
+ || (message === null || message === void 0 ? void 0 : message.statusMentionMessage)
1506
+ || (message === null || message === void 0 ? void 0 : message.pollCreationOptionImageMessage)
1507
+ || (message === null || message === void 0 ? void 0 : message.associatedChildMessage)
1508
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMentionMessage)
1509
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV4)
1510
+ || (message === null || message === void 0 ? void 0 : message.pollCreationMessageV5)
1511
+ || (message === null || message === void 0 ? void 0 : message.statusAddYours)
1512
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMessage)
1513
+ || (message === null || message === void 0 ? void 0 : message.limitSharingMessage)
1514
+ || (message === null || message === void 0 ? void 0 : message.botTaskMessage)
1515
+ || (message === null || message === void 0 ? void 0 : message.questionMessage)
1516
+ || (message === null || message === void 0 ? void 0 : message.groupStatusMessageV2)
1517
+ || (message === null || message === void 0 ? void 0 : message.botForwardedMessage));
1518
+ }
1519
+ };
1520
+ exports.normalizeMessageContent = normalizeMessageContent;
1521
+ /**
1522
+ * Extract the true message content from a message
1523
+ * Eg. extracts the inner message from a disappearing message/view once message
1524
+ */
1525
+ const extractMessageContent = (content) => {
1526
+ var _a, _b, _c, _d, _e, _f;
1527
+ const extractFromTemplateMessage = (msg) => {
1528
+ if (msg.imageMessage) {
1529
+ return { imageMessage: msg.imageMessage };
1530
+ }
1531
+ else if (msg.documentMessage) {
1532
+ return { documentMessage: msg.documentMessage };
1533
+ }
1534
+ else if (msg.videoMessage) {
1535
+ return { videoMessage: msg.videoMessage };
1536
+ }
1537
+ else if (msg.locationMessage) {
1538
+ return { locationMessage: msg.locationMessage };
1539
+ }
1540
+ else {
1541
+ return {
1542
+ conversation: 'contentText' in msg
1543
+ ? msg.contentText
1544
+ : ('hydratedContentText' in msg ? msg.hydratedContentText : '')
1545
+ };
1546
+ }
1547
+ };
1548
+ content = (0, exports.normalizeMessageContent)(content);
1549
+ if (content === null || content === void 0 ? void 0 : content.buttonsMessage) {
1550
+ return extractFromTemplateMessage(content.buttonsMessage);
1551
+ }
1552
+ if ((_a = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _a === void 0 ? void 0 : _a.hydratedFourRowTemplate) {
1553
+ return extractFromTemplateMessage((_b = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _b === void 0 ? void 0 : _b.hydratedFourRowTemplate);
1554
+ }
1555
+ if ((_c = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _c === void 0 ? void 0 : _c.hydratedTemplate) {
1556
+ return extractFromTemplateMessage((_d = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _d === void 0 ? void 0 : _d.hydratedTemplate);
1557
+ }
1558
+ if ((_e = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _e === void 0 ? void 0 : _e.fourRowTemplate) {
1559
+ return extractFromTemplateMessage((_f = content === null || content === void 0 ? void 0 : content.templateMessage) === null || _f === void 0 ? void 0 : _f.fourRowTemplate);
1560
+ }
1561
+ return content;
1562
+ };
1563
+ exports.extractMessageContent = extractMessageContent;
1564
+ /**
1565
+ * Returns the device predicted by message ID
1566
+ */
1567
+ const getDevice = (id) => /^3A.{18}$/.test(id) ? 'ios' :
1568
+ /^3E.{20}$/.test(id) ? 'web' :
1569
+ /^(.{21}|.{32})$/.test(id) ? 'android' :
1570
+ /^(3F|.{18}$)/.test(id) ? 'desktop' :
1571
+ 'unknown';
1572
+ exports.getDevice = getDevice;
1573
+ /** Upserts a receipt in the message */
1574
+ const updateMessageWithReceipt = (msg, receipt) => {
1575
+ msg.userReceipt = msg.userReceipt || [];
1576
+ const recp = msg.userReceipt.find(m => m.userJid === receipt.userJid);
1577
+ if (recp) {
1578
+ Object.assign(recp, receipt);
1579
+ }
1580
+ else {
1581
+ msg.userReceipt.push(receipt);
1582
+ }
1583
+ };
1584
+ exports.updateMessageWithReceipt = updateMessageWithReceipt;
1585
+ /** Update the message with a new reaction */
1586
+ const updateMessageWithReaction = (msg, reaction) => {
1587
+ const authorID = (0, generics_1.getKeyAuthor)(reaction.key);
1588
+ const reactions = (msg.reactions || [])
1589
+ .filter(r => (0, generics_1.getKeyAuthor)(r.key) !== authorID);
1590
+ reaction.text = reaction.text || '';
1591
+ reactions.push(reaction);
1592
+ msg.reactions = reactions;
1593
+ };
1594
+ exports.updateMessageWithReaction = updateMessageWithReaction;
1595
+ /** Update the message with a new poll update */
1596
+ const updateMessageWithPollUpdate = (msg, update) => {
1597
+ var _a, _b;
1598
+ const authorID = (0, generics_1.getKeyAuthor)(update.pollUpdateMessageKey);
1599
+ const reactions = (msg.pollUpdates || [])
1600
+ .filter(r => (0, generics_1.getKeyAuthor)(r.pollUpdateMessageKey) !== authorID);
1601
+ if ((_b = (_a = update.vote) === null || _a === void 0 ? void 0 : _a.selectedOptions) === null || _b === void 0 ? void 0 : _b.length) {
1602
+ reactions.push(update);
1603
+ }
1604
+ msg.pollUpdates = reactions;
1605
+ };
1606
+ exports.updateMessageWithPollUpdate = updateMessageWithPollUpdate;
1607
+ /**
1608
+ * Aggregates all poll updates in a poll.
1609
+ * @param msg the poll creation message
1610
+ * @param meId your jid
1611
+ * @returns A list of options & their voters
1612
+ */
1613
+ function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
1614
+ var _a, _b, _c;
1615
+ 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) || [];
1616
+ const voteHashMap = opts.reduce((acc, opt) => {
1617
+ const hash = (0, crypto_2.sha256)(Buffer.from(opt.optionName || '')).toString();
1618
+ acc[hash] = {
1619
+ name: opt.optionName || '',
1620
+ voters: []
1621
+ };
1622
+ return acc;
1623
+ }, {});
1624
+ for (const update of pollUpdates || []) {
1625
+ const { vote } = update;
1626
+ if (!vote) {
1627
+ continue;
1628
+ }
1629
+ for (const option of vote.selectedOptions || []) {
1630
+ const hash = option.toString();
1631
+ let data = voteHashMap[hash];
1632
+ if (!data) {
1633
+ voteHashMap[hash] = {
1634
+ name: 'Unknown',
1635
+ voters: []
1636
+ };
1637
+ data = voteHashMap[hash];
1638
+ }
1639
+ voteHashMap[hash].voters.push((0, generics_1.getKeyAuthor)(update.pollUpdateMessageKey, meId));
1640
+ }
1641
+ }
1642
+ return Object.values(voteHashMap);
1643
+ }
1644
+ /** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
1645
+ const aggregateMessageKeysNotFromMe = (keys) => {
1646
+ const keyMap = {};
1647
+ for (const { remoteJid, id, participant, fromMe } of keys) {
1648
+ if (!fromMe) {
1649
+ const uqKey = `${remoteJid}:${participant || ''}`;
1650
+ if (!keyMap[uqKey]) {
1651
+ keyMap[uqKey] = {
1652
+ jid: remoteJid,
1653
+ participant: participant,
1654
+ messageIds: []
1655
+ };
1656
+ }
1657
+ keyMap[uqKey].messageIds.push(id);
1658
+ }
1659
+ }
1660
+ return Object.values(keyMap);
1661
+ };
1662
+ exports.aggregateMessageKeysNotFromMe = aggregateMessageKeysNotFromMe;
1663
+ const REUPLOAD_REQUIRED_STATUS = [410, 404];
1664
+ /**
1665
+ * Downloads the given message. Throws an error if it's not a media message
1666
+ */
1667
+ const downloadMediaMessage = async (message, type, options, ctx) => {
1668
+ const result = await downloadMsg()
1669
+ .catch(async (error) => {
1670
+ var _a;
1671
+ if (ctx) {
1672
+ if (axios_1.default.isAxiosError(error)) {
1673
+ // check if the message requires a reupload
1674
+ if (REUPLOAD_REQUIRED_STATUS.includes((_a = error.response) === null || _a === void 0 ? void 0 : _a.status)) {
1675
+ ctx.logger.info({ key: message.key }, 'sending reupload media request...');
1676
+ // request reupload
1677
+ message = await ctx.reuploadRequest(message);
1678
+ const result = await downloadMsg();
1679
+ return result;
1680
+ }
1681
+ }
1682
+ }
1683
+ throw error;
1684
+ });
1685
+ return result;
1686
+ async function downloadMsg() {
1687
+ const mContent = (0, exports.extractMessageContent)(message.message);
1688
+ if (!mContent) {
1689
+ throw new boom_1.Boom('No message present', { statusCode: 400, data: message });
1690
+ }
1691
+ const contentType = (0, exports.getContentType)(mContent);
1692
+ let mediaType = contentType === null || contentType === void 0 ? void 0 : contentType.replace('Message', '');
1693
+ const media = mContent[contentType];
1694
+ if (!media || typeof media !== 'object' || (!('url' in media) && !('thumbnailDirectPath' in media))) {
1695
+ throw new boom_1.Boom(`"${contentType}" message is not a media message`);
1696
+ }
1697
+ let download;
1698
+ if ('thumbnailDirectPath' in media && !('url' in media)) {
1699
+ download = {
1700
+ directPath: media.thumbnailDirectPath,
1701
+ mediaKey: media.mediaKey
1702
+ };
1703
+ mediaType = 'thumbnail-link';
1704
+ }
1705
+ else {
1706
+ download = media;
1707
+ }
1708
+ const stream = await (0, messages_media_1.downloadContentFromMessage)(download, mediaType, options);
1709
+ if (type === 'buffer') {
1710
+ const bufferArray = [];
1711
+ for await (const chunk of stream) {
1712
+ bufferArray.push(chunk);
1713
+ }
1714
+ return Buffer.concat(bufferArray);
1715
+ }
1716
+ return stream;
1717
+ }
1718
+ };
1719
+ exports.downloadMediaMessage = downloadMediaMessage;
1720
+ /** Checks whether the given message is a media message; if it is returns the inner content */
1721
+ const assertMediaContent = (content) => {
1722
+ content = (0, exports.extractMessageContent)(content);
1723
+ const mediaContent = (content === null || content === void 0 ? void 0 : content.documentMessage)
1724
+ || (content === null || content === void 0 ? void 0 : content.imageMessage)
1725
+ || (content === null || content === void 0 ? void 0 : content.videoMessage)
1726
+ || (content === null || content === void 0 ? void 0 : content.audioMessage)
1727
+ || (content === null || content === void 0 ? void 0 : content.stickerMessage);
1728
+ if (!mediaContent) {
1729
+ throw new boom_1.Boom('given message is not a media message', { statusCode: 400, data: content });
1730
+ }
1731
+ return mediaContent;
1732
+ };
1733
+ exports.assertMediaContent = assertMediaContent;
1734
+ const cache_manager_1 = require("./cache-manager");
1735
+ const performance_config_1 = require("./performance-config");
1736
+ /**
1737
+ * Get cache statistics for monitoring performance
1738
+ */
1739
+ const getCacheStats = () => {
1740
+ try {
1741
+ const cacheManager = cache_manager_1.default;
1742
+ const config = performance_config_1.getPerformanceConfig();
1743
+
1744
+ if (!cacheManager || !cacheManager.caches) {
1745
+ return {
1746
+ lidCache: { size: 0, maxSize: 0, ttl: config.cache.lidCache.ttl },
1747
+ jidCache: { size: 0, maxSize: 0, ttl: config.cache.jidCache.ttl }
1748
+ };
1749
+ }
1750
+
1751
+ const lidStats = cacheManager.getStats('lidCache');
1752
+ const jidStats = cacheManager.getStats('jidCache');
1753
+
1754
+ return {
1755
+ lidCache: {
1756
+ size: lidStats?.keys || 0,
1757
+ maxSize: lidStats?.max || config.cache.lidCache.maxSize || 0,
1758
+ ttl: config.cache.lidCache.ttl
1759
+ },
1760
+ jidCache: {
1761
+ size: jidStats?.keys || 0,
1762
+ maxSize: jidStats?.max || config.cache.jidCache.maxSize || 0,
1763
+ ttl: config.cache.jidCache.ttl
1764
+ }
1765
+ };
1766
+ } catch (error) {
1767
+ const config = performance_config_1.getPerformanceConfig();
1768
+ return {
1769
+ lidCache: { size: 0, maxSize: 0, ttl: config.cache.lidCache.ttl },
1770
+ jidCache: { size: 0, maxSize: 0, ttl: config.cache.jidCache.ttl }
1771
+ };
1772
+ }
1773
+ };
1774
+ exports.getCacheStats = getCacheStats;
1775
+ /**
1776
+ * Clear all caches (useful for testing or memory management)
1777
+ */
1778
+ const clearCache = () => {
1779
+ try {
1780
+ const cacheManager = cache_manager_1.default;
1781
+ if (cacheManager && cacheManager.caches) {
1782
+ Object.keys(cacheManager.caches).forEach(cacheName => {
1783
+ const cache = cacheManager.caches[cacheName];
1784
+ if (cache && typeof cache.flushAll === 'function') {
1785
+ cache.flushAll();
1786
+ }
1787
+ });
1788
+ }
1789
+ } catch (error) {
1790
+ // Silently fail if cache manager is not available
1791
+ }
1792
+ };
1793
+ exports.clearCache = clearCache;