Universal Notification Gateway. A self-hosted rules engine that accepts arbitrary JSON webhooks, exposes every payload item as a template variable, and routes matched notifications to services such as Pushover and email.
- Recursively flattens arbitrary JSON into dotted variables such as
events.0.alert_key. - Matches exact paths or wildcard paths such as
events.*.alert_key. - Supports all/any condition groups and common text, number, existence, list, and regular-expression operators.
- Builds Pushover titles and messages from static text, variables, and Pushover-supported HTML.
- Provides an authenticated
/adminpage for Pushover and SMTP settings, rule management, payload inspection, service health, and friendly event/log review. - Provides a Semantic UI administration console for general site settings, users, roles and permissions, service health, destinations, global email templates, and the system audit log.
- Separates inbound matching rules, outbound message templates, and reusable Pushover or email destinations.
- Includes built-in Administrator and User roles, optional enforced TOTP two-factor authentication, and auditable configuration changes.
- Supports user-triggered Pushover and email tests, email fallback, profile settings, Gravatar or uploaded avatars, and password recovery through email or Pushover.
- Preserves compatibility with the existing
/alarmid.phpwebhook path as well as/webhook. - Encrypts Pushover credentials at rest with a deployment-only Fernet key.
- Create a Python 3.11+ virtual environment and install with
pip install -e ".[test]". - Copy
.env.exampleto a deployment-only environment file outside the repository and replace every placeholder. - Generate the password hash with
python -c "from werkzeug.security import generate_password_hash; print(generate_password_hash(input('Password: ')))". - Generate the encryption key with
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())". - Start with
notifyrouter; put it behind HTTPS and a trusted reverse proxy.
For a container deployment, use compose.example.yml as the Portainer stack basis, keep the real environment file outside the repository, and proxy / to 127.0.0.1:8080 over HTTPS.
The php/ directory is the native Apache/PHP deployment. Its generated configuration and SQLite state live outside the document root in a private state directory; they must never be committed.
Point a webhook source at https://notify.example.com/webhook?token=YOUR_WEBHOOK_TOKEN (or the compatible /alarmid.php path). The token must live only in the deployment environment, never in source control.
[{"path":"events.*.alert_key","operator":"equals","value":"CLIENT_CONNECTED"}]Templates use {{ dotted.path }} placeholders. Payload-derived values are inserted as text; enabling HTML allows static Pushover HTML in the template without treating payload values as template code.
- Admin sessions use HTTP-only, same-site, secure cookies by default and CSRF tokens on every state-changing form.
- The inbound webhook can require
NOTIFYROUTER_WEBHOOK_TOKENthrough a header or query parameter. - Request bodies are limited to 1 MiB.
.env, SQLite databases, virtual environments, caches, and bytecode are excluded from Git.- No live credentials, controller addresses, private payloads, or operational logs belong in this public repository.
Run the complete PHP production-path suite on a host with PHP, SQLite, Sodium, cURL, and the curl command:
sh tests/run_all.shThe suite uses disposable directories under /tmp, performs core unit tests and HTTP integration tests, and removes its test database, configuration, session cookies, and server process when finished. A successful full pass is required before deployment or publication.
The Python reference implementation retains its separate test suite:
python -m pytestVersion 0.5.1 adds modular repository quality gates for secret scanning, Python, PHP, shell scripts, and documentation. Local pre-commit and pre-push hooks use the same portable secret policy as GitHub Actions, with an additional private publication-safety policy configured outside the repository.
Version 0.5.0 removes the legacy password-only Administrator path and makes every administrator a normal database-backed user. Initial setup creates an enabled Administrator account, while Administration now includes a General page containing the Site Support User selector and global 2FA policy; the former Security page has been removed. The selected Site Support User cannot be disabled or deleted without first choosing a replacement. It retains the production-safe root and /admin routes, Semantic UI interface, role-based access control, reusable destinations and outbound templates, service-health configuration, global email templates, audit logging, optional TOTP two-factor authentication, favicons, and the complete PHP release test suite. Production secrets and runtime event data remain outside the public repository.
