Release 1.0.0

This commit is contained in:
2026-03-12 21:45:01 +00:00
parent 28be3105b6
commit b2a9f74f59
12 changed files with 1028 additions and 522 deletions
+11 -8
View File
@@ -11,26 +11,29 @@ REDDIT_USERNAME=YOUR_USERNAME_HERE
REDDIT_PASSWORD=YOUR_PASSWORD_HERE REDDIT_PASSWORD=YOUR_PASSWORD_HERE
# Which subreddit to post to # Which subreddit to post to
SUBREDDIT=YOUR_SUBREDDIT_HERE REDDIT_SUBREDDIT=YOUR_SUBREDDIT_HERE
# Optional: customize the user agent # Optional: customize the user agent
# REDDIT_USER_AGENT=MinecraftUpdateBot/1.0 # REDDIT_USER_AGENT=MinecraftUpdateBot/1.0
# Optional: what types of releases to check for # Optional: what types of releases to check for
# Options: release, snapshot, old_beta, old_alpha # Options: release, snapshot, old_beta, old_alpha
# Multiple: RELEASE_TYPES=release,snapshot # Multiple: REDDIT_RELEASE_TYPES=release,snapshot
RELEASE_TYPES=release REDDIT_RELEASE_TYPES=release,snapshot
# Optional: Check for Bedrock Edition releases (Windows) # Optional: Check for Bedrock Edition releases
# true to enable, false to disable # true to enable, false to disable
CHECK_BEDROCK=false REDDIT_CHECK_BEDROCK=true
# Optional: how often to check for updates (in seconds) # Optional: how often to check for updates (in seconds)
# Default: 3600 (1 hour) # Default: 3600 (1 hour)
# For testing: 600 (10 minutes) # For testing: 600 (10 minutes)
CHECK_INTERVAL=3600 REDDIT_CHECK_INTERVAL=3600
# Wiki Configuration # Wiki Configuration
# Post titles and bodies are loaded from the subreddit wiki page "minecraft_update_bot" # Name of the wiki page to load post templates from
# Format: YAML with release_type sections containing title and body # Default: minecraft_update_bot
REDDIT_WIKI_PAGE_NAME=minecraft_update_bot
# Wiki Format: YAML with release_type sections containing title and body
# Example: See WIKI_CONFIG.md for complete documentation # Example: See WIKI_CONFIG.md for complete documentation
+190 -93
View File
@@ -1,6 +1,4 @@
# Running with Docker Compose # Docker Deployment Guide
This project includes Docker and Docker Compose configuration for easy deployment.
## Prerequisites ## Prerequisites
@@ -9,16 +7,12 @@ This project includes Docker and Docker Compose configuration for easy deploymen
## Quick Start ## Quick Start
### 1. Copy Environment File 1. Copy environment template:
```bash ```bash
copy .env.example .env copy .env.example .env
``` ```
### 2. Edit .env 2. Edit `.env` with your Reddit credentials:
Open `.env` and fill in your Reddit credentials:
```env ```env
REDDIT_CLIENT_ID=your_client_id REDDIT_CLIENT_ID=your_client_id
REDDIT_CLIENT_SECRET=your_client_secret REDDIT_CLIENT_SECRET=your_client_secret
@@ -27,127 +21,230 @@ REDDIT_PASSWORD=your_password
SUBREDDIT=your_subreddit SUBREDDIT=your_subreddit
``` ```
### 3. (Optional) Set Up Wiki Configuration 3. Start the bot:
Create a wiki page on your subreddit named `minecraft_update_bot` with your post templates in YAML format. This allows different posts for releases, snapshots, etc.
See [WIKI_CONFIG.md](WIKI_CONFIG.md) for detailed instructions and examples.
### 4. Start the Bot
```bash ```bash
docker-compose up -d docker-compose up -d
``` ```
This will: 4. Verify it's running:
- Build the Docker image
- Start the bot in a container
- Persist data in a Docker volume named `minecraft-bot-db`
- Auto-restart the container if it crashes
### 5. View Logs
```bash ```bash
# Watch logs in real-time
docker-compose logs -f
# Or check status
docker-compose ps docker-compose ps
``` ```
### 5. Stop the Bot 5. View logs:
```bash
docker-compose logs -f
```
## Environment Variables
Required variables (in `.env`):
- REDDIT_CLIENT_ID - OAuth client ID from Reddit app
- REDDIT_CLIENT_SECRET - OAuth client secret
- REDDIT_USERNAME - Your Reddit account username
- REDDIT_PASSWORD - Your Reddit account password
- SUBREDDIT - Target subreddit name
Optional variables:
- REDDIT_RELEASE_TYPES - Comma-separated types (default: release)
- Examples: "release", "release,snapshot"
- REDDIT_CHECK_BEDROCK - Enable Bedrock Edition detection (default: false)
- Set to "true" or "false"
- REDDIT_CHECK_INTERVAL - Seconds between checks (default: 3600)
- Example: 600 for 10-minute checks
- REDDIT_WIKI_PAGE_NAME - Post template wiki page name (default: minecraft_update_bot)
- REDDIT_USER_AGENT - API user agent (default: MinecraftUpdateBot/1.0)
## Configuration File
Edit `.env` to control all behavior. Example with all options:
```env
REDDIT_CLIENT_ID=abc123
REDDIT_CLIENT_SECRET=xyz789
REDDIT_USERNAME=mybot
REDDIT_PASSWORD=botpass
SUBREDDIT=mysubreddit
REDDIT_RELEASE_TYPES=release,snapshot
REDDIT_CHECK_BEDROCK=true
REDDIT_CHECK_INTERVAL=3600
REDDIT_WIKI_PAGE_NAME=minecraft_update_bot
REDDIT_USER_AGENT=MinecraftUpdateBot/1.0
```
## Container Management
Start the bot:
```bash
docker-compose up -d
```
Stop the bot:
```bash ```bash
docker-compose down docker-compose down
``` ```
## Configuration Restart the bot:
All configuration is done via the `.env` file. The following variables are available:
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `REDDIT_CLIENT_ID` | ✓ | - | Your Reddit app client ID |
| `REDDIT_CLIENT_SECRET` | ✓ | - | Your Reddit app secret |
| `REDDIT_USERNAME` | ✓ | - | Your Reddit username |
| `REDDIT_PASSWORD` | ✓ | - | Your Reddit password |
| `SUBREDDIT` | ✓ | - | Subreddit to post to |
| `RELEASE_TYPES` | | `release` | Comma-separated: `release,snapshot` |
| `CHECK_BEDROCK` | | `false` | Enable Bedrock Edition detection: `true` or `false` |
| `CHECK_INTERVAL` | | `3600` | Seconds between checks |
| `REDDIT_USER_AGENT` | | `MinecraftUpdateBot/1.0` | API user agent |
### Examples
**Check for both releases and snapshots:**
```env
RELEASE_TYPES=release,snapshot
```
**Check every 10 minutes (for testing):**
```env
CHECK_INTERVAL=600
```
## Data Persistence
The bot's database (list of posted versions) is stored in a Docker volume called `minecraft-bot-db`. This persists between container restarts.
To view the data:
```bash ```bash
docker volume inspect minecraft-bot-db docker-compose restart
``` ```
To reset the database (post all versions again): Rebuild after code changes:
```bash
docker volume rm minecraft-bot-db
```
## Building
To rebuild the image after code changes:
```bash ```bash
docker-compose build --no-cache docker-compose build --no-cache
docker-compose up -d docker-compose up -d
``` ```
View logs:
```bash
docker-compose logs -f minecraftupdatebot
```
View specific log entries:
```bash
docker-compose logs minecraftupdatebot | grep "[BOT]"
```
## Data Persistence
The bot's version database persists in a Docker volume named `minecraft-bot-db`.
View volume details:
```bash
docker volume inspect minecraft-bot-db
```
The database file is located at `/app/DB/posted_versions.json` inside the container.
Reset the database (allows reposting all versions):
```bash
docker-compose down
docker volume rm minecraft-bot-db
docker-compose up -d
```
Check database contents from host:
```bash
docker run --rm -v minecraft-bot-db:/data alpine cat /data/posted_versions.json
```
## Wiki Configuration
The bot loads post templates from a subreddit wiki page (default name: minecraft_update_bot).
Create the wiki page on your subreddit with YAML configuration:
```yaml
release:
title: "Minecraft {version} Released"
body: |
New version available!
Version: {version}
Released: {release_date}
snapshot:
title: "Minecraft {version} Snapshot"
body: |
Test build available
Released: {release_date}
bedrock-windows:
title: "Bedrock Edition {version} Available"
body: |
Bedrock update available
Released: {release_date}
```
See WIKI_CONFIG.md for complete documentation.
## Monitoring
Check bot status:
```bash
docker-compose ps
```
Monitor logs in real-time:
```bash
docker-compose logs -f
```
Look for these status messages:
- [BOT] Successfully connected to Reddit
- [BOT] Started update checker
- [BOT] New Java release found
- [BOT] New Bedrock release found
- [BOT] Posted Minecraft
For errors, look for:
- [BOT] Error messages
- [BEDROCK_CHECKER] Error messages
- [CHAT] Error messages
## Troubleshooting ## Troubleshooting
### Container won't start Container won't start:
```bash ```bash
docker-compose logs docker-compose logs
``` ```
Check for missing credentials or configuration errors.
Check for configuration errors or missing credentials. Reddit authentication fails:
- Verify credentials in .env are correct
- Check Reddit app still exists at https://www.reddit.com/prefs/apps
- Ensure the bot account has permission to post to the subreddit
### Reddit authentication error No posts being made:
1. Check logs: `docker-compose logs -f`
2. Verify subreddit name in REDDIT_SUBREDDIT env var
3. Check database: `docker run --rm -v minecraft-bot-db:/data alpine cat /data/posted_versions.json`
4. Verify wiki configuration loaded: Look for "[WIKI_CONFIG] Loaded" in logs
- Verify your credentials in `.env` Bedrock detection not working:
- Check that your Reddit app still exists at https://www.reddit.com/prefs/apps - Ensure REDDIT_CHECK_BEDROCK is set to "true" in .env
- Make sure your account can post to the subreddit - Check logs for minecraft.wiki scraping errors
- Bedrock detection requires internet access to minecraft.wiki
### No posts being made Chat commands not working:
- Only subreddit moderators can send commands
- Send messages containing "reload-config" or "repost-latest"
- Check logs for [CHAT] messages
- Check the logs: `docker-compose logs -f` ## Network Access
- Verify the subreddit name in `.env`
- Check `docker exec minecraft-bot cat /app/DB/posted_versions.json` to see what's been posted
## Advanced Options The bot requires:
- Reddit API connectivity (PRAW library)
- Minecraft launcher manifest (launchermeta.mojang.com)
- minecraft.wiki (for Bedrock detection if enabled)
- Update server (updts.slfhstd.uk for bot version checking)
### Custom Post Template If behind a proxy, configure Docker networking accordingly.
Mount your config file to customize the post format: ## Performance
Edit `docker-compose.yml`: Default settings:
```yaml - Checks every 3600 seconds (1 hour)
volumes: - Allows 86400 seconds (24 hours) between update notifications
- minecraft-bot-db:/app/DB - Wiki config refreshes on each check (cached for 5 minutes)
- ./config.py:/app/config.py # Uncomment this line
For testing with faster checks:
```env
REDDIT_CHECK_INTERVAL=300
``` ```
Then edit `config.py` locally to customize `POST_TEMPLATE`. For production (less frequent):
```env
REDDIT_CHECK_INTERVAL=7200
```
## Security
Best practices:
- Never commit .env file with real credentials to version control
- .env is listed in .gitignore by default
- Use Reddit app credentials, not your personal account password if possible
- Restrict subreddit moderator permissions for bot accounts
- Review logs regularly for unauthorized access attempts
### Resource Limits ### Resource Limits
+2 -2
View File
@@ -2,7 +2,7 @@ FROM python:3.11-slim
WORKDIR /app WORKDIR /app
# Install dependencies # Install Python dependencies
COPY requirements.txt . COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements.txt
@@ -11,6 +11,6 @@ COPY . .
# Create DB directory # Create DB directory
RUN mkdir -p DB RUN mkdir -p DB
ENV PYTHONUNBUFFERED=1
# Run the bot # Run the bot
CMD ["python", "main.py"] CMD ["python", "main.py"]
+152 -42
View File
@@ -1,65 +1,175 @@
# Quick Start Guide # Quick Start Guide
## 1️⃣ Installation ## Installation
### Docker (Recommended)
1. Copy environment template:
```bash
copy .env.example .env
```
2. Edit `.env` with credentials:
```
REDDIT_CLIENT_ID=your_client_id
REDDIT_CLIENT_SECRET=your_client_secret
REDDIT_USERNAME=your_username
REDDIT_PASSWORD=your_password
SUBREDDIT=your_subreddit
```
3. Start the bot:
```bash
docker-compose up -d
```
4. Check logs:
```bash
docker-compose logs -f
```
### Manual Installation
1. Install dependencies:
```bash ```bash
cd d:\Git Repos\MinecraftUpdates
pip install -r requirements.txt pip install -r requirements.txt
``` ```
## 2️⃣ Reddit Setup 2. Create Reddit app at https://www.reddit.com/prefs/apps (select "Script" type)
1. Go to https://www.reddit.com/prefs/apps
2. Click "Create an app" (type: Script)
3. Get your credentials: Client ID, Client Secret
## 3️⃣ Configure 3. Set environment variables:
Edit `config.py`:
```python
REDDIT_CLIENT_ID = "your_client_id"
REDDIT_CLIENT_SECRET = "your_client_secret"
REDDIT_USERNAME = "your_username"
REDDIT_PASSWORD = "your_password"
SUBREDDIT = "your_subreddit"
```
## 4️⃣ Test
```bash ```bash
python test_setup.py set REDDIT_CLIENT_ID=your_client_id
set REDDIT_CLIENT_SECRET=your_client_secret
set REDDIT_USERNAME=your_username
set REDDIT_PASSWORD=your_password
set SUBREDDIT=your_subreddit
``` ```
Should show: 4. Run the bot:
- ✓ Configuration checked
- ✓ Minecraft API working
- ✓ Reddit connection working
## 5️⃣ Run
```bash ```bash
python main.py python main.py
``` ```
See posts appear in your subreddit automatically! ## Configuration
--- Required env vars:
- REDDIT_CLIENT_ID
- REDDIT_CLIENT_SECRET
- REDDIT_USERNAME
- REDDIT_PASSWORD
- SUBREDDIT
## Optional Config Changes Optional env vars:
- REDDIT_RELEASE_TYPES (default: release)
- Examples: "release", "release,snapshot"
- REDDIT_CHECK_BEDROCK (default: false)
- Set to "true" to enable Bedrock Edition detection
- REDDIT_CHECK_INTERVAL (default: 3600)
- Number of seconds between version checks
- REDDIT_WIKI_PAGE_NAME (default: minecraft_update_bot)
- Wiki page name for post templates
### Check for Snapshots Too ## Wiki Configuration
```python
RELEASE_TYPES = ["release", "snapshot"] Create a wiki page named minecraft_update_bot on your subreddit with YAML content:
```yaml
release:
title: "Minecraft {version} Released"
body: |
New version available!
**Version:** {version}
**Released:** {release_date}
snapshot:
title: "Minecraft {version} Snapshot"
body: |
New snapshot available for testing!
**Version:** {version}
**Released:** {release_date}
``` ```
### Check More Frequently (testing) Placeholders: {version}, {release_date}, {type}
```python
CHECK_INTERVAL = 600 # 10 minutes instead of 1 hour See WIKI_CONFIG.md for complete examples.
## Testing
### Manual Version Checker Test
```bash
python -c "from minecraft_checker import get_latest_releases; import json; print(json.dumps(get_latest_releases(['release']), indent=2))"
``` ```
### Customize Post Format ### Bedrock Checker Test
Edit the `POST_TEMPLATE` in `config.py` - it uses `{version}` and `{release_date}` placeholders.
--- ```bash
python -c "from bedrock_checker import get_latest_bedrock_release; import json; result = get_latest_bedrock_release(); print(json.dumps(result, indent=2))"
```
## Files Overview ### Full Configuration Test
- `main.py` - The bot itself
- `config.py` - Settings (edit this!) ```bash
- `minecraft_checker.py` - Fetches Minecraft version data python test_setup.py
- `test_setup.py` - Tests your configuration ```
- `DB/` - Stores tracking of posted versions (auto-created)
Expected output:
- Configuration loaded successfully
- Minecraft API reachable
- Reddit connection working
- Wiki configuration loaded
## Moderator Commands
Send these messages via Reddit chat to control the bot:
**reload-config**
- Reloads wiki configuration without restarting
- Usage: Send a chat message containing "reload-config"
**repost-latest**
- Manually repost latest versions (bypasses duplicate check)
- Usage: Send a chat message containing "repost-latest"
Note: Only subreddit moderators can use these commands.
## File Overview
- main.py - Bot orchestration and command handler
- config.py - Configuration loader
- minecraft_checker.py - Java Edition version checker
- bedrock_checker.py - Bedrock Edition version checker
- wiki_config.py - Wiki configuration manager
- update_checker.py - Bot update checker
- requirements.txt - Python dependencies
- Dockerfile - Container image
- docker-compose.yml - Docker composition
- DB/ - Version tracking database
## Logs
Docker:
```bash
docker-compose logs -f
```
Manual:
```
Watch console output for [BOT], [CHAT], [BEDROCK_CHECKER] messages
```
## Common Issues
No posts appearing:
- Check logs for errors
- Verify subreddit name in REDDIT_SUBREDDIT
- Check DB/posted_versions.json for version tracking
Bot not detecting Bedrock:
- Ensure REDDIT_CHECK_BEDROCK is set to true
- Check bedrock_checker logs for wiki scraping errors
Wiki config not loading:
- Verify wiki page name is exactly "minecraft_update_bot"
- Ensure YAML syntax is valid
+158 -115
View File
@@ -1,127 +1,65 @@
# Minecraft Update Bot 🎮 # Minecraft Update Bot
Automatically detects new Minecraft releases and posts them to a subreddit. Version 1.0.0 - Automatically detects new Minecraft releases (Java and Bedrock editions) and posts announcements to a subreddit.
## Features ## Features
- ✅ Checks Minecraft launcher manifest for new releases Core functionality:
- ✅ Posts to Reddit whenever a new version is detected - Polls the official Minecraft launcher manifest for new Java Edition releases
- ✅ Tracks posted versions to avoid duplicates - Detects Minecraft Bedrock Edition updates via minecraft.wiki scraping
- ✅ Runs continuously with configurable check interval - Posts new releases to a configured subreddit automatically
- ✅ Supports multiple release types (releases, snapshots, etc.) - Maintains a database of posted versions to prevent duplicate posts
- **Bedrock Edition support** - Detects Windows Bedrock releases - Supports multiple release types (releases, snapshots, beta versions)
- ✅ Docker & Docker Compose ready - Configurable check interval for polling
-**Customizable post templates via subreddit wiki**
-**Different post formats for different release types**
-**Auto-update notifications** - Gets alerted when new bot versions are available
## Quick Start - Docker (Recommended) Advanced features:
- Customizable post templates via subreddit wiki configuration
- Different post formats for different release types
- Moderator chat commands for config reload and manual reposting
- Automatic bot update notifications via modmail
- Docker and Docker Compose deployment ready
- Persistent version tracking across container restarts
## Quick Start
### Docker (Recommended)
1. Copy the environment template:
```bash ```bash
# Copy and edit environment file
copy .env.example .env copy .env.example .env
# Edit .env with your Reddit credentials ```
# Start the bot 2. Edit `.env` with your Reddit credentials:
```
REDDIT_CLIENT_ID=your_id
REDDIT_CLIENT_SECRET=your_secret
REDDIT_USERNAME=your_username
REDDIT_PASSWORD=your_password
SUBREDDIT=your_subreddit
```
3. Start the bot:
```bash
docker-compose up -d docker-compose up -d
```
# View logs 4. View logs:
```bash
docker-compose logs -f docker-compose logs -f
``` ```
See [DOCKER.md](DOCKER.md) for detailed Docker setup instructions. See [DOCKER.md](DOCKER.md) for detailed Docker setup instructions.
## Customizing Posts with Wiki Configuration ### Manual Setup
The bot loads post templates from your subreddit's wiki page `minecraft_update_bot`. This allows you to:
- Create different post formats for releases vs. snapshots
- Customize titles and bodies without restarting
- Support legacy version types with custom messages
**Quick Setup:**
1. Create a wiki page named `minecraft_update_bot` on your subreddit
2. Add YAML configuration with your templates (see example below)
3. Bot auto-loads every 30 minutes
**Simple Example:**
```yaml
release:
title: "Minecraft {version} Released!"
body: |
# Minecraft {version}
Available now! Get it at [minecraft.net](https://minecraft.net)
**Released:** {release_date}
snapshot:
title: "Minecraft {version} Snapshot"
body: |
# New Snapshot Available
Test {version} before the official release!
```
👉 See [WIKI_CONFIG.md](WIKI_CONFIG.md) for complete setup and examples.
## Bedrock Edition Support
The bot can track **Minecraft Bedrock Edition (Windows)** releases in addition to Java Edition.
**To enable Bedrock tracking:**
1. **With Docker:** Add to your `.env` file:
```
CHECK_BEDROCK=true
```
2. **Manual:** Set environment variable before running:
```bash
set CHECK_BEDROCK=true
python main.py
```
3. **Configure Bedrock posts** in your wiki page (optional):
```yaml
bedrock-windows:
title: "Minecraft Bedrock {version} Available (Windows)"
body: |
# Bedrock Edition {version}
Download from the Microsoft Store
**Released:** {release_date}
```
The bot will now check for both Java and Bedrock releases every cycle, posting about each separately.
## Manual Setup
### 1. Install Dependencies
1. Install dependencies:
```bash ```bash
pip install -r requirements.txt pip install -r requirements.txt
``` ```
### 2. Create Reddit Application 2. Create a Reddit application at https://www.reddit.com/prefs/apps (select "Script" type)
1. Go to [https://www.reddit.com/prefs/apps](https://www.reddit.com/prefs/apps)
2. Click "Create an app" or "Create another app"
3. Fill in the form:
- **Name:** MinecraftUpdateBot
- **App type:** Script
- **Redirect URI:** http://localhost:8080
4. Copy the credentials
### 3. Configure the Bot
Edit `config.py` and fill in your credentials:
```python
REDDIT_CLIENT_ID = "YOUR_CLIENT_ID" # From app page
REDDIT_CLIENT_SECRET = "YOUR_CLIENT_SECRET" # From app page
REDDIT_USERNAME = "YOUR_USERNAME" # Your Reddit username
REDDIT_PASSWORD = "YOUR_PASSWORD" # Your Reddit password
SUBREDDIT = "YOUR_SUBREDDIT" # Subreddit to post to
```
Or use environment variables (Docker-friendly):
3. Configure environment variables or edit config.py:
```bash ```bash
set REDDIT_CLIENT_ID=your_client_id set REDDIT_CLIENT_ID=your_client_id
set REDDIT_CLIENT_SECRET=your_client_secret set REDDIT_CLIENT_SECRET=your_client_secret
@@ -131,22 +69,127 @@ set SUBREDDIT=your_subreddit
python main.py python main.py
``` ```
### 4. Customize (Optional) ## Configuration
In `config.py`: ### Environment Variables
- **RELEASE_TYPES:** Change `["release"]` to include snapshots or other types
- Options: `"release"`, `"snapshot"`, `"old_beta"`, `"old_alpha"`
- **CHECK_INTERVAL:** How often to check for updates (in seconds)
- Default: 3600 (1 hour)
- **POST_TEMPLATE:** Customize the post format
Examples: Required variables:
```python - REDDIT_CLIENT_ID - Your Reddit OAuth app client ID
# Check for both releases and snapshots - REDDIT_CLIENT_SECRET - Your Reddit OAuth app secret
RELEASE_TYPES = ["release", "snapshot"] - REDDIT_USERNAME - Reddit account username
- REDDIT_PASSWORD - Reddit account password
- SUBREDDIT - Target subreddit name
# Check every 30 minutes Optional variables:
CHECK_INTERVAL = 1800 - REDDIT_RELEASE_TYPES - Comma-separated types: release,snapshot (default: release)
- REDDIT_CHECK_BEDROCK - Enable Bedrock detection: true or false (default: false)
- REDDIT_CHECK_INTERVAL - Seconds between checks (default: 3600)
- REDDIT_WIKI_PAGE_NAME - Wiki page for post templates (default: minecraft_update_bot)
- REDDIT_USER_AGENT - API user agent string (default: MinecraftUpdateBot/1.0)
### Wiki Configuration
Post templates are defined in a subreddit wiki page (default name: minecraft_update_bot).
Create entries for each release type with title and body templates:
```yaml
release:
title: "Minecraft {version} Released"
body: |
New version available at minecraft.net
Released: {release_date}
snapshot:
title: "Minecraft {version} Snapshot"
body: |
Test build available in launcher
Released: {release_date}
bedrock-windows:
title: "Bedrock Edition {version} Available"
body: |
Download from Microsoft Store
Released: {release_date}
```
Available placeholders: {version}, {release_date}, {type}
See [WIKI_CONFIG.md](WIKI_CONFIG.md) for complete wiki configuration details.
## Moderator Chat Commands
Moderators can control the bot via Reddit chat messages:
**reload-config**
- Reloads wiki configuration without restarting the bot
- Usage: Send a chat message containing "reload-config"
- Response: Bot replies with success or failure status
**repost-latest**
- Reposts the latest releases (bypasses duplicate check)
- Usage: Send a chat message containing "repost-latest"
- Response: Bot replies with number of versions reposted
## Bedrock Edition Support
The bot can track Minecraft Bedrock Edition (Windows) releases by scraping the official minecraft.wiki version history page.
Enable with Docker:
```env
REDDIT_CHECK_BEDROCK=true
```
Or environment variable:
```bash
set REDDIT_CHECK_BEDROCK=true
python main.py
```
Note: Bedrock versions use the new format (26.x, 27.x, etc.) and are detected from the wiki page. Java Edition will eventually use the same versioning scheme.
## Release Types
Supported Java Edition release types:
- release - Final Java Edition releases
- snapshot - Development snapshots
- old_beta - Legacy beta versions
- old_alpha - Legacy alpha versions
Supported Bedrock Edition types:
- bedrock-windows - Windows Bedrock releases
## Database and Persistence
Posted versions are tracked in DB/posted_versions.json. This prevents duplicate posts when the bot restarts.
With Docker, data persists in a named volume (minecraft-bot-db).
To reset the database and repost all versions:
- Docker: `docker volume rm minecraft-bot-db` then restart
- Manual: Delete DB/posted_versions.json
## Logs
Docker logs:
```bash
docker-compose logs -f
```
Watch for status messages with [BOT], [CHAT], [BEDROCK_CHECKER] prefixes.
## Files Overview
- main.py - Bot orchestration and update checking
- config.py - Configuration loader
- minecraft_checker.py - Java Edition version checker
- bedrock_checker.py - Bedrock Edition version checker via wiki scraping
- wiki_config.py - Wiki page configuration manager
- update_checker.py - Bot update notifications
- requirements.txt - Python dependencies
- Dockerfile - Container image definition
- docker-compose.yml - Docker Compose configuration
- DB/ - Version tracking database (auto-created)
# Check every 10 minutes (for testing) # Check every 10 minutes (for testing)
CHECK_INTERVAL = 600 CHECK_INTERVAL = 600
+232 -138
View File
@@ -1,203 +1,297 @@
# Wiki Configuration Setup # Wiki Configuration Guide
The Minecraft Update Bot uses a subreddit wiki page to store customizable post templates. This allows you to configure different post formats for different release types (releases, snapshots, etc.) without restarting the bot. The Minecraft Update Bot uses a subreddit wiki page to manage customizable post templates. This allows different post formats for different release types without restarting the bot.
## Quick Setup ## Quick Setup
1. **Create the wiki page on your subreddit** 1. Go to your subreddit settings and edit wiki pages
- Go to your subreddit settings 2. Create a new page named "minecraft_update_bot"
- Navigate to "Edit wiki page" 3. Add YAML configuration for your post templates
- Create a new page named `minecraft_update_bot` 4. Bot loads the configuration automatically
2. **Add the configuration in YAML format** The wiki page name can be customized via the REDDIT_WIKI_PAGE_NAME environment variable.
Copy and paste the following into your wiki page: ## Configuration Format
The wiki page must contain valid YAML with this structure:
```yaml
release_type:
title: "Post title with placeholders"
body: |
Post body content
with {placeholders}
```
## Available Placeholders
Both title and body can use these placeholders:
- {version} - The release version number (e.g., "1.21", "26.3")
- {release_date} - Formatted release date (e.g., "June 13, 2024")
- {type} - The release type (e.g., "release", "snapshot")
## Release Types
Create configuration sections for these release types:
Java Edition:
- release - Final Java Edition releases
- snapshot - Development snapshots
- old_beta - Legacy beta versions
- old_alpha - Legacy alpha versions
Bedrock Edition:
- bedrock-windows - Bedrock Edition
Special:
- default - Fallback for unconfigured types
## Example Configurations
### Basic Setup (Releases Only)
```yaml ```yaml
release: release:
title: "Minecraft {version} Released!" title: "Minecraft {version} is Available"
body: | body: |
# Minecraft {version} Released A new version of Minecraft Java Edition is available!
A new version of Minecraft Java Edition is now available! Version: {version}
Released: {release_date}
**Version:** {version} Download from minecraft.net or use the Minecraft launcher.
**Released:** {release_date} ```
Download it from [minecraft.net](https://minecraft.net) or use the Minecraft launcher. ### Multiple Release Types
```yaml
release:
title: "Minecraft {version} Released"
body: |
# Minecraft {version}
A new release is available!
Version: {version}
Released: {release_date}
Download: https://minecraft.net
snapshot: snapshot:
title: "Minecraft {version} Snapshot Available" title: "Minecraft {version} Snapshot"
body: | body: |
# Minecraft {version} Snapshot # Minecraft {version} Snapshot
A new snapshot is available for testing! A new development snapshot is available for testing.
**Version:** {version} Version: {version}
**Released:** {release_date} Released: {release_date}
Try it in the launcher with the development profiles. Enable snapshots in your launcher preferences.
bedrock-windows: bedrock-windows:
title: "Minecraft Bedrock Edition {version} Available (Windows)" title: "Bedrock Edition {version} Available"
body: | body: |
# Minecraft Bedrock Edition {version} # Minecraft Bedrock Edition {version}
A new version is available for Windows! A new Bedrock Edition update is available for Windows.
**Version:** {version} Version: {version}
**Released:** {release_date} Released: {release_date}
Download from the Microsoft Store or via the Minecraft Launcher. Download from the Microsoft Store or through the Minecraft Launcher.
old_beta:
title: "Minecraft Beta {version} Archive"
body: |
Version {version} is now archived.
Released: {release_date}
old_alpha:
title: "Minecraft Alpha {version} Archive"
body: |
Version {version} is now archived.
Released: {release_date}
default: default:
title: "Minecraft {version} ({type})" title: "Minecraft {version} ({type})"
body: | body: |
# Minecraft {version} New {type} build: {version}
A new {type} build has been released!
**Version:** {version}
**Released:** {release_date}
```
3. **Save the wiki page**
- The bot will automatically load this config on startup
- Changes to the wiki are refreshed every 30 minutes
## Configuration Format
The wiki page must be valid YAML with this structure:
```yaml
release_type:
title: "Post title with {placeholders}"
body: |
Multi-line post body
with {placeholders}
```
### Available Placeholders
In both title and body, you can use:
- `{version}` - The Minecraft version (e.g., "1.21")
- `{release_date}` - The formatted release date (e.g., "June 13, 2024")
- `{type}` - The release type (e.g., "release", "snapshot")
### Release Types
Create sections for each release type you want custom posts for:
- `release` - Java Edition final releases
- `snapshot` - Java Edition snapshots
- `old_beta` - Java Edition old beta versions
- `old_alpha` - Java Edition old alpha versions
- `bedrock-windows` - Bedrock Edition (Windows)
- `default` - Fallback for any unconfigured type
## Examples
### Example 1: Simple Setup (Releases Only)
```yaml
release:
title: "Minecraft {version} is Out!"
body: |
{version} is available now!
Get it at minecraft.net
```
### Example 2: Different Templates per Type
```yaml
release:
title: "🎉 Minecraft {version} Released"
body: |
# Minecraft {version}
The full release is here!
**Download:** [minecraft.net](https://minecraft.net)
**Date:** {release_date}
snapshot:
title: "📸 Minecraft {version} Snapshot"
body: |
# Snapshot Available
Test drive {version} before the official release!
**Date:** {release_date}
old_beta:
title: "[LEGACY] Minecraft {version} Beta"
body: |
Archive: Minecraft {version} beta
Released: {release_date} Released: {release_date}
``` ```
### Example 3: Minimal Setup with Default ### Minimal Setup with Defaults
```yaml ```yaml
default: default:
title: "Minecraft {version}" title: "Minecraft {version}"
body: | body: |
New {type}: {version} # New {type} Available
{release_date}
Version: {version}
Released: {release_date}
``` ```
## Features ## Loading and Caching
- **Multiple Configurations:** Different posts for releases, snapshots, legacy versions, etc. The wiki configuration:
- **Auto-Refresh:** Wiki changes are loaded every 30 minutes automatically - Loads on bot startup
- **Fallback:** If a release type isn't configured, it uses the `default` config - Refreshes automatically during version checks
- **No Restart Required:** Changes take effect on the next check cycle - Is cached for 5 minutes to avoid excessive wiki requests
- **Flexible:** Use any text, formatting, and placeholders you want - Falls back to embedded defaults if the wiki page is missing or invalid
Warning messages in logs:
- "Error fetching YAML config from wiki" - Cannot read the page
- "Wiki config missing required 'triggers' key" - Invalid YAML format
- An error YAML parse message - Syntax error in configuration
## Formatting Guidelines
YAML syntax rules:
- Use correct indentation (2 spaces recommended)
- Start multi-line strings with | or |-
- Values in double quotes: "string with special characters"
- No tab characters (spaces only)
Text formatting in posts:
- Standard Reddit Markdown supported
- Headers: # Title (single hash for main title)
- Bold: **text**
- Italic: *text*
- Links: [text](url)
- Line breaks: Use actual newlines in the YAML body
## Fallback Behavior
If a release type is not configured:
1. Bot looks for a "default" section
2. If no default exists, uses embedded defaults
3. Embedded default format:
```
Title: Minecraft {version} ({type})
Body: New {type}: {version}. Released: {release_date}
```
## YAML Validation
Test your YAML before adding to wiki:
- Use an online YAML validator at https://www.yamllint.com/
- Check for correct indentation and quotes
- Verify all colons have spaces after them
Common mistakes:
- Indentation with tabs (must be spaces)
- Missing quotes around values with special characters
- Unbalanced quotes
- Trailing colons without values
## Testing Configuration
After updating the wiki page:
1. Send a "reload-config" chat message to the bot (moderators only)
2. Check bot logs for these messages:
- "[WIKI_CONFIG] Successfully fetched wiki page"
- "[WIKI_CONFIG] Loaded X configuration(s)"
3. Look for error messages with parsing details
Command for moderators:
```
Send a Reddit chat message to the bot containing: reload-config
```
The bot will reply with success or failure status.
## Troubleshooting ## Troubleshooting
### Configuration Not Loading Wiki configuration not loading:
1. Check page name is exactly "minecraft_update_bot" (or your custom name)
2. Verify the bot can read the wiki (check subreddit permissions)
3. Use YAML validator to find syntax errors
4. Check bot logs for error messages
1. Check the bot logs: Posts not formatting correctly:
```bash - Verify placeholder names: {version}, {release_date}, {type}
docker-compose logs minecraft-bot - Check YAML indentation is consistent
``` - Use | for multi-line bodies (not single quotes)
- Test problematic sections in a YAML validator
2. Verify the wiki page name is exactly `minecraft_update_bot` Configuration not updating after wiki change:
- Wait up to 5 minutes (cache timeout)
- Or send "reload-config" chat command (moderators)
- Check bot logs to confirm reload was successful
3. Ensure the YAML is valid (use a YAML validator if needed) Fallback config triggering:
- Check for YAML parse errors in logs
- Verify the wiki page is readable
- Ensure "release" configuration exists or "default" is defined
4. Check that the bot has permissions to read the wiki ## Examples with Real-World Scenarios
### Posts Not Formatting Correctly ### Example 1: Simple Release Announcements
- Verify placeholder names are correct: `{version}`, `{release_date}`, `{type}` For a subreddit that only posts final releases:
- Check that the YAML syntax is correct (indentation matters!)
- Use the pipe `|` for multi-line bodies
### Reverting to Default
If the wiki page is empty or invalid, the bot will use embedded defaults:
```yaml ```yaml
release: release:
title: "Minecraft {version} Released!" title: "Minecraft {version} - Out Now!"
body: "# Minecraft {version}\n\nA new version is available!\n\n**Version:** {version}\n**Released:** {release_date}\n\nGet it at [minecraft.net](https://minecraft.net)" body: |
The official release of Minecraft {version} is now available!
Released: {release_date}
``` ```
## Advanced: Testing Your Configuration ### Example 2: Community-Focused Posts
To test without posting to your subreddit: ```yaml
release:
title: "What's New in Minecraft {version}?"
body: |
# Minecraft {version} Released
1. View the bot logs: We have a new version!
```bash
docker-compose logs -f **Version:** {version}
**Release Date:** {release_date}
What are you most excited to try?
snapshot:
title: "Snapshot: Try the Latest Features"
body: |
# {version} Snapshot Available
Want to test upcoming features? This is your chance!
Released: {release_date}
Remember: Snapshots can be unstable. Use separate worlds for testing!
``` ```
2. Watch for the line: ### Example 3: Structured with Emojis (if preferred)
```
[WIKI_CONFIG] ✓ Loaded X configuration(s) ```yaml
release:
title: "[RELEASE] Minecraft {version}"
body: |
Minecraft {version} is now available!
Released: {release_date}
snapshot:
title: "[SNAPSHOT] Minecraft {version}"
body: |
New snapshot available!
Released: {release_date}
``` ```
## Wiki Markup
Reddit wiki pages support:
- Standard Markdown
- Escape special characters with backslash: \{text\}
- HTML not processed in wiki pages
- Some Reddit-specific formatting may have limitations
3. This confirms your configs were loaded successfully 3. This confirms your configs were loaded successfully
4. When a new version is posted, you'll see: 4. When a new version is posted, you'll see:
+75 -77
View File
@@ -1,99 +1,97 @@
"""
Minecraft Bedrock Edition version checker - tracks Windows releases
"""
import requests import requests
import json from bs4 import BeautifulSoup
import re
from datetime import datetime from datetime import datetime
# Bedrock version tracking endpoints
# Using third-party services that track Bedrock version history
BEDROCK_VERSIONS_URL = "https://raw.githubusercontent.com/pmmp/PocketMine-MP/master/src/VersionInfo.php"
# Alternative: Direct launcher check (if available) def get_latest_bedrock_release():
BEDROCK_LAUNCHER_API = "https://launcher.mojang.com/v1/products/bedrock-launcher/latest" """Get the latest Bedrock edition version by scraping minecraft.wiki.
TIMEOUT = 10 Parses the version history page to find the latest release.
Returns dict with id, version, type, releaseTime, or None if scraping fails.
def get_bedrock_versions():
""" """
Fetch Bedrock version information. print("[BEDROCK_CHECKER] Fetching bedrock version from minecraft.wiki...")
Attempts multiple sources for reliability.
Returns:
Dict with version info or None
"""
# Try the launcher API first
try:
response = requests.get(BEDROCK_LAUNCHER_API, timeout=TIMEOUT)
if response.status_code == 200:
data = response.json()
if data:
return data
except Exception as e:
print(f"[BEDROCK_CHECKER] Launcher API error: {e}")
# Fallback: try Windows version manifest
try:
# Query Microsoft's update service for Bedrock
response = requests.get(
"https://launcher.mojang.com/v1/products/bedrock-launcher/16/latest",
headers={"Accept": "application/json"},
timeout=TIMEOUT
)
if response.status_code == 200:
return response.json()
except Exception as e:
print(f"[BEDROCK_CHECKER] Manifest error: {e}")
return None
def parse_bedrock_version(response_data):
"""
Parse response data into standardized version format.
Args:
response_data: JSON response from version endpoint
Returns:
Dict with keys: id, version, type, releaseTime
"""
if not response_data:
return None
try: try:
# Extract version information from different possible response formats url = "https://minecraft.wiki/w/Bedrock_Edition_version_history"
version = response_data.get('version') or response_data.get('latest') response = requests.get(url, timeout=10, headers={'User-Agent': 'MinecraftUpdateBot/1.0'})
if not version: if response.status_code != 200:
print(f"[BEDROCK_CHECKER] Failed to fetch wiki: {response.status_code}")
return None return None
soup = BeautifulSoup(response.content, 'html.parser')
# Find the first version number mentioned in the actual content
# Look for patterns like "26.3", "1.21.132", etc.
page_text = soup.get_text()
# The page structure has version numbers in tables
# Let's look for the section with "26.x" or "1.21" which are current
# Try to get version from table data
tables = soup.find_all('table', {"class": "wikitable"})
if tables:
for table in tables:
rows = table.find_all('tr')
if len(rows) > 1:
# Second row (first data row) has the latest version
cells = rows[1].find_all('td')
if cells:
version_text = cells[0].get_text(strip=True)
# Clean up the version text
if version_text and not version_text.lower().startswith('version'):
# Extract just the version number
version_match = re.match(r'^([\d.]+)', version_text)
if version_match:
version = version_match.group(1)
print(f"[BEDROCK_CHECKER] ✓ Found version from wiki table: {version}")
return { return {
"id": version, "id": version,
"version": version, "version": version,
"type": "bedrock-windows", "type": "bedrock-windows",
"releaseTime": response_data.get('releaseTime', datetime.utcnow().isoformat() + "+00:00"), "source": "minecraft_wiki",
"platform": "windows" "releaseTime": datetime.now().isoformat()
} }
except Exception as e:
print(f"[BEDROCK_CHECKER] Parse error: {e}") # Fallback: parse page text for version patterns
# Look for the new versioning format (26.x, 27.x, etc.) - not old 1.21.x format
# New format is major.minor (e.g., 26.3, 27.0)
version_pattern = r'\b(2[6-9]|[3-9]\d)\.(\d{1,2})\b'
matches = re.findall(version_pattern, page_text)
if matches:
# Get the first match (oldest format would be 26.x, newest would be higher)
for major_str, minor_str in matches:
try:
major = int(major_str)
minor = int(minor_str)
# Accept versions 26.x and above
if major >= 26 and minor >= 0:
version = f"{major}.{minor}"
print(f"[BEDROCK_CHECKER] ✓ Found version from wiki: {version}")
return {
"id": version,
"version": version,
"type": "bedrock-windows",
"source": "minecraft_wiki",
"releaseTime": datetime.now().isoformat()
}
except ValueError:
continue
print("[BEDROCK_CHECKER] ✗ Could not find version number in wiki page")
return None return None
except requests.exceptions.Timeout:
def get_latest_bedrock_release(): print("[BEDROCK_CHECKER] ✗ Timeout fetching wiki page")
""" return None
Get the latest Bedrock Windows release. except requests.exceptions.RequestException as e:
print(f"[BEDROCK_CHECKER] ✗ Request error: {e}")
Returns: return None
Dict with version info or None
"""
try:
version_data = get_bedrock_versions()
return parse_bedrock_version(version_data)
except Exception as e: except Exception as e:
print(f"[BEDROCK_CHECKER] Error getting latest release: {e}") print(f"[BEDROCK_CHECKER] Error scraping wiki: {e}")
return None return None
+10 -6
View File
@@ -9,17 +9,17 @@ REDDIT_USERNAME = os.getenv("REDDIT_USERNAME", "YOUR_USERNAME")
REDDIT_PASSWORD = os.getenv("REDDIT_PASSWORD", "YOUR_PASSWORD") REDDIT_PASSWORD = os.getenv("REDDIT_PASSWORD", "YOUR_PASSWORD")
# Subreddit to post to # Subreddit to post to
SUBREDDIT = os.getenv("SUBREDDIT", "YOUR_SUBREDDIT") SUBREDDIT = os.getenv("REDDIT_SUBREDDIT", "YOUR_SUBREDDIT")
# Minecraft release types to check for # Minecraft release types to check for
# Options: "release", "snapshot", "old_beta", "old_alpha" # Options: "release", "snapshot", "old_beta", "old_alpha"
# Can set via env as comma-separated: RELEASE_TYPES=release,snapshot # Can set via env as comma-separated: REDDIT_RELEASE_TYPES=release,snapshot
release_types_env = os.getenv("RELEASE_TYPES", "release") release_types_env = os.getenv("REDDIT_RELEASE_TYPES", "release")
RELEASE_TYPES = [t.strip() for t in release_types_env.split(",")] RELEASE_TYPES = [t.strip() for t in release_types_env.split(",")]
# Check for Bedrock Edition releases (Windows) # Check for Bedrock Edition releases (Windows)
# Set to true to detect and post Bedrock releases # Set to true to detect and post Bedrock releases
CHECK_BEDROCK = os.getenv("CHECK_BEDROCK", "false").lower() in ("true", "1", "yes") CHECK_BEDROCK = os.getenv("REDDIT_CHECK_BEDROCK", "false").lower() in ("true", "1", "yes")
# Post templates # Post templates
# NOTE: Post titles and bodies are now fetched from the subreddit wiki page "minecraft_update_bot" # NOTE: Post titles and bodies are now fetched from the subreddit wiki page "minecraft_update_bot"
@@ -46,5 +46,9 @@ CHECK_BEDROCK = os.getenv("CHECK_BEDROCK", "false").lower() in ("true", "1", "ye
# Check interval in seconds (default: 3600 = 1 hour) # Check interval in seconds (default: 3600 = 1 hour)
# Can be set via environment variable: CHECK_INTERVAL=3600 # Can be set via environment variable: REDDIT_CHECK_INTERVAL=3600
CHECK_INTERVAL = int(os.getenv("CHECK_INTERVAL", "3600")) CHECK_INTERVAL = int(os.getenv("REDDIT_CHECK_INTERVAL", "3600"))
# Wiki page name for post templates
# Can be set via environment variable: REDDIT_WIKI_PAGE_NAME=mods/minecraft-update-bot
WIKI_PAGE_NAME = os.getenv("REDDIT_WIKI_PAGE_NAME", "minecraft_update_bot")
+11 -14
View File
@@ -1,22 +1,23 @@
services: services:
minecraft-bot: minecraftupdatebot:
build: . build: .
image: minecraft-update-bot:latest image: slfhstd.uk/slfhstd/minecraftupdatebot:latest
container_name: minecraft-bot container_name: minecraftupdatebot
env_file: .env
environment: environment:
# Reddit Configuration
REDDIT_CLIENT_ID: ${REDDIT_CLIENT_ID} REDDIT_CLIENT_ID: ${REDDIT_CLIENT_ID}
REDDIT_CLIENT_SECRET: ${REDDIT_CLIENT_SECRET} REDDIT_CLIENT_SECRET: ${REDDIT_CLIENT_SECRET}
REDDIT_USER_AGENT: ${REDDIT_USER_AGENT:-MinecraftUpdateBot/1.0} REDDIT_USER_AGENT: ${REDDIT_USER_AGENT}
REDDIT_USERNAME: ${REDDIT_USERNAME} REDDIT_USERNAME: ${REDDIT_USERNAME}
REDDIT_PASSWORD: ${REDDIT_PASSWORD} REDDIT_PASSWORD: ${REDDIT_PASSWORD}
# Bot Configuration REDDIT_SUBREDDIT: ${REDDIT_SUBREDDIT}
SUBREDDIT: ${SUBREDDIT} REDDIT_RELEASE_TYPES: ${REDDIT_RELEASE_TYPES}
RELEASE_TYPES: ${RELEASE_TYPES:-release} REDDIT_CHECK_INTERVAL: ${REDDIT_CHECK_INTERVAL}
CHECK_INTERVAL: ${CHECK_INTERVAL:-3600} REDDIT_CHECK_BEDROCK: ${REDDIT_CHECK_BEDROCK}
REDDIT_WIKI_PAGE_NAME: ${REDDIT_WIKI_PAGE_NAME}
volumes: volumes:
# Persist the database of posted versions # Persist the database of posted versions
- minecraft-bot-db:/app/DB - ./DB:/app/DB
# Optional: mount config.py for easy editing # Optional: mount config.py for easy editing
# - ./config.py:/app/config.py # - ./config.py:/app/config.py
restart: unless-stopped restart: unless-stopped
@@ -26,7 +27,3 @@ services:
# limits: # limits:
# cpus: '0.5' # cpus: '0.5'
# memory: 256M # memory: 256M
volumes:
minecraft-bot-db:
driver: local
+158 -3
View File
@@ -16,7 +16,7 @@ from update_checker import start_update_checker
# Bot version (increment when making changes) # Bot version (increment when making changes)
BOT_VERSION = "1.0" BOT_VERSION = "1.0.0"
# Database file to track posted versions # Database file to track posted versions
DB_DIR = os.path.join(os.path.dirname(__file__), 'DB') DB_DIR = os.path.join(os.path.dirname(__file__), 'DB')
@@ -135,21 +135,172 @@ def check_for_updates(reddit):
# Check Bedrock Edition releases if enabled # Check Bedrock Edition releases if enabled
if config.CHECK_BEDROCK: if config.CHECK_BEDROCK:
print(f"[BOT] Checking Bedrock Edition releases...")
bedrock_release = get_latest_bedrock_release() bedrock_release = get_latest_bedrock_release()
if bedrock_release: if bedrock_release:
bedrock_id = f"bedrock-{bedrock_release['version']}" bedrock_id = f"bedrock-{bedrock_release['version']}"
source = bedrock_release.get('source', 'unknown')
if bedrock_id not in posted_versions: if bedrock_id not in posted_versions:
print(f"[BOT] New Bedrock release found: {bedrock_release['version']}") print(f"[BOT] New Bedrock release found: {bedrock_release['version']} (from {source})")
if post_to_subreddit(reddit, bedrock_release): if post_to_subreddit(reddit, bedrock_release):
save_posted_version(bedrock_id) save_posted_version(bedrock_id)
else: else:
print(f"[BOT] Bedrock version {bedrock_release['version']} already posted, skipping") print(f"[BOT] Bedrock version {bedrock_release['version']} already posted, skipping")
else:
print(f"[BOT] ⚠ No Bedrock release data available")
else:
print(f"[BOT] Bedrock Edition checking is disabled (REDDIT_CHECK_BEDROCK={config.CHECK_BEDROCK})")
except Exception as e: except Exception as e:
print(f"[BOT] ✗ Error checking for updates: {e}") print(f"[BOT] ✗ Error checking for updates: {e}")
def repost_latest_versions(reddit):
"""
Repost the latest Minecraft releases (Java & Bedrock).
This bypasses the "already posted" check, allowing moderators to
manually repost the latest versions via the "repost-latest" chat command.
Args:
reddit: PRAW Reddit instance
"""
try:
posted_count = 0
# Repost latest Java Edition releases
java_releases = get_latest_releases(config.RELEASE_TYPES)
for version_info in java_releases:
version_id = version_info["id"]
print(f"[BOT] Reposting Java release: {version_id}")
if post_to_subreddit(reddit, version_info):
posted_count += 1
# Repost latest Bedrock Edition release if enabled
if config.CHECK_BEDROCK:
bedrock_release = get_latest_bedrock_release()
if bedrock_release:
version_id = bedrock_release["id"]
print(f"[BOT] Reposting Bedrock release: {version_id}")
if post_to_subreddit(reddit, bedrock_release):
posted_count += 1
else:
print(f"[BOT] ⚠ No Bedrock release data available for repost")
print(f"[BOT] ✓ Reposted {posted_count} version(s)")
return posted_count > 0
except Exception as e:
print(f"[BOT] ✗ Error reposting latest versions: {e}")
return False
def chat_message_watcher(reddit):
"""
Background thread that watches for chat messages with reload commands.
Monitors Reddit chat messages for moderators sending "reload-config"
to trigger a reload of the wiki configuration without restarting the bot.
Args:
reddit: PRAW Reddit instance
"""
chat_requests_file = os.path.join(DB_DIR, 'chat_wiki_requests.txt')
processed_message_ids = set()
subreddit = reddit.subreddit(config.SUBREDDIT)
print("[CHAT] Chat message watcher started")
# Load previously processed message IDs
if os.path.exists(chat_requests_file):
try:
with open(chat_requests_file, 'r', encoding='utf-8') as f:
for line in f:
processed_message_ids.add(line.strip())
except Exception as e:
print(f"[CHAT] Error loading processed message IDs: {e}")
while True:
try:
for message in reddit.inbox.stream():
# Skip if no ID or already processed
if not hasattr(message, 'id') or message.id in processed_message_ids:
continue
# Mark as processed
processed_message_ids.add(message.id)
try:
with open(chat_requests_file, 'a', encoding='utf-8') as f:
f.write(message.id + '\n')
except Exception as e:
print(f"[CHAT] Error saving message ID: {e}")
# Check for reload-config command
if hasattr(message, 'body') and 'reload-config' in message.body.lower():
author = getattr(message, 'author', None)
# Verify sender is a moderator
try:
if author and author in subreddit.moderator():
print(f"[CHAT] Moderator '{author}' requested config reload")
# Reload wiki configuration
try:
wiki_config.fetch_from_wiki()
print("[CHAT] Wiki config reloaded successfully")
reply_text = "✓ Wiki config reloaded successfully!"
except Exception as e:
print(f"[CHAT] Failed to reload wiki config: {e}")
reply_text = f"✗ Failed to reload wiki config: {e}"
# Reply to the message
try:
message.reply(reply_text)
print(f"[CHAT] Replied to message {message.id}")
except Exception as e:
print(f"[CHAT] Error replying to message {message.id}: {e}")
else:
print(f"[CHAT] Non-moderator '{author}' attempted reload-config (ignored)")
except Exception as e:
print(f"[CHAT] Error checking moderator status: {e}")
# Check for repost-latest command
elif hasattr(message, 'body') and 'repost-latest' in message.body.lower():
author = getattr(message, 'author', None)
# Verify sender is a moderator
try:
if author and author in subreddit.moderator():
print(f"[CHAT] Moderator '{author}' requested repost of latest versions")
# Repost latest versions
try:
if repost_latest_versions(reddit):
reply_text = "✓ Latest versions reposted successfully!"
else:
reply_text = "✗ Failed to repost latest versions."
except Exception as e:
print(f"[CHAT] Error reposting latest versions: {e}")
reply_text = f"✗ Error reposting latest versions: {e}"
# Reply to the message
try:
message.reply(reply_text)
print(f"[CHAT] Replied to message {message.id}")
except Exception as e:
print(f"[CHAT] Error replying to message {message.id}: {e}")
else:
print(f"[CHAT] Non-moderator '{author}' attempted repost-latest (ignored)")
except Exception as e:
print(f"[CHAT] Error checking moderator status: {e}")
except Exception as e:
print(f"[CHAT] Error in chat message watcher: {e}")
time.sleep(30)
def bot_thread(reddit): def bot_thread(reddit):
""" """
Background thread that periodically checks for Minecraft updates. Background thread that periodically checks for Minecraft updates.
@@ -191,10 +342,14 @@ def start_bot():
# Do an initial check # Do an initial check
check_for_updates(reddit) check_for_updates(reddit)
# Start background thread # Start background thread for update checking
thread = threading.Thread(target=bot_thread, args=(reddit,), daemon=True) thread = threading.Thread(target=bot_thread, args=(reddit,), daemon=True)
thread.start() thread.start()
# Start background thread for chat commands
chat_thread = threading.Thread(target=chat_message_watcher, args=(reddit,), daemon=True)
chat_thread.start()
print("[BOT] ✓ Bot is running") print("[BOT] ✓ Bot is running")
# Keep main thread alive # Keep main thread alive
+1
View File
@@ -1,3 +1,4 @@
praw==7.7.0 praw==7.7.0
requests==2.31.0 requests==2.31.0
PyYAML==6.0.1 PyYAML==6.0.1
beautifulsoup4==4.12.2
+7 -3
View File
@@ -7,10 +7,10 @@ import json
import re import re
import yaml import yaml
from typing import Dict, Optional, Tuple from typing import Dict, Optional, Tuple
import config
# Cache TTL in seconds (refresh wiki config every 30 minutes) # Cache TTL in seconds (refresh wiki config every 30 minutes)
WIKI_CACHE_TTL = 1800 WIKI_CACHE_TTL = 1800
WIKI_PAGE_NAME = "minecraft_update_bot"
class WikiConfig: class WikiConfig:
@@ -72,7 +72,10 @@ class WikiConfig:
""" """
try: try:
subreddit = self.reddit.subreddit(self.subreddit_name) subreddit = self.reddit.subreddit(self.subreddit_name)
wiki_page = subreddit.wiki[WIKI_PAGE_NAME] print(f"[WIKI_CONFIG] Attempting to fetch wiki page: {config.WIKI_PAGE_NAME}")
# Try the wiki page with the configured name
wiki_page = subreddit.wiki[config.WIKI_PAGE_NAME]
content = wiki_page.content_md content = wiki_page.content_md
self.configs = self._parse_yaml_content(content) self.configs = self._parse_yaml_content(content)
@@ -88,7 +91,8 @@ class WikiConfig:
return False return False
except Exception as e: except Exception as e:
print(f"[WIKI_CONFIG] ✗ Error fetching wiki: {e}") print(f"[WIKI_CONFIG] ✗ Error fetching wiki page '{config.WIKI_PAGE_NAME}' from r/{self.subreddit_name}: {e}")
print(f"[WIKI_CONFIG] ⚠ Check that the page exists at reddit.com/r/{self.subreddit_name}/wiki/{config.WIKI_PAGE_NAME}")
return False return False
def _parse_yaml_content(self, content: str) -> Dict[str, Dict[str, str]]: def _parse_yaml_content(self, content: str) -> Dict[str, Dict[str, str]]: