A Django email backend for Amazon's Simple Email Service

Related tags

Emaildjango-ses
Overview

Django-SES

Info: A Django email backend for Amazon's Simple Email Service
Author: Harry Marr (http://github.com/hmarr, http://twitter.com/harrymarr)
Collaborators: Paul Craciunoiu (http://github.com/pcraciunoiu, http://twitter.com/embrangler)

pypi build python django

A bird's eye view

Django-SES is a drop-in mail backend for Django. Instead of sending emails through a traditional SMTP mail server, Django-SES routes email through Amazon Web Services' excellent Simple Email Service (SES).

Changelog

For details about each release, see the GitHub releases page: https://github.com/django-ses/django-ses/releases

Using Django directly

Amazon SES allows you to also setup usernames and passwords. If you do configure things that way, you do not need this package. The Django default email backend is capable of authenticating with Amazon SES and correctly sending email.

Using django-ses gives you additional features like deliverability reports that can be hard and/or cumbersome to obtain when using the SMTP interface.

Note: In order to use smtp with Amazon SES, you may have to install some supporting packages for ssl. Check out this SMTP SSL email backend for Django

Why SES instead of SMTP?

Configuring, maintaining, and dealing with some complicated edge cases can be time-consuming. Sending emails with Django-SES might be attractive to you if:

  • You don't want to maintain mail servers.
  • You are already deployed on EC2 (In-bound traffic to SES is free from EC2 instances).
  • You need to send a high volume of email.
  • You don't want to have to worry about PTR records, Reverse DNS, email whitelist/blacklist services.
  • You want to improve delivery rate and inbox cosmetics by DKIM signing your messages using SES's Easy DKIM feature.
  • Django-SES is a truely drop-in replacement for the default mail backend. Your code should require no changes.

Getting going

Assuming you've got Django installed, you'll need Boto3 1.0.0 or higher. Boto is a Python library that wraps the AWS API.

You can do the following to install boto3 (we're using --upgrade here to make sure you get the latest version):

pip install --upgrade boto3

Install django-ses:

pip install django-ses

Add the following to your settings.py:

EMAIL_BACKEND = 'django_ses.SESBackend'

# These are optional -- if they're set as environment variables they won't
# need to be set here as well
AWS_ACCESS_KEY_ID = 'YOUR-ACCESS-KEY-ID'
AWS_SECRET_ACCESS_KEY = 'YOUR-SECRET-ACCESS-KEY'

# Additionally, if you are not using the default AWS region of us-east-1,
# you need to specify a region, like so:
AWS_SES_REGION_NAME = 'us-west-2'
AWS_SES_REGION_ENDPOINT = 'email.us-west-2.amazonaws.com'

Alternatively, instead of AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, you can include the following two settings values. This is useful in situations where you would like to use a separate access key to send emails via SES than you would to upload files via S3:

AWS_SES_ACCESS_KEY_ID = 'YOUR-ACCESS-KEY-ID'
AWS_SES_SECRET_ACCESS_KEY = 'YOUR-SECRET-ACCESS-KEY'

Now, when you use django.core.mail.send_mail, Simple Email Service will send the messages by default.

Since SES imposes a rate limit and will reject emails after the limit has been reached, django-ses will attempt to conform to the rate limit by querying the API for your current limit and then sending no more than that number of messages in a two-second period (which is half of the rate limit, just to be sure to stay clear of the limit). This is controlled by the following setting:

AWS_SES_AUTO_THROTTLE = 0.5 # (default; safety factor applied to rate limit)

To turn off automatic throttling, set this to None.

Check out the example directory for more information.

Monitoring email status using Amazon Simple Notification Service (Amazon SNS)

To set this up, install django-ses with the events extra:

pip install django-ses[events]

Then add a event url handler in your urls.py:

from django_ses.views import SESEventWebhookView
from django.views.decorators.csrf import csrf_exempt
urlpatterns = [ ...
                url(r'^ses/event-webhook/$', SESEventWebhookView.as_view(), name='handle-event-webhook'),
                ...
]

SESEventWebhookView handles bounce, complaint, send, delivery, open and click events. It is also capable of auto confirming subscriptions, it handles SubscriptionConfirmation notification.

On AWS

  1. Add an SNS topic.

2. In SES setup an SNS destination in "Configuration Sets". Use this configuration set by setting AWS_SES_CONFIGURATION_SET. Set the topic to what you created in 1.

3. Add an https subscriber to the topic. (eg. https://www.yourdomain.com/ses/event-webhook/) Do not check "Enable raw message delivery".

Bounces

Using signal 'bounce_received' for manager bounce email. For example:

from django_ses.signals import bounce_received
from django.dispatch import receiver


@receiver(bounce_received)
def bounce_handler(sender, mail_obj, bounce_obj, raw_message, *args, **kwargs):
    # you can then use the message ID and/or recipient_list(email address) to identify any problematic email messages that you have sent
    message_id = mail_obj['messageId']
    recipient_list = mail_obj['destination']
    ...
    print("This is bounce email object")
    print(mail_obj)

Complaint

Using signal 'complaint_received' for manager complaint email. For example:

from django_ses.signals import complaint_received
from django.dispatch import receiver


@receiver(complaint_received)
def complaint_handler(sender, mail_obj, complaint_obj, raw_message,  *args, **kwargs):
    ...

Send

Using signal 'send_received' for manager send email. For example:

from django_ses.signals import send_received
from django.dispatch import receiver


@receiver(send_received)
def send_handler(sender, mail_obj, raw_message,  *args, **kwargs):
    ...

Delivery

Using signal 'delivery_received' for manager delivery email. For example:

from django_ses.signals import delivery_received
from django.dispatch import receiver


@receiver(delivery_received)
def delivery_handler(sender, mail_obj, delivery_obj, raw_message,  *args, **kwargs):
    ...

Open

Using signal 'open_received' for manager open email. For example:

from django_ses.signals import open_received
from django.dispatch import receiver


@receiver(open_received)
def open_handler(sender, mail_obj, raw_message, *args, **kwargs):
    ...

Click

Using signal 'click_received' for manager send email. For example:

from django_ses.signals import click_received
from django.dispatch import receiver


@receiver(click_received)
def click_handler(sender, mail_obj, raw_message, *args, **kwargs):
    ...

Testing Signals

If you would like to test your signals, you can optionally disable AWS_SES_VERIFY_EVENT_SIGNATURES in settings. Examples for the JSON object AWS SNS sends can be found here: https://docs.aws.amazon.com/sns/latest/dg/sns-message-and-json-formats.html#http-subscription-confirmation-json

SES Event Monitoring with Configuration Sets

You can track your SES email sending at a granular level using SES Event Publishing. To do this, you set up an SES Configuration Set and add event handlers to it to send your events on to a destination within AWS (SNS, Cloudwatch or Kinesis Firehose) for further processing and analysis.

To ensure that emails you send via django-ses will be tagged with your SES Configuration Set, set the AWS_SES_CONFIGURATION_SET setting in your settings.py to the name of the configuration set:

AWS_SES_CONFIGURATION_SET = 'my-configuration-set-name'

This will add the X-SES-CONFIGURATION-SET header to all your outgoing e-mails.

If you want to set the SES Configuration Set on a per message basis, set AWS_SES_CONFIGURATION_SET to a callable. The callable should conform to the following prototype:

def ses_configuration_set(message, dkim_domain=None, dkim_key=None,
                            dkim_selector=None, dkim_headers=()):
    configuration_set = 'my-default-set'
    # use message and dkim_* to modify configuration_set
    return configuration_set

AWS_SES_CONFIGURATION_SET = ses_configuration_set

where

  • message is a django.core.mail.EmailMessage object (or subclass)
  • dkim_domain is a string containing the DKIM domain for this message
  • dkim_key is a string containing the DKIM private key for this message
  • dkim_selector is a string containing the DKIM selector (see DKIM, below for explanation)
  • dkim_headers is a list of strings containing the names of the headers to be DKIM signed (see DKIM, below for explanation)

DKIM

Using DomainKeys is entirely optional, however it is recommended by Amazon for authenticating your email address and improving delivery success rate. See http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/DKIM.html. Besides authentication, you might also want to consider using DKIM in order to remove the via email-bounces.amazonses.com message shown to gmail users - see http://support.google.com/mail/bin/answer.py?hl=en&answer=1311182.

Currently there are two methods to use DKIM with Django-SES: traditional Manual Signing and the more recently introduced Amazon Easy DKIM feature.

Easy DKIM

Easy DKIM is a feature of Amazon SES that automatically signs every message that you send from a verified email address or domain with a DKIM signature.

You can enable Easy DKIM in the AWS Management Console for SES. There you can also add the required domain verification and DKIM records to Route 53 (or copy them to your alternate DNS).

Once enabled and verified Easy DKIM needs no additional dependencies or DKIM specific settings to work with Django-SES.

For more information and a setup guide see: http://docs.aws.amazon.com/ses/latest/DeveloperGuide/easy-dkim.html

Manual DKIM Signing

To enable Manual DKIM Signing you should install the pydkim package and specify values for the DKIM_PRIVATE_KEY and DKIM_DOMAIN settings. You can generate a private key with a command such as openssl genrsa 512 and get the public key portion with openssl rsa -pubout <private.key. The public key should be published to ses._domainkey.example.com if your domain is example.com. You can use a different name instead of ses by changing the DKIM_SELECTOR setting.

The SES relay will modify email headers such as Date and Message-Id so by default only the From, To, Cc, Subject headers are signed, not the full set of headers. This is sufficient for most DKIM validators but can be overridden with the DKIM_HEADERS setting.

Example settings.py:

DKIM_DOMAIN = 'example.com'
DKIM_PRIVATE_KEY = '''
-----BEGIN RSA PRIVATE KEY-----
xxxxxxxxxxx
-----END RSA PRIVATE KEY-----
'''

Example DNS record published to Route53 with boto:

route53 add_record ZONEID ses._domainkey.example.com. TXT '"v=DKIM1; p=xxx"' 86400

SES Sending Stats

Django SES comes with two ways of viewing sending statistics.

The first one is a simple read-only report on your 24 hour sending quota, verified email addresses and bi-weekly sending statistics.

To generate and view SES sending statistics reports, include, update INSTALLED_APPS:

INSTALLED_APPS = (
    # ...
    'django.contrib.admin',
    'django_ses',
    # ...
)

... and urls.py:

urlpatterns += (url(r'^admin/django-ses/', include('django_ses.urls')),)

Optional enhancements to stats:

Link the dashboard from the admin

You can use adminplus for this (https://github.com/jsocol/django-adminplus):

from django_ses.views import dashboard
admin.site.register_view('django-ses', dashboard, 'Django SES Stats')

Store daily stats

If you need to keep send statistics around for longer than two weeks, django-ses also comes with a model that lets you store these. To use this feature you'll need to run:

python manage.py migrate

To collect the statistics, run the get_ses_statistics management command (refer to next section for details). After running this command the statistics will be viewable via /admin/django_ses/.

Django SES Management Commands

To use these you must include django_ses in your INSTALLED_APPS.

Managing Verified Email Addresses

Manage verified email addresses through the management command.

python manage.py ses_email_address --list

Add emails to the verified email list through:

python manage.py ses_email_address --add [email protected]

Remove emails from the verified email list through:

python manage.py ses_email_address --delete [email protected]

You can toggle the console output through setting the verbosity level.

python manage.py ses_email_address --list --verbosity 0

Collecting Sending Statistics

To collect and store SES sending statistics in the database, run:

python manage.py get_ses_statistics

Sending statistics are aggregated daily (UTC time). Stats for the latest day (when you run the command) may be inaccurate if run before end of day (UTC). If you want to keep your statistics up to date, setup cron to run this command a short time after midnight (UTC) daily.

Django Builtin-in Error Emails

If you'd like Django's Builtin Email Error Reporting to function properly (actually send working emails), you'll have to explicitly set the SERVER_EMAIL setting to one of your SES-verified addresses. Otherwise, your error emails will all fail and you'll be blissfully unaware of a problem.

Note: You will need to sign up for SES and verify any emails you're going to use in the from_email argument to django.core.mail.send_email(). Boto has a verify_email_address() method: https://github.com/boto/boto/blob/master/boto/ses/connection.py

Requirements

django-ses requires boto3 and django >= 2.2.

Full List of Settings

AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
Required. Your API keys for Amazon SES.
AWS_SES_ACCESS_KEY_ID, AWS_SES_SECRET_ACCESS_KEY
Required. Alternative API keys for Amazon SES. This is useful in situations where you would like to use separate access keys for different AWS services.
AWS_SES_REGION_NAME, AWS_SES_REGION_ENDPOINT
Optionally specify what region your SES service is using. Note that this is required if your SES service is not using us-east-1, as omitting these settings implies this region. Details: http://readthedocs.org/docs/boto/en/latest/ref/ses.html#boto.ses.regions http://docs.aws.amazon.com/general/latest/gr/rande.html
AWS_SES_RETURN_PATH
Instruct Amazon SES to forward bounced emails and complaints to this email. For more information please refer to http://aws.amazon.com/ses/faqs/#38
AWS_SES_CONFIGURATION_SET
Optional. Use this to mark your e-mails as from being from a particular SES Configuration Set. Set this to a string if you want all messages to have the same configuration set. Set this to a callable if you want to set configuration set on a per message basis.
TIME_ZONE
Default Django setting, optionally set this. Details: https://docs.djangoproject.com/en/dev/ref/settings/#time-zone
DKIM_DOMAIN, DKIM_PRIVATE_KEY
Optional. If these settings are defined and the pydkim module is installed then email messages will be signed with the specified key. You will also need to publish your public key on DNS; the selector is set to ses by default. See http://dkim.org/ for further detail.
AWS_SES_VERIFY_EVENT_SIGNATURES, AWS_SES_VERIFY_BOUNCE_SIGNATURES
Optional. Default is True. Verify the contents of the message by matching the signature you recreated from the message contents with the signature that Amazon SNS sent with the message. See https://docs.aws.amazon.com/sns/latest/dg/sns-verify-signature-of-message.html for further detail.
EVENT_CERT_DOMAINS, BOUNCE_CERT_DOMAINS
Optional. Default is 'amazonaws.com' and 'amazon.com'.

Proxy

If you are using a proxy, please enable it via the env variables.

If your proxy server does not have a password try the following:

import os
os.environ["HTTP_PROXY"] = "http://proxy.com:port"
os.environ["HTTPS_PROXY"] = "https://proxy.com:port"

if your proxy server has a password try the following:

import os
os.environ["HTTP_PROXY"] = "http://user:[email protected]:port"
os.environ["HTTPS_PROXY"] = "https://user:[email protected]:port"

Source: https://stackoverflow.com/a/33501223/1331671

Contributing

If you'd like to fix a bug, add a feature, etc

  1. Start by opening an issue.
    Be explicit so that project collaborators can understand and reproduce the issue, or decide whether the feature falls within the project's goals. Code examples can be useful, too.
  2. File a pull request.
    You may write a prototype or suggested fix.
  3. Check your code for errors, complaints.
    Use check.py
  4. Write and run tests.
    Write your own test showing the issue has been resolved, or the feature works as intended.

Running Tests

To run the tests:

python runtests.py

If you want to debug the tests, just add this file as a python script to your IDE run configuration.

Creating a Release

To create a release:

virtualenv -p python3 ~/.virtualenvs/django-ses
workon django-ses
pip3 install twine
python3 setup.py sdist
python3 setup.py bdist_wheel --universal
twine upload dist/*
Comments
  • Upgrade from boto to boto3, and use env variables

    Upgrade from boto to boto3, and use env variables

    Hi guys,

    I started the migration from boto to boto3.

    I tried it out locally and now I can send from an email region which has this new auth type v4.

    Here's a list of stuff I already did:

    • Upgrade from boto to boto3
    • Some flake8 linting
    • Fixed both management command
    • Sending mails from eu-central-region works now
    • Removed proxy and updated docs

    Fixes #181 #78

    opened by GitRon 27
  • Fixing bug with DefaultHost

    Fixing bug with DefaultHost

    SESConnection.DefaultHost was split into 2 vars.

    https://github.com/boto/boto/blob/3437d7e9e42179f67e6e39da4be69d229f0ee47a/boto/ses/connection.py#L36

    opened by kimsterv 21
  • InvalidClientTokenId with

    InvalidClientTokenId with "AWS_SES_REGION_NAME = 'eu-central-1'"

    Hi,

    I have been using Django-ses for a while and everything worked fine. When I wanted to move out of the ses sandbox, I realised that I had not set the region to "eu-central-1".

    After I did that, I cannot send emails anymore and instead get this error message:

    boto.exception.BotoServerError: BotoServerError: 403 Forbidden
    <ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
      <Error>
        <Type>Sender</Type>
        <Code>InvalidClientTokenId</Code>
        <Message>The security token included in the request is invalid.</Message>
      </Error>
      <RequestId>ec8c6de9-9bdc-48ab-8a35-50c8caf4fcd1</RequestId>
    </ErrorResponse>
    

    Any idea what the problem is? Cheers, Gregor

    BTW: my settings.py looks like this:

    DEFAULT_FROM_EMAIL = '***@gmail.com'
    EMAIL_BACKEND = 'django_ses.SESBackend'
    with open('/etc/AWS_ACCESS_KEY_ID.txt') as f:
        AWS_ACCESS_KEY_ID = f.read().strip()
    
    with open('/etc/AWS_SECRET_ACCESS_KEY.txt') as f:
        AWS_SECRET_ACCESS_KEY = f.read().strip()
    
    AWS_SES_REGION_NAME = 'eu-central-1'
    AWS_SES_REGION_ENDPOINT = 'email.eu-central-1.amazonaws.com'
    
    opened by gha2012 18
  • Ported to Python3

    Ported to Python3

    If you preffer merge my fork or create a new repository for Python 3 it's up to you. If you find some error (you shouln't) please send me a private message.

    opened by Zeioth 18
  • AWS SES Signature V4 : Can't find the request header in the log

    AWS SES Signature V4 : Can't find the request header in the log

    I was using django-ses 0.8.5 as my email backend and I could see the request header in my application log, which belonged to signature V3.

    Final headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'User-Agent': 'Boto/2.49.0 Python/3.7.0 Linux/4.14.209-160.335.amzn2.x86_64', 'Date': 'Sun, 14 Feb 2021 20:32:57 GMT', 'X-Amzn-Authorization': 'AWS3-HTTPS AWSAccessKeyId=AKIEXAMPLEDTA,Algorithm=HmacSHA256,Signature=adWwLkredkdhfhfhhhdhxxxpxKa6o=', 'Content-Length': '44640', 'Host': 'email.us-east-1.amazonaws.com'}

    according to the AWS announcement, they are moving to signature version 4. So I have updated Django-ses 0.8.5 to 1.0.3 latest.

    these are my current versions django-ses == 1.0.3 boto3 == 1.17.7 botocore=1.20.7

    But, After I update these, I can't see the request header in my application logs to identify the signature version. could you please advise on this?

    opened by prabath88 16
  • Support for Boto3

    Support for Boto3

    First, love this package great work!

    I'd love to an update for Boto3 ( https://aws.amazon.com/blogs/aws/now-available-aws-sdk-for-python-3-boto3/ ) as it's encouraged to become the starting point for new projects.

    Thanks!

    opened by bwebsterhv 15
  • Bounce notifications

    Bounce notifications

    This is a pull request for issue #44

    The pull request adds a "handle_bounce" view that handles SES bounce and complaint messages via a SNS webhook.

    The View

    The "handle_bounce" view accepts a SNS notification message and based on the notification type calls one two new Django signals. If the notification is a bounce message the "bounce_received" signal is called, otherwise if the notification is a complaint the "complaint_received" signal is called.

    The view also accepts and and automatically confirms subscription confirmation requests.

    Other changes

    The example project hadn't been updated in a while so I updated to make it usable and so It could be used to test SNS messages.

    Signature verification

    Currently the signature of the bounce/cancel requests are verified by default. This requires the M2Crypto and requests libraries to be installed but they are left out of the dependencies in setup.py as they are optional. Some kind of documentation might be needed in the future.

    opened by ianlewis 14
  • "Email address is not verified" for verified email

    TBH, I'm not sure where this bug is coming from, Boto, SES or my own configuration.

    Here it is though:

    BotoServerError at /accounts/signup/

    BotoServerError: 400 Bad Request Sender MessageRejected Email address is not verified. 9360bdd6-c549-11e0-82fb-b9b4121fdb69

    $ ./manage.py ses_email_address -l Fetching list of verified emails: [email protected]

    Settings.py: EMAIL_BACKEND = 'django_ses.SESBackend' EMAIL_FROM = '[email protected]' EMAIL_HOST_USER='[email protected]' DEFAULT_FROM_EMAIL='[email protected]' SERVER_EMAIL='[email protected]'

    Went through the notification confirmation email from Amazon.. so why the rejected message?

    opened by Miserlou 14
  • Error if AWS_SES_AUTO_THROTTLE set to None

    Error if AWS_SES_AUTO_THROTTLE set to None

    If I set AWS_SES_AUTO_THROTTLE to None in my django settings, I get an error on initializing the SESBackend, I believe because of this commit coercing the setting to a float.

    The README instructs users to set AWS_SES_AUTO_THROTTLE to None to turn off automatic throttling, as does a comment

    Looks like this could be fixed by doing this coercion here or falling back to 0 here

    In case it's helpful to see a traceback:

    Traceback (most recent call last):                                                                                                                                                                   
      File "/usr/src/app/./manage.py", line 15, in <module>
        execute_from_command_line(sys.argv)                                                           
      File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
        utility.execute()                                                                             
      File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 413, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)                                   
      File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 354, in run_from_argv
        self.execute(*args, **cmd_options)                                                                                                                                                               
      File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 398, in execute
        output = self.handle(*args, **options)                                                                                                                                                           
      File "/usr/src/app/scheduler/management/commands/send_test_email.py", line 24, in handle
        send_email(                                                                                   
      File "/usr/src/app/authapp/utils.py", line 70, in send_email
        email.send()                                                                                  
      File "/usr/local/lib/python3.9/site-packages/django/core/mail/message.py", line 284, in send
        return self.get_connection(fail_silently).send_messages([self])                                                                                                                                    File "/usr/local/lib/python3.9/site-packages/django/core/mail/message.py", line 241, in get_connection
        self.connection = get_connection(fail_silently=fail_silently)
      File "/usr/local/lib/python3.9/site-packages/django/core/mail/__init__.py", line 35, in get_connection
        return klass(fail_silently=fail_silently, **kwds)                                                                                                                                                  File "/usr/local/lib/python3.9/site-packages/django_ses/__init__.py", line 63, in __init__
        self._throttle = float(aws_auto_throttle or settings.AWS_SES_AUTO_THROTTLE)
    TypeError: float() argument must be a string or a number, not 'NoneType'   
    
    opened by curtismorales 9
  • Switch to cryptography for X509 certificate verification

    Switch to cryptography for X509 certificate verification

    Issue #176 is annoying for Mac OS X users, partly because most of us likely use linux as our production target, so any deviation for setup instructions just causes issues and frustration.

    I've taken a look at the logic around how M2Crypto is used and it appears that swapping to using cryptography's X509 verification shouldn't take much work.

    I'm opening the issue here to see if anyone would be willing to implement before my team does and also if they'd be up for testing it (we'll test but it's always nice having more). The change would also adjust the extra install to use cryptography, effectively removing M2Crypto from the project.

    If that's not ideal, we can provide a callable into the library to all projects to use whichever x509 validator they'd like (just give us a function to call to get the certificate info based on the data), but I really hope we don't have to do that and so that won't be part of our code change.

    opened by jheld 9
  • swap m2crypto for cryptography

    swap m2crypto for cryptography

    This PR has the primary purpose of replacing m2crypto with the cryptography package. Along the way, it:

    • Updates the readme to simplify and clarify it.

    • Updates several verification methods to make them less deeply nested.

      Early method exits FTW.

    • Fixes a bug in the verification code that could make a process hang

      Gotta, just have to, provide the danged timeout parameter to python requests.

    • Adds caching of verification certificates from AWS so they're not fetched for every notification.

      I did not do this in any special "secure" way because I couldn't think of a way that was more secure than a simple dict on the module file. That said, I think doing a get request per notification is unacceptable in a big environment like ours, so a cache with this level of security is a better trade off. Perhaps not! Thoughts welcome here.

    • Fixes a bug in the new pyproject.toml file so extras work properly.

      See details here, if curious: https://stackoverflow.com/questions/60971502/python-poetry-how-to-install-optional-dependencies

    As in my prior PR, more details are in the commit messages.

    The one piece that's not complete so far is updating tests, but I plan to do that next. I'd love a review in the meantime to make sure this is OK so far.

    One question I've had: Is it worth having the install extras? Maybe we just install everything all at once. Every program is going to have requests already anyway, and cryptography is an easy installation. Maybe we don't make those optional anymore?

    I'm sorry it's gotten as big as it has, but I think most changes are cosmetic and the commits are small and tidy enough to be easy to review one by one.

    Thank you!

    Fixes: #182 Fixes: #176

    opened by mlissner 8
  • SES Signature Version 4 Error Message

    SES Signature Version 4 Error Message

    I have spent a considerable amount of time trying to get through the following error message sent by my Django application through AWS SES:

    Signature Version 3 requests are deprecated from March 1, 2021. From that date on, we are progressively rejecting such requests. To resolve the issue you must migrate to Signature Version 4. If you are self-signing your requests, refer to the documentation for Authenticating requests to the Amazon SES API [1] with Signature Version 4 [2]. If you are not self-signing your requests, simply update your SDK/CLI to the latest version. 
    

    I have upgraded my requirements.txt file to use django-ses>2.4.0, and after restarting the Docker container, the error remains. I have also ensured there are valid SMTP credentials (FullSESAccess) in the IAM user being provided.

    What should be my next steps in trying to “upgrade” my libraries to be compliant with this new signature version? I have tinkered with all sorts of Django-SES and boto3 versions, but the same exact error comes up each time.

    Thank you!

    opened by WDC 1
  • AWS_SES_REGION_ENDPOINT connection error

    AWS_SES_REGION_ENDPOINT connection error

    If I assign ses smtp endpoint such as 'email-smtp.ap-northeast-2.amazonaws.com' to AWS_SES_REGION_ENDPOINT on settings, it seems that it cannot be connected to the SES Server. However, if I assign region to AWS_SES_REGION_NAME only, it works perfectly.

    Am I missing something or any updates for this?

    opened by jihoon-MRX 3
  • Receive emails

    Receive emails

    It would be great if django-ses would allow to also receive emails. As far as I understand it, after setting up SNS, the only thing that is missing is adding another signal analog to the existing ones:

    bounce_received = Signal()
    complaint_received = Signal()
    delivery_received = Signal()
    send_received = Signal()
    open_received = Signal()
    click_received = Signal()
    

    Something like mail_received?

    opened by fabge 1
  • Problems with tracking SES email opens/clicks for a bulk email

    Problems with tracking SES email opens/clicks for a bulk email

    I recently implemented django-ses for an SES based email server. I have gotten my emails sending as expected, and I have set up the events subscriber so I may start logging successful deliveries, opens, and clicks. These event notifications are reaching my subscriber correctly.

    One of the most common use cases for my email server is receiving a list of recipients to send to in bulk. When I receive an event notification, an open event for example, I want to check the specific recipient who opened the email. When looking through the mail_obj and raw_message parameters, I can only seem to find a list of all message recipients rather than just the specific recipient who triggered the event.

    Am I missing something, or is this a limitation of SES? Thanks!

    opened by jmyre1999 0
  • is it possible to send email with a SES template?

    is it possible to send email with a SES template?

    I'm sorry, if this question is already answered, but I haven't been able to find it.

    Is there a way to make django-ses to send emails using a SES template?, it seems that the only option is rendering (to text) Django templates.

    SES templates are not actually that great, but they're a little bit of an improvement compared to managing transactional templates with django templates.

    Thank you for the info.

    opened by mikeiwi 2
  • Error: SignatureDoesNotMatch when calling the GetSendQuota operation

    Error: SignatureDoesNotMatch when calling the GetSendQuota operation

    I'm getting the following error:

    An error occurred (SignatureDoesNotMatch) when calling the GetSendQuota operation: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

    I have created an IAM user using this doc then gave them full SES permissions by adding them to the AMAZONSESFullAccess group:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "ses:*"
                ],
                "Resource": "*"
            }
        ]
    }
    

    In my Django config I have set:

    AWS_ACCESS_KEY_ID = "**************"
    AWS_SECRET_ACCESS_KEY = "*****************************************************"
    AWS_SES_REGION_NAME = 'eu-west-1'
    AWS_SES_REGION_ENDPOINT = 'email.eu-west-1.amazonaws.com'
    
    EMAIL_BACKEND = 'django_ses.SESBackend'
    

    My server time is set to GMT, the same as eu-west-1

    Now when I try to send an email using

    send_mail("testing", "text body", "[email protected]",
              ["[email protected]"], fail_silently=False)
    

    I get the above error. Both [email protected] and [email protected] are replaced by my AWS verified email addresses. Any ideas what might be causing the error?

    opened by looeee 1
Releases(v3.1.2)
Churn Emails Inbox - Churn Emails Inbox Using Python

Churn Emails Inbox In this project, I have used the Python programming langauge

2 Nov 13, 2022
Command line interface for sending email using SMTP (ships with Gmail configuration).

mailsend Description Lightweight command line interface for sending email using SMTP. Default configuration is set for Gmail (smtp.gmail.com at port 5

Keith Mathe 1 Mar 22, 2022
Django email backends and webhooks for Amazon SES, Mailgun, Mailjet, Postmark, SendGrid, Sendinblue, SparkPost and more

Django email backends and webhooks for Amazon SES, Mailgun, Mailjet, Postmark, SendGrid, Sendinblue, SparkPost and more

1.4k Jan 01, 2023
Simple, powerfull and nonobstructive django email middleware.

djmail djmail is a BSD Licensed, simple and nonobstructive django email middleware. Why use djmail? Because it: Sends emails asynchronously without ad

David Barragán Merino 77 Aug 30, 2021
check disk storage's amount and if necessary, send alert message by email

DiskStorageAmountChecker What is this script? (このスクリプトは何ですか?) This script check disk storage's available amount of specified servers and send alerting

Hajime Kurita 1 Oct 22, 2021
Esio_dev 3 Oct 15, 2021
automatic mails sender with attachments

أزعجني لين تدربني Automatic mails sender with attachments. Note: You need to have gmail account & and you need to turn on "Less secure app access" set

6 Dec 30, 2022
SMTP In some vulnerable configurations, email servers can also be aggregated Use information that gives us information about the host or network Give

SMTP In some vulnerable configurations, email servers can also be aggregated Use information that gives us information about the host or network Give. The SMTP protocol supports some basic commands s

m3hr44n 1 Jan 16, 2022
A Django email backend that uses a celery task for sending the email.

django-celery-email - A Celery-backed Django Email Backend A Django email backend that uses a Celery queue for out-of-band sending of the messages. Wa

Paul McLanahan 430 Dec 16, 2022
Collection of emails sent from the Hungarian gov and Viktor Orbán to the citizens of Hungary

Public list of Hungary and Viktor Orbán's emails since March 2021 Collection of emails sent from the Hungarian government and Viktor Orbán to the citi

Miguel Sozinho Ramalho 1 Mar 28, 2022
Automatically Send Custom Named Certificates via Mail

Welcome to Certificate Launchpad 🚀 Automatically Send Custom Named Certificates via Email Intro After any event, sending certificates to attendees or

Dc7 16 Oct 16, 2022
A python script that helps you understand why your E-Mail ended up in Spam

decode-spam-headers.py Whether you are trying to understand why a specific e-mail ended up in SPAM/Junk for your daily Administrative duties or for yo

Mariusz Banach 316 Jan 05, 2023
Python library for sending emails.

Mail.py Python library for sending emails. Installation git clone https://github.com/SunPodder/Mail.py cd Mail.py python setup.py install Usage Imp

Sun 4 Nov 24, 2021
📧 CLI to deduplicate mails from mail boxes.

Mail Deduplicate Command-line tool to deduplicate mails from a set of boxes. Stable release: Development: Features Duplicate detection based on cherry

Kevin Deldycke 134 Dec 14, 2022
A news curator and newsletter subscription package for Django

django-newsfeed What is django-newsfeed? django-newsfeed is a news curator and newsletter subscription package for django. It can be used to create a

Maksudul Haque 179 Nov 14, 2022
A script based on an article I wrote on decluttering emails.

Decluttering_Email A script based on an article I wrote on decluttering emails. What does this program do? This program is a python script that sends

Ogheneyoma Obomate Okobiah 6 Oct 21, 2021
A django package which act as a gateway to send and receive email with amazon SES.

django-email-gateway: Introduction: A Simple Django app to easily send emails, receive inbound emails from users with different email vendors like AWS

MicroPyramid 28 Nov 09, 2022
Mail hosting made simple

Modoboa Modoboa is a mail hosting and management platform including a modern and simplified Web User Interface. It provides useful components such as

Modoboa 2.4k Jan 03, 2023
Send Emails through the terminal , fast and secure

Send Emails through the terminal , fast and secure

11 Aug 07, 2022
EmailAll - a powerful Email Collect tool

EmailAll A powerful Email Collect tool 0x1 介绍 😲 EmailAll is a powerful Email Co

473 Dec 22, 2022