Dixith/pamgolding-bot
0
1const chatbotToggler = document.querySelector(".chatbot-toggler");2const closeBtn = document.querySelector(".close-btn");3const chatbox = document.querySelector(".chatbox");4const chatInput = document.querySelector(".chat-input textarea");5const sendChatBtn = document.querySelector(".chat-input span");6const microphoneBtn = document.getElementById('microphone-btn');7 8let userMessage = null;9const inputInitHeight = chatInput.scrollHeight;10 11// Function to get or create a unique user ID12function getUserId() {13 let userId = localStorage.getItem('userId');14 if (!userId) {15 userId = 'user_' + Math.random().toString(36).substr(2, 9);16 localStorage.setItem('userId', userId);17 }18 return userId;19}20 21function linkify(inputText) {22 var replacedText, replacePattern1, replacePattern2, replacePattern3;23 24 // URLs starting with http://, https://, or ftp://25 replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;26 replacedText = inputText.replace(replacePattern1, (match) => {27 // Exception for the Calendly link28 if (match === "https://calendly.com/dixith_mediga/30min") {29 // If you want to keep it as plain text or handle it differently30 return match; // Just return the match without linking it31 // Or, if you need to handle it differently, adjust this return statement accordingly32 }33 else if (match.match(/\.(jpeg|jpg|gif|png)$/) != null) {34 return `<img src="${match}" alt="Image" style="max-width:100%;height:auto;">`;35 } else {36 return `<a href="${match}" target="_blank">here</a>`;37 }38 });39 40 // URLs starting with "www."41 replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;42 replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" target="_blank">$2</a>');43 44 // Change email addresses to mailto:: links.45 replacePattern3 = /(([a-zA-Z0-9\-_.])+@[a-zA-Z0-9\-_.]+\.[a-zA-Z]{2,5})/gim;46 replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>');47 48 return replacedText;49}50 51 52const createChatLi = (message, className) => {53 const chatLi = document.createElement("li");54 chatLi.classList.add("chat", className);55 let chatContent = className === "outgoing" ? 56 `<p>${message}</p>` : 57 `<span class="material-symbols-outlined">smart_toy</span><p>${linkify(message)}</p>`;58 chatLi.innerHTML = chatContent;59 return chatLi;60};61 62const generateResponse = (chatElement, typingInterval) => {63 const SERVER_URL = "https://dixith-pamgolding-bot.hf.space//get-response";64 const userId = getUserId();65 66 fetch(SERVER_URL, {67 method: "POST",68 headers: {69 "Content-Type": "application/json"70 },71 body: JSON.stringify({ 72 message: userMessage,73 user_id: userId74 })75 })76 .then(res => res.json())77 .then(data => {78 clearInterval(typingInterval); // Make sure to clear the typing animation79 const incomingChatLi = createChatLi(data.response, "incoming"); // Create a new chat bubble for the response80 chatbox.replaceChild(incomingChatLi, chatElement); // Replace the "Typing..." bubble with the response bubble81 chatbox.scrollTo(0, chatbox.scrollHeight); // Scroll to the new message82 })83 .catch((error) => {84 clearInterval(typingInterval); // Also clear the typing animation in case of error85 console.error('Error:', error);86 chatElement.querySelector("p").textContent = "Oops! Something went wrong. Please try again.";87 });88}89 90 91 92 93 94const handleSend = () => {95 userMessage = chatInput.value.trim();96 if (!userMessage) return;97 98 const outgoingChatLi = createChatLi(userMessage, "outgoing");99 chatbox.appendChild(outgoingChatLi);100 chatbox.scrollTo(0, chatbox.scrollHeight);101 chatInput.value = "";102 chatInput.style.height = `${inputInitHeight}px`;103 104 setTimeout(() => {105 const incomingChatLi = createChatLi("Typing.", "incoming");106 chatbox.appendChild(incomingChatLi);107 chatbox.scrollTo(0, chatbox.scrollHeight);108 109 let dotCount = 1;110 const typingInterval = setInterval(() => {111 incomingChatLi.innerHTML = `<span class="material-symbols-outlined">smart_toy</span><p>Typing${'.'.repeat(dotCount)}</p>`;112 dotCount = (dotCount % 6) + 1; // Cycle dotCount from 1 to 6113 }, 500);114 115 generateResponse(incomingChatLi, typingInterval); // Pass the typingInterval to the generateResponse function116 }, 600);117};118 119 120function updateTypingMessage(message) {121 const typingElements = document.getElementsByClassName('typing');122 if(typingElements.length > 0) {123 // Assuming there's only one typing element at a time124 typingElements[0].innerText = message;125 } else {126 // Create new typing element if it doesn't exist127 const incomingChatLi = createChatLi(message, "incoming");128 chatbox.appendChild(incomingChatLi);129 chatbox.scrollTo(0, chatbox.scrollHeight);130 }131}132 133chatInput.addEventListener("input", () => {134 chatInput.style.height = "auto";135 chatInput.style.height = `${chatInput.scrollHeight}px`;136});137 138chatInput.addEventListener("keydown", (e) => {139 if (e.key === "Enter" && !e.shiftKey) {140 e.preventDefault(); // Prevent the default action to avoid a newline141 handleSend(); // Call the send handler142 }143});144 145sendChatBtn.addEventListener("click", handleSend);146closeBtn.addEventListener("click", () => document.body.classList.remove("show-chatbot"));147chatbotToggler.addEventListener("click", () => document.body.classList.toggle("show-chatbot"));148 149 150// Enhanced Speech Recognition setup151const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();152recognition.continuous = false;153recognition.lang = 'en-US';154recognition.interimResults = false;155recognition.maxAlternatives = 1;156 157let isSpeechDetected = false;158let recognitionTimeout;159 160function updateMicrophoneIcon(isListening) {161 if (isListening) {162 microphoneBtn.classList.add('listening');163 } else {164 microphoneBtn.classList.remove('listening');165 }166}167 168recognition.onstart = function() {169 console.log('Voice recognition activated. Start speaking.');170 updateMicrophoneIcon(true);171 clearTimeout(recognitionTimeout);172 isSpeechDetected = false;173};174 175recognition.onspeechend = function() {176 setTimeout(() => {177 recognition.stop();178 if (!isSpeechDetected) {179 chatbox.appendChild(createChatLi("No speech detected. Please try again.", "incoming"));180 }181 }, 2000 + Math.random() * 2000); // Random delay between 2 to 4 seconds182};183 184recognition.onresult = function(event) {185 isSpeechDetected = true;186 const transcript = event.results[0][0].transcript;187 chatInput.value = transcript;188 updateMicrophoneIcon(false);189 handleChat();190};191 192recognition.onerror = function(event) {193 console.error('Speech recognition error detected: ' + event.error);194 updateMicrophoneIcon(false);195 chatbox.appendChild(createChatLi(`Error in speech recognition: ${event.error}`, "incoming"));196};197 198microphoneBtn.addEventListener('click', function() {199 if (microphoneBtn.classList.contains('listening')) {200 recognition.stop();201 } else {202 recognition.start();203 recognitionTimeout = setTimeout(() => {204 if (!isSpeechDetected) {205 recognition.stop();206 updateMicrophoneIcon(false);207 chatbox.appendChild(createChatLi("No speech detected. Please try again.", "incoming"));208 }209 }, 12000); // Adjusted total time to 12 seconds (10 seconds listening + up to 2 seconds delay)210 }211});