The Context class represents an incoming message with its metadata and provides convenient methods for replying. It extends the Message class and is passed to all middleware functions.
Import
import type { Context } from 'wapi' ;
Context objects are automatically created by the Bot and passed to your middleware. You typically don’t instantiate them directly.
Properties
Bot Reference
Reference to the parent Bot instance
bot . command ( 'ping' , async ( ctx ) => {
// Access bot properties through ctx
await ctx . reply ( `Latency: ${ ctx . bot . ping } ms` );
});
The prefix character used to invoke the command (e.g., "!" or "/"). Empty string if not a command.
The command name in lowercase (without prefix). Empty string if not a command.
Array of command arguments (space-separated words after the command name)
Example: Parse Arguments
Example: Argument Validation
bot . command ( 'calc' , async ( ctx ) => {
// User sent: "!calc 10 + 20"
console . log ( ctx . prefixUsed ); // "!"
console . log ( ctx . commandName ); // "calc"
console . log ( ctx . args ); // ["10", "+", "20"]
const [ a , op , b ] = ctx . args ;
// Perform calculation...
});
Message Properties (from Message class)
Raw Baileys message object
Chat information: Phone number (for private chats)
type
'private' | 'group' | 'unknown'
Chat type
Message type: "conversation", "imageMessage", "videoMessage", "audioMessage", "documentMessage", "stickerMessage", etc.
Message timestamp (Unix epoch in milliseconds)
File SHA256 hash (for media messages)
MIME type (for media messages)
Message text content (or caption for media)
File size in bytes (for media) or text length
Array of mentioned user JIDs
Array of URLs, emails, and phone numbers found in the message
Quoted/replied message object (if this is a reply)
Example: Access Message Info
Example: Check Message Type
bot . use ( async ( ctx , next ) => {
console . log ( `From: ${ ctx . from . name } ` );
console . log ( `Chat: ${ ctx . chat . name } ( ${ ctx . chat . type } )` );
console . log ( `Type: ${ ctx . type } ` );
console . log ( `Text: ${ ctx . text } ` );
console . log ( `Time: ${ new Date ( ctx . timestamp ) } ` );
if ( ctx . mentions . length > 0 ) {
console . log ( `Mentions: ${ ctx . mentions . join ( ', ' ) } ` );
}
if ( ctx . quoted ) {
console . log ( `Replying to: ${ ctx . quoted . text } ` );
}
await next ();
});
Methods
reply()
Sends a text reply to the message.
await ctx . reply ( text : string , options ?: IReplyOptions ): Promise < Context >
Optional reply options: Additional user JIDs to mention
Additional context information (advanced)
Context object for the sent reply
Simple Reply
Reply with Mention
Chain Replies
bot . command ( 'hello' , async ( ctx ) => {
await ctx . reply ( 'Hello there! 👋' );
});
replyWithImage()
Sends an image reply to the message.
await ctx . replyWithImage (
image : string | Buffer ,
options ?: IReplyWithImageOptions
): Promise < Context >
Image data as Buffer or URL string
Show IReplyWithImageOptions
MIME type (default: "image/jpeg")
Send as view-once message
User JIDs to mention in caption
Context object for the sent image
From URL
From Buffer
View Once
bot . command ( 'cat' , async ( ctx ) => {
await ctx . replyWithImage (
'https://cataas.com/cat' ,
{ caption: 'Here \' s a random cat! 🐱' }
);
});
replyWithVideo()
Sends a video reply to the message.
await ctx . replyWithVideo (
video : string | Buffer ,
options ?: IReplyWithVideoOptions
): Promise < Context >
Video data as Buffer or URL string
Show IReplyWithVideoOptions
MIME type (default: "video/mp4")
Send as view-once message
Play as GIF (loop without sound)
User JIDs to mention in caption
Context object for the sent video
bot . command ( 'tutorial' , async ( ctx ) => {
await ctx . replyWithVideo (
'https://example.com/tutorial.mp4' ,
{ caption: 'Watch this tutorial' }
);
});
replyWithAudio()
Sends an audio reply to the message.
await ctx . replyWithAudio (
audio : string | Buffer ,
options ?: IReplyWithAudioOptions
): Promise < Context >
Audio data as Buffer or URL string
Show IReplyWithAudioOptions
MIME type (default: "audio/mpeg")
Send as view-once message
Send as voice note (push-to-talk)
Context object for the sent audio
bot . command ( 'song' , async ( ctx ) => {
await ctx . replyWithAudio (
'https://example.com/song.mp3'
);
});
replyWithSticker()
Sends a sticker reply to the message.
await ctx . replyWithSticker (
sticker : Buffer ,
options ?: IReplyOptions
): Promise < Context >
Sticker data as WebP Buffer
Optional reply options (mentions, contextInfo)
Context object for the sent sticker
Stickers must be in WebP format. Use a library like sharp to convert images to WebP.
import sharp from 'sharp' ;
bot . command ( 'sticker' , async ( ctx ) => {
if ( ctx . type !== 'imageMessage' ) {
await ctx . reply ( '❌ Please send an image' );
return ;
}
// Download the image
const imageBuffer = await ctx . download ();
// Convert to WebP sticker
const stickerBuffer = await sharp ( imageBuffer )
. resize ( 512 , 512 , { fit: 'contain' })
. webp ()
. toBuffer ();
await ctx . replyWithSticker ( stickerBuffer );
});
del()
Deletes the message.
await ctx . del (): Promise < void >
Only works for messages sent by the bot (where message.key.fromMe === true) or messages in groups where the bot is an admin.
Auto-Delete Spam
Self-Destruct Command
bot . use ( async ( ctx , next ) => {
if ( containsSpam ( ctx . text )) {
await ctx . del ();
await ctx . bot . sendMessage (
ctx . chat . jid ,
{ text: '⚠️ Spam message deleted' }
);
return ; // Don't call next()
}
await next ();
});
edit()
Edits a message sent by the bot.
await ctx . edit ( text : string ): Promise < Context >
Context object for the edited message
Only messages sent by the bot (message.key.fromMe === true) can be edited.
Edit Own Message
Progress Updates
bot . command ( 'countdown' , async ( ctx ) => {
const msg = await ctx . reply ( 'Starting in 3...' );
await new Promise ( r => setTimeout ( r , 1000 ));
await msg . edit ( 'Starting in 2...' );
await new Promise ( r => setTimeout ( r , 1000 ));
await msg . edit ( 'Starting in 1...' );
await new Promise ( r => setTimeout ( r , 1000 ));
await msg . edit ( '🚀 Go!' );
});
download()
Downloads media content from the message.
await ctx . download (): Promise < Buffer >
Only works for media messages (images, videos, audio, documents, stickers).
Download and Process Image
Save Document
Image to Sticker
bot . use ( async ( ctx , next ) => {
if ( ctx . type === 'imageMessage' ) {
try {
const buffer = await ctx . download ();
console . log ( `Downloaded image: ${ buffer . length } bytes` );
// Process the image...
// await processImage(buffer);
} catch ( error ) {
await ctx . reply ( '❌ Failed to download image' );
}
}
await next ();
});
Complete Example
import { Bot } from 'wapi' ;
import { MessageBuilder } from 'wapi' ;
const bot = new Bot ( /* ... */ );
// Logging middleware
bot . use ( async ( ctx , next ) => {
console . log ( `[ ${ ctx . chat . type } ] ${ ctx . from . name } : ${ ctx . text } ` );
await next ();
});
// Anti-spam middleware
bot . use ( async ( ctx , next ) => {
if ( ctx . text . toLowerCase (). includes ( 'spam' )) {
await ctx . reply ( '⚠️ Please don \' t spam' );
await ctx . del ();
return ;
}
await next ();
});
// Info command
bot . command ( 'info' , async ( ctx ) => {
const info = new MessageBuilder ()
. addTitle ( 'MESSAGE INFO' )
. addBlankLine ()
. addDescription ( `ID: ${ ctx . id } ` )
. addDescription ( `Type: ${ ctx . type } ` )
. addDescription ( `From: ${ ctx . from . name } ` )
. addDescription ( `Chat: ${ ctx . chat . name } ` )
. addDescription ( `Time: ${ new Date ( ctx . timestamp ). toLocaleString () } ` )
. addBlankLine ()
. addDescription ( `Size: ${ ctx . size } bytes` )
. addDescription ( `Mentions: ${ ctx . mentions . length } ` )
. addDescription ( `Links: ${ ctx . links . length } ` )
. build ();
await ctx . reply ( info );
});
// Echo command
bot . command ( 'echo' , async ( ctx ) => {
const text = ctx . args . join ( ' ' );
if ( ! text ) {
await ctx . reply ( 'Usage: !echo <message>' );
return ;
}
await ctx . reply ( text );
});
// Mention command
bot . command ( 'mention' , async ( ctx ) => {
if ( ctx . chat . type !== 'group' ) {
await ctx . reply ( '❌ This command only works in groups' );
return ;
}
await ctx . reply (
`Hello @ ${ ctx . from . pn } ! 👋` ,
{ mentions: [ ctx . from . jid ] }
);
});
// Download media
bot . use ( async ( ctx , next ) => {
if ( ctx . type === 'imageMessage' && ctx . text . includes ( '#download' )) {
const buffer = await ctx . download ();
await ctx . reply ( `✅ Downloaded ${ buffer . length } bytes` );
return ;
}
await next ();
});
await bot . login ( 'qr' );
See Also
Bot Learn about the Bot class
Message Builder Build formatted messages