npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kyuuna/baileys

v2.0.9

Published

@kyuuna/baileys

Readme

@kyuuna/baileys

🚀 High-Performance Pterodactyl Panel Server - Full Admin Support

🌟 ACCESS KYUUNA PANEL

https://kyuuna.my.id/

High-performance Pterodactyl Panel Server with full admin support ⚡️

Below is a high-performance Pterodactyl server panel with full admin support.


Run Your WhatsApp Bot with Panel

Launch your WhatsApp bot with our powerful and modern Panel! Get access to the best server infrastructure with cutting-edge cloud.

💝 Donation (Solana)

8xN639anSq5q64793tseCjPaXNgXEPaKxr91CKEuggKd

🤖 @kyuuna/baileys

@kyuuna/baileys is a modern TypeScript-based library for WhatsApp Web API integration, with fixes for @lid/@jid issues in groups.


✨ Key Features

🚀 Modern & Fast — TypeScript & WebSocket based
🔧 Fix @lid & @jid — group identity fixes
📱 Multi-Device — supports WhatsApp multi-device
🔐 End-to-End Encryption — fully encrypted communication
📨 All Message Types — text, media, polls, albums, stories, broadcasts
🎯 Easy to Use — intuitive & flexible API

⚠️ Disclaimer: Not affiliated with WhatsApp. Use responsibly, avoid spam & prohibited activities.


📦 Installation

Stable:

npm install @kyuuna/baileys

Edge (latest features):

npm install @kyuuna/baileys@latest

Yarn:

yarn add @kyuuna/baileys

Import:

import makeWASocket from "@kyuuna/baileys"

🚀 Quick Start

Basic Connection

import makeWASocket, { DisconnectReason, useMultiFileAuthState } from "@kyuuna/baileys"
import { Boom } from "@hapi/boom"

