Documentation Index
Fetch the complete documentation index at: https://mintlify.com/sam-ayo/recall_sdk/llms.txt
Use this file to discover all available pages before exploring further.
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