BotOfTheSpecter Help

Run BotOfTheSpecter Yourself

Self-host BotOfTheSpecter and have complete control over your bot deployment

Complete Freedom & Control

To run the source code of BotOfTheSpecter on your own set of servers and not use our hosted system, you'll have complete freedom to host it yourself with more control over your data. BotOfTheSpecter runs on a full headless Linux server architecture.

Advanced Setup Required

Running SpecterSystems yourself requires technical knowledge of server administration, Python, PHP and Linux. This is recommended for experienced developers and system administrators only.

Server Architecture

Recommended Hosting: Linode

We recommend running the SpecterSystems on Linode. Our systems have been fully tested and optimized to work seamlessly on Linode's infrastructure.

Get $100 in free credit: Use our referral link to receive $100 of Linode credit to use within 60 days once you've entered a valid payment method to your Linode account.

Get $100 Linode Credit

Minimum Requirements: 4 Servers

The minimum server setup required to run SpecterSystems consists of 4 servers running on a headless Linux architecture:

Server 1: Web/Dashboard
  • OS: Linux (Ubuntu 24.04 LTS+)
  • CPU: 1+ core
  • RAM: 1GB minimum
  • Service: PHP/Apache2 Dashboard
Server 2: API
  • OS: Linux (Ubuntu 24.04 LTS+)
  • CPU: 1+ core
  • RAM: 1GB minimum
  • Service: FastAPI server
Server 3: WebSocket
  • OS: Linux (Ubuntu 24.04 LTS+)
  • CPU: 1+ core
  • RAM: 1GB minimum
  • Service: Python SocketIO server
Server 4: Database
  • OS: Linux (Ubuntu 24.04 LTS+)
  • CPU: 2+ cores
  • RAM: 4GB minimum
  • Service: MySQL

Recommended Setup: 5 Servers

For production deployments with improved reliability and scalability, a 5-server setup is recommended, adding a dedicated bot server (this is how SpecterSystems currently runs):

Server 5: Bot
  • OS: Linux (Ubuntu 24.04 LTS+)
  • CPU: 2+ cores
  • RAM: 4GB minimum
  • Service: Python bot process
Note: The 2+ cores and 4GB RAM configuration is optimized for running many bots through the service for multiple users. If you're only running a single bot for personal use, 1 core and 1GB RAM is sufficient.

Common Software Requirements (All Servers)

  • OS: Linux (Ubuntu 24.04 LTS or newer)
  • Python: 3.8+ (Bot, API, and WebSocket servers)
  • PHP: 8.0+ (Web/Dashboard server)
  • Apache2: (Web/Dashboard server)
  • MySQL: (Database server)
  • Git: For version control

Network & Services

  • Twitch API credentials (OAuth tokens)
  • Discord bot token (optional)
  • Spotify API credentials (optional)
  • OpenWeatherMap API key (optional)
  • SSL/TLS certificates for secure communication
  • Firewall configured for internal communication

Installation Steps

Prerequisites (All Servers)

Before deploying to individual servers, ensure each Linux server has:

# Update system packages (All Servers)
sudo apt update && sudo apt upgrade -y

# Install common dependencies (All Servers)
sudo apt install -y curl wget git build-essential openssl ssl-cert

# Create botofthespecter user (All Servers)
sudo useradd -m -s /bin/bash botofthespecter
sudo usermod -aG sudo botofthespecter

# For Servers 1, 2, 3, 5 - Install Python and pip
sudo apt install -y python3 python3-pip python3-venv

# For Server 1 Only - Install PHP and Apache2
sudo apt install -y php php-cli php-fpm php-curl php-json php-mysql php-ssh2 apache2 libapache2-mod-php

# For Server 4 Only - Install MySQL
sudo apt install -y mysql-server
        

Step 1: Clone the Repository (Servers 1, 2, 3, 5)

Clone the BotOfTheSpecter repository to a temporary directory on each server (except Server 4 - Database):

cd /tmp
git clone https://github.com/YourStreamingTools/BotOfTheSpecter.git botofthespecter-temp
cd botofthespecter-temp

Then move the appropriate files to their destinations based on your server type:

