ntfy is a simple and open-source notification service that allows you to send push notifications to various devices and platforms, including smartphones, tablets, and desktops. It is designed to be lightweight and easy to use, making it a popular choice for developers and users who need a straightforward way to receive alerts or updates from their applications or scripts.
Its easy to integrate into any of your applications just by sending a HTTP PUT or POST to the server and it’ll appear on your devices as a notification. You can also setup your own ntfy servers, but we’ll get into that another time.
Below is a simple PHP trait that can integrate directly into your existing classes:
<?php
trait NtfyTrait {
public function sendNtfyNotification(
string $topic,
string $message,
string $title = '',
array $options = [],
string $ntfyUrl = 'https://ntfy.sh'
): bool {
// Build the ntfy API endpoint URL
$url = rtrim($ntfyUrl, '/') . '/' . urlencode($topic);
// Prepare the headers and payload
$headers = ['Content-Type: application/json'];
$payload = [
'message' => $message,
];
if ($title !== '') {
$payload['title'] = $title;
}
// Merge additional options into the payload
$payload = array_merge($payload, $this->formatNtfyOptions($options));
// Convert the payload to JSON
try {
$jsonPayload = json_encode($payload, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
error_log('JSON encoding error: ' . $e->getMessage());
return false;
}
// Send the notification using cURL
$ch = curl_init($url);
if ($ch === false) {
error_log('Failed to initialize cURL.');
return false;
}
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonPayload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
// Error handling
if ($response === false) {
error_log('cURL error: ' . $curlError);
return false;
}
if ($httpCode !== 200) {
error_log("Unexpected HTTP code: $httpCode. Response: $response");
return false;
}
return true;
}
private function formatNtfyOptions(array $options): array {
$formattedOptions = [];
// Handle priority
if (isset($options['priority'])) {
$formattedOptions['priority'] = (int)$options['priority'];
}
// Handle tags
if (isset($options['tags']) && is_array($options['tags'])) {
$formattedOptions['tags'] = $options['tags'];
}
// Handle click URL
if (isset($options['click'])) {
$formattedOptions['click'] = $options['click'];
}
// Handle other custom options (e.g., actions, attach, delay)
foreach (['actions', 'attach', 'delay', 'email', 'icon'] as $key) {
if (isset($options[$key])) {
$formattedOptions[$key] = $options[$key];
}
}
return $formattedOptions;
}
}
This should allow us to send realtime notifications to a channel on ntfy, below is how you can use this trait in your own classes and get sending notifications. This would be a great addition to any framework that requires some sort of alerting and realtime communication.
<?php
require 'NtfyTrait.php';
class NotificationService {
use NtfyTrait;
public function notifyUser(string $topic, string $message) {
$title = 'User Notification';
$options = [
'priority' => 5,
'tags' => ['alert', 'user'],
'click' => 'https://example.com/user-dashboard'
];
return $this->sendNtfyNotification($topic, $message, $title, $options);
}
}
// Example usage
$notifier = new NotificationService();
if ($notifier->notifyUser("your-topic", "Hello, this is a test message")) {
echo "Notification sent successfully!";
} else {
echo "Failed to send notification.";
}
So, now we’ve setup ntfy notifications lets talk about the security. By default ntfy isn’t inherently secure – anyone who knows the topic name can subscribe to it, so its no good for sending personal, or any details really you don’t want anyone to know.
You can always setup and host your own ntfy server and use the basic auth options to secure your own topics from prying eyes.