(function() { const AGENT_ID = "692da0151980498cdf0f59c3"; const API_URL = "https://glav-bot.ru/api/functions"; // Persist Visitor ID let VISITOR_ID = localStorage.getItem('chat_visitor_id_' + AGENT_ID); if (!VISITOR_ID) { VISITOR_ID = 'visitor_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); localStorage.setItem('chat_visitor_id_' + AGENT_ID, VISITOR_ID); } const WIDGET_COLOR = "#0d0d0d"; const WELCOME_MESSAGE = "Привет! Как могу помочь?"; const AGENT_NAME = "Summator Support"; console.log('ChatBot Init:', { AGENT_ID, API_URL }); // Debug log let isOpen = false; let messages = []; if (document.getElementById('chatbot-widget-root')) return; const root = document.createElement('div'); root.id = 'chatbot-widget-root'; document.body.appendChild(root); const style = document.createElement('style'); style.textContent = ` #chatbot-widget-root { font-family: system-ui, -apple-system, sans-serif; } #chatbot-widget-root * { box-sizing: border-box; } #chatbot-button { position: fixed; bottom: 20px; right: 20px; width: 60px; height: 60px; border-radius: 50%; background: ${WIDGET_COLOR}; border: none; cursor: pointer; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 2147483646; display: flex; align-items: center; justify-content: center; transition: transform 0.2s; } #chatbot-button:hover { transform: scale(1.05); } #chatbot-button svg { width: 28px; height: 28px; fill: white; } #chatbot-window { position: fixed; bottom: 90px; right: 20px; width: 380px; height: 600px; max-height: calc(100vh - 110px); background: white; border-radius: 16px; box-shadow: 0 8px 32px rgba(0,0,0,0.15); display: none; flex-direction: column; z-index: 2147483647; opacity: 0; transform: translateY(20px); transition: opacity 0.3s, transform 0.3s; } #chatbot-window.open { display: flex; opacity: 1; transform: translateY(0); } #chatbot-header { background: ${WIDGET_COLOR}; color: white; padding: 16px; border-radius: 16px 16px 0 0; font-weight: 600; display: flex; justify-content: space-between; align-items: center; } #chatbot-close { background: none; border: none; color: white; cursor: pointer; opacity: 0.8; padding: 4px; } #chatbot-close:hover { opacity: 1; } #chatbot-messages { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 12px; } .message { max-width: 85%; padding: 10px 14px; font-size: 14px; line-height: 1.5; } .message.user { align-self: flex-end; background: #e5e7eb; color: #1f2937; border-radius: 16px 16px 4px 16px; } .message.assistant { align-self: flex-start; background: #f3f4f6; color: #1f2937; border-radius: 16px 16px 16px 4px; } .message.assistant strong { font-weight: 600; } .message.assistant p { margin: 0; } #chatbot-input-area { border-top: 1px solid #e5e7eb; padding: 12px; display: flex; gap: 8px; background: white; border-radius: 0 0 16px 16px; } #chatbot-input { flex: 1; border: 1px solid #e5e7eb; border-radius: 8px; padding: 10px; outline: none; font-size: 14px; transition: border-color 0.2s; } #chatbot-input:focus { border-color: ${WIDGET_COLOR}; } #chatbot-send { background: ${WIDGET_COLOR}; color: white; border: none; padding: 0 12px; border-radius: 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; } #chatbot-send:disabled { opacity: 0.5; cursor: not-allowed; } @media (max-width: 480px) { #chatbot-window { width: 100%; height: 100%; bottom: 0; right: 0; border-radius: 0; max-height: 100vh; } #chatbot-header { border-radius: 0; } #chatbot-button { bottom: 20px; right: 20px; } } `; document.head.appendChild(style); const button = document.createElement('button'); button.id = 'chatbot-button'; button.innerHTML = ''; button.onclick = toggleChat; root.appendChild(button); const chatWindow = document.createElement('div'); chatWindow.id = 'chatbot-window'; chatWindow.innerHTML = `
${AGENT_NAME}
`; root.appendChild(chatWindow); document.getElementById('chatbot-close').onclick = toggleChat; const input = document.getElementById('chatbot-input'); const sendBtn = document.getElementById('chatbot-send'); const messagesDiv = document.getElementById('chatbot-messages'); let lastMessageTimestamp = null; let pollInterval = null; // Poll for new messages async function pollMessages() { if (!isOpen) return; try { const response = await fetch(API_URL + '/getWebsiteMessages', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ agentId: AGENT_ID, visitorId: VISITOR_ID, afterTimestamp: lastMessageTimestamp }) }); const data = await response.json(); if (data.messages && data.messages.length > 0) { data.messages.forEach(msg => { // Update timestamp to latest if (!lastMessageTimestamp || new Date(msg.timestamp) > new Date(lastMessageTimestamp)) { lastMessageTimestamp = msg.timestamp; } // Message Handling Logic const msgContent = msg.content; const msgRole = msg.role; // Determine display role const displayRole = (msgRole === 'operator' || msgRole === 'assistant') ? 'assistant' : 'user'; // Check for duplicates in recent history // We compare against raw content if possible, but we only have display content in DOM/memory. // Note: We modify operator content with prefix. const isOperator = msgRole === 'operator'; const contentToCheck = isOperator ? '👮 ' + msgContent : msgContent; const isDuplicate = messages.slice(-10).some(m => m.content === contentToCheck && m.role === displayRole); if (!isDuplicate) { addMessage(displayRole, contentToCheck); } }); } } catch (e) { console.error('Poll error', e); } } function toggleChat() { isOpen = !isOpen; chatWindow.classList.toggle('open', isOpen); button.style.transform = isOpen ? 'scale(0)' : 'scale(1)'; if (isOpen) { if (messages.length === 0) { // Initial load / Welcome pollMessages().then(() => { if (messages.length === 0) addMessage('assistant', WELCOME_MESSAGE); }); } pollInterval = setInterval(pollMessages, 3000); setTimeout(() => input.focus(), 100); } else { clearInterval(pollInterval); } } function addMessage(role, content) { messages.push({ role, content }); const msgDiv = document.createElement('div'); msgDiv.className = 'message ' + role; if (role === 'assistant') { let html = content .replace(/\*\*(.+?)\*\*/g, '$1') .replace(/\n/g, '
'); msgDiv.innerHTML = html; } else { msgDiv.textContent = content; } messagesDiv.appendChild(msgDiv); messagesDiv.scrollTop = messagesDiv.scrollHeight; } async function sendMessage() { const message = input.value.trim(); if (!message) return; const externalId = 'web_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); input.value = ''; input.disabled = true; sendBtn.disabled = true; addMessage('user', message); try { const response = await fetch(API_URL + '/sendWebsiteMessage', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ agentId: AGENT_ID, visitorId: VISITOR_ID, message, externalId }) }); if (!response.ok) { let errorDetails = response.status + ' ' + response.statusText; try { const errData = await response.json(); if (errData.error) errorDetails = errData.error; } catch (e) {} throw new Error(errorDetails); } const data = await response.json(); if (data.response) { addMessage('assistant', data.response); } } catch (error) { console.error('Chat error:', error); addMessage('assistant', 'Ошибка: ' + error.message + ' (' + API_URL + ')'); } finally { input.disabled = false; sendBtn.disabled = false; input.focus(); } } sendBtn.onclick = sendMessage; input.onkeypress = (e) => { if (e.key === 'Enter') sendMessage(); }; })();