npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

signalk-ntfy

v0.0.3

Published

Send SignalK notifications to ntfy.sh or self-hosted ntfy servers

Readme

SignalK ntfy Notifications Plugin

Reliable push notifications and bidirectional communication for your boat: from automatic SignalK alerts to interactive mobile controls.

What does this plugin do?

This plugin offers two levels of integration between your SignalK server and ntfy:

  • Basic Mode (ready to use):
    Automatically sends SignalK alerts (alarm, warn, etc.) to an ntfy topic of your choice.
    You only need to:

    • Create a topic (on ntfy.sh or your local server),
    • Install the free ntfy mobile app (no account required),
    • Enable the plugin and select your alert levels.
      That’s it! If you just want reliable boat notifications on your phone — even when offline onboard — you already have a complete solution.
  • Advanced Mode (requires additional setup):
    Enables bidirectional communication:

    • Send custom notifications with interactive buttons ("Ok"/"Cancel").
    • Listen to two configurable ntfy topics: one for commands and one for responses.
    • Publish any received messages to two predefined SignalK paths:
      • communications.ntfy.commands
      • communications.ntfy.responses

This second level does not include processing logic: the plugin acts only as a bridge. You decide what to do with those messages (via Node-RED, scripts, another plugin, etc.).

What this plugin does NOT do

  • It does not interpret or execute the commands it receives. It only publishes them in SignalK for other tools to handle.
  • It does not configure your mobile devices. You choose how to send commands to your server (e.g., with HTTP Shortcuts, the ntfy app itself, or any HTTP client).
  • It does not manage security beyond what ntfy and SignalK already provide. The responsibility for using secure topic names, tokens, and best practices rests entirely with you.

In summary

  • Just want automatic notifications? → Install, set your topic, and you’re done.
  • Want interactive control from your phone? → The plugin gives you the channels; you build the logic on top.

Why ntfy (pronounced "notify")?

ntfy is a lightweight, secure, self-hostable, and dependency-free alternative to services like Telegram or Pushover:

| Feature | ntfy | Common Alternatives | |-----------------------|-----------------------------------|----------------------------| | Self-hostable | Yes (100% offline possible) | Usually not | | No account required | Use topics like “passwords” | Registration required | | Bidirectional | WebSockets + interactive buttons | Limited or non-native | | Open Source | Apache 2.0 / GPLv2 | Closed or partial | | Network-friendly | Small messages, low bandwidth | Often heavier |

Ideal for marine environments: works on local networks, doesn’t rely on external services, and uses minimal resources.


Two usage modes

The plugin is designed for all skill levels:

1. Basic Mode – Automatic notifications (ready in 2 minutes!)

Perfect for receiving SignalK alerts (alarm, warn, etc.) on your mobile device with minimal setup.
You only need:

  • A topic on ntfy.sh (or your local server)
  • Enable the plugin and select alert levels
  • The ntfy mobile app

Example use case:
“Engine overheating” → Instant push notification on your phone.

2. Advanced Mode – Bidirectional communication

This is the plugin’s core functionality.
Send commands from your phone (e.g., restart a server or turn off lights) and receive confirmations or responses in SignalK.

Key features:

  • Send custom notifications via REST API (POST /send)
  • Interactive buttons with HTTP actions ("Ok"/"Cancel")
  • Receive responses under communications.ntfy.responses
  • Native integration with Node-RED, HTTP Shortcuts, etc.
  • Automatic server switching (local <--> ntfy.sh) based on WiFi presence

Example use case:
Notification: “Reboot RPi4?” → User taps "OK" -> Command executed via SSH -> Confirmation received in SignalK.
Ideal for embedded control systems where secure, app-free interaction is essential.


Mobile app required

To receive push notifications on your phone, you’ll need the official ntfy app:

The app runs in the background, listens to your topics, and delivers instant, reliable notifications — even when your phone is idle. No account needed.


Responsible use: respect ntfy.sh limits

If you use the public ntfy.sh service, please respect its free-tier limits:

  • ~250 messages/day
  • ~150 subscriptions/day
  • All topics are public: anyone can read or write to them.

Important: On ntfy.sh, tokens do not restrict access to topics.

The public server runs in open mode (auth-default-access: read-write for everyone), meaning anyone who knows your topic name can both read and publish to it, even without a token.

The only effective protection on ntfy.sh is to:

  • Use long, random, hard-to-guess topic names (treat the topic name like a password).
  • Never reuse common names like boat, alerts, or commands.

If you need true topic privacy, authenticated publishing, or reserved names:

  • Self-host your own ntfy server with ACLs enabled, or
  • Use a paid ntfy.sh plan (which allows topic reservation, though still no ACL-based write protection).

Best practices for marine use