async function connectToWhatsApp() {
    const { state, saveCreds } = await useMultiFileAuthState("auth_info_baileys")
    const sock = makeWASocket({
        auth: state,
        printQRInTerminal: true,
        browser: ["@kyuuna/baileys", "Desktop", "3.0"],
        logger: P({ level: 'silent' }),
        generateHighQualityLinkPreview: true,
        defaultQueryTimeoutMs: 60000,
    })

    sock.ev.on("connection.update", ({ connection, lastDisconnect, qr }) => {
        if (qr) {
            console.log("📱 Scan this QR code with your WhatsApp")
        }
        if (connection === "close") {
            const shouldReconnect = (lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
            console.log("❌ Connection closed. Reconnecting:", shouldReconnect)
            if (shouldReconnect) {
                setTimeout(connectToWhatsApp, 3000)
            }
        } else if (connection === "open") {
            console.log("✅ Connected to WhatsApp successfully!")
        }
    })

    sock.ev.on("messages.upsert", async ({ messages }) => {
        for (const m of messages) {
            if (!m.message) continue
            console.log("📩 New message:", JSON.stringify(m, undefined, 2))
            
            // Auto reply example
            if (m.message.conversation === "hi") {
                await sock.sendMessage(m.key.remoteJid!, { 
                    text: "Hello! I'm powered by @kyuuna/baileys 🤖" 
                })
            }
        }
    })

    sock.ev.on("creds.update", saveCreds)
    return sock
}

connectToWhatsApp()

🔑 Authentication Methods

1. QR Code Login

import makeWASocket from "@kyuuna/baileys"

const sock = makeWASocket({
    printQRInTerminal: true,
    browser: ["KYUUNABaileys", "Chrome", "4.0.0"]
})

2. Pairing Code Login

import makeWASocket, { useMultiFileAuthState } from "@kyuuna/baileys"

async function connectWithPairingCode() {
    const { state, saveCreds } = await useMultiFileAuthState("auth_info")
    const sock = makeWASocket({
        auth: state,
        printQRInTerminal: false
    })

    if (!sock.authState.creds.registered) {
        const phoneNumber = "6281234567890" // your phone number
        const code = await sock.requestPairingCode(phoneNumber)
        console.log("🔑 Pairing Code:", code)
    }

    sock.ev.on("creds.update", saveCreds)
    return sock
}

3. Custom Pairing Code

async function connectWithCustomPairing() {
    const { state, saveCreds } = await useMultiFileAuthState("auth_info")
    const sock = makeWASocket({
        auth: state,
        printQRInTerminal: false
    })

    if (!sock.authState.creds.registered) {
        const phoneNumber = "6281234567890"
        const customPair = "KYUUNA25" // 8 characters
        const code = await sock.requestPairingCode(phoneNumber, customPair)
        console.log("🔑 Custom Pairing Code:", code)
    }

    sock.ev.on("creds.update", saveCreds)
    return sock
}

4. Session Restoration

import { useMultiFileAuthState } from "@kyuuna/baileys"

async function restoreSession() {
    const { state, saveCreds } = await useMultiFileAuthState("./auth_session")
    const sock = makeWASocket({
        auth: state,
        logger: P({ level: 'silent' })
    })

    sock.ev.on("creds.update", saveCreds)
    return sock
}

📩 Basic Messaging

Send Text Message

// Simple text
await sock.sendMessage("[email protected]", { 
    text: "Hello from @kyuuna/baileys!" 
})

// With formatting
await sock.sendMessage(jid, { 
    text: "*Bold* _italic_ ~strikethrough~ ```monospace```" 
})

// Long text with preview
await sock.sendMessage(jid, {
    text: "Check out this amazing library: https://github.com/kyuuna-network/baileys",
    linkPreview: true
})

Receive Messages

sock.ev.on("messages.upsert", async ({ messages }) => {
    for (const message of messages) {
        if (!message.message) continue

        const sender = message.key.remoteJid
        const messageType = Object.keys(message.message)[0]
        
        console.log(`📨 Message from ${sender}: ${messageType}`)

        switch (messageType) {
            case 'conversation':
                console.log("Text:", message.message.conversation)
                break
            case 'extendedTextMessage':
                console.log("Extended text:", message.message.extendedTextMessage.text)
                break
            case 'imageMessage':
                console.log("Image received with caption:", message.message.imageMessage.caption)
                break
            case 'videoMessage':
                console.log("Video received")
                break
        }
    }
})

Reply/Quote Messages

// Quote reply
await sock.sendMessage(jid, { 
    text: "This is a quoted reply!" 
}, { 
    quoted: message 
})

// Reply with different content types
await sock.sendMessage(jid, {
    image: { url: "./image.jpg" },
    caption: "Replied with image"
}, { quoted: message })

Mention Users

// Single mention
await sock.sendMessage(jid, {
    text: "Hello @6281234567890!",
    mentions: ["[email protected]"]
})

// Multiple mentions
await sock.sendMessage(jid, {
    text: "Meeting today @6281234567890 @6289876543210 at 2 PM",
    mentions: [
        "[email protected]",
        "[email protected]"
    ]
})

// Mention all in group
const groupMetadata = await sock.groupMetadata(jid)
const participants = groupMetadata.participants.map(p => p.id)
await sock.sendMessage(jid, {
    text: "Hello everyone! 👋",
    mentions: participants
})

🎨 Interactive Messages & Buttons

Simple Text Buttons

await sock.sendMessage(jid, {
    text: "Welcome! Choose an option:",
    footer: "Powered by @kyuuna/baileys",
    buttons: [
        { buttonId: "menu", buttonText: { displayText: "📋 Main Menu" }, type: 1 },
        { buttonId: "help", buttonText: { displayText: "❓ Help" }, type: 1 },
        { buttonId: "about", buttonText: { displayText: "ℹ️ About" }, type: 1 }
    ],
    headerType: 1
})

Advanced Interactive Buttons

await sock.sendMessage(jid, {
    text: "🚀 Choose your action:",
    interactiveButtons: [
        {
            name: "quick_reply",
            buttonParamsJson: JSON.stringify({
                display_text: "⚡ Quick Reply",
                id: "quick_reply_1"
            })
        },
        {
            name: "cta_url",
            buttonParamsJson: JSON.stringify({
                display_text: "🌐 Visit Website",
                url: "https://kyuuna.my.id",
                merchant_url: "https://kyuuna.my.id"
            })
        },
        {
            name: "cta_copy",
            buttonParamsJson: JSON.stringify({
                display_text: "📋 Copy Code",
                id: "copy_code",
                copy_code: "KYUUNA2025"
            })
        },
        {
            name: "cta_call",
            buttonParamsJson: JSON.stringify({
                display_text: "📞 Call Support",
                phone_number: "+6281234567890"
            })
        }
    ]
})

List Messages

await sock.sendMessage(jid, {
    text: "Select a service:",
    buttonText: "View Options",
    sections: [
        {
            title: "🔧 Development Services",
            rows: [
                { title: "WhatsApp Bot", description: "Custom WhatsApp automation", rowId: "service_bot" },
                { title: "Web Development", description: "Modern web applications", rowId: "service_web" },
                { title: "Mobile App", description: "iOS & Android apps", rowId: "service_mobile" }
            ]
        },
        {
            title: "☁️ Cloud Services",
            rows: [
                { title: "Server Hosting", description: "High-performance servers", rowId: "service_hosting" },
                { title: "Database", description: "Managed databases", rowId: "service_database" },
                { title: "CDN", description: "Content delivery network", rowId: "service_cdn" }
            ]
        }
    ]
})

Rich Media with Buttons

await sock.sendMessage(jid, {
    image: { url: "https://kyuuna.my.id/assets/banner.png" },
    caption: "🚀 Welcome to KYUUNA Services!\n\nHigh-performance solutions for modern businesses.",
    footer: "KYUUNA Network © 2025",
    interactiveButtons: [
        {
            name: "quick_reply",
            buttonParamsJson: JSON.stringify({
                display_text: "📋 Get Started",
                id: "get_started"
            })
        },
        {
            name: "cta_url",
            buttonParamsJson: JSON.stringify({
                display_text: "🌐 Visit Panel",
                url: "https://kyuuna.my.id"
            })
        }
    ]
})

🎥 Media Messages

Images

// Send image from URL
await sock.sendMessage(jid, {
    image: { url: "https://example.com/image.jpg" },
    caption: "Beautiful sunset 🌅"
})

// Send image from buffer
import fs from 'fs'
const imageBuffer = fs.readFileSync('./local-image.png')
await sock.sendMessage(jid, {
    image: imageBuffer,
    caption: "Local image with caption"
})

// Send with view once
await sock.sendMessage(jid, {
    image: { url: "./secret.jpg" },
    caption: "This will disappear after viewing! 👁️",
    viewOnce: true
})

// Send as sticker
await sock.sendMessage(jid, {
    sticker: { url: "./sticker.webp" }
})

Videos

// Video with caption
await sock.sendMessage(jid, {
    video: { url: "https://example.com/video.mp4" },
    caption: "Amazing video content! 🎬",
    jpegThumbnail: thumbnailBuffer // optional thumbnail
})

// GIF support
await sock.sendMessage(jid, {
    video: { url: "./animation.gif" },
    caption: "Animated GIF",
    gifPlayback: true
})

// Video note (circular video)
await sock.sendMessage(jid, {
    video: { url: "./video-note.mp4" },
    videoNote: true
})

Audio & Voice

// Audio file
await sock.sendMessage(jid, {
    audio: { url: "./music.mp3" },
    mimetype: "audio/mp3",
    fileName: "awesome-song.mp3"
})

// Voice note (PTT)
await sock.sendMessage(jid, {
    audio: { url: "./voice-note.ogg" },
    mimetype: "audio/ogg; codecs=opus",
    ptt: true
})

// Audio with waveform
await sock.sendMessage(jid, {
    audio: { url: "./audio.mp3" },
    mimetype: "audio/mp3",
    waveform: [0,1,2,3,4,5,6,7,8,9], // optional waveform
    contextInfo: {
        externalAdReply: {
            title: "Now Playing",
            body: "Artist - Song Title",
            thumbnailUrl: "https://example.com/cover.jpg",
            sourceUrl: "https://music-platform.com/song"
        }
    }
})

Documents

// Send document
await sock.sendMessage(jid, {
    document: { url: "./document.pdf" },
    mimetype: "application/pdf",
    fileName: "important-document.pdf",
    caption: "Please review this document 📄"
})

// Excel file
await sock.sendMessage(jid, {
    document: { url: "./spreadsheet.xlsx" },
    mimetype: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    fileName: "data-report.xlsx"
})

// Word document
await sock.sendMessage(jid, {
    document: { url: "./report.docx" },
    mimetype: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    fileName: "monthly-report.docx"
})

🏟️ Location & Contact

Send Location

// Point location
await sock.sendMessage(jid, {
    location: {
        degreesLatitude: -6.2088,
        degreesLongitude: 106.8456,
        name: "KYUUNA, KYUUNA",
        address: "KYUUNA Special Capital Region, KYUUNA"
    }
})

// Live location (for 60 seconds)
await sock.sendMessage(jid, {
    liveLocation: {
        degreesLatitude: -6.2088,
        degreesLongitude: 106.8456,
        caption: "I'm here! 📍",
        sequenceNumber: 1,
        timeOffset: 60
    }
})

Send Contact

// Single contact
await sock.sendMessage(jid, {
    contacts: {
        displayName: "John Doe",
        contacts: [{
            vcard: `BEGIN:VCARD
VERSION:3.0
FN:John Doe
ORG:KYUUNA Network
TEL;type=CELL;type=VOICE;waid=6281234567890:+62 812-3456-7890
END:VCARD`
        }]
    }
})

// Multiple contacts
await sock.sendMessage(jid, {
    contacts: {
        displayName: "Team Contacts",
        contacts: [
            {
                displayName: "John Doe",
                vcard: "BEGIN:VCARD\nVERSION:3.0\nFN:John Doe\nTEL:+6281234567890\nEND:VCARD"
            },
            {
                displayName: "Jane Smith", 
                vcard: "BEGIN:VCARD\nVERSION:3.0\nFN:Jane Smith\nTEL:+6289876543210\nEND:VCARD"
            }
        ]
    }
})

👥 Group Management

Create & Manage Groups

// Create group
const group = await sock.groupCreate("KYUUNA Developers", [
    "[email protected]",
    "[email protected]"
])
console.log("✅ Group created:", group.id)

// Add participants
await sock.groupParticipantsUpdate(
    group.id, 
    ["[email protected]"], 
    "add"
)

// Remove participants
await sock.groupParticipantsUpdate(
    group.id,
    ["[email protected]"],
    "remove"
)

// Promote to admin
await sock.groupParticipantsUpdate(
    group.id,
    ["[email protected]"],
    "promote"
)

// Demote admin
await sock.groupParticipantsUpdate(
    group.id,
    ["[email protected]"],
    "demote"
)

Group Settings

// Update group name
await sock.groupUpdateSubject(group.id, "🚀 KYUUNA Dev Team")

// Update group description
await sock.groupUpdateDescription(group.id, 
    "Official developer group for KYUUNA Network projects.\n\n" +
    "Rules:\n• Be respectful\n• Share knowledge\n• Have fun! 🎉"
)

// Update group photo
const groupPhoto = fs.readFileSync('./group-photo.jpg')
await sock.updateProfilePicture(group.id, groupPhoto)

// Group settings
await sock.groupSettingUpdate(group.id, 'announcement') // Only admins can send
await sock.groupSettingUpdate(group.id, 'not_announcement') // Everyone can send
await sock.groupSettingUpdate(group.id, 'locked') // Only admins can edit info
await sock.groupSettingUpdate(group.id, 'unlocked') // Everyone can edit info

Group Information

// Get group metadata
const groupInfo = await sock.groupMetadata(group.id)
console.log("Group Info:", {
    name: groupInfo.subject,
    description: groupInfo.desc,
    participantCount: groupInfo.participants.length,
    admins: groupInfo.participants.filter(p => p.admin).map(p => p.id)
})

// Get group participants
const participants = await sock.groupMetadata(group.id)
participants.participants.forEach(participant => {
    console.log(`${participant.id} - ${participant.admin || 'member'}`)
})

// Leave group
await sock.groupLeave(group.id)

🔔 Message Status & Reactions

Message Reactions

// Add reaction
await sock.sendMessage(jid, {
    react: {
        text: "❤️", // emoji
        key: message.key
    }
})

// Remove reaction
await sock.sendMessage(jid, {
    react: {
        text: "",
        key: message.key
    }
})

// Multiple reactions example
const reactions = ["👍", "❤️", "😂", "😮", "😢", "🙏"]
const randomReaction = reactions[Math.floor(Math.random() * reactions.length)]
await sock.sendMessage(jid, {
    react: {
        text: randomReaction,
        key: message.key
    }
})

Read Receipts & Presence

// Mark as read
await sock.readMessages([message.key])

// Send presence (typing, recording, etc.)
await sock.sendPresenceUpdate('composing', jid) // typing
await sock.sendPresenceUpdate('recording', jid) // recording audio
await sock.sendPresenceUpdate('paused', jid) // stopped typing

// Available/Unavailable
await sock.sendPresenceUpdate('available')
await sock.sendPresenceUpdate('unavailable')

🔒 Privacy Settings

Update Privacy Settings

// Last seen privacy
await sock.updateLastSeenPrivacy('all') // everyone can see
await sock.updateLastSeenPrivacy('contacts') // only contacts
await sock.updateLastSeenPrivacy('contact_blacklist') // contacts except...
await sock.updateLastSeenPrivacy('none') // nobody can see

// Online status privacy
await sock.updateOnlinePrivacy('all')
await sock.updateOnlinePrivacy('match_last_seen')

// Profile photo privacy
await sock.updateProfilePicturePrivacy('all')
await sock.updateProfilePicturePrivacy('contacts')
await sock.updateProfilePicturePrivacy('none')

// Status privacy
await sock.updateStatusPrivacy('all')
await sock.updateStatusPrivacy('contacts')
await sock.updateStatusPrivacy('contact_blacklist')

// Read receipts
await sock.updateReadReceiptsPrivacy('all')
await sock.updateReadReceiptsPrivacy('none')

// Groups add privacy
await sock.updateGroupsAddPrivacy('all')
await sock.updateGroupsAddPrivacy('contacts')
await sock.updateGroupsAddPrivacy('contact_blacklist')

Block/Unblock Users

// Block user
await sock.updateBlockStatus("[email protected]", "block")

// Unblock user
await sock.updateBlockStatus("[email protected]", "unblock")

// Get blocked list
const blockedUsers = await sock.fetchBlocklist()
console.log("Blocked users:", blockedUsers)

🛠️ Utility Functions

Profile Management

// Get profile picture URL
const ppUrl = await sock.profilePictureUrl("[email protected]", "image")
console.log("Profile picture:", ppUrl)

// Update your profile picture
const newProfilePic = fs.readFileSync('./my-new-photo.jpg')
await sock.updateProfilePicture(sock.user.id, newProfilePic)

// Update profile name
await sock.updateProfileName("KYUUNA Bot")

// Update status/about
await sock.updateProfileStatus("Building the future with @kyuuna/baileys 🚀")

// Get user status
const userStatus = await sock.fetchStatus("[email protected]")
console.log("User status:", userStatus)

Business Profile

// Get business profile
const businessProfile = await sock.getBusinessProfile("[email protected]")
console.log("Business info:", businessProfile)

// Update business profile
await sock.updateBusinessProfile({
    description: "We provide high-performance server solutions",
    email: "[email protected]",
    category: "Technology",
    address: "KYUUNA, KYUUNA",
    website: ["https://kyuuna.my.id"]
})

Message Information

// Get message info (read receipts)
const messageInfo = await sock.messageInfo(jid, message.key.id)
console.log("Message info:", messageInfo)

// Search messages
const searchResults = await sock.searchMessages("hello", jid, 10, 0)
console.log("Search results:", searchResults)

// Get chat history
const messages = await sock.fetchMessageHistory(jid, 50, message.key)
console.log("Chat history:", messages)

📊 Store & Caching

In-Memory Store

import { makeInMemoryStore } from "@kyuuna/baileys"

// Create store
const store = makeInMemoryStore({
    logger: P({ level: 'silent' })
})

// Save/load store
store.readFromFile('./baileys_store.json')
setInterval(() => {
    store.writeToFile('./baileys_store.json')
}, 10_000) // save every 10 seconds

// Bind store to socket
store.bind(sock.ev)

// Use store data
const chats = store.chats.all()
const messages = store.messages[jid]?.array || []
const contacts = store.contacts

Custom Store Implementation

import { proto } from "@kyuuna/baileys"

class CustomStore {
    constructor() {
        this.chats = new Map()
        this.messages = new Map()
        this.contacts = new Map()
    }

    bind(ev) {
        ev.on('chats.set', ({ chats }) => {
            chats.forEach(chat => this.chats.set(chat.id, chat))
        })

        ev.on('messages.upsert', ({ messages }) => {
            messages.forEach(msg => {
                const jid = msg.key.remoteJid
                if (!this.messages.has(jid)) {
                    this.messages.set(jid, [])
                }
                this.messages.get(jid).push(msg)
            })
        })

        ev.on('contacts.set', ({ contacts }) => {
            contacts.forEach(contact => {
                this.contacts.set(contact.id, contact)
            })
        })
    }

    async saveToDatabase() {
        // Save to your database
        console.log("💾 Saving to database...")
    }
}

const customStore = new CustomStore()
customStore.bind(sock.ev)

🛡️ Error Handling & Best Practices

Robust Error Handling

// Retry mechanism
async function sendMessageWithRetry(jid, content, maxRetries = 3) {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            return await sock.sendMessage(jid, content)
        } catch (error) {
            console.log(`❌ Attempt ${attempt} failed:`, error.message)
            
            if (attempt === maxRetries) {
                throw new Error(`Failed to send message after ${maxRetries} attempts: ${error.message}`)
            }

            // Exponential backoff
            const delay = Math.pow(2, attempt) * 1000
            console.log(`⏳ Waiting ${delay}ms before retry...`)
            await new Promise(resolve => setTimeout(resolve, delay))
        }
    }
}

