malvin-baileys
v2.2.5
Published
WhatsApp Web API Library Modification By Malvin King.
Downloads
629
Maintainers
Readme
malvin-baileys
malvin-baileys is a cutting-edge, open-source Node.js library for seamless WhatsApp automation and integration. Built on WebSocket technology, it bypasses browser dependencies to deliver lightweight, high-performance connections. Ideal for developers crafting bots, chat automations, customer service platforms, and dynamic communication tools.
Developer: @XdKing2 | Package: npmjs.com/package/malvin-baileys
🙏 Credits & Attribution
[!NOTE] This project stands on the shoulders of those who came before it. Proper credit matters — always.
📦 Upstream & Original Authors
| Project | Author | Role | |---|---|---| | Baileys | @WhiskeySockets | Original upstream library |
✨ About This Fork
This fork builds upon malvin-baileys with a focus on production readiness and transparency.
Full credit for the foundational fork goes to @XdKing2 — this project would not exist without their work.
[!IMPORTANT] If you fork or redistribute this project, please:
- ✅ Keep original attributions intact
- ✅ Credit @XdKing2 for the v2 fork base
- ✅ Credit @WhiskeySockets for the upstream library
- 🚫 Do not claim others' work as your own
- 🚫 Do not rename and reupload without meaningful changes and proper credit
Made with 🤍 — because open source thrives on honesty.
⚙️ Changes from Upstream
🛠️ Internal Adjustments
- 🖼️ Fixed an issue where media could not be sent to newsletters due to an upstream issue.
- 📁 Reintroduced
makeInMemoryStorewith a minimal ESM adaptation and small adjustments for Baileys v7. - 📦 Switched FFmpeg execution from
exectospawnfor safer process handling. - 🗃️ Added
@napi-rs/imageas a supported image processing backend ingetImageProcessingLibrary(), offering a balance between performance and compatibility.
📨 Message Handling & Compatibility
- 👉 Added support for sending interactive message types (button, list, interactive, template, carousel).
- 📩 Added support for:
- 🖼️ Album messages
- 👤 Group status messages
- 🎞️ Status mention messages
- 📦 Sticker pack messages
- 🗓️ Event messages
- ✨ Rich response messages
- 🧾 Messages with code blocks
- 📋 Messages with tables
- 📊 Poll update messages
- 💭 Button/list/flow response messages
- 💳 Payment-related messages (request payment, payment invite, order, invoice)
- 📰 Simplified sending messages with ad thumbnails via
externalAdReplywithout requiring manualcontextInfo. - 💭 Added support for quoting messages inside channels (newsletters).
🧩 Additional Message Options
- 👁️ Added optional boolean flags:
- 🤖
ai— AI icon on message - 📣
mentionAll— Mention all group participants without requiring JIDs - 🐱
isLottie— Lottie sticker wrapper - 📑
spoiler— Spoiler message wrapper - 🔧
ephemeral,groupStatus,viewOnce,viewOnceV2,viewOnceV2Extension,interactiveAsTemplate— Message wrappers - 🔒
secureMetaServiceLabel— Secure meta service label on message - 📄
raw— Build your message manually (DO NOT USE FOR EXPLOITATION)
- 🤖
📋 Index
- 📥 Installation
- 🧩 Import (ESM & CJS)
- 🌐 Connect to WhatsApp
- 🗄️ Implementing a Data Store
- 🪪 WhatsApp IDs (JID) Formats
- ✉️ Sending Messages
- 📁 Sending Media Messages
- 👉 Sending Interactive Messages
- ✨ Rich & Structured Messages
- 💳 Sending Payment Messages
- 👁️ Other Message Options
- ♻️ Modify Messages
- 🧰 Additional Utilities
- 📣 Newsletter Management
- 👥 Group Management
- 👥 Community Management
- 🛒 Business Management
- 👤 Profile Management
- 🔐 Privacy Management
- 📡 Events
- 📦 Fork Base
- 📣 Credits
📥 Installation
# npm
npm install malvin-baileys
# yarn
yarn add malvin-baileys
# pnpm
pnpm add malvin-baileysVia package.json:
{
"dependencies": {
"malvin-baileys": "latest"
}
}Requirements: Node.js ≥ 20.x
🧩 Import (ESM & CJS)
// ESM
import { makeWASocket } from 'malvin-baileys'
// CJS (tested and working on Node.js 24 ✅)
const { makeWASocket } = require('malvin-baileys')🌐 Connect to WhatsApp
import { makeWASocket, delay, DisconnectReason, useMultiFileAuthState } from 'malvin-baileys'
import { Boom } from '@hapi/boom'
import pino from 'pino'
const myPhoneNumber = '263XXXXXXXX'
const logger = pino({ level: 'silent' })
const connectToWhatsApp = async () => {
const { state, saveCreds } = await useMultiFileAuthState('session')
const sock = makeWASocket({ logger, auth: state })
sock.ev.on('creds.update', saveCreds)
sock.ev.on('connection.update', async (update) => {
const { connection, lastDisconnect } = update
if (connection === 'connecting' && !sock.authState.creds.registered) {
await delay(1500)
const code = await sock.requestPairingCode(myPhoneNumber, "MRMALVIN")
console.log('🔗 Pairing code:', code)
} else if (connection === 'close') {
const shouldReconnect = new Boom(lastDisconnect?.error)?.output?.statusCode !== DisconnectReason.loggedOut
console.log('⚠️ Connection closed, reconnecting:', shouldReconnect)
if (shouldReconnect) connectToWhatsApp()
} else if (connection === 'open') {
console.log('✅ Successfully connected to WhatsApp')
}
})
sock.ev.on('messages.upsert', async ({ messages }) => {
for (const message of messages) {
if (!message.message) continue
console.log('🔔 Got new message:', message)
await sock.sendMessage(message.key.remoteJid, { text: '👋🏻 Hello world' })
}
})
}
connectToWhatsApp()🔐 Auth State
[!NOTE] You can use the experimental useSingleFileAuthState and useSqliteAuthState as an alternative to useMultiFileAuthState. However, useSingleFileAuthState already includes an internal caching mechanism, so there is no need to wrap state.keys with makeCacheableSignalKeyStore.
🗄️ Implementing a Data Store
[!CAUTION] Keeping an entire chat history in memory can lead to excessive RAM usage. Build your own data store for production.
import { makeWASocket, makeInMemoryStore, useMultiFileAuthState } from 'malvin-baileys'
import pino from 'pino'
const storePath = './store.json'
const logger = pino({ level: 'silent' })
const connectToWhatsApp = async () => {
const { state, saveCreds } = await useMultiFileAuthState('session')
const sock = makeWASocket({ logger, auth: state })
const store = makeInMemoryStore({ logger, socket: sock })
store.bind(sock.ev)
sock.ev.on('creds.update', saveCreds)
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))
})
// Read store from file on startup
store.readFromFile(storePath)
// Auto-save every 3 minutes
setInterval(() => store.writeToFile(storePath), 180000)
}
connectToWhatsApp()🪪 WhatsApp IDs (JID) Formats
Type Format Private chat [email protected] LID 12699999999@lid Group [email protected] Meta AI 11111111111@bot Broadcast [timestamp]@broadcast Stories status@broadcast Newsletter 1234XXXX@newsletter
✉️ Sending Messages
[!NOTE] You can get the jid from message.key.remoteJid.
🔠 Text
sock.sendMessage(jid, {
text: '👋🏻 Hello'
}, {
quoted: message
})🔔 Mention
// Regular mention
sock.sendMessage(jid, {
text: '👋🏻 Hello @948123456789',
mentions: ['[email protected]']
}, {
quoted: message
})
// Mention all (no JIDs needed)
sock.sendMessage(jid, {
text: '👋🏻 Hello @all',
mentionAll: true
}, {
quoted: message
})😁 Reaction
sock.sendMessage(jid, {
react: {
key: message.key,
text: '✨'
}
})📌 Pin Message
sock.sendMessage(jid, {
pin: message.key,
time: 86400, // 86400 (1d), 604800 (7d), 2592000 (30d)
type: 1 // 0 to unpin
})🔖 Keep Chat
[!NOTE] Keep Chat can only be used in chats or groups with disappearing messages enabled.
sock.sendMessage(jid, {
keep: message.key,
type: 1 // Or 2 to remove
})➡️ Forward Message
sock.sendMessage(jid, {
forward: message,
force: true // Optional
})👤 Contact
const vcard = 'BEGIN:VCARD\n'
+ 'VERSION:3.0\n'
+ 'FN:Malvin King\n'
+ 'ORG:Malvin Tech;\n'
+ 'TEL;type=CELL;type=VOICE;waid=263XXXXXXXX:+263 XXXXXXX\n'
+ 'END:VCARD'
sock.sendMessage(jid, {
contacts: {
displayName: 'Malvin King',
contacts: [{ vcard }]
}
}, {
quoted: message
})📍 Location
sock.sendMessage(jid, {
location: {
degreesLatitude: 24.121231,
degreesLongitude: 55.1121221,
name: '👋🏻 I am here'
}
}, {
quoted: message
})🗓️ Event
sock.sendMessage(jid, {
event: {
name: '🎶 Tech Meetup',
description: 'Join us for AI innovations and networking!',
call: 'video',
startDate: new Date(Date.now() + 3600000),
endDate: new Date(Date.now() + 28800000),
isCancelled: false,
isScheduleCall: false,
extraGuestsAllowed: false,
location: {
name: 'Online',
degreesLatitude: -6.2,
degreesLongitude: 106.8
}
}
}, {
quoted: message
})👥 Group Invite
const inviteCode = groupUrl.split('chat.whatsapp.com/')[1]?.split('?')[0]
sock.sendMessage(jid, {
groupInvite: {
inviteCode,
inviteExpiration: Date.now() + 86400000,
text: '👋🏻 Hello, we invite you to join our group.',
jid: '[email protected]',
subject: 'malvin-baileys',
}
}, {
quoted: message
})🛍️ Product
import { randomUUID } from 'crypto'
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
body: '👋🏻 Check my product here!',
footer: 'malvin-baileys',
product: {
currencyCode: 'USD',
description: '🛍️ Premium product!',
priceAmount1000: 70_000_000,
productId: randomUUID(),
productImageCount: 1,
salePriceAmount1000: 65_000_000,
signedUrl: 'https://npmjs.com/package/malvin-baileys',
title: '📦 Malvin Premium',
url: 'https://npmjs.com/package/malvin-baileys'
},
businessOwnerJid: '[email protected]'
})📊 Polls
// Regular poll
sock.sendMessage(jid, {
poll: {
name: '🔥 Voting time',
values: ['Yes', 'No'],
selectableCount: 1,
toAnnouncementGroup: false,
endDate: new Date(Date.now() + 28800000), // Optional
hideVoter: false, // Optional
canAddOption: false // Optional
}
}, {
quoted: message
})
// Quiz (newsletter only)
sock.sendMessage('1211111111111@newsletter', {
poll: {
name: '🔥 Quiz',
values: ['Yes', 'No'],
correctAnswer: 'Yes',
pollType: 1
}
})
// Poll result
sock.sendMessage(jid, {
pollResult: {
name: '📝 Poll Result',
votes: [
{ name: 'Nice', voteCount: 10 },
{ name: 'Nah', voteCount: 2 }
],
pollType: 0 // 1 for quiz
}
})
// Poll update
sock.sendMessage(jid, {
pollUpdate: {
metadata: {},
key: message.key,
vote: {
enclv: /* <Buffer> */,
encPayload: /* <Buffer> */
}
}
}, {
quoted: message
})💭 Button Response
// Using buttonsResponseMessage
sock.sendMessage(jid, {
type: 'plain',
buttonReply: {
id: '#Menu',
displayText: '✨ Interesting Menu'
}
}, {
quoted: message
})
// Using interactiveResponseMessage
sock.sendMessage(jid, {
flowReply: {
format: 0,
text: '💭 Response',
name: 'menu_options',
paramsJson: JSON.stringify({
id: '#Menu',
description: '✨ Interesting Menu'
})
}
}, {
quoted: message
})
// Using listResponseMessage
sock.sendMessage(jid, {
listReply: {
title: '📄 See More',
description: '✨ Interesting Menu',
id: '#Menu'
}
}, {
quoted: message
})
// Using templateButtonReplyMessage
sock.sendMessage(jid, {
type: 'template',
buttonReply: {
id: '#Menu',
displayText: '✨ Interesting Menu',
index: 1
}
}, {
quoted: message
})🎞️ Status Mention
sock.sendMessage([jidA, jidB, jidC], {
text: 'Hello! 👋🏻'
})📁 Sending Media Messages
[!NOTE] For media, you can pass a Buffer, { stream: Readable }, or { url: string } (local path or HTTP/HTTPS URL).
🖼️ Image
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
caption: '🔥 Superb'
}, {
quoted: message
})🎥 Video
sock.sendMessage(jid, {
video: { url: './path/to/video.mp4' },
gifPlayback: false, // true → send as GIF
ptv: false, // true → Picture-in-Picture (PTV)
caption: '🔥 Superb'
}, {
quoted: message
})📃 Sticker
sock.sendMessage(jid, {
sticker: { url: './path/to/sticker.webp' }
}, {
quoted: message
})💽 Audio
sock.sendMessage(jid, {
audio: { url: './path/to/audio.mp3' },
ptt: false // true → Voice Note
}, {
quoted: message
})🗂️ Document
sock.sendMessage(jid, {
document: { url: './path/to/document.pdf' },
mimetype: 'application/pdf',
caption: '✨ My work!'
}, {
quoted: message
})🖼️ Album (Image & Video)
sock.sendMessage(jid, {
album: [{
image: { url: './path/to/image.jpg' },
caption: '1st image'
}, {
video: { url: './path/to/video.mp4' },
caption: '1st video'
}, {
image: { url: './path/to/image.jpg' },
caption: '2nd image'
}, {
video: { url: './path/to/video.mp4' },
caption: '2nd video'
}]
}, {
quoted: message
})📦 Sticker Pack
[!IMPORTANT] If sharp or @napi-rs/image is not installed, cover and stickers must already be in WebP format.
sock.sendMessage(jid, {
cover: { url: './path/to/cover.webp' },
stickers: [
{ data: { url: './path/to/s1.webp' } },
{ data: { url: './path/to/s2.webp' } },
{ data: { url: './path/to/s3.webp' } }
],
name: '📦 Malvin Sticker Pack',
publisher: '🌟 Malvin King',
description: 'malvin-baileys'
}, {
quoted: message
})👉 Sending Interactive Messages
1️⃣ Buttons
// Simple buttons
sock.sendMessage(jid, {
text: '👆🏻 Buttons!',
footer: 'malvin-baileys',
buttons: [{
text: '👋🏻 SignUp',
id: '#SignUp'
}]
}, {
quoted: message
})
// Buttons with media & native flow sections
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
caption: '👆🏻 Buttons and Native Flow!',
footer: 'malvin-baileys',
buttons: [{
text: '👋🏻 Rating',
id: '#Rating'
}, {
text: '📋 Select',
sections: [{
title: '✨ Section 1',
rows: [{
header: '',
title: '💭 Secret Ingredient',
description: '',
id: '#SecretIngredient'
}]
}, {
title: '✨ Section 2',
highlight_label: '🔥 Popular',
rows: [{
header: '',
title: '🏷️ Coupon',
description: '',
id: '#CouponCode'
}]
}]
}]
}, {
quoted: message
})2️⃣ List
[!NOTE] List messages only work in private chat (@s.whatsapp.net).
sock.sendMessage(jid, {
text: '📋 List!',
footer: 'malvin-baileys',
buttonText: '📋 Select',
title: '👋🏻 Hello',
sections: [{
title: '🚀 Menu 1',
rows: [{
title: '✨ AI',
description: '',
rowId: '#AI'
}]
}, {
title: '🌱 Menu 2',
rows: [{
title: '🔍 Search',
description: '',
rowId: '#Search'
}]
}]
}, {
quoted: message
})3️⃣ Interactive (Native Flow)
// Native Flow
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
caption: '🗄️ Interactive!',
footer: 'malvin-baileys',
optionText: '👉🏻 Select Options',
optionTitle: '📄 Select Options',
offerText: '🏷️ Newest Coupon!',
offerCode: 'MALVIN2026',
offerUrl: 'https://npmjs.com/package/malvin-baileys',
offerExpiration: Date.now() + 3_600_000,
nativeFlow: [{
text: '👋🏻 Greeting',
id: '#Greeting',
icon: 'review'
}, {
text: '📞 Call',
call: '263XXXXXXXX'
}, {
text: '📋 Copy',
copy: 'MALVIN-BAILEYS'
}, {
text: '🌐 Source',
url: 'https://npmjs.com/package/malvin-baileys',
useWebview: true
}, {
text: '📋 Select',
sections: [{
title: '✨ Section 1',
rows: [{ header: '', title: '🏷️ Coupon', description: '', id: '#CouponCode' }]
}, {
title: '✨ Section 2',
highlight_label: '🔥 Popular',
rows: [{ header: '', title: '💭 Secret Ingredient', description: '', id: '#SecretIngredient' }]
}],
icon: 'default'
}],
interactiveAsTemplate: false
}, {
quoted: message
})
// Native Flow with Audio in the Footer
sock.sendMessage(jid, {
text: '🔈 Music in the footer!',
audioFooter: {
url: './path/to/audio.mp3'
},
nativeFlow: [{
text: '👍🏻 Good, next',
id: '#Next',
icon: 'review'
}, {
text: '👎🏻 Skip',
id: '#Skip',
icon: 'default'
}]
}, {
quoted: message
})4️⃣ Carousel
sock.sendMessage(jid, {
text: '🗂️ Interactive with Carousel!',
footer: 'malvin-baileys',
cards: [{
image: { url: './path/to/image.jpg' },
caption: '🖼️ Image 1',
footer: '🏷️ Malvin Tech',
nativeFlow: [{
text: '🌐 Source',
url: 'https://npmjs.com/package/malvin-baileys',
useWebview: true
}]
}, {
image: { url: './path/to/image.jpg' },
caption: '🖼️ Image 2',
footer: '🏷️ Malvin Tech',
offerText: '🏷️ New Coupon!',
offerCode: 'MALVIN2026',
offerUrl: 'https://npmjs.com/package/malvin-baileys',
offerExpiration: Date.now() + 3_600_000,
nativeFlow: [{
text: '🌐 Source',
url: 'https://npmjs.com/package/malvin-baileys'
}]
}, {
image: { url: './path/to/image.jpg' },
caption: '🖼️ Image 3',
footer: '🏷️ Malvin Tech',
optionText: '👉🏻 Select Options',
optionTitle: '📄 Select Options',
offerText: '🏷️ New Coupon!',
offerCode: 'MALVIN2026',
offerExpiration: Date.now() + 3_600_000,
nativeFlow: [{
text: '🛒 Product',
id: '#Product',
icon: 'default'
}, {
text: '🌐 Source',
url: 'https://npmjs.com/package/malvin-baileys'
}]
}]
}, {
quoted: message
})5️⃣ Hydrated Template
sock.sendMessage(jid, {
title: '👋🏻 Hello',
image: { url: './path/to/image.jpg' },
caption: '🫙 Template!',
footer: 'malvin-baileys',
templateButtons: [{
text: '👉🏻 Tap Here',
id: '#Order'
}, {
text: '🌐 Source',
url: 'https://npmjs.com/package/malvin-baileys'
}, {
text: '📞 Call',
call: '263XXXXXXXX'
}]
}, {
quoted: message
})✨ Rich & Structured Messages
✨ Rich Response
[!NOTE] richResponse[] is a representation of submessages[] inside richResponseMessage. You can still use the original submessages[] field directly — the helper below is optional.
sock.sendMessage(jid, {
richResponse: [{
text: 'Example Usage',
}, {
language: 'javascript',
code: [{
highlightType: 0,
codeContent: 'console.log("Hello, World!")'
}]
}, {
text: 'Pretty simple, right?\n'
}, {
text: 'Comparison between Node.js, Bun, and Deno',
}, {
title: 'Runtime Comparison',
table: [{
isHeading: true,
items: ['', 'Node.js', 'Bun', 'Deno']
}, {
isHeading: false,
items: ['Engine', 'V8 (C++)', 'JavaScriptCore (C++)', 'V8 (C++)']
}, {
isHeading: false,
items: ['Performance', '4/5', '5/5', '4/5']
}]
}, {
text: 'Does this help clarify the differences?'
}]
})[!TIP] You can add syntax highlighting by importing tokenizeCode directly from the package.
import { tokenizeCode } from 'malvin-baileys'
const language = 'javascript'
const code = 'console.log("Hello, World!")'
sock.sendMessage(jid, {
richResponse: [{
text: 'Example Usage',
}, {
language,
code: tokenizeCode(code, language)
}, {
text: 'Pretty simple, right?'
}]
})🧾 Message with Code Block
[!NOTE] This feature already includes a built-in tokenizer.
sock.sendMessage(jid, {
headerText: '## Example Usage',
contentText: '---',
code: 'console.log("Hello, World!")',
language: 'javascript',
footerText: 'Pretty simple, right?'
})🌏 Message with Inline Entities
sock.sendMessage(jid, {
headerText: '## Check Out!',
contentText: '---',
links: [{
text: '1. GitHub',
title: 'Malvin Baileys Repository',
url: 'https://github.com/XdKing2/malvin-baileys'
}, {
text: '2. NPM',
title: 'NPM Package',
url: 'https://npmjs.com/package/malvin-baileys'
}, {
text: '3. WhatsApp Channel',
title: 'Malvin Tech Updates',
url: 'https://whatsapp.com/channel/0029VbB3YxTDJ6H15SKoBv3S'
}],
footerText: '---'
})📋 Message with Table
sock.sendMessage(jid, {
headerText: '## Comparison between Node.js, Bun, and Deno',
contentText: '---',
title: 'Runtime Comparison',
table: [
['', 'Node.js', 'Bun', 'Deno'],
['Engine', 'V8 (C++)', 'JavaScriptCore (C++)', 'V8 (C++)'],
['Performance', '4/5', '5/5', '4/5']
],
noHeading: false,
footerText: 'Does this help clarify the differences?'
})💳 Sending Payment Messages
1️⃣ Payment Invite
sock.sendMessage(jid, {
paymentInviteServiceType: 3 // 1, 2, or 3
})2️⃣ Invoice
[!NOTE] Invoice messages are not fully supported yet.
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
invoiceNote: '🏷️ Invoice'
})3️⃣ Order
sock.sendMessage(jid, {
orderText: '🛍️ Order',
thumbnail: fs.readFileSync('./path/to/image.jpg') // Must be Buffer
}, {
quoted: message
})4️⃣ Request Payment
sock.sendMessage(jid, {
text: '💳 Request Payment',
requestPaymentFrom: '[email protected]'
})👁️ Other Message Options
1️⃣ AI Label
[!NOTE] Only works in private chat (@s.whatsapp.net).
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
caption: '🤖 AI Labeled!',
ai: true
}, {
quoted: message
})2️⃣ Ephemeral
[!NOTE] Wraps message into ephemeralMessage.
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
caption: '👁️ Ephemeral',
ephemeral: true
})3️⃣ External Ad Reply
[!NOTE] Adds an ad thumbnail to messages (may not be displayed on all WhatsApp versions).
sock.sendMessage(jid, {
text: '📰 External Ad Reply',
externalAdReply: {
title: '📝 Malvin Baileys',
body: '❓ Powerful WhatsApp API',
thumbnail: fs.readFileSync('./path/to/image.jpg'),
largeThumbnail: false,
url: 'https://npmjs.com/package/malvin-baileys'
}
}, {
quoted: message
})4️⃣ Group Status
[!NOTE] Only works in group chat (@g.us).
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
caption: '👥 Group Status!',
groupStatus: true
})5️⃣ Lottie Sticker
[!NOTE] Wraps message into lottieStickerMessage.
sock.sendMessage(jid, {
sticker: { url: './path/to/sticker.webp' },
isLottie: true
})6️⃣ Raw
sock.sendMessage(jid, {
extendedTextMessage: {
text: '📃 Built manually from scratch using the raw WhatsApp proto structure',
contextInfo: {
externalAdReply: {
title: 'malvin-baileys',
thumbnail: fs.readFileSync('./path/to/image.jpg'),
sourceApp: 'whatsapp',
showAdAttribution: true,
mediaType: 1
}
}
},
raw: true
}, {
quoted: message
})7️⃣ Secure Meta Service Label
sock.sendMessage(jid, {
text: '🏷️ Just a label!',
secureMetaServiceLabel: true
})8️⃣ Spoiler
[!NOTE] Wraps message into spoilerMessage.
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
caption: '❔ Spoiler',
spoiler: true
})9️⃣ View Once
[!NOTE] Wraps message into viewOnceMessage.
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
caption: '👁️ View Once',
viewOnce: true
})🔟 View Once V2
[!NOTE] Wraps message into viewOnceMessageV2.
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
caption: '👁️ View Once V2',
viewOnceV2: true
})1️⃣1️⃣ View Once V2 Extension
[!NOTE] Wraps message into viewOnceMessageV2Extension.
sock.sendMessage(jid, {
image: { url: './path/to/image.jpg' },
caption: '👁️ View Once V2 Extension',
viewOnceV2Extension: true
})♻️ Modify Messages
🗑️ Delete Messages
sock.sendMessage(jid, {
delete: message.key
})✏️ Edit Messages
// Edit plain text
sock.sendMessage(jid, {
text: '✨ I mean, nice!',
edit: message.key
})
// Edit media caption
sock.sendMessage(jid, {
caption: '✨ I mean, here is the image!',
edit: message.key
})🧰 Additional Utilities
🏷️ Find User ID (JID / LID)
[!NOTE] The ID must contain numbers only (no +, (), or -) and must include the country code.
// By phone number
const ids = await sock.findUserId('[email protected]')
// By LID
const ids = await sock.findUserId('43411111111111@lid')
console.log(ids)
// Output: { phoneNumber: '[email protected]', lid: '43411111111111@lid' }
// On failure: { phoneNumber: '...', lid: 'id-not-found' }🔑 Custom Pairing Code
[!NOTE] Phone number must contain numbers only, no +, (), or -.
const phoneNumber = '263XXXXXXXX'
const customPairingCode = 'MRMALVIN'
await sock.requestPairingCode(phoneNumber, customPairingCode)
console.log('🔗 Pairing code:', customPairingCode)🖼️ Image Processing
[!NOTE] Automatically uses the best available image processing library: sharp, @napi-rs/image, or jimp.
import { getImageProcessingLibrary } from 'malvin-baileys'
import { readFile } from 'fs/promises'
const lib = await getImageProcessingLibrary()
const bufferOrFilePath = './path/to/image.jpg'
const width = 512
let output
// If sharp is installed
if (lib.sharp?.default) {
const img = lib.sharp.default(bufferOrFilePath)
output = await img.resize(width).jpeg({ quality: 80 }).toBuffer()
}
// If @napi-rs/image is installed
else if (lib.image?.Transformer) {
const inputBuffer = Buffer.isBuffer(bufferOrFilePath)
? bufferOrFilePath
: await readFile(bufferOrFilePath)
const img = new lib.image.Transformer(inputBuffer)
output = await img.resize(width, undefined, 0).jpeg(50)
}
// If jimp is installed
else if (lib.jimp?.Jimp) {
const img = await lib.jimp.Jimp.read(bufferOrFilePath)
output = await img
.resize({ w: width, mode: lib.jimp.ResizeStrategy.BILINEAR })
.getBuffer('image/jpeg', { quality: 50 })
}
// Fallback
else {
throw new Error('No image processing library available')
}
console.log('✅ Process completed!')
console.dir(output, { depth: null })📣 Newsletter Management
// Create
sock.newsletterCreate('Malvin Baileys', '📣 Fresh updates weekly')
// Get info
const metadata = await sock.newsletterMetadata('1231111111111@newsletter')
console.dir(metadata, { depth: null })
// Get subscribers count
const subscribers = await sock.newsletterSubscribers('1231111111111@newsletter')
console.dir(subscribers, { depth: null })
// Follow and Unfollow
sock.newsletterFollow('1231111111111@newsletter')
sock.newsletterUnfollow('1231111111111@newsletter')
// Mute and Unmute
sock.newsletterMute('1231111111111@newsletter')
sock.newsletterUnmute('1231111111111@newsletter')
// Demote admin
sock.newsletterDemote('1231111111111@newsletter', '[email protected]')
// Change owner
sock.newsletterChangeOwner('1231111111111@newsletter', '[email protected]')
// Generic update
sock.newsletterUpdate('1231111111111@newsletter', { name: 'malvin-baileys' })
// Update name & description
sock.newsletterUpdateName('1231111111111@newsletter', '📦 malvin-baileys')
sock.newsletterUpdateDescription('1231111111111@newsletter', '📣 Fresh updates weekly')
// Update / remove photo
sock.newsletterUpdatePicture('1231111111111@newsletter', { url: './image.jpg' })
sock.newsletterRemovePicture('1231111111111@newsletter')
// React to a message
sock.newsletterReactMessage('1231111111111@newsletter', '100', '💛')
// Get admin count
const count = await sock.newsletterAdminCount('1231111111111@newsletter')
// Get all subscribed newsletters
const newsletters = await sock.newsletterSubscribed()
console.dir(newsletters, { depth: null })
// Fetch messages
const messages = sock.newsletterFetchMessages('jid', '1231111111111@newsletter', 50, 0, 0)
console.dir(messages, { depth: null })
// Delete newsletter
sock.newsletterDelete('1231111111111@newsletter')👥 Group Management
// Create and add participants
const group = await sock.groupCreate('malvin-baileys', ['[email protected]'])
console.dir(group, { depth: null })
// Get info
const metadata = await sock.groupMetadata(jid)
console.dir(metadata, { depth: null })
// Invite management
sock.groupInviteCode(jid)
sock.groupRevokeInvite(jid)
sock.groupAcceptInvite(inviteCode)
sock.groupLeave(jid)
// Get group info from invite link
const group = await sock.groupGetInviteInfo('https://chat.whatsapp.com/ABC123')
console.log('👥 Got group info from link:', group)
// Members
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'add')
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'remove')
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'promote')
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'demote')
// Accept join requests
sock.groupRequestParticipantsUpdate(jid, ['[email protected]'], 'approve')
// Update info
sock.groupUpdateSubject(jid, '📦 malvin-baileys')
sock.groupUpdateDescription(jid, 'Updated description')
sock.updateProfilePicture(jid, { url: './image.jpg' })
sock.removeProfilePicture(jid)
// Settings
sock.groupSettingUpdate(jid, 'announcement') // Admin only chat
sock.groupSettingUpdate(jid, 'not_announcement') // Open chat
sock.groupSettingUpdate(jid, 'locked') // Admin only info edit
sock.groupSettingUpdate(jid, 'unlocked') // All can edit info
sock.groupMemberAddMode(jid, 'admin_add') // Admin only can add
sock.groupMemberAddMode(jid, 'all_member_add') // All can add
// Disappearing messages
sock.groupToggleEphemeral(jid, 86400) // Enable (1 day)
sock.groupToggleEphemeral(jid, 0) // Disable
// Approval mode
sock.groupJoinApprovalMode(jid, 'on')
sock.groupJoinApprovalMode(jid, 'off')
// Fetch all participating groups
const groups = await sock.groupFetchAllParticipating()
console.dir(groups, { depth: null })
// Get pending join requests
const requests = await sock.groupRequestParticipantsList(jid)
console.dir(requests, { depth: null })
// Update bot member label
sock.updateMemberLabel(jid, 'malvin-baileys')👥 Community Management
// Create a new community with description
const community = await sock.communityCreate('malvin-baileys', '📣 Fresh updates weekly')
console.dir(community, { depth: null })
// Create a subgroup for community and add participants
const group = await sock.communityCreateGroup('📢 Announcements', ['[email protected]'], communityJid)
// Link / unlink an existing group
sock.communityLinkGroup(groupJid, communityJid)
sock.communityUnlinkGroup(groupJid, communityJid)
// Get info
const metadata = await sock.communityMetadata(jid)
console.dir(metadata, { depth: null })
// Invite management
const inviteCode = await sock.communityInviteCode(jid)
sock.communityRevokeInvite(jid)
sock.communityAcceptInvite(inviteCode)
sock.communityLeave(jid)
// Get community info from invite code
const communityInfo = await sock.communityGetInviteInfo('ABC123456789')
console.log('👥 Got community info from invite code:', communityInfo)
// Accept join requests
sock.communityRequestParticipantsUpdate(jid, ['[email protected]'], 'approve')
// Update info
sock.communityUpdateSubject(jid, '📦 malvin-baileys')
sock.communityUpdateDescription(jid, 'Updated description')
// Settings
sock.communitySettingUpdate(jid, 'announcement') // Admin only chat
sock.communitySettingUpdate(jid, 'not_announcement') // Open chat
sock.communitySettingUpdate(jid, 'locked') // Admin only info edit
sock.communitySettingUpdate(jid, 'unlocked') // All can edit info
sock.communityMemberAddMode(jid, 'admin_add') // Admin only can add
sock.communityMemberAddMode(jid, 'all_member_add') // All can add
// Disappearing messages
sock.communityToggleEphemeral(jid, 86400) // Enable (1 day)
sock.communityToggleEphemeral(jid, 0) // Disable
// Approval mode
sock.communityJoinApprovalMode(jid, 'on')
sock.communityJoinApprovalMode(jid, 'off')
// Fetch all participating communities
const communities = await sock.communityFetchAllParticipating()
console.dir(communities, { depth: null })
// Fetch all linked groups
const linked = await sock.communityFetchLinkedGroups(jid)
console.dir(linked, { depth: null })
// Get pending join requests
const communityRequests = await sock.communityRequestParticipantsList(jid)
console.dir(communityRequests, { depth: null })🛒 Business Management
// Create a new product
const product = await sock.productCreate({
name: '🧩 Malvin Premium Product',
description: 'Get a full version of our product!',
price: 100000,
currency: 'USD',
originCountryCode: 'US',
images: [
bufferImage,
{ url: './path/to/image.jpg' }
]
})
console.dir(product, { depth: null })
// Update product
await sock.productUpdate(productId, {
name: '🧩 Malvin Premium Product',
description: 'Get a full version with more features!',
price: 75000,
currency: 'USD',
images: [{ url: './path/to/image.jpg' }]
})
// Delete product
sock.productDelete([productId])
// Get catalog info
const { products, nextPageCursor } = await sock.getCatalog({
jid: '[email protected]',
limit: 10
})
// Get collections
const collections = await sock.getCollections('[email protected]', 10)
console.dir(collections, { depth: null })
// Get order info
const order = await sock.getOrderDetails(orderId, tokenBase64)
console.dir(order, { depth: null })
// Update business profile
await sock.updateBusinessProfile({
address: 'Harare, Zimbabwe',
description: '🛒 Malvin Official Store',
websites: ['https://npmjs.com/package/malvin-baileys'],
email: '[email protected]',
hours: {
timezone: 'Africa/Harare',
days: [{ day: 'mon', mode: 'open_24h' }]
}
})
// Update / remove cover photo
sock.updateCoverPhoto({ url: './path/to/image.jpg' })
sock.removeCoverPhoto(coverId)
// Quick replies
sock.addOrEditQuickReply({
shortcut: 'hello',
message: 'Hello from Malvin business account',
})
sock.removeQuickReply(timestamp)👤 Profile Management
// Get profile picture URL
const url = await sock.profilePictureUrl(jid, 'image')
console.log('🖼️ Got profile url:', url)
// Update / remove profile picture
sock.updateProfilePicture(jid, buffer)
sock.updateProfilePicture(jid, { url })
sock.removeProfilePicture(jid)
// Update name and status
sock.updateProfileName('Malvin Bot')
sock.updateProfileStatus('Available')
// Presence
sock.sendPresenceUpdate('available', jid)
sock.presenceSubscribe(jid)
// Read receipts
sock.readMessages([message.key])
sock.sendReceipt(jid, participant, [messageId], 'read')
// Block / Unblock
sock.updateBlockStatus(jid, 'block')
sock.updateBlockStatus(jid, 'unblock')
// Fetch blocklist
const blocked = await sock.fetchBlocklist()
console.dir(blocked, { depth: null })
// Modify chats
sock.chatModify({ archive: true, lastMessageOrig: message, lastMessage: message }, jid)
// Star messages
sock.star(jid, [{ id: messageId, fromMe: true }], true)
// Contacts
sock.addOrEditContact(jid, { displayName: 'Malvin King' })
sock.removeContact(jid)
// Labels
sock.addChatLabel(jid, labelId)
sock.removeChatLabel(jid, labelId)
sock.addMessageLabel(jid, messageId, labelId)
// App state sync
sock.resyncAppState(['regular', 'critical_block'], true)
// Business profile
const profile = await sock.getBusinessProfile(jid)
console.dir(profile, { depth: null })🔐 Privacy Management
// Last seen
sock.updateLastSeenPrivacy('all')
sock.updateLastSeenPrivacy('contacts')
sock.updateLastSeenPrivacy('contact_blacklist')
sock.updateLastSeenPrivacy('nobody')
// Online status
sock.updateOnlinePrivacy('all')
sock.updateOnlinePrivacy('match_last_seen')
// Profile picture
sock.updateProfilePicturePrivacy('contacts')
// Status
sock.updateStatusPrivacy('contacts')
// Read receipts
sock.updateReadReceiptsPrivacy('all')
sock.updateReadReceiptsPrivacy('none')
// Groups
sock.updateGroupsAddPrivacy('all')
sock.updateGroupsAddPrivacy('contacts')
// Messages
sock.updateMessagesPrivacy('all')
sock.updateMessagesPrivacy('contacts')
sock.updateMessagesPrivacy('nobody')
// Calls
sock.updateCallPrivacy('everyone')
// Default disappearing mode
sock.updateDefaultDisappearingMode(86400)
// Link previews
sock.updateDisableLinkPreviewsPrivacy(true)📡 Events
sock.ev.on('connection.update', (update) => {})
sock.ev.on('creds.update', (update) => {})
sock.ev.on('messaging-history.set', (update) => {})
sock.ev.on('messaging-history.status', (update) => {})
sock.ev.on('chats.upsert', (update) => {})
sock.ev.on('chats.update', (update) => {})
sock.ev.on('chats.delete', (update) => {})
sock.ev.on('chats.lock', (update) => {})
sock.ev.on('lid-mapping.update', (update) => {})
sock.ev.on('presence.update', (update) => {})
sock.ev.on('contacts.upsert', (update) => {})
sock.ev.on('contacts.update', (update) => {})
sock.ev.on('messages.delete', (update) => {})
sock.ev.on('messages.update', (update) => {})
sock.ev.on('messages.media-update', (update) => {})
sock.ev.on('messages.upsert', (update) => {})
sock.ev.on('messages.reaction', (update) => {})
sock.ev.on('message-receipt.update', (update) => {})
sock.ev.on('groups.upsert', (update) => {})
sock.ev.on('groups.update', (update) => {})
sock.ev.on('group-participants.update', (update) => {})
sock.ev.on('group.join-request', (update) => {})
sock.ev.on('group.member-tag.update', (update) => {})
sock.ev.on('blocklist.set', (update) => {})
sock.ev.on('blocklist.update', (update) => {})
sock.ev.on('call', (update) => {})
sock.ev.on('labels.edit', (update) => {})
sock.ev.on('labels.association', (update) => {})
sock.ev.on('newsletter.reaction', (update) => {})
sock.ev.on('newsletter.view', (update) => {})
sock.ev.on('newsletter-participants.update', (update) => {})
sock.ev.on('newsletter-settings.update', (update) => {})
sock.ev.on('settings.update', (update) => {})📦 Fork Base
[!NOTE] This fork is based on Baileys (GitHub) via malvin-baileys v2
📣 Credits
[!IMPORTANT] This fork uses Protocol Buffer definitions maintained by WPP Connect via wa-proto
Full credit goes to the original Baileys maintainers and contributors:
· WhiskeySockets/Baileys · @XdKing2 for the malvin-baileys distribution · purpshell · jlucaso1 · adiwajshing
Additional enhancements and modifications by Malvin King
Credits are mandatory and must remain unchanged in any form of redistribution or fork.
📄 License
MIT © Malvin King — See LICENSE for details.
📞 Support & Contact
· GitHub: @XdKing2 · NPM: malvin-baileys · WhatsApp Channel: Malvin Tech
Built with ❤️ for the WhatsApp dev community. Let's automate the future! 🚀
