django-delayed-notifications 0.12.3
django-delayed-notifications provides tracking of notifications, and delayed sending.
License: MIT
Requires Python: >=3.11
Keywords: delayed sending, django, notifications

# Notifications

This application sends notifications to the user and emails addresses.
It stores messages into a database, and sends can be delayed through a cron task.

## Installation

```shell
$ pip install django-delayed-notifications
```

Add `django_notifications` to your `INSTALLED_APPS`:

```python
INSTALLED_APPS = (
    ...
    "django_notifications",
    ...
)
```

Apply the migrations:

```shell
$ ./manage.py migrate
```

## Usage

Instead of sending a raw email, with the `send_mail` django function, you can create a Notification object and program
the sending.

### Notification creation

```python
from pathlib import Path
from django_notifications.models import Notification, Attachment
from django.core.files import File
from django.utils.timezone import now
from datetime import timedelta

# **Basic creation**
my_instance = "<A random object in the application>"
notification = Notification.objects.create(
    subject="My beautiful email",
    text_body="My text body",
    html_body="""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="x-apple-disable-message-reformatting">
    <title>My beautiful email</title>
</head>
<body>My HTML body</body>
</html>
    """,
    from_email="foo@example.org",  # Optional
    related_object=my_instance,  # Optional
)

# ** Related objects states management **
# When using FSM, you can provide the states from / to (Optional)
notification.state_from = "active"
notification.state_to = "processing"

# **Attachments management**
# Include file from a raw file
from django.core.files.base import ContentFile

_attachment = Attachment.objects.create(
    notification=notification,
    attachment_file=ContentFile(Path("<my_file>").open("r"), name="my_file.txt")
)

# Including an attachment from a FileField
from django.db.models.fields import FieldFile

assert isinstance(my_instance.file, FieldFile)

_attachment = Attachment.objects.create(
    notification=notification,
    attachment_file=ContentFile(my_instance.file.read(), name=my_instance.file.name)
)

# **Recipients management**
# You can provide users
notification.recipients.set("<User instance>", "<User instance>", ...)

# And / Or provides email address, `\n` separated
notification.email_recipients = "\n".join([
    "foo@example.org", "bar@example.org"
])
notification.save()

# You can set the delayed sending date
notification.delayed_sending_at = now() + timedelta(days=1)
notification.save()

# Or you can send the email immediately
notification.send()
```

### Management command

#### Send notifications

This command can be used in a `cron`, to provide delayed sending.

```shell
$ ./manage.py send_notifications --help
usage: manage.py send_notifications [-h] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks]

options:
  -h, --help            show this help message and exit
  --version             Show program's version number and exit.
  -v {0,1,2,3}, --verbosity {0,1,2,3}
                        Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output
  --settings SETTINGS   The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used.
  --pythonpath PYTHONPATH
                        A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".
  --traceback           Display a full stack trace on CommandError exceptions.
  --no-color            Don't colorize the command output.
  --force-color         Force colorization of the command output.
  --skip-checks         Skip system checks.

$ ./manage.py send_notifications
12 notifications sent.
```

#### Clean notifications

It's possible to clean attachments and notification (files are removed for storage too)

```shell
$ ./manage.py clean_notifications --help
usage: manage.py clean_notifications [-h] [--dry-run] [--days DAYS] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks]

Remove older notifications.

options:
  -h, --help            show this help message and exit
  --dry-run, -n         Do not perform deletions
  --days DAYS, -d DAYS  Delete notifications older already sent since <days> days.
  --version             Show program's version number and exit.
  -v {0,1,2,3}, --verbosity {0,1,2,3}
                        Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output
  --settings SETTINGS   The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used.
  --pythonpath PYTHONPATH
                        A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".
  --traceback           Display a full stack trace on CommandError exceptions.
  --no-color            Don't colorize the command output.
  --force-color         Force colorization of the command output.
  --skip-checks         Skip system checks.

$ ./manage.py clean_notifications -d 30
20 notifications and 10 attachments are about to be deleted.
20 notifications and 10 attachments are DELETED.
```

### Templates

The application provides some basic templates for emails, and provides some basic blocks.

#### Provided blocks
```html
{% extends "django_notifications/base_email.html" %
{% block extrahead %}<!-- JS / CSS to add to header -->{% endblock extrahead %}
{% block header %}<!-- Email header (empty) -->{% endblock header %}
{% block page_title %}
  {% block title-content %}{{ subject }}{% endblock title-content %}
{% endblock page_title %}
{% block main-content %}<!-- Main content on the email -->{% endblock main-content %}
{% block buttons %}
    <div class="buttons">
      {% block buttons-content %}<!-- Link buttons -->{% endblock buttons-content %}
    </div>
{% endblock buttons %}
{% block signature %}
    <div class="signature">
      {% block signature-content %}<!-- Email signature content -->{% endblock signature-content %}
    </div>
{% endblock signature %}
```

### Config

This application provides an admin interface for notifications.

+ delay_notifications: Delay notification sending, using the cron job
+ delay: Delay to apply to notifications
+ receive_notifications_field: Name of the field to allow notification send
+ receive_messages_field: Name of the field to allow notification send -- **NOT USED**
+ enable_debug_notifications: Enable (re)sending emails
+ debug_notifications_email: Target recipient of the email debugging

## Notes

The application is available in English and translated to French.