@pontasockets/baileys 0.2.2 โ†’ 0.2.4

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
@@ -62,6 +62,9 @@ This fork introduces targeted custom patches on top of the original Baileys libr
62
62
  | # | Patch | Description |
63
63
  |---|-------|-------------|
64
64
  | `01` | ๐Ÿค– **Code Block Message** | Send syntax-highlighted code via `{ code, language }` โ€” renders as AI bot message in WhatsApp |
65
+ | `02` | ๐Ÿ“Š **Table Message** | Send structured tables via `{ table: { title?, headers, rows } }` โ€” renders as rich table in WhatsApp |
66
+ | `03` | ๐Ÿ“ **Rich Text Message** | Send styled text via `{ richText: '...' }` โ€” renders as AI bot markdown text in WhatsApp |
67
+ | `04` | ๐Ÿ”€ **Mixed Rich Message** | Combine text + code + table in one message via `{ items: [...] }` |
65
68
  | `02` | ๐Ÿชช **Custom Message ID** | All outgoing message IDs prefixed with `PONTASOCKETS` |
66
69
  | `03` | ๐Ÿ› **LID Bug Fixes** | Full fix for participant, mentionedJid, sender, and group admin LID resolution |
67
70
  | `04` | ๐Ÿ“ฆ **makeInMemoryStore Fix** | Corrected store behavior for stable session handling |
