
The Always-On Contact Centre Scorecard
A strategic guide to AI solutions and automation.
This is some text inside of a div block.
This is some text inside of a div block.
AI
Customers increasingly expect to access support at any time of day, across voice and digital channels. But increasing headcount to cover 24/7 expectations isn't a sustainable model for most contact centres operating on tight margins.
However, an “always-on” contact centre doesn’t mean staffing agents around the clock.
It’s about using AI and automation to absorb predictable demand across inbound and outbound without the need for a live agent. This allows human agents to step away from repetitive tasks and focus on complex, high-judgment conversations where they bring the most value.
(() => {
const WORDS_PER_MINUTE = 200;
const MULTIPLIER = 1; // your choice
const estimateMinutes = (el) => {
if (!el) return null;
const text = (el.innerText || el.textContent || "").trim();
if (!text) return 1;
const words = (text.match(/\S+/g) || []).length;
const baseMinutes = Math.max(1, Math.ceil(words / WORDS_PER_MINUTE));
return Math.max(1, Math.ceil(baseMinutes * MULTIPLIER));
};
const findNearestTargetInItem = (itemRoot, rt) => {
if (!itemRoot) return null;
return itemRoot.querySelector('[data="read-time"]');
};
const applyWithin = (root) => {
root.querySelectorAll('[data-rich-text], [data-rich-text="true"]').forEach((rt) => {
const itemRoot =
rt.closest('[role="listitem"]') ||
rt.closest('.w-dyn-item') ||
rt.parentElement ||
root;
const target = findNearestTargetInItem(itemRoot, rt);
if (!target) return;
const mins = estimateMinutes(rt);
if (mins != null) {
target.textContent = `${mins} MIN READ`;
target.classList.toggle('toggle-opacity');
}
});
};
const init = () => {
applyWithin(document);
// Re-apply on dynamic changes (pagination/filters)
const mo = new MutationObserver((mutations) => {
for (const m of mutations) {
for (const n of m.addedNodes) {
if (!(n instanceof Element)) continue;
if (
n.matches('[data-rich-text], [data-rich-text="true"], [role="list"], .w-dyn-items, .w-dyn-item') ||
n.querySelector?.('[data-rich-text], [data-rich-text="true"]')
) {
applyWithin(n);
}
}
}
});
mo.observe(document.body, { childList: true, subtree: true });
};
// Robust bootstrapping
if (window.Webflow && Array.isArray(window.Webflow)) {
window.Webflow.push(init);
} else if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init, { once: true });
} else {
init();
}
})();