k.eaven 204cc6704c
CI/CD Pipeline / Unit Tests (Python 3.12) (push) Failing after 7s
CI/CD Pipeline / Unit Tests (Python 3.11) (push) Successful in 32s
CI/CD Pipeline / Security Scanning (push) Successful in 27s
CI/CD Pipeline / Build Docker Image (push) Skipped
CI/CD Pipeline / CI/CD Pipeline Status (push) Successful in 1s
CI/CD Pipeline / Unit Tests (Python 3.13) (push) Successful in 34s
CI/CD Pipeline / Integration Tests (push) Skipped
CI/CD Pipeline / Code Quality & Linting (push) Successful in 28s
CI/CD Pipeline / Generate Test Report (push) Successful in 3s
Chore: correct errors in README
2026-10-30 11:06:14 +00:00
2025-09-10 09:47:04 -07:00
2025-09-22 16:16:23 +00:00
2025-10-26 13:26:49 +00:00
2025-10-23 13:20:39 +00:00
2025-07-17 11:47:42 +00:00
2026-10-30 11:06:14 +00:00

Pterodisbot the Pterodactyl Discord Bot

Pterodactyl X Discord

A feature-rich Discord bot for monitoring and managing Pterodactyl game servers through Discord, providing real-time status monitoring and control capabilities with an intuitive interface.

Table of Contents

Features

🎮 Server Management

  • Interactive Server Selection: Choose servers from an intuitive dropdown menu showing all available game servers
  • Real-time Power Controls: Start, stop, and restart servers with color-coded button controls
    • 🟢 Green Start button
    • 🔴 Red Stop button
    • 🔵 Blue Restart button
  • Connection Information: Instantly view server IP addresses and ports with the "Show Address" button
  • Multi-channel Embeds: Deploy server status displays across any channels where the bot has permissions

📊 Server Monitoring

  • Live Status Tracking: Auto-updating embeds display current server state (online/offline/starting)
  • Resource Usage Metrics: Detailed monitoring of:
    • CPU usage with dynamic scaling for multi-core servers
    • Memory consumption in real-time
    • Disk space utilization
    • Network activity (incoming/outgoing traffic)
    • Server uptime counter with human-readable formatting
  • Visual Metrics Graphs:
    • Combined CPU and memory usage graphs over the last minute
    • 6 data points captured at 10-second intervals
    • Discord dark theme-optimized styling
    • Automatic graph generation and embedding for running servers
    • Dynamic CPU scaling (100% increments) for accurate multi-vCPU visualization
    • Trend indicators (increasing/decreasing/stable) for quick status assessment

🔄 Intelligent Update System

  • Smart Update Triggers: Embeds refresh automatically when:
    • Server power state changes (offline ↔ starting ↔ running)
    • CPU usage shifts by more than 50%
    • Server is detected for the first time
    • Running servers reach 10-minute intervals (for uptime accuracy)
  • Rate Limit Protection: Built-in delays prevent Discord API throttling
  • Optimized API Calls: Minimizes unnecessary requests through change detection
  • Background Task Management: Asynchronous update loop runs every 10 seconds

🔒 Security & Access Control

  • Multi-Guild Support: Bot operates across multiple designated Discord servers simultaneously
  • Per-Guild Server Tracking: Each guild tracks servers independently with isolated embeds
  • Role-based Permissions: "Game Server User" role required for all server interactions (per guild)
  • Administrator Commands: Special management commands restricted to server administrators (per guild)
  • Interaction Validation: Every button press and command verified for proper authorization within its guild

💾 Data Persistence

  • Embed Location Storage: Automatically remembers where embeds are posted (survives bot restarts)
  • JSON-based Storage: Human-readable embed tracking in embed_locations.json
  • Metrics History: Maintains 1 minute of server metrics data (6 data points per server)
  • Automatic Cleanup: Removes tracking for deleted embeds and inactive servers

🛡️ Reliability Features

  • Comprehensive Error Handling: Graceful recovery from API failures and network issues
  • Rotating Log Files: Automatic log rotation (5MB max, 3 backup files)
  • Debug-level Logging: Detailed operation logs for troubleshooting
  • Graceful Shutdown: Proper cleanup on SIGINT/SIGTERM signals (Docker-friendly)
  • Configuration Validation: Startup verification of all required settings
  • API Key Validation: Checks for correct Pterodactyl API key formats

🎨 User Interface

  • Color-coded Status: Visual indicators for server states
    • 🔵 Blue for online servers
    • 🔴 Red for offline servers
  • Ephemeral Interactions: Private responses visible only to command users
  • Real-time Feedback: Instant confirmation messages for all actions
  • Persistent Controls: Server control buttons remain functional indefinitely
  • Responsive Design: Clean, Discord-optimized embed layouts

🔧 Administrator Tools

  • Bulk Embed Refresh: Force-refresh all server status embeds with one command
  • Complete Purge System: Remove all bot embeds from the server with detailed statistics
  • Progress Tracking: Real-time progress updates during multi-embed operations
  • Comprehensive Logging: All administrative actions logged with user attribution

Installation

Discord Bot Setup

Before installing the bot software, you need to create a Discord application and bot account.

1. Create Discord Application

  1. Navigate to the Discord Developer Portal
  2. Click the "New Application" button in the top-right corner
  3. Enter a name for your application (e.g., "Pterodactyl Bot")
  4. Accept the Terms of Service and click "Create"

2. Configure Bot Settings

  1. In the left sidebar, click on "Bot"
  2. Click "Add Bot" and confirm by clicking "Yes, do it!"
  3. Under the bot's username, you'll see a Token section:
    • Click "Reset Token" and then "Copy" to get your bot token
    • ⚠️ Keep this token secret! Never share it publicly or commit it to version control
  4. Scroll down to "Privileged Gateway Intents" and enable:
    • ✅ Message Content Intent (required for the bot to read message content)
  5. Click "Save Changes" at the bottom

3. Set Bot Permissions

  1. In the left sidebar, click on "OAuth2" → "URL Generator"
  2. Under "Scopes", select:
    • ✅ bot
    • ✅ applications.commands
  3. Under "Bot Permissions", select:
    • ✅ View Channels (allows bot to see channels)
    • ✅ Send Messages (allows bot to post embeds)
    • ✅ Embed Links (required for rich embeds)
    • ✅ Attach Files (required for metrics graphs)
    • ✅ Read Message History (allows bot to edit existing messages)
    • ✅ Use Slash Commands (required for /server_status commands)

4. Invite Bot to Your Server

  1. Copy the Generated URL at the bottom of the OAuth2 URL Generator page
  2. Paste this URL into your browser and press Enter
  3. Select the Discord server where you want to add the bot
  4. Click "Authorize" and complete the CAPTCHA if prompted
  5. The bot should now appear in your server (offline until you start the application)

5. Get Your Guild ID

  1. In Discord, enable Developer Mode:
    • Click the ⚙️ gear icon (User Settings)
    • Navigate to "Advanced" under "App Settings"
    • Toggle on "Developer Mode"
  2. Right-click on your server icon in the left sidebar
  3. Click "Copy Server ID" at the bottom of the menu
  4. Save this ID - you'll need it for the bot configuration

6. Create Server Role

  1. In your Discord server, click the server name at the top to open the dropdown menu
  2. Select "Server Settings" → "Roles"
  3. Click "Create Role"
  4. Name the role exactly: Game Server User
  5. The role doesn't need any special permissions - it's only used for bot access control
  6. Click "Save Changes"
  7. Assign this role to any users who should be able to control game servers

Prerequisites

  • Python 3.8 or higher or Docker
  • Discord bot token (from setup above)
  • Discord server (guild) ID (from setup above)
  • Pterodactyl panel with API access
  • Pterodactyl Client API key (starts with ptlc_)
  • Pterodactyl Application API key (starts with ptla_)

