@queenanya/baileys 9.2.4 → 9.4.3

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 (301) hide show
  1. package/README.md +329 -1237
  2. package/WAProto/fix-imports.js +22 -18
  3. package/WAProto/index.js +22 -18
  4. package/lib/Defaults/index.d.ts +17 -0
  5. package/lib/Defaults/index.d.ts.map +1 -1
  6. package/lib/Defaults/index.js +29 -3
  7. package/lib/Defaults/index.js.map +1 -1
  8. package/lib/Signal/libsignal.d.ts.map +1 -1
  9. package/lib/Signal/libsignal.js +61 -2
  10. package/lib/Signal/libsignal.js.map +1 -1
  11. package/lib/Signal/lid-mapping.d.ts +5 -9
  12. package/lib/Signal/lid-mapping.d.ts.map +1 -1
  13. package/lib/Signal/lid-mapping.js +170 -70
  14. package/lib/Signal/lid-mapping.js.map +1 -1
  15. package/lib/Socket/business.d.ts +114 -2
  16. package/lib/Socket/business.d.ts.map +1 -1
  17. package/lib/Socket/chats.d.ts +14 -1
  18. package/lib/Socket/chats.d.ts.map +1 -1
  19. package/lib/Socket/chats.js +253 -38
  20. package/lib/Socket/chats.js.map +1 -1
  21. package/lib/Socket/communities.d.ts +114 -2
  22. package/lib/Socket/communities.d.ts.map +1 -1
  23. package/lib/Socket/groups.d.ts +9 -0
  24. package/lib/Socket/groups.d.ts.map +1 -1
  25. package/lib/Socket/groups.js +6 -0
  26. package/lib/Socket/groups.js.map +1 -1
  27. package/lib/Socket/index.d.ts +114 -2
  28. package/lib/Socket/index.d.ts.map +1 -1
  29. package/lib/Socket/index.js +0 -6
  30. package/lib/Socket/index.js.map +1 -1
  31. package/lib/Socket/messages-recv.d.ts +115 -3
  32. package/lib/Socket/messages-recv.d.ts.map +1 -1
  33. package/lib/Socket/messages-recv.js +739 -150
  34. package/lib/Socket/messages-recv.js.map +1 -1
  35. package/lib/Socket/messages-send.d.ts +118 -4
  36. package/lib/Socket/messages-send.d.ts.map +1 -1
  37. package/lib/Socket/messages-send.js +328 -86
  38. package/lib/Socket/messages-send.js.map +1 -1
  39. package/lib/Socket/newsletter.d.ts +9 -0
  40. package/lib/Socket/newsletter.d.ts.map +1 -1
  41. package/lib/Socket/newsletter.js +2 -2
  42. package/lib/Socket/newsletter.js.map +1 -1
  43. package/lib/Socket/socket.d.ts +2 -0
  44. package/lib/Socket/socket.d.ts.map +1 -1
  45. package/lib/Socket/socket.js +143 -17
  46. package/lib/Socket/socket.js.map +1 -1
  47. package/lib/Types/Auth.d.ts +2 -0
  48. package/lib/Types/Auth.d.ts.map +1 -1
  49. package/lib/Types/Call.d.ts +10 -1
  50. package/lib/Types/Call.d.ts.map +1 -1
  51. package/lib/Types/Contact.d.ts +2 -0
  52. package/lib/Types/Contact.d.ts.map +1 -1
  53. package/lib/Types/Events.d.ts +21 -1
  54. package/lib/Types/Events.d.ts.map +1 -1
  55. package/lib/Types/GroupMetadata.d.ts +4 -0
  56. package/lib/Types/GroupMetadata.d.ts.map +1 -1
  57. package/lib/Types/Message.d.ts +530 -16
  58. package/lib/Types/Message.d.ts.map +1 -1
  59. package/lib/Types/Message.js.map +1 -1
  60. package/lib/Types/Newsletter.d.ts +37 -31
  61. package/lib/Types/Newsletter.d.ts.map +1 -1
  62. package/lib/Types/Newsletter.js +27 -23
  63. package/lib/Types/Newsletter.js.map +1 -1
  64. package/lib/Types/State.d.ts +54 -0
  65. package/lib/Types/State.d.ts.map +1 -1
  66. package/lib/Types/State.js +42 -0
  67. package/lib/Types/State.js.map +1 -1
  68. package/lib/Types/index.d.ts +9 -0
  69. package/lib/Types/index.d.ts.map +1 -1
  70. package/lib/Types/index.js.map +1 -1
  71. package/lib/Utils/browser-utils.d.ts +13 -0
  72. package/lib/Utils/browser-utils.d.ts.map +1 -1
  73. package/lib/Utils/browser-utils.js +90 -10
  74. package/lib/Utils/browser-utils.js.map +1 -1
  75. package/lib/Utils/chat-utils.d.ts +30 -0
  76. package/lib/Utils/chat-utils.d.ts.map +1 -1
  77. package/lib/Utils/chat-utils.js +81 -52
  78. package/lib/Utils/chat-utils.js.map +1 -1
  79. package/lib/Utils/companion-reg-client-utils.d.ts +17 -0
  80. package/lib/Utils/companion-reg-client-utils.d.ts.map +1 -0
  81. package/lib/Utils/companion-reg-client-utils.js +34 -0
  82. package/lib/Utils/companion-reg-client-utils.js.map +1 -0
  83. package/lib/Utils/crypto.d.ts +4 -8
  84. package/lib/Utils/crypto.d.ts.map +1 -1
  85. package/lib/Utils/crypto.js +2 -26
  86. package/lib/Utils/crypto.js.map +1 -1
  87. package/lib/Utils/decode-wa-message.d.ts +12 -0
  88. package/lib/Utils/decode-wa-message.d.ts.map +1 -1
  89. package/lib/Utils/decode-wa-message.js +16 -0
  90. package/lib/Utils/decode-wa-message.js.map +1 -1
  91. package/lib/Utils/event-buffer.js +10 -1
  92. package/lib/Utils/event-buffer.js.map +1 -1
  93. package/lib/Utils/generics.d.ts +3 -1
  94. package/lib/Utils/generics.d.ts.map +1 -1
  95. package/lib/Utils/generics.js +16 -3
  96. package/lib/Utils/generics.js.map +1 -1
  97. package/lib/Utils/history.d.ts +5 -2
  98. package/lib/Utils/history.d.ts.map +1 -1
  99. package/lib/Utils/history.js +53 -17
  100. package/lib/Utils/history.js.map +1 -1
  101. package/lib/Utils/identity-change-handler.d.ts +44 -0
  102. package/lib/Utils/identity-change-handler.d.ts.map +1 -0
  103. package/lib/Utils/identity-change-handler.js +50 -0
  104. package/lib/Utils/identity-change-handler.js.map +1 -0
  105. package/lib/Utils/index.d.ts +6 -0
  106. package/lib/Utils/index.d.ts.map +1 -1
  107. package/lib/Utils/index.js +6 -0
  108. package/lib/Utils/index.js.map +1 -1
  109. package/lib/Utils/interactive-message.d.ts +201 -0
  110. package/lib/Utils/interactive-message.d.ts.map +1 -0
  111. package/lib/Utils/interactive-message.js +256 -0
  112. package/lib/Utils/interactive-message.js.map +1 -0
  113. package/lib/Utils/lt-hash.d.ts +7 -12
  114. package/lib/Utils/lt-hash.d.ts.map +1 -1
  115. package/lib/Utils/lt-hash.js +2 -42
  116. package/lib/Utils/lt-hash.js.map +1 -1
  117. package/lib/Utils/message-composer.d.ts +5 -0
  118. package/lib/Utils/message-composer.d.ts.map +1 -0
  119. package/lib/Utils/message-composer.js +5 -0
  120. package/lib/Utils/message-composer.js.map +1 -0
  121. package/lib/Utils/message-retry-manager.d.ts +30 -2
  122. package/lib/Utils/message-retry-manager.d.ts.map +1 -1
  123. package/lib/Utils/message-retry-manager.js +59 -2
  124. package/lib/Utils/message-retry-manager.js.map +1 -1
  125. package/lib/Utils/messages-media.d.ts +19 -5
  126. package/lib/Utils/messages-media.d.ts.map +1 -1
  127. package/lib/Utils/messages-media.js +26 -17
  128. package/lib/Utils/messages-media.js.map +1 -1
  129. package/lib/Utils/messages.d.ts.map +1 -1
  130. package/lib/Utils/messages.js +433 -13
  131. package/lib/Utils/messages.js.map +1 -1
  132. package/lib/Utils/noise-handler.d.ts +2 -2
  133. package/lib/Utils/noise-handler.d.ts.map +1 -1
  134. package/lib/Utils/noise-handler.js +10 -10
  135. package/lib/Utils/noise-handler.js.map +1 -1
  136. package/lib/Utils/offline-node-processor.d.ts +17 -0
  137. package/lib/Utils/offline-node-processor.d.ts.map +1 -0
  138. package/lib/Utils/offline-node-processor.js +40 -0
  139. package/lib/Utils/offline-node-processor.js.map +1 -0
  140. package/lib/Utils/process-message.d.ts.map +1 -1
  141. package/lib/Utils/process-message.js +96 -16
  142. package/lib/Utils/process-message.js.map +1 -1
  143. package/lib/Utils/reporting-utils.js +2 -2
  144. package/lib/Utils/reporting-utils.js.map +1 -1
  145. package/lib/Utils/stanza-ack.d.ts +11 -0
  146. package/lib/Utils/stanza-ack.d.ts.map +1 -0
  147. package/lib/Utils/stanza-ack.js +38 -0
  148. package/lib/Utils/stanza-ack.js.map +1 -0
  149. package/lib/Utils/sync-action-utils.d.ts.map +1 -1
  150. package/lib/Utils/sync-action-utils.js +2 -1
  151. package/lib/Utils/sync-action-utils.js.map +1 -1
  152. package/lib/Utils/tc-token-utils.d.ts +26 -1
  153. package/lib/Utils/tc-token-utils.d.ts.map +1 -1
  154. package/lib/Utils/tc-token-utils.js +149 -4
  155. package/lib/Utils/tc-token-utils.js.map +1 -1
  156. package/lib/Utils/use-mongo-file-auth-state.d.ts +16 -0
  157. package/lib/Utils/use-mongo-file-auth-state.d.ts.map +1 -0
  158. package/lib/Utils/use-mongo-file-auth-state.js +60 -0
  159. package/lib/Utils/use-mongo-file-auth-state.js.map +1 -0
  160. package/lib/Utils/use-multi-file-auth-state.js +1 -1
  161. package/lib/Utils/use-multi-file-auth-state.js.map +1 -1
  162. package/lib/Utils/validate-connection.d.ts.map +1 -1
  163. package/lib/Utils/validate-connection.js +11 -1
  164. package/lib/Utils/validate-connection.js.map +1 -1
  165. package/lib/WABinary/generic-utils.d.ts +9 -0
  166. package/lib/WABinary/generic-utils.d.ts.map +1 -1
  167. package/lib/WABinary/generic-utils.js +23 -0
  168. package/lib/WABinary/generic-utils.js.map +1 -1
  169. package/lib/WABinary/jid-utils.js.map +1 -1
  170. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -1
  171. package/lib/WAUSync/Protocols/USyncContactProtocol.js +26 -3
  172. package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -1
  173. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
  174. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +1 -0
  175. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
  176. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +1 -0
  177. package/lib/WAUSync/Protocols/index.d.ts +1 -0
  178. package/lib/WAUSync/Protocols/index.d.ts.map +1 -1
  179. package/lib/WAUSync/Protocols/index.js +1 -0
  180. package/lib/WAUSync/Protocols/index.js.map +1 -1
  181. package/lib/WAUSync/USyncQuery.d.ts +1 -0
  182. package/lib/WAUSync/USyncQuery.d.ts.map +1 -1
  183. package/lib/WAUSync/USyncQuery.js +5 -1
  184. package/lib/WAUSync/USyncQuery.js.map +1 -1
  185. package/lib/WAUSync/USyncUser.d.ts +4 -0
  186. package/lib/WAUSync/USyncUser.d.ts.map +1 -1
  187. package/lib/WAUSync/USyncUser.js +8 -0
  188. package/lib/WAUSync/USyncUser.js.map +1 -1
  189. package/lib/addons/anti-delete.d.ts +72 -0
  190. package/lib/addons/anti-delete.d.ts.map +1 -0
  191. package/lib/addons/anti-delete.js +165 -0
  192. package/lib/addons/anti-delete.js.map +1 -0
  193. package/lib/addons/auto-reply.d.ts +67 -0
  194. package/lib/addons/auto-reply.d.ts.map +1 -0
  195. package/lib/addons/auto-reply.js +145 -0
  196. package/lib/addons/auto-reply.js.map +1 -0
  197. package/lib/addons/browser-presets.d.ts +16 -0
  198. package/lib/addons/browser-presets.d.ts.map +1 -0
  199. package/lib/addons/browser-presets.js +24 -0
  200. package/lib/addons/browser-presets.js.map +1 -0
  201. package/lib/addons/button-sender.d.ts +260 -0
  202. package/lib/addons/button-sender.d.ts.map +1 -0
  203. package/lib/addons/button-sender.js +771 -0
  204. package/lib/addons/button-sender.js.map +1 -0
  205. package/lib/addons/call-handler.d.ts +79 -0
  206. package/lib/addons/call-handler.d.ts.map +1 -0
  207. package/lib/addons/call-handler.js +342 -0
  208. package/lib/addons/call-handler.js.map +1 -0
  209. package/lib/addons/from-chats.d.ts +30 -0
  210. package/lib/addons/from-chats.d.ts.map +1 -0
  211. package/lib/addons/from-chats.js +38 -0
  212. package/lib/addons/from-chats.js.map +1 -0
  213. package/lib/addons/from-messages-recv.d.ts +59 -0
  214. package/lib/addons/from-messages-recv.d.ts.map +1 -0
  215. package/lib/addons/from-messages-recv.js +326 -0
  216. package/lib/addons/from-messages-recv.js.map +1 -0
  217. package/lib/addons/from-messages-send.d.ts +50 -0
  218. package/lib/addons/from-messages-send.d.ts.map +1 -0
  219. package/lib/addons/from-messages-send.js +148 -0
  220. package/lib/addons/from-messages-send.js.map +1 -0
  221. package/lib/addons/from-messages.d.ts +52 -0
  222. package/lib/addons/from-messages.d.ts.map +1 -0
  223. package/lib/addons/from-messages.js +304 -0
  224. package/lib/addons/from-messages.js.map +1 -0
  225. package/lib/addons/index.d.ts +67 -0
  226. package/lib/addons/index.d.ts.map +1 -0
  227. package/lib/addons/index.js +86 -0
  228. package/lib/addons/index.js.map +1 -0
  229. package/lib/addons/interactive-message.d.ts +201 -0
  230. package/lib/addons/interactive-message.d.ts.map +1 -0
  231. package/lib/addons/interactive-message.js +256 -0
  232. package/lib/addons/interactive-message.js.map +1 -0
  233. package/lib/addons/jid-plot.d.ts +49 -0
  234. package/lib/addons/jid-plot.d.ts.map +1 -0
  235. package/lib/addons/jid-plot.js +84 -0
  236. package/lib/addons/jid-plot.js.map +1 -0
  237. package/lib/addons/jid-plotting.d.ts +54 -0
  238. package/lib/addons/jid-plotting.d.ts.map +1 -0
  239. package/lib/addons/jid-plotting.js +150 -0
  240. package/lib/addons/jid-plotting.js.map +1 -0
  241. package/lib/addons/lid-support.d.ts +41 -0
  242. package/lib/addons/lid-support.d.ts.map +1 -0
  243. package/lib/addons/lid-support.js +42 -0
  244. package/lib/addons/lid-support.js.map +1 -0
  245. package/lib/addons/message-composer.d.ts +142 -0
  246. package/lib/addons/message-composer.d.ts.map +1 -0
  247. package/lib/addons/message-composer.js +377 -0
  248. package/lib/addons/message-composer.js.map +1 -0
  249. package/lib/addons/message-scheduler.d.ts +77 -0
  250. package/lib/addons/message-scheduler.d.ts.map +1 -0
  251. package/lib/addons/message-scheduler.js +108 -0
  252. package/lib/addons/message-scheduler.js.map +1 -0
  253. package/lib/addons/message-search.d.ts +51 -0
  254. package/lib/addons/message-search.d.ts.map +1 -0
  255. package/lib/addons/message-search.js +171 -0
  256. package/lib/addons/message-search.js.map +1 -0
  257. package/lib/addons/message-utils.d.ts +88 -0
  258. package/lib/addons/message-utils.d.ts.map +1 -0
  259. package/lib/addons/message-utils.js +292 -0
  260. package/lib/addons/message-utils.js.map +1 -0
  261. package/lib/addons/outgoing-calls.d.ts +64 -0
  262. package/lib/addons/outgoing-calls.d.ts.map +1 -0
  263. package/lib/addons/outgoing-calls.js +139 -0
  264. package/lib/addons/outgoing-calls.js.map +1 -0
  265. package/lib/addons/pairing-fix.d.ts +31 -0
  266. package/lib/addons/pairing-fix.d.ts.map +1 -0
  267. package/lib/addons/pairing-fix.js +74 -0
  268. package/lib/addons/pairing-fix.js.map +1 -0
  269. package/lib/addons/past-participants.d.ts +42 -0
  270. package/lib/addons/past-participants.d.ts.map +1 -0
  271. package/lib/addons/past-participants.js +41 -0
  272. package/lib/addons/past-participants.js.map +1 -0
  273. package/lib/addons/rich-response.d.ts +111 -0
  274. package/lib/addons/rich-response.d.ts.map +1 -0
  275. package/lib/addons/rich-response.js +152 -0
  276. package/lib/addons/rich-response.js.map +1 -0
  277. package/lib/addons/scheduling.d.ts +41 -0
  278. package/lib/addons/scheduling.d.ts.map +1 -0
  279. package/lib/addons/scheduling.js +110 -0
  280. package/lib/addons/scheduling.js.map +1 -0
  281. package/lib/addons/status-posting.d.ts +177 -0
  282. package/lib/addons/status-posting.d.ts.map +1 -0
  283. package/lib/addons/status-posting.js +240 -0
  284. package/lib/addons/status-posting.js.map +1 -0
  285. package/lib/addons/stickerpack.d.ts +37 -0
  286. package/lib/addons/stickerpack.d.ts.map +1 -0
  287. package/lib/addons/stickerpack.js +39 -0
  288. package/lib/addons/stickerpack.js.map +1 -0
  289. package/lib/addons/templates.d.ts +72 -0
  290. package/lib/addons/templates.d.ts.map +1 -0
  291. package/lib/addons/templates.js +145 -0
  292. package/lib/addons/templates.js.map +1 -0
  293. package/lib/addons/vcard.d.ts +59 -0
  294. package/lib/addons/vcard.d.ts.map +1 -0
  295. package/lib/addons/vcard.js +88 -0
  296. package/lib/addons/vcard.js.map +1 -0
  297. package/lib/index.d.ts +1 -0
  298. package/lib/index.d.ts.map +1 -1
  299. package/lib/index.js +1 -0
  300. package/lib/index.js.map +1 -1
  301. package/package.json +5 -3
