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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@aventa/boredom

v0.0.2

Published

@aventa/baileys

Readme

@yupra/baileys - Modern WhatsApp Web API

WhatsApp API

npm version License Downloads

@yupra/baileys is a modern WebSocket-based TypeScript library for interacting with the WhatsApp Web API. This library has been enhanced to address issues with WhatsApp group @lid and @jid handling, ensuring robust performance.

✨ Key Features

  • 🚀 Modern & Fast - Built with TypeScript and cutting-edge technologies
  • 🔧 Fixed @lid & @jid - Resolved WhatsApp group @lid and @jid issues
  • 📱 Multi-Device Support - Supports WhatsApp multi-device connections
  • 🔐 End-to-End Encryption - Fully encrypted communications
  • 📨 All Message Types - Supports all message types (text, media, polls, etc.)
  • 🎯 Easy to Use - Simple and intuitive API

⚠️ Disclaimer

This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with WhatsApp or any of its subsidiaries or affiliates. The official WhatsApp website can be found at whatsapp.com.

The maintainers of @yupra/baileys do not condone the use of this application in practices that violate WhatsApp's Terms of Service. We urge users to exercise personal responsibility and use this application fairly and responsibly.

Use wisely. Avoid spamming. Refrain from excessive automated usage.

📦 Installation

Stable Version (Recommended)

npm install @yupra/baileys

Edge Version (Latest Features)

npm install @yupra/baileys@latest
# or
yarn add @yupra/baileys@latest

Import in Code

const { default: makeWASocket } = require("@yupra/baileys")
// or ES6
import makeWASocket from "@yupra/baileys"

🚀 Quick Start

Example

Here is an example you can use: example.ts or follow this tutorial to run the Baileys WhatsApp API code:

  1. cd path/to/baileys
  2. npm install
  3. node example.js

Basic Example

const { default: makeWASocket, DisconnectReason, useMultiFileAuthState } = require('@yupra/baileys')
const { Boom } = require('@hapi/boom')

async function connectToWhatsApp() {
    const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')
    
    const sock = makeWASocket({
        auth: state,
        printQRInTerminal: true,
        browser: ['@yupra/baileys', 'Desktop', '3.0']
    })

    sock.ev.on('connection.update', (update) => {
        const { connection, lastDisconnect } = update
        if(connection === 'close') {
            const shouldReconnect = (lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
            console.log('Connection closed due to ', lastDisconnect.error, ', reconnecting ', shouldReconnect)
            if(shouldReconnect) {
                connectToWhatsApp()
            }
        } else if(connection === 'open') {
            console.log('✅ Successfully connected to WhatsApp!')
        }
    })

    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
            await sock.sendMessage(m.key.remoteJid!, { 
                text: 'Hello! I am a WhatsApp bot using @yupra/baileys 🤖' 
            })
        }
    })

    sock.ev.on('creds.update', saveCreds)
}

connectToWhatsApp()

Index

Connecting Account

WhatsApp provides a multi-device API that allows @yupra/baileys to authenticate as a secondary WhatsApp client via QR code or pairing code.

Starting Socket with QR Code

[!TIP] Customize the browser name using the Browsers constant. See available configurations here.

const { default: makeWASocket, Browsers } = require("@yupra/baileys")

const sock = makeWASocket({
    browser: Browsers.ubuntu('My App'),
    printQRInTerminal: true
})

Upon successful connection, a QR code will be printed in the terminal. Scan it with WhatsApp on your phone to log in.

Starting Socket with Pairing Code

[!IMPORTANT] Pairing codes are not part of the Mobile API. They allow connecting WhatsApp Web without a QR code, but only one device can be connected. See WhatsApp FAQ.

Phone numbers must exclude +, (), or -, and include the country code.

const { default: makeWASocket } = require("@yupra/baileys")

const sock = makeWASocket({
    printQRInTerminal: false
})

// Normal Pairing
if (!sock.authState.creds.registered) {
    const number = '6285134816783'
    const code = await sock.requestPairingCode(number)
    console.log('🔑 Pairing Code:', code)
}

// Custom Pairing
if (!sock.authState.creds.registered) {
    const pair = "YP240125" // 8 characters
    const number = '6285134816783'
    const code = await sock.requestPairingCode(number, pair)
    console.log('🔑 Custom Pairing Code:', code)
}

Receive Full History

  1. Set syncFullHistory to true.
  2. By default, Baileys uses Chrome browser config. For desktop-like connections (to receive more message history), use:
const { default: makeWASocket, Browsers } = require("@yupra/baileys")

const sock = makeWASocket({
    browser: Browsers.macOS('Desktop'),
    syncFullHistory: true
})

Important Notes About Socket Config

Caching Group Metadata (Recommended)

For group usage, implement caching for group metadata:

const { default: makeWASocket } = require("@yupra/baileys")
const NodeCache = require('node-cache')

const groupCache = new NodeCache({ stdTTL: 5 * 60, useClones: false })

const sock = makeWASocket({
    cachedGroupMetadata: async (jid) => groupCache.get(jid)
})

sock.ev.on('groups.update', async ([event]) => {
    const metadata = await sock.groupMetadata(event.id)
    groupCache.set(event.id, metadata)
})

sock.ev.on('group-participants.update', async (event) => {
    const metadata = await sock.groupMetadata(event.id)
    groupCache.set(event.id, metadata)
})

Improve Retry System & Decrypt Poll Votes

Enhance message sending and poll vote decryption with a store:

const sock = makeWASocket({
    getMessage: async (key) => await getMessageFromStore(key)
})

Receive Notifications in WhatsApp App

Disable online status to receive notifications:

const sock = makeWASocket({
    markOnlineOnConnect: false
})

Saving & Restoring Sessions

Avoid rescanning QR codes by saving credentials:

const makeWASocket = require("@yupra/baileys").default
const { useMultiFileAuthState } = require("@yupra/baileys")

async function connect() {
    const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')
    const sock = makeWASocket({ auth: state })
    sock.ev.on('creds.update', saveCreds)
}

connect()

[!IMPORTANT] useMultiFileAuthState saves auth state in a folder. For production, use SQL/no-SQL databases and carefully manage key updates.

Handling Events

Baileys uses EventEmitter for events, fully typed for IDE support.

[!IMPORTANT] See all events here.

const sock = makeWASocket()
sock.ev.on('messages.upsert', ({ messages }) => {
    console.log('Got messages:', messages)
})

Example to Start

const makeWASocket = require("@yupra/baileys").default
const { DisconnectReason, useMultiFileAuthState } = require("@yupra/baileys")
const { Boom } = require('@hapi/boom')

async function connectToWhatsApp() {
    const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')
    const sock = makeWASocket({
        auth: state,
        printQRInTerminal: true
    })

    sock.ev.on('connection.update', (update) => {
        const { connection, lastDisconnect } = update
        if(connection === 'close') {
            const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
            console.log('Connection closed due to ', lastDisconnect.error, ', reconnecting ', shouldReconnect)
            if(shouldReconnect) {
                connectToWhatsApp()
            }
        } else if(connection === 'open') {
            console.log('Opened connection')
        }
    })

    sock.ev.on('messages.upsert', async ({ messages }) => {
        for (const m of messages) {
            console.log(JSON.stringify(m, undefined, 2))
            console.log('Replying to', m.key.remoteJid)
            await sock.sendMessage(m.key.remoteJid!, { text: 'Hello World' })
        }
    })

    sock.ev.on('creds.update', saveCreds)
}

connectToWhatsApp()

Decrypt Poll Votes

Handle encrypted poll votes:

sock.ev.on('messages.update', async (event) => {
    for(const { key, update } of event) {
        if(update.pollUpdates) {
            const pollCreation = await getMessage(key)
            if(pollCreation) {
                console.log(
                    'Got poll update, aggregation: ',
                    getAggregateVotesInPollMessage({
                        message: pollCreation,
                        pollUpdates: update.pollUpdates,
                    })
                )
            }
        }
    }
})

Summary of Events on First Connection

  1. connection.update triggers, requesting socket restart.
  2. History messages are received in messaging.history-set.

Implementing a Data Store

Baileys provides an in-memory store for chats, contacts, and messages:

const makeWASocket = require("@yupra/baileys").default
const { makeInMemoryStore } = require("@yupra/baileys")

const store = makeInMemoryStore({})
store.readFromFile('./baileys_store.json')
setInterval(() => {
    store.writeToFile('./baileys_store.json')
}, 10_000)

const sock = makeWASocket({})
store.bind(sock.ev)

sock.ev.on('chats.upsert', () => {
    console.log('Got chats', store.chats.all())
})

sock.ev.on('contacts.upsert', () => {
    console.log('Got contacts', Object.values(store.contacts))
})

[!IMPORTANT] For production, implement a custom store to avoid memory issues.

WhatsApp IDs Explained

WhatsApp IDs (jid) formats:

  • Personal Chat: [country code][phone number]@s.whatsapp.net (e.g., [email protected])
  • Group Chat (Fixed @jid): [email protected]
  • Broadcast: [timestamp]@broadcast (e.g., 1234567890@broadcast)
  • Status/Story: status@broadcast
  • Newsletter: 1234567890@newsletter

[!NOTE] @lid and @jid issues in groups are fixed in this library.

Utility Functions

  • getContentType: Returns message content type.
  • getDevice: Identifies device from message.
  • makeCacheableSignalKeyStore: Optimizes auth store.
  • downloadContentFromMessage: Downloads message content.

Sending Messages

Send messages using:

const jid: string
const content: AnyMessageContent
const options: MiscMessageGenerationOptions

sock.sendMessage(jid, content, options)

Non-Media Messages

Buttons Message

await sock.sendMessage(jid, {
    text: "Hello World!",
    footer: "YP - 2025",
    buttons: [
        {
            buttonId: `🚀`,
            buttonText: { displayText: '🗿' },
            type: 1
        }
    ],
    headerType: 1,
    viewOnce: true
}, { quoted: null })

Buttons Flow

await sock.sendMessage(jid, {
    text: "Hello World!",
    footer: "© YP",
    buttons: [
        {
            buttonId: '.tes',
            buttonText: { displayText: 'TESTING BOT' },
            type: 1
        },
        {
            buttonId: ' ',
            buttonText: { displayText: 'PRIVATE SCRIPT' },
            type: 1
        },
        {
            buttonId: 'action',
            buttonText: { displayText: 'Interactive Message' },
            type: 4,
            nativeFlowInfo: {
                name: 'single_select',
                paramsJson: JSON.stringify({
                    title: 'message',
                    sections: [
                        {
                            title: 'YP - 2025',
                            highlight_label: '☺',
                            rows: [
                                { header: 'HEADER', title: 'TITLE', description: 'DESCRIPTION', id: 'YOUR ID' },
                                { header: 'HEADER', title: 'TITLE', description: 'DESCRIPTION', id: 'YOUR ID' }
                            ]
                        }
                    ]
                })
            }
        }
    ],
    headerType: 1,
    viewOnce: true
}, { quoted: m })

Interactive Message

let msg = generateWAMessageFromContent(m.chat, {
    viewOnceMessage: {
        message: {
            messageContextInfo: {
                deviceListMetadata: {},
                deviceListMetadataVersion: 2
            },
            interactiveMessage: proto.Message.InteractiveMessage.create({
                body: proto.Message.InteractiveMessage.Body.create({ text: "YP" }),
                footer: proto.Message.InteractiveMessage.Footer.create({ text: "Bot" }),
                header: proto.Message.InteractiveMessage.Header.create({
                    title: "Igna",
                    subtitle: "test",
                    hasMediaAttachment: false
                }),
                nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({
                    buttons: [
                        {
                            name: "single_select",
                            buttonParamsJson: "{\"title\":\"title\",\"sections\":[{\".menu\":\".play dj webito\",\"highlight_label\":\"label\",\"rows\":[{\"header\":\"header\",\"title\":\"title\",\"description\":\"description\",\"id\":\"id\"},{\"header\":\"header\",\"title\":\"title\",\"description\":\"description\",\"id\":\"id\"}]}]}"
                        },
                        { name: "cta_reply", buttonParamsJson: "{\"display_text\":\"quick_reply\",\"id\":\"message\"}" },
                        { name: "cta_url", buttonParamsJson: "{\"display_text\":\"url\",\"url\":\"https://www.google.com\",\"merchant_url\":\"https://www.google.com\"}" },
                        { name: "cta_call", buttonParamsJson: "{\"display_text\":\"call\",\"id\":\"message\"}" },
                        { name: "cta_copy", buttonParamsJson: "{\"display_text\":\"copy\",\"id\":\"123456789\",\"copy_code\":\"message\"}" },
                        { name: "cta_reminder", buttonParamsJson: "{\"display_text\":\"Recordatorio\",\"id\":\"message\"}" },
                        { name: "cta_cancel_reminder", buttonParamsJson: "{\"display_text\":\"cta_cancel_reminder\",\"id\":\"message\"}" },
                        { name: "address_message", buttonParamsJson: "{\"display_text\":\"address_message\",\"id\":\"message\"}" },
                        { name: "send_location", buttonParamsJson: "" }
                    ]
                })
            })
        }
    }
}, {})

return sock.relayMessage(msg.key.remoteJid, msg.message, { messageId: msg.key.id })

Text Message

await sock.sendMessage(jid, { text: 'Hello World' })

Quote Message (works with all types)

await sock.sendMessage(jid, { text: 'Hello World' }, { quoted: message })

Mention User (works with most types)

await sock.sendMessage(
    jid,
    {
        text: '@6285134816783',
        mentions: ['[email protected]']
    }
)

Mention Status

await sock.StatusMentions(
    {
        text: "Hello",
    },
    [
        "[email protected]",
        "[email protected]"
    ]
)

Result Poll From Newsletter

await sock.sendMessage(
    jid,
    {
        pollResult: {
            name: "Text poll",
            votes: [["Option 1", 10], ["Option 2", 10]]
        }
    }, { quoted: message }
)

Send Album Message

await sock.sendAlbumMessage(
    jid,
    [
        {
            image: { url: "https://example.jpg" },
            caption: "Hello World"
        },
        {
            video: { url: "https://example.mp4" },
            caption: "Hello World"
        }
    ],
    { 
        quoted: message, 
        delay: 2000
    }
)

Interactive Response

await sock.sendMessage(
    jid, 
    {
        buttonReply: {
            text: 'Text',
            nativeFlow: { version: 3 }
        },
        type: 'interactive',
        ephemeral: true
    }
)

Request Payment

// Non-media sticker
await sock.sendMessage(
    jid,
    {
        requestPayment: {      
            currency: "IDR",
            amount: "10000000",
            from: "[email protected]",
            note: "Hi Guys",
            background: {}
        }
    },
    { quoted: message }
)

// With media sticker buffer
await sock.sendMessage(
    jid,
    {
        requestPayment: {      
            currency: "IDR",
            amount: "10000000",
            from: "[email protected]",
            sticker: Buffer,
            background: {}
        }
    },
    { quoted: message }
)

// With media sticker URL
await sock.sendMessage(
    jid,
    {
        requestPayment: {      
            currency: "IDR",
            amount: "10000000",
            from: "[email protected]",
            sticker: { url: 'https://example.com/sticker.png' },
            background: {}
        }
    },
    { quoted: message }
)

