- JavaScript 99.3%
- Dockerfile 0.7%
| .forgejo/workflows | ||
| docs | ||
| src | ||
| test | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| Dockerfile | ||
| package.json | ||
| README.md | ||
Automatic Front Notifications
Private, self-hosted front-change notifications for authorized PluralKit systems.
Current milestone
This repository currently contains only the Dispatch validation receiver. It proves whether front changes initiated in Constellations synchronise into PluralKit and produce usable Dispatch events. It does not call the PluralKit API, post to Discord, retain member data, or calculate front changes.
The receiver accepts POST /webhooks/pluralkit, validates the Dispatch signing_token in constant time, restricts events to configured systems, and writes only this data for switch events: receipt time, event type, system ID, and switch ID. GET /healthz has no configuration or member data.
PluralKit requires invalid signed PING requests to receive HTTP 401; accepting them can cause its webhook to be removed. A valid PING receives HTTP 200 and creates no record. See the PluralKit Dispatch documentation.
Run locally
cp .env.example .env
set -a; . ./.env; set +a
node src/server.js
The deployment must mount /data as the service's only writable location and terminate public HTTPS at the existing reverse proxy. Do not expose a port directly to the internet or add the infrastructure reference before the validation plan is approved.
The approved validation placement is Runner behind the Primary reverse proxy at https://front.delaire.xyz. The shared Discord destination will be configured only on the server; friends do not supply webhooks. The encrypted SQLite database is the live multi-system registry. See the deployment runbook.
Invite only setup
An administrator creates a one-use invitation that expires after 24 hours by default. The friend opens its /setup/... URL, copies the displayed pk;s webhook ... command, and confirms it in PluralKit. The page polls a capability-limited status endpoint and confirms the first signed PING automatically binds the system and its Dispatch token. The token is encrypted before it reaches SQLite; neither the friend nor the administrator copies it into an environment file.
Use /admin to add a destination, optionally include a Discord thread ID, select one or more destinations for a setup invitation, and review connected systems. The admin page requires ADMIN_TOKEN; it never returns stored webhook URLs.
Validation procedure
- Obtain the friend's explicit consent for the receiver, destination, and retained validation fields.
- Choose a dedicated hostname and configure the reverse proxy for HTTPS to this receiver.
- Register
https://HOSTNAME/webhooks/pluralkitfrom the friend's PluralKit account. Store the generated signing token only in the deployment secret store. - Confirm the valid
PINGreceives 200 and an intentionally invalidPINGreceives 401. - Change the front in Constellations, including a co-front join. Compare the recorded switch event type, ID, and receipt time with the change time.
- Repeat through PluralKit directly, then edit and delete a current switch to observe correction events.
- Keep no raw payloads. Delete the validation journal when the test concludes, unless the friend agrees to retain it for a defined operational period.
Next milestone
Only after the validation confirms usable Constellations-originated Dispatch events: implement the debounced current-fronter refresh, SQLite deduplication, Discord webhook formatting, retries, and the complete state-transition test suite.