Release 1.0.0
This commit is contained in:
+11
-8
@@ -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
|
||||||
|
|||||||
@@ -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,145 +7,244 @@ This project includes Docker and Docker Compose configuration for easy deploymen
|
|||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
### 1. Copy Environment File
|
1. Copy environment template:
|
||||||
|
```bash
|
||||||
|
copy .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
```bash
|
2. Edit `.env` with your Reddit credentials:
|
||||||
copy .env.example .env
|
```env
|
||||||
```
|
REDDIT_CLIENT_ID=your_client_id
|
||||||
|
REDDIT_CLIENT_SECRET=your_client_secret
|
||||||
|
REDDIT_USERNAME=your_username
|
||||||
|
REDDIT_PASSWORD=your_password
|
||||||
|
SUBREDDIT=your_subreddit
|
||||||
|
```
|
||||||
|
|
||||||
### 2. Edit .env
|
3. Start the bot:
|
||||||
|
```bash
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
Open `.env` and fill in your Reddit credentials:
|
4. Verify it's running:
|
||||||
|
```bash
|
||||||
|
docker-compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
```env
|
||||||
REDDIT_CLIENT_ID=your_client_id
|
REDDIT_CLIENT_ID=abc123
|
||||||
REDDIT_CLIENT_SECRET=your_client_secret
|
REDDIT_CLIENT_SECRET=xyz789
|
||||||
REDDIT_USERNAME=your_username
|
REDDIT_USERNAME=mybot
|
||||||
REDDIT_PASSWORD=your_password
|
REDDIT_PASSWORD=botpass
|
||||||
SUBREDDIT=your_subreddit
|
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
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. (Optional) Set Up Wiki Configuration
|
## Container Management
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
Start the bot:
|
||||||
```bash
|
```bash
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
This will:
|
Stop the bot:
|
||||||
- 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
|
|
||||||
# Watch logs in real-time
|
|
||||||
docker-compose logs -f
|
|
||||||
|
|
||||||
# Or check status
|
|
||||||
docker-compose ps
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. 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
@@ -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"]
|
||||||
|
|||||||
+154
-44
@@ -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
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Create Reddit app at https://www.reddit.com/prefs/apps (select "Script" type)
|
||||||
|
|
||||||
|
3. Set environment variables:
|
||||||
|
```bash
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Run the bot:
|
||||||
|
```bash
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Required env vars:
|
||||||
|
- REDDIT_CLIENT_ID
|
||||||
|
- REDDIT_CLIENT_SECRET
|
||||||
|
- REDDIT_USERNAME
|
||||||
|
- REDDIT_PASSWORD
|
||||||
|
- SUBREDDIT
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
## Wiki Configuration
|
||||||
|
|
||||||
|
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}
|
||||||
|
```
|
||||||
|
|
||||||
|
Placeholders: {version}, {release_date}, {type}
|
||||||
|
|
||||||
|
See WIKI_CONFIG.md for complete examples.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Manual Version Checker Test
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd d:\Git Repos\MinecraftUpdates
|
python -c "from minecraft_checker import get_latest_releases; import json; print(json.dumps(get_latest_releases(['release']), indent=2))"
|
||||||
pip install -r requirements.txt
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2️⃣ Reddit Setup
|
### Bedrock Checker Test
|
||||||
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
|
```bash
|
||||||
Edit `config.py`:
|
python -c "from bedrock_checker import get_latest_bedrock_release; import json; result = get_latest_bedrock_release(); print(json.dumps(result, indent=2))"
|
||||||
```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
|
### Full Configuration Test
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python test_setup.py
|
python test_setup.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Should show:
|
Expected output:
|
||||||
- ✓ Configuration checked
|
- Configuration loaded successfully
|
||||||
- ✓ Minecraft API working
|
- Minecraft API reachable
|
||||||
- ✓ Reddit connection working
|
- Reddit connection working
|
||||||
|
- Wiki configuration loaded
|
||||||
|
|
||||||
## 5️⃣ Run
|
## 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
|
```bash
|
||||||
python main.py
|
docker-compose logs -f
|
||||||
```
|
```
|
||||||
|
|
||||||
See posts appear in your subreddit automatically!
|
Manual:
|
||||||
|
```
|
||||||
---
|
Watch console output for [BOT], [CHAT], [BEDROCK_CHECKER] messages
|
||||||
|
|
||||||
## Optional Config Changes
|
|
||||||
|
|
||||||
### Check for Snapshots Too
|
|
||||||
```python
|
|
||||||
RELEASE_TYPES = ["release", "snapshot"]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Check More Frequently (testing)
|
## Common Issues
|
||||||
```python
|
|
||||||
CHECK_INTERVAL = 600 # 10 minutes instead of 1 hour
|
|
||||||
```
|
|
||||||
|
|
||||||
### Customize Post Format
|
No posts appearing:
|
||||||
Edit the `POST_TEMPLATE` in `config.py` - it uses `{version}` and `{release_date}` placeholders.
|
- 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
|
||||||
|
|
||||||
## Files Overview
|
Wiki config not loading:
|
||||||
- `main.py` - The bot itself
|
- Verify wiki page name is exactly "minecraft_update_bot"
|
||||||
- `config.py` - Settings (edit this!)
|
- Ensure YAML syntax is valid
|
||||||
- `minecraft_checker.py` - Fetches Minecraft version data
|
|
||||||
- `test_setup.py` - Tests your configuration
|
|
||||||
- `DB/` - Stores tracking of posted versions (auto-created)
|
|
||||||
|
|||||||
@@ -1,152 +1,195 @@
|
|||||||
# 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
|
||||||
|
|
||||||
```bash
|
## Quick Start
|
||||||
# Copy and edit environment file
|
|
||||||
copy .env.example .env
|
|
||||||
# Edit .env with your Reddit credentials
|
|
||||||
|
|
||||||
# Start the bot
|
### Docker (Recommended)
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# View logs
|
1. Copy the environment template:
|
||||||
docker-compose logs -f
|
```bash
|
||||||
```
|
copy .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
4. View logs:
|
||||||
|
```bash
|
||||||
|
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:
|
1. Install dependencies:
|
||||||
- Create different post formats for releases vs. snapshots
|
```bash
|
||||||
- Customize titles and bodies without restarting
|
pip install -r requirements.txt
|
||||||
- Support legacy version types with custom messages
|
```
|
||||||
|
|
||||||
**Quick Setup:**
|
2. Create a Reddit application at https://www.reddit.com/prefs/apps (select "Script" type)
|
||||||
1. Create a wiki page named `minecraft_update_bot` on your subreddit
|
|
||||||
2. Add YAML configuration with your templates (see example below)
|
3. Configure environment variables or edit config.py:
|
||||||
3. Bot auto-loads every 30 minutes
|
```bash
|
||||||
|
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
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
Required variables:
|
||||||
|
- REDDIT_CLIENT_ID - Your Reddit OAuth app client ID
|
||||||
|
- REDDIT_CLIENT_SECRET - Your Reddit OAuth app secret
|
||||||
|
- REDDIT_USERNAME - Reddit account username
|
||||||
|
- REDDIT_PASSWORD - Reddit account password
|
||||||
|
- SUBREDDIT - Target subreddit name
|
||||||
|
|
||||||
|
Optional variables:
|
||||||
|
- 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:
|
||||||
|
|
||||||
**Simple Example:**
|
|
||||||
```yaml
|
```yaml
|
||||||
release:
|
release:
|
||||||
title: "Minecraft {version} Released!"
|
title: "Minecraft {version} Released"
|
||||||
body: |
|
body: |
|
||||||
# Minecraft {version}
|
New version available at minecraft.net
|
||||||
Available now! Get it at [minecraft.net](https://minecraft.net)
|
Released: {release_date}
|
||||||
**Released:** {release_date}
|
|
||||||
|
|
||||||
snapshot:
|
snapshot:
|
||||||
title: "Minecraft {version} Snapshot"
|
title: "Minecraft {version} Snapshot"
|
||||||
body: |
|
body: |
|
||||||
# New Snapshot Available
|
Test build available in launcher
|
||||||
Test {version} before the official release!
|
Released: {release_date}
|
||||||
|
|
||||||
|
bedrock-windows:
|
||||||
|
title: "Bedrock Edition {version} Available"
|
||||||
|
body: |
|
||||||
|
Download from Microsoft Store
|
||||||
|
Released: {release_date}
|
||||||
```
|
```
|
||||||
|
|
||||||
👉 See [WIKI_CONFIG.md](WIKI_CONFIG.md) for complete setup and examples.
|
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
|
## Bedrock Edition Support
|
||||||
|
|
||||||
The bot can track **Minecraft Bedrock Edition (Windows)** releases in addition to Java Edition.
|
The bot can track Minecraft Bedrock Edition (Windows) releases by scraping the official minecraft.wiki version history page.
|
||||||
|
|
||||||
**To enable Bedrock tracking:**
|
Enable with Docker:
|
||||||
|
```env
|
||||||
1. **With Docker:** Add to your `.env` file:
|
REDDIT_CHECK_BEDROCK=true
|
||||||
```
|
|
||||||
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
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip install -r requirements.txt
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Create Reddit Application
|
Or environment variable:
|
||||||
|
|
||||||
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):
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
set REDDIT_CLIENT_ID=your_client_id
|
set REDDIT_CHECK_BEDROCK=true
|
||||||
set REDDIT_CLIENT_SECRET=your_client_secret
|
|
||||||
set REDDIT_USERNAME=your_username
|
|
||||||
set REDDIT_PASSWORD=your_password
|
|
||||||
set SUBREDDIT=your_subreddit
|
|
||||||
python main.py
|
python main.py
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Customize (Optional)
|
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.
|
||||||
|
|
||||||
In `config.py`:
|
## Release Types
|
||||||
- **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:
|
Supported Java Edition release types:
|
||||||
```python
|
- release - Final Java Edition releases
|
||||||
# Check for both releases and snapshots
|
- snapshot - Development snapshots
|
||||||
RELEASE_TYPES = ["release", "snapshot"]
|
- old_beta - Legacy beta versions
|
||||||
|
- old_alpha - Legacy alpha versions
|
||||||
|
|
||||||
# Check every 30 minutes
|
Supported Bedrock Edition types:
|
||||||
CHECK_INTERVAL = 1800
|
- 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
|
||||||
|
|||||||
+234
-140
@@ -1,202 +1,296 @@
|
|||||||
# 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
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Watch for the line:
|
**Version:** {version}
|
||||||
```
|
**Release Date:** {release_date}
|
||||||
[WIKI_CONFIG] ✓ Loaded X configuration(s)
|
|
||||||
```
|
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!
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 3: Structured with Emojis (if preferred)
|
||||||
|
|
||||||
|
```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
|
||||||
|
|
||||||
|
|||||||
+75
-77
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
|
|
||||||
|
|||||||
@@ -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,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
@@ -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]]:
|
||||||
|
|||||||
Reference in New Issue
Block a user