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
analytics.pyzip.goapp.py
bot/app.py
Raw Download
Find: Go to:
"""
Slack Bot Assistant - Core Application
Developer: Molla Samser (Founder, RSK World)
Design & Testing: Rima Khatun
Website: https://rskworld.in
Contact: hello@rskworld.in | +91 93305 39277
Year: 2026
Description: Slack bot for team collaboration and productivity automation.
"""

import os
import json
import threading
import time
from datetime import datetime, timedelta
from typing import Dict, Optional
import requests

from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from slack_sdk.errors import SlackApiError

from config import Config
from models import (
    init_db, get_db, UserConfig, Reminder, Task, MeetingSummary,
    MessageSentiment, CommandHistory, Poll
)
from utils import (
    get_personality_response, generate_channel_report, analyze_sentiment,
    parse_reminder_time, format_task_list, generate_meeting_summary,
    validate_task_priority, get_weather_emoji, sanitize_text
)
from helpers import (
    get_random_quote, format_timestamp, truncate_text, extract_urls,
    calculate_time_difference, format_list, create_progress_bar
)

# Initialize database
if Config.ENABLE_DATABASE:
    init_db()

# Initialize Slack app
app = App(
    token=Config.SLACK_BOT_TOKEN,
    signing_secret=Config.SLACK_SIGNING_SECRET
)

# Background thread for reminder checking
def check_reminders():
    """Background thread to check and send reminders"""
    while Config.ENABLE_SCHEDULING:
        try:
            db = get_db()
            now = datetime.utcnow()
            reminders = db.query(Reminder).filter(
                Reminder.reminder_time <= now,
                Reminder.is_completed == False
            ).all()
            
            for reminder in reminders:
                try:
                    # Send reminder message
                    channel = reminder.channel_id if reminder.channel_id else reminder.user_id
                    app.client.chat_postMessage(
                        channel=channel,
                        text=f"ā° *Reminder:* {reminder.message}",
                        user=reminder.user_id
                    )
                    reminder.is_completed = True
                    db.commit()
                except Exception as e:
                    print(f"Error sending reminder {reminder.id}: {e}")
            
            db.close()
        except Exception as e:
            print(f"Error in reminder checker: {e}")
        
        time.sleep(Config.REMINDER_CHECK_INTERVAL)

# Start reminder checker thread
if Config.ENABLE_SCHEDULING:
    reminder_thread = threading.Thread(target=check_reminders, daemon=True)
    reminder_thread.start()

def get_user_config(user_id: str) -> Dict:
    """Get user configuration from database or return defaults"""
    if not Config.ENABLE_DATABASE:
        return {"personality": Config.DEFAULT_PERSONALITY, "language": Config.DEFAULT_LANGUAGE}
    
    db = None
    try:
        db = get_db()
        user_config = db.query(UserConfig).filter(UserConfig.user_id == user_id).first()
        if user_config:
            config = {
                "personality": user_config.personality,
                "language": user_config.language,
                "timezone": user_config.timezone
            }
            db.close()
            return config
        db.close()
    except Exception as e:
        print(f"Error getting user config: {e}")
        if db:
            db.close()
    
    return {"personality": Config.DEFAULT_PERSONALITY, "language": Config.DEFAULT_LANGUAGE}

def save_user_config(user_id: str, personality: str, language: str):
    """Save user configuration to database"""
    if not Config.ENABLE_DATABASE:
        return
    
    db = None
    try:
        db = get_db()
        user_config = db.query(UserConfig).filter(UserConfig.user_id == user_id).first()
        if user_config:
            user_config.personality = personality
            user_config.language = language
            user_config.updated_at = datetime.utcnow()
        else:
            user_config = UserConfig(
                user_id=user_id,
                personality=personality,
                language=language
            )
            db.add(user_config)
        db.commit()
        db.close()
    except Exception as e:
        print(f"Error saving user config: {e}")
        if db:
            db.close()

