@nuiisweety/baileys
v0.1.19
Published
A WebSockets library for interacting with WhatsApp Web — forked STRICTLY from @whiskeysockets/baileys only, NOT from any other baileys fork. Modified by NuiiS4TORU.
Readme
📋 Daftar Isi
Instalasi · QR Code · Pairing Code · Browser Identity · Opsi Koneksi
Teks · Gambar · Video · Audio & Voice Note · Dokumen · Sticker · Lokasi · Kontak
Reaksi · Poll · Poll Result · Poll Update · Forward · Hapus Pesan · Edit Pesan · Pin Pesan
Album · Event · Group Status / Story · Status Mention · Channel (Newsletter) · Flow Reply · Button Reply · Keep In Chat · Scheduled Call · Group Invite · Product
View Once · View Once V2 · Ephemeral · Spoiler · Group Status Wrap · Lottie Sticker · AI Icon · Secure Meta Label
Buttons Location Header · Buttons · List Message · Template Buttons · Native Flow · Carousel
List Reply · Sticker Pack · External Ad Reply · Request Payment · Invoice · Order · Disappearing Messages · Raw Message
addText · addCode · addTable · addImage · addVideo · addSource · addReels · addProduct · addPost · addTip · addSuggest · Map · LaTeX · Grid Image · Inline Image · Dynamic/GIF · Content Items · Rich Response · Terima & Decode
📦 Instalasi
// CommonJS
const { default: makeWASocket } = require('@nuiisweety/baileys')
// ESM
import makeWASocket from '@nuiisweety/baileys'📱 Koneksi QR Code
const {
default: makeWASocket,
useMultiFileAuthState,
DisconnectReason,
fetchLatestBaileysVersion
} = require('@nuiisweety/baileys')
async function start() {
const { state, saveCreds } = await useMultiFileAuthState('auth_info')
const { version } = await fetchLatestBaileysVersion()
const sock = makeWASocket({
version,
auth: state,
printQRInTerminal: true
})
sock.ev.on('creds.update', saveCreds)
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
if (connection === 'close') {
const code = lastDisconnect?.error?.output?.statusCode
if (code !== DisconnectReason.loggedOut) start()
} else if (connection === 'open') {
console.log('Connected!')
}
})
}
start()🔑 Koneksi Pairing Code
Cocok untuk server/VPS tanpa tampilan terminal.
const sock = makeWASocket({ version, auth: state, printQRInTerminal: false })
sock.ev.on('creds.update', saveCreds)
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
if (connection === 'close') {
if (lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut) start()
}
})
// Nomor HP format internasional tanpa +
if (!sock.authState.creds.registered) {
const code = await sock.requestPairingCode('628123456789')
console.log('Pairing code:', code)
}
// Custom pairing code (8 karakter)
const code = await sock.requestPairingCode('628123456789', 'NUYY2822')🌐 Browser Identity
const { Browsers } = require('@nuiisweety/baileys')
makeWASocket({
browser: Browsers.macOS('Chrome'), // Mac OS — Chrome
browser: Browsers.macOS('Firefox'), // Mac OS — Firefox
browser: Browsers.windows('Chrome'), // Windows — Chrome
browser: Browsers.ubuntu('Chrome'), // Ubuntu — Chrome
browser: Browsers.baileys('Chrome'), // Baileys — Chrome
browser: ['MyBot', 'Chrome', '1.0.0'] // custom
})⚙️ Opsi Koneksi
makeWASocket({
version,
auth: state,
printQRInTerminal: true,
browser: Browsers.macOS('Chrome'),
connectTimeoutMs: 20000,
keepAliveIntervalMs: 30000,
markOnlineOnConnect: true,
syncFullHistory: false,
generateHighQualityLinkPreview: false,
emitOwnEvents: true,
getMessage: async key => store?.messages?.[key.remoteJid]?.get(key.id)?.message
})📬 Terima Pesan
sock.ev.on('messages.upsert', async ({ messages, type }) => {
if (type !== 'notify') return
for (const m of messages) {
if (!m.message) continue
if (m.key.fromMe) continue
const jid = m.key.remoteJid
const isGroup = jid.endsWith('@g.us')
const sender = isGroup ? m.key.participant : jid
const text =
m.message.conversation ||
m.message.extendedTextMessage?.text ||
m.message.imageMessage?.caption ||
m.message.videoMessage?.caption || ''
await sock.readMessages([m.key])
await sock.sendPresenceUpdate('composing', jid)
}
})👥 Handle Grup
// Anggota masuk/keluar
sock.ev.on('group-participants.update', ({ id, participants, action }) => {
// action: 'add' | 'remove' | 'promote' | 'demote'
})
// Info grup diupdate
sock.ev.on('groups.update', updates => {})
// Metadata grup
const meta = await sock.groupMetadata(groupJid)
console.log(meta.subject, meta.participants)
// Semua grup
const groups = await sock.groupFetchAllParticipating()
// Tambah / keluarkan / promote / demote
await sock.groupParticipantsUpdate(groupJid, ['[email protected]'], 'add')
await sock.groupParticipantsUpdate(groupJid, ['[email protected]'], 'remove')
await sock.groupParticipantsUpdate(groupJid, ['[email protected]'], 'promote')
await sock.groupParticipantsUpdate(groupJid, ['[email protected]'], 'demote')
// Ubah nama / deskripsi
await sock.groupUpdateSubject(groupJid, 'Nama Baru')
await sock.groupUpdateDescription(groupJid, 'Deskripsi baru')
// Kunci / buka grup
await sock.groupSettingUpdate(groupJid, 'announcement')
await sock.groupSettingUpdate(groupJid, 'not_announcement')
// Mention semua anggota
const meta2 = await sock.groupMetadata(groupJid)
const members = meta2.participants.map(p => p.id)
await sock.sendMessage(groupJid, {
text: members.map(m => `@${m.split('@')[0]}`).join(' '),
mentions: members
})💬 Teks
await sock.sendMessage(jid, { text: 'Halo!' })
// Dengan mention
await sock.sendMessage(jid, {
text: '@628xxx halo!',
mentions: ['[email protected]']
}, { quoted: m })🖼️ Gambar
// URL
await sock.sendMessage(jid, {
image: { url: 'https://example.com/image.jpg' },
caption: 'Keterangan'
})
// Buffer
await sock.sendMessage(jid, {
image: fs.readFileSync('image.jpg'),
caption: 'Keterangan'
})🎬 Video
await sock.sendMessage(jid, {
video: { url: 'https://example.com/video.mp4' },
caption: 'Keterangan',
gifPlayback: false // true = GIF looping
})
// Video note (bubble)
await sock.sendMessage(jid, {
video: fs.readFileSync('video.mp4'),
ptv: true
})🎙️ Audio & Voice Note
// Audio biasa
await sock.sendMessage(jid, {
audio: { url: 'https://example.com/audio.mp3' },
mimetype: 'audio/mpeg'
})
// Voice note (PTT)
await sock.sendMessage(jid, {
audio: fs.readFileSync('voice.ogg'),
mimetype: 'audio/ogg; codecs=opus',
ptt: true
})📄 Dokumen
await sock.sendMessage(jid, {
document: fs.readFileSync('file.pdf'),
mimetype: 'application/pdf',
fileName: 'dokumen.pdf',
caption: 'File ini'
})🎴 Sticker
await sock.sendMessage(jid, { sticker: fs.readFileSync('sticker.webp') })📍 Lokasi
await sock.sendMessage(jid, {
location: {
degreesLatitude: -6.2088,
degreesLongitude: 106.8456,
name: 'Monas',
address: 'Jakarta Pusat'
}
})👤 Kontak
await sock.sendMessage(jid, {
contacts: {
displayName: 'Nama',
contacts: [{
vcard: 'BEGIN:VCARD\nVERSION:3.0\nFN:Nama\nTEL:+62812345678\nEND:VCARD'
}]
}
})❤️ Reaksi
await sock.sendMessage(jid, { react: { text: '❤️', key: m.key } })
// Hapus reaksi
await sock.sendMessage(jid, { react: { text: '', key: m.key } })📊 Poll
await sock.sendMessage(jid, {
poll: {
name: 'Pilih salah satu',
values: ['Opsi A', 'Opsi B', 'Opsi C'],
selectableCount: 1 // 0 = boleh pilih banyak
}
})
// Poll dengan fitur tambahan
await sock.sendMessage(jid, {
poll: {
name: 'Nama Poll',
values: ['Opsi A', 'Opsi B'],
selectableCount: 1,
endDate: new Date('2025-12-31'),
hideVoter: true,
canAddOption: false,
toAnnouncementGroup: false
}
})
// Quiz (Poll dengan jawaban benar)
await sock.sendMessage(jid, {
poll: {
name: 'Ibu kota Indonesia?',
values: ['Jakarta', 'Surabaya', 'Bandung'],
selectableCount: 1,
pollType: 1, // 1 = QUIZ
correctAnswer: 'Jakarta'
}
})📈 Poll Result
await sock.sendMessage(jid, {
pollResult: {
name: 'Nama Poll',
votes: [
{ name: 'Opsi A', voteCount: 10 },
{ name: 'Opsi B', voteCount: 5 }
],
pollType: 0 // 0 = POLL, 1 = QUIZ
}
})🔄 Poll Update
await sock.sendMessage(jid, {
pollUpdate: {
key: pollMessage.key,
vote: encryptedVotePayload,
metadata: optionalMetadata
}
})↗️ Forward
await sock.sendMessage(jid, {
forward: targetMessage,
force: true // paksa tampil sebagai forwarded
})🗑️ Hapus Pesan
await sock.sendMessage(jid, { delete: m.key })✏️ Edit Pesan
await sock.sendMessage(jid, {
text: 'Teks yang sudah diedit',
edit: m.key
})📌 Pin Pesan
// Pin
await sock.sendMessage(jid, {
pin: m.key,
type: 1,
time: 86400 // 86400=1hr | 604800=7hr | 2592000=30hr
})
// Unpin
await sock.sendMessage(jid, { pin: m.key, type: 2 })🗂️ Album
await sock.sendMessage(jid, {
album: [
{ image: { url: 'https://example.com/1.jpg' }, caption: 'Foto 1' },
{ image: { url: 'https://example.com/2.jpg' }, caption: 'Foto 2' },
{ video: { url: 'https://example.com/vid.mp4' }, caption: 'Video' }
]
})
// minimal 2 media📅 Event
await sock.sendMessage(jid, {
event: {
name: 'Nama Acara',
description: 'Deskripsi',
startDate: new Date('2025-12-01T10:00:00'),
endDate: new Date('2025-12-01T12:00:00'),
location: {
degreesLatitude: -6.2088,
degreesLongitude: 106.8456,
name: 'Monas, Jakarta'
},
extraGuestsAllowed: true
}
})
// Event dengan scheduled call
await sock.sendMessage(jid, {
event: {
name: 'Meeting Online',
startDate: new Date('2025-12-01T10:00:00'),
call: 'audio', // 'audio' | 'video'
isScheduleCall: true
}
})📖 Group Status / Group Story
// Teks
await sock.sendMessage(groupJid, {
groupStatusMessage: { text: 'Status teks' }
})
// Gambar
await sock.sendMessage(groupJid, {
groupStatusMessage: {
image: { url: 'https://example.com/image.jpg' },
caption: 'Keterangan'
}
})
// Video
await sock.sendMessage(groupJid, {
groupStatusMessage: {
video: { url: 'https://example.com/video.mp4' },
caption: 'Keterangan'
}
})
// Audio
await sock.sendMessage(groupJid, {
groupStatusMessage: {
audio: { url: 'https://example.com/audio.mp3' },
mimetype: 'audio/mpeg'
}
})
// Audio Voice Note (PTT)
await sock.sendMessage(groupJid, {
groupStatusMessage: {
audio: fs.readFileSync('voice.ogg'),
mimetype: 'audio/ogg; codecs=opus',
ptt: true
}
})Catatan audio: Saat audio dikirim sebagai group status (
groupStatusMessageV2), pesan dikirim dengantype="text"dan tanpamediatypeattribute — perilaku sama dengan Baileys upstream. Berbeda dengan media lain (gambar/video) yang dikirim dengantype="media".
🏷️ Status Mention
// Kirim ke array JID untuk trigger status mention
await sock.sendMessage(['[email protected]', '[email protected]'], {
text: 'Hei kamu!',
backgroundColor: '#ff6b9d'
})
// Gambar dengan mention
await sock.sendMessage(['[email protected]'], {
image: { url: 'https://example.com/image.jpg' },
caption: 'Untuk kamu'
})Untuk grup, otomatis pakai
groupStatusMentionMessage.
📡 Channel (Newsletter)
Fix v0.1.16 — Pengiriman media ke channel sebelumnya tidak berfungsi karena dua bug:
mediatypeattribute tidak dikirim ke server dan thumbnail tidak digenerate. Keduanya sudah diperbaiki di versi ini.
Hanya admin/owner channel yang bisa posting. JID channel menggunakan format
@newsletter.
const channelJid = '120363425154682710@newsletter'
// Teks
await sock.sendMessage(channelJid, { text: 'Halo dari channel!' })
// Gambar dari URL
await sock.sendMessage(channelJid, {
image: { url: 'https://example.com/image.jpg' },
caption: 'Keterangan gambar'
})
// Gambar dari file lokal
await sock.sendMessage(channelJid, {
image: { url: './gambar.jpg' },
caption: 'Dari file lokal'
})
// Gambar dari Buffer
await sock.sendMessage(channelJid, {
image: fs.readFileSync('gambar.jpg'),
caption: 'Dari buffer'
})
// Video
await sock.sendMessage(channelJid, {
video: { url: 'https://example.com/video.mp4' },
caption: 'Keterangan video'
})
// Audio
await sock.sendMessage(channelJid, {
audio: { url: 'https://example.com/audio.mp3' },
mimetype: 'audio/mpeg'
})
// Dokumen
await sock.sendMessage(channelJid, {
document: { url: 'https://example.com/file.pdf' },
mimetype: 'application/pdf',
fileName: 'dokumen.pdf'
})
// Poll
await sock.sendMessage(channelJid, {
poll: {
name: 'Pertanyaan untuk subscriber',
values: ['Opsi A', 'Opsi B', 'Opsi C'],
selectableCount: 1
}
})
// Edit pesan channel
await sock.sendMessage(channelJid, {
text: 'Teks yang sudah diedit',
edit: pesanLama.key
})
// Hapus pesan channel
await sock.sendMessage(channelJid, { delete: pesanLama.key })Catatan: Channel tidak mendukung enkripsi E2E — media di-upload sebagai file mentah (unencrypted), berbeda dengan chat biasa.
🔁 Flow Reply
await sock.sendMessage(jid, {
flowReply: {
name: 'quick_reply',
paramsJson: '{"id":"btn1"}',
text: 'Teks balasan',
format: 1,
version: 1
}
})🔘 Button Reply
// Template button
await sock.sendMessage(jid, {
buttonReply: { displayText: 'Opsi yang dipilih', id: 'btn_id', index: 0 },
type: 'template'
})
// Plain button
await sock.sendMessage(jid, {
buttonReply: { displayText: 'Opsi yang dipilih', id: 'btn_id' },
type: 'plain'
})📎 Keep In Chat
await sock.sendMessage(jid, {
keep: m.key,
keepType: 1 // 1 = keep, 2 = unkeep
})📞 Scheduled Call
await sock.sendMessage(jid, {
call: {
time: Date.now() + 3600000,
type: 1, // 1 = voice, 2 = video
title: 'Meeting'
}
})🔗 Group Invite
await sock.sendMessage(jid, {
groupInvite: {
jid: '[email protected]',
inviteCode: 'kode',
inviteExpiration: Date.now() + 86400000,
subject: 'Nama Grup',
text: 'Bergabunglah bersama kami'
}
})🛍️ Product
await sock.sendMessage(jid, {
product: {
productImage: fs.readFileSync('produk.jpg'),
productId: 'prod_123',
title: 'Nama Produk',
description: 'Deskripsi produk',
currencyCode: 'IDR',
priceAmount1000: 50000000,
retailerId: 'sku_001',
url: 'https://toko.example.com/produk'
},
businessOwnerJid: '[email protected]' // wajib diisi
})👁️ View Once
await sock.sendMessage(jid, {
image: { url: 'https://example.com/image.jpg' },
viewOnce: true
})👁️ View Once V2
await sock.sendMessage(jid, {
image: { url: 'https://example.com/image.jpg' },
viewOnceV2: true
})
// viewOnceV2Extension
await sock.sendMessage(jid, {
image: { url: 'https://example.com/image.jpg' },
viewOnceV2Extension: true
})⏳ Ephemeral
await sock.sendMessage(jid, {
text: 'Pesan ini ephemeral',
ephemeral: true
})🙈 Spoiler
await sock.sendMessage(jid, {
image: { url: 'https://example.com/image.jpg' },
caption: 'Spoiler!',
spoiler: true
})🎭 Group Status Wrap
Wrapper groupStatus: true membungkus pesan apapun ke dalam groupStatusMessageV2 secara otomatis.
// Teks
await sock.sendMessage(jid, {
text: 'Status di grup ini',
groupStatus: true
})
// Gambar
await sock.sendMessage(jid, {
image: { url: 'https://example.com/image.jpg' },
caption: 'Keterangan',
groupStatus: true
})
// Audio
await sock.sendMessage(jid, {
audio: { url: 'https://example.com/audio.mp3' },
mimetype: 'audio/mpeg',
groupStatus: true
})Catatan audio: Pesan audio yang dibungkus
groupStatus: truedikirim dengantype="text"dan tanpamediatype(perilaku Baileys upstream). Ini hanya berlaku untuk audio — gambar dan video tetap dikirim sebagaitype="media".
🎞️ Lottie Sticker
await sock.sendMessage(jid, {
sticker: fs.readFileSync('sticker.webp'),
isLottie: true
})🤖 AI Icon
// Hanya untuk private chat (bukan grup)
await sock.sendMessage(jid, { text: 'Respons dari AI', ai: true })
await sock.sendMessage(jid, {
image: { url: 'https://example.com/image.jpg' },
caption: 'Dihasilkan oleh AI',
ai: true
})🔒 Secure Meta Service Label
await sock.sendMessage(jid, {
text: 'Pesan layanan resmi',
secureMetaServiceLabel: true
})📍 Buttons dengan Location Header
Kirim tombol menggunakan buttonsMessage secara langsung — berguna untuk header tipe Location (headerType: 6) yang tidak bisa dibuat lewat shorthand buttons.
// Tombol dengan header lokasi (headerType 6)
await sock.sendMessage(jid, {
buttonsMessage: {
locationMessage: {
degreesLatitude: 0,
degreesLongitude: 0,
name: 'NuiiSweety',
address: 'NuiiSweety Bot',
jpegThumbnail: './src/img/menu.jpg' // path file, URL, atau Buffer
},
contentText: 'Pilih menu di bawah ini',
footerText: 'Powered by @nuiisweety/baileys',
buttons: [
{ buttonId: 'allmenu', buttonText: { displayText: 'All Menu' }, type: 1 }
],
headerType: 6
}
})
// Header kosong (teks saja) — headerType 1
await sock.sendMessage(jid, {
buttonsMessage: {
contentText: 'Pilih opsi',
footerText: 'Bot Footer',
buttons: [
{ buttonId: 'yes', buttonText: { displayText: 'Ya' }, type: 1 },
{ buttonId: 'no', buttonText: { displayText: 'Tidak' }, type: 1 }
],
headerType: 1
}
})Nilai headerType:
| Nilai | Tipe Header |
|:-----:|-------------|
| 1 | Teks (contentText) |
| 2 | Gambar (imageMessage) |
| 3 | Video (videoMessage) |
| 4 | Dokumen (documentMessage) |
| 6 | Lokasi (locationMessage) |
jpegThumbnailpadalocationMessagebisa berupa path file lokal, URL, atau Buffer — otomatis diproses oleh Baileys.
🎛️ Buttons
// Teks dengan tombol (quick reply)
await sock.sendMessage(jid, {
text: 'Pilih salah satu',
footer: 'Footer pesan',
buttons: [
{ id: 'btn1', text: 'Tombol 1' },
{ id: 'btn2', text: 'Tombol 2' },
{ id: 'btn3', text: 'Tombol 3' }
]
})
// Gambar sebagai header
await sock.sendMessage(jid, {
image: { url: 'https://example.com/image.jpg' },
caption: 'Isi pesan',
footer: 'Footer',
buttons: [
{ id: 'btn1', text: 'Pilih A' },
{ id: 'btn2', text: 'Pilih B' }
]
})
// Shorthand: sections langsung di button (otomatis jadi single_select)
await sock.sendMessage(jid, {
text: 'Pilih menu',
buttons: [{
text: 'Buka Menu',
sections: [{
title: 'Kategori A',
rows: [
{ id: 'row1', title: 'Item 1', description: 'Deskripsi' },
{ id: 'row2', title: 'Item 2' }
]
}]
}]
})Field tombol: gunakan
textataubuttonTextuntuk label. Quick reply pakaiid/buttonId. Native flow pakainame+paramsJson.
📋 List Message
await sock.sendMessage(jid, {
text: 'Silakan pilih', // → description (isi pesan)
title: 'Judul List', // → title (judul di atas list)
buttonText: 'Buka Daftar', // → teks tombol pembuka
footer: 'Footer pesan', // → footerText
sections: [
{
title: 'Bagian 1',
rows: [
{ id: 'row1', title: 'Pilihan A', description: 'Deskripsi A' },
{ id: 'row2', title: 'Pilihan B', description: 'Deskripsi B' }
]
},
{
title: 'Bagian 2',
rows: [
{ id: 'row3', title: 'Pilihan C' }
]
}
]
})Trigger key:
sections.listTypeotomatis di-set keSINGLE_SELECT. Fieldtextdi-map kedescription— gunakantitleuntuk judul list.
🗃️ Template Buttons
// Teks
await sock.sendMessage(jid, {
text: 'Pesan template',
footer: 'Footer',
id: 'template-unik', // opsional, auto-generate jika tidak diisi
templateButtons: [
{ id: 'btn1', text: 'Quick Reply' },
{ url: 'https://example.com', text: 'Kunjungi Website' },
{ call: '+62812345678', text: 'Hubungi Kami' }
]
})
// Gambar sebagai header
await sock.sendMessage(jid, {
image: { url: 'https://example.com/img.jpg' },
caption: 'Isi pesan',
title: 'Judul',
footer: 'Footer',
templateButtons: [
{ id: 'btn1', text: 'Klik Sini' },
{ url: 'https://example.com', text: 'Buka Link' }
]
})Tipe tombol:
{ id, text }→ quick reply ·{ url, text }→ URL button ·{ call, text }→ call button.
🌊 Native Flow
// Quick reply
await sock.sendMessage(jid, {
text: 'Pilih aksi',
footer: 'Footer pesan',
nativeFlow: [
{ id: '1', text: 'Opsi 1' },
{ id: '2', text: 'Opsi 2' }
]
})
// URL button
await sock.sendMessage(jid, {
text: 'Kunjungi kami',
nativeFlow: [
{ url: 'https://example.com', text: 'Buka Website' }
]
})
// Copy code button
await sock.sendMessage(jid, {
text: 'Kode promo kamu',
nativeFlow: [
{ copy: 'PROMO2025', text: 'Salin Kode' }
]
})
// Call button
await sock.sendMessage(jid, {
text: 'Hubungi kami',
nativeFlow: [
{ call: '+62812345678', text: 'Telepon Sekarang' }
]
})
// Single select (list dalam button)
await sock.sendMessage(jid, {
text: 'Pilih menu',
nativeFlow: [
{
sections: [{
title: 'Kategori A',
rows: [
{ id: 'row1', title: 'Item 1', description: 'Deskripsi' },
{ id: 'row2', title: 'Item 2' }
]
}],
text: 'Buka Daftar'
}
]
})
// Gambar sebagai header
await sock.sendMessage(jid, {
image: { url: 'https://example.com/img.jpg' },
caption: 'Isi pesan',
title: 'Judul',
subtitle: 'Subjudul',
footer: 'Footer',
nativeFlow: [
{ id: '1', text: 'Tombol 1' }
]
})
// offerText — limited time offer banner
await sock.sendMessage(jid, {
text: 'Penawaran terbatas!',
offerText: 'Diskon 50%',
offerUrl: 'https://example.com/promo',
offerCode: 'DISKON50',
offerExpiration: 1800000000,
nativeFlow: [
{ id: 'claim', text: 'Klaim Sekarang' }
]
})
// optionText — tombol masuk ke bottom sheet
await sock.sendMessage(jid, {
text: 'Pilih opsi',
optionText: 'Lihat Semua Opsi',
optionTitle: 'Daftar Pilihan',
nativeFlow: [
{ id: '1', text: 'Opsi A' },
{ id: '2', text: 'Opsi B' }
]
})Tipe tombol ditentukan otomatis:
id→ quick_reply ·url→ cta_url ·copy→ cta_copy ·call→ cta_call ·sections→ single_select. Fieldiconopsional (contoh:'CHECK','LINK').
🎠 Carousel
await sock.sendMessage(jid, {
text: 'Carousel utama',
footer: 'Footer utama',
cards: [
{
image: { url: 'https://example.com/1.jpg' },
title: 'Kartu 1',
caption: 'Deskripsi kartu 1',
footer: 'Footer kartu 1',
nativeFlow: [
{ name: 'quick_reply', paramsJson: '{"id":"c1"}', text: 'Pilih Ini' }
]
},
{
image: { url: 'https://example.com/2.jpg' },
title: 'Kartu 2',
caption: 'Deskripsi kartu 2',
nativeFlow: [
{ name: 'quick_reply', paramsJson: '{"id":"c2"}', text: 'Pilih Itu' }
]
}
]
})🤖 Rich Message (AI)
Rich message menggunakan format
AIRichResponseMessageyang tampil seperti respons AI di WhatsApp. Semua tipe bisa dipakai secara flat (field langsung) atau dikombinasikan viarichResponse: [...].
⚠️ Penting:
contentText,headerText,footerText, dandisclaimerTextbukan trigger key. Jika hanya field itu yang dikirim, pesan tidak akan diproses sebagai rich message dan menghasilkan Error: Invalid media type. Selalu sertakan minimal satu trigger key (code,table,richImage,richVideo,richResponse, dll).
✍️ addText
// ✅ Cara benar — pakai richResponse array untuk teks murni
await sock.sendMessage(jid, {
richResponse: [
{ text: 'Ini teks dari AI dengan *markdown* dan **bold**.' }
],
headerText: 'Judul',
footerText: 'Footer',
disclaimerText: 'Generated by AI'
})// ❌ SALAH — contentText saja tidak trigger rich message
await sock.sendMessage(jid, {
contentText: 'halooo',
headerText: 'Judul'
// → Error: Invalid media type
})💻 addCode
await sock.sendMessage(jid, {
code: 'console.log("Hello World!")',
language: 'javascript', // default: 'javascript'
headerText: 'Contoh kode:',
footerText: 'Semoga membantu',
disclaimerText: 'Generated by AI'
})Bahasa yang didukung:
| Bahasa | Key |
|--------|-----|
| JavaScript | javascript, js |
| TypeScript | typescript, ts |
| Python | python, py |
| Go | go, golang |
| C++ | cpp, c++ |
| Rust | rust, rs |
| Java | java |
| PHP | php |
| Ruby | ruby, rb |
| Kotlin | kotlin, kt |
| Swift | swift |
| C | c |
| SQL/MySQL/PostgreSQL | sql, mysql, postgresql, sqlite |
| Bash/Shell | bash, sh, shell |
| HTML | html |
| CSS | css |
| JSON | json |
| YAML | yaml, yml |
📊 addTable
await sock.sendMessage(jid, {
table: [
['Nama', 'Usia', 'Kota'], // baris pertama = header
['Hana', '20', 'Jakarta'],
['Risa', '22', 'Bandung'],
['Yuki', '21', 'Surabaya']
],
title: 'Data Anggota',
headerText: 'Berikut datanya',
footerText: 'Data per Juni 2025'
})
// Tanpa baris header
await sock.sendMessage(jid, {
table: [
['Item A', 'Rp 10.000'],
['Item B', 'Rp 20.000']
],
noHeading: true,
title: 'Daftar Harga'
})🖼️ addImage
// Satu gambar
await sock.sendMessage(jid, {
richImage: 'https://example.com/photo.jpg',
headerText: 'Gambar untuk kamu'
})
// Beberapa gambar (grid)
await sock.sendMessage(jid, {
richImage: [
'https://example.com/photo1.jpg',
'https://example.com/photo2.jpg',
'https://example.com/photo3.jpg'
],
headerText: 'Koleksi gambar'
})🎬 addVideo
// Satu video
await sock.sendMessage(jid, {
richVideo: 'https://example.com/video.mp4',
headerText: 'Video untuk kamu'
})
// Dengan durasi (format: 'url|durasi_detik')
await sock.sendMessage(jid, {
richVideo: 'https://example.com/video.mp4|120',
headerText: 'Video berdurasi 2 menit'
})
// Beberapa video
await sock.sendMessage(jid, {
richVideo: [
'https://example.com/video1.mp4|60',
'https://example.com/video2.mp4|90'
],
headerText: 'Playlist video'
})🔗 addSource
await sock.sendMessage(jid, {
source: [
{
url: 'https://example.com/artikel',
title: 'Judul Artikel',
display_name: 'Example.com',
subtitle: 'Sumber terpercaya',
favicon: 'https://example.com/favicon.ico'
},
{
url: 'https://docs.example.com/api',
title: 'Dokumentasi API',
display_name: 'Docs',
subtitle: 'Referensi lengkap'
}
],
headerText: 'Sumber referensi'
})| Field | Tipe | Keterangan |
|-------|------|------------|
| url | string | URL tujuan (wajib) |
| title | string | Judul sumber |
| display_name | string | Nama tampilan |
| subtitle | string | Subjudul/deskripsi singkat |
| favicon | string | URL favicon (opsional) |
| source_type | string | Default 'THIRD_PARTY' |
🎥 addReels
await sock.sendMessage(jid, {
reels: [
{
username: 'creator1',
videoUrl: 'https://example.com/reel1.mp4',
thumbnailUrl: 'https://example.com/thumb1.jpg',
profileIconUrl: 'https://example.com/avatar1.jpg',
reels_title: 'Judul Reel 1',
likes_count: 1200,
view_count: 50000,
reel_source: 'IG',
is_verified: true
}
],
headerText: 'Rekomendasi video'
})| Field | Tipe | Keterangan |
|-------|------|------------|
| username / title | string | Nama kreator |
| videoUrl / url | string | URL video |
| thumbnailUrl / thumbnail | string | URL thumbnail |
| profileIconUrl / profile_url | string | URL foto profil |
| reels_title | string | Judul reel |
| likes_count / like | number | Jumlah like |
| view_count / view | number | Jumlah views |
| reel_source / source | string | 'IG', 'TT', dll |
| is_verified / verified | boolean | Akun terverifikasi |
🛍️ addProduct
// Satu produk (Single layout)
await sock.sendMessage(jid, {
richProduct: {
title: 'Nama Produk',
brand: 'Nama Brand',
price: 'Rp 150.000',
sale_price: 'Rp 120.000',
product_url: 'https://toko.example.com/produk',
image_url: 'https://example.com/produk.jpg'
},
headerText: 'Rekomendasi produk untukmu'
})
// Beberapa produk (HScroll layout)
await sock.sendMessage(jid, {
richProduct: [
{
title: 'Produk A',
price: 'Rp 50.000',
product_url: 'https://toko.example.com/a',
image_url: 'https://example.com/a.jpg'
},
{
title: 'Produk B',
price: 'Rp 75.000',
sale_price: 'Rp 60.000',
product_url: 'https://toko.example.com/b',
image_url: 'https://example.com/b.jpg'
}
],
headerText: 'Produk pilihan hari ini'
})Object tunggal → Single layout · Array → HScroll layout
📝 addPost
// Satu post
await sock.sendMessage(jid, {
richPost: {
username: 'namauser',
profile_picture_url: 'https://example.com/avatar.jpg',
is_verified: true,
thumbnail_url: 'https://example.com/thumb.jpg',
post_caption: 'Caption post ini',
likes_count: 5000,
post_url: 'https://instagram.com/p/xxx',
source_app: 'INSTAGRAM',
orientation: 'LANDSCAPE'
},
headerText: 'Post terpopuler'
})
// Beberapa post (carousel horizontal)
await sock.sendMessage(jid, {
richPost: [
{
username: 'user1',
thumbnail_url: 'https://example.com/thumb1.jpg',
likes_count: 3000,
post_url: 'https://instagram.com/p/aaa',
source_app: 'INSTAGRAM'
},
{
username: 'user2',
thumbnail_url: 'https://example.com/thumb2.jpg',
likes_count: 1500,
post_url: 'https://tiktok.com/@user2/video/yyy',
source_app: 'TIKTOK'
}
],
headerText: 'Post trending hari ini'
})💡 addTip
await sock.sendMessage(jid, {
tip: 'Informasi ini dibuat oleh AI berdasarkan data terbaru.',
headerText: 'Ringkasan'
})🔮 addSuggest
// Beberapa saran (tampil sebagai pill button)
await sock.sendMessage(jid, {
contentText: 'Apakah ada yang ingin kamu tanyakan?',
suggest: [
'Contoh kodenya?',
'Apa perbedaannya?',
'Kapan sebaiknya digunakan?',
'Ada alternatif lain?'
]
})🗺️ Map (Rich)
await sock.sendMessage(jid, {
map: {
centerLatitude: -6.2088,
centerLongitude: 106.8456,
latitudeDelta: 0.05,
longitudeDelta: 0.05,
showInfoList: true,
annotations: [
{
number: 1,
latitude: -6.2088,
longitude: 106.8456,
title: 'Jakarta Pusat',
body: 'Ibu kota Indonesia'
}
]
},
headerText: 'Lokasi yang kamu cari'
})🧮 LaTeX (Rich)
urldi setiap expression akan otomatis di-generate dari latex.codecogs.com jika tidak diisi.
await sock.sendMessage(jid, {
latex: {
text: 'Rumus-rumus fisika dasar:',
expressions: [
{ expression: 'F = ma', width: 80, height: 35 },
{ expression: 'v = u + at', width: 100, height: 35 },
{ expression: 's = ut + \\frac{1}{2}at^2', width: 160, height: 50 }
]
},
headerText: 'Hukum Newton'
})🖼️ Grid Image (Rich)
await sock.sendMessage(jid, {
gridImage: {
gridImageUrl: 'https://picsum.photos/id/10/300/300',
imageUrls: ['https://picsum.photos/id/11/300/300']
},
headerText: 'Hasil pencarian gambar'
})📸 Inline Image (Rich)
await sock.sendMessage(jid, {
inlineImage: {
imageUrl: 'https://picsum.photos/id/237/300/300',
imageText: 'Ilustrasi gambar',
alignment: 2, // 0 = leading, 1 = trailing, 2 = center
tapLinkUrl: 'https://picsum.photos'
},
headerText: 'Berikut ilustrasinya'
})🎞️ Dynamic / GIF (Rich)
await sock.sendMessage(jid, {
dynamic: {
url: 'https://example.com/animation.gif',
type: 2, // 1 = IMAGE, 2 = GIF
version: 1,
loopCount: 0 // 0 = loop selamanya
},
headerText: 'Animasi untuk kamu'
})📦 Content Items (Rich)
await sock.sendMessage(jid, {
contentItems: {
contentType: 1, // 0 = DEFAULT, 1 = CAROUSEL
items: [
{
kind: 'reel',
title: 'Tutorial Coding JavaScript',
profileIconUrl: 'https://example.com/avatar1.jpg',
thumbnailUrl: 'https://example.com/thumb1.jpg',
videoUrl: 'https://example.com/video1.mp4'
}
]
},
headerText: 'Rekomendasi video'
})🎁 Rich Response (Gabungan)
await sock.sendMessage(jid, {
richResponse: [
{ text: 'Penjelasan singkat:' },
{ code: 'const x = 1 + 1', language: 'javascript' },
{
table: [['Kolom A', 'Kolom B'], ['Nilai 1', 'Nilai 2']],
title: 'Hasil'
},
{ richImage: ['https://example.com/img1.jpg', 'https://example.com/img2.jpg'] },
{ source: [{ url: 'https://example.com', title: 'Sumber Data' }] },
{ tip: 'Informasi ini dihasilkan secara otomatis.' },
{ suggest: ['Tanya lebih lanjut', 'Lihat contoh lain'] }
],
disclaimerText: 'Generated by AI'
})📥 Terima & Decode Rich Message
const { normalizeMessageContent, parseRichMessage } = require('@nuiisweety/baileys')
sock.ev.on('messages.upsert', async ({ messages }) => {
for (const msg of messages) {
const inner = normalizeMessageContent(msg.message)
const parsed = parseRichMessage(inner?.richResponseMessage)
if (!parsed) continue
for (const sub of parsed.submessages) {
switch (sub.type) {
case 'text': console.log('Teks:', sub.text); break
case 'code': console.log('Kode:', sub.language, sub.raw); break
case 'table': console.log('Tabel:', sub.title, sub.rows); break
case 'gridImage': console.log('Grid Image:', sub.gridImageUrl); break
case 'inlineImage': console.log('Inline Image:', sub.imageUrl); break
case 'dynamic': console.log('Dynamic:', sub.url); break
case 'map': console.log('Map:', sub.centerLatitude, sub.centerLongitude); break
case 'latex': console.log('LaTeX:', sub.expressions); break
case 'contentItems': console.log('Content Items:', sub.items); break
}
}
}
})
parseRichMessagemenerimanullatauundefineddengan aman — returnnulljika tidak ada rich message.
Standalone Functions
// sendLatex
await sock.sendLatex(jid, m, {
text: 'Rumus Pythagoras:',
expressions: [
{ latexExpression: 'a^2 + b^2 = c^2', width: 150, height: 45 }
],
headerText: 'Matematika'
})
// sendTable
await sock.sendTable(jid, 'Data Kota', ['Kota', 'Populasi'], [['Jakarta', '10jt'], ['Surabaya', '3jt']], m)
// sendList
await sock.sendList(jid, 'Daftar Belanja', ['Apel', 'Jeruk', 'Mangga'], m)
// sendCodeBlock
await sock.sendCodeBlock(jid, 'console.log("Hello")', m, { language: 'javascript', title: 'Contoh JS' })
// sendLink
await sock.sendLink(jid, 'Kunjungi dokumentasi', [{ url: 'https://docs.example.com', displayName: 'Docs' }], m)
// sendRichMessage
await sock.sendRichMessage(jid, [
{ messageType: 2, messageText: 'Teks pertama' },
{ messageType: 2, messageText: 'Teks kedua' }
], m)📃 List Reply
await sock.sendMessage(jid, {
listReply: {
title: 'Pilihan Saya',
description: 'Deskripsi pilihan',
id: 'row1' // selectedRowId dari baris yang dipilih
}
})🎴 Sticker Pack
await sock.sendMessage(jid, {
cover: fs.readFileSync('cover.webp'), // wajib
name: 'Pack Manis',
publisher: 'NuiiS4TORU',
description: 'Sticker pack cantik',
stickers: [
{
data: fs.readFileSync('sticker1.webp'),
emojis: ['🌸', '💕'],
accessibilityLabel: 'stiker manis'
},
{
data: { url: 'https://example.com/sticker2.webp' },
emojis: ['🌷']
}
// maksimal 60 sticker
]
})📢 External Ad Reply
await sock.sendMessage(jid, {
text: 'Cek produk ini',
externalAdReply: {
title: 'Judul Iklan',
body: 'Deskripsi iklan',
thumbnail: fs.readFileSync('thumbnail.jpg'), // harus Buffer
url: 'https://example.com/produk',
mediaType: 1,
largeThumbnail: false
}
})💳 Request Payment
await sock.sendMessage(jid, {
text: 'Tolong transfer ya',
requestPaymentFrom: '[email protected]',
amount1000: 50000000, // Rp 50.000 (unit 1/1000)
currencyCodeIso4217: 'IDR',
expiryTimestamp: Date.now() + 86400000
})🧾 Invoice
// Dengan gambar
await sock.sendMessage(jid, {
image: fs.readFileSync('invoice.jpg'),
invoiceNote: 'Invoice pembelian\nTotal: Rp 150.000'
})
// Dengan PDF
await sock.sendMessage(jid, {
document: fs.readFileSync('invoice.pdf'),
mimetype: 'application/pdf',
fileName: 'invoice.pdf',
invoiceNote: 'Terima kasih atas pesananmu'
})📦 Order
await sock.sendMessage(jid, {
order: {
orderId: 'order_001',
thumbnail: fs.readFileSync('produk.jpg'), // wajib
itemCount: 3,
status: 'PAYMENT_PENDING',
surface: 'CATALOG',
message: 'Pesanan kamu sedang diproses',
orderTitle: 'Pesanan #001',
sellerJid: '[email protected]',
token: 'token_unik',
totalAmount1000: 150000000,
totalCurrencyCode: 'IDR'
}
})💨 Disappearing Messages
// Aktifkan (default 86400 detik = 24 jam)
await sock.sendMessage(groupJid, { disappearingMessagesInChat: true })
// Nonaktifkan
await sock.sendMessage(groupJid, { disappearingMessagesInChat: false })
// Durasi kustom (detik)
await sock.sendMessage(groupJid, { disappearingMessagesInChat: 604800 }) // 7 hariHanya berfungsi di grup (
@g.us).
⚡ Raw Message
await sock.sendMessage(jid, {
raw: true,
extendedTextMessage: {
text: 'Pesan raw langsung ke proto'
}
})Ketika
raw: trueada, semua properti lain diteruskan langsung sebagai WAProto message tanpa pemrosesan tambahan.
