{"id":26201658,"url":"https://github.com/nichtlegacy/plexboxd","last_synced_at":"2026-02-02T00:04:19.649Z","repository":{"id":281888112,"uuid":"946772378","full_name":"nichtlegacy/Plexboxd","owner":"nichtlegacy","description":"Plexboxd is a Discord bot that tracks movies watched on Plex, sends rich notifications to Discord, and logs ratings to Letterboxd seamlessly. Built with Python, it integrates Plex, Discord, and Letterboxd APIs for a streamlined movie-watching experience.","archived":false,"fork":false,"pushed_at":"2025-05-18T17:03:08.000Z","size":72,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-18T18:23:02.716Z","etag":null,"topics":["automation","bot","discord","discord-bot","letterboxd","movies","plex","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nichtlegacy.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-03-11T16:46:51.000Z","updated_at":"2025-05-18T17:00:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"f2c6d33f-3dcd-4e53-aa23-af917ebe5d80","html_url":"https://github.com/nichtlegacy/Plexboxd","commit_stats":null,"previous_names":["nichtlegacy/plexboxd"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/nichtlegacy/Plexboxd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nichtlegacy%2FPlexboxd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nichtlegacy%2FPlexboxd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nichtlegacy%2FPlexboxd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nichtlegacy%2FPlexboxd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nichtlegacy","download_url":"https://codeload.github.com/nichtlegacy/Plexboxd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nichtlegacy%2FPlexboxd/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264000627,"owners_count":23542112,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","bot","discord","discord-bot","letterboxd","movies","plex","python"],"created_at":"2025-03-12T03:23:07.310Z","updated_at":"2026-02-02T00:04:19.642Z","avatar_url":"https://github.com/nichtlegacy.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Plexboxd\n\n[![GitHub release](https://img.shields.io/github/release/nichtlegacy/plexboxd.svg?style=flat-square)](https://github.com/nichtlegacy/plexboxd/releases/latest)\n![Made with Python](https://img.shields.io/badge/Made%20with-Python-3776AB?style=flat-square\u0026logo=python\u0026logoColor=white)\n![Discord](https://img.shields.io/badge/Discord-Bot-5865F2?style=flat-square\u0026logo=discord\u0026logoColor=white)\n![Plex](https://img.shields.io/badge/Plex-Server-E5A00D?style=flat-square\u0026logo=plex\u0026logoColor=white)\n![Letterboxd](https://img.shields.io/badge/Letterboxd-Integration-00D735?style=flat-square)\n![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)\n\n\nPlexboxd is a Discord bot that automatically tracks movies watched on Plex and integrates with Letterboxd to log and rate them. It monitors your Plex server for watched content and sends an embed with all necessary information to a Discord channel, allowing you to rate films directly from Discord - which then automatically adds them to your Letterboxd diary.\n\n![Plexboxd Notification Example](https://i.imgur.com/Sm9RIqc.png)\n\n## Features\n\n- 🎬 **Plex Integration**: Monitors your Plex server for newly watched movies\n- 🤖 **Discord Notifications**: Sends an embed with all necessary movie information to a Discord channel when you finish watching a film\n- ⭐ **Letterboxd Integration**: Rate movies directly from Discord with seamless Letterboxd logging\n- 📊 **Watch History**: Keeps track of your viewing history with timestamps and rating data\n- 🌙 **Date Threshold**: Configurable time threshold to determine if late-night watches count for the current or previous day\n- 📚 **Multi-Library Support**: Correctly identifies which library a movie was played from, even with duplicates across libraries\n- 🚫 **Library Exclusion**: Exclude specific libraries from notifications (e.g., 4K or Kids libraries)\n\n## Requirements\n\n- Python 3.7+\n- A Discord account and a Discord server where you have admin permissions\n- A Plex Media Server\n- A Letterboxd account\n\n## Installation\n\n1. Clone the repository\n```bash\ngit clone https://github.com/nichtlegacy/plexboxd.git\ncd plexboxd\n```\n\n2. Install the required dependencies\n```bash\npip install -r requirements.txt\n```\n\n3. Create a `.env` file based on the provided `.env.example`\n```bash\ncp .env.example .env\n```\n\n4. Fill in the required environment variables in the `.env` file (see Configuration section)\n\n5. Start the bot\n```bash\npython src/plex_bot.py\n```\n\n## Docker Support\n\nPlexboxd now supports running in a Docker container, making it easier to deploy and manage on any system that supports Docker. The official image is available on GitHub Container Registry (GHCR) at `ghcr.io/nichtlegacy/plexboxd:latest`.\n\n### Running with Docker\n\nYou can run Plexboxd using Docker in two ways: via the `docker run` command or with a `docker-compose.yml` file (recommended for easier configuration and persistence).\n\n#### Prerequisites for Docker\n- Docker installed on your system ([Install Docker](https://docs.docker.com/get-docker/))\n- (Optional) Docker Compose installed for using `docker-compose.yml` ([Install Docker Compose](https://docs.docker.com/compose/install/))\n\n#### Option 1: Using `docker run`\nPull the latest image and run it with your environment variables:\n\n```bash\ndocker run -d \\\n  --name plexboxd \\\n  --restart unless-stopped \\\n  -e DISCORD_TOKEN=\"your-discord-token\" \\\n  -e DISCORD_LOGGING_WEBHOOK_URL=\"your-webhook-url\" \\\n  -e DISCORD_USER_ID=\"your-user-id\" \\\n  -e PLEX_USERNAME=\"your-plex-username\" \\\n  -e PLEX_TOKEN=\"your-plex-token\" \\\n  -e PLEX_SERVER_URL=\"http://your-plex-server:32400\" \\\n  -e EXCLUDED_LIBRARIES=\"\" \\\n  -e NOTIFY_CHANNEL_ID=\"your-channel-id\" \\\n  -e GUILD_ID=\"your-guild-id\" \\\n  -e LETTERBOXD_USERNAME=\"your-letterboxd-username\" \\\n  -e LETTERBOXD_PASSWORD=\"your-letterboxd-password\" \\\n  -e DATE_THRESHOLD_HOUR=\"7\" \\\n  -v /path/to/your/logs:/app/logs \\\n  -v /path/to/your/data:/app/data \\\n  ghcr.io/nichtlegacy/plexboxd:latest\n```\n\nReplace `/path/to/your/logs` and `/path/to/your/data` with actual paths on your host system (e.g., `/mnt/user/appdata/plexboxd/logs` and `/mnt/user/appdata/plexboxd/data`).\n\n#### Option 2: Using Docker Compose (Recommended)\nUsing `docker-compose` simplifies configuration by allowing you to use a `.env` file and manage persistent volumes more easily. Below is an example `docker-compose.yml`:\n\n```yaml\nversion: '3.8'\n\nservices:\n  plexboxd:\n    image: ghcr.io/nichtlegacy/plexboxd:latest\n    container_name: plexboxd\n    restart: unless-stopped\n    env_file:\n      - .env\n    volumes:\n      - ./logs:/app/logs\n      - ./data:/app/data\n```\n\n##### Steps to Use Docker Compose\n1. Save the above content in a file named `docker-compose.yml`.\n2. Create a `.env` file in the same directory with the following variables (see [Configuration](#configuration) for details):\n\n   ```bash\n   DISCORD_TOKEN=your-discord-token\n   DISCORD_LOGGING_WEBHOOK_URL=your-webhook-url\n   DISCORD_USER_ID=your-user-id\n   PLEX_USERNAME=your-plex-username\n   PLEX_TOKEN=your-plex-token\n   PLEX_SERVER_URL=http://your-plex-server:32400\n   EXCLUDED_LIBRARIES=\n   NOTIFY_CHANNEL_ID=your-channel-id\n   GUILD_ID=your-guild-id\n   LETTERBOXD_USERNAME=your-letterboxd-username\n   LETTERBOXD_PASSWORD=your-letterboxd-password\n   DATE_THRESHOLD_HOUR=7\n   ```\n\n3. (Optional, but recommended) Create the `logs` and `data` directories for persistence:\n   ```bash\n   mkdir logs data\n   ```\n\n4. Start the container:\n   ```bash\n   docker-compose up -d\n   ```\n\n5. To stop it:\n   ```bash\n   docker-compose down\n   ```\n\n#### Persistent Volumes\nTo ensure logs and data (like `movie_data.db`) persist across container restarts, map the following volumes:\n- **Logs**: Host path (e.g., `./logs`) to container path `/app/logs`\n- **Data**: Host path (e.g., `./data`) to container path `/app/data`\n\nThese mappings are included in the `docker-compose.yml` example above. Adjust the host paths to suit your system (e.g., `/mnt/user/appdata/plexboxd/logs` on Unraid).\n\n## Configuration\n\n### Environment Variables\n\nThe `.env` file contains all the necessary configuration parameters:\n\n#### Discord Configuration\n- `DISCORD_TOKEN`: Your Discord bot token from the [Discord Developer Portal](https://discord.com/developers/applications)\n- `DISCORD_LOGGING_WEBHOOK_URL`: Webhook URL for sending logs to a Discord channel\n- `NOTIFY_CHANNEL_ID`: ID of the Discord channel where movie notifications will be sent\n- `GUILD_ID`: ID of your Discord server\n- `DISCORD_USER_ID`: Your Discord user ID to be notified when a movie is watched\n\n#### Plex Configuration\n- `PLEX_USERNAME`: Your Plex account username\n- `PLEX_TOKEN`: Your Plex authentication token\n- `PLEX_SERVER_URL`: URL of your Plex server (e.g., `http://192.168.1.100:32400`)\n- `EXCLUDED_LIBRARIES`: Comma-separated list of library names to exclude from notifications (e.g., `4K Movies,Kids Movies`)\n\n#### Letterboxd Configuration\n- `LETTERBOXD_USERNAME`: Your Letterboxd username\n- `LETTERBOXD_PASSWORD`: Your Letterboxd password\n- `DATE_THRESHOLD_HOUR`: Hour (in 24-hour format) to determine the cutoff for assigning movie watch dates (default: 7)\n\n### How to Get Required Tokens\n\n#### Discord Bot Token\n1. Go to the [Discord Developer Portal](https://discord.com/developers/applications)\n2. Create a new application\n3. Go to the \"Bot\" tab and create a bot\n4. Copy the token and add it to your `.env` file\n\n#### Discord Channel and Guild IDs\n1. Enable Developer Mode in Discord (User Settings \u003e Advanced \u003e Developer Mode)\n2. Right-click on your server icon and select \"Copy ID\" for the Guild ID\n3. Right-click on the notification channel and select \"Copy ID\" for the Channel ID\n\n#### Plex Token\n1. Log in to your Plex Web App\n2. Play any media item\n3. Right-click anywhere and choose \"View Page Source\"\n4. Search for \"X-Plex-Token\" and copy the token value\n\n## Project Structure\n\n```\n📦 Plexboxd\n├─ /data                            # Stores persistent data\n│  └─ movie_data.db               # Cached movie data and watch history\n├─ /logs                            # Log files directory\n│  ├─ letterboxd_integration.log    # Letterboxd integration logs\n│  └─ plex_bot.log                  # Main bot logs\n├─ /src                             # Source code\n│  ├─ letterboxd_integration.py     # Letterboxd API interaction and logging\n│  ├─ logging_config.py             # Logging configuration for the bot\n│  ├─ plex_bot.py                   # Main bot code and Plex monitoring\n│  ├─ utils.py                      # Utility functions for Discord embeds\n│  └─ views.py                      # Discord UI components (buttons, selects)\n├─ .env                             # Environment variables (sensitive data)\n├─ .env.example                     # Example environment variables file\n├─ .gitignore                       # Git ignore configuration\n└─ requirements.txt                 # Python dependencies\n```\n\n## How It Works\n\n1. **Plex Monitoring**: The bot connects to your Plex server and periodically checks for recently watched movies.\n\n2. **Discord Notifications**: When a movie is watched, the bot sends an embed with all necessary movie information to the configured Discord channel.\n\n   ![Movie Notification](https://i.imgur.com/4FbqqRk.png)\n\n3. **Rating Interface**: Each notification includes a dropdown menu to rate the movie directly from Discord.\n\n   ![Rating Interface](https://i.imgur.com/9cOsJwx.png)\n\n4. **Letterboxd Integration**: When you rate a movie, the bot:\n   - Logs into your Letterboxd account using `requests`\n   - Searches for the movie using Selenium (headless)\n   - Adds it to your diary with the correct date and rating via `requests`\n   - Confirms the action with a success message\n\n   ![Rating Confirmation](https://i.imgur.com/ukaeAVI.png)\n\n5. **Date Assignment Logic**: The bot uses the `DATE_THRESHOLD_HOUR` setting to determine if late-night watches count for the current or previous day in your Letterboxd diary.\n\n## Logging\n\nThe bot maintains two primary log files:\n\n1. **plex_bot.log**\n   - Bot startup and initialization\n   - Plex connection status\n   - Movie detection events\n   - Discord notification events\n   - Error messages\n\n2. **letterboxd_integration.log**\n   - Letterboxd login attempts\n   - Movie search operations\n   - Diary entry creation\n   - Date assignment decisions\n\nBoth logs can also be forwarded to a Discord channel using the `DISCORD_LOGGING_WEBHOOK_URL` for easier monitoring.\n\n## Troubleshooting\n\n### Common Issues\n\n1. **Bot can't connect to Plex**\n   - Verify your Plex server is running\n   - Check your `PLEX_SERVER_URL` and `PLEX_TOKEN` in the `.env` file\n   - Ensure your firewall allows connections to your Plex server\n\n2. **Letterboxd integration fails**\n   - Verify your Letterboxd credentials\n   - Check if Letterboxd is experiencing downtime\n   - Ensure you have Chrome installed for Selenium (used for movie search)\n\n3. **Discord notifications aren't showing up**\n   - Verify your bot has proper permissions in the Discord server\n   - Check if the `NOTIFY_CHANNEL_ID` is correct\n   - Make sure the bot has access to the notification channel\n\n### Checking Logs\n\n- Review the log files in the `/logs` directory for detailed error information\n- If you've configured Discord logging, check the logging channel for real-time updates\n\n## Security Notes\n\n- Your Letterboxd credentials and other sensitive information are stored in the `.env` file. Keep this file secure and never commit it to version control.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Acknowledgements\n\n- [Plex](https://www.plex.tv) for providing an excellent media server platform that makes tracking watched movies possible.\n- [Letterboxd](https://letterboxd.com) for their movie logging and rating service, which inspired the core integration of this bot.\n- [Discord](https://discord.com) for their robust API and bot framework, enabling seamless notifications and interactions.\n- [PlexAPI](https://github.com/pkkid/python-plexapi) - A Python library for interacting with Plex servers, heavily utilized in this project for movie tracking.\n- [Selenium](https://www.selenium.dev) - Used for headless browser automation to search for movies on Letterboxd.\n- [discord.py](https://github.com/Rapptz/discord.py) - The backbone of the Discord bot functionality, making embeds and interactive components possible.\n\n## Disclaimer\n\nThis project is not affiliated with or endorsed by Plex, Letterboxd, or Discord. It is an independent tool built for personal use and shared for educational purposes. Use it at your own risk and be respectful of the respective APIs by avoiding excessive requests. The developers are not responsible for any issues arising from misuse, including potential account restrictions by the integrated services.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnichtlegacy%2Fplexboxd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnichtlegacy%2Fplexboxd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnichtlegacy%2Fplexboxd/lists"}