Baileys Provider
The Baileys library originated as a project for CS-2362 at Ashoka University and is not affiliated with or endorsed by WhatsApp. Use it at your own discretion and avoid spamming individuals. We discourage the use of stalkerware, bulk messaging, or any automated messaging practices.
Baileys is a free WhatsApp provider that operates via WhatsApp Web. It interacts directly with WhatsApp Web using a WebSocket and does not require Selenium or any other browser. By avoiding Selenium or Chromium, Baileys conserves significant RAM resources.
Avoid using buttons and lists as they are not fully compatible. While they may display on some devices, they often fail to function as intended.
QR Code
Link device QR Code In the code below you can see the standard way to link a device by scanning the QR code with the whatsapp application.
app.ts
import { createBot, createProvider, createFlow, addKeyword } from '@builderbot/bot'
import { BaileysProvider as Provider } from '@builderbot/provider-baileys'
import { MemoryDB as Database } from '@builderbot/bot'
const PORT = process.env.PORT ?? 3008
const welcomeFlow = addKeyword<Provider, Database>(['hi', 'hello', 'hola'])
.addAnswer(`🙌 Hello welcome to this *Chatbot*`)
const main = async () => {
const adapterFlow = createFlow([welcomeFlow])
const adapterProvider = createProvider(Provider)
const adapterDB = new Database()
const { httpServer } = await createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
httpServer(+PORT)
}
main()
Pairing code
Link device pairing code, In the code below you can see the alternative way to link the whatsapp account through a pairing code.
app.ts
import { createBot, createProvider, createFlow, addKeyword } from '@builderbot/bot'
import { BaileysProvider as Provider } from '@builderbot/provider-baileys'
import { MemoryDB as Database } from '@builderbot/bot'
import { config } from 'dotenv'
config()
const PHONE_NUMBER = process.env.PHONE_NUMBER
const welcomeFlow = addKeyword<Provider, Database>(['hi', 'hello', 'hola'])
.addAnswer(`🙌 Hello welcome to this *Chatbot*`)
const main = async () => {
const adapterFlow = createFlow([welcomeFlow])
const adapterProvider = createProvider(Provider, { usePairingCode: true, phoneNumber: PHONE_NUMBER })
const adapterDB = new Database()
const botResult = await createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
}
main()
Send Presence Update
The method sendPresenceUpdate lets the person/group with id know whether you're online, offline, typing etc. This method has the following signature:
(property) sendPresenceUpdate: (type: WAPresence, toJid?: string) => Promise<void>
WAPresence can be one of the following:
type WAPresence = 'unavailable' | 'available' | 'composing' | 'recording' | 'paused'
app.ts
import { createBot, createProvider, createFlow, addKeyword, EVENTS } from '@builderbot/bot'
import { MemoryDB as Database } from '@builderbot/bot'
import { BaileysProvider as Provider } from '@builderbot/provider-baileys'
import { config } from 'dotenv'
config()
const PHONE_NUMBER = process.env.PHONE_NUMBER
const waitT = (ms: number) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(ms)
}, ms)
})
}
const welcomeFlow = addKeyword<Provider, Database>(EVENTS.WELCOME)
.addAnswer(`💡 Example *Sending Presence Update*`)
.addAction(
async (ctx, { provider, flowDynamic }) => {
await flowDynamic('This is an example of presence update')
await provider.vendor.sendPresenceUpdate('recording', ctx.key.remoteJid)
await waitT(5000)
await provider.vendor.sendPresenceUpdate('composing', ctx.key.remoteJid)
await waitT(5000)
await flowDynamic('Great!')
}
)
const main = async () => {
const adapterFlow = createFlow([welcomeFlow])
const adapterProvider = createProvider(Provider, { usePairingCode: true, phoneNumber: PHONE_NUMBER })
const adapterDB = new Database()
const botResult = await createBot(
{
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
}
)
}
main()
Video Send Presence Update
Number Exists on WhatsApp
To check if an entered number exists on WhatsApp, you use the onWhatsApp method of the provider. This method has the following signature:
onWhatsApp: (...jids: string[]) => Promise<{
exists: boolean;
jid: string;
}[]>
This method accepts one or more phone numbers (JIDs) as arguments and returns a promise that resolves to an array of objects containing the existence status (exists) and JID (jid) for each number.
app.ts
import { createBot, createProvider, createFlow, addKeyword, EVENTS } from '@builderbot/bot'
import { MemoryDB as Database } from '@builderbot/bot'
import { BaileysProvider as Provider } from '@builderbot/provider-baileys'
import { config } from 'dotenv'
config()
const PHONE_NUMBER = process.env.PHONE_NUMBER
const welcomeFlow = addKeyword<Provider, Database>(EVENTS.WELCOME)
.addAnswer(`💡 Example *Number Exist on Whatsapp*`)
.addAnswer(
'*Enter the number to check:*',
{ capture: true },
async (ctx, { provider, flowDynamic }) => {
const checkNumber = ctx.body
try {
const onWhats = await provider.vendor.onWhatsApp(checkNumber)
if (onWhats[0]?.exists) {
await flowDynamic([`*Exists:* ${onWhats[0].exists}\n*JID:* ${onWhats[0].jid}`, `*Object:* ${JSON.stringify(onWhats, null, 6)}`])
}
else {
await flowDynamic(`The number *${checkNumber}* does not exists on Whatsapp.`)
}
} catch (error) {
await flowDynamic(`*Error:* ${error}`);
}
}
)
const main = async () => {
const adapterFlow = createFlow([welcomeFlow])
const adapterProvider = createProvider(Provider, { usePairingCode: true, phoneNumber: PHONE_NUMBER })
const adapterDB = new Database()
const botResult = await createBot(
{
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
}
)
}
main()
Profile Picture
The method profilePictureUrl allows us to retrieve the profile picture of a given number. This method has the following signature:
(property) profilePictureUrl: (jid: string, type?: "image" | "preview", timeoutMs?: number) => Promise<string>
app.ts
import { createBot, createProvider, createFlow, addKeyword, EVENTS } from '@builderbot/bot'
import { BaileysProvider as Provider } from '@builderbot/provider-baileys'
import { MemoryDB as Database } from '@builderbot/bot'
import { config } from 'dotenv'
config()
const PHONE_NUMBER = process.env.PHONE_NUMBER
const welcomeFlow = addKeyword<Provider, Database>(EVENTS.WELCOME)
.addAnswer(`💡 Example *profile Picture*`)
.addAnswer(
'Enter number to check image profile: ', { capture: true },
async (ctx, { provider, flowDynamic, fallBack, endFlow }) => {
const check = ctx.body + '@s.whatsapp.net'
try {
const imageProfile = await provider.vendor.profilePictureUrl(check.replace(/\+/g, ''), 'image', 10000)
await flowDynamic([
{
body: '*Profile Picture:*',
media: imageProfile
}
])
return endFlow('End.')
} catch (error) {
await flowDynamic(`Error: ${error.message}`)
return fallBack('Try it again.')
}
}
)
const main = async () => {
const adapterFlow = createFlow([welcomeFlow])
const adapterProvider = createProvider(Provider, { usePairingCode: true, phoneNumber: PHONE_NUMBER })
const adapterDB = new Database()
const botResult = await createBot(
{
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
}
)
}
main()
Modifying Chats
The chatModify method provides various options to modify a chat, including:
- Archive a chat
- Mute/unmute a chat
- Mark a chat read/unread
- Delete a message for me
- Delete a chat
- Pin/unpin a chat
- Star/unstar a message
This method has the following signature:
(property) chatModify: (mod: ChatModification, jid: string) => Promise
Delete a message for me when the received message does not comply with my business logic rules. (Develop your own logic rules)
app.ts
import { createBot, createProvider, createFlow, addKeyword, EVENTS } from '@builderbot/bot'
import { BaileysProvider as Provider } from '@builderbot/provider-baileys'
import { MemoryDB as Database } from '@builderbot/bot'
import { config } from 'dotenv'
config()
const PHONE_NUMBER = process.env.PHONE_NUMBER
const badWords = ['fuck', 'ass hole', 'motherfucker']
const waitT = (ms: number) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(ms);
}, ms)
})
}
const welcomeFlow = addKeyword<Provider, Database>(EVENTS.WELCOME)
.addAnswer(`💡 Example *Delete User Message:*`)
.addAction(
async (ctx, { provider, flowDynamic }) => {
const resp = ctx.body.toLocaleLowerCase()
const containsBadWord = badWords.some(word => resp.includes(word))
const id = ctx.key.id
const fromMe = ctx.key.fromMe
const timeStamp = ctx.messageTimestamp
if (containsBadWord) {
await flowDynamic('Your message is going to be deleted as you are sending inappropriate language.')
await waitT(3500)
try {
await provider.vendor.chatModify(
{ clear: { messages: [{ id: id, fromMe: fromMe, timestamp: timeStamp }] } },
ctx.key.remoteJid
)
await flowDynamic(`Message deleted successfully.`)
} catch (error) {
await flowDynamic(`Error: ${JSON.stringify(error, null, 3)}`)
}
}
await flowDynamic('Welcome!')
}
)
const main = async () => {
const adapterFlow = createFlow([welcomeFlow])
const adapterProvider = createProvider(Provider, { usePairingCode: true, phoneNumber: PHONE_NUMBER })
const adapterDB = new Database()
const botResult = await createBot(
{
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
}
)
}
main()
Delete user message
Improve performance with Baileys
Baileys is a powerful provider for WhatsApp, but its ability to listen and process a wide range of events in real-time can lead to significant resource consumption, especially for highly active accounts. This guide will help you optimize your builderbot.app bot's performance when using Baileys as a provider.
Quickly optimize your Baileys provider
Activate these options in your Baileys provider configuration to improve performance:
const adapterProvider = createProvider(Provider, {
experimentalStore: true, // Significantly reduces resource consumption
timeRelease: 10800000, // Cleans up data every 3 hours (in milliseconds)
})
In addition to this configuration I recommend a reboot every 12 or 24 hours depending on how active your bot is. You can follow this guide to configure the restarts
Benefits:
experimentalStore: true
: Limits processing to individual messages only, drastically reducing resource usage.timeRelease: 10800000
: Performs periodic cleanups of accumulated data every 3 hours.
Note: experimentalStore
may limit some advanced WhatsApp functionalities, especially for groups.
Types of monitored events
Baileys constantly monitors various types of events, including:
- Individual messages: Sending and receiving messages in one-on-one chats.
- Group messages: All activity in WhatsApp groups.
- Read states: Updates when messages are read.
- Contact stories: Posting and viewing of statuses/stories.
- Message editing and deletion: Changes to existing messages.
- Reactions: Emojis and other reactions to messages.
- Profile updates: Changes in profile pictures, statuses, etc.
- Calls: Notifications of incoming and outgoing calls.
Impact on resources
- Constant processing: Each event triggers processes in the bot, consuming CPU.
- Data storage: Events are recorded in "baileys_store.json", increasing storage usage.
- Frequent overwriting: The file is updated with each new event, which can be I/O intensive.
- Exponential growth: In very active accounts, the volume of events can grow rapidly.
Optimization strategies
1. Using ExperimentalStore
The experimentalStore: true
option is an advanced feature in builderbot.app designed to significantly optimize the bot's resource usage.
How it works:
- Limits listening and processing to only individual message events.
- Drastically reduces resource consumption by ignoring other types of events.
Implementation:
const adapterProvider = createProvider(Provider, {
experimentalStore: true,
timeRelease: 10800000, // 3 hours in milliseconds
})
Important limitations:
- Only for individual messages: Works exclusively with "message" type events for individual chats.
- Not compatible with group functions: Not suitable for bots requiring group functionalities.
- Feature restriction: Some advanced WhatsApp features may not work correctly.
2. Event filtering
Configure Baileys to ignore non-essential events for your bot. This can be done through provider configuration or by selectively handling events in your code.
3. Periodic cleanup
Use the timeRelease
option or scheduled restarts to clear accumulated data. This helps keep the storage file size under control.
4. Selective monitoring
If possible, limit the number of chats or groups actively monitored. This can significantly reduce the number of processed events.
Implementation example
Here's an example of how to implement these strategies in your bot:
This example uses experimentalStore
and timeRelease
to optimize the bot's performance.
import { createBot, createProvider, createFlow, addKeyword } from '@builderbot/bot'
import { BaileysProvider as Provider } from '@builderbot/provider-baileys'
import { MemoryDB as Database } from '@builderbot/bot'
import { config } from 'dotenv'
config()
const welcomeFlow = addKeyword<Provider, Database>(['hi', 'hello', 'hola'])
.addAnswer(`🙌 Hello welcome to this *Chatbot*`)
const main = async () => {
const adapterFlow = createFlow([welcomeFlow])
const adapterProvider = createProvider(Provider, {
timeRelease: 10800000, // 3 hours in milliseconds
})
const adapterDB = new Database()
const botResult = await createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
}
main()
More examples
If you want to see more examples applying Baiely's functions you can check the links below
Delete Bot Message | Delete an existing message in the conversation |
Blocked Users on Bot | Block Whatsapp user using the provider |
Fetch Status | Retrieve all whatsapp profile status information |