bot-blueprint / index.html
kattastrofik-kattastrofey's picture
Add 2 files
26bfc4b verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Bot Builder - Create Your Custom AI Assistant</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@keyframes float {
0% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
100% { transform: translateY(0px); }
}
.floating {
animation: float 3s ease-in-out infinite;
}
.chat-container {
height: 70vh;
transition: all 0.3s ease;
}
.message {
max-width: 80%;
opacity: 0;
transform: translateY(10px);
transition: all 0.3s ease;
}
.message.show {
opacity: 1;
transform: translateY(0);
}
.typing-indicator::after {
content: '...';
position: absolute;
animation: ellipsis 1.5s infinite;
}
@keyframes ellipsis {
0% { content: '.'; }
33% { content: '..'; }
66% { content: '...'; }
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.7); }
70% { box-shadow: 0 0 0 10px rgba(99, 102, 241, 0); }
100% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0); }
}
</style>
</head>
<body class="bg-gradient-to-br from-indigo-50 to-blue-100 min-h-screen">
<div class="container mx-auto px-4 py-8">
<header class="flex justify-between items-center mb-8">
<div class="flex items-center">
<i class="fas fa-robot text-4xl text-indigo-600 mr-3 floating"></i>
<h1 class="text-3xl font-bold text-indigo-900">AI Bot Builder</h1>
</div>
<div class="hidden md:flex space-x-4">
<button class="px-4 py-2 bg-indigo-100 text-indigo-700 rounded-full hover:bg-indigo-200 transition">Features</button>
<button class="px-4 py-2 bg-indigo-100 text-indigo-700 rounded-full hover:bg-indigo-200 transition">Pricing</button>
<button class="px-4 py-2 bg-indigo-600 text-white rounded-full hover:bg-indigo-700 transition">Sign Up</button>
</div>
</header>
<div class="flex flex-col lg:flex-row gap-8">
<div class="lg:w-1/3 bg-white rounded-2xl shadow-xl p-6 self-start sticky top-8">
<h2 class="text-xl font-bold text-indigo-900 mb-4">Your Bot Blueprint</h2>
<div class="space-y-4">
<div class="p-4 bg-indigo-50 rounded-lg">
<h3 class="font-medium text-indigo-800">Bot Type</h3>
<p id="bot-type-summary" class="text-gray-600">Not selected yet</p>
</div>
<div class="p-4 bg-indigo-50 rounded-lg">
<h3 class="font-medium text-indigo-800">Template</h3>
<p id="template-summary" class="text-gray-600">Not selected yet</p>
</div>
<div class="p-4 bg-indigo-50 rounded-lg">
<h3 class="font-medium text-indigo-800">Personality</h3>
<p id="personality-summary" class="text-gray-600">Not configured yet</p>
</div>
<div class="p-4 bg-indigo-50 rounded-lg">
<h3 class="font-medium text-indigo-800">Features</h3>
<div id="features-summary" class="text-gray-600">
<div class="flex items-center mb-1"><i class="fas fa-check-circle text-green-500 mr-2"></i> Text Chat</div>
<div class="flex items-center mb-1"><i class="fas fa-microphone text-indigo-500 mr-2"></i> Voice Interaction</div>
<div class="flex items-center"><i class="fas fa-heart text-pink-500 mr-2"></i> Emotional Intelligence (Hume AI)</div>
</div>
</div>
</div>
<div class="mt-6 pt-4 border-t border-gray-200">
<button id="download-btn" class="hidden w-full bg-indigo-600 text-white py-3 rounded-lg font-medium hover:bg-indigo-700 transition flex items-center justify-center">
<i class="fas fa-download mr-2"></i> Download Your Bot
</button>
<button id="expert-call-btn" class="hidden w-full mt-3 bg-pink-500 text-white py-3 rounded-lg font-medium hover:bg-pink-600 transition flex items-center justify-center">
<i class="fas fa-phone-alt mr-2"></i> Talk to AI Expert
</button>
</div>
</div>
<div class="lg:w-2/3 bg-white rounded-2xl shadow-xl overflow-hidden">
<div class="p-4 bg-indigo-700 text-white flex items-center">
<div class="w-3 h-3 rounded-full bg-red-500 mr-2"></div>
<div class="w-3 h-3 rounded-full bg-yellow-500 mr-2"></div>
<div class="w-3 h-3 rounded-full bg-green-500 mr-2"></div>
<div class="ml-2 font-medium">AI Bot Builder Assistant</div>
</div>
<div id="chat-container" class="chat-container p-4 overflow-y-auto bg-gray-50" style="height: 60vh;">
<div class="message show mb-4 bg-indigo-100 text-indigo-900 rounded-2xl rounded-tl-none p-4 self-start">
<div class="flex items-start">
<div class="w-8 h-8 rounded-full bg-indigo-500 text-white flex items-center justify-center mr-2 flex-shrink-0">
<i class="fas fa-robot"></i>
</div>
<div>
<p>Hey there! I'm your AI bot-building buddy. Let's create an amazing AI assistant together! 🤖✨</p>
<p class="mt-2">First things first - are you looking to create a <span class="font-bold">Personal</span> or <span class="font-bold">Business</span> AI agent?</p>
</div>
</div>
</div>
</div>
<div class="p-4 border-t border-gray-200 bg-white">
<div id="input-container" class="flex">
<input id="user-input" type="text" placeholder="Type your answer here..." class="flex-1 border border-gray-300 rounded-l-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-indigo-500">
<button id="send-btn" class="bg-indigo-600 text-white px-6 py-3 rounded-r-lg hover:bg-indigo-700 transition">
<i class="fas fa-paper-plane"></i>
</button>
</div>
<div id="voice-controls" class="mt-3 flex justify-center">
<button id="voice-btn" class="pulse px-6 py-2 bg-pink-500 text-white rounded-full flex items-center">
<i class="fas fa-microphone mr-2"></i> Tap to Speak
</button>
</div>
<div id="options-container" class="mt-3 hidden">
<p class="text-sm text-gray-500 mb-2">Quick select:</p>
<div class="flex flex-wrap gap-2" id="quick-options"></div>
</div>
</div>
</div>
</div>
</div>
<script>
// Bot configuration object
const botConfig = {
type: null,
template: null,
personality: {
tone: null,
expertise: null,
humorLevel: null,
formality: null
},
contactInfo: {
name: null,
email: null,
phone: null
}
};
// Templates data
const templates = {
personal: [
{ id: 'life-coach', name: 'Life Coach', description: 'Helps with personal growth and daily motivation' },
{ id: 'sports-pro', name: 'Sports Pro', description: 'Your personal trainer and sports advisor' },
{ id: 'mental-health', name: 'Mental Health', description: 'Supportive companion for mental wellbeing' }
],
business: [
{ id: 'recruiter', name: 'Recruiter', description: 'Screens candidates and schedules interviews' },
{ id: 'real-estate', name: 'Real Estate', description: 'Virtual property assistant for clients' },
{ id: 'service-business', name: 'Service Business', description: 'Handles customer inquiries and bookings' }
]
};
// Current conversation state
let conversationState = 'select-type';
let selectedTemplate = null;
// DOM elements
const chatContainer = document.getElementById('chat-container');
const userInput = document.getElementById('user-input');
const sendBtn = document.getElementById('send-btn');
const voiceBtn = document.getElementById('voice-btn');
const optionsContainer = document.getElementById('options-container');
const quickOptions = document.getElementById('quick-options');
const botTypeSummary = document.getElementById('bot-type-summary');
const templateSummary = document.getElementById('template-summary');
const personalitySummary = document.getElementById('personality-summary');
const downloadBtn = document.getElementById('download-btn');
const expertCallBtn = document.getElementById('expert-call-btn');
// Speech recognition setup
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
let recognition;
let isListening = false;
if (SpeechRecognition) {
recognition = new SpeechRecognition();
recognition.continuous = false;
recognition.interimResults = false;
recognition.lang = 'en-US';
recognition.onstart = () => {
voiceBtn.innerHTML = '<i class="fas fa-microphone-slash mr-2"></i> Listening...';
voiceBtn.classList.remove('bg-pink-500');
voiceBtn.classList.add('bg-red-500');
isListening = true;
};
recognition.onend = () => {
if (isListening) {
voiceBtn.innerHTML = '<i class="fas fa-microphone mr-2"></i> Tap to Speak';
voiceBtn.classList.remove('bg-red-500');
voiceBtn.classList.add('bg-pink-500');
isListening = false;
}
};
recognition.onresult = (event) => {
const transcript = event.results[0][0].transcript;
userInput.value = transcript;
handleUserResponse(transcript);
};
recognition.onerror = (event) => {
console.error('Speech recognition error', event.error);
addBotMessage("Oops! I didn't catch that. Could you try typing instead?");
voiceBtn.innerHTML = '<i class="fas fa-microphone mr-2"></i> Tap to Speak';
voiceBtn.classList.remove('bg-red-500');
voiceBtn.classList.add('bg-pink-500');
isListening = false;
};
} else {
voiceBtn.style.display = 'none';
}
// Event listeners
sendBtn.addEventListener('click', () => {
if (userInput.value.trim()) {
handleUserResponse(userInput.value.trim());
userInput.value = '';
}
});
userInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && userInput.value.trim()) {
handleUserResponse(userInput.value.trim());
userInput.value = '';
}
});
voiceBtn.addEventListener('click', () => {
if (!isListening) {
try {
recognition.start();
} catch (e) {
console.error('Speech recognition failed:', e);
addBotMessage("Voice input isn't working right now. Could you type instead?");
}
} else {
recognition.stop();
}
});
// Helper functions
function addBotMessage(text, isHtml = false) {
const messageDiv = document.createElement('div');
messageDiv.className = 'message mb-4 bg-indigo-100 text-indigo-900 rounded-2xl rounded-tl-none p-4 self-start';
const messageContent = `
<div class="flex items-start">
<div class="w-8 h-8 rounded-full bg-indigo-500 text-white flex items-center justify-center mr-2 flex-shrink-0">
<i class="fas fa-robot"></i>
</div>
<div>${isHtml ? text : `<p>${text}</p>`}</div>
</div>
`;
messageDiv.innerHTML = messageContent;
chatContainer.appendChild(messageDiv);
// Scroll to bottom
chatContainer.scrollTop = chatContainer.scrollHeight;
// Show message with animation
setTimeout(() => {
messageDiv.classList.add('show');
}, 10);
}
function addUserMessage(text) {
const messageDiv = document.createElement('div');
messageDiv.className = 'message mb-4 bg-indigo-600 text-white rounded-2xl rounded-tr-none p-4 self-end';
const messageContent = `
<div class="flex items-start justify-end">
<div class="ml-2 text-right">
<p>${text}</p>
</div>
<div class="w-8 h-8 rounded-full bg-white text-indigo-600 flex items-center justify-center ml-2 flex-shrink-0">
<i class="fas fa-user"></i>
</div>
</div>
`;
messageDiv.innerHTML = messageContent;
chatContainer.appendChild(messageDiv);
// Scroll to bottom
chatContainer.scrollTop = chatContainer.scrollHeight;
// Show message with animation
setTimeout(() => {
messageDiv.classList.add('show');
}, 10);
}
function showTypingIndicator() {
const typingDiv = document.createElement('div');
typingDiv.className = 'message mb-4 bg-indigo-100 text-indigo-900 rounded-2xl rounded-tl-none p-4 self-start';
typingDiv.style.width = '80px';
typingDiv.innerHTML = `
<div class="flex items-center">
<div class="w-8 h-8 rounded-full bg-indigo-500 text-white flex items-center justify-center mr-2 flex-shrink-0">
<i class="fas fa-robot"></i>
</div>
<div class="typing-indicator"></div>
</div>
`;
chatContainer.appendChild(typingDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
setTimeout(() => {
typingDiv.classList.add('show');
}, 10);
return typingDiv;
}
function hideTypingIndicator(typingDiv) {
if (typingDiv && typingDiv.parentNode) {
typingDiv.classList.remove('show');
setTimeout(() => {
typingDiv.remove();
}, 300);
}
}
function showQuickOptions(options) {
quickOptions.innerHTML = '';
options.forEach(option => {
const btn = document.createElement('button');
btn.className = 'px-3 py-1 bg-indigo-100 text-indigo-700 rounded-full text-sm hover:bg-indigo-200 transition';
btn.textContent = option;
btn.addEventListener('click', () => {
handleUserResponse(option);
});
quickOptions.appendChild(btn);
});
optionsContainer.classList.remove('hidden');
}
function hideQuickOptions() {
optionsContainer.classList.add('hidden');
}
// Main conversation handler
function handleUserResponse(response) {
addUserMessage(response);
hideQuickOptions();
const typingIndicator = showTypingIndicator();
setTimeout(() => {
hideTypingIndicator(typingIndicator);
processResponse(response);
}, 1000 + Math.random() * 1000); // Simulate thinking time
}
function processResponse(response) {
response = response.toLowerCase();
switch (conversationState) {
case 'select-type':
if (response.includes('personal') || response.includes('person')) {
botConfig.type = 'personal';
botTypeSummary.textContent = 'Personal AI Assistant';
addBotMessage("Awesome! Personal AI it is. Let's pick a template that fits your needs:");
showTemplateOptions('personal');
conversationState = 'select-template';
} else if (response.includes('business') || response.includes('bus')) {
botConfig.type = 'business';
botTypeSummary.textContent = 'Business AI Assistant';
addBotMessage("Great choice! Business AI coming right up. Which template works best for you?");
showTemplateOptions('business');
conversationState = 'select-template';
} else {
addBotMessage("Hmm, I'm not sure I caught that. Are you building a <b>Personal</b> or <b>Business</b> AI? (You can say or type either)");
showQuickOptions(['Personal', 'Business']);
}
break;
case 'select-template':
const templatesList = botConfig.type === 'personal' ? templates.personal : templates.business;
const matchedTemplate = templatesList.find(t =>
response.includes(t.id) || response.includes(t.name.toLowerCase())
);
if (matchedTemplate) {
selectedTemplate = matchedTemplate;
botConfig.template = matchedTemplate.id;
templateSummary.textContent = matchedTemplate.name;
addBotMessage(`Excellent choice! The ${matchedTemplate.name} template is perfect for ${matchedTemplate.description}.`);
addBotMessage("Now let's give your AI some personality! How would you like it to sound?");
addBotMessage("1. Professional and formal<br>2. Friendly and casual<br>3. Enthusiastic and motivational<br>4. Something else (tell me what you're thinking)", true);
conversationState = 'select-personality-tone';
} else {
addBotMessage("I didn't quite catch which template you want. Here are your options again:");
showTemplateOptions(botConfig.type);
}
break;
case 'select-personality-tone':
if (response.includes('1') || response.includes('professional') || response.includes('formal')) {
botConfig.personality.tone = 'Professional and formal';
addBotMessage("Got it! Your AI will be all business (but still helpful). Next question:");
} else if (response.includes('2') || response.includes('friendly') || response.includes('casual')) {
botConfig.personality.tone = 'Friendly and casual';
addBotMessage("Casual and friendly it is! I like your style. Next up:");
} else if (response.includes('3') || response.includes('enthus') || response.includes('motiv')) {
botConfig.personality.tone = 'Enthusiastic and motivational';
addBotMessage("Woo! Let's get pumped! Your AI will be full of energy. Now:");
} else {
botConfig.personality.tone = response;
addBotMessage(`Interesting! I'll note that down as "${response}". Now:`);
}
personalitySummary.textContent = botConfig.personality.tone;
addBotMessage("How expert should your AI sound in its field?<br>1. Beginner level (explains basics)<br>2. Intermediate (good balance)<br>3. Expert (assumes knowledge)<br>4. Guru (cutting-edge insights)", true);
conversationState = 'select-expertise';
break;
case 'select-expertise':
if (response.includes('1') || response.includes('beginner')) {
botConfig.personality.expertise = 'Beginner level';
} else if (response.includes('2') || response.includes('intermediate')) {
botConfig.personality.expertise = 'Intermediate';
} else if (response.includes('3') || response.includes('expert')) {
botConfig.personality.expertise = 'Expert';
} else if (response.includes('4') || response.includes('guru')) {
botConfig.personality.expertise = 'Guru';
} else {
botConfig.personality.expertise = response;
}
personalitySummary.textContent = `${botConfig.personality.tone}, ${botConfig.personality.expertise}`;
addBotMessage("Noted! Now, how funny should your AI be?<br>1. Serious (no jokes)<br>2. Occasionally witty<br>3. Pretty funny<br>4. Stand-up comedian level", true);
conversationState = 'select-humor';
break;
case 'select-humor':
if (response.includes('1') || response.includes('serious')) {
botConfig.personality.humorLevel = 'Serious';
} else if (response.includes('2') || response.includes('witty')) {
botConfig.personality.humorLevel = 'Occasionally witty';
} else if (response.includes('3') || response.includes('pretty funny')) {
botConfig.personality.humorLevel = 'Pretty funny';
} else if (response.includes('4') || response.includes('stand-up') || response.includes('comedian')) {
botConfig.personality.humorLevel = 'Stand-up comedian';
} else {
botConfig.personality.humorLevel = response;
}
personalitySummary.textContent = `${botConfig.personality.tone}, ${botConfig.personality.expertise}, ${botConfig.personality.humorLevel}`;
addBotMessage("Haha, got it! Last personality question:");
addBotMessage("How formal should conversations be?<br>1. Very formal (Mr./Ms.)<br>2. Moderately formal<br>3. First-name basis<br>4. Like old friends", true);
conversationState = 'select-formality';
break;
case 'select-formality':
if (response.includes('1') || response.includes('very formal')) {
botConfig.personality.formality = 'Very formal';
} else if (response.includes('2') || response.includes('moderate')) {
botConfig.personality.formality = 'Moderately formal';
} else if (response.includes('3') || response.includes('first-name')) {
botConfig.personality.formality = 'First-name basis';
} else if (response.includes('4') || response.includes('old friends')) {
botConfig.personality.formality = 'Like old friends';
} else {
botConfig.personality.formality = response;
}
personalitySummary.textContent = `${botConfig.personality.tone}, ${botConfig.personality.expertise}, ${botConfig.personality.humorLevel}, ${botConfig.personality.formality}`;
addBotMessage("Perfect! Your AI's personality is all set. Now, let's get your contact info so we can send your bot when it's ready.");
addBotMessage("What's your name? (First name is fine)");
conversationState = 'get-name';
break;
case 'get-name':
botConfig.contactInfo.name = response;
addBotMessage(`Nice to meet you, ${response}! What's your email address?`);
conversationState = 'get-email';
break;
case 'get-email':
if (response.includes('@') && response.includes('.')) {
botConfig.contactInfo.email = response;
addBotMessage("Got it! And finally, what's your phone number? (We'll only use it if we need to clarify something)");
conversationState = 'get-phone';
} else {
addBotMessage("Hmm, that doesn't look like a valid email. Could you try again?");
}
break;
case 'get-phone':
botConfig.contactInfo.phone = response;
addBotMessage("Thanks! We're all set. Here's what we've created:");
addBotMessage(`<b>Type:</b> ${botConfig.type}<br>
<b>Template:</b> ${selectedTemplate.name}<br>
<b>Personality:</b> ${botConfig.personality.tone}, ${botConfig.personality.expertise}, ${botConfig.personality.humorLevel}, ${botConfig.personality.formality}<br>
<b>Contact:</b> ${botConfig.contactInfo.name}, ${botConfig.contactInfo.email}, ${botConfig.contactInfo.phone}`, true);
addBotMessage("Would you like to <b>download your bot now</b> or schedule a <b>free consultation call</b> with one of our AI experts to go over your setup?", true);
showQuickOptions(['Download now', 'Talk to expert']);
conversationState = 'final-choice';
break;
case 'final-choice':
if (response.includes('download') || response.includes('now')) {
downloadBtn.classList.remove('hidden');
addBotMessage("Awesome! Your AI bot is being prepared for download. It'll be with you in just a moment. 🚀");
addBotMessage("While you wait, did you know our AI bots can learn from conversations? The more you chat, the smarter they get!");
} else if (response.includes('expert') || response.includes('talk') || response.includes('call')) {
expertCallBtn.classList.remove('hidden');
addBotMessage("Great choice! Our AI experts are like bot whisperers. They'll help you get the most out of your new AI assistant.");
addBotMessage("You'll receive a calendar link in your email shortly to schedule your free consultation. Meanwhile, here's a fun fact: The average business saves 20 hours/week using our AI bots!");
} else {
addBotMessage("I'm not sure what you'd like to do. Would you prefer to <b>download now</b> or <b>talk to an expert</b> first?", true);
showQuickOptions(['Download now', 'Talk to expert']);
}
break;
}
}
function showTemplateOptions(type) {
const templateList = templates[type];
let message = "Here are our available templates:<br><br>";
templateList.forEach((template, index) => {
message += `<b>${index + 1}. ${template.name}</b>: ${template.description}<br>`;
});
message += "<br>Which one would you like to use? (You can say the name or number)";
addBotMessage(message, true);
const quickOptions = templateList.map(t => t.name);
showQuickOptions(quickOptions);
}
// Initialize with a fun message after a short delay
setTimeout(() => {
addBotMessage("Pro tip: You can type or use the microphone button to speak. I'm all ears! 🎤");
}, 3000);
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=kattastrofik-kattastrofey/bot-blueprint" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>