def log_command(user_id: str, channel_id: str, command: str, parameters: str = None):
    """Log command usage for analytics"""
    if not Config.ENABLE_DATABASE:
        return
    
    db = None
    try:
        db = get_db()
        cmd_history = CommandHistory(
            user_id=user_id,
            channel_id=channel_id,
            command=command,
            parameters=parameters
        )
        db.add(cmd_history)
        db.commit()
        db.close()
    except Exception as e:
        print(f"Error logging command: {e}")
        if db:
            db.close()

@app.event("app_mention")
def handle_mentions(event, say, client):
    """Handle mentions of the bot to provide AI assistance with advanced features."""
    user = event['user']
    text = event['text']
    channel = event.get('channel', '')
    
    # Get user configuration
    config = get_user_config(user)
    
    # Analyze sentiment and log
    sentiment_data = analyze_sentiment(text)
    if Config.ENABLE_DATABASE:
        db = None
        try:
            db = get_db()
            sentiment_record = MessageSentiment(
                user_id=user,
                channel_id=channel,
                message=text[:500],  # Limit message length
                sentiment=sentiment_data["sentiment"],
                sentiment_score=sentiment_data.get("score", 0.5)
            )
            db.add(sentiment_record)
            db.commit()
            db.close()
        except Exception as e:
            print(f"Error logging sentiment: {e}")
            if db:
                db.close()
    
    # Use advanced response logic
    response = get_personality_response(text, personality=config['personality'], language=config['language'])
    
    say(f"Hi <@{user}>! {response}")

@app.command("/bot-settings")
def update_settings(ack, body, client):
    """Slash command to configure bot personality and language."""
    ack()
    user_id = body["user_id"]
    config = get_user_config(user_id)
    
    client.views_open(
        trigger_id=body["trigger_id"],
        view={
            "type": "modal",
            "callback_id": "settings_modal",
            "title": {"type": "plain_text", "text": "Bot Settings"},
            "blocks": [
                {
                    "type": "input",
                    "block_id": "personality_block",
                    "element": {
                        "type": "static_select",
                        "action_id": "personality_select",
                        "initial_option": {
                            "text": {"type": "plain_text", "text": config["personality"]},
                            "value": config["personality"]
                        },
                        "options": [
                            {"text": {"type": "plain_text", "text": "Professional"}, "value": "Professional"},
                            {"text": {"type": "plain_text", "text": "Casual"}, "value": "Casual"},
                            {"text": {"type": "plain_text", "text": "Technical"}, "value": "Technical"},
                            {"text": {"type": "plain_text", "text": "Friendly"}, "value": "Friendly"},
                            {"text": {"type": "plain_text", "text": "Formal"}, "value": "Formal"}
                        ]
                    },
                    "label": {"type": "plain_text", "text": "AI Personality"}
                },
                {
                    "type": "input",
                    "block_id": "language_block",
                    "element": {
                        "type": "static_select",
                        "action_id": "language_select",
                        "initial_option": {
                            "text": {"type": "plain_text", "text": config["language"]},
                            "value": config["language"]
                        },
                        "options": [
                            {"text": {"type": "plain_text", "text": lang}, "value": lang}
                            for lang in Config.SUPPORTED_LANGUAGES
                        ]
                    },
                    "label": {"type": "plain_text", "text": "Language"}
                }
            ],
            "submit": {"type": "plain_text", "text": "Save"}
        }
    )

@app.view("settings_modal")
def handle_settings_submission(ack, body, client):
    """Handle settings modal submission"""
    ack()
    user_id = body["user"]["id"]
    values = body["view"]["state"]["values"]
    
    personality = values["personality_block"]["personality_select"]["selected_option"]["value"]
    language = values["language_block"]["language_select"]["selected_option"]["value"]
    
    save_user_config(user_id, personality, language)
    
    client.chat_postMessage(
        channel=user_id,
        text=f"āœ… Settings updated! Personality: {personality}, Language: {language}"
    )

@app.command("/manage-channel")
def manage_channel(ack, respond, command):
    """Slash command for channel management tasks."""
    ack()
    log_command(command["user_id"], command["channel_id"], "/manage-channel")
    channel_name = command.get('channel_name', 'general')
    report = generate_channel_report(channel_name)
    respond(f"Channel Management Report for #{channel_name}:\n{report}")

