🚀 ¡Nuevo! builderbot cloud para No-code ¡Pruébalo gratis!

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.


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()
API Call Example

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()
API Call Example

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.

Types of monitored events

Baileys constantly monitors various types of events, including:

  1. Individual messages: Sending and receiving messages in one-on-one chats.
  2. Group messages: All activity in WhatsApp groups.
  3. Read states: Updates when messages are read.
  4. Contact stories: Posting and viewing of statuses/stories.
  5. Message editing and deletion: Changes to existing messages.
  6. Reactions: Emojis and other reactions to messages.
  7. Profile updates: Changes in profile pictures, statuses, etc.
  8. Calls: Notifications of incoming and outgoing calls.

Impact on resources

  1. Constant processing: Each event triggers processes in the bot, consuming CPU.
  2. Data storage: Events are recorded in "baileys_store.json", increasing storage usage.
  3. Frequent overwriting: The file is updated with each new event, which can be I/O intensive.
  4. 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 MessageDelete an existing message in the conversation
Blocked Users on BotBlock Whatsapp user using the provider
Fetch StatusRetrieve all whatsapp profile status information

Guides

My first chatbot

Learn how build your first chatbot in few minutes

Read more

Concepts

Understand the essential concepts for building bots

Read more

Add Functions

The key to learning how to write flows is add-functions.

Read more

Plugins

Unlimitate and start implementing the community plugins.

Read more

Resources

Modularize

Learn how to modularise flows so that you can have a more maintainable bot.

Send Message

How to send a message via HTTP to start conversations, you can send multimedia as well.

Dockerizer

A good practice is to dockerise your bots to make them more maintainable and effective.

Events

Learning about events will make us more fluent when creating chatbots.