For Server 1 (Web/Dashboard):
sudo rm -rf /var/www/html
sudo cp -r /tmp/botofthespecter-temp/dashboard /var/www/
sudo cp -r /tmp/botofthespecter-temp/home /var/www/
sudo cp -r /tmp/botofthespecter-temp/html /var/www/
sudo cp -r /tmp/botofthespecter-temp/overlay /var/www/
sudo cp -r /tmp/botofthespecter-temp/roadmap /var/www/
sudo cp -r /tmp/botofthespecter-temp/tts /var/www/
sudo cp -r /tmp/botofthespecter-temp/walkons /var/www/
sudo cp -r /tmp/botofthespecter-temp/videoalerts /var/www/
sudo cp -r /tmp/botofthespecter-temp/soundalerts /var/www/
sudo cp -r /tmp/botofthespecter-temp/config /var/www/
sudo cp -r /tmp/botofthespecter-temp/cdn /var/www/
sudo chown -R www-data:www-data /var/www
For Server 2 (API):
sudo cp -r /tmp/botofthespecter-temp/api /home/botofthespecter/
sudo chown -R botofthespecter:botofthespecter /home/botofthespecter
For Server 3 (WebSocket):
sudo cp -r /tmp/botofthespecter-temp/websocket /home/botofthespecter/
sudo chown -R botofthespecter:botofthespecter /home/botofthespecter
For Server 5 (Bot):
sudo cp -r /tmp/botofthespecter-temp/bot /home/botofthespecter/
sudo chown -R botofthespecter:botofthespecter /home/botofthespecter
Clean up temporary directory (All Servers):
rm -rf /tmp/botofthespecter-temp

Step 2: Configure Database Server (Server 4 Only)

Note: Server 4 (Database) does not require any files from the repository. It only needs MySQL installed and configured.

Important: User-specific databases are created automatically on login, so you do not need to create them manually.

You only need to create the following databases manually:

Required Databases:
  • spam_patterns - For the bot to auto-ban users matching spam patterns
  • website - For the main website
  • specterdiscordbot - If running the Discord bot (optional)
  • roadmap - If running the roadmap site (optional)

Run the following SQL commands to set up the database(s). The user-specific databases are created automatically on login; the following are the manual databases and tables you should create for core features:

sudo mysql -u root -p
-- spam_patterns: stores spam regex/phrases for auto-ban
CREATE DATABASE IF NOT EXISTS spam_patterns;
USE spam_patterns;
CREATE TABLE IF NOT EXISTS spam_patterns (
    id INT AUTO_INCREMENT PRIMARY KEY,
    spam_pattern TEXT NOT NULL
);

-- roadmap: roadmap site schema
CREATE DATABASE IF NOT EXISTS roadmap;
USE roadmap;

-- roadmap_items: Main roadmap items
CREATE TABLE IF NOT EXISTS roadmap_items (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(255) NOT NULL,
    description LONGTEXT,
    category ENUM('REQUESTS', 'IN PROGRESS', 'BETA TESTING', 'COMPLETED', 'REJECTED') NOT NULL DEFAULT 'REQUESTS',
    subcategory ENUM('TWITCH BOT', 'DISCORD BOT', 'WEBSOCKET SERVER', 'API SERVER', 'WEBSITE') NOT NULL,
    priority ENUM('LOW', 'MEDIUM', 'HIGH', 'CRITICAL') NOT NULL DEFAULT 'MEDIUM',
    website_type ENUM('DASHBOARD', 'OVERLAYS') DEFAULT NULL,
    completed_date DATE,
    created_by VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_category (category),
    INDEX idx_subcategory (subcategory),
    INDEX idx_priority (priority),
    INDEX idx_created_at (created_at)
);

-- roadmap_comments: Comments on roadmap items
CREATE TABLE IF NOT EXISTS roadmap_comments (
    id INT PRIMARY KEY AUTO_INCREMENT,
    item_id INT NOT NULL,
    username VARCHAR(255) NOT NULL,
    comment TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (item_id) REFERENCES roadmap_items(id) ON DELETE CASCADE,
    INDEX idx_item_id (item_id),
    INDEX idx_created_at (created_at)
);

-- specterdiscordbot: Discord bot
CREATE DATABASE IF NOT EXISTS specterdiscordbot;
USE specterdiscordbot;