@app.command("/task-create")
def create_task(ack, body, client, command):
    """Create a new task with advanced options."""
    ack()
    user_id = command["user_id"]
    channel_id = command["channel_id"]
    text = command.get('text', '').strip()
    
    log_command(user_id, channel_id, "/task-create", text)
    
    if not text:
        respond("āŒ Usage: `/task-create <title> | <description> | <priority> | <due_date>`\n"
                "Example: `/task-create Fix login bug | Update authentication logic | high | tomorrow 5pm`")
        return
    
    # Parse task input
    parts = [p.strip() for p in text.split('|')]
    title = parts[0] if parts else "Untitled Task"
    description = parts[1] if len(parts) > 1 else ""
    priority = validate_task_priority(parts[2]) if len(parts) > 2 else "medium"
    due_date_str = parts[3] if len(parts) > 3 else None
    
    due_date = None
    if due_date_str:
        due_date = parse_reminder_time(due_date_str)
    
    # Save task to database
    if Config.ENABLE_DATABASE:
        try:
            db = get_db()
            task = Task(
                user_id=user_id,
                channel_id=channel_id,
                title=title,
                description=description,
                priority=priority,
                due_date=due_date,
                status="pending"
            )
            db.add(task)
            db.commit()
            task_id = task.id
            db.close()
            
            due_str = f" (Due: {due_date.strftime('%Y-%m-%d %H:%M')})" if due_date else ""
            respond(f"āœ… Task created (ID: {task_id})!\n"
                   f"šŸ“ *{title}*\n"
                   f"Priority: {priority.upper()}{due_str}\n"
                   f"{description if description else ''}")
        except Exception as e:
            respond(f"āŒ Error creating task: {str(e)}")
    else:
        respond(f"āœ… Task created!\nšŸ“ *{title}*\nPriority: {priority.upper()}")

@app.command("/task-list")
def list_tasks(ack, respond, command):
    """List all tasks for the user."""
    ack()
    user_id = command["user_id"]
    log_command(user_id, command["channel_id"], "/task-list")
    
    if Config.ENABLE_DATABASE:
        try:
            db = get_db()
            tasks = db.query(Task).filter(
                Task.user_id == user_id,
                Task.status.in_(["pending", "in_progress"])
            ).order_by(Task.created_at.desc()).limit(20).all()
            
            task_list = []
            for task in tasks:
                task_list.append({
                    "title": task.title,
                    "description": task.description,
                    "status": task.status,
                    "priority": task.priority,
                    "due_date": task.due_date.strftime('%Y-%m-%d %H:%M') if task.due_date else None
                })
            
            db.close()
            respond(format_task_list(task_list))
        except Exception as e:
            respond(f"āŒ Error retrieving tasks: {str(e)}")
    else:
        respond("šŸ“‹ Task management requires database. Please enable database in configuration.")

@app.command("/set-reminder")
def set_reminder(ack, respond, command):
    """Sets a productivity reminder with advanced time parsing."""
    ack()
    user_id = command["user_id"]
    channel_id = command["channel_id"]
    text = command.get('text', '').strip()
    
    log_command(user_id, channel_id, "/set-reminder", text)
    
    if not text:
        respond("āŒ Usage: `/set-reminder <message> | <time>`\n"
                "Example: `/set-reminder Team meeting | in 2 hours`\n"
                "Or: `/set-reminder Review PR | tomorrow 10am`")
        return
    
    # Parse reminder input
    parts = [p.strip() for p in text.split('|')]
    if len(parts) < 2:
        respond("āŒ Please provide both message and time separated by `|`")
        return
    
    message = parts[0]
    time_str = parts[1]
    
    reminder_time = parse_reminder_time(time_str)
    
    if Config.ENABLE_DATABASE:
        try:
            db = get_db()
            # Check reminder limit
            reminder_count = db.query(Reminder).filter(
                Reminder.user_id == user_id,
                Reminder.is_completed == False
            ).count()
            
            if reminder_count >= Config.MAX_REMINDERS_PER_USER:
                respond(f"āŒ You have reached the maximum limit of {Config.MAX_REMINDERS_PER_USER} active reminders.")
                db.close()
                return
            
            reminder = Reminder(
                user_id=user_id,
                channel_id=channel_id,
                message=message,
                reminder_time=reminder_time
            )
            db.add(reminder)
            db.commit()
            reminder_id = reminder.id
            db.close()
            
            respond(f"ā° Reminder set for {reminder_time.strftime('%Y-%m-%d %H:%M')}!\n"
                   f"Message: {message}\n"
                   f"Reminder ID: {reminder_id}")
        except Exception as e:
            respond(f"āŒ Error setting reminder: {str(e)}")
    else:
        respond(f"ā° Reminder set: {message} at {time_str}")

@app.command("/summarize-meeting")
def summarize_meeting(ack, respond, command, client):
    """Summarizes recent messages in the channel as a meeting summary."""
    ack()
    user_id = command["user_id"]
    channel_id = command["channel_id"]
    
    log_command(user_id, channel_id, "/summarize-meeting")
    
    try:
        # Fetch recent messages from channel
        response = client.conversations_history(
            channel=channel_id,
            limit=Config.MEETING_SUMMARY_MESSAGE_COUNT
        )
        
        messages = []
        for msg in response.get("messages", []):
            messages.append({
                "user": msg.get("user", "unknown"),
                "text": msg.get("text", ""),
                "ts": msg.get("ts", "")
            })
        
        summary_text = generate_meeting_summary(messages)
        
        # Save summary to database
        if Config.ENABLE_DATABASE:
            try:
                db = get_db()
                summary = MeetingSummary(
                    channel_id=channel_id,
                    summary=summary_text,
                    participant_count=len(set(m.get("user") for m in messages)),
                    message_count=len(messages),
                    created_by=user_id
                )
                db.add(summary)
                db.commit()
                db.close()
            except Exception as e:
                print(f"Error saving summary: {e}")
        
        respond(summary_text)
    except SlackApiError as e:
        respond(f"āŒ Error fetching messages: {e.response['error']}")

@app.command("/weather")
def get_weather(ack, respond, command):
    """Get weather information (requires OpenWeather API key)."""
    ack()
    user_id = command["user_id"]
    channel_id = command["channel_id"]
    location = command.get('text', 'New York').strip()
    
    log_command(user_id, channel_id, "/weather", location)
    
    if not Config.ENABLE_WEATHER:
        respond("āŒ Weather feature is not enabled. Please configure OPENWEATHER_API_KEY in environment variables.")
        return
    
    try:
        url = f"http://api.openweathermap.org/data/2.5/weather"
        params = {
            "q": location,
            "appid": Config.OPENWEATHER_API_KEY,
            "units": "metric"
        }
        response = requests.get(url, params=params, timeout=5)
        
        if response.status_code == 200:
            data = response.json()
            temp = data["main"]["temp"]
            feels_like = data["main"]["feels_like"]
            condition = data["weather"][0]["description"]
            humidity = data["main"]["humidity"]
            emoji = get_weather_emoji(condition)
            
            respond(f"{emoji} *Weather in {location}*\n"
                   f"Temperature: {temp}°C (feels like {feels_like}°C)\n"
                   f"Condition: {condition.title()}\n"
                   f"Humidity: {humidity}%")
        else:
            respond(f"āŒ Could not fetch weather for {location}. Please check the location name.")
    except Exception as e:
        respond(f"āŒ Error fetching weather: {str(e)}")

@app.command("/poll")
def create_poll(ack, body, client, command):
    """Create a poll with multiple options."""
    ack()
    user_id = command["user_id"]
    channel_id = command["channel_id"]
    text = command.get('text', '').strip()
    
    log_command(user_id, channel_id, "/poll", text)
    
    if not text:
        respond("āŒ Usage: `/poll <question> | <option1> | <option2> | ...`\n"
                "Example: `/poll Best meeting time? | 9am | 2pm | 5pm`")
        return
    
    parts = [p.strip() for p in text.split('|')]
    if len(parts) < 3:
        respond("āŒ Please provide a question and at least 2 options")
        return
    
    question = parts[0]
    options = parts[1:]
    
    if Config.ENABLE_DATABASE:
        try:
            db = get_db()
            poll = Poll(
                channel_id=channel_id,
                created_by=user_id,
                question=question,
                options=json.dumps(options),
                votes=json.dumps({}),
                is_active=True
            )
            db.add(poll)
            db.commit()
            poll_id = poll.id
            db.close()
            
            # Format poll message
            options_text = "\n".join([f"{i+1}. {opt}" for i, opt in enumerate(options)])
            respond(f"šŸ“Š *Poll Created*\n\n*{question}*\n\n{options_text}\n\n"
                   f"Poll ID: {poll_id}\n"
                   f"Use reactions or `/poll-vote {poll_id} <option_number>` to vote")
        except Exception as e:
            respond(f"āŒ Error creating poll: {str(e)}")
    else:
        options_text = "\n".join([f"{i+1}. {opt}" for i, opt in enumerate(options)])
        respond(f"šŸ“Š *Poll*\n\n*{question}*\n\n{options_text}")

@app.command("/standup")
def standup(ack, respond, command):
    """Generate a standup summary template."""
    ack()
    user_id = command["user_id"]
    channel_id = command["channel_id"]
    
    log_command(user_id, channel_id, "/standup")
    
    standup_template = (
        "šŸ“‹ *Daily Standup*\n\n"
        "1. *What did I accomplish yesterday?*\n"
        "   - \n\n"
        "2. *What will I work on today?*\n"
        "   - \n\n"
        "3. *Any blockers or challenges?*\n"
        "   - \n\n"
        "4. *Goals for this week?*\n"
        "   - "
    )
    
    respond(standup_template)

@app.command("/quote")
def get_quote(ack, respond, command):
    """Get a random motivational quote."""
    ack()
    user_id = command["user_id"]
    channel_id = command["channel_id"]
    
    log_command(user_id, channel_id, "/quote")
    
    quote = get_random_quote()
    respond(f"šŸ’¬ *Motivational Quote*\n\n{quote}")

@app.command("/note")
def create_note(ack, respond, command):
    """Create a quick note (stored in database)."""
    ack()
    user_id = command["user_id"]
    channel_id = command["channel_id"]
    text = command.get('text', '').strip()
    
    log_command(user_id, channel_id, "/note", text)
    
    if not text:
        respond("āŒ Usage: `/note <your note>`\n"
                "Example: `/note Remember to update documentation tomorrow`")
        return
    
    if Config.ENABLE_DATABASE:
        try:
            db = get_db()
            # Store note as a task with note tag
            note = Task(
                user_id=user_id,
                channel_id=channel_id,
                title=f"Note: {truncate_text(text, 50)}",
                description=text,
                priority="low",
                status="pending"
            )
            db.add(note)
            db.commit()
            note_id = note.id
            db.close()
            
            respond(f"šŸ“ *Note saved* (ID: {note_id})\n\n{text}")
        except Exception as e:
            respond(f"āŒ Error saving note: {str(e)}")
    else:
        respond(f"šŸ“ *Note*\n\n{text}")

