@rennzsync/baileys 10.2.4 → 10.5.0

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.id.md CHANGED
@@ -1,10 +1,10 @@
1
1
  <div align="center">
2
2
 
3
- # renz/baileys
3
+ # rennzsync/baileys
4
4
 
5
- **Library bot WhatsApp ringan — rebase penuh ke `@whiskeysockets/baileys` 7.0.0-rc14**
5
+ **Library WhatsApp Bot ringan — full rebase dari `@whiskeysockets/baileys` 7.0.0-rc14**
6
6
 
7
- [![Version](https://img.shields.io/badge/npm-10.2.0-25D366?style=for-the-badge&logo=whatsapp&logoColor=white)](https://www.npmjs.com/package/@renz/baileys)
7
+ [![Version](https://img.shields.io/badge/npm-10.5.0-25D366?style=for-the-badge&logo=whatsapp&logoColor=white)](https://www.npmjs.com/package/@rennzsync/baileys)
8
8
  [![Node](https://img.shields.io/badge/Node.js-%3E%3D20.0.0-339933?style=for-the-badge&logo=node.js&logoColor=white)](https://nodejs.org)
9
9
  [![Baileys](https://img.shields.io/badge/Base-Baileys%207.0.0--rc14-blue?style=for-the-badge)](https://github.com/WhiskeySockets/Baileys)
10
10
  [![License](https://img.shields.io/badge/License-MIT%20%2B%20GPL--3.0%20dep-blue?style=for-the-badge)](LICENSE)
@@ -13,56 +13,57 @@
13
13
 
14
14
  </div>
15
15
 
16
- Library WhatsApp Multi-Device yang direbase penuh ke Baileys v7 rc14, memakai engine Signal Protocol asli (`libsignal`, GPL-3.0) — sama seperti yang dipakai stock `@whiskeysockets/baileys` rc14.
16
+ Library WhatsApp Multi-Device hasil rebase dari Baileys v7 rc14, pakai engine Signal Protocol yang asli (`libsignal`, GPL-3.0) — sama persis dengan yang dipakai stock `@whiskeysockets/baileys` rc14.
17
17
 
18
- > **Catatan lisensi:** kode `renz/baileys` sendiri MIT, tapi bergantung ke `libsignal` (GPL-3.0) saat runtime buat crypto Signal Protocol-nya. Kalau mau publish/redistribusikan package ini, cek dulu implikasi kepatuhan GPL-3.0-nya buat kebutuhanmu — ini bukan nasihat hukum.
18
+ > **Catatan lisensi:** Kode `rennzsync/baileys` sendiri berlisensi MIT, tapi bergantung pada `libsignal` (GPL-3.0) saat runtime untuk kripto Signal Protocol. Kalau kamu mau publish atau redistribusi package ini, cek dulu apa arti kepatuhan GPL-3.0 buat use case kamu — ini bukan nasihat hukum.
19
19
 
20
- Fokus proyek ini: **bot WhatsApp multi-media** — kirim/terima audio, video, gambar, stiker, dan **Rich WebUI** (antarmuka HTML inline di dalam bubble chat), dengan konfigurasi default yang hemat RAM.
20
+ Fokus proyek: **bot WhatsApp multimedia** — pipeline audio, video, gambar, dan stiker, plus **Rich WebUI** (interface HTML inline yang dirender langsung di dalam bubble chat), dengan default yang hemat RAM.
21
21
 
22
22
  ---
23
23
 
24
- ## Fitur Utama
24
+ ## Fitur Unggulan
25
25
 
26
- - **Paritas Baileys 7.0.0-rc14** — TC-token lengkap (trusted contact token dengan expiry & re-issue), Signal Repository API v7 (`getSessionInfo`, `hasSenderKey`, `getSenderKeyDistributionMessage`), format QR/pairing terbaru, penanganan reachout timelock.
27
- - **Engine Signal Protocol standar** — pakai `libsignal` langsung, sama seperti stock Baileys rc14; nggak ada native crypto custom yang perlu dirawat.
28
- - **Pipeline multi-media terpusat** — utilitas `media-processor` (ffmpeg/sharp/audio-decode, lazy-load).
29
- - **Rich WebUI** — render antarmuka HTML/CSS/JS langsung di bubble chat via `sendInlineWebUI`.
30
- - **RAM-friendly by default** — `syncFullHistory: false`, `enableRecentMessageCache: false`, TTL cache moderat.
26
+ - **Full parity Baileys 7.0.0-rc14** — implementasi lengkap TC-token (trusted contact token dengan expiry & re-issue), Signal Repository API v7 (`getSessionInfo`, `hasSenderKey`, `getSenderKeyDistributionMessage`), format QR/pairing baru, penanganan reachout timelock.
27
+ - **Engine Signal Protocol standar** — pakai `libsignal` langsung, sama seperti stock Baileys rc14; nggak ada kripto native custom yang perlu di-maintain.
28
+ - **Pipeline multimedia terpusat** — utility `media-processor` (ffmpeg/sharp/audio-decode, lazy-loaded).
29
+ - **Rich WebUI** — render interface HTML/CSS/JS langsung di dalam bubble chat lewat `sendInlineWebUI`.
30
+ - **Widget & rich menu (10.5.0)** — `sock.sendA2UI` (widget A2UI), `sock.richMenu`, dan opsi kirim `viewOnceV2` / `viewOnceV2Extension`.
31
+ - **Hemat RAM secara default** — `syncFullHistory: false`, `enableRecentMessageCache: false`, TTL cache moderat.
31
32
 
32
33
  ---
33
34
 
34
- ## Syarat
35
+ ## Requirement
35
36
 
36
- | Kebutuhan | Versi |
37
+ | Requirement | Versi |
37
38
  |---|---|
38
39
  | Node.js | >= 20.0.0 |
39
40
 
40
- Dukungan platform ngikutin apa yang didukung `libsignal` (^6.0.0) di sistemmu — cek dokumentasi package itu buat detail prebuilt binary/platform-nya.
41
+ Dukungan platform mengikuti apapun yang didukung `libsignal` (^6.0.0) di sistem kamu — cek dokumentasi package tersebut buat cakupan binary/platform prebuilt-nya.
41
42
 
42
43
  ---
43
44
 
44
45
  ## Instalasi
45
46
 
46
47
  ```bash
47
- npm install @renz/baileys
48
+ npm install @rennzsync/baileys
48
49
  ```
49
50
 
50
- ### Dependency opsional (install sesuai fitur)
51
+ ### Dependency opsional (install sesuai fitur yang dipakai)
51
52
 
52
- | Package | Untuk fitur |
53
+ | Package | Fitur |
53
54
  |---|---|
54
- | `audio-decode` | Waveform voice note (`ptt: true`) — **wajib untuk voice note** |
55
- | `sharp` | Resize/kompres gambar |
55
+ | `audio-decode` | Waveform voice note (`ptt: true`) — **wajib buat voice note** |
56
+ | `sharp` | Resize/kompresi gambar |
56
57
  | `fluent-ffmpeg` | Konversi video/audio, thumbnail video |
57
58
  | `jimp` | Thumbnail alternatif (tanpa sharp) |
58
- | `link-preview-js` | Link preview |
59
+ | `link-preview-js` | Preview link |
59
60
 
60
61
  ---
61
62
 
62
63
  ## Quick Start
63
64
 
64
65
  ```js
65
- import makeWASocket, { useMultiFileAuthState } from '@renz/baileys';
66
+ import makeWASocket, { useMultiFileAuthState } from '@rennzsync/baileys';
66
67
 
67
68
  const { state, saveCreds } = await useMultiFileAuthState('auth_info');
68
69
 
@@ -88,13 +89,13 @@ sock.ev.on('messages.upsert', async ({ messages }) => {
88
89
 
89
90
  ---
90
91
 
91
- ## Contoh: Multi-Media
92
+ ## Contoh: Multimedia
92
93
 
93
94
  ### Kirim gambar dengan caption
94
95
 
95
96
  ```js
96
97
  await sock.sendMessage(jid, {
97
- image: { url: 'https://example.com/foto.jpg' },
98
+ image: { url: 'https://example.com/photo.jpg' },
98
99
  caption: 'Halo!'
99
100
  });
100
101
  ```
@@ -110,40 +111,40 @@ await sock.sendMessage(jid, {
110
111
  });
111
112
  ```
112
113
 
113
- ### Konversi video/audio sebelum kirim (media-processor)
114
+ ### Konversi video/audio sebelum dikirim (media-processor)
114
115
 
115
116
  ```js
116
- import { convertToWhatsAppVideo, convertToOpusAudio, getVideoThumbnail, resizeImage } from '@renz/baileys';
117
+ import { convertToWhatsAppVideo, convertToOpusAudio, getVideoThumbnail, resizeImage } from '@rennzsync/baileys';
117
118
 
118
119
  // Video apapun -> MP4/H.264 kompatibel WhatsApp (butuh fluent-ffmpeg)
119
- const mp4 = await convertToWhatsAppVideo(bufferMentah);
120
- await sock.sendMessage(jid, { video: mp4, caption: 'Video terkonversi' });
120
+ const mp4 = await convertToWhatsAppVideo(rawBuffer);
121
+ await sock.sendMessage(jid, { video: mp4, caption: 'Video hasil konversi' });
121
122
 
122
- // Audio apapun -> OGG/Opus untuk voice note
123
- const opus = await convertToOpusAudio(bufferAudio);
123
+ // Audio apapun -> OGG/Opus buat voice note
124
+ const opus = await convertToOpusAudio(audioBuffer);
124
125
 
125
126
  // Thumbnail video & resize gambar (butuh sharp)
126
127
  const thumb = await getVideoThumbnail(mp4, 1);
127
128
  const small = await resizeImage(imageBuffer, { width: 300, height: 300 });
128
129
  ```
129
130
 
130
- ### Probe metadata media
131
+ ### Cek metadata media
131
132
 
132
133
  ```js
133
- import { probeMedia, getMp4Duration } from '@renz/baileys';
134
+ import { probeMedia, getMp4Duration } from '@rennzsync/baileys';
134
135
 
135
136
  const meta = await probeMedia(buffer, 'audio/mpeg'); // { duration, bitrate, container, codec }
136
- const dur = getMp4Duration(mp4Buffer); // tanpa ffmpeg — parse atom langsung
137
+ const dur = getMp4Duration(mp4Buffer); // nggak butuh ffmpeg — parse atom langsung
137
138
  ```
138
139
 
139
140
  ---
140
141
 
141
142
  ## Contoh: Rich WebUI (HTML inline di bubble chat)
142
143
 
143
- Kirim antarmuka HTML/CSS/JS yang **ter-render langsung di dalam pesan** — cocok untuk menu interaktif, mini-app, dashboard:
144
+ Kirim interface HTML/CSS/JS yang **dirender langsung di dalam bubble pesan** — cocok buat menu interaktif, mini-app, dan dashboard:
144
145
 
145
146
  ```js
146
- import { sendInlineWebUI } from '@renz/baileys';
147
+ import { sendInlineWebUI } from '@rennzsync/baileys';
147
148
 
148
149
  const html = `<!DOCTYPE html>
149
150
  <html><head><style>body{background:#111b21;color:#fff;font-family:sans-serif;padding:16px}</style></head>
@@ -158,24 +159,119 @@ await sendInlineWebUI(sock, jid, html, 'Menu Bot', {
158
159
  });
159
160
  ```
160
161
 
161
- > Catatan: nama primitive HTML (`GenAIaeacdsnwHtmlPrimitive`) adalah identifier obfuscated WhatsApp Web dan bisa berubah antar versi. Jika WebUI berhenti ter-render, update identifier dari bundle WA Web terbaru.
162
+ > Catatan: nama primitive HTML-nya (`GenAIaeacdsnwHtmlPrimitive`) adalah identifier obfuscated dari WhatsApp Web dan bisa berubah antar versi WA. Kalau WebUI berhenti render, update identifier-nya dari bundle WA Web terbaru.
162
163
 
163
164
  ---
164
165
 
165
- ## Store & auth SQLite (baru di 10.1.0)
166
+ ## Contoh: Button & list klasik (render di semua device, baru di 10.0.1)
166
167
 
167
- `lib/Store/*` nyediain store chat/kontak/pesan yang bisa dicolok ke `sock.ev`, plus dua backend auth-state:
168
+ Card `interactiveMessage` + `nativeFlowMessage` **udah nggak dirender** di banyak client WhatsApp — `relayMessage` sukses tanpa error tapi pesannya diam-diam nggak muncul. Template klasik `buttonsMessage` dan `listMessage` render dengan reliable di **semua** client (Android/iOS/Web/Desktop).
169
+
170
+ `@rennzsync/baileys@10.5.0` menyediakan builder siap pakai di `lib/Utils/rich-classic.js`:
171
+
172
+ ```js
173
+ import { buildButtonsMessage, buildListMessage, sendClassicMessage } from '@rennzsync/baileys';
174
+
175
+ // 1-3 tombol quick-reply (opsional dengan header location+thumbnail)
176
+ const buttons = buildButtonsMessage({
177
+ text: 'Halo Bro — pilih opsi',
178
+ footer: '© My Bot',
179
+ buttons: [
180
+ { buttonId: '.owner', buttonText: 'Owner' },
181
+ { buttonId: '.allmenu', buttonText: 'Allmenu' },
182
+ ],
183
+ locationMessage: { jpegThumbnail, name: 'My Bot', address: 'v10.0.1' },
184
+ });
185
+
186
+ // List scrollable dengan section dan row
187
+ const list = buildListMessage({
188
+ title: 'Menu — 1271 command',
189
+ description: 'Pilih kategori',
190
+ buttonText: 'Pilih Kategori',
191
+ sections: [{
192
+ title: 'Kategori',
193
+ rows: [
194
+ { title: 'main', description: '19 command', rowId: '.menucat main' },
195
+ { title: 'sticker', description: '42 command', rowId: '.menucat sticker' },
196
+ ],
197
+ }],
198
+ });
199
+
200
+ // Kirim lewat relayMessage — userJid dinormalisasi otomatis
201
+ // (nangani sock.user.id vs sock.user.jid yang legacy dan sebenarnya nggak pernah ada)
202
+ await sendClassicMessage(sock, jid, buttons);
203
+ await sendClassicMessage(sock, jid, list);
204
+ ```
205
+
206
+ Juga meng-export `normalizeUserJid(sockOrUserOrJid)` — `sock.user.jid` nggak pernah ada di baileys 7.x (`sock.user` itu `creds.me`, yang punya `.id`); helper ini nerima bentuk apapun dan mengembalikan jid yang valid.
207
+
208
+ ---
209
+
210
+ ## Contoh: Carousel & native-flow button (baru di 10.0.3, perlu hati-hati)
211
+
212
+ `lib/Utils/rich-carousel.js` menambahkan builder `interactiveMessage`/`carouselMessage` (format card scroll horizontal), buat kasus di mana kamu butuh spesifik carousel atau tipe tombol CTA yang lebih kaya (`cta_url`, `cta_call`, `cta_copy`, `cta_reminder`, `single_select`) yang nggak dicakup template klasik di atas. Catatan rendering tetap sama: pakai `rich-classic.js` kecuali memang butuh yang ini.
213
+
214
+ ```js
215
+ import { buildCarouselMessage, sendCarouselMessage, sendInteractiveMessage } from '@rennzsync/baileys';
216
+
217
+ // satu bubble native-flow (tanpa carousel)
218
+ await sendInteractiveMessage(sock, jid, {
219
+ text: 'Pilih aksi:',
220
+ footer: '© My Bot',
221
+ buttons: [
222
+ { type: 'quick_reply', displayText: 'Owner', id: '.owner' },
223
+ { type: 'cta_url', displayText: 'Docs', url: 'https://github.com/RennZSync/baileys' },
224
+ ],
225
+ });
226
+
227
+ // carousel multi-card
228
+ await sendCarouselMessage(sock, jid, {
229
+ text: 'Pilih produk:',
230
+ cards: [
231
+ {
232
+ header: { title: 'Produk A', mediaKind: 'thumbnail', jpegThumbnail },
233
+ text: 'Rp 50.000',
234
+ buttons: [{ type: 'quick_reply', displayText: 'Beli', id: 'buy_a' }],
235
+ },
236
+ {
237
+ header: { title: 'Produk B', mediaKind: 'thumbnail', jpegThumbnail },
238
+ text: 'Rp 75.000',
239
+ buttons: [{ type: 'quick_reply', displayText: 'Beli', id: 'buy_b' }],
240
+ },
241
+ ],
242
+ });
243
+ ```
244
+
245
+ `buildInteractiveCard(...)` dan `buildNativeFlowButton(...)` level rendah juga di-export kalau kamu mau object content mentahnya, bukan shortcut kirim.
246
+
247
+ ---
248
+
249
+ ## Foto profil ukuran penuh (baru di 10.0.3)
250
+
251
+ `generateProfilePicture` (dipakai oleh `updateProfilePicture` dan `newsletterUpdatePicture`) sekarang menerima `{ full: true }` buat skip crop paksa 640×640/quality-50 dan upload mendekati resolusi/kualitas asli:
168
252
 
169
253
  ```js
170
- import makeWASocket, { makeInMemoryStore, useSqliteAuthState, useMultiFileAuthState } from '@renz/baileys';
254
+ await sock.updateProfilePicture(sock.user.id, imageBuffer, { full: true }); // ~quality 92, tanpa resize
255
+ await sock.updateProfilePicture(sock.user.id, imageBuffer, { width: 1024, height: 1024, quality: 85 }); // custom
256
+ await sock.updateProfilePicture(sock.user.id, imageBuffer); // perilaku default tidak berubah (640x640, q50)
257
+ ```
258
+
259
+ ---
260
+
261
+ ## Store in-memory / cache-manager & auth SQLite (baru di 10.1.0)
262
+
263
+ `lib/Store/*` menyediakan store chat/contact/message yang bisa dipasang ke `sock.ev`, plus dua backend auth-state:
264
+
265
+ ```js
266
+ import makeWASocket, { makeInMemoryStore, useSqliteAuthState, useMultiFileAuthState } from '@rennzsync/baileys';
171
267
 
172
268
  const store = makeInMemoryStore({});
173
269
  store.readFromFile('./store.json');
174
270
  setInterval(() => store.writeToFile('./store.json'), 10_000);
175
271
 
176
- // Auth pakai SQLite (butuh Node >= 22.5, node:sqlite bawaan — throw error jelas di Node lebih lama)
272
+ // Auth SQLite (butuh Node >= 22.5, node:sqlite bawaan — lempar error jelas di Node lama)
177
273
  const { state, saveCreds } = await useSqliteAuthState('./auth.db');
178
- // atau tetap pakai yang berbasis file:
274
+ // atau yang klasik berbasis file, tetap sama:
179
275
  // const { state, saveCreds } = await useMultiFileAuthState('auth_info');
180
276
 
181
277
  const sock = makeWASocket({ auth: state });
@@ -183,18 +279,18 @@ store.bind(sock.ev);
183
279
  sock.ev.on('creds.update', saveCreds);
184
280
  ```
185
281
 
186
- `makeCacheManagerAuthState` juga tersedia kalau mau nyimpen auth state pakai store `cache-manager` (peer dependency opsional, cuma wajib kalau beneran dipakai).
282
+ `makeCacheManagerAuthState` juga tersedia kalau kamu mau auth state di-backup pakai store `cache-manager` (peer dependency opsional, cuma dibutuhkan kalau benar-benar dipanggil).
187
283
 
188
- `sock.sendMessage(jid, content, { isSecret, protected, me })` — tiga filter device/recipient tambahan hasil port dari `@vansnowi/baileys`, langsung diteruskan ke `relayMessage`.
284
+ `sock.sendMessage(jid, content, { isSecret, protected, me })` — tiga filter device/penerima tambahan yang di-port dari `@vansnowi/baileys`, diteruskan langsung ke `relayMessage`.
189
285
 
190
286
  ---
191
287
 
192
288
  ## Poll gambar (baru di 10.2.0)
193
289
 
194
- Kirim poll yang tiap opsinya berupa gambar, bukan teks biasa (`pollCreationMessageV3` dengan `pollContentType: IMAGE`, satu `pollCreationOptionImageMessage` per opsi, terhubung ke poll induk lewat asosiasi `MEDIA_POLL`):
290
+ Kirim poll di mana tiap opsinya berupa gambar, bukan teks biasa (`pollCreationMessageV3` dengan `pollContentType: IMAGE`, satu `pollCreationOptionImageMessage` per opsi, terhubung ke poll induk lewat `MEDIA_POLL`):
195
291
 
196
292
  ```js
197
- import { generateWAMessageFromImagePoll } from '@renz/baileys';
293
+ import { generateWAMessageFromImagePoll } from '@rennzsync/baileys';
198
294
 
199
295
  await generateWAMessageFromImagePoll(jid, {
200
296
  name: 'Pilih gambar favorit',
@@ -206,56 +302,125 @@ await generateWAMessageFromImagePoll(jid, {
206
302
  }, (msg, opts) => sock.relayMessage(jid, msg, opts), { upload: sock.waUploadToServer });
207
303
  ```
208
304
 
209
- `hashImagePollOption(optionName, fileSha256)` juga di-export terpisah kalau cuma butuh hash opsi tanpa flow kirim lengkap. Catatan: ini implementasi sisi-klien buat tipe pesan yang protonya udah ada di WhatsApp tapi belum ada fork Baileys manapun (termasuk upstream) yang bikin builder-nya — anggap eksperimental, coba dulu di WA client target sebelum dipakai produksi.
305
+ `hashImagePollOption(optionName, fileSha256)` juga di-export terpisah kalau kamu cuma butuh hash opsinya tanpa alur kirim lengkap. Catatan: ini implementasi sisi klien dari tipe pesan yang memang ada di proto WhatsApp tapi nggak ada fork Baileys manapun (termasuk upstream) yang menyediakan builder-nya — anggap eksperimental dan verifikasi rendering-nya di build client WA target kamu sebelum dipakai produksi.
306
+
307
+ ---
308
+
309
+ ## View Once V2 / V2 Extension (baru di 10.5.0)
310
+
311
+ ```js
312
+ await sock.sendMessage(jid, { text: 'Pesan Rahasia', viewOnceV2Extension: true }) // viewOnceMessageV2Extension
313
+ await sock.sendMessage(jid, { text: 'Pesan Rahasia', viewOnceV2: true }) // viewOnceMessageV2
314
+ ```
315
+
316
+ Pesan dibungkus ke `viewOnceMessageV2Extension` / `viewOnceMessageV2`; untuk teks, `viewOnce: true` di-set di dalam `extendedTextMessage`.
317
+
318
+ ---
319
+
320
+ ## Rich Menu (baru di 10.5.0, perlu hati-hati)
321
+
322
+ Port `richMenu` dari `@vansnowi/baileys` (juga diekspor sebagai `buildRichMenuMessage` / `sendRichMenu` dari `lib/Utils/rich-menu.js`). Tombolnya adalah CTA widget dengan toast, bukan quick-reply yang mengirim pesan balik. Pakai format GenAI `unifiedResponse` internal, jadi bisa saja tidak dirender di semua client WhatsApp.
323
+
324
+ ```js
325
+ // tombol
326
+ await sock.richMenu(jid, {
327
+ header: { title: 'Main Menu', image: { url: 'https://example.com/banner.png' } },
328
+ body: { title: 'Pick one', buttons: ['Profile', 'Settings', 'Help'], toast: 'opening...' },
329
+ footer: { text: 'Join us', url: 't.me/example' }
330
+ })
331
+
332
+ // kartu geser (carousel: true) / baris (row: true)
333
+ await sock.richMenu(jid, {
334
+ body: {
335
+ carousel: true,
336
+ cards: [
337
+ { title: 'Card 1', buttons: ['A', 'B'], toast: '...' },
338
+ { title: 'Card 2', buttons: ['C', 'D'], toast: '...' }
339
+ ]
340
+ }
341
+ })
342
+ ```
343
+
344
+ `footer.url` wajib diisi untuk tombol open-URL (tidak ada link default).
345
+
346
+ ---
347
+
348
+ ## Widget A2UI (baru di 10.5.0, perlu hati-hati)
349
+
350
+ Widget deklaratif (`Text`, `Image`, `Video`, `Button`, `Card`, `Column`, `Row`, `Divider`, `CheckBox`, `TextField`, `ChoicePicker`, plus `listCard`) yang dikirim sebagai `interactiveMessage.bloksWidget`. Diekspor juga sebagai `A2UI` / `sendA2UIWidget` dari `lib/Utils/a2ui.js`. Proto sekarang punya `InteractiveMessage.BloksWidget` (field 8). Format internal WhatsApp, jadi bisa tidak dirender di semua client.
351
+
352
+ ```js
353
+ import { A2UI } from '@rennzsync/baileys'
354
+
355
+ const ui = new A2UI()
356
+ const title = ui.text('Halo!', { variant: 'h1' })
357
+ const label = ui.text('Klik saya')
358
+ const btn = ui.button(label, { action: { name: 'noop' } })
359
+ ui.root([ui.card(ui.column([title, btn]))])
360
+
361
+ await sock.sendA2UI(jid, { a2ui: ui, bodyText: 'Widget', footer: 'A2UI' })
362
+
363
+ // list card
364
+ const list = new A2UI().listCard({
365
+ title: 'Menu',
366
+ items: [{ title: 'Nasi Goreng', price: 'Rp15.000' }, { title: 'Es Teh', price: 'Rp5.000' }]
367
+ })
368
+ await sock.sendA2UI(jid, { a2ui: list, bodyText: 'Pesan menu' })
369
+ ```
370
+
371
+ Opsi: `singleScreen`, `buttons` (native flow `{ name, params }`), `expiration`, `contextInfo`, `quoted`, `wrapped`, `type`.
210
372
 
211
373
  ---
212
374
 
213
- ## Konfigurasi Default (RAM-friendly)
375
+ ## Konfigurasi Default (hemat RAM)
214
376
 
215
377
  ```js
216
378
  const sock = makeWASocket({
217
379
  auth: state,
218
- // default sudah irit; override bila perlu:
219
- syncFullHistory: false, // tidak menarik riwayat chat penuh
220
- enableRecentMessageCache: false, // tidak menyimpan pesan terbaru di RAM
380
+ // sudah hemat secara default; override kalau perlu:
381
+ syncFullHistory: false, // jangan tarik full chat history
382
+ enableRecentMessageCache: false, // jangan simpan pesan terbaru di RAM
221
383
  });
222
384
  ```
223
385
 
224
386
  ---
225
387
 
226
- ## Breaking Changes dari 9.x (oktz-baileys lama)
388
+ ## Perubahan Besar dari 9.x (legacy renzsync-baileys)
227
389
 
228
- - Base direbase ke Baileys **7.0.0-rc14** (bukan lagi ourin-baileys 9.0.21).
229
- - Modul yang **dihapus**: `lib/VoIP/*` (call client WebRTC), `Modded/message_builder.js`, `Utils/rich-messages.js`, `Socket/dugong.js`, `Utils/sticker-pack.js`.
390
+ - Base di-rebase ke Baileys **7.0.0-rc14**
391
+ - Modul yang dihapus: `lib/VoIP/*` (WebRTC call client), `Modded/message_builder.js`, `Utils/rich-messages.js`, `Socket/dugong.js`, `Utils/sticker-pack.js`.
230
392
  - `rejectCall` tetap tersedia (core `messages-recv`).
231
- - Pengganti rich message lama: `rich-webui.js` (`sendInlineWebUI`, `buildWebuiMessage`).
232
- - **Rebrand:** package berganti nama jadi `@renz/baileys`, kini dirawat oleh [RennZz-Dev](https://github.com/RennZSync). Tidak ada perubahan API cukup ganti import dari `onigis` ke `@renz/baileys`.
233
- - **Signal engine balik ke stock:** engine custom `@renz/signal`/`@renz/curve25519` (MIT, native Rust) dilepas, balik pakai `libsignal` (GPL-3.0) asli seperti stock Baileys rc14 implementasi Signal Protocol sama, tanpa native binary custom lagi. Lihat catatan lisensi di bagian atas file ini.
234
- - Default config berubah: `syncFullHistory` dan `enableRecentMessageCache` kini `false`.
235
- - `protobufjs-cli` dipin ke `^1.1.3` (fix konflik peer dependency); `link-preview-js` ke `^5.0.0` (fix advisory SSRF).
236
- - **10.1.0:** gabung `lib/Store/*` (in-memory store, cache-manager store, keyed-db/ordered-dictionary/object-repository) dari `@vansnowi/baileys`, plus `useSqliteAuthState` (Node 22.5+, `node:sqlite` bawaan, fallback error jelas di Node lama) dan filter kirim `isSecret`/`protected`/`me` di `sock.sendMessage`.
237
- - **10.2.0:** tambah `generateWAMessageFromImagePoll` / `hashImagePollOption` builder sisi-klien buat tipe pesan image-poll WhatsApp (`pollCreationMessageV3` + `pollCreationOptionImageMessage`, asosiasi `MEDIA_POLL`). Eksperimental belum ada fork Baileys manapun yang punya ini.
393
+ - Pengganti rich messages lama: `rich-webui.js` (`sendInlineWebUI`, `buildWebuiMessage`).
394
+ - **10.0.1:** menambahkan `rich-classic.js` (`buildButtonsMessage`, `buildListMessage`, `sendClassicMessage`, `normalizeUserJid`) card `interactiveMessage`/`nativeFlowMessage` udah nggak render di banyak client; pakai template klasik buat kompatibilitas maksimal.
395
+ - **10.0.2:** mengembalikan auto-inject node stanza `<biz>` dari ob9 (di-port dari ourin-baileys 9.0.21) `relayMessage` sekarang otomatis melampirkan node interactive `biz` buat payload `buttonsMessage` / `listMessage` / `interactiveMessage`+`nativeFlowMessage`, kecuali si pemanggil udah menyediakan sendiri. Tanpa node ini server menerima stanza-nya tapi client penerima nggak pernah render card-nya (relay sukses diam-diam, pesan nggak pernah muncul). Ini regresi selama rebase ke Baileys 7 dan jadi akar masalah menu button/list yang invisible.
396
+ - **10.0.3:** menambahkan `rich-carousel.js` (`buildCarouselMessage`, `buildInteractiveMessage`, `buildInteractiveCard`, `buildNativeFlowButton`, `sendCarouselMessage`, `sendInteractiveMessage`) buat carousel card dan tombol CTA native-flow yang lebih kaya (`cta_url`/`cta_call`/`cta_copy`/`cta_reminder`/`single_select`). Juga memperluas `generateProfilePicture` (dan `updateProfilePicture` / `newsletterUpdatePicture`) dengan opsi `{ full: true }` buat upload foto profil di resolusi/kualitas asli, bukan downscale paksa 640×640 quality-50.
397
+ - **10.1.0:** menggabungkan `lib/Store/*` (in-memory store, cache-manager store, keyed-db/ordered-dictionary/object-repository) dari `@vansnowi/baileys`, plus `useSqliteAuthState` (node:sqlite bawaan Node 22.5+, dengan fallback error yang jelas di Node lama) dan filter kirim `isSecret`/`protected`/`me`-only yang dipasang ke `sock.sendMessage`.
398
+ - **10.2.0:** menambahkan `generateWAMessageFromImagePoll` / `hashImagePollOption` builder sisi klien buat tipe pesan image-poll WhatsApp (`pollCreationMessageV3` + `pollCreationOptionImageMessage`, asosiasi `MEDIA_POLL`). Eksperimental nggak ada fork Baileys upstream yang menyediakan ini.
399
+ - **10.5.0:** menambahkan opsi kirim `viewOnceV2` / `viewOnceV2Extension` (pesan dibungkus `viewOnceMessageV2` / `viewOnceMessageV2Extension`; untuk teks, `viewOnce: true` di-set di dalam `extendedTextMessage`); `sock.richMenu` (`rich-menu.js`: `buildRichMenuMessage`, `sendRichMenu` — tombol, kartu carousel/row, header gambar, footer open-URL) di-port dari `@vansnowi/baileys` tanpa link footer default bawaannya; widget A2UI (`a2ui.js`: `A2UI`, `sendA2UIWidget`, `sock.sendA2UI`) dikirim lewat `interactiveMessage.bloksWidget`, dengan `InteractiveMessage.BloksWidget` (field 8) ditambahkan ke WAProto (`WAProto.proto`, `index.js`, `index.d.ts`). `richMenu` dan A2UI memakai format internal WhatsApp, jadi bisa tidak dirender di semua client.
400
+ - Konfigurasi default berubah: `syncFullHistory` dan `enableRecentMessageCache` sekarang `false`.
401
+ - `protobufjs-cli` di-pin ke `^1.1.3` (fix konflik peer dependency); `link-preview-js` ke `^5.0.0` (fix advisory SSRF).
402
+ - **Rebrand:** package diganti nama jadi `@rennzsync/baileys`, sekarang dirawat oleh [RennZz-Dev](https://github.com/RennZSync). Nggak ada perubahan API — update import kamu dari `onigis` ke `@rennzsync/baileys`.
403
+ - **Engine Signal dikembalikan ke stock:** menghapus engine custom `@rennzsync/signal`/`@rennzsync/curve25519` (MIT, native Rust) dan kembali ke `libsignal` asli (GPL-3.0) yang dipakai stock Baileys rc14 — implementasi Signal Protocol yang sama, nggak ada lagi binary native custom yang perlu di-build/dikirim. Lihat catatan lisensi di bagian atas file ini.
238
404
 
239
405
  ---
240
406
 
241
407
  ## Testing
242
408
 
243
409
  ```bash
244
- npm test
410
+ npm test
245
411
  ```
246
412
 
247
- Termasuk unit test: JID utils (PN/LID/hosted), Rich WebUI (build + roundtrip proto encode/decode).
413
+ Termasuk unit test buat: JID utils (PN/LID/hosted), Rich WebUI (build + roundtrip encode/decode proto).
248
414
 
249
415
  ---
250
416
 
251
417
  ## Kredit
252
418
 
253
- - **[RennZz-Dev](https://github.com/RennZSync)** — maintainer `renz/baileys`: rebrand, perawatan & penyesuaian untuk kebutuhan bot
254
- - **[KzorArsuy](https://github.com/rozzak2009)** — audit, rebase rc14, optimasi, multimedia & WebUI
255
- - **[WhiskeySockets/Baileys](https://github.com/WhiskeySockets/Baileys)** — upstream library & wrapper Signal Protocol asli (berbasis `libsignal`)
419
+ - **[RennZz-Dev](https://github.com/RennZSync)** — maintainer `rennzsync/baileys`: rebrand, perawatan berkelanjutan & penyesuaian fokus bot
420
+ - **[WhiskeySockets/Baileys](https://github.com/WhiskeySockets/Baileys)** — library upstream & wrapper Signal Protocol asli (berbasis `libsignal`)
256
421
 
257
422
  ---
258
423
 
259
424
  ## Lisensi
260
425
 
261
- **MIT** untuk kode `renz/baileys` sendiri — tapi bergantung ke `libsignal` (GPL-3.0) saat runtime buat crypto Signal Protocol. Cek dulu implikasinya buat kebutuhanmu sebelum redistribusi.
426
+ **MIT** buat kode `rennzsync/baileys` sendiri — tapi bergantung pada `libsignal` (GPL-3.0) saat runtime untuk kripto Signal Protocol. Cek dulu apa artinya buat use case kamu sebelum redistribusi.