用于Amazon的简单电子邮件服务(SES)的Django电子邮件后端
项目描述
- 信息:
亚马逊简单电子邮件服务(SES)的Django电子邮件后端
- 合作者:
Paul Craciunoiu (http://github.com/pcraciunoiu, http://twitter.com/embrangler)
概述
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_ID 和 AWS_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上
添加一个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_BLACKLIST和AWS_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_BLACKLIST和AWS_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_KEY 和 DKIM_DOMAIN 设置的值。您可以使用如 openssl genrsa 512 这样的命令生成私钥,并使用 openssl rsa -pubout <private.key 获取公钥部分。如果您的域是 example.com,则公钥应发布到 ses._domainkey.example.com。您可以通过更改 DKIM_SELECTOR 设置来使用除 ses 之外的其他名称。
SES 中继将修改诸如 Date 和 Message-Id 等电子邮件头,因此默认情况下仅签名 From、To、Cc 和 Subject 头,而不是完整的头集合。这对于大多数 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'),
从管理员处链接仪表板
您可以使用adminplus来完成此操作(https://github.com/jsocol/django-adminplus)
from django_ses.views import DashboardView admin.site.register_view('django-ses', DashboardView.as_view(), '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_DOMAIN,DKIM_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_SIGNATURES,AWS_SES_VERIFY_BOUNCE_SIGNATURES
可选。默认为True。通过将您从消息内容重新创建的签名与Amazon SNS随消息发送的签名进行匹配来验证消息的内容。有关更多详情,请参阅https://docs.aws.amazon.com/sns/latest/dg/sns-verify-signature-of-message.html。
- EVENT_CERT_DOMAINS,BOUNCE_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"
贡献
如果您想修复一个错误,添加一个功能等
- 首先,打开一个问题。
要明确,以便项目协作者可以理解和重现问题,或者决定该功能是否在项目目标之内。代码示例也很有用。
- 提交一个拉取请求。
您可以编写一个原型或建议的修复。
- 检查代码中的错误和投诉。
使用check.py
- 编写和运行测试。
编写自己的测试来显示问题已解决,或者功能按预期工作。
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默认不推送标签)。