Files

59 lines
2.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 24/7 assistant widget: floating bubble, slide-up panel, /api/chat.
(function () {
const root = document.createElement('div');
root.id = 'iapChat';
root.innerHTML = '<button id="iapChatBtn" aria-label="Chat with us" type="button">💬</button>'
+ '<div id="iapChatPanel" hidden>'
+ '<div class="ch-head"><b>Ask anything</b><span class="ch-sub">Real answers, around the clock</span>'
+ '<button id="iapChatClose" aria-label="Close chat" type="button">×</button></div>'
+ '<div class="ch-msgs" id="iapChatMsgs">'
+ '<div class="ch-m bot">Hey. Ask me how the payments work, what the packages buy, or anything else. Straight answers only, no income hype.</div>'
+ '</div>'
+ '<div class="ch-input"><input id="iapChatIn" placeholder="Type your question…" maxlength="600">'
+ '<button id="iapChatSend" type="button">Send</button></div>'
+ '</div>';
document.body.appendChild(root);
const $ = id => document.getElementById(id);
const msgs = $('iapChatMsgs');
const input = $('iapChatIn');
let history = [];
const add = (text, who) => {
const d = document.createElement('div');
d.className = 'ch-m ' + who;
// linkify plain URLs
d.innerHTML = String(text).replace(/[&<>]/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' }[c]))
.replace(/(https?:\/\/[^\s]+)/g, '<a href="$1" target="_blank" rel="noopener">$1</a>');
msgs.appendChild(d);
msgs.scrollTop = msgs.scrollHeight;
return d;
};
async function send() {
const q = input.value.trim();
if (!q) return;
input.value = '';
add(q, 'me');
const wait = add('…', 'bot');
try {
const r = await (await fetch('/api/chat', { method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: q, history: history.slice(-4).join(' | ') }) })).json();
wait.remove();
add(r.reply || r.error || 'No answer came back. Try again.', 'bot');
history.push('Q: ' + q, 'A: ' + (r.reply || ''));
} catch (e) {
wait.remove();
add('Connection hiccup. Try that again.', 'bot');
}
}
$('iapChatBtn').addEventListener('click', () => {
const p = $('iapChatPanel');
p.hidden = !p.hidden;
if (!p.hidden) input.focus();
});
$('iapChatClose').addEventListener('click', () => { $('iapChatPanel').hidden = true; });
$('iapChatSend').addEventListener('click', send);
input.addEventListener('keydown', e => { if (e.key === 'Enter') send(); });
})();