Skip to content

Latest commit

 

History

History
161 lines (117 loc) · 4.95 KB

File metadata and controls

161 lines (117 loc) · 4.95 KB

Custom Channels

Create custom delivery channels:

from generic_notifications.channels import BaseChannel, register

@register
class SMSChannel(BaseChannel):
    key = "sms"
    name = "SMS"
    supports_realtime = True
    supports_digest = False

    def should_send(self, notification):
        return bool(getattr(notification.recipient, "phone_number", None))

    def send_now(self, notification):
        # Send SMS using your preferred service
        send_sms(
            to=notification.recipient.phone_number,
            message=notification.get_text()
        )

Required Channels

Make certain channels mandatory for critical notifications:

from generic_notifications.types import NotificationType
from generic_notifications.channels import EmailChannel

@register
class SecurityAlert(NotificationType):
    key = "security_alert"
    name = "Security Alerts"
    description = "Important security notifications"
    required_channels = [EmailChannel]  # Cannot be disabled

Forbidden Channels

Prevent certain channels from being used for specific notification types:

from generic_notifications.types import NotificationType
from generic_notifications.channels import SMSChannel

@register
class CommentReceivedNotification(NotificationType):
    key = "comment_received"
    name = "Comment received"
    description = "You received a comment"
    forbidden_channels = [SMSChannel]  # Never send via SMS

Forbidden channels take highest priority - they cannot be enabled even if specified in default_channels, required_channels, or user preferences.

Defaults Channels

By default all channels are enabled for all users, and for all notifications types. Control which channels are enabled by default.

Per-Channel Defaults

Disable a channel by default across all notification types:

@register
class SMSChannel(BaseChannel):
    key = "sms"
    name = "SMS"
    supports_realtime = True
    supports_digest = False
    enabled_by_default = False  # Opt-in only - users must explicitly enable

Per-NotificationType Defaults

By default all channels are enabled for every notification type. You can override channel defaults for specific notification types:

@register
class MarketingEmail(NotificationType):
    key = "marketing"
    name = "Marketing Updates"
    # Only enable email by default
    # (users can still opt-in to enable other channels)
    default_channels = [EmailChannel]

Priority Order

The system determines enabled channels in this priority order:

  1. Forbidden channels - Always disabled (cannot be overridden)
  2. Required channels - Always enabled (cannot be disabled)
  3. User preferences - Explicit user enable/disable choices (see preferences.md)
  4. NotificationType.default_channels - Per-type defaults (if specified)
  5. BaseChannel.enabled_by_default - Global channel defaults

Custom Frequencies

Add custom email frequencies:

from generic_notifications.frequencies import BaseFrequency, register

@register
class WeeklyFrequency(BaseFrequency):
    key = "weekly"
    name = "Weekly digest"
    is_realtime = False
    description = "Receive a weekly summary every Monday"

When you add custom email frequencies you'll have to run send_notification_digests for them as well. For example, if you created that weekly digest:

# Send weekly digest every Monday at 9 AM
0 9 * * 1 cd /path/to/project && uv run ./manage.py send_notification_digests --frequency weekly

Email Templates

Customize email templates by creating these files in your templates directory:

Real-time emails

  • notifications/email/realtime/{notification_type}_subject.txt
  • notifications/email/realtime/{notification_type}.html
  • notifications/email/realtime/{notification_type}.txt

If notification-type specific templates are not found, the system will fall back to:

  • notifications/email/realtime/subject.txt
  • notifications/email/realtime/message.html
  • notifications/email/realtime/message.txt

This allows you to create generic templates that work for all notification types while still having the flexibility to create specific templates for certain types.

Template context:

  • recipient: The recipient user (same as notification.recipient)
  • notification: The Notification instance
  • actor: The actor who triggered the notification (if any)
  • target: The target object of the notification (if any)

Digest emails

  • notifications/email/digest/subject.txt
  • notifications/email/digest/message.html
  • notifications/email/digest/message.txt

Template context:

  • recipient: The recipient user
  • notifications: Queryset of all notifications in the digest
  • notifications_by_type: Dictionary grouping notifications by their type
  • count: Total number of notifications in the digest
  • frequency: The frequency instance (e.g., DailyFrequency)