For typical boating scenarios, you don’t need enterprise-grade security — but you do need sensible naming:

  • Use long, random topic names (e.g., boat_alerts_aB3xK9mQ2p, commands_rZ7wL4vN8s).
  • ntfy allows letters (A–Z, a–z), digits (0–9), and underscores (_).
  • Avoid dictionary words or boat names like myyacht or sailboat123.
  • Separate topics by function:
    • One for outgoing alerts (lower risk).
    • One for responses (medium risk).
    • One dedicated, highly random topic for commands (highest risk).
  • Use tokens only if you self-host ntfy or have a paid ntfy.sh plan — they prevent unauthorized publishing in those setups.
  • On the free public server, tokens have no effect; security relies entirely on unpredictable topic names.

Important: The commandsTopic is the most sensitive — it can trigger actions on your boat (reboots, power switches, etc.). Always use a long, random name and combine it with a token if using self-host.

Is this “secure enough”?

For most boaters, yes:

  • Brute-forcing a 12-character random topic would take centuries, even without rate limits.
  • ntfy.sh applies strict rate limiting (60 requests burst, then 1/10s) and IP bans via fail2ban.
  • On a local network, topics are only exposed to devices on your boat — no internet exposure.

If you need full ACLs, authentication, or TLS isolation, self-host ntfy on your Raspberry Pi or PC and disable public access.


Local network setup (important!)

Never use localhost in your server URL if you interact from mobile devices.
Your phone interprets localhost as itself — not your SignalK server.


Installation & Requirements

  • SignalK server
  • Access to ntfy (public or self-hosted)

Documentation

See the plugin’s built-in documentation for:

  • Step-by-step configuration (basic → advanced)
  • Ready-to-use Node-RED subflows
  • Troubleshooting common issues
  • REST API integration examples

SignalK Paths & API Endpoints

The plugin creates the following SignalK data paths and REST API endpoints to enable full integration:

SignalK Data Paths

  • communications.ntfy.settings.activeServer (always available)
    String indicating the ID of the currently active ntfy server (e.g., "local" or "ntfysh"). Updated on startup and every 30 seconds.

  • communications.ntfy.responses (advanced mode only)
    Received ntfy interactive button responses (e.g., user taps "Ok" or "Cancel") appear here as SignalK deltas.

  • communications.ntfy.commands (advanced mode only)
    Custom commands sent via ntfy (e.g., "action:reboot,value:true") are published here for consumption by Node-RED, other plugins, or automation logic.

These paths allow seamless integration with SignalK-compatible tools without polling or external dependencies.

REST API Endpoints

The plugin exposes the following endpoints under SignalK’s plugin router (/plugins/signalk-ntfy):

  • POST /plugins/signalk-ntfy/send Send a custom notification to the configured ntfy server.
    You may optionally override the default topic in the request body (useful for dynamic routing).

    Note: Responses from interactive buttons will always be published to the configured responsesTopic (communications.ntfy.responses), regardless of the topic used in the original message.

Example request:

{
    "title": "Cabin Lights Control",
    "message": "Turn off cabin lights?",
    "topic": "boat_alerts",
    "actions": [
      {
        "action": "broadcast",
        "label": "Yes",
        "message": "action:lights_off,value:true",
        "actionId": "cabin_lights_123"
      },
      {
        "action": "broadcast",
        "label": "No",
        "message": "action:lights_off,value:false",
        "actionId": "cabin_lights_123"
      }
    ]
  }
  • GET /plugins/signalk-ntfy/status
    Returns the current status of the pluExample response:ponse:
{
    "status": "active",
    "plugin": "signalk-ntfy",
    "configured": true,
    "ntfyUrl": "https://ntfy.sh",
    "defaultTopic": "boat_alerts",
    "timestamp": "2025-11-04T12:00:00.000Z"
  }
  • PUT /plugins/signalk-ntfy/settings/server
    Dynamically switch the active ntfy server and persist the selection. Restarts listeners if advanced mode is Example request:e request:
{
    "serverId": "local"
  }

Example successful response:

{
    "status": "updated",
    "activeServer": "local",
    "persistent": true,
    "listenersRestarted": true,
    "timestamp": "2025-11-04T12:00:00.000Z"
  }

For full request/response schemas and validation rules, see the included openApi.json file.


License

License: Apache-2.0

Special thanks to an anonymous technical collaborator whose guidance significantly improved the design and robustness of this plugin. Thanks to the SignalK community and ntfy.sh for building reliable, open tools.
This plugin is not affiliated with ntfy.sh or SignalK. Use at your own risk and in compliance with services.

Example: Notification with confirmation

{
  "title": "Cabin Lights Control",
  "message": "Turn off cabin lights?",
  "actions": [
    {
      "action": "broadcast","label": "Yes",
      "message": "action:lights_off,value:true",
      "actionId": "cabin_lights_123"
    },
    {
      "action": "broadcast",
      "label": "No",
      "message": "action:lights_off,value:false",
      "actionId": "cabin_lights_123"
    }
  ]
}