Solusi komprehensif untuk mengirim tombol interaktif dan native flow WhatsApp menggunakan WhiskeySockets (fork Baileys) tanpa memodifikasi kode sumber inti.
- Gambaran Umum
- Pernyataan Masalah
- Solusi
- Fitur Utama
- Instalasi
- Memulai Cepat
- Jenis Tombol yang Didukung
- Referensi API
- Detail Teknis
- Kompatibilitas
- Kontribusi
- Lisensi
Package ini menyediakan fungsi untuk mengirim setiap jenis tombol interaktif dan native flow WhatsApp yang saat ini diketahui menggunakan WhiskeySockets. Fungsi ini dikemas sebagai package npm buttons-warpper, yang mereproduksi struktur binary node yang dipancarkan oleh klien WhatsApp resmi, memastikan tombol dirender dengan benar baik di chat pribadi maupun grup.
Secara default, WhiskeySockets tidak dapat mengirim tombol interaktif, sementara itsukichan bisa. Penyebab utamanya adalah WhiskeySockets tidak memiliki pembungkus binary node yang diperlukan (biz, interactive, native_flow) yang diharapkan oleh WhatsApp untuk pesan interaktif.
Fungsi yang ditingkatkan yang disediakan oleh package buttons-warpper mengatasi masalah ini dengan:
- Mendeteksi pesan tombol menggunakan logika yang sama dengan itsukichan
- Mengonversi format interactiveButtonsWhiskeySockets ke struktur protobuf yang tepat
- Menambahkan binary node yang hilang (biz,interactive,native_flow,bot) melaluiadditionalNodes
- Menangani secara otomatis persyaratan chat pribadi vs grup
- Menginjeksi method langsung ke object sock untuk kemudahan penggunaan
- β Tidak ada modifikasi pada folder WhiskeySockets
- β Method terintegrasi langsung ke sock object
- β Fungsionalitas template dihapus sesuai permintaan
- β Injeksi binary node otomatis untuk pesan tombol
- β
 Dukungan chat pribadi (menambahkan node botdenganbiz_bot: '1')
- β
 Dukungan chat grup (hanya menambahkan node biz)