-- channel_mappings
CREATE TABLE IF NOT EXISTS channel_mappings (
    channel_code VARCHAR(255) NOT NULL,
    guild_id VARCHAR(255) NOT NULL DEFAULT '',
    channel_id VARCHAR(255) NOT NULL DEFAULT '',
    channel_name VARCHAR(255),
    user_id VARCHAR(255),
    username VARCHAR(255),
    twitch_display_name VARCHAR(255),
    twitch_user_id VARCHAR(255),
    guild_name VARCHAR(255),
    stream_alert_channel_id VARCHAR(255),
    moderation_channel_id VARCHAR(255),
    alert_channel_id VARCHAR(255),
    online_text TEXT,
    offline_text TEXT,
    is_active TINYINT(1) DEFAULT 1,
    event_count INT DEFAULT 0,
    last_event_type VARCHAR(255),
    last_seen_at TIMESTAMP NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (channel_code),
    KEY idx_guild_id (guild_id),
    KEY idx_channel_id (channel_id),
    KEY idx_twitch_user_id (twitch_user_id)
);

-- live_notifications
CREATE TABLE IF NOT EXISTS live_notifications (
    guild_id VARCHAR(255) NOT NULL DEFAULT '',
    username VARCHAR(255) NOT NULL,
    stream_id VARCHAR(255) NOT NULL,
    started_at DATETIME,
    posted_at DATETIME,
    PRIMARY KEY (guild_id, stream_id),
    KEY idx_username (username)
);

-- role_selection_messages
CREATE TABLE IF NOT EXISTS role_selection_messages (
    id INT AUTO_INCREMENT PRIMARY KEY,
    server_id VARCHAR(255),
    channel_id VARCHAR(255),
    message_id VARCHAR(255),
    message_text TEXT,
    mappings TEXT,
    role_mappings JSON,
    allow_multiple TINYINT(1) DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    KEY idx_server_id (server_id),
    KEY idx_channel_id (channel_id),
    KEY idx_message_id (message_id)
);

-- rules_messages
CREATE TABLE IF NOT EXISTS rules_messages (
    id INT AUTO_INCREMENT PRIMARY KEY,
    server_id VARCHAR(255),
    channel_id VARCHAR(255),
    message_id VARCHAR(255),
    title TEXT,
    rules_content TEXT,
    color VARCHAR(7),
    accept_role_id VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    KEY idx_server_id (server_id),
    KEY idx_channel_id (channel_id),
    KEY idx_message_id (message_id)
);

-- server_management
CREATE TABLE IF NOT EXISTS server_management (
    id INT AUTO_INCREMENT PRIMARY KEY,
    server_id VARCHAR(255) NOT NULL,
    welcomeMessage TINYINT(1) DEFAULT 0,
    autoRole TINYINT(1) DEFAULT 0,
    roleHistory TINYINT(1) DEFAULT 0,
    messageTracking TINYINT(1) DEFAULT 0,
    roleTracking TINYINT(1) DEFAULT 0,
    serverRoleManagement TINYINT(1) DEFAULT 0,
    userTracking TINYINT(1) DEFAULT 0,
    reactionRoles TINYINT(1) DEFAULT 0,
    rulesConfiguration TINYINT(1) DEFAULT 0,
    streamSchedule TINYINT(1) DEFAULT 0,
    stream_schedule_configuration TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    welcome_message_configuration_channel VARCHAR(255),
    welcome_message_configuration_message VARCHAR(50),
    welcome_message_configuration_default INT,
    welcome_message_configuration_embed TINYINT(1) DEFAULT 0,
    welcome_message_configuration_colour VARCHAR(7) DEFAULT '#00d1b2',
    auto_role_assignment_configuration_role_id VARCHAR(255),
    role_history_configuration_setting INT,
    role_history_configuration_option VARCHAR(255),
    message_tracking_configuration_channel VARCHAR(255),
    message_tracking_configuration_message_edits INT,
    message_tracking_configuration_message_delete INT,
    role_tracking_configuration_channel VARCHAR(255),
    role_tracking_configuration_role_added INT,
    role_tracking_configuration_role_removed INT,
    server_role_management_configuration_channel VARCHAR(255),
    server_role_management_configuration_role_created INT,
    server_role_management_configuration_role_deleted INT,
    user_tracking_configuration_channel VARCHAR(255),
    user_tracking_configuration_nickname INT,
    user_tracking_configuration_avatar INT,
    user_tracking_configuration_status INT,
    reaction_roles_configuration JSON,
    rules_configuration JSON,
    KEY idx_server_id (server_id)
);

