No description
Find a file
2026-02-05 23:02:42 -08:00
.github lock down alpine version, code clean ups, optimize release size with upx 2026-02-05 22:19:38 -08:00
.vscode WIP: rewrite in golang 2026-02-01 00:18:22 -08:00
assets rename to prism 2026-01-31 02:00:29 -08:00
public lock down alpine version, code clean ups, optimize release size with upx 2026-02-05 22:19:38 -08:00
service lock down alpine version, code clean ups, optimize release size with upx 2026-02-05 22:19:38 -08:00
.air.toml use air for fast reloads, cleap code and make it work again (TODO proton) 2026-02-01 23:38:29 -08:00
.dockerignore nits 2026-02-03 21:18:09 -08:00
.env.example re-architect to a new integration system, ensure that signal is optional, adding telegram support 2026-02-05 15:46:28 -08:00
.gitattributes clean up emoji 2026-01-19 02:05:01 -08:00
.gitignore re-architect to a new integration system, ensure that signal is optional, adding telegram support 2026-02-05 15:46:28 -08:00
.golangci.yml fix linting issues 2026-02-01 00:48:01 -08:00
docker-compose.dev.yml lock down alpine version, code clean ups, optimize release size with upx 2026-02-05 22:19:38 -08:00
docker-compose.yml re-architect to a new integration system, ensure that signal is optional, adding telegram support 2026-02-05 15:46:28 -08:00
Dockerfile lock down alpine version, code clean ups, optimize release size with upx 2026-02-05 22:19:38 -08:00
Dockerfile.signal-cli fix signal-cli release 2026-02-05 23:02:42 -08:00
go.mod re-architect to a new integration system, ensure that signal is optional, adding telegram support 2026-02-05 15:46:28 -08:00
go.sum re-architect to a new integration system, ensure that signal is optional, adding telegram support 2026-02-05 15:46:28 -08:00
LICENSE init project 2026-01-13 22:10:12 -08:00
main.go lock down alpine version, code clean ups, optimize release size with upx 2026-02-05 22:19:38 -08:00
Makefile lock down alpine version, code clean ups, optimize release size with upx 2026-02-05 22:19:38 -08:00
README.md re-architect to a new integration system, ensure that signal is optional, adding telegram support 2026-02-05 15:46:28 -08:00
VERSION WIP: rewrite in golang 2026-02-01 00:18:22 -08:00

Prism Icon

Prism

Self-hosted notification gateway using WebPush and optional Signal for transport

SetupReal-World ExamplesArchitecture

Prism is a self-hosted notification gateway that receives HTTP requests and routes them through WebPush apps or optionally through Signal groups. Route notifications through Signal to avoid exposing unique network fingerprints, or forward them to your own WebPush apps for custom handling.

Setup

# Download docker-compose.yml
curl -L -O https://raw.githubusercontent.com/lone-cloud/prism/master/docker-compose.yml

# Download .env.example
curl -L -O https://raw.githubusercontent.com/lone-cloud/prism/master/.env.example

# Configure your API key
cp .env.example .env
nano .env  # Set API_KEY=your-secret-key-here

# Start Prism
docker compose up -d

Prism is now running at http://localhost:8080. By default, all notifications use WebPush (encrypted push notifications or plain HTTP webhooks). Enable optional integrations below for Signal or Telegram delivery, or Proton Mail monitoring.

Integrations

All integrations are optional. Enable only what you need.

Signal

Send notifications through Signal groups instead of WebPush.

1. Enable Signal in .env:

FEATURE_ENABLE_SIGNAL=true

2. Restart Prism:

docker compose down
docker compose up -d

3. Link your Signal account:

Visit http://localhost:8080, authenticate with your API_KEY, and scan the QR code from your Signal app:

Settings → Linked Devices → Link New Device

QR code linking screen

Once linked, new apps will default to Signal delivery.

Telegram

Send notifications through Telegram instead of WebPush.

1. Create a Telegram bot:

  • Message @BotFather on Telegram
  • Send /newbot and follow the prompts
  • Copy the bot token (looks like 123456789:ABCdefGHIjklMNOpqrsTUVwxyz)

2. Enable Telegram in .env:

FEATURE_ENABLE_TELEGRAM=true
TELEGRAM_BOT_TOKEN=your-bot-token-here

3. Restart Prism:

docker compose down
docker compose up -d

4. Get your chat ID:

  • Message @userinfobot on Telegram
  • Copy your Chat ID from the bot's response

5. Add chat ID to .env:

