@badzz88/baileys 8.5.4 → 8.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/README.md +2 -2
  2. package/WAProto/fix-imports.js +69 -79
  3. package/WAProto/index.d.ts +15305 -87935
  4. package/WAProto/index.js +41109 -194076
  5. package/engine-requirements.js +15 -8
  6. package/package.json +23 -19
  7. package/src/Defaults/index.js +186 -0
  8. package/src/Signal/Group/ciphertext-message.js +15 -0
  9. package/src/Signal/Group/group-session-builder.js +86 -0
  10. package/src/Signal/Group/group_cipher.js +82 -0
  11. package/src/Signal/Group/index.js +140 -0
  12. package/src/Signal/Group/keyhelper.js +77 -0
  13. package/src/Signal/Group/sender-chain-key.js +29 -0
  14. package/src/Signal/Group/sender-key-distribution-message.js +66 -0
  15. package/src/Signal/Group/sender-key-message.js +69 -0
  16. package/src/Signal/Group/sender-key-name.js +51 -0
  17. package/src/Signal/Group/sender-key-record.js +44 -0
  18. package/src/Signal/Group/sender-key-state.js +87 -0
  19. package/src/Signal/Group/sender-message-key.js +29 -0
  20. package/src/Signal/libsignal.js +455 -0
  21. package/src/Signal/lid-mapping.js +273 -0
  22. package/src/Socket/Client/index.js +31 -0
  23. package/src/Socket/Client/types.js +13 -0
  24. package/src/Socket/Client/websocket.js +61 -0
  25. package/src/Socket/aigroups.js +221 -0
  26. package/src/Socket/business.js +411 -0
  27. package/src/Socket/chats.js +1449 -0
  28. package/src/Socket/communities.js +463 -0
  29. package/src/Socket/graphql.js +523 -0
  30. package/src/Socket/groups.js +516 -0
  31. package/src/Socket/index.js +31 -0
  32. package/src/Socket/interactive-handler.js +527 -0
  33. package/src/Socket/interop.js +339 -0
  34. package/src/Socket/luxu.js +349 -0
  35. package/src/Socket/managed-account.js +98 -0
  36. package/src/Socket/messages-recv.js +2685 -0
  37. package/src/Socket/messages-send.js +2047 -0
  38. package/src/Socket/mex.js +57 -0
  39. package/src/Socket/newsletter.js +455 -0
  40. package/src/Socket/privacy.js +125 -0
  41. package/src/Socket/registration.js +236 -0
  42. package/src/Socket/socket.js +983 -0
  43. package/src/Socket/text-router.js +65 -0
  44. package/src/Socket/username.js +130 -0
  45. package/src/Store/index.js +33 -0
  46. package/src/Store/keyed-db.js +118 -0
  47. package/src/Store/make-cache-manager-store.js +84 -0
  48. package/src/Store/make-in-memory-store.js +551 -0
  49. package/src/Store/make-ordered-dictionary.js +81 -0
  50. package/src/Store/object-repository.js +26 -0
  51. package/src/Types/Auth.js +31 -0
  52. package/src/Types/Bussines.js +2 -0
  53. package/src/Types/Call.js +2 -0
  54. package/src/Types/Chat.js +4 -0
  55. package/src/Types/Contact.js +2 -0
  56. package/src/Types/Events.js +2 -0
  57. package/src/Types/GroupMetadata.js +2 -0
  58. package/src/Types/Label.js +26 -0
  59. package/src/Types/LabelAssociation.js +8 -0
  60. package/src/Types/Message.js +93 -0
  61. package/src/Types/Mex.js +112 -0
  62. package/src/Types/Newsletter.js +109 -0
  63. package/src/Types/Product.js +2 -0
  64. package/src/Types/Signal.js +2 -0
  65. package/src/Types/Socket.js +2 -0
  66. package/src/Types/State.js +62 -0
  67. package/src/Types/USync.js +2 -0
  68. package/src/Types/index.js +56 -0
  69. package/src/Utils/auth-utils.js +254 -0
  70. package/src/Utils/browser-utils.js +112 -0
  71. package/src/Utils/business.js +240 -0
  72. package/src/Utils/chat-utils.js +1230 -0
  73. package/src/Utils/command-loader.d.ts +27 -0
  74. package/src/Utils/command-loader.js +89 -0
  75. package/src/Utils/companion-reg-client-utils.js +40 -0
  76. package/src/Utils/consumer-application.js +105 -0
  77. package/src/Utils/crypto.js +118 -0
  78. package/src/Utils/curve25519-js.js +242 -0
  79. package/src/Utils/decode-wa-message.js +529 -0
  80. package/src/Utils/event-buffer.js +580 -0
  81. package/src/Utils/generics.js +483 -0
  82. package/src/Utils/group-history.js +44 -0
  83. package/src/Utils/history.js +232 -0
  84. package/src/Utils/identity-change-handler.js +52 -0
  85. package/src/Utils/index.js +58 -0
  86. package/src/Utils/jid-display-normalization.js +195 -0
  87. package/src/Utils/link-preview.js +135 -0
  88. package/src/Utils/logger.js +8 -0
  89. package/src/Utils/lt-hash.js +25 -0
  90. package/src/Utils/make-mutex.js +36 -0
  91. package/src/Utils/message-composer.js +471 -0
  92. package/src/Utils/message-retry-manager.js +217 -0
  93. package/src/Utils/messages-media.js +843 -0
  94. package/src/Utils/messages.js +2817 -0
  95. package/src/Utils/meta-ai-msmsg.js +222 -0
  96. package/src/Utils/native-bridge.js +68 -0
  97. package/src/Utils/noise-handler.js +169 -0
  98. package/src/Utils/offline-node-processor.js +34 -0
  99. package/src/Utils/pre-key-manager.js +90 -0
  100. package/src/Utils/process-message.js +950 -0
  101. package/src/Utils/reporting-utils.js +261 -0
  102. package/src/Utils/session-pool.d.ts +14 -0
  103. package/src/Utils/session-pool.js +70 -0
  104. package/src/Utils/signal.js +217 -0
  105. package/src/Utils/stanza-ack.js +30 -0
  106. package/src/Utils/sticker.d.ts +13 -0
  107. package/src/Utils/sticker.js +123 -0
  108. package/src/Utils/sync-action-utils.js +45 -0
  109. package/src/Utils/tc-token-utils.js +158 -0
  110. package/src/Utils/use-multi-file-auth-state.js +111 -0
  111. package/src/Utils/validate-connection.js +209 -0
  112. package/src/Utils/view-once-cache.d.ts +12 -0
  113. package/src/Utils/view-once-cache.js +63 -0
  114. package/src/Utils/voip-rekey.js +22 -0
  115. package/src/WABinary/constants.js +1304 -0
  116. package/src/WABinary/decode.js +342 -0
  117. package/src/WABinary/encode.js +225 -0
  118. package/src/WABinary/generic-utils.js +238 -0
  119. package/src/WABinary/index.js +34 -0
  120. package/src/WABinary/jid-utils.js +351 -0
  121. package/src/WABinary/types.js +2 -0
  122. package/src/WAM/BinaryInfo.js +13 -0
  123. package/src/WAM/constants.js +39484 -0
  124. package/src/WAM/encode.js +149 -0
  125. package/src/WAM/index.js +32 -0
  126. package/src/WAUSync/Protocols/USyncBotProfileProtocol.js +53 -0
  127. package/src/WAUSync/Protocols/USyncBusinessProtocol.js +44 -0
  128. package/src/WAUSync/Protocols/USyncContactProtocol.js +55 -0
  129. package/src/WAUSync/Protocols/USyncDeviceProtocol.js +55 -0
  130. package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.js +31 -0
  131. package/src/WAUSync/Protocols/USyncFeatureProtocol.js +54 -0
  132. package/src/WAUSync/Protocols/USyncLIDProtocol.js +32 -0
  133. package/src/WAUSync/Protocols/USyncNewsletterProtocol.js +473 -0
  134. package/src/WAUSync/Protocols/USyncPictureProtocol.js +34 -0
  135. package/src/WAUSync/Protocols/USyncSidelistProtocol.js +29 -0
  136. package/src/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  137. package/src/WAUSync/Protocols/USyncTextStatusProtocol.js +38 -0
  138. package/src/WAUSync/Protocols/USyncUsernameProtocol.js +28 -0
  139. package/src/WAUSync/Protocols/index.js +40 -0
  140. package/src/WAUSync/USyncQuery.js +126 -0
  141. package/src/WAUSync/USyncUser.js +50 -0
  142. package/src/WAUSync/index.js +32 -0
  143. package/src/antiban.js +4152 -0
  144. package/{lib → src}/index.js +51 -49
  145. package/lib/Defaults/index.js +0 -195
  146. package/lib/Signal/Group/ciphertext-message.js +0 -15
  147. package/lib/Signal/Group/group-session-builder.js +0 -92
  148. package/lib/Signal/Group/group_cipher.js +0 -89
  149. package/lib/Signal/Group/index.js +0 -136
  150. package/lib/Signal/Group/keyhelper.js +0 -73
  151. package/lib/Signal/Group/sender-chain-key.js +0 -32
  152. package/lib/Signal/Group/sender-key-distribution-message.js +0 -66
  153. package/lib/Signal/Group/sender-key-message.js +0 -69
  154. package/lib/Signal/Group/sender-key-name.js +0 -50
  155. package/lib/Signal/Group/sender-key-record.js +0 -44
  156. package/lib/Signal/Group/sender-key-state.js +0 -97
  157. package/lib/Signal/Group/sender-message-key.js +0 -30
  158. package/lib/Signal/libsignal.js +0 -470
  159. package/lib/Signal/lid-mapping.js +0 -280
  160. package/lib/Socket/Client/index.js +0 -30
  161. package/lib/Socket/Client/types.js +0 -13
  162. package/lib/Socket/Client/websocket.js +0 -62
  163. package/lib/Socket/aigroups.js +0 -240
  164. package/lib/Socket/business.js +0 -414
  165. package/lib/Socket/chats.js +0 -2165
  166. package/lib/Socket/communities.js +0 -545
  167. package/lib/Socket/graphql.js +0 -863
  168. package/lib/Socket/groups.js +0 -685
  169. package/lib/Socket/index.js +0 -41
  170. package/lib/Socket/interactive-handler.js +0 -579
  171. package/lib/Socket/interop.js +0 -430
  172. package/lib/Socket/managed-account.js +0 -214
  173. package/lib/Socket/messages-recv.js +0 -3000
  174. package/lib/Socket/messages-send.js +0 -2155
  175. package/lib/Socket/mex.js +0 -47
  176. package/lib/Socket/newsletter.js +0 -814
  177. package/lib/Socket/privacy.js +0 -261
  178. package/lib/Socket/registration.js +0 -434
  179. package/lib/Socket/socket.js +0 -1074
  180. package/lib/Socket/username.js +0 -160
  181. package/lib/Store/index.js +0 -36
  182. package/lib/Store/make-cache-manager-store.js +0 -90
  183. package/lib/Store/make-in-memory-store.js +0 -488
  184. package/lib/Store/make-ordered-dictionary.js +0 -81
  185. package/lib/Store/object-repository.js +0 -29
  186. package/lib/Types/Auth.js +0 -38
  187. package/lib/Types/Bussines.js +0 -2
  188. package/lib/Types/Call.js +0 -2
  189. package/lib/Types/Chat.js +0 -4
  190. package/lib/Types/Contact.js +0 -2
  191. package/lib/Types/Events.js +0 -2
  192. package/lib/Types/GroupMetadata.js +0 -2
  193. package/lib/Types/Label.js +0 -27
  194. package/lib/Types/LabelAssociation.js +0 -9
  195. package/lib/Types/Message.js +0 -95
  196. package/lib/Types/Newsletter.js +0 -152
  197. package/lib/Types/Product.js +0 -2
  198. package/lib/Types/Signal.js +0 -2
  199. package/lib/Types/Socket.js +0 -2
  200. package/lib/Types/State.js +0 -70
  201. package/lib/Types/USync.js +0 -2
  202. package/lib/Types/index.js +0 -55
  203. package/lib/Utils/auth-utils.js +0 -301
  204. package/lib/Utils/browser-utils.js +0 -114
  205. package/lib/Utils/business.js +0 -243
  206. package/lib/Utils/chat-utils.js +0 -1272
  207. package/lib/Utils/consumer-application.js +0 -107
  208. package/lib/Utils/crypto.js +0 -125
  209. package/lib/Utils/decode-wa-message.js +0 -793
  210. package/lib/Utils/event-buffer.js +0 -583
  211. package/lib/Utils/generics.js +0 -617
  212. package/lib/Utils/group-history.js +0 -51
  213. package/lib/Utils/history.js +0 -244
  214. package/lib/Utils/identity-change-handler.js +0 -52
  215. package/lib/Utils/index.js +0 -53
  216. package/lib/Utils/jid-display-normalization.js +0 -218
  217. package/lib/Utils/link-preview.js +0 -138
  218. package/lib/Utils/logger.js +0 -9
  219. package/lib/Utils/lt-hash.js +0 -6
  220. package/lib/Utils/make-mutex.js +0 -36
  221. package/lib/Utils/message-composer.js +0 -479
  222. package/lib/Utils/message-inspect.js +0 -393
  223. package/lib/Utils/message-retry-manager.js +0 -205
  224. package/lib/Utils/messages-media.js +0 -925
  225. package/lib/Utils/messages.js +0 -2482
  226. package/lib/Utils/meta-ai-msmsg.js +0 -122
  227. package/lib/Utils/noise-handler.js +0 -194
  228. package/lib/Utils/offline-node-processor.js +0 -37
  229. package/lib/Utils/pre-key-manager.js +0 -97
  230. package/lib/Utils/process-message.js +0 -1139
  231. package/lib/Utils/reporting-utils.js +0 -262
  232. package/lib/Utils/signal.js +0 -189
  233. package/lib/Utils/stanza-ack.js +0 -67
  234. package/lib/Utils/sync-action-utils.js +0 -51
  235. package/lib/Utils/tc-token-utils.js +0 -156
  236. package/lib/Utils/use-multi-file-auth-state.js +0 -137
  237. package/lib/Utils/validate-connection.js +0 -259
  238. package/lib/Utils/voip-rekey.js +0 -22
  239. package/lib/WABinary/constants.js +0 -1304
  240. package/lib/WABinary/decode.js +0 -377
  241. package/lib/WABinary/encode.js +0 -58
  242. package/lib/WABinary/generic-utils.js +0 -150
  243. package/lib/WABinary/index.js +0 -33
  244. package/lib/WABinary/jid-utils.js +0 -374
  245. package/lib/WABinary/types.js +0 -2
  246. package/lib/WAM/BinaryInfo.js +0 -13
  247. package/lib/WAM/constants.js +0 -39486
  248. package/lib/WAM/encode.js +0 -142
  249. package/lib/WAM/index.js +0 -31
  250. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +0 -55
  251. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +0 -100
  252. package/lib/WAUSync/Protocols/USyncContactProtocol.js +0 -60
  253. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +0 -65
  254. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +0 -27
  255. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +0 -72
  256. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +0 -31
  257. package/lib/WAUSync/Protocols/USyncNewsletterProtocol.js +0 -865
  258. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +0 -32
  259. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +0 -29
  260. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +0 -44
  261. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +0 -38
  262. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +0 -28
  263. package/lib/WAUSync/Protocols/index.js +0 -40
  264. package/lib/WAUSync/USyncBackoff.js +0 -26
  265. package/lib/WAUSync/USyncQuery.js +0 -204
  266. package/lib/WAUSync/USyncUser.js +0 -58
  267. package/lib/WAUSync/index.js +0 -32
  268. package/lib/antiban.js +0 -4391
  269. /package/{lib → src}/Defaults/phonenumber-mcc.json +0 -0
