Retrieves detailed logs of the bot’s activity during the meeting lifecycle. Useful for debugging issues and understanding bot behavior.
Method Signature
bot.getBotLogs(params: BaseBotParams): Promise<BotLogs>
Parameters
The unique identifier of the bot
Response
Returns an array of log entries:
Array of log entry objectsISO 8601 timestamp when the log entry was created
Log level: “info”, “warning”, “error”, or “debug”
Log message describing the event
Type of event (e.g., “bot_joining”, “recording_started”, “error_occurred”)
Additional context and details about the event
Example
import { Recall } from '@recall.ai/sdk';
const client = new Recall({
apiKey: 'your-api-key',
region: 'us-west-2'
});
// Get bot logs
const logs = await client.bot.getBotLogs({
id: 'bot_1234567890'
});
console.log(`Total log entries: ${logs.logs.length}`);
for (const log of logs.logs) {
console.log(`[${log.timestamp}] ${log.level.toUpperCase()}: ${log.message}`);
}
Example: Filter Errors
async function getErrors(botId: string) {
const logs = await client.bot.getBotLogs({ id: botId });
const errors = logs.logs.filter(log => log.level === 'error');
if (errors.length === 0) {
console.log('No errors found');
return [];
}
console.log(`Found ${errors.length} error(s):`);
for (const error of errors) {
console.log(`\n[${error.timestamp}]`);
console.log(`Event: ${error.event_type}`);
console.log(`Message: ${error.message}`);
if (error.details) {
console.log('Details:', JSON.stringify(error.details, null, 2));
}
}
return errors;
}
await getErrors('bot_1234567890');
Example: Track Bot Progress
async function trackBotProgress(botId: string) {
const logs = await client.bot.getBotLogs({ id: botId });
const milestones = logs.logs.filter(log =>
['bot_created', 'bot_joining', 'bot_joined', 'recording_started',
'recording_stopped', 'bot_left', 'processing_complete'].includes(log.event_type)
);
console.log('Bot Lifecycle Timeline:');
console.log('='.repeat(50));
for (const milestone of milestones) {
const time = new Date(milestone.timestamp).toLocaleTimeString();
console.log(`${time} - ${milestone.message}`);
}
}
await trackBotProgress('bot_1234567890');
Example: Debug Bot Issues
async function debugBot(botId: string) {
const bot = await client.bot.retrieve({ id: botId });
const logs = await client.bot.getBotLogs({ id: botId });
console.log('Bot Debug Information');
console.log('='.repeat(50));
console.log(`Bot ID: ${bot.id}`);
console.log(`Status: ${bot.status}`);
console.log(`Platform: ${bot.meeting_url.platform}`);
console.log(`\nRecent Logs (last 10):`);
const recentLogs = logs.logs.slice(-10);
for (const log of recentLogs) {
const time = new Date(log.timestamp).toLocaleTimeString();
const level = log.level.toUpperCase().padEnd(7);
console.log(`${time} [${level}] ${log.message}`);
}
// Check for common issues
const hasErrors = logs.logs.some(log => log.level === 'error');
const hasPermissionDenied = logs.logs.some(log =>
log.message.includes('permission') && log.message.includes('denied')
);
console.log('\nDiagnostics:');
if (hasErrors) {
console.log('⚠️ Errors detected - see error logs above');
}
if (hasPermissionDenied) {
console.log('⚠️ Recording permission was denied');
}
if (!hasErrors && !hasPermissionDenied) {
console.log('✓ No obvious issues detected');
}
}
await debugBot('bot_1234567890');
Example: Export Logs to File
import { writeFile } from 'fs/promises';
async function exportLogs(botId: string, filename: string) {
const logs = await client.bot.getBotLogs({ id: botId });
let content = `Bot Logs - ${botId}\n`;
content += '='.repeat(80) + '\n\n';
for (const log of logs.logs) {
content += `[${log.timestamp}] ${log.level.toUpperCase()}\n`;
content += `Event: ${log.event_type}\n`;
content += `Message: ${log.message}\n`;
if (log.details) {
content += `Details: ${JSON.stringify(log.details)}\n`;
}
content += '\n';
}
await writeFile(filename, content);
console.log(`Logs exported to ${filename}`);
}
await exportLogs('bot_1234567890', 'bot-logs.txt');
Example: Monitor Bot in Real-time
async function monitorBot(botId: string, intervalSeconds: number = 10) {
let lastLogCount = 0;
const checkLogs = async () => {
const logs = await client.bot.getBotLogs({ id: botId });
const bot = await client.bot.retrieve({ id: botId });
if (logs.logs.length > lastLogCount) {
const newLogs = logs.logs.slice(lastLogCount);
for (const log of newLogs) {
const time = new Date(log.timestamp).toLocaleTimeString();
console.log(`[${time}] ${log.message}`);
}
lastLogCount = logs.logs.length;
}
if (['done', 'fatal', 'media_expired'].includes(bot.status)) {
console.log(`\nBot reached final status: ${bot.status}`);
clearInterval(interval);
}
};
console.log(`Monitoring bot ${botId}...`);
const interval = setInterval(checkLogs, intervalSeconds * 1000);
await checkLogs(); // Initial check
}
await monitorBot('bot_1234567890', 5);
Notes
- Logs are continuously updated as the bot progresses through its lifecycle
- Logs are retained for a limited time after the meeting ends
- Use logs for debugging issues like permission denials, connection problems, or unexpected behavior
- Error-level logs indicate issues that prevented the bot from functioning normally