// Usage
try {
    await sendMessageWithRetry(jid, { text: "Hello with retry logic!" })
    console.log("✅ Message sent successfully")
} catch (error) {
    console.error("❌ Final send failed:", error.message)
}

Connection Management

let reconnectAttempts = 0
const maxReconnectAttempts = 5

sock.ev.on("connection.update", ({ connection, lastDisconnect }) => {
    if (connection === "close") {
        const shouldReconnect = (lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
        
        if (shouldReconnect && reconnectAttempts < maxReconnectAttempts) {
            reconnectAttempts++
            const delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000)
            
            console.log(`🔄 Reconnecting... (attempt ${reconnectAttempts}/${maxReconnectAttempts})`)
            setTimeout(connectToWhatsApp, delay)
        } else {
            console.log("❌ Max reconnection attempts reached or logged out")
            process.exit(1)
        }
    } else if (connection === "open") {
        reconnectAttempts = 0 // reset on successful connection
        console.log("✅ Connected successfully!")
    }
})

Message Queue System

class MessageQueue {
    constructor(sock) {
        this.sock = sock
        this.queue = []
        this.isProcessing = false
        this.delay = 2000 // 2 seconds between messages
    }

    add(jid, content) {
        this.queue.push({ jid, content, timestamp: Date.now() })
        this.process()
    }

    async process() {
        if (this.isProcessing || this.queue.length === 0) return

        this.isProcessing = true

        while (this.queue.length > 0) {
            const { jid, content } = this.queue.shift()
            
            try {
                await this.sock.sendMessage(jid, content)
                console.log("✅ Message sent from queue")
            } catch (error) {
                console.error("❌ Queue send failed:", error)
                // Could re-add to queue or handle differently
            }

            // Wait before next message
            await new Promise(resolve => setTimeout(resolve, this.delay))
        }

        this.isProcessing = false
    }
}

// Usage
const messageQueue = new MessageQueue(sock)
messageQueue.add(jid, { text: "Queued message 1" })
messageQueue.add(jid, { text: "Queued message 2" })

Rate Limiting

class RateLimiter {
    constructor(limit = 10, window = 60000) { // 10 messages per minute
        this.limit = limit
        this.window = window
        this.requests = new Map()
    }

    canSend(jid) {
        const now = Date.now()
        const requests = this.requests.get(jid) || []
        
        // Remove old requests outside the window
        const validRequests = requests.filter(time => now - time < this.window)
        
        this.requests.set(jid, validRequests)
        return validRequests.length < this.limit
    }

    recordRequest(jid) {
        const requests = this.requests.get(jid) || []
        requests.push(Date.now())
        this.requests.set(jid, requests)
    }
}

