@alannxd/baileys 6.0.4 → 6.0.5

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