-- tickets
CREATE TABLE IF NOT EXISTS tickets (
    ticket_id INT AUTO_INCREMENT PRIMARY KEY,
    guild_id VARCHAR(255) NOT NULL DEFAULT '',
    user_id VARCHAR(255) NOT NULL DEFAULT '',
    username VARCHAR(255),
    channel_id VARCHAR(255),
    issue TEXT,
    status ENUM('open','closed') NOT NULL DEFAULT 'open',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    closed_at DATETIME NULL,
    closed_by BIGINT NULL,
    KEY idx_guild_id (guild_id),
    KEY idx_user_id (user_id)
);

-- ticket_comments
CREATE TABLE IF NOT EXISTS ticket_comments (
    comment_id INT AUTO_INCREMENT PRIMARY KEY,
    guild_id VARCHAR(255),
    ticket_id INT NOT NULL,
    user_id VARCHAR(255),
    username VARCHAR(255),
    comment TEXT NOT NULL,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    KEY idx_ticket_id (ticket_id),
    FOREIGN KEY (ticket_id) REFERENCES tickets(ticket_id) ON DELETE CASCADE
);

-- ticket_history
CREATE TABLE IF NOT EXISTS ticket_history (
    history_id INT AUTO_INCREMENT PRIMARY KEY,
    ticket_id INT NOT NULL,
    user_id VARCHAR(255),
    username VARCHAR(255),
    action VARCHAR(100),
    details TEXT,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    KEY idx_ticket_id (ticket_id),
    FOREIGN KEY (ticket_id) REFERENCES tickets(ticket_id) ON DELETE CASCADE
);

-- ticket_settings
CREATE TABLE IF NOT EXISTS ticket_settings (
    id INT AUTO_INCREMENT PRIMARY KEY,
    guild_id VARCHAR(255),
    owner_id VARCHAR(255),
    info_channel_id VARCHAR(255),
    category_id VARCHAR(255),
    closed_category_id VARCHAR(255),
    support_role_id VARCHAR(255),
    mod_channel_id VARCHAR(255),
    enabled TINYINT(1) DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- website: core website tables (api metrics, users, tokens, settings)
CREATE DATABASE IF NOT EXISTS website;
USE website;

CREATE TABLE IF NOT EXISTS api_counts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    type VARCHAR(50),
    count INT DEFAULT 0,
    reset_day INT,
    updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS discord_users (
    user_id INT AUTO_INCREMENT PRIMARY KEY,
    discord_id VARCHAR(255),
    access_token VARCHAR(255),
    refresh_token VARCHAR(255),
    reauth INT DEFAULT 0,
    manual_ids INT DEFAULT 0,
    guild_id VARCHAR(255),
    live_channel_id VARCHAR(255),
    stream_alert_channel_id VARCHAR(255),
    moderation_channel_id VARCHAR(255),
    alert_channel_id VARCHAR(255),
    member_streams_id VARCHAR(255),
    stream_alert_everyone TINYINT(1) DEFAULT 1,
    stream_alert_custom_role VARCHAR(255),
    online_text VARCHAR(20) DEFAULT 'Live on Twitch',
    offline_text VARCHAR(20) DEFAULT 'Not Live',
    auto_role_id VARCHAR(255)
);

CREATE TABLE IF NOT EXISTS languages (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    code VARCHAR(50) NOT NULL
);

CREATE TABLE IF NOT EXISTS moderator_access (
    moderator_id VARCHAR(255) NOT NULL,
    broadcaster_id VARCHAR(255) NOT NULL,
    PRIMARY KEY (moderator_id, broadcaster_id)
);

CREATE TABLE IF NOT EXISTS restricted_users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50),
    twitch_user_id VARCHAR(50)
);

