collabSupport/integrations/webex/reportsCsv.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

73 lines
2.2 KiB
JavaScript

// integrations/webex/reportsCsv.js
// Pure CSV helpers for Webex Reports (no Webex client import).
export function reportDateRangeFromWindow(window) {
const startDay = String(window.startTime).slice(0, 10);
const endDay = String(window.endTime).slice(0, 10);
return { startDate: startDay, endDate: endDay };
}
function splitCsvLine(line) {
const out = [];
let cur = '';
let inQ = false;
for (let i = 0; i < line.length; i++) {
const c = line[i];
if (c === '"') {
inQ = !inQ;
continue;
}
if (c === ',' && !inQ) {
out.push(cur.trim());
cur = '';
continue;
}
cur += c;
}
out.push(cur.trim());
return out;
}
function normKey(k) {
return String(k || '').toLowerCase().replace(/[^a-z0-9]+/g, '');
}
export function parseMediaQualityCsv(text) {
if (!text || !String(text).trim()) return { headers: [], rows: [] };
const lines = String(text).split(/\r?\n/).filter((l) => l.trim());
if (!lines.length) return { headers: [], rows: [] };
const headers = splitCsvLine(lines[0]);
const rows = [];
for (let i = 1; i < lines.length; i++) {
const cols = splitCsvLine(lines[i]);
if (!cols.some(Boolean)) continue;
const row = {};
headers.forEach((h, idx) => { row[h] = cols[idx] ?? ''; });
row._norm = Object.fromEntries(
headers.map((h, idx) => [normKey(h), cols[idx] ?? '']),
);
rows.push(row);
}
return { headers, rows };
}
export function filterMediaQualityRows(rows, { locationName, window }) {
const loc = String(locationName || '').toLowerCase();
const startMs = new Date(window.startTime).getTime();
const endMs = new Date(window.endTime).getTime();
return (rows || []).filter((row) => {
const n = row._norm || {};
const rowLoc = String(
n.location || n.sitelocation || n.sitename || row.Location || '',
).toLowerCase();
if (loc && rowLoc && !rowLoc.includes(loc) && !loc.includes(rowLoc)) {
return false;
}
const startRaw = n.starttime || n.callstarttime || n.start || row['Start Time'] || '';
if (!startRaw) return true;
const t = new Date(startRaw).getTime();
if (!Number.isFinite(t)) return true;
return t >= startMs && t <= endMs;
});
}