const rateLimiter = new RateLimiter(15, 60000) // 15 messages per minute

// Usage in message handler
sock.ev.on("messages.upsert", async ({ messages }) => {
    for (const message of messages) {
        const jid = message.key.remoteJid
        
        if (!rateLimiter.canSend(jid)) {
            console.log("⚠️ Rate limit exceeded for", jid)
            continue
        }

        // Process message
        await sock.sendMessage(jid, { text: "Response message" })
        rateLimiter.recordRequest(jid)
    }
})

🎯 Advanced Features

Story/Status Management

// Upload status
await sock.sendMessage("status@broadcast", {
    image: { url: "./status-image.jpg" },
    caption: "Check out our latest update! 🚀"
})

// Text status
await sock.sendMessage("status@broadcast", {
    text: "Working on something amazing! 💻✨",
    backgroundColor: "#FF6B6B", // background color
    font: 3 // font style
})

// Video status
await sock.sendMessage("status@broadcast", {
    video: { url: "./status-video.mp4" },
    caption: "Behind the scenes 🎬"
})

// Get status updates
sock.ev.on("messages.upsert", ({ messages }) => {
    messages.forEach(msg => {
        if (msg.key.remoteJid === "status@broadcast") {
            console.log("📱 New status update:", msg)
        }
    })
})

Broadcast Messages

// Create broadcast list
const broadcastJids = [
    "[email protected]",
    "[email protected]",
    "[email protected]"
]

// Send broadcast message
async function sendBroadcast(content) {
    const results = []
    
    for (const jid of broadcastJids) {
        try {
            await new Promise(resolve => setTimeout(resolve, 2000)) // 2s delay
            const result = await sock.sendMessage(jid, content)
            results.push({ jid, success: true, result })
            console.log(`✅ Broadcast sent to ${jid}`)
        } catch (error) {
            results.push({ jid, success: false, error: error.message })
            console.log(`❌ Broadcast failed to ${jid}:`, error.message)
        }
    }
    
    return results
}

