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
slack-bot-assistant
/
bot
RSK World
slack-bot-assistant
Slack Bot Assistant - Python + Slack API + SQLite + PHP Dashboard + Bot Commands + Automation
bot
  • __pycache__
  • app.py30.8 KB
  • config.py1.9 KB
  • helpers.py5.5 KB
  • models.py4.4 KB
  • scheduler.py3.1 KB
  • utils.py12.6 KB
utils.py
bot/utils.py
Raw Download
Find: Go to:
"""
Slack Bot Assistant - Utilities
Developer: Molla Samser (Founder, RSK World)
Design & Testing: Rima Khatun
Website: https://rskworld.in
Contact: hello@rskworld.in | +91 93305 39277
Year: 2026
"""

import logging
import re
from datetime import datetime, timedelta
from typing import Dict, List, Optional
try:
    from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
    VADER_AVAILABLE = True
except ImportError:
    VADER_AVAILABLE = False
    logging.warning("VADER sentiment analyzer not available, using basic sentiment analysis")

from config import Config

# Setup logging
logging.basicConfig(
    level=getattr(logging, Config.LOG_LEVEL),
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(Config.LOG_FILE),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

# Initialize VADER sentiment analyzer if available
if VADER_AVAILABLE:
    sentiment_analyzer = SentimentIntensityAnalyzer()

def analyze_sentiment(text: str) -> Dict[str, any]:
    """
    Advanced sentiment analysis using VADER or fallback to keyword-based.
    Returns dict with sentiment label and score.
    """
    text_lower = text.lower()
    
    # Enhanced keyword detection
    urgent_keywords = ["urgent", "immediately", "asap", "help", "broken", "critical", "emergency", "down", "error"]
    positive_keywords = ["thanks", "great", "awesome", "good", "solved", "perfect", "excellent", "wonderful", "amazing"]
    negative_keywords = ["bad", "terrible", "worst", "hate", "disappointed", "frustrated", "failed", "broken"]
    
    # Check for urgent keywords first
    if any(word in text_lower for word in urgent_keywords):
        return {"sentiment": "URGENT", "score": 0.9, "confidence": "high"}
    
    # Use VADER if available
    if VADER_AVAILABLE:
        try:
            scores = sentiment_analyzer.polarity_scores(text)
            compound = scores['compound']
            
            if compound >= 0.05:
                return {"sentiment": "POSITIVE", "score": compound, "confidence": "high"}
            elif compound <= -0.05:
                return {"sentiment": "NEGATIVE", "score": abs(compound), "confidence": "high"}
            else:
                return {"sentiment": "NEUTRAL", "score": abs(compound), "confidence": "medium"}
        except Exception as e:
            logger.error(f"Error in VADER sentiment analysis: {e}")
    
    # Fallback to keyword-based analysis
    if any(word in text_lower for word in positive_keywords):
        return {"sentiment": "POSITIVE", "score": 0.7, "confidence": "medium"}
    elif any(word in text_lower for word in negative_keywords):
        return {"sentiment": "NEGATIVE", "score": 0.7, "confidence": "medium"}
    
    return {"sentiment": "NEUTRAL", "score": 0.5, "confidence": "low"}

def get_personality_response(query: str, personality: str = "Professional", language: str = "English") -> str:
    """
    Returns a response based on selected personality and language.
    Enhanced with better sentiment analysis.
    """
    sentiment_data = analyze_sentiment(query)
    sentiment = sentiment_data["sentiment"]
    base_response = ""
    
    # Enhanced response logic based on sentiment
    if sentiment == "URGENT":
        base_response = "I've detected this is urgent. I'm prioritizing your request immediately."
    elif sentiment == "NEGATIVE":
        base_response = "I understand this is concerning. Let me help resolve this quickly."
    elif "status" in query.lower() or "health" in query.lower():
        base_response = "All team systems are operational. No critical issues detected."
    elif "task" in query.lower() or "todo" in query.lower():
        base_response = "I can help you manage tasks. Use /task-create to add a new task."
    elif "reminder" in query.lower():
        base_response = "I can set reminders for you. Use /set-reminder to schedule one."
    elif "meeting" in query.lower() or "summary" in query.lower():
        base_response = "I can summarize meetings. Use /summarize-meeting in a channel."
    else:
        base_response = "I've logged your request. Our productivity engine is analyzing the best way to assist you."

    # Apply Personality Tone
    if personality == "Casual":
        base_response = f"Hey! {base_response.replace('request', 'thing').replace('I\'ve', 'I\'ve').replace('Our', 'Our')}. Catch you in a bit! 🚀"
    elif personality == "Technical":
        base_response = f"[Bot Logs]: Trace ID {abs(hash(query)) % 10000} | Sentiment: {sentiment} | Score: {sentiment_data['score']:.2f} | Action: {base_response}"
    elif personality == "Friendly":
        base_response = f"Hi there! 😊 {base_response} Feel free to ask if you need anything else!"
    elif personality == "Formal":
        base_response = f"Dear colleague, {base_response} Please do not hesitate to contact me if you require further assistance."
    
    # Enhanced Translation Support
    if language == "Hindi":
        translation_map = {
            "I've detected this is urgent": "मैंने पहचाना है कि यह जरूरी है",
            "I understand this is concerning": "मैं समझता हूं कि यह चिंताजनक है",
            "All team systems are operational": "सभी टीम सिस्टम चालू हैं",
            "I've logged your request": "मैंने आपका अनुरोध दर्ज कर लिया है",
            "I can help you manage tasks": "मैं आपको कार्य प्रबंधन में मदद कर सकता हूं",
            "I can set reminders for you": "मैं आपके लिए अनुस्मारक सेट कर सकता हूं"
        }
        for eng, hin in translation_map.items():
            if eng in base_response:
                base_response = base_response.replace(eng, hin)
    
    return base_response

def generate_channel_report(channel_name: str) -> str:
    """
    Generates an advanced mock report for channel management.
    Enhanced with more detailed analytics.
    """
    return (
        f"📊 *Advanced Channel Analytics for #{channel_name}*\n"
        f"- Active Members: 12 (↑ 2 this week)\n"
        f"- Sentiment Index: 0.85 (Steady)\n"
        f"- Most Active Hour: 2:00 PM IST\n"
        f"- Message Volume: 342 messages this week\n"
        f"- Response Rate: 94%\n"
        f"- Top Contributors: @user1, @user2, @user3\n"
        f"- AI Suggestion: Channel health is good. Schedule a sync for pending tasks."
    )

def parse_reminder_time(time_str: str) -> Optional[datetime]:
    """
    Parse various time formats for reminders.
    Supports: "in 2 hours", "tomorrow 10am", "2024-12-31 14:00", etc.
    """
    time_str = time_str.lower().strip()
    now = datetime.now()
    
    # Relative time parsing
    if time_str.startswith("in "):
        try:
            parts = time_str.replace("in ", "").split()
            value = int(parts[0])
            unit = parts[1] if len(parts) > 1 else "minutes"
            
            if "minute" in unit:
                return now + timedelta(minutes=value)
            elif "hour" in unit:
                return now + timedelta(hours=value)
            elif "day" in unit:
                return now + timedelta(days=value)
            elif "week" in unit:
                return now + timedelta(weeks=value)
        except (ValueError, IndexError):
            pass
    
    # Tomorrow parsing
    if "tomorrow" in time_str:
        target_date = now + timedelta(days=1)
        # Try to extract time
        time_match = re.search(r'(\d{1,2})(?::(\d{2}))?\s*(am|pm)?', time_str)
        if time_match:
            hour = int(time_match.group(1))
            minute = int(time_match.group(2)) if time_match.group(2) else 0
            am_pm = time_match.group(3)
            if am_pm == "pm" and hour != 12:
                hour += 12
            elif am_pm == "am" and hour == 12:
                hour = 0
            target_date = target_date.replace(hour=hour, minute=minute, second=0, microsecond=0)
        return target_date
    
    # Try ISO format
    try:
        return datetime.fromisoformat(time_str)
    except (ValueError, AttributeError):
        pass
    
    # Default: 1 hour from now
    logger.warning(f"Could not parse time string: {time_str}, defaulting to 1 hour from now")
    return now + timedelta(hours=1)

def format_task_list(tasks: List[Dict]) -> str:
    """
    Format a list of tasks into a readable string.
    """
    if not tasks:
        return "No tasks found."
    
    formatted = "📋 *Your Tasks:*\n"
    for i, task in enumerate(tasks, 1):
        status_emoji = {
            "pending": "⏳",
            "in_progress": "🔄",
            "completed": "✅",
            "cancelled": "❌"
        }.get(task.get("status", "pending"), "📝")
        
        priority_emoji = {
            "low": "🟢",
            "medium": "🟡",
            "high": "🟠",
            "urgent": "🔴"
        }.get(task.get("priority", "medium"), "🟡")
        
        formatted += f"{i}. {status_emoji} {priority_emoji} *{task.get('title', 'Untitled')}*\n"
        if task.get("description"):
            formatted += f"   {task['description'][:100]}{'...' if len(task.get('description', '')) > 100 else ''}\n"
        if task.get("due_date"):
            formatted += f"   📅 Due: {task['due_date']}\n"
        formatted += "\n"
    
    return formatted

def generate_meeting_summary(messages: List[Dict]) -> str:
    """
    Generate a summary from a list of messages.
    Enhanced with better analysis.
    """
    if not messages:
        return "No messages to summarize."
    
    total_messages = len(messages)
    unique_users = len(set(msg.get("user", "unknown") for msg in messages))
    
    # Extract key topics (simple keyword extraction)
    all_text = " ".join(msg.get("text", "") for msg in messages).lower()
    topics = []
    topic_keywords = {
        "deployment": ["deploy", "release", "production"],
        "bugs": ["bug", "error", "issue", "fix"],
        "features": ["feature", "add", "implement", "new"],
        "meetings": ["meeting", "sync", "standup"],
        "deadlines": ["deadline", "due", "urgent", "asap"]
    }
    
    for topic, keywords in topic_keywords.items():
        if any(kw in all_text for kw in keywords):
            topics.append(topic)
    
    summary = f"📝 *Meeting Summary*\n"
    summary += f"- *Participants:* {unique_users} members\n"
    summary += f"- *Messages Analyzed:* {total_messages}\n"
    summary += f"- *Key Topics:* {', '.join(topics[:5]) if topics else 'General discussion'}\n\n"
    summary += "*Highlights:*\n"
    
    # Extract action items (messages with keywords like "will", "todo", "action")
    action_items = []
    for msg in messages[:20]:  # Check first 20 messages
        text = msg.get("text", "").lower()
        if any(word in text for word in ["will", "todo", "action", "need to", "should"]):
            action_items.append(msg.get("text", "")[:100])
    
    if action_items:
        summary += "\n*Action Items:*\n"
        for item in action_items[:5]:
            summary += f"- {item}\n"
    
    return summary

def validate_task_priority(priority: str) -> str:
    """
    Validate and normalize task priority.
    """
    priority = priority.lower().strip()
    valid_priorities = ["low", "medium", "high", "urgent"]
    if priority in valid_priorities:
        return priority
    return "medium"

def get_weather_emoji(condition: str) -> str:
    """
    Get emoji for weather condition.
    """
    condition_lower = condition.lower()
    if "sun" in condition_lower or "clear" in condition_lower:
        return "☀️"
    elif "rain" in condition_lower or "drizzle" in condition_lower:
        return "🌧️"
    elif "cloud" in condition_lower:
        return "☁️"
    elif "snow" in condition_lower:
        return "❄️"
    elif "storm" in condition_lower or "thunder" in condition_lower:
        return "⛈️"
    elif "fog" in condition_lower or "mist" in condition_lower:
        return "🌫️"
    else:
        return "🌤️"

def sanitize_text(text: str, max_length: int = 2000) -> str:
    """
    Sanitize and truncate text for Slack messages.
    """
    # Remove excessive whitespace
    text = re.sub(r'\s+', ' ', text)
    # Truncate if too long
    if len(text) > max_length:
        text = text[:max_length - 3] + "..."
    return text.strip()
314 lines•12.6 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