A Discord bot that monitors UniFi community releases and posts announcements to a Discord channel.
- Modular Scraper Architecture: Swappable backends for different scraping needs
- GraphQL API: Direct API access for reliable data fetching
- Docker Ready: Optimized Alpine-based container (157MB)
- Environment Configuration: Easy backend switching via environment variables
- π Automatic Monitoring: Checks for new UniFi releases every 10 minutes
- π± Platform Detection: Automatically tags releases with platform-specific emojis (iOS π±, Android π€, Desktop π»)
- π― Smart Filtering: Only posts new releases, avoiding duplicates
- βΈοΈ Kubernetes Support: Ready for deployment on k3s/Kubernetes clusters
- Python 3.13
- Discord Bot Token
- Discord Channel ID where announcements will be posted
-
Clone the repository:
git clone <repository-url> cd unifi-release-announcer
-
Install dependencies using uv:
uv sync --extra dev
-
Configure environment variables:
Create a
.envfile in the project root:DISCORD_BOT_TOKEN=your_discord_bot_token DISCORD_CHANNEL_ID=your_discord_channel_id SCRAPER_BACKEND=graphql # or 'rss' if you prefer
-
Run the application:
uv run main.py
-
Build the Docker image:
docker compose build
-
Run the container:
docker compose run announcer
For the best development experience, use the provided dev container configuration:
-
Prerequisites:
- VS Code with the Dev Containers extension
- Docker Desktop
-
Open in Dev Container:
- Open the project in VS Code
- Press
Ctrl+Shift+P(orCmd+Shift+Pon Mac) - Select "Dev Containers: Reopen in Container"
- Wait for the container to build and start
-
Features included:
- Pre-configured Python environment with all dependencies
- GraphQL API support
- Python extensions (Black, Ruff, MyPy, Pytest)
- Volume mounts for live code editing
- Automatic dependency installation
See the k8s/README.md for detailed Kubernetes deployment instructions.
| Variable | Description | Required |
|---|---|---|
DISCORD_BOT_TOKEN |
Your Discord bot token | Yes |
DISCORD_CHANNEL_ID |
Discord channel ID for announcements | Yes |
SCRAPER_BACKEND |
Backend to use for scraping: graphql (default) or rss |
No |
TAGS |
Comma-separated list of UniFi product tags to monitor (e.g., "unifi-protect,unifi-network"). Defaults to "unifi-protect" if not set. See Available Tags below. | No |
- Go to the Discord Developer Portal
- Create a new application
- Go to the "Bot" section and create a bot
- Copy the bot token
- Invite the bot to your server with "Send Messages" permission
- Get your channel ID by right-clicking on the channel and selecting "Copy ID"
The following tags are available for filtering UniFi releases:
UniFi Products:
unifi- General UniFi releasesunifi-access- UniFi Access (door access control)unifi-cloud-gateway- UniFi Cloud Gatewayunifi-connect- UniFi Connectunifi-design-center- UniFi Design Centerunifi-drive- UniFi Drive (storage)unifi-gateway-cloudkey- UniFi Gateway and Cloud Keyunifi-led- UniFi LEDunifi-mobility- UniFi Mobilityunifi-network- UniFi Network (switches, routers)unifi-play- UniFi Playunifi-portal- UniFi Portalunifi-protect- UniFi Protect (security cameras) - Defaultunifi-routing-switching- UniFi Routing and Switchingunifi-switching- UniFi Switchingunifi-talk- UniFi Talk (VoIP)unifi-video- UniFi Video (legacy)unifi-voip- UniFi VoIPunifi-wireless- UniFi Wireless (access points)
Other Ubiquiti Products:
60GHz- 60GHz wireless productsaircontrol- AirControl softwareairfiber- AirFiber productsairfiber-ltu- AirFiber LTUairmax- AirMax productsairmax-aircube- AirMax AirCubeamplifi- AmpliFi consumer routersedgemax- EdgeMax routersedgeswitch- EdgeSwitch productsgigabeam- GigaBeam productsinnerspace- InnerSpace location servicesisp- ISP solutionsisp-design-center- ISP Design Centerufiber- UFiber productsuid- UID productsuisp-app- UISP applicationuisp-power- UISP Power managementunms- UNMS (legacy)wave- Wave productswifiman- WiFiman application
General Categories:
community-feedback- Community feedbackgeneral- General announcementsrouting- Routing productssecurity- Security productssite-manager- Site managementsolar- Solar productsswitching- Switching products
Examples:
# Monitor only UniFi Protect releases (default)
TAGS="unifi-protect"
# Monitor UniFi Protect and Network releases
TAGS="unifi-protect,unifi-network"
# Monitor all UniFi products
TAGS="unifi,unifi-protect,unifi-network,unifi-access,unifi-talk"
# Monitor EdgeMax and AmpliFi products
TAGS="edgemax,amplifi"- Scraping: The bot scrapes the Ubiquiti Community forums for the latest UniFi releases
- Comparison: It compares the latest release URL with the previously posted one (stored in
/cache/release_state.json) - Posting: If a new release is found, it formats a message with platform tags and posts to Discord
- State Management: Updates the stored URL to prevent duplicate posts (stored in
/cache/release_state.json)
The bot posts messages in this format:
π **New UniFi Release Posted**
π [UniFi Protect iOS 2.13.1](https://community.ui.com/releases/...) π±Platform tags:
- π± for iOS releases
- π€ for Android releases
- π» for Desktop/Application releases
- π§ UniFi for other releases
βββ main.py # Main Discord bot application
βββ scraper_interface.py # Scraper backend interface and factory
βββ scraper_backends/ # Scraper backend implementations
β βββ graphql_backend.py
β βββ rss_backend.py
βββ test_scraper_interface.py # Unit tests for the scraper interface
βββ test_integration.py # Integration tests
βββ pyproject.toml # Project dependencies
βββ Dockerfile # Container configuration
βββ k8s/ # Kubernetes manifests
β βββ deployment.yaml
β βββ secret.yaml
β βββ kustomization.yaml
β βββ README.md
βββ README.md # This fileRun all tests using
task dev-install
task testOr run the tests directly using
uv run python -m pytest test_scraper_interface.py -v
uv run python -m pytest test_integration.py -v- Bot not posting: Check that the bot has "Send Messages" permission in the target channel
- Environment variables: Ensure both
DISCORD_BOT_TOKENandDISCORD_CHANNEL_IDare set - Channel ID format: The channel ID must be a valid number (Discord snowflake)
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
MIT License