@@ -1,2482 +0,0 @@
1
- 'use strict'
2
- Object.defineProperty(exports, '__esModule', { value: true })
3
- exports.generateWAMessage =
4
- exports.generateWAMessageFromContent =
5
- exports.generateWAMessageContent =
6
- exports.hasNonNullishProperty =
7
- exports.generateForwardMessageContent =
8
- exports.prepareDisappearingMessageSettingContent =
9
- exports.prepareWAMessageMedia =
10
- exports.generateLinkPreviewIfRequired =
11
- exports.extractUrlFromText =
12
- void 0
13
- const boom_1 = require('@hapi/boom')
14
- const crypto_1 = require('crypto')
15
- const fs_1 = require('fs')
16
- const lru_cache_1 = require('lru-cache')
17
- const WAProto_1 = require('../../WAProto/index.js')
18
- const Defaults_1 = require('../Defaults')
19
- const Types_1 = require('../Types')
20
- const WABinary_1 = require('../WABinary')
21
- const crypto_2 = require('./crypto')
22
- const generics_1 = require('./generics')
23
- const messages_media_1 = require('./messages-media')
24
- const reporting_utils_1 = require('./reporting-utils')
25
- const jid_display_normalization_1 = require('./jid-display-normalization')
26
- const message_inspect_1 = require('./message-inspect')
27
- Object.assign(exports, message_inspect_1)
28
-
29
-
30
-
31
- const groupInviteThumbnailCache = new lru_cache_1.LRUCache({ max: 100, ttl: 5 * 60 * 1000 })
32
- const MIMETYPE_MAP = {
33
- image: 'image/jpeg',
34
- video: 'video/mp4',
35
- document: 'application/pdf',
36
- audio: 'audio/ogg; codecs=opus',
37
- sticker: 'image/webp',
38
- 'product-catalog-image': 'image/jpeg'
39
- }
40
- const MessageTypeProto = {
41
- image: WAProto_1.proto.Message.ImageMessage,
42
- video: WAProto_1.proto.Message.VideoMessage,
43
- audio: WAProto_1.proto.Message.AudioMessage,
44
- sticker: WAProto_1.proto.Message.StickerMessage,
45
- document: WAProto_1.proto.Message.DocumentMessage
46
- }
47
-
48
-
49
- const MEDIA_MESSAGE_TYPE_ALIASES = {
50
- imageMessage: 'image',
51
- videoMessage: 'video',
52
- audioMessage: 'audio',
53
- documentMessage: 'document',
54
- stickerMessage: 'sticker',
55
-
56
- ptvMessage: 'video'
57
- }
58
- const MEDIA_MESSAGE_TYPE_ALIAS_KEYS = Object.keys(MEDIA_MESSAGE_TYPE_ALIASES)
59
- const hasMediaPayload = message =>
60
- Defaults_1.MEDIA_KEYS.some(key => key in message) || MEDIA_MESSAGE_TYPE_ALIAS_KEYS.some(key => key in message)
61
-
62
- const ButtonType = WAProto_1.proto.Message.ButtonsMessage.HeaderType
63
-
64
- const RICH_RESPONSE_CODE_KEYWORDS = new Set([
65
- 'break',
66
- 'case',
67
- 'catch',
68
- 'continue',
69
- 'debugger',
70
- 'default',
71
- 'delete',
72
- 'do',
73
- 'else',
74
- 'finally',
75
- 'for',
76
- 'function',
77
- 'if',
78
- 'in',
79
- 'instanceof',
80
- 'new',
81
- 'return',
82
- 'switch',
83
- 'this',
84
- 'throw',
85
- 'try',
86
- 'typeof',
87
- 'var',
88
- 'void',
89
- 'while',
90
- 'with',
91
- 'true',
92
- 'false',
93
- 'null',
94
- 'undefined',
95
- 'NaN',
96
- 'Infinity',
97
- 'class',
98
- 'const',
99
- 'let',
100
- 'super',
101
- 'extends',
102
- 'export',
103
- 'import',
104
- 'yield',
105
- 'static',
106
- 'constructor',
107
- 'of',
108
- 'async',
109
- 'await',
110
- 'get',
111
- 'set',
112
- 'implements',
113
- 'interface',
114
- 'package',
115
- 'private',
116
- 'protected',
117
- 'public',
118
- 'enum',
119
- 'throws',
120
- 'transient'
121
- ])
122
- const tokenizeCode = code => {
123
- const tokens = []
124
- let i = 0
125
- const len = code.length
126
- while (i < len) {
127
- if (/\s/.test(code[i])) {
128
- const start = i
129
- while (i < len && /\s/.test(code[i])) i++
130
- tokens.push({ content: code.slice(start, i), type: 'DEFAULT' })
131
- continue
132
- }
133
- if (code[i] === '"' || code[i] === "'" || code[i] === '`') {
134
- const start = i
135
- const quote = code[i]
136
- i++
137
- while (i < len && code[i] !== quote) {
138
- if (code[i] === '\\') i++
139
- i++
140
- }
141
- i++
142
- tokens.push({ content: code.slice(start, i), type: 'STR' })
143
- continue
144
- }
145
- if (code[i] === '/' && i + 1 < len && code[i + 1] === '/') {
146
- const start = i
147
- while (i < len && code[i] !== '\n') i++
148
- tokens.push({ content: code.slice(start, i), type: 'COMMENT' })
149
- continue
150
- }
151
- if (code[i] === '/' && i + 1 < len && code[i + 1] === '*') {
152
- const start = i
153
- i += 2
154
- while (i + 1 < len && !(code[i] === '*' && code[i + 1] === '/')) i++
155
- i += 2
156
- tokens.push({ content: code.slice(start, i), type: 'COMMENT' })
157
- continue
158
- }
159
- if (/[0-9]/.test(code[i])) {
160
- const start = i
161
- while (i < len && /[0-9.]/.test(code[i])) i++
162
- tokens.push({ content: code.slice(start, i), type: 'NUMBER' })
163
- continue
164
- }
165
- if (/[a-zA-Z_$]/.test(code[i])) {
166
- const start = i
167
- while (i < len && /[a-zA-Z0-9_$]/.test(code[i])) i++
168
- const word = code.slice(start, i)
169
- if (RICH_RESPONSE_CODE_KEYWORDS.has(word)) {
170
- tokens.push({ content: word, type: 'KEYWORD' })
171
- } else {
172
- let j = i
173
- while (j < len && /\s/.test(code[j])) j++
174
- tokens.push({ content: word, type: j < len && code[j] === '(' ? 'METHOD' : 'DEFAULT' })
175
- }
176
- continue
177
- }
178
- tokens.push({ content: code[i], type: 'DEFAULT' })
179
- i++
180
- }
181
- const merged = []
182
- for (const t of tokens) {
183
- if (merged.length && merged[merged.length - 1].type === 'DEFAULT' && t.type === 'DEFAULT') {
184
- merged[merged.length - 1].content += t.content
185
- } else {
186
- merged.push(t)
187
- }
188
- }
189
- return merged
190
- }
191
-
192
-
193
- const extractUrlFromText = text => text.match(Defaults_1.URL_REGEX)?.[0]
194
- exports.extractUrlFromText = extractUrlFromText
195
- const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
196
- const url = (0, exports.extractUrlFromText)(text)
197
- if (!!getUrlInfo && url) {
198
- try {
199
- const urlInfo = await getUrlInfo(url)
200
- return urlInfo
201
- } catch (error) {
202
-
203
- logger?.warn({ trace: error.stack }, 'url generation failed')
204
- }
205
- }
206
- }
207
- exports.generateLinkPreviewIfRequired = generateLinkPreviewIfRequired
208
- const assertColor = async color => {
209
- let assertedColor
210
- if (typeof color === 'number') {
211
- assertedColor = color > 0 ? color : 0xffffffff + Number(color) + 1
212
- } else {
213
- let hex = color.trim().replace('#', '')
214
- if (hex.length <= 6) {
215
- hex = 'FF' + hex.padStart(6, '0')
216
- }
217
- assertedColor = parseInt(hex, 16)
218
- return assertedColor
219
- }
220
- }
221
- const prepareWAMessageMedia = async (message, options) => {
222
- const logger = options.logger
223
-
224
- const mediaAbProps = options.mediaAbProps || null
225
- const getMediaProp = propName => (0, messages_media_1.getMediaProp)(mediaAbProps, propName)
226
- let mediaType
227
- for (const key of Defaults_1.MEDIA_KEYS) {
228
- if (key in message) {
229
- mediaType = key
230
- }
231
- }
232
- if (!mediaType) {
233
- throw new boom_1.Boom('Invalid media type', { statusCode: 400 })
234
- }
235
- const uploadData = {
236
- ...message,
237
- media: message[mediaType]
238
- }
239
- delete uploadData[mediaType]
240
-
241
-
242
-
243
-
244
- if (mediaType === 'video' && uploadData.mimetype) {
245
- const isHevc = uploadData.mimetype.includes('hevc') || uploadData.mimetype.includes('x-matroska')
246
- if (isHevc && !getMediaProp('hevc_video_dual_upload')) {
247
-
248
- uploadData.mimetype = MIMETYPE_MAP['video']
249
- }
250
-
251
- }
252
-
253
-
254
- const cacheableKey =
255
- typeof uploadData.media === 'object' &&
256
- 'url' in uploadData.media &&
257
- !!uploadData.media.url &&
258
- !!options.mediaCache &&
259
- mediaType + ':' + uploadData.media.url.toString()
260
- if (mediaType === 'document' && !uploadData.fileName) {
261
- uploadData.fileName = 'file'
262
- }
263
- if (!uploadData.mimetype) {
264
- uploadData.mimetype = MIMETYPE_MAP[mediaType]
265
- }
266
- if (cacheableKey) {
267
- const mediaBuff = await options.mediaCache.get(cacheableKey)
268
- if (mediaBuff) {
269
- logger?.debug({ cacheableKey }, 'got media cache hit')
270
- const obj = WAProto_1.proto.Message.decode(mediaBuff)
271
- const key = `${mediaType}Message`
272
- Object.assign(obj[key], { ...uploadData, media: undefined })
273
- return obj
274
- }
275
- }
276
- const isNewsletter = !!options.jid && (0, WABinary_1.isJidNewsletter)(options.jid)
277
- if (isNewsletter) {
278
- logger?.info({ key: cacheableKey }, 'Preparing raw media for newsletter')
279
- const { filePath, fileSha256, fileLength } = await (0, messages_media_1.getRawMediaUploadData)(
280
- uploadData.media,
281
- options.mediaTypeOverride || mediaType,
282
- logger
283
- )
284
- const fileSha256B64 = fileSha256.toString('base64')
285
- const { mediaUrl, directPath } = await options.upload(filePath, {
286
- fileEncSha256B64: fileSha256B64,
287
- mediaType: mediaType,
288
- timeoutMs: options.mediaUploadTimeoutMs
289
- })
290
- await fs_1.promises.unlink(filePath)
291
- const obj = WAProto_1.proto.Message.fromObject({
292
-
293
- [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
294
- url: mediaUrl,
295
- directPath,
296
- fileSha256,
297
- fileLength,
298
- ...uploadData,
299
- media: undefined
300
- })
301
- })
302
- if (uploadData.ptv) {
303
- obj.ptvMessage = obj.videoMessage
304
- delete obj.videoMessage
305
- }
306
- if (obj.stickerMessage) {
307
- obj.stickerMessage.stickerSentTs = Date.now()
308
- }
309
- if (cacheableKey) {
310
- logger?.debug({ cacheableKey }, 'set cache')
311
- await options.mediaCache.set(cacheableKey, WAProto_1.proto.Message.encode(obj).finish())
312
- }
313
- return obj
314
- }
315
- const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined'
316
- const requiresThumbnailComputation =
317
- (mediaType === 'image' || mediaType === 'video') && typeof uploadData['jpegThumbnail'] === 'undefined'
318
-
319
- const requiresWaveformProcessing =
320
- mediaType === 'audio' && uploadData.ptt === true && typeof uploadData.waveform === 'undefined'
321
- const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true
322
- const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation
323
- const { mediaKey, encFilePath, originalFilePath, fileEncSha256, fileSha256, fileLength } = await (0,
324
- messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
325
- logger,
326
- saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
327
- opts: options.options
328
- })
329
- const fileEncSha256B64 = fileEncSha256.toString('base64')
330
- const [{ mediaUrl, directPath }] = await Promise.all([
331
- (async () => {
332
- const result = await options.upload(encFilePath, {
333
- fileEncSha256B64,
334
- mediaType,
335
- timeoutMs: options.mediaUploadTimeoutMs
336
- })
337
- logger?.debug({ mediaType, cacheableKey }, 'uploaded media')
338
- return result
339
- })(),
340
- (async () => {
341
- try {
342
- if (requiresThumbnailComputation) {
343
- const { thumbnail, originalImageDimensions } = await (0, messages_media_1.generateThumbnail)(
344
- originalFilePath,
345
- mediaType,
346
- options
347
- )
348
- uploadData.jpegThumbnail = thumbnail
349
- if (!uploadData.width && originalImageDimensions) {
350
- uploadData.width = originalImageDimensions.width
351
- uploadData.height = originalImageDimensions.height
352
- logger?.debug('set dimensions')
353
- }
354
- logger?.debug('generated thumbnail')
355
- }
356
- if (requiresDurationComputation) {
357
- uploadData.seconds = await (0, messages_media_1.getAudioDuration)(originalFilePath)
358
- logger?.debug('computed audio duration')
359
- }
360
- if (requiresWaveformProcessing) {
361
- uploadData.waveform = await (0, messages_media_1.getAudioWaveform)(originalFilePath, logger)
362
- logger?.debug('processed waveform')
363
- }
364
- if (requiresAudioBackground) {
365
- uploadData.backgroundArgb = await assertColor(options.backgroundColor)
366
- logger?.debug('computed backgroundColor audio status')
367
- }
368
- } catch (error) {
369
- logger?.warn({ trace: error.stack }, 'failed to obtain extra info')
370
- }
371
- })()
372
- ]).finally(async () => {
373
- try {
374
- await fs_1.promises.unlink(encFilePath)
375
- if (originalFilePath) {
376
- await fs_1.promises.unlink(originalFilePath)
377
- }
378
- logger?.debug('removed tmp files')
379
- } catch (error) {
380
- logger?.warn('failed to remove tmp file')
381
- }
382
- })
383
-
384
-
385
-
386
- const hdImageEnabled = mediaType === 'image' && getMediaProp('hd_image_dual_upload') && !!uploadData.hd
387
- const hdVideoEnabled = mediaType === 'video' && getMediaProp('hd_video_dual_upload') && !!uploadData.hd
388
- if (hdImageEnabled || hdVideoEnabled) {
389
- uploadData.mediaHd = true
390
- logger?.debug({ mediaType }, 'HD dual upload enabled, setting mediaHd flag')
391
- }
392
-
393
-
394
-
395
- if (mediaType === 'image' && uploadData.motionPhoto != null) {
396
-
397
-
398
- if (typeof uploadData.motionPhoto === 'boolean') {
399
- uploadData.motionPhoto = uploadData.motionPhoto ? 1 : 0
400
- }
401
- logger?.debug('motion photo field set on image message')
402
- }
403
-
404
- const obj = WAProto_1.proto.Message.fromObject({
405
- [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
406
- url: mediaUrl,
407
- directPath,
408
- mediaKey,
409
- fileEncSha256,
410
- fileSha256,
411
- fileLength,
412
- mediaKeyTimestamp: (0, generics_1.unixTimestampSeconds)(),
413
- ...uploadData,
414
- media: undefined
415
- })
416
- })
417
- if (uploadData.ptv) {
418
- obj.ptvMessage = obj.videoMessage
419
- delete obj.videoMessage
420
- }
421
- if (cacheableKey) {
422
- logger?.debug({ cacheableKey }, 'set cache')
423
- await options.mediaCache.set(cacheableKey, WAProto_1.proto.Message.encode(obj).finish())
424
- }
425
- return obj
426
- }
427
- exports.prepareWAMessageMedia = prepareWAMessageMedia
428
- const prepareDisappearingMessageSettingContent = ephemeralExpiration => {
429
- ephemeralExpiration = ephemeralExpiration || 0
430
- const content = {
431
- ephemeralMessage: {
432
- message: {
433
- protocolMessage: {
434
- type: WAProto_1.proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
435
- ephemeralExpiration
436
- }
437
- }
438
- }
439
- }
440
- return WAProto_1.proto.Message.fromObject(content)
441
- }
442
- exports.prepareDisappearingMessageSettingContent = prepareDisappearingMessageSettingContent
443
-
444
- const generateForwardMessageContent = (message, forceForward) => {
445
- let content = message.message
446
- if (!content) {
447
- throw new boom_1.Boom('no content in message', { statusCode: 400 })
448
- }
449
-
450
- content = (0, exports.normalizeMessageContent)(content)
451
- content = WAProto_1.proto.Message.decode(WAProto_1.proto.Message.encode(content).finish())
452
- let key = Object.keys(content)[0]
453
- let score = content?.[key]?.contextInfo?.forwardingScore || 0
454
- score += message.key.fromMe && !forceForward ? 0 : 1
455
- if (key === 'conversation') {
456
- content.extendedTextMessage = { text: content[key] }
457
- delete content.conversation
458
- key = 'extendedTextMessage'
459
- }
460
- const key_ = content?.[key]
461
- if (score > 0) {
462
- key_.contextInfo = { forwardingScore: score, isForwarded: true }
463
- } else {
464
- key_.contextInfo = {}
465
- }
466
- return content
467
- }
468
- exports.generateForwardMessageContent = generateForwardMessageContent
469
- const hasNonNullishProperty = (message, key) => {
470
- return (
471
- typeof message === 'object' &&
472
- message !== null &&
473
- key in message &&
474
- message[key] !== null &&
475
- message[key] !== undefined
476
- )
477
- }
478
- exports.hasNonNullishProperty = hasNonNullishProperty
479
- function hasOptionalProperty(obj, key) {
480
- return typeof obj === 'object' && obj !== null && key in obj && obj[key] !== null
481
- }
482
- const normalizeEarFields = ear => {
483
- const result = { ...ear }
484
- const applyAlias = (fromKey, toKey) => {
485
- if (result[fromKey] !== undefined && result[toKey] === undefined) result[toKey] = result[fromKey]
486
- }
487
- applyAlias('thumbnail_url', 'thumbnailUrl')
488
- applyAlias('thumbnailUrl', 'thumbnail')
489
- applyAlias('source_url', 'sourceUrl')
490
- applyAlias('media_type', 'mediaType')
491
- applyAlias('show_ad_attribution', 'showAdAttribution')
492
- applyAlias('render_larger_thumbnail', 'renderLargerThumbnail')
493
- if (result.thumbnail && !result.jpegThumbnail) result.jpegThumbnail = result.thumbnail
494
- if (result.largeThumbnail !== undefined && result.renderLargerThumbnail === undefined)
495
- result.renderLargerThumbnail = result.largeThumbnail
496
- if (result.url && !result.sourceUrl) result.sourceUrl = result.url
497
- delete result.thumbnail
498
- delete result.largeThumbnail
499
- delete result.url
500
- delete result.thumbnail_url
501
- delete result.source_url
502
- delete result.media_type
503
- delete result.show_ad_attribution
504
- delete result.render_larger_thumbnail
505
- return result
506
- }
507
- const normalizeQuickReplyButton = button => {
508
- var _a
509
- if (button.name && typeof button.name === 'string') {
510
- return {
511
- name: button.name,
512
- buttonParamsJson:
513
- typeof button.buttonParamsJson === 'string'
514
- ? button.buttonParamsJson
515
- : JSON.stringify(button.buttonParamsJson || {})
516
- }
517
- }
518
- if (button.type === 4 && button.nativeFlowInfo) {
519
- const { name, paramsJson } = button.nativeFlowInfo
520
- return {
521
- name: name || 'quick_reply',
522
- buttonParamsJson: typeof paramsJson === 'string' ? paramsJson : JSON.stringify(paramsJson || {})
523
- }
524
- }
525
- const buttonTextObject = button.buttonText && typeof button.buttonText === 'object' ? button.buttonText : undefined
526
- const displayTextCandidates = [
527
- button.text,
528
- button.displayText,
529
- button.display_text,
530
- typeof button.buttonText === 'string' ? button.buttonText : undefined,
531
- buttonTextObject === null || buttonTextObject === void 0 ? void 0 : buttonTextObject.displayText,
532
- buttonTextObject === null || buttonTextObject === void 0 ? void 0 : buttonTextObject.display_text
533
- ]
534
- const displayText = displayTextCandidates.find(value => typeof value === 'string' && value.length > 0) || ''
535
- const id =
536
- button.buttonId || button.id || ((_a = button.buttonParamsJson) === null || _a === void 0 ? void 0 : _a.id) || ''
537
- return {
538
- name: 'quick_reply',
539
- buttonParamsJson: JSON.stringify({
540
- display_text: displayText,
541
- id
542
- })
543
- }
544
- }
545
- const asciiDecode = arr => arr.map(e => String.fromCharCode(e)).join('')
546
-
547
- const applyContextInfoAndMentions = (interactiveMessage, message) => {
548
- if ('contextInfo' in message && !!message.contextInfo) {
549
- interactiveMessage.contextInfo = message.contextInfo
550
- }
551
- if ('mentions' in message && !!message.mentions) {
552
- interactiveMessage.contextInfo = {
553
- ...(interactiveMessage.contextInfo || {}),
554
- mentionedJid: message.mentions
555
- }
556
- }
557
- }
558
- const buildPaymentNoteMessage = async (paymentPayload, options, fallbackText = '') => {
559
- let notes
560
- if (paymentPayload === null || paymentPayload === void 0 ? void 0 : paymentPayload.sticker) {
561
- const stickerPrep = await (0, exports.prepareWAMessageMedia)({ sticker: paymentPayload.sticker }, options)
562
- notes = {
563
- stickerMessage: {
564
- ...(stickerPrep === null || stickerPrep === void 0 ? void 0 : stickerPrep.stickerMessage),
565
- contextInfo: paymentPayload === null || paymentPayload === void 0 ? void 0 : paymentPayload.contextInfo
566
- }
567
- }
568
- } else if (
569
- typeof (paymentPayload === null || paymentPayload === void 0 ? void 0 : paymentPayload.note) === 'string'
570
- ) {
571
- notes = {
572
- extendedTextMessage: {
573
- text: paymentPayload.note,
574
- contextInfo: paymentPayload === null || paymentPayload === void 0 ? void 0 : paymentPayload.contextInfo
575
- }
576
- }
577
- } else if (
578
- (paymentPayload === null || paymentPayload === void 0 ? void 0 : paymentPayload.noteMessage) &&
579
- typeof paymentPayload.noteMessage === 'object'
580
- ) {
581
- const noteKeys = Object.keys(paymentPayload.noteMessage)
582
- const allowedNoteMessageKeys = ['extendedTextMessage', 'stickerMessage']
583
- const hasOnlyAllowedKeys = noteKeys.length > 0 && noteKeys.every(key => allowedNoteMessageKeys.includes(key))
584
- if (!noteKeys.length || !hasOnlyAllowedKeys) {
585
- throw new boom_1.Boom('Invalid payment noteMessage', { statusCode: 400 })
586
- }
587
- notes = paymentPayload.noteMessage
588
- } else {
589
- notes = { extendedTextMessage: { text: fallbackText } }
590
- }
591
- return notes
592
- }
593
-
594
- const generateWAMessageContent = async (message, options) => {
595
- var _a, _b
596
- let m = {}
597
- const hasCaptionWithoutMedia = 'caption' in message && !hasMediaPayload(message)
598
- const hasCaptionContainer =
599
- ('groupStatus' in message && !!message.groupStatus) || ('viewOnce' in message && !!message.viewOnce)
600
- if ((0, exports.hasNonNullishProperty)(message, 'text')) {
601
- const extContent = { text: message.text }
602
- let urlInfo = message.linkPreview
603
- if (typeof urlInfo === 'undefined') {
604
- urlInfo = await (0, exports.generateLinkPreviewIfRequired)(message.text, options.getUrlInfo, options.logger)
605
- }
606
- if (urlInfo) {
607
- extContent.matchedText = urlInfo['matched-text']
608
- extContent.jpegThumbnail = urlInfo.jpegThumbnail
609
- extContent.description = urlInfo.description
610
- extContent.title = urlInfo.title
611
- extContent.previewType = 0
612
- const img = urlInfo.highQualityThumbnail
613
- if (img) {
614
- extContent.thumbnailDirectPath = img.directPath
615
- extContent.mediaKey = img.mediaKey
616
- extContent.mediaKeyTimestamp = img.mediaKeyTimestamp
617
- extContent.thumbnailWidth = img.width
618
- extContent.thumbnailHeight = img.height
619
- extContent.thumbnailSha256 = img.fileSha256
620
- extContent.thumbnailEncSha256 = img.fileEncSha256
621
- }
622
- }
623
- if (options.backgroundColor) {
624
- extContent.backgroundArgb = await assertColor(options.backgroundColor)
625
- }
626
- if (options.font) {
627
- extContent.font = options.font
628
- }
629
- if (
630
- options.jid &&
631
- (0, WABinary_1.isInteropUser)(options.jid) &&
632
- !options.backgroundColor &&
633
- !options.font &&
634
- !urlInfo
635
- ) {
636
- m.conversation = message.text
637
- } else {
638
- m.extendedTextMessage = extContent
639
- }
640
- } else if ((0, exports.hasNonNullishProperty)(message, 'contacts')) {
641
- const contactLen = message.contacts.contacts.length
642
- if (!contactLen) {
643
- throw new boom_1.Boom('require atleast 1 contact', { statusCode: 400 })
644
- }
645
- if (contactLen === 1) {
646
- m.contactMessage = WAProto_1.proto.Message.ContactMessage.create(message.contacts.contacts[0])
647
- } else {
648
- m.contactsArrayMessage = WAProto_1.proto.Message.ContactsArrayMessage.create(message.contacts)
649
- }
650
- } else if ((0, exports.hasNonNullishProperty)(message, 'location')) {
651
- m.locationMessage = WAProto_1.proto.Message.LocationMessage.create(message.location)
652
- } else if ((0, exports.hasNonNullishProperty)(message, 'react')) {
653
- if (!message.react.senderTimestampMs) {
654
- message.react.senderTimestampMs = Date.now()
655
- }
656
- m.reactionMessage = WAProto_1.proto.Message.ReactionMessage.create(message.react)
657
- } else if ((0, exports.hasNonNullishProperty)(message, 'delete')) {
658
- m.protocolMessage = {
659
- key: message.delete,
660
- type: WAProto_1.proto.Message.ProtocolMessage.Type.REVOKE
661
- }
662
- } else if ((0, exports.hasNonNullishProperty)(message, 'forward')) {
663
- m = (0, exports.generateForwardMessageContent)(message.forward, message.force)
664
- } else if ((0, exports.hasNonNullishProperty)(message, 'disappearingMessagesInChat')) {
665
- const exp =
666
- typeof message.disappearingMessagesInChat === 'boolean'
667
- ? message.disappearingMessagesInChat
668
- ? Defaults_1.WA_DEFAULT_EPHEMERAL
669
- : 0
670
- : message.disappearingMessagesInChat
671
- m = (0, exports.prepareDisappearingMessageSettingContent)(exp)
672
- } else if ((0, exports.hasNonNullishProperty)(message, 'groupInvite')) {
673
- m.groupInviteMessage = {}
674
- m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode
675
- m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration
676
- m.groupInviteMessage.caption = message.groupInvite.text
677
- m.groupInviteMessage.groupJid = message.groupInvite.jid
678
- m.groupInviteMessage.groupName = message.groupInvite.subject
679
- if (options.getProfilePicUrl) {
680
- const cached = groupInviteThumbnailCache.get(message.groupInvite.jid)
681
- if (cached) {
682
- m.groupInviteMessage.jpegThumbnail = cached
683
- } else {
684
- const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview')
685
- if (pfpUrl) {
686
- const resp = await fetch(pfpUrl, { method: 'GET', dispatcher: options?.options?.dispatcher })
687
- if (resp.ok) {
688
- const buf = Buffer.from(await resp.arrayBuffer())
689
- m.groupInviteMessage.jpegThumbnail = buf
690
- groupInviteThumbnailCache.set(message.groupInvite.jid, buf)
691
- }
692
- }
693
- }
694
- }
695
- } else if ((0, exports.hasNonNullishProperty)(message, 'pin')) {
696
- m.pinInChatMessage = {}
697
- m.messageContextInfo = {}
698
- m.pinInChatMessage.key = message.pin
699
- m.pinInChatMessage.type = message.type
700
- m.pinInChatMessage.senderTimestampMs = Date.now()
701
- m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0
702
- } else if ((0, exports.hasNonNullishProperty)(message, 'buttonReply')) {
703
- switch (message.type) {
704
- case 'template':
705
- m.templateButtonReplyMessage = {
706
- selectedDisplayText: message.buttonReply.displayText,
707
- selectedId: message.buttonReply.id,
708
- selectedIndex: message.buttonReply.index
709
- }
710
- break
711
- case 'plain':
712
- m.buttonsResponseMessage = {
713
- selectedButtonId: message.buttonReply.id,
714
- selectedDisplayText: message.buttonReply.displayText,
715
- type: WAProto_1.proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT
716
- }
717
- break
718
- case 'interactive':
719
- m.interactiveResponseMessage = {
720
- body: {
721
- text: message.buttonReply.displayText,
722
- format: WAProto_1.proto.Message.InteractiveResponseMessage.Body.Format.EXTENSIONS_1
723
- },
724
- nativeFlowResponseMessage: {
725
- name: message.buttonReply.nativeFlows.name,
726
- paramsJson: message.buttonReply.nativeFlows.paramsJson,
727
- version: message.buttonReply.nativeFlows.version
728
- }
729
- }
730
- break
731
- case 'list':
732
- m.listResponseMessage = {
733
- title: message.buttonReply.title,
734
- description: message.buttonReply.description,
735
- singleSelectReply: {
736
- selectedRowId: message.buttonReply.rowId
737
- },
738
- listType: WAProto_1.proto.Message.ListResponseMessage.ListType.SINGLE_SELECT
739
- }
740
- break
741
- }
742
- } else if (hasOptionalProperty(message, 'ptv') && message.ptv) {
743
- const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options)
744
- m.ptvMessage = videoMessage
745
- } else if ((0, exports.hasNonNullishProperty)(message, 'product')) {
746
- const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options)
747
- m.productMessage = WAProto_1.proto.Message.ProductMessage.create({
748
- ...message,
749
- product: {
750
- ...message.product,
751
- productImage: imageMessage
752
- }
753
- })
754
- } else if ((0, exports.hasNonNullishProperty)(message, 'listReply')) {
755
- m.listResponseMessage = { ...message.listReply }
756
- } else if ((0, exports.hasNonNullishProperty)(message, 'event')) {
757
- m.eventMessage = {}
758
- const startTime = Math.floor(message.event.startDate.getTime() / 1000)
759
- if (message.event.call && options.getCallLink) {
760
- const token = await options.getCallLink(message.event.call, { startTime })
761
- m.eventMessage.joinLink =
762
- (message.event.call === 'audio' ? Defaults_1.CALL_AUDIO_PREFIX : Defaults_1.CALL_VIDEO_PREFIX) + token
763
- }
764
- m.messageContextInfo = {
765
-
766
- messageSecret: message.event.messageSecret || (0, crypto_1.randomBytes)(32)
767
- }
768
- m.eventMessage.name = message.event.name
769
- m.eventMessage.description = message.event.description
770
- m.eventMessage.startTime = startTime
771
- m.eventMessage.endTime = message.event.endDate ? message.event.endDate.getTime() / 1000 : undefined
772
- m.eventMessage.isCanceled = message.event.isCancelled ?? false
773
- m.eventMessage.extraGuestsAllowed = message.event.extraGuestsAllowed
774
- m.eventMessage.isScheduleCall = message.event.isScheduleCall ?? false
775
- m.eventMessage.location = message.event.location
776
- } else if ((0, exports.hasNonNullishProperty)(message, 'poll')) {
777
- ;(_a = message.poll).selectableCount || (_a.selectableCount = 0)
778
- ;(_b = message.poll).toAnnouncementGroup || (_b.toAnnouncementGroup = false)
779
- if (!Array.isArray(message.poll.values)) {
780
- throw new boom_1.Boom('Invalid poll values', { statusCode: 400 })
781
- }
782
- if (message.poll.selectableCount < 0 || message.poll.selectableCount > message.poll.values.length) {
783
- throw new boom_1.Boom(`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`, {
784
- statusCode: 400
785
- })
786
- }
787
- m.messageContextInfo = {
788
- messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32)
789
- }
790
- const isQuiz = message.poll.type === 'quiz' || message.poll.pollType === WAProto_1.proto.Message.PollType.QUIZ
791
- const pollTypeEnum = WAProto_1.proto.Message.PollType
792
- const pollCreationMessage = {
793
- name: message.poll.name,
794
- selectableOptionsCount: message.poll.selectableCount,
795
- options: message.poll.values.map(optionName => ({ optionName })),
796
- pollType: isQuiz ? pollTypeEnum.QUIZ : pollTypeEnum.POLL,
797
- ...(isQuiz && message.poll.correctAnswer ? { correctAnswer: { optionName: message.poll.correctAnswer } } : {}),
798
- ...(message.poll.endTime
799
- ? {
800
- endTime:
801
- message.poll.endTime instanceof Date
802
- ? Math.floor(message.poll.endTime.getTime() / 1000)
803
- : Number(message.poll.endTime)
804
- }
805
- : {}),
806
- ...(message.poll.hideParticipantName !== undefined
807
- ? { hideParticipantName: !!message.poll.hideParticipantName }
808
- : {}),
809
- ...(message.poll.allowAddOption !== undefined ? { allowAddOption: !!message.poll.allowAddOption } : {}),
810
-
811
-
812
- ...((0, messages_media_1.getMediaProp)(options.mediaAbProps, 'media_poll') && message.poll.mediaPoll != null
813
- ? { mediaPoll: !!message.poll.mediaPoll }
814
- : {})
815
- }
816
- if (message.poll.version === 6 || message.poll.v6) {
817
- m.pollCreationMessageV6 = pollCreationMessage
818
- } else if (message.poll.version === 5 || message.poll.v5) {
819
- m.pollCreationMessageV5 = pollCreationMessage
820
- } else if (message.poll.toAnnouncementGroup) {
821
-
822
- m.pollCreationMessageV2 = pollCreationMessage
823
- } else {
824
- if (message.poll.selectableCount === 1) {
825
-
826
- m.pollCreationMessageV3 = pollCreationMessage
827
- } else {
828
-
829
- m.pollCreationMessage = pollCreationMessage
830
- }
831
- }
832
- } else if ('inviteAdmin' in message) {
833
- m.newsletterAdminInviteMessage = {}
834
- m.newsletterAdminInviteMessage.inviteExpiration = message.inviteAdmin.inviteExpiration
835
- m.newsletterAdminInviteMessage.caption = message.inviteAdmin.text
836
- m.newsletterAdminInviteMessage.newsletterJid = message.inviteAdmin.jid
837
- m.newsletterAdminInviteMessage.newsletterName = message.inviteAdmin.subject
838
- m.newsletterAdminInviteMessage.jpegThumbnail = message.inviteAdmin.thumbnail
839
- } else if ('requestPayment' in message || 'requestPaymentMessage' in message) {
840
- if ('requestPayment' in message && 'requestPaymentMessage' in message) {
841
- throw new boom_1.Boom('Use either requestPayment or requestPaymentMessage, not both', { statusCode: 400 })
842
- }
843
- const requestPayment = message.requestPayment || message.requestPaymentMessage
844
- const notes = await buildPaymentNoteMessage(requestPayment, options)
845
- const amountValue = requestPayment.amount ?? requestPayment.amount1000
846
- const amount1000Raw =
847
- typeof (amountValue === null || amountValue === void 0 ? void 0 : amountValue.toNumber) === 'function'
848
- ? amountValue.toNumber()
849
- : Number(amountValue)
850
- const amount1000 = Number.isFinite(amount1000Raw) ? Math.round(amount1000Raw) : amount1000Raw
851
- const currencyCodeIso4217 = requestPayment.currency ?? requestPayment.currencyCodeIso4217
852
- const requestFrom = requestPayment.from ?? requestPayment.requestFrom ?? options.recipientJid
853
- const missingFields = []
854
- if (amountValue === undefined) missingFields.push('amount/amount1000')
855
- if (currencyCodeIso4217 === undefined) missingFields.push('currency/currencyCodeIso4217')
856
- if (requestFrom === undefined) missingFields.push('from/requestFrom')
857
- if (missingFields.length) {
858
- throw new boom_1.Boom(`Invalid requestPayment fields: missing ${missingFields.join(', ')}`, { statusCode: 400 })
859
- }
860
- if (
861
- typeof amount1000 !== 'number' ||
862
- !Number.isFinite(amount1000) ||
863
- !Number.isInteger(amount1000) ||
864
- amount1000 <= 0
865
- ) {
866
- throw new boom_1.Boom('Invalid requestPayment fields: amount/amount1000 must be a positive integer', {
867
- statusCode: 400
868
- })
869
- }
870
- const bg = requestPayment.background
871
- m.requestPaymentMessage = WAProto_1.proto.Message.RequestPaymentMessage.fromObject({
872
- expiryTimestamp: requestPayment.expiry ?? requestPayment.expiryTimestamp,
873
- amount1000,
874
- currencyCodeIso4217,
875
- requestFrom,
876
- noteMessage: notes,
877
- ...(bg != null ? { background: bg } : {})
878
- })
879
- } else if ('sendPayment' in message || 'sendPaymentMessage' in message) {
880
- if ('sendPayment' in message && 'sendPaymentMessage' in message) {
881
- throw new boom_1.Boom('Use either sendPayment or sendPaymentMessage, not both', { statusCode: 400 })
882
- }
883
- const sendPayment = message.sendPayment || message.sendPaymentMessage
884
- const notes = await buildPaymentNoteMessage(sendPayment, options, message.text || '')
885
- const requestMessageKey = sendPayment.requestMessageKey ?? sendPayment.requestKey ?? sendPayment.request
886
- if (!requestMessageKey) {
887
- throw new boom_1.Boom('Invalid sendPayment fields: missing requestMessageKey/requestKey/request', {
888
- statusCode: 400
889
- })
890
- }
891
- m.sendPaymentMessage = WAProto_1.proto.Message.SendPaymentMessage.fromObject({
892
- noteMessage: notes,
893
- requestMessageKey,
894
- ...(sendPayment.background != null ? { background: sendPayment.background } : {}),
895
- ...(sendPayment.transactionData != null ? { transactionData: sendPayment.transactionData } : {})
896
- })
897
- } else if ('declinePaymentRequest' in message || 'declinePaymentRequestMessage' in message) {
898
- if ('declinePaymentRequest' in message && 'declinePaymentRequestMessage' in message) {
899
- throw new boom_1.Boom('Use either declinePaymentRequest or declinePaymentRequestMessage, not both', {
900
- statusCode: 400
901
- })
902
- }
903
- const declinePayment = message.declinePaymentRequest || message.declinePaymentRequestMessage
904
- const key = (declinePayment === null || declinePayment === void 0 ? void 0 : declinePayment.key) || declinePayment
905
- if (!key) {
906
- throw new boom_1.Boom('Invalid declinePaymentRequest fields: missing key', { statusCode: 400 })
907
- }
908
- m.declinePaymentRequestMessage = WAProto_1.proto.Message.DeclinePaymentRequestMessage.fromObject({ key })
909
- } else if ('cancelPaymentRequest' in message || 'cancelPaymentRequestMessage' in message) {
910
- if ('cancelPaymentRequest' in message && 'cancelPaymentRequestMessage' in message) {
911
- throw new boom_1.Boom('Use either cancelPaymentRequest or cancelPaymentRequestMessage, not both', {
912
- statusCode: 400
913
- })
914
- }
915
- const cancelPayment = message.cancelPaymentRequest || message.cancelPaymentRequestMessage
916
- const key = (cancelPayment === null || cancelPayment === void 0 ? void 0 : cancelPayment.key) || cancelPayment
917
- if (!key) {
918
- throw new boom_1.Boom('Invalid cancelPaymentRequest fields: missing key', { statusCode: 400 })
919
- }
920
- m.cancelPaymentRequestMessage = WAProto_1.proto.Message.CancelPaymentRequestMessage.fromObject({ key })
921
- } else if ('requestPaymentFrom' in message && !!message.requestPaymentFrom) {
922
- const noteText = message.text || ''
923
- m.requestPaymentMessage = WAProto_1.proto.Message.RequestPaymentMessage.fromObject({
924
- requestFrom: message.requestPaymentFrom,
925
- noteMessage: { extendedTextMessage: { text: noteText } }
926
- })
927
- } else if ('invoiceNote' in message) {
928
- const preparedInvoice = await (0, exports.prepareWAMessageMedia)(message, options)
929
- const mediaType = Object.keys(preparedInvoice)[0]
930
- const mediaMsg = preparedInvoice[mediaType] || {}
931
- m.invoiceMessage = WAProto_1.proto.Message.InvoiceMessage.fromObject({
932
- note: message.invoiceNote,
933
- token: message.invoiceToken || '',
934
- attachmentType: mediaType === 'imageMessage' ? 1 : 0,
935
- attachmentMimetype: mediaMsg.mimetype,
936
- attachmentMediaKey: mediaMsg.mediaKey,
937
- attachmentMediaKeyTimestamp: mediaMsg.mediaKeyTimestamp,
938
- attachmentFileSha256: mediaMsg.fileSha256,
939
- attachmentFileEncSha256: mediaMsg.fileEncSha256,
940
- attachmentDirectPath: mediaMsg.directPath,
941
- attachmentJpegThumbnail: mediaMsg.jpegThumbnail
942
- })
943
- } else if ('orderText' in message) {
944
- m.orderMessage = WAProto_1.proto.Message.OrderMessage.fromObject({
945
- message: message.orderText,
946
- thumbnail: message.thumbnail,
947
- status: message.orderStatus || 1,
948
- surface: message.orderSurface || 1
949
- })
950
- } else if ('paymentInviteServiceType' in message) {
951
- m.paymentInviteMessage = {
952
- serviceType: message.paymentInviteServiceType,
953
- expiryTimestamp: message.paymentInviteExpiry
954
- }
955
- } else if ((0, exports.hasNonNullishProperty)(message, 'sharePhoneNumber')) {
956
- m.protocolMessage = {
957
- type: WAProto_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
958
- }
959
- } else if ((0, exports.hasNonNullishProperty)(message, 'requestPhoneNumber')) {
960
- m.requestPhoneNumberMessage = {}
961
- } else if ((0, exports.hasNonNullishProperty)(message, 'limitSharing')) {
962
- m.protocolMessage = {
963
- type: WAProto_1.proto.Message.ProtocolMessage.Type.LIMIT_SHARING,
964
- limitSharing: {
965
- sharingLimited: message.limitSharing === true,
966
- trigger: 1,
967
- limitSharingSettingTimestamp: Date.now(),
968
- initiatedByMe: true
969
- }
970
- }
971
- } else if ('album' in message) {
972
- const imageMessages = message.album.filter(item => 'image' in item)
973
- const videoMessages = message.album.filter(item => 'video' in item)
974
- m.albumMessage = WAProto_1.proto.Message.AlbumMessage.fromObject({
975
- expectedImageCount: imageMessages.length,
976
- expectedVideoCount: videoMessages.length
977
- })
978
- } else if ('pollResult' in message) {
979
- if (!Array.isArray(message.pollResult.values)) {
980
- throw new boom_1.Boom('Invalid pollResult values', { statusCode: 400 })
981
- }
982
- const isQuizResult =
983
- message.pollResult.type === 'quiz' || message.pollResult.pollType === WAProto_1.proto.Message.PollType.QUIZ
984
- const pollVotes = message.pollResult.values.map(([optionName, optionVoteCount]) => ({
985
- optionName,
986
- optionVoteCount
987
- }))
988
- const snapshotPayload = {
989
- name: message.pollResult.name,
990
- pollVotes,
991
- pollType: isQuizResult ? WAProto_1.proto.Message.PollType.QUIZ : WAProto_1.proto.Message.PollType.POLL
992
- }
993
- if (message.pollResult.version === 3 || message.pollResult.v3) {
994
- m.pollResultSnapshotMessageV3 = WAProto_1.proto.Message.PollResultSnapshotMessage.fromObject(snapshotPayload)
995
- } else {
996
- m.pollResultSnapshotMessage = snapshotPayload
997
- }
998
- } else if ('stickerPack' in message || 'stickerPackMessage' in message) {
999
- if ('stickerPack' in message && 'stickerPackMessage' in message) {
1000
- throw new boom_1.Boom('Cannot specify both stickerPack and stickerPackMessage; use only one property.', {
1001
- statusCode: 400
1002
- })
1003
- }
1004
- const stickerPackMessage = 'stickerPack' in message ? message.stickerPack : message.stickerPackMessage
1005
- m.stickerPackMessage = WAProto_1.proto.Message.StickerPackMessage.fromObject(stickerPackMessage)
1006
- } else if ('listMessage' in message) {
1007
- const lm = { ...message.listMessage }
1008
- if (lm.text !== undefined && lm.description === undefined) {
1009
- lm.description = lm.text
1010
- delete lm.text
1011
- }
1012
- m = { listMessage: lm }
1013
- } else if ('buttonsMessage' in message) {
1014
- m = {
1015
- buttonsMessage: WAProto_1.proto.Message.ButtonsMessage.fromObject(message.buttonsMessage)
1016
- }
1017
- } else if ('interactiveMessage' in message) {
1018
- m = { interactiveMessage: message.interactiveMessage }
1019
- } else if ('richResponse' in message) {
1020
-
1021
- } else if ('groupStatusMessage' in message) {
1022
- m = { groupStatusMessage: WAProto_1.proto.Message.GroupStatusMessage.fromObject(message.groupStatusMessage) }
1023
- } else if (hasCaptionWithoutMedia && !hasCaptionContainer) {
1024
- m.extendedTextMessage = { text: message.caption }
1025
- } else if (hasCaptionWithoutMedia && hasCaptionContainer) {
1026
- m = {}
1027
- } else if (!hasCaptionWithoutMedia && hasMediaPayload(message)) {
1028
- m = await (0, exports.prepareWAMessageMedia)(message, options)
1029
- }
1030
- if ('buttons' in message && !!message.buttons) {
1031
- const interactiveMessage = {
1032
- nativeFlowMessage: WAProto_1.proto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
1033
- buttons: message.buttons.map(normalizeQuickReplyButton)
1034
- })
1035
- }
1036
- if ('text' in message) {
1037
- interactiveMessage.body = { text: message.text }
1038
- } else if ('caption' in message) {
1039
- interactiveMessage.body = { text: message.caption }
1040
- interactiveMessage.header = {
1041
- title: message.title || '',
1042
- subtitle: message.subtitle,
1043
- hasMediaAttachment: Boolean(message.hasMediaAttachment)
1044
- }
1045
- Object.assign(interactiveMessage.header, m)
1046
- }
1047
- if ('title' in message && !!message.title && !interactiveMessage.header) {
1048
- interactiveMessage.header = {
1049
- title: message.title,
1050
- subtitle: message.subtitle,
1051
- hasMediaAttachment: Boolean(message.hasMediaAttachment)
1052
- }
1053
- } else if ('title' in message && !!message.title && interactiveMessage.header) {
1054
- interactiveMessage.header.title = message.title
1055
- if (message.subtitle !== undefined) {
1056
- interactiveMessage.header.subtitle = message.subtitle
1057
- }
1058
- }
1059
- if ('footer' in message && !!message.footer) {
1060
- interactiveMessage.footer = { text: message.footer }
1061
- }
1062
- applyContextInfoAndMentions(interactiveMessage, message)
1063
- m = { interactiveMessage }
1064
- } else if ('templateButtons' in message && !!message.templateButtons) {
1065
- const msg = {
1066
- hydratedButtons: message.templateButtons
1067
- }
1068
- if ('text' in message) {
1069
- msg.hydratedContentText = message.text
1070
- } else {
1071
- if ('caption' in message) {
1072
- msg.hydratedContentText = message.caption
1073
- }
1074
- Object.assign(msg, m)
1075
- }
1076
- if ('footer' in message && !!message.footer) {
1077
- msg.hydratedFooterText = message.footer
1078
- }
1079
- m = {
1080
- templateMessage: {
1081
- fourRowTemplate: msg,
1082
- hydratedTemplate: msg
1083
- }
1084
- }
1085
- }
1086
- if ('sections' in message && !!message.sections) {
1087
- const listMessage = {
1088
- sections: message.sections,
1089
- buttonText: message.buttonText,
1090
- title: message.title,
1091
- footerText: message.footer,
1092
- description: message.text,
1093
- listType: WAProto_1.proto.Message.ListMessage.ListType.SINGLE_SELECT
1094
- }
1095
- m = { listMessage }
1096
- } else if ('productList' in message && !!message.productList) {
1097
- if (
1098
- !Array.isArray(message.productList) ||
1099
- message.productList.length === 0 ||
1100
- !Array.isArray(message.productList[0].products) ||
1101
- message.productList[0].products.length === 0
1102
- ) {
1103
- throw new boom_1.Boom('Invalid productList: must contain at least one section with one product', {
1104
- statusCode: 400
1105
- })
1106
- }
1107
- m.listMessage = {
1108
- title: message.title,
1109
- buttonText: message.buttonText,
1110
- footerText: message.footer,
1111
- description: message.text,
1112
- productListInfo: {
1113
- productSections: message.productList,
1114
- headerImage: {
1115
- productId: message.productList[0].products[0].productId
1116
- },
1117
- businessOwnerJid: message.businessOwnerJid
1118
- },
1119
- listType: WAProto_1.proto.Message.ListMessage.ListType.PRODUCT_LIST
1120
- }
1121
- }
1122
- if ('interactiveButtons' in message && !!message.interactiveButtons) {
1123
- const interactiveMessage = {
1124
- nativeFlowMessage: WAProto_1.proto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
1125
- buttons: message.interactiveButtons
1126
- })
1127
- }
1128
- if ('text' in message) {
1129
- interactiveMessage.body = {
1130
- text: message.text
1131
- }
1132
- } else if ('caption' in message) {
1133
- interactiveMessage.body = {
1134
- text: message.caption
1135
- }
1136
- interactiveMessage.header = {
1137
- title: message.title,
1138
- subtitle: message.subtitle,
1139
- hasMediaAttachment: Boolean(message.hasMediaAttachment)
1140
- }
1141
- Object.assign(interactiveMessage.header, m)
1142
- }
1143
- if ('footer' in message && !!message.footer) {
1144
- interactiveMessage.footer = {
1145
- text: message.footer
1146
- }
1147
- }
1148
- if ('title' in message && !!message.title) {
1149
- interactiveMessage.header = {
1150
- title: message.title,
1151
- subtitle: message.subtitle,
1152
- hasMediaAttachment: Boolean(message.hasMediaAttachment)
1153
- }
1154
- Object.assign(interactiveMessage.header, m)
1155
- }
1156
- applyContextInfoAndMentions(interactiveMessage, message)
1157
- m = { interactiveMessage }
1158
- }
1159
- if ('shop' in message && !!message.shop) {
1160
- const interactiveMessage = {
1161
- shopStorefrontMessage: WAProto_1.proto.Message.InteractiveMessage.ShopMessage.fromObject({
1162
- surface: (_l = message.shop) === null || _l === void 0 ? void 0 : _l.surface,
1163
- id: (_m = message.shop) === null || _m === void 0 ? void 0 : _m.id
1164
- })
1165
- }
1166
- if ('text' in message) {
1167
- interactiveMessage.body = {
1168
- text: message.text
1169
- }
1170
- } else if ('caption' in message) {
1171
- interactiveMessage.body = {
1172
- text: message.caption
1173
- }
1174
- interactiveMessage.header = {
1175
- title: message.title,
1176
- subtitle: message.subtitle,
1177
- hasMediaAttachment: Boolean(message.hasMediaAttachment)
1178
- }
1179
- Object.assign(interactiveMessage.header, m)
1180
- }
1181
- if ('footer' in message && !!message.footer) {
1182
- interactiveMessage.footer = {
1183
- text: message.footer
1184
- }
1185
- }
1186
- if ('title' in message && !!message.title) {
1187
- interactiveMessage.header = {
1188
- title: message.title,
1189
- subtitle: message.subtitle,
1190
- hasMediaAttachment: Boolean(message.hasMediaAttachment)
1191
- }
1192
- Object.assign(interactiveMessage.header, m)
1193
- }
1194
- applyContextInfoAndMentions(interactiveMessage, message)
1195
- m = { interactiveMessage }
1196
- if ('interactiveAsTemplate' in message && message.interactiveAsTemplate !== false) {
1197
- m = { templateMessage: { interactiveMessageTemplate: interactiveMessage } }
1198
- }
1199
- }
1200
- if ('richResponse' in message) {
1201
- const {
1202
- text,
1203
- code,
1204
- language = 'javascript',
1205
- botJid = '259786046210223@bot',
1206
- table,
1207
- latex,
1208
- map,
1209
- imageUrl,
1210
- imageUrls,
1211
- responseId,
1212
- messageSecret: richSecret
1213
- } = message.richResponse
1214
- const sections = []
1215
- if (text) {
1216
- sections.push({
1217
- view_model: {
1218
- primitive: { text, __typename: 'GenAIMarkdownTextUXPrimitive' },
1219
- __typename: 'GenAISingleLayoutViewModel'
1220
- }
1221
- })
1222
- }
1223
- if (code) {
1224
- sections.push({
1225
- view_model: {
1226
- primitive: {
1227
- language,
1228
- code_blocks: tokenizeCode(String(code)),
1229
- __typename: 'GenAICodeUXPrimitive'
1230
- },
1231
- __typename: 'GenAISingleLayoutViewModel'
1232
- }
1233
- })
1234
- }
1235
- if (table && Array.isArray(table.rows)) {
1236
- sections.push({
1237
- view_model: {
1238
- primitive: {
1239
- rows: table.rows.map(row => ({
1240
- cells: Array.isArray(row) ? row.map(c => ({ text: String(c) })) : row.cells
1241
- })),
1242
- __typename: 'GenAITableUXPrimitive'
1243
- },
1244
- __typename: 'GenAISingleLayoutViewModel'
1245
- }
1246
- })
1247
- }
1248
- if (latex) {
1249
- const expressions = Array.isArray(latex)
1250
- ? latex.map(e => (typeof e === 'string' ? { expression: e } : e))
1251
- : [{ expression: String(latex) }]
1252
- sections.push({
1253
- view_model: {
1254
- primitive: { expressions, __typename: 'GenAILatexUXPrimitive' },
1255
- __typename: 'GenAISingleLayoutViewModel'
1256
- }
1257
- })
1258
- }
1259
- if (map) {
1260
- sections.push({
1261
- view_model: {
1262
- primitive: {
1263
- latitude: map.latitude,
1264
- longitude: map.longitude,
1265
- zoom: map.zoom,
1266
- title: map.title,
1267
- annotations: map.annotations || [],
1268
- __typename: 'GenAIMapUXPrimitive'
1269
- },
1270
- __typename: 'GenAISingleLayoutViewModel'
1271
- }
1272
- })
1273
- }
1274
- if (imageUrl) {
1275
- sections.push({
1276
- view_model: {
1277
- primitive: { url: imageUrl, __typename: 'GenAIInlineImageUXPrimitive' },
1278
- __typename: 'GenAISingleLayoutViewModel'
1279
- }
1280
- })
1281
- }
1282
- if (imageUrls && Array.isArray(imageUrls) && imageUrls.length > 0) {
1283
- sections.push({
1284
- view_model: {
1285
- primitive: {
1286
- urls: imageUrls.map(u => (typeof u === 'string' ? { url: u } : u)),
1287
- __typename: 'GenAIGridImageUXPrimitive'
1288
- },
1289
- __typename: 'GenAISingleLayoutViewModel'
1290
- }
1291
- })
1292
- }
1293
- if (!sections.length && !text) {
1294
- sections.push({
1295
- view_model: {
1296
- primitive: { text: '', __typename: 'GenAIMarkdownTextUXPrimitive' },
1297
- __typename: 'GenAISingleLayoutViewModel'
1298
- }
1299
- })
1300
- }
1301
- const unifiedData = {
1302
- response_id: responseId || (0, crypto_1.randomUUID)(),
1303
- sections
1304
- }
1305
- return WAProto_1.proto.Message.fromObject({
1306
- messageContextInfo: {
1307
- deviceListMetadata: {},
1308
- deviceListMetadataVersion: 2,
1309
- messageSecret: richSecret || (0, crypto_1.randomBytes)(32)
1310
- },
1311
- botForwardedMessage: {
1312
- message: {
1313
- richResponseMessage: {
1314
- submessages: [],
1315
- messageType: 1,
1316
- unifiedResponse: { data: Buffer.from(JSON.stringify(unifiedData)) },
1317
- contextInfo: {
1318
- forwardingScore: 2,
1319
- isForwarded: true,
1320
- forwardedAiBotMessageInfo: { botJid },
1321
- botMessageSharingInfo: {
1322
- botEntryPointOrigin: 1,
1323
- forwardScore: 2
1324
- }
1325
- }
1326
- }
1327
- }
1328
- }
1329
- })
1330
- }
1331
- if ('statusNotification' in message || 'statusNotificationMessage' in message) {
1332
- const notifData = 'statusNotification' in message ? message.statusNotification : message.statusNotificationMessage
1333
- m = { statusNotificationMessage: WAProto_1.proto.Message.StatusNotificationMessage.fromObject(notifData) }
1334
- } else if ('statusQuestionAnswer' in message || 'statusQuestionAnswerMessage' in message) {
1335
- const qaData =
1336
- 'statusQuestionAnswer' in message ? message.statusQuestionAnswer : message.statusQuestionAnswerMessage
1337
- m = { statusQuestionAnswerMessage: WAProto_1.proto.Message.StatusQuestionAnswerMessage.fromObject(qaData) }
1338
- } else if ('questionResponse' in message || 'questionResponseMessage' in message) {
1339
- const qrData = 'questionResponse' in message ? message.questionResponse : message.questionResponseMessage
1340
- m = { questionResponseMessage: WAProto_1.proto.Message.QuestionResponseMessage.fromObject(qrData) }
1341
- } else if ('statusQuoted' in message || 'statusQuotedMessage' in message) {
1342
- const sqData = 'statusQuoted' in message ? message.statusQuoted : message.statusQuotedMessage
1343
- m = { statusQuotedMessage: WAProto_1.proto.Message.StatusQuotedMessage.fromObject(sqData) }
1344
- } else if ('statusStickerInteraction' in message || 'statusStickerInteractionMessage' in message) {
1345
- const ssiData =
1346
- 'statusStickerInteraction' in message ? message.statusStickerInteraction : message.statusStickerInteractionMessage
1347
- m = { statusStickerInteractionMessage: WAProto_1.proto.Message.StatusStickerInteractionMessage.fromObject(ssiData) }
1348
- } else if ('newsletterFollowerInvite' in message || 'newsletterFollowerInviteMessageV2' in message) {
1349
- const nfiData =
1350
- 'newsletterFollowerInvite' in message
1351
- ? message.newsletterFollowerInvite
1352
- : message.newsletterFollowerInviteMessageV2
1353
- m = {
1354
- newsletterFollowerInviteMessageV2: WAProto_1.proto.Message.NewsletterFollowerInviteMessage.fromObject(nfiData)
1355
- }
1356
- } else if ('messageHistoryNotice' in message) {
1357
- m = { messageHistoryNotice: WAProto_1.proto.Message.MessageHistoryNotice.fromObject(message.messageHistoryNotice) }
1358
- } else if ('scheduledCall' in message || 'scheduledCallCreationMessage' in message) {
1359
- if ('scheduledCall' in message && 'scheduledCallCreationMessage' in message) {
1360
- throw new boom_1.Boom('Use either scheduledCall or scheduledCallCreationMessage, not both', { statusCode: 400 })
1361
- }
1362
- const sc = message.scheduledCall || message.scheduledCallCreationMessage
1363
- const scheduledTs =
1364
- sc.scheduledAt instanceof Date
1365
- ? sc.scheduledAt.getTime()
1366
- : sc.scheduledAt
1367
- ? Number(sc.scheduledAt)
1368
- : sc.scheduledTimestampMs
1369
- ? Number(sc.scheduledTimestampMs)
1370
- : Date.now() + 3600000
1371
- const callTypeEnum = WAProto_1.proto.Message.ScheduledCallCreationMessage.CallType
1372
- let callType = callTypeEnum.UNKNOWN
1373
- if (sc.isVideo || sc.callType === 'video' || sc.callType === callTypeEnum.VIDEO) {
1374
- callType = callTypeEnum.VIDEO
1375
- } else if (sc.callType === 'voice' || sc.callType === callTypeEnum.VOICE || sc.callType === undefined) {
1376
- callType = callTypeEnum.VOICE
1377
- } else {
1378
- callType = sc.callType ?? callTypeEnum.VOICE
1379
- }
1380
- m.scheduledCallCreationMessage = WAProto_1.proto.Message.ScheduledCallCreationMessage.fromObject({
1381
- scheduledTimestampMs: scheduledTs,
1382
- callType,
1383
- title: sc.title || ''
1384
- })
1385
- } else if ('editScheduledCall' in message || 'scheduledCallEditMessage' in message) {
1386
- if ('editScheduledCall' in message && 'scheduledCallEditMessage' in message) {
1387
- throw new boom_1.Boom('Use either editScheduledCall or scheduledCallEditMessage, not both', { statusCode: 400 })
1388
- }
1389
- const esc = message.editScheduledCall || message.scheduledCallEditMessage
1390
- const key = esc.key || esc
1391
- if (!key || typeof key !== 'object' || !key.id) {
1392
- throw new boom_1.Boom('editScheduledCall requires a valid message key with id', { statusCode: 400 })
1393
- }
1394
- m.scheduledCallEditMessage = WAProto_1.proto.Message.ScheduledCallEditMessage.fromObject({
1395
- key,
1396
- editType: WAProto_1.proto.Message.ScheduledCallEditMessage.EditType.CANCEL
1397
- })
1398
- } else if ('eventInvite' in message || 'eventInviteMessage' in message) {
1399
- if ('eventInvite' in message && 'eventInviteMessage' in message) {
1400
- throw new boom_1.Boom('Use either eventInvite or eventInviteMessage, not both', { statusCode: 400 })
1401
- }
1402
- const ei = message.eventInvite || message.eventInviteMessage
1403
- const startTime =
1404
- ei.startDate instanceof Date
1405
- ? Math.floor(ei.startDate.getTime() / 1000)
1406
- : ei.startTime
1407
- ? Number(ei.startTime)
1408
- : undefined
1409
- const endTime =
1410
- ei.endDate instanceof Date ? Math.floor(ei.endDate.getTime() / 1000) : ei.endTime ? Number(ei.endTime) : undefined
1411
- if (!ei.eventId && !ei.id) {
1412
- throw new boom_1.Boom('eventInvite requires an eventId', { statusCode: 400 })
1413
- }
1414
- m.eventInviteMessage = WAProto_1.proto.Message.EventInviteMessage.fromObject({
1415
- eventId: ei.eventId || ei.id,
1416
- eventTitle: ei.title || ei.eventTitle || '',
1417
- caption: ei.text || ei.caption || '',
1418
- startTime,
1419
- endTime,
1420
- isCanceled: ei.isCancelled ?? ei.isCanceled ?? false,
1421
- jpegThumbnail: ei.thumbnail || ei.jpegThumbnail,
1422
- contextInfo: ei.contextInfo
1423
- })
1424
- } else if ('comment' in message || 'commentMessage' in message) {
1425
- if ('comment' in message && 'commentMessage' in message) {
1426
- throw new boom_1.Boom('Use either comment or commentMessage, not both', { statusCode: 400 })
1427
- }
1428
- const cm = message.comment || message.commentMessage
1429
- if (!cm.targetMessageKey && !cm.key) {
1430
- throw new boom_1.Boom('comment requires a targetMessageKey', { statusCode: 400 })
1431
- }
1432
- m.commentMessage = WAProto_1.proto.Message.CommentMessage.fromObject({
1433
- message: cm.message || cm.replyMessage,
1434
- targetMessageKey: cm.targetMessageKey || cm.key
1435
- })
1436
- } else if ('splitPayment' in message || 'splitPaymentMessage' in message) {
1437
- if ('splitPayment' in message && 'splitPaymentMessage' in message) {
1438
- throw new boom_1.Boom('Use either splitPayment or splitPaymentMessage, not both', { statusCode: 400 })
1439
- }
1440
- const sp = message.splitPayment || message.splitPaymentMessage
1441
- if (!sp.totalAmount || !sp.participants?.length) {
1442
- throw new boom_1.Boom('splitPayment requires totalAmount and at least one participant', { statusCode: 400 })
1443
- }
1444
- m.splitPaymentMessage = WAProto_1.proto.Message.SplitPaymentMessage.fromObject({
1445
- splitId: sp.splitId || (0, crypto_1.randomUUID)(),
1446
- totalAmount: sp.totalAmount,
1447
- description: sp.description || '',
1448
- requesterJid: sp.requesterJid || options.userJid,
1449
- participants: sp.participants.map(p => ({
1450
- jid: p.jid,
1451
- amount: p.amount,
1452
- status: p.status ?? WAProto_1.proto.Message.SplitPaymentParticipant.SplitPaymentStatus.PENDING
1453
- })),
1454
- createdAtMs: sp.createdAtMs || Date.now(),
1455
- contextInfo: sp.contextInfo
1456
- })
1457
- } else if ('p2pPaymentReminder' in message || 'p2PPaymentReminderNotification' in message) {
1458
- if ('p2pPaymentReminder' in message && 'p2PPaymentReminderNotification' in message) {
1459
- throw new boom_1.Boom('Use either p2pPaymentReminder or p2PPaymentReminderNotification, not both', {
1460
- statusCode: 400
1461
- })
1462
- }
1463
- const pr = message.p2pPaymentReminder || message.p2PPaymentReminderNotification
1464
- const freqEnum = WAProto_1.proto.Message.P2PPaymentReminderNotification.ReminderFrequency
1465
- const stateEnum = WAProto_1.proto.Message.P2PPaymentReminderNotification.ReminderState
1466
- const freqMap = {
1467
- weekly: freqEnum.WEEKLY,
1468
- biweekly: freqEnum.BIWEEKLY,
1469
- monthly: freqEnum.MONTHLY,
1470
- custom: freqEnum.CUSTOM
1471
- }
1472
- const stateMap = {
1473
- active: stateEnum.ACTIVE,
1474
- paused: stateEnum.PAUSED,
1475
- stopped: stateEnum.STOPPED,
1476
- expired: stateEnum.EXPIRED,
1477
- cancelled: stateEnum.CANCELLED
1478
- }
1479
- m.p2PPaymentReminderNotification = WAProto_1.proto.Message.P2PPaymentReminderNotification.fromObject({
1480
- reminderId: pr.reminderId || (0, crypto_1.randomUUID)(),
1481
- amount: pr.amount,
1482
- frequency:
1483
- typeof pr.frequency === 'string'
1484
- ? (freqMap[pr.frequency.toLowerCase()] ?? freqEnum.UNKNOWN_FREQUENCY)
1485
- : (pr.frequency ?? freqEnum.UNKNOWN_FREQUENCY),
1486
- nextReminderTimestamp: pr.nextReminderTimestamp,
1487
- expiryTimestamp: pr.expiryTimestamp,
1488
- state:
1489
- typeof pr.state === 'string'
1490
- ? (stateMap[pr.state.toLowerCase()] ?? stateEnum.ACTIVE)
1491
- : (pr.state ?? stateEnum.ACTIVE),
1492
- description: pr.description || '',
1493
- creatorJid: pr.creatorJid || options.userJid,
1494
- receiverJid: pr.receiverJid,
1495
- upiId: pr.upiId,
1496
- createdTimestamp: pr.createdTimestamp || Date.now()
1497
- })
1498
- } else if ('conditionalReveal' in message || 'conditionalRevealMessage' in message) {
1499
- if ('conditionalReveal' in message && 'conditionalRevealMessage' in message) {
1500
- throw new boom_1.Boom('Use either conditionalReveal or conditionalRevealMessage, not both', { statusCode: 400 })
1501
- }
1502
- const cr = message.conditionalReveal || message.conditionalRevealMessage
1503
- m.conditionalRevealMessage = WAProto_1.proto.Message.ConditionalRevealMessage.fromObject({
1504
- conditionalRevealMessageType:
1505
- WAProto_1.proto.Message.ConditionalRevealMessage.ConditionalRevealMessageType.SCHEDULED_MESSAGE,
1506
- revealKeyId: cr.revealKeyId || (0, crypto_1.randomUUID)()
1507
- })
1508
- m.messageContextInfo = {
1509
- messageSecret: cr.messageSecret || (0, crypto_1.randomBytes)(32)
1510
- }
1511
- } else if ('callLog' in message || 'callLogMessage' in message) {
1512
- if ('callLog' in message && 'callLogMessage' in message) {
1513
- throw new boom_1.Boom('Use either callLog or callLogMessage, not both', { statusCode: 400 })
1514
- }
1515
- const cl = message.callLog || message.callLogMessage
1516
- const outcomeEnum = WAProto_1.proto.Message.CallLogMessage.CallOutcome
1517
- const callTypeEnum = WAProto_1.proto.Message.CallLogMessage.CallType
1518
- const outcomeMap = {
1519
- connected: outcomeEnum.CONNECTED,
1520
- missed: outcomeEnum.MISSED,
1521
- failed: outcomeEnum.FAILED,
1522
- rejected: outcomeEnum.REJECTED,
1523
- accepted_elsewhere: outcomeEnum.ACCEPTED_ELSEWHERE,
1524
- ongoing: outcomeEnum.ONGOING,
1525
- silenced_by_dnd: outcomeEnum.SILENCED_BY_DND,
1526
- silenced_unknown_caller: outcomeEnum.SILENCED_UNKNOWN_CALLER
1527
- }
1528
- const callTypeMap = {
1529
- regular: callTypeEnum.REGULAR,
1530
- scheduled_call: callTypeEnum.SCHEDULED_CALL,
1531
- voice_chat: callTypeEnum.VOICE_CHAT
1532
- }
1533
- m.callLogMesssage = WAProto_1.proto.Message.CallLogMessage.fromObject({
1534
- isVideo: cl.isVideo ?? false,
1535
- callOutcome:
1536
- typeof cl.outcome === 'string'
1537
- ? (outcomeMap[cl.outcome.toLowerCase()] ?? outcomeEnum.CONNECTED)
1538
- : (cl.outcome ?? outcomeEnum.CONNECTED),
1539
- durationSecs: cl.durationSecs || 0,
1540
- callType:
1541
- typeof cl.callType === 'string'
1542
- ? (callTypeMap[cl.callType.toLowerCase()] ?? callTypeEnum.REGULAR)
1543
- : (cl.callType ?? callTypeEnum.REGULAR),
1544
- participants: (cl.participants || []).map(p => ({
1545
- jid: p.jid,
1546
- callOutcome:
1547
- typeof p.outcome === 'string'
1548
- ? (outcomeMap[p.outcome.toLowerCase()] ?? outcomeEnum.CONNECTED)
1549
- : (p.outcome ?? p.callOutcome ?? outcomeEnum.CONNECTED)
1550
- }))
1551
- })
1552
- } else if ('statusMention' in message || 'statusMentionMsg' in message) {
1553
- const sm = message.statusMention || message.statusMentionMsg
1554
- if (!sm || typeof sm !== 'object') {
1555
- throw new boom_1.Boom('statusMention must be an object with a message property', { statusCode: 400 })
1556
- }
1557
- m.statusMentionMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1558
- message: sm.message || sm
1559
- })
1560
- } else if ('question' in message || 'questionMessage' in message) {
1561
- const q = message.question || message.questionMessage
1562
- m.questionMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1563
- message: q.message || (typeof q === 'object' && 'conversation' in q ? q : { conversation: String(q) })
1564
- })
1565
- } else if ('questionReply' in message || 'questionReplyMessage' in message) {
1566
- const qr = message.questionReply || message.questionReplyMessage
1567
- m.questionReplyMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1568
- message: qr.message || (typeof qr === 'object' && 'conversation' in qr ? qr : { conversation: String(qr) })
1569
- })
1570
- } else if ('statusAddYours' in message) {
1571
- const say = message.statusAddYours
1572
- m.statusAddYours = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1573
- message: say.message || say
1574
- })
1575
- } else if ('eventCoverImage' in message) {
1576
- const eci = message.eventCoverImage
1577
- m.eventCoverImage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1578
- message: eci.message || eci
1579
- })
1580
- } else if ('spoilerMessage' in message || 'spoiler' in message) {
1581
- const sp = message.spoilerMessage || message.spoiler
1582
- m.spoilerMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1583
- message: sp.message || sp
1584
- })
1585
- } else if ('lottieStickerMessage' in message || 'lottieSticker' in message) {
1586
- const ls = message.lottieStickerMessage || message.lottieSticker
1587
- m.lottieStickerMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1588
- message: ls.message || ls
1589
- })
1590
- } else if ('groupStatusV2' in message || 'groupStatusMessageV2' in message) {
1591
- const gsv2 = message.groupStatusV2 || message.groupStatusMessageV2
1592
- m.groupStatusMessageV2 = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1593
- message: gsv2.message || gsv2
1594
- })
1595
- } else if ('newsletterAdminProfile' in message || 'newsletterAdminProfileMessage' in message) {
1596
- const nap = message.newsletterAdminProfile || message.newsletterAdminProfileMessage
1597
- m.newsletterAdminProfileMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1598
- message: nap.message || nap
1599
- })
1600
- } else if ('newsletterAdminProfileV2' in message || 'newsletterAdminProfileMessageV2' in message) {
1601
- const nap2 = message.newsletterAdminProfileV2 || message.newsletterAdminProfileMessageV2
1602
- m.newsletterAdminProfileMessageV2 = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1603
- message: nap2.message || nap2
1604
- })
1605
- } else if ('botTask' in message || 'botTaskMessage' in message) {
1606
- const bt = message.botTask || message.botTaskMessage
1607
- m.botTaskMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1608
- message: bt.message || bt
1609
- })
1610
- } else if ('botInvoke' in message || 'botInvokeMessage' in message) {
1611
- const bi = message.botInvoke || message.botInvokeMessage
1612
- m.botInvokeMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1613
- message: bi.message || bi
1614
- })
1615
- } else if ('associatedChild' in message || 'associatedChildMessage' in message) {
1616
- const ac = message.associatedChild || message.associatedChildMessage
1617
- m.associatedChildMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1618
- message: ac.message || ac
1619
- })
1620
- } else if ('groupStatusMention' in message || 'groupStatusMentionMessage' in message) {
1621
- const gsm = message.groupStatusMention || message.groupStatusMentionMessage
1622
- m.groupStatusMentionMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1623
- message: gsm.message || gsm
1624
- })
1625
- } else if ('pollCreationOptionImage' in message || 'pollCreationOptionImageMessage' in message) {
1626
- const pcoi = message.pollCreationOptionImage || message.pollCreationOptionImageMessage
1627
- m.pollCreationOptionImageMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1628
- message: pcoi.message || pcoi
1629
- })
1630
- } else if ('newsletterAdminProfileStatus' in message || 'newsletterAdminProfileStatusMessage' in message) {
1631
- const naps = message.newsletterAdminProfileStatus || message.newsletterAdminProfileStatusMessage
1632
- m.newsletterAdminProfileStatusMessage = WAProto_1.proto.Message.FutureProofMessage.fromObject({
1633
- message: naps.message || naps
1634
- })
1635
- } else if ('placeholder' in message || 'placeholderMessage' in message) {
1636
- const ph = message.placeholder || message.placeholderMessage
1637
- const phTypeEnum = WAProto_1.proto.Message.PlaceholderMessage.PlaceholderType
1638
- const phTypeMap = {
1639
- e2e_reenable: phTypeEnum.PLACEHOLDER_MESSAGE_TYPE_E2E_REENABLE_MSG,
1640
- linked_devices: phTypeEnum.PLACEHOLDER_MESSAGE_TYPE_LINKED_DEVICES_MESSAGE
1641
- }
1642
- m.placeholderMessage = WAProto_1.proto.Message.PlaceholderMessage.fromObject({
1643
- type:
1644
- typeof ph.type === 'string'
1645
- ? (phTypeMap[ph.type.toLowerCase()] ?? phTypeEnum.PLACEHOLDER_MESSAGE_TYPE_E2E_REENABLE_MSG)
1646
- : (ph.type ?? phTypeEnum.PLACEHOLDER_MESSAGE_TYPE_E2E_REENABLE_MSG)
1647
- })
1648
- } else if ('tapLink' in message || 'tapLinkMessage' in message) {
1649
- const tl = message.tapLink || message.tapLinkMessage
1650
- const inner = {
1651
- extendedTextMessage: {
1652
- text: tl.text || tl.title || '',
1653
- matchedText: tl.url || tl.tapUrl,
1654
- title: tl.title || tl.text || '',
1655
- contextInfo: {
1656
- actionLink: {
1657
- url: tl.url || tl.tapUrl || '',
1658
- buttonTitle: tl.buttonTitle || 'Open'
1659
- }
1660
- }
1661
- }
1662
- }
1663
- Object.assign(m, inner)
1664
- } else if ('citation' in message) {
1665
- const cit = message.citation
1666
- m.extendedTextMessage = {
1667
- text: cit.text || cit.title || '',
1668
- title: cit.title || '',
1669
- description: cit.subtitle || cit.description || '',
1670
- ...(cit.imageUrl ? { jpegThumbnail: undefined, previewType: 0 } : {})
1671
- }
1672
- } else if ('embeddedMusic' in message) {
1673
- const em = message.embeddedMusic
1674
- m.extendedTextMessage = {
1675
- text: em.text || `🎵 ${em.title || ''} — ${em.author || ''}`,
1676
- title: em.title || '',
1677
- description: em.author || em.artistAttribution || '',
1678
- previewType: 0
1679
- }
1680
- }
1681
- if ('keepInChat' in message || 'keepInChatMessage' in message) {
1682
- const kic = message.keepInChat || message.keepInChatMessage
1683
- const keepTypeEnum = WAProto_1.proto.KeepType
1684
- const keepTypeMap = { keep: keepTypeEnum.KEEP_FOR_ALL, undo: keepTypeEnum.UNDO_KEEP_FOR_ALL }
1685
- m.keepInChatMessage = WAProto_1.proto.Message.KeepInChatMessage.fromObject({
1686
- key: kic.key || kic,
1687
- keepType:
1688
- typeof kic.keepType === 'string'
1689
- ? (keepTypeMap[kic.keepType.toLowerCase()] ?? keepTypeEnum.KEEP_FOR_ALL)
1690
- : (kic.keepType ?? keepTypeEnum.KEEP_FOR_ALL),
1691
- timestampMs: kic.timestampMs || Date.now()
1692
- })
1693
- }
1694
- if ('botFeedback' in message || 'botFeedbackMessage' in message) {
1695
- const bf = message.botFeedback || message.botFeedbackMessage
1696
- const kindEnum = WAProto_1.proto.BotFeedbackMessage.BotFeedbackKind
1697
- const kindMap = {
1698
- positive: kindEnum.BOT_FEEDBACK_POSITIVE,
1699
- negative: kindEnum.BOT_FEEDBACK_NEGATIVE,
1700
- negative_generic: kindEnum.BOT_FEEDBACK_NEGATIVE_GENERIC,
1701
- negative_helpful: kindEnum.BOT_FEEDBACK_NEGATIVE_HELPFUL,
1702
- negative_interesting: kindEnum.BOT_FEEDBACK_NEGATIVE_INTERESTING,
1703
- negative_accurate: kindEnum.BOT_FEEDBACK_NEGATIVE_ACCURATE,
1704
- negative_safe: kindEnum.BOT_FEEDBACK_NEGATIVE_SAFE,
1705
- negative_other: kindEnum.BOT_FEEDBACK_NEGATIVE_OTHER
1706
- }
1707
- m.protocolMessage = {
1708
- type: WAProto_1.proto.Message.ProtocolMessage.Type.BOT_FEEDBACK_MESSAGE,
1709
- key: bf.key,
1710
- botFeedbackMessage: WAProto_1.proto.BotFeedbackMessage.fromObject({
1711
- feedbackId: bf.feedbackId || bf.key?.id || '',
1712
- kind:
1713
- typeof bf.kind === 'string'
1714
- ? (kindMap[bf.kind.toLowerCase()] ?? kindEnum.BOT_FEEDBACK_POSITIVE)
1715
- : (bf.kind ?? kindEnum.BOT_FEEDBACK_POSITIVE)
1716
- })
1717
- }
1718
- }
1719
- if ('pollAddOption' in message || 'pollAddOptionMessage' in message) {
1720
- const pao = message.pollAddOption || message.pollAddOptionMessage
1721
- if (!pao.pollCreationMessageKey && !pao.key) {
1722
- throw new boom_1.Boom('pollAddOption requires a pollCreationMessageKey', { statusCode: 400 })
1723
- }
1724
- m.pollAddOptionMessage = WAProto_1.proto.Message.PollAddOptionMessage.fromObject({
1725
- pollCreationMessageKey: pao.pollCreationMessageKey || pao.key,
1726
- addOption: { optionName: pao.optionName || pao.option }
1727
- })
1728
- }
1729
- if ('chatTheme' in message || 'chatThemeMessage' in message) {
1730
- const ct = message.chatTheme || message.chatThemeMessage
1731
- const themeSetting = {
1732
- settingTimestampMs: Date.now(),
1733
- clearTheme: ct.clear ?? false,
1734
- colorSchemeId: ct.colorSchemeId
1735
- }
1736
- if (ct.solidColor) {
1737
- const sc = typeof ct.solidColor === 'object' ? ct.solidColor : {}
1738
- themeSetting.solidColor = WAProto_1.proto.Message.ChatSolidColorWallpaper.fromObject({
1739
- colorLight: sc.colorLight || sc.color || '#FFFFFF',
1740
- colorDark: sc.colorDark || sc.color || '#000000',
1741
- isDoodleEnabled: sc.isDoodleEnabled ?? false
1742
- })
1743
- } else if (ct.stockImage) {
1744
- const si = typeof ct.stockImage === 'object' ? ct.stockImage : {}
1745
- themeSetting.stockImage = WAProto_1.proto.Message.ChatStockImageWallpaper.fromObject({
1746
- stockImageId: si.id || si.stockImageId || String(ct.stockImage),
1747
- dimLevel: (si.dimLevel ?? si.opacity != null) ? (si.opacity ?? 100) / 100 : 0
1748
- })
1749
- } else if (ct.defaultWallpaper) {
1750
- themeSetting.defaultWallpaper = WAProto_1.proto.Message.ChatDefaultWallpaper.fromObject({
1751
- isDoodleEnabled: ct.defaultWallpaper.isDoodleEnabled ?? false
1752
- })
1753
- } else if (ct.customImage) {
1754
- themeSetting.customImage = WAProto_1.proto.Message.ChatCustomImageWallpaper.fromObject({
1755
- directPath: ct.customImage.directPath,
1756
- mediaKey: ct.customImage.mediaKey,
1757
- fileEncSha256: ct.customImage.fileEncSha256,
1758
- fileSha256: ct.customImage.fileSha256,
1759
- dimLevel: ct.customImage.dimLevel ?? 0
1760
- })
1761
- }
1762
- m.protocolMessage = {
1763
- type: WAProto_1.proto.Message.ProtocolMessage.Type.CHAT_THEME_SETTING,
1764
- chatThemeSetting: WAProto_1.proto.Message.ChatThemeSetting.fromObject(themeSetting)
1765
- }
1766
- }
1767
- if ('stopGeneration' in message) {
1768
- const sg = message.stopGeneration
1769
- m.protocolMessage = {
1770
- type: WAProto_1.proto.Message.ProtocolMessage.Type.STOP_GENERATION_MESSAGE,
1771
- key: sg.key || sg
1772
- }
1773
- }
1774
- if ('unscheduleMessage' in message) {
1775
- const us = message.unscheduleMessage
1776
- m.protocolMessage = {
1777
- type: WAProto_1.proto.Message.ProtocolMessage.Type.MESSAGE_UNSCHEDULE,
1778
- key: us.key || us
1779
- }
1780
- }
1781
- if ('bcall' in message || 'bcallMessage' in message) {
1782
- const bc = message.bcall || message.bcallMessage
1783
- const mediaTypeEnum = WAProto_1.proto.Message.BCallMessage.MediaType
1784
- const mediaTypeMap = { audio: mediaTypeEnum.AUDIO, video: mediaTypeEnum.VIDEO }
1785
- m.bcallMessage = WAProto_1.proto.Message.BCallMessage.fromObject({
1786
- sessionId: bc.sessionId || (0, crypto_1.randomUUID)(),
1787
- mediaType:
1788
- typeof bc.mediaType === 'string'
1789
- ? (mediaTypeMap[bc.mediaType.toLowerCase()] ?? mediaTypeEnum.AUDIO)
1790
- : (bc.mediaType ?? mediaTypeEnum.AUDIO),
1791
- masterKey: bc.masterKey || (0, crypto_1.randomBytes)(32),
1792
- caption: bc.caption || ''
1793
- })
1794
- }
1795
- if ('liveLocationUpdate' in message) {
1796
- const llu = message.liveLocationUpdate
1797
- m.liveLocationMessage = WAProto_1.proto.Message.LiveLocationMessage.fromObject({
1798
- degreesLatitude: llu.latitude,
1799
- degreesLongitude: llu.longitude,
1800
- accuracyInMeters: llu.accuracy,
1801
- speedInMps: llu.speed,
1802
- degreesClockwiseFromMagneticNorth: llu.heading,
1803
- sequenceNumber: llu.sequence || 1,
1804
- timeOffset: llu.timeOffset || 0,
1805
- jpegThumbnail: llu.thumbnail
1806
- })
1807
- }
1808
- if ('stopLiveLocation' in message) {
1809
- const sll = message.stopLiveLocation
1810
- m.protocolMessage = {
1811
- type: WAProto_1.proto.Message.ProtocolMessage.Type.REVOKE,
1812
- key: sll.key || sll
1813
- }
1814
- }
1815
- if ('carousel' in message || 'carouselMessage' in message) {
1816
- const c = message.carousel || message.carouselMessage
1817
- if (!Array.isArray(c.cards) || !c.cards.length) {
1818
- throw new boom_1.Boom('carousel requires at least one card', { statusCode: 400 })
1819
- }
1820
- const cardTypeEnum = WAProto_1.proto.Message.InteractiveMessage.CarouselMessage.CarouselCardType
1821
- const cardTypeMap = {
1822
- horizontal: cardTypeEnum.HSCROLL_CARDS,
1823
- album: cardTypeEnum.ALBUM_IMAGE,
1824
- hscroll: cardTypeEnum.HSCROLL_CARDS
1825
- }
1826
- m.interactiveMessage = {
1827
- carouselMessage: WAProto_1.proto.Message.InteractiveMessage.CarouselMessage.fromObject({
1828
- cards: c.cards.map(card => card.interactiveMessage || card),
1829
- messageVersion: c.messageVersion || 1,
1830
- carouselCardType:
1831
- typeof c.cardType === 'string'
1832
- ? (cardTypeMap[c.cardType.toLowerCase()] ?? cardTypeEnum.HSCROLL_CARDS)
1833
- : (c.carouselCardType ?? cardTypeEnum.HSCROLL_CARDS)
1834
- })
1835
- }
1836
- }
1837
- if ('aiMediaCollection' in message || 'aiMediaCollectionMessage' in message) {
1838
- const amc = message.aiMediaCollection || message.aiMediaCollectionMessage
1839
- m.protocolMessage = {
1840
- type: WAProto_1.proto.Message.ProtocolMessage.Type.AI_MEDIA_COLLECTION_MESSAGE,
1841
- aiMediaCollectionMessage: WAProto_1.proto.AIMediaCollectionMessage.fromObject({
1842
- collectionId: amc.collectionId || (0, crypto_1.randomUUID)(),
1843
- expectedMediaCount: amc.expectedMediaCount || amc.count || 1,
1844
- hasGlobalCaption: amc.hasGlobalCaption ?? false
1845
- })
1846
- }
1847
- }
1848
- if ('botCapabilities' in message && Array.isArray(message.botCapabilities) && message.botCapabilities.length) {
1849
- const capEnum = WAProto_1.proto.BotCapabilityMetadata.BotCapabilityType
1850
- const capStrMap = Object.fromEntries(Object.entries(capEnum).map(([k, v]) => [k.toLowerCase(), v]))
1851
- const caps = message.botCapabilities
1852
- .map(c => (typeof c === 'string' ? (capStrMap[c.toLowerCase()] ?? capEnum.UNKNOWN) : c))
1853
- .filter(c => typeof c === 'number' && c !== capEnum.UNKNOWN)
1854
- m.messageContextInfo = m.messageContextInfo || {}
1855
- m.messageContextInfo.botMetadata = WAProto_1.proto.BotMetadata.fromObject({
1856
- capabilityMetadata: { capabilities: caps }
1857
- })
1858
- }
1859
- if ('botThreadInfo' in message && message.botThreadInfo) {
1860
- const bt = message.botThreadInfo
1861
- const threadTypeEnum = WAProto_1.proto.AIThreadInfo.AIThreadClientInfo.AIThreadType
1862
- const threadTypeMap = Object.fromEntries(Object.entries(threadTypeEnum).map(([k, v]) => [k.toLowerCase(), v]))
1863
- const existing = m.messageContextInfo?.botMetadata
1864
- ? WAProto_1.proto.BotMetadata.toObject(m.messageContextInfo.botMetadata)
1865
- : {}
1866
- m.messageContextInfo = m.messageContextInfo || {}
1867
- m.messageContextInfo.botMetadata = WAProto_1.proto.BotMetadata.fromObject({
1868
- ...existing,
1869
- botThreadInfo: {
1870
- clientInfo: {
1871
- type:
1872
- typeof bt.type === 'string'
1873
- ? (threadTypeMap[bt.type.toLowerCase()] ?? threadTypeEnum.UNKNOWN)
1874
- : (bt.type ?? threadTypeEnum.UNKNOWN),
1875
- sourceChatJid: bt.sourceChatJid || ''
1876
- }
1877
- }
1878
- })
1879
- }
1880
- if ('messageAssociation' in message && message.messageAssociation) {
1881
- const ma = message.messageAssociation
1882
- const assocTypeEnum = WAProto_1.proto.MessageAssociation.AssociationType
1883
- const assocTypeMap = Object.fromEntries(Object.entries(assocTypeEnum).map(([k, v]) => [k.toLowerCase(), v]))
1884
- m.messageContextInfo = m.messageContextInfo || {}
1885
- m.messageContextInfo.messageAssociation = WAProto_1.proto.MessageAssociation.fromObject({
1886
- associationType:
1887
- typeof ma.type === 'string'
1888
- ? (assocTypeMap[ma.type.toLowerCase()] ?? assocTypeEnum.UNKNOWN)
1889
- : (ma.associationType ?? ma.type ?? assocTypeEnum.UNKNOWN),
1890
- parentMessageKey: ma.parentMessageKey || ma.parentKey,
1891
- messageIndex: ma.messageIndex || 0
1892
- })
1893
- }
1894
- if ('threadId' in message && message.threadId) {
1895
- const tid = message.threadId
1896
- const threadTypeEnum = WAProto_1.proto.ThreadID.ThreadType
1897
- m.messageContextInfo = m.messageContextInfo || {}
1898
- m.messageContextInfo.threadId = [
1899
- WAProto_1.proto.ThreadID.fromObject({
1900
- threadType:
1901
- tid.type === 'ai'
1902
- ? threadTypeEnum.AI_THREAD
1903
- : tid.type === 'replies'
1904
- ? threadTypeEnum.VIEW_REPLIES
1905
- : (tid.threadType ?? threadTypeEnum.UNKNOWN),
1906
- threadKey: tid.key || tid.threadKey
1907
- })
1908
- ]
1909
- }
1910
- if ('featureEligibilities' in message && message.featureEligibilities) {
1911
- const fe = message.featureEligibilities
1912
- const [msgType] = Object.keys(m)
1913
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
1914
- m[msgType].contextInfo = {
1915
- ...(m[msgType].contextInfo || {}),
1916
- featureEligibilities: {
1917
- cannotBeReactedTo: fe.cannotBeReactedTo ?? false,
1918
- cannotBeRanked: fe.cannotBeRanked ?? false,
1919
- canRequestFeedback: fe.canRequestFeedback ?? false,
1920
- canBeReshared: fe.canBeReshared ?? true,
1921
- canReceiveMultiReact: fe.canReceiveMultiReact ?? true
1922
- }
1923
- }
1924
- }
1925
- }
1926
- if ('forwardOrigin' in message) {
1927
- const [msgType] = Object.keys(m)
1928
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
1929
- const foEnum = WAProto_1.proto.ContextInfo.ForwardOrigin
1930
- const foMap = {
1931
- chat: foEnum.CHAT,
1932
- status: foEnum.STATUS,
1933
- channels: foEnum.CHANNELS,
1934
- meta_ai: foEnum.META_AI,
1935
- ugc: foEnum.UGC
1936
- }
1937
- m[msgType].contextInfo = {
1938
- ...(m[msgType].contextInfo || {}),
1939
- forwardOrigin:
1940
- typeof message.forwardOrigin === 'string'
1941
- ? (foMap[message.forwardOrigin.toLowerCase()] ?? foEnum.CHAT)
1942
- : (message.forwardOrigin ?? foEnum.CHAT)
1943
- }
1944
- }
1945
- }
1946
- if ('statusAudienceMetadata' in message && message.statusAudienceMetadata) {
1947
- const [msgType] = Object.keys(m)
1948
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
1949
- const audType = WAProto_1.proto.ContextInfo.StatusAudienceMetadata.AudienceType
1950
- const sam = message.statusAudienceMetadata
1951
- m[msgType].contextInfo = {
1952
- ...(m[msgType].contextInfo || {}),
1953
- statusAudienceMetadata: {
1954
- audienceType: sam.closeFriends ? audType.CLOSE_FRIENDS : audType.UNKNOWN,
1955
- listName: sam.listName,
1956
- listEmoji: sam.listEmoji
1957
- }
1958
- }
1959
- }
1960
- }
1961
- if ('aiGenerated' in message && message.aiGenerated === true) {
1962
- if (m.videoMessage) {
1963
- m.videoMessage.videoSourceType = WAProto_1.proto.Message.VideoMessage.VideoSourceType.AI_GENERATED
1964
- }
1965
- if (m.imageMessage) {
1966
- m.imageMessage.imageSourceType = WAProto_1.proto.Message.ImageMessage.ImageSourceType.AI_GENERATED
1967
- }
1968
- }
1969
- if ('aiModified' in message && message.aiModified === true) {
1970
- if (m.imageMessage) {
1971
- m.imageMessage.imageSourceType = WAProto_1.proto.Message.ImageMessage.ImageSourceType.AI_MODIFIED
1972
- }
1973
- }
1974
- if ('imageSourceType' in message) {
1975
- if (m.imageMessage) {
1976
- const istEnum = WAProto_1.proto.Message.ImageMessage.ImageSourceType
1977
- const istMap = {
1978
- user: istEnum.USER_IMAGE,
1979
- ai_generated: istEnum.AI_GENERATED,
1980
- ai_modified: istEnum.AI_MODIFIED,
1981
- rasterized: istEnum.RASTERIZED_TEXT_STATUS
1982
- }
1983
- m.imageMessage.imageSourceType =
1984
- typeof message.imageSourceType === 'string'
1985
- ? (istMap[message.imageSourceType.toLowerCase()] ?? istEnum.USER_IMAGE)
1986
- : (message.imageSourceType ?? istEnum.USER_IMAGE)
1987
- }
1988
- }
1989
- if ('qrUrl' in message && message.qrUrl && m.imageMessage) {
1990
- m.imageMessage.qrUrl = message.qrUrl
1991
- }
1992
- if ('videoContentUrl' in message && message.videoContentUrl && m.extendedTextMessage) {
1993
- m.extendedTextMessage.videoContentUrl = message.videoContentUrl
1994
- }
1995
- if ('endCardTiles' in message && Array.isArray(message.endCardTiles) && m.extendedTextMessage) {
1996
- m.extendedTextMessage.endCardTiles = message.endCardTiles.map(tile =>
1997
- WAProto_1.proto.Message.VideoEndCard.fromObject({
1998
- username: tile.username || tile.user,
1999
- caption: tile.caption || tile.text,
2000
- thumbnailImageUrl: tile.thumbnailUrl || tile.thumbnail,
2001
- profilePictureUrl: tile.profilePictureUrl || tile.avatar
2002
- })
2003
- )
2004
- }
2005
- if ('musicMetadata' in message && message.musicMetadata && m.extendedTextMessage) {
2006
- const mm = message.musicMetadata
2007
- m.extendedTextMessage.musicMetadata = WAProto_1.proto.EmbeddedMusic.fromObject({
2008
- songId: mm.songId,
2009
- author: mm.author || mm.artist,
2010
- title: mm.title,
2011
- artistAttribution: mm.artistAttribution,
2012
- isExplicit: mm.isExplicit ?? false,
2013
- musicSongStartTimeInMs: mm.startTimeMs || 0,
2014
- derivedContentStartTimeInMs: mm.derivedStartTimeMs || 0,
2015
- overlapDurationInMs: mm.overlapDurationMs || 0
2016
- })
2017
- }
2018
- if ('businessInteractionPills' in message && message.businessInteractionPills) {
2019
- const bip = message.businessInteractionPills
2020
- const pillTypeEnum = WAProto_1.proto.ContextInfo.BusinessInteractionPills.PillType
2021
- const entryEnum = WAProto_1.proto.ContextInfo.BusinessInteractionPills.EntryPoint
2022
- const pillMap = Object.fromEntries(Object.entries(pillTypeEnum).map(([k, v]) => [k.toLowerCase(), v]))
2023
- const entryMap = Object.fromEntries(Object.entries(entryEnum).map(([k, v]) => [k.toLowerCase(), v]))
2024
- const [msgType] = Object.keys(m)
2025
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2026
- m[msgType].contextInfo = {
2027
- ...(m[msgType].contextInfo || {}),
2028
- businessInteractionPills: WAProto_1.proto.ContextInfo.BusinessInteractionPills.fromObject({
2029
- businessJid: bip.businessJid,
2030
- entryPoint:
2031
- typeof bip.entryPoint === 'string'
2032
- ? (entryMap[bip.entryPoint.toLowerCase()] ?? entryEnum.ENTRY_POINT_UNKNOWN)
2033
- : bip.entryPoint,
2034
- pills: (bip.pills || []).map(p => ({
2035
- pillType:
2036
- typeof p.type === 'string'
2037
- ? (pillMap[p.type.toLowerCase()] ?? pillTypeEnum.UNKNOWN)
2038
- : (p.pillType ?? pillTypeEnum.UNKNOWN),
2039
- actionUrl: p.url || p.actionUrl
2040
- }))
2041
- })
2042
- }
2043
- }
2044
- }
2045
- if ('dataSharingContext' in message && message.dataSharingContext) {
2046
- const dsc = message.dataSharingContext
2047
- const [msgType] = Object.keys(m)
2048
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2049
- m[msgType].contextInfo = {
2050
- ...(m[msgType].contextInfo || {}),
2051
- dataSharingContext: WAProto_1.proto.ContextInfo.DataSharingContext.fromObject({
2052
- showMmDisclosure: dsc.showMmDisclosure ?? false,
2053
- encryptedSignalTokenConsented: dsc.encryptedToken,
2054
- dataSharingFlags: dsc.flags || 0
2055
- })
2056
- }
2057
- }
2058
- }
2059
- if ('botSession' in message && message.botSession) {
2060
- const bs = message.botSession
2061
- const srcEnum = WAProto_1.proto.BotSessionSource
2062
- const srcMap = Object.fromEntries(Object.entries(srcEnum).map(([k, v]) => [k.toLowerCase(), v]))
2063
- m.messageContextInfo = m.messageContextInfo || {}
2064
- const existing = m.messageContextInfo.botMetadata
2065
- ? WAProto_1.proto.BotMetadata.toObject(m.messageContextInfo.botMetadata)
2066
- : {}
2067
- m.messageContextInfo.botMetadata = WAProto_1.proto.BotMetadata.fromObject({
2068
- ...existing,
2069
- sessionMetadata: {
2070
- sessionId: bs.sessionId,
2071
- sessionSource:
2072
- typeof bs.source === 'string'
2073
- ? (srcMap[bs.source.toLowerCase()] ?? srcEnum.NONE)
2074
- : (bs.sessionSource ?? srcEnum.NONE)
2075
- }
2076
- })
2077
- }
2078
- if ('botReminder' in message && message.botReminder) {
2079
- const br = message.botReminder
2080
- const actionEnum = WAProto_1.proto.BotReminderMetadata.ReminderAction
2081
- const freqEnum = WAProto_1.proto.BotReminderMetadata.ReminderFrequency
2082
- const actionMap = {
2083
- notify: actionEnum.NOTIFY,
2084
- create: actionEnum.CREATE,
2085
- delete: actionEnum.DELETE,
2086
- update: actionEnum.UPDATE
2087
- }
2088
- const freqMap = {
2089
- once: freqEnum.ONCE,
2090
- daily: freqEnum.DAILY,
2091
- weekly: freqEnum.WEEKLY,
2092
- biweekly: freqEnum.BIWEEKLY,
2093
- monthly: freqEnum.MONTHLY
2094
- }
2095
- m.messageContextInfo = m.messageContextInfo || {}
2096
- const existing = m.messageContextInfo.botMetadata
2097
- ? WAProto_1.proto.BotMetadata.toObject(m.messageContextInfo.botMetadata)
2098
- : {}
2099
- m.messageContextInfo.botMetadata = WAProto_1.proto.BotMetadata.fromObject({
2100
- ...existing,
2101
- reminderMetadata: {
2102
- requestMessageKey: br.requestMessageKey || br.key,
2103
- action:
2104
- typeof br.action === 'string'
2105
- ? (actionMap[br.action.toLowerCase()] ?? actionEnum.NOTIFY)
2106
- : (br.action ?? actionEnum.NOTIFY),
2107
- name: br.name,
2108
- nextTriggerTimestamp: br.nextTriggerTimestamp || br.timestamp,
2109
- frequency:
2110
- typeof br.frequency === 'string'
2111
- ? (freqMap[br.frequency.toLowerCase()] ?? freqEnum.ONCE)
2112
- : (br.frequency ?? freqEnum.ONCE)
2113
- }
2114
- })
2115
- }
2116
- if ('botPlugin' in message && message.botPlugin) {
2117
- const bp = message.botPlugin
2118
- const ptEnum = WAProto_1.proto.BotPluginMetadata.PluginType
2119
- const spEnum = WAProto_1.proto.BotPluginMetadata.SearchProvider
2120
- const ptMap = { reels: ptEnum.REELS, search: ptEnum.SEARCH }
2121
- const spMap = { bing: spEnum.BING, google: spEnum.GOOGLE, support: spEnum.SUPPORT }
2122
- m.messageContextInfo = m.messageContextInfo || {}
2123
- const existing = m.messageContextInfo.botMetadata
2124
- ? WAProto_1.proto.BotMetadata.toObject(m.messageContextInfo.botMetadata)
2125
- : {}
2126
- m.messageContextInfo.botMetadata = WAProto_1.proto.BotMetadata.fromObject({
2127
- ...existing,
2128
- pluginMetadata: WAProto_1.proto.BotPluginMetadata.fromObject({
2129
- provider:
2130
- typeof bp.provider === 'string'
2131
- ? (spMap[bp.provider.toLowerCase()] ?? spEnum.UNKNOWN)
2132
- : (bp.provider ?? spEnum.UNKNOWN),
2133
- pluginType:
2134
- typeof bp.pluginType === 'string'
2135
- ? (ptMap[bp.pluginType.toLowerCase()] ?? ptEnum.UNKNOWN_PLUGIN)
2136
- : (bp.pluginType ?? ptEnum.UNKNOWN_PLUGIN),
2137
- searchProviderUrl: bp.searchProviderUrl,
2138
- searchQuery: bp.searchQuery,
2139
- thumbnailCdnUrl: bp.thumbnailCdnUrl,
2140
- profilePhotoCdnUrl: bp.profilePhotoCdnUrl,
2141
- expectedLinksCount: bp.expectedLinksCount || 0,
2142
- referenceIndex: bp.referenceIndex || 0
2143
- })
2144
- })
2145
- }
2146
- if ('isSpoiler' in message && message.isSpoiler === true) {
2147
- const [msgType] = Object.keys(m)
2148
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2149
- m[msgType].contextInfo = {
2150
- ...(m[msgType].contextInfo || {}),
2151
- isSpoiler: true
2152
- }
2153
- }
2154
- }
2155
- if ('expiration' in message && typeof message.expiration === 'number') {
2156
- const [msgType] = Object.keys(m)
2157
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2158
- m[msgType].contextInfo = {
2159
- ...(m[msgType].contextInfo || {}),
2160
- expiration: message.expiration
2161
- }
2162
- }
2163
- }
2164
- if ('ephemeralSettingTimestamp' in message) {
2165
- const [msgType] = Object.keys(m)
2166
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2167
- m[msgType].contextInfo = {
2168
- ...(m[msgType].contextInfo || {}),
2169
- ephemeralSettingTimestamp: message.ephemeralSettingTimestamp
2170
- }
2171
- }
2172
- }
2173
- if ('groupSubject' in message && message.groupSubject) {
2174
- const [msgType] = Object.keys(m)
2175
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2176
- m[msgType].contextInfo = {
2177
- ...(m[msgType].contextInfo || {}),
2178
- groupSubject: message.groupSubject
2179
- }
2180
- }
2181
- }
2182
- if ('parentGroupJid' in message && message.parentGroupJid) {
2183
- const [msgType] = Object.keys(m)
2184
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2185
- m[msgType].contextInfo = {
2186
- ...(m[msgType].contextInfo || {}),
2187
- parentGroupJid: message.parentGroupJid
2188
- }
2189
- }
2190
- }
2191
- if ('memberLabel' in message && message.memberLabel) {
2192
- const [msgType] = Object.keys(m)
2193
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2194
- m[msgType].contextInfo = {
2195
- ...(m[msgType].contextInfo || {}),
2196
- memberLabel: message.memberLabel
2197
- }
2198
- }
2199
- }
2200
- if ('trustBanner' in message && message.trustBanner) {
2201
- const tb = message.trustBanner
2202
- const [msgType] = Object.keys(m)
2203
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2204
- m[msgType].contextInfo = {
2205
- ...(m[msgType].contextInfo || {}),
2206
- ...(tb.type != null ? { trustBannerType: tb.type } : {}),
2207
- ...(tb.action != null ? { trustBannerAction: tb.action } : {})
2208
- }
2209
- }
2210
- }
2211
- if ('entryPoint' in message && message.entryPoint) {
2212
- const ep = message.entryPoint
2213
- const [msgType] = Object.keys(m)
2214
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2215
- m[msgType].contextInfo = {
2216
- ...(m[msgType].contextInfo || {}),
2217
- ...(ep.source ? { entryPointConversionSource: ep.source } : {}),
2218
- ...(ep.app ? { entryPointConversionApp: ep.app } : {}),
2219
- ...(ep.delaySecs != null ? { entryPointConversionDelaySeconds: ep.delaySecs } : {}),
2220
- ...(ep.externalSource ? { entryPointConversionExternalSource: ep.externalSource } : {}),
2221
- ...(ep.externalMedium ? { entryPointConversionExternalMedium: ep.externalMedium } : {})
2222
- }
2223
- }
2224
- }
2225
- if ('utm' in message && message.utm) {
2226
- const [msgType] = Object.keys(m)
2227
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2228
- m[msgType].contextInfo = {
2229
- ...(m[msgType].contextInfo || {}),
2230
- utm: WAProto_1.proto.ContextInfo.UTMInfo.fromObject({
2231
- utmSource: message.utm.source,
2232
- utmCampaign: message.utm.campaign
2233
- })
2234
- }
2235
- }
2236
- }
2237
- if ('partiallySelectedContent' in message && message.partiallySelectedContent) {
2238
- const [msgType] = Object.keys(m)
2239
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2240
- m[msgType].contextInfo = {
2241
- ...(m[msgType].contextInfo || {}),
2242
- partiallySelectedContent: message.partiallySelectedContent
2243
- }
2244
- }
2245
- }
2246
- if ('crossAppSource' in message && message.crossAppSource) {
2247
- const [msgType] = Object.keys(m)
2248
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2249
- m[msgType].contextInfo = {
2250
- ...(m[msgType].contextInfo || {}),
2251
- crossAppSource: message.crossAppSource
2252
- }
2253
- }
2254
- }
2255
- if ('isQuestion' in message && message.isQuestion === true) {
2256
- const [msgType] = Object.keys(m)
2257
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2258
- m[msgType].contextInfo = {
2259
- ...(m[msgType].contextInfo || {}),
2260
- isQuestion: true
2261
- }
2262
- }
2263
- }
2264
- if ('afterReadDuration' in message && typeof message.afterReadDuration === 'number') {
2265
- const [msgType] = Object.keys(m)
2266
- if (msgType && m[msgType] && typeof m[msgType] === 'object') {
2267
- m[msgType].contextInfo = {
2268
- ...(m[msgType].contextInfo || {}),
2269
- afterReadDuration: message.afterReadDuration
2270
- }
2271
- }
2272
- m.messageContextInfo = {
2273
- ...(m.messageContextInfo || {}),
2274
- messageAddOnDurationInSecs: message.afterReadDuration,
2275
- messageAddOnExpiryType: WAProto_1.proto.MessageContextInfo.MessageAddonExpiryType.DEPENDENT_ON_PARENT
2276
- }
2277
- }
2278
- if ('raw' in message && !!message.raw) {
2279
- const { raw: _, externalAdReply: _ear, ...rawMsg } = message
2280
- if ('externalAdReply' in message && !!message.externalAdReply) {
2281
- const ear = normalizeEarFields(message.externalAdReply)
2282
- const [rawType] = Object.keys(rawMsg)
2283
- if (rawType && rawMsg[rawType]) {
2284
- rawMsg[rawType].contextInfo = {
2285
- ...(rawMsg[rawType].contextInfo || {}),
2286
- externalAdReply: ear
2287
- }
2288
- }
2289
- }
2290
- return WAProto_1.proto.Message.fromObject(rawMsg)
2291
- } else if (Object.keys(m).length === 0) {
2292
- m = await (0, exports.prepareWAMessageMedia)(message, options)
2293
- }
2294
-
2295
- if (hasOptionalProperty(message, 'viewOnce') && !!message.viewOnce) {
2296
- const viewOnceVersion = message.viewOnceVersion || message.viewOnce
2297
- if (viewOnceVersion === 'v2' || viewOnceVersion === 2) {
2298
- m = { viewOnceMessageV2: { message: m } }
2299
- } else if (viewOnceVersion === 'v2ext' || viewOnceVersion === 'v2extension') {
2300
- m = { viewOnceMessageV2Extension: { message: m } }
2301
- } else {
2302
- m = { viewOnceMessage: { message: m } }
2303
- }
2304
- }
2305
- if (hasOptionalProperty(message, 'documentWithCaption') && !!message.documentWithCaption) {
2306
- m = { documentWithCaptionMessage: { message: m } }
2307
- }
2308
- if (hasOptionalProperty(message, 'ephemeral') && !!message.ephemeral) {
2309
- m = { ephemeralMessage: { message: m } }
2310
- }
2311
- if (hasOptionalProperty(message, 'groupMentioned') && !!message.groupMentioned) {
2312
- m = { groupMentionedMessage: { message: m } }
2313
- }
2314
- if ('groupStatus' in message && !!message.groupStatus) {
2315
- m = { groupStatusMessage: { message: m } }
2316
- }
2317
- if (
2318
- (hasOptionalProperty(message, 'mentions') && message.mentions?.length) ||
2319
- (hasOptionalProperty(message, 'mentionAll') && message.mentionAll)
2320
- ) {
2321
- const normalizedMentions = await (0, jid_display_normalization_1.normalizeMentionedJidsForSend)(
2322
- message.mentions,
2323
- options.groupData,
2324
- options.signalRepository,
2325
- options.logger
2326
- )
2327
- const messageType = Object.keys(m)[0]
2328
- const key = m[messageType]
2329
- if (key && 'contextInfo' in key) {
2330
- key.contextInfo = key.contextInfo || {}
2331
- if (normalizedMentions?.length) {
2332
- key.contextInfo.mentionedJid = normalizedMentions
2333
- }
2334
- if (message.mentionAll) {
2335
- key.contextInfo.nonJidMentions = 1
2336
- } else if (!key) {
2337
- key.contextInfo = {
2338
- mentionedJid: normalizedMentions,
2339
- nonJidMentions: message.mentionAll ? 1 : 0
2340
- }
2341
- }
2342
- }
2343
- }
2344
- if (hasOptionalProperty(message, 'edit')) {
2345
- m = {
2346
- protocolMessage: {
2347
- key: message.edit,
2348
- editedMessage: m,
2349
- timestampMs: Date.now(),
2350
- type: WAProto_1.proto.Message.ProtocolMessage.Type.MESSAGE_EDIT
2351
- }
2352
- }
2353
- }
2354
- if (hasOptionalProperty(message, 'contextInfo') && !!message.contextInfo) {
2355
- const messageType = Object.keys(m)[0]
2356
- const key = m[messageType]
2357
- if ('contextInfo' in key && !!key.contextInfo) {
2358
- key.contextInfo = { ...key.contextInfo, ...message.contextInfo }
2359
- } else if (key) {
2360
- key.contextInfo = message.contextInfo
2361
- }
2362
- }
2363
- if ((0, reporting_utils_1.shouldIncludeReportingToken)(m) && !(0, WABinary_1.isInteropUser)(options.jid)) {
2364
- m.messageContextInfo = m.messageContextInfo || {}
2365
- if (!m.messageContextInfo.messageSecret) {
2366
- m.messageContextInfo.messageSecret = (0, crypto_1.randomBytes)(32)
2367
- }
2368
- }
2369
-
2370
- if ('externalAdReply' in message && !!message.externalAdReply) {
2371
- const wrappers = [
2372
- 'viewOnceMessage',
2373
- 'viewOnceMessageV2',
2374
- 'viewOnceMessageV2Extension',
2375
- 'ephemeralMessage',
2376
- 'groupStatusMessage',
2377
- 'templateMessage'
2378
- ]
2379
- const [outerType] = Object.keys(m)
2380
- const inner = wrappers.includes(outerType) ? m[outerType].message : m
2381
- const [innerType] = Object.keys(inner)
2382
- const innerPayload = innerType ? inner[innerType] : undefined
2383
- if (innerType && innerType !== 'carouselMessage' && innerPayload && typeof innerPayload === 'object') {
2384
- const ear = normalizeEarFields(message.externalAdReply)
2385
- innerPayload.contextInfo = {
2386
- ...(innerPayload.contextInfo || {}),
2387
- externalAdReply: ear
2388
- }
2389
- }
2390
- }
2391
- if ('secureMetaServiceLabel' in message && !!message.secureMetaServiceLabel) {
2392
- const [messageType] = Object.keys(m)
2393
- m[messageType] = m[messageType] || {}
2394
- m[messageType].contextInfo = {
2395
- ...(m[messageType].contextInfo || {}),
2396
- secureMetaServiceLabel: 1
2397
- }
2398
- }
2399
-
2400
- return WAProto_1.proto.Message.create(m)
2401
- }
2402
- exports.generateWAMessageContent = generateWAMessageContent
2403
- const generateWAMessageFromContent = (jid, message, options) => {
2404
-
2405
-
2406
- if (!options.timestamp) {
2407
- options.timestamp = new Date()
2408
- }
2409
- const innerMessage = (0, exports.normalizeMessageContent)(message)
2410
- const key = (0, exports.getContentType)(innerMessage)
2411
- const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp)
2412
- const { quoted, userJid } = options
2413
- if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
2414
- const participant = quoted.key.fromMe
2415
- ? userJid
2416
- : quoted.participant || quoted.key.participant || quoted.key.remoteJid
2417
- let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message)
2418
- const msgType = (0, exports.getContentType)(quotedMsg)
2419
-
2420
- quotedMsg = WAProto_1.proto.Message.create({ [msgType]: quotedMsg[msgType] })
2421
- const quotedContent = quotedMsg[msgType]
2422
- if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
2423
- delete quotedContent.contextInfo
2424
- }
2425
- const contextInfo = ('contextInfo' in innerMessage[key] && innerMessage[key]?.contextInfo) || {}
2426
- contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant)
2427
- contextInfo.stanzaId = quoted.key.id
2428
- contextInfo.quotedMessage = quotedMsg
2429
-
2430
-
2431
- if (jid !== quoted.key.remoteJid) {
2432
- contextInfo.remoteJid = quoted.key.remoteJid
2433
- }
2434
- if (contextInfo && innerMessage[key]) {
2435
-
2436
- innerMessage[key].contextInfo = contextInfo
2437
- }
2438
- }
2439
- if (
2440
-
2441
- !!options.ephemeralExpiration &&
2442
-
2443
- key !== 'protocolMessage' &&
2444
-
2445
- key !== 'ephemeralMessage' &&
2446
-
2447
- !(0, WABinary_1.isJidNewsletter)(jid)
2448
- ) {
2449
-
2450
- innerMessage[key].contextInfo = {
2451
- ...(innerMessage[key].contextInfo || {}),
2452
- expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL
2453
-
2454
- }
2455
- }
2456
- message = WAProto_1.proto.Message.create(message)
2457
- const messageJSON = {
2458
- key: {
2459
- remoteJid: jid,
2460
- fromMe: true,
2461
- id: options?.messageId || (0, generics_1.generateMessageIDV2)()
2462
- },
2463
- message: message,
2464
- messageTimestamp: timestamp,
2465
- messageStubParameters: [],
2466
- participant: (0, WABinary_1.isJidGroup)(jid) || (0, WABinary_1.isJidStatusBroadcast)(jid) ? userJid : undefined,
2467
- status: Types_1.WAMessageStatus.PENDING
2468
- }
2469
- return WAProto_1.proto.WebMessageInfo.fromObject(messageJSON)
2470
- }
2471
- exports.generateWAMessageFromContent = generateWAMessageFromContent
2472
- const generateWAMessage = async (jid, content, options) => {
2473
-
2474
- options.logger = options?.logger?.child({ msgId: options.messageId })
2475
-
2476
- return (0, exports.generateWAMessageFromContent)(
2477
- jid,
2478
- await (0, exports.generateWAMessageContent)(content, { ...options, jid }),
2479
- options
2480
- )
2481
- }
2482
- exports.generateWAMessage = generateWAMessage