@app.command("/random")
def random_command(ack, respond, command):
    """Get random number or choose from options."""
    ack()
    user_id = command["user_id"]
    channel_id = command["channel_id"]
    text = command.get('text', '').strip()
    
    log_command(user_id, channel_id, "/random", text)
    
    if not text:
        # Generate random number between 1-100
        import random
        number = random.randint(1, 100)
        respond(f"šŸŽ² *Random Number*\n\n{number} (between 1-100)")
        return
    
    # If text contains options separated by commas or |
    if ',' in text or '|' in text:
        separator = ',' if ',' in text else '|'
        options = [opt.strip() for opt in text.split(separator) if opt.strip()]
        if len(options) > 1:
            import random
            chosen = random.choice(options)
            respond(f"šŸŽ² *Random Choice*\n\nFrom: {', '.join(options)}\n\n✨ *Chosen:* {chosen}")
        else:
            respond("āŒ Please provide at least 2 options separated by commas or |")
    else:
        # Try to parse as number range (e.g., "1-10")
        try:
            if '-' in text:
                parts = text.split('-')
                if len(parts) == 2:
                    start, end = int(parts[0].strip()), int(parts[1].strip())
                    import random
                    number = random.randint(start, end)
                    respond(f"šŸŽ² *Random Number*\n\n{number} (between {start}-{end})")
                else:
                    respond("āŒ Invalid range format. Use: `/random 1-100`")
            else:
                # Single number - generate between 1 and that number
                max_num = int(text)
                import random
                number = random.randint(1, max_num)
                respond(f"šŸŽ² *Random Number*\n\n{number} (between 1-{max_num})")
        except ValueError:
            respond("āŒ Usage: `/random` or `/random 1-100` or `/random option1, option2, option3`")

@app.command("/translate")
def translate_text(ack, respond, command):
    """Translate text (basic implementation - can be extended with API)."""
    ack()
    user_id = command["user_id"]
    channel_id = command["channel_id"]
    text = command.get('text', '').strip()
    
    log_command(user_id, channel_id, "/translate", text)
    
    if not text:
        respond("āŒ Usage: `/translate <text> | <target_language>`\n"
                "Example: `/translate Hello | Hindi`\n"
                "Supported languages: Hindi, Spanish, French, German")
        return
    
    # Parse input
    parts = [p.strip() for p in text.split('|')]
    if len(parts) < 2:
        respond("āŒ Please provide text and target language separated by `|`")
        return
    
    text_to_translate = parts[0]
    target_lang = parts[1].lower()
    
    # Basic translation dictionary (can be extended with API)
    translations = {
        "hindi": {
            "hello": "ą¤Øą¤®ą¤øą„ą¤¤ą„‡",
            "thanks": "ą¤§ą¤Øą„ą¤Æą¤µą¤¾ą¤¦",
            "good": "ą¤…ą¤šą„ą¤›ą¤¾",
            "yes": "हाँ",
            "no": "ą¤Øą¤¹ą„€ą¤‚"
        },
        "spanish": {
            "hello": "Hola",
            "thanks": "Gracias",
            "good": "Bueno",
            "yes": "SĆ­",
            "no": "No"
        },
        "french": {
            "hello": "Bonjour",
            "thanks": "Merci",
            "good": "Bon",
            "yes": "Oui",
            "no": "Non"
        },
        "german": {
            "hello": "Hallo",
            "thanks": "Danke",
            "good": "Gut",
            "yes": "Ja",
            "no": "Nein"
        }
    }
    
    if target_lang in translations:
        text_lower = text_to_translate.lower()
        if text_lower in translations[target_lang]:
            translated = translations[target_lang][text_lower]
            respond(f"🌐 *Translation*\n\n*Original:* {text_to_translate}\n*{target_lang.title()}:* {translated}\n\n"
                   f"ā„¹ļø Note: This is a basic translation. For full translation, configure GOOGLE_TRANSLATE_API_KEY")
        else:
            respond(f"āŒ Translation not available for '{text_to_translate}'. Configure GOOGLE_TRANSLATE_API_KEY for full translation support.")
    else:
        respond(f"āŒ Language '{target_lang}' not supported. Supported: Hindi, Spanish, French, German")

