@sairidev/baileys-new
v0.3.18
Published
Enhanced Baileys v7
Maintainers
Readme
🌱 @sairidev/baileys
✨ Highlights
This fork designed for production use with a focus on clarity and safety:
- 🚫 No obfuscation. Easy to read and audit.
- 🚫 No auto-follow channel (newsletter) behavior.
[!IMPORTANT] Hi everyone,
I need to say this clearly.
Some npm packages are reuploading my fork under different names, with almost no meaningful changes:
They:
- Renamed my fork under different package names
- Removed or ignored proper maintainer credit
- Added unnecessary overhead
- Rewrote changelogs and modification notes under their own names
- Claimed existing work and changes as if they made them
- Copied code directly from my fork with little to no meaningful modification
This is not acceptable.
To be clear, I am NOT the original maintainer of Baileys. full respect goes to https://github.com/WhiskeySockets/Baileys.
This issue is about attribution, honesty, and respecting open-source contributions.
Forking is completely fine. Removing credits and presenting someone else's work as your own is not.
Please report if necessary.
Thank you. 🤍
[!NOTE] 📄 This project is maintained with limited scope and is not intended to replace upstream Baileys.
😞 And, really sorry for my bad english.
🛠️ 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.
📨 Messages Handling & Compatibility
- 📩 Expanded messages support for:
- 🖼️ Album Message
- 👤 Group Status Message
- 👉🏻 Interactive Message (buttons, lists, native flows, templates, carousels).
- 🎞️ Status Mention Message
- 📦 Sticker Pack Message
- ✨ Rich Response Message [NEW]
- 🧾 Message with Code Blocks [NEW]
- 🌏 Message with Inline Entities [NEW]
- 📋 Message with Table [NEW]
- 💳 Payment-related Message (payment requests, invites, orders, invoices).
- 📰 Simplified sending messages with ad thumbnail using
externalAdReply, without requiring manualcontextInfo. - 💭 Added support for quoting messages inside channel (newsletter). [NEW]
- 🎀 Added support for custom button icon. [NEW]
🧩 Additional Message Options
- 👁️ Added optional boolean flags for message handling:
- 🤖
ai- AI icon on message - 📣
mentionAll- Mention all group participants without requiring their JIDs inmentionsormentionedJid[NEW] - 🔧
ephemeral,groupStatus,isLottie,spoiler,viewOnce,viewOnceV2,viewOnceV2Extension,interactiveAsTemplate- Message wrappers - 🔒
secureMetaServiceLabel- Secure meta service label on message [NEW] - 📄
raw- Build your message manually (DO NOT USE FOR EXPLOITATION)
- 🤖
📋 Table of Contents
- ✨ Highlights
- 🛠️ Internal Adjustments
- 📨 Messages Handling & Compatibility
- 🧩 Additional Message Options
- 📥 Installation
- 🌐 Connect to WhatsApp (Quick Step)
- 🗄️ Implementing Data Store
- 🪪 WhatsApp IDs Explain
- ✉️ Sending Messages
- 📁 Sending Media Messages
- 👉🏻 Sending Interactive Messages
- 💳 Sending Payment Messages
- 👁️ Other Message Options
- ♻️ Modify Messages
- 🧰 Additional Contents
- 🚀 Try the Bot
- 📦 Fork Base
- 📣 Credits
📥 Installation
- 📄 Via
package.json
# NPM
"dependencies": {
"@sairidev/baileys": "latest"
}
# GitHub
"dependencies": {
"@sairidev/baileys": "github:sairidev/baileys"
}- ⌨️ Via terminal
# NPM
npm i @sairidev/baileys@latest
# GitHub
npm i github:sairidev/baileys🧩 Import (ESM & CJS)
// --- ESM
import { makeWASocket } from '@sairidev/baileys'
// --- CJS (tested and working on Node.js 24 ✅)
const { makeWASocket } = require('@sairidev/baileys')🌐 Connect to WhatsApp (Quick Step)
import { makeWASocket, delay, DisconnectReason, useMultiFileAuthState } from '@sairidev/baileys'
import { Boom } from '@hapi/boom'
import pino from 'pino'
// --- Connect with pairing code
const myPhoneNumber = '6288888888888'
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', (update) => {
const { connection, lastDisconnect } = update
if (connection === 'connecting' && !sock.authState.creds.registered) {
await delay(1500)
const code = await sock.requestPairingCode(myPhoneNumber)
console.log('🔗 Pairing code', ':', code)
}
else if (connection === 'close') {
const shouldReconnect = new Boom(connection?.lastDisconnect?.error)?.output?.statusCode !== DisconnectReason.loggedOut
console.log('⚠️ Connection closed because', 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 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
useSingleFileAuthStateanduseSqliteAuthStateas an alternative touseMultiFileAuthState. However,useSingleFileAuthStatealready includes an internal caching mechanism, so there is no need to wrapstate.keyswithmakeCacheableSignalKeyStore.
🗄️ Implementing Data Store
[!CAUTION] I highly recommend building your own data store, as keeping an entire chat history in memory can lead to excessive RAM usage.
import { makeWASocket, makeInMemoryStore, delay, DisconnectReason, useMultiFileAuthState } from '@sairidev/baileys'
import { Boom } from '@hapi/boom'
import pino from 'pino'
const myPhoneNumber = '6288888888888'
// --- Create your store path
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('connection.update', (update) => {
const { connection, lastDisconnect } = update
if (connection === 'connecting' && !sock.authState.creds.registered) {
await delay(1500)
const code = await sock.requestPairingCode(myPhoneNumber)
console.log('🔗 Pairing code', ':', code)
}
else if (connection === 'close') {
const shouldReconnect = new Boom(connection?.lastDisconnect?.error)?.output?.statusCode !== DisconnectReason.loggedOut
console.log('⚠️ Connection closed because', lastDisconnect.error, ', reconnecting ', shouldReconnect)
if (shouldReconnect) {
connectToWhatsApp()
}
}
else if (connection === 'open') {
console.log('✅ Successfully connected to WhatsApp')
}
})
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
store.readFromFile(storePath)
// --- Save store every 3 minutes
setInterval(() => {
store.writeToFile(storePath)
}, 180000)
}
connectToWhatsApp()🪪 WhatsApp IDs Explain
id is the WhatsApp ID, called jid and lid too, of the person or group you're sending the message to.
- It must be in the format
[country code][phone number]@s.whatsapp.net- Example for people:
[email protected]and12699999999@lid. - For groups, it must be in the format
[email protected].
- Example for people:
- For Meta AI, it's
11111111111@bot. - For broadcast lists, it's
[timestamp of creation]@broadcast. - For stories, the ID is
status@broadcast.
✉️ Sending Messages
[!NOTE] You can get the
jidfrommessage.key.remoteJidin the first example.
🔠 Text
// --- Send a regular text message
sock.sendMessage(jid, {
text: '👋🏻 Hello'
}, {
quoted: message
})
// --- Send a text message with a link preview
const urlA = 'https://www.npmjs.com/package/@sairidev/baileys'
sock.sendMessage(jid, {
text: urlA + ' 👆🏻 Check it out!',
linkPreview: {
'matched-text': urlA,
title: '🌱 @sairidev/baileys',
description: 'Underrated Baileys Fork',
previewType: 0, // --- Use 1 for video playback in the link preview
jpegThumbnail: fs.readFileSync('./path/to/image.jpg')
}
})
// --- Send a text message with a large link preview and favicon
import { prepareWAMessageMedia } from '@sairidev/baileys'
const urlB = 'https://www.npmjs.com/package/@sairidev/baileys#readme'
const { imageMessage: image } = await prepareWAMessageMedia({
image: {
url: './path/to/image.jpg'
}
}, {
upload: sock.waUploadToServer,
mediaTypeOverride: 'thumbnail-link'
})
// --- Set the thumbnail display size
image.height = 720
image.width = 480
sock.sendMessage(jid, {
text: urlB + ' 👆🏻 Check it out!',
linkPreview: {
'matched-text': urlB,
title: '🌱 @sairidev/baileys',
description: 'Underrated Baileys Fork',
previewType: 0,
jpegThumbnail: fs.readFileSync('./path/to/image.jpg'),
highQualityThumbnail: image,
linkPreviewMetadata: {
linkMediaDuration: 0, // --- Duration in seconds (for video/audio content)
socialMediaPostType: 1, // --- Enum: 0 = NONE, 1 = REEL, 2 = LIVE_VIDEO, 3 = LONG_VIDEO, 4 = SINGLE_IMAGE, 5 = CAROUSEL
} // --- Additional metadata for large link preview
},
favicon: {
url: './path/to/tiny-image.ico'
}
})🔔 Mention
// --- Regular mention
sock.sendMessage(jid, {
text: '👋🏻 Hello @628123456789',
mentions: ['[email protected]']
}, {
quoted: message
})
// --- Mention all
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, // --- Set the value in seconds: 86400 (1d), 604800 (7d), or 2592000 (30d)
type: 1 // --- Or 2 to remove
})🔖 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:Lia Wynn\n'
+ 'ORG:Waitress;\n'
+ 'TEL;type=CELL;type=VOICE;waid=628123456789:+62 8123 4567 89\n'
+ 'END:VCARD'
sock.sendMessage(jid, {
contacts: {
displayName: 'Lia Wynn',
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: '🎶 Meet & Mingle Party',
description: 'Meet & Mingle Party is a fun, casual gathering to connect, chat, and build new relationships within the community.',
call: 'audio', // --- Or "video", this field is optional
startDate: new Date(Date.now() + 3600000),
endDate: new Date(Date.now() + 28800000),
isCancelled: false, // --- Optional
isScheduleCall: false, // --- Optional
extraGuestsAllowed: false, // --- Optional
location: {
name: 'Jakarta',
degreesLatitude: -6.2,
degreesLongitude: 106.8
}
}
}, {
quoted: message
})👥 Group Invite
const inviteCode = groupUrl
.split('chat.whatsapp.com/')[1]
?.split('?')[0]
const groupJid = '[email protected]'
const groupName = '@sairidev/baileys'
sock.sendMessage(jid, {
groupInvite: {
inviteCode,
inviteExpiration: Date.now() + 86400000,
text: '👋🏻 Hello, we invite you to join our group.',
jid: groupJid,
subject: groupName,
}
}, {
quoted: message
})🛍️ Product
import { randomUUID } from 'crypto'
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
body: '👋🏻 Check my product here!',
footer: '@sairidev/baileys',
product: {
currencyCode: 'IDR',
description: '🛍️ Interesting product!',
priceAmount1000: 70_000_000,
productId: randomUUID(),
productImageCount: 1,
salePriceAmount1000: 65_000_000,
signedUrl: 'https://www.npmjs.com/package/@sairidev/baileys',
title: '📦 Starseed (Premium)',
url: 'https://www.npmjs.com/package/@sairidev/baileys'
},
businessOwnerJid: '[email protected]'
})📊 Poll
// --- Regular poll message
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 (only for newsletter)
sock.sendMessage('1211111111111@newsletter', {
poll: {
name: '🔥 Quiz',
values: ['Yes', 'No'],
correctAnswer: 'Yes',
pollType: 1
}
}, {
quoted: message
})
// --- Poll result
sock.sendMessage(jid, {
pollResult: {
name: '📝 Poll Result',
votes: [{
name: 'Nice',
voteCount: 10
}, {
name: 'Nah',
voteCount: 2
}],
pollType: 0 // Or 1 for quiz
}
}, {
quoted: message
})
// --- 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
})✨ Rich Response
[!NOTE]
richResponse[]is a representation ofsubmessages[]insiderichResponseMessage.
[!TIP] You can still use the original
submessages[]field directly. The code example below is just an implementation using a helper, not a required structure.
sock.sendMessage(jid, {
disclaimerText: 'RAW submessages structure example',
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 easily add syntax highlighting by importing
tokenizeCodedirectly from Baileys.
import { tokenizeCode } from '@sairidev/baileys'
const language = 'javascript'
const code = 'console.log("Hello, World!")'
sock.sendMessage(jid, {
disclaimerText: 'Example of tokenizing Code Block',
richResponse: [{
text: 'Example Usage',
}, {
language,
code: tokenizeCode(code, language)
}, {
text: 'Pretty simple, right?'
}]
})💡 Supported Languages:
css,html,javascript,typescript,python,golang,rust,c,c#,c++,bash,bat,powershell.
🧾 Message with Code Block
[!NOTE] This feature already includes a built-in tokenizer with
tokenizeCode.
sock.sendMessage(jid, {
disclaimerText: 'Code Block',
headerText: '## Example Usage',
contentText: '---',
code: 'console.log("Hello, World!")',
language: 'javascript',
footerText: 'Pretty simple, right?'
})🌏 Message with Inline Entities
sock.sendMessage(jid, {
disclaimerText: 'Inline Entities',
headerText: '## Check Out!',
contentText: '---',
links: [{
text: '1. Google',
title: 'Popular Search Engine',
url: 'https://www.google.com/'
}, {
text: '2. YouTube',
title: 'Popular Streaming Platform',
url: 'https://www.youtube.com/'
}, {
text: '3. Modded Baileys',
title: 'Underrated Baileys Fork',
url: 'https://www.npmjs.com/package/@sairidev/baileys'
}],
footerText: '---'
})📋 Message with Table
sock.sendMessage(jid, {
disclaimerText: 'Table',
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, // --- Optional
footerText: 'Does this help clarify the differences?'
})🎞️ Status Mention
sock.sendMessage([jidA, jidB, jidC], {
text: 'Hello! 👋🏻'
})📁 Sending Media Messages
[!NOTE] For media messages, you can pass a
Bufferdirectly, or an object with either{ stream: Readable }or{ url: string }(local file 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, // --- Set true if you want to send video as GIF
ptv: false, // --- Set true if you want to send video as 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 // --- Set true if you want to send audio as 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
sharpor@napi-rs/imageis not installed, thecoverandstickersmust already be in WebP format.
sock.sendMessage(jid, {
cover: {
url: './path/to/image.webp'
},
stickers: [{
data: {
url: './path/to/image.webp'
}
}, {
data: {
url: './path/to/image.webp'
}
}, {
data: {
url: './path/to/image.webp'
}
}],
name: '📦 My Sticker Pack',
publisher: '🌟 Lia Wynn',
description: '@sairidev/baileys'
}, {
quoted: message
})👉🏻 Sending Interactive Messages
🔘 Buttons
// --- Regular buttons message
sock.sendMessage(jid, {
text: '👆🏻 Buttons!',
footer: '@sairidev/baileys',
buttons: [{
text: '👋🏻 SignUp',
id: '#SignUp'
}]
}, {
quoted: message
})
// --- Buttons with Media & Native Flow
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: '👆🏻 Buttons and Native Flow!',
footer: '@sairidev/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
})📋 List
[!NOTE] It only works in private chat (
@s.whatsapp.net).
sock.sendMessage(jid, {
text: '📋 List!',
footer: '@sairidev/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
})🗄️ Interactive
// --- Native Flow
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: '🗄️️ Interactive!',
footer: '@sairidev/baileys',
optionText: '👉🏻 Select Options', // --- Optional, wrap all native flow into a single list
optionTitle: '📄 Select Options', // --- Optional
offerText: '🏷️ Newest Coupon!', // --- Optional, add an offer into message
offerCode: '@sairidev/baileys', // --- Optional
offerUrl: 'https://www.npmjs.com/package/@sairidev/baileys', // --- Optional
offerExpiration: Date.now() + 3_600_000, // --- Optional
nativeFlow: [{
text: '👋🏻 Greeting',
id: '#Greeting',
icon: 'review' // --- Optional
}, {
text: '📞 Call',
call: '628123456789'
}, {
text: '📋 Copy',
copy: '@sairidev/baileys'
}, {
text: '🌐 Source',
url: 'https://www.npmjs.com/package/@sairidev/baileys',
useWebview: true // --- Optional
}, {
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' // --- Optional
}],
interactiveAsTemplate: false, // --- Optional, wrap the interactive message into a template
}, {
quoted: message
})
// --- Carousel & Native Flow
sock.sendMessage(jid, {
text: '🗂️ Interactive with Carousel!',
footer: '@sairidev/baileys',
cards: [{
image: {
url: './path/to/image.jpg'
},
caption: '🖼️ Image 1',
footer: '🏷️️ Pinterest',
nativeFlow: [{
text: '🌐 Source',
url: 'https://www.npmjs.com/package/@sairidev/baileys',
useWebview: true
}]
}, {
image: {
url: './path/to/image.jpg'
},
caption: '🖼️ Image 2',
footer: '🏷️ Pinterest',
offerText: '🏷️ New Coupon!',
offerCode: '@sairidev/baileys',
offerUrl: 'https://www.npmjs.com/package/@sairidev/baileys',
offerExpiration: Date.now() + 3_600_000,
nativeFlow: [{
text: '🌐 Source',
url: 'https://www.npmjs.com/package/@sairidev/baileys'
}]
}, {
image: {
url: './path/to/image.jpg'
},
caption: '🖼️ Image 3',
footer: '🏷️ Pinterest',
optionText: '👉🏻 Select Options',
optionTitle: '👉🏻 Select Options',
offerText: '🏷️ New Coupon!',
offerCode: '@sairidev/baileys',
offerUrl: 'https://www.npmjs.com/package/@sairidev/baileys',
offerExpiration: Date.now() + 3_600_000,
nativeFlow: [{
text: '🛒 Product',
id: '#Product',
icon: 'default'
}, {
text: '🌐 Source',
url: 'https://www.npmjs.com/package/@sairidev/baileys'
}]
}]
}, {
quoted: message
})
// --- Native Flow with Audio in the Footer
sock.sendMessage(jid, {
text: '🔈 Music in the footer!',
audioFooter: {
url: './path/to/audio.mp3'
}, // --- Like other media upload methods, buffers and streams are supported
nativeFlow: [{
text: '👍🏻 Good, next',
id: '#Next',
icon: 'review'
}, {
text: '👎🏻 Skip',
id: '#Skip',
icon: 'default'
}]
}, {
quoted: message
})🫙 Hydrated Template
sock.sendMessage(jid, {
title: '👋🏻 Hello',
image: {
url: './path/to/image.jpg'
},
caption: '🫙 Template!',
footer: '@sairidev/baileys',
templateButtons: [{
text: '👉🏻 Tap Here',
id: '#Order'
}, {
text: '🌐 Source',
url: 'https://www.npmjs.com/package/@sairidev/baileys'
}, {
text: '📞 Call',
call: '628123456789'
}]
}, {
quoted: message
})💳 Sending Payment Messages
➕ Invite Payment
sock.sendMessage(jid, {
paymentInviteServiceType: 3 // 1, 2, or 3
})🧾 Invoice
[!NOTE] Invoice message are not supported yet.
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
invoiceNote: '🏷️ Invoice'
})🛍️ Order
sock.sendMessage(chat, {
orderText: '🛍️ Order',
thumbnail: fs.readFileSync('./path/to/image.jpg') // --- Must in buffer format
}, {
quoted: message
})💳 Request Payment
sock.sendMessage(jid, {
text: '💳 Request Payment',
requestPaymentFrom: '[email protected]'
})👁️ Other Message Options
🤖 AI Icon
[!NOTE] It only works in private chat (
@s.whatsapp.net).
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: '🤖 With AI icon!',
ai: true
}, {
quoted: message
})🕒 Ephemeral
[!NOTE] Wrap message into
ephemeralMessage
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: '👁️ Ephemeral',
ephemeral: true
})📰 External Ad Reply
[!NOTE] Add an ad thumbnail to messages (may not be displayed on some WhatsApp versions).
sock.sendMessage(jid, {
text: '📰 External Ad Reply',
externalAdReply: {
title: '📝 Did you know?',
body: '❓ I dont know',
thumbnail: fs.readFileSync('./path/to/image.jpg'), // --- Must in buffer format
largeThumbnail: false, // --- Or true for bigger thumbnail
url: 'https://www.npmjs.com/package/@sairidev/baileys' // --- Optional, used for WhatsApp internal thumbnail caching and direct URL
}
}, {
quoted: message
})🧑🧑🧒 Group Status
[!NOTE] It only works in group chat (
@g.us)
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: '👥 Group Status!',
groupStatus: true
})🐱 Lottie Sticker
[!NOTE] Wrap message into
lottieStickerMessage
sock.sendMessage(jid, {
sticker: {
url: './path/to/sticker.webp'
},
isLottie: true
})🧩 Raw
sock.sendMessage(jid, {
extendedTextMessage: {
text: '📃 Built manually from scratch using the raw WhatsApp proto structure',
contextInfo: {
externalAdReply: {
title: '@sairidev/baileys',
thumbnail: fs.readFileSync('./path/to/image.jpg'),
sourceApp: 'whatsapp',
showAdAttribution: true,
mediaType: 1
}
}
},
raw: true
}, {
quoted: message
})🏷️ Secure Meta Service Label
sock.sendMessage(jid, {
text: '🏷️ Just a label!',
secureMetaServiceLabel: true
})📑 Spoiler
[!NOTE] Wrap message into
spoilerMessage
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: '❔ Spoiler',
spoiler: true
})👁️ View Once
[!NOTE] Wrap message into
viewOnceMessage
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: '👁️ View Once',
viewOnce: true
})👁️ View Once V2
[!NOTE] Wrap message into
viewOnceMessageV2
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: '👁️ View Once V2',
viewOnceV2: true
})👁️ View Once V2 Extension
[!NOTE] Wrap 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 messages caption
sock.sendMessage(jid, {
caption: '✨ I mean, here is the image!',
edit: message.key
})🧰 Additional Contents
🏷️ Find User ID (JID|PN/LID)
[!NOTE] The ID must contain numbers only (no +, (), or -) and must include the country code with WhatsApp ID format.
// --- PN (Phone Number)
const phoneNumber = '[email protected]'
const ids = await sock.findUserId(phoneNumber)
console.log('🏷️ Got user ID', ':', ids)
// --- LID (Local Identifier)
const lid = '43411111111111@lid'
const ids = await sock.findUserId(lid)
console.log('🏷️ Got user ID', ':', ids)
// --- Output
// {
// phoneNumber: '[email protected]',
// lid: '43411111111111@lid'
// }
// --- Output when failed
// {
// phoneNumber: '[email protected]',
// lid: undefined
// }
// --- Same output shape regardless of input type🔑 Request Custom Pairing Code
[!NOTE] The phone number must contain numbers only (no +, (), or -) and must include the country code.
const phoneNumber = '6281111111111'
const customPairingCode = 'STARFALL'
await sock.requestPairingCode(phoneNumber, customPairingCode)
console.log('🔗 Pairing code', ':', customPairingCode)🖼️ Image Processing
[!NOTE] Automatically use available image processing library:
sharp,@napi-rs/image, orjimp
import { getImageProcessingLibrary } from '@sairidev/baileys'
import { readFile } from 'fs/promises'
const lib = await getImageProcessingLibrary()
const bufferOrFilePath = './path/to/image.jpg'
const width = 512
let output
// --- If sharp installed
if (lib.sharp?.default) {
const img = lib.sharp.default(bufferOrFilePath)
output = await img.resize(width)
.jpeg({ quality: 80 })
.toBuffer()
}
// --- If @napi-rs/image installed
else if (lib.image?.Transformer) {
// --- Must in buffer format
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 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 available')
}
console.log('✅ Process completed!')
console.dir(output, { depth: null })📣 Newsletter Management
// --- Create a new one
sock.newsletterCreate('@sairidev/baileys', '📣 Fresh updates weekly')
// --- Get info
const metadata = 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]')
// --- Update newsletter
sock.newsletterUpdate('1231111111111@newsletter', { name: '@sairidev/baileys' })
// --- Change name
sock.newsletterUpdateName('1231111111111@newsletter', '📦 @sairidev/baileys')
// --- Change description
sock.newsletterUpdateDescription('1231111111111@newsletter', '📣 Fresh updates weekly')
// --- Change photo
sock.newsletterUpdatePicture('1231111111111@newsletter', {
url: 'path/to/image.jpg'
})
// --- Remove photo
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 newsletter 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 a new one and add participants using their JIDs
const group = sock.groupCreate('@sairidev/baileys', ['[email protected]'])
console.dir(group, { depth: null })
// --- Get info
const metadata = await sock.groupMetadata(jid)
console.dir(metadata, { depth: null })
// --- Get group invite code
const inviteCode = await sock.groupInviteCode(jid)
console.dir(inviteCode, { depth: null })
// --- Revoke invite link
sock.groupRevokeInvite(jid)
// --- Accept group invite
sock.groupAcceptInvite(inviteCode)
// --- Leave group
sock.groupLeave(jid)
// --- Add participants
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'add')
// --- Remove participants
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'remove')
// --- Promote to admin
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'promote')
// --- Demote from admin
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'demote')
// --- Accept join requests
sock.groupRequestParticipantsUpdate(jid, ['[email protected]'], 'approve')
// --- Change name
sock.groupUpdateSubject(jid, '📦 @sairidev/baileys')
// --- Change description
sock.groupUpdateDescription(jid, 'Updated description')
// --- Change photo
sock.updateProfilePicture(jid, {
url: 'path/to/image.jpg'
})
// --- Remove photo
sock.removeProfilePicture(jid)
// --- Set group as admin only for chatting
sock.groupSettingUpdate(jid, 'announcement')
// --- Set group as open to all for chatting
sock.groupSettingUpdate(jid, 'not_announcement')
// --- Set admin only can edit group info
sock.groupSettingUpdate(jid, 'locked')
// --- Set all participants can edit group info
sock.groupSettingUpdate(jid, 'unlocked')
// --- Set admin only can add participants
sock.groupMemberAddMode(jid, 'admin_add')
// --- Set all participants can add participants
sock.groupMemberAddMode(jid, 'all_member_add')
// --- Enable or disable temporary messages with seconds format
sock.groupToggleEphemeral(jid, 86400)
// --- Disable temporary messages
sock.groupToggleEphemeral(jid, 0)
// --- Enable or disable membership approval mode
sock.groupJoinApprovalMode(jid, 'on')
sock.groupJoinApprovalMode(jid, 'off')
// --- Get all groups metadata
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 })
// --- Get group info from link
const group = await sock.groupGetInviteInfo('ABC123456789')
console.log('👥 Got group info from invite code', ':', group)
// --- Update bot member label
sock.updateMemberLabel(jid, '@sairidev/baileys')👥 Community Management
// --- Create a new one and add description
const community = await sock.communityCreate('@sairidev/baileys', '📣 Fresh updates weekly')
console.dir(community, { depth: null })
// --- Create a subgroup for community and add participants using their JIDs
const group = await sock.communityCreateGroup('📢 Announcements', ['[email protected]'], communityJid)
// --- Link an existing group
sock.communityLinkGroup(groupJid, communityJid)
// --- Unlink an existing group
sock.communityUnlinkGroup(groupJid, communityJid)
// --- Get info
const metadata = await sock.communityMetadata(jid)
console.dir(metadata, { depth: null })
// --- Get community invite code
const inviteCode = await sock.communityInviteCode(jid)
console.dir(inviteCode, { depth: null })
// --- Revoke invite link
sock.communityRevokeInvite(jid)
// --- Accept community invite
sock.communityAcceptInvite(inviteCode)
// --- Leave community
sock.communityLeave(jid)
// --- Accept join requests
sock.communityRequestParticipantsUpdate(jid, ['[email protected]'], 'approve')
// --- Change name
sock.communityUpdateSubject(jid, '📦 @sairidev/baileys')
// --- Change description
sock.communityUpdateDescription(jid, 'Updated description')
// --- Set community as admin only for chatting
sock.communitySettingUpdate(jid, 'announcement')
// --- Set community as open to all for chatting
sock.communitySettingUpdate(jid, 'not_announcement')
// --- Set admin only can edit community info
sock.communitySettingUpdate(jid, 'locked')
// --- Set all participants can edit community info
sock.communitySettingUpdate(jid, 'unlocked')
// --- Set admin only can add participants
sock.communityMemberAddMode(jid, 'admin_add')
// --- Set all participants can add participants
sock.communityMemberAddMode(jid, 'all_member_add')
// --- Enable or disable temporary messages with seconds format
sock.communityToggleEphemeral(jid, 86400)
// --- Disable temporary messages
sock.communityToggleEphemeral(jid, 0)
// --- Enable or disable membership approval mode
sock.communityJoinApprovalMode(jid, 'on')
sock.communityJoinApprovalMode(jid, 'off')
// --- Get all communities metadata
const communities = await sock.communityFetchAllParticipating()
console.dir(communities, { depth: null })
// --- Get all community linked groups
const linked = await sock.communityFetchLinkedGroups(jid)
console.dir(linked, { depth: null })
// --- Get pending join requests
const requests = await sock.communityRequestParticipantsList(jid)
console.dir(requests, { depth: null })
// --- Get community info from link
const community = await sock.communityGetInviteInfo('ABC123456789')
console.log('👥 Got community info from invite code', ':', community)👤 Profile Management
// --- Get user profile picture
const url = await sock.profilePictureUrl(jid, 'image')
console.log('🖼️ Got user profile url', url)
// --- Update profile picture
sock.updateProfilePicture(jid, buffer)
sock.updateProfilePicture(jid, { url })
// --- Remove profile picture
sock.removeProfilePicture(jid)
// --- Update profile name
sock.updateProfileName('My Name')
// --- Update profile status
sock.updateProfileStatus('Available')
// --- Presence
sock.sendPresenceUpdate('available', jid)
sock.presenceSubscribe(jid)
// --- Read receipts
sock.readMessages([message.key])
sock.sendReceipt(jid, participant, [messageId], 'read')
// --- Block user
sock.updateBlockStatus(jid, 'block')
// --- Unblock user
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)
// --- Contact
sock.addOrEditContact(jid, { displayName: 'Starseed' })
sock.removeContact(jid)
// --- Label
sock.addChatLabel(jid, labelId)
sock.removeChatLabel(jid, labelId)
sock.addMessageLabel(jid, messageId, labelId)
// --- App state sync
sock.resyncAppState(['regular', 'critical_block'], true)
// --- Get business profile
const profile = await sock.getBusinessProfile(jid)
console.dir(profile, { depth: null })🛒 Business Management
// --- Create a new product
const product = await sock.productCreate({
name: '🧩 Starseed (Premium)',
description: 'Get a full version of Starseed!',
price: 100000,
currency: 'IDR',
originCountryCode: 'ID',
images: [
bufferImage,
{
url: './path/to/image.jpg'
}
]
})
console.dir(product, { depth: null })
// --- Update product
await sock.productUpdate(productId, {
name: '🧩 Starseed (Premium)',
description: 'Get a full version of Starseed with more features!',
price: 75000,
currency: 'IDR',
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: 'Jakarta, Indonesia',
description: '🛒 Official Starseed Store',
websites: ['https://www.npmjs.com/package/@sairidev/baileys'],
email: '[email protected]',
hours: {
timezone: 'Asia/Jakarta',
days: [{ day: 'mon', mode: 'open_24h' }]
}
})
// --- Update cover
sock.updateCoverPhoto({
url: './path/to/image.jpg'
})
// --- Remove cover
sock.removeCoverPhoto(coverId)
// --- Update quick replies
sock.addOrEditQuickReply({
shortcut: 'hello',
message: 'Hello from business account',
})
// --- Remove quick reply
sock.removeQuickReply(timestamp)🔐 Privacy Management
// --- Update last seen privacy
sock.updateLastSeenPrivacy('all')
sock.updateLastSeenPrivacy('contacts')
sock.updateLastSeenPrivacy('contact_blacklist')
sock.updateLastSeenPrivacy('nobody')
// --- Update online privacy
sock.updateOnlinePrivacy('all')
sock.updateOnlinePrivacy('match_last_seen')
// --- Update profile picture privacy
sock.updateProfilePicturePrivacy('contacts')
// --- Update status privacy
sock.updateStatusPrivacy('contacts')
// --- Update read receipts privacy
sock.updateReadReceiptsPrivacy('all')
sock.updateReadReceiptsPrivacy('none')
// --- Update groups add privacy
sock.updateGroupsAddPrivacy('all')
sock.updateGroupsAddPrivacy('contacts')
// --- Update messages privacy
sock.updateMessagesPrivacy('all')
sock.updateMessagesPrivacy('contacts')
sock.updateMessagesPrivacy('nobody')
// --- Update call privacy
sock.updateCallPrivacy('everyone')
// --- Update default disappearing mode
sock.updateDefaultDisappearingMode(86400)
// --- Update link previews privacy
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) => {})🚀 Try the Bot
A fast, lightweight, and modular WhatsApp bot built with @sairidev/baileys. Perfect for managing groups, moderating chats, and adding fun with quiz games and handy tools.
📦 Fork Base
This fork is based on Baileys (GitHub)
📣 Credits
This fork uses Protocol Buffer definitions maintained by WPP Connect via wa-proto
Full credit is attributed to the original maintainers and contributors of Baileys:
This fork includes additional enhancements and modifications by sairidev
Special thanks to itsreimau for the fix to the updateBlockStatus implementation.
[!CAUTION] ⚠️ Modification, removal, or misrepresentation of these credits is strictly prohibited. Any redistribution or fork must preserve this section in its original form without exception.

