Navigation

Getting Started

Messaging

Status & Stories

Groups

Advanced

Gifted-Baileys

A WebSocket-based JavaScript library for the WhatsApp Web API

npm version npm downloads GitHub stars

Disclaimer

Important Notice

This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with WhatsApp or any of its subsidiaries or affiliates. Use at your own discretion. Do not spam people with this. We discourage any stalkerware, bulk or automated messaging usage.

Installation

Install gifted-baileys using npm or yarn:

NPM

npm install gifted-baileys

Yarn

yarn add gifted-baileys

Import in Your Project

CommonJS (Recommended)

const { default: makeWASocket, useMultiFileAuthState, Browsers } = require('gifted-baileys')

ES Modules / TypeScript

import pkg from 'gifted-baileys'
const { default: makeWASocket, useMultiFileAuthState, Browsers } = pkg
Buttons Support

For sending buttons, please use the gifted-btns package.

Connecting Account

WhatsApp provides a multi-device API that allows gifted-baileys to be authenticated as a second WhatsApp client by scanning a QR code or using a Pairing Code.

Connect with QR Code

const { default: makeWASocket, useMultiFileAuthState, Browsers } = require('gifted-baileys')

async function connectToWhatsApp() {
    const { state, saveCreds } = await useMultiFileAuthState('auth_info')
    
    const sock = makeWASocket({
        auth: state,
        browser: Browsers.ubuntu('Gifted'),
        printQRInTerminal: true
    })
    
    sock.ev.on('creds.update', saveCreds)
    
    sock.ev.on('connection.update', (update) => {
        const { connection, lastDisconnect } = update
        if (connection === 'close') {
            console.log('Connection closed, reconnecting...')
            connectToWhatsApp()
        } else if (connection === 'open') {
            console.log('Connected successfully!')
        }
    })
    
    sock.ev.on('messages.upsert', async ({ messages }) => {
        const m = messages[0]
        if (!m.message) return
        console.log('Received message:', m)
    })
}

connectToWhatsApp()

Connect with Pairing Code

The pairing code method allows you to connect without scanning a QR code. This is useful for terminal-based applications and session generators.

const { default: makeWASocket, useMultiFileAuthState, Browsers } = require('gifted-baileys')

async function connectWithPairingCode() {
    const { state, saveCreds } = await useMultiFileAuthState('auth_info')
    
    const sock = makeWASocket({
        auth: state,
        browser: Browsers.ubuntu('Gifted'),
        printQRInTerminal: false
    })
    
    sock.ev.on('creds.update', saveCreds)
    
    // Request pairing code for a phone number
    if (!sock.authState.creds.registered) {
        const phoneNumber = '254700000000' // Your phone number with country code
        const code = await sock.requestPairingCode(phoneNumber)
        console.log('Your pairing code:', code)
    }
    
    sock.ev.on('connection.update', (update) => {
        const { connection } = update
        if (connection === 'open') {
            console.log('Connected successfully!')
        }
    })
}

connectWithPairingCode()

Session Management

gifted-baileys provides built-in session management to save and restore your connection state:

const { useMultiFileAuthState } = require('gifted-baileys')

// Initialize auth state from a folder
const { state, saveCreds } = await useMultiFileAuthState('auth_info')

const sock = makeWASocket({
    auth: state
})

// Save credentials when they update
sock.ev.on('creds.update', saveCreds)

Sending Messages

Text Message

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

Reply to a Message (Quote)

await sock.sendMessage(jid, {
    text: 'This is a reply!'
}, { quoted: quotedMessage })

Mention Users

await sock.sendMessage(groupJid, {
    text: '@user1 @user2 Hello!',
    mentions: ['254700000000@s.whatsapp.net', '254711111111@s.whatsapp.net']
})

Location Message

await sock.sendMessage(jid, {
    location: {
        degreesLatitude: -1.2921,
        degreesLongitude: 36.8219,
        name: 'Nairobi, Kenya',
        address: 'Nairobi City'
    }
})

Contact Message

const vcard = 'BEGIN:VCARD\n' +
    'VERSION:3.0\n' +
    'FN:John Doe\n' +
    'TEL;type=CELL;type=VOICE;waid=254700000000:+254 700 000 000\n' +
    'END:VCARD'

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

Poll Message

await sock.sendMessage(jid, {
    poll: {
        name: 'What is your favorite color?',
        values: ['Red', 'Blue', 'Green', 'Yellow'],
        selectableCount: 1
    }
})

Reaction Message

await sock.sendMessage(jid, {
    react: {
        text: '👍', // Emoji to react with
        key: messageKey // Key of the message to react to
    }
})

Pin Message

await sock.sendMessage(jid, {
    pin: {
        type: 1, // 1 to pin, 2 to unpin
        time: 86400 // Duration in seconds (24 hours)
    }
})

Forward Message

const { generateForwardMessageContent } = require('gifted-baileys')

const forwardContent = generateForwardMessageContent(message, false)
await sock.sendMessage(jid, forwardContent)

Delete Message (for everyone)

await sock.sendMessage(jid, { delete: messageKey })

Edit Message

await sock.sendMessage(jid, {
    text: 'Edited message content',
    edit: messageKey
})

Media Messages

Image Message

// From URL
await sock.sendMessage(jid, {
    image: { url: 'https://example.com/image.jpg' },
    caption: 'Check out this image!'
})

// From file path
await sock.sendMessage(jid, {
    image: { url: './image.jpg' },
    caption: 'Local image'
})

// From buffer
await sock.sendMessage(jid, {
    image: imageBuffer,
    caption: 'Image from buffer'
})

Video Message

await sock.sendMessage(jid, {
    video: { url: './video.mp4' },
    caption: 'Check out this video!'
})

// As GIF (gifPlayback)
await sock.sendMessage(jid, {
    video: { url: './animation.mp4' },
    gifPlayback: true
})

Audio Message

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

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

Document Message

await sock.sendMessage(jid, {
    document: { url: './document.pdf' },
    mimetype: 'application/pdf',
    fileName: 'document.pdf'
})

Sticker Message

await sock.sendMessage(jid, {
    sticker: { url: './sticker.webp' }
})

View Once Message

await sock.sendMessage(jid, {
    image: { url: './secret-image.jpg' },
    viewOnce: true
})

Downloading Media

const { downloadMediaMessage } = require('gifted-baileys')
const { writeFileSync } = require('fs')

const buffer = await downloadMediaMessage(
    message,
    'buffer',
    {},
    {
        logger,
        reuploadRequest: sock.updateMediaMessage
    }
)

writeFileSync('./downloaded-media.jpg', buffer)

Group Status (Story) Sending

gifted-baileys supports sending status/story messages directly to groups. This feature allows you to share status updates with specific groups.

About Group Status

Group status messages appear as status updates within the group chat. This is different from broadcasting to all contacts.

Send Image Status to Group

await sock.sendMessage('120363419778858313@g.us', {
    groupStatusMessage: {
        image: { url: 'https://example.com/image.jpg' },
        caption: 'Check out my status!'
    }
})

Send Video Status to Group

await sock.sendMessage('120363419778858313@g.us', {
    groupStatusMessage: {
        video: { url: 'https://example.com/video.mp4' },
        caption: 'My video status!'
    }
})

Send Text Status to Group

await sock.sendMessage('120363419778858313@g.us', {
    groupStatusMessage: {
        text: 'Hello from my status!',
        backgroundColor: '#FF5733',
        font: 1
    }
})

Send Audio Status to Group

await sock.sendMessage('120363419778858313@g.us', {
    groupStatusMessage: {
        audio: { url: 'https://example.com/audio.mp3' },
        mimetype: 'audio/mp4',
        ptt: true
    }
})

Alternative Helper Method

You can also use the built-in helper method:

await sock.giftedStatus.sendGroupStatus('120363419778858313@g.us', {
    image: { url: 'https://example.com/image.jpg' },
    caption: 'My group status!'
})

Broadcast Stories

Send status updates to all your contacts using the broadcast JID.

Send Image Story

await sock.sendMessage('status@broadcast', {
    image: { url: './status-image.jpg' },
    caption: 'My new status!'
})

Send Video Story

await sock.sendMessage('status@broadcast', {
    video: { url: './status-video.mp4' },
    caption: 'Video status update!'
})

Send Text Story

await sock.sendMessage('status@broadcast', {
    text: 'My text status!',
    backgroundColor: '#128C7E',
    font: 2
})

Group Management

Create a Group

const group = await sock.groupCreate('My Group', [
    '254700000000@s.whatsapp.net',
    '254711111111@s.whatsapp.net'
])
console.log('Group created:', group.id)

Add/Remove Participants

// Add participants
await sock.groupParticipantsUpdate(
    groupJid,
    ['254700000000@s.whatsapp.net'],
    'add'
)

// Remove participants
await sock.groupParticipantsUpdate(
    groupJid,
    ['254700000000@s.whatsapp.net'],
    'remove'
)

// Promote to admin
await sock.groupParticipantsUpdate(
    groupJid,
    ['254700000000@s.whatsapp.net'],
    'promote'
)

// Demote admin
await sock.groupParticipantsUpdate(
    groupJid,
    ['254700000000@s.whatsapp.net'],
    'demote'
)

Group Settings

// Update group subject (name)
await sock.groupUpdateSubject(groupJid, 'New Group Name')

// Update group description
await sock.groupUpdateDescription(groupJid, 'New group description')

// Get group metadata
const metadata = await sock.groupMetadata(groupJid)
console.log('Group name:', metadata.subject)
console.log('Participants:', metadata.participants)

// Get invite code
const code = await sock.groupInviteCode(groupJid)
console.log('Invite link:', `https://chat.whatsapp.com/${code}`)

// Revoke invite code
await sock.groupRevokeInvite(groupJid)

// Join group by invite code
await sock.groupAcceptInvite('invite-code-here')

// Leave group
await sock.groupLeave(groupJid)

Group Settings Modification

// Only admins can send messages
await sock.groupSettingUpdate(groupJid, 'announcement')

// Everyone can send messages
await sock.groupSettingUpdate(groupJid, 'not_announcement')

// Only admins can edit group info
await sock.groupSettingUpdate(groupJid, 'locked')

// Everyone can edit group info
await sock.groupSettingUpdate(groupJid, 'unlocked')

Privacy Settings

Block/Unblock User

// Block user
await sock.updateBlockStatus(jid, 'block')

// Unblock user
await sock.updateBlockStatus(jid, 'unblock')

Get Privacy Settings

const settings = await sock.fetchPrivacySettings()
console.log(settings)

Get Block List

const blocklist = await sock.fetchBlocklist()
console.log('Blocked users:', blocklist)

Update Privacy Settings

// Update last seen privacy
await sock.updateLastSeenPrivacy('contacts') // 'all', 'contacts', 'none'

// Update online privacy
await sock.updateOnlinePrivacy('all') // 'all', 'match_last_seen'

// Update profile picture privacy
await sock.updateProfilePicturePrivacy('contacts') // 'all', 'contacts', 'none'

// Update status privacy
await sock.updateStatusPrivacy('contacts') // 'all', 'contacts', 'none'

// Update read receipts
await sock.updateReadReceiptsPrivacy('all') // 'all', 'none'

Profile Management

Update Profile Name

await sock.updateProfileName('New Name')

Update Profile Status

await sock.updateProfileStatus('My new status')

Update Profile Picture

await sock.updateProfilePicture(sock.user.id, { url: './new-picture.jpg' })

Remove Profile Picture

await sock.removeProfilePicture(sock.user.id)

