Skip to content

theam/coldfront_notifications

Repository files navigation

coldfront-notifications

A ColdFront plugin for sending bulk email notifications to targeted user groups. Designed for HPC centers running ColdFront.

Features

Compose & Send

  • Cascading recipient filters — filter by Project, Department, Allocation, Resource, Allocation Status, and User Role. Each filter narrows the downstream options in real time.
  • Template-based composition — pick a saved template or write a one-off. Templates support {{variable}} placeholders that resolve per recipient.
  • Live email preview — preview the rendered email for sample recipients before sending. A dropdown lets you switch between recipients to see how variable substitution looks for each.
  • Per-user dedupe control — users matched on multiple projects/allocations can receive one email per context or be deduped to one. Controlled per-user in the recipient preview with a "Dedupe all" option.
  • Pre-flight validation — checks every {{token}} resolves for every recipient before enabling Send. Unknown tokens, empty values, and resolution errors are surfaced with clear messages.
  • Per-email delivery — each recipient gets an individually addressed email with their specific variable substitution. No bulk BCC.

Template Variables

  • Query variables — auto-resolved per recipient from ColdFront data. 28 built-in resolver paths covering Recipient, Project, PI, Department, Role, Allocation, and Resource fields.
  • Manual variables — fixed values defined once at creation time and reused across all notifications (e.g. a maintenance date, a renewal URL).
  • Full CRUD UI — create, edit, soft-delete variables from the plugin's own interface. Query variables pick from a whitelisted dropdown; manual variables store a typed value.

Notifications

  • Dashboard — stat cards (Total Delivered, Sending Now, Failed 30d, Total Notifications) plus a recent notifications table.
  • Notification detail — live delivery progress (AJAX polling), per-recipient log with status badges, and a view icon showing the exact rendered email as delivered.
  • Resend failed — one-click resend to failed recipients.
  • Soft delete — deleted templates and variables remain visible (crossed out) on past notification details.

Settings

  • Sender & Reply-To management — configure available From/Reply-To addresses with default flags.

Infrastructure

  • Batched delivery — sends in configurable batches with delay between them to avoid SMTP rate limits. Single SMTP connection reused across all emails.
  • Retry on transient errors — 4xx SMTP errors and disconnects are retried with exponential backoff.
  • Celery-optional — queues via Celery when a broker is available; falls back to a background thread for environments without a worker.
  • Django messages — success/error/warning banners for every user action.

Installation

From source (production)

pip install "git+https://github.com/theam/coldfront_notifications.git"

To install from a specific branch:

pip install "git+https://github.com/theam/coldfront_notifications.git@<branch-name>"

From source (development)

git clone https://github.com/theam/coldfront_notifications.git
cd coldfront-notifications
pip install -e .

Enable the plugin

Add to your ColdFront local_settings.py:

INSTALLED_APPS += ["coldfront_notifications"]

EXTRA_APPS_URLS = [
    ("notifications/", "coldfront_notifications.urls", "notifications"),
]

If your ColdFront instance doesn't already wire EXTRA_APPS_URLS, add this to your main urls.py:

from django.conf import settings
from django.urls import path, include

for url_prefix, module, namespace in getattr(settings, "EXTRA_APPS_URLS", []):
    urlpatterns += [path(url_prefix, include((module, namespace)))]

Run migrations

python manage.py migrate coldfront_notifications

Add the navbar dropdown

Add this line to your ColdFront authorized_navbar.html (typically in templates/common/authorized_navbar.html), inside the <ul> that holds the nav items:

{% include "coldfront_notifications/navbar.html" %}

The dropdown is only visible to staff/superusers.

Seed the default Template Variables catalog (optional)

python manage.py shell -c "
import json
from coldfront_notifications.models import NotificationVariable
with open('coldfront_notifications/coldfront_notifications/fixtures/variables.json') as f:
    for row in json.load(f):
        fields = row['fields']
        NotificationVariable.objects.update_or_create(
            key=fields['key'],
            defaults={k: v for k, v in fields.items() if k != 'key'},
        )
"

Or create your own variables from the UI: Notifications → Template Variables → New Variable.

Configure sender addresses

If your ColdFront instance has EMAIL_SENDER, EMAIL_TICKET_SYSTEM_ADDRESS, or EMAIL_DIRECTOR_EMAIL_ADDRESS in settings, seed them in one command:

python manage.py seed_notification_senders

Safe to re-run — skips addresses that already exist. You can also manage addresses manually at Notifications → Settings.


Configuration

All settings are optional. Defaults work out of the box. Override in local_settings.py:

# Email dispatch
NOTIFICATION_BATCH_SIZE          = 50    # emails per SMTP batch
NOTIFICATION_BATCH_DELAY         = 2.0   # seconds between batches
NOTIFICATION_MAX_RETRIES         = 3     # retries per email on transient SMTP errors
NOTIFICATION_RETRY_DELAY         = 1.0   # initial retry delay (doubles each retry)

# UI
NOTIFICATION_PREVIEW_PAGE_SIZE   = 50    # rows per page in recipient preview
NOTIFICATION_PREVIEW_RENDER_LIMIT = 10   # sample recipients in email preview modal

Testing Email with MailHog

MailHog catches all outbound email and provides a web UI — no emails actually delivered.

Docker setup

# docker-compose.yml
services:
  mailhog:
    image: mailhog/mailhog:latest
    ports:
      - "127.0.0.1:8025:8025"
docker compose up -d mailhog

Add to local_settings.py:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'mailhog'  # or 'localhost' if not using Docker networking
EMAIL_PORT = 1025
EMAIL_USE_TLS = False

Open http://127.0.0.1:8025 to see sent emails.

Switching to production SMTP

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.example.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your-username'
EMAIL_HOST_PASSWORD = 'your-password'

No code changes — the SMTP path is identical.


Navigation

Menu item Path Description
Dashboard /notifications/ Stats + recent notifications
Notifications /notifications/campaigns/ Full list with status filter
Compose Notification /notifications/compose/ Build and send
Templates /notifications/templates/ Create/edit/delete templates
Template Variables /notifications/variables/ Create/edit/delete {{token}} definitions
Settings /notifications/settings/ Sender/reply-to addresses

License

GPL-3.0

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors