Skip to content

Added ntfy integration#760

Open
TonyKaito wants to merge 2 commits into
FOGProject:dev-branchfrom
TonyKaito:dev-branch
Open

Added ntfy integration#760
TonyKaito wants to merge 2 commits into
FOGProject:dev-branchfrom
TonyKaito:dev-branch

Conversation

@TonyKaito

Copy link
Copy Markdown

Created a new plugin that sends event notifications to an ntfy push notification server, whether ntfy.sh main server or a self-hosted one

@rluzuriaga rluzuriaga self-assigned this Dec 5, 2025
@Neustradamus

Copy link
Copy Markdown

@rluzuriaga, @mastacontrola: Any progress on it?

@mastacontrola

Copy link
Copy Markdown
Member

Thanks for this, @TonyKaito! 🙏 The feature is a good idea, and the reason it hasn't merged is that dev-branch (1.5.x) isn't really where notification plugins are heading — working-1.6 is, and it recently gained a per-plugin schema-migration system that any new table-owning plugin now has to participate in. So rather than let this stall, I've ported and reworked it onto working-1.6.

Branch: feature-760-ntfy · commit 8fb4099

Context I found while reviewing

The plugin was forked from the older pushbullet plugin (the pushNote/_parseRecipient/device_iden/channel_tag bits are Pushbullet's API), so it inherited some Pushbullet-isms and predates everything working-1.6 changed about plugins.

Flaws fixed

  • Wire protocol — the handler still spoke Pushbullet's JSON (type=note&title=…&body=… form fields). ntfy takes the message as the POST body and the title via a Title header, so as written it published a literal type=note… string with no title. Reworked to speak ntfy. (Verified against a live ntfy.sh topic: title + message land correctly.)
  • NftyException typo, bareword array keys ($data[email] → fatal on PHP 8), and a referenced-but-undefined $this->_apiKey path — all removed/fixed.
  • ->find() doesn't exist on FOGManagerController in 1.6 (dedup would've fataled); switched to distinct().
  • Page never registered — the page loader only discovers *.page.php whose class matches the filename. The file was ntfymanagementpage.class.php / NtfyManagementPage, so node=ntfy would 404. Renamed to ntfymanagement.page.php / NtfyManagement.
  • Unescaped output — values were echoed straight into value="…" attributes; rebuilt on makeInput/makeLabel/makeButton/formFields/makeFormTag (which run through Initiator::e()), added checkAuthAndCSRF() + HTTPResponseCodes to addPost.
  • Removed Slack leftovers (unset($Slack), commented blocks) and the manual FOG_VERSION bump (the pre-commit hook owns versioning on working-1.6).

Brought up to working-1.6 conventions

  • Schema migrations: createSql() + append-only schema() + non-destructive install() via Schema::applyUpdates() — no more drop-and-recreate on re-install; plugs into the dashboard "update available" flow. See docs/PLUGIN_SCHEMA_MIGRATIONS.md.
  • Added the missing API and JS hooks (the JS hook is why fog.ntfy.*.js now actually loads); menu hook converted to the hook_main pattern; JS split into fog.ntfy.add.js / fog.ntfy.list.js.

New: auth for protected topics

The unused credentials column is now wired up — user:pass → HTTP basic auth, anything else → Authorization: Bearer <token>. Empty = public topic.

Verified so far

php -l clean across all files; full app bootstraps with the plugin (all 14 classes autoload); schema() emits valid non-destructive SQL; ntfy protocol confirmed against ntfy.sh. Still to do (manual, in-browser): install → table create, menu item, add-topic round-trip, and a live event firing.

Credit stays with you in the file headers. Once it's verified in the UI I'll open a PR from feature-760-ntfy into working-1.6.

@mastacontrola

Copy link
Copy Markdown
Member

Landed on working-1.6 🎉

This is now merged into working-1.6 as #842 (merge 9ac9b9a9). Your authorship is preserved in the new file headers — thanks again, @TonyKaito.

Rather than merge here against dev-branch, we moved it to working-1.6, which is where notification plugins are heading and which recently gained a per-plugin schema-migration system any new table-owning plugin must use. How we approached the port:

Brought to working-1.6 conventions

  • Schema via createSql() + append-only schema() + non-destructive install() (Schema::applyUpdates()), so re-install no longer drops data and upgrades flow through the dashboard "update available" banner. See docs/PLUGIN_SCHEMA_MIGRATIONS.md.
  • Added the missing API + JS hooks (the JS hook is why fog.ntfy.*.js loads); menu hook moved to the hook_main pattern; page rebuilt on the makeInput/formFields/makeFormTag helpers with checkAuthAndCSRF() + HTTPResponseCodes; JS split into add/list.
  • Page renamed to ntfymanagement.page.php / class NtfyManagement so the page loader (which only registers *.page.php whose class matches the filename) picks it up.

Correctness fixes

  • The handler now speaks ntfy's protocol (message = POST body, title = Title header) instead of pushbullet's JSON, so notifications actually render. Verified against ntfy.sh.
  • Wired up the previously-unused credentials column for protected topics: user:pass → basic auth, else Authorization: Bearer <token>.
  • Fixed NtfyException typo, bareword array keys (PHP 8 fatal), the undefined _apiKey path, an unescaped form value, and a dedup that hit a core distinct() multi-placeholder bug (now uses exists()).

Re: the event closure / dev-branch
While testing, the fired-event path 500'd on working-1.6 because self::$eventloop($x) is parsed as a static method named by a local variable, not as invoking the closure. Worth noting for context here: dev-branch is not affected — its pushbullet (and your original PR) invoke via array_map(self::$eventloop, ...->find()), which passes the closure as a value. The bug is specific to the working-1.6 foreach { self::$eventloop($x) } refactor (which also swapped find() for Route::listem, since working-1.6 dropped find()). #842 fixes it for both ntfy and the existing pushbullet plugin on working-1.6; nothing to change on dev-branch.

Since the feature now lives on working-1.6, this PR can be closed unless you'd also like a dev-branch build of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants