ntfy - TundraSoft/tundra-connect GitHub Wiki

ntfy

Typed ntfy client for Deno, Bun, Node.js and Cloudflare Workers. Publish push notifications to a topic on ntfy.sh or a self-hosted ntfy server, with optional auth for protected topics.

JSR JSR Score

Overview

ntfy is an open, HTTP-based pub-sub protocol: publish a message to a topic, and anyone subscribed to that topic gets notified. Topics on the public https://ntfy.sh instance need no account and no credentials — pick a topic name and start publishing. This connect exposes a single method, publish(), covering ntfy's JSON publish form (POST /), which is a strict superset of the plain-text POST /<topic> form. It uses RESTler for transport and Guardian for runtime request/response validation.

import { Ntfy } from '@tundraconnect/ntfy';

// No account, no API key — just pick a topic and publish.
const client = new Ntfy();
await client.publish({ topic: 'mytopic', message: 'Hello from ntfy!' });

Testing your code

Your tests don't need to fake HTTP. Have your code take a Ntfy instance and pass in a stand-in that returns the shapes from @tundraconnect/ntfy/schemas or throws a real NtfyError:

import { NtfyError } from '@tundraconnect/ntfy/errors';

const outage = new NtfyError('SERVICE_UNAVAILABLE', { status: 503 });
console.log(outage.code);

To exercise the client itself against a fake transport, subclass it and reassign the protected _fetch.

Documentation

Topic Description
API Client configuration and endpoint methods
Errors Error codes and diagnostic metadata
Schemas Public Guardian schemas and inferred types

Upstream

Installation

Deno:

deno add jsr:@tundraconnect/ntfy

Bun:

bunx jsr add @tundraconnect/ntfy

Node.js:

npx jsr add @tundraconnect/ntfy

Quick Start

import { Ntfy } from '@tundraconnect/ntfy';

const client = new Ntfy();

const message = await client.publish({
  topic: 'mytopic',
  title: 'Disk space alert',
  message: 'Disk usage on server1 is at 90%',
  priority: 4,
  tags: ['warning', 'floppy_disk'],
});

console.log(message.id);

Publishing to a protected topic, or against a self-hosted instance, only needs auth/baseURL — both plain RESTlerOptions fields:

import { Ntfy } from '@tundraconnect/ntfy';

const client = new Ntfy({
  baseURL: 'https://ntfy.example.com',
  auth: { type: 'BEARER', token: 'tk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' },
});

Limits

The public https://ntfy.sh instance enforces (as documented, subject to change): a default request-rate limit of 60 requests burst then 1 per 10s per visitor, a 4,096-byte message body before ntfy auto-converts it to an attachment, and a 15 MB max attachment size (100 MB total per visitor, expiring after 3 hours). See the ntfy.sh docs for current numbers — this connect does not enforce them client-side.

License

MIT. Part of Tundra Connect, typed vendor API clients for Deno, Bun, Node.js and Cloudflare Workers.

⚠️ **GitHub.com Fallback** ⚠️