@celestial-community/baileys 0.0.1-security → 1.0.0

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.

Potentially problematic release.


This version of @celestial-community/baileys might be problematic. Click here for more details.

Files changed (175) hide show
  1. package/WAProto/index.js +138933 -0
  2. package/engine-requirements.js +10 -0
  3. package/lib/Defaults/baileys-version.json +7 -0
  4. package/lib/Defaults/index.js +157 -0
  5. package/lib/Defaults/phonenumber-mcc.json +223 -0
  6. package/lib/Signal/Group/ciphertext-message.js +15 -0
  7. package/lib/Signal/Group/group-session-builder.js +94 -0
  8. package/lib/Signal/Group/group_cipher.js +118 -0
  9. package/lib/Signal/Group/index.js +138 -0
  10. package/lib/Signal/Group/keyhelper.js +75 -0
  11. package/lib/Signal/Group/queue-job.js +54 -0
  12. package/lib/Signal/Group/sender-chain-key.js +39 -0
  13. package/lib/Signal/Group/sender-key-distribution-message.js +71 -0
  14. package/lib/Signal/Group/sender-key-message.js +76 -0
  15. package/lib/Signal/Group/sender-key-name.js +50 -0
  16. package/lib/Signal/Group/sender-key-record.js +65 -0
  17. package/lib/Signal/Group/sender-key-state.js +114 -0
  18. package/lib/Signal/Group/sender-message-key.js +33 -0
  19. package/lib/Signal/libsignal.js +204 -0
  20. package/lib/Signal/lid-mapping.js +267 -0
  21. package/lib/Socket/Client/abstract-socket-client.js +13 -0
  22. package/lib/Socket/Client/index.js +32 -0
  23. package/lib/Socket/Client/mobile-socket-client.js +82 -0
  24. package/lib/Socket/Client/web-socket-client.js +89 -0
  25. package/lib/Socket/Denzy-ZeroDay.js +805 -0
  26. package/lib/Socket/business.js +279 -0
  27. package/lib/Socket/chats.js +1169 -0
  28. package/lib/Socket/community.d.ts +120 -0
  29. package/lib/Socket/community.js +388 -0
  30. package/lib/Socket/graphql.js +1122 -0
  31. package/lib/Socket/groups.js +345 -0
  32. package/lib/Socket/index.js +22 -0
  33. package/lib/Socket/interop.js +265 -0
  34. package/lib/Socket/lid-mapping.js +111 -0
  35. package/lib/Socket/messages-recv.js +1385 -0
  36. package/lib/Socket/messages-send.js +956 -0
  37. package/lib/Socket/mex.js +69 -0
  38. package/lib/Socket/newsletter.js +424 -0
  39. package/lib/Socket/privacy.js +229 -0
  40. package/lib/Socket/registration.js +190 -0
  41. package/lib/Socket/socket.js +783 -0
  42. package/lib/Socket/username.d.ts +185 -0
  43. package/lib/Socket/username.js +168 -0
  44. package/lib/Socket/usync.js +80 -0
  45. package/lib/Store/index.js +14 -0
  46. package/lib/Store/keyed-db.js +158 -0
  47. package/lib/Store/make-cache-manager-store.js +88 -0
  48. package/lib/Store/make-in-memory-store.js +484 -0
  49. package/lib/Store/make-ordered-dictionary.js +78 -0
  50. package/lib/Store/object-repository.js +27 -0
  51. package/lib/Types/Auth.js +2 -0
  52. package/lib/Types/Call.js +2 -0
  53. package/lib/Types/Chat.js +10 -0
  54. package/lib/Types/Contact.js +2 -0
  55. package/lib/Types/Events.js +2 -0
  56. package/lib/Types/GroupMetadata.js +2 -0
  57. package/lib/Types/Label.js +27 -0
  58. package/lib/Types/LabelAssociation.js +9 -0
  59. package/lib/Types/Message.js +14 -0
  60. package/lib/Types/MexUpdates.js +19 -0
  61. package/lib/Types/Newsletter.js +38 -0
  62. package/lib/Types/Product.js +2 -0
  63. package/lib/Types/RichType.js +30 -0
  64. package/lib/Types/Signal.js +2 -0
  65. package/lib/Types/Socket.js +2 -0
  66. package/lib/Types/State.js +2 -0
  67. package/lib/Types/USync.js +2 -0
  68. package/lib/Types/index.js +58 -0
  69. package/lib/Utils/anti-ban.js +339 -0
  70. package/lib/Utils/anti-delete.d.ts +158 -0
  71. package/lib/Utils/anti-delete.js +293 -0
  72. package/lib/Utils/antiban-presets.js +91 -0
  73. package/lib/Utils/antiban-profiles.js +43 -0
  74. package/lib/Utils/auth-utils.js +210 -0
  75. package/lib/Utils/baileys-event-stream.js +66 -0
  76. package/lib/Utils/browser-utils.js +52 -0
  77. package/lib/Utils/business.js +261 -0
  78. package/lib/Utils/chat-control.d.ts +113 -0
  79. package/lib/Utils/chat-control.js +230 -0
  80. package/lib/Utils/chat-utils.js +922 -0
  81. package/lib/Utils/companion-reg-client-utils.js +37 -0
  82. package/lib/Utils/contact-graph-warmer.js +208 -0
  83. package/lib/Utils/crypto.js +196 -0
  84. package/lib/Utils/decode-wa-message.js +208 -0
  85. package/lib/Utils/delivery-tracker.js +110 -0
  86. package/lib/Utils/device-fingerprint.js +135 -0
  87. package/lib/Utils/event-buffer.js +531 -0
  88. package/lib/Utils/generics.js +571 -0
  89. package/lib/Utils/group-operation-guard.js +147 -0
  90. package/lib/Utils/health-monitor.js +207 -0
  91. package/lib/Utils/history.js +122 -0
  92. package/lib/Utils/human-entropy.js +226 -0
  93. package/lib/Utils/identity-change-handler.js +72 -0
  94. package/lib/Utils/index.js +83 -0
  95. package/lib/Utils/interactive-message.d.ts +139 -0
  96. package/lib/Utils/interactive-message.js +273 -0
  97. package/lib/Utils/legitimacy-signal-injector.js +180 -0
  98. package/lib/Utils/link-preview.js +106 -0
  99. package/lib/Utils/logger.d.ts +13 -0
  100. package/lib/Utils/logger.js +9 -0
  101. package/lib/Utils/lt-hash.js +54 -0
  102. package/lib/Utils/make-mutex.js +41 -0
  103. package/lib/Utils/message-composer.d.ts +106 -0
  104. package/lib/Utils/message-composer.js +721 -0
  105. package/lib/Utils/message-retry-manager.d.ts +88 -0
  106. package/lib/Utils/message-retry-manager.js +160 -0
  107. package/lib/Utils/message-search.d.ts +52 -0
  108. package/lib/Utils/message-search.js +226 -0
  109. package/lib/Utils/messages-media.js +899 -0
  110. package/lib/Utils/messages.js +2698 -0
  111. package/lib/Utils/noise-handler.js +175 -0
  112. package/lib/Utils/offline-node-processor.js +45 -0
  113. package/lib/Utils/pre-key-manager.js +131 -0
  114. package/lib/Utils/presence-choreographer.js +438 -0
  115. package/lib/Utils/process-message.js +423 -0
  116. package/lib/Utils/rate-limiter.js +232 -0
  117. package/lib/Utils/reconnect-throttle.js +157 -0
  118. package/lib/Utils/reply-ratio-guard.js +137 -0
  119. package/lib/Utils/reporting-utils.js +307 -0
  120. package/lib/Utils/retry-reason-tracker.js +140 -0
  121. package/lib/Utils/rich-message-utils.d.ts +48 -0
  122. package/lib/Utils/rich-message-utils.js +400 -0
  123. package/lib/Utils/rich-response-utils.js +461 -0
  124. package/lib/Utils/scheduling.d.ts +135 -0
  125. package/lib/Utils/scheduling.js +246 -0
  126. package/lib/Utils/session-fingerprint.js +226 -0
  127. package/lib/Utils/session-stability.js +224 -0
  128. package/lib/Utils/signal.js +188 -0
  129. package/lib/Utils/stanza-ack.js +38 -0
  130. package/lib/Utils/state-manager.js +91 -0
  131. package/lib/Utils/status-posting.d.ts +81 -0
  132. package/lib/Utils/status-posting.js +187 -0
  133. package/lib/Utils/stealth-connect.js +124 -0
  134. package/lib/Utils/sync-action-utils.js +55 -0
  135. package/lib/Utils/tc-token-utils.js +171 -0
  136. package/lib/Utils/templates.d.ts +54 -0
  137. package/lib/Utils/templates.js +244 -0
  138. package/lib/Utils/timelock-guard.js +162 -0
  139. package/lib/Utils/use-mongo-file-auth-state.d.ts +6 -0
  140. package/lib/Utils/use-mongo-file-auth-state.js +81 -0
  141. package/lib/Utils/use-multi-file-auth-state.js +125 -0
  142. package/lib/Utils/use-single-file-auth-state.d.ts +13 -0
  143. package/lib/Utils/use-single-file-auth-state.js +86 -0
  144. package/lib/Utils/use-sqlite-auth-state.js +187 -0
  145. package/lib/Utils/vCard.d.ts +71 -0
  146. package/lib/Utils/vCard.js +196 -0
  147. package/lib/Utils/validate-connection.js +253 -0
  148. package/lib/Utils/warmup.js +154 -0
  149. package/lib/WABinary/constants.js +1303 -0
  150. package/lib/WABinary/decode.js +270 -0
  151. package/lib/WABinary/encode.js +279 -0
  152. package/lib/WABinary/generic-utils.js +223 -0
  153. package/lib/WABinary/index.js +34 -0
  154. package/lib/WABinary/jid-utils.js +84 -0
  155. package/lib/WABinary/types.js +2 -0
  156. package/lib/WAM/BinaryInfo.js +13 -0
  157. package/lib/WAM/constants.js +15254 -0
  158. package/lib/WAM/encode.js +149 -0
  159. package/lib/WAM/index.js +32 -0
  160. package/lib/WAUSync/Protocols/USyncContactProtocol.js +37 -0
  161. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +71 -0
  162. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +32 -0
  163. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +49 -0
  164. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +23 -0
  165. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +58 -0
  166. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -0
  167. package/lib/WAUSync/Protocols/index.js +34 -0
  168. package/lib/WAUSync/USyncQuery.js +99 -0
  169. package/lib/WAUSync/USyncUser.js +26 -0
  170. package/lib/WAUSync/USyncUsernameProtocol.d.ts +9 -0
  171. package/lib/WAUSync/USyncUsernameProtocol.js +37 -0
  172. package/lib/WAUSync/index.js +32 -0
  173. package/lib/index.js +59 -0
  174. package/package.json +105 -5
  175. package/README.md +0 -5
@@ -0,0 +1,140 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.retry_reason_tracker = void 0
4
+
5
+ /**
6
+ * @file retry-reason-tracker.js
7
+ * @description Classifies message send failures/retries into known reasons
8
+ * (bad_mac, no_session, decryption_failure, server 429/463, etc) and
9
+ * detects "retry spirals" — a message stuck retrying repeatedly, which
10
+ * usually signals a broken session that needs manual intervention.
11
+ * Off by default.
12
+ * @author Denzy ZeroDay
13
+ */
14
+
15
+ const default_config = {
16
+ enabled: false,
17
+ max_retries: 5,
18
+ spiral_threshold: 3,
19
+ onSpiral: () => {}
20
+ }
21
+
22
+ class retry_reason_tracker {
23
+ constructor(config) {
24
+ this.config = { ...default_config, ...config }
25
+ this.retries = new Map()
26
+ this.total_retries = 0
27
+ this.reason_counts = {
28
+ no_session: 0,
29
+ invalid_key: 0,
30
+ bad_mac: 0,
31
+ decryption_failure: 0,
32
+ server_error_463: 0,
33
+ server_error_429: 0,
34
+ timeout: 0,
35
+ no_route: 0,
36
+ node_malformed: 0,
37
+ unknown: 0
38
+ }
39
+ this.spirals_detected = 0
40
+ }
41
+
42
+ /**
43
+ * Call when a messages.update event arrives with a status/error.
44
+ * Classifies and records the retry.
45
+ */
46
+ on_message_update(update) {
47
+ if (!this.config.enabled) return
48
+ const msg_id = update.key?.id
49
+ if (!msg_id) return
50
+ if (update.status !== 0 && !update.error) return
51
+ const reason = this.classify(update.error || update)
52
+ this.record_retry(msg_id, reason)
53
+ }
54
+
55
+ /** Classify an arbitrary error object into a retry reason */
56
+ classify(err) {
57
+ if (!err) return 'unknown'
58
+ const status_code = err.output?.statusCode || err.statusCode || err.status
59
+ if (status_code === 463) return 'server_error_463'
60
+ if (status_code === 429) return 'server_error_429'
61
+
62
+ const error_msg = (err.message || err.text || String(err)).toLowerCase()
63
+ if (error_msg.includes('bad mac')) return 'bad_mac'
64
+ if (error_msg.includes('no session') || error_msg.includes('session not found'))
65
+ return 'no_session'
66
+ if (error_msg.includes('invalid key') || error_msg.includes('key error'))
67
+ return 'invalid_key'
68
+ if (error_msg.includes('decryption') || error_msg.includes('decrypt'))
69
+ return 'decryption_failure'
70
+ if (error_msg.includes('timeout') || error_msg.includes('timed out')) return 'timeout'
71
+ if (
72
+ error_msg.includes('no route') ||
73
+ error_msg.includes('unreachable') ||
74
+ error_msg.includes('offline')
75
+ )
76
+ return 'no_route'
77
+ if (error_msg.includes('malformed') || error_msg.includes('invalid node'))
78
+ return 'node_malformed'
79
+ return 'unknown'
80
+ }
81
+
82
+ /** Record a retry for a message */
83
+ record_retry(msg_id, reason) {
84
+ const now = Date.now()
85
+ let record = this.retries.get(msg_id)
86
+ if (!record) {
87
+ record = { msgId: msg_id, count: 0, reasons: [], firstRetry: now, lastRetry: now }
88
+ this.retries.set(msg_id, record)
89
+ }
90
+ record.count++
91
+ record.reasons.push(reason)
92
+ record.lastRetry = now
93
+ this.total_retries++
94
+ this.reason_counts[reason]++
95
+
96
+ if (record.count >= this.config.spiral_threshold) {
97
+ this.spirals_detected++
98
+ this.config.onSpiral(msg_id, reason)
99
+ }
100
+ }
101
+
102
+ /** Should we warn the user this message is spiraling? */
103
+ is_spiraling(msg_id) {
104
+ const record = this.retries.get(msg_id)
105
+ return record ? record.count >= this.config.spiral_threshold : false
106
+ }
107
+
108
+ /** Reset counters for a specific message (call on successful delivery) */
109
+ clear(msg_id) {
110
+ this.retries.delete(msg_id)
111
+ }
112
+
113
+ /** Get current stats */
114
+ get_stats() {
115
+ return {
116
+ totalRetries: this.total_retries,
117
+ byReason: { ...this.reason_counts },
118
+ spiralsDetected: this.spirals_detected,
119
+ activeRetries: this.retries.size
120
+ }
121
+ }
122
+
123
+ /** Clean up old retry records (>5 minutes old) */
124
+ cleanup() {
125
+ const now = Date.now()
126
+ const max_age = 5 * 60 * 1000
127
+ for (const [msg_id, record] of this.retries.entries()) {
128
+ if (now - record.lastRetry > max_age) this.retries.delete(msg_id)
129
+ }
130
+ }
131
+
132
+ /** Destroy and clean up */
133
+ destroy() {
134
+ this.retries.clear()
135
+ this.cleanup()
136
+ }
137
+ }
138
+
139
+ exports.retry_reason_tracker = retry_reason_tracker
140
+ module.exports = { retry_reason_tracker }
@@ -0,0 +1,48 @@
1
+ export function tokenizeCode(code: any, language?: string): {
2
+ highlightType: any;
3
+ codeContent: string | undefined;
4
+ }[];
5
+ export function toUnified(submessages: any, uuid: any): {
6
+ response_id: any;
7
+ sections: any;
8
+ };
9
+ export function prepareRichResponseMessage(content: any): {
10
+ messageContextInfo: {
11
+ botMetadata: {
12
+ verificationMetadata: {
13
+ proofs: {
14
+ certificateChain: Uint8Array[];
15
+ version: number;
16
+ useCase: number;
17
+ signature: Uint8Array;
18
+ }[];
19
+ };
20
+ };
21
+ };
22
+ botForwardedMessage: {
23
+ message: {
24
+ richResponseMessage: any;
25
+ };
26
+ };
27
+ };
28
+ export function botMetadataSignature(): Uint8Array;
29
+ export function botMetadataCertificate(length?: number): Uint8Array;
30
+ export function wrapToBotForwardedMessage(richResponseMessage: any): {
31
+ messageContextInfo: {
32
+ botMetadata: {
33
+ verificationMetadata: {
34
+ proofs: {
35
+ certificateChain: Uint8Array[];
36
+ version: number;
37
+ useCase: number;
38
+ signature: Uint8Array;
39
+ }[];
40
+ };
41
+ };
42
+ };
43
+ botForwardedMessage: {
44
+ message: {
45
+ richResponseMessage: any;
46
+ };
47
+ };
48
+ };
@@ -0,0 +1,400 @@
1
+ 'use strict'
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true })
4
+
5
+ const crypto = require('crypto')
6
+ const Defaults = require('../Defaults')
7
+ const constants = require('../WABinary/constants')
8
+ const RichType = require('../Types/RichType')
9
+ const WAProto = require('../../WAProto')
10
+ const generics = require('./generics')
11
+
12
+ const DONATE_URL = ''
13
+ const NOOP = new Set([])
14
+
15
+ const tokenizeCode = (code, language = 'javascript') => {
16
+ const keywords = constants.LANGUAGE_KEYWORDS[language] || NOOP
17
+ const blocks = []
18
+ Defaults.LEXER_REGEX.lastIndex = 0
19
+ let match
20
+ while ((match = Defaults.LEXER_REGEX.exec(code)) !== null) {
21
+ if (match[1]) {
22
+ blocks.push({
23
+ highlightType: RichType.CodeHighlightType.COMMENT,
24
+ codeContent: match[1]
25
+ })
26
+ } else if (match[2]) {
27
+ blocks.push({ highlightType: RichType.CodeHighlightType.STRING, codeContent: match[2] })
28
+ } else if (match[3]) {
29
+ blocks.push({
30
+ highlightType: keywords.has(match[3])
31
+ ? RichType.CodeHighlightType.KEYWORD
32
+ : RichType.CodeHighlightType.METHOD,
33
+ codeContent: match[3]
34
+ })
35
+ } else if (match[4]) {
36
+ blocks.push({
37
+ highlightType: keywords.has(match[4])
38
+ ? RichType.CodeHighlightType.KEYWORD
39
+ : RichType.CodeHighlightType.DEFAULT,
40
+ codeContent: match[4]
41
+ })
42
+ } else if (match[5]) {
43
+ blocks.push({ highlightType: RichType.CodeHighlightType.NUMBER, codeContent: match[5] })
44
+ } else {
45
+ blocks.push({
46
+ highlightType: RichType.CodeHighlightType.DEFAULT,
47
+ codeContent: match[6]
48
+ })
49
+ }
50
+ }
51
+ return blocks
52
+ }
53
+
54
+ const toUnified = (submessages, uuid) => ({
55
+ response_id: uuid || crypto.randomUUID(),
56
+ sections: submessages.map((submessage) => {
57
+ switch (submessage.messageType) {
58
+ case RichType.RichSubMessageType.CODE:
59
+ const codeMetadata = submessage.codeMetadata
60
+ return {
61
+ view_model: {
62
+ primitive: {
63
+ language: codeMetadata.codeLanguage,
64
+ code_blocks: codeMetadata.codeBlocks.map((block) => ({
65
+ content: block.codeContent,
66
+ type: RichType.CodeHighlightType[block.highlightType] || 'DEFAULT'
67
+ })),
68
+ __typename: 'GenAICodeUXPrimitive'
69
+ },
70
+ __typename: 'GenAISingleLayoutViewModel'
71
+ }
72
+ }
73
+ case RichType.RichSubMessageType.CONTENT_ITEMS:
74
+ return {}
75
+ case RichType.RichSubMessageType.INLINE_IMAGE:
76
+ return {}
77
+ case RichType.RichSubMessageType.LATEX:
78
+ return {}
79
+ case RichType.RichSubMessageType.TABLE:
80
+ const tableMetadata = submessage.tableMetadata
81
+ return {
82
+ view_model: {
83
+ primitive: {
84
+ title: tableMetadata.title,
85
+ rows: tableMetadata.rows.map((row) => ({
86
+ is_header: row.isHeading,
87
+ cells: row.items,
88
+ markdown_cells: row.items.map((item) => ({ text: item }))
89
+ })),
90
+ __typename: 'GenATableUXPrimitive'
91
+ },
92
+ __typename: 'GenAISingleLayoutViewModel'
93
+ }
94
+ }
95
+ case RichType.RichSubMessageType.TEXT:
96
+ return {
97
+ view_model: {
98
+ primitive: {
99
+ text: submessage.messageText,
100
+ inline_entities: submessage.inlineEntities || [],
101
+ __typename: 'GenAIMarkdownTextUXPrimitive'
102
+ },
103
+ __typename: 'GenAISingleLayoutViewModel'
104
+ }
105
+ }
106
+ }
107
+ return submessage
108
+ })
109
+ })
110
+
111
+ const prepareRichResponseMessage = (content) => {
112
+ const {
113
+ alignment,
114
+ code,
115
+ contentText,
116
+ disclaimerText,
117
+ footerText,
118
+ headerText,
119
+ imageText,
120
+ inlineImage,
121
+ inlineVideo,
122
+ items,
123
+ language,
124
+ latex,
125
+ links,
126
+ noHeading,
127
+ posts,
128
+ products,
129
+ suggested,
130
+ richResponse,
131
+ table,
132
+ tapLinkUrl,
133
+ title
134
+ } = content
135
+ let submessages = []
136
+ if (Array.isArray(richResponse)) {
137
+ submessages = richResponse.map((submessage) => {
138
+ if (submessage.text) {
139
+ return {
140
+ messageType: RichType.RichSubMessageType.TEXT,
141
+ messageText: submessage.text,
142
+ inlineEntities: submessage.inlineEntities
143
+ }
144
+ } else if (submessage.code) {
145
+ return {
146
+ messageType: RichType.RichSubMessageType.CODE,
147
+ codeMetadata: {
148
+ codeLanguage: submessage.language,
149
+ codeBlocks: submessage.code
150
+ }
151
+ }
152
+ } else if (submessage.items) {
153
+ return {
154
+ messageType: RichType.RichSubMessageType.CONTENT_ITEMS,
155
+ contentItemsMetadata: {
156
+ itemsMetadata: submessage.items,
157
+ contentType:
158
+ WAProto.proto.AIRichResponseContentItemsMetadata.ContentType.CAROUSEL
159
+ }
160
+ }
161
+ } else if (submessage.inlineImage) {
162
+ return {
163
+ messageType: RichType.RichSubMessageType.INLINE_IMAGE,
164
+ imageMetadata: {
165
+ imageUrl: submessage.inlineImage,
166
+ imageText: submessage.imageText,
167
+ alignment: submessage.alignment,
168
+ tapLinkUrl: submessage.tapLinkUrl
169
+ }
170
+ }
171
+ } else if (submessage.inlineVideo) {
172
+ return {
173
+ messageType: RichType.RichSubMessageType.TEXT,
174
+ messageText: 'INLINE_VIDEO'
175
+ }
176
+ } else if (submessage.latex) {
177
+ return {
178
+ messageType: RichType.RichSubMessageType.LATEX,
179
+ latexMetadata: {
180
+ text: submessage.text,
181
+ expressions: submessage.latex
182
+ }
183
+ }
184
+ } else if (submessage.posts) {
185
+ return {
186
+ messageType: RichType.RichSubMessageType.TEXT,
187
+ messageText: 'POSTS'
188
+ }
189
+ } else if (submessage.products) {
190
+ return {
191
+ messageType: RichType.RichSubMessageType.TEXT,
192
+ messageText: 'PRODUCTS'
193
+ }
194
+ } else if (submessage.suggested) {
195
+ return {
196
+ messageType: RichType.RichSubMessageType.TEXT,
197
+ messageText: 'SUGGESTED_PROMPT'
198
+ }
199
+ } else if (submessage.table) {
200
+ return {
201
+ messageType: RichType.RichSubMessageType.TABLE,
202
+ tableMetadata: {
203
+ title: submessage.title,
204
+ rows: submessage.table
205
+ }
206
+ }
207
+ }
208
+ return submessage
209
+ })
210
+ } else {
211
+ if (headerText) {
212
+ submessages.push({
213
+ messageType: RichType.RichSubMessageType.TEXT,
214
+ messageText: headerText
215
+ })
216
+ }
217
+ if (contentText) {
218
+ submessages.push({
219
+ messageType: RichType.RichSubMessageType.TEXT,
220
+ messageText: contentText
221
+ })
222
+ }
223
+ if (code) {
224
+ const lang = language || 'javascript'
225
+ submessages.push({
226
+ messageType: RichType.RichSubMessageType.CODE,
227
+ codeMetadata: {
228
+ codeLanguage: lang,
229
+ codeBlocks: tokenizeCode(code, lang)
230
+ }
231
+ })
232
+ }
233
+ if (items) {
234
+ submessages.push({
235
+ messageType: RichType.RichSubMessageType.CONTENT_ITEMS,
236
+ contentItemsMetadata: {
237
+ itemsMetadata: items,
238
+ contentType:
239
+ WAProto.proto.AIRichResponseContentItemsMetadata.ContentType.CAROUSEL
240
+ }
241
+ })
242
+ }
243
+ if (inlineImage) {
244
+ submessages.push({
245
+ messageType: RichType.RichSubMessageType.INLINE_IMAGE,
246
+ imageMetadata: {
247
+ imageUrl: inlineImage,
248
+ imageText,
249
+ alignment,
250
+ tapLinkUrl
251
+ }
252
+ })
253
+ }
254
+ if (inlineVideo) {
255
+ submessages.push({
256
+ messageType: RichType.RichSubMessageType.TEXT,
257
+ messageText: 'INLINE_VIDEO'
258
+ })
259
+ }
260
+ if (latex) {
261
+ submessages.push({
262
+ messageType: RichType.RichSubMessageType.LATEX,
263
+ latexMetadata: {
264
+ text: content.text,
265
+ expressions: latex
266
+ }
267
+ })
268
+ }
269
+ if (links) {
270
+ links.forEach((linkField, index) => {
271
+ const prefix = 'SS_' + index
272
+ const url = linkField.url || DONATE_URL
273
+ const sources = linkField.sources?.map((sourceField) => ({
274
+ source_type: 'THIRD_PARTY',
275
+ source_display_name: sourceField.displayName || 'Donate',
276
+ source_subtitle: sourceField.subtitle || '',
277
+ source_url: sourceField.url || url
278
+ }))
279
+ submessages.push({
280
+ messageType: RichType.RichSubMessageType.TEXT,
281
+ messageText: linkField.text + ` {{${prefix}}}¹{{/${prefix}}} `,
282
+ inlineEntities: [
283
+ {
284
+ key: prefix,
285
+ metadata: {
286
+ reference_id: index + 1,
287
+ reference_url: url,
288
+ reference_title: linkField.title || 'Citation Reference',
289
+ reference_display_name: linkField.displayName || 'Reference',
290
+ sources: sources || [],
291
+ __typename: 'GenAISearchCitationItem'
292
+ }
293
+ }
294
+ ]
295
+ })
296
+ })
297
+ }
298
+ if (posts) {
299
+ submessages.push({
300
+ messageType: RichType.RichSubMessageType.TEXT,
301
+ messageText: 'POSTS'
302
+ })
303
+ }
304
+ if (products) {
305
+ submessages.push({
306
+ messageType: RichType.RichSubMessageType.TEXT,
307
+ messageText: 'PRODUCTS'
308
+ })
309
+ }
310
+ if (suggested) {
311
+ submessages.push({
312
+ messageType: RichType.RichSubMessageType.TEXT,
313
+ messageText: 'SUGGESTED_PROMPT'
314
+ })
315
+ }
316
+ if (table) {
317
+ submessages.push({
318
+ messageType: RichType.RichSubMessageType.TABLE,
319
+ tableMetadata: {
320
+ title,
321
+ rows: table.map((rowItems, index) => ({
322
+ isHeading: !noHeading && index == 0,
323
+ items: rowItems
324
+ }))
325
+ }
326
+ })
327
+ }
328
+ if (footerText) {
329
+ submessages.push({
330
+ messageType: RichType.RichSubMessageType.TEXT,
331
+ messageText: footerText
332
+ })
333
+ }
334
+ }
335
+ const uuid = crypto.randomUUID()
336
+ const unified = toUnified(submessages, uuid)
337
+ const richResponseMessage = WAProto.proto.AIRichResponseMessage.create({
338
+ submessages,
339
+ messageType: WAProto.proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
340
+ unifiedResponse: {
341
+ data: Buffer.from(JSON.stringify(unified))
342
+ },
343
+ contextInfo: {
344
+ isForwarded: true,
345
+ forwardingScore: 1,
346
+ forwardedAiBotMessageInfo: { botJid: '867051314767696@bot' },
347
+ forwardOrigin: 4
348
+ }
349
+ })
350
+ const wrappedMsg = wrapToBotForwardedMessage(richResponseMessage)
351
+ const botMetadata = wrappedMsg.messageContextInfo.botMetadata
352
+ if (disclaimerText) {
353
+ botMetadata.messageDisclaimerText = disclaimerText
354
+ }
355
+ botMetadata.botResponseId = uuid
356
+ return wrappedMsg
357
+ }
358
+
359
+ const botMetadataSignature = () => {
360
+ const signature = new Uint8Array(64)
361
+ crypto.randomFillSync(signature)
362
+ return signature
363
+ }
364
+
365
+ const botMetadataCertificate = (length = 685) => {
366
+ const certificate = new Uint8Array(length)
367
+ certificate[0] = 48
368
+ certificate[1] = 130
369
+ crypto.randomFillSync(certificate.subarray(2))
370
+ return certificate
371
+ }
372
+
373
+ const wrapToBotForwardedMessage = (richResponseMessage) => ({
374
+ messageContextInfo: {
375
+ botMetadata: {
376
+ verificationMetadata: {
377
+ proofs: [
378
+ {
379
+ certificateChain: [botMetadataCertificate(), botMetadataCertificate(892)],
380
+ version: 1,
381
+ useCase: 1,
382
+ signature: botMetadataSignature()
383
+ }
384
+ ]
385
+ }
386
+ }
387
+ },
388
+ botForwardedMessage: {
389
+ message: { richResponseMessage }
390
+ }
391
+ })
392
+
393
+ module.exports = {
394
+ tokenizeCode,
395
+ toUnified,
396
+ prepareRichResponseMessage,
397
+ botMetadataSignature,
398
+ botMetadataCertificate,
399
+ wrapToBotForwardedMessage
400
+ }