Enhanced Baileys v7 with fixed newsletter media upload, plus support for interactive messages, albums, and more message types.
β For donation: Saweria
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
- Added unnecessary overhead
- Rewrote all changelogs and note changes with their own names
- Claimed the modifications as their own work
This is not acceptable.
To be clear, I am not the original author of Baileys (full respect to https://github.com/WhiskeySockets/Baileys). This is about proper attribution and honesty in contributions.
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.
- πΌοΈ 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.
- π© 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]
- ποΈ 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,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)
- π€
- β¨ Highlights
- π οΈ Internal Adjustments
- π¨ Messages Handling & Compatibility
- π§© Additional Message Options
- π₯ Installation
- π Connect to WhatsApp (Quick Step)
- ποΈ Implementing Data Store
- πͺͺ WhatsApp IDs Explain
- βοΈ Sending Messages
- π Text
- π Mention
- π Reaction
- π Pin Message
- β‘οΈ Forward Message
- π€ Contact
- π Location
- ποΈ Event
- π₯ Group Invite
- ποΈ Product
- π Poll
- π Button Response
- β¨ Rich Response
- π§Ύ Message with Code Block
- π Message with Inline Entities
- π Message with Table
- ποΈ Status Mention
- π Sending Media Messages
- ππ» Sending Interactive Messages
- π³ Sending Payment Messages
- ποΈ Other Message Options
- β»οΈ Modify Messages
- π§° Additional Contents
- π Try the Bot
- π¦ Fork Base
- π£ Credits
- π Via
package.json
# NPM
"dependencies": {
"@itsliaaa/baileys": "latest"
}
# GitHub
"dependencies": {
"@itsliaaa/baileys": "github:itsliaaa/baileys"
}- β¨οΈ Via terminal
# NPM
npm i @itsliaaa/baileys@latest
# GitHub
npm i github:itsliaaa/baileys// --- ESM
import { makeWASocket } from '@itsliaaa/baileys'
// --- CJS (tested and working on Node.js 24 β
)
const { makeWASocket } = require('@itsliaaa/baileys')import { makeWASocket, delay, DisconnectReason, useMultiFileAuthState } from '@itsliaaa/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()Note
You can use the experimental useSingleFileAuthState as an alternative to useMultiFileAuthState. However, useSingleFileAuthState already includes an internal caching mechanism, so there is no need to wrap state.keys with makeCacheableSignalKeyStore.
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 '@itsliaaa/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()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:
19999999999@s.whatsapp.netand12699999999@lid. - For groups, it must be in the format
123456789-123345@g.us.
- 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.
Note
You can get the jid from message.key.remoteJid in the first example.
// --- 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/@itsliaaa/baileys'
sock.sendMessage(jid, {
text: urlA + ' ππ» Check it out!',
linkPreview: {
'matched-text': urlA,
title: 'π± @itsliaaa/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 '@itsliaaa/baileys'
const urlB = 'https://www.npmjs.com/package/@itsliaaa/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: 'π± @itsliaaa/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.jpg'
}
})// --- Regular mention
sock.sendMessage(jid, {
text: 'ππ» Hello @628123456789',
mentions: ['628123456789@s.whatsapp.net']
}, {
quoted: message
})
// --- Mention all
sock.sendMessage(jid, {
text: 'ππ» Hello @all',
mentionAll: true
}, {
quoted: message
})sock.sendMessage(jid, {
react: {
key: message.key,
text: 'β¨'
}
}, {
quoted: message
})sock.sendMessage(jid, {
pin: message.key,
time: 86400, // --- Set the value in seconds: 86400 (1d), 604800 (7d), or 2592000 (30d)
type: 1 // --- Or 0 to remove
}, {
quoted: message
})sock.sendMessage(jid, {
forward: message,
force: true // --- Optional
})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
})sock.sendMessage(jid, {
location: {
degreesLatitude: 24.121231,
degreesLongitude: 55.1121221,
name: 'ππ» I am here'
}
}, {
quoted: message
})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
})const inviteCode = groupUrl
.split('chat.whatsapp.com/')[1]
?.split('?')[0]
const groupJid = '1201111111111@g.us'
const groupName = '@itsliaaa/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
})import { randomUUID } from 'crypto'
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
body: 'ππ» Check my product here!',
footer: '@itsliaaa/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/@itsliaaa/baileys',
title: 'π¦ Starseed (Premium)',
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
},
businessOwnerJid: '0@s.whatsapp.net'
})// --- Regular poll message
sock.sendMessage(jid, {
poll: {
name: 'π₯ Voting time',
values: ['Yes', 'No'],
selectableCount: 1,
toAnnouncementGroup: false
}
}, {
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
})// --- 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
})Note
richResponse[] is a representation of submessages[] inside richResponseMessage.
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, {
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 tokenizeCode directly from Baileys.
import { tokenizeCode } from '@itsliaaa/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?'
}]
})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?'
})sock.sendMessage(jid, {
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/@itsliaaa/baileys'
}],
footerText: '---'
})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, // --- Optional
footerText: 'Does this help clarify the differences?'
})sock.sendMessage([jidA, jidB, jidC], {
text: 'Hello! ππ»'
})Note
For media messages, you can pass a Buffer directly, or an object with either { stream: Readable } or { url: string } (local file path or HTTP/HTTPS URL).
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: 'π₯ Superb'
}, {
quoted: message
})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
})sock.sendMessage(jid, {
sticker: {
url: './path/to/sticker.webp'
}
}, {
quoted: message
})sock.sendMessage(jid, {
audio: {
url: './path/to/audio.mp3'
},
ptt: false, // --- Set true if you want to send audio as Voice Note
}, {
quoted: message
})sock.sendMessage(jid, {
document: {
url: './path/to/document.pdf'
},
mimetype: 'application/pdf',
caption: 'β¨ My work!'
}, {
quoted: message
})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
})Important
If sharp or @napi-rs/image is not installed, the cover and stickers must 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: '@itsliaaa/baileys'
}, {
quoted: message
})// --- Regular buttons message
sock.sendMessage(jid, {
text: 'ππ» Buttons!',
footer: '@itsliaaa/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: '@itsliaaa/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
})Note
It only works in private chat (@s.whatsapp.net).
sock.sendMessage(jid, {
text: 'π List!',
footer: '@itsliaaa/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
})// --- Native Flow
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: 'ποΈοΈ Interactive!',
footer: '@itsliaaa/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: '@itsliaaa/baileys', // --- Optional
offerUrl: 'https://www.npmjs.com/package/@itsliaaa/baileys', // --- Optional
offerExpiration: Date.now() + 3_600_000, // --- Optional
nativeFlow: [{
text: 'ππ» Greeting',
id: '#Greeting',
icon: 'review' // --- Optional
}, {
text: 'π Call',
call: '628123456789'
}, {
text: 'π Copy',
copy: '@itsliaaa/baileys'
}, {
text: 'π Source',
url: 'https://www.npmjs.com/package/@itsliaaa/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: '@itsliaaa/baileys',
cards: [{
image: {
url: './path/to/image.jpg'
},
caption: 'πΌοΈ Image 1',
footer: 'π·οΈοΈ Pinterest',
nativeFlow: [{
text: 'π Source',
url: 'https://www.npmjs.com/package/@itsliaaa/baileys',
useWebview: true
}]
}, {
image: {
url: './path/to/image.jpg'
},
caption: 'πΌοΈ Image 2',
footer: 'π·οΈ Pinterest',
offerText: 'π·οΈ New Coupon!',
offerCode: '@itsliaaa/baileys',
offerUrl: 'https://www.npmjs.com/package/@itsliaaa/baileys',
offerExpiration: Date.now() + 3_600_000,
nativeFlow: [{
text: 'π Source',
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
}]
}, {
image: {
url: './path/to/image.jpg'
},
caption: 'πΌοΈ Image 3',
footer: 'π·οΈ Pinterest',
optionText: 'ππ» Select Options',
optionTitle: 'ππ» Select Options',
offerText: 'π·οΈ New Coupon!',
offerCode: '@itsliaaa/baileys',
offerUrl: 'https://www.npmjs.com/package/@itsliaaa/baileys',
offerExpiration: Date.now() + 3_600_000,
nativeFlow: [{
text: 'π Product',
id: '#Product',
icon: 'default'
}, {
text: 'π Source',
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
}]
}]
}, {
quoted: message
})sock.sendMessage(jid, {
title: 'ππ» Hello',
image: {
url: './path/to/image.jpg'
},
caption: 'π« Template!',
footer: '@itsliaaa/baileys',
templateButtons: [{
text: 'ππ» Tap Here',
id: '#Order'
}, {
text: 'π Source',
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
}, {
text: 'π Call',
call: '628123456789'
}]
}, {
quoted: message
})sock.sendMessage(jid, {
paymentInviteServiceType: 3 // 1, 2, or 3
})Note
Invoice message are not supported yet.
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
invoiceNote: 'π·οΈ Invoice'
})sock.sendMessage(chat, {
orderText: 'ποΈ Order',
thumbnail: fs.readFileSync('./path/to/image.jpg') // --- Must in buffer format
}, {
quoted: message
})sock.sendMessage(jid, {
text: 'π³ Request Payment',
requestPaymentFrom: '0@s.whatsapp.net'
})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
})Note
Wrap message into ephemeralMessage
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: 'ποΈ Ephemeral',
ephemeral: true
})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/@itsliaaa/baileys' // --- Optional, used for WhatsApp internal thumbnail caching and direct URL
}
}, {
quoted: message
})Note
It only works in group chat (@g.us)
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: 'π₯ Group Status!',
groupStatus: true
})sock.sendMessage(jid, {
extendedTextMessage: {
text: 'π Built manually from scratch using the raw WhatsApp proto structure',
contextInfo: {
externalAdReply: {
title: '@itsliaaa/baileys',
thumbnail: fs.readFileSync('./path/to/image.jpg'),
sourceApp: 'whatsapp',
showAdAttribution: true,
mediaType: 1
}
}
},
raw: true
}, {
quoted: message
})sock.sendMessage(jid, {
text: 'π·οΈ Just a label!',
secureMetaServiceLabel: true
})Note
Wrap message into viewOnceMessage
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: 'ποΈ View Once',
viewOnce: true
})Note
Wrap message into viewOnceMessageV2
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: 'ποΈ View Once V2',
viewOnceV2: true
})Note
Wrap message into viewOnceMessageV2Extension
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: 'ποΈ View Once V2 Extension',
viewOnceV2Extension: true
})Note
Wrap message into spoilerMessage
sock.sendMessage(jid, {
image: {
url: './path/to/image.jpg'
},
caption: 'β Spoiler',
spoiler: true
})sock.sendMessage(jid, {
delete: message.key
})// --- 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
})Note
The ID must contain numbers only (no +, (), or -) and must include the country code with WhatsApp ID format.
// --- PN (Phone Number)
const phoneNumber = '6281111111111@s.whatsapp.net'
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: '6281111111111@s.whatsapp.net',
// lid: '43411111111111@lid'
// }
// --- Output when failed
// {
// phoneNumber: '6281111111111@s.whatsapp.net',
// lid: undefined
// }
// --- Same output shape regardless of input typeNote
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)Note
Automatically use available image processing library: sharp, @napi-rs/image, or jimp
import { getImageProcessingLibrary } from '@itsliaaa/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 })// --- Create a new one
sock.newsletterCreate('@itsliaaa/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', '6281111111111@s.whatsapp.net')
// --- Change owner
sock.newsletterChangeOwner('1231111111111@newsletter', '6281111111111@s.whatsapp.net')
// --- Update newsletter
sock.newsletterUpdate('1231111111111@newsletter', { name: '@itsliaaa/baileys' })
// --- Change name
sock.newsletterUpdateName('1231111111111@newsletter', 'π¦ @itsliaaa/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')// --- Create a new one and add participants using their JIDs
const group = sock.groupCreate('@itsliaaa/baileys', ['628123456789@s.whatsapp.net'])
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, ['628123456789@s.whatsapp.net'], 'add')
// --- Remove participants
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'remove')
// --- Promote to admin
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'promote')
// --- Demote from admin
sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'demote')
// --- Accept join requests
sock.groupRequestParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'approve')
// --- Change name
sock.groupUpdateSubject(jid, 'π¦ @itsliaaa/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, '@itsliaaa/baileys')// --- Create a new one and add description
const community = await sock.communityCreate('@itsliaaa/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', ['628123456789@s.whatsapp.net'], 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, ['628123456789@s.whatsapp.net'], 'approve')
// --- Change name
sock.communityUpdateSubject(jid, 'π¦ @itsliaaa/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)// --- 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 })// --- 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: '628123456789@s.whatsapp.net',
limit: 10
})
// --- Get collections
const collections = await sock.getCollections('628123456789@s.whatsapp.net', 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/@itsliaaa/baileys'],
email: 'more-more@gmail.com',
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)// --- 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)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) => {})A fast, lightweight, and modular WhatsApp bot built with @itsliaaa/baileys. Perfect for managing groups, moderating chats, and adding fun with quiz games and handy tools.
ππ» @itsliaaa/starseed
This fork is based on Baileys (GitHub)
This project utilizes Protocol Buffer definitions maintained by WPPConnect through the wa-proto repository.
Full credit is attributed to the original maintainers and contributors of Baileys:
This fork includes additional enhancements and modifications by Lia Wynn
Special thanks to itsreimau for the fix to the updateBlockStatus implementation.
Caution
