Skip to main content

Send emails the easy way

Project description

django-notifiedby

Integrate django-notifiedby to send emails and manage email flows through the NotifiedBy API.

Features

  • Email Backend: Drop-in replacement for Django's email backend
  • Flow Management: Subscribe users to automated email sequences (onboarding, drip campaigns, newsletters)
  • Recipient Management: Create and manage recipients with metadata and flags for segmentation
  • Email Querying: Check delivery status and query email history
  • Simple API: Pythonic functions that are easy to use

Installation

Using pip:

pip install django-notifiedby

Configuration

Add the notifiedby email backend to your Django settings:

# my_project/settings.py

# Required: Set your NotifiedBy API key
EMAIL_BACKEND = "notifiedby.NotifiedByEmailBackend"
NOTIFIEDBY_API_KEY = "your-api-key-here"

# Optional: Add encryption key if you use encrypted emails
NOTIFIEDBY_ENCRYPTION_KEY = "your-encryption-key"  # Optional

API Keys can be purchased from NotifiedBy.com

Usage

Sending Transactional Emails

The built-in Django emails will automatically send through NotifiedBy:

from django.core.mail import EmailMessage

email = EmailMessage(
    subject='Subject Here',
    body='Body of the email here',
    from_email='your_email@example.com',
    to=['recipient@example.com'],
    cc=['cc_recipient@example.com'],  # CC
    bcc=['bcc_recipient@example.com'],  # BCC
)

# Attach a file
email.attach('example.pdf', b'Some binary data', 'application/pdf')
email.send()

Flow Management

Subscribe users to automated email sequences:

from notifiedby import subscribe_to_flow, unsubscribe_from_flow

# Subscribe a user to a welcome email series
subscribe_to_flow(
    flow_trigger='welcome_series',
    email='user@example.com',
    first_name='John',
    last_name='Doe',
    flags=['free_plan', 'new_user']
)

# Unsubscribe from a flow
unsubscribe_from_flow('newsletter_weekly', 'user@example.com')

# List all flow subscriptions
from notifiedby import list_flow_subscriptions

subscriptions = list_flow_subscriptions(page=1)
print(f"Total subscriptions: {subscriptions['count']}")
for sub in subscriptions['results']:
    print(f"{sub['recipient_email']} - {sub['flow_name']} ({sub['status']})")

Common Flow Patterns

User Signup Flow:

from django.contrib.auth.signals import user_signed_up
from notifiedby import subscribe_to_flow

def on_user_signup(sender, user, **kwargs):
    """Automatically subscribe new users to onboarding flow"""
    subscribe_to_flow(
        flow_trigger='onboarding',
        email=user.email,
        first_name=user.first_name,
        flags=['free_plan']
    )

user_signed_up.connect(on_user_signup)

Subscription Upgrade Flow:

from notifiedby import subscribe_to_flow, set_recipient_flags

def upgrade_to_premium(user):
    # Update user flags
    set_recipient_flags(user.email, ['premium', 'paid'])

    # Subscribe to premium onboarding
    subscribe_to_flow(
        flow_trigger='premium_onboarding',
        email=user.email,
        first_name=user.first_name
    )

Recipient Management

Create and manage recipients with metadata:

from notifiedby import (
    create_or_update_recipient,
    set_recipient_flags,
    clear_recipient_flags,
    list_recipients
)

# Create or update a recipient
recipient = create_or_update_recipient(
    email='user@example.com',
    first_name='Jane',
    last_name='Smith',
    flags=['premium', 'beta_tester']
)
print(f"Recipient ID: {recipient['sqid']}")

# Set flags for segmentation (adds to existing flags)
set_recipient_flags('user@example.com', ['annual_plan', 'power_user'])

# Clear specific flags
clear_recipient_flags('user@example.com', ['trial', 'pending'])

# List all recipients
recipients = list_recipients(page=1)
for recipient in recipients['results']:
    print(f"{recipient['email']} - Created: {recipient['created_at']}")

Flags are custom tags for segmentation (e.g., 'premium', 'churned', 'early_adopter'). Use them to:

  • Trigger different email flows based on user status
  • Filter and segment your audience
  • Track user lifecycle stages

Email Querying

Check email delivery status and query sent emails:

from notifiedby import (
    get_email_detail,
    list_sent_emails,
    get_email_delivery_status,
    send_email_via_api
)
from django.core.mail import EmailMessage

# Send an email and get the ID
message = EmailMessage(
    subject='Test Email',
    body='Hello!',
    to=['user@example.com']
)
email_id = send_email_via_api(message)

