Message Handler
The message handler receives all messages and decides how to respond:Copy
router.onMessage(async (message, context) => {
// Return string for custom response
// Return null to let AI handle
if (message.content === '/help') {
return 'Here are the available commands...';
}
return null; // Let AI respond
});
Message Object
Copy
router.onMessage(async (message, context) => {
console.log({
content: message.content, // User's message text
userId: message.userId, // User ID
platform: message.platform, // Platform name
channelId: message.channelId, // Channel/chat ID (if applicable)
timestamp: message.timestamp // Message timestamp
});
});
Context Object
Copy
router.onMessage(async (message, context) => {
// Access Core SDK
const bots = await context.boostgpt.listBots();
// Access router config
console.log(context.config.defaultBotId);
// Platform-specific data
console.log(context.platform);
});
Command Handling
Handle specific commands:Copy
router.onMessage(async (message, context) => {
const content = message.content.toLowerCase();
// Help command
if (content === '/help' || content === 'help') {
return 'Available commands:\n/help - Show this message\n/ping - Test bot\n/info - Bot information';
}
// Ping command
if (content === '/ping') {
return 'Pong! Bot is online.';
}
// Info command
if (content === '/info') {
const bots = await context.boostgpt.listBots();
return `Running ${bots.response.length} bots`;
}
// Let AI handle everything else
return null;
});
Pattern Matching
Use regex for flexible commands:Copy
router.onMessage(async (message, context) => {
const content = message.content;
// Match /weather <city>
const weatherMatch = content.match(/^\/weather\s+(.+)/i);
if (weatherMatch) {
const city = weatherMatch[1];
return `Weather in ${city}: Sunny, 72�F`;
}
// Match /search <query>
const searchMatch = content.match(/^\/search\s+(.+)/i);
if (searchMatch) {
const query = searchMatch[1];
// Perform search...
return `Search results for: ${query}`;
}
return null;
});
User-Specific Logic
Handle users differently:Copy
const admins = ['user_123', 'user_456'];
router.onMessage(async (message, context) => {
// Admin-only commands
if (message.content === '/admin' && admins.includes(message.userId)) {
return 'Admin panel: ...';
}
// Block specific users
if (message.userId === 'blocked_user') {
return 'You are blocked from using this bot.';
}
return null;
});
Platform-Specific Handling
Copy
router.onMessage(async (message, context) => {
if (message.platform === 'discord') {
// Discord-specific logic
if (message.content === '/roles') {
return 'Discord roles: ...';
}
}
if (message.platform === 'telegram') {
// Telegram-specific logic
if (message.content === '/telegram_only') {
return 'This command only works on Telegram';
}
}
return null;
});
Rate Limiting
Implement rate limiting per user:Copy
const userLastMessage = new Map();
const RATE_LIMIT_MS = 5000; // 5 seconds
router.onMessage(async (message, context) => {
const lastTime = userLastMessage.get(message.userId);
const now = Date.now();
if (lastTime && now - lastTime < RATE_LIMIT_MS) {
return 'Please wait a few seconds before sending another message.';
}
userLastMessage.set(message.userId, now);
return null; // Continue with AI
});
Access User Session
Maintain user context:Copy
router.onMessage(async (message, context) => {
const sessionId = `${message.platform}_${message.userId}`;
const response = await context.boostgpt.chat({
bot_id: context.config.defaultBotId,
message: message.content,
session_id: sessionId,
user_id: message.userId
});
if (response.err) {
return 'Sorry, something went wrong.';
}
return response.response;
});
Error Handling
Handle errors gracefully:Copy
router.onMessage(async (message, context) => {
try {
if (message.content === '/stats') {
const bots = await context.boostgpt.listBots();
if (bots.err) {
return 'Error fetching stats. Please try again.';
}
return `You have ${bots.response.length} bots`;
}
return null;
} catch (error) {
console.error('Handler error:', error);
return 'An unexpected error occurred.';
}
});
Complete Example
Copy
import { Router, DiscordAdapter } from '@boostgpt/router';
const router = new Router({
apiKey: process.env.BOOSTGPT_API_KEY,
projectId: process.env.BOOSTGPT_PROJECT_ID,
defaultBotId: process.env.BOOSTGPT_BOT_ID,
adapters: [
new DiscordAdapter({
discordToken: process.env.DISCORD_TOKEN
})
]
});
const admins = ['admin_123'];
const userLastMessage = new Map();
router.onMessage(async (message, context) => {
// Rate limiting
const lastTime = userLastMessage.get(message.userId);
if (lastTime && Date.now() - lastTime < 3000) {
return 'Please wait before sending another message.';
}
userLastMessage.set(message.userId, Date.now());
const content = message.content.toLowerCase();
// Help command
if (content === '/help') {
return 'Commands: /help, /ping, /stats';
}
// Ping command
if (content === '/ping') {
return 'Pong!';
}
// Stats (admin only)
if (content === '/stats' && admins.includes(message.userId)) {
const bots = await context.boostgpt.listBots();
return `Bots: ${bots.response.length}`;
}
// Let AI handle everything else
return null;
});
await router.start();