Skip to main content

An implementation of Django's EmailBackend compatible with sendgrid-python v5+

Project description

django-sendgrid-v5

Latest Release

This package implements an email backend for Django that relies on sendgrid's REST API for message delivery.

It is under active development, and pull requests are more than welcome!

To use the backend, simply install the package (using pip), set the EMAIL_BACKEND setting in Django, and add a SENDGRID_API_KEY key (set to the appropriate value) to your Django settings.

How to Install

  1. pip install django-sendgrid-v5
  2. In your project's settings.py script:
    1. Set EMAIL_BACKEND = "sendgrid_backend.SendgridBackend"
    2. Set the SENDGRID_API_KEY in settings.py to your api key that was provided to you by sendgrid. SENDGRID_API_KEY = os.environ["SENDGRID_API_KEY"]

Other settings

  1. To toggle sandbox mode (when django is running in DEBUG mode), set SENDGRID_SANDBOX_MODE_IN_DEBUG = True/False.
    1. To err on the side of caution, this defaults to True, so emails sent in DEBUG mode will not be delivered, unless this setting is explicitly set to False.
  2. To enable sandbox mode unconditionally (regardless of DEBUG), set SENDGRID_SANDBOX_MODE = True. This is useful for non-production environments like QA or staging where DEBUG may be False but you still don't want to send real emails.
  3. SENDGRID_ECHO_TO_STDOUT will echo to stdout or any other file-like object that is passed to the backend via the stream kwarg.
  4. SENDGRID_TRACK_EMAIL_OPENS - defaults to true and tracks email open events via the Sendgrid service. These events are logged in the Statistics UI, Email Activity interface, and are reported by the Event Webhook.
  5. SENDGRID_TRACK_CLICKS_HTML - defaults to true and, if enabled in your Sendgrid account, will tracks click events on links found in the HTML message sent.
  6. SENDGRID_TRACK_CLICKS_PLAIN - defaults to true and, if enabled in your Sendgrid account, will tracks click events on links found in the plain text message sent.
  7. SENDGRID_HOST_URL - Allows changing the base API URI. Set to https://api.eu.sendgrid.com to use the EU region.

Usage

Simple

from django.core.mail import send_mail

send_mail(
    'Subject here',
    'Here is the message.',
    'from@example.com',
    ['to@example.com'],
    fail_silently=False,
)

Dynamic Template with JSON Data

First, create a dynamic template and copy the ID.

from django.core.mail import EmailMessage

msg = EmailMessage(
  from_email='to@example.com',
  to=['to@example.com'],
)
msg.template_id = "your-dynamic-template-id"
msg.dynamic_template_data = {
  "title": foo
}
msg.send(fail_silently=False)

The kitchen sink EmailMessage (all of the supported sendgrid-specific properties)

from django.core.mail import EmailMessage

msg = EmailMessage(
  from_email='to@example.com',
  to=['to@example.com'],
  cc=['cc@example.com'],
  bcc=['bcc@example.com'],
)

# Personalization custom args
# https://sendgrid.com/docs/for-developers/sending-email/personalizations/
msg.custom_args = {'arg1': 'value1', 'arg2': 'value2'}

# Reply to email address (sendgrid only supports 1 reply-to email address)
msg.reply_to = 'reply-to@example.com'

# Send at (accepts an integer per the sendgrid docs)
# https://docs.sendgrid.com/for-developers/sending-email/scheduling-parameters#send-at
msg.send_at = 1600188812

# Transactional templates
# https://sendgrid.com/docs/ui/sending-email/how-to-send-an-email-with-dynamic-transactional-templates/
msg.template_id = "your-dynamic-template-id"
msg.dynamic_template_data = {  # Sendgrid v6+ only
  "title": foo
}
msg.substitutions = {
  "title": bar
}

# Unsubscribe groups
# https://sendgrid.com/docs/ui/sending-email/unsubscribe-groups/
msg.asm = {'group_id': 123, 'groups_to_display': ['group1', 'group2']}

# Categories
# https://sendgrid.com/docs/glossary/categories/
msg.categories = ['category1', 'category2']

# IP Pools
# https://sendgrid.com/docs/ui/account-and-settings/ip-pools/
msg.ip_pool_name = 'my-ip-pool'


msg.send(fail_silently=False)

Webhook Helpers

Version 6 of the sendgrid package or later includes some helper functions to cryptographically verify the signature and contents of events from the Sendgrid Events webhook.

This project includes some additional helpers for Sendgrid's webhook signature verification.

  1. Enable signature verification for Sendgrid webhooks (see Sendgrid docs). Once you have saved the webhook and edited it again, copy the verification key.
  2. Modify your project's settings.py and set SENDGRID_WEBHOOK_VERIFICATION_KEY to your verification key value.
  3. Setup a project URLConf and view. Below is an example view you can adapt to your needs.
import json
from datetime import datetime

from django.db import transaction
from django.http import HttpRequest, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from post_office.models import Email, Log as EmailLog, STATUS
from pytz import utc
from sendgrid_backend.decorators import verify_sendgrid_webhook_signature

EVENTS = {'delivered': STATUS.sent, 'bounce': STATUS.failed, 'blocked': STATUS.failed}

@csrf_exempt
@require_POST
@verify_sendgrid_webhook_signature
def sendgrid_deliverability_webhook_handler(request: HttpRequest) -> HttpResponse:
    """
    Example webhook handler to save delivered, bounce, and blocked events to
    the email log.
    """
    for msg_dict in reversed(json.loads(request.body)):
        if event := EVENTS.get(msg_dict.get('event', None), None):
            event_timestamp = datetime.fromtimestamp(msg_dict.get('timestamp'), tz=utc)
            with transaction.atomic():
                Email.objects.filter(message_id=msg_dict.get('smtp-id', None)).update(
                    last_updated=event_timestamp,
                    status=event,
                )

                EmailLog.objects.create(
                    email__message_id=msg_dict.get('smtp-id', None),
                    date=event_timestamp,
                    status=event,
                    message=json.dumps(msg_dict),
                )
    return HttpResponse("ok")

FAQ

How to change a Sender's Name ?

from_email="John Smith <john.smith@example.org>" You can just include the name in the from_email field of the EmailMessage class

msg = EmailMessage(
  from_email='Sender Name <from@example.com>',
  to=['to@example.com'],
)

How to make mails to multiple users private (hide all the email addresses to which the mail is sent) to each person (personalization) ?

Setting the make_private attribute to True will help us achieve it

msg = EmailMessage(
  from_email='Sender Name <from@example.com>',
  to=['to@example.com','abc@example.com','xyz@example.com'],
)
msg.make_private = True

Examples

Stargazers over time

Stargazers over time

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_sendgrid_v5-1.3.1.tar.gz (19.0 kB view details)

Uploaded Source

Built Distribution

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

django_sendgrid_v5-1.3.1-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file django_sendgrid_v5-1.3.1.tar.gz.

File metadata

  • Download URL: django_sendgrid_v5-1.3.1.tar.gz
  • Upload date:
  • Size: 19.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.11.2 requests/2.32.3 setuptools/65.5.0 requests-toolbelt/1.0.0 tqdm/4.67.1 CPython/3.11.5

File hashes

Hashes for django_sendgrid_v5-1.3.1.tar.gz
Algorithm Hash digest
SHA256 ed3dc4edc26c07dc09bee7ab50634716edf4e2de9430af4667320091b7255591
MD5 a6b7953436327e0e1b3c2bcfaf10a0b8
BLAKE2b-256 88a8544372be6be89ae9a650734e5c78b0e3128ec21dd3c9cd53641c71d2d781

See more details on using hashes here.

File details

Details for the file django_sendgrid_v5-1.3.1-py3-none-any.whl.

File metadata

  • Download URL: django_sendgrid_v5-1.3.1-py3-none-any.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.11.2 requests/2.32.3 setuptools/65.5.0 requests-toolbelt/1.0.0 tqdm/4.67.1 CPython/3.11.5

File hashes

Hashes for django_sendgrid_v5-1.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 29c308b8fe92fcae31aa4cae6a04efcd1e62613226e90d199d950fadd44c4189
MD5 9f9434b8401e1f5e2e4e5f4b7d2d6938
BLAKE2b-256 1fc8be0e6866b9f5e623b15c4492b78ad8a4f380d761169f6ab15696b3c94713

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