help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • Blog
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
real-estate-bot
/
src
RSK World
real-estate-bot
Real Estate Bot - Python + Flask + OpenAI + SQLite + Property Search + AI Chatbot + Viewing Scheduler
src
  • __pycache__
  • __init__.py476 B
  • ai_recommendation_engine.py20.6 KB
  • app.py7.8 KB
  • blockchain_integration.py1.5 KB
  • chatbot.py15.5 KB
  • database.py18.4 KB
  • image_enhancer.py7.9 KB
  • multilang_support.py8.8 KB
  • neighborhood_analyzer.py6.1 KB
  • price_prediction_engine.py25.1 KB
  • property_search.py15.6 KB
  • virtual_tour_manager.py21.8 KB
  • voice_assistant.py27.6 KB
chatbot.py
src/chatbot.py
Raw Download
Find: Go to:
"""
Real Estate Chatbot Core Logic
Author: RSK World (https://rskworld.in)
Founded by: Molla Samser
Designer & Tester: Rima Khatun
Contact: info@rskworld.com, +91 93305 39277
Year: 2026
"""

import re
from datetime import datetime, timedelta
from typing import List, Dict, Any

class RealEstateChatbot:
    def __init__(self, openai_client, property_search_engine, database_manager):
        """
        Initialize the Real Estate Chatbot
        
        Args:
            openai_client: OpenAI API client
            property_search_engine: Property search engine instance
            database_manager: Database manager instance
        """
        self.openai = openai_client
        self.property_search = property_search_engine
        self.db_manager = database_manager
        self.conversation_history = {}
        
    def process_message(self, message: str, user_id: str) -> str:
        """
        Process user message and generate response
        
        Args:
            message: User's message
            user_id: User identifier
            
        Returns:
            Chatbot response
        """
        # Initialize conversation history if not exists
        if user_id not in self.conversation_history:
            self.conversation_history[user_id] = []
        
        # Add user message to history
        self.conversation_history[user_id].append({
            'role': 'user',
            'content': message,
            'timestamp': datetime.now()
        })
        
        # Determine intent and extract entities
        intent, entities = self._analyze_message(message)
        
        # Generate response based on intent
        response = self._generate_response(intent, entities, user_id)
        
        # Add bot response to history
        self.conversation_history[user_id].append({
            'role': 'assistant',
            'content': response,
            'timestamp': datetime.now()
        })
        
        # Keep only last 10 messages in history
        if len(self.conversation_history[user_id]) > 10:
            self.conversation_history[user_id] = self.conversation_history[user_id][-10:]
        
        return response
    
    def _analyze_message(self, message: str) -> tuple:
        """
        Analyze user message to determine intent and extract entities
        
        Args:
            message: User's message
            
        Returns:
            Tuple of (intent, entities)
        """
        message_lower = message.lower()
        
        # Property search patterns
        search_patterns = [
            r'(?:search|find|looking for|show me).*(?:property|house|home|apartment|flat)',
            r'(?:property|house|home|apartment|flat).*(?:in|at|near)',
            r'(?:buy|rent|lease).*(?:property|house|home|apartment|flat)'
        ]
        
        # Scheduling patterns
        scheduling_patterns = [
            r'(?:schedule|book|arrange).*(?:viewing|visit|tour|appointment)',
            r'(?:see|visit|view).*(?:property|house|home)',
            r'(?:when|what time).*(?:available|can.*visit)'
        ]
        
        # Inquiry patterns
        inquiry_patterns = [
            r'(?:tell me|what|how).*(?:about|regarding)',
            r'(?:information|details).*(?:about|of)',
            r'(?:price|cost|rate).*(?:of|for)'
        ]
        
        # Check for intent
        intent = 'general'
        for pattern in search_patterns:
            if re.search(pattern, message_lower):
                intent = 'property_search'
                break
        
        if intent == 'general':
            for pattern in scheduling_patterns:
                if re.search(pattern, message_lower):
                    intent = 'schedule_viewing'
                    break
        
        if intent == 'general':
            for pattern in inquiry_patterns:
                if re.search(pattern, message_lower):
                    intent = 'property_inquiry'
                    break
        
        # Extract entities
        entities = self._extract_entities(message, intent)
        
        return intent, entities
    
    def _extract_entities(self, message: str, intent: str) -> Dict[str, Any]:
        """
        Extract entities from user message
        
        Args:
            message: User's message
            intent: Detected intent
            
        Returns:
            Dictionary of extracted entities
        """
        entities = {}
        message_lower = message.lower()
        
        # Extract location
        location_patterns = [
            r'(?:in|at|near)\s+([a-z\s]+(?:city|area|location|place|district|state))',
            r'([a-z\s]+(?:city|area|location|place|district|state))\s*(?:property|house|home)',
        ]
        
        for pattern in location_patterns:
            match = re.search(pattern, message_lower)
            if match:
                entities['location'] = match.group(1).strip()
                break
        
        # Extract price range
        price_patterns = [
            r'(?:under|below|less than)\s*(?:\$|₹|rs|rupees)?\s*(\d+(?:,\d+)*)',
            r'(?:between|range)\s*(?:\$|₹|rs|rupees)?\s*(\d+(?:,\d+)*)\s*(?:and|to|-)\s*(?:\$|₹|rs|rupees)?\s*(\d+(?:,\d+)*)',
            r'(?:over|above|more than)\s*(?:\$|₹|rs|rupees)?\s*(\d+(?:,\d+)*)'
        ]
        
        for pattern in price_patterns:
            match = re.search(pattern, message_lower)
            if match:
                if len(match.groups()) == 2:
                    entities['price_min'] = int(match.group(1).replace(',', ''))
                    entities['price_max'] = int(match.group(2).replace(',', ''))
                else:
                    if 'under' in pattern or 'below' in pattern or 'less than' in pattern:
                        entities['price_max'] = int(match.group(1).replace(',', ''))
                    else:
                        entities['price_min'] = int(match.group(1).replace(',', ''))
                break
        
        # Extract property type
        property_types = {
            'apartment': ['apartment', 'flat', 'unit'],
            'house': ['house', 'home', 'villa', 'bungalow'],
            'condo': ['condo', 'condominium'],
            'townhouse': ['townhouse', 'town home']
        }
        
        for prop_type, keywords in property_types.items():
            if any(keyword in message_lower for keyword in keywords):
                entities['property_type'] = prop_type
                break
        
        # Extract bedrooms
        bedroom_match = re.search(r'(\d+)\s*(?:bedroom|bed|bhk)', message_lower)
        if bedroom_match:
            entities['bedrooms'] = int(bedroom_match.group(1))
        
        # Extract date/time for scheduling
        if intent == 'schedule_viewing':
            date_patterns = [
                r'(?:tomorrow|today|next week|this week)',
                r'\d{1,2}[/-]\d{1,2}[/-]\d{2,4}',
                r'(?:monday|tuesday|wednesday|thursday|friday|saturday|sunday)'
            ]
            
            for pattern in date_patterns:
                match = re.search(pattern, message_lower)
                if match:
                    entities['preferred_date'] = match.group(0)
                    break
        
        # Extract property ID if mentioned
        property_id_match = re.search(r'property\s*(?:id|#|number)?\s*:?\s*(\d+)', message_lower)
        if property_id_match:
            try:
                entities['property_id'] = int(property_id_match.group(1))
            except ValueError:
                pass
        
        return entities
    
    def _generate_response(self, intent: str, entities: Dict[str, Any], user_id: str) -> str:
        """
        Generate response based on intent and entities
        
        Args:
            intent: User's intent
            entities: Extracted entities
            user_id: User identifier
            
        Returns:
            Generated response
        """
        if intent == 'property_search':
            return self._handle_property_search(entities, user_id)
        elif intent == 'schedule_viewing':
            return self._handle_schedule_viewing(entities, user_id)
        elif intent == 'property_inquiry':
            return self._handle_property_inquiry(entities, user_id)
        else:
            return self._handle_general_query(entities, user_id)
    
    def _handle_property_search(self, entities: Dict[str, Any], user_id: str) -> str:
        """Handle property search requests"""
        try:
            # Search for properties based on criteria
            properties = self.property_search.search(entities)
            
            if not properties:
                return "I couldn't find any properties matching your criteria. Would you like to try with different search parameters?"
            
            # Format response
            response = f"I found {len(properties)} properties matching your criteria:\n\n"
            
            for i, prop in enumerate(properties[:5], 1):  # Show top 5 results
                area = prop.get('area_sqft', prop.get('area', 'N/A'))
                area_str = f"{area} sqft" if isinstance(area, (int, float)) else str(area)
                price = prop.get('price', 'Price not specified')
                price_str = f"₹{price:,}" if isinstance(price, (int, float)) else str(price)
                
                response += f"{i}. {prop.get('title', 'Property Title')}\n"
                response += f"   📍 {prop.get('location', 'Location not specified')}\n"
                response += f"   💰 {price_str}\n"
                response += f"   🏠 {prop.get('bedrooms', 'N/A')} bedrooms, {prop.get('bathrooms', 'N/A')} bathrooms\n"
                response += f"   📐 {area_str}\n\n"
            
            if len(properties) > 5:
                response += f"And {len(properties) - 5} more properties. Would you like to see more details about any specific property?"
            
            return response
            
        except Exception as e:
            return f"I apologize, but I encountered an error while searching for properties: {str(e)}"
    
    def _handle_schedule_viewing(self, entities: Dict[str, Any], user_id: str) -> str:
        """Handle viewing scheduling requests"""
        try:
            property_id = entities.get('property_id')
            preferred_date = entities.get('preferred_date')
            
            if not property_id:
                # Try to find property from recent search results or ask user
                return ("To schedule a viewing, please specify which property you're interested in. "
                       "You can mention the property ID (e.g., 'Schedule viewing for property 1') "
                       "or first search for properties and then mention which one you'd like to view.")
            
            # Check if property exists
            property_info = self.property_search.get_property_by_id(property_id)
            if not property_info:
                return (f"I couldn't find property ID {property_id}. "
                       "Please check the property ID and try again, or search for available properties first.")
            
            # Schedule appointment
            appointment_id = self.db_manager.schedule_appointment(
                user_id=user_id,
                property_id=property_id,
                date_time=preferred_date or datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                contact_info=entities
            )
            
            response = f"Great! I've scheduled your viewing for:\n\n"
            response += f"🏠 Property: {property_info.get('title', 'Property Title')}\n"
            response += f"📍 Location: {property_info.get('location', 'Location not specified')}\n"
            response += f"📅 Date: {preferred_date or 'To be confirmed'}\n"
            response += f"📋 Appointment ID: {appointment_id}\n\n"
            response += "Our team will contact you shortly to confirm the exact time. You can reach us at +91 93305 39277 for any questions."
            
            return response
            
        except Exception as e:
            return f"I apologize, but I encountered an error while scheduling your viewing: {str(e)}"
    
    def _handle_property_inquiry(self, entities: Dict[str, Any], user_id: str) -> str:
        """Handle property inquiries"""
        try:
            property_id = entities.get('property_id')
            
            if property_id:
                # Get specific property details
                property_info = self.property_search.get_property_by_id(property_id)
                if property_info:
                    response = f"Here are the details for {property_info.get('title', 'Property Title')}:\n\n"
                    area = property_info.get('area_sqft', property_info.get('area', 'Not specified'))
                    area_str = f"{area} sqft" if isinstance(area, (int, float)) else str(area)
                    price = property_info.get('price', 'Not specified')
                    price_str = f"₹{price:,}" if isinstance(price, (int, float)) else str(price)
                    
                    response += f"📍 **Location:** {property_info.get('location', 'Not specified')}\n"
                    response += f"💰 **Price:** {price_str}\n"
                    response += f"🏠 **Type:** {property_info.get('property_type', 'Not specified')}\n"
                    response += f"🛏️ **Bedrooms:** {property_info.get('bedrooms', 'Not specified')}\n"
                    response += f"🚿 **Bathrooms:** {property_info.get('bathrooms', 'Not specified')}\n"
                    response += f"📐 **Area:** {area_str}\n"
                    response += f"📝 **Description:** {property_info.get('description', 'No description available')}\n\n"
                    response += "Would you like to schedule a viewing or do you have any specific questions about this property?"
                    return response
            
            # General inquiry response
            return ("I'd be happy to help you with information about our properties. You can ask me about:\n\n"
                   "• Property prices and availability\n"
                   "• Location details and neighborhoods\n"
                   "• Property features and amenities\n"
                   "• Scheduling viewings\n"
                   "• General real estate questions\n\n"
                   "What specific information are you looking for?")
            
        except Exception as e:
            return f"I apologize, but I encountered an error while processing your inquiry: {str(e)}"
    
    def _handle_general_query(self, entities: Dict[str, Any], user_id: str) -> str:
        """Handle general queries"""
        return """Hello! I'm your Real Estate Assistant, here to help you find your perfect property. I can help you with:

🏠 **Property Search:** Find properties based on location, price, type, and features
📅 **Schedule Viewings:** Book appointments to visit properties
💬 **Property Information:** Get detailed information about specific properties
📍 **Location Insights:** Learn about neighborhoods and areas

You can ask me questions like:
• "Show me apartments in Mumbai under 50 lakhs"
• "I'm looking for a 3-bedroom house in Delhi"
• "Schedule a viewing for property ID 123"
• "What's the price of the 2BHK flat in Bangalore?"

How can I assist you today?"""
359 lines•15.5 KB
python

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer