Spaces:
Sleeping
Sleeping
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"> | |
<style> | |
body { | |
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
background-color: #f4f7fb; | |
margin: 0; | |
padding: 0; | |
} | |
#chat-container { | |
max-width: 500px; | |
margin: auto; | |
padding: 25px; | |
border-radius: 15px; | |
background-color: #fff; | |
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); | |
position: relative; | |
} | |
#chat-history { | |
height: 400px; | |
overflow-y: auto; | |
padding: 15px; | |
background: linear-gradient(135deg, #f3f4f8 0%, #d3e0f0 100%); | |
border-radius: 15px; | |
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1); | |
margin-bottom: 15px; | |
} | |
.message { | |
padding: 12px 15px; | |
margin: 10px 0; | |
border-radius: 20px; | |
font-size: 0.9em; | |
line-height: 1.4em; | |
position: relative; | |
} | |
.user-message { | |
background: linear-gradient(135deg, #c9e6f5 0%, #91c9e6 100%); | |
color: #006c8e; | |
margin-left: auto; | |
border-radius: 20px 20px 0 20px; | |
} | |
.bot-message { | |
background: linear-gradient(135deg, #fce0e0 0%, #85cfb6 100%); | |
color: #8b3e40; | |
margin-right: auto; | |
border-radius: 20px 20px 20px 0; | |
} | |
.user-icon, .bot-icon { | |
margin-right: 10px; | |
font-size: 1.2em; | |
} | |
#user-input { | |
border: 1px solid #ddd; | |
border-radius: 8px; | |
resize: none; | |
padding: 12px; | |
font-size: 1em; | |
width: calc(10% - 48px); | |
} | |
#user-input:focus { | |
border-color: #007bff; | |
outline: none; | |
} | |
.btn-send, .btn-mic { | |
background-color: #007bff; | |
color: white; | |
border-radius: 8px; | |
padding: 10px 15px; | |
border: none; | |
cursor: pointer; | |
font-size: 1.1em; | |
transition: background-color 0.3s; | |
} | |
.btn-send:hover, .btn-mic:hover { | |
background-color: #0056b3; | |
} | |
#language-selector { | |
margin-bottom: 10px; | |
} | |
</style> | |
<title>Multilanguage Voice Chatbot</title> | |
</head> | |
<body> | |
<div id="chat-container"> | |
<select id="language-selector" class="form-control"> | |
<option value="en-US" selected>English</option> | |
<option value="hi-IN">हिंदी (Hindi)</option> | |
<option value="es-ES">Español (Spanish)</option> | |
<option value="fr-FR">Français (French)</option> | |
<option value="te-IN">తెలుగు (Telugu)</option> | |
<option value="ta-IN">தமிழ் (Tamil)</option> | |
<option value="kn-IN">ಕನ್ನಡ (Kannada)</option> | |
<option value="ml-IN">മലയാളം (Malayalam)</option> | |
<option value="mr-IN">मराठी (Marathi)</option> | |
<option value="gu-IN">ગુજરાતી (Gujarati)</option> | |
<option value="bn-IN">বাংলা (Bengali)</option> | |
<option value="pa-IN">ਪੰਜਾਬੀ (Punjabi)</option> | |
<option value="ur-IN">اردو (Urdu)</option> | |
<option value="zh-CN">简体中文 (Chinese Simplified)</option> | |
<option value="zh-TW">繁體中文 (Chinese Traditional)</option> | |
<option value="ja-JP">日本語 (Japanese)</option> | |
<option value="ko-KR">한국어 (Korean)</option> | |
<option value="de-DE">Deutsch (German)</option> | |
<option value="it-IT">Italiano (Italian)</option> | |
<option value="pt-PT">Português (Portuguese)</option> | |
<option value="pt-BR">Português (Brasil) (Portuguese Brazil)</option> | |
<option value="ru-RU">Русский (Russian)</option> | |
<option value="ar-SA">العربية (Arabic)</option> | |
<option value="id-ID">Bahasa Indonesia (Indonesian)</option> | |
<option value="vi-VN">Tiếng Việt (Vietnamese)</option> | |
<option value="th-TH">ไทย (Thai)</option> | |
<option value="tr-TR">Türkçe (Turkish)</option> | |
<option value="pl-PL">Polski (Polish)</option> | |
<option value="nl-NL">Nederlands (Dutch)</option> | |
<option value="sv-SE">Svenska (Swedish)</option> | |
<option value="da-DK">Dansk (Danish)</option> | |
<option value="fi-FI">Suomi (Finnish)</option> | |
<option value="no-NO">Norsk (Norwegian)</option> | |
<option value="cs-CZ">Čeština (Czech)</option> | |
<option value="hu-HU">Magyar (Hungarian)</option> | |
<option value="el-GR">Ελληνικά (Greek)</option> | |
<option value="ro-RO">Română (Romanian)</option> | |
<option value="sk-SK">Slovenčina (Slovak)</option> | |
<option value="uk-UA">Українська (Ukrainian)</option> | |
<option value="hr-HR">Hrvatski (Croatian)</option> | |
<option value="sr-RS">Српски (Serbian)</option> | |
<option value="bg-BG">Български (Bulgarian)</option> | |
<option value="lt-LT">Lietuvių (Lithuanian)</option> | |
<option value="lv-LV">Latviešu (Latvian)</option> | |
<option value="et-EE">Eesti (Estonian)</option> | |
<option value="sl-SI">Slovenščina (Slovenian)</option> | |
<option value="mt-MT">Malti (Maltese)</option> | |
<option value="sq-AL">Shqip (Albanian)</option> | |
<option value="mk-MK">Македонски (Macedonian)</option> | |
<option value="bs-BA">Bosanski (Bosnian)</option> | |
<option value="is-IS">Íslenska (Icelandic)</option> | |
</select> | |
<div id="chat-history"></div> | |
<div class="input-group"> | |
<textarea id="user-input" class="form-control" rows="1" placeholder="Type or speak your message..." aria-label="Message input"></textarea> | |
<button id="mic-button" class="btn-mic"><i class="fas fa-microphone"></i></button> | |
<button id="send-button" class="btn-send"><i class="fas fa-paper-plane"></i></button> | |
</div> | |
</div> | |
<script> | |
const chatHistoryArray = []; | |
let currentLanguage = "en-US"; // Default language | |
// Handle language selection | |
document.getElementById("language-selector").addEventListener("change", (event) => { | |
currentLanguage = event.target.value; | |
}); | |
// Add message to chat history | |
function addMessage(sender, message, className) { | |
const chatHistory = document.getElementById("chat-history"); | |
const messageElement = document.createElement("div"); | |
messageElement.className = `message ${className}`; | |
messageElement.innerHTML = `<strong>${sender}:</strong> ${message}`; | |
chatHistory.appendChild(messageElement); | |
chatHistory.scrollTop = chatHistory.scrollHeight; | |
} | |
// Send message to server | |
async function sendMessage() { | |
const input = document.getElementById("user-input"); | |
const message = input.value.trim(); | |
if (!message) return; | |
addMessage("User", message, "user-message"); | |
chatHistoryArray.push({ sender: "User", message }); | |
input.value = ""; | |
// Simulate bot typing | |
const botTyping = document.createElement("div"); | |
botTyping.className = "typing-indicator"; | |
botTyping.textContent = "Bot is typing..."; | |
document.getElementById("chat-history").appendChild(botTyping); | |
try { | |
const response = await fetch("/chat/", { | |
method: "POST", | |
headers: { "Content-Type": "application/json" }, | |
body: JSON.stringify({ message, language: currentLanguage }) | |
}); | |
const data = await response.json(); | |
botTyping.remove(); | |
const botMessage = data.response; | |
addMessage("Bot", botMessage, "bot-message"); | |
chatHistoryArray.push({ sender: "Bot", message: botMessage }); | |
if (data.audioUrl) { | |
const baseUrl = window.location.origin; // Get the base URL (e.g., http://localhost:8000) | |
const fullAudioUrl = `${baseUrl}/${data.audioUrl}`; // Append the audio URL to the base | |
playAudio(fullAudioUrl); // Pass the constructed URL to playAudio | |
} | |
} catch (error) { | |
botTyping.remove(); | |
console.error("Error:", error); | |
const errorMessage = "Sorry, something went wrong."; | |
addMessage("Bot", errorMessage, "bot-message"); | |
} | |
} | |
// Play audio from gTTS | |
// Play audio from server response | |
function playAudio(url) { | |
if (!url) { | |
console.error("Audio URL is missing."); | |
addMessage("Bot", "Error: Unable to play audio.", "bot-message"); | |
return; | |
} | |
const audio = new Audio(url); | |
audio.onerror = () => { | |
console.error("Error loading audio:", url); | |
addMessage("Bot", "Error: Unable to load audio.", "bot-message"); | |
}; | |
audio.oncanplaythrough = () => { | |
console.log("Playing audio:", url); | |
audio.play().catch((error) => { | |
console.error("Error during audio playback:", error); | |
addMessage("Bot", "Error: Unable to play audio.", "bot-message"); | |
}); | |
}; | |
audio.load(); | |
} | |
// Speech-to-Text function | |
function startListening() { | |
let recognition; | |
if (window.SpeechRecognition || window.webkitSpeechRecognition) { | |
recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)(); | |
} else { | |
alert("Your browser does not support speech recognition."); | |
return; | |
} | |
recognition.lang = currentLanguage; | |
recognition.interimResults = false; | |
recognition.onresult = (event) => { | |
const transcript = event.results[0][0].transcript; | |
document.getElementById("user-input").value = transcript; | |
sendMessage(); | |
}; | |
recognition.onerror = (event) => { | |
console.error("Speech recognition error:", event.error); | |
let errorMessage = "Sorry, I couldn't understand you."; | |
if (event.error === "not-allowed") { | |
errorMessage = "Microphone access is blocked. Please allow access."; | |
} else if (event.error === "network") { | |
errorMessage = "Network error. Please check your connection."; | |
} | |
addMessage("Bot", errorMessage, "bot-message"); | |
}; | |
recognition.start(); | |
} | |
// Event Listeners | |
document.getElementById("send-button").addEventListener("click", sendMessage); | |
document.getElementById("mic-button").addEventListener("click", startListening); | |
</script> | |
</body> | |
</html> | |