/** * Split a markdown report into Webex-message-sized chunks. * * Webex caps message bodies at ~7439 chars; we round down to 7000 to leave * headroom for the bot framework and any wrapping the client may add. * * Strategy: * 1. If the whole report fits, return it as a single chunk. * 2. Otherwise, prefer breaking on section boundaries (`\n\n` immediately * followed by `**`, which is how every section header in our reports is * delimited). This keeps markdown intact across chunks. * 3. If a single section is itself larger than the limit, fall back to a * hard slice on the limit so we never lose data. */ const DEFAULT_LIMIT = 7000; function chunkReport(report, maxLen = DEFAULT_LIMIT) { if (!report) return []; const trimmed = report.trim(); if (trimmed.length <= maxLen) return [trimmed]; // Split on `\n\n**` but keep the `**` (consume only the leading `\n\n`). const sections = trimmed.split(/\n\n(?=\*\*)/); const sectionChunks = []; let current = ''; for (const section of sections) { const candidate = current ? `${current}\n\n${section}` : section; if (candidate.length > maxLen && current) { sectionChunks.push(current); current = section; } else { current = candidate; } } if (current) sectionChunks.push(current); // Hard-split any chunk still over the limit (rare — only happens if one // section by itself exceeds maxLen, e.g. a store with hundreds of clients). const finalChunks = []; for (const c of sectionChunks) { if (c.length <= maxLen) { finalChunks.push(c); } else { for (let i = 0; i < c.length; i += maxLen) { finalChunks.push(c.slice(i, i + maxLen)); } } } return finalChunks; } module.exports = { chunkReport, DEFAULT_LIMIT };