Skip to main content
The blacklist feature lets you prevent specific users from interacting with your bot. You can also use it as a whitelist to allow only specific users.

How Blacklisting Works

When a user is blacklisted:
  • The bot ignores all their messages
  • They receive no responses
  • Their messages don’t trigger any flows
  • The blacklist persists in memory until the bot restarts

Basic Usage

Initial Blacklist

Set an initial blacklist when creating your bot:
import { createBot } from '@builderbot/bot'

const { httpServer } = await createBot(
    {
        flow: adapterFlow,
        provider: adapterProvider,
        database: adapterDB,
    },
    {
        blackList: ['1234567890', '0987654321']  // Blocked numbers
    }
)

Adding to Blacklist

Block users dynamically using the blacklist API:
const blockFlow = addKeyword('block')
    .addAction(async (ctx, { blacklist, flowDynamic }) => {
        blacklist.add(ctx.from)
        await flowDynamic('You have been blocked')
    })

Removing from Blacklist

Unblock users:
const unblockFlow = addKeyword('unblock-me')
    .addAction(async (ctx, { blacklist, flowDynamic }) => {
        try {
            blacklist.remove(ctx.from)
            await flowDynamic('You have been unblocked')
        } catch (error) {
            await flowDynamic('You were not blocked')
        }
    })
blacklist.remove() throws an error if the number is not in the blacklist. Wrap it in try-catch to handle this.

Blacklist via HTTP Endpoints

Manage the blacklist through your API:
1

Create add/remove endpoint

adapterProvider.server.post(
    '/v1/blacklist',
    handleCtx(async (bot, req, res) => {
        const { number, intent } = req.body
        
        if (intent === 'add') {
            bot.blacklist.add(number)
        } else if (intent === 'remove') {
            bot.blacklist.remove(number)
        }
        
        res.writeHead(200, { 'Content-Type': 'application/json' })
        return res.end(JSON.stringify({ 
            status: 'ok', 
            number, 
            intent 
        }))
    })
)
2

Create list endpoint

adapterProvider.server.get(
    '/v1/blacklist/list',
    handleCtx(async (bot, req, res) => {
        const blacklist = bot.blacklist.getList()
        
        res.writeHead(200, { 'Content-Type': 'application/json' })
        return res.end(JSON.stringify({ 
            status: 'ok', 
            blacklist 
        }))
    })
)
3

Test the API

# Add to blacklist
curl -X POST http://localhost:3008/v1/blacklist \
  -H "Content-Type: application/json" \
  -d '{"number": "1234567890", "intent": "add"}'

# Remove from blacklist
curl -X POST http://localhost:3008/v1/blacklist \
  -H "Content-Type: application/json" \
  -d '{"number": "1234567890", "intent": "remove"}'

# Get blacklist
curl http://localhost:3008/v1/blacklist/list

Blacklist Methods

Available methods on the blacklist object:

add()

Add one or more numbers to the blacklist:
// Add single number
blacklist.add('1234567890')

// Add multiple numbers
blacklist.add(['1234567890', '0987654321'])
Returns: Array of status messages
const messages = blacklist.add(['1234567890', '1234567890'])
// Returns: [
//   'Número 1234567890 añadido exitosamente.',
//   'El número de teléfono 1234567890 ya está en la lista negra.'
// ]

remove()

Remove a number from the blacklist:
try {
    blacklist.remove('1234567890')
    console.log('Removed successfully')
} catch (error) {
    console.log('Number was not in blacklist')
}
Throws: Error if number is not in the blacklist

checkIf()

Check if a number is blacklisted:
if (blacklist.checkIf('1234567890')) {
    console.log('This number is blocked')
} else {
    console.log('This number is allowed')
}
Returns: true if blacklisted, false otherwise

getList()

Get all blacklisted numbers:
const numbers = blacklist.getList()
console.log('Blacklisted numbers:', numbers)
// Returns: ['1234567890', '0987654321']
Returns: Array of phone numbers

Whitelist Mode

