# 📣 riyoo

<p align="center">
   WhatsApp Web API library — fork dari <a href="https://github.com/WhiskeySockets/Baileys">Baileys</a> dengan perbaikan LID/PN JID handling, dukungan pesan interaktif, album, newsletter, dan berbagai tipe pesan tambahan.
   <br><br>
   <img src="https://img.shields.io/badge/node-%3E%3D20-339933?logo=node.js&labelColor=green&logoColor=white&style=for-the-badge"/>
   <img src="https://img.shields.io/badge/ESM-only-yellow?logo=javascript&logoColor=black&style=for-the-badge"/>
   <img src="https://img.shields.io/badge/license-MIT-blue?style=for-the-badge"/>
</p>

---

### ✨ Fitur Utama

- 🔧 Fix LID/PN JID handling untuk grup (addressing mode `lid` & `s.whatsapp.net/@g.us`)
- 🚫 Tanpa obfuscation — kode mudah dibaca dan diaudit
- 🚫 Tanpa auto-follow channel (newsletter)
- 📦 Includes `makeInMemoryStore` dengan adaptasi ESM minimal
- 🖼️ Support multi image processing backend: `sharp`, `@napi-rs/image`, atau `jimp`
- 📦 FFmpeg menggunakan `spawn` (lebih aman dari `exec`)

---

### 🛠️ Perbaikan Internal

- 🔑 **Fix variable shadowing `isLidUser`** di `getUSyncDevices` — mencegah konflik antara variabel lokal dan fungsi import
- 📍 **Fix server encoding untuk `@lid` JID** — memastikan JID yang diminta sebagai LID tetap `@lid`, bukan berubah jadi `@s.whatsapp.net`
- 👥 **Fix participant list di grup** — null-check eksplisit, normalisasi JID via `jidNormalizedUser`, dan cross-field validation antara `phoneNumber` dan `lid`
- 🔊 **Fix ptt: true, stabil no error**
- 🖼️ **Fix media upload ke newsletter**
- 🔒 Fix `updateBlockStatus` implementation

---

### 📨 Tipe Pesan yang Didukung

- 🖼️ Album (Image & Video)
- 👥 Group Status Message
- 👉🏻 Interactive Message (buttons, list, native flow, template, carousel)
- 🧩 Interactive Message Raw (native flow penuh: `cta_copy`, `cta_url`, `cta_call`, `quick_reply`, `single_select`, `call_permission_request`)
- 🎞️ Status Mention Message
- 📦 Sticker Pack Message
- ✨ Rich Response Message
- 🧾 Message with Code Block
- 🌏 Message with Inline Entities
- 📋 Message with Table
- 💳 Payment-related Message (request, invite, order, invoice)
- 🎠 Carousel Message
- 🤖 Rich Response / AI Message (code block, table, inline link)
- 🎥 PTV (Circle Video / Picture-in-Picture)
- 👥 Group Invite Link Message
- 📞 Share / Request Phone Number
- 🗳️ Quiz (Poll with correct answer)
- 📊 Poll Result Snapshot

---

### 📋 Daftar Isi