CREATE TABLE IF NOT EXISTS spotify_tokens (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT,
    email TEXT DEFAULT NULL,
    has_access INT DEFAULT 0,
    access_token VARCHAR(255),
    refresh_token VARCHAR(255),
    auth TINYINT DEFAULT 1,
    own_client TINYINT DEFAULT 0,
    client_id VARCHAR(255) NULL,
    client_secret VARCHAR(255) NULL
);

CREATE TABLE IF NOT EXISTS streamelements_tokens (
    twitch_user_id VARCHAR(50) PRIMARY KEY,
    access_token VARCHAR(255),
    refresh_token VARCHAR(255),
    jwt_token LONGTEXT DEFAULT NULL
);

CREATE TABLE IF NOT EXISTS streamlabs_tokens (
    twitch_user_id VARCHAR(255) PRIMARY KEY,
    access_token VARCHAR(255),
    refresh_token VARCHAR(255)
);

CREATE TABLE IF NOT EXISTS system_metrics (
    id INT AUTO_INCREMENT PRIMARY KEY,
    server_name VARCHAR(255),
    cpu_percent FLOAT,
    ram_percent FLOAT,
    ram_used FLOAT,
    ram_total FLOAT,
    disk_percent FLOAT,
    disk_used FLOAT,
    disk_total FLOAT,
    net_sent FLOAT,
    net_recv FLOAT,
    last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS timezones (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255)
);

CREATE TABLE IF NOT EXISTS twitch_bot_access (
    twitch_user_id VARCHAR(255) PRIMARY KEY,
    twitch_access_token VARCHAR(255)
);

CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50),
    twitch_display_name VARCHAR(50),
    twitch_user_id VARCHAR(255),
    access_token VARCHAR(255) DEFAULT NULL,
    refresh_token VARCHAR(255) DEFAULT NULL,
    api_key VARCHAR(32),
    is_admin TINYINT(1) DEFAULT 0,
    beta_access TINYINT(1) DEFAULT 0,
    is_technical TINYINT(1) DEFAULT 0,
    signup_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    last_login TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    profile_image VARCHAR(255) DEFAULT 'https://cdn.botofthespecter.com/noimage.png',
    email VARCHAR(255) DEFAULT NULL,
    app_password VARCHAR(50) DEFAULT NULL,
    language VARCHAR(5) DEFAULT 'EN'
);

-- custom_bots: Stores any user-created/custom bot entries
CREATE TABLE IF NOT EXISTS custom_bots (
    channel_id VARCHAR(255) NOT NULL,
    bot_username VARCHAR(255),
    bot_channel_id VARCHAR(255),
    access_token VARCHAR(255),
    refresh_token VARCHAR(255),
    token_expires DATETIME,
    is_verified INT DEFAULT 0,
    PRIMARY KEY (channel_id)
);

