ntfy.sh notifications for forgejo
I use ntfy.sh (self-hosted) for notifications on my degoolged android device, and forgejo (fork of gitea, which is a fork of gogs) for my source control.
Forgejo's webhooks don't currently support custom webhooks, but do support several “standard” webhook targets (like slack, discord etc.) and some others including other forgejo instances.
As I have renovate updating my argocd managed self-hosted kubernetes applications, I want notifications when there's an upgrade ready (PR opened).
Well, it turns out that ntfy.sh has the option to basically reformat any json provided as gotemplate (ugh, it's not nice but at least it works).
So, to get nice notifications I simply set up a forgejo webhook of type forgejo and give it the ntfy details as follows :
Target URL : http://ntfy.ntfy.svc.cluster.local./git?template=yes&title=ForgeJo%20Pull%20request%20%23%7B%7B.number%7D%7D%20%7B%7B.action%7D%7D&message=%7B%7B.pull_request.html_url%7D%7D%0A%0A%7B%7B.pull_request.title%7D%7D%0A%0A%7B%7B.pull_request.body%7D%7D
HTTP Method : POST
POST content type : application/json
Authorization header : Bearer <<token I created in ntfy.sh>>
And personally I only have it send a notification on “Pull request events (modification)”
And done. Okay, let's break that down a bit :
There's some interesting things in the URL : ?template=yes
enables gotemplate rendering of the title
and message
fields. Those fields unencoded look like this :
title: ForgeJo Pull request #{{.number}} {{.action}}
message:
{{.pull_request.html_url}}
{{.pull_request.title}}
{{.pull_request.body}}
By switching to POST
, the URL doesn't have anything overridden, and ntfy knows that if there's a body content type of application/json
, to apply that data to the templated title and message fields.
The authorization header is a token created with ntfy token add <<username>>
so yes, it's a secret, but not a high-value one.
If your ntfy client supports markdown, you can add &markdown=true
to your message and use markdown in your templates, but the android app isn't great at it, so I went with plain-text, urls are automatically parsed.
Until someone implements custom webhooks, this will do me, and hopefully someone finds it useful as well.