@pontasockets/baileys 0.2.4 โ†’ 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
+ }
@@ -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,131 +235,118 @@ 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 = []
247
-
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 = [{ text: content.richText }]
256
- } else {
257
- items = [{ code: content.code, language: content.language }]
258
- }
259
-
260
- const built = items.map(item => {
261
- // โ”€โ”€ TEXT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
262
- if ('text' in item) {
263
- return {
264
- submessage: proto.AIRichResponseSubMessage.create({
265
- messageType: RichSubMessageType.TEXT, // 2
266
- messageText: item.text
267
- }),
268
- unified: {
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 } | ...] }
248
+
249
+ let submessages = []
250
+
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 {
269
256
  messageType: RichSubMessageType.TEXT,
270
- messageText: item.text
257
+ messageText: sub.text,
258
+ ...(sub.inlineEntities ? { inlineEntities: sub.inlineEntities } : {})
271
259
  }
272
260
  }
273
- }
274
-
275
- // โ”€โ”€ TABLE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
276
- if (item.table) {
277
- const { title, headers, rows } = item.table
278
-
279
- // Build rows: header row dulu (kalau ada), baru data rows
280
- const allRows = []
281
- if (headers && headers.length) {
282
- allRows.push(proto.AIRichResponseTableMetadata.AIRichResponseTableRow.create({
283
- items: headers,
284
- isHeading: true
285
- }))
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
+ }
286
270
  }
287
- for (const row of (rows || [])) {
288
- allRows.push(proto.AIRichResponseTableMetadata.AIRichResponseTableRow.create({
289
- items: row,
290
- isHeading: false
291
- }))
271
+ if (sub.table !== undefined) {
272
+ return {
273
+ messageType: RichSubMessageType.TABLE,
274
+ tableMetadata: {
275
+ ...(sub.title ? { title: sub.title } : {}),
276
+ rows: sub.table
277
+ }
278
+ }
292
279
  }
280
+ // passthrough โ€” kalau ada tipe lain langsung lewat
281
+ return sub
282
+ })
283
+ } else {
284
+ // โ”€โ”€ shorthand / items mode โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
285
+ let items = []
286
+
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 }]
299
+ }
293
300
 
294
- const tableMetadata = proto.AIRichResponseTableMetadata.create({
295
- title: title || null,
296
- rows: allRows
297
- })
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 } : {})
308
+ }
309
+ }
298
310
 
299
- return {
300
- submessage: proto.AIRichResponseSubMessage.create({
301
- messageType: RichSubMessageType.TABLE, // 4
302
- tableMetadata
303
- }),
304
- unified: {
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 {
305
322
  messageType: RichSubMessageType.TABLE,
306
323
  tableMetadata: {
307
- title: title || null,
308
- rows: [
309
- ...(headers ? [{ items: headers, isHeading: true }] : []),
310
- ...(rows || []).map(r => ({ items: r, isHeading: false }))
311
- ]
324
+ ...(title ? { title } : {}),
325
+ rows: allRows
312
326
  }
313
327
  }
314
328
  }
315
- }
316
329
 
317
- // โ”€โ”€ CODE (default) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
318
- const lang = item.language || 'javascript'
319
- const codeBlocks = tokenizeCode(item.code, lang)
320
- return {
321
- submessage: proto.AIRichResponseSubMessage.create({
322
- messageType: RichSubMessageType.CODE, // 5
323
- codeMetadata: proto.AIRichResponseCodeMetadata.create({
324
- codeLanguage: lang,
325
- codeBlocks: codeBlocks.map(b =>
326
- proto.AIRichResponseCodeMetadata.AIRichResponseCodeBlock.create({
327
- highlightType: b.highlightType,
328
- codeContent: b.codeContent
329
- })
330
- )
331
- })
332
- }),
333
- unified: {
330
+ // โ”€โ”€ CODE (default) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
331
+ const lang = item.language || 'javascript'
332
+ const codeBlocks = tokenizeCode(item.code, lang)
333
+ return {
334
334
  messageType: RichSubMessageType.CODE,
335
- codeMetadata: { codeLanguage: lang, codeBlocks }
335
+ codeMetadata: {
336
+ codeLanguage: lang,
337
+ codeBlocks: codeBlocks.map(b => ({
338
+ highlightType: b.highlightType,
339
+ codeContent: b.codeContent
340
+ }))
341
+ }
336
342
  }
337
- }
338
- })
343
+ })
344
+ }
339
345
 
340
346
  const uuid = crypto_1.randomUUID()
341
- const unified = toUnified(built.map(b => b.unified), uuid)
342
-
343
- // Build AIRichResponseMessage using E2E proto class
344
- const richResponseMessage = proto.AIRichResponseMessage.create({
345
- submessages: built.map(b => b.submessage),
346
- messageType: 1, // AI_RICH_RESPONSE_TYPE_STANDARD
347
- unifiedResponse: proto.AIRichResponseUnifiedResponse
348
- ? proto.AIRichResponseUnifiedResponse.create({
349
- data: Buffer.from(JSON.stringify(unified))
350
- })
351
- : { data: Buffer.from(JSON.stringify(unified)) },
352
- contextInfo: {
353
- isForwarded: true,
354
- forwardingScore: 1,
355
- forwardedAiBotMessageInfo: { botJid: '867051314767696@bot' },
356
- forwardOrigin: 4
357
- }
358
- })
347
+ const unified = toUnified(submessages, uuid)
359
348
 
360
- // Wrap in botForwardedMessage
361
- const message = {
349
+ return {
362
350
  messageContextInfo: {
363
351
  botMetadata: {
364
352
  verificationMetadata: {
@@ -373,10 +361,22 @@ const prepareRichResponseMessage = (content) => {
373
361
  }
374
362
  },
375
363
  botForwardedMessage: {
376
- message: { richResponseMessage }
364
+ message: {
365
+ richResponseMessage: {
366
+ messageType: 1,
367
+ submessages,
368
+ unifiedResponse: {
369
+ data: Buffer.from(JSON.stringify(unified))
370
+ },
371
+ contextInfo: {
372
+ isForwarded: true,
373
+ forwardingScore: 1,
374
+ forwardedAiBotMessageInfo: { botJid: '867051314767696@bot' },
375
+ forwardOrigin: 4
376
+ }
377
+ }
378
+ }
377
379
  }
378
380
  }
379
-
380
- return message
381
381
  }
382
- exports.prepareRichResponseMessage = prepareRichResponseMessage
382
+ exports.prepareRichResponseMessage = prepareRichResponseMessage
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pontasockets/baileys",
3
- "version": "0.2.4",
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",