← Blog

When a print finishes: notifications in PrintStash

Configure PrintStash alerts for completed, failed, or cancelled prints and offline printers through Discord, Telegram, ntfy, or a signed webhook.

guidenotifications

PrintStash can send print and printer events to Discord, Telegram, ntfy, or a generic webhook. Notifications are off by default and only a superuser can configure them.

What fires and when

Each channel can subscribe to:

  • print completed;
  • print failed;
  • print cancelled;
  • printer offline after a real online-to-offline transition.

The offline event does not fire merely because PrintStash starts while a printer is unreachable. There is no separate printer-online event.

Choose events per channel and optionally limit a channel to specific printers. Keeping cancellation separate is useful when test jobs are cancelled often but actual failures still need attention.

Setting up a channel

Open Settings -> Notifications, enable the master switch, and add a channel.

  • Discord needs a webhook URL from the server integration settings.
  • Telegram needs a BotFather token and the target chat ID.
  • ntfy needs a server URL, topic, and optional access token. The default server is https://ntfy.sh; a self-hosted ntfy server must be reachable at a public address that passes the outbound URL checks.
  • A generic webhook receives a JSON body and can use an optional HMAC signing secret.

PrintStash blocks webhook destinations that resolve to private, loopback, or link-local addresses. This SSRF protection means http://homeassistant.local and a private n8n IP will not work directly. Use a public HTTPS endpoint, an allowed relay, or another integration path rather than weakening the server’s outbound-request checks.

Press Test and confirm the message arrives before relying on the channel.

How retries work

PrintStash writes the event to an outbox in the same database transaction as the state change. A background dispatcher sends it and retries failures with increasing delays.

Delivery is at least once. A retry or recovery can produce a duplicate, so generic webhook receivers should deduplicate with the Idempotency-Key header. If you configure a signing secret, verify the X-PrintStash-Signature HMAC against the exact request body.

A service response with Retry-After is honored without consuming the normal retry budget. A channel that fails repeatedly is disabled to stop endless noise. Fix it and re-enable it manually; PrintStash does not send another alert about the disabled alert channel.

A small war story

The first implementation found two wonderfully ordinary failures. Telegram rejected an underscore in bracket_v2.gcode under its Markdown rules. ntfy put a Unicode title in an HTTP header that could not carry it safely. Both bugs were fixed, but they are good reasons to test with real filenames rather than test.gcode.

Channel secrets are stored unencrypted in the database, like other configured service credentials. Keep the install on a trusted network, restrict Settings access, and include the database in your security and backup plan.

See the small-farm stack for alert routing alongside printer controllers and Spoolman, or the security model for stored-secret and outbound-request boundaries.