Feature: Notifications System
Relevant source files
The following files were used as context for generating this wiki page:
- app/Notifications/PriceAlertNotification.php
- app/Notifications/Channels/GotifyChannel.php
- app/Notifications/Channels/AppriseChannel.php
- app/Services/Helpers/NotificationsHelper.php
- app/Filament/Pages/AppSettingsPage.php
- app/Notifications/Messages/GenericNotificationMessage.php
- app/Filament/Resources/UserResource.php
- app/Filament/Actions/Notifications/TestGotifyAction.php
- app/Filament/Actions/Notifications/TestAppriseAction.php
The PriceBuddy Notifications System is a modular and extensible feature responsible for alerting users about events within the application, primarily price changes for tracked products. It leverages Laravel's notification system and extends it with custom channels to support a variety of services including Email, Pushover, Gotify, and Apprise.
The system is designed to be configurable through the Filament admin panel, allowing administrators to set up global notification service settings. Users can also override certain settings on a per-user basis. The architecture is centered around specific Notification classes that define the content for different events and Channel classes that handle the delivery to external services.
Core Components
The notification system is composed of several key parts that work together to deliver alerts.
| Component | Description | Relevant Files |
|---|---|---|
| Notifications Helper | A service class (NotificationsHelper) that centralizes logic for retrieving notification settings and determining which channels are enabled for a given user. | app/Services/Helpers/NotificationsHelper.php |
| Notification Classes | Concrete implementations of Laravel's Notification class. PriceAlertNotification is a key example, defining the message content for price drop events across various channels. | app/Notifications/PriceAlertNotification.php |
| Custom Channels | Classes that implement the logic for sending notifications to specific third-party services. GotifyChannel and AppriseChannel are custom implementations for this project. | app/Notifications/Channels/GotifyChannel.php, app/Notifications/Channels/AppriseChannel.php |
| Message DTOs | Simple data transfer objects like GenericNotificationMessage are used to create a standardized message structure for custom channels. | app/Notifications/Messages/GenericNotificationMessage.php |
| Configuration UI | Filament pages (AppSettingsPage, UserResource) provide the user interface for managing global and user-specific notification settings. | app/Filament/Pages/AppSettingsPage.php, app/Filament/Resources/UserResource.php |
Architecture Overview
The following diagram illustrates the main classes and their relationships within the notification system.
Notification Flow
When an event triggers a notification, the system follows a defined sequence to determine which channels to use and how to format the message for each one.
This sequence diagram shows the process for sending a PriceAlertNotification.
Notification Types
PriceAlertNotification
This is the primary notification for alerting users about a price drop for a product they are tracking.
- Trigger: Sent when a product's price drops to a desired level.
- Constructor: Takes an
App\Models\Urlobject which contains the product and price information.Sources: [app/Notifications/PriceAlertNotification.php:24-28](https://github.com/luffyorhuy02-blip/pricebuddy/blob/HEAD/app/Notifications/PriceAlertNotification.php#L24-L28)
- Channels: The
via()method dynamically determines the delivery channels by callingNotificationsHelper::getEnabledChannels(). It always includes thedatabasechannel.Sources: [app/Notifications/PriceAlertNotification.php:32-36](https://github.com/luffyorhuy02-blip/pricebuddy/blob/HEAD/app/Notifications/PriceAlertNotification.php#L32-L36)
Channel-Specific Formatting
The PriceAlertNotification class defines methods to format the message for each supported channel.
| Method | Channel | Output Type | Description |
|---|---|---|---|
toMail() | MailMessage | Formats the notification as a markdown email. | |
toDatabase() | Database | array | Formats the notification for storage in the database, including actions for viewing the product or buying it. |
toPushover() | Pushover | PushoverMessage | Creates a simple push notification with a title and summary. |
toGotify() | Gotify | GenericNotificationMessage | Creates a generic message with a title, summary, URL, and priority of 5. |
toApprise() | Apprise | GenericNotificationMessage | Creates a generic message with a title, summary, URL, and priority of 5. |
Sources: app/Notifications/PriceAlertNotification.php:41-105
The toGotify() and toApprise() methods use the GenericNotificationMessage DTO to structure the data.
// app/Notifications/PriceAlertNotification.php:112-117
public function toGotify($notifiable)
{
return GenericNotificationMessage::create($this->getSummary())
->title($this->getTitle())
->url($this->getUrl())
->priority(5);
}
Sources: app/Notifications/PriceAlertNotification.php:112-117
Custom Notification Channels
PriceBuddy implements custom channels to integrate with notification services not included in Laravel by default.
GotifyChannel
This channel sends notifications to a self-hosted Gotify server.
- URL Construction: The API endpoint is built by appending
/messageto the configured server URL and adding the application token as a query parameter.// app/Notifications/Channels/GotifyChannel.php:37-41 public static function makeUrl(string $apiUrl, string $token): string { return Uri::of(rtrim($apiUrl, '/').'/message') ->withQuery(['token' => $token]) ->value(); } - Request Payload: It sends a
POSTrequest with a JSON body containingtitle,message,priority, and anextrasobject for a clickable URL.// app/Notifications/Channels/GotifyChannel.php:48-59 public static function sendRequest(string $apiUrl, string $title, string $message, string $url, int $priority = 0): Response { return Http::post($apiUrl, [ 'title' => $title, 'message' => $message, 'priority' => $priority, 'extras' => [ 'client::notification' => [ 'click' => $url, ], ], ]); }
Sources: app/Notifications/Channels/GotifyChannel.php
AppriseChannel
This channel sends notifications using an Apprise API server, which can then distribute the message to dozens of services.
- Settings Precedence: A key feature of this channel is its ability to merge global settings with user-specific overrides. A user can provide their own
tagsandtokenin their profile, which will take precedence over the system-wide settings. If a user setting is not provided, the global setting is used. The default tag isall.// app/Notifications/Channels/AppriseChannel.php:49-57 public static function getSettings($notifiable): array { $settings = NotificationsHelper::getSettings(NotificationMethods::Apprise); $userSettings = $notifiable->getNotificationSettings(NotificationMethods::Apprise); $settings['tags'] = empty($userSettings['tags']) ? 'all' : $userSettings['tags']; $settings['token'] = empty($userSettings['token']) ? ($settings['token'] ?? '') : $userSettings['token']; return $settings; } - URL Construction: The API endpoint is built by appending
/notify/{token}to the configured server URL.Sources: [app/Notifications/Channels/AppriseChannel.php:62-65](https://github.com/luffyorhuy02-blip/pricebuddy/blob/HEAD/app/Notifications/Channels/AppriseChannel.php#L62-L65)
- Request Payload: It sends a
POSTrequest with a JSON body containingtitle,body, andtags.Sources: [app/Notifications/Channels/AppriseChannel.php:67-74](https://github.com/luffyorhuy02-blip/pricebuddy/blob/HEAD/app/Notifications/Channels/AppriseChannel.php#L67-L74)
Sources: app/Notifications/Channels/AppriseChannel.php, app/Filament/Resources/UserResource.php:127-138
Configuration
Notification services are configured in the Filament admin panel under System > Settings.
Sources: app/Filament/Pages/AppSettingsPage.php
Global Settings (AppSettingsPage)
The following notification services can be configured globally.
| Service | Settings | Description |
|---|---|---|
smtp_host, smtp_port, smtp_user, smtp_password, from_address, encryption | Standard SMTP server settings for sending email notifications. | |
| Pushover | token | The Pushover application token. |
| Gotify | url, token | The Gotify server URL and application token. Includes a "Test" button. |
| Apprise | url, token | The Apprise API server URL and default configuration token. Includes a "Test" button. |
Sources: app/Filament/Pages/AppSettingsPage.php:124-219
User-Specific Settings (UserResource)
Users can override some notification settings in their user profile.
| Service | Settings | Description |
|---|---|---|
| Pushover | user_key | The user's specific Pushover key. |
| Apprise | tags, token | Override the global Apprise tags and configuration token. |
Sources: app/Filament/Resources/UserResource.php:115-138
Test Actions
To help administrators validate their configurations, "Test" actions are provided for Gotify and Apprise in the settings page. These actions send a predefined test notification to the configured service.
This diagram shows the logic within TestGotifyAction and TestAppriseAction.
Sources: app/Filament/Actions/Notifications/TestGotifyAction.php, app/Filament/Actions/Notifications/TestAppriseAction.php