baileys-joss
v2.0.1
Published
A WebSockets library for interacting with WhatsApp Web
Maintainers
Readme
✨ Kenapa Baileys-Joss?
📦 Installation
# npm
npm install [email protected]
# Yarn
yarn add [email protected]
# pnpm
pnpm add [email protected]// Untuk mengganti @whiskeysockets/baileys
{
"dependencies": {
"@whiskeysockets/baileys": "npm:baileys-joss"
}
}
// Untuk mengganti @adiwajshing/baileys
{
"dependencies": {
"@adiwajshing/baileys": "npm:baileys-joss"
}
}🚀 Quick Start
The complete runnable demo is in Example/wa-baileys-joss-complete.js. It demonstrates connection handling, QR display, message routing, media helpers, interactive messages, LID/senderPn utilities, and the custom helper modules exported by this fork.
Minimal TypeScript connection
import makeWASocket, {
DisconnectReason,
useMultiFileAuthState,
} from "baileys-joss";
import P from "pino";
const start = async () => {
const { state, saveCreds } = await useMultiFileAuthState("./auth_info");
const sock = makeWASocket({
auth: state,
logger: P({ level: "silent" }),
});
sock.ev.on("creds.update", saveCreds);
sock.ev.on("connection.update", ({ connection, lastDisconnect, qr }) => {
if (qr) console.log("Scan this QR with WhatsApp:", qr);
if (connection === "open") console.log("WhatsApp connection opened");
if (
connection === "close" &&
(lastDisconnect?.error as { output?: { statusCode?: number } })?.output
?.statusCode !== DisconnectReason.loggedOut
) {
void start();
}
});
sock.ev.on("messages.upsert", async ({ messages }) => {
const message = messages[0];
const jid = message?.key.remoteJid;
const text =
message?.message?.conversation ??
message?.message?.extendedTextMessage?.text;
if (jid && text === "!ping") await sock.sendMessage(jid, { text: "pong" });
});
};
void start();For the full event loop, pairing-code flow, media examples, interactive messages, albums, groups, and custom helpers, use the complete demo linked above.
🎯 Features
Fitur button interactive yang lebih lengkap dan mudah digunakan:
import {
generateInteractiveButtonMessage,
generateInteractiveListMessage,
generateTemplateMessage,
generateCombinedButtons,
generateCopyCodeButton,
generateUrlButtonMessage,
generateQuickReplyButtons,
} from "baileys-joss";
// Quick Reply Buttons
const quickButtons = generateQuickReplyButtons(
"Pilih opsi di bawah ini:",
[
{ id: "btn-1", displayText: "✅ Setuju" },
{ id: "btn-2", displayText: "❌ Tolak" },
{ id: "btn-3", displayText: "📞 Hubungi CS" },
],
{ footer: "Powered by Baileys-Joss" },
);
await sock.sendMessage(jid, quickButtons);
// URL Button
const urlButton = generateUrlButtonMessage(
"Kunjungi website kami untuk info lebih lanjut",
[{ displayText: "🌐 Buka Website", url: "https://example.com" }],
{ title: "Info Produk", footer: "Click untuk membuka" },
);
await sock.sendMessage(jid, urlButton);
// Copy Code Button (untuk OTP, kode promo, dll)
const copyButton = generateCopyCodeButton(
"Kode OTP Anda adalah:",
"123456",
"📋 Copy Kode",
);
await sock.sendMessage(jid, copyButton);
// Combined Buttons (mix URL, Reply, Copy, Call)
const combinedButtons = generateCombinedButtons(
"Pilih aksi:",
[
{ type: "reply", displayText: "🛒 Pesan Sekarang", id: "order" },
{ type: "url", displayText: "🌐 Website", url: "https://example.com" },
{ type: "call", displayText: "📞 Telepon", phoneNumber: "+6281234567890" },
{ type: "copy", displayText: "📋 Copy Promo", copyCode: "PROMO2024" },
],
{ title: "Menu Utama", footer: "Baileys-Joss" },
);
await sock.sendMessage(jid, combinedButtons);
// List Message
const listMessage = generateInteractiveListMessage({
title: "📋 Menu Produk",
buttonText: "Lihat Menu",
description: "Silahkan pilih produk yang diinginkan",
footer: "Ketik nomor untuk memesan",
sections: [
{
title: "Makanan",
rows: [
{
rowId: "nasi-goreng",
title: "Nasi Goreng",
description: "Rp 25.000",
},
{ rowId: "mie-goreng", title: "Mie Goreng", description: "Rp 22.000" },
],
},
{
title: "Minuman",
rows: [
{ rowId: "es-teh", title: "Es Teh", description: "Rp 5.000" },
{ rowId: "kopi", title: "Kopi", description: "Rp 10.000" },
],
},
],
});
await sock.sendMessage(jid, listMessage);Kirim beberapa gambar/video sekaligus dalam format album:
// Send Album (grouped images/videos)
const albumMedia = [
{ image: { url: "https://example.com/pic1.jpg" }, caption: "Photo 1" },
{ image: { url: "https://example.com/pic2.jpg" }, caption: "Photo 2" },
{ video: { url: "https://example.com/video.mp4" }, caption: "Video" },
];
await sock.sendMessage(jid, {
album: albumMedia,
caption: "My Album 📸",
});
// Album dari file lokal
const localAlbum = [
{ image: fs.readFileSync("./image1.jpg") },
{ image: fs.readFileSync("./image2.jpg") },
{ video: fs.readFileSync("./video.mp4"), gifPlayback: true },
];
await sock.sendMessage(jid, { album: localAlbum });Tambahkan ikon AI stylish pada pesan:
// Kirim pesan dengan AI icon
await sock.sendMessage(jid, {
text: "Halo! Saya adalah asisten AI Anda 🤖",
ai: true, // Menampilkan ikon AI pada pesan
});
// AI dengan media
await sock.sendMessage(jid, {
image: { url: "https://example.com/ai-generated.jpg" },
caption: "Generated by AI",
ai: true,
});Kirim gambar dan video tanpa kompresi dalam kualitas HD:
// Kirim gambar HD (kualitas tinggi, tidak dikompres)
await sock.sendMessage(jid, {
image: { url: "./photo-hd.jpg" },
caption: "Foto HD 📸",
hd: true, // Kirim tanpa kompresi
});
// Kirim video HD
await sock.sendMessage(jid, {
video: { url: "./video-4k.mp4" },
caption: "Video 4K 🎬",
hd: true, // Kualitas asli
});
// HD dengan media dari URL
await sock.sendMessage(jid, {
image: { url: "https://example.com/high-res-photo.jpg" },
hd: true,
caption: "High Resolution Photo",
});Set foto profil panorama (wide) tanpa cropping:
// Set panorama profile picture (tidak di-crop square)
await sock.updatePanoramaProfilePicture(myJid, { url: "./panorama.jpg" });
// Dengan opsi kustom
await sock.updatePanoramaProfilePicture(
myJid,
{ url: "./wide-photo.jpg" },
{
maxWidth: 1080, // Maximum width
quality: 90, // JPEG quality (1-100)
},
);
// Set panorama untuk grup
await sock.updatePanoramaProfilePicture(groupJid, {
url: "./group-banner.jpg",
});
// Atau gunakan profile picture biasa (square crop)
await sock.updateProfilePicture(myJid, { url: "./square-photo.jpg" });Buat polling dengan mudah:
// Create a Poll
const pollMessage = {
name: "🎨 Warna Favorit?",
values: ["🔴 Merah", "🔵 Biru", "🟢 Hijau", "🟡 Kuning"],
selectableCount: 1, // Jumlah pilihan yang bisa dipilih
};
await sock.sendMessage(jid, { poll: pollMessage });
// Multi-select Poll
const multiPoll = {
name: "🍕 Topping Pizza Favorit?",
values: ["Pepperoni", "Mushroom", "Cheese", "Olive", "Bacon"],
selectableCount: 3, // Bisa pilih hingga 3 opsi
};
await sock.sendMessage(jid, { poll: multiPoll });Kelola WhatsApp Channel dengan lengkap:
// Create Newsletter/Channel
await sock.newsletterCreate("My Channel", "Channel description");
// Update channel info
await sock.newsletterUpdateName(channelJid, "New Channel Name");
await sock.newsletterUpdateDescription(channelJid, "Updated description");
await sock.newsletterUpdatePicture(channelJid, {
url: "https://example.com/pic.jpg",
});
// Follow/Unfollow
await sock.newsletterFollow(channelJid);
await sock.newsletterUnfollow(channelJid);
// Mute/Unmute
await sock.newsletterMute(channelJid);
await sock.newsletterUnmute(channelJid);
// Send reaction to channel message
await sock.newsletterReactMessage(channelJid, "server_id", "🔥");
// Get channel metadata
const metadata = await sock.newsletterMetadata("jid", channelJid);
console.log("Subscribers:", metadata.subscribers);
// Admin operations
await sock.newsletterChangeOwner(channelJid, newOwnerLid);
await sock.newsletterDemote(channelJid, adminLid);
const adminCount = await sock.newsletterAdminCount(channelJid);Generate custom alphanumeric pairing code:
// Standard pairing code
const code = await sock.requestPairingCode("6281234567890");
console.log("Your Pairing Code:", code);
// Custom alphanumeric pairing code
const customCode = await sock.requestPairingCode("6281234567890", "MYCODE12");
console.log("Your Custom Code:", customCode);Utilities untuk mengelola JID, LID (Linked ID), dan senderPn:
import {
parseJid,
getSenderPn,
getCurrentSenderInfo,
isSelf,
plotJid,
normalizePhoneToJid,
extractPhoneNumber,
formatJidDisplay,
isSameUser,
getJidVariants,
getRemoteJidFromMessage,
createJidPlotter,
} from "baileys-joss";
// Get info tentang current session (senderPn)
const senderInfo = getCurrentSenderInfo(sock.authState);
console.log("Phone:", senderInfo.phoneNumber);
console.log("Phone JID:", senderInfo.phoneJid);
console.log("LID:", senderInfo.lid);
console.log("Device ID:", senderInfo.deviceId);
console.log("Name:", senderInfo.pushName);
// Parse JID untuk info lengkap
const jidInfo = parseJid("[email protected]");
console.log("User:", jidInfo.user);
console.log("Is LID:", jidInfo.isLid);
console.log("Is PN:", jidInfo.isPn);
console.log("Device:", jidInfo.device);
// Check apakah JID adalah diri sendiri
const isMe = isSelf(someJid, senderInfo);
// Normalize berbagai format nomor
const jid = normalizePhoneToJid("+62 812-3456-7890"); // -> [email protected]
// Extract phone number dari JID
const phone = extractPhoneNumber("[email protected]"); // -> 6281234567890
// Format untuk display
const display = formatJidDisplay("6281234567890:[email protected]", {
showDevice: true,
showType: true,
}); // -> 6281234567890:1 (PN)
// Compare dua JID
const same = isSameUser(
"[email protected]",
"6281234567890:[email protected]",
); // true
// Get sender dari message
sock.ev.on("messages.upsert", async ({ messages }) => {
for (const msg of messages) {
const { chatJid, senderJid } = getRemoteJidFromMessage(msg);
console.log("Chat:", chatJid);
console.log("Sender:", senderJid);
}
});
// Advanced: Create plotter dengan LID mapping support
const plotter = createJidPlotter(
sock.lidMapping.getLIDForPN.bind(sock.lidMapping),
sock.lidMapping.getPNForLID.bind(sock.lidMapping),
);
const plotted = await plotter.plotBidirectional("[email protected]");
console.log("Phone:", plotted.pn);
console.log("LID:", plotted.lid);Kirim lokasi dengan mudah:
// Send location
await sock.sendMessage(jid, {
location: {
degreesLatitude: -6.2088,
degreesLongitude: 106.8456,
name: "Jakarta, Indonesia",
address: "Jl. Sudirman, Jakarta Pusat",
},
});Kelola grup dengan lengkap:
// Create group
const group = await sock.groupCreate("My Group", [
"[email protected]",
]);
// Update group info
await sock.groupUpdateSubject(groupJid, "New Group Name");
await sock.groupUpdateDescription(groupJid, "New description");
// Manage participants
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",
);
// Get group metadata
const metadata = await sock.groupMetadata(groupJid);
console.log("Group Name:", metadata.subject);
console.log("Members:", metadata.participants.length);
// Group settings
await sock.groupSettingUpdate(groupJid, "announcement"); // Only admins can send
await sock.groupSettingUpdate(groupJid, "not_announcement"); // Everyone can send
await sock.groupSettingUpdate(groupJid, "locked"); // Only admins can edit info
await sock.groupSettingUpdate(groupJid, "unlocked"); // Everyone can edit info
// Leave group
await sock.groupLeave(groupJid);🚀 Quick Start
import makeWASocket, {
useMultiFileAuthState,
DisconnectReason,
// Interactive Message features
generateQuickReplyButtons,
generateInteractiveListMessage,
generateCombinedButtons,
// JID Plotting features
getCurrentSenderInfo,
parseJid,
isSelf,
} from "baileys-joss";
async function startBot() {
const { state, saveCreds } = await useMultiFileAuthState("auth_session");
const sock = makeWASocket({
auth: state,
printQRInTerminal: true,
});
sock.ev.on("creds.update", saveCreds);
sock.ev.on("connection.update", (update) => {
const { connection, lastDisconnect } = update;
if (connection === "close") {
const shouldReconnect =
lastDisconnect?.error?.output?.statusCode !==
DisconnectReason.loggedOut;
if (shouldReconnect) {
startBot();
}
} else if (connection === "open") {
console.log("✅ Connected!");
// Get sender info
const sender = getCurrentSenderInfo(sock.authState);
console.log("📱 Logged in as:", sender?.phoneNumber);
}
});
sock.ev.on("messages.upsert", async ({ messages }) => {
const msg = messages[0];
if (!msg.message || msg.key.fromMe) return;
const text =
msg.message.conversation || msg.message.extendedTextMessage?.text || "";
if (text === "/menu") {
// Kirim interactive buttons
const buttons = generateQuickReplyButtons(
"🤖 Bot Menu\n\nPilih opsi:",
[
{ id: "help", displayText: "❓ Bantuan" },
{ id: "info", displayText: "ℹ️ Info" },
{ id: "order", displayText: "🛒 Order" },
],
{ footer: "Baileys-Joss Bot" },
);
await sock.sendMessage(msg.key.remoteJid!, buttons);
}
if (text === "/poll") {
// Kirim poll
await sock.sendMessage(msg.key.remoteJid!, {
poll: {
name: "🗳️ Vote sekarang!",
values: ["Option A", "Option B", "Option C"],
selectableCount: 1,
},
});
}
if (text === "/ai") {
// Kirim pesan dengan AI style
await sock.sendMessage(msg.key.remoteJid!, {
text: "Halo! Saya asisten AI Anda 🤖",
ai: true,
});
}
});
}
startBot();💡 Use Case Examples
// Create a newsletter
await sock.newsletterCreate("My Updates Channel", "Stay updated!");
// Update description
await sock.newsletterUpdateDescription(channelJid, "Fresh updates weekly 🔥");
// Send reaction to channel message
await sock.newsletterReactMessage(channelJid, "server_id", "❤️");
// Fetch channel messages
const messages = await sock.newsletterFetchMessages("jid", channelJid, 10);// Native Flow Buttons
const buttons = generateCombinedButtons(
"Welcome to our service! 🎉",
[
{ type: "reply", displayText: "📋 View Menu", id: "menu" },
{
type: "url",
displayText: "🌐 Visit Website",
url: "https://example.com",
},
{ type: "call", displayText: "📞 Call Us", phoneNumber: "+1234567890" },
{ type: "copy", displayText: "📋 Copy Promo", copyCode: "SAVE20" },
],
{ title: "Welcome!", footer: "Powered by Baileys-Joss" },
);
await sock.sendMessage(jid, buttons);const media = [
{ image: { url: "https://example.com/pic1.jpg" }, caption: "Photo 1 📸" },
{ image: { url: "https://example.com/pic2.jpg" }, caption: "Photo 2 📸" },
{ video: { url: "https://example.com/clip.mp4" }, caption: "Video 🎬" },
];
await sock.sendMessage(jid, {
album: media,
caption: "My Vacation Memories 🌴",
});// Request standard pairing code
const code = await sock.requestPairingCode("6281234567890");
console.log("Your Pairing Code:", code);
// Request custom pairing code
const customCode = await sock.requestPairingCode("6281234567890", "BAILEYS1");
console.log("Your Custom Code:", customCode);const pollMessage = {
name: "🎬 Film Favorit Weekend Ini?",
values: ["🦸 Superhero Movie", "😂 Comedy", "😱 Horror", "💑 Romance"],
selectableCount: 1,
};
await sock.sendMessage(jid, { poll: pollMessage });await sock.sendMessage(jid, {
location: {
degreesLatitude: -6.2088,
degreesLongitude: 106.8456,
name: "Monas Jakarta",
address: "Jalan Medan Merdeka, Jakarta Pusat",
},
});// Create group
const group = await sock.groupCreate("My Awesome Group", [
"[email protected]",
"[email protected]",
]);
console.log("Group created:", group.id);
// Update group settings
await sock.groupUpdateSubject(group.id, "Updated Group Name");
await sock.groupSettingUpdate(group.id, "announcement");
// Add members
await sock.groupParticipantsUpdate(
group.id,
["[email protected]"],
"add",
);🆕 Baileys-Joss v2.0.1 New Features
Jadwalkan pesan untuk dikirim otomatis di waktu tertentu:
import { createMessageScheduler } from "baileys-joss";
// Buat scheduler
const scheduler = createMessageScheduler(
(jid, content) => sock.sendMessage(jid, content),
{
onSent: (scheduled, message) => {
console.log(`Pesan terkirim ke ${scheduled.jid}`);
},
onFailed: (scheduled, error) => {
console.log(`Gagal kirim: ${error.message}`);
},
},
);
// Jadwalkan pesan untuk waktu tertentu
const scheduled = scheduler.schedule(
"[email protected]",
{ text: "Selamat Ulang Tahun! 🎂" },
new Date("2024-12-25 09:00:00"),
);
// Jadwalkan dengan delay (30 menit dari sekarang)
scheduler.scheduleDelay(jid, { text: "Reminder!" }, 30 * 60 * 1000);
// Cancel scheduled message
scheduler.cancel(scheduled.id);
// Get all pending messages
const pending = scheduler.getPending();
// Stop scheduler
scheduler.stop();Kirim pesan massal ke banyak kontak dengan rate limiting:
import { createBulkSender, sendBulkMessages } from "baileys-joss";
// Method 1: Create bulk sender instance
const bulkSender = createBulkSender(
(jid, content) => sock.sendMessage(jid, content),
{
delayBetweenMessages: 2000, // 2 detik delay
randomDelay: 1000, // Random 0-1 detik tambahan
maxRetries: 2,
onProgress: (progress) => {
console.log(
`Progress: ${progress.sent}/${progress.total} (${progress.percentage}%)`,
);
},
onComplete: (results) => {
const success = results.filter((r) => r.success).length;
console.log(`Selesai: ${success}/${results.length} berhasil`);
},
},
);
// Kirim pesan yang sama ke banyak JID
const jids = [
"[email protected]",
"[email protected]",
"[email protected]",
];
const results = await bulkSender.sendToMany(jids, { text: "Hello everyone!" });
// Kirim pesan berbeda ke JID berbeda
const messages = [
{ jid: "[email protected]", content: { text: "Hi John!" } },
{ jid: "[email protected]", content: { text: "Hi Jane!" } },
];
await bulkSender.send(messages);
// Method 2: Quick helper
await sendBulkMessages((jid, content) => sock.sendMessage(jid, content), jids, {
text: "Broadcast message",
});Sistem balasan otomatis berdasarkan keyword/pattern:
import { createAutoReply } from "baileys-joss";
// Buat auto-reply handler
const autoReply = createAutoReply(
(jid, content, options) => sock.sendMessage(jid, content, options),
(jid, presence) => sock.sendPresenceUpdate(presence, jid),
{
simulateTyping: true,
typingDuration: 1500,
globalCooldown: 1000,
},
);
// Tambah rule berdasarkan keywords
autoReply.addRule({
keywords: ["harga", "price", "biaya"],
response: { text: "Silakan cek katalog kami di example.com" },
cooldown: 60000, // 1 menit cooldown per user
quoted: true, // Reply dengan quote
});
// Rule dengan regex pattern
autoReply.addRule({
pattern: /^(hi|hello|halo|hay)/i,
response: { text: "Hai! Ada yang bisa dibantu? 😊" },
privateOnly: true, // Hanya di private chat
});
// Rule dengan dynamic response
autoReply.addRule({
keywords: ["order"],
response: async (message, match) => {
const sender = message.key.remoteJid;
return { text: `Terima kasih sudah order! ID: ${Date.now()}` };
},
});
// Rule untuk grup saja
autoReply.addRule({
exactMatch: "/menu",
response: { text: "Menu:\n1. Help\n2. Info\n3. Contact" },
groupsOnly: true,
});
// Proses pesan masuk
sock.ev.on("messages.upsert", async ({ messages }) => {
for (const msg of messages) {
if (!msg.key.fromMe) {
await autoReply.processMessage(msg);
}
}
});Kirim kartu kontak lengkap dengan detail:
import {
createContactCard,
createContactCards,
quickContact,
generateVCard,
} from "baileys-joss";
// Quick contact (simple)
const simple = quickContact("John Doe", "+628123456789", {
organization: "PT Example",
email: "[email protected]",
});
await sock.sendMessage(jid, createContactCard(simple));
// Full vCard with all details
const fullContact = {
fullName: "Dr. John Doe",
displayName: "John D.",
organization: "Hospital ABC",
title: "Senior Doctor",
phones: [
{ number: "+628123456789", type: "CELL" },
{ number: "+622112345678", type: "WORK" },
],
emails: [
{ email: "[email protected]", type: "WORK" },
{ email: "[email protected]", type: "HOME" },
],
urls: [{ url: "https://linkedin.com/in/johndoe", type: "WORK" }],
addresses: [
{
street: "Jl. Sudirman No. 123",
city: "Jakarta",
state: "DKI Jakarta",
postalCode: "12345",
country: "Indonesia",
type: "WORK",
},
],
birthday: "1990-05-15",
note: "Met at conference 2024",
};
await sock.sendMessage(jid, createContactCard(fullContact));
// Send multiple contacts
const contacts = [
quickContact("Alice", "+628111111111"),
quickContact("Bob", "+628222222222"),
quickContact("Charlie", "+628333333333"),
];
await sock.sendMessage(jid, createContactCards(contacts));
// Generate raw vCard string
const vcardString = generateVCard(fullContact);
console.log(vcardString);Posting status WhatsApp (foto, video, text):
import {
StatusHelper,
STATUS_BROADCAST_JID,
STATUS_BACKGROUNDS,
STATUS_FONTS,
} from "baileys-joss";
const statusJid = STATUS_BROADCAST_JID; // 'status@broadcast'
// Post text status
await sock.sendMessage(
statusJid,
StatusHelper.text("Hello World! 🌍", STATUS_BACKGROUNDS.solid.green),
);
// Post image status
const imageBuffer = fs.readFileSync("./my-photo.jpg");
await sock.sendMessage(
statusJid,
StatusHelper.image(imageBuffer, "Beautiful day! ☀️"),
);
// Post video status
const videoBuffer = fs.readFileSync("./my-video.mp4");
await sock.sendMessage(
statusJid,
StatusHelper.video(videoBuffer, "Check this out! 🎬"),
);
// Post GIF status
await sock.sendMessage(statusJid, StatusHelper.gif(gifBuffer, "Animated! 🎭"));
// Custom text status with font
import { createTextStatus } from "baileys-joss";
await sock.sendMessage(
statusJid,
createTextStatus({
text: "Custom styled status!",
backgroundColor: STATUS_BACKGROUNDS.solid.purple,
font: STATUS_FONTS.DANCING,
textColor: "#FFFFFF",
}),
);Template pesan siap pakai untuk berbagai keperluan:
import {
createTemplateManager,
renderTemplate,
PRESET_TEMPLATES,
} from "baileys-joss";
// Create manager with preset templates
const templates = createTemplateManager(true);
// Render preset template
const orderConfirmation = templates.render("order_confirmation", {
orderId: "ORD-12345",
customerName: "John Doe",
orderDate: "2024-01-15",
items: "1x Product A\n2x Product B",
total: "150,000",
});
await sock.sendMessage(jid, { text: orderConfirmation });
// Create custom template
templates.create({
name: "Welcome Message",
content: `Halo {{name}}! 👋
Selamat datang di {{company}}!
Berikut layanan kami:
{{services}}
Contact: {{phone:021-12345678}}`,
category: "greeting",
});
// Render custom template
const welcome = templates.render("welcome_message", {
name: "Budi",
company: "PT Example",
services: "- Layanan A\n- Layanan B\n- Layanan C",
});
// Quick template rendering (tanpa manager)
const quick = renderTemplate(
"Hi {{name}}, your order #{{orderId}} is {{status:processing}}",
{ name: "Alice", orderId: "123" },
);
// List available templates
const allTemplates = templates.getAll();
const invoiceTemplates = templates.getByCategory("invoice");
// Export/Import templates
const exportJson = templates.export();
templates.import(exportJson, true); // true = overwrite existingKelola dan kirim ke broadcast list:
import { createBroadcastManager } from "baileys-joss";
const broadcast = createBroadcastManager((jid, content) =>
sock.sendMessage(jid, content),
);
// Create broadcast list
const customerList = broadcast.create({
name: "VIP Customers",
description: "Premium customers for promo",
recipients: ["[email protected]", "[email protected]"],
});
// Add more recipients
broadcast.addRecipients(customerList.id, ["[email protected]"]);
// Send to broadcast list
const result = await broadcast.broadcast(
customerList.id,
{ text: "🎉 Special promo for VIP customers!" },
{
delay: 2000,
onProgress: (sent, total, jid) => {
console.log(`Sending ${sent}/${total}: ${jid}`);
},
},
);
console.log(`Sent: ${result.sent}, Failed: ${result.failed}`);
// Get statistics
const stats = broadcast.getStats();
console.log(
`Total lists: ${stats.totalLists}, Recipients: ${stats.totalRecipients}`,
);
// Export/Import lists
const json = broadcast.export();
broadcast.import(json);Simulasi sedang mengetik:
import { createTypingIndicator } from "baileys-joss";
const typing = createTypingIndicator((jid, presence) =>
sock.sendPresenceUpdate(presence, jid),
);
// Start typing
await typing.startTyping(jid, {
duration: 5000, // Auto pause after 5 seconds
autoPause: true,
});
// Start recording (for voice notes)
await typing.startRecording(jid, { duration: 3000 });
// Stop typing
await typing.stopTyping(jid);
// Simulate typing then send
await typing.simulateTyping(jid, 2000, async () => {
return sock.sendMessage(jid, { text: "Hello!" });
});
// Stop all typing indicators
await typing.stopAll();Kontrol centang biru:
import { createReadReceiptController } from "baileys-joss";
const readReceipts = createReadReceiptController(
(jid, participant, messageIds) =>
sock.readMessages([{ remoteJid: jid, id: messageIds[0] }]),
{
enabled: true,
readDelay: 1000, // 1 second delay
excludeJids: ["[email protected]"],
},
);
// Toggle read receipts
readReceipts.disable(); // Stop sending read receipts
readReceipts.enable(); // Resume
// Check status
console.log(readReceipts.isEnabled());
// Manual read (respects config)
await readReceipts.markRead(jid, participant, ["messageId123"]);
// Force read (ignores config)
await readReceipts.forceMarkRead(jid, participant, ["messageId123"]);
// Update config
readReceipts.setConfig({
enabled: true,
readDelay: 2000,
});Cari pesan dalam chat:
import { createMessageSearch, searchMessages } from "baileys-joss";
// Create search manager
const search = createMessageSearch();
// Add messages to index
search.addMessages(chatMessages);
// Search by text
const results = search.search("harga produk", {
caseSensitive: false,
limit: 20,
messageTypes: ["text", "image"], // Include captions
fromDate: new Date("2024-01-01"),
});
for (const result of results) {
console.log(`Found: "${result.matchedText}"`);
console.log(`Score: ${result.relevanceScore}`);
console.log(`Message ID: ${result.message.key.id}`);
}
// Search with regex
const regexResults = search.searchRegex(/order\s*#?\d+/i);
// Get messages by type
const images = search.getByType("image");
const videos = search.getByType("video");
// Get messages by sender
const fromSender = search.getBySender("[email protected]");
// Quick search (without manager)
const quickResults = searchMessages(messages, "keyword", {
jid: specificChatJid,
fromMe: false,
});Statistik dan analitik chat:
import { createChatAnalytics } from "baileys-joss";
const analytics = createChatAnalytics();
// Add messages for analysis
analytics.addMessages(allMessages);
// Get stats for specific chat
const chatStats = analytics.getChatStats("[email protected]");
console.log(`Total messages: ${chatStats.totalMessages}`);
console.log(`From me: ${chatStats.messagesFromMe}`);
console.log(`Media count: ${chatStats.mediaCount}`);
console.log(`Links shared: ${chatStats.linkCount}`);
console.log(`Emojis used: ${chatStats.emojiCount}`);
console.log(`Most active hour: ${chatStats.mostActiveHour}:00`);
console.log(`Most active day: ${chatStats.mostActiveDay}`);
console.log(`Avg messages/day: ${chatStats.averageMessagesPerDay}`);
// Message breakdown by type
console.log("Messages by type:", chatStats.messagesByType);
// { text: 150, image: 45, video: 12, audio: 8, ... }
// Global stats across all chats
const globalStats = analytics.getGlobalStats();
console.log(`Total chats: ${globalStats.totalChats}`);
console.log(`Total messages: ${globalStats.totalMessages}`);
console.log(`Most active chat: ${globalStats.mostActiveChat?.jid}`);
// Activity analysis
const hourlyActivity = analytics.getActivityByHour(jid); // Array[24]
const dailyActivity = analytics.getActivityByDay(jid); // { Sunday: 10, Monday: 25, ... }
// Top participants in group
const topParticipants = analytics.getTopParticipants(groupJid, 5);
for (const p of topParticipants) {
console.log(`${p.participant}: ${p.count} messages`);
}Export chat ke JSON, HTML, TXT, atau CSV:
import { createChatExporter, exportChat } from "baileys-joss";
const exporter = createChatExporter();
// Add messages
exporter.addMessages(jid, chatMessages);
// Export to JSON
const jsonExport = exporter.export(jid, {
format: "json",
includeMediaInfo: true,
includeMetadata: true,
});
fs.writeFileSync(jsonExport.filename, jsonExport.content);
// Export to HTML (readable format)
const htmlExport = exporter.export(jid, {
format: "html",
title: "Chat dengan John",
dateFormat: "YYYY-MM-DD HH:mm",
});
fs.writeFileSync(htmlExport.filename, htmlExport.content);
// Export to TXT (simple text)
const txtExport = exporter.export(jid, {
format: "txt",
dateRange: {
start: new Date("2024-01-01"),
end: new Date("2024-12-31"),
},
});
// Export to CSV (for spreadsheet)
const csvExport = exporter.export(jid, {
format: "csv",
includeMetadata: true,
});
// Quick export (without manager)
const result = exportChat(messages, jid, { format: "json" });
console.log(`Exported ${result.messageCount} messages`);
// Export all chats
const allExports = exporter.exportAll({ format: "json" });Game sederhana untuk chat interaktif:
import {
MiniGamesManager,
createTicTacToeGame,
createQuiz,
} from "baileys-joss";
// Create games manager
const games = new MiniGamesManager();
// 🎯 Guess Number Game
const guessSession = games.startGuessNumber("[email protected]", {
minNumber: 1,
maxNumber: 100,
maxAttempts: 7,
});
// Handle guess
const result = games.handleGuess(guessSession.id, 50);
if (result.correct) {
await sock.sendMessage(jid, {
text: `🎉 Correct! The number was ${result.answer}`,
});
} else {
await sock.sendMessage(jid, {
text: `${result.hint} (${result.remaining} attempts left)`,
});
}
// 🧠 Quiz Game
const quizSession = games.startQuiz(jid, {
questions: [
{
question: "Apa ibukota Indonesia?",
options: ["Jakarta", "Bandung", "Surabaya", "Medan"],
correctIndex: 0,
explanation: "Jakarta adalah ibukota Indonesia sejak 1945",
},
],
category: "geography",
});
await sock.sendMessage(jid, {
text: `📝 Quiz:\n${quizSession.data.currentQuestion}\n\n${quizSession.data.options.map((o, i) => `${i + 1}. ${o}`).join("\n")}`,
});
// ❌⭕ TicTacToe Game
const tttSession = games.startTicTacToe(jid, player1Jid, player2Jid);
const moveResult = games.handleMove(tttSession.id, player1Jid, 4); // Center position
await sock.sendMessage(jid, {
text: `${games.renderBoard(tttSession)}\n\n${moveResult.message}`,
});
// 🎲 Quick Games
const dice = games.rollDice(); // { value: 1-6, emoji: '🎲' }
const coin = games.flipCoin(); // { result: 'heads'|'tails', emoji: '🪙' }
const rps = games.playRockPaperScissors("rock", "scissors"); // { winner: 'player1', ... }
// 🏆 Leaderboard
const leaderboard = games.getLeaderboard(10);Deteksi otomatis berbagai jenis konten dalam pesan:
import {
ContentDetector,
ContentFilter,
hasLinks,
hasPhoneNumbers,
hasEmails,
hasMediaContent,
} from "baileys-joss";
// Create detector
const detector = new ContentDetector();
// Full analysis
const result = detector.analyze(message);
console.log("Has media:", result.hasMedia);
console.log("Media type:", result.mediaType);
console.log("Links found:", result.links);
console.log("Phone numbers:", result.phoneNumbers);
console.log("Emails:", result.emails);
console.log("Mentions:", result.mentions);
console.log("Hashtags:", result.hashtags);
console.log("Word count:", result.wordCount);
// Quick checks
if (hasLinks(message)) {
console.log("Message contains links!");
}
if (hasPhoneNumbers(message)) {
console.log("Message contains phone numbers!");
}
if (hasMediaContent(message)) {
console.log("Message has media attachment!");
}
// Content filtering
const filter = new ContentFilter({
blockLinks: true,
blockedDomains: ["spam.com", "malware.xyz"],
blockPhoneNumbers: false,
sensitiveKeywords: ["spam", "promo", "click here"],
maxMessageLength: 1000,
});
const filterResult = filter.check(message);
if (!filterResult.allowed) {
await sock.sendMessage(jid, {
text: `⚠️ Message blocked: ${filterResult.blockedReason}`,
});
}Sistem untuk mendeteksi dan mencegah spam:
import { AntiSpamManager } from "baileys-joss";
// Create anti-spam manager
const antispam = new AntiSpamManager({
maxMessagesPerMinute: 15,
maxDuplicates: 3,
duplicateWindow: 60000, // 1 minute
minMessageDelay: 500,
whitelist: ["[email protected]"],
onSpamDetected: async (jid, message, result) => {
console.log(`Spam detected from ${jid}: ${result.reason}`);
if (result.action === "mute") {
await sock.sendMessage(jid, { text: "⚠️ You are muted for spamming!" });
}
},
});
// Add custom spam pattern
antispam.addRule({
id: "promo_spam",
name: "Promotional Spam",
type: "pattern",
enabled: true,
config: { patterns: [/FREE\s+\d+\s+TOKEN/i, /CLICK\s+HERE.*WIN/i] },
action: "delete",
});
// Check incoming messages
sock.ev.on("messages.upsert", async ({ messages }) => {
for (const msg of messages) {
const result = await antispam.checkMessage(msg);
if (result.isSpam) {
console.log(
`🛡️ Spam blocked! Score: ${result.score}, Reason: ${result.reason}`,
);
// Handle based on action
if (result.action === "delete") {
await sock.sendMessage(msg.key.remoteJid, { delete: msg.key });
} else if (result.action === "warn") {
await sock.sendMessage(msg.key.remoteJid, {
text: `⚠️ Warning: ${result.reason}`,
});
}
continue;
}
// Process non-spam message...
}
});
// Whitelist trusted users
antispam.whitelist("[email protected]");
// Mute spammer temporarily
antispam.muteUser("[email protected]", 3600); // 1 hour
// Ban repeat offender
antispam.banUser("[email protected]");
// Get spam statistics
const stats = antispam.getStats();
console.log("Total spam blocked:", stats.totalBlocked);Scan dan validasi URL untuk keamanan:
import { LinkScanner, scanUrls, isUrlSafe } from "baileys-joss";
// Create scanner
const scanner = new LinkScanner({
followRedirects: true,
maxRedirects: 5,
timeout: 5000,
enablePhishingDetection: true,
});
// Scan single URL
const result = await scanner.scanUrl("https://suspicious-link.xyz/login");
console.log("Safe:", result.safe);
console.log("Risk level:", result.riskLevel); // 'safe' | 'low' | 'medium' | 'high' | 'critical'
console.log("Threats:", result.threats);
console.log("Details:", result.details);
// Scan all URLs in a message
const messageResults = await scanner.scanMessage(message);
for (const urlResult of messageResults) {
if (!urlResult.safe) {
await sock.sendMessage(jid, {
text: `⚠️ Warning! Suspicious link detected:\n${urlResult.url}\n\nRisk: ${urlResult.riskLevel}\nThreats: ${urlResult.threats.join(", ")}`,
});
}
}
// Quick safety check
const isSafe = await scanner.isUrlSafe("https://example.com");
// Add custom patterns
scanner.addPhishingPattern(/banking.*verify.*account/i);
scanner.addTrustedDomain("mytrusted.com");
scanner.addMaliciousDomain("known-scam.xyz");
// Auto-scan in message handler
sock.ev.on("messages.upsert", async ({ messages }) => {
for (const msg of messages) {
const scanResults = await scanner.scanMessage(msg);
const dangerous = scanResults.filter(
(r) => r.riskLevel === "high" || r.riskLevel === "critical",
);
if (dangerous.length > 0) {
await sock.sendMessage(
msg.key.remoteJid,
{
text: `🚨 Dangerous link(s) detected! ${dangerous.length} threat(s) found.`,
},
{ quoted: msg },
);
}
}
});Logging aktivitas untuk audit trail:
import { ActivityLogger } from "baileys-joss";
// Create logger
const logger = new ActivityLogger({
fileLogging: true,
logFilePath: "./logs/bot-activity.log",
maxMemoryEntries: 1000,
maxFileSize: 10 * 1024 * 1024, // 10MB
minLevel: "info",
categories: ["message", "user", "group", "bot"],
onLog: (entry) => {
if (entry.level === "error") {
// Send alert to admin
console.error(`[ALERT] ${entry.action}: ${entry.details.message}`);
}
},
});
// Log message activity
logger.logMessage(message, "received", {
processed: true,
responseTime: 150,
});
// Log user action
logger.logUserAction("[email protected]", "command_executed", {
command: "/help",
success: true,
});
// Log group action
logger.logGroupAction("[email protected]", "member_added", {
addedBy: "[email protected]",
newMember: "[email protected]",
});
// Log custom activity
logger.log({
level: "info",
category: "bot",
action: "scheduled_task",
actor: "system",
details: { task: "daily_backup", status: "completed" },
});
// Query logs
const recentErrors = logger.query({
level: "error",
fromDate: new Date(Date.now() - 24 * 60 * 60 * 1000), // Last 24 hours
limit: 50,
});
// Get statistics
const stats = logger.getStats();
console.log("Total entries:", stats.totalEntries);
console.log("By level:", stats.byLevel);
console.log("Top actors:", stats.topActors);
// Export logs
const jsonLogs = logger.export("json");
const csvLogs = logger.export("csv");Generate meme sederhana dengan text overlay:
import {
MemeGenerator,
MEME_TEMPLATES,
drakeMeme,
expandingBrainMeme,
thisIsFineMeme,
} from "baileys-joss";
// Create generator
const meme = new MemeGenerator();
// List available templates
const templates = meme.getTemplates();
console.log(
"Available templates:",
templates.map((t) => t.name),
);
// Generate Drake meme (quick helper)
const drake = drakeMeme(
"Debugging code manually", // Rejected
"Using console.log everywhere", // Approved
);
await sock.sendMessage(jid, { text: drake.htmlContent });
// Generate Expanding Brain meme
const brain = expandingBrainMeme([
"Using var",
"Using let",
"Using const",
"Using TypeScript",
]);
await sock.sendMessage(jid, { text: brain.htmlContent });
// Generate "This is Fine" meme
const fine = thisIsFineMeme("Production is on fire but it's fine");
await sock.sendMessage(jid, { text: fine.htmlContent });
// Custom meme with template
const custom = meme.generateTextMeme({
template: "distracted",
texts: {
boyfriend: "Me",
girlfriend: "My deadlines",
other: "New side project",
},
fontSize: 24,
fontColor: "#ffffff",
});
// Generate SVG meme (for advanced use)
const svgMeme = meme.generateSvgMeme({
template: "two_buttons",
texts: {
button1: "Sleep early",
button2: "One more episode",
},
});
// Send as formatted text meme
await sock.sendMessage(jid, {
text: `🎭 *MEME*\n\n${custom.htmlContent}`,
});Timer produktivitas dengan teknik Pomodoro:
import { PomodoroManager, DEFAULT_POMODORO_CONFIG } from "baileys-joss";
// Create pomodoro manager
const pomodoro = new PomodoroManager();
// Register event handler
pomodoro.onEvent(async (event) => {
const jid = event.session.jid;
switch (event.type) {
case "work_start":
await sock.sendMessage(jid, {
text: `🍅 *WORK SESSION STARTED*\n\n⏱️ Duration: 25 minutes\n🎯 Session: ${event.session.currentSession}/${event.session.totalSessions}\n\n💪 Stay focused!`,
});
break;
case "work_end":
await sock.sendMessage(jid, {
text: `✅ *WORK SESSION COMPLETE!*\n\n🎉 Great job! Time for a break.\n\nType /break to start break timer.`,
});
break;
case "break_start":
await sock.sendMessage(jid, {
text: `☕ *BREAK TIME*\n\n⏱️ Duration: 5 minutes\n\n🧘 Relax and recharge!`,
});
break;
case "break_end":
await sock.sendMessage(jid, {
text: `⏰ *BREAK OVER!*\n\nReady for next session?\nType /work to continue.`,
});
break;
}
});
// Start work session
const session = pomodoro.start("[email protected]", {
workDuration: 25, // 25 minutes
shortBreakDuration: 5, // 5 minutes
longBreakDuration: 15, // 15 minutes
sessionsBeforeLongBreak: 4,
autoStartBreaks: true,
});
// Pause/Resume
pomodoro.pause(jid);
pomodoro.resume(jid);
// Start break manually
pomodoro.startBreak(jid);
// Get current status
const status = pomodoro.status(jid);
console.log("Status:", status.status); // 'work' | 'short_break' | 'long_break' | 'paused'
console.log("Time remaining:", status.remainingTime);
console.log("Current session:", status.currentSession);
// Stop and reset
pomodoro.stop(jid);
// Get statistics
const stats = pomodoro.stats(jid);
console.log("Total work sessions:", stats.totalWorkSessions);
console.log("Total work minutes:", stats.totalWorkMinutes);
console.log("Current streak:", stats.currentStreak);Random quotes dan quotes harian:
import {
QuoteManager,
getRandomQuote,
getQuoteOfTheDay,
getMotivationalQuote,
getIslamicQuote,
getFunnyQuote,
quoteCommand,
QUOTES,
} from "baileys-joss";
// Quick helpers
const random = getRandomQuote();
await sock.sendMessage(jid, {
text: `💬 *Quote*\n\n"${random.text}"\n\n— ${random.author}`,
});
// Quote of the day (same quote all day)
const qotd = getQuoteOfTheDay();
await sock.sendMessage(jid, {
text: `📅 *Quote of the Day*\n\n"${qotd.quote.text}"\n\n— ${qotd.quote.author}`,
});
// Category-specific quotes
const motivational = getMotivationalQuote();
const islamic = getIslamicQuote();
const funny = getFunnyQuote();
// Using QuoteManager for more control
const quoteManager = new QuoteManager();
// Get quote by category
const loveQuote = quoteManager.getByCategory("love");
const wisdomQuote = quoteManager.getByCategory("wisdom");
// Get quote by language
const indonesianQuote = quoteManager.getByLanguage("id");
const englishQuote = quoteManager.getByLanguage("en");
// Search quotes
const searchResults = quoteManager.search("success");
// Add custom quote
quoteManager.addQuote({
id: "custom1",
text: "My custom inspirational quote",
author: "Me",
category: "inspirational",
language: "en",
});
// Parse command (for bot integration)
// Supported: /quote, /quote motivational, /quote islamic, /quote funny
const commandResult = quoteCommand("/quote motivational");
await sock.sendMessage(jid, { text: commandResult });
// Send random quote with formatting
const formatted = quoteManager.format(getRandomQuote(), {
style: "fancy", // 'simple' | 'fancy' | 'minimal'
includeCategory: true,
});
await sock.sendMessage(jid, { text: formatted });Informasi cuaca dengan integrasi OpenWeatherMap:
import {
WeatherBot,
getWeather,
getSimpleWeather,
weatherCommand,
} from "baileys-joss";
// Create weather bot (with API key for full features)
const weather = new WeatherBot({
apiKey: "YOUR_OPENWEATHERMAP_API_KEY", // Optional: enables API mode
units: "metric", // 'metric' | 'imperial'
language: "id",
defaultCity: "Jakarta",
});
// Get weather for a city
const data = await weather.getWeather("Jakarta");
await sock.sendMessage(jid, {
text: `🌤️ *Weather in ${data.city}, ${data.country}*\n\n🌡️ Temperature: ${data.temperature}°C\n🤒 Feels like: ${data.feelsLike}°C\n💧 Humidity: ${data.humidity}%\n💨 Wind: ${data.windSpeed} m/s\n☁️ Condition: ${data.description}\n\n🌅 Sunrise: ${new Date(data.sunrise * 1000).toLocaleTimeString()}\n🌇 Sunset: ${new Date(data.sunset * 1000).toLocaleTimeString()}`,
});
// Quick helper (uses sample data if no API key)
const simpleWeather = await getSimpleWeather("Tokyo");
await sock.sendMessage(jid, { text: simpleWeather });
// Get 5-day forecast
const forecast = await weather.getForecast("Singapore");
let forecastText = `📅 *5-Day Forecast for ${forecast.city}*\n\n`;
for (const day of forecast.forecasts.slice(0, 5)) {
forecastText += `${day.date}: ${day.temperature}°C, ${day.description}\n`;
}
await sock.sendMessage(jid, { text: forecastText });
// Weather alerts
const alerts = await weather.getAlerts("Miami");
if (alerts.length > 0) {
for (const alert of alerts) {
await sock.sendMessage(jid, {
text: `⚠️ *Weather Alert*\n\n${alert.event}\n\nSeverity: ${alert.severity}\n${alert.description}`,
});
}
}
// Parse weather command (for bot integration)
// Supported: /weather Jakarta, /cuaca Bandung
const result = await weatherCommand("/weather Singapore", weather);
await sock.sendMessage(jid, { text: result });
// Format with emoji
const formatted = weather.formatWeather(data, {
includeEmoji: true,
includeDetails: true,
language: "id",
});
await sock.sendMessage(jid, { text: formatted });Generate QR code custom untuk pairing:
import {
createQRGenerator,
QRHelper,
createQRHandler,
createWhatsAppQR,
} from "baileys-joss";
// Quick QR generation
const terminalQR = await QRHelper.terminal(pairingCode);
console.log(terminalQR);
// Generate SVG QR
const svgQR = await QRHelper.svg(pairingCode, {
size: 300,
foregroundColor: "#128C7E", // WhatsApp green
backgroundColor: "#FFFFFF",
});
// Generate base64 QR (for web)
const base64QR = await QRHelper.base64(pairingCode);
// Generate PNG buffer
const pngBuffer = await QRHelper.buffer(pairingCode);
fs.writeFileSync("qr.png", pngBuffer);
// Custom generator
const generator = createQRGenerator({
size: 256,
errorCorrectionLevel: "H",
foregroundColor: "#000000",
margin: 4,
});
const qr = await generator.generate(data);
// WhatsApp-styled QR
const waQR = await createWhatsAppQR(pairingCode);
// Use as QR event handler
const sock = makeWASocket({
// ...
printQRInTerminal: false,
});
sock.ev.on("connection.update", async ({ qr }) => {
if (qr) {
const qrHandler = createQRHandler({
maxAttempts: 5,
onQR: (rendered, raw, attempt) => {
console.log(`\nScan QR (${attempt}/5):\n`);
console.log(rendered);
},
});
await qrHandler(qr);
}
});Download semua media dari chat:
import { createMediaDownloader, downloadAllMedia } from "baileys-joss";
const downloader = createMediaDownloader(async (key) =>
store.loadMessage(key.remoteJid, key.id),
);
// Download all media from chat
const summary = await downloader.downloadFromChat(
"[email protected]",
chatMessages,
{
outputDir: "./downloads/john-doe",
types: ["image", "video", "document"], // or ['all']
createSubfolders: true, // images/, videos/, etc.
skipExisting: true,
maxFileSize: 50 * 1024 * 1024, // 50MB limit
delay: 500, // Delay between downloads
onProgress: (current, total, filename) => {
console.log(`Downloading ${current}/${total}: ${filename}`);
},
onError: (msg, error) => {
console.log(`Failed: ${error.message}`);
},
},
);
console.log(`Downloaded: ${summary.successful}/${summary.total}`);
console.log(`Total size: ${(summary.totalSize / 1024 / 1024).toFixed(2)} MB`);
console.log(`Failed: ${summary.failed}`);
// Download single media
const singleResult = await downloader.downloadSingle(
mediaMessage,
"./downloads",
{ filenameTemplate: "{type}_{date}_{id}{ext}" },
);
// Quick download all (without manager)
await downloadAllMedia(messages, "./downloads/all-media", {
types: ["image"],
onProgress: (curr, total) => console.log(`${curr}/${total}`),
});📋 API Reference
| Function | Description |
| ------------------------------------ | ---------------------------------------------- |
| generateInteractiveButtonMessage() | Buat button message dengan media header |
| generateInteractiveListMessage() | Buat list message dengan sections |
| generateTemplateMessage() | Buat template message (Quick Reply, URL, Call) |
| generateNativeFlowMessage() | Buat native flow message (format terbaru) |
| generateCopyCodeButton() | Button untuk copy code |
| generateUrlButtonMessage() | Button dengan URL |
| generateQuickReplyButtons() | Quick reply buttons |
| generateCombinedButtons() | Gabungan berbagai jenis button |
| Function | Description |
| --------------------------- | ----------------------------------------- |
| parseJid() | Parse JID dan extract info lengkap |
| getSenderPn() | Get senderPn dari AuthenticationCreds |
| getCurrentSenderInfo() | Get current sender info dari authState |
| isSelf() | Check apakah JID adalah diri sendiri |
| plotJid() | Plot JID (basic, tanpa LID mapping) |
| normalizePhoneToJid() | Normalize nomor ke JID |
| extractPhoneNumber() | Extract phone number dari JID |
| formatJidDisplay() | Format JID untuk display |
| isSameUser() | Compare dua JID |
| getJidVariants() | Get semua variant JID dari nomor |
| constructJidWithDevice() | Construct JID dengan device ID |
| getRemoteJidFromMessage() | Get remoteJid dari message |
| createJidPlotter() | Create plotter dengan LID mapping support |
| Function | Description |
| ------------------------------- | ------------------------- |
| newsletterCreate() | Buat channel baru |
| newsletterUpdateName() | Update nama channel |
| newsletterUpdateDescription() | Update deskripsi channel |
| newsletterUpdatePicture() | Update foto channel |
| newsletterFollow() | Follow channel |
| newsletterUnfollow() | Unfollow channel |
| newsletterMute() | Mute notifikasi channel |
| newsletterUnmute() | Unmute notifikasi channel |
| newsletterReactMessage() | React ke pesan channel |
| newsletterMetadata() | Get metadata channel |
| newsletterAdminCount() | Get jumlah admin |
| newsletterChangeOwner() | Ganti owner channel |
| newsletterDemote() | Demote admin channel |
| newsletterDelete() | Hapus channel |
| Function | Description |
| --------------------------- | -------------------------------- |
| groupCreate() | Buat grup baru |
| groupUpdateSubject() | Update nama grup |
| groupUpdateDescription() | Update deskripsi grup |
| groupParticipantsUpdate() | Add/remove/promote/demote member |
| groupSettingUpdate() | Update pengaturan grup |
| groupMetadata() | Get metadata grup |
| groupLeave() | Keluar dari grup |
| groupInviteCode() | Get kode invite grup |
| groupAcceptInvite() | Join grup via invite code |
| Type | Description |
| ---------- | ------------------------------------------------------- |
| text | Pesan teks biasa |
| image | Kirim gambar (dengan opsi hd: true untuk kualitas HD) |
| video | Kirim video (dengan opsi hd: true untuk kualitas HD) |
| audio | Kirim audio |
| document | Kirim dokumen |
| sticker | Kirim sticker |
| location | Kirim lokasi |
| contacts | Kirim kontak |
| poll | Buat polling |
| album | Kirim album (multiple media) |
| react | React ke pesan |
| edit | Edit pesan |
| delete | Hapus pesan |
| Function | Description |
| -------------------------------- | ------------------------------------------------- |
| updateProfilePicture() | Update foto profil (square crop) |
| updatePanoramaProfilePicture() | Update foto profil panorama (wide, tidak di-crop) |
| removeProfilePicture() | Hapus foto profil |
| profilePictureUrl() | Get URL foto profil |
| Function | Description |
| ------------------------------- | ----------------------------------- |
| MiniGamesManager | Main class untuk manage semua games |
| games.startGuessNumber() | Start guess number game |
| games.startQuiz() | Start quiz game |
| games.startTicTacToe() | Start TicTacToe (vs bot/player) |
| games.playRockPaperScissors() | Play RPS game
