WhatsApp Web API with Interactive Buttons, List Messages, Albums, AI Messages, Polls, LID/SenderPn Plotting, Mini Games, Content Detection, Anti-Spam - A feature-rich Baileys fork
npm install baileys-joss
WhatsApp Web API Library dengan Fitur Ekstra Premium
Fork dari Baileys dengan penambahan fitur Interactive Button, Albums, AI Message, LID Plotting, dan lainnya.
📦 Installation •
✨ Features •
🚀 Quick Start •
💡 Examples •
📋 API •
🤝 Contributing
📖 Documentation:
🇮🇩 Indonesia |
🇺🇸 English
🎮 Full Demo:
📝 Complete Example Code (Gist) |
📁 Local Example File
| 🎯 Feature | Baileys Original | Baileys-Joss |
|---|---|---|
| 🖱️ Interactive Buttons | ❌ | ✅ |
| 📋 List Messages | ❌ | ✅ |
| 📋 Copy Code Button | ❌ | ✅ |
| 🔗 URL Buttons | ❌ | ✅ |
| 🔄 Combined Button Types | ❌ | ✅ |
| 🎨 Native Flow Messages | ❌ | ✅ |
| 👤 LID/SenderPn Plotting | ❌ | ✅ |
| 🖼️ Album Messages | ❌ | ✅ |
| 🤖 AI Message Style | ❌ | ✅ |
| 📊 Poll Creation | ✅ | ✅ Enhanced |
| 📢 Newsletter/Channel Control | ✅ | ✅ Enhanced |
| 🔐 Custom Pairing Code | ❌ | ✅ |
| 📷 HD Profile Pictures | ✅ | ✅ |
| 🔧 Fixed Button Delivery | ❌ | ✅ |
| 📸 HD Images (Uncompressed) | ❌ | ✅ |
| 🎬 HD Videos (Uncompressed) | ❌ | ✅ |
| 🌄 Panorama Profile Picture | ❌ | ✅ |
| 📅 Message Scheduling | ❌ | ✅ |
| 📨 Bulk Messaging | ❌ | ✅ |
| 🔄 Auto Reply System | ❌ | ✅ |
| 📇 Contact Card (vCard) | ⚠️ Basic | ✅ Enhanced |
| 📺 Status/Story Posting | ⚠️ Basic | ✅ Enhanced |
| 🎤 Voice Note Helper | ❌ | ✅ |
| 📋 Message Templates | ❌ | ✅ |
| 📡 Broadcast Manager | ❌ | ✅ |
| ⌨️ Typing Indicator | ⚠️ Basic | ✅ Enhanced |
| ✅ Read Receipt Control | ⚠️ Basic | ✅ Enhanced |
| 🔍 Message Search | ❌ | ✅ |
| 📊 Chat Analytics | ❌ | ✅ |
| 💾 Chat Export | ❌ | ✅ |
| 🔗 QR Code Generator | ⚠️ Basic | ✅ Enhanced |
| 📁 Media Downloader | ❌ | ✅ |
| 🎮 Mini Games | ❌ | ⚠️ Untested |
| 🔍 Content Detector | ❌ | ⚠️ Untested |
| 🛡️ Anti-Spam System | ❌ | ⚠️ Untested |
| 🔗 Link Scanner | ❌ | ⚠️ Untested |
| 📝 Activity Logger | ❌ | ⚠️ Untested |
| 🎭 Meme Generator | ❌ | ⚠️ Untested |
| 🍅 Pomodoro Timer | ❌ | ⚠️ Untested |
| 💬 Quote Generator | ❌ | ⚠️ Untested |
| 🌤️ Weather Bot | ❌ | ⚠️ Untested |
bash
Menggunakan npm
npm install baileys-joss
Menggunakan yarn
yarn add baileys-joss
Menggunakan pnpm
pnpm add baileys-joss
`
📦 Via package.json (Fork Override)
`json
// Untuk mengganti @whiskeysockets/baileys
{
"dependencies": {
"@whiskeysockets/baileys": "npm:baileys-joss"
}
}
// Untuk mengganti @adiwajshing/baileys
{
"dependencies": {
"@adiwajshing/baileys": "npm:baileys-joss"
}
}
`
---
🎯 Features
🖱️ Interactive Messages & Buttons
Fitur button interactive yang lebih lengkap dan mudah digunakan:
`typescript
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)
`
🖼️ Album Messages (Carousel)
Kirim beberapa gambar/video sekaligus dalam format album:
`typescript
// 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 })
`
🤖 AI Message Style
Tambahkan ikon AI stylish pada pesan:
`typescript
// 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
})
`
📸 HD Images & Videos (Uncompressed)
Kirim gambar dan video tanpa kompresi dalam kualitas HD:
`typescript
// 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'
})
`
🌄 Panorama Profile Picture
Set foto profil panorama (wide) tanpa cropping:
`typescript
// 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' })
`
📊 Poll Creation
Buat polling dengan mudah:
`typescript
// 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 })
`
📢 Newsletter/Channel Control
Kelola WhatsApp Channel dengan lengkap:
`typescript
// 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)
`
🔐 Custom Pairing Code
Generate custom alphanumeric pairing code:
`typescript
// 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)
`
📍 LID & SenderPn Plotting
Utilities untuk mengelola JID, LID (Linked ID), dan senderPn:
`typescript
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('6281234567890@s.whatsapp.net')
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') // -> 6281234567890@s.whatsapp.net
// Extract phone number dari JID
const phone = extractPhoneNumber('6281234567890@s.whatsapp.net') // -> 6281234567890
// Format untuk display
const display = formatJidDisplay('6281234567890:1@s.whatsapp.net', {
showDevice: true,
showType: true
}) // -> 6281234567890:1 (PN)
// Compare dua JID
const same = isSameUser('6281234567890@s.whatsapp.net', '6281234567890:1@s.whatsapp.net') // 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('6281234567890@s.whatsapp.net')
console.log('Phone:', plotted.pn)
console.log('LID:', plotted.lid)
`
📍 Location Sharing
Kirim lokasi dengan mudah:
`typescript
// Send location
await sock.sendMessage(jid, {
location: {
degreesLatitude: -6.2088,
degreesLongitude: 106.8456,
name: 'Jakarta, Indonesia',
address: 'Jl. Sudirman, Jakarta Pusat'
}
})
`
👥 Group Management
Kelola grup dengan lengkap:
`typescript
// Create group
const group = await sock.groupCreate('My Group', ['6281234567890@s.whatsapp.net'])
// Update group info
await sock.groupUpdateSubject(groupJid, 'New Group Name')
await sock.groupUpdateDescription(groupJid, 'New description')
// Manage participants
await sock.groupParticipantsUpdate(groupJid, ['6281234567890@s.whatsapp.net'], 'add')
await sock.groupParticipantsUpdate(groupJid, ['6281234567890@s.whatsapp.net'], 'remove')
await sock.groupParticipantsUpdate(groupJid, ['6281234567890@s.whatsapp.net'], 'promote')
await sock.groupParticipantsUpdate(groupJid, ['6281234567890@s.whatsapp.net'], '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
`typescript
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
📬 Newsletter Control
`typescript
// 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)
`
📌 Interactive Messaging
`typescript
// 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)
`
🖼️ Send Album
`typescript
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 🌴'
})
`
🔐 Pairing with Custom Code
`typescript
// 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)
`
📊 Poll Creation
`typescript
const pollMessage = {
name: '🎬 Film Favorit Weekend Ini?',
values: [
'🦸 Superhero Movie',
'😂 Comedy',
'😱 Horror',
'💑 Romance'
],
selectableCount: 1
}
await sock.sendMessage(jid, { poll: pollMessage })
`
📍 Location Sharing
`typescript
await sock.sendMessage(jid, {
location: {
degreesLatitude: -6.2088,
degreesLongitude: 106.8456,
name: 'Monas Jakarta',
address: 'Jalan Medan Merdeka, Jakarta Pusat'
}
})
`
👥 Group Management
`typescript
// Create group
const group = await sock.groupCreate('My Awesome Group', [
'6281234567890@s.whatsapp.net',
'6281234567891@s.whatsapp.net'
])
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, [
'6281234567892@s.whatsapp.net'
], 'add')
`
---
🆕 Baileys-Joss v1.0.2 New Features
📅 Message Scheduling
Jadwalkan pesan untuk dikirim otomatis di waktu tertentu:
`typescript
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(
'6281234567890@s.whatsapp.net',
{ 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()
`
📨 Bulk Messaging
Kirim pesan massal ke banyak kontak dengan rate limiting:
`typescript
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 = [
'6281234567890@s.whatsapp.net',
'6281234567891@s.whatsapp.net',
'6281234567892@s.whatsapp.net'
]
const results = await bulkSender.sendToMany(jids, { text: 'Hello everyone!' })
// Kirim pesan berbeda ke JID berbeda
const messages = [
{ jid: '6281...@s.whatsapp.net', content: { text: 'Hi John!' } },
{ jid: '6282...@s.whatsapp.net', content: { text: 'Hi Jane!' } }
]
await bulkSender.send(messages)
// Method 2: Quick helper
await sendBulkMessages(
(jid, content) => sock.sendMessage(jid, content),
jids,
{ text: 'Broadcast message' }
)
`
🔄 Auto Reply System
Sistem balasan otomatis berdasarkan keyword/pattern:
`typescript
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)
}
}
})
`
📇 Contact Card (vCard)
Kirim kartu kontak lengkap dengan detail:
`typescript
import {
createContactCard,
createContactCards,
quickContact,
generateVCard
} from 'baileys-joss'
// Quick contact (simple)
const simple = quickContact('John Doe', '+628123456789', {
organization: 'PT Example',
email: 'john@example.com'
})
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: 'john@hospital.com', type: 'WORK' },
{ email: 'john.personal@gmail.com', 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)
`
📺 Status/Story Posting
Posting status WhatsApp (foto, video, text):
`typescript
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! 🎭'
))
// Post voice note status
await sock.sendMessage(statusJid, StatusHelper.voiceNote(audioBuffer))
// 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'
}))
`
🎤 Voice Note Helper
Rekam dan kirim voice note dengan PTT mode:
`typescript
import {
createVoiceNote,
createAudioMessage,
VoiceNoteHelper
} from 'baileys-joss'
// Simple voice note from buffer
const voiceNote = await VoiceNoteHelper.fromBuffer(audioBuffer, 15) // 15 seconds
await sock.sendMessage(jid, voiceNote)
// Voice note from file
const vnFromFile = await VoiceNoteHelper.fromFile('./recording.mp3')
await sock.sendMessage(jid, vnFromFile)
// Regular audio (not PTT)
const audio = await VoiceNoteHelper.audioFromBuffer(audioBuffer)
await sock.sendMessage(jid, audio)
// Check if FFmpeg is available (for conversions)
const hasFFmpeg = await VoiceNoteHelper.checkFFmpeg()
// Convert audio to Opus (WhatsApp format)
const opusBuffer = await VoiceNoteHelper.toOpus(mp3Buffer)
// Get audio duration
const duration = await VoiceNoteHelper.getDuration(audioBuffer)
console.log(Audio duration: ${duration} seconds)
// Full control with createVoiceNote
const customVN = await createVoiceNote(audioBuffer, {
seconds: 30,
sampleRate: 48000,
channels: 1
})
await sock.sendMessage(jid, customVN)
`
📋 Message Templates
Template pesan siap pakai untuk berbagai keperluan:
`typescript
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}}! 👋
,
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 existing
`
📡 Broadcast Manager
Kelola dan kirim ke broadcast list:
`typescript
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: [
'6281234567890@s.whatsapp.net',
'6281234567891@s.whatsapp.net'
]
})
// Add more recipients
broadcast.addRecipients(customerList.id, [
'6281234567892@s.whatsapp.net'
])
// 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)
`
⌨️ Typing Indicator
Simulasi sedang mengetik:
`typescript
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()
`
✅ Read Receipt Control
Kontrol centang biru:
`typescript
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: ['blocked@s.whatsapp.net']
}
)
// 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
})
`
🔍 Message Search
Cari pesan dalam chat:
`typescript
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('6281234567890@s.whatsapp.net')
// Quick search (without manager)
const quickResults = searchMessages(messages, 'keyword', {
jid: specificChatJid,
fromMe: false
})
`
📊 Chat Analytics
Statistik dan analitik chat:
`typescript
import { createChatAnalytics } from 'baileys-joss'
const analytics = createChatAnalytics()
// Add messages for analysis
analytics.addMessages(allMessages)
// Get stats for specific chat
const chatStats = analytics.getChatStats('6281234567890@s.whatsapp.net')
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)
}
`
💾 Chat Export
Export chat ke JSON, HTML, TXT, atau CSV:
`typescript
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' })
`
🎮 Mini Games (UNTESTED ⚠️)
Game sederhana untuk chat interaktif:
`typescript
import {
MiniGamesManager,
createTicTacToeGame,
createQuiz
} from 'baileys-joss'
// Create games manager
const games = new MiniGamesManager()
// 🎯 Guess Number Game
const guessSession = games.startGuessNumber('6281234567890@s.whatsapp.net', {
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)
`
🔍 Content Detector (UNTESTED ⚠️)
Deteksi otomatis berbagai jenis konten dalam pesan:
`typescript
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}
})
}
`
🛡️ Anti-Spam System (UNTESTED ⚠️)
Sistem untuk mendeteksi dan mencegah spam:
`typescript
import { AntiSpamManager } from 'baileys-joss'
// Create anti-spam manager
const antispam = new AntiSpamManager({
maxMessagesPerMinute: 15,
maxDuplicates: 3,
duplicateWindow: 60000, // 1 minute
minMessageDelay: 500,
whitelist: ['admin@s.whatsapp.net'],
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('trusteduser@s.whatsapp.net')
// Mute spammer temporarily
antispam.muteUser('spammer@s.whatsapp.net', 3600) // 1 hour
// Ban repeat offender
antispam.banUser('baduser@s.whatsapp.net')
// Get spam statistics
const stats = antispam.getStats()
console.log('Total spam blocked:', stats.totalBlocked)
`
🔗 Link Scanner (UNTESTED ⚠️)
Scan dan validasi URL untuk keamanan:
`typescript
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 })
}
}
})
`
📝 Activity Logger (UNTESTED ⚠️)
Logging aktivitas untuk audit trail:
`typescript
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('6281234567890@s.whatsapp.net', 'command_executed', {
command: '/help',
success: true
})
// Log group action
logger.logGroupAction('groupjid@g.us', 'member_added', {
addedBy: 'admin@s.whatsapp.net',
newMember: 'newuser@s.whatsapp.net'
})
// 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')
`
🎭 Meme Generator (UNTESTED ⚠️)
Generate meme sederhana dengan text overlay:
`typescript
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}
})
`
🍅 Pomodoro Timer (UNTESTED ⚠️)
Timer produktivitas dengan teknik Pomodoro:
`typescript
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('6281234567890@s.whatsapp.net', {
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)
`
💬 Quote Generator (UNTESTED ⚠️)
Random quotes dan quotes harian:
`typescript
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 })
`
🌤️ Weather Bot (UNTESTED ⚠️)
Informasi cuaca dengan integrasi OpenWeatherMap:
`typescript
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 })
`
🔗 QR Code Generator
Generate QR code custom untuk pairing:
`typescript
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)
}
})
`
📁 Media Downloader
Download semua media dari chat:
`typescript
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(
'6281234567890@s.whatsapp.net',
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
🖱️ Interactive Messages
| 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 |
📍 JID Plotting
| 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 |
📢 Newsletter/Channel
| 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 |
👥 Group Management
| 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