How to send notification to ntfy instance?

This isn’t really a problem, but more of a question. On the Raspberry PI where I installed Nextcloud, I also run an instance of ntfy, among other things. I use this to receive notifications from various system services. Other devices in the house also use this instance to send me various notifications/log files, etc.

I have only been using Nextcloud for a few weeks. So this is a new addition. Nextcloud now also has various notifications that I can see in the WebGUI. They are also sent to me by email if I do not respond to them within one day.

Can I also have these notifications sent to the ntfy instance? In theory, a simple curl command would suffice. Presumably, this can be done via these workflows, but I have no idea how to proceed. All I have seen so far about the workflows is that I can download additional workflows from the store. However, there is no ready-made workflow for ntfy available there yet.

The Nextcloud app doesn’t receive notifications on my device because it wasn’t installed from the Play Store. Delivering them via ntfy would be a great alternative.

I have not found a build in solution, but i created now a small PHP Script. This runs every 5 minutes and checks via /ocs/v2.php/apps/notifications/api/v2/notifications if there are unread notifications. If so, I send the notification to a ntfy instance. To not send a double notification, i cache the send notifications in a small json file, so that i don’t send the same message twice.

With that, i have only the overhead on the server itself, to check periodically, if new messages are available and send only a new push, when needed.

If someone is interested, i can publish the code here. Its just a simple script. Maybe someone can make a NC app out of this. This is a little bit beyond my NC knowledge, since i startet with NC not long ago.

2 Likes

Awesome! I would be interested in your script since the solution via Nextcloud’s Push-Proxy seems quite convoluted to me. Also, it again is reliant on a third party server.. :confused:

Sorry, I was on vacation for the last few days. Here is the script. I run it every 30 minutes using a systemd timer unit. Crontab or similar are also OK.

There are probably still some bugs in it, but at least it has been working without any problems here so far.

<?php
$n_url = 'https://<your_nc_domain.com>/ocs/v2.php/apps/notifications/api/v2/notifications';
$p_url  = 'https://<your_ntfy_domain.com>/<topic>';
$token	= '<your_ntfy_token>';
$sfile	= '/<path_to_your_status_file>/send.json';
$nc_usr = '<your_nc_username>';
$nc_pwd = '<your_nc_paasword>';

$hostname = gethostname();
$asend = json_decode(file_get_contents($sfile));
$bef = md5(serialize($asend));

$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $n_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'OCS-APIRequest: true',
	'Accept: application/json',
	'Authorization: Basic '. base64_encode("$nc_usr:$nc_pwd")
));

$response = json_decode(curl_exec($ch), true);
curl_close($ch);

if(is_array($response) && isset($response['ocs'])) {
	$status = $response['ocs']['meta']['statuscode'];
	$notifications = $response['ocs']['data'];
} else {
	die();
}

if($status === 200) {
	if(count($notifications) > 0) {
		foreach ($notifications as $key => $notification) {
			if (!in_array($notification['notification_id'], $asend)) {
				$subject = $notification['subject'];
				$text = (isset($notification['message']) && $notification['message'] != '') ? $notification['message']:$notification['subject'];
				$tag = $notification['app'];
				$link = $notification['link'];
				$icon = $notification['icon'];

				$nres = json_decode(file_get_contents($p_url, false, stream_context_create([
					'http' => [
						'method' => 'POST',
						'header' =>
							"Content-Type: text/plain\r\n".
							"Title: $subject\r\n".
							"Priority: 3\r\n" .
							"Tags: nextcloud, $hostname, $tag\r\n".
							"Click: $link\r\n".
							"Authorization: Bearer $token\r\n",
						'content' => $text
					]
				])), true);

				if(isset($nres['event']) && $nres['event'] === 'message') {
					$asend[] = $notification['notification_id'];
				}
			}
		}
	}

	if ($bef !== md5(serialize($asend))) file_put_contents($sfile, json_encode($asend));
} else {
	echo "Error in Response. Status $status.";
}
?>
2 Likes

Awesome, thanks.

I’ll try it when I find some free time again :smiley:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.