Get Profile Picture

const ppUrl = await sock.profilePictureUrl(jid, 'image')
console.log('Profile picture URL:', ppUrl)

Event Handling

gifted-baileys uses an event-driven architecture. Here are the main events you can listen to:

// Connection updates
sock.ev.on('connection.update', (update) => {
    const { connection, lastDisconnect, qr } = update
    if (qr) {
        console.log('QR code received')
    }
    if (connection === 'close') {
        const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== 401
        if (shouldReconnect) {
            connectToWhatsApp()
        }
    } else if (connection === 'open') {
        console.log('Connected!')
    }
})

// New messages
sock.ev.on('messages.upsert', async ({ messages, type }) => {
    for (const msg of messages) {
        console.log('New message:', msg)
    }
})

// Message updates (delivered, read, etc.)
sock.ev.on('messages.update', async (updates) => {
    for (const update of updates) {
        console.log('Message update:', update)
    }
})

// Presence updates
sock.ev.on('presence.update', (presence) => {
    console.log('Presence:', presence)
})

// Chat updates
sock.ev.on('chats.upsert', (chats) => {
    console.log('New chats:', chats)
})

// Group updates
sock.ev.on('groups.upsert', (groups) => {
    console.log('New groups:', groups)
})

// Group participant updates
sock.ev.on('group-participants.update', (update) => {
    console.log('Group participants update:', update)
})

// Credentials update (save session)
sock.ev.on('creds.update', saveCreds)

WhatsApp IDs (JIDs)

WhatsApp uses different JID formats for different chat types:

Type Format Example
Personal Chat phone@s.whatsapp.net 254700000000@s.whatsapp.net
Group Chat id@g.us 120363419778858313@g.us
Broadcast/Story status@broadcast status@broadcast
Newsletter id@newsletter 123456789012345678@newsletter
LID (Link ID) lid@lid 123456789:0@lid

Utility Functions

const {
    jidDecode,
    jidEncode,
    jidNormalizedUser,
    isJidUser,
    isJidGroup,
    isJidBroadcast,
    isJidStatusBroadcast,
    isLidUser,
    areJidsSameUser,
    getContentType,
    extractMessageContent,
    generateMessageID
} = require('gifted-baileys')

// Decode a JID
const decoded = jidDecode('254700000000@s.whatsapp.net')
// { user: '254700000000', server: 's.whatsapp.net' }

// Check JID type
isJidUser('254700000000@s.whatsapp.net') // true
isJidGroup('120363419778858313@g.us') // true
isJidStatusBroadcast('status@broadcast') // true
isLidUser('123456789:0@lid') // true

// Get content type from message
const type = getContentType(message.message)
// 'imageMessage', 'videoMessage', 'conversation', etc.

// Extract message content
const content = extractMessageContent(message.message)

Modifying Chats

Archive/Unarchive

// Archive
await sock.chatModify({ archive: true }, jid)

// Unarchive
await sock.chatModify({ archive: false }, jid)

Mute/Unmute

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

// Unmute
await sock.chatModify({ mute: null }, jid)

Mark as Read/Unread

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

// Mark as unread
await sock.chatModify({ markRead: false }, jid)

Pin/Unpin Chat

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

// Unpin chat
await sock.chatModify({ pin: false }, jid)

Delete Chat

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

Clear Chat

await sock.chatModify({ clear: { messages: [{ id: messageId, fromMe: true }] } }, jid)

User Queries

Check if Number Exists on WhatsApp

const [result] = await sock.onWhatsApp('254700000000')
if (result.exists) {
    console.log('User exists:', result.jid)
}

Get User Status

const status = await sock.fetchStatus(jid)
console.log('Status:', status.status)
console.log('Set at:', status.setAt)

Get Business Profile

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

Subscribe to Presence

await sock.presenceSubscribe(jid)

sock.ev.on('presence.update', (update) => {
    console.log('Presence update:', update)
})