<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Your Website</title>
<style>
.chat-widget {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 9999;
font-family: Arial, sans-serif;
}
.chat-toggle {
width: 60px;
height: 60px;
border-radius: 50%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
cursor: pointer;
color: white;
font-size: 24px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
}
.chat-toggle:hover {
transform: scale(1.1);
}
.chat-container {
position: fixed;
bottom: 100px;
right: 20px;
width: 350px;
height: 500px;
background: white;
border-radius: 12px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
display: none;
flex-direction: column;
}
.chat-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 15px;
border-radius: 12px 12px 0 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.chat-messages {
flex: 1;
padding: 15px;
overflow-y: auto;
max-height: 350px;
}
.message {
margin-bottom: 10px;
padding: 10px;
border-radius: 8px;
max-width: 80%;
}
.user-message {
background: #e3f2fd;
margin-left: auto;
text-align: right;
}
.bot-message {
background: #f5f5f5;
}
.chat-input {
padding: 15px;
border-top: 1px solid #eee;
}
.chat-input input {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 20px;
outline: none;
}
.chat-input input:focus {
border-color: #667eea;
}
.close-btn {
background: none;
border: none;
color: white;
cursor: pointer;
font-size: 18px;
}
.mic-button {
background: #667eea;
color: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
cursor: pointer;
margin-left: 10px;
}
.input-container {
display: flex;
align-items: center;
}
</style>
</head>
<body>
<h1>Welcome to Your Website</h1>
<p>This is where your content goes. The chatbot will appear as a floating widget.</p>
<div class="chat-widget">
<button class="chat-toggle" onclick="toggleChat()">💬</button>
<div class="chat-container" id="chatContainer">
<div class="chat-header">
<span>Fitness Coach</span>
<button class="close-btn" onclick="toggleChat()">✕</button>
</div>
<div class="chat-messages" id="chatMessages">
<div class="message bot-message">Hey champion! 💪 Ready to crush your fitness goals today? Let's get moving!</div>
</div>
<div class="chat-input">
<div class="input-container">
<input type="text" id="messageInput" placeholder="Type your message..." onkeypress="handleKeyPress(event)">
<button class="mic-button" id="micButton" onclick="toggleVoice()">🎤</button>
</div>
</div>
</div>
</div>
<script>
const CONFIG = {
GEMINI_API_KEY: 'YOUR_GEMINI_API_KEY_HERE',
MURF_API_KEY: 'YOUR_MURF_API_KEY_HERE',
AGENT_NAME: 'Fitness Coach',
SYSTEM_PROMPT: 'You are an energetic and motivational fitness coach. You provide workout advice, nutrition tips, and keep people motivated on their fitness journey. You're encouraging but also realistic about goals.',
VOICE_ID: 'en-US-ken',
AUTO_MODE: true,
SILENCE_TIMEOUT: 1000,
};
let isOpen = false;
let isListening = false;
let recognition = null;
let silenceTimeout = null;
const chatContainer = document.getElementById('chatContainer');
const chatMessages = document.getElementById('chatMessages');
const messageInput = document.getElementById('messageInput');
const micButton = document.getElementById('micButton');
const toggleButton = document.querySelector('.chat-toggle');
document.addEventListener('DOMContentLoaded', function() {
setTimeout(() => {
toggleChat();
}, 3000);
initializeSpeechRecognition();
});
function toggleChat() {
isOpen = !isOpen;
if (isOpen) {
chatContainer.style.display = 'flex';
toggleButton.innerHTML = '✕';
messageInput.focus();
} else {
chatContainer.style.display = 'none';
toggleButton.innerHTML = '💬';
if (isListening) {
stopListening();
}
}
}
function handleKeyPress(event) {
if (event.key === 'Enter') {
sendMessage();
}
}
function sendMessage() {
const message = messageInput.value.trim();
if (message) {
addMessage(message, 'user');
messageInput.value = '';
generateAIResponse(message);
}
}
function addMessage(text, sender) {
const messageDiv = document.createElement('div');
messageDiv.className = 'message ' + sender + '-message';
messageDiv.textContent = text;
chatMessages.appendChild(messageDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
async function generateAIResponse(userInput) {
if (!CONFIG.GEMINI_API_KEY || CONFIG.GEMINI_API_KEY === 'YOUR_GEMINI_API_KEY_HERE') {
addMessage('Please configure your Gemini API key in the CONFIG section.', 'bot');
return;
}
try {
const response = await fetch('https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key=' + CONFIG.GEMINI_API_KEY, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
contents: [
{
role: "user",
parts: [{ text: CONFIG.SYSTEM_PROMPT + "\n\nUser: " + userInput }]
}
],
})
});
if (!response.ok) {
throw new Error('Failed to generate response');
}
const data = await response.json();
const aiResponse = data.candidates[0].content.parts[0].text;
addMessage(aiResponse, 'bot');
if (CONFIG.MURF_API_KEY && CONFIG.MURF_API_KEY !== 'YOUR_MURF_API_KEY_HERE') {
await generateAndPlayAudio(aiResponse);
}
} catch (error) {
console.error('Error generating AI response:', error);
addMessage('Sorry, I encountered an error. Please try again.', 'bot');
}
}
async function generateAndPlayAudio(text) {
try {
const response = await fetch('https://api.murf.ai/v1/speech/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'api-key': CONFIG.MURF_API_KEY,
},
body: JSON.stringify({
text: text,
voiceId: CONFIG.VOICE_ID,
}),
});
if (!response.ok) {
throw new Error('Failed to generate audio');
}
const data = await response.json();
if (data.audioFile) {
playAudio(data.audioFile);
}
} catch (error) {
console.error('Error generating audio:', error);
}
}
function playAudio(audioUrl) {
const audio = new Audio(audioUrl);
audio.play().catch(error => {
console.error('Error playing audio:', error);
});
}
function initializeSpeechRecognition() {
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SpeechRecognition) {
console.warn('Speech recognition not supported');
return;
}
recognition = new SpeechRecognition();
recognition.continuous = true;
recognition.interimResults = true;
recognition.lang = 'en-US';
recognition.onstart = () => {
isListening = true;
micButton.style.background = '#f44336';
};
recognition.onresult = (event) => {
let finalTranscript = '';
for (let i = event.resultIndex; i < event.results.length; i++) {
const transcript = event.results[i][0].transcript;
if (event.results[i].isFinal) {
finalTranscript += transcript;
}
}
if (finalTranscript) {
messageInput.value = finalTranscript;
if (CONFIG.AUTO_MODE) {
if (silenceTimeout) {
clearTimeout(silenceTimeout);
}
silenceTimeout = setTimeout(() => {
if (finalTranscript.trim()) {
sendMessage();
}
}, CONFIG.SILENCE_TIMEOUT);
}
}
};
recognition.onerror = (event) => {
console.error('Speech recognition error:', event.error);
stopListening();
};
recognition.onend = () => {
stopListening();
};
}
function toggleVoice() {
if (isListening) {
stopListening();
} else {
startListening();
}
}
function startListening() {
if (recognition && !isListening) {
try {
recognition.start();
} catch (error) {
console.error('Error starting speech recognition:', error);
}
}
}
function stopListening() {
if (recognition && isListening) {
recognition.stop();
isListening = false;
micButton.style.background = '#667eea';
if (silenceTimeout) {
clearTimeout(silenceTimeout);
silenceTimeout = null;
}
}
}
</script>
</body>
</html>
Features:
Setup Instructions:
YOUR_GEMINI_API_KEY_HERE
with your actual Gemini API keyYOUR_MURF_API_KEY_HERE
with your actual Murf AI API key