Talk to Me, TinyLLaMA: Build a Web Voice Assistant with Django


β¨ Why Did We Edit chat.html
Like This?
In our previous blog, our chatbot could only read text that we typed in manually.
But letβs be real β
If I can talk to Siri and Alexa, why not to my own bot? π
So in this blog, we upgraded chat.html
to turn it into a mini voice assistant β both listener and speaker π€π£οΈ
π‘ What We Added and Why:
β 1. Mic Button with JavaScript
We created a cute little π€ button that floats at the bottom-right corner of the screen.
When clicked:
It starts listening to your voice using
SpeechRecognition
Converts your speech to text
Puts it right into the input box like β¨magicβ¨
No typing needed!
β 2. Text-to-Speech Response
After the bot replies, we added a script that:
Grabs the botβs response from Django (
{{ response }}
)Uses
speechSynthesis
to speak it aloudNow your bot can talk back to you like a real assistant π§ π¬
Updated chat.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Chatbot</title> <style> body { font-family: Arial, sans-serif; background-color: #f2f2f2; margin: 0; padding: 0; height: 100vh; } .robot-btn { position: fixed; bottom: 20px; right: 20px; background: #0d6efd; border: none; border-radius: 50%; width: 60px; height: 60px; cursor: pointer; font-size: 30px; color: white; box-shadow: 0 2px 8px rgba(0,0,0,0.3); z-index: 9999; } .chat-popup { position: fixed; bottom: 90px; right: 20px; width: 350px; max-width: 90%; background: white; border-radius: 10px; box-shadow: 0 0 10px rgba(0,0,0,0.3); display: none; flex-direction: column; overflow: hidden; z-index: 9998; } .header { background: #0d6efd; color: #fff; padding: 10px; text-align: center; font-weight: bold; position: relative; } .end-btn { position: absolute; top: 5px; right: 8px; background: transparent; border: none; font-size: 18px; color: white; cursor: pointer; } .chat-history { flex: 1; padding: 10px; max-height: 300px; overflow-y: auto; } .message { margin: 5px 0; display: flex; } .message.user { justify-content: flex-end; } .message.bot { justify-content: flex-start; } .bubble { max-width: 70%; padding: 8px 12px; border-radius: 15px; font-size: 14px; line-height: 1.4; } .message.user .bubble { background-color: #0d6efd; color: #fff; border-bottom-right-radius: 0; } .message.bot .bubble { background-color: #d9edf8; color: #333; border-bottom-left-radius: 0; } .input-area { display: flex; border-top: 1px solid #ccc; } .input-area input { flex: 1; padding: 10px; border: none; outline: none; } .input-area button { background: #0d6efd; color: white; border: none; padding: 0 15px; cursor: pointer; font-size: 18px; } .input-area button:hover { background: #0b5ed7; } </style> </head> <body> <!-- Floating Robot Button --> <button class="robot-btn">π€</button> <!-- Chat Popup --> <div class="chat-popup" id="chatPopup"> <div class="header"> Chat with the Bot <button class="end-btn" id="endBtn">β</button> </div> <div class="chat-history" id="chatHistory"> {% if question %} <div class="message user"><div class="bubble">{{ question }}</div></div> {% endif %} {% if response %} <div class="message bot"><div class="bubble">{{ response }}</div></div> {% endif %} </div> <form method="post" class="input-area"> {% csrf_token %} <input type="text" name="question" placeholder="Type a message..." autocomplete="off" id="textInput"> <button type="submit">βοΈ</button> </form> </div> <script> const robotBtn = document.querySelector('.robot-btn'); const chatPopup = document.getElementById('chatPopup'); const textInput = document.getElementById('textInput'); const form = document.querySelector('form'); const chatHistory = document.getElementById('chatHistory'); const endBtn = document.getElementById('endBtn'); let synth = window.speechSynthesis; // Show/hide chat popup robotBtn.addEventListener('click', (e) => { chatPopup.style.display = chatPopup.style.display === 'flex' ? 'none' : 'flex'; e.stopPropagation(); }); // Close on outside click document.addEventListener('click', (e) => { if (!chatPopup.contains(e.target) && !robotBtn.contains(e.target)) { chatPopup.style.display = 'none'; } }); // End button click β also stop speech endBtn.addEventListener('click', () => { chatPopup.style.display = 'none'; if (synth.speaking) { synth.cancel(); // π Stop the bot from speaking } }); // Add mic button const micBtn = document.createElement('button'); micBtn.type = "button"; micBtn.innerText = "π€"; micBtn.style.background = "#0d6efd"; micBtn.style.color = "#fff"; micBtn.style.border = "none"; micBtn.style.cursor = "pointer"; micBtn.style.fontSize = "18px"; micBtn.style.marginLeft = "5px"; form.appendChild(micBtn); let recognition; let voiceTimeout; micBtn.addEventListener('click', () => { if (!('webkitSpeechRecognition' in window)) { alert("Voice not supported π’."); return; } recognition = new webkitSpeechRecognition(); recognition.lang = "en-US"; recognition.continuous = false; recognition.interimResults = false; recognition.start(); recognition.onresult = function (event) { const transcript = event.results[0][0].transcript; textInput.value = transcript; if (voiceTimeout) clearTimeout(voiceTimeout); voiceTimeout = setTimeout(() => { form.submit(); }, 3000); }; recognition.onerror = function (event) { alert("Speech error: " + event.error); }; }); // Bot speaks its response const botResponse = `{{ response|escapejs }}`; if (botResponse) { const utterance = new SpeechSynthesisUtterance(botResponse); utterance.lang = "en-US"; synth.speak(utterance); } </script> </body> </html>
π Together, These Two Changes Make It...
A real web-based voice assistant, built with
β€οΈ Django + ποΈ Web Speech API + π¦ LangChain + β¨ You!And the best part?
Still no APIs, no fees, no tokens β itβs all local and yours πPart 4 is gonna be extra magical β time to make your bot remember, personalize, and feel more like your own little assistant friend ππ§
Subscribe to my newsletter
Read articles from Sudharshini Jothikumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Sudharshini Jothikumar
Sudharshini Jothikumar
I am Sudharshini, a dynamic force in the world of technology and creativity, currently pursuing my MSc in Software Systems. With a passion for problem-solving, I have not only honed my skills but emerged victorious in numerous hackathons, showcasing my prowess in the ever-evolving realm of software development. Beyond the lines of code, I am also a wordsmith, having penned and published two captivating books that reflect my diverse interests. My ability to weave narratives demonstrates a depth of creativity that extends beyond the digital domain. I am also a national-level champion in both Silambam and Adimurai, showcasing my physical prowess and discipline. Whether it's mastering the intricacies of software architecture or gracefully wielding traditional weapons, I embodied a perfect blend of the modern and the traditional. In a world where versatility is key, I stand out as a multifaceted individual, seamlessly navigating the realms of technology, literature, and martial arts with finesse. My journey is not just a narrative of achievements but a testament to the limitless possibilities that arise when one embraces a holistic approach to life.