-- feedback: User-submitted feedback/messages for the site & services
CREATE TABLE IF NOT EXISTS feedback (
    id INT AUTO_INCREMENT PRIMARY KEY,
    twitch_user_id VARCHAR(64),
    display_name VARCHAR(255),
    message TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Then create your database user with access to all databases:

CREATE USER 'your_username'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON *.* TO 'your_username'@'%';
FLUSH PRIVILEGES;

Configure MySQL to accept connections from other servers by editing /etc/mysql/mysql.conf.d/mysqld.cnf:

bind-address = 0.0.0.0

Step 3: Set Up Python Environment (Servers 2, 3, & 5)

All application servers share the same repository path: /home/botofthespecter. Create the virtual environment in that directory and use the venv's pip/python directly so commands are deterministic and work the same on every server.

Recommended venv location: /home/botofthespecter/botofthespecter

# create the venv (run as the botofthespecter user)
python3 -m venv botofthespecter
# install all required packages from the single shared requirements file
/home/botofthespecter/botofthespecter/bin/pip install -r /home/botofthespecter/requirements.txt

Production notes:

  • Reference the virtualenv executables directly in systemd unit files. Example: Environment="PATH=/home/botofthespecter/botofthespecter/bin" and ExecStart=/home/botofthespecter/botofthespecter/bin/python /home/botofthespecter/api/api.py.
  • Always run the venv creation and package installs as the botofthespecter user to ensure correct ownership of files and installed packages.
  • Always run the venv creation and package installs as the botofthespecter user to ensure correct ownership of files and installed packages.
  • Step 4: Configure Environment Variables (All Servers)

    Create a .env file in /home/botofthespecter with your configuration. Replace the database credentials with the username and password you created in Step 2:

    # SQL Data
    SQL_HOST=
    SQL_USER=
    SQL_PASSWORD=
    SQL_PORT=
    # API STUFF
    SHAZAM_API=
    WEATHER_API=
    STEAM_API=
    OPENAI_KEY=
    STREAMELEMENTS_CLIENT_ID=
    STREAMELEMENTS_SECRET_KEY=
    HYPERATE_API_KEY=
    # Twitch Bot
    OAUTH_TOKEN=oauth:
    TWITCH_OAUTH_API_TOKEN=
    TWITCH_OAUTH_API_CLIENT_ID=
    CLIENT_ID=
    CLIENT_SECRET=
    TWITCH_GQL=
    TIMEZONE_API=
    EXCHANGE_RATE_API=
    SPOTIFY_CLIENT_ID=
    SPOTIFY_CLIENT_SECRET=
    # Discord Bot
    DISCORD_TOKEN=
    DISCORD_PUBLIC_KEY=
    API_KEY=
    DISCORD_CLIENT_ID=
    DISCORD_CLIENT_SECRET=
    # Guided Bot
    GUIDED_BOT_USER_ID=
    GUIDED_BOT_TOKEN=
    # ADMINS
    ADMIN_KEY=
    # BACKUP SYSTEM
    USE_BACKUP_SYSTEM=False
    BACKUP_CLIENT_ID=
    BACKUP_SECRET_KEY=
    # SSH Settings
    SSH_USERNAME=
    SSH_PASSWORD=
    API-HOST=
    WEBSOCKET-HOST=
    BOT-SRV-HOST=
    SQL-HOST=
    WEB-HOST=
    BILLING-HOST=
    STREAM-AU-EAST-1-HOST=
    STREAM-US-EAST-1-HOST=
    STREAM-US-WEST-1-HOST=

    Step 5: Set Up Python Environment (Server 3 - WebSocket)

    Install Python dependencies for the WebSocket server:

    cd /home/botofthespecter
    source /home/botofthespecter/botofthespecter/bin/activate
    /home/botofthespecter/botofthespecter/bin/pip install -r /home/botofthespecter/requirements.txt

    Step 6: Set Up Web Server (Server 1)

    Configure Apache2 to serve the PHP dashboard:

    sudo apt install -y apache2 libapache2-mod-php
    # Enable Apache2 modules
    sudo a2enmod rewrite
    sudo a2enmod php8.1
    # Create Apache2 configuration
    sudo nano /etc/apache2/sites-available/botofthespecter.conf

    Configure Apache (or your web server) however you prefer. You must serve the dashboard and related assets under your domain and the following example subdomains. We don't enforce a specific VirtualHost layout — pick the configuration that matches your infrastructure and SSL setup.

    Example DNS / subdomain names you should configure for your deployment:
    example.com
    dashboard.example.com
    overlay.example.com
    videoalert.example.com
    soundalert.example.com
    tts.example.com
    
    Tip: Use separate subdomains for static assets or features you want to scale independently.
    Ensure each subdomain points to the correct server (Server 1 for the dashboard/static sites) and that TLS is enabled (Let's Encrypt is recommended).

    Running the Services

    Server 1: Start the Web/Dashboard Server

    Ensure Apache2 and PHP are running:

    sudo systemctl enable apache2
    sudo systemctl start apache2
    sudo systemctl status apache2

    Server 2: Start the API Server

    From the API Server:

    cd /home/botofthespecter
    source /home/botofthespecter/botofthespecter/bin/activate
    # Run the API with TLS (replace the paths with your domain's Let's Encrypt certs)
    python -m uvicorn api.api:app --host 0.0.0.0 --port 443 \
      --ssl-keyfile=/etc/letsencrypt/live/api.example.com/privkey.pem \
      --ssl-certfile=/etc/letsencrypt/live/api.example.com/fullchain.pem

    Note: TLS is required for the API server. Update the cert paths above to match your domain (for example: /etc/letsencrypt/live/api.botofthespecter.com/privkey.pem).

    For production, create a systemd service similar to the bot service below.

    Server 3: Start the WebSocket Server

    From the WebSocket Server:

    cd /home/botofthespecter
    source /home/botofthespecter/botofthespecter/bin/activate
    python /home/botofthespecter/server.py

    For production, create a systemd service similar to the bot service below.

    Server 4: MySQL/MariaDB Database

    Ensure the database service is running:

    sudo systemctl enable mysql
    sudo systemctl start mysql
    sudo systemctl status mysql

    Server 5: Bot Service

    The bot is controlled and started from the dashboard (Server 1). No manual setup or startup is required on Server 5; it is ready once the Python environment and `.env` configuration from the earlier steps are complete.

    Inter-Server Networking

    Configure your servers to communicate securely with each other:

    • Internal Network: Use private IP addresses for inter-server communication
    • DNS/Hostnames: Set up DNS or /etc/hosts entries for server-to-server connections
    • Firewall Rules: Only allow necessary ports between servers
    • SSL/TLS: Encrypt communication between services

    Firewall Configuration Example

    # Server 1 (Web) - Allow HTTP/HTTPS and communication with other services
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw allow from 10.10.10.2:8001  # API Server
    sudo ufw allow from 10.10.10.3:8000  # WebSocket Server
    sudo ufw allow from 10.10.10.4:3306  # Database Server
    
    # Server 2 (API) - Allow inbound from Web and Bot servers
    sudo ufw allow from 10.10.10.1:any   # Web Server
    sudo ufw allow from 10.10.10.5:any   # Bot Server
    
    # Server 3 (WebSocket) - Allow inbound from Web and Bot servers
    sudo ufw allow from 10.10.10.1:any   # Web Server
    sudo ufw allow from 10.10.10.5:any   # Bot Server
    
    # Server 4 (Database) - Allow inbound from all services
    sudo ufw allow from 10.10.10.1:any   # Web Server
    sudo ufw allow from 10.10.10.2:any   # API Server
    sudo ufw allow from 10.10.10.5:any   # Bot Server
    
    # Server 5 (Bot) - Allow outbound to API, WebSocket, and Database
    sudo ufw allow to 10.10.10.2:8001    # API Server
    sudo ufw allow to 10.10.10.3:8000    # WebSocket Server
    sudo ufw allow to 10.10.10.4:3306    # Database Server

    Security Considerations

    • HTTPS/SSL: Always use SSL certificates for secure communication (Let's Encrypt is free)
    • Firewall: Configure firewalls to restrict database access to localhost only
    • Environment Variables: Never commit .env files to version control
    • Database Backups: Set up automated daily backups of your database
    • Updates: Keep dependencies updated to patch security vulnerabilities
    • Monitoring: Monitor system resources and bot logs for issues

    Troubleshooting

    Bot Not Connecting to Twitch

    • Verify your OAuth token is valid and not expired
    • Check that your Twitch Client ID and Secret are correct
    • Ensure the bot account has the proper permissions in your channel
    • Review logs in bot/logs/ for error messages

    Database Connection Errors

    • Verify MySQL/MariaDB is running
    • Check database credentials in .env and configuration files
    • Ensure the user has proper database permissions
    • Test connection: mysql -u botuser -p -h localhost botofthespecter

    API Server Not Responding

    • Verify FastAPI/Uvicorn is running correctly
    • Check that port 443 is not in use by another service
    • Review API logs for startup errors
    • Ensure all Python dependencies are installed

    WebSocket Connection Issues

    • Verify WebSocket server is running on port 8000
    • Check firewall rules allow WebSocket connections
    • Ensure the WebSocket URL is correctly configured in clients
    • Review WebSocket server logs for errors

    Maintenance

    Regular Tasks

    • Daily: Check logs for errors and unusual activity
    • Weekly: Verify all services are running and responsive
    • Monthly: Update dependencies and apply security patches
    • Quarterly: Review and optimize database performance

    Updating BotOfTheSpecter

    git pull origin main
    pip install -r bot/requirements.txt --upgrade
    pip install -r api/requirements.txt --upgrade

    Need Help?

    If you encounter issues while self-hosting BotOfTheSpecter: