{"id":50780051,"url":"https://github.com/jaiwargacki/alertbot","last_synced_at":"2026-06-12T03:00:25.072Z","repository":{"id":362948265,"uuid":"1260897276","full_name":"jaiwargacki/AlertBot","owner":"jaiwargacki","description":"Configurable, YAML-driven Discord bot that monitors services, files, and more — and alerts you on Discord","archived":false,"fork":false,"pushed_at":"2026-06-06T18:06:18.000Z","size":83,"stargazers_count":0,"open_issues_count":18,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-06T18:16:08.871Z","etag":null,"topics":["alerting","discord-bot","self-hosted","yaml"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaiwargacki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-06T02:07:21.000Z","updated_at":"2026-06-06T18:06:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jaiwargacki/AlertBot","commit_stats":null,"previous_names":["jaiwargacki/alertbot"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/jaiwargacki/AlertBot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaiwargacki%2FAlertBot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaiwargacki%2FAlertBot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaiwargacki%2FAlertBot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaiwargacki%2FAlertBot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaiwargacki","download_url":"https://codeload.github.com/jaiwargacki/AlertBot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaiwargacki%2FAlertBot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34226629,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alerting","discord-bot","self-hosted","yaml"],"created_at":"2026-06-12T03:00:15.302Z","updated_at":"2026-06-12T03:00:25.063Z","avatar_url":"https://github.com/jaiwargacki.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AlertBot\n\n## Requirements\n\n- [uv](https://docs.astral.sh/uv/getting-started/installation/) — used for dependency management and running the bot\n\n**Windows:**\n```powershell\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n```\n\n**Linux/macOS:**\n```bash\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n```\n\n## Setup\n\nInstall dependencies:\n\n```bash\nuv sync\n```\n\nThen point AlertBot at a config directory (see **Configuration** below). The\nservice reads its Discord token and root user from `alertbot.yaml` /\n`secrets.env` — not a `.env` file.\n\n## Running\n\n```bash\nuv run src/bot.py\n```\n\n`bot.py` loads the configuration, builds the monitors, and runs the engine: it\npolls each monitor on its schedule and posts alerts (with ack/snooze/mute\nbuttons) to the Discord channels named by `notify:`, DMing the root user for\n`critical`. Monitor state persists to the SQLite store, so `alertbot list` /\n`alertbot status` reflect what the running service sees.\n\nWhile it runs, the root user can open the **`/monitors` control panel** in a DM\nto enable/disable monitors at runtime — individually or by group (a group is one\n`monitors.d/*.yaml` file) — straight from a phone, no YAML edit or shell access.\nToggles persist across config reloads and restarts; a disabled monitor stops\nbeing polled on the next cycle. Set `dm_control: false` on a monitor to keep it\nout of the panel's reach.\n\nConfig and store locations are resolved the same way the CLI resolves them, so\nthe service and `alertbot` agree:\n\n| Variable | Default | Purpose |\n|---|---|---|\n| `ALERTBOT_CONFIG_DIR` | `/etc/alertbot` | directory holding `alertbot.yaml`, `secrets.env`, `monitors.d/` |\n| `ALERTBOT_STORE` | `/var/lib/alertbot/alertbot.db` | SQLite state store |\n| `ALERTBOT_PID_FILE` | `/run/alertbot/alertbot.pid` | PID file (lets `alertbot status` report \"running\") |\n| `ALERTBOT_READY_FILE` | `/run/alertbot/ready` | readiness marker, stamped once Discord connects — the health signal `deploy/update.sh` polls |\n\nOn the Windows dev box, point these at local paths, e.g.:\n\n```powershell\n$env:ALERTBOT_CONFIG_DIR = \"examples\\alertbot\"\n$env:ALERTBOT_STORE = \"$env:LOCALAPPDATA\\AlertBot\\alertbot.db\"\nuv run src/bot.py\n```\n\nThe service fails fast — invalid config, a missing token, or a bad `schedule:`\nexits with a clear `file:line` error before it connects — and shuts down\ncleanly on SIGINT/SIGTERM (and Windows Ctrl-C), draining in-flight checks first.\nConfig changes hot-reload without a restart: `alertbot reload` (or\n`systemctl reload` / SIGHUP on Linux) re-validates and swaps the monitor set in\nplace — a bad config is rejected and the running config keeps serving.\n\n## Deployment (Ubuntu / systemd)\n\nFor a production box, run AlertBot as a long-lived systemd service — auto-restart,\nstart on boot, config-validate on start, hot-reload on `systemctl reload`, and\nlogs to the journal. Everything you need is in [`deploy/`](deploy):\n\n```bash\ngit clone https://github.com/jaiwargacki/AlertBot.git\ncd AlertBot\nsudo ./deploy/install.sh     # sets up the service user, /etc/alertbot, the venv, the unit\n# then fill in /etc/alertbot/secrets.env + alertbot.yaml and:\nsudo systemctl start alertbot\njournalctl -u alertbot -f\n```\n\nUpdating is operator-run and safety-checked: `deploy/update.sh` fast-forwards the\nsource checkout, runs the tests, redeploys, restarts, health-checks via the\nreadiness marker, and **rolls back automatically** if the new version doesn't come\nup healthy. An opt-in staleness monitor (`deploy/alertbot-self-stale.yaml` +\n`check-update.sh`) nudges you in Discord when the deployed bot falls behind\n`origin/main`.\n\nSee [`deploy/README.md`](deploy/README.md) for the full walkthrough (manual steps,\nsecrets permissions, journald logging, reload/restart, reboot recovery, updating,\nthe staleness monitor, and uninstall).\n\n## Configuration (monitors)\n\nAlertBot is driven by YAML config, not code changes. A config directory holds:\n\n```\nalertbot/\n├── alertbot.yaml      # global: Discord token ref, channel IDs, defaults\n├── secrets.env        # ${VAR} values, chmod 600, never committed\n└── monitors.d/        # drop-in directory — one concern per file\n    ├── 10-incoming-image.yaml   # directory watch: post each new image to a channel\n    └── 20-backup-script.yaml    # command: run a script, alert on failure + recovery\n```\n\nSee [`examples/alertbot/`](examples/alertbot) for a working template with exactly\nthis layout.\n\n- **Drop-in:** add a watch by dropping a `*.yaml` file in `monitors.d/`. Numeric\n  prefixes control load order.\n- **Disable:** rename a file to `*.yaml.off`, or set `enabled: false` on a monitor.\n  At runtime, the root user can also toggle monitors (or whole files' worth) from\n  the `/monitors` panel in Discord — see **Running** above.\n- **Secrets:** config references secrets as `${DISCORD_BOT_TOKEN}`, resolved from\n  `secrets.env` (or the environment). Config is safe to commit; secrets are not.\n- **Validation:** the loader reports every problem with a `file:line` location and\n  an \"did you mean\" hint for misspelled fields, and never crashes on bad input.\n\n## CLI (`alertbot`)\n\n`uv sync` installs an `alertbot` command that reads the same config and store\nthe service does, so you can build confidence in a config before and while the\nservice runs. It resolves paths via the same flags / `ALERTBOT_*` env vars.\n\n```bash\nuv run alertbot validate    # parse + schema-check every file and monitor; non-zero exit on error\nuv run alertbot list        # table of configured monitors (type, schedule, severity) + current state\nuv run alertbot status      # whether the service is running (PID file) + last state/event per monitor\nuv run alertbot reload      # signal the running service to re-validate and hot-swap its config\nuv run alertbot test \u003cid\u003e   # fire one monitor now and preview the exact embed (--send to deliver)\nuv run alertbot send \"msg\"  # deliver an ad-hoc alert to confirm the pipe end to end (--preview to dry-run)\n```\n\n`validate` catches a bad config before it ever applies. `list` and `status` are\nread-only — a missing store simply reports unknown state, never creating it —\nand show monitors disabled from the `/monitors` panel as `disabled` (distinct\nfrom config-disabled monitors, which aren't loaded at all).\n\n## Tests\n\n```bash\nuv run pytest\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaiwargacki%2Falertbot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaiwargacki%2Falertbot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaiwargacki%2Falertbot/lists"}