@@ -3,6 +3,7 @@ import { randomBytes } from 'crypto';
3
3
  import { promises as fs } from 'fs';
4
4
  import {} from 'stream';
5
5
  import { proto } from '../../WAProto/index.js';
6
+ import { buildAdminInviteMessage, buildCallMessage, buildPaymentInviteMessage, buildStickerPackMessage } from '../addons/from-messages.js';
6
7
  import { CALL_AUDIO_PREFIX, CALL_VIDEO_PREFIX, MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
7
8
  import { WAMessageStatus, WAProto } from '../Types/index.js';
8
9
  import { isJidGroup, isJidNewsletter, isJidStatusBroadcast, jidNormalizedUser } from '../WABinary/index.js';
@@ -101,19 +102,22 @@ export const prepareWAMessageMedia = async (message, options) => {
101
102
  logger?.info({ key: cacheableKey }, 'Preparing raw media for newsletter');
102
103
  const { filePath, fileSha256, fileLength } = await getRawMediaUploadData(uploadData.media, options.mediaTypeOverride || mediaType, logger);
103
104
  const fileSha256B64 = fileSha256.toString('base64');
104
- const { mediaUrl, directPath } = await options.upload(filePath, {
105
+ const { directPath, thumbnailDirectPath, thumbnailSha256 } = await options.upload(filePath, {
105
106
  fileEncSha256B64: fileSha256B64,
106
107
  mediaType: mediaType,
107
- timeoutMs: options.mediaUploadTimeoutMs
108
+ timeoutMs: options.mediaUploadTimeoutMs,
109
+ newsletter: true
108
110
  });
109
111
  await fs.unlink(filePath);
110
112
  const obj = WAProto.Message.fromObject({
111
113
  // todo: add more support here
112
114
  [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
113
- url: mediaUrl,
115
+ // url intentionally omitted — newsletters use directPath only
114
116
  directPath,
115
117
  fileSha256,
116
118
  fileLength,
119
+ thumbnailDirectPath,
120
+ thumbnailSha256: thumbnailSha256 ? Buffer.from(thumbnailSha256, 'base64') : undefined,
117
121
  ...uploadData,
118
122
  media: undefined
119
123
  })
@@ -133,7 +137,7 @@ export const prepareWAMessageMedia = async (message, options) => {
133
137
  }
134
138
  const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
135
139
  const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && typeof uploadData['jpegThumbnail'] === 'undefined';
136
- const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true;
140
+ const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true && typeof uploadData.waveform === 'undefined';
137
141
  const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
138
142
  const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
139
143
  const { mediaKey, encFilePath, originalFilePath, fileEncSha256, fileSha256, fileLength } = await encryptedStream(uploadData.media, options.mediaTypeOverride || mediaType, {
@@ -155,7 +159,7 @@ export const prepareWAMessageMedia = async (message, options) => {
155
159
  (async () => {
156
160
  try {
157
161
  if (requiresThumbnailComputation) {
158
- const { thumbnail, originalImageDimensions } = await generateThumbnail(originalFilePath, mediaType, options);
162
+ const { thumbnail, originalImageDimensions } = await generateThumbnail(originalFilePath, mediaType, { ...options, hdMode: !!message.hd });
159
163
  uploadData.jpegThumbnail = thumbnail;
160
164
  if (!uploadData.width && originalImageDimensions) {
161
165
  uploadData.width = originalImageDimensions.width;
@@ -386,6 +390,29 @@ export const generateWAMessageContent = async (message, options) => {
386
390
  type: proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT
387
391
  };
388
392
  break;
393
+ case 'list':
394
+ m.listResponseMessage = {
395
+ title: message.buttonReply.title,
396
+ description: message.buttonReply.description,
397
+ singleSelectReply: {
398
+ selectedRowId: message.buttonReply.rowId
399
+ },
400
+ listType: proto.Message.ListResponseMessage.ListType.SINGLE_SELECT
401
+ };
402
+ break;
403
+ case 'interactive':
404
+ m.interactiveResponseMessage = {
405
+ body: {
406
+ text: message.buttonReply.displayText,
407
+ format: proto.Message.InteractiveResponseMessage.Body.Format.EXTENSIONS_1
408
+ },
409
+ nativeFlowResponseMessage: {
410
+ name: message.buttonReply.nativeFlows?.name,
411
+ paramsJson: message.buttonReply.nativeFlows?.paramsJson,
412
+ version: message.buttonReply.nativeFlows?.version
413
+ }
414
+ };
415
+ break;
389
416
  }
390
417
  }
391
418
  else if (hasOptionalProperty(message, 'ptv') && message.ptv) {
@@ -436,10 +463,13 @@ export const generateWAMessageContent = async (message, options) => {
436
463
  statusCode: 400
437
464
  });
438
465
  }
439
- m.messageContextInfo = {
440
- // encKey
441
- messageSecret: message.poll.messageSecret || randomBytes(32)
442
- };
466
+ // messageSecret must NOT be set for newsletter polls —
467
+ // newsletters handle encryption differently and a secret causes send failures
468
+ if (!options.jid || !isJidNewsletter(options.jid)) {
469
+ const providedSecret = message.poll.messageSecret;
470
+ const messageSecret = providedSecret instanceof Uint8Array && providedSecret.length === 32 ? providedSecret : randomBytes(32);
471
+ m.messageContextInfo = { messageSecret };
472
+ }
443
473
  const pollCreationMessage = {
444
474
  name: message.poll.name,
445
475
  selectableOptionsCount: message.poll.selectableCount,
@@ -460,6 +490,31 @@ export const generateWAMessageContent = async (message, options) => {
460
490
  }
461
491
  }
462
492
  }
493
+ else if ('adminInvite' in message && !!message.adminInvite) {
494
+ // addons/from-messages.ts → buildAdminInviteMessage
495
+ m.newsletterAdminInviteMessage = await buildAdminInviteMessage(message.adminInvite, message.contextInfo, options);
496
+ }
497
+ else if ('order' in message && !!message.order) {
498
+ // order → OrderMessage (from addons)
499
+ m.orderMessage = WAProto.Message.OrderMessage.fromObject(message.order);
500
+ }
501
+ else if ('keep' in message && !!message.keep) {
502
+ // keep → KeepInChatMessage (from addons)
503
+ const k = message.keep;
504
+ m.keepInChatMessage = {
505
+ key: k.key,
506
+ keepType: k.type ?? 1,
507
+ timestampMs: k.time ?? Date.now()
508
+ };
509
+ }
510
+ else if ('call' in message && !!message.call) {
511
+ // addons/from-messages.ts → buildCallMessage
512
+ m.scheduledCallCreationMessage = buildCallMessage(message.call);
513
+ }
514
+ else if ('paymentInvite' in message && !!message.paymentInvite) {
515
+ // addons/from-messages.ts → buildPaymentInviteMessage
516
+ m.paymentInviteMessage = buildPaymentInviteMessage(message.paymentInvite);
517
+ }
463
518
  else if (hasNonNullishProperty(message, 'sharePhoneNumber')) {
464
519
  m.protocolMessage = {
465
520
  type: proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
@@ -479,21 +534,377 @@ export const generateWAMessageContent = async (message, options) => {
479
534
  }
480
535
  };
481
536
  }
537
+ else if ('productList' in message && !!message.productList) {
538
+ // productList handled below after this block — just skip media
539
+ }
540
+ else if ('album' in message && !!message.album) {
541
+ // album handled in sendMessage — just set albumMessage header
542
+ const albumOpts = message.album;
543
+ m.albumMessage = {
544
+ expectedImageCount: albumOpts.expectedImageCount,
545
+ expectedVideoCount: albumOpts.expectedVideoCount
546
+ };
547
+ }
548
+ else if ('stickerPack' in message && !!message.stickerPack) {
549
+ // addons/from-messages.ts → buildStickerPackMessage
550
+ m.stickerPackMessage = await buildStickerPackMessage(message.stickerPack, options);
551
+ }
482
552
  else {
483
553
  m = await prepareWAMessageMedia(message, options);
484
554
  }
555
+ // ── productList → ListMessage with products ────────────────────────────────
556
+ if ('productList' in message && !!message.productList) {
557
+ const thumbnail = message.thumbnail
558
+ ? await generateThumbnail(message.thumbnail, 'image', {})
559
+ : null;
560
+ const listMessage = {
561
+ title: message.title,
562
+ buttonText: message.buttonText,
563
+ footerText: message.footer,
564
+ description: message.text,
565
+ productListInfo: {
566
+ productSections: message.productList,
567
+ headerImage: {
568
+ productId: message.productList[0]?.products?.[0]?.productId,
569
+ jpegThumbnail: thumbnail?.thumbnail ?? null
570
+ },
571
+ businessOwnerJid: message.businessOwnerJid
572
+ },
573
+ listType: proto.Message.ListMessage.ListType.PRODUCT_LIST
574
+ };
575
+ listMessage.contextInfo = {
576
+ ...(message.contextInfo || {}),
577
+ ...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
578
+ ...(message.mentionAll ? { nonJidMentions: 1 } : {})
579
+ };
580
+ m = { listMessage };
581
+ }
582
+ // ── sections → ListMessage (standalone if, runs independently like fork) ──
583
+ if ('sections' in message && !!message.sections) {
584
+ const listMessage = {
585
+ title: message.title,
586
+ buttonText: message.buttonText,
587
+ footerText: message.footer,
588
+ description: message.text,
589
+ sections: message.sections,
590
+ listType: proto.Message.ListMessage.ListType.SINGLE_SELECT
591
+ };
592
+ listMessage.contextInfo = {
593
+ ...(message.contextInfo || {}),
594
+ ...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
595
+ ...(message.mentionAll ? { nonJidMentions: 1 } : {})
596
+ };
597
+ m = { listMessage };
598
+ }
599
+ // ── buttons → buttonsMessage ──────────────────────────────────────────────
600
+ else if ('buttons' in message && !!message.buttons) {
601
+ const buttonsMessage = {
602
+ buttons: message.buttons.map((b) => ({
603
+ ...b,
604
+ type: proto.Message.ButtonsMessage.Button.Type.RESPONSE
605
+ }))
606
+ };
607
+ if ('text' in message) {
608
+ buttonsMessage.contentText = message.text;
609
+ buttonsMessage.headerType = proto.Message.ButtonsMessage.HeaderType.EMPTY;
610
+ }
611
+ else {
612
+ if ('caption' in message) {
613
+ buttonsMessage.contentText = message.caption;
614
+ }
615
+ const mediaType = Object.keys(m)[0]?.replace('Message', '').toUpperCase();
616
+ if (mediaType && mediaType in proto.Message.ButtonsMessage.HeaderType) {
617
+ buttonsMessage.headerType =
618
+ proto.Message.ButtonsMessage.HeaderType[mediaType];
619
+ }
620
+ Object.assign(buttonsMessage, m);
621
+ }
622
+ if ('footer' in message && !!message.footer) {
623
+ buttonsMessage.footerText = message.footer;
624
+ }
625
+ if ('title' in message && !!message.title) {
626
+ buttonsMessage.text = message.title;
627
+ buttonsMessage.headerType = proto.Message.ButtonsMessage.HeaderType.TEXT;
628
+ }
629
+ buttonsMessage.contextInfo = {
630
+ ...(message.contextInfo || {}),
631
+ ...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
632
+ ...(message.mentionAll ? { nonJidMentions: 1 } : {})
633
+ };
634
+ m = { buttonsMessage };
635
+ }
636
+ // ── templateButtons → TemplateMessage ─────────────────────────────────────
637
+ else if ('templateButtons' in message && !!message.templateButtons) {
638
+ const hydratedTemplate = {
639
+ hydratedButtons: message.templateButtons
640
+ };
641
+ if ('text' in message) {
642
+ hydratedTemplate.hydratedContentText = message.text;
643
+ }
644
+ else if ('caption' in message) {
645
+ hydratedTemplate.hydratedContentText = message.caption;
646
+ Object.assign(hydratedTemplate, m);
647
+ }
648
+ if ('footer' in message && !!message.footer) {
649
+ hydratedTemplate.hydratedFooterText = message.footer;
650
+ }
651
+ ;
652
+ hydratedTemplate.contextInfo = {
653
+ ...(message.contextInfo || {}),
654
+ ...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
655
+ ...(message.mentionAll ? { nonJidMentions: 1 } : {})
656
+ };
657
+ m = { templateMessage: { hydratedTemplate } };
658
+ }
659
+ // ── interactiveButtons → InteractiveMessage native flow (Android + iOS) ──
660
+ else if ('interactiveButtons' in message && !!message.interactiveButtons) {
661
+ const interactiveMessage = {
662
+ // FIX Bug 2: messageParamsJson: '' is required — without it iOS doesn't render buttons
663
+ nativeFlowMessage: { buttons: message.interactiveButtons, messageParamsJson: '' }
664
+ };
665
+ if ('text' in message) {
666
+ interactiveMessage.body = { text: message.text };
667
+ interactiveMessage.header = {
668
+ title: message.title,
669
+ subtitle: message.subtitle,
670
+ hasMediaAttachment: false
671
+ };
672
+ }
673
+ else if ('caption' in message) {
674
+ interactiveMessage.body = { text: message.caption ?? '' };
675
+ // FIX Bug 1: Object.assign(interactiveMessage, m) was mutating interactiveMessage
676
+ // AND spreading the whole corrupted object into header — completely broken.
677
+ // Correct fix: extract only the media fields from m and place them in header.
678
+ interactiveMessage.header = {
679
+ title: message.title,
680
+ subtitle: message.subtitle,
681
+ hasMediaAttachment: !!(m.imageMessage || m.videoMessage || m.documentMessage),
682
+ imageMessage: m.imageMessage ?? undefined,
683
+ videoMessage: m.videoMessage ?? undefined,
684
+ documentMessage: m.documentMessage ?? undefined
685
+ };
686
+ }
687
+ if ('footer' in message && !!message.footer) {
688
+ interactiveMessage.footer = { text: message.footer };
689
+ }
690
+ interactiveMessage.contextInfo = {
691
+ ...(message.contextInfo || {}),
692
+ ...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
693
+ ...(message.mentionAll ? { nonJidMentions: 1 } : {})
694
+ };
695
+ m = { interactiveMessage };
696
+ }
697
+ // ── shop → InteractiveMessage (shopStorefrontMessage) ─────────────────────
698
+ else if ('shop' in message && !!message.shop) {
699
+ const interactiveMessage = {
700
+ shopStorefrontMessage: {
701
+ surface: message.shop.surface,
702
+ id: message.shop.id
703
+ }
704
+ };
705
+ if ('text' in message) {
706
+ interactiveMessage.body = { text: message.text };
707
+ interactiveMessage.header = {
708
+ title: message.title,
709
+ subtitle: message.subtitle,
710
+ hasMediaAttachment: false
711
+ };
712
+ }
713
+ else if ('caption' in message) {
714
+ interactiveMessage.body = { text: message.caption ?? '' };
715
+ // FIX Bug 1: same Object.assign corruption as interactiveButtons — fixed
716
+ interactiveMessage.header = {
717
+ title: message.title,
718
+ subtitle: message.subtitle,
719
+ hasMediaAttachment: !!(m.imageMessage || m.videoMessage || m.documentMessage),
720
+ imageMessage: m.imageMessage ?? undefined,
721
+ videoMessage: m.videoMessage ?? undefined,
722
+ documentMessage: m.documentMessage ?? undefined
723
+ };
724
+ }
725
+ if ('footer' in message && !!message.footer) {
726
+ interactiveMessage.footer = { text: message.footer };
727
+ }
728
+ interactiveMessage.contextInfo = {
729
+ ...(message.contextInfo || {}),
730
+ ...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
731
+ ...(message.mentionAll ? { nonJidMentions: 1 } : {})
732
+ };
733
+ m = { interactiveMessage };
734
+ }
735
+ // ── collection → InteractiveMessage (collectionMessage) ───────────────────
736
+ else if ('collection' in message && !!message.collection) {
737
+ const interactiveMessage = {
738
+ collectionMessage: {
739
+ bizJid: message.collection.bizJid,
740
+ id: message.collection.id,
741
+ messageVersion: message.collection.version ?? message.collection.messageVersion
742
+ }
743
+ };
744
+ if ('text' in message) {
745
+ interactiveMessage.body = { text: message.text };
746
+ interactiveMessage.header = {
747
+ title: message.title,
748
+ subtitle: message.subtitle,
749
+ hasMediaAttachment: false
750
+ };
751
+ }
752
+ else if ('caption' in message) {
753
+ interactiveMessage.body = { text: message.caption ?? '' };
754
+ // FIX Bug 1: same Object.assign corruption — fixed
755
+ interactiveMessage.header = {
756
+ title: message.title,
757
+ subtitle: message.subtitle,
758
+ hasMediaAttachment: !!(m.imageMessage || m.videoMessage || m.documentMessage),
759
+ imageMessage: m.imageMessage ?? undefined,
760
+ videoMessage: m.videoMessage ?? undefined,
761
+ documentMessage: m.documentMessage ?? undefined
762
+ };
763
+ }
764
+ if ('footer' in message && !!message.footer) {
765
+ interactiveMessage.footer = { text: message.footer };
766
+ }
767
+ interactiveMessage.contextInfo = {
768
+ ...(message.contextInfo || {}),
769
+ ...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
770
+ ...(message.mentionAll ? { nonJidMentions: 1 } : {})
771
+ };
772
+ m = { interactiveMessage };
773
+ }
774
+ // ── cards → InteractiveMessage (carouselMessage, wrapped in viewOnce) ──────
775
+ else if ('cards' in message && !!message.cards) {
776
+ const normalizeMedia = (media) => {
777
+ if (!media)
778
+ return undefined;
779
+ if (Buffer.isBuffer(media))
780
+ return media;
781
+ if (typeof media === 'string')
782
+ return { url: media };
783
+ return media;
784
+ };
785
+ const slides = await Promise.all(message.cards.map(async (slide) => {
786
+ const { image, video, document: doc, product, title, body, footer, buttons } = slide;
787
+ let header = {};
788
+ if (product) {
789
+ const { imageMessage } = await prepareWAMessageMedia({ image: normalizeMedia(product.productImage) }, options);
790
+ header.productMessage = { product: { ...product, productImage: imageMessage } };
791
+ }
792
+ else if (image) {
793
+ const prepared = await prepareWAMessageMedia({ image: normalizeMedia(image) }, options);
794
+ if (prepared.imageMessage)
795
+ prepared.imageMessage.viewOnce = true;
796
+ header = prepared;
797
+ }
798
+ else if (video) {
799
+ const prepared = await prepareWAMessageMedia({ video: normalizeMedia(video) }, options);
800
+ if (prepared.videoMessage) {
801
+ prepared.videoMessage.viewOnce = true;
802
+ prepared.videoMessage.gifPlayback = false;
803
+ }
804
+ header = prepared;
805
+ }
806
+ else if (doc) {
807
+ const prepared = await prepareWAMessageMedia({
808
+ document: normalizeMedia(doc),
809
+ mimetype: slide.mimetype || 'application/octet-stream',
810
+ fileName: slide.fileName
811
+ }, options);
812
+ header = prepared;
813
+ }
814
+ const headerProps = {
815
+ title,
816
+ hasMediaAttachment: !!(header.imageMessage ||
817
+ header.videoMessage ||
818
+ header.documentMessage ||
819
+ header.productMessage),
820
+ ...header
821
+ };
822
+ return WAProto.Message.InteractiveMessage.create({
823
+ header: WAProto.Message.InteractiveMessage.Header.create(headerProps),
824
+ body: WAProto.Message.InteractiveMessage.Body.create({ text: body }),
825
+ footer: WAProto.Message.InteractiveMessage.Footer.create({ text: footer }),
826
+ nativeFlowMessage: WAProto.Message.InteractiveMessage.NativeFlowMessage.create({
827
+ buttons: buttons ?? []
828
+ })
829
+ });
830
+ }));
831
+ const interactiveMessage = {
832
+ carouselMessage: WAProto.Message.InteractiveMessage.CarouselMessage.create({ cards: slides })
833
+ };
834
+ if ('text' in message) {
835
+ interactiveMessage.body = WAProto.Message.InteractiveMessage.Body.create({
836
+ text: message.text ?? ''
837
+ });
838
+ interactiveMessage.header = WAProto.Message.InteractiveMessage.Header.create({
839
+ title: message.title,
840
+ subtitle: message.subtitle,
841
+ hasMediaAttachment: false
842
+ });
843
+ }
844
+ if ('footer' in message && !!message.footer) {
845
+ interactiveMessage.footer = WAProto.Message.InteractiveMessage.Footer.create({
846
+ text: message.footer ?? ''
847
+ });
848
+ }
849
+ interactiveMessage.contextInfo = {
850
+ ...(message.contextInfo || {}),
851
+ ...(message.mentions?.length ? { mentionedJid: message.mentions } : {}),
852
+ ...(message.mentionAll ? { nonJidMentions: 1 } : {})
853
+ };
854
+ // Wrap in viewOnceMessage matching innovators pattern for correct WA rendering
855
+ m = { interactiveMessage };
856
+ }
485
857
  if (hasOptionalProperty(message, 'viewOnce') && !!message.viewOnce) {
486
858
  m = { viewOnceMessage: { message: m } };
487
859
  }
488
- if (hasOptionalProperty(message, 'mentions') && message.mentions?.length) {
860
+ // ── viewOnceExt viewOnceMessageV2Extension ──────────────────────────────
861
+ if (hasOptionalProperty(message, 'viewOnceExt') && !!message.viewOnceExt) {
862
+ m = { viewOnceMessageV2Extension: { message: m } };
863
+ }
864
+ // ── groupStatus → groupStatusMessageV2 ────────────────────────────────────
865
+ if (hasOptionalProperty(message, 'groupStatus') && !!message.groupStatus) {
489
866
  const messageType = Object.keys(m)[0];
867
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
490
868
  const key = m[messageType];
491
- if ('contextInfo' in key && !!key.contextInfo) {
492
- key.contextInfo.mentionedJid = message.mentions;
869
+ if (key && 'contextInfo' in key && !!key.contextInfo) {
870
+ key.contextInfo.isGroupStatus = message.groupStatus;
871
+ }
872
+ else if (key) {
873
+ key.contextInfo = { isGroupStatus: message.groupStatus };
874
+ }
875
+ m = { groupStatusMessageV2: { message: m } };
876
+ }
877
+ // ── interactiveAsTemplate → templateMessage.interactiveMessageTemplate ────
878
+ // FIX Bug 4: was `else if` — so it was silently skipped whenever groupStatus was set.
879
+ // Must be an independent `if` so both can apply independently.
880
+ if (hasOptionalProperty(message, 'interactiveAsTemplate') && !!message.interactiveAsTemplate) {
881
+ if (!m.interactiveMessage) {
882
+ throw new Boom('Invalid message type for template', { statusCode: 400 });
883
+ }
884
+ m = {
885
+ templateMessage: {
886
+ interactiveMessageTemplate: m.interactiveMessage,
887
+ templateId: message.id || `template-${Date.now()}`
888
+ }
889
+ };
890
+ }
891
+ if ((hasOptionalProperty(message, 'mentions') && message.mentions?.length) ||
892
+ (hasOptionalProperty(message, 'mentionAll') && message.mentionAll)) {
893
+ const messageType = Object.keys(m)[0];
894
+ const key = m[messageType];
895
+ if (key && 'contextInfo' in key) {
896
+ key.contextInfo = key.contextInfo || {};
897
+ if (message.mentions?.length) {
898
+ key.contextInfo.mentionedJid = message.mentions;
899
+ }
900
+ if (message.mentionAll) {
901
+ key.contextInfo.nonJidMentions = 1;
902
+ }
493
903
  }
494
904
  else if (key) {
495
905
  key.contextInfo = {
496
- mentionedJid: message.mentions
906
+ mentionedJid: message.mentions,
907
+ nonJidMentions: message.mentionAll ? 1 : 0
497
908
  };
498
909
  }
499
910
  }
@@ -517,6 +928,15 @@ export const generateWAMessageContent = async (message, options) => {
517
928
  key.contextInfo = message.contextInfo;
518
929
  }
519
930
  }
931
+ if (hasOptionalProperty(message, 'albumParentKey') && !!message.albumParentKey) {
932
+ m.messageContextInfo = {
933
+ ...m.messageContextInfo,
934
+ messageAssociation: {
935
+ associationType: WAProto.MessageAssociation.AssociationType.MEDIA_ALBUM,
936
+ parentMessageKey: message.albumParentKey
937
+ }
938
+ };
939
+ }
520
940
  if (shouldIncludeReportingToken(m)) {
521
941
  m.messageContextInfo = m.messageContextInfo || {};
522
942
  if (!m.messageContextInfo.messageSecret) {