// Usage
const broadcastResults = await sendBroadcast({
    text: "🎉 Important announcement!\n\nOur new panel is now live at https://kyuuna.my.id",
    contextInfo: {
        externalAdReply: {
            title: "KYUUNA Panel Launch",
            body: "High-performance server management",
            thumbnailUrl: "https://kyuuna.my.id/assets/banner.png",
            sourceUrl: "https://kyuuna.my.id"
        }
    }
})

console.log("📊 Broadcast results:", broadcastResults)

Advanced Media with Context

// Image with rich context
await sock.sendMessage(jid, {
    image: { url: "https://kyuuna.my.id/assets/product.jpg" },
    caption: "🚀 New server deployment ready!",
    contextInfo: {
        externalAdReply: {
            title: "High-Performance Server",
            body: "Pterodactyl Panel • 99.9% Uptime",
            thumbnailUrl: "https://kyuuna.my.id/assets/logo.png",
            sourceUrl: "https://kyuuna.my.id",
            mediaType: 1,
            renderLargerThumbnail: true
        }
    }
})

// Video with preview
await sock.sendMessage(jid, {
    video: { url: "./demo-video.mp4" },
    caption: "🎥 Watch our panel demo",
    contextInfo: {
        externalAdReply: {
            title: "Panel Demo Video",
            body: "See how easy server management can be",
            thumbnailUrl: "https://kyuuna.my.id/video-thumb.jpg",
            sourceUrl: "https://kyuuna.my.id/demo",
            mediaType: 2
        }
    }
})

// Audio with metadata
await sock.sendMessage(jid, {
    audio: { url: "./notification-sound.mp3" },
    mimetype: "audio/mp3",
    contextInfo: {
        externalAdReply: {
            title: "System Alert",
            body: "Server notification sound",
            thumbnailUrl: "https://kyuuna.my.id/audio-icon.png",
            sourceUrl: "https://kyuuna.my.id",
            mediaType: 1
        }
    }
})

Poll Messages

// Create poll
await sock.sendMessage(jid, {
    poll: {
        name: "Which feature should we prioritize next?",
        values: [
            "🚀 Performance optimization",
            "🎨 UI/UX improvements", 
            "🔐 Security enhancements",
            "📱 Mobile app",
            "🤖 AI integration"
        ],
        selectableCount: 1 // single choice
    }
})

// Multiple choice poll
await sock.sendMessage(jid, {
    poll: {
        name: "What services are you interested in? (Multiple choice)",
        values: [
            "Web Development",
            "Mobile Apps",
            "Server Hosting",
            "Database Management",
            "DevOps Services"
        ],
        selectableCount: 3 // allow up to 3 choices
    }
})

// Handle poll responses
sock.ev.on("messages.upsert", ({ messages }) => {
    messages.forEach(msg => {
        if (msg.message?.pollUpdateMessage) {
            const pollUpdate = msg.message.pollUpdateMessage
            console.log("📊 Poll vote received:", pollUpdate)
        }
    })
})

Newsletter Management

// Create newsletter
const newsletter = await sock.newsletterCreate({
    name: "KYUUNA Tech Updates",
    description: "Latest news and updates from KYUUNA Network",
    picture: fs.readFileSync("./newsletter-cover.jpg")
})

// Follow newsletter  
await sock.newsletterFollow(newsletter.id)

// Send newsletter message
await sock.sendMessage(newsletter.id, {
    text: "🚀 Monthly Tech Update\n\nNew features launched this month:\n• Enhanced performance\n• Better security\n• Mobile optimization",
    contextInfo: {
        isNewsletterMessage: true
    }
})

// Unfollow newsletter
await sock.newsletterUnfollow(newsletter.id)

🔍 Message Parsing & Utilities

Message Parser

class MessageParser {
    static extractText(message) {
        return message?.conversation || 
               message?.extendedTextMessage?.text ||
               message?.imageMessage?.caption ||
               message?.videoMessage?.caption || ""
    }

    static getMessageType(message) {
        return Object.keys(message)[0]
    }

    static isMedia(message) {
        const mediaTypes = ['imageMessage', 'videoMessage', 'audioMessage', 'documentMessage', 'stickerMessage']
        return mediaTypes.includes(this.getMessageType(message))
    }

    static extractMentions(message) {
        const text = this.extractText(message)
        const mentions = text.match(/@(\d+)/g) || []
        return mentions.map(mention => mention.replace('@', '') + '@s.whatsapp.net')
    }

    static extractUrls(message) {
        const text = this.extractText(message)
        const urlRegex = /(https?:\/\/[^\s]+)/g
        return text.match(urlRegex) || []
    }

    static isCommand(message, prefix = '!') {
        const text = this.extractText(message)
        return text.startsWith(prefix)
    }

    static parseCommand(message, prefix = '!') {
        const text = this.extractText(message)
        if (!this.isCommand(message, prefix)) return null

        const args = text.slice(prefix.length).trim().split(' ')
        const command = args.shift().toLowerCase()
        
        return { command, args }
    }
}

// Usage
sock.ev.on("messages.upsert", ({ messages }) => {
    messages.forEach(msg => {
        if (!msg.message) return

        const text = MessageParser.extractText(msg.message)
        const type = MessageParser.getMessageType(msg.message)
        
        console.log(`📝 ${type}: ${text}`)

        if (MessageParser.isCommand(msg.message)) {
            const { command, args } = MessageParser.parseCommand(msg.message)
            handleCommand(msg.key.remoteJid, command, args, msg)
        }
    })
})