- β Kompatibilitas mundur (pesan reguler diteruskan tanpa perubahan)
- β Dukungan TypeScript (definisi tipe lengkap disertakan)
npm install buttons-warpperatau
yarn add buttons-warpperimport { makeWASocket } from "@whiskeysockets/baileys";
import initFunction from "buttons-warpper";
const startSock = async function() {
  const sock = makeWASocket({ /* Options */ });
  
  // Inisialisasi wrapper - menambahkan method ke sock
  await initFunction(sock);
  
  // Sekarang sock memiliki method tambahan:
  // - sock.sendButtons()
  // - sock.sendInteractiveMessage()
}Setelah inisialisasi, Anda dapat langsung memanggil method dari sock:
// Method sendButtons sudah terintegrasi ke sock
await sock.sendButtons(jid, {
  title: 'Judul Header',              // header opsional
  text: 'Pilih salah satu opsi di bawah',    // body
  footer: 'Teks footer',              // footer opsional
  buttons: [
    { id: 'quick_1', text: 'Balasan Cepat' },       // bentuk sederhana legacy yang dikonversi otomatis
    {
      name: 'cta_url',
      buttonParamsJson: JSON.stringify({
        display_text: 'Buka Situs',
        url: 'https://example.com'
      })
    }
  ]
});Untuk kontrol penuh dengan beberapa jenis tombol lanjutan dalam satu pesan, gunakan sendInteractiveMessage yang juga sudah terintegrasi:
// Method sendInteractiveMessage sudah terintegrasi ke sock
await sock.sendInteractiveMessage(jid, {
  text: 'Demo native flow lanjutan',
  footer: 'Semua fitur',
  interactiveButtons: [
    // Balasan cepat (bentuk eksplisit)
    {
      name: 'quick_reply',
      buttonParamsJson: JSON.stringify({ display_text: 'Balas A', id: 'reply_a' })
    },
    // Pemilih select tunggal (list dalam tombol)
    {
      name: 'single_select',
      buttonParamsJson: JSON.stringify({
        title: 'Pilih Satu',
        sections: [{
          title: 'Pilihan',
          rows: [
            { header: 'H', title: 'Halo', description: 'Mengucapkan hai', id: 'opt_hello' },
            { header: 'B', title: 'Selamat Tinggal', description: 'Mengucapkan bye', id: 'opt_bye' }
          ]
        }]
      })
    }
  ]
});Berikut adalah nilai name yang paling umum dan diamati untuk nativeFlowMessage.buttons[] beserta kunci JSON yang diperlukan. Anda dapat mencampur beberapa jenis dalam satu array interactiveButtons.
| Nama | Tujuan | Kunci yang Diperlukan | 
|---|---|---|
| quick_reply | Balasan sederhana yang mengirim kembali idnya | display_text,id | 
| single_select | List pemilih dalam tombol | title,sections | 
| cta_url | Buka URL | display_text,url | 
| cta_copy | Salin teks ke clipboard | display_text,copy_code | 
| cta_call | Ketuk untuk panggilan | display_text,phone_number | 
| cta_catalog | Buka katalog bisnis | display_text(opsional) | 
| send_location | Minta lokasi pengguna | display_text(opsional) | 
| review_and_pay | Ringkasan pesanan/pembayaran | Payload terstruktur pembayaran | 
| payment_info | Alur info pembayaran | Payload terstruktur pembayaran | 
| mpm | Pesan multi produk | Struktur internal vendor | 
| wa_payment_transaction_details | Tampilkan transaksi | Kunci referensi transaksi | 
Catatan: Jenis tombol stabil inti untuk bot adalah:
quick_reply,single_select,cta_url,cta_copy, dancta_call.
await sock.sendInteractiveMessage(jid, {
  text: 'Aksi kontak',
  interactiveButtons: [
    { 
      name: 'cta_url', 
      buttonParamsJson: JSON.stringify({ 
        display_text: 'Dokumentasi', 
        url: 'https://example.com' 
      }) 
    },
    { 
      name: 'cta_copy', 
      buttonParamsJson: JSON.stringify({ 
        display_text: 'Salin Kode', 
        copy_code: 'ABC-123' 
      }) 
    },
    { 
      name: 'cta_call', 
      buttonParamsJson: JSON.stringify({ 
        display_text: 'Hubungi Dukungan', 
        phone_number: '+1234567890' 
      }) 
    }
  ]
});await sock.sendInteractiveMessage(jid, {
  text: 'Jelajahi produk atau balas',
  interactiveButtons: [
    { 
      name: 'quick_reply', 
      buttonParamsJson: JSON.stringify({ 
        display_text: 'Halo', 
        id: 'hi' 
      }) 
    },
    { 
      name: 'quick_reply', 
      buttonParamsJson: JSON.stringify({ 
        display_text: 'Harga', 
        id: 'pricing' 
      }) 
    },
    { 
      name: 'cta_catalog', 
      buttonParamsJson: JSON.stringify({}) 
    }
  ]
});await sock.sendInteractiveMessage(jid, {
  text: 'Silakan bagikan lokasi Anda',
  interactiveButtons: [
    { 
      name: 'send_location', 
      buttonParamsJson: JSON.stringify({ 
        display_text: 'Bagikan Lokasi' 
      }) 
    }
  ]
});await sock.sendInteractiveMessage(jid, {
  text: 'Pilih satu item',
  interactiveButtons: [
    { 
      name: 'single_select', 
      buttonParamsJson: JSON.stringify({
        title: 'Menu',
        sections: [{
          title: 'Utama',
          rows: [
            { id: 'it_1', title: 'Pertama', description: 'Pilihan pertama' },
            { id: 'it_2', title: 'Kedua', description: 'Pilihan kedua' }
          ]
        }]
      }) 
    }
  ]
});Fungsi inisialisasi yang menambahkan method sendInteractiveMessage dan sendButtons ke object sock.
- sock(Object): Socket WhiskeySockets/Baileys yang aktif
Promise yang menyelesaikan dengan sock object yang sudah di-extend dengan method tambahan.
import { makeWASocket } from "@whiskeysockets/baileys";
import initFunction from "buttons-warpper";
const sock = makeWASocket({ /* Options */ });
await initFunction(sock);
// Sekarang sock memiliki method tambahan
await sock.sendButtons(jid, { /* ... */ });
await sock.sendInteractiveMessage(jid, { /* ... */ });Method terintegrasi untuk mengirim pesan interaktif dengan kontrol penuh.
- jid(String): JID WhatsApp tujuan (pengguna atau grup)
- content(Object): Konten pesan dengan properti berikut:- text(String): Teks body
- footer(String): Teks footer (opsional)
- title(String): Judul header (opsional)
- subtitle(String): Subjudul header (opsional)
- interactiveButtons(Array): Array deskriptor tombol
 
