How-To: Customize Notifications
Relevant source files
The following files were used as context for generating this wiki page:- app/Filament/Pages/AppSettingsPage.php
- app/Filament/Resources/UserResource.php
- app/Notifications/Channels/AppriseChannel.php
- app/Notifications/Channels/GotifyChannel.php
- app/Notifications/PriceAlertNotification.php
- app/Notifications/Messages/GenericNotificationMessage.php
- app/Filament/Actions/Notifications/TestAppriseAction.php
- app/Filament/Actions/Notifications/TestGotifyAction.php
- tests/Unit/Notifications/Channels/AppriseChannelTest.php
Introduction
PriceBuddy features a flexible and extensible notification system designed to alert users about events, such as product price drops. The system supports multiple delivery channels, including Email, Pushover, Gotify, and Apprise. Configuration is managed on two levels: globally for the entire application and on a per-user basis, allowing individuals to tailor their notification preferences.
This document provides a technical overview of the notification architecture, configuration options, and how to customize notification content and channels. The system is built on Laravel's notification framework, with custom channels to integrate with various third-party services.
Architecture Overview
The notification system is composed of several key components that work together to deliver alerts. When an event triggers a notification (e.g., a price change), a Notification class is dispatched to one or more users. The system then determines the enabled channels for each user and formats the message accordingly before sending it.
The general data flow for sending a notification is as follows:
This diagram illustrates the process from an event trigger to the final delivery of the notification via an external service.
Sources: app/Notifications/PriceAlertNotification.php:33-36, app/Notifications/Channels/GotifyChannel.php:12-14, app/Notifications/Channels/AppriseChannel.php:15-17
Core Components
| Component | Description | Relevant Files |
|---|---|---|
| Notification Classes | Defines the content of a notification for various channels. e.g., PriceAlertNotification. | app/Notifications/PriceAlertNotification.php |
| Notification Channels | Classes responsible for sending the formatted notification to a specific service like Gotify or Apprise. | app/Notifications/Channels/GotifyChannel.php, app/Notifications/Channels/AppriseChannel.php |
| Message DTOs | Simple data transfer objects like GenericNotificationMessage used to standardize the payload for certain channels. | app/Notifications/Messages/GenericNotificationMessage.php |
| Configuration UI | Filament pages for managing global (AppSettingsPage) and user-specific (UserResource) notification settings. | app/Filament/Pages/AppSettingsPage.php, app/Filament/Resources/UserResource.php |
| Helpers | Utility classes like NotificationsHelper that abstract logic for retrieving settings and enabled channels. | app/Notifications/Channels/AppriseChannel.php:50 |
Configuration
Notification settings are managed at two distinct levels: global application settings and individual user settings. User settings can override global configurations.
Global Notification Settings
Global settings are managed by an administrator in the Settings page of the Filament admin panel. These settings provide the base configuration for all notification services.
Sources: app/Filament/Pages/AppSettingsPage.php:126-241
Email (SMTP)
Configured via the getEmailSettings method.
| Field | Input Type | Description |
|---|---|---|
smtp_host | Text | Host domain or IP address of the SMTP server. |
smtp_port | Text | The port of the SMTP server (default: 25). |
smtp_user | Text | The optional username for the SMTP server. |
smtp_password | Password | The optional password for the SMTP server. |
from_address | Text | The email address to send emails from. |
encryption | Select | The encryption method to use (TLS, SSL, or None). |
| Sources: app/Filament/Pages/AppSettingsPage.php:128-163 |
Pushover
Configured via the getPushoverSettings method.
| Field | Input Type | Description |
|---|---|---|
token | Text | Your Pushover application token. |
| Sources: app/Filament/Pages/AppSettingsPage.php:165-179 |
Gotify
Configured via the getGotifySettings method. Includes a test action to verify settings.
| Field | Input Type | Description |
|---|---|---|
url | Text | The base URL of your Gotify server. |
token | Password | The application token for Gotify. |
| Sources: app/Filament/Pages/AppSettingsPage.php:181-200 |
Apprise
Configured via the getAppriseSettings method. Includes a test action to verify settings.
| Field | Input Type | Description |
|---|---|---|
url | Text | The base URL of your Apprise API server. |
token | Text | The configuration token (or key) for Apprise. |
| Sources: app/Filament/Pages/AppSettingsPage.php:202-221 |
User-Specific Notification Settings
Users can customize their notification preferences by editing their user profile. They can enable or disable channels and, in some cases, override global settings.
Sources: app/Filament/Resources/UserResource.php:73-131
The following diagram shows how settings are resolved, with user settings taking precedence over global settings.
This diagram shows that for Apprise, user token and tags override global settings, while for Gotify, the user can only enable/disable the channel.
Sources: app/Notifications/Channels/AppriseChannel.php:51-54, app/Filament/Resources/UserResource.php:118-131
User Overrides
| Channel | Overridable Fields | Description |
|---|---|---|
enabled | Enable or disable email notifications. | |
| Pushover | enabled, user_key | Enable/disable and provide the required user-specific key. |
| Gotify | enabled | Enable or disable Gotify notifications. |
| Apprise | enabled, tags, token | Enable/disable, override the notification tags, or override the configuration token. |
| Sources: app/Filament/Resources/UserResource.php:104-131 |
Notification Channels
Custom notification channels handle the logic for sending notifications to specific services. The application includes channels for Apprise and Gotify.
AppriseChannel
This channel sends notifications via an Apprise API server.
Sending Logic:
- The
sendmethod is called by Laravel's notification system. - It retrieves the message content by calling
toApprise()on thePriceAlertNotificationobject. - It calls
getSettings()to merge global and user-specific Apprise settings. The user'stokenandtagswill override the global ones if provided. - It constructs the target URL using
makeUrl():[base_url]/notify/[token]. - It dispatches an HTTP POST request to the Apprise API with a
title,body, andtags.
Sources: app/Notifications/Channels/AppriseChannel.php
The sequence diagram below illustrates this process.
GotifyChannel
This channel sends notifications to a Gotify server.
Sending Logic:
- The
sendmethod is invoked. - It retrieves the message by calling
toGotify()on the notification. - It retrieves the global Gotify settings (
url,token) viagetSettings(). - It constructs the target URL using
makeUrl():[base_url]/message?token=[token]. - It dispatches an HTTP POST request with
title,message,priority, and anextraspayload containing a clickable URL.
Sources: app/Notifications/Channels/GotifyChannel.php
Notification Content
The content for each notification is defined within a dedicated notification class, such as PriceAlertNotification.
PriceAlertNotification
This class is responsible for creating price drop alerts. It defines methods that format the notification for each delivery channel.
via(User $notifiable): Dynamically determines which channels are enabled for the given user by callingNotificationsHelper::getEnabledChannels. It always includes thedatabasechannel.toMail(): Returns aMailMessagefor email notifications.toDatabase(): Returns an array for storing the notification in the database, including actions for viewing the product or buying it.toGotify()/toApprise(): Return aGenericNotificationMessageobject populated with the alert details.
Sources: app/Notifications/PriceAlertNotification.php
GenericNotificationMessage
This is a simple Data Transfer Object (DTO) used to create a standardized message structure for channels that consume a simple title/content format, like Apprise and Gotify. It uses a fluent interface to set its properties.
// Example from PriceAlertNotification.php
public function toGotify($notifiable)
{
return GenericNotificationMessage::create($this->getSummary())
->title($this->getTitle())
->url($this->getUrl())
->priority(5);
}
Sources: app/Notifications/PriceAlertNotification.php:101-107, [app/Notifications/Messages/GenericNotificationMessage.php]
Testing Notifications
The administrator interface provides a "Test" button for both Gotify and Apprise to allow for easy verification of the settings.
These buttons trigger dedicated Filament Action classes: TestGotifyAction and TestAppriseAction.
Workflow:
- The action is triggered from the UI.
- It retrieves the current form state to get the
urlandtoken. - It validates that the settings are not empty.
- It calls the static
sendRequestmethod on the corresponding channel class (GotifyChannelorAppriseChannel) with a predefined test message. - It uses Filament's own notification system to report success or failure to the administrator.
Sources: app/Filament/Actions/Notifications/TestGotifyAction.php, app/Filament/Actions/Notifications/TestAppriseAction.php
Summary
The PriceBuddy notification system is a robust feature that leverages Laravel's core architecture while extending it with custom channels for popular services like Apprise and Gotify. Its dual-layer configuration (global and user-specific) provides both administrative control and user flexibility. By defining content within dedicated Notification classes and using standardized message objects, the system remains clean, maintainable, and easy to extend with new notification channels or alert types.