跳转到主要内容

用于Amazon的简单电子邮件服务(SES)的Django电子邮件后端

项目描述

信息:

亚马逊简单电子邮件服务(SES)的Django电子邮件后端

作者:

Harry Marr (http://github.com/hmarr, http://twitter.com/harrymarr)

合作者:

Paul Craciunoiu (http://github.com/pcraciunoiu, http://twitter.com/embrangler)

pypi pypi-downloads build python django

概述

Django-SES是Django的即插即用邮件后端。与传统的SMTP邮件服务器发送电子邮件不同,Django-SES通过亚马逊网络服务的优秀简单电子邮件服务(SES)路由电子邮件。(SES)。

请贡献力量!

该项目由维护者维护,但不是积极使用。有兴趣帮助维护此项目?如果您正在积极使用 django-ses 并有兴趣为其做出贡献,请通过GitHub Issues联系。

变更日志

有关每个版本的详细信息,请参阅GitHub发行页面:https://github.com/django-ses/django-ses/releases 或 CHANGES.md。

直接使用Django

亚马逊SES还允许您设置用户名和密码。如果您那样配置,您不需要这个包。Django默认邮件后端能够与亚马逊SES进行身份验证并正确发送电子邮件。

使用django-ses为您提供了SMTP接口难以或繁琐获得的额外功能,如送达率报告。

为什么选择SES而不是SMTP?

配置、维护和处理一些复杂的边缘情况可能会耗费时间。如果您不想维护邮件服务器、已经在EC2上部署(SES接收来自EC2实例的流量是免费的)、需要发送大量电子邮件、不希望担心PTR记录、反向DNS、电子邮件白名单/黑名单服务,或者想通过使用SES的Easy DKIM功能对您的消息进行DKIM签名来提高送达率和收件箱美观性,那么使用Django-SES可能对您有吸引力。

  • 您不想维护邮件服务器。

  • 您已经部署在EC2上(SES接收来自EC2实例的流量是免费的)。

  • 您需要发送大量电子邮件。

  • 您不希望担心PTR记录、反向DNS、电子邮件白名单/黑名单服务。

  • 您想通过使用SES的Easy DKIM功能对您的消息进行DKIM签名来提高送达率和收件箱美观性。

  • Django-SES是默认邮件后端的真正替代品。您的代码不需要任何更改。

开始使用

假设您已安装Django,您只需安装django-ses

pip install django-ses

要接收回弹或webhook事件,请安装“extra”事件

pip install django-ses[events]

将以下内容添加到您的settings.py中

EMAIL_BACKEND = 'django_ses.SESBackend'

# These are optional if you are using AWS IAM Roles https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html
AWS_ACCESS_KEY_ID = 'YOUR-ACCESS-KEY-ID'
AWS_SECRET_ACCESS_KEY = 'YOUR-SECRET-ACCESS-KEY'
# https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-files.html
AWS_SESSION_PROFILE = 'YOUR-PROFILE-NAME'
# 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'

# If you want to use the SESv2 client
USE_SES_V2 = True

或者,您可以通过以下两种设置值替换 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY。这在您希望使用与通过SES发送电子邮件不同的访问密钥通过S3上传文件的情况下很有用

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

现在,当您使用 django.core.mail.send_mail 时,默认会通过简单电子邮件服务发送消息。

由于SES(Simple Email Service)限制了发送速率,并在达到限制后拒绝电子邮件,django-ses将尝试通过查询API获取当前限制,然后在两秒内(这是速率限制的一半,以确保不会触及限制)发送不超过该数量的消息。这由以下设置控制:

AWS_SES_AUTO_THROTTLE = 0.5 # (默认值;应用于速率限制的安全系数)

要关闭自动节流,将其设置为None。

请查看example目录以获取更多信息。

使用亚马逊简单通知服务(Amazon SNS)监控电子邮件状态

要设置此功能,使用events额外组件安装django-ses

pip install django-ses[events]

然后在你的urls.py中添加一个事件URL处理器。

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处理退订、投诉、发送、投递、打开和点击事件。它还可以自动确认订阅,处理SubscriptionConfirmation通知。

在AWS上

  1. 添加一个SNS主题。

2. 在SES设置中,在“配置集”中设置一个SNS目标。通过设置AWS_SES_CONFIGURATION_SET使用此配置集。将主题设置为第1步中创建的主题。

3. 将https订阅者添加到主题。(例如https://www.yourdomain.com/ses/event-webhook/)不要勾选“启用原始消息投递”。

退订

使用信号‘bounce_received’来管理退订电子邮件。例如

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)

不可恢复退订(状态5xx)的最常见用途是将导致退订的电子邮件地址添加到黑名单中,以避免发送更多电子邮件并触发更多退订。django-ses提供了一个内置的黑名单,可以完成此操作。检查AWS_SES_ADD_BOUNCE_TO_BLACKLISTAWS_SES_USE_BLACKLIST

投诉

使用信号‘complaint_received’来管理投诉电子邮件。例如

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):
    ...

投诉的最常见用途是将导致投诉的电子邮件地址添加到黑名单中,以避免发送更多电子邮件并触发更多投诉。django-ses提供了一个内置的黑名单,可以完成此操作。检查AWS_SES_ADD_COMPLAINT_TO_BLACKLISTAWS_SES_USE_BLACKLIST

发送

使用信号‘send_received’来管理发送电子邮件。例如

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_received’来管理投递电子邮件。例如

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_received’来管理打开电子邮件。例如

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_received’来管理发送电子邮件。例如

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):
    ...

