{"id":44331900,"url":"https://github.com/lone-cloud/prism","last_synced_at":"2026-05-24T08:06:10.008Z","repository":{"id":334172726,"uuid":"1132472683","full_name":"lone-cloud/prism","owner":"lone-cloud","description":"Self-hosted notification gateway","archived":false,"fork":false,"pushed_at":"2026-05-04T20:56:45.000Z","size":165468,"stargazers_count":25,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-05-04T22:30:35.884Z","etag":null,"topics":["protonmail","push-notifications","self-hosted","signal","signal-cli","telegram","telegrambot","unifiedpush","webhook","webpush","webpush-notifications"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lone-cloud.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"github":"lone-cloud"}},"created_at":"2026-01-12T02:16:37.000Z","updated_at":"2026-05-04T20:56:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lone-cloud/prism","commit_stats":null,"previous_names":["lone-cloud/sup","lone-cloud/prism"],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/lone-cloud/prism","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lone-cloud%2Fprism","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lone-cloud%2Fprism/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lone-cloud%2Fprism/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lone-cloud%2Fprism/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lone-cloud","download_url":"https://codeload.github.com/lone-cloud/prism/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lone-cloud%2Fprism/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33426014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T22:14:44.296Z","status":"online","status_checked_at":"2026-05-24T02:00:06.296Z","response_time":57,"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":["protonmail","push-notifications","self-hosted","signal","signal-cli","telegram","telegrambot","unifiedpush","webhook","webpush","webpush-notifications"],"created_at":"2026-02-11T10:08:26.067Z","updated_at":"2026-05-24T08:06:10.001Z","avatar_url":"https://github.com/lone-cloud.png","language":"Go","funding_links":["https://github.com/sponsors/lone-cloud"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"assets/prism.webp\" alt=\"Prism Icon\" width=\"80\" height=\"80\" /\u003e\n\n# Prism\n\n**Private notification gateway**\n\n[Setup](#setup) • [Integrations](#integrations) • [API](#api) • [Examples](#real-world-examples) • [Monitoring](#monitoring)\n\n\u003c/div\u003e\n\n\u003c!-- markdownlint-enable MD033 --\u003e\n\nPrism sits between your services and your phone. Services send HTTP notifications; Prism delivers them to Signal, Telegram or WebPush. Prism is ntfy-compatible, so existing integrations work without changes. It can optionally monitor a Proton Mail inbox and send a notification for new emails.\n\nAndroid companion app: [prism-android](https://github.com/lone-cloud/prism-android)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/screenshots/light.webp\" alt=\"Prism Dashboard (light)\" width=\"70%\" /\u003e\n  \u003cimg src=\"assets/screenshots/dark.webp\" alt=\"Prism Dashboard (dark)\" width=\"70%\" /\u003e\n\u003c/p\u003e\n\n## Setup\n\n### Docker (Recommended)\n\n```bash\ncurl -L -O https://raw.githubusercontent.com/lone-cloud/prism/master/.env.example\nmv .env.example .env\nnano .env  # Set API_KEY=your-secret-key-here\n\ncurl -L -O https://raw.githubusercontent.com/lone-cloud/prism/master/docker-compose.yml\ndocker compose up -d\n```\n\n### Binary (Alternative)\n\n```bash\ncurl -L -O https://github.com/lone-cloud/prism/releases/latest/download/prism-linux-amd64\nchmod +x prism-linux-amd64\nmv prism-linux-amd64 prism\n\ncurl -L -O https://raw.githubusercontent.com/lone-cloud/prism/master/.env.example\nmv .env.example .env\nnano .env  # Set API_KEY=your-secret-key-here\n\n./prism\n```\n\nPrism is now running at \u003chttp://localhost:8080\u003e.\n\n## Security\n\n**Deploy behind HTTPS.** Every API request sends your `API_KEY` in the `Authorization` header. Over plain HTTP that header is transmitted in cleartext — anyone who can observe the traffic between your callers and the server can read the key and make authenticated requests. Use a reverse proxy with TLS termination (Caddy, nginx, Traefik) or a tunnel service like Cloudflare Tunnel in front of Prism.\n\nOnly use http URLs when callers run on the same host and traffic never leaves the machine.\n\n## Integrations\n\nAll integrations are configured through the web UI. Authenticate with your `API_KEY` as the password (username can be anything).\n\n### Signal\n\nSend notifications through Signal Messenger.\n\n**Setup:**\n\n1. Visit \u003chttp://localhost:8080\u003e and authenticate with your API_KEY\n2. Expand the Signal integration card\n3. Click \"Link Device\"\n4. Scan the QR code with Signal on your phone:\n   - Open Signal → Settings → Linked Devices → Link New Device\n   - Scan the displayed QR code\n5. Your device will link automatically\n\n\u003e **Note:** Binary installs require [signal-cli](https://github.com/AsamK/signal-cli/releases) in your PATH. Docker includes it automatically.\n\n### Telegram\n\nSend notifications through a Telegram bot.\n\n**Setup:**\n\n1. Create a bot:\n   - Message [@BotFather](https://t.me/BotFather) on Telegram\n   - Send `/newbot` and follow the prompts\n   - Copy the bot token\n\n2. Get your Chat ID:\n   - Message [@userinfobot](https://t.me/userinfobot) on Telegram\n   - Copy your Chat ID from the response\n\n3. Configure in Prism:\n   - Visit \u003chttp://localhost:8080\u003e and authenticate with your API_KEY\n   - Expand the Telegram integration card\n   - Enter your bot token and chat ID\n   - Click \"Configure\"\n\n### Proton Mail\n\nMonitor a Proton Mail account and forward new emails as notifications through Signal or Telegram.\n\n**Setup:**\n\n1. Visit \u003chttp://localhost:8080\u003e and authenticate with your API_KEY\n2. Configure Signal or Telegram first (required for routing)\n3. Expand the Proton Mail integration card\n4. Enter your Proton Mail credentials:\n   - Email address\n   - Password\n   - 2FA code (if enabled)\n5. Click \"Link\"\n\nNew emails appear as notifications from the \"Proton Mail\" app. Credentials are encrypted (AES-256-GCM) and tokens refresh automatically.\n\n### WebPush\n\nSend notifications directly to your browser.\n\n**Setup:**\n\n1. Visit \u003chttp://localhost:8080\u003e and authenticate with your API_KEY\n2. Allow browser notifications when prompted\n3. Apps without Signal or Telegram configured will automatically use WebPush\n\n## API\n\nAll API endpoints require authentication with your API key:\n\n```bash\nAuthorization: Bearer YOUR_API_KEY\n```\n\n### ntfy-compatible publish API\n\nPublish notifications to `POST /{appName}`.\n\n`{appName}` is the target app/topic name. Messages are routed to all subscriptions configured for that app (Signal, Telegram, WebPush).\n\n**JSON payload:**\n\n```bash\ncurl -X POST http://localhost:8080/my-app \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"title\": \"Alert\", \"message\": \"Something happened\"}'\n```\n\n**JSON payload with image:**\n\n```bash\ncurl -X POST http://localhost:8080/my-app \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"title\": \"Motion Detected\", \"message\": \"Front door\", \"attach\": \"https://example.com/snapshot.jpg\"}'\n```\n\n**Plain text payload:**\n\n```bash\ncurl -X POST http://localhost:8080/my-app \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -d \"Simple message text\"\n```\n\n### WebPush subscription API\n\nRegister and remove WebPush subscriptions for an app.\n\n#### POST /api/v1/webpush/subscriptions\n\nCreates a WebPush subscription.\n\nRequired fields:\n\n- `appName`\n- `pushEndpoint`\n\nOptional encrypted payload fields (must be provided together):\n\n- `p256dh`\n- `auth`\n- `vapidPrivateKey`\n\n```bash\ncurl -X POST http://localhost:8080/api/v1/webpush/subscriptions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"appName\": \"my-app\",\n    \"pushEndpoint\": \"https://example.push.service/send/abc123\",\n    \"p256dh\": \"BASE64URL_P256DH\",\n    \"auth\": \"BASE64URL_AUTH\",\n    \"vapidPrivateKey\": \"BASE64URL_VAPID_PRIVATE_KEY\"\n  }'\n```\n\nMinimal registration (without encrypted payload fields):\n\n```bash\ncurl -X POST http://localhost:8080/api/v1/webpush/subscriptions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"appName\": \"my-app\",\n    \"pushEndpoint\": \"http://localhost:9001/mock-push\"\n  }'\n```\n\n#### DELETE /api/v1/webpush/subscriptions/{subscriptionId}\n\nRemoves a WebPush subscription by ID.\n\n```bash\ncurl -X DELETE http://localhost:8080/api/v1/webpush/subscriptions/SUBSCRIPTION_ID \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n```\n\n## Real-World Examples\n\n### Home Assistant\n\nAdd to `configuration.yaml`:\n\n```yaml\nnotify:\n  - platform: rest\n    name: Prism\n    resource: \"http://\u003cYour Prism server network IP\u003e/Home Assistant\"\n    method: POST_JSON\n    headers:\n      Authorization: !secret prism_api_key\n    data_template:\n      title: \"{{ title }}\"\n      message: \"{{ message }}\"\n      image: \"{{ data.image | default('') }}\"\n```\n\nAdd to `secrets.yaml`:\n\n```bash\nprism_api_key: \"Bearer YOUR_API_KEY_HERE\"\n```\n\nThen use the `notify.prism` action in automations.\n\n**Sending an image from a camera snapshot:**\n\nTake a snapshot first, save it to HA's local static file server, then send the URL:\n\n```yaml\nactions:\n  - action: camera.snapshot\n    target:\n      entity_id: camera.front_door\n    data:\n      filename: /config/www/snapshot_front.jpg\n  - action: notify.prism\n    data:\n      title: \"Motion Detected\"\n      message: \"Front door camera triggered\"\n      data:\n        image: https://\u003cyour-ha-domain\u003e/local/snapshot_front.jpg\n```\n\nThe `/config/www/` directory is served as `/local/` by Home Assistant's built-in HTTP server. Use your HA's external HTTPS URL so Prism can fetch the image when delivering the notification.\n\n### Beszel\n\nIn [Beszel](https://beszel.dev)'s **Settings → Notifications**, add:\n\n```\nntfy://:YOUR_API_KEY@\u003cprism-host\u003e:\u003cport\u003e/Beszel?disableTLS=yes\n```\n\n`disableTLS=yes` is only needed for local HTTP. The app name (`Beszel`) can be anything.\n\n## Monitoring\n\n### Health Endpoints\n\n#### GET /health\n\nPublic. Returns `200 OK` when running.\n\n```bash\ncurl http://localhost:8080/health\n```\n\n#### GET /api/v1/health\n\nAuthenticated. Returns uptime and integration status:\n\n```bash\ncurl http://localhost:8080/api/v1/health \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"\n```\n\n```json\n{\n  \"version\": \"1.2.0\",\n  \"uptime\": \"2h15m\",\n  \"signal\": {\"linked\": true, \"account\": \"+1234567890\"},\n  \"telegram\": {\"linked\": true, \"account\": \"123456789\"},\n  \"proton\": {\"linked\": true, \"account\": \"user@proton.me\"}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flone-cloud%2Fprism","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flone-cloud%2Fprism","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flone-cloud%2Fprism/lists"}