collabSupport/commands/voiceReport.js
jmcqueen 1eaabbcee1 Add /voicereport store digest and harden Webex CDR feed handling.
Groups cdr_feed legs by Correlation ID for call-level summaries, fixes report-column field parsing and Docker proxy routing, and adds /calltest post-call Twilio and CDR enrichment.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 13:43:11 -04:00

64 lines
2.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// commands/voiceReport.js
import { logger } from '../utils/logger.js';
import { collectVoiceReport } from '../services/voiceReport/voiceReportService.js';
import { renderVoiceReportMarkdown } from '../services/renderers/voiceReportRenderer.js';
function pickDateArg(args) {
for (let i = 1; i < args.length; i++) {
const a = String(args[i] || '').trim();
if (!a || a.startsWith('--')) continue;
if (/^\d{2,4}$/.test(a) && i === 1) continue;
return a;
}
const flag = args.find((a) => String(a).startsWith('--date='));
if (flag) return flag.split('=').slice(1).join('=');
const idx = args.indexOf('--date');
if (idx >= 0 && args[idx + 1]) return args[idx + 1];
return null;
}
function hasDetailFlag(args, query) {
return args.some((a) => ['detail', 'detailed', '--detail', '--detailed'].includes(String(a).toLowerCase()))
|| query.detail === 'true'
|| query.detailed === 'true';
}
export async function handleVoiceReport(bot, trigger) {
logger('voicereport', 'Handler entered', 'debug');
const query = trigger.query || {};
const args = trigger.args || [];
let storeNum = args[0]?.trim() || query.storeNum || query.store || query.s;
const dateArg = pickDateArg(args) || query.date || null;
const detail = hasDetailFlag(args, query);
if (!storeNum || !/^\d{2,4}$/.test(storeNum)) {
await bot.say(
'markdown',
'**Voice report usage**\n\n' +
'`/voicereport <store>` — yesterday 9am9pm local (default)\n' +
'`/voicereport <store> today` — today 9am → 5 min ago\n' +
'`/voicereport <store> 2026-07-22` — specific day\n' +
'`/voicereport <store> --detail` — include per-call table\n\n' +
'HTTP: `?storeNum=782&date=yesterday&detail=true`',
);
return;
}
await bot.say(
'markdown',
`**Voice report** — generating for store **${storeNum}** ` +
`(${dateArg || 'yesterday'})… This may take 13 minutes while Webex builds the Media Quality report.`,
);
try {
const report = await collectVoiceReport(storeNum, { dateArg });
const md = renderVoiceReportMarkdown(report, { detail });
await bot.say('markdown', md);
} catch (err) {
logger('voicereport', `Failed for store ${storeNum}: ${err.message}`, 'error');
await bot.say('markdown', `❌ Voice report failed for store ${storeNum}: ${err.message}`);
}
}