What is a Provider?
A provider is an adapter that connects BuilderBot to a specific messaging platform (WhatsApp, Telegram, Instagram, Meta, etc.). The provider handles platform-specific communication, message sending, media handling, and event management.
Provider Class Overview
All providers extend the abstract ProviderClass, which defines a standard interface:
abstract class ProviderClass<V = any>
extends EventEmitterClass<ProviderEventTypes>
implements ProviderHttpServer {
public abstract globalVendorArgs: GlobalVendorArgs
public vendor: Vendor<V>
public server: Polka
public idBotName: string = 'bot'
public idCtxBot: string = 'id-ctx-bot'
}
Key Components:
vendor - The underlying messaging platform SDK/API instance
server - HTTP server (Polka) for webhooks and API endpoints
- Event emitter capabilities for message handling
- Abstract methods that each provider must implement
Creating a Provider
Use the createProvider function to instantiate a provider:
import { createProvider } from '@builderbot/bot'
import { BaileysProvider } from '@builderbot/provider-baileys'
const adapterProvider = createProvider(BaileysProvider)
With Configuration
const adapterProvider = createProvider(MetaProvider, {
jwtToken: 'your-jwt-token',
numberId: 'phone-number-id',
verifyToken: 'verify-token',
version: 'v21.0'
})
Available Providers
BuilderBot supports multiple messaging platforms:
Baileys (WhatsApp)
Meta (WhatsApp Business)
Telegram
Twilio
import { BaileysProvider } from '@builderbot/provider-baileys'
const provider = createProvider(BaileysProvider, {
name: 'bot-name',
port: 3008
})
Direct WhatsApp connection using Baileys library.import { MetaProvider } from '@builderbot/provider-meta'
const provider = createProvider(MetaProvider, {
jwtToken: process.env.JWT_TOKEN,
numberId: process.env.NUMBER_ID,
verifyToken: process.env.VERIFY_TOKEN,
version: 'v21.0'
})
Official WhatsApp Business API.import { TelegramProvider } from '@builderbot/provider-telegram'
const provider = createProvider(TelegramProvider, {
token: process.env.TELEGRAM_BOT_TOKEN
})
Telegram Bot API integration.import { TwilioProvider } from '@builderbot/provider-twilio'
const provider = createProvider(TwilioProvider, {
accountSid: process.env.TWILIO_ACCOUNT_SID,
authToken: process.env.TWILIO_AUTH_TOKEN,
vendorNumber: process.env.TWILIO_NUMBER
})
Twilio messaging API.
Provider Lifecycle
Providers follow a specific initialization sequence:
Construction
Provider instance is created and HTTP server is built:constructor() {
super()
this.server = this.buildHTTPServer()
}
Vendor Initialization
The platform-specific SDK is initialized:protected abstract initVendor(): Promise<any>
Event Registration
Platform events are registered and listeners attached:protected abstract busEvents(): Array<{
event: string | number | symbol
func: Function
}>
HTTP Server Start
Webhook endpoints and HTTP server start listening:beforeHttpServerInit()
start(methods, callback)
afterHttpServerInit()
Abstract Methods
Each provider must implement these core methods:
sendMessage
public abstract sendMessage<K = any>(
userId: string,
message: any,
args?: any
): Promise<K>
Send a message to a user on the platform.
Example:
await provider.sendMessage('1234567890', 'Hello!', {
media: 'https://example.com/image.jpg'
})
saveFile
public abstract saveFile(
ctx: any,
options?: { path: string }
): Promise<string>
Download and save media files from messages.
Example:
const filePath = await provider.saveFile(ctx, {
path: './downloads'
})
initVendor
protected abstract initVendor(): Promise<any>
Initialize the platform SDK/API client.
busEvents
protected abstract busEvents(): Array<{
event: string | number | symbol
func: Function
}>
Define platform event listeners.
HTTP Server
Every provider includes a built-in HTTP server (Polka) for webhooks and custom endpoints:
public buildHTTPServer(): Polka {
return polka()
.use(cors())
.use(urlencoded({ extended: true }))
.use(json())
}
Adding Custom Endpoints
const { handleCtx } = await createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
// Custom endpoint for sending messages via API
adapterProvider.server.post(
'/v1/messages',
handleCtx(async (bot, req, res) => {
const { number, message, urlMedia } = req.body
await bot.sendMessage(number, message, { media: urlMedia ?? null })
return res.end('sent')
})
)
// Custom endpoint for triggering flows
adapterProvider.server.post(
'/v1/register',
handleCtx(async (bot, req, res) => {
const { number, name } = req.body
await bot.dispatch('REGISTER_FLOW', { from: number, name })
return res.end('triggered')
})
)
Route Discovery
Get all registered routes:
const routes = provider.getListRoutes(provider.server)
console.log(routes)
// Output:
// [
// '[POST]: http://localhost:3008/v1/messages',
// '[POST]: http://localhost:3008/v1/register',
// '[GET]: http://localhost:3008/webhook'
// ]
Event System
Providers emit events that BuilderBot listens to:
type ProviderEventTypes = {
message: [arg1: BotContext]
require_action: [arg1: {
title: string
instructions: string[]
payload?: { qr?: string; code?: string; [key: string]: any }
}]
notice: [arg1: { title: string; instructions: string[] }]
ready: any
auth_failure: any
host: any
[key: string]: any
}
Listening to Provider Events
adapterProvider.on('ready', () => {
console.log('Provider is ready!')
})
adapterProvider.on('message', (ctx) => {
console.log('Message received:', ctx.body)
})
adapterProvider.on('notice', ({ title, instructions }) => {
console.log(title)
instructions.forEach(i => console.log(i))
})
Dispatching Custom Events
Trigger flows programmatically using the dispatch method:
public dispatchInside(payload: {
body: string
name: string
from: string
}) {
this.emit('message', { ...payload })
}
Example:
adapterProvider.dispatchInside({
from: '1234567890',
name: 'John Doe',
body: setEvent('WELCOME')
})
Context Middleware
The inHandleCtx method provides a safe wrapper for HTTP endpoint handlers:
public inHandleCtx<T extends Pick<ProviderClass<V>, 'sendMessage'> & {
provider: V
}>(
ctxPolka: (bot: T, req: Request, res: PolkaRes) => Promise<void>
): (...args: any[]) => any
Features:
- Automatic error handling
- Bot context injection
- Authentication state validation
Starting and Stopping
Start the Server
public start(
vendor: BotCtxMiddleware,
cb: (arg?: any) => void = () => null
): void
Called internally by createBot, but can be invoked manually if needed.
Stop the Server
public stop(): Promise<void>
Gracefully shutdown the HTTP server:
await adapterProvider.stop()
console.log('Provider stopped')
Practical Example
Complete bot setup with provider configuration:
import { createBot, createProvider, createFlow, addKeyword } from '@builderbot/bot'
import { BaileysProvider } from '@builderbot/provider-baileys'
import { MemoryDB } from '@builderbot/bot'
const welcomeFlow = addKeyword(['hi', 'hello'])
.addAnswer('Welcome to our bot!')
const main = async () => {
const adapterFlow = createFlow([welcomeFlow])
const adapterProvider = createProvider(BaileysProvider)
const adapterDB = new MemoryDB()
const { handleCtx, httpServer } = await createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
// Custom API endpoint
adapterProvider.server.post(
'/v1/send',
handleCtx(async (bot, req, res) => {
const { to, message } = req.body
await bot.sendMessage(to, message)
res.end('Message sent')
})
)
// Listen on custom events
adapterProvider.on('ready', () => {
console.log('Bot is ready!')
})
httpServer(3008)
}
main()
Best Practices
Environment Variables: Store sensitive credentials in environment variables, never hardcode them.
Error Handling: Always implement error handling in custom endpoints to prevent crashes.
Port Configuration: Ensure the port number doesn’t conflict with other services. The default is 3008.
Multiple Providers: You can run multiple bots with different providers simultaneously by using different ports.