async function handleCommand(jid, command, args, message) {
    switch (command) {
        case 'ping':
            await sock.sendMessage(jid, { text: '🏓 Pong!' }, { quoted: message })
            break
            
        case 'info':
            await sock.sendMessage(jid, {
                text: '🤖 Bot Information:\n' +
                      '• Version: 2.0.0\n' +
                      '• Powered by: @kyuuna/baileys\n' +
                      '• Uptime: ' + process.uptime() + 's'
            })
            break
            
        case 'weather':
            const city = args.join(' ') || 'KYUUNA'
            // Implement weather API call
            await sock.sendMessage(jid, { 
                text: `🌤️ Weather for ${city}: 28°C, Sunny` 
            })
            break
    }
}

File Download Utility

import { downloadMediaMessage } from "@kyuuna/baileys"

async function downloadAndSaveMedia(message) {
    try {
        const buffer = await downloadMediaMessage(
            message,
            'buffer',
            {},
            { 
                logger: P({ level: 'silent' }),
                reuploadRequest: sock.updateMediaMessage
            }
        )

        const messageType = Object.keys(message.message)[0]
        let extension = 'bin'
        
        switch (messageType) {
            case 'imageMessage': extension = 'jpg'; break
            case 'videoMessage': extension = 'mp4'; break
            case 'audioMessage': extension = 'mp3'; break
            case 'documentMessage': 
                extension = message.message.documentMessage.fileName?.split('.').pop() || 'pdf'
                break
        }

        const fileName = `downloads/${Date.now()}.${extension}`
        fs.writeFileSync(fileName, buffer)
        
        console.log(`💾 Media saved as: ${fileName}`)
        return { success: true, fileName, buffer }
    } catch (error) {
        console.error('❌ Download failed:', error)
        return { success: false, error: error.message }
    }
}

// Usage
sock.ev.on("messages.upsert", async ({ messages }) => {
    for (const msg of messages) {
        if (!msg.message) continue

        if (MessageParser.isMedia(msg.message)) {
            const result = await downloadAndSaveMedia(msg)
            if (result.success) {
                await sock.sendMessage(msg.key.remoteJid!, {
                    text: `✅ Media downloaded: ${result.fileName}`
                })
            }
        }
    }
})

🔧 Configuration & Environment

Environment Configuration

// .env file
/*
PHONE_NUMBER=6281234567890
SESSION_PATH=./auth_session
WEBHOOK_URL=https://your-webhook.com/whatsapp
DATABASE_URL=mongodb://localhost:27017/whatsapp_bot
REDIS_URL=redis://localhost:6379
LOG_LEVEL=info
ADMIN_NUMBERS=6281234567890,6289876543210
*/

import dotenv from 'dotenv'
dotenv.config()

const config = {
    phoneNumber: process.env.PHONE_NUMBER,
    sessionPath: process.env.SESSION_PATH || './auth_info',
    webhookUrl: process.env.WEBHOOK_URL,
    databaseUrl: process.env.DATABASE_URL,
    redisUrl: process.env.REDIS_URL,
    logLevel: process.env.LOG_LEVEL || 'info',
    adminNumbers: process.env.ADMIN_NUMBERS?.split(',') || []
}

// Advanced socket configuration
const sock = makeWASocket({
    auth: state,
    printQRInTerminal: true,
    logger: P({ level: config.logLevel }),
    browser: ["KYUUNABaileys", "Chrome", "4.0.0"],
    generateHighQualityLinkPreview: true,
    syncFullHistory: false,
    markOnlineOnConnect: true,
    fireInitQueries: true,
    emitOwnEvents: false,
    defaultQueryTimeoutMs: 60000,
    keepAliveIntervalMs: 30000,
    connectTimeoutMs: 30000,
    qrTimeout: 45000,
    msgRetryCounterCache: {},
    shouldSyncHistoryMessage: () => true,
    shouldIgnoreJid: (jid) => isJidBroadcast(jid),
    linkPreviewImageThumbnailWidth: 192,
    transactionOpts: { 
        maxCommitRetries: 10, 
        delayBetweenTriesMs: 3000 
    },
    getMessage: async (key) => {
        if (store) {
            const msg = await store.loadMessage(key.remoteJid!, key.id!)
            return msg?.message || undefined
        }
        return proto.Message.fromObject({})
    }
})

Database Integration

// MongoDB integration example
import { MongoClient } from 'mongodb'

class DatabaseManager {
    constructor(url) {
        this.client = new MongoClient(url)
        this.db = null
    }

    async connect() {
        await this.client.connect()
        this.db = this.client.db('whatsapp_bot')
        console.log('📦 Connected to MongoDB')
    }

    async saveMessage(message) {
        const collection = this.db.collection('messages')
        await collection.insertOne({
            ...message,
            timestamp: new Date(),
            processed: false
        })
    }

    async saveUser(jid, userData) {
        const collection = this.db.collection('users')
        await collection.updateOne(
            { jid },
            { $set: { ...userData, lastSeen: new Date() } },
            { upsert: true }
        )
    }

    async getUser(jid) {
        const collection = this.db.collection('users')
        return await collection.findOne({ jid })
    }

    async saveChat(chatData) {
        const collection = this.db.collection('chats')
        await collection.updateOne(
            { id: chatData.id },
            { $set: chatData },
            { upsert: true }
        )
    }
}

