@pontasockets/baileys 0.2.5 โ†’ 0.2.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.
package/README.md CHANGED
@@ -65,6 +65,7 @@ This fork introduces targeted custom patches on top of the original Baileys libr
65
65
  | `02` | ๐Ÿ“Š **Table Message** | Send structured tables via `{ table: { title?, headers, rows } }` โ€” renders as rich table in WhatsApp |
66
66
  | `03` | ๐Ÿ“ **Rich Text Message** | Send styled text via `{ richText: '...' }` โ€” renders as AI bot markdown text in WhatsApp |
67
67
  | `04` | ๐Ÿ”€ **Mixed Rich Message** | Combine text + code + table in one message via `{ items: [...] }` |
68
+ | `05` | ๐Ÿ”— **Inline Citation Message** | Send text with clickable footnote citations via `{ richResponse: [...] }` |
68
69
  | `02` | ๐Ÿชช **Custom Message ID** | All outgoing message IDs prefixed with `PONTASOCKETS` |
69
70
  | `03` | ๐Ÿ› **LID Bug Fixes** | Full fix for participant, mentionedJid, sender, and group admin LID resolution |
70
71
  | `04` | ๐Ÿ“ฆ **makeInMemoryStore Fix** | Corrected store behavior for stable session handling |
@@ -485,7 +486,111 @@ await sock.sendMessage(jid, {
485
486
 
486
487
  > **Tipe yang valid di dalam `items`:**
487
488
  > - `{ text: 'string' }` โ€” teks / markdown
488
- > - `{ code: 'string', language: 'string' }` โ€” code block
489
+ > -
490
+
491
+ <details>
492
+ <summary><b>๐Ÿ”— Inline Citation Message <kbd>NEW</kbd></b></summary>
493
+ <br>
494
+
495
+ > Render teks dengan citation/footnote yang bisa diklik โ€” mirip jawaban AI WhatsApp yang punya referensi sumber
496
+
497
+ **Single citation**
498
+
499
+ ```javascript
500
+ await sock.sendMessage(jid, {
501
+ richResponse: [
502
+ {
503
+ text: 'Koperasi Merah Putih adalah inisiatif pemerintah. {{SS_0}}ยน{{/SS_0}} ',
504
+ inlineEntities: [{
505
+ key: 'SS_0',
506
+ metadata: {
507
+ reference_id: 1,
508
+ reference_url: 'https://example.com',
509
+ reference_title: 'Judul Sumber',
510
+ reference_display_name: 'Sumber',
511
+ sources: [{
512
+ source_type: 'THIRD_PARTY',
513
+ source_display_name: 'Sumber',
514
+ source_subtitle: 'example.com',
515
+ source_url: 'https://example.com'
516
+ }],
517
+ __typename: 'GenAISearchCitationItem'
518
+ }
519
+ }]
520
+ }
521
+ ]
522
+ }, { quoted: message })
523
+ ```
524
+
525
+ **Multi citation dalam satu teks**
526
+
527
+ ```javascript
528
+ await sock.sendMessage(jid, {
529
+ richResponse: [
530
+ {
531
+ text: 'Node.js {{SS_0}}ยน{{/SS_0}} adalah runtime JavaScript. Dibuat oleh Ryan Dahl {{SS_1}}ยฒ{{/SS_1}} pada 2009.',
532
+ inlineEntities: [
533
+ {
534
+ key: 'SS_0',
535
+ metadata: {
536
+ reference_id: 1,
537
+ reference_url: 'https://nodejs.org',
538
+ reference_title: 'Node.js Official',
539
+ reference_display_name: 'nodejs.org',
540
+ sources: [{ source_type: 'THIRD_PARTY', source_display_name: 'nodejs.org', source_subtitle: 'nodejs.org', source_url: 'https://nodejs.org' }],
541
+ __typename: 'GenAISearchCitationItem'
542
+ }
543
+ },
544
+ {
545
+ key: 'SS_1',
546
+ metadata: {
547
+ reference_id: 2,
548
+ reference_url: 'https://wikipedia.org/wiki/Ryan_Dahl',
549
+ reference_title: 'Ryan Dahl - Wikipedia',
550
+ reference_display_name: 'Wikipedia',
551
+ sources: [{ source_type: 'THIRD_PARTY', source_display_name: 'Wikipedia', source_subtitle: 'wikipedia.org', source_url: 'https://wikipedia.org/wiki/Ryan_Dahl' }],
552
+ __typename: 'GenAISearchCitationItem'
553
+ }
554
+ }
555
+ ]
556
+ }
557
+ ]
558
+ }, { quoted: message })
559
+ ```
560
+
561
+ **Citation + Code Block dalam satu pesan**
562
+
563
+ ```javascript
564
+ await sock.sendMessage(jid, {
565
+ richResponse: [
566
+ {
567
+ text: 'Cara install Node.js {{SS_0}}ยน{{/SS_0}}:',
568
+ inlineEntities: [{
569
+ key: 'SS_0',
570
+ metadata: {
571
+ reference_id: 1,
572
+ reference_url: 'https://nodejs.org/en/download',
573
+ reference_title: 'Download Node.js',
574
+ reference_display_name: 'nodejs.org',
575
+ sources: [{ source_type: 'THIRD_PARTY', source_display_name: 'nodejs.org', source_subtitle: 'nodejs.org', source_url: 'https://nodejs.org/en/download' }],
576
+ __typename: 'GenAISearchCitationItem'
577
+ }
578
+ }]
579
+ },
580
+ { code: 'curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -\napt-get install -y nodejs', language: 'bash' },
581
+ { text: '_Verifikasi instalasi dengan_ `node --version`' }
582
+ ]
583
+ }, { quoted: message })
584
+ ```
585
+
586
+ > **Format citation di teks:** `{{KEY}}N{{/KEY}}` โ€” `KEY` harus cocok dengan `key` di `inlineEntities`, `N` adalah nomor urut footnote
587
+
588
+ > **`richResponse` array** support semua tipe yang sama dengan `items`:
589
+ > - `{ text, inlineEntities? }` โ€” teks / markdown dengan optional citation
590
+ > - `{ code, language }` โ€” code block
591
+ > - `{ table, title? }` โ€” tabel (rows langsung array of arrays `[items[], isHeading?]`)
592
+
593
+ </details>`{ code: 'string', language: 'string' }` โ€” code block
489
594
  > - `{ table: { title?, headers?, rows } }` โ€” tabel
490
595
 
491
596
  </details>
@@ -1108,4 +1213,4 @@ This project is licensed for **personal and non-commercial use only**.
1108
1213
 
1109
1214
  *Made with โ™ฅ by PONTASOCKETS*
1110
1215
 
1111
- </div>
1216
+ </div>
@@ -409,7 +409,7 @@ const generateForwardMessageContent = (message, forceForward) => {
409
409
 
410
410
  const generateWAMessageContent = async (message, options) => {
411
411
  let m = {}
412
- if ('code' in message || 'codes' in message || 'table' in message || 'items' in message || 'richText' in message) {
412
+ if ('code' in message || 'codes' in message || 'table' in message || 'items' in message || 'richText' in message || 'richResponse' in message) {
413
413
  return rich_message_utils_1.prepareRichResponseMessage(message)
414
414
  } else if ('text' in message) {
415
415
  const extContent = {
@@ -1728,4 +1728,4 @@ module.exports = {
1728
1728
  downloadMediaMessage,
1729
1729
  assertMediaContent,
1730
1730
  patchMessageForMdIfRequired
1731
- }
1731
+ }
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * rich-message-utils.js
5
- * @pontasockets/baileys
5
+ * @pontasockets-baileys
6
6
  * Tambahkan file ini ke: node_modules/@whiskeysockets/baileys/lib/Utils/rich-message-utils.js
7
7
  */
8
8
 
@@ -174,10 +174,11 @@ const toUnified = (submessages, uuid) => ({
174
174
  primitive: {
175
175
  title: tm.title || null,
176
176
  rows: tm.rows.map(row => ({
177
+ is_header: row.isHeading || false,
177
178
  cells: row.items,
178
- is_heading: row.isHeading || false
179
+ markdown_cells: row.items.map(item => ({ text: item }))
179
180
  })),
180
- __typename: 'GenAITableUXPrimitive'
181
+ __typename: 'GenATableUXPrimitive'
181
182
  },
182
183
  __typename: 'GenAISingleLayoutViewModel'
183
184
  }
@@ -204,7 +205,7 @@ const toUnified = (submessages, uuid) => ({
204
205
  view_model: {
205
206
  primitive: {
206
207
  text: submessage.messageText,
207
- inline_entities: [],
208
+ inline_entities: submessage.inlineEntities || [],
208
209
  __typename: 'GenAIMarkdownTextUXPrimitive'
209
210
  },
210
211
  __typename: 'GenAISingleLayoutViewModel'
@@ -234,129 +235,117 @@ const botMetadataCertificate = (length = 685) => {
234
235
  // โ”€โ”€โ”€ prepareRichResponseMessage โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
235
236
 
236
237
  const prepareRichResponseMessage = (content) => {
237
- const proto = WAProto_1.proto
238
238
 
239
239
  // Normalize ke array of items
240
240
  // Support:
241
- // { code, language } โ€” single code block
242
- // { codes: [{ code, language }, ...] } โ€” multi code block
243
- // { table: { title?, headers?, rows } } โ€” single table
244
- // { text: 'string' } โ€” single text
245
- // { items: [{ text } | { code, language } | { table }] } โ€” mixed, bebas urutan
246
- let items = []
241
+ // { code, language } โ€” single code block
242
+ // { codes: [{ code, language }, ...] } โ€” multi code block
243
+ // { table: { title?, headers?, rows } } โ€” single table
244
+ // { richText: 'string' } โ€” single text
245
+ // { items: [{ text } | { code, language } | { table }] } โ€” mixed, bebas urutan
246
+ // { richResponse: [{ text, inlineEntities? } | { code, language } โ€” full array mode
247
+ // | { table, title? } | { inlineImage } | ...] }
247
248
 
248
- if (content.items) {
249
- items = content.items
250
- } else if (content.codes) {
251
- items = content.codes.map(c => ({ code: c.code, language: c.language }))
252
- } else if (content.table) {
253
- items = [{ table: content.table }]
254
- } else if ('richText' in content) {
255
- items = Array.isArray(content.richText)
256
- ? content.richText.map(t => ({ text: t }))
257
- : [{ text: content.richText }]
258
- } else {
259
- items = [{ code: content.code, language: content.language }]
260
- }
249
+ let submessages = []
261
250
 
262
- // Build submessages as plain objects (sesuai struktur relay)
263
- const submessages = items.map(item => {
264
- // โ”€โ”€ TEXT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
265
- if ('text' in item) {
266
- return {
267
- messageType: RichSubMessageType.TEXT, // 2
268
- messageText: item.text
269
- }
270
- }
271
-
272
- // โ”€โ”€ TABLE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
273
- if (item.table) {
274
- const { title, headers, rows } = item.table
275
- const allRows = []
276
- if (headers && headers.length) {
277
- allRows.push({ items: headers, isHeading: true })
251
+ if (Array.isArray(content.richResponse)) {
252
+ // โ”€โ”€ richResponse array mode (dari Lia) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
253
+ submessages = content.richResponse.map(sub => {
254
+ if (sub.text !== undefined) {
255
+ return {
256
+ messageType: RichSubMessageType.TEXT,
257
+ messageText: sub.text,
258
+ ...(sub.inlineEntities ? { inlineEntities: sub.inlineEntities } : {})
259
+ }
278
260
  }
279
- for (const row of (rows || [])) {
280
- allRows.push({ items: row, isHeading: false })
261
+ if (sub.code !== undefined) {
262
+ const lang = sub.language || 'javascript'
263
+ return {
264
+ messageType: RichSubMessageType.CODE,
265
+ codeMetadata: {
266
+ codeLanguage: lang,
267
+ codeBlocks: tokenizeCode(sub.code, lang)
268
+ }
269
+ }
281
270
  }
282
- return {
283
- messageType: RichSubMessageType.TABLE, // 4
284
- tableMetadata: {
285
- ...(title ? { title } : {}),
286
- rows: allRows
271
+ if (sub.table !== undefined) {
272
+ return {
273
+ messageType: RichSubMessageType.TABLE,
274
+ tableMetadata: {
275
+ ...(sub.title ? { title: sub.title } : {}),
276
+ rows: sub.table
277
+ }
287
278
  }
288
279
  }
289
- }
280
+ // passthrough โ€” kalau ada tipe lain langsung lewat
281
+ return sub
282
+ })
283
+ } else {
284
+ // โ”€โ”€ shorthand / items mode โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
285
+ let items = []
290
286
 
291
- // โ”€โ”€ CODE (default) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
292
- const lang = item.language || 'javascript'
293
- const codeBlocks = tokenizeCode(item.code, lang)
294
- return {
295
- messageType: RichSubMessageType.CODE, // 5
296
- codeMetadata: {
297
- codeLanguage: lang,
298
- codeBlocks: codeBlocks.map(b => ({
299
- highlightType: b.highlightType,
300
- codeContent: b.codeContent
301
- }))
302
- }
287
+ if (content.items) {
288
+ items = content.items
289
+ } else if (content.codes) {
290
+ items = content.codes.map(c => ({ code: c.code, language: c.language }))
291
+ } else if (content.table) {
292
+ items = [{ table: content.table }]
293
+ } else if ('richText' in content) {
294
+ items = Array.isArray(content.richText)
295
+ ? content.richText.map(t => ({ text: t }))
296
+ : [{ text: content.richText }]
297
+ } else {
298
+ items = [{ code: content.code, language: content.language }]
303
299
  }
304
- })
305
300
 
306
- const uuid = crypto_1.randomUUID()
307
-
308
- // Build unified JSON untuk unifiedResponse
309
- const unifiedSections = submessages.map(sub => {
310
- if (sub.messageType === RichSubMessageType.TEXT) {
311
- return {
312
- view_model: {
313
- primitive: {
314
- text: sub.messageText,
315
- inline_entities: [],
316
- __typename: 'GenAIMarkdownTextUXPrimitive'
317
- },
318
- __typename: 'GenAISingleLayoutViewModel'
301
+ submessages = items.map(item => {
302
+ // โ”€โ”€ TEXT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
303
+ if ('text' in item) {
304
+ return {
305
+ messageType: RichSubMessageType.TEXT,
306
+ messageText: item.text,
307
+ ...(item.inlineEntities ? { inlineEntities: item.inlineEntities } : {})
319
308
  }
320
309
  }
321
- }
322
- if (sub.messageType === RichSubMessageType.TABLE) {
323
- const tm = sub.tableMetadata
324
- return {
325
- view_model: {
326
- primitive: {
327
- ...(tm.title ? { title: tm.title } : {}),
328
- rows: tm.rows.map(row => ({
329
- cells: row.items,
330
- is_heading: row.isHeading || false
331
- })),
332
- __typename: 'GenAITableUXPrimitive'
333
- },
334
- __typename: 'GenAISingleLayoutViewModel'
310
+
311
+ // โ”€โ”€ TABLE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
312
+ if (item.table) {
313
+ const { title, headers, rows } = item.table
314
+ const allRows = []
315
+ if (headers && headers.length) {
316
+ allRows.push({ items: headers, isHeading: true })
317
+ }
318
+ for (const row of (rows || [])) {
319
+ allRows.push({ items: row, isHeading: false })
320
+ }
321
+ return {
322
+ messageType: RichSubMessageType.TABLE,
323
+ tableMetadata: {
324
+ ...(title ? { title } : {}),
325
+ rows: allRows
326
+ }
335
327
  }
336
328
  }
337
- }
338
- if (sub.messageType === RichSubMessageType.CODE) {
339
- const cm = sub.codeMetadata
329
+
330
+ // โ”€โ”€ CODE (default) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
331
+ const lang = item.language || 'javascript'
332
+ const codeBlocks = tokenizeCode(item.code, lang)
340
333
  return {
341
- view_model: {
342
- primitive: {
343
- language: cm.codeLanguage,
344
- code_blocks: cm.codeBlocks.map(b => ({
345
- content: b.codeContent,
346
- type: Object.keys(CodeHighlightType).find(k => CodeHighlightType[k] === b.highlightType) || 'DEFAULT'
347
- })),
348
- __typename: 'GenAICodeUXPrimitive'
349
- },
350
- __typename: 'GenAISingleLayoutViewModel'
334
+ messageType: RichSubMessageType.CODE,
335
+ codeMetadata: {
336
+ codeLanguage: lang,
337
+ codeBlocks: codeBlocks.map(b => ({
338
+ highlightType: b.highlightType,
339
+ codeContent: b.codeContent
340
+ }))
351
341
  }
352
342
  }
353
- }
354
- return {}
355
- })
343
+ })
344
+ }
356
345
 
357
- const unified = { response_id: uuid, sections: unifiedSections }
346
+ const uuid = crypto_1.randomUUID()
347
+ const unified = toUnified(submessages, uuid)
358
348
 
359
- // Plain object structure โ€” sama persis kayak relay
360
349
  return {
361
350
  messageContextInfo: {
362
351
  botMetadata: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pontasockets/baileys",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "Baileys is a lightweight JavaScript library for interacting with the WhatsApp Web API using WebSocket.",
5
5
  "keywords": [
6
6
  "facebook",