Traditional Installation

  1. Clone the repository:

    git clone https://git.serendipity.systems/k.eaven/pterodisbot.git
    cd pterodactyl-discord-bot
    
  2. Install required dependencies:

    pip install -r requirements.txt
    
  3. Create and configure your config.ini file (see Configuration section)

  4. Run the bot:

    python pterodisbot.py
    

Docker Installation

  1. Clone the repository:

    git clone https://git.serendipity.systems/k.eaven/pterodisbot.git
    cd pterodactyl-discord-bot
    
  2. Build the Docker image:

    docker build -t pterodisbot .
    
  3. Create a directory for configuration:

    mkdir -p bot-config
    
  4. Create a config.ini file in the bot-config directory with your settings

  5. Run the container with the config mounted:

    docker run -d \
      --name pterodisbot \
      -v $(pwd)/bot-config:/app \
      pterodisbot
    
  6. For Docker Compose, create a docker-compose.yml file:

    services:
      pterodisbot:
        build: .
        environment:
          # Remove brackets and spaces in environment variables
          # Ideally, use .env file to assign values to these instead
          - DISCORD_TOKEN={Your Discord bot token from Developer Portal}
          - ALLOWED_GUILD_ID={Your Discord server ID from step 5 above}
          - PANEL_URL={Your Pterodactyl panel URL with https://}
          - CLIENT_API_KEY={Pterodactyl client API key starting with ptlc_}
          - APPLICATION_API_KEY={Pterodactyl application API key starting with ptla_}
        volumes:
          - bot_logs:/app/logs
          - bot_embed:/app/embed
        restart: unless-stopped
    
    volumes:
      bot_logs:
      bot_embed:
    

    Then run:

    docker-compose up -d
    

Kubernetes Installation

  1. Clone the repository:

    git clone https://git.serendipity.systems/k.eaven/pterodisbot.git
    cd pterodactyl-discord-bot
    
  2. Build and push the Docker image to your container registry:

    docker build -t your-registry/pterodisbot:latest .
    docker push your-registry/pterodisbot:latest
    
  3. Create a Kubernetes namespace (optional but recommended):

    kubectl create namespace pterodisbot
    
  4. Create a Kubernetes Secret with your configuration:

    kubectl create secret generic pterodisbot-config \
      --from-literal=DISCORD_TOKEN='your-discord-bot-token' \
      --from-literal=ALLOWED_GUILD_ID='your-discord-guild-id' \
      --from-literal=PANEL_URL='https://your.pterodactyl.panel' \
      --from-literal=CLIENT_API_KEY='ptlc_your-client-api-key' \
      --from-literal=APPLICATION_API_KEY='ptla_your-application-api-key' \
      -n pterodisbot
    
  5. Create a PersistentVolumeClaim for logs and embed data:

    # pvc.yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pterodisbot-data
      namespace: pterodisbot
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    
    kubectl apply -f pvc.yaml
    
  6. Create the Deployment:

    # deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pterodisbot
      namespace: pterodisbot
      labels:
        app: pterodisbot
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: pterodisbot
      template:
        metadata:
          labels:
            app: pterodisbot
        spec:
          containers:
            - name: pterodisbot
              image: your-registry/pterodisbot:latest
              imagePullPolicy: Always
              envFrom:
                - secretRef:
                    name: pterodisbot-config
              volumeMounts:
                - name: pterodisbot-data
                  mountPath: /app/logs
                  subPath: logs
                - name: pterodisbot-data
                  mountPath: /app/embed
                  subPath: embed
              resources:
                requests:
                  memory: "256Mi"
                  cpu: "100m"
                limits:
                  memory: "512Mi"
                  cpu: "500m"
              livenessProbe:
                exec:
                  command: ["python", "-c", "import sys; sys.exit(0)"]
                initialDelaySeconds: 30
                periodSeconds: 30
              readinessProbe:
                exec:
                  command: ["python", "-c", "import sys; sys.exit(0)"]
                initialDelaySeconds: 10
                periodSeconds: 10
          volumes:
            - name: pterodisbot-data
              persistentVolumeClaim:
                claimName: pterodisbot-data
    
    kubectl apply -f deployment.yaml
    
  7. (Optional) Create a Service if you need to expose metrics or health checks:

    # service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: pterodisbot
      namespace: pterodisbot
      labels:
        app: pterodisbot
    spec:
      selector:
        app: pterodisbot
      ports:
        - name: http
          port: 8080
          targetPort: 8080
      type: ClusterIP
    
    kubectl apply -f service.yaml
    
  8. (Optional) Create a HorizontalPodAutoscaler for automatic scaling:

    # hpa.yaml
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: pterodisbot
      namespace: pterodisbot
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: pterodisbot
      minReplicas: 1
      maxReplicas: 3
      metrics:
        - type: Resource
          resource:
            name: cpu
            target:
              type: Utilization
              averageUtilization: 70
    
    kubectl apply -f hpa.yaml
    
  9. Verify the deployment:

    kubectl get pods -n pterodisbot
    kubectl logs -n pterodisbot -l app=pterodisbot -f
    
  10. For production, consider using a Helm chart or Kustomize for better configuration management. Create a kustomization.yaml:

    # kustomization.yaml
    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    namespace: pterodisbot
    resources:
      - pvc.yaml
      - deployment.yaml
      - service.yaml
      - hpa.yaml
    images:
      - name: pterodisbot
        newTag: latest
    commonLabels:
      app: pterodisbot
    
    kubectl apply -k .
    

Configuration

Environment Variables

When using Docker or generating the config automatically, these environment variables are required:

  • DISCORD_TOKEN: Your Discord bot token (from Discord Developer Portal)
  • ALLOWED_GUILD_IDS: Comma-separated list of Discord server IDs where the bot should operate (e.g., 123456789,987654321)
  • PANEL_URL: Your Pterodactyl panel URL (must include http:// or https://)
  • CLIENT_API_KEY: Pterodactyl client API key (starts with ptlc_)
  • APPLICATION_API_KEY: Pterodactyl application API key (starts with ptla_)

Note

: The legacy ALLOWED_GUILD_ID (singular) environment variable is still supported for backward compatibility.

Configuration File

The bot uses a config.ini file with this structure:

[Pterodactyl]
PanelURL = https://your.pterodactyl.panel
ClientAPIKey = ptlc_yourclientkey
ApplicationAPIKey = ptla_yourapplicationkey

[Discord]
Token = your.discord.bot.token
AllowedGuildIDs = 123456789012345678,987654321098765432

To generate the config file from environment variables:

python generate_config.py

Usage

First Run Setup

  1. Ensure your bot is invited to your Discord server with proper permissions (see Discord Bot Setup)

  2. Verify the "Game Server User" role exists in your server

  3. Start the bot using your preferred installation method

  4. The bot should appear online in your server

  5. Use the /server_status command to create your first status embed

Bot Commands

All commands are guild-scoped - they only affect the guild (server) where they are invoked.

/server_status

Display an interactive dropdown menu containing all available servers from your Pterodactyl panel. Select a server to create a permanent status embed in the current channel with real-time monitoring and control buttons.

Features:

  • Shows total server count and online/offline statistics
  • Lists all servers with descriptions
  • Creates persistent, auto-updating embeds
  • Automatically removes old embeds when recreating for the same server in this guild

/refresh_embeds (Admin only)

Force a complete refresh of all server status embeds in the current guild. This command:

  • Recreates all tracked embeds with fresh data
  • Deletes old embed messages to prevent duplication
  • Updates embed tracking storage
  • Provides statistics on deleted and created embeds

Use cases:

  • Embeds appear out of sync with actual server states
  • After bot configuration changes
  • Following Discord API issues

/purge_embeds (Admin only)

Permanently delete all server status embeds from the current Discord server. This command:

  • Removes all tracked embed messages
  • Clears the embed tracking file for this guild
  • Provides real-time progress updates
  • Shows detailed statistics (deleted, missing, errors)

Use cases:

  • Starting fresh with new embed layout
  • Removing bot from server
  • Cleaning up after testing

Embed System

Status embeds dynamically display:

Header Information:

  • Server name with current state (color-coded)
  • Server description
  • Last updated timestamp

Status Fields:

  • 🆔 Server ID (Pterodactyl identifier)
  • ℹ️ Status (Active or Suspended)
  • ⏱️ Uptime (for running servers)

Resource Usage (when online):

  • CPU percentage with dynamic scaling
  • Memory usage (current vs. allocated)
  • Disk usage (current vs. allocated)
  • Network traffic (incoming/outgoing)

Metrics Visualization (when running):

  • Combined CPU and memory graph
  • Last 1 minute of data (6 data points)
  • Trend indicators
  • Data point counter

Interactive Buttons:

  • 🟢 Start - Powers on the server
  • 🔴 Stop - Gracefully shuts down the server
  • 🔵 Restart - Reboots the server
  • ⚪ Show Address - Displays connection information (IP:Port)

Automatic Updates: Embeds refresh when server state changes, including:

  • Power state transitions
  • Significant resource usage changes
  • Periodic updates for uptime accuracy

Embed locations are stored in embed/embed_locations.json and persist between bot restarts.

Permissions

The bot implements multi-guild access control with per-guild isolation:

1. Guild Allowlist

The bot only responds to commands and interactions from Discord servers whose IDs are listed in AllowedGuildIDs. This prevents unauthorized use if the bot is accidentally added to other servers.

2. Per-Guild Role-Based Access

Users must have the "Game Server User" role (exact name match) in the specific guild where they are interacting to:

  • Use server control buttons (Start/Stop/Restart)
  • View server addresses
  • Interact with any bot features

Each guild maintains its own "Game Server User" role independently.

3. Per-Guild Administrator Access

Server administrators (users with Discord's Administrator permission) in a specific guild can additionally:

  • Use /refresh_embeds command (affects only that guild)
  • Use /purge_embeds command (affects only that guild)
  • No special role required - based on Discord permissions in that guild

Note: The /server_status command can be used by anyone in an allowed guild, but only users with the "Game Server User" role in that guild can interact with the resulting embeds.

Logging System

The bot maintains comprehensive logs in two locations:

1. File Logs

  • Location: logs/pterodisbot.log
  • Rotation: Automatic rotation when file reaches 5MB
  • Backups: Keeps 3 previous log files (pterodisbot.log.1, .2, .3)
  • Format: YYYY-MM-DD HH:MM:SS - LEVEL - MESSAGE

2. Console Output

  • Real-time: Logs appear in stdout/stderr
  • Format: Same as file logs
  • Level: INFO and above (less verbose than file logs)

Log Levels

  • DEBUG: Detailed operational information (API calls, state changes, cache operations)
  • INFO: General operational messages (bot startup, command usage, successful operations)
  • WARNING: Potential issues (missing embeds, API warnings, permission issues)
  • ERROR: Operational failures (API errors, Discord API issues, failed operations)
  • CRITICAL: Critical failures (configuration errors, startup failures, unrecoverable errors)

Example Log Entries

2025-09-29 03:51:13,743 - INFO - Initialized logging system with file and console output
2025-09-29 03:51:16,828 - INFO - Starting full refresh of all server embeds
2025-09-29 03:51:16,829 - INFO - Bot connected as Petrodisbot (ID: 1419694924458360964)
2025-09-29 03:52:10,481 - INFO - Start button pressed for Minecraft Server by username
2025-09-29 03:52:14,406 - DEBUG - Power state changed for Minecraft Server: offline -> starting

Troubleshooting

Common Issues

Embeds not updating

Symptoms: Embeds show outdated information or don't change when server state changes

Solutions:

  • Verify the bot has proper channel permissions (View Channel, Send Messages, Embed Links)
  • Check that both API keys are valid and have correct permissions
  • Review logs for API errors or rate limiting
  • Use /refresh_embeds to force-recreate all embeds
  • Ensure the bot hasn't been rate-limited by Discord (check logs for HTTP 429 errors)

Buttons not working

Symptoms: Clicking Start/Stop/Restart buttons shows permission errors

Solutions:

  • Confirm users have the "Game Server User" role (exact name match)
  • Verify the role is properly assigned to users
  • Check bot permissions:
    • View Channel
    • Send Messages
    • Embed Links
    • Use Slash Commands
  • Ensure the interaction is happening in the correct Discord server (guild)

Commands not appearing

Symptoms: Slash commands don't show up when typing /

Solutions:

  • Wait 5-10 minutes after bot startup (command sync takes time)
  • Verify bot has "Use Slash Commands" permission
  • Check that the bot is in the correct guild (server)
  • Review logs for command sync errors
  • Try kicking and re-inviting the bot with proper OAuth2 URL

API errors

Symptoms: Bot logs show Pterodactyl API failures

Solutions:

  • Double-check your Pterodactyl panel URL (must include https://)
  • Verify API keys are correct and not expired
  • Confirm the server exists in Pterodactyl panel
  • Check API key permissions:
    • Client key needs: server resource access, power control
    • Application key needs: server list access, server details
  • Test API keys directly using Pterodactyl API documentation

Graphs not appearing

Symptoms: Embeds show "Usage Trends" section but no graph image

Solutions:

  • Wait at least 20 seconds after server starts (needs 2 data points minimum)
  • Check that the server is in "running" state
  • Verify matplotlib is installed correctly (pip install matplotlib)
  • Review logs for graph generation errors
  • Ensure /tmp/matplotlib directory has write permissions (Docker)

Bot crashes on startup

Symptoms: Bot exits immediately with configuration errors

Solutions:

  • Verify all required fields in config.ini:
    • No empty values
    • Correct format for all URLs (must include protocol)
    • API keys have correct prefixes (ptlc_ and ptla_)
    • Guild ID is a valid integer
  • Check file permissions on config.ini
  • Review startup logs for specific validation errors
  • Test configuration validation: python -c "from pterodisbot import validate_config; validate_config()"

Checking Logs

For real-time log monitoring:

# Traditional installation
tail -f logs/pterodisbot.log

# Docker installation
docker logs -f pterodisbot

# Docker Compose
docker-compose logs -f pterodisbot

For searching logs:

# Find all ERROR level messages
grep "ERROR" logs/pterodisbot.log

# Find logs for specific server
grep "Server_Name" logs/pterodisbot.log

# View last 100 lines
tail -n 100 logs/pterodisbot.log

Getting Help

If issues persist after trying these solutions:

  1. Enable DEBUG logging by reviewing recent log files
  2. Check the Git Issues for similar problems
  3. Verify your setup matches all requirements in Prerequisites
  4. Test each component individually (Discord bot, Pterodactyl API, permissions)

License

This project is licensed under the GPL-3.0 License - see the LICENSE file for details.


Note: This bot supports a singular Pterodactyl or Pelican domain with multiple Discord guilds. Each guild tracks servers independently while sharing the same Pterodactyl/Pelican infrastructure. Users from multiple Discord guilds can view and control the same servers running on a given Pterodaactyl/Pelican domain simultaneously.

S
Description
A simple Discord bot for monitoring and managing Pterodactyl/Pelican Panel game servers with real-time status, interactive controls, resource metrics, and visual graphs.
Readme GPL-3.0
1 MiB
0 Stars 1 Watchers 0 Forks
2026-11-03 11:17:38 +00:00
Languages
Python 99.9%