A Discord bot that interfaces with your Plex server through Tautulli's API, offering rich features like user statistics, media recommendations, live download tracking from qBittorrent, and more!
- Top Plex Users: Track and display the most active viewers with automatic Discord role assignments
- Media Recommendations: Get personalized recommendations based on watch history and genre preferences
- Random Media Suggestions: Discover content from your library with filtering by genre and media type
- Live Activity: See who's currently watching what on your Plex server
- Download Tracking: Monitor qBittorrent downloads in real time (optional)
- Media Statistics: Generate detailed viewing statistics with visual charts
- Efficient Media Cache: Optimized caching system for fast responses even with large libraries
Being a hobby project, don't be surprised by the use of AI models in commits — I encourage and invite you to do the same! Use whatever tools help you build and contribute.
- Python 3.12+ (required by nextcord 3.2.0)
- A working Tautulli setup (Tautulli GitHub)
- Discord Bot Token (Discord Developer Portal)
- Optional: qBittorrent for download tracking
- Optional: TMDB API Key for enhanced metadata
-
Clone the repository:
git clone https://github.com/brah/plex-bot.git cd plex-bot -
Install dependencies:
pip install -r requirements.txt
-
Configure the bot:
Option 1: Migrate from an existing configuration
If you have a previous version of PlexBot with
config.jsonandbot_config.pyfiles, use the migration script:python migrate_config.py
Option 2: Create a new configuration
Copy the bundled template and fill in your values:
cp config.example.json config.json
The template mirrors this structure (everything not listed falls back to sensible defaults):
{ "core": { "token": "<Your Discord Bot Token>", "prefix": "plex ", "log_level": "INFO" }, "tautulli": { "ip": "localhost:8181", "apikey": "<Your Tautulli API Key>", "use_https": false }, "discord": { "server_id": "<Your Discord Server ID>", "top_role_id": 123456789, "second_role_id": 123456789, "third_role_id": 123456789 }, "qbittorrent": { "ip": "localhost", "port": "8080", "username": "username", "password": "password" }, "tmdb": { "apikey": "<Your TMDB API Key>" } }Note:
top_role_id,second_role_id, andthird_role_idare role IDs which you've created to highlight the top 3 media watchers on your server. -
Run the bot:
python plexbot.py
PlexBot now uses a unified configuration system that organizes settings into logical sections:
- core: Basic bot settings (token, prefix)
- tautulli: Tautulli API connection settings
- discord: Discord server and role settings
- qbittorrent: qBittorrent connection settings
- tmdb: TMDB API settings
- ui: User interface customization
- cache: Media cache settings
- defaults: Default values for commands
- charts: Chart visualization settings
- commands: Command-specific settings
- api: API request settings
- media_types: Media type mappings
- colors: Visualization color schemes
If you're upgrading from an older version of PlexBot, follow these steps:
-
Backup your existing configuration: The migration script will automatically create backups, but it's always good practice to make your own.
-
Run the migration script:
python migrate_config.py
-
Review the new configuration: Check the generated
config.jsonfile to ensure all settings were correctly transferred. -
Additional options:
--force: Override existing config.json--no-backup: Skip creating backups--output FILE: Specify output location--backup-dir DIR: Specify backup directory
For 24/7 operation, pick one of the two supported options below. The bot is a single long-running process with no inbound ports, and a Discord token allows one connection — run exactly one instance. Because it talks to Tautulli (and optionally qBittorrent) over your local network, it normally runs on the same host/network as Tautulli.
Best if you already run a Dockerized media stack. Requires Docker with the
Compose plugin. A Dockerfile and docker-compose.yml are included.
-
Create your config and an empty mappings file in the repo directory:
cp config.example.json config.json # then edit it echo "[]" > map.json
-
Make Tautulli reachable from the container — set
tautulli.ipinconfig.jsonaccordingly (see the networking notes indocker-compose.yml). Do not uselocalhost; inside a container that points at the container itself. Use your host's LAN IP, ahost.docker.internal:8181mapping, or the Tautulli service name if it shares this Docker network. -
Build and start:
docker compose up -d --build
-
Manage it:
docker compose logs -f # follow logs git pull && docker compose up -d --build # update
config.json and map.json stay on the host (mounted in); the media cache lives
in a named Docker volume. The container runs as UID:GID 1000:1000 — if your host
user differs, set user: in docker-compose.yml (or chown 1000:1000 config.json map.json) so it can read/write them.
Best for a bare-metal or VM host. A ready-to-edit unit lives at
deploy/plexbot.service.
-
Install the bot (e.g. into
/opt/plex-bot) with a virtualenv and deps, and createconfig.json(see Installation). Using a venv is important — the unit runs the bot viavenv/bin/python, not the systempython3, which won't have the pinned Python 3.12+ dependencies. -
Install and enable the service (edit
User=and the paths inside the unit first):sudo cp deploy/plexbot.service /etc/systemd/system/plexbot.service sudo systemctl daemon-reload sudo systemctl enable --now plexbot -
Logs:
journalctl -u plexbot -f
For quick testing only — these do not restart on reboot. Run python plexbot.py inside a screen -S plexbot or tmux new -s plexbot session and
detach (Ctrl+A D / Ctrl+B D).
| Command | Description |
|---|---|
plex top |
Shows the top Plex users and assigns roles |
plex random [media_type] [genre] |
Shows a random item from your library with optional filtering |
plex tv <show name> |
Looks up a TV show in your library with watch stats |
plex movie <movie name> |
Looks up a movie in your library with watch stats |
plex recommend [@user] |
Recommends media based on watch history |
plex watchers |
Shows who's currently watching Plex |
plex downloading |
Shows current qBittorrent downloads |
plex recent [amount] |
Shows recently added media |
plex stats [days] |
Shows server statistics for the specified time period |
plex shows |
Shows top users by TV show watch time |
plex history [@user/username] |
Shows watch history for a user |
plex hot [days] |
Shows trending content and activity insights |
plex chart |
Shows options for visualized data/charts |
plex chart hours [@user] [days] |
Shows most active hours |
plex chart days [@user] [days] |
Shows most active days of week |
plex chart users [days] |
Shows most active users |
plex chart media [@user] [days] |
Shows media types watched per day |
plex chart months [@user] [days] |
Shows activity by month |
plex status |
Shows server status information |
plex killstream [session_key] [message] |
Terminates a user's stream (admin only) |
plex mapdiscord [plex_username] [@user] |
Maps Discord user to Plex username (admin only) |
plex ignore [plex_username] |
Toggles ignoring a user in stats (admin only) |
plex refresh_cache |
Manually refreshes the media cache (admin only) |
plex force_refresh_cache |
Fully invalidates and rebuilds the media cache (admin only) |
plex help [command] |
Shows help information |
- Bot not responding to commands: Ensure the bot token is correct and the bot has proper permissions in your Discord server.
- No data from Tautulli: Double-check your Tautulli API key and IP address settings.
- qBittorrent integration issues: Verify qBittorrent WebUI is enabled and credentials are correct.
- Missing roles: Make sure the bot has permission to manage roles and the role IDs are correctly configured.
- Chart generation errors: Ensure matplotlib and seaborn are correctly installed.
The bot logs information to both the console and plexbot.log. If you're experiencing issues, check these logs for details.
- plexbot.py: Main entry point
- config/: Configuration system
- errors/: Error handling system
- cogs/: Command modules
- media_commands.py: Media-related commands
- plex_data.py: Data collection and processing
- plex_stats.py: Statistics commands
- recommendations.py: Recommendation system
- server_commands.py: Server management
- user_management.py: User mapping
- utility_commands.py: Utility commands
- visualizations.py: Chart commands
- tautulli_wrapper.py: Tautulli API wrapper
- media_cache.py: Media caching system
- utilities.py: Utility functions
- tests/: Unit tests for the helper functions
The bot includes a robust error handling system that provides:
- Consistent error messages to users
- Detailed logging for troubleshooting
- Custom exceptions for specific error cases
If you experience issues, check the console output or log file for detailed error information.
You can customize the appearance of bot messages by modifying the UI settings in your configuration:
"ui": {
"plex_embed_color": 15040013,
"plex_image": "https://images-na.ssl-images-amazon.com/images/I/61-kdNZrX9L.png"
}Control the appearance of generated charts:
"charts": {
"width": 14,
"height": 6,
"dpi": 100
}Adjust default command behaviors:
"defaults": {
"recent_count": 10,
"stats_duration": 7,
"time_range": 30
}-
Pull the latest code:
git pull origin main
-
Run the migration script to update your configuration:
python migrate_config.py
-
Install any new dependencies:
pip install -r requirements.txt
-
Restart the bot:
python plexbot.py