@itsliaaa/baileys 0.1.23 → 0.1.24

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
@@ -453,10 +453,11 @@ sock.sendMessage(jid, {
453
453
 
454
454
  ```javascript
455
455
  sock.sendMessage(jid, {
456
- header: 'Example Usage',
456
+ headerText: '## Example Usage',
457
+ contentText: '---'
457
458
  code: 'console.log("Hello, World!")',
458
- footer: 'Pretty simple, right?',
459
- language: 'javascript'
459
+ language: 'javascript',
460
+ footerText: 'Pretty simple, right?'
460
461
  })
461
462
  ```
462
463
 
@@ -464,14 +465,15 @@ sock.sendMessage(jid, {
464
465
 
465
466
  ```javascript
466
467
  sock.sendMessage(jid, {
467
- header: 'Comparison between Node.js, Bun, and Deno',
468
+ headerText: '## Comparison between Node.js, Bun, and Deno',
469
+ contentText: '---',
468
470
  title: 'Runtime Comparison',
469
471
  table: [
470
472
  ['', 'Node.js', 'Bun', 'Deno'],
471
473
  ['Engine', 'V8 (C++)', 'JavaScriptCore (C++)', 'V8 (C++)'],
472
474
  ['Performance', '4/5', '5/5', '4/5']
473
475
  ],
474
- footer: 'Does this help clarify the differences?'
476
+ footerText: 'Does this help clarify the differences?'
475
477
  })
476
478
  ```
477
479
 
@@ -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, 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') => {
@@ -51,16 +52,18 @@ export const toUnified = (submessages) =>
51
52
  sections: submessages.map((submessage) => {
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'
62
64
  }
63
65
  };
66
+ break;
64
67
  case RichSubMessageType.CONTENT_ITEMS:
65
68
  return {
66
69
  view_model: {
@@ -83,15 +86,17 @@ export const toUnified = (submessages) =>
83
86
  __typename: 'GenAIHScrollLayoutViewModel'
84
87
  }
85
88
  };
89
+ break;
86
90
  case RichSubMessageType.LATEX:
91
+ const latexMetadata = submessage.latexMetadata;
87
92
  const item = {
88
- latex_expression: submessage.latexMetadata.expressions[0]?.latexExpression,
89
- font_height: submessage.latexMetadata.expressions[0]?.fontHeight,
93
+ latex_expression: latexMetadata.expressions[0]?.latexExpression,
94
+ font_height: latexMetadata.expressions[0]?.fontHeight,
90
95
  padding: 15,
91
96
  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
97
+ url: latexMetadata.expressions[0]?.url,
98
+ width: latexMetadata.expressions[0]?.width || 388,
99
+ height: latexMetadata.expressions[0]?.height || 160
95
100
  }
96
101
  };
97
102
  return {
@@ -104,17 +109,20 @@ export const toUnified = (submessages) =>
104
109
  __typename: 'GenAISingleLayoutViewModel'
105
110
  }
106
111
  };
112
+ break;
107
113
  case RichSubMessageType.TABLE:
114
+ const tableMetadata = submessage.tableMetadata;
108
115
  return {
109
116
  view_model: {
110
117
  primitive: {
111
- title: submessage.tableMetadata.title,
112
- rows: submessage.tableMetadata.rows.map((row) => ({ is_header: row.isHeading, cells: row.items, markdown_cells: [] })),
118
+ title: tableMetadata.title,
119
+ rows: tableMetadata.rows.map((row) => ({ is_header: row.isHeading, cells: row.items, markdown_cells: [] })),
113
120
  __typename: 'GenATableUXPrimitive'
114
121
  },
115
122
  __typename: 'GenAISingleLayoutViewModel'
116
123
  }
117
124
  };
125
+ break;
118
126
  case RichSubMessageType.TEXT:
119
127
  return {
120
128
  view_model: {
@@ -122,202 +130,236 @@ export const toUnified = (submessages) =>
122
130
  __typename: 'GenAISingleLayoutViewModel'
123
131
  }
124
132
  };
133
+ break;
125
134
  }
126
135
  return submessage;
127
136
  })
