Skip to main content

Published on Django Packages

django-mail-analytics

Simple python module that add email tracking features for both mail opening (via a hidden pixel) and for link clicks (via a redirecting proxy)

  • This works only for email with an html body
  • The changes to your code is minimal as we monkey patch the standard django.core.mail.EmailMessage object
  • Three new models are added to save mail sent, mail recipients and mail recipient's action such as opening and link clicking

Installation

  • Run pip install django-mail-analytics
  • Add django_mail_analytics to your installed INSTALLED_APPS
  • Add re_path(r"^m/", include("django_mail_analytics.urls")) to your urls
  • Add this to your settings:
MAIL_ANALYTICS = {
    "DOMAIN": "localhost", #add the domain of your app to be used in the pixel/proxy url of your mail sent
    "SCHEME": "http", #http or https
  # "SALT": "my-salt", #comment to use global SECRET_KEY instead
    "LENGTH": 6,  # minimal length of encoded id
}

Usage

All email sent with an html body will be modified on the fly to incorporate a pixel tracking and to rewrite link urls:

from django.core.mail import send_mail

send_mail(
    "Subject here",
    "Here is the message.",
    "from@example.com",
    ["to@example.com"],
    fail_silently=False,
    html_message="""
    <body>
    <a href="https://google.com">link</a>
    </body>
    """,
)

The above code will actually send an html body email that is rewritten like this:

<body>
    <a href="http://localhost/m/p?q=OJe2wr&u=https%3A%2F%2Fgoogle.com">link</a>
    <img src="http://localhost/m/i?q=OJe2wr" height="0px" width="0px"/>
</body>

There is no perciple change for the user that receive the email. But as soon as it opens (or reopens) the email, we create a MailRecipientAction with an empty action. If the user clicks on the link we would create another MailRecipientAction with an action equal to the link url: "https://google.com" in this example.

Every email send trigger the creation of a Mail object. In addition, a MailRecipient object is also created for every recipients of the email.

Note, that multiple emails sharing the same "key" and sending "date" are merged together into a single Mail Object. So no need to worry about sending mass emails (they will only create one single Mail object). The email "key" is either the email subject OR the first recipient with a "@DMA" email address. This recipient is ignored from the sending list, it's just an easy way to track mails of a given category.

So typical usage is like this:

send_mail(
    subject="subject",
    message="message",
    html_message="html_message,
    from_email=None,
    recipient_list=[user.email, f"EMAIL_KEY@DMA"],
)

Admin

There is a django admin for the three added models that can easilly be used to monitor your email success rate and typical use behaviour.


Remarks

Email were not developped for tracking in the first place. So adding a pixel tracking and link proxy is just a workaround to add tracking capabilities to email. One of the limitation of this workaround is that sending the email to multiple recipients doesn't allow to distinguish who among the recipients is currently opening the email... just that someone did it. Similarly if the email is forwarded to somebody else, we can only know that the email was opened a second time, but not that it's from a different people.


Testing

# clone repository
git clone https://github.com/quertenmont/django-mail-analytics.git && cd django_mail_analytics

# create virtualenv and activate it
python -m venv venv && . venv/bin/activate

# upgrade pip
python -m pip install --upgrade pip

# install requirements
pip install -r requirements.txt -r requirements-test.txt

# install pre-commit to run formatters and linters
pre-commit install --install-hooks

# run tests
tox
# or
python runtests.py
# or
python -m django test --settings "tests.settings"

License

Released under MIT License.


Supporting

Metadata

Release files for django-mail-analytics 1.0.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-mail-analytics 1.0.10
File Size Uploaded Provenance Actions
django_mail_analytics-1.0.10.tar.gz 16.5 kB With provenance Details for django_mail_analytics-1.0.10.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for django-mail-analytics 1.0.10
File Interpreter ABI Platform Actions
django_mail_analytics-1.0.10-py3-none-any.whl Python 3 none any Details for django_mail_analytics-1.0.10-py3-none-any.whl

Total release size: 30.2 kB

Release files / django_mail_analytics-1.0.10.tar.gz

Download URL django_mail_analytics-1.0.10.tar.gz
Size 16.5 kB
Tags Source
SHA-256 checksum
How to use checksums
41143b0b2be14b874c6384c69cc86ddf97de29969536ec2f811c6f4ac75c45e9
BLAKE2b-256 checksum
How to use checksums
bd0f8fef4322f5ca6a23a1a4915c46a2eeaa08bcfc499a5264eeb4353cbd1db2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

Release files / django_mail_analytics-1.0.10-py3-none-any.whl

Download URL django_mail_analytics-1.0.10-py3-none-any.whl
Size 13.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
36c5831d164c97a5de4b29bbcc9ea4b5767dc501892a63595888b81a7d539d6c
BLAKE2b-256 checksum
How to use checksums
37cb262a01002fdcf78eac582a5e5106e6487a0910037435dc527f652a66712a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

Security for django-mail-analytics 1.0.10

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for django_mail_analytics-1.0.10.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page