CityCheers AssistantHello, I am the CityCheers AI Assistant! Ask me anything about CityCheers and I will do my best to answer.
'; } else { div.innerHTML = '
CityCheers Assistant' + renderMessage(text) + '
'; } log.appendChild(div); log.scrollTop = log.scrollHeight; } function showError(msg) { if (!errorBox) return; errorBox.textContent = 'Error: ' + (msg || 'Unknown error'); errorBox.style.display = 'block'; } function hideError() { if (!errorBox) return; errorBox.style.display = 'none'; errorBox.textContent = ''; } // Hit the refresh_nonce endpoint to get a fresh token function refreshNonce() { var fd = new FormData(); fd.append('action', 'citycheers_ai_refresh_nonce'); return fetch(ajax, { method: 'POST', body: fd, credentials: 'same-origin', headers: { 'Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest' } }) .then(function(r) { return r.json(); }) .then(function(data) { if (data && data.success && data.data && data.data.nonce) { nonce = data.data.nonce; wrap.setAttribute('data-nonce', nonce); return true; } throw new Error('Could not refresh security token.'); }) .catch(function(err) { console.error('[CC-AI] refreshNonce failed:', err); return false; }); } // OPTIONAL: keep nonce fresh while support tab is open (every 20 minutes) setInterval(function() { refreshNonce(); }, 20 * 60 * 1000); form.addEventListener('submit', function(e) { e.preventDefault(); hideError(); var q = (input.value || '').trim(); if (!q) return; appendMsg('user', q); input.value = ''; var thinking = document.createElement('div'); thinking.className = 'cc-ai-msg cc-ai-msg--bot'; thinking.style.opacity = '0.8'; thinking.style.margin = '8px 0'; thinking.innerHTML = '
CityCheers AssistantThinking...
'; log.appendChild(thinking); log.scrollTop = log.scrollHeight; function sendQuery(attempt) { var fd = new FormData(); fd.append('action', 'citycheers_ai_ask'); fd.append('nonce', nonce); fd.append('question', q); return fetch(ajax, { method: 'POST', body: fd, credentials: 'same-origin', headers: { 'Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest' } }) .then(function(r) { var status = r.status; return r.text().then(function(raw) { return { status: status, raw: raw }; }); }) .then(function(result) { var status = result.status; var raw = result.raw; var data; try { data = JSON.parse(raw); } catch(e) { throw new Error('Non-JSON from server. Preview: ' + raw.slice(0,300)); } var invalid = (status === 403) || (data && data.error === 'Invalid nonce'); if (invalid && attempt === 0) { return refreshNonce().then(function(ok) { if (!ok) { if (thinking && thinking.parentNode) thinking.remove(); throw new Error('Your session has expired. Please refresh the page and try again.'); } return sendQuery(1); }); } if (invalid) { if (thinking && thinking.parentNode) thinking.remove(); throw new Error('Your session has expired. Please refresh the page and try again.'); } if (data && data.answer) { if (thinking && thinking.parentNode) thinking.remove(); appendMsg('bot', data.answer); return; } if (thinking && thinking.parentNode) thinking.remove(); throw new Error((data && data.error) || 'Unknown error'); }) .catch(function(err) { if (thinking && thinking.parentNode) thinking.remove(); showError(err.message || err); }); } sendQuery(0); }); })();
Can’t find what you’re looking for?
Call (408) 377-5100
Hours: 8am – 5pm CST • Monday – Friday