测试信号

如果您想测试您的信号,您可以在设置中可选地禁用AWS_SES_VERIFY_EVENT_SIGNATURES。AWS SNS发送的JSON对象示例可以在此处找到:[https://docs.aws.amazon.com/sns/latest/dg/sns-message-and-json-formats.html#http-subscription-confirmation-json](https://docs.aws.amazon.com/sns/latest/dg/sns-message-and-json-formats.html#http-subscription-confirmation-json)

使用配置集的SES事件监控

您可以使用SES事件发布在更细粒度级别跟踪您的SES电子邮件发送。为此,您设置一个SES配置集并向其中添加事件处理器,以便将事件发送到AWS内部(SNS、CloudWatch或Kinesis Firehose)以进行进一步处理和分析。

为确保您通过django-ses发送的电子邮件将带有您的SES配置集,请将settings.py中的AWS_SES_CONFIGURATION_SET设置设置为配置集的名称

AWS_SES_CONFIGURATION_SET = 'my-configuration-set-name'

这将向所有发出的电子邮件添加X-SES-CONFIGURATION-SET标题。

如果您想按消息设置SES配置集,将AWS_SES_CONFIGURATION_SET设置为可调用对象。可调用对象应遵循以下原型

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

其中

  • message 是一个 django.core.mail.EmailMessage 对象(或其子类)

  • dkim_domain 是一个包含此消息 DKIM 域的字符串

  • dkim_key 是一个包含此消息 DKIM 私钥的字符串

  • dkim_selector 是一个包含 DKIM 选择器的字符串(请见下文 DKIM 的解释)

  • dkim_headers 是一个包含要 DKIM 签名的头名称的字符串列表(请见下文 DKIM 的解释)

DKIM

使用 DomainKeys 是完全可选的,但是 Amazon 推荐使用它来验证您的电子邮件地址并提高投递成功率。请参见 http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/DKIM.html。除了身份验证之外,您可能还希望考虑使用 DKIM 来移除显示给 Gmail 用户的 via email-bounces.amazonses.com 消息 - 请见 http://support.google.com/mail/bin/answer.py?hl=en&answer=1311182

目前有两种方法可以在 Django-SES 中使用 DKIM:传统的手动签名和最近引入的 Amazon Easy DKIM 功能。

Easy DKIM

Easy DKIM 是 Amazon SES 的一项功能,它可以自动使用 DKIM 签名对从已验证的电子邮件地址或域发送的每条消息进行签名。

您可以在 AWS 管理控制台中为 SES 启用 Easy DKIM。在那里,您还可以将所需的域验证和 DKIM 记录添加到 Route 53(或复制到您的备用 DNS)。

启用并验证 Easy DKIM 后,无需额外的依赖项或 DKIM 特定设置即可与 Django-SES 一起使用。

有关更多信息及设置指南,请参见: http://docs.aws.amazon.com/ses/latest/DeveloperGuide/easy-dkim.html

手动 DKIM 签名

要启用手动 DKIM 签名,您应安装 pydkim 软件包,并指定 DKIM_PRIVATE_KEYDKIM_DOMAIN 设置的值。您可以使用如 openssl genrsa 512 这样的命令生成私钥,并使用 openssl rsa -pubout <private.key 获取公钥部分。如果您的域是 example.com,则公钥应发布到 ses._domainkey.example.com。您可以通过更改 DKIM_SELECTOR 设置来使用除 ses 之外的其他名称。

SES 中继将修改诸如 DateMessage-Id 等电子邮件头,因此默认情况下仅签名 FromToCcSubject 头,而不是完整的头集合。这对于大多数 DKIM 验证器来说是足够的,但可以通过 DKIM_HEADERS 设置来覆盖。

示例 settings.py

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

使用 boto 发布到 Route53 的示例 DNS 记录

route53 add_record ZONEID ses._domainkey.example.com. TXT ‘“v=DKIM1; p=xxx”’ 86400

身份所有者

使用身份所有者,您可以在多个账户中使用经过验证的 SES 域: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-authorization-delegate-sender-tasks-email.html

如果您的多个环境位于不同的账户中,但仍然想通过同一域发送邮件,这很有用。

您可以使用以下环境变量来配置它们,如 boto3-docs 中所述

AWS_SES_SOURCE_ARN=arn:aws:ses:eu-central-1:012345678910:identity/example.com
AWS_SES_FROM_ARN=arn:aws:ses:eu-central-1:012345678910:identity/example.com
AWS_SES_RETURN_PATH_ARN=arn:aws:ses:eu-central-1:012345678910:identity/example.com

SES 发送统计

Django SES 提供了两种查看发送统计的方法。

第一种是一个简单的只读报告,关于您的 24 小时发送配额、已验证的电子邮件地址和双周发送统计。

要启用仪表板从 AWS 获取数据,您需要通过添加以下操作来更新 IAM 策略

{
    "Effect": "Allow",
    "Action": [
        "ses:ListVerifiedEmailAddresses",
        "ses:GetSendStatistics"
    ],
    "Resource": "*"
}

要生成和查看 SES 发送统计报告,包含,更新 INSTALLED_APPS

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

… 以及 urls.py

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

可选的统计数据增强

覆盖仪表板视图

您可以通过覆盖仪表板视图来添加更多上下文数据,例如。

class CustomSESDashboardView(DashboardView):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update(**admin.site.each_context(self.request))
        return context

然后更新您的URL

urlpatterns += path('admin/django-ses/', CustomSESDashboardView.as_view(), name='django_ses_stats'),

存储每日统计数据

如果您需要将发送的统计数据保留超过两周,django-ses还提供了一个模型,允许您存储这些数据。要使用此功能,您需要运行

python manage.py migrate

要收集统计数据,请运行get_ses_statistics管理命令(有关详细信息,请参阅下一节)。运行此命令后,统计数据将通过/admin/django_ses/可查看。

Django SES 管理命令

要使用这些命令,您必须在您的INSTALLED_APPS中包含django_ses

管理验证的电子邮件地址

通过管理命令管理验证的电子邮件地址。

python manage.py ses_email_address –list

通过以下方式将电子邮件添加到验证的电子邮件列表中

python manage.py ses_email_address –add john.doe@example.com

通过以下方式从验证的电子邮件列表中删除电子邮件

python manage.py ses_email_address –delete john.doe@example.com

您可以通过设置详细级别来切换控制台输出。

python manage.py ses_email_address –list –verbosity 0

收集发送统计信息

要收集和存储数据库中的SES发送统计信息,请运行

python manage.py get_ses_statistics

发送统计信息每日汇总(UTC时间)。如果运行时间早于UTC时间一天结束之前,最新一天的统计数据可能不准确。如果您想保持统计数据更新,请设置cron在午夜(UTC)后不久运行此命令。

管理黑名单

要管理黑名单(添加、删除、列出),请运行

python manage.py blacklist

Django 内置错误电子邮件

如果您希望Django的内置错误报告功能正常运行(实际上发送有效的电子邮件),您必须显式设置SERVER_EMAIL设置为您的SES验证地址之一。否则,您的错误电子邮件都会失败,您将 blissfully 无知于问题。

注意:您需要注册SES,并在from_email参数中验证您将要使用的任何电子邮件。Boto有一个verify_email_address()方法:https://github.com/boto/boto/blob/master/boto/ses/connection.py

要求

django-ses需要支持的Django或Python版本。

设置完整列表

AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY

必需。 您的Amazon SES API密钥。

AWS_SES_ACCESS_KEY_ID, AWS_SES_SECRET_ACCESS_KEY

必需。 Amazon SES的替代API密钥。这在您想为不同的AWS服务使用不同的访问密钥的情况下很有用。

AWS_SES_SESSION_TOKEN, AWS_SES_SECRET_ACCESS_KEY

可选。在临时凭证的情况下,使用AWS_SES_SESSION_TOKEN提供会话令牌。详细信息:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html

AWS_SES_REGION_NAME, AWS_SES_REGION_ENDPOINT

可选地指定您的SES服务正在使用的区域。注意,如果您的SES服务不是使用us-east-1,则此设置为必填项。省略这些设置意味着使用该区域。详情:http://readthedocs.org/docs/boto/en/latest/ref/ses.html#boto.ses.regions http://docs.aws.amazon.com/general/latest/gr/rande.html

USE_SES_V2

可选。如果您想使用客户端v2,则需要添加USE_SES_V2=True。某些设置需要启用此标志。请参阅https://boto3.amazonaws.com/v1/documentation/api/1.26.31/reference/services/sesv2.html#id87

AWS_SES_FROM_EMAIL

可选。用作邮件“发件人”地址的电子邮件地址。您指定的地址必须经过验证。有关更多信息,请参阅https://boto3.amazonaws.com/v1/documentation/api/1.26.31/reference/services/sesv2.html#SESV2.Client.send_email

AWS_SES_RETURN_PATH

可选。使用AWS_SES_RETURN_PATH接收投诉通知。您必须通过设置USE_SES_V2=True来使用v2客户端才能启用此设置,否则将被忽略。https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html#API_SendEmail_RequestSyntax

AWS_SES_CONFIGURATION_SET

可选。使用此功能将电子邮件标记为来自特定的SES配置集。如果您想所有消息都具有相同的配置集,请将其设置为字符串。如果您想按消息设置配置集,请将其设置为可调用对象。

TIME_ZONE

默认Django设置,可选设置。详情:https://docs.django.ac.cn/en/dev/ref/settings/#time-zone

DKIM_DOMAINDKIM_PRIVATE_KEY

可选。如果这些设置已定义并且已安装pydkim模块,则电子邮件消息将使用指定的密钥进行签名。您还需要在DNS上发布您的公钥;默认选择器设置为ses。有关更多详情,请参阅http://dkim.org/

AWS_SES_SOURCE_ARN

指示Amazon SES使用来自另一个账户的域。有关更多信息,请参阅https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-authorization-delegate-sender-tasks-email.html

AWS_SES_FROM_ARN

指示Amazon SES使用来自另一个账户的域。有关更多信息,请参阅https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-authorization-delegate-sender-tasks-email.html

AWS_SES_RETURN_PATH_ARN

指示Amazon SES使用来自另一个账户的域。有关更多信息,请参阅https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-authorization-delegate-sender-tasks-email.html

AWS_SES_VERIFY_EVENT_SIGNATURESAWS_SES_VERIFY_BOUNCE_SIGNATURES

可选。默认为True。通过将您从消息内容重新创建的签名与Amazon SNS随消息发送的签名进行匹配来验证消息的内容。有关更多详情,请参阅https://docs.aws.amazon.com/sns/latest/dg/sns-verify-signature-of-message.html

EVENT_CERT_DOMAINSBOUNCE_CERT_DOMAINS

可选。默认为‘amazonaws.com’和‘amazon.com’。

AWS_SES_ADD_BOUNCE_TO_BLACKLIST

如果设置为True(默认为False),则触发了不可恢复退信(状态在5xx范围内)的电子邮件地址将被添加到黑名单。注意,电子邮件将以小写存储。

AWS_SES_ADD_COMPLAINT_TO_BLACKLIST

如果设置为True(默认为False),则触发了投诉的电子邮件地址将被添加到黑名单。注意,电子邮件将以小写存储。

AWS_SES_USE_BLACKLIST

如果设置为True(默认为False),则调用send_mail()方法将导致使用黑名单过滤收件人。任何存在于黑名单中的收件人将从电子邮件中删除。

代理

如果您正在使用代理,请通过环境变量启用它。

如果您的代理服务器没有密码,请尝试以下操作

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

如果您的代理服务器有密码,请尝试以下操作

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

来源:https://stackoverflow.com/a/33501223/1331671

贡献

如果您想修复一个错误,添加一个功能等

  1. 首先,打开一个问题。

    要明确,以便项目协作者可以理解和重现问题,或者决定该功能是否在项目目标之内。代码示例也很有用。

  2. 提交一个拉取请求。

    您可以编写一个原型或建议的修复。

  3. 检查代码中的错误和投诉。

    使用check.py

  4. 编写和运行测试。

    编写自己的测试来显示问题已解决,或者功能按预期工作。

Git钩子(通过pre-commit)

我们使用pre-push钩子来确保只有经过lint的代码才能到达我们的远程仓库,并且不会无谓地触发管道。

要启用配置的pre-push钩子,您需要[安装](https://pre-commit.git-scm.cn/) pre-commit并运行一次

pre-commit install -t pre-push -t pre-commit --install-hooks

这将永久地将git钩子安装到本地[.git/hooks](./.git/hooks)文件夹中,前端和后端的钩子配置在[.pre-commit-config.yaml](.pre-commit-config.yaml)中。

您可以使用[run](https://pre-commit.git-scm.cn/#pre-commit-run)命令来检查钩子是否按预期工作

pre-commit run [hook-id] [options]

示例:运行单个钩子

pre-commit run ruff --all-files --hook-stage push

示例:运行pre-push阶段的全部钩子

pre-commit run --all-files --hook-stage push

运行测试

要运行测试

python runtests.py

如果您想调试测试,只需将其作为Python脚本添加到IDE的运行配置中即可。

创建一个版本

要创建版本

  • 按照[文档](https://poetry.pythonlang.cn/docs/cli/#version)中的说明运行poetry version {patch|minor|major}。这将更新pyproject.toml中的版本。

  • 提交该更改,并使用git为该提交添加一个与模式v*.*.*匹配的版本标签。

  • 推送标签和提交(注意某些IDE默认不推送标签)。

由以下组织支持