Event Message

await sock.sendMessage(
    jid, 
    { 
        event: {
            isCanceled: false,
            name: "Name Event",
            description: "Description Event",
            location: { 
                degreesLatitude: 0,
                degreesLongitude: 0
            },
            link: 'https://call.link',
            startTime: m.messageTimestamp.low,
            endTime: m.messageTimestamp.low + 86400,
            extraGuestsAllowed: true
        }
    },
    { quoted: message }
)

Interactive

// Non-header media
await sock.sendMessage(
    jid,
    {
        text: "Description Of Messages",
        title: "Title Of Messages",
        subtitle: "Subtitle Message",
        footer: "Footer Messages",
        interactiveButtons: [
            {
                name: "quick_reply",
                buttonParamsJson: JSON.stringify({ display_text: "Display Button", id: "ID" })
            },
            {
                name: "cta_url",
                buttonParamsJson: JSON.stringify({ display_text: "Display Button", url: "https://www.example.com" })
            }
        ]
    },
    { quoted: message }
)

// With media
await sock.sendMessage(
    jid,
    {
        image: { url: "https://example.jpg" },
        caption: "Description Of Messages",
        title: "Title Of Messages",
        subtitle: "Subtitle Message",
        footer: "Footer Messages",
        media: true,
        interactiveButtons: [
            {
                name: "quick_reply",
                buttonParamsJson: JSON.stringify({ display_text: "Display Button", id: "ID" })
            },
            {
                name: "cta_url",
                buttonParamsJson: JSON.stringify({ display_text: "Display Button", url: "https://www.example.com" })
            }
        ]
    },
    { quoted: message }
)

// With header product
await sock.sendMessage(
    jid,
    {
        product: {
            productImage: { url: "https://example.jpg" },
            productImageCount: 1,
            title: "Title Product",
            description: "Description Product",
            priceAmount1000: 20000 * 1000,
            currencyCode: "IDR",
            retailerId: "Retail",
            url: "https://example.com"
        },
        businessOwnerJid: "[email protected]",
        caption: "Description Of Messages",
        title: "Title Of Messages",
        footer: "Footer Messages",
        media: true,
        interactiveButtons: [
            {
                name: "quick_reply",
                buttonParamsJson: JSON.stringify({ display_text: "Display Button", id: "ID" })
            },
            {
                name: "cta_url",
                buttonParamsJson: JSON.stringify({ display_text: "Display Button", url: "https://www.example.com" })
            }
        ]
    },
    { quoted: message }
)

Forward Messages

const msg = getMessageFromStore()
await sock.sendMessage(jid, { forward: msg })

Location Message

await sock.sendMessage(
    jid,
    {
        location: {
            degreesLatitude: 24.121231,
            degreesLongitude: 55.1121221
        }
    }
)

Contact Message

const vcard = 'BEGIN:VCARD\n'
    + 'VERSION:3.0\n'
    + 'FN:Jeff Singh\n'
    + 'ORG:Ashoka Uni;\n'
    + 'TEL;type=CELL;type=VOICE;waid=6285134816783:+6285134816783\n'
    + 'END:VCARD'

await sock.sendMessage(
    jid,
    {
        contacts: {
            displayName: 'Jeff',
            contacts: [{ vcard }]
        }
    }
)

Reaction Message

await sock.sendMessage(
    jid,
    {
        react: {
            text: '💖',
            key: message.key
        }
    }
)

Pin Message

await sock.sendMessage(
    jid,
    {
        pin: {
            type: 1,
            time: 86400,
            key: message.key
        }
    }
)

Poll Message

await sock.sendMessage(
    jid,
    {
        poll: {
            name: 'My Poll',
            values: ['Option 1', 'Option 2'],
            selectableCount: 1,
            toAnnouncementGroup: false
        }
    }
)

Sending Messages with Link Previews

Add link-preview-js dependency:

yarn add link-preview-js

Send a link:

await sock.sendMessage(
    jid,
    {
        text: 'Hi, this was sent using https://github.com/yupranetwork/baileys'
    }
)

Media Messages

[!NOTE] Use { stream: Stream }, { url: Url }, or Buffer for media. See WAMediaUpload.

GIF Message

await sock.sendMessage(
    jid,
    {
        video: fs.readFileSync('Media/ma_gif.mp4'),
        caption: 'Hello World',
        gifPlayback: true
    }
)

Video Message

await sock.sendMessage(
    jid,
    {
        video: { url: './Media/ma_gif.mp4' },
        caption: 'Hello World',
        ptv: false
    }
)

Audio Message

await sock.sendMessage(
    jid,
    {
        audio: { url: './Media/audio.mp3' },
        mimetype: 'audio/mp4'
    }
)

Image Message

await sock.sendMessage(
    jid,
    {
        image: { url: './Media/ma_img.png' },
        caption: 'Hello World'
    }
)

View Once Message

await sock.sendMessage(
    jid,
    {
        image: { url: './Media/ma_img.png' },
        viewOnce: true,
        caption: 'Hello World'
    }
)

Modify Messages

Deleting Messages (for everyone)

const msg = await sock.sendMessage(jid, { text: 'Hello World' })
await sock.sendMessage(jid, { delete: msg.key })

Editing Messages

await sock.sendMessage(jid, {
    text: 'Updated text goes here',
    edit: response.key
})

Manipulating Media Messages

Thumbnail in Media Messages

Add jimp or sharp for image/sticker thumbnails:

yarn add jimp
# or
yarn add sharp

For video thumbnails, install ffmpeg.

Downloading Media Messages

const { createWriteStream } = require('fs')
const { downloadMediaMessage, getContentType } = require("@yupra/baileys")

sock.ev.on('messages.upsert', async ({ messages: [m] }) => {
    if (!m.message) return
    const messageType = getContentType(m.message)

    if (messageType === 'imageMessage') {
        const stream = await downloadMediaMessage(
            m,
            'stream',
            {},
            {
                logger,
                reuploadRequest: sock.updateMediaMessage
            }
        )
        const writeStream = createWriteStream('./my-download.jpeg')
        stream.pipe(writeStream)
    }
})

Re-upload Media Message to WhatsApp

await sock.updateMediaMessage(msg)

Reject Call

await sock.rejectCall(callId, callFrom)

Send States in Chat

Reading Messages

const key: WAMessageKey
await sock.readMessages([key])

Update Presence

await sock.sendPresenceUpdate('available', jid)

Modifying Chats

Archive a Chat

const lastMsgInChat = await getLastMessageInChat(jid)
await sock.chatModify({ archive: true, lastMessages: [lastMsgInChat] }, jid)

Mute/Unmute a Chat

await sock.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid) // Mute for 8 hours
await sock.chatModify({ mute: null }, jid) // Unmute

Mark a Chat Read/Unread

const lastMsgInChat = await getLastMessageInChat(jid)
await sock.chatModify({ markRead: false, lastMessages: [lastMsgInChat] }, jid)

Delete a Message for Me

await sock.chatModify(
    {
        clear: {
            messages: [
                {
                    id: 'ATWYHDNNWU81732J',
                    fromMe: true,
                    timestamp: '1654823909'
                }
            ]
        }
    },
    jid
)

Delete a Chat

const lastMsgInChat = await getLastMessageInChat(jid)
await sock.chatModify({
    delete: true,
    lastMessages: [
        {
            key: lastMsgInChat.key,
            messageTimestamp: lastMsgInChat.messageTimestamp
        }
    ]
}, jid)

Pin/Unpin a Chat

await sock.chatModify({
    pin: true
}, jid)

Star/Unstar a Message

