Your 24/7 Arlington & DFW Mobile Service Provider

¡Si habla español!

Choctaw Stadium, Suite 310 | (972) 850-6982 | Parking & Directions

SAVE TIME & MONEY: BOOK ONLINE INSTANTLY! BOOK NOW!

Your 24/7 Arlington & DFW Mobile Service Provider

¡Si habla español!

Choctaw Stadium, Suite 310 | (972) 850-6982 | Parking

Book Online, Save Time
in comments.) try { var phrases = [ 'Or for same-origin deployment', 'Gracie Chat Widget', 'Prevent double-loading', 'Get API base URL', 'gracieWidgetLoaded', 'apiBase', 'chatEndpoint', 'Gracie is thinking' ]; var pattern = /(\*+\s*)?Or for same-origin deployment|Gracie Chat Widget|gracieWidgetLoaded|chatEndpoint|apiBase/i; var root = document.documentElement || document.body; var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null); var toRemove = []; while (walker.nextNode()) { var node = walker.currentNode; var text = (node.nodeValue || '').trim(); if (!text) continue; var matched = false; for (var i = 0; i < phrases.length; i++) { if (text.indexOf(phrases[i]) !== -1) { matched = true; break; } } if (!matched && pattern.test(text)) matched = true; if (matched) toRemove.push(node); } // Also scrub any element nodes that contain the leaked script text var elements = (root || document).querySelectorAll ? (root || document).querySelectorAll('pre, code, div, p, span') : []; for (var j = 0; j < elements.length; j++) { var el = elements[j]; var t = (el && el.textContent) ? el.textContent : ''; if (t && pattern.test(t)) { el.textContent = ''; } } toRemove.forEach(function(n) { if (n && n.parentNode) n.parentNode.removeChild(n); }); // If leaked text is outside , try to remove from document child nodes. var topNodes = document.childNodes || []; for (var k = 0; k < topNodes.length; k++) { var tn = topNodes[k]; if (tn && tn.nodeType === 3 && pattern.test(String(tn.nodeValue || ''))) { document.removeChild(tn); } } } catch (e) { // non-fatal } // Create widget HTML var widget = document.createElement('div'); widget.id = 'gracie-widget'; widget.innerHTML = `
Just Doing Business LLC
Hi there! Welcome to Just Doing Business. I'm Gracie - how can I help you today?
`; document.body.appendChild(widget); // Get elements var toggleBtn = document.getElementById('gracie-toggle'); var closeBtn = document.getElementById('gracie-close'); var messagesDiv = document.getElementById('gracie-messages'); var inputField = document.getElementById('gracie-input'); var sendBtn = document.getElementById('gracie-send'); // FIX 2026-02-11: Generate persistent session ID // This ensures conversation state is maintained across messages function getSessionId() { var stored = sessionStorage.getItem('gracie_session_id'); if (stored) return stored; // Generate new session ID (timestamp + random for uniqueness) var newId = 'widget_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); sessionStorage.setItem('gracie_session_id', newId); console.log('[Gracie Widget] New session:', newId); return newId; } var sessionId = getSessionId(); // Open/close handlers toggleBtn.onclick = function() { widget.classList.add('open'); inputField.focus(); }; closeBtn.onclick = function() { widget.classList.remove('open'); }; // Add message to chat function addMessage(text, type) { var msg = document.createElement('div'); msg.className = 'gracie-msg ' + type; msg.textContent = text; messagesDiv.appendChild(msg); messagesDiv.scrollTop = messagesDiv.scrollHeight; return msg; } function addTypingIndicator() { var msg = document.createElement('div'); msg.className = 'gracie-msg agent typing'; msg.innerHTML = 'Gracie is thinking '; messagesDiv.appendChild(msg); messagesDiv.scrollTop = messagesDiv.scrollHeight; return msg; } // Send message var isSending = false; async function sendMessage() { var text = inputField.value.trim(); if (!text || isSending) return; isSending = true; sendBtn.disabled = true; inputField.value = ''; // Add user message addMessage(text, 'user'); // Add typing indicator var typingMsg = addTypingIndicator(); var typingStart = Date.now(); var minTypingMs = 350; try { var response = await fetch(chatEndpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'ngrok-skip-browser-warning': 'true' }, body: JSON.stringify({ message: text, user: sessionId, // FIX 2026-02-11: Use persistent session ID source: window.location.hostname || 'widget' }) }); if (!response.ok) { throw new Error('Server returned ' + response.status); } var data = await response.json(); // Remove typing indicator var elapsed = Date.now() - typingStart; var waitMs = Math.max(0, minTypingMs - elapsed); setTimeout(function() { typingMsg.remove(); }, waitMs); // Add agent response var agentText = data.response || 'Sorry, I could not process that. Please try again.'; addMessage(agentText, 'agent'); } catch (error) { console.error('[Gracie Widget] Error:', error); // Remove typing indicator var elapsed = Date.now() - typingStart; var waitMs = Math.max(0, minTypingMs - elapsed); setTimeout(function() { typingMsg.remove(); }, waitMs); // Show error message addMessage('Connection error. Please call us at (972) 850-6982', 'agent'); } isSending = false; sendBtn.disabled = false; inputField.focus(); } // Event listeners sendBtn.onclick = sendMessage; inputField.onkeydown = function(e) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }; console.log('[Gracie Widget] Loaded successfully'); })();

Leave a Reply

Your email address will not be published. Required fields are marked *