A versatile Discord bot that monitors multiple RSS feeds and GitHub repositories to deliver AI-generated summaries. Keep your community informed with automated updates from blogs, game engines, tech sites, and any RSS-enabled source.
- π° Multiple RSS feed support - Register and monitor unlimited RSS feeds
- π GitHub PR monitoring with high-value filtering and auto-categorization
- β° Time-based scheduling - Set specific check times per feed (HH:MM format)
- π€ Automatic RSS monitoring with flexible per-feed scheduling
- π§ AI-powered summaries using Google Gemini 2.5 Flash
- π’ Multi-channel support with configurable limits
- π Many-to-many architecture: channels can subscribe to multiple feeds
- π― Per-feed customization: different schedules, different channels
- π Admin-only feed and channel management via slash commands
- πΎ Redis-backed persistence with per-feed pending queues
- π‘οΈ Cost management with rate limiting and circuit breaker
- π Automatic retry logic with exponential backoff
- π Token counting to prevent API quota overruns
- π Multilingual summaries in 6 languages (pt-BR, en, es, fr, de, ja)
- β Fully tested with TDD architecture (55 tests across all packages)
- Go 1.23+
- Redis Server
- Discord Bot Token
- Google Gemini API Key
- Clone and setup:
git clone <repository-url>
cd guara-bot
cp .env.example .env- Configure
.env:
DISCORD_TOKEN=your_discord_bot_token
GEMINI_API_KEY=your_gemini_api_key
MAX_CHANNELS_LIMIT=5
CHECK_INTERVAL_MINUTES=15 # Fallback for feeds without schedules
REDIS_URL=localhost:6379
REDIS_PASSWORD=
# GitHub Integration (Optional)
GITHUB_TOKEN=your_github_pat
GITHUB_CHECK_INTERVAL_MINUTES=30
GITHUB_BATCH_THRESHOLD=5
GITHUB_FILTER_MIN_CHANGES=5
# Rate Limiting (Gemini Free Tier Protection)
GEMINI_MAX_REQUESTS_PER_MINUTE=10
GEMINI_MAX_TOKENS_PER_MINUTE=200000
GEMINI_MAX_TOKENS_PER_REQUEST=4000
GEMINI_CIRCUIT_BREAKER_THRESHOLD=5
GEMINI_CIRCUIT_BREAKER_TIMEOUT_MINUTES=5
GEMINI_RETRY_ATTEMPTS=3
GEMINI_RETRY_BACKOFF_SECONDS=1- Run with Docker:
docker-compose up -dOr run locally:
go run ./cmd/botFor more information, please check out here
# Register RSS feeds from various sources
/register-feed godot https://godotengine.org/rss.xml "Godot Engine" "Game engine news"
/register-feed gdquest https://www.gdquest.com/rss.xml "GDQuest" "Godot tutorials"
/register-feed techcrunch https://techcrunch.com/feed/ "TechCrunch" "Tech news"
/register-feed dev-to https://dev.to/feed "DEV Community" "Developer articles"
# List all registered feeds
/list-feeds
# Set check times for each feed (9 AM, 1 PM, 6 PM)
/schedule-feed godot 09:00,18:00
/schedule-feed techcrunch 08:00,12:00,17:00
# Remove a feed
/unregister-feed gdquest# Subscribe channels to specific feeds
/setup-feed-channel #game-news godot
/setup-feed-channel #tutorials gdquest
/setup-feed-channel #tech-news techcrunch
# A single channel can subscribe to multiple feeds
/setup-feed-channel #general godot
/setup-feed-channel #general techcrunch
/setup-feed-channel #general dev-to
# Unsubscribe from a feed
/remove-feed-channel #tutorials gdquest
# Force immediate check of a specific feed
/update-feed godot
/update-feed techcrunch
# Force immediate check of all registered feeds
/update-all-feedsThe bot automatically creates a default feed called godot-official pointing to Godot Engine news for backward compatibility. You can remove it and add your own feeds as needed.
# Register repositories to monitor
/register-repo godot-engine godotengine godot master
/register-repo rust-lang rust-lang rust master
/register-repo python python cpython main
# Subscribe channels to repository updates
/setup-repo-channel #pr-updates godot-engine
/setup-repo-channel #rust-news rust-lang
# Set check schedules (9 AM, 1 PM, 6 PM)
/schedule-repo godot-engine 09:00,13:00,18:00
/schedule-repo rust-lang 10:00,16:00
# List all registered repos with stats
/list-repos
# Force immediate check and process one batch
/update-repo godot-engine
# Force check all repositories
/update-all-repos
# Unsubscribe channel
/remove-repo-channel #pr-updates godot-engine
# Remove repository entirely
/unregister-repo rust-langHow GitHub Monitoring Works:
- Bot fetches merged PRs from the last 3 days
- Filters PRs based on labels and minimum line changes (default: 5)
- Adds high-value PRs to pending queue
- When threshold reached (default: 5), processes one batch
- Generates AI summary with categorization and "Why it matters"
- Posts to all subscribed channels in their configured language
- Repeats on next scheduled check or manual trigger
PR Filtering:
- Accepted labels: bug, enhancement, performance, optimization, usability, accessibility, security
- Minimum changes: 5 lines (configurable via
GITHUB_FILTER_MIN_CHANGES) - Rejected: Documentation-only, trivial changes, unlabeled minor PRs
- Example logs:
β PR #114978 accepted (label: bug, changes: 14 lines) β PR #114979 rejected (too few changes: 1 < 5)
Batch Processing:
- Processes 5 PRs at a time (configurable via
GITHUB_BATCH_THRESHOLD) - If 42 PRs pending with 3 daily checks = ~3 days to clear queue
- Each batch gets AI-categorized into: Features, Bugfixes, Performance, UI/UX, Security
- Gradual processing prevents token limit overruns
The bot includes comprehensive cost management to protect against exceeding Gemini API free tier limits:
- Token Counting: Estimates input/output tokens before making requests
- Rate Limiting: Enforces 10 RPM and 200k TPM limits (configurable)
- Circuit Breaker: Temporarily stops requests after 5 consecutive failures
- Retry Logic: Automatic retries with exponential backoff (1s, 2s, 4s, etc.)
- Wait for Capacity: Automatically waits when limits are reached
- 15 requests per minute (RPM)
- 250,000 tokens per minute (TPM)
- Bot defaults to conservative 10 RPM / 200k TPM
All rate limits are configurable via environment variables (see .env.example). The defaults are set conservatively to ensure you stay well within the free tier limits.
Check logs for rate limiting information:
Rate Limiting: 10 RPM, 200000 TPM, Circuit Breaker: 5 failures
Token estimate: input=1234, estimated_output=1500, total=2734
Request successful, recorded 2850 tokens
Contributions are welcome! Please:
- Write tests for new features
- Follow Go conventions
- Use table-driven tests
- Keep interfaces for testability
- Run
go fmtbefore committing
- Ensure bot has proper Discord permissions
- Check bot token is correct
- Verify bot is invited with
applications.commandsscope
- Use
/list-feedsto verify feeds are registered - Use
/list-channelsto ensure channels are subscribed - Check feed schedules with
/list-feedsor set them with/schedule-feed - Verify feed URL is accessible:
curl <feed-url> - Verify Gemini API key is valid
- Use
/update-feedto trigger immediate check - Check logs for error messages
- Note: Bot checks every minute for scheduled times
- Ensure Redis server is running:
redis-cli ping - Check Redis URL and password in
.env - Verify Redis port is not blocked by firewall
- For Docker: ensure container is accessible
- Run
go mod downloadto ensure dependencies - Check Go version is 1.23+
- Run with
-vflag for verbose output - Tests use miniredis, so external Redis not needed
MIT