The Bot class is the main entry point for creating and managing WhatsApp bot instances. It extends Node.js EventEmitter and handles authentication, connection management, message routing, and middleware execution.
Import
import { Bot } from 'wapi' ;
Constructor
Creates a new Bot instance with authentication and account configuration.
new Bot ( uuid : UUID , auth : IBotAuth , account : IBotAccount , logger ?: Logger )
Unique identifier for the bot instance (from node:crypto)
Authentication handler implementing the IBotAuth interface: init
() => Promise<IBotAuthInit>
Initializes and returns authentication credentials and keys
Saves current authentication state
Removes stored authentication data
Account information object: Show IBotAccount Interface
WhatsApp JID (LID format)
Optional custom logger instance. If not provided, a default logger is created.
Example
import { Bot } from 'wapi' ;
import { randomUUID } from 'node:crypto' ;
const bot = new Bot (
randomUUID (),
authHandler ,
{ jid: '' , pn: '' , name: '' }
);
Properties
Unique identifier for this bot instance
The Baileys WebSocket connection instance. Null when disconnected.
Authentication handler for managing credentials
Current account information (updated after successful login)
Current connection status: "close", "open", or "reconnecting"
Logger instance for debugging and monitoring
Last message send latency in milliseconds (updated after each sendMessage call)
Command prefix characters. Default is "!/" allowing both ! and / as prefixes.
Methods
use()
Registers global middleware functions that run for all incoming messages.
bot . use ( ... middlewares : MiddlewareFn []): void
One or more middleware functions with signature: ( ctx : Context , next : () => Promise < void >) => Promise < void >
Example: Single Middleware
Example: Multiple Middlewares
bot . use ( async ( ctx , next ) => {
console . log ( `Received: ${ ctx . text } ` );
await next ();
});
command()
Registers command-specific middleware that only runs when a command is invoked.
bot . command ( name : string , ... middlewares : MiddlewareFn []): void
Command name (without prefix). Must be at least 1 character long.
Middleware functions to execute for this command
Example: Simple Command
Example: Command with Arguments
Example: Multiple Command Middlewares
bot . command ( 'hello' , async ( ctx ) => {
await ctx . reply ( 'Hello! 👋' );
});
Command names are case-insensitive and automatically converted to lowercase.
login()
Initiates the WhatsApp connection using QR code or OTP authentication.
await bot . login ( method : "qr" | "otp" ): Promise < void >
Authentication method:
"qr": Generates QR codes for scanning (emits qr event)
"otp": Sends one-time password to phone number (emits otp event)
import qrcode from 'qrcode-terminal' ;
bot . on ( 'qr' , ( qr ) => {
qrcode . generate ( qr , { small: true });
console . log ( 'Scan the QR code above' );
});
bot . on ( 'open' , ( account ) => {
console . log ( `Logged in as ${ account . name } ` );
});
await bot . login ( 'qr' );
For OTP login, the account.pn must be set with a valid phone number before calling login().
disconnect()
Gracefully disconnects the bot from WhatsApp.
await bot . disconnect ( reason ?: Error ): Promise < void >
Optional error describing the disconnect reason. Defaults to “Intentional disconnection.”
// Graceful disconnect
await bot . disconnect ();
// Disconnect with reason
await bot . disconnect ( new Error ( 'Maintenance mode' ));
logout()
Logs out from WhatsApp and clears authentication data.
await bot . logout ( reason ?: Boom ): Promise < void >
Optional Boom error with logout reason
import { Boom } from '@hapi/boom' ;
await bot . logout ( new Boom ( 'User requested logout' ));
After logout, you’ll need to authenticate again using QR code or OTP.
parseMentions()
Extracts WhatsApp mentions from text.
bot . parseMentions ( text : string , server : JidServer ): string []
Text containing mentions in format @1234567890
JID server type: "s.whatsapp.net" (phone numbers) or "lid" (LID format)
const text = 'Hello @1234567890 and @9876543210' ;
const mentions = bot . parseMentions ( text , 's.whatsapp.net' );
// Returns: ['1234567890@s.whatsapp.net', '9876543210@s.whatsapp.net']
parseLinks()
Extracts URLs, emails, and phone numbers from text.
bot . parseLinks ( text : string ): string []
Array of extracted links (URLs, emails, phone numbers)
const text = 'Visit https://example.com or email test@example.com' ;
const links = bot . parseLinks ( text );
// Returns: ['https://example.com', 'mailto:test@example.com']
sendMessage()
Sends a message to a WhatsApp chat.
await bot . sendMessage (
jid : string ,
content : AnyMessageContent ,
options ?: IBotSendMessageOptions
): Promise < Context | null >
content
AnyMessageContent
required
Message content object from Baileys: Show Common Content Types
Image message with optional caption, mimetype
Video message with optional caption, gifPlayback
Audio message with optional ptt (push-to-talk)
Document with fileName, mimetype
Send options: Show IBotSendMessageOptions
Message to quote/reply to
Addressing mode for mentions
Ephemeral message expiration in seconds
Context object for the sent message, or null if sending failed
Text Message
Image with Caption
Reply to Message
With Mentions
const ctx = await bot . sendMessage (
'1234567890@s.whatsapp.net' ,
{ text: 'Hello World!' }
);
The ping property is automatically updated with send latency after each call.
Retrieves metadata for a group chat.
await bot . groupMetadata ( jid : string ): Promise < GroupMetadata | null >
Group JID (must end with @g.us)
returns
Promise<GroupMetadata | null>
Group metadata object containing:
id: Group JID
subject: Group name
owner: Creator JID
creation: Creation timestamp
desc: Group description
participants: Array of participant objects
announce: Admin-only posting mode
restrict: Restrict group info changes
const metadata = await bot . groupMetadata ( '123456789@g.us' );
if ( metadata ) {
console . log ( `Group: ${ metadata . subject } ` );
console . log ( `Members: ${ metadata . participants . length } ` );
console . log ( `Created: ${ new Date ( metadata . creation * 1000 ) } ` );
}
Results are cached automatically to reduce API calls.
profilePictureUrl()
Gets the profile picture URL for a user or group.
await bot . profilePictureUrl ( jid : string ): Promise < string >
Profile picture URL. Returns a default placeholder if no picture is set or on error.
const avatarUrl = await bot . profilePictureUrl ( ctx . from . jid );
await ctx . replyWithImage (
avatarUrl ,
{ caption: 'Your profile picture' }
);
Events
The Bot class emits the following events:
Emitted when a QR code is generated during login.
bot . on ( 'qr' , ( qr : string ) => {
// Display QR code for scanning
console . log ( qr );
});
QR code data string (can be rendered with qrcode libraries)
otp
Emitted when an OTP code is generated.
bot . on ( 'otp' , ( code : string ) => {
// Display OTP code to user
console . log ( `Your code: ${ code } ` );
});
open
Emitted when connection is successfully established.
bot . on ( 'open' , ( account : IBotAccount ) => {
console . log ( `Connected as ${ account . name } ` );
console . log ( `JID: ${ account . jid } ` );
console . log ( `Phone: ${ account . pn } ` );
});
Updated account information with JID, phone number, and name
close
Emitted when connection is closed.
bot . on ( 'close' , ( reason : string ) => {
console . log ( `Disconnected: ${ reason } ` );
});
Human-readable disconnect reason (includes status code and error message)
error
Emitted when an error occurs.
bot . on ( 'error' , ( error : Error ) => {
console . error ( 'Bot error:' , error );
});
Error object describing what went wrong
Always handle the error event to prevent unhandled promise rejections.
Complete Example
import { Bot } from 'wapi' ;
import { randomUUID } from 'node:crypto' ;
import qrcode from 'qrcode-terminal' ;
// Create bot instance
const bot = new Bot (
randomUUID (),
authHandler ,
{ jid: '' , pn: '' , name: '' }
);
// Set custom prefix
bot . prefix = '!/' ;
// Global middleware
bot . use ( async ( ctx , next ) => {
console . log ( `Message from ${ ctx . from . name } : ${ ctx . text } ` );
await next ();
});
// Register commands
bot . command ( 'ping' , async ( ctx ) => {
await ctx . reply ( `🏓 Pong! ( ${ bot . ping . toFixed ( 0 ) } ms)` );
});
bot . command ( 'help' , async ( ctx ) => {
await ctx . reply ( `
Available commands:
• !ping - Check bot latency
• !help - Show this message
` . trim ());
});
bot . command ( 'groups' , async ( ctx ) => {
if ( ctx . chat . type !== 'group' ) {
await ctx . reply ( '❌ This command only works in groups' );
return ;
}
const metadata = await bot . groupMetadata ( ctx . chat . jid );
if ( ! metadata ) {
await ctx . reply ( '❌ Failed to get group info' );
return ;
}
await ctx . reply ( `
Group: ${ metadata . subject }
Members: ${ metadata . participants . length }
Created: ${ new Date ( metadata . creation * 1000 ). toLocaleDateString () }
` . trim ());
});
// Event handlers
bot . on ( 'qr' , ( qr ) => {
qrcode . generate ( qr , { small: true });
});
bot . on ( 'open' , ( account ) => {
console . log ( `✅ Logged in as ${ account . name } ` );
});
bot . on ( 'close' , ( reason ) => {
console . log ( `❌ Disconnected: ${ reason } ` );
});
bot . on ( 'error' , ( error ) => {
console . error ( 'Error:' , error );
});
// Start bot
await bot . login ( 'qr' );
See Also
Context Learn about the Context object passed to middleware
Message Builder Build formatted messages easily