WA punya banyak jenis tombol interaktif: native buttons, template buttons, list select, dan rich response ala AI.
Tombol bawaan WA yang muncul di bawah pesan. Bisa pake header image, title, text, footer. Setiap tombol punya id unik buat identifikasi.
| Field | Tipe | Keterangan |
|---|---|---|
text | string | Teks utama (wajib minimal spasi kalo ga pake teks) |
buttons | Array<{buttonId, buttonText, type}> | Array tombol. Maks 3 tombol |
image / video | WAMediaUpload | Header berupa media (opsional) |
title | string | Header teks (opsional, dipake kalo ga ada media) |
footer | string | Teks footer (opsional) |
| Field | Keterangan |
|---|---|
buttonId | ID unik tombol (buat deteksi pas di-klik) |
buttonText.displayText | Teks yang tampil di tombol |
type | 1 = reply, biasanya pake ini |
// Button dengan text header await sock.sendMessage(jid, { text: 'Pilih opsi di bawah:', title: 'Menu Utama', footer: 'Pilih salah satu', buttons: [ { buttonId: '1', buttonText: { displayText: 'Produk' }, type: 1 }, { buttonId: '2', buttonText: { displayText: 'Bantuan' }, type: 1 }, { buttonId: '3', buttonText: { displayText: 'Tentang' }, type: 1 }, ], }) // Button dengan header gambar await sock.sendMessage(jid, { text: 'Promo spesial!', image: { url: './banner.jpg' }, buttons: [ { buttonId: 'beli', buttonText: { displayText: 'Beli Sekarang' }, type: 1 }, ], })
Waktu user klik button, WA bakal ngirim pesan balasan berupa buttonsResponseMessage. Cek di event messages.upsert:
sock.ev.on('messages.upsert', ({ messages }) => { for (const msg of messages) { const btn = msg.message?.buttonsResponseMessage if (btn) { console.log('User pilih:', btn.selectedButtonId, btn.selectedDisplayText) // Lakukan sesuatu berdasarkan btn.selectedButtonId } } })
Tiga jenis tombol template: URL (buka link di browser), Quick Reply (kirim balasan), Call (telepon).
| Field | Keterangan |
|---|---|
text | Teks utama |
templateButtons | Array tombol. Bisa campur ketiga jenis |
footer | Footer (opsional) |
| Jenis | Field | Keterangan |
|---|---|---|
| URL | { urlButton: { displayText, url } } | Buka link di browser. WA bakal minta konfirmasi |
| Quick Reply | { quickReplyButton: { displayText, id } } | Kirim balasan otomatis. id buat deteksi |
| Call | { callButton: { displayText, phoneNumber } } | Telepon nomor tertentu |
await sock.sendMessage(jid, { text: 'Butuh bantuan?', templateButtons: [ { urlButton: { displayText: 'Kunjungi Website', url: 'https://example.com', } }, { quickReplyButton: { displayText: 'Ya, saya butuh', id: 'butuh_bantuan', } }, { callButton: { displayText: 'Hubungi CS', phoneNumber: '+6281234567890', } }, ], })
Sama kaya native button, responnya lewat buttonsResponseMessage:
sock.ev.on('messages.upsert', ({ messages }) => { for (const msg of messages) { if (msg.message?.buttonsResponseMessage) { const { selectedButtonId, selectedDisplayText } = msg.message.buttonsResponseMessage console.log(`User klik "${selectedDisplayText}" (${selectedButtonId})`) } } })
Menu dropdown dengan section dan row. Cocok buat menu bertingkat, pilihan banyak, atau katalog.
| Field | Tipe | Keterangan |
|---|---|---|
text | string | Teks utama |
buttonText | string | Teks yang tampil di tombol dropdown |
title | string | Judul (opsional) |
footer | string | Footer (opsional) |
sections | Section[] | Array kategori. Masing-masing punya title & rows |
| Field | Keterangan |
|---|---|
id | ID unik (buat deteksi pas dipilih) |
title | Nama item |
description | Deskripsi item (opsional) |
await sock.sendMessage(jid, { text: 'Pilih menu:', buttonText: 'Lihat Menu', title: 'Menu Makanan', footer: 'Pilih salah satu', sections: [ { title: 'Minuman', rows: [ { id: 'kopi', title: 'Kopi Hitam', description: 'Espresso mantap' }, { id: 'teh', title: 'Teh Manis', description: 'Teh segar' }, { id: 'jus', title: 'Jus Jeruk', description: 'Peras segar' }, ], }, { title: 'Makanan', rows: [ { id: 'nasi', title: 'Nasi Goreng', description: 'Nasi goreng spesial' }, { id: 'mie', title: 'Mie Ayam', description: 'Mie ayam lengkap' }, ], }, ], })
Respon dari list select berupa listResponseMessage:
sock.ev.on('messages.upsert', ({ messages }) => { for (const msg of messages) { const list = msg.message?.listResponseMessage if (list) { const selectedId = list.singleSelectReply?.selectedRowId const selectedTitle = list.singleSelectReply?.selectedRowTitle console.log(`Dipilih: ${selectedTitle} (${selectedId})`) } } })
Semua button di atas (native, template, list select) internally diubah jadi native_flow message. Cara nanganinya tetap sama lewat buttonsResponseMessage atau listResponseMessage atau interactiveResponseMessage.
sock.ev.on('messages.upsert', ({ messages }) => { for (const msg of messages) { const interactive = msg.message?.interactiveResponseMessage if (interactive) { const { nativeFlowResponseMessage } = interactive console.log('Response:', nativeFlowResponseMessage) } } })
Fitur ini mengubah markdown jadi interactive message ala chat AI (mirip ChatGPT di WA). Caranya: tambah rich: true dan tulis markdown di text.
| Fitur | Syntax | Hasil |
|---|---|---|
| Heading | # Judul sampai #### | Header teks bold |
| Bold | *teks* | Teks tebal |
| Italic | _teks_ | Teks miring |
| Strikethrough | ~teks~ | Teks dicoret |
| Code Block | ```javascript ... ``` | Syntax-highlighted code |
| Tabel | | A | B |\n|---|---|\n| 1 | 2 | | Tabel terformat |
| Gambar |  | Gambar inline |
| Blockquote | > teks | Teks quote |
| Horizontal Rule | --- / *** / ___ | Garis pemisah |
| Suggestion Prompts | :::suggest ... ::: | Tombol saran (pill) |
const markdown = [ '# Dashboard Bot', '', 'Status: *Online* _24/7_ ~maintenance~', '', '## Kode Terbaru', '```javascript', 'const handler = async (msg) => {', " console.log('Pesan:', msg.key.id)", '}', '```', '', '## Statistik', '| Metrik | Nilai |', '|--------|-------|', '| User | 1.234 |', '| Pesan | 5.678 |', '', '', '', '> Bot ini berjalan 24 jam', '', ':::suggest', 'Cek Status | Restart Bot | Bantuan', ':::', ].join('\n') await sock.sendMessage(jid, { text: markdown, rich: true })
Catatan: Rich response cuma bisa dikirim sebagai text + rich: true. Ga bisa dikombinasi dengan media atau button. Fitur ini berguna banget buat bot AI atau dashboard interaktif.
Minta user buat share nomor HP-nya lewat tombol bawaan. Begitu user klik, WA ngirim pesan yang berisi nomor HP user.
await sock.sendMessage(jid, { requestPhoneNumber: true })
Waktu user share nomor, bot bakal nerima pesan berupa requestPhoneNumberMessage atau interactiveResponseMessage:
sock.ev.on('messages.upsert', ({ messages }) => { for (const msg of messages) { if (msg.message?.requestPhoneNumberMessage) { console.log('Nomor user:', msg.key.participant || msg.key.remoteJid) } } })