@app.command("/help")
def help_command(ack, respond, command):
    """Display help information for all commands."""
    ack()
    log_command(command["user_id"], command["channel_id"], "/help")
    
    help_text = (
        "šŸ¤– *Slack Bot Assistant - Commands*\n\n"
        "*Basic Commands:*\n"
        "• `/bot-settings` - Configure bot personality and language\n"
        "• `/help` - Show this help message\n\n"
        "*Task Management:*\n"
        "• `/task-create <title> | <description> | <priority> | <due_date>` - Create a new task\n"
        "• `/task-list` - List your active tasks\n"
        "• `/note <text>` - Create a quick note\n\n"
        "*Productivity:*\n"
        "• `/set-reminder <message> | <time>` - Set a reminder\n"
        "• `/summarize-meeting` - Generate meeting summary from recent messages\n"
        "• `/standup` - Get standup template\n\n"
        "*Team Collaboration:*\n"
        "• `/manage-channel` - Get channel analytics and management report\n"
        "• `/poll <question> | <option1> | <option2> | ...` - Create a poll\n\n"
        "*Utilities:*\n"
        "• `/weather <location>` - Get weather information\n"
        "• `/quote` - Get a random motivational quote\n"
        "• `/random` - Generate random number or choose from options\n"
        "• `/translate <text> | <language>` - Translate text\n\n"
        "*Mentions:*\n"
        "Mention @BotAssistant in any channel for AI assistance!\n\n"
        "For more information, visit: https://rskworld.in"
    )
    
    respond(help_text)

@app.shortcut("automate_workflow")
def open_workflow_modal(ack, shortcut, client):
    """Global shortcut to trigger workflow automation."""
    ack()
    client.views_open(
        trigger_id=shortcut["trigger_id"],
        view={
            "type": "modal",
            "title": {"type": "plain_text", "text": "Workflow Automation"},
            "close": {"type": "plain_text", "text": "Close"},
            "submit": {"type": "plain_text", "text": "Run"},
            "blocks": [
                {
                    "type": "section",
                    "text": {"type": "mrkdwn", "text": "Select a workflow to automate:"}
                },
                {
                    "type": "input",
                    "element": {
                        "type": "static_select",
                        "placeholder": {"type": "plain_text", "text": "Select workflow"},
                        "options": [
                            {"text": {"type": "plain_text", "text": "Daily Sync Setup"}, "value": "sync"},
                            {"text": {"type": "plain_text", "text": "Ticket Escalation"}, "value": "escalation"},
                            {"text": {"type": "plain_text", "text": "Weekly Report"}, "value": "weekly_report"},
                            {"text": {"type": "plain_text", "text": "Onboarding Checklist"}, "value": "onboarding"}
                        ],
                        "action_id": "workflow_select"
                    },
                    "label": {"type": "plain_text", "text": "Workflow Type"}
                }
            ]
        }
    )

@app.error
def global_error_handler(error, body, logger):
    """Global error handler"""
    logger.error(f"Error: {error}")
    logger.error(f"Request body: {body}")

if __name__ == "__main__":
    print("šŸ¤– Slack Bot Assistant - Advanced Edition")
    print("=" * 50)
    print(f"Database: {'āœ… Enabled' if Config.ENABLE_DATABASE else 'āŒ Disabled'}")
    print(f"Scheduling: {'āœ… Enabled' if Config.ENABLE_SCHEDULING else 'āŒ Disabled'}")
    print(f"Weather API: {'āœ… Enabled' if Config.ENABLE_WEATHER else 'āŒ Disabled'}")
    print("=" * 50)
    
    if Config.SLACK_BOT_TOKEN and Config.SLACK_APP_TOKEN:
        try:
            handler = SocketModeHandler(app, Config.SLACK_APP_TOKEN)
            handler.start()
            print("āœ… Bot is running and listening for events...")
        except Exception as e:
            print(f"āŒ Error starting bot: {e}")
            print("Please check your SLACK_BOT_TOKEN and SLACK_APP_TOKEN environment variables.")
    else:
        print("āš ļø  Configuration Required")
        print("Please set the following environment variables:")
        print("  - SLACK_BOT_TOKEN")
        print("  - SLACK_SIGNING_SECRET")
        print("  - SLACK_APP_TOKEN (for Socket Mode)")
846 lines•30.8 KB
python
šŸš€ Support RSK World

Subscribe to our YouTube channel for latest tutorials & updates!



Click subscribe & support our work ā¤ļø

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