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

@chatunity/baileys

v1.1.2

Published

whatsapp api by ChatUnity

Readme

ChatUnity Baileys - TypeScript & Node.js Based

Important Note

This library was created by combining multiple libraries together. We thank @realvare for the library and frequent updates ❤️

Responsibility and License Information

The developers of Baileys and its maintainers cannot be held responsible for misuse of the application, as indicated in the MIT License.
The team does not approve any use that violates WhatsApp's Terms of Service. Every user is invited to act responsibly and use the tool only for its intended purposes.

  • Baileys does not require Selenium or any browser to work with WhatsApp Web: it uses a WebSocket directly.
  • Avoiding Selenium or Chromium saves approximately half a gigabyte of RAM.
  • Baileys supports both the multi-device version and the web version of WhatsApp.

[!IMPORTANT]
The original repository was removed by the main author – development continues officially in this new community-maintained version.

Getting Started

You can check out and run the example available in example.ts to see practical usage of the library.
The script demonstrates the most common use cases.
To run it:

  1. cd path/to/Baileys
  2. yarn
  3. yarn example

Installation

Use the stable version:

yarn add @chatunitycenter/baileys

Use the edge version (no guarantee of stability, but latest fixes + features)

yarn add github:chatunitycenter/baileys

Then import in your code using:

import makeWASocket from '@chatunitycenter/baileys'

Connecting Account

WhatsApp provides a multi-device system that allows Baileys to authenticate as a second WhatsApp client via QR code or Pairing Code scanned from the app on your phone.

[!NOTE] Here you'll find a simple event handling example

[!TIP] You can view all supported socket configurations here (Recommended)

Connect with QR-CODE

[!TIP] If you connect via QR-CODE, you can customize the browser name using the Browser constant. Several predefined configurations are available, viewable here.

import makeWASocket from '@chatunitycenter/baileys'

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

If the connection is successful, you will see a QR code printed on your terminal screen. Scan it with WhatsApp on your phone and you'll be logged in!

Connect with Pairing Code

[!IMPORTANT] Pairing Code is not Mobile API; it's a method to connect WhatsApp Web without QR-CODE. You can only connect with one device, see here

The phone number cannot have +, (), or -, only numbers. You must provide country code.

import makeWASocket from '@chatunitycenter/baileys'

const chatunity = makeWASocket({
    printQRInTerminal: false // must be false
})

if (!chatunity.authState.creds.registered) {
    const number = 'XXXXXXXXXXX'
    const code = await chatunity.requestPairingCode(number)
    console.log(code)
}

Receive Full History

  1. Set syncFullHistory to true
  2. Use a desktop browser configuration to receive more message history:
const chatunity = makeWASocket({
    browser: Browsers.macOS('Desktop'),
    syncFullHistory: true
})

Socket Configuration

Cache Group Metadata

If you use Baileys for groups, we recommend setting cachedGroupMetadata in socket config:

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

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

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

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

Improve Retry System & Decrypt Poll Votes

To improve message sending, retrying on errors, and decrypt poll votes, set up a store with getMessage config:

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

Receive Notifications in WhatsApp App

To receive notifications in the WhatsApp app, set markOnlineOnConnect to false:

const chatunity = makeWASocket({
    markOnlineOnConnect: false
})

Saving & Restoring Sessions

You don't need to scan the QR code every time you connect. Load credentials to log back in:

import makeWASocket, { useMultiFileAuthState } from '@chatunitycenter/baileys'

const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')

const chatunity = makeWASocket({ auth: state })

chatunity.ev.on('creds.update', saveCreds)

[!IMPORTANT] useMultiFileAuthState is a utility function to help save the auth state in a folder. This serves as a good guide for implementing auth & key states for SQL/NoSQL databases, which is recommended for production systems.

[!NOTE] When messages are received/sent, auth keys need updating. You must save updated keys. The useMultiFileAuthState function handles this automatically, but for other implementations you must be careful with key state management.

Alternative Auth Methods

import makeWASocket, { useSingleFileAuthState, useMongoFileAuthState } from '@chatunitycenter/baileys'

// Single File Auth
const { state, saveState } = await useSingleFileAuthState('./auth_info_baileys.json') 
const chatunity = makeWASocket({ auth: state, printQRInTerminal: true })
chatunity.ev.on('creds.update', saveState)