await sock.chatModify({
    star: {
        messages: [
            {
                id: 'messageID',
                fromMe: true
            }
        ],
        star: true
    }
}, jid)

Disappearing Messages

await sock.sendMessage(
    jid,
    { disappearingMessagesInChat: 604800 }
)

await sock.sendMessage(jid, { text: 'Hello' }, { ephemeralExpiration: 604800 })

await sock.sendMessage(
    jid,
    { disappearingMessagesInChat: false }
)

User Queries

Check If ID Exists in WhatsApp

const [result] = await sock.onWhatsApp(jid)
if (result.exists) console.log(`${jid} exists on WhatsApp, as jid: ${result.jid}`)

Query Chat History (groups too)

const msg = await getOldestMessageInChat(jid)
await sock.fetchMessageHistory(
    50,
    msg.key,
    msg.messageTimestamp
)

Fetch Status

const status = await sock.fetchStatus(jid)
console.log('Status: ' + status)

Fetch Profile Picture (groups too)

const ppUrl = await sock.profilePictureUrl(jid, 'image')
console.log(ppUrl)

Fetch Business Profile (such as description or category)

const profile = await sock.getBusinessProfile(jid)
console.log('Business description: ' + profile.description + ', category: ' + profile.category)

Fetch Someone's Presence (if they're typing or online)

sock.ev.on('presence.update', console.log)
await sock.presenceSubscribe(jid)

Change Profile

Change Profile Status

await sock.updateProfileStatus('Hello World!')

Change Profile Name

await sock.updateProfileName('My Name')

Change Display Picture (groups too)

await sock.updateProfilePicture(jid, { url: './new-profile-picture.jpeg' })

Remove Display Picture (groups too)

await sock.removeProfilePicture(jid)

Groups

Create a Group

const group = await sock.groupCreate('My Fab Group', ['[email protected]', '[email protected]'])
console.log('Created group with id: ' + group.gid)
await sock.sendMessage(group.id, { text: 'Hello there' })

Add/Remove or Demote/Promote

await sock.groupParticipantsUpdate(
    jid,
    ['[email protected]', '[email protected]'],
    'add'
)

Change Subject (name)

await sock.groupUpdateSubject(jid, 'New Subject!')

Change Description

await sock.groupUpdateDescription(jid, 'New Description!')

Change Settings

await sock.groupSettingUpdate(jid, 'announcement')
await sock.groupSettingUpdate(jid, 'not_announcement')
await sock.groupSettingUpdate(jid, 'unlocked')
await sock.groupSettingUpdate(jid, 'locked')

Leave a Group

await sock.groupLeave(jid)

Get Invite Code

const code = await sock.groupInviteCode(jid)
console.log('Group code: ' + code)

Revoke Invite Code

const code = await sock.groupRevokeInvite(jid)
console.log('New group code: ' + code)

Join Using Invitation Code

const response = await sock.groupAcceptInvite(code)
console.log('Joined to: ' + response)

Get Group Info by Invite Code

const response = await sock.groupGetInviteInfo(code)
console.log('Group information: ' + response)

Query Metadata (participants, name, description...)

const metadata = await sock.groupMetadata(jid)
console.log(metadata.id + ', title: ' + metadata.subject + ', description: ' + metadata.desc)

Join using groupInviteMessage

const response = await sock.groupAcceptInviteV4(jid, groupInviteMessage)
console.log('Joined to: ' + response)

Get Request Join List

const response = await sock.groupRequestParticipantsList(jid)
console.log(response)

Approve/Reject Request Join

const response = await sock.groupRequestParticipantsUpdate(
    jid,
    ['[email protected]', '[email protected]'],
    'approve'
)
console.log(response)

Get All Participating Groups Metadata

const response = await sock.groupFetchAllParticipating()
console.log(response)

Toggle Ephemeral

await sock.groupToggleEphemeral(jid, 86400)

Change Add Mode

await sock.groupMemberAddMode(
    jid,
    'all_member_add'
)

