feed Forgejo notifications to ntfy.sh
Find a file
2026-01-07 08:14:09 +01:00
forgejo_ntfy doc: rough function descriptions, info on template placeholders 2026-01-02 09:21:01 +01:00
.changelog.md.j2 initial commit 2026-01-01 14:55:57 +01:00
.gitignore initial commit 2026-01-01 14:55:57 +01:00
.noannex initial commit 2026-01-01 14:55:57 +01:00
CHANGELOG.md bump: version 0.0.0 → 0.1.0 2026-01-07 08:14:09 +01:00
LICENSE Complete license terms. 2026-01-01 17:07:11 +01:00
pyproject.toml test: verify commits after the inital one 2026-01-01 15:08:38 +01:00
README.md doc: rough function descriptions, info on template placeholders 2026-01-02 09:21:01 +01:00

forgejo-ntfy

PyPI version fury.io Hatch project

Feed Forgejo notifications to ntfy.sh.

Forgejo can send notifications by email, but (presently) does not support other types of "push" notifications. This tool fetches notifications from Forgejo's API (with an access token that grants read-permissions for notifications), and posts them to a ntfy service -- including self-hosted ones.

forgejo-ntfy is meant to be set up on a "server", and to be executed repeatedly (think "cronjob").

Notification can be received via a variety of ntfy clients, including mobile apps.

Installation

Install the development version

Using uv it is trivial to install straight from the source code repository.

uv tool install https://codeberg.org/mih/forgejo-ntfy.git

Afterwards, the forgejo-ntfy executable can be used.

Configuration

Configuration is done in a TOML file at ${XGD_CONFIG_HOME}/.config/forgejo-ntfy.toml (where XDG_CONFIG_HOME is defined by the XDG Base Directory Specification, and will typically be ${HOME}).

A minimal configuration can look like this

[defaults.ntfy]
topic = "<long-unguessable-topic-name>"

[monitors.<name>.forgejo]
api-url = "https://<forgejo-site-url>/api"
token = "<forgejo-access-token-notification-read-permissions>"

When executing forgejo-ntfy without any parameters, the setup above will publish the notifications of the user associated with the given token, at the Forgejo site accessible at api-url, and will publish it at the given topic on the public ntfy.sh instance at https://ntfy.sh.

To receive these notifications on a mobile device, install the ntfy app from F-Droid, or the big commercial app stores, and subscribe to the topic by its name.

Configuration defaults

Common monitor settings can be given in a global defaults configuration section. The following listing documents all available configuration items, and their "factory default" values.

[defaults.ntfy]
# this is the main free-to-use ntfy deployment
url = "https://ntfy.sh"
# a token to be used with any ntfy service (no default)
token =

# notification priority, see
# https://docs.ntfy.sh/publish/#message-priority
priority = "default"

# template string for notification titles (see below for placeholders)
title-template = "{title}"
# template string for notification bodies (see below for placeholders)
body-template = "{loc} [{humantime}]"

# (comma-separated) tags for notifications of particular types and states,
# see: https://docs.ntfy.sh/emojis/
issue-open-tag = "warning"
issue-closed-tag = "heavy_check_mark"
pull-open-tag = "adhesive_bandage"
pull-closed-tag = "x"
pull-merged-tag = "heavy_check_mark"
repo-tag = "hut"

[defaults.forgejo]
# maximum number of notifications to post on first query
max-on-init = 3
# maximum number of notification to fetch from Forgejo per request
# (multiple requests will be made until all notifications have bee
# fetched)
request-limit = 50
# limit queries to notifications of a particular type (default is any),
# give as TOML array, e.g.: `["issue", "pull"]
subject-type =

Any of these defaults can be overwritten for a particular monitor declaration. To set a particular notification priority for monitor mymonitor set

[monitors.mymonitor.ntfy]
priority = "high"

Using private/access-protected ntfy services

The use an access-protected, custom ntfy deployment, simply configure its url and an access token. See https://docs.ntfy.sh/config/#access-tokens on setting up access tokens for ntfy.

[defaults.ntfy]
url = "https://ntfy.example.org"
token = "tk_<another-29-chars>"

Running repeately

Typically, forgejo-ntfy is executed repeatedly to poll notifications. One of the best ways to achieve that continues to be a cronjob. On the machine that shall run forgejo-ntfy, use crontab -e to add a line like the following:

*/15 7-21 * * * /home/<username>/.local/bin/forgejo-ntfy > /dev/null

This calls forgejo-ntfy, where uv tool install would place it. It is called every 15 minutes, every day between 7:00 and 21:00 (suppressing any non-error output).

Template placeholders

The templates for notification titles and bodies can use any of the following placeholders:

  • title: Title of the Forgejo notification
  • url: Full html_url of the Forgejo notification
  • loc: Shortened html_url with the protocol stripped
  • humantime: Notification timestamp processed by humanize to create descriptions like "15min ago"

Localization

Language in notifications is passed on unmodified (or as given in the documentation).

For localization of timing information it is possible to set the locale configuration flag to any value supported by humanize.

Behavior

For every configured monitor (watching a particular user's notifications at a particular Forgejo site), forgejo-ntfy queries the Forgejo API for current notifications. For each notification a ntfy post is assembled, using configurable templates and tags, and is posted to a configurable ntfy service and topic.

When no notifications have been fetched for a monitor yet, a configurable maximum (defaults.forgejo.max-on-init) of "old" notifications are fetched. The timestamp of the most recent notification for a monitor is stored at ${XDG_STATE_HOME/forgejo-ntfy.json. Subsequent queries will only query for notifications more recent than this timestamp.

For each posted notification a line starting with POST is written to STDOUT.