@isaxn/bailyes
v2.2.0
Published
WhatsApp Bot Framework built on Baileys, with QR and pairing code login, a built-in contact/chat/message store, and a modular interactive message builder (Button, ButtonV2, Carousel, AIRich).
Maintainers
Readme
@isaxn/bailyes
Framework WhatsApp bot berbasis [email protected], dengan:
- Login QR dan pairing code
- Auto-reconnect yang tidak kehilangan event setelah socket diganti
Storebawaan (kontak, chat, pesan, metadata grup) — penggantimakeInMemoryStoreyang sudah dihapus dari Baileys- Cara panggil simpel satu-fungsi lewat
bx(bx.button,bx.list,bx.card,bx.rich,bx.richText,bx.livePhoto,bx.liveThumbnail,bx.linkPreview) - 100% bisa dipakai lewat
require(...), tidak perlu ESM
Instalasi
Gunakan Node.js 20 atau lebih baru.
npm install @isaxn/bailyes sharpPaket ini memuat [email protected] secara dinamis di dalam. Baileys 7
menggunakan ESM, tetapi aplikasi bot tetap dapat memakai
require("@isaxn/bailyes") seperti biasa.
const bailyes = require("@isaxn/bailyes");
const { Bailyes, bx, Store } = bailyes;Quick start — bot sederhana
const { Bailyes } = require("@isaxn/bailyes");
const bot = new Bailyes({
auth: "auth",
prefix: ["!", "."]
});
bot.command("ping", async (ctx) => {
await ctx.reply("pong");
});
bot.onFramework("ready", () => console.log("Bot connected"));
bot.start();Menjalankan node bot.js akan menampilkan QR code di terminal secara default.
Login dengan pairing code
const bot = new Bailyes({
auth: "auth",
pairingCode: true,
phoneNumber: "6281234567890"
});
bot.onFramework("pairing-code", (code) => {
console.log("Masukkan kode ini di WhatsApp:", code);
});
bot.start();Referensi semua fungsi
Bailyes — class utama bot
new Bailyes(options)| Opsi | Default | Keterangan |
|---|---|---|
| auth | "auth" | folder penyimpanan sesi login |
| prefix | ["!"] | array prefix command |
| cooldown | 0 | jeda antar pesan per-chat (ms), 0 = nonaktif |
| pairingCode | false | pakai kode pairing, bukan QR |
| phoneNumber | null | wajib diisi kalau pairingCode: true |
| store | {} | opsi Store, atau false untuk matikan |
| reconnectDelay | 3000 | delay dasar reconnect (ms) |
| maxReconnectDelay | 30000 | batas atas delay reconnect (ms) |
| maxReconnectAttempts | 0 | 0 = tidak dibatasi |
Method:
bot.on(event, fn)— dengarkan event mentah dari Baileys (messages.upsert,chats.update, dst)bot.onFramework(event, fn)— dengarkan event framework:ready,qr,pairing-code,close,logged-out,error,messagebot.command(name | [names], fn)— daftarkan commandbot.action(id | [ids], fn)— tangani ID balasan daribx.button,bx.list, atau tombol reply padabx.cardbot.hear(stringOrRegex, fn)— respons tanpa prefixbot.start()— mulai koneksi, returnsockbot.stop()— putus koneksi & hentikan autosaveStorebot.store— getter ke instanceStoreyang aktifbot.sock— instance socket Baileys aktif setelahready
bx — pemanggilan cepat satu fungsi
bx.button(sock, jid, { title, subtitle, body, footer, thumbnail, media, buttons, contextInfo, options })— Button V2 berbasisbuttonsMessage;thumbnailditempatkan melalui headerlocationMessagebx.list(sock, jid, { title, body, footer, sections: [{ title, highlight, rows: [{ header, title, description, id }] }], contextInfo, options })bx.card(sock, jid, { body, footer, cards: [{ title, subtitle, body, footer, image, video, buttons: [{ type: "url"|"call"|"copy"|"reply", text, value }] }], contextInfo, options })bx.rich(sock, jid, { title, text, code: { language, content }, table, tip, options })— pesan AIRich asli dari protokol Baileys 7bx.richText(sock, jid, { title, text, code: { language, content }, table, tip, options })— fallback teks WhatsApp standarbx.linkPreview(sock, jid, { text, link, title, description, thumbnail, options })bx.livePhoto(sock, jid, { image, video, options })— kirim gambar yang otomatis "hidup" jadi video singkat saat ditekan, mirip Live Photo di iPhonebx.liveThumbnail(sock, jid, { key, text, link, title, description, images: [...], size, interval, loops, quality })— edit pesan berulang dengan thumbnail link-preview yang berganti-ganti
Contoh mengirim tombol:
const { bx } = require("@isaxn/bailyes");
await bx.button(bot.sock, "[email protected]", {
title: "Menu",
subtitle: "Pilih layanan",
body: "Silakan pilih:",
footer: "Isaxn Bailyes",
thumbnail: "https://picsum.photos/seed/menu/600/600",
buttons: [
{ type: "reply", text: "Cek profil", id: "profile" },
{ type: "reply", text: "Bantuan", id: "help" }
]
});buttons wajib berupa array. Jika type tidak ditulis, tombol dianggap sebagai
reply, sehingga format ringkas { text, id } tetap dapat digunakan.
thumbnail bukan tombol lokasi. Gambar tersebut dibungkus sebagai
buttonsMessage.locationMessage.jpegThumbnail dengan title sebagai name
dan subtitle sebagai address.
Contoh bx.rich():
await bx.rich(ctx.sock, ctx.chat, {
title: "Asisten",
text: "Ini contoh pesan yang pasti tampil di WhatsApp.",
code: {
language: "javascript",
content: "console.log('halo dari bailyes')"
},
table: [
["Menu", "Status"],
["Ping", "Aktif"],
["Profil", "Aktif"]
],
tip: "Ketik !menu untuk melihat semua perintah",
options: { quoted: ctx.msg }
});bx.rich() memakai richResponseMessage yang sudah tersedia di protokol
Baileys 7 RC13. Untuk fallback teks WhatsApp standar, gunakan bx.richText()
dengan objek konfigurasi yang sama.
Contoh mengirim tombol dari dalam command:
bot.command("menu", async (ctx) => {
await bx.button(ctx.sock, ctx.chat, {
title: "Menu Bot",
subtitle: "Pilih layanan",
body: "Pilih menu:",
thumbnail: "https://picsum.photos/seed/menu-bot/600/600",
buttons: [
{ type: "reply", text: "Produk", id: "products" },
{ type: "reply", text: "Kontak", id: "contact" }
],
options: { quoted: ctx.msg }
});
});
bot.action("products", async (ctx) => {
await ctx.reply("Kamu memilih Produk");
});
bot.action("contact", async (ctx) => {
await ctx.reply("Kamu memilih Kontak");
});
ID pada buttons, rows, dan tombol bertipe reply akan masuk ke ctx.action.
Daftarkan ID tersebut menggunakan bot.action(id, handler). Respons interaktif lama
yang dikirim sebagai buttonsResponseMessage, templateButtonReplyMessage, atau
listResponseMessage, serta respons native-flow dari button/list/card, semuanya dibaca.
AIRich — rich response ala AI
const { AIRich } = require("@isaxn/bailyes");
bot.command("airich", async (ctx) => {
const msg = new AIRich(ctx.sock)
.addText("Fiora Sylvie")
.addCode("javascript", 'console.log("Hello World")')
.addTable([
["Nama", "Umur"],
["Fiora", "20"],
["Sylvie", "21"]
]);
await msg.send(ctx.chat, { quoted: ctx.msg });
});Builder juga menyediakan .setTitle(), .setFooter(), .setContextInfo(),
.addSource(), .addReels(), .addImage(), .addVideo(), .addProduct(),
.addPost(), .addTip(), .addSuggest(), .addSubmessage(),
.addSection(), .build(), dan .send().
Toolkit — util media (static, tidak perlu instance)
Toolkit.extractIE(text, opts)— parser[teks](url)untuk tautan/sitasi/latexToolkit.waitAllPromises(input)— resolve semua Promise bersarang di dalam objek/arrayToolkit.resize(buffer, x, y, fit?)— resize gambar pakaisharpToolkit.fetchBuffer(url, fetchOpts?, { silent })— unduh jadiBufferToolkit.toUrl(sock, buffer|url, mediaType)— upload ke server WA, hasil URLToolkit.resolveMedia(sock, media, mediaType, opts)— serba-bisa: url/buffer/base64 -> url/buffer/base64Toolkit.getMp4Duration(buffer, { silent })— durasi video dari buffer mp4Toolkit.getMp4Preview(buffer, { time, result, resize, width, height, silent })— screenshot frame video jadi gambar
Store — memory kontak, chat, pesan
new Store({ file, autosaveInterval, maxMessagesPerChat })store.bind(ev)— dipanggil otomatis olehWAClient/Bailyesstore.getName(jid)— nama kontak (fallback ke nomor)store.getContact(jid)/store.getChat(jid)/store.getGroupMetadata(jid)store.loadMessage(jid, id)— ambil pesan lama dari memory (berguna untuk quoted/anti-delete)store.upsertContact(obj)/store.upsertChat(obj)/store.upsertMessage(msg)/store.upsertGroupMetadata(obj)store.toJSON()/store.fromJSON(data)store.writeToFile(path?)/store.readFromFile(path?)store.stop()— hentikan autosave
Context (ctx) — wrapper pesan masuk di dalam bot.command()/bot.hear()
Properti: ctx.sock, ctx.msg, ctx.chat, ctx.sender, ctx.isGroup, ctx.isLid, ctx.fromMe, ctx.text, ctx.command, ctx.args, ctx.action, ctx.actionType, ctx.interactiveResponse, ctx.isImage, ctx.isVideo, ctx.isAudio, ctx.isSticker, ctx.isDocument, ctx.isVN
Method:
ctx.getName(jid?)— nama kontak lewatStorectx.getProfilePicture(jid?)— url foto profil,nullkalau gagal (termasuk@lid)ctx.downloadMedia(folder?)— unduh media pesan masuk ke diskctx.reply(text, opts?)— balas teksctx.replyButtons(text, buttons, footer?, opts?)— balas dengan buttonsMessage cepatctx.react(emoji)— kirim reaksi ke pesan
WAClient — koneksi tingkat rendah (dipakai Bailyes di dalam)
new WAClient(options)
.connect()
.stop()Event: open, close, qr, pairing-code, logged-out, error, plus semua event Baileys asli (messages.upsert, chats.update, dst) diteruskan langsung.
Event close mengirim objek ringkas { statusCode, reason, message }. Untuk kode 515, nilai message berisi Oops, koneksi terputus. Mencoba menyambungkan ulang..., sehingga cukup tampilkan:
bot.onFramework("close", ({ message }) => console.log(message));Error mentah masih tersedia melalui properti error bila benar-benar diperlukan untuk debugging, tetapi tidak ikut tercetak saat objek close ditampilkan dengan console.log.
Handler / Events — dipakai internal oleh Bailyes
new Handler(prefix)—.command(name, fn),.action(id, fn),.hear(pattern, fn),.handle(ctx)new Events()—.on(event, fn),.off(event, fn),.emit(event, data)
bind(sock) / sendLinkPreview
bind(sock)— tempelsock.sendLinkPreview(jid, text, link, title, description, thumbnail, opts), otomatis dipanggilBailyes.start()sendLinkPreview(sock, jid, { text, link, title, description, thumbnail, options })— versi fungsi berdiri sendiri, dipakai juga olehbx.linkPreview
Perbaikan dari versi sebelumnya
require()sekarang benar-benar berfungsi tanpa perlu build step terpisah (dist/), karena Baileys (ESM) di-load lewatimport()dinamis yang di-cache, dipanggil dari dalam fungsiasync— bukanimportstatis yang bikinrequire()gagal.- Pairing code ditambahkan (
pairingCode: true+phoneNumber), sebelumnya hanya QR. - Reconnect tidak lagi memutus listener command — sebelumnya
sock.ev.on("messages.upsert", ...)didaftarkan sekali distart(), jadi setelah reconnect (socket baru), listener lama menunjuk ke socket basi. Sekarang event diteruskan lewatWAClient(EventEmitter sendiri) yang stabil lintas reconnect. - Log koneksi kode
515diringkas menjadi pesan yang mudah dibaca tanpa memenuhi console dengan stack error. - Respons button/list/card sekarang terbaca — ID respons interaktif diekstrak ke
ctx.actiondan dapat ditangani langsung lewatbot.action(id, fn). - Reconnect lebih aman — event socket lama diabaikan dan timer reconnect dibersihkan ketika bot dihentikan.
- Store/memory kontak dibuat manual (
Store) karena Baileys tidak lagi menyediakanmakeInMemoryStorebawaan. @liddan JID lain yang gagal diambil foto profilnya tidak lagi melempar exception —ctx.getProfilePicture()mengembalikannulldengan aman lewat try/catch.- Dependency dipindahkan dari
@whiskeysockets/baileyske[email protected]dan minimum Node.js dinaikkan ke versi 20. - AIRich asli diaktifkan kembali karena Baileys 7 RC13 sudah membawa skema
AIRichResponseMessage; payload divalidasi melalui proto sebelum dikirim. - File tunggal 2600+ baris dipecah jadi modul-modul kecil per tanggung jawab supaya gampang di-maintain dan tidak saling tabrak saat diedit.
- Ditambahkan
bx— cara panggil satu fungsi yang ringkas, plus fitur barubx.livePhotodanbx.liveThumbnail.
Saran update selanjutnya
- Plugin loader otomatis — folder
plugins/di-scan, tiap file otomatis jadi command. - Anti-delete berbasis
Store— dengarkanmessages.delete, kirim ulang isi pesan lama pakaistore.loadMessage(). - Rate limiter per-command —
cooldownsekarang masih per-chat global, bisa dibuat per-command per-user. - Poll message builder —
bx.poll(sock, jid, { question, options }). - Session multi-akun —
SessionManageruntuk jalankan banyakBailyesinstance sekaligus (multi-nomor). - Backend
Storeopsional ke SQLite — biar tidak makan RAM untuk bot dengan banyak chat/pesan. - Webhook/HTTP bridge — endpoint HTTP kecil biar bot bisa dikontrol dari luar.
Testing
npm testLisensi
MIT — lihat LICENSE.