128
137
  });
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
138
+ // Lia@Note 17-04-26 --- WIP
139
+ export const buildAdditionalBotMetadataContext = (submessages) => {
140
+ const sources = [];
141
+ const mediaDetailsMetadataList = [];
142
+ for (let i = 0; i < submessages.length; i++) {
143
+ const submessage = submessages[i];
144
+ switch (submessage.messageType) {
145
+ case RichSubMessageType.CONTENT_ITEMS:
146
+ const itemsMetadata = submessage.contentItemsMetadata.itemsMetadata;
147
+ for (let n = 0; n < itemsMetadata.length; n++) {
148
+ const reelItem = itemsMetadata[n].reelItem;
149
+ sources.push({
150
+ provider: 0,
151
+ thumbnailCdnUrl: reelItem.thumbnailUrl,
152
+ sourceProviderUrl: reelItem.videoUrl,
153
+ sourceQuery: '',
154
+ faviconCdnUrl: '',
155
+ citationNumber: i + 1,
156
+ sourceTitle: reelItem.title
157
+ });
158
+ mediaDetailsMetadataList.push({
159
+ id: randomBytes(32).toString('hex'),
160
+ previewMedia: {
161
+ fileSha256: '',
162
+ mediaKey: '',
163
+ fileEncSha256: '',
164
+ directPath: '',
165
+ mediaKeyTimestamp: unixTimestampSeconds(),
166
+ mimetype: 'image/jpeg'
167
+ }
168
+ });
169
+ }
170
+ break;
171
+ case RichSubMessageType.LATEX:
172
+ const expressions = submessage.latexMetadata.expressions;
173
+ for (let n = 0; n < expressions.length; n++) {
174
+ const expression = expressions[n];
175
+ mediaDetailsMetadataList.push({
176
+ id: randomBytes(32).toString('hex'),
177
+ previewMedia: {
178
+ fileSha256: '',
179
+ mediaKey: '',
180
+ fileEncSha256: '',
181
+ directPath: '',
182
+ mediaKeyTimestamp: unixTimestampSeconds(),
183
+ mimetype: 'image/jpeg'
184
+ }
185
+ });
186
+ }
187
+ break;
205
188
  }
206
- });
207
- if (footer) {
208
- submessages.push({
209
- messageType: RichSubMessageType.TEXT,
210
- messageText: footer
211
- });
212
189
  }
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
190
+ return { sources, mediaDetailsMetadataList };
191
+ }
192
+ export const prepareRichResponseMessage = (content) => {
193
+ const { code, contentText, expressions, footerText, headerText, items, language, richResponse, table, text, title } = content;
194
+ let submessages = [];
195
+ if (Array.isArray(richResponse)) {
196
+ submessages = richResponse.map((submessage) => {
197
+ if (submessage.text) {
198
+ return {
199
+ messageType: RichSubMessageType.TEXT,
200
+ messageText: submessage.text
201
+ };
202
+ }
203
+ else if (submessage.code) {
204
+ return {
205
+ messageType: RichSubMessageType.CODE,
206
+ codeMetadata: {
207
+ codeLanguage: submessage.language,
208
+ codeBlocks: submessage.code
209
+ }
210
+ };
211
+ }
212
+ else if (submessage.expressions) {
213
+ return {
214
+ messageType: RichSubMessageType.LATEX,
215
+ latexMetadata: {
216
+ text: submessage.text,
217
+ expressions: submessage.expressions
218
+ }
219
+ };
220
+ }
221
+ else if (submessage.items) {
222
+ return {
223
+ messageType: RichSubMessageType.CONTENT_ITEMS,
224
+ contentItemsMetadata: {
225
+ itemsMetadata: submessage.items
226
+ }
227
+ };
228
+ }
229
+ else if (submessage.table) {
230
+ return {
231
+ messageType: RichSubMessageType.TABLE,
232
+ tableMetadata: {
233
+ title: submessage.title,
234
+ rows: submessage.table
235
+ }
236
+ };
237
+ }
238
+ return submessage;
233
239
  });
234
240
  }
235
- submessages.push({
236
- messageType: RichSubMessageType.TABLE,
237
- tableMetadata: {
238
- title,
239
- rows: tableRows
241
+ else {
242
+ if (headerText) {
243
+ submessages.push({
244
+ messageType: RichSubMessageType.TEXT,
245
+ messageText: headerText
246
+ });
240
247
  }
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 {
248
+ if (contentText) {
249
+ submessages.push({
262
250
  messageType: RichSubMessageType.TEXT,
263
- messageText: submessage.text
264
- };
251
+ messageText: contentText
252
+ });
265
253
  }
266
- else if (submessage.code) {
267
- return {
254
+ if (code) {
255
+ language ??= 'javascript';
256
+ submessages.push({
268
257
  messageType: RichSubMessageType.CODE,
269
258
  codeMetadata: {
270
- codeLanguage: submessage.language,
271
- codeBlocks: submessage.code
259
+ codeLanguage: language,
260
+ codeBlocks: tokenizeCode(code, language)
272
261
  }
273
- };
262
+ });
274
263
  }
275
- else if (submessage.expressions) {
276
- return {
264
+ else if (expressions) {
265
+ submessages.push({
277
266
  messageType: RichSubMessageType.LATEX,
278
267
  latexMetadata: {
279
- text: submessage.text,
280
- expressions: submessage.expressions
268
+ text,
269
+ expressions
281
270
  }
282
- };
271
+ });
283
272
  }
284
- else if (submessage.items) {
285
- return {
273
+ else if (items) {
274
+ submessages.push({
286
275
  messageType: RichSubMessageType.CONTENT_ITEMS,
287
276
  contentItemsMetadata: {
288
- itemsMetadata: submessage.items
277
+ itemsMetadata: items.map((item) => ({ reelItem: item })),
278
+ contentType: proto.AIRichResponseContentItemsMetadata.ContentType.CAROUSEL
289
279
  }
290
- };
280
+ });
291
281
  }
292
- else if (submessage.table) {
293
- return {
282
+ else if (table) {
283
+ const tableRows = table.map((items, index) => ({
284
+ isHeading: index == 0,
285
+ items
286
+ }));
287
+ submessages.push({
294
288
  messageType: RichSubMessageType.TABLE,
295
289
  tableMetadata: {
296
- title: submessage.title,
297
- rows: submessage.table
290
+ title,
291
+ rows: tableRows
298
292
  }
299
- };
293
+ });
300
294
  }
301
- return submessage;
302
- });
295
+ if (footerText) {
296
+ submessages.push({
297
+ messageType: RichSubMessageType.TEXT,
298
+ messageText: footerText
299
+ });
300
+ }
301
+ }
303
302
  const unified = toUnified(submessages);
304
- return {
303
+ const message = wrapToBotForwardedMessage({
305
304
  submessages,
306
305
  messageType: proto.AIRichResponseMessageType.AI_RICH_RESPONSE_TYPE_STANDARD,
307
306
  unifiedResponse: {
308
307
  data: textEncoder.encode(JSON.stringify(unified))
309
308
  },
310
- contextInfo: FORWARDED_AI_BOT_INFO
311
- };
309
+ contextInfo: {
310
+ isForwarded: true,
311
+ forwardingScore: 1,
312
+ forwardedAiBotMessageInfo: { botJid: '867051314767696@bot' },
313
+ forwardOrigin: 4
314
+ }
315
+ });
316
+ // Lia@Note 17-04-26 --- TODO: Fill mediaDetailsMetadataList and sources field
317
+ const { sources, mediaDetailsMetadataList } = buildAdditionalBotMetadataContext(submessages);
318
+ const botMetadata = message.messageContextInfo.botMetadata;
319
+ if (sources.length > 0) {
320
+ botMetadata.richResponseSourcesMetadata = { sources };
321
+ }
322
+ if (mediaDetailsMetadataList.length > 0) {
323
+ botMetadata.unifiedResponseMutation = { mediaDetailsMetadataList };
324
+ }
325
+ return message;
326
+ }
327
+ // Lia@Note 17-04-26 --- signature and certificateChain for proofs[] field
328
+ export const botMetadataSignature = () => {
329
+ const signature = new Uint8Array(64);
330
+ getRandomValues(signature);
331
+ return signature;
332
+ }
333
+ export const botMetadataCertificate = (length = 700) => {
334
+ const certificate = new Uint8Array(length);
335
+ certificate[0] = 48;
336
+ certificate[1] = 130;
337
+ getRandomValues(certificate.subarray(2));
338
+ return certificate;
312
339
  }
313
- export const wrapToBotForwardedMessage = (message) =>
340
+ export const wrapToBotForwardedMessage = (richResponseMessage) =>
314
341
  ({
315
342
  messageContextInfo: {
316
343
  botMetadata: {
344
+ pluginMetadata: {},
317
345
  // Lia@Note 09-04-26 --- TODO: Fill verificationMetadata field
318
- verificationMetadata: {},
346
+ verificationMetadata: {
347
+ proofs: [
348
+ {
349
+ certificateChain: [
350
+ botMetadataCertificate(684),
351
+ botMetadataCertificate(892)
352
+ ],
353
+ version: 1,
354
+ useCase: 1,
355
+ signature: botMetadataSignature()
356
+ }
357
+ ]
358
+ },
319
359
  botRenderingConfigMetadata: BOT_RENDERING_CONFIG_METADATA
320
360
  }
321
361
  },
322
- botForwardedMessage: { message }
362
+ botForwardedMessage: {
363
+ message: { richResponseMessage }
364
+ }
323
365
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itsliaaa/baileys",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
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",