const dbManager = new DatabaseManager(config.databaseUrl)
await dbManager.connect()

// Integration with message handler
sock.ev.on("messages.upsert", async ({ messages }) => {
    for (const message of messages) {
        await dbManager.saveMessage(message)
        
        if (message.key.fromMe) continue
        
        const jid = message.key.remoteJid
        await dbManager.saveUser(jid, {
            jid,
            pushName: message.pushName,
            lastMessage: MessageParser.extractText(message.message)
        })
    }
})

🚀 Production Deployment

Docker Configuration

# Dockerfile
FROM node:18-alpine

WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm ci --only=production

# Copy application
COPY . .

# Create directories
RUN mkdir -p auth_session downloads logs

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node healthcheck.js

# Start application
CMD ["node", "index.js"]
# docker-compose.yml
version: '3.8'

services:
  whatsapp-bot:
    build: .
    restart: unless-stopped
    volumes:
      - ./auth_session:/app/auth_session
      - ./downloads:/app/downloads
      - ./logs:/app/logs
    environment:
      - NODE_ENV=production
      - PHONE_NUMBER=${PHONE_NUMBER}
      - DATABASE_URL=${DATABASE_URL}
      - REDIS_URL=redis://redis:6379
    depends_on:
      - redis
      - mongodb
    networks:
      - bot-network

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redis_data:/data
    networks:
      - bot-network

  mongodb:
    image: mongo:6
    restart: unless-stopped
    volumes:
      - mongo_data:/data/db
    environment:
      - MONGO_INITDB_ROOT_USERNAME=${MONGO_USER}
      - MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD}
    networks:
      - bot-network

volumes:
  redis_data:
  mongo_data:

networks:
  bot-network:
    driver: bridge

Process Manager (PM2)

// ecosystem.config.js
module.exports = {
    apps: [{
        name: 'whatsapp-bot',
        script: './index.js',
        instances: 1,
        exec_mode: 'fork',
        watch: false,
        max_memory_restart: '1G',
        env: {
            NODE_ENV: 'production',
            PORT: 3000
        },
        error_file: './logs/err.log',
        out_file: './logs/out.log',
        log_file: './logs/combined.log',
        time: true,
        autorestart: true,
        max_restarts: 10,
        min_uptime: '10s',
        restart_delay: 4000
    }]
}

Logging System

import winston from 'winston'

const logger = winston.createLogger({
    level: config.logLevel,
    format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.errors({ stack: true }),
        winston.format.json()
    ),
    defaultMeta: { service: 'whatsapp-bot' },
    transports: [
        new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
        new winston.transports.File({ filename: 'logs/combined.log' }),
        new winston.transports.Console({
            format: winston.format.combine(
                winston.format.colorize(),
                winston.format.simple()
            )
        })
    ]
})

// Usage throughout the application
logger.info('🚀 Bot starting...')
logger.error('❌ Connection failed', { error: error.message })
logger.warn('⚠️ Rate limit exceeded for user', { jid })

📜 License & Credits

License: MIT / GPL-3.0
Maintainer: KYUUNA Network
Inspired by: Baileys Community
Repository: @kyuuna/baileys on NPM

🤝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📞 Support

⭐ Show Your Support

Give a ⭐️ if this project helped you!

🙏 Acknowledgments

  • WhatsApp for the amazing platform
  • The original Baileys contributors
  • The Node.js and TypeScript communities
  • All developers using and contributing to @kyuuna/baileys

📊 Performance Tips

Memory Optimization

// Optimize memory usage
const sock = makeWASocket({
    // ... other options
    syncFullHistory: false, // Don't sync full chat history
    emitOwnEvents: false,   // Don't emit events for own messages
    shouldSyncHistoryMessage: (msg) => {
        // Only sync recent messages
        const twoDaysAgo = Date.now() - (2 * 24 * 60 * 60 * 1000)
        return msg.messageTimestamp * 1000 > twoDaysAgo
    },
    msgRetryCounterCache: new NodeCache({ 
        stdTTL: 300, // 5 minutes
        checkperiod: 60 
    })
})

// Clean up old messages periodically
setInterval(() => {
    if (store) {
        const cutoff = Date.now() - (7 * 24 * 60 * 60 * 1000) // 7 days
        store.cleanupMessages(cutoff)
    }
}, 24 * 60 * 60 * 1000) // daily cleanup

Connection Optimization

// Optimize connection settings
const connectionOpts = {
    connectTimeoutMs: 60000,
    defaultQueryTimeoutMs: 60000,
    keepAliveIntervalMs: 30000,
    qrTimeout: 45000,
    maxMsgRetryCount: 5,
    retryRequestDelayMs: 250,
    fireInitQueries: true,
    markOnlineOnConnect: false, // Don't auto-mark online
    syncFullHistory: false
}

// Connection health monitoring
let lastPong = Date.now()
setInterval(async () => {
    try {
        await sock.query({
            tag: 'iq',
            attrs: { type: 'get', xmlns: 'w:p', to: 'g.us' }
        })
        lastPong = Date.now()
    } catch (error) {
        const timeSinceLastPong = Date.now() - lastPong
        if (timeSinceLastPong > 60000) { // 1 minute
            console.log('🔄 Connection seems unhealthy, reconnecting...')
            sock.end(new Error('Health check failed'))
        }
    }
}, 30000) // Check every 30 seconds

Made with ❤️ by https://kyuuna.my.id