Spaces:
Build error
Build error
| """ | |
| Voice Banking Assistant for BankBot | |
| Enables voice-based banking queries and responses | |
| """ | |
| import os | |
| import json | |
| import speech_recognition as sr | |
| import pyttsx3 | |
| from gtts import gTTS | |
| import io | |
| import streamlit as st | |
| from datetime import datetime | |
| class VoiceAssistant: | |
| """Handles voice input and output for banking queries""" | |
| def __init__(self): | |
| self.recognizer = sr.Recognizer() | |
| self.engine = pyttsx3.init() | |
| self.engine.setProperty('rate', 150) # Speaking rate | |
| self.microphone = sr.Microphone() | |
| # Initialize text-to-speech properties | |
| self.engine.setProperty('volume', 0.9) # Volume level (0.0 to 1.0) | |
| def listen_to_user(self, timeout=10): | |
| """ | |
| Capture audio input from microphone and convert to text | |
| Returns: Recognized text or None if recognition fails | |
| """ | |
| try: | |
| with self.microphone as source: | |
| # Adjust for ambient noise | |
| self.recognizer.adjust_for_ambient_noise(source, duration=0.5) | |
| # Listen for audio | |
| audio = self.recognizer.listen(source, timeout=timeout, phrase_time_limit=15) | |
| # Try to recognize using Google Speech Recognition | |
| text = self.recognizer.recognize_google(audio) | |
| return text.lower() | |
| except sr.RequestError as e: | |
| return None # Could not request results; network error | |
| except sr.UnknownValueError: | |
| return None # Unable to recognize speech | |
| except Exception as e: | |
| print(f"Error listening to user: {e}") | |
| return None | |
| def speak_response(self, text, use_gtts=False): | |
| """ | |
| Provide audio output for the response | |
| Args: | |
| text: Response text | |
| use_gtts: Use Google Text-to-Speech instead of pyttsx3 | |
| Returns: Audio data or None | |
| """ | |
| try: | |
| if use_gtts: | |
| # Use Google TTS (requires internet, better quality) | |
| tts = gTTS(text=text, lang='en', slow=False) | |
| audio_fp = io.BytesIO() | |
| tts.write_to_fp(audio_fp) | |
| audio_fp.seek(0) | |
| return audio_fp | |
| else: | |
| # Use pyttsx3 (offline, works locally) | |
| self.engine.say(text) | |
| self.engine.runAndWait() | |
| return True | |
| except Exception as e: | |
| print(f"Error in text-to-speech: {e}") | |
| return None | |
| def process_voice_query(self, transcribed_text, user_data, transactions): | |
| """ | |
| Process voice query and extract banking intent | |
| Returns: Query type, extracted information | |
| """ | |
| text_lower = transcribed_text.lower() | |
| # Balance query | |
| if any(word in text_lower for word in ["balance", "how much", "account balance"]): | |
| return "balance", None | |
| # Transaction history | |
| elif any(word in text_lower for word in ["transactions", "history", "recent", "last"]): | |
| return "transactions", None | |
| # Spending analysis | |
| elif any(word in text_lower for word in ["spending", "spent", "expenses", "how much did i spend"]): | |
| return "spending", None | |
| # Transfer query | |
| elif any(word in text_lower for word in ["transfer", "send", "pay"]): | |
| return "transfer", None | |
| # Loan info | |
| elif any(word in text_lower for word in ["loan", "emi", "borrow", "credit"]): | |
| return "loan", None | |
| # FD/Investment | |
| elif any(word in text_lower for word in ["fixed deposit", "fd", "invest", "investment"]): | |
| return "fd", None | |
| # Help/Support | |
| elif any(word in text_lower for word in ["help", "support", "assist", "how do i"]): | |
| return "help", None | |
| else: | |
| return "general", None | |
| def generate_voice_response(self, query_type, user_data, transactions, get_ai_response_fn=None): | |
| """ | |
| Generate appropriate response for voice query | |
| Returns: Response text and audio | |
| """ | |
| balance = user_data.get('balance', 0) | |
| if query_type == "balance": | |
| response = f"Your current account balance is rupees {balance:.2f}" | |
| elif query_type == "transactions": | |
| recent = transactions[:5] if transactions else [] | |
| if not recent: | |
| response = "You have no recent transactions." | |
| else: | |
| response = f"Your last transaction was {recent[0].get('amount')} rupees for {recent[0].get('details', 'banking service')}" | |
| elif query_type == "spending": | |
| # Calculate spending | |
| debit_txns = [t for t in transactions if t.get('type') == 'debit'] | |
| total_spent = sum(float(t.get('amount', 0)) for t in debit_txns[-10:]) | |
| response = f"You have spent {total_spent:.2f} rupees in your recent transactions." | |
| elif query_type == "help": | |
| response = "I can help you with balance inquiries, transaction history, spending analysis, fund transfers, and loan information. What would you like to know?" | |
| elif query_type == "general" and get_ai_response_fn: | |
| # Use AI for general banking queries | |
| response = get_ai_response_fn("user query", []) | |
| else: | |
| response = "I didn't quite understand. Could you please rephrase your question?" | |
| return response | |
| def extract_voice_command(self, transcribed_text): | |
| """Extract command-specific parameters from voice input""" | |
| # Extract amounts from voice | |
| amount_words = { | |
| "hundred": 100, "thousand": 1000, "lakh": 100000, | |
| "rupees": 1, "rupee": 1, "paisa": 0.01 | |
| } | |
| # Extract recipient name if present | |
| # Extract date references if present | |
| return None | |
| def record_voice_query(username, users_data, get_ai_response_fn): | |
| """ | |
| Record and process voice query through Streamlit UI | |
| """ | |
| st.markdown(""" | |
| <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| padding: 20px; border-radius: 10px; margin: 10px 0;"> | |
| <h3 style="color: white; margin: 0;">π€ Voice Banking Assistant</h3> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| col1, col2, col3 = st.columns([1, 2, 1]) | |
| with col2: | |
| if st.button("ποΈ Start Recording", key="voice_record", use_container_width=True): | |
| with st.spinner("π§ Listening... Speak now!"): | |
| assistant = VoiceAssistant() | |
| recognized_text = assistant.listen_to_user(timeout=10) | |
| if recognized_text: | |
| st.success(f"β Recognized: {recognized_text}") | |
| # Process the query | |
| user_data = users_data.get(username, {}) | |
| transactions = user_data.get('transactions', []) | |
| query_type, _ = assistant.process_voice_query(recognized_text, user_data, transactions) | |
| response = assistant.generate_voice_response( | |
| query_type, | |
| user_data, | |
| transactions, | |
| get_ai_response_fn | |
| ) | |
| # Display response | |
| st.info(f"π€ Response: {response}") | |
| # Provide audio feedback | |
| with st.spinner("π Converting to speech..."): | |
| assistant.speak_response(response, use_gtts=False) | |
| st.success("β Response delivered") | |
| else: | |
| st.error("β Could not recognize speech. Please try again.") | |
| def voice_mode_demo(): | |
| """Demo voice banking queries""" | |
| demo_queries = [ | |
| "What's my balance?", | |
| "Show my recent transactions", | |
| "How much did I spend this month?", | |
| "Transfer 5000 to John", | |
| "Tell me about loan eligibility" | |
| ] | |
| return demo_queries | |