@@ -240,6 +243,8 @@ await sock.sendMessage(jid, {
240
243
 
241
244
  > Renders as a syntax-highlighted code block in WhatsApp (AI bot style message)
242
245
 
246
+ **Single Code Block**
247
+
243
248
  ```javascript
244
249
  // JavaScript
245
250
  await sock.sendMessage(jid, {
@@ -260,6 +265,39 @@ await sock.sendMessage(jid, {
260
265
  }, { quoted: message })
261
266
  ```
262
267
 
268
+ **Multiple Code Blocks in One Message**
269
+
270
+ > Gunakan key `codes` (array) untuk kirim lebih dari satu code block sekaligus dalam satu pesan
271
+
272
+ ```javascript
273
+ // 2 bahasa berbeda dalam 1 pesan
274
+ await sock.sendMessage(jid, {
275
+ codes: [
276
+ { code: 'console.log("Hello World")', language: 'javascript' },
277
+ { code: 'print("Hello World")', language: 'python' }
278
+ ]
279
+ }, { quoted: message })
280
+
281
+ // Input vs Output
282
+ await sock.sendMessage(jid, {
283
+ codes: [
284
+ { code: 'SELECT * FROM users WHERE id = 1;', language: 'sql' },
285
+ { code: '{ "id": 1, "name": "Ponta", "role": "admin" }', language: 'json' }
286
+ ]
287
+ }, { quoted: message })
288
+
289
+ // Banyak snippet sekaligus
290
+ await sock.sendMessage(jid, {
291
+ codes: [
292
+ { code: 'npm install @pontasockets/baileys', language: 'bash' },
293
+ { code: 'import makeWASocket from "@pontasockets/baileys"', language: 'javascript' },
294
+ { code: 'const sock = makeWASocket({ printQRInTerminal: true })', language: 'javascript' }
295
+ ]
296
+ }, { quoted: message })
297
+ ```
298
+
299
+ > **Note:** Key `code` (single) dan `codes` (array) keduanya tetap support โ€” tidak breaking change.
300
+
263
301
  **Supported Languages:**
264
302
 
265
303
  | Language | Keys |
@@ -277,6 +315,178 @@ await sock.sendMessage(jid, {
277
315
  | HTML | `html` |
278
316
  | PowerShell | `powershell` ยท `ps1` |
279
317
  | CMD | `cmd` ยท `bat` |
318
+ | SQL | `sql` |
319
+ | JSON | `json` |
320
+
321
+ </details>
322
+
323
+ <details>
324
+ <summary><b>๐Ÿ“Š Table Message <kbd>NEW</kbd></b></summary>
325
+ <br>
326
+
327
+ > Renders as a structured table in WhatsApp (AI bot style rich message)
328
+
329
+ **Simple Table**
330
+
331
+ ```javascript
332
+ await sock.sendMessage(jid, {
333
+ table: {
334
+ title: 'Daftar User',
335
+ headers: ['Name', 'Role', 'Status'],
336
+ rows: [
337
+ ['Ponta', 'Admin', 'Active'],
338
+ ['Yue', 'Member', 'Idle'],
339
+ ['Frieren', 'Guest', 'Offline']
340
+ ]
341
+ }
342
+ }, { quoted: message })
343
+ ```
344
+
345
+ **Table tanpa title**
346
+
347
+ ```javascript
348
+ await sock.sendMessage(jid, {
349
+ table: {
350
+ headers: ['Command', 'Description'],
351
+ rows: [
352
+ ['.ping', 'Cek latency bot'],
353
+ ['.info', 'Info bot'],
354
+ ['.help', 'List semua command']
355
+ ]
356
+ }
357
+ }, { quoted: message })
358
+ ```
359
+
360
+ **Table tanpa header (data only)**
361
+
362
+ ```javascript
363
+ await sock.sendMessage(jid, {
364
+ table: {
365
+ rows: [
366
+ ['RAM', '512 MB'],
367
+ ['CPU', '4 Core'],
368
+ ['Uptime', '99.9%']
369
+ ]
370
+ }
371
+ }, { quoted: message })
372
+ ```
373
+
374
+ **Mixed: Table + Code Block dalam 1 pesan**
375
+
376
+ > Gunakan key `items` untuk gabungkan berbagai tipe dalam urutan bebas
377
+
378
+ ```javascript
379
+ await sock.sendMessage(jid, {
380
+ items: [
381
+ {
382
+ table: {
383
+ title: 'Query Result',
384
+ headers: ['id', 'name', 'score'],
385
+ rows: [
386
+ ['1', 'Ponta', '98'],
387
+ ['2', 'Yue', '87']
388
+ ]
389
+ }
390
+ },
391
+ { code: 'SELECT * FROM users ORDER BY score DESC', language: 'sql' }
392
+ ]
393
+ }, { quoted: message })
394
+ ```
395
+
396
+ > **Note:** `items` array juga bisa diisi full code blocks saja (pengganti `codes`), atau full tables saja, atau campuran keduanya โ€” bebas urutannya.
397
+
398
+ </details>
399
+
400
+ <details>
401
+ <summary><b>๐Ÿ“ Rich Text Message <kbd>NEW</kbd></b></summary>
402
+ <br>
403
+
404
+ > Renders as AI bot markdown-style text dalam WhatsApp (gunakan `richText`, bukan `text` โ€” supaya tidak konflik dengan text message biasa)
405
+
406
+ ```javascript
407
+ // Simple text
408
+ await sock.sendMessage(jid, {
409
+ richText: 'Halo! Ini adalah pesan teks rich dari bot.'
410
+ }, { quoted: message })
411
+
412
+ // Markdown supported (bold, italic, code inline)
413
+ await sock.sendMessage(jid, {
414
+ richText: '*Hasil eksekusi:*\nStatus: `success`\nWaktu: _120ms_'
415
+ }, { quoted: message })
416
+ ```
417
+
418
+ </details>
419
+
420
+ <details>
421
+ <summary><b>๐Ÿ”€ Mixed Rich Message <kbd>NEW</kbd></b></summary>
422
+ <br>
423
+
424
+ > Gabungkan text, code block, dan table dalam urutan bebas dalam satu pesan menggunakan key `items`
425
+
426
+ **Text โ†’ Code โ†’ Text**
427
+
428
+ ```javascript
429
+ await sock.sendMessage(jid, {
430
+ items: [
431
+ { text: 'Contoh fungsi JavaScript:' },
432
+ { code: 'function greet(name) {\n return `Hello, ${name}!`\n}', language: 'javascript' },
433
+ { text: 'Panggil fungsi di atas dengan `greet("Ponta")` untuk mendapat output `Hello, Ponta!`' }
434
+ ]
435
+ }, { quoted: message })
436
+ ```
437
+
438
+ **Text โ†’ Code โ†’ Table**
439
+
440
+ ```javascript
441
+ await sock.sendMessage(jid, {
442
+ items: [
443
+ { text: 'Query yang dijalankan:' },
444
+ { code: 'SELECT id, name, score FROM users ORDER BY score DESC LIMIT 3', language: 'sql' },
445
+ { text: 'Hasil:' },
446
+ {
447
+ table: {
448
+ headers: ['id', 'name', 'score'],
449
+ rows: [
450
+ ['1', 'Ponta', '98'],
451
+ ['2', 'Yue', '87'],
452
+ ['3', 'Frieren', '75']
453
+ ]
454
+ }
455
+ }
456
+ ]
457
+ }, { quoted: message })
458
+ ```
459
+
460
+ **Full mixed**
461
+
462
+ ```javascript
463
+ await sock.sendMessage(jid, {
464
+ items: [
465
+ { text: '*Dokumentasi Command `.eval`*' },
466
+ { text: 'Syntax:' },
467
+ { code: '.eval <kode javascript>', language: 'bash' },
468
+ { text: 'Contoh penggunaan:' },
469
+ { code: 'return 1 + 1', language: 'javascript' },
470
+ { text: 'Supported types:' },
471
+ {
472
+ table: {
473
+ headers: ['Type', 'Contoh'],
474
+ rows: [
475
+ ['Expression', '2 ** 10'],
476
+ ['Statement', 'let x = 5; return x'],
477
+ ['Async', 'await fetch(url)']
478
+ ]
479
+ }
480
+ },
481
+ { text: '_Hanya owner yang bisa menggunakan command ini._' }
482
+ ]
483
+ }, { quoted: message })
484
+ ```
485
+
486
+ > **Tipe yang valid di dalam `items`:**
487
+ > - `{ text: 'string' }` โ€” teks / markdown
488
+ > - `{ code: 'string', language: 'string' }` โ€” code block
489
+ > - `{ table: { title?, headers?, rows } }` โ€” tabel
280
490
 
281
491
  </details>
282
492
 
@@ -898,4 +1108,4 @@ This project is licensed for **personal and non-commercial use only**.
898
1108
 
899
1109
  *Made with โ™ฅ by PONTASOCKETS*
900
1110
 
901
- </div>
1111
+ </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) {
412
+ if ('code' in message || 'codes' in message || 'table' in message || 'items' in message || 'richText' in message) {
413
413
  return rich_message_utils_1.prepareRichResponseMessage(message)
414
414
  } else if ('text' in message) {
415
415
  const extContent = {
@@ -24,7 +24,7 @@ const CodeHighlightType = {
24
24
  }
25
25
 
26
26
  const RichSubMessageType = {
27
- UNKNOWN: 0, TEXT: 2, CODE: 5
27
+ UNKNOWN: 0, TEXT: 2, TABLE: 4, CODE: 5
28
28
  }
29
29
 
30
30
  // โ”€โ”€โ”€ Keyword Sets โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
@@ -167,6 +167,22 @@ exports.tokenizeCode = tokenizeCode
167
167
  const toUnified = (submessages, uuid) => ({
168
168
  response_id: uuid,
169
169
  sections: submessages.map((submessage) => {
170
+ if (submessage.messageType === RichSubMessageType.TABLE) {
171
+ const tm = submessage.tableMetadata
172
+ return {
173
+ view_model: {
174
+ primitive: {
175
+ title: tm.title || null,
176
+ rows: tm.rows.map(row => ({
177
+ cells: row.items,
178
+ is_heading: row.isHeading || false
179
+ })),
180
+ __typename: 'GenAITableUXPrimitive'
181
+ },
182
+ __typename: 'GenAISingleLayoutViewModel'
183
+ }
184
+ }
185
+ }
170
186
  if (submessage.messageType === RichSubMessageType.CODE) {
171
187
  const cm = submessage.codeMetadata
172
188
  return {
@@ -218,35 +234,115 @@ const botMetadataCertificate = (length = 685) => {
218
234
  // โ”€โ”€โ”€ prepareRichResponseMessage โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
219
235
 
220
236
  const prepareRichResponseMessage = (content) => {
221
- const { code, language } = content
222
- const lang = language || 'javascript'
223
237
  const proto = WAProto_1.proto
224
238
 
225
- const codeBlocks = tokenizeCode(code, lang)
226
-
227
- // Build submessage using AICommon proto classes
228
- const submessage = proto.AIRichResponseSubMessage.create({
229
- messageType: RichSubMessageType.CODE, // 5
230
- codeMetadata: proto.AIRichResponseCodeMetadata.create({
231
- codeLanguage: lang,
232
- codeBlocks: codeBlocks.map(b =>
233
- proto.AIRichResponseCodeMetadata.AIRichResponseCodeBlock.create({
234
- highlightType: b.highlightType,
235
- codeContent: b.codeContent
239
+ // Normalize ke array of items
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: {
269
+ messageType: RichSubMessageType.TEXT,
270
+ messageText: item.text
271
+ }
272
+ }
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
+ }))
286
+ }
287
+ for (const row of (rows || [])) {
288
+ allRows.push(proto.AIRichResponseTableMetadata.AIRichResponseTableRow.create({
289
+ items: row,
290
+ isHeading: false
291
+ }))
292
+ }
293
+
294
+ const tableMetadata = proto.AIRichResponseTableMetadata.create({
295
+ title: title || null,
296
+ rows: allRows
297
+ })
298
+
299
+ return {
300
+ submessage: proto.AIRichResponseSubMessage.create({
301
+ messageType: RichSubMessageType.TABLE, // 4
302
+ tableMetadata
303
+ }),
304
+ unified: {
305
+ messageType: RichSubMessageType.TABLE,
306
+ tableMetadata: {
307
+ title: title || null,
308
+ rows: [
309
+ ...(headers ? [{ items: headers, isHeading: true }] : []),
310
+ ...(rows || []).map(r => ({ items: r, isHeading: false }))
311
+ ]
312
+ }
313
+ }
314
+ }
315
+ }
316
+
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
+ )
236
331
  })
237
- )
238
- })
332
+ }),
333
+ unified: {
334
+ messageType: RichSubMessageType.CODE,
335
+ codeMetadata: { codeLanguage: lang, codeBlocks }
336
+ }
337
+ }
239
338
  })
240
339
 
241
340
  const uuid = crypto_1.randomUUID()
242
- const unified = toUnified([{
243
- messageType: RichSubMessageType.CODE,
244
- codeMetadata: { codeLanguage: lang, codeBlocks }
245
- }], uuid)
341
+ const unified = toUnified(built.map(b => b.unified), uuid)
246
342
 
247
343
  // Build AIRichResponseMessage using E2E proto class
248
344
  const richResponseMessage = proto.AIRichResponseMessage.create({
249
- submessages: [submessage],
345
+ submessages: built.map(b => b.submessage),
250
346
  messageType: 1, // AI_RICH_RESPONSE_TYPE_STANDARD
251
347
  unifiedResponse: proto.AIRichResponseUnifiedResponse
252
348
  ? proto.AIRichResponseUnifiedResponse.create({
@@ -283,4 +379,4 @@ const prepareRichResponseMessage = (content) => {
283
379
 
284
380
  return message
285
381
  }
286
- 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.2",
3
+ "version": "0.2.4",
4
4
  "description": "Baileys is a lightweight JavaScript library for interacting with the WhatsApp Web API using WebSocket.",
5
5
  "keywords": [
6
6
  "facebook",