Use the blacklist as a whitelist by prefixing allowed numbers with !:
const { httpServer } = await createBot(
    {
        flow: adapterFlow,
        provider: adapterProvider,
        database: adapterDB,
    },
    {
        blackList: [
            '!1234567890',  // Only this number is allowed
            '!0987654321'   // And this one
        ]
    }
)
When ANY number starts with !, the blacklist switches to whitelist mode. Only numbers with ! prefix can interact with the bot.

Whitelist Example

// Whitelist mode: Only allow specific users
const { httpServer } = await createBot(
    { flow, provider, database },
    {
        blackList: [
            '!1111111111',  // Admin 1
            '!2222222222',  // Admin 2
            '!3333333333'   // Admin 3
        ]
    }
)

// Now only these three numbers can use the bot

Dynamic Blacklist Management

Admin-Controlled Blacklist

Let admins manage the blacklist:
const ADMIN_NUMBERS = ['1111111111', '2222222222']

const blockUserFlow = addKeyword('block')
    .addAnswer(
        'Enter number to block:',
        { capture: true },
        async (ctx, { blacklist, flowDynamic }) => {
            // Check if user is admin
            if (!ADMIN_NUMBERS.includes(ctx.from)) {
                return flowDynamic('Unauthorized')
            }
            
            const numberToBlock = ctx.body.trim()
            blacklist.add(numberToBlock)
            
            await flowDynamic(`Blocked: ${numberToBlock}`)
        }
    )

const unblockUserFlow = addKeyword('unblock')
    .addAnswer(
        'Enter number to unblock:',
        { capture: true },
        async (ctx, { blacklist, flowDynamic }) => {
            if (!ADMIN_NUMBERS.includes(ctx.from)) {
                return flowDynamic('Unauthorized')
            }
            
            const numberToUnblock = ctx.body.trim()
            
            try {
                blacklist.remove(numberToUnblock)
                await flowDynamic(`Unblocked: ${numberToUnblock}`)
            } catch (error) {
                await flowDynamic('Number was not blocked')
            }
        }
    )

Time-Based Temporary Bans

const tempBanFlow = addKeyword('tempban')
    .addAction(async (ctx, { blacklist, flowDynamic }) => {
        const userNumber = ctx.from
        
        // Add to blacklist
        blacklist.add(userNumber)
        await flowDynamic('You are temporarily banned for 1 hour')
        
        // Remove after 1 hour
        setTimeout(() => {
            try {
                blacklist.remove(userNumber)
                console.log(`Temp ban expired for ${userNumber}`)
            } catch (error) {
                console.log('User already unblocked')
            }
        }, 60 * 60 * 1000)  // 1 hour
    })

Rate Limit Protection

Block users who spam:
const messageCount = new Map()

const checkSpam = (number) => {
    const count = messageCount.get(number) || 0
    const newCount = count + 1
    messageCount.set(number, newCount)
    
    // Reset after 1 minute
    setTimeout(() => {
        messageCount.set(number, 0)
    }, 60000)
    
    return newCount > 10  // More than 10 messages per minute
}

const welcomeFlow = addKeyword(['hi', 'hello'])
    .addAction(async (ctx, { blacklist, flowDynamic }) => {
        if (checkSpam(ctx.from)) {
            blacklist.add(ctx.from)
            await flowDynamic('Blocked due to spam')
            return
        }
        
        await flowDynamic('Welcome!')
    })

Complete Blacklist Example

import { createBot, createProvider, createFlow, addKeyword } from '@builderbot/bot'
import { MemoryDB } from '@builderbot/bot'
import { BaileysProvider } from '@builderbot/provider-baileys'

const PORT = process.env.PORT ?? 3008
const ADMIN_NUMBERS = ['1111111111']

const welcomeFlow = addKeyword(['hi', 'hello'])
    .addAnswer('Welcome! Type *help* for commands')

const blockFlow = addKeyword('block')
    .addAnswer(
        'Enter number to block:',
        { capture: true },
        async (ctx, { blacklist, flowDynamic }) => {
            if (!ADMIN_NUMBERS.includes(ctx.from)) {
                return flowDynamic('Only admins can block users')
            }
            
            blacklist.add(ctx.body.trim())
            await flowDynamic(`Blocked: ${ctx.body}`)
        }
    )

const unblockFlow = addKeyword('unblock')
    .addAnswer(
        'Enter number to unblock:',
        { capture: true },
        async (ctx, { blacklist, flowDynamic }) => {
            if (!ADMIN_NUMBERS.includes(ctx.from)) {
                return flowDynamic('Only admins can unblock users')
            }
            
            try {
                blacklist.remove(ctx.body.trim())
                await flowDynamic(`Unblocked: ${ctx.body}`)
            } catch (error) {
                await flowDynamic('Number was not blocked')
            }
        }
    )

const listBlockedFlow = addKeyword('blocked')
    .addAction(async (ctx, { blacklist, flowDynamic }) => {
        if (!ADMIN_NUMBERS.includes(ctx.from)) {
            return flowDynamic('Only admins can view blacklist')
        }
        
        const blocked = blacklist.getList()
        
        if (blocked.length === 0) {
            await flowDynamic('No blocked numbers')
        } else {
            await flowDynamic(`Blocked numbers:\n${blocked.join('\n')}`)
        }
    })

const main = async () => {
    const adapterFlow = createFlow([welcomeFlow, blockFlow, unblockFlow, listBlockedFlow])
    const adapterProvider = createProvider(BaileysProvider)
    const adapterDB = new MemoryDB()

    const { handleCtx, httpServer } = await createBot(
        {
            flow: adapterFlow,
            provider: adapterProvider,
            database: adapterDB,
        },
        {
            blackList: []  // Start with empty blacklist
        }
    )

    // HTTP endpoints for blacklist management
    adapterProvider.server.post(
        '/v1/blacklist',
        handleCtx(async (bot, req, res) => {
            const { number, intent } = req.body
            
            if (intent === 'add') {
                bot.blacklist.add(number)
            } else if (intent === 'remove') {
                bot.blacklist.remove(number)
            }
            
            res.writeHead(200, { 'Content-Type': 'application/json' })
            return res.end(JSON.stringify({ status: 'ok', number, intent }))
        })
    )

    adapterProvider.server.get(
        '/v1/blacklist/list',
        handleCtx(async (bot, req, res) => {
            const blacklist = bot.blacklist.getList()
            res.writeHead(200, { 'Content-Type': 'application/json' })
            return res.end(JSON.stringify({ status: 'ok', blacklist }))
        })
    )

    httpServer(+PORT)
}

main()

Best Practices

The blacklist is stored in memory and resets on bot restart. For persistence:
// On bot start, load from database
const savedBlacklist = await database.loadBlacklist()
const { httpServer } = await createBot(
    { flow, provider, database },
    { blackList: savedBlacklist }
)

// When adding to blacklist, save to database
blacklist.add(number)
await database.saveBlacklist(blacklist.getList())
Send a final message before blocking:
.addAction(async (ctx, { blacklist, flowDynamic }) => {
    await flowDynamic('You have been blocked for violating our terms')
    blacklist.add(ctx.from)
})
Keep an audit trail:
blacklist.add(number)
console.log(`[${new Date().toISOString()}] Blocked: ${number}`)
await database.logAction('blacklist_add', { number })
Always check permissions before allowing blacklist changes:
const isAdmin = (number) => ADMIN_NUMBERS.includes(number)

if (!isAdmin(ctx.from)) {
    return flowDynamic('Unauthorized')
}

Troubleshooting

Check that the number format matches exactly:
// These are different:
blacklist.add('1234567890')      // Without country code
blacklist.add('521234567890')    // With country code

// Check actual number format
console.log('User number:', ctx.from)
Ensure at least one number has the ! prefix:
// This is blacklist mode (blocks these numbers)
blackList: ['1234567890', '0987654321']

// This is whitelist mode (only allows these numbers)
blackList: ['!1234567890', '!0987654321']
Remember remove() throws an error if number isn’t blocked:
try {
    blacklist.remove(number)
} catch (error) {
    console.log('Number was not in blacklist')
}

Next Steps

Build docs developers (and LLMs) love