# Check delivery status
if email_id:
    status = get_email_delivery_status(email_id)
    print(f"Delivery status: {status}")

# Get email details by ID
email = get_email_detail(sqid='abc123xyz')
print(f"Subject: {email['subject']}")
print(f"Sent to: {email['recipient']}")

# Get most recent email to a recipient
email = get_email_detail(email='user@example.com')

# List all sent emails
emails = list_sent_emails(page=1)
print(f"Total emails sent: {emails['count']}")

# Filter by recipient
user_emails = list_sent_emails(recipient='user@example.com')
for email in user_emails['results']:
    print(f"{email['subject']} - {email['created_on']}")

Error Handling

The library provides specific exceptions for different error scenarios:

from notifiedby import subscribe_to_flow
from notifiedby.exceptions import (
    NotifiedByAPIError,
    NotifiedByValidationError,
    NotifiedByAuthError,
    NotifiedByConfigError,
    NotifiedByNotFoundError,
)

try:
    subscribe_to_flow('welcome', 'user@example.com')
except NotifiedByConfigError as e:
    # API key not configured
    print(f"Configuration error: {e}")
except NotifiedByValidationError as e:
    # Invalid data (bad email, unknown flow, etc.)
    print(f"Validation error: {e}")
except NotifiedByAuthError as e:
    # Authentication failed (invalid API key)
    print(f"Auth error: {e}")
except NotifiedByNotFoundError as e:
    # Resource not found
    print(f"Not found: {e}")
except NotifiedByAPIError as e:
    # Other API errors
    print(f"API error: {e.status_code} - {e}")

Advanced Usage

Custom Client for Testing

You can inject a custom client for testing or using a different API endpoint:

from notifiedby import NotifiedByClient, subscribe_to_flow

# Create a test client
test_client = NotifiedByClient(
    api_key='test_key',
    base_url='http://localhost:8000'
)

# Use with any function
subscribe_to_flow(
    'welcome',
    'test@example.com',
    client=test_client
)

Direct API Usage

For more control, use the NotifiedByClient directly:

from notifiedby import NotifiedByClient

client = NotifiedByClient()

# Make custom API calls
response = client.post('/flows/subscribe/', json={
    'flow_trigger': 'custom_flow',
    'email': 'user@example.com'
})

# GET request with parameters
subscriptions = client.get('/flows/subscriptions/', params={'page': 2})

# DELETE request
client.delete('/flows/subscriptions/')

Contributing

In order to contribute to the plugin itself so just need to clone the repo, create the venv and install the dev requirements.

git clone git@gitlab.com:rezero-consulting/django-notifiedby.git
python -m venv venv
source venv/bin/activate
pip install -r dev-requirements.txt

Updating PyPi

This plugin is hosted on PiPy and needs to be uploaded when anything is updated

When a change has been make you need to update the version number in pyproject.toml You then need to build the distribution files

cd django-notifiedby
python -m build

This will build new version files in the dist folder and update some other files in the django_notifiedby.egg-info folder. All these files can be added to the repo but only the two new files in the dist folder need uploading to PyPi.

In order to upload this plugin to PyPi you will need a valid key for the PyPi project. Contact rich@rezero.net about this. Once you have a key upload to PyPi with:

cd django-notifiedby
twine upload dist/django_nofitiedby-[version]*

Where [version] is the version you've just built.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_notifiedby-0.2.0.tar.gz (14.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_notifiedby-0.2.0-py3-none-any.whl (14.6 kB view details)

Uploaded Python 3

File details

Details for the file django_notifiedby-0.2.0.tar.gz.

File metadata

  • Download URL: django_notifiedby-0.2.0.tar.gz
  • Upload date:
  • Size: 14.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for django_notifiedby-0.2.0.tar.gz
Algorithm Hash digest
SHA256 57b86f9b75d2ea9d38bfabedfdbf1450caebfd636885ac8e1ee9ed495bf57e09
MD5 9747e9f13b4f2abb1819c4325c94f1df
BLAKE2b-256 323fd76df499e4a165b74a321a6200e0798738449c76a23cec57d7412865f281

See more details on using hashes here.

File details

Details for the file django_notifiedby-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_notifiedby-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 297871c0f0e06229b1b1b1c8fe52f53e04ed42be8ceb0dcab958de5626455420
MD5 aaf9f755cba9c9cd41bfc927ba3b58bc
BLAKE2b-256 d488af91651404725c090ebc9f9e9235af938cc6c03ae6a3cabd1f81d7408207

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page