TELEGRAM_CHAT_ID=123456789

6. Restart Prism:

docker compose down
docker compose up -d

All notifications will now be sent to your Telegram chat. Unlike Signal, Telegram doesn't create separate groups per app - all notifications go to the configured chat ID.

Proton Mail

Receive notifications when new Proton Mail emails arrive.

Note: The default image (shenxn/protonmail-bridge:build) compiles from source and supports all architectures. For x86_64 only, you can use shenxn/protonmail-bridge:latest (smaller, faster).

1. Initialize the bridge:

docker compose run --rm protonmail-bridge init

2. Login at the >>> prompt:

>>> login
# Enter your Proton Mail email
# Enter your password
# Enter your 2FA code

3. Get IMAP credentials:

>>> info
# Copy the Username and Password
>>> exit

4. Add credentials to .env:

FEATURE_ENABLE_PROTON=true
PROTON_IMAP_USERNAME=username-from-info-command
PROTON_IMAP_PASSWORD=password-from-info-command

5. Start with Proton profile:

docker compose --profile proton up -d

Prism will now forward Proton Mail notifications to your configured channel (Signal, Telegram, or WebPush).

Real-World Examples

Proton Mail Notifications

Receive Signal notifications when new emails arrive in your Proton Mail inbox.

Prism monitors a Proton Mail account via the local bridge and forwards email alerts through Signal. This relies on the same technology that a third-party email client like Thunderbird would be using to integrate with Proton Mail.

Home Assistant Alerts

Add a rest notification configuration (eg. add to configuration.yaml) to Home Assistant like:

notify:
  - platform: rest
    name: Prism
    resource: "http://<Your Prism server network IP>/Home Assistant"
    method: POST
    headers:
      Authorization: !secret prism_api_key

Since Home Assistant and Prism are both on your local network, HTTP is allowed automatically - no additional configuration needed.

Add your API_KEY to your secrets.yaml:

prism_api_key: "Bearer YOUR_API_KEY_HERE"

Reboot your Home Assistant system and you'll then be able to send Signal notifications to yourself by using this notify prism action.

API Reference

Send Notification

POST /{topic}

Send a notification to a registered app/topic. Compatible with ntfy format.

curl -X POST http://localhost:8080/my-app \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title": "Alert", "message": "Something happened"}'

Or ntfy-style:

curl -X POST http://localhost:8080/my-app \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d "Simple message text"

WebPush/Webhook Management

POST /webpush/app

Register or update a WebPush subscription or plain webhook.

Encrypted WebPush (all crypto fields required):

curl -X POST http://localhost:8080/webpush/app \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "appName": "my-app",
    "pushEndpoint": "https://updates.push.services.mozilla.org/...",
    "p256dh": "base64-encoded-key",
    "auth": "base64-encoded-auth",
    "vapidPrivateKey": "base64-encoded-vapid-key"
  }'

Plain HTTP webhook (no encryption):

curl -X POST http://localhost:8080/webpush/app \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "appName": "my-app",
    "pushEndpoint": "https://your-server.com/webhook"
  }'

DELETE /webpush/app/{appName}

Unregister a WebPush subscription (clears WebPush settings, reverts to Signal).

curl -X DELETE http://localhost:8080/webpush/app/my-app \
  -H "Authorization: Bearer YOUR_API_KEY"

Monitoring

The health of the system can be viewed in the same admin UI used for linking Signal. Prism uses basic access authentication - provide your API_KEY as the password (username can be anything).

For API-based monitoring, call /api/health which returns JSON:

{"uptime":"3s","signal":{"daemon":"running","linked":true},"protonMail":"connected"}

Architecture

Prism accepts notifications via HTTP POST requests and routes them based on your configured delivery method:

  • WebPush (default): Supports both encrypted WebPush (with VAPID signing and payload encryption) and plain HTTP webhooks
    • Encrypted WebPush: Full WebPush protocol with end-to-end encryption - requires appName, pushEndpoint, p256dh, auth, and vapidPrivateKey
    • Plain webhooks: Simple JSON POST to any HTTP endpoint - only requires appName and pushEndpoint
  • Signal groups (optional): Uses signal-cli-rest-api to create a Signal group for each app and send notifications as messages

Each app can be independently configured to use either delivery method through the admin UI.

For the optional Proton Mail integration, Prism requires a server that runs Proton's official proton-bridge. Prism's docker compose process will run an image from protonmail-bridge-docker. Once authenticated, the communication between Prism and proton-bridge will be over IMAP.