@itsliaaa/baileys 0.1.23 โ†’ 0.1.25

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.
package/README.md CHANGED
@@ -34,16 +34,13 @@ This fork designed for production use with a focus on clarity and safety:
34
34
  - ๐Ÿšซ No obfuscation. Easy to read and audit.
35
35
  - ๐Ÿšซ No auto-follow channel (newsletter) behavior.
36
36
 
37
- ### โš™๏ธ Changes
38
-
39
- #### ๐Ÿ› ๏ธ Internal Adjustments
37
+ ### ๐Ÿ› ๏ธ Internal Adjustments
40
38
  - ๐Ÿ–ผ๏ธ Fixed an issue where media could not be sent to newsletters due to an upstream issue.
41
39
  - ๐Ÿ“ Reintroduced [`makeInMemoryStore`](#%EF%B8%8F-implementing-a-data-store) with a minimal ESM adaptation and small adjustments for Baileys v7.
42
40
  - ๐Ÿ“ฆ Switched FFmpeg execution from `exec` to `spawn` for safer process handling.
43
41
  - ๐Ÿ—ƒ๏ธ Added [`@napi-rs/image`](https://www.npmjs.com/package/@napi-rs/image) as a supported image processing backend in [`getImageProcessingLibrary()`](#%EF%B8%8F-image-processing), offering a balance between performance and compatibility.
44
42
 
45
- #### ๐Ÿ“จ Message Handling & Compatibility
46
- - ๐Ÿ“ฐ Simplified sending messages with ad thumbnail using [`externalAdReply`](#3%EF%B8%8Fโƒฃ-external-ad-reply), without requiring manual `contextInfo`.
43
+ ### ๐Ÿ“จ Message Handling & Compatibility
47
44
  - ๐Ÿ“ฉ Expanded message support for:
48
45
  - ๐Ÿ–ผ๏ธ [Album Message](#%EF%B8%8F-album-image--video)
49
46
  - ๐Ÿ‘ค [Group Status Message](#4%EF%B8%8Fโƒฃ-group-status)
@@ -54,8 +51,9 @@ This fork designed for production use with a focus on clarity and safety:
54
51
  - ๐Ÿงพ [Message with Code Blocks](#-message-with-code-block) **[NEW]**
55
52
  - ๐Ÿ“‹ [Message with Table](#-message-with-table) **[NEW]**
56
53
  - ๐Ÿ’ณ [Payment-related Message](#-sending-payment-messages) (payment requests, invites, orders, invoices).
54
+ - ๐Ÿ“ฐ Simplified sending messages with ad thumbnail using [`externalAdReply`](#3%EF%B8%8Fโƒฃ-external-ad-reply), without requiring manual `contextInfo`.
57
55
 
58
- #### ๐Ÿงฉ Additional Message Options
56
+ ### ๐Ÿงฉ Additional Message Options
59
57
  - ๐Ÿ‘๏ธ Added optional boolean flags for message handling:
60
58
  - ๐Ÿค– [`ai`](#1%EF%B8%8Fโƒฃ-ai-icon) - AI icon on message
61
59
  - ๐Ÿ“ฃ [`mentionAll`](#-mention) - Mention all group participants without requiring their JIDs in `mentions` or `mentionedJid` **[NEW]**
@@ -340,6 +338,29 @@ sock.sendMessage(jid, {
340
338
  quoted: message
341
339
  })
342
340
  ```
341
+ ##### ๐Ÿ—“๏ธ Event
342
+
343
+ ```javascript
344
+ sock.sendMessage(jid, {
345
+ event: {
346
+ name: '๐ŸŽถ Meet & Mingle Party',
347
+ description: 'Meet & Mingle Party is a fun, casual gathering to connect, chat, and build new relationships within the community.',
348
+ call: 'audio', // --- Or "video", this field is optional
349
+ startDate: new Date(Date.now() + 3600000),
350
+ endDate: new Date(Date.now() + 28800000),
351
+ isCancelled: false, // --- Optional
352
+ isScheduleCall: false, // --- Optional
353
+ extraGuestsAllowed: false, // --- Optional
354
+ location: {
355
+ name: 'Jakarta',
356
+ degreesLatitude: -6.2,
357
+ degreesLongitude: 106.8
358
+ }
359
+ }
360
+ }, {
361
+ quoted: message
362
+ })
363
+ ```
343
364
 
344
365
  ##### ๐Ÿ“Š Poll
345
366
 
@@ -400,11 +421,56 @@ sock.sendMessage(jid, {
400
421
  })
401
422
  ```
402
423
 
403
- ##### ๐ŸŽž๏ธ Status Mention
424
+ ##### ๐Ÿ’ญ Response
404
425
 
405
426
  ```javascript
406
- sock.sendMessage([jidA, jidB, jidC], {
407
- text: 'Hello! ๐Ÿ‘‹๐Ÿป'
427
+ // --- Using buttonsResponseMessage
428
+ sock.sendMessage(jid, {
429
+ type: 'plain',
430
+ buttonReply: {
431
+ id: '#Menu',
432
+ displayText: 'โœจ Interesting Menu'
433
+ }
434
+ }, {
435
+ quoted: message
436
+ })
437
+
438
+ // --- Using interactiveResponseMessage
439
+ sock.sendMessage(jid, {
440
+ flowReply: {
441
+ format: 0,
442
+ text: '๐Ÿ’ญ Response',
443
+ name: 'menu_options',
444
+ paramsJson: JSON.stringify({
445
+ id: '#Menu',
446
+ description: 'โœจ Interesting Menu'
447
+ })
448
+ }
449
+ }, {
450
+ quoted: message
451
+ })
452
+
453
+ // --- Using listResponseMessage
454
+ sock.sendMessage(jid, {
455
+ listReply: {
456
+ title: '๐Ÿ“„ See More',
457
+ description: 'โœจ Interesting Menu',
458
+ id: '#Menu'
459
+ }
460
+ }, {
461
+ quoted: message
462
+ })
463
+
464
+ // --- Using templateButtonReplyMessage
465
+ sock.sendMessage(jid, {
466
+ type: 'template',
467
+ buttonReply: {
468
+ id: '#Menu',
469
+ displayText: 'โœจ Interesting Menu',
470
+ index: 1
471
+ }
472
+ }, {
473
+ quoted: message
408
474
  })
409
475
  ```
410
476
 
@@ -453,10 +519,11 @@ sock.sendMessage(jid, {
453
519
 
454
520
  ```javascript
455
521
  sock.sendMessage(jid, {
456
- header: 'Example Usage',
522
+ headerText: '## Example Usage',
523
+ contentText: '---',
457
524
  code: 'console.log("Hello, World!")',
458
- footer: 'Pretty simple, right?',
459
- language: 'javascript'
525
+ language: 'javascript',
526
+ footerText: 'Pretty simple, right?'
460
527
  })
461
528
  ```
462
529
 
@@ -464,14 +531,23 @@ sock.sendMessage(jid, {
464
531
 
465
532
  ```javascript
466
533
  sock.sendMessage(jid, {
467
- header: 'Comparison between Node.js, Bun, and Deno',
534
+ headerText: '## Comparison between Node.js, Bun, and Deno',
535
+ contentText: '---',
468
536
  title: 'Runtime Comparison',
469
537
  table: [
470
538
  ['', 'Node.js', 'Bun', 'Deno'],
471
539
  ['Engine', 'V8 (C++)', 'JavaScriptCore (C++)', 'V8 (C++)'],
472
540
  ['Performance', '4/5', '5/5', '4/5']
473
541
  ],
474
- footer: 'Does this help clarify the differences?'
542
+ footerText: 'Does this help clarify the differences?'
543
+ })
544
+ ```
545
+
546
+ ##### ๐ŸŽž๏ธ Status Mention
547
+
548
+ ```javascript
549
+ sock.sendMessage([jidA, jidB, jidC], {
550
+ text: 'Hello! ๐Ÿ‘‹๐Ÿป'
475
551
  })
476
552
  ```
477
553
 
@@ -145,10 +145,4 @@ export const TimeMs = {
145
145
  export const BOT_RENDERING_CONFIG_METADATA = {
146
146
  bloksVersioningId: '0903aa5f7f47de66789d5f4c86d3bd6e05e4bc3ff85e454a9f907d5ed7fef97c',
147
147
  pixelDensity: 2.75
148
- };
149
- export const FORWARDED_AI_BOT_INFO = {
150
- isForwarded: true,
151
- forwardingScore: 1,
152
- forwardedAiBotMessageInfo: { botJid: '867051314767696@bot' },
153
- forwardOrigin: 4
154
148
  };
@@ -10,7 +10,7 @@ import { isPnUser, isLidUser, isJidGroup, isJidNewsletter, isJidStatusBroadcast,
10
10
  import { sha256 } from './crypto.js';
11
11
  import { generateMessageIDV2, getKeyAuthor, unixTimestampSeconds } from './generics.js';
12
12
  import { downloadContentFromMessage, encryptedStream, generateThumbnail, getAudioDuration, getAudioWaveform, getImageProcessingLibrary, getRawMediaUploadData, getStream, toBuffer } from './messages-media.js';
13
- import { prepareRichCodeBlock, prepareRichLatex, prepareRichReels, prepareRichResponseMessage, prepareRichTable, wrapToBotForwardedMessage } from './rich-message-utils.js';
13
+ import { prepareRichResponseMessage } from './rich-message-utils.js';
14
14
  import { shouldIncludeReportingToken } from './reporting-utils.js';
15
15
  const MIMETYPE_MAP = {
16
16
  image: 'image/jpeg',
@@ -695,6 +695,14 @@ export const generateWAMessageContent = async (message, options) => {
695
695
  delete message.raw;
696
696
  return message;
697
697
  }
698
+ // Lia@Changes 09-04-26 --- Add support for code block, latex, reels carousel, table with richResponseMessage
699
+ else if (hasNonNullishProperty(message, 'code') ||
700
+ hasNonNullishProperty(message, 'expressions') ||
701
+ hasNonNullishProperty(message, 'items') ||
702
+ hasNonNullishProperty(message, 'table') ||
703
+ hasNonNullishProperty(message, 'richResponse')) {
704
+ m = prepareRichResponseMessage(message);
705
+ }
698
706
  else if (hasNonNullishProperty(message, 'text')) {
699
707
  const extContent = { text: message.text };
700
708
  let urlInfo = message.linkPreview;
@@ -1018,22 +1026,6 @@ export const generateWAMessageContent = async (message, options) => {
1018
1026
  expectedVideoCount: videoCount
1019
1027
  };
1020
1028
  }
1021
- // Lia@Changes 09-04-26 --- Add support for code block, latex, reels carousel, table with richResponseMessage
1022
- else if (hasNonNullishProperty(message, 'code')) {
1023
- m.richResponseMessage = prepareRichCodeBlock(message);
1024
- }
1025
- else if (hasNonNullishProperty(message, 'expressions')) {
1026
- m.richResponseMessage = prepareRichLatex(message);
1027
- }
1028
- else if (hasNonNullishProperty(message, 'items')) {
1029
- m.richResponseMessage = prepareRichReels(message);
1030
- }
1031
- else if (hasNonNullishProperty(message, 'table')) {
1032
- m.richResponseMessage = prepareRichTable(message);
1033
- }
1034
- else if (hasNonNullishProperty(message, 'richResponse')) {
1035
- m.richResponseMessage = prepareRichResponseMessage(message.richResponse);
1036
- }
1037
1029
  else {
1038
1030
  m = await prepareWAMessageMedia(message, options);
1039
1031
  }
@@ -1425,10 +1417,6 @@ export const generateWAMessageContent = async (message, options) => {
1425
1417
  m = { viewOnceMessageV2Extension: { message: m } };
1426
1418
  delete message.viewOnceV2Extension;
1427
1419
  }
1428
- // Lia@Note 09-04-26 --- Wrap richResponseMessage into botForwardedMessage
1429
- if (!!m.richResponseMessage) {
1430
- m = wrapToBotForwardedMessage(m)
1431
- }
1432
1420
  if (hasOptionalProperty(message, 'edit')) {
1433
1421
  m = {
1434
1422
  protocolMessage: {
@@ -4,11 +4,12 @@
4
4
  *
5
5
  * If you use or copy this code, please credit my name or project.
6
6
  */
7
- import { randomUUID } from 'crypto';
8
- import { BOT_RENDERING_CONFIG_METADATA, FORWARDED_AI_BOT_INFO, LEXER_REGEX } from '../Defaults/index.js';
7
+ import { getRandomValues, randomUUID, randomBytes } from 'crypto';
8
+ import { BOT_RENDERING_CONFIG_METADATA, DONATE_URL, LEXER_REGEX } from '../Defaults/index.js';
9
9
  import { LANGUAGE_KEYWORDS } from '../WABinary/constants.js';
10
10
  import { CodeHighlightType, RichSubMessageType } from '../Types/RichType.js';
11
11
  import { proto } from '../../WAProto/index.js';
12
+ import { unixTimestampSeconds } from './generics.js';
12
13
  const textEncoder = new TextEncoder();
13
14
  const NOOP = new Set([]);
14
15
  export const tokenizeCode = (code, language = 'javascript') => {
@@ -48,14 +49,15 @@ export const tokenizeCode = (code, language = 'javascript') => {
48
49
  export const toUnified = (submessages) =>
49
50
  ({
50
51
  response_id: randomUUID(),
51
- sections: submessages.map((submessage) => {
52
+ sections: submessages.map((submessage, index) => {
52
53
  switch (submessage.messageType) {
53
54
  case RichSubMessageType.CODE:
55
+ const codeMetadata = submessage.codeMetadata;
54
56
  return {
55
57
  view_model: {
56
58
  primitive: {
57
- language: submessage.codeMetadata.codeLanguage,
58
- code_blocks: submessage.codeMetadata.codeBlocks.map((block) => ({ content: block.codeContent, type: CodeHighlightType[block.highlightType] })),
59
+ language: codeMetadata.codeLanguage,
60
+ code_blocks: codeMetadata.codeBlocks.map((block) => ({ content: block.codeContent, type: CodeHighlightType[block.highlightType] })),
59
61
  __typename: 'GenAICodeUXPrimitive'
60
62
  },
61
63
  __typename: 'GenAISingleLayoutViewModel'
@@ -84,14 +86,15 @@ export const toUnified = (submessages) =>
84
86
  }
85
87
  };
86
88
  case RichSubMessageType.LATEX:
89
+ const latexMetadata = submessage.latexMetadata;
87
90
  const item = {
88
- latex_expression: submessage.latexMetadata.expressions[0]?.latexExpression,
89
- font_height: submessage.latexMetadata.expressions[0]?.fontHeight,
91
+ latex_expression: latexMetadata.expressions[0]?.latexExpression,
92
+ font_height: latexMetadata.expressions[0]?.fontHeight,
90
93
  padding: 15,
91
94
  latex_image: {
92
- url: submessage.latexMetadata.expressions[0]?.url,
93
- width: submessage.latexMetadata.expressions[0]?.width || 388,
94
- height: submessage.latexMetadata.expressions[0]?.height || 160
95
+ url: latexMetadata.expressions[0]?.url,
96
+ width: latexMetadata.expressions[0]?.width || 388,
97
+ height: latexMetadata.expressions[0]?.height || 160
95
98
  }
96
99
  };
97
100
  return {
@@ -105,20 +108,47 @@ export const toUnified = (submessages) =>
105
108
  }
106
109
  };
107
110
  case RichSubMessageType.TABLE:
111
+ const tableMetadata = submessage.tableMetadata;
108
112
  return {
109
113
  view_model: {
110
114
  primitive: {
111
- title: submessage.tableMetadata.title,
112
- rows: submessage.tableMetadata.rows.map((row) => ({ is_header: row.isHeading, cells: row.items, markdown_cells: [] })),
115
+ title: tableMetadata.title,
116
+ rows: tableMetadata.rows.map((row) => ({ is_header: row.isHeading, cells: row.items, markdown_cells: [] })),
113
117
  __typename: 'GenATableUXPrimitive'
114
118
  },
115
119
  __typename: 'GenAISingleLayoutViewModel'
116
120
  }
117
121
  };
118
122
  case RichSubMessageType.TEXT:
123
+ const shouldAddInlineEntity = index == 0;
124
+ const inlineEntity = [{
125
+ key: 'Starseed',
126
+ metadata: {
127
+ reference_id: 1,
128
+ reference_url: DONATE_URL,
129
+ reference_title: 'For Donation via Saweria',
130
+ reference_display_name: 'Donate',
131
+ sources: [{
132
+ source_type: 'THIRD_PARTY',
133
+ source_display_name: 'Donate',
134
+ source_subtitle: '',
135
+ source_url: DONATE_URL
136
+ }],
137
+ __typename: 'GenAISearchCitationItem'
138
+ }
139
+ }];
140
+ const textEntity = shouldAddInlineEntity ?
141
+ '{{Starseed}}ยน{{/Starseed}}' :
142
+ '';
119
143
  return {
120
144
  view_model: {
121
- primitive: { text: submessage.messageText, inline_entities: [], __typename: 'GenAIMarkdownTextUXPrimitive' },
145
+ primitive: {
146
+ text: submessage.messageText + textEntity,
147
+ inline_entities: shouldAddInlineEntity ?
148
+ inlineEntity :
149
+ [],
150
+ __typename: 'GenAIMarkdownTextUXPrimitive'
151
+ },
122
152
  __typename: 'GenAISingleLayoutViewModel'
123
153
  }
124
154
  };
@@ -126,198 +156,231 @@ export const toUnified = (submessages) =>
126
156
  return submessage;
127
157
  })
128
158
  });
129
- export const prepareRichCodeBlock = ({ header, code, footer, language } = {}) => {
130
- language ??= 'javascript';
131
- const submessages = [];
132
- if (header) {
133
- submessages.push({
134
- messageType: RichSubMessageType.TEXT,
135
- messageText: header
136
- });
137
- }
138
- submessages.push({
139
- messageType: RichSubMessageType.CODE,
140
- codeMetadata: {
141
- codeLanguage: language,
142
- codeBlocks: tokenizeCode(code, language)
143
- }
144
- });
145
- if (footer) {
146
- submessages.push({
147
- messageType: RichSubMessageType.TEXT,
148
- messageText: footer
149
- });
150
- }
151
- const unified = toUnified(submessages);
152
- return {
153
- submessages,
154
- messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
155
- unifiedResponse: {
156
- data: textEncoder.encode(JSON.stringify(unified))
157
- },
158
- contextInfo: FORWARDED_AI_BOT_INFO
159
- };
160
- };
161
- export const prepareRichReels = ({ header, items, footer } = {}) => {
162
- const submessages = [];
163
- if (header) {
164
- submessages.push({
165
- messageType: RichSubMessageType.TEXT,
166
- messageText: header
167
- });
168
- }
169
- submessages.push({
170
- messageType: RichSubMessageType.CONTENT_ITEMS,
171
- contentItemsMetadata: {
172
- itemsMetadata: items.map((item) => ({ reelItem: item })),
173
- contentType: proto.AIRichResponseContentItemsMetadata.ContentType.CAROUSEL
174
- }
175
- });
176
- if (footer) {
177
- submessages.push({
178
- messageType: RichSubMessageType.TEXT,
179
- messageText: footer
180
- });
181
- }
182
- const unified = toUnified(submessages);
183
- return {
184
- submessages,
185
- messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
186
- unifiedResponse: {
187
- data: textEncoder.encode(JSON.stringify(unified))
188
- },
189
- contextInfo: FORWARDED_AI_BOT_INFO
190
- };
191
- };
192
- export const prepareRichLatex = ({ header, text, expressions, footer } = {}) => {
193
- const submessages = [];
194
- if (header) {
195
- submessages.push({
196
- messageType: RichSubMessageType.TEXT,
197
- messageText: header
198
- });
199
- }
200
- submessages.push({
201
- messageType: RichSubMessageType.LATEX,
202
- latexMetadata: {
203
- text,
204
- expressions
159
+ // Lia@Note 17-04-26 --- WIP
160
+ export const buildAdditionalBotMetadataContext = (submessages) => {
161
+ const sources = [];
162
+ const mediaDetailsMetadataList = [];
163
+ for (let i = 0; i < submessages.length; i++) {
164
+ const submessage = submessages[i];
165
+ switch (submessage.messageType) {
166
+ case RichSubMessageType.CONTENT_ITEMS:
167
+ const itemsMetadata = submessage.contentItemsMetadata.itemsMetadata;
168
+ for (let n = 0; n < itemsMetadata.length; n++) {
169
+ const reelItem = itemsMetadata[n].reelItem;
170
+ sources.push({
171
+ provider: 0,
172
+ thumbnailCdnUrl: reelItem.thumbnailUrl,
173
+ sourceProviderUrl: reelItem.videoUrl,
174
+ sourceQuery: '',
175
+ faviconCdnUrl: '',
176
+ citationNumber: i + 1,
177
+ sourceTitle: reelItem.title
178
+ });
179
+ mediaDetailsMetadataList.push({
180
+ id: randomBytes(32).toString('hex'),
181
+ previewMedia: {
182
+ fileSha256: '',
183
+ mediaKey: '',
184
+ fileEncSha256: '',
185
+ directPath: '',
186
+ mediaKeyTimestamp: unixTimestampSeconds(),
187
+ mimetype: 'image/jpeg'
188
+ }
189
+ });
190
+ }
191
+ break;
192
+ case RichSubMessageType.LATEX:
193
+ const expressions = submessage.latexMetadata.expressions;
194
+ for (let n = 0; n < expressions.length; n++) {
195
+ const expression = expressions[n];
196
+ mediaDetailsMetadataList.push({
197
+ id: randomBytes(32).toString('hex'),
198
+ previewMedia: {
199
+ fileSha256: '',
200
+ mediaKey: '',
201
+ fileEncSha256: '',
202
+ directPath: '',
203
+ mediaKeyTimestamp: unixTimestampSeconds(),
204
+ mimetype: 'image/jpeg'
205
+ }
206
+ });
207
+ }
208
+ break;
205
209
  }
206
- });
207
- if (footer) {
208
- submessages.push({
209
- messageType: RichSubMessageType.TEXT,
210
- messageText: footer
211
- });
212
210
  }
213
- const unified = toUnified(submessages);
214
- return {
215
- submessages,
216
- messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
217
- unifiedResponse: {
218
- data: textEncoder.encode(JSON.stringify(unified))
219
- },
220
- contextInfo: FORWARDED_AI_BOT_INFO
221
- };
222
- };
223
- export const prepareRichTable = ({ header, title, table, footer } = {}) => {
224
- const tableRows = table.map((items, index) => ({
225
- isHeading: index == 0,
226
- items
227
- }));
228
- const submessages = [];
229
- if (header) {
230
- submessages.push({
231
- messageType: RichSubMessageType.TEXT,
232
- messageText: header
211
+ return { sources, mediaDetailsMetadataList };
212
+ }
213
+ export const prepareRichResponseMessage = (content) => {
214
+ const { code, contentText, expressions, footerText, headerText, items, language, richResponse, table, text, title } = content;
215
+ let submessages = [];
216
+ if (Array.isArray(richResponse)) {
217
+ submessages = richResponse.map((submessage) => {
218
+ if (submessage.text) {
219
+ return {
220
+ messageType: RichSubMessageType.TEXT,
221
+ messageText: submessage.text
222
+ };
223
+ }
224
+ else if (submessage.code) {
225
+ return {
226
+ messageType: RichSubMessageType.CODE,
227
+ codeMetadata: {
228
+ codeLanguage: submessage.language,
229
+ codeBlocks: submessage.code
230
+ }
231
+ };
232
+ }
233
+ else if (submessage.expressions) {
234
+ return {
235
+ messageType: RichSubMessageType.LATEX,
236
+ latexMetadata: {
237
+ text: submessage.text,
238
+ expressions: submessage.expressions
239
+ }
240
+ };
241
+ }
242
+ else if (submessage.items) {
243
+ return {
244
+ messageType: RichSubMessageType.CONTENT_ITEMS,
245
+ contentItemsMetadata: {
246
+ itemsMetadata: submessage.items
247
+ }
248
+ };
249
+ }
250
+ else if (submessage.table) {
251
+ return {
252
+ messageType: RichSubMessageType.TABLE,
253
+ tableMetadata: {
254
+ title: submessage.title,
255
+ rows: submessage.table
256
+ }
257
+ };
258
+ }
259
+ return submessage;
233
260
  });
234
261
  }
235
- submessages.push({
236
- messageType: RichSubMessageType.TABLE,
237
- tableMetadata: {
238
- title,
239
- rows: tableRows
262
+ else {
263
+ if (headerText) {
264
+ submessages.push({
265
+ messageType: RichSubMessageType.TEXT,
266
+ messageText: headerText
267
+ });
240
268
  }
241
- });
242
- if (footer) {
243
- submessages.push({
244
- messageType: RichSubMessageType.TEXT,
245
- messageText: footer
246
- });
247
- }
248
- const unified = toUnified(submessages);
249
- return {
250
- submessages,
251
- messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
252
- unifiedResponse: {
253
- data: textEncoder.encode(JSON.stringify(unified))
254
- },
255
- contextInfo: FORWARDED_AI_BOT_INFO
256
- };
257
- };
258
- export const prepareRichResponseMessage = (content) => {
259
- const submessages = content.map((submessage) => {
260
- if (submessage.text) {
261
- return {
269
+ if (contentText) {
270
+ submessages.push({
262
271
  messageType: RichSubMessageType.TEXT,
263
- messageText: submessage.text
264
- };
272
+ messageText: contentText
273
+ });
265
274
  }
266
- else if (submessage.code) {
267
- return {
275
+ if (code) {
276
+ language ??= 'javascript';
277
+ submessages.push({
268
278
  messageType: RichSubMessageType.CODE,
269
279
  codeMetadata: {
270
- codeLanguage: submessage.language,
271
- codeBlocks: submessage.code
280
+ codeLanguage: language,
281
+ codeBlocks: tokenizeCode(code, language)
272
282
  }
273
- };
283
+ });
274
284
  }
275
- else if (submessage.expressions) {
276
- return {
285
+ else if (expressions) {
286
+ submessages.push({
277
287
  messageType: RichSubMessageType.LATEX,
278
288
  latexMetadata: {
279
- text: submessage.text,
280
- expressions: submessage.expressions
289
+ text,
290
+ expressions
281
291
  }
282
- };
292
+ });
283
293
  }
284
- else if (submessage.items) {
285
- return {
294
+ else if (items) {
295
+ submessages.push({
286
296
  messageType: RichSubMessageType.CONTENT_ITEMS,
287
297
  contentItemsMetadata: {
288
- itemsMetadata: submessage.items
298
+ itemsMetadata: items.map((item) => ({ reelItem: item })),
299
+ contentType: proto.AIRichResponseContentItemsMetadata.ContentType.CAROUSEL
289
300
  }
290
- };
301
+ });
291
302
  }
292
- else if (submessage.table) {
293
- return {
303
+ else if (table) {
304
+ const tableRows = table.map((items, index) => ({
305
+ isHeading: index == 0,
306
+ items
307
+ }));
308
+ submessages.push({
294
309
  messageType: RichSubMessageType.TABLE,
295
310
  tableMetadata: {
296
- title: submessage.title,
297
- rows: submessage.table
311
+ title,
312
+ rows: tableRows
298
313
  }
299
- };
314
+ });
300
315
  }
301
- return submessage;
302
- });
316
+ if (footerText) {
317
+ submessages.push({
318
+ messageType: RichSubMessageType.TEXT,
319
+ messageText: footerText
320
+ });
321
+ }
322
+ }
303
323
  const unified = toUnified(submessages);
304
- return {
324
+ const message = wrapToBotForwardedMessage({
305
325
  submessages,
306
326
  messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
307
327
  unifiedResponse: {
308
328
  data: textEncoder.encode(JSON.stringify(unified))
309
329
  },
310
- contextInfo: FORWARDED_AI_BOT_INFO
311
- };
330
+ contextInfo: {
331
+ isForwarded: true,
332
+ forwardingScore: 1,
333
+ forwardedAiBotMessageInfo: { botJid: '867051314767696@bot' },
334
+ forwardOrigin: 4
335
+ }
336
+ });
337
+ // Lia@Note 17-04-26 --- TODO: Fill mediaDetailsMetadataList and sources field
338
+ const { sources, mediaDetailsMetadataList } = buildAdditionalBotMetadataContext(submessages);
339
+ const botMetadata = message.messageContextInfo.botMetadata;
340
+ if (sources.length > 0) {
341
+ botMetadata.richResponseSourcesMetadata = { sources };
342
+ }
343
+ if (mediaDetailsMetadataList.length > 0) {
344
+ botMetadata.unifiedResponseMutation = { mediaDetailsMetadataList };
345
+ }
346
+ return message;
347
+ }
348
+ // Lia@Note 17-04-26 --- signature and certificateChain for proofs[] field
349
+ export const botMetadataSignature = () => {
350
+ const signature = new Uint8Array(64);
351
+ getRandomValues(signature);
352
+ return signature;
353
+ }
354
+ export const botMetadataCertificate = (length = 700) => {
355
+ const certificate = new Uint8Array(length);
356
+ certificate[0] = 48;
357
+ certificate[1] = 130;
358
+ getRandomValues(certificate.subarray(2));
359
+ return certificate;
312
360
  }
313
- export const wrapToBotForwardedMessage = (message) =>
361
+ export const wrapToBotForwardedMessage = (richResponseMessage) =>
314
362
  ({
315
363
  messageContextInfo: {
316
364
  botMetadata: {
365
+ pluginMetadata: {},
317
366
  // Lia@Note 09-04-26 --- TODO: Fill verificationMetadata field
318
- verificationMetadata: {},
367
+ verificationMetadata: {
368
+ proofs: [
369
+ {
370
+ certificateChain: [
371
+ botMetadataCertificate(684),
372
+ botMetadataCertificate(892)
373
+ ],
374
+ version: 1,
375
+ useCase: 1,
376
+ signature: botMetadataSignature()
377
+ }
378
+ ]
379
+ },
319
380
  botRenderingConfigMetadata: BOT_RENDERING_CONFIG_METADATA
320
381
  }
321
382
  },
322
- botForwardedMessage: { message }
383
+ botForwardedMessage: {
384
+ message: { richResponseMessage }
385
+ }
323
386
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itsliaaa/baileys",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "description": "Enhanced Baileys v7 with fixed newsletter media upload, plus support for interactive messages, albums, and more message types.",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
@@ -24,6 +24,7 @@
24
24
  "baileys",
25
25
  "baileys-fork",
26
26
  "baileys-mod",
27
+ "interactive-messages",
27
28
  "js-whatsapp",
28
29
  "multi-device",
29
30
  "whatsapp",