// MongoDB Auth
import { MongoClient } from "mongodb"

const connectAuth = async() => {
    const client = new MongoClient('mongoURL')
    await client.connect()
    const collection = client.db("@itchatunitychann").collection("sessions")
    return collection
}

const Authentication = await connectAuth()
const { state, saveCreds } = await useMongoFileAuthState(Authentication)
const chatunity = makeWASocket({ auth: state, printQRInTerminal: true })
chatunity.ev.on('creds.update', saveCreds)

Handling Events

Baileys uses the EventEmitter syntax for events with full TypeScript support.

[!IMPORTANT] See all available events here

const chatunity = makeWASocket()
chatunity.ev.on('messages.upsert', ({ messages }) => {
    console.log('got messages', messages)
})

Example to Start

import makeWASocket, { DisconnectReason, useMultiFileAuthState } from '@chatunitycenter/baileys'
import { Boom } from '@hapi/boom'

async function connectToWhatsApp () {
    const { state, saveCreds } = await useMultiFileAuthState('./auth_info_baileys')
    const chatunity = makeWASocket({
        auth: state,
        printQRInTerminal: true
    })
    chatunity.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')
        }
    })
    chatunity.ev.on('messages.upsert', event => {
        for (const m of event.messages) {
            console.log(JSON.stringify(m, undefined, 2))
            console.log('replying to', m.key.remoteJid)
            await chatunity.sendMessage(m.key.remoteJid!, { text: 'Hello World' })
        }
    })
    chatunity.ev.on('creds.update', saveCreds)
}

connectToWhatsApp()

[!IMPORTANT] In messages.upsert, use a loop like for (const message of event.messages) to handle all messages in the array.

Decrypt Poll Votes

Poll votes are encrypted by default and handled in messages.update:

import pino from "pino"
import { makeInMemoryStore, getAggregateVotesInPollMessage } from '@chatunitycenter/baileys'

const logger = pino({ timestamp: () => `,"time":"${new Date().toJSON()}"` }).child({ class: "@Itchatunitychann" })
logger.level = "fatal"
const store = makeInMemoryStore({ logger })

async function getMessage(key){
    if (store) {
        const msg = await store.loadMessage(key.remoteJid, key.id)
        return msg?.message
    }
    return { conversation: "Itchatunityi Kawaiii" }
} 

chatunity.ev.on("messages.update", async (chatUpdate) => {
    for(const { key, update } of chatUpdate) {
         if(update.pollUpdates && key.fromMe) {
           const pollCreation = await getMessage(key)
             if(pollCreation) {
               const pollUpdate = await getAggregateVotesInPollMessage({
                    message: pollCreation,
                    pollUpdates: update.pollUpdates,
                })
               const toCmd = pollUpdate.filter(v => v.voters.length !== 0)[0]?.name
               if (toCmd == undefined) return
               console.log(toCmd)
	        }
        }
    } 
})

Decrypt Event Response

Event responses are encrypted by default and handled in messages.update:

import { jidNormalizedUser, getAggregateResponsesInEventMessage } from '@chatunitycenter/baileys'

chatunity.ev.on("messages.update", async ([chatUpdate]) => {
    const eventResponses = chatUpdate.update?.eventResponses
    const agregate = getAggregateResponsesInEventMessage({ eventResponses }, jidNormalizedUser(chatunity.user.lid)) 
    console.log(agregate) 
})

Summary of Events on First Connection

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

Implementing a Data Store

Baileys does not include built-in storage for chats, contacts, or messages. However, a simple in-memory implementation is provided:

[!IMPORTANT] We highly recommend building your own data store, as storing entire chat history in memory wastes RAM.

import makeWASocket, { makeInMemoryStore } from '@chatunitycenter/baileys'

const store = makeInMemoryStore({ })
store.readFromFile('./baileys_store.json')

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

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

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

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

WhatsApp IDs Explained

  • id (also called jid) is the WhatsApp ID of the person or group you're messaging.
    • Format for people: [country code][phone number]@s.whatsapp.net
    • Broadcast lists: [timestamp of creation]@broadcast
    • Stories: status@broadcast

Utility Functions

  • getContentType - returns the content type for any message
  • getDevice - returns the device from a message
  • makeCacheableSignalKeyStore - speeds up auth store
  • downloadContentFromMessage - downloads content from any message

Sending Messages

Send all types of messages with a single function:

await chatunity.sendMessage(jid, content, options)

Non-Media Messages

Text Message

await chatunity.sendMessage(jid, { text: 'hello world' })

Quote Message

await chatunity.sendMessage(jid, { text: 'hello world' }, { quoted: message })

Mention User

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

Forward Messages

const msg = getMessageFromStore()
await chatunity.sendMessage(jid, { forward: msg, force: true })

Location Message

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

Live Location Message

await chatunity.sendMessage(jid, {
    location: {
        degreesLatitude: 24.121231,
        degreesLongitude: 55.1121221
    }, 
    live: true
})

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=911234567890:+91 12345 67890\n'
            + 'END:VCARD'

await chatunity.sendMessage(id, { 
    contacts: { 
        displayName: 'Itchatunitychann', 
        contacts: [{ vcard }] 
    }
})

Reaction Message

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

Pin Message

await chatunity.sendMessage(jid, {
    pin: {
        type: 1, // 2 to remove
        time: 86400, // 24h in seconds
        key: Key
    }
})

Keep Message

await chatunity.sendMessage(jid, {
    keep: {
        key: Key,
        type: 1
    }
})

Poll Message

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

Poll Result Message

await chatunity.sendMessage(jid, {
    pollResult: {
        name: 'Hi', 
        values: [['Option 1', 1000], ['Option 2', 2000]]
    }
})

Call Message

await chatunity.sendMessage(jid, {
    call: {
        name: 'Hey',
        type: 1 // 2 for video
    }
})

Event Message

await chatunity.sendMessage(jid, {
    event: {
        isCanceled: false,
        name: 'Holiday together!',
        description: 'Who wants to come along?', 
        location: {
            degreesLatitude: 24.121231,
            degreesLongitude: 55.1121221,
            name: 'Location name'
        },
        call: 'audio',
        startTime: number, 
        endTime: number, 
        extraGuestsAllowed: true
    }
})

Order Message

await chatunity.sendMessage(jid, {
    order: {
        orderId: '574xxx',
        thumbnail: 'your_thumbnail', 
        itemCount: 'your_count',
        status: 'INQUIRY',
        surface: 'CATALOG',
        message: 'your_caption',
        orderTitle: "your_title",
        sellerJid: 'your_jid',
        token: 'your_token',
        totalAmount1000: 'your_amount',
        totalCurrencyCode: 'IDR'
    }
})

Product Message

await chatunity.sendMessage(jid, {
    product: {
        productImage: { url: 'your_url' },
        productId: 'your_id', 
        title: 'your_title',
        description: 'your_description', 
        currencyCode: 'IDR', 
        priceAmount1000: 'your_amount', 
        url: 'your_url',
        productImageCount: 'your_imageCount'
    },
    businessOwnerJid: 'your_jid' 
})

Payment Message

await chatunity.sendMessage(jid, {
    payment: {
        note: 'Hi!',
        currency: 'IDR',
        amount: '10000',
        expiry: 0
    }
})

Payment Invite Message

await chatunity.sendMessage(id, { 
    paymentInvite: {
        type: 1,
        expiry: 0 
    }   
})

Admin Invite Message

await chatunity.sendMessage(jid, {
    adminInvite: {
        jid: '123xxx@newsletter',
        name: 'newsletter_name', 
        caption: 'Please be my channel admin',
        expiration: 86400
    }
})

Group Invite Message

await chatunity.sendMessage(jid, {
    groupInvite: {
        jid: '[email protected]',
        name: 'group_name', 
        caption: 'Please Join My WhatsApp Group',
        code: 'code_invite',
        expiration: 86400
    }
})

Sticker Pack Message

await chatunity.sendMessage(jid, {
    stickerPack: {
        name: 'Hiii', 
        publisher: 'By Itchatunitychann', 
        description: 'Hello', 
        cover: Buffer,
        stickers: [{
            sticker: { url: 'https://example.com/1234kjd.webp' }, 
            emojis: ['❤'],
            isLottie: false,
            isAnimated: false
        }]
    }
})

Share Phone Number Message

await chatunity.sendMessage(jid, { sharePhoneNumber: {} })

Request Phone Number Message

