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>
73 lines
2.2 KiB
JavaScript
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;
|
|
});
|
|
}
|