1document.addEventListener("DOMContentLoaded", function () { 2 // Inject Chatbot HTML and Button into Footer 3 const chatbotContainer = document.createElement("div"); 4 chatbotContainer.innerHTML = ` 5 <button id="chatbotToggle" style="position: fixed; bottom: 20px; right: 20px; padding: 10px 15px; background: #0073aa; color: white; border: none; border-radius: 5px; cursor: pointer;">I am Bot</button> 6 <div id="chatContainer" style="display: none; position: fixed; bottom: 70px; right: 20px; width: 300px; border: 1px solid #ccc; border-radius: 5px; background: #fff; box-shadow: 0 2px 10px rgba(0,0,0,0.1);"> 7 <div id="chatMessages" style="height: 250px; overflow-y: auto; padding: 10px; border-bottom: 1px solid #ddd;"></div> 8 <form id="chatForm" style="display: flex; padding: 10px;"> 9 <input type="text" id="chatInput" placeholder="Type your message..." required style="flex: 1; padding: 5px; border: 1px solid #ccc; border-radius: 3px;"> 10 <button type="submit" style="margin-left: 5px; padding: 5px 10px; background: #0073aa; color: white; border: none; border-radius: 3px;">Send</button> 11 </form> 12 </div> 13 `; 14 document.body.appendChild(chatbotContainer); 15 16 // Variables 17 const chatForm = document.getElementById("chatForm"); 18 const inputField = document.getElementById("chatInput"); 19 const chatMessages = document.getElementById("chatMessages"); 20 const chatContainer = document.getElementById("chatContainer"); 21 const chatbotToggle = document.getElementById("chatbotToggle"); 22 23 let userName = ""; 24 let botStarted = false; // Track if the welcome message sequence has started 25 26 // Predefined Responses 27 const responses = { 28 "service": "Check our services here: <a href='https://teddingtontown.co.uk/estate-agents/' target='_blank'>Estate Agents</a>", 29 "contact": "You can contact us at: [email protected], 0981234567 or visit <a href='https://teddingtontown.co.uk/advertise-with-us/' target='_blank'>this page</a>.", 30 "advertise": "For advertising, contact [email protected] or visit <a href='https://teddingtontown.co.uk/advertise-with-us/' target='_blank'>this page</a>." 31 }; 32 33 // Toggle Chatbot Visibility 34 chatbotToggle.addEventListener("click", function () { 35 chatContainer.style.display = chatContainer.style.display === "none" ? "block" : "none"; 36 37 // Start welcome messages if not already started 38 if (!botStarted) { 39 botStarted = true; 40 startWelcomeSequence(); 41 } 42 }); 43 44 45 function showTypingIndicator(callback) { 46 // Remove any existing typing indicators to prevent duplicates 47 const existingIndicator = document.getElementById("typingIndicator"); 48 if (existingIndicator) { 49 existingIndicator.remove(); 50 } 51 52 // Create new typing indicator 53 const typingDiv = document.createElement("div"); 54 typingDiv.id = "typingIndicator"; // Unique ID to prevent duplicates 55 typingDiv.textContent = "Bot is typing..."; 56 typingDiv.style.fontStyle = "italic"; 57 chatMessages.appendChild(typingDiv); 58 chatMessages.scrollTop = chatMessages.scrollHeight; 59 60 setTimeout(() => { 61 typingDiv.remove(); // Remove the indicator after the delay 62 callback(); 63 }, 1000); // Typing delay (1s) 64 } 65 66 67 68 69 // Add Messages with Delay 70 function addMessage(text, isHTML = false) { 71 showTypingIndicator(() => { 72 const messageDiv = document.createElement("div"); 73 messageDiv.style.padding = "5px"; 74 75 if (isHTML) { 76 messageDiv.innerHTML = text; 77 } else { 78 messageDiv.textContent = text; 79 } 80 81 chatMessages.appendChild(messageDiv); 82 chatMessages.scrollTop = chatMessages.scrollHeight; 83 }); 84 } 85 86 // Extract Name Smartly 87 function extractName(userInput) { 88 userInput = userInput.toLowerCase(); 89 90 if (userInput.split(" ").length === 1) { 91 return capitalizeFirstLetter(userInput); 92 } 93 94 if (userInput.includes("my name is")) { 95 let nameParts = userInput.split("my name is"); 96 let name = nameParts[1].trim().split(" ")[0]; 97 return capitalizeFirstLetter(name); 98 } 99 100 return null; 101 } 102 103 // Capitalize first letter of name 104 function capitalizeFirstLetter(string) { 105 return string.charAt(0).toUpperCase() + string.slice(1); 106 } 107 108 // Handle User Messages 109 chatForm.addEventListener("submit", function (event) { 110 event.preventDefault(); 111 handleUserMessage(); 112 }); 113 114function handleUserMessage() { 115 const message = inputField.value.trim(); 116 if (!message) return; 117 118 addMessage("You: " + message); 119 inputField.value = ""; 120 121 if (!userName) { 122 let extractedName = extractName(message); 123 if (extractedName) { 124 userName = extractedName; 125 addMessage(`Bot: Nice to meet you, ${userName}!`); 126 setTimeout(() => { 127 addMessage("Bot: How can I help you?"); 128 }, 1000); 129 } else { 130 addMessage("Bot: Sorry, I didn't catch your name. Can you say it again?"); 131 } 132 return; 133 } 134 135 // Match keywords within message 136 let botResponse = null; 137 for (let keyword in responses) { 138 if (message.toLowerCase().includes(keyword)) { 139 botResponse = `Bot: ${responses[keyword]}`; 140 break; 141 } 142 } 143 144 if (botResponse) { 145 addMessage(botResponse, true); 146 } else { 147 // If no predefined response, search WordPress posts/pages 148 showTypingIndicator(() => { 149 fetch(chatbotAjax.ajaxurl, { 150 method: "POST", 151 headers: { "Content-Type": "application/x-www-form-urlencoded" }, 152 body: `action=chatbot_search_query&message=${encodeURIComponent(message)}` 153 }) 154 .then(response => response.json()) 155 .then(data => { 156 if (data.success) { 157 addMessage(`Bot: ${data.data.response}`, true); 158 } else { 159 addMessage("Bot: Sorry, something went wrong."); 160 } 161 }) 162 .catch(() => addMessage("Bot: Sorry, something went wrong.")); 163 }); 164 } 165} 166 167 168 169 // Welcome Message Sequence 170 function startWelcomeSequence() { 171 setTimeout(() => addMessage("Bot: Hello, Welcome to Teddington, Middlesex, UK."), 500); 172 setTimeout(() => addMessage("Bot: A local website for local people."), 1500); 173 setTimeout(() => addMessage("Bot: My name is Bot."), 2500); 174 setTimeout(() =>
174 addMessage("Bot: May I know your name?"), 3500); 175 } 176});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.