await chatunity.sendMessage(jid, { requestPhoneNumber: {} })

Button Reply Message

// List
await chatunity.sendMessage(jid, {
    buttonReply: {
        name: 'Hi', 
        description: 'description', 
        rowId: 'ID'
    }, 
    type: 'list'
})

// Plain
await chatunity.sendMessage(jid, {
    buttonReply: {
        displayText: 'Hi', 
        id: 'ID'
    }, 
    type: 'plain'
})

// Template
await chatunity.sendMessage(jid, {
    buttonReply: {
        displayText: 'Hi', 
        id: 'ID', 
        index: 'number'
    }, 
    type: 'template'
})

// Interactive
await chatunity.sendMessage(jid, {
    buttonReply: {
        body: 'Hi', 
        nativeFlows: {
            name: 'menu_options', 
            paramsJson: JSON.stringify({ id: 'ID', description: 'description' }),
            version: 1
        }
    }, 
    type: 'interactive'
})

Buttons Message

await chatunity.sendMessage(jid, {
    text: 'This is a button message!',
    footer: 'Hello World!',  
    buttons: [{ 
        buttonId: 'Id1', 
        buttonText: { displayText: 'Button 1' }
    }, { 
        buttonId: 'Id2', 
        buttonText: { displayText: 'Button 2' }
    }]
})

Buttons List Message

await chatunity.sendMessage(jid, {
    text: 'This is a list!', 
    footer: 'Hello World!', 
    title: 'Amazing list title', 
    buttonText: 'View list', 
    sections: [{
        title: 'Section 1',
        rows: [{
            title: 'Option 1', 
            rowId: 'option1'
        }, {
            title: 'Option 2', 
            rowId: 'option2', 
            description: 'Description'
        }]
    }]
})

Buttons Product List Message

await chatunity.sendMessage(jid, {
    text: 'This is a list!', 
    footer: 'Hello World!', 
    title: 'Product list', 
    buttonText: 'View list', 
    productList: [{
        title: 'This is a title', 
        products: [{ productId: '1234' }, { productId: '5678' }]
    }], 
    businessOwnerJid: '[email protected]', 
    thumbnail: 'https://example.com/image.jpg'
})

Buttons Cards Message

await chatunity.sendMessage(jid, {
    text: 'Body Message',
    title: 'Title Message', 
    cards: [{
        image: { url: 'https://example.com/image.jpg' },
        title: 'Card Title',
        body: 'Card Body',
        footer: 'Card Footer',
        buttons: [{
            name: 'quick_reply',
            buttonParamsJson: JSON.stringify({
                display_text: 'Button',
                id: 'ID'
            })
        }]
    }]
})

Buttons Interactive Message

await chatunity.sendMessage(jid, {
    text: 'Interactive message',
    title: 'Title',
    footer: 'Footer',
    interactiveButtons: [
        {
            name: 'quick_reply',
            buttonParamsJson: JSON.stringify({
                display_text: 'Click Me!',
                id: 'your_id'
            })
        },
        {
            name: 'cta_url',
            buttonParamsJson: JSON.stringify({
                display_text: 'Follow',
                url: 'https://whatsapp.com/channel/0029Vag9VSI2ZjCocqa2lB1y'
            })
        },
        {
            name: 'cta_call',
            buttonParamsJson: JSON.stringify({
                display_text: 'Call',
                phone_number: '628xxx'
            })
        },
        {
            name: 'open_webview',
            buttonParamsJson: JSON.stringify({
                title: 'Follow',
                link: { url: 'https://example.com' }
            })
        }
    ]
})

Buttons Interactive Message PIX

await chatunity.sendMessage(jid, { 
    text: '',
    interactiveButtons: [{ 
        name: 'payment_info', 
        buttonParamsJson: JSON.stringify({ 
            payment_settings: [{
                type: "pix_static_code", 
                pix_static_code: { 
                    merchant_name: 'Your Name', 
                    key: '[email protected]', 
                    key_type: 'EMAIL'
                } 
            }] 
        }) 
    }] 
})

Buttons Interactive Message PAY

