// src/commands/vcMonitor.js // Thin handler for /vcMonitor [start|stop|status] [Full|Limited|...] // First iteration: on-demand start of packet capture via cloud xAPI ExtendedLogging. import { startPacketCapture, stopPacketCapture, getExtendedLoggingStatus } from '../services/vcMonitorService.js'; import { logger } from '../utils/logger.js'; export async function handleVcMonitor(bot, trigger) { logger('vc-monitor', 'Handler entered'); const args = trigger.args || []; const query = trigger.query || {}; const serialNumber = args[0]?.trim() || query.serial || query.serialNumber || query.s || query.serialnum; if (!serialNumber) { logger('vc-monitor', 'No serial number provided – showing usage', 'warn'); await bot.say('markdown', '**Usage:** `/vcMonitor [action] [PacketDumpType]`\n\n' + 'Actions (default = start):\n' + '• `start` (or omit) — begin capture\n' + '• `stop` — stop the current extended logging session\n' + '• `status` — show current Logging.ExtendedLogging.Mode + PacketDump\n\n' + 'PacketDumpType (only for start):\n' + '• `Full` — everything including RTP media (~3 min)\n' + '• `Limited` — non-RTP/signaling only (~10 min)\n' + '• `FullRotate` — rolling capture (last ~1h worth)\n\n' + 'Examples:\n' + '• `/vcMonitor FOC2419NTN2` — start Full capture (on demand)\n' + '• `/vcMonitor FOC2419NTN2 Limited`\n' + '• `/vcMonitor FOC2419NTN2 stop`\n' + '• `/vcMonitor FOC2419NTN2 status`\n\n' + '**After capture:** Download the full log bundle from Control Hub (Issues & Diagnostics → System Logs). The .pcap files are inside the bundle.' ); return; } // Parse action + optional dump type let action = (args[1] || query.action || 'start').toLowerCase().trim(); let dumpType = args[2] || query.type || query.packetDump || query.dump || 'Full'; // Convenience: allow `/vcMonitor SERIAL Full` to mean start Full if (['full', 'limited', 'fullrotate', 'none'].includes(action)) { dumpType = action; action = 'start'; } logger('vc-monitor', `Command for ${serialNumber}: action=${action} dumpType=${dumpType}`); try { if (action === 'start' || action === 'begin' || action === 'capture') { await startPacketCapture(bot, serialNumber, dumpType); } else if (action === 'stop' || action === 'end') { await stopPacketCapture(bot, serialNumber); } else if (action === 'status' || action === 'show' || action === 'state') { await getExtendedLoggingStatus(bot, serialNumber); } else { await bot.say('markdown', `Unknown action "${action}". Supported: start, stop, status.\n\n` + `Example: \`/vcMonitor ${serialNumber} start Full\`` ); } } catch (error) { // Service already sent user-facing error + logged. Just make sure we don't crash the handler. logger('vc-monitor', `Handler caught error for ${serialNumber}/${action}: ${error.message}`, 'error'); } }