- [📥 Instalasi](#-instalasi)
- [🌐 Koneksi ke WhatsApp](#-koneksi-ke-whatsapp)
- [🗄️ Data Store](#️-data-store)
- [🪪 Penjelasan WhatsApp ID](#-penjelasan-whatsapp-id)
- [✉️ Mengirim Pesan](#️-mengirim-pesan)
- [📁 Mengirim Media](#-mengirim-media)
- [👉🏻 Pesan Interaktif](#-pesan-interaktif)
- [🧩 Interactive Message Raw](#-interactive-message-raw-native-flow-penuh)
- [💳 Pesan Pembayaran](#-pesan-pembayaran)
- [🛒 Pesan Order & Invoice](#-pesan-order--invoice)
- [👁️ Opsi Pesan Lainnya](#️-opsi-pesan-lainnya)
- [♻️ Modifikasi Pesan](#️-modifikasi-pesan)
- [↩️ Pesan Balasan Interaktif](#️-pesan-balasan-interaktif)
- [🧰 Konten Tambahan](#-konten-tambahan)
- [📣 Credits](#-credits)

---

### 📥 Instalasi

```bash
# Via NPM
npm i baileys-yorkv2

# Via GitHub
npm i github:baileys-yorkv2 ( gada repo nya yaa )
```

```json
// package.json
"dependencies": {
   "baileys-yorkv2": "latest"
}
```

#### 🧩 Import (ESM & CJS)

```javascript
// ESM
import { makeWASocket } from 'baileys-yorkv2'

// CJS
const { makeWASocket } = require('baileys-yorkv2')
```

---

### 🌐 Koneksi ke WhatsApp

```javascript
import { makeWASocket, delay, DisconnectReason, useMultiFileAuthState } from 'baileys-yorkv2'
import { Boom } from '@hapi/boom'
import pino from 'pino'

const myPhoneNumber = '6288888888888'
const logger = pino({ level: 'silent' })

const connectToWhatsApp = async () => {
   const { state, saveCreds } = await useMultiFileAuthState('session')

   const sock = makeWASocket({
      logger,
      auth: state
   })

   sock.ev.on('creds.update', saveCreds)

   sock.ev.on('connection.update', async (update) => {
      const { connection, lastDisconnect } = update
      if (connection === 'connecting' && !sock.authState.creds.registered) {
         await delay(1500)
         const code = await sock.requestPairingCode(myPhoneNumber)
         console.log('🔗 Pairing code:', code)
      }
      else if (connection === 'close') {
         const shouldReconnect = new Boom(lastDisconnect?.error)?.output?.statusCode !== DisconnectReason.loggedOut
         if (shouldReconnect) connectToWhatsApp()
      }
      else if (connection === 'open') {
         console.log('✅ Terhubung ke WhatsApp')
      }
   })

   sock.ev.on('messages.upsert', async ({ messages }) => {
      for (const message of messages) {
         if (!message.message) continue
         await sock.sendMessage(message.key.remoteJid, { text: '👋🏻 Halo!' })
      }
   })
}

connectToWhatsApp()
```

#### 🔐 Auth State

> [!NOTE]
> Bisa juga pakai `useSingleFileAuthState` atau `useSqliteAuthState` sebagai alternatif dari `useMultiFileAuthState`.

---

### 🗄️ Data Store

> [!CAUTION]
> Sangat disarankan membangun data store sendiri — menyimpan seluruh riwayat chat di memori bisa menyebabkan penggunaan RAM yang berlebihan.

```javascript
import { makeWASocket, makeInMemoryStore, useMultiFileAuthState } from 'baileys-yorkv2'
import pino from 'pino'

const logger = pino({ level: 'silent' })
const storePath = './store.json'

const connectToWhatsApp = async () => {
   const { state, saveCreds } = await useMultiFileAuthState('session')

   const sock = makeWASocket({ logger, auth: state })
   const store = makeInMemoryStore({ logger, socket: sock })

   store.bind(sock.ev)
   store.readFromFile(storePath)
   setInterval(() => store.writeToFile(storePath), 180_000)

   sock.ev.on('creds.update', saveCreds)
}

connectToWhatsApp()
```

---

### 🪪 Penjelasan WhatsApp ID

`jid` adalah ID WhatsApp pengguna atau grup.

- **Pengguna PN**: `6281111111111@s.whatsapp.net`
- **Pengguna LID**: `43411111111111@lid`
- **Grup**: `123456789-123345@g.us`
- **Meta AI**: `11111111111@bot`
- **Broadcast list**: `[timestamp]@broadcast`
- **Stories**: `status@broadcast`
- **Newsletter**: `1231111111111@newsletter`

> [!NOTE]
> Nomor telepon harus menggunakan format internasional tanpa `+`, `()`, atau `-`.

---

### ✉️ Mengirim Pesan

#### 🔠 Teks

```javascript
// Teks biasa
sock.sendMessage(jid, { text: '👋🏻 Halo' }, { quoted: message })

// Teks dengan link preview
sock.sendMessage(jid, {
   text: 'https://github.com — cek ini!',
   linkPreview: {
      'matched-text': 'https://github.com',
      title: 'GitHub',
      description: 'Where the world builds software',
      previewType: 0
   }
})
```

#### 🔔 Mention

```javascript
// Mention spesifik
sock.sendMessage(jid, {
   text: '👋🏻 Halo @628123456789',
   mentions: ['628123456789@s.whatsapp.net']
}, { quoted: message })

// Mention semua
sock.sendMessage(jid, {
   text: '👋🏻 Halo @all',
   mentionAll: true
}, { quoted: message })
```

#### 😁 Reaksi

```javascript
sock.sendMessage(jid, {
   react: { key: message.key, text: '✨' }
})
```

#### 📌 Pin Pesan

```javascript
sock.sendMessage(jid, {
   pin: message.key,
   time: 86400, // detik: 86400 (1h), 604800 (7h), 2592000 (30h)
   type: 1 // 2 untuk unpin
})
```

#### 🔖 Keep Chat

> [!NOTE]
> Hanya untuk chat dengan disappearing messages aktif.

```javascript
sock.sendMessage(jid, { keep: message.key, type: 1 }) // type: 2 untuk remove
```

#### ➡️ Forward

```javascript
sock.sendMessage(jid, { forward: message, force: true })
```

#### 👤 Kontak

```javascript
const vcard = 'BEGIN:VCARD\nVERSION:3.0\nFN:Nama Kontak\nTEL;type=CELL;waid=628123456789:+62 8123 456 789\nEND:VCARD'

sock.sendMessage(jid, {
   contacts: {
      displayName: 'Nama Kontak',
      contacts: [{ vcard }]
   }
}, { quoted: message })
```

#### 📍 Lokasi

```javascript
sock.sendMessage(jid, {
   location: {
      degreesLatitude: -6.2,
      degreesLongitude: 106.8,
      name: '📍 Jakarta'
   }
}, { quoted: message })
```

#### 🗓️ Event

```javascript
sock.sendMessage(jid, {
   event: {
      name: '🎉 Acara Seru',
      description: 'Deskripsi acara di sini.',
      startDate: new Date(Date.now() + 3_600_000),
      endDate: new Date(Date.now() + 28_800_000),
      location: { name: 'Jakarta', degreesLatitude: -6.2, degreesLongitude: 106.8 }
   }
}, { quoted: message })
```

#### 📊 Polling

```javascript
sock.sendMessage(jid, {
   poll: {
      name: '🔥 Pilih satu!',
      values: ['Ya', 'Tidak'],
      selectableCount: 1,
      endDate: new Date(Date.now() + 28_800_000)
   }
}, { quoted: message })
```

#### 🗳️ Quiz (Newsletter)

> [!NOTE]
> Hanya berfungsi di newsletter (`@newsletter`).

```javascript
sock.sendMessage(jid, {
   poll: {
      name: '❓ Ibu kota Indonesia?',
      values: ['Jakarta', 'Bandung', 'Surabaya', 'Nusantara'],
      pollType: 1,          // 1 = quiz
      correctAnswer: 'Nusantara'
   }
}, { quoted: message })
```

---

### 📁 Mengirim Media

> [!NOTE]
> Media bisa berupa `Buffer`, `{ stream: Readable }`, atau `{ url: string }` (path lokal atau URL HTTP/HTTPS).

#### 🖼️ Gambar

```javascript
sock.sendMessage(jid, {
   image: { url: './path/to/image.jpg' },
   caption: '🔥 Keren!'
}, { quoted: message })
```

#### 🎥 Video

```javascript
sock.sendMessage(jid, {
   video: { url: './path/to/video.mp4' },
   gifPlayback: false,
   caption: '🎬 Video keren!'
}, { quoted: message })
```

#### 📃 Stiker

```javascript
sock.sendMessage(jid, {
   sticker: { url: './path/to/sticker.webp' }
}, { quoted: message })
```

#### 💽 Audio

```javascript
sock.sendMessage(jid, {
   audio: { url: './path/to/audio.mp3' },
   ptt: false // true = Voice Note
}, { quoted: message })
```

#### 🗂️ Dokumen

```javascript
sock.sendMessage(jid, {
   document: { url: './path/to/file.pdf' },
   mimetype: 'application/pdf',
   caption: '📄 Dokumen saya'
}, { quoted: message })
```

#### 🖼️ Album (Gambar & Video)

```javascript
sock.sendMessage(jid, {
   album: [
      { image: { url: './image1.jpg' }, caption: 'Foto 1' },
      { video: { url: './video1.mp4' }, caption: 'Video 1' },
      { image: { url: './image2.jpg' }, caption: 'Foto 2' }
   ]
}, { quoted: message })
```

#### 📦 Sticker Pack

> [!IMPORTANT]
> Jika `sharp` atau `@napi-rs/image` tidak terpasang, `cover` dan `stickers` harus sudah dalam format WebP.

```javascript
sock.sendMessage(jid, {
   cover: { url: './cover.webp' },
   stickers: [
      { data: { url: './sticker1.webp' } },
      { data: { url: './sticker2.webp' } }
   ],
   name: '📦 Sticker Pack Ku',
   publisher: '🌟 Nama Kamu'
}, { quoted: message })
```

#### 🎥 PTV (Circle Video)

```javascript
sock.sendMessage(jid, {
   video: { url: './path/to/video.mp4' },
   ptv: true
}, { quoted: message })
```

---

### 👉🏻 Pesan Interaktif

#### 🔘 Tombol (Buttons)

```javascript
sock.sendMessage(jid, {
   text: '👆🏻 Pilih opsi:',
   footer: 'riyoo',
   buttons: [
      { text: '👋🏻 Halo', id: '#Halo' },
      { text: '❓ Bantuan', id: '#Bantuan' }
   ]
}, { quoted: message })
```

#### 📋 List

> [!NOTE]
> Hanya berfungsi di chat pribadi (`@s.whatsapp.net`).

```javascript
sock.sendMessage(jid, {
   text: '📋 Menu',
   footer: 'riyoo',
   buttonText: '📋 Pilih',
   sections: [{
      title: '🚀 Menu Utama',
      rows: [
         { title: '✨ Fitur A', description: '', rowId: '#FiturA' },
         { title: '🔍 Cari', description: '', rowId: '#Cari' }
      ]
   }]
}, { quoted: message })
```

#### 🗄️ Interactive (Native Flow)

```javascript
sock.sendMessage(jid, {
   image: { url: './image.jpg' },
   caption: '🗄️ Menu Interaktif',
   footer: 'riyoo',
   nativeFlow: [
      { text: '👋🏻 Sapa', id: '#Sapa', icon: 'review' },
      { text: '🌐 Website', url: 'https://github.com', useWebview: true },
      { text: '📋 Salin', copy: 'teks yang disalin' },
      { text: '📞 Hubungi', call: '628123456789' }
   ]
}, { quoted: message })
```

#### 🫙 Template

```javascript
sock.sendMessage(jid, {
   title: '👋🏻 Halo',
   image: { url: './image.jpg' },
   caption: '🫙 Template',
   footer: 'riyoo',
   templateButtons: [
      { text: '👉🏻 Tap', id: '#Tap' },
      { text: '🌐 Buka', url: 'https://github.com' },
      { text: '📞 Telepon', call: '628123456789' }
   ]
}, { quoted: message })
```

#### 🧩 Interactive Message Raw (Native Flow Penuh)

Gunakan `interactiveMessage` langsung untuk kontrol penuh atas struktur pesan — mendukung `nativeFlowMessage` dengan `messageParamsJson` kustom, `bottom_sheet`, `limited_time_offer`, `tap_target_configuration`, `call_permission_request`, dan kombinasi tombol kompleks.

```javascript
sock.sendMessage(jid, {
   interactiveMessage: {
      title: '📋 Judul Pesan',
      footer: 'Footer Pesan',
      thumbnail: 'https://example.com/image.jpg', // URL string, Buffer, atau { url }
      nativeFlowMessage: {
         messageParamsJson: JSON.stringify({
            limited_time_offer: {
               text: 'Penawaran Terbatas',
               url: 'https://example.com',
               copy_code: 'KODE123',
               expiration_time: Date.now() + 3_600_000
            },
            bottom_sheet: {
               in_thread_buttons_limit: 2,
               divider_indices: [1, 2, 3],
               list_title: 'Pilih Menu',
               button_title: '📋 Buka Menu'
            },
            tap_target_configuration: {
               title: '▸ Info ◂',
               description: 'Deskripsi',
               canonical_url: '',
               domain: 'shop.example.com',
               button_index: 0
            }
         }),
         buttons: [
            // Tombol izin panggilan
            {
               name: 'call_permission_request',
               buttonParamsJson: JSON.stringify({ has_multiple_buttons: true })
            },
            // Tombol list/pilihan
            {
               name: 'single_select',
               buttonParamsJson: JSON.stringify({
                  title: '📋 Pilih Opsi',
                  sections: [{
                     title: 'Menu Utama',
                     highlight_label: 'Home',
                     rows: [
                        { title: 'Fitur A', description: 'Deskripsi A', id: '#FiturA' },
                        { title: 'Fitur B', description: 'Deskripsi B', id: '#FiturB' }
                     ]
                  }],
                  has_multiple_buttons: true
               })
            },
            // Tombol URL
            {
               name: 'cta_url',
               buttonParamsJson: JSON.stringify({
                  display_text: '🌐 Kunjungi',
                  url: 'https://example.com',
                  merchant_url: 'https://example.com'
               })
            },
            // Tombol salin kode
            {
               name: 'cta_copy',
               buttonParamsJson: JSON.stringify({
                  display_text: '📋 Salin Kode',
                  copy_code: 'KODE123'
               })
            },
            // Tombol telepon
            {
               name: 'cta_call',
               buttonParamsJson: JSON.stringify({
                  display_text: '📞 Hubungi',
                  phone_number: '628123456789'
               })
            },
            // Tombol quick reply
            {
               name: 'quick_reply',
               buttonParamsJson: JSON.stringify({
                  display_text: '👉🏻 Balas',
                  id: '#Balas'
               })
            }
         ]
      },
      contextInfo: {
         mentionedJid: ['628123456789@s.whatsapp.net'],
         isForwarded: true,
         forwardedNewsletterMessageInfo: {
            newsletterJid: '1231111111111@newsletter',
            newsletterName: 'Channel Name',
            serverMessageId: -1
         }
      }
   }
}, { quoted: message })
```

> [!NOTE]
> Semua nama tombol yang valid: `quick_reply`, `cta_url`, `cta_copy`, `cta_call`, `single_select`, `call_permission_request`.
> Field `thumbnail` bisa berupa string URL, `Buffer`, atau objek `{ url: '...' }`.

#### 🎠 Carousel

```javascript
sock.sendMessage(jid, {
   text: '🎠 Pilih kartu:',
   footer: 'riyoo',
   cards: [
      {
         image: { url: './image1.jpg' },
         caption: '🃏 Kartu 1',
         footer: 'Footer kartu 1',
         nativeFlow: [
            { text: '👉🏻 Pilih', id: '#Kartu1' },
            { text: '🌐 Info', url: 'https://example.com' }
         ]
      },
      {
         image: { url: './image2.jpg' },
         caption: '🃏 Kartu 2',
         footer: 'Footer kartu 2',
         nativeFlow: [
            { text: '👉🏻 Pilih', id: '#Kartu2' }
         ]
      }
   ]
}, { quoted: message })
```

#### 👥 Group Invite Link

```javascript
sock.sendMessage(jid, {
   groupInvite: {
      jid: '123456789-123345@g.us',
      subject: 'Nama Grup',
      inviteCode: 'XXXXXXXXXXXX',
      inviteExpiration: Date.now() + 86_400_000,
      text: '🔗 Bergabunglah!'
   }
}, { quoted: message })
```

---

### 💳 Pesan Pembayaran

```javascript
// Undang pembayaran
sock.sendMessage(jid, { paymentInviteServiceType: 3 })

// Request pembayaran
sock.sendMessage(jid, {
   text: '💳 Request Pembayaran',
   requestPaymentFrom: '628123456789@s.whatsapp.net'
})
```

---

### 🛒 Pesan Order & Invoice

#### 📦 Order Message

> [!IMPORTANT]
> Field `thumbnail` wajib berupa `Buffer`.

```javascript
import fs from 'fs'

sock.sendMessage(jid, {
   orderText: 'Pesanan kamu sudah siap!',
   thumbnail: fs.readFileSync('./product.jpg'),
   itemCount: 2,
   totalAmount1000: 50000,   // harga × 1000 (Rp 50.000)
   totalCurrencyCode: 'IDR'
}, { quoted: message })
```

#### 🧾 Invoice Message

> [!IMPORTANT]
> Harus disertai media (`image` atau `document`) sebelum `invoiceNote`.

```javascript
sock.sendMessage(jid, {
   image: { url: './invoice.jpg' },
   invoiceNote: '🧾 Invoice #001 — Terima kasih telah berbelanja!'
}, { quoted: message })
```

---

### 👁️ Opsi Pesan Lainnya

#### 🤖 Ikon AI

> [!NOTE]
> Hanya berfungsi di chat pribadi (`@s.whatsapp.net`).

```javascript
sock.sendMessage(jid, {
   image: { url: './image.jpg' },
   caption: '🤖 Pesan AI',
   ai: true
})
```

#### 🎨 Warna Latar & Font Teks

```javascript
// Warna latar (status / ptt)
sock.sendMessage(jid, {
   text: '🎨 Pesan berwarna',
   backgroundColor: '#FF6B6B'   // hex color string
})

// Font kustom
sock.sendMessage(jid, {
   text: '✍️ Font kustom',
   font: 1   // 1–8, lihat WAProto ExtendedTextMessage.FontType
})
```

#### 🌐 Favicon Teks

```javascript
import fs from 'fs'

sock.sendMessage(jid, {
   text: 'Cek https://example.com',
   favicon: fs.readFileSync('./favicon.png')  // Buffer favicon
})
```

#### 📊 Group Status

Tandai pesan agar tampil sebagai pesan status grup (muncul di sistem grup).

```javascript
sock.sendMessage(jid, {
   text: '📢 Pengumuman grup',
   groupStatus: true
})
```

#### 📞 Berbagi / Minta Nomor Telepon

```javascript
// Kirim nomor kamu ke lawan bicara
sock.sendMessage(jid, { sharePhoneNumber: true })

// Minta nomor telepon lawan bicara
sock.sendMessage(jid, { requestPhoneNumber: true })

// Batasi berbagi (limit sharing)
sock.sendMessage(jid, { limitSharing: true })   // true = batasi, false = buka
```

#### 📑 Spoiler

```javascript
sock.sendMessage(jid, {
   image: { url: './image.jpg' },
   caption: '❔ Spoiler nih',
   spoiler: true
})
```

#### 👁️ View Once

```javascript
sock.sendMessage(jid, {
   image: { url: './image.jpg' },
   caption: '👁️ Lihat sekali saja',
   viewOnce: true
})
```

#### 🕒 Ephemeral

```javascript
sock.sendMessage(jid, {
   image: { url: './image.jpg' },
   caption: '🕒 Ephemeral',
   ephemeral: true
})
```

#### 📰 External Ad Reply

```javascript
sock.sendMessage(jid, {
   text: '📰 External Ad',
   externalAdReply: {
      title: '📝 Info Menarik',
      body: 'Cek ini!',
      thumbnail: fs.readFileSync('./thumb.jpg'),
      largeThumbnail: false,
      url: 'https://github.com'
   }
}, { quoted: message })
```

#### 🧩 Raw

```javascript
sock.sendMessage(jid, {
   extendedTextMessage: {
      text: '📃 Dibuat manual dari struktur proto WhatsApp',
      contextInfo: {
         externalAdReply: {
            title: 'riyoo',
            thumbnail: fs.readFileSync('./thumb.jpg'),
            sourceApp: 'whatsapp',
            showAdAttribution: true,
            mediaType: 1
         }
      }
   },
   raw: true
}, { quoted: message })
```

---

### ♻️ Modifikasi Pesan

#### 🗑️ Hapus Pesan

```javascript
sock.sendMessage(jid, { delete: message.key })
```

#### ✏️ Edit Pesan

```javascript
// Edit teks
sock.sendMessage(jid, { text: '✨ Sudah diedit!', edit: message.key })

// Edit caption media
sock.sendMessage(jid, { caption: '✨ Caption baru', edit: message.key })
```

---

### ↩️ Pesan Balasan Interaktif

#### 🔘 Button Reply

```javascript
// Template button reply
sock.sendMessage(jid, {
   buttonReply: {
      displayText: '👉🏻 Tap',
      id: '#Tap',
      index: 0
   },
   type: 'template'
})

// Plain button reply
sock.sendMessage(jid, {
   buttonReply: {
      displayText: '👉🏻 Tap',
      id: '#Tap'
   },
   type: 'plain'
})
```

#### 📋 List Reply

```javascript
sock.sendMessage(jid, {
   listReply: {
      title: '✨ Fitur A',
      description: 'Kamu memilih Fitur A',
      id: '#FiturA'
   }
})
```

#### 🗄️ Flow Reply (Native Flow Response)

```javascript
sock.sendMessage(jid, {
   flowReply: {
      name: 'quick_reply',
      paramsJson: JSON.stringify({ id: '#Pilihan1', display_text: 'Pilihan 1' }),
      text: 'Saya memilih ini',
      version: 3
   }
})
```

---

### 🧰 Konten Tambahan

#### 🏷️ Cari User ID (JID | PN / LID)

```javascript
// Via PN
const ids = await sock.findUserId('6281111111111@s.whatsapp.net')
console.log('🏷️ User ID:', ids)
// Output: { phoneNumber: '6281111111111@s.whatsapp.net', lid: '43411111111111@lid' }

// Via LID
const ids = await sock.findUserId('43411111111111@lid')
console.log('🏷️ User ID:', ids)
```

#### 🔑 Pairing Code Kustom

```javascript
const code = await sock.requestPairingCode('6281111111111', 'CUSTOMKODE')
console.log('🔗 Pairing code:', code)
```

#### 🖼️ Image Processing

```javascript
import { getImageProcessingLibrary } from 'riyoo'
import { readFile } from 'fs/promises'

const lib = await getImageProcessingLibrary()
const width = 512

if (lib.sharp?.default) {
   const output = await lib.sharp.default('./image.jpg').resize(width).jpeg({ quality: 80 }).toBuffer()
} else if (lib.image?.Transformer) {
   const buf = await readFile('./image.jpg')
   const output = await new lib.image.Transformer(buf).resize(width, undefined, 0).jpeg(50)
} else if (lib.jimp?.Jimp) {
   const img = await lib.jimp.Jimp.read('./image.jpg')
   const output = await img.resize({ w: width }).getBuffer('image/jpeg', { quality: 50 })
}
```

#### 📣 Manajemen Newsletter

```javascript
sock.newsletterCreate('Nama Channel', 'Deskripsi channel')
sock.newsletterFollow('1231111111111@newsletter')
sock.newsletterUnfollow('1231111111111@newsletter')
sock.newsletterMute('1231111111111@newsletter')
sock.newsletterUnmute('1231111111111@newsletter')
sock.newsletterDelete('1231111111111@newsletter')
```

#### 👥 Manajemen Grup

```javascript
// Buat grup
const group = await sock.groupCreate('Nama Grup', ['628123456789@s.whatsapp.net'])

// Info grup
const metadata = await sock.groupMetadata(jid)

// Update peserta
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'add')    // tambah
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'remove') // keluarkan
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'promote') // jadikan admin
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'demote')  // cabut admin

// Pengaturan grup
sock.groupSettingUpdate(jid, 'announcement')    // hanya admin yang bisa chat
sock.groupSettingUpdate(jid, 'not_announcement') // semua bisa chat
sock.groupToggleEphemeral(jid, 86400) // aktifkan pesan hilang (86400 = 1 hari)
sock.groupToggleEphemeral(jid, 0)     // nonaktifkan pesan hilang
sock.groupLeave(jid)
```

#### 👤 Manajemen Profil

```javascript
sock.updateProfileName('Nama Saya')
sock.updateProfileStatus('Sedang sibuk')
sock.updateProfilePicture(jid, { url: './photo.jpg' })
sock.removeProfilePicture(jid)
sock.updateBlockStatus(jid, 'block')
sock.updateBlockStatus(jid, 'unblock')
sock.readMessages([message.key])
```

#### 🔐 Manajemen Privasi

```javascript
sock.updateLastSeenPrivacy('all')       // semua bisa lihat last seen
sock.updateLastSeenPrivacy('nobody')    // tidak ada yang bisa lihat
sock.updateOnlinePrivacy('all')
sock.updateProfilePicturePrivacy('contacts')
sock.updateReadReceiptsPrivacy('all')
sock.updateReadReceiptsPrivacy('none')
sock.updateGroupsAddPrivacy('contacts')
sock.updateCallPrivacy('everyone')
sock.updateDefaultDisappearingMode(86400)
```

#### 📡 Events

```javascript
sock.ev.on('connection.update', (update) => {})
sock.ev.on('creds.update', (update) => {})
sock.ev.on('messages.upsert', (update) => {})
sock.ev.on('messages.update', (update) => {})
sock.ev.on('messages.reaction', (update) => {})
sock.ev.on('message-receipt.update', (update) => {})
sock.ev.on('chats.upsert', (update) => {})
sock.ev.on('chats.update', (update) => {})
sock.ev.on('contacts.upsert', (update) => {})
sock.ev.on('contacts.update', (update) => {})
sock.ev.on('groups.upsert', (update) => {})
sock.ev.on('groups.update', (update) => {})
sock.ev.on('group-participants.update', (update) => {})
sock.ev.on('group.join-request', (update) => {})
sock.ev.on('presence.update', (update) => {})
sock.ev.on('lid-mapping.update', (update) => {})
sock.ev.on('blocklist.set', (update) => {})
sock.ev.on('blocklist.update', (update) => {})
sock.ev.on('call', (update) => {})
sock.ev.on('newsletter.reaction', (update) => {})
sock.ev.on('newsletter.view', (update) => {})
sock.ev.on('settings.update', (update) => {})
```

---

### 🤖 Rich Response / AI Message

Pesan berformat kaya (AI-style) dengan dukungan code block berwarna, tabel, dan inline link. Dibungkus otomatis dalam `botForwardedMessage`.

#### 🧾 Code Block

```javascript
sock.sendMessage(jid, {
   code: `function halo() {\n  return 'Halo Dunia'\n}`,
   language: 'javascript',   // opsional, default: 'javascript'
   disclaimerText: '⚠️ Kode ini dibuat otomatis'
})
```

#### 📋 Tabel

```javascript
sock.sendMessage(jid, {
   table: [
      ['Nama', 'Umur', 'Kota'],     // baris pertama = heading otomatis
      ['Alice', '24', 'Jakarta'],
      ['Bob', '30', 'Surabaya']
   ],
   title: '📋 Data Pengguna'
})
```

#### 🌐 Teks + Inline Link (Kutipan/Referensi)

```javascript
sock.sendMessage(jid, {
   links: [
      {
         text: 'Baca selengkapnya di sini',
         title: 'GitHub Baileys',
         url: 'https://github.com/WhiskeySockets/Baileys',
         displayName: 'Baileys',
         sources: [
            {
               displayName: 'WhiskeySockets',
               subtitle: 'GitHub',
               url: 'https://github.com/WhiskeySockets/Baileys'
            }
         ]
      }
   ]
})
```

#### 🧩 Rich Response Gabungan (Array)

```javascript
sock.sendMessage(jid, {
   richResponse: [
      { text: '📝 Penjelasan fungsi di bawah:' },
      {
         code: [
            { highlightType: 'KEYWORD', codeContent: 'function' },
            { highlightType: 'DEFAULT', codeContent: ' halo() { return ' },
            { highlightType: 'STRING',  codeContent: "'Halo'" },
            { highlightType: 'DEFAULT', codeContent: ' }' }
         ],
         language: 'javascript'
      },
      {
         table: [
            { isHeading: true,  items: ['Key', 'Value'] },
            { isHeading: false, items: ['name', 'riyoo'] }
         ],
         title: 'Output'
      }
   ],
   disclaimerText: '✨ Dibuat otomatis'
})
```

> [!NOTE]
> Rich Response hanya bisa dilihat di WhatsApp terbaru. Tipe `richResponse` array menggunakan token highlight manual (`highlightType`: `KEYWORD`, `STRING`, `COMMENT`, `NUMBER`, `METHOD`, `DEFAULT`).

---

### 📣 Credits

Menggunakan definisi Protocol Buffer yang dikelola oleh [WPP Connect](https://github.com/wppconnect-team) via [`wa-proto`](https://github.com/wppconnect-team/wa-proto).

Kredit penuh diberikan kepada para maintainer dan kontributor asli Baileys:
- [purpshell](https://github.com/purpshell)
- [jlucaso1](https://github.com/jlucaso1)
- [adiwajshing](https://github.com/adiwajshing)
