MystiGuardian - Your server's mystical protector and entertainment extraordinaire. Uniting moderation with fun, it ensures a secure and delightful Discord experience.
⚠️ License Notice: This project is licensed under Apache License 2.0. Any use, modification, or distribution must comply with the license terms. See LICENSE and NOTICE for details.
Automatically scrapes and posts degree apprenticeship opportunities to Discord channels:
-
Higher In (Rate My Apprenticeship) - Scrapes 150+ categories including:
- Technology (Computer Science, Cyber Security, Software Engineering, AI, etc.)
- Business & Finance (Accounting, Banking, Management Consulting, etc.)
- Engineering (Mechanical, Civil, Electrical, Aerospace, etc.)
- And many more across all industries
-
GOV.UK Find an Apprenticeship - Comprehensive coverage of all 15 official route categories:
- Agriculture, environmental and animal care
- Business and administration
- Care services
- Catering and hospitality
- Construction and the built environment
- Creative and design
- Digital
- Education and early years
- Engineering and manufacturing
- Hair and beauty
- Health and science
- Legal, finance and accounting
- Protective services
- Sales, marketing and procurement
- Transport and logistics
- ✅ Automated scraping with configurable scheduling
- ✅ Duplicate detection - only new apprenticeships are posted
- ✅ Google Sheets integration for data persistence
- ✅ Rich Discord embeds with all relevant information
- ✅ Category-based role pinging
- ✅ Batch posting with rate limiting
- ✅ Robust error handling - errors in one category don't stop others
- Server protection and moderation tools
- User management and permissions
- Secure data handling with encryption
- Fun commands and interactions
- Server utilities and management
- YouTube integration for content updates
- DiscordBot - Main bot with JDA integration and commands
- ApprenticeshipScraper - Web scraping and Google Sheets management
HigherinScraper- Specialized scraper for Higher InFindAnApprenticeshipScraper- Specialized scraper for GOV.UKApprenticeshipScraper- Facade coordinating both scrapers
- OAuth - OAuth authentication and web service
- Annotations - Custom annotations for the project
- Java 21+ with virtual threads support
- JDA (Java Discord API) for Discord integration
- OkHttp for efficient HTTP requests with connection pooling
- Jsoup for HTML parsing (GOV.UK)
- Jackson for JSON processing (Higher In)
- Google Sheets API for data persistence
- PostgreSQL with JOOQ for database operations
- Gradle with Kotlin DSL and Version Catalog
The following is required in your config.json file:
{
"token": "",
"ownerId": "",
"githubToken": "",
"daConfig": {
"discordChannelId": "",
"guildId": "",
"spreadsheetId": ""
},
"youtube": {
"apiKey": "",
"channelId": "",
"discordChannelId": "",
"guildId": ""
},
"dataSource": {
"user": "",
"password": "",
"driver": "org.postgresql.Driver",
"port": "",
"name": "postgres",
"host": "",
"url": ""
},
"discord-auth": {
"clientId": "",
"clientSecret": ""
},
"tripAdvisor": {
"apiKey": ""
},
"log": {
"logGuildId": "",
"logChannelId": ""
}
}You will also need a public and private key for the bot to use for encryption. These should be placed in your home directory under the names public.key and private.key respectively.
For apprenticeship scraping, you'll need:
- A Google Cloud project with Sheets API enabled
- Service account credentials
- A Google Sheet with appropriate permissions for the service account
- The spreadsheet ID configured in
daConfig.spreadsheetId
- Moved hardcoded category and route lists into dedicated configuration classes for easier maintenance:
HigherinCategories- organizes Higher In category slugs by sectorGovUkRoutes- maps GOV.UK route names to official IDs
- Reorganized packages to improve clarity and separation of concerns (scraper, categories, apprenticeship models, manager, config)
- Cleaner code structure: specialized scrapers and a small facade
ApprenticeshipScraper - Improved Javadoc and documentation for category configuration classes
- Immutable collections used for category/route definitions
- No breaking changes to spreadsheet format or Discord posting
- Scrapers now read categories from the new configuration classes, making updates easier without touching scraper logic
See CHANGELOG.md for the full version history.
- VERSION_MANAGEMENT.md - Complete guide to Gradle Version Catalog
- VERSION_CATALOG_QUICK_REFERENCE.md - Quick reference for dependency management
- CHANGELOG.md - Detailed version history
- .github/copilot-instructions.md - Project conventions and guidelines
- Java 21 or higher
- PostgreSQL database
- Google Cloud project with Sheets API
- Discord bot token
./gradlew build./gradlew runOr use the shadow JAR:
java -jar build/libs/MystiGuardian-0.0.9.jarCopyright 2024 RealYusufIsmail
This project is licensed under the Apache License 2.0. This means:
- ✅ You CAN: Use, modify, and distribute this code (with conditions)
- ✅ You CAN: Use this for commercial purposes
- ✅ You CAN: Distribute modified versions
- ❌ You MUST: Include the original copyright notice
- ❌ You MUST: Include a copy of the Apache License 2.0
- ❌ You MUST: State significant changes made
- ❌ You CANNOT: Use trademarks without permission
- ❌ You CANNOT: Hold the author liable
Important Files:
- LICENSE - Full Apache License 2.0 text
- NOTICE - Required attribution and third-party licenses
- SECURITY.md - Security policy and vulnerability reporting
All source code files include copyright headers. If you use this code:
- Retain all copyright notices from source files
- Include LICENSE and NOTICE files in distributions
- Document changes you make to the code
- Provide attribution to the original project
Example attribution:
Based on MystiGuardian by RealYusufIsmail
https://github.com/RealYusufIsmail/MystiGuardian
Licensed under Apache License 2.0
- 🔐 Never commit sensitive data -
config.json,service-account.json, tokens, passwords - 🛡️ Report vulnerabilities responsibly - See SECURITY.md
- 🔑 Rotate credentials regularly - Discord tokens, database passwords, API keys
- 📋 Follow security best practices - Use environment variables in production
⚠️ Keep dependencies updated - Run./gradlew dependencyUpdatesregularly
Found a security issue? Contact the maintainer privately - do NOT open public issues for security vulnerabilities.
This project follows the Contributor Covenant Code of Conduct. By participating, you agree to:
- 🤝 Be respectful and inclusive
- 💡 Provide constructive feedback
- 🎯 Focus on what's best for the community
- ⚖️ Respect intellectual property rights
- 🚫 Not engage in harassment or inappropriate behavior
Violations of the license or code of conduct will result in removal from the community and may result in legal action.
Licensed under the Apache License, Version 2.0. See LICENSE for details.
Contributions are welcome! Please read our guidelines first:
- 📖 CONTRIBUTING.md - How to contribute
- 📋 CODE_OF_CONDUCT.md - Community standards
- 🔒 SECURITY.md - Security policy
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes following our code standards
- Format your code:
./gradlew spotlessApply - Test your changes:
./gradlew test - Commit with clear messages:
git commit -m "feat: Add amazing feature" - Push to your fork:
git push origin feature/amazing-feature - Open a Pull Request
This project uses:
- Spotless for code formatting (Google Java Style)
- Gradle Version Catalog for dependency management
- Semantic Versioning for releases
- Keep a Changelog format for version history
Please ensure your code follows the project conventions before submitting PRs.