await chatunity.sendMessage(jid, { 
    text: '',
    interactiveButtons: [{ 
        name: 'review_and_pay', 
        buttonParamsJson: JSON.stringify({ 
            currency: 'IDR', 
            total_amount: { value: '999999999', offset: '100' }, 
            reference_id: '45XXXXX',
            type: 'physical-goods',
            order: {
                status: 'completed', 
                items: [{
                    name: 'Product', 
                    amount: { value: '999999999', offset: '100' }, 
                    quantity: '1'
                }]
            }
        }) 
    }] 
})

Status Mentions Message

const jids = ['[email protected]', '[email protected]']

// Text
await chatunity.sendStatusMentions(
    {
        text: 'Hello Everyone :3', 
        font: 2
    }, 
    jids
)

// Image
await chatunity.sendStatusMentions(
    { image: { url: 'https://example.com/image.jpg' } }, 
    jids
)

// Video
await chatunity.sendStatusMentions(
    { video: { url: 'https://example.com/video.mp4' } }, 
    jids
)

Shop Message

await chatunity.sendMessage(jid, {      
    text: 'Body',
    title: 'Title', 
    footer: 'Footer',
    shop: {
        surface: 1,
        id: 'https://example.com'
    }, 
    viewOnce: true
})

Collection Message

await chatunity.sendMessage(jid, {      
    text: 'Body',
    title: 'Title', 
    footer: 'Footer',
    collection: {
        bizJid: 'jid', 
        id: 'https://example.com', 
        version: 1
    }, 
    viewOnce: true
})

Media Messages

Sending media (video, stickers, images) is easier and more efficient.

[!NOTE] You can pass { stream: Stream }, { url: Url }, or Buffer directly. See more here

[!TIP] Use Stream or Url to save memory

GIF Message

await chatunity.sendMessage(jid, { 
    video: fs.readFileSync('Media/gif.mp4'),
    caption: 'hello world',
    gifPlayback: true
})

Video Message

await chatunity.sendMessage(id, { 
    video: { url: './Media/video.mp4' },
    caption: 'hello world'
})

Video PTV Message

await chatunity.sendMessage(id, { 
    video: { url: './Media/video.mp4' },
    ptv: true
})

Audio Message

Audio needs to be converted to OGG format with ffmpeg:

ffmpeg -i input.mp4 -avoid_negative_ts make_zero -ac 1 output.ogg
await chatunity.sendMessage(jid, {
    audio: { url: './Media/audio.mp3' },
    mimetype: 'audio/mp4'
})

Image Message

await chatunity.sendMessage(id, { 
    image: { url: './Media/image.png' },
    caption: 'hello world'
})

Album Message

await chatunity.sendMessage(id, { 
    album: [{
        image: { url: 'https://example.com/image.jpg' }, 
        caption: 'Caption'
    }, {
        video: { url: 'https://example.com/video.mp4' }, 
        caption: 'Caption'
    }]
})

View Once Message

await chatunity.sendMessage(id, { 
    image: { url: './Media/image.png' },
    viewOnce: true,
    caption: 'hello world'
})

Link Previews

By default, WhatsApp does not generate link previews when sent from web. Baileys provides this functionality.

To enable link previews, add link-preview-js to your project:

yarn add link-preview-js

Then send a link:

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

AI Icon Feature

await chatunity.sendMessage(jid, { text: 'Hi' }, { ai: true })

// With relay
await chatunity.relayMessage(jid, { extendedTextMessage: { text: 'Hi' } }, { AI: true })

Modifying Messages

Delete Messages (for everyone)

const msg = await chatunity.sendMessage(jid, { text: 'hello world' })
await chatunity.sendMessage(jid, { delete: msg.key })

Editing Messages

await chatunity.sendMessage(jid, { edit: msg.key, text: 'edited message' })

Working with Media

Thumbnail in Media Messages

Thumbnails can be generated automatically for images & stickers if you add jimp or sharp:

yarn add jimp
# or
yarn add sharp

For videos, install ffmpeg on your system.

Downloading Media Messages

import { createWriteStream } from 'fs'
import { downloadMediaMessage, getContentType } from '@chatunitycenter/baileys'

chatunity.ev.on('messages.upsert', async ({ messages }) => {
    for (const m of messages) {
        if (!m.message) return
        const messageType = getContentType(m)

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

Re-upload Media Message to WhatsApp

const downloadedContent = await downloadMediaMessage(...)
const uploadedUrl = await chatunity.uploadMedia(downloadedContent)

Table of Contents