- options(Object): Opsi tambahan (opsional):- additionalNodes(Array): Binary node khusus
- additionalAttributes(Object): Atribut relay tambahan
- statusJidList(Array): List status JID
- useCachedGroupMetadata(Boolean): Gunakan metadata grup yang di-cache
 
Promise yang menyelesaikan dengan objek WAMessage lengkap yang dibangun.
await sock.sendInteractiveMessage(jid, {
  text: 'Pilih atau jelajahi',
  footer: 'Demo lanjutan',
  interactiveButtons: [
    { 
      name: 'quick_reply', 
      buttonParamsJson: JSON.stringify({ display_text: 'Hai', id: 'hi' }) 
    },
    { 
      name: 'cta_url', 
      buttonParamsJson: JSON.stringify({ 
        display_text: 'Dokumentasi', 
        url: 'https://example.com' 
      }) 
    }
  ]
});Method terintegrasi yang disederhanakan untuk skenario tombol umum.
- jid(String): JID WhatsApp tujuan (pengguna atau grup)
- data(Object): Data tombol dengan properti berikut:- text(String): Teks body (default: '')
- footer(String): Teks footer (default: '')
- title(String): Judul header (opsional)
- subtitle(String): Subjudul header (opsional)
- buttons(Array): Array tombol (bentuk sederhana atau lengkap)
 
- options(Object): Opsi tambahan (sama dengan sendInteractiveMessage)
Promise yang menyelesaikan dengan objek WAMessage lengkap yang dibangun.
await sock.sendButtons(jid, {
  text: 'Pilih opsi',
  footer: 'Powered by Bot',
  buttons: [
    { id: 'opt1', text: 'Opsi 1' },
    { id: 'opt2', text: 'Opsi 2' }
  ]
});Package ini bekerja dengan menginjeksi method langsung ke object sock melalui fungsi initFunction. Setelah inisialisasi, method sendButtons dan sendInteractiveMessage menjadi bagian dari sock dan dapat dipanggil seperti method bawaan lainnya.
makeWASocket() β initFunction(sock) β sock dengan method tambahan
                                       β
                                   sock.sendButtons()
                                   sock.sendInteractiveMessage()
Wrapper secara otomatis menyuntikkan struktur binary node yang diperlukan:
Chat Pribadi:
biz β interactive β native_flow β buttons + bot (biz_bot=1)
Chat Grup:
biz β interactive β native_flow β buttons
Wrapper mendeteksi jenis tombol menggunakan logika yang sama dengan itsukichan:
- listMessageβ 'list'
- buttonsMessageβ 'buttons'
- interactiveMessage.nativeFlowMessageβ 'native_flow'
Authoring (input):
{ 
  text, 
  footer, 
  interactiveButtons: [{ name, buttonParamsJson }, ...] 
}Output wrapper (dikirim ke WhatsApp):
{ 
  interactiveMessage: { 
    nativeFlowMessage: { buttons: [...] }, 
    body: { text }, 
    footer: { text } 
  } 
}| Komponen | Versi | 
|---|---|
| WhiskeySockets | 7.0.0-rc.2+ | 
| Node.js | 20+ | 
| Jenis Tombol | Semua jenis yang didukung oleh itsukichan | 
| Jenis Chat | Chat pribadi dan grup | 
Kontribusi sangat diterima! Jangan ragu untuk mengirimkan Pull Request.
- Fork repositori
- Buat branch fitur Anda (git checkout -b feature/FiturMenakjubkan)
- Commit perubahan Anda (git commit -m 'Menambahkan FiturMenakjubkan')
- Push ke branch (git push origin feature/FiturMenakjubkan)
- Buka Pull Request
Proyek ini dilisensikan di bawah Lisensi MIT - lihat file LICENSE untuk detailnya.
- Tim WhiskeySockets untuk fork Baileys yang sangat baik
- itsukichan untuk wawasan implementasi tombol
- Semua kontributor yang membantu meningkatkan package ini
Dibuat dengan β€οΈ oleh komunitas