PageSourceSearch

https://teddingtontown.co.uk/wp-content/themes/ColorMagChild/js/chatbot.js?ver=1789021355

js teddingtontown.co.uk collected 2026-10-02 14:43:13 UTC 6,748 bytes, 176 lines download raw bytes

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.