Privacy

Block/Unblock User

await sock.updateBlockStatus(jid, 'block')
await sock.updateBlockStatus(jid, 'unblock')

Get Privacy Settings

const privacySettings = await sock.fetchPrivacySettings(true)
console.log('Privacy settings: ' + privacySettings)

Get BlockList

const response = await sock.fetchBlocklist()
console.log(response)

Update LastSeen Privacy

await sock.updateLastSeenPrivacy('contacts')

Update Online Privacy

await sock.updateOnlinePrivacy('all')

Update Profile Picture Privacy

await sock.updateProfilePicturePrivacy('contacts')

Update Status Privacy

await sock.updateStatusPrivacy('contacts')

Update Read Receipts Privacy

await sock.updateReadReceiptsPrivacy('all')

Update Groups Add Privacy

await sock.updateGroupsAddPrivacy('contacts')

Update Default Disappearing Mode

await sock.updateDefaultDisappearingMode(86400)

Broadcast Lists & Stories

Send Broadcast & Stories

await sock.sendMessage(
    jid,
    {
        image: { url: 'story.jpg' },
        caption: 'Story from @yupra/baileys'
    },
    {
        backgroundColor: '#FF6B6B',
        font: 1,
        statusJidList: ['[email protected]'],
        broadcast: true
    }
)

Query a Broadcast List's Recipients & Name

const bList = await sock.getBroadcastListInfo('1234567890@broadcast')
console.log(`List name: ${bList.name}, recipients: ${bList.recipients}`)

Writing Custom Functionality

Enabling Debug Level in Baileys Logs

const sock = makeWASocket({
    logger: P({ level: 'debug' })
})

How WhatsApp Communicates With Us

[!TIP] Study the Libsignal Protocol and Noise Protocol for WhatsApp communication details.

Example for tracking battery percentage:

{
    "level": 10,
    "fromMe": false,
    "frame": {
        "tag": "ib",
        "attrs": { "from": "@s.whatsapp.net" },
        "content": [
            {
                "tag": "edge_routing",
                "attrs": {},
                "content": [
                    {
                        "tag": "routing_info",
                        "attrs": {},
                        "content": { "type": "Buffer", "data": [8,2,8,5] }
                    }
                ]
            }
        ]
    },
    "msg": "communication"
}

Register a Callback for WebSocket Events

sock.ws.on('CB:edge_routing', (node) => {})
sock.ws.on('CB:edge_routing,id:abcd', (node) => {})
sock.ws.on('CB:edge_routing,id:abcd,routing_info', (node) => {})

Tips & Best Practices

  1. Rate Limiting
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))
for (const contact of contacts) {
    await sock.sendMessage(contact, { text: 'Broadcast message' })
    await delay(2000)
}
  1. Memory Management
const fs = require('fs')
await sock.sendMessage('[email protected]', {
    document: fs.createReadStream('./large-file.pdf'),
    mimetype: 'application/pdf',
    fileName: 'document.pdf'
})
  1. Error Recovery
async function sendWithRetry(jid, content, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
        try {
            return await sock.sendMessage(jid, content)
        } catch (error) {
            console.log(`Attempt ${i + 1} failed:`, error.message)
            if (i === maxRetries - 1) throw error
            await delay(1000 * (i + 1))
        }
    }
}

Troubleshooting

  1. QR Code Not Appearing
const sock = makeWASocket({
    printQRInTerminal: true
})
  1. Group @jid Not Working ✅ FIXED
const groupId = '[email protected]'
  1. Session Lost
sock.ev.on('creds.update', saveCreds)
  1. Memory Leak
const store = makeInMemoryStore({})
store.bind(sock.ev)

License

Distributed under the GPL-3.0 License. See LICENSE for more information.

Acknowledgments


Made with ❤️ by [YuPra Network]

@yupra/baileys - Modern WhatsApp Web API with Fixed @lid & @jid Issues