使用 Gmail 报告 Django 错误
Django error reporting with Gmail
我正在尝试设置我的 Django 帐户以接收错误报告 (docs here)。
我已将 ADMINS
添加到我的 settings.py
。然后,根据文档:
In order to send email, Django requires a few settings telling it how
to connect to your mail server. At the very least, you’ll need to
specify EMAIL_HOST and possibly EMAIL_HOST_USER and
EMAIL_HOST_PASSWORD, though other settings may be also required
depending on your mail server’s configuration. Consult the Django
settings documentation for a full list of email-related settings.
但这是我迷路的时候。
我有一个 Business Gmail 帐户,这是我想要在此处 link 的帐户。 This post 解释得很精彩,
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'myemail@mydomain.com'
EMAIL_HOST_PASSWORD = 'mypassword'
但上面写着:
In 2016 Gmail is not allowing this anymore.
显然,问题出在 EMAIL_HOST_PASSWORD
设置中,它必须是一个特定的密码,如 this other post 中所述。
但是,很难相信 Gmail 不允许这样做,尤其是对于您要为服务付费的企业帐户。
不幸的是,我找到的所有相关信息都早于 2016 年,因此不再有用。
有没有办法将 Django 应用程序与 Gmail 连接起来?
最终对我有用的解决方法是为此创建一个新的 Gmail 帐户。这目前有效,尽管我在其他地方读到的一些评论说的是相反的。
请注意,这个新帐户将没有两步验证,但安全性并不是一个大问题,因为该帐户将 "only" 处理 Django 电子邮件。
您可以使用 Gmail API 通过 Gmail 电子邮件地址发送授权电子邮件。一个好的起点是文档:https://developers.google.com/gmail/api/quickstart/python
我一直 运行 遇到这个问题,所以我记录了如何使用 API 博客 post:https://www.willcarh.art/blog/Automating-Emails-in-Python/
我最终构建了自己的 Python 实用程序来通过 Gmail API 发送电子邮件,这实在是太痛苦了。这是我最初的原型:
import os
import sys
import pickle
import base64
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from email.mime.text import MIMEText
def get_gmail_api_instance():
"""
Setup Gmail API instance
"""
if not os.path.exists('token.pickle'):
return None
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
service = build('gmail', 'v1', credentials=creds)
return service
def create_message(sender, to, subject, message_text):
"""
Create a message for an email
:sender: (str) the email address of the sender
:to: (str) the email address of the receiver
:subject: (str) the subject of the email
:message_text: (str) the content of the email
"""
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
raw = base64.urlsafe_b64encode(message.as_bytes())
raw = raw.decode()
body = {'raw': raw}
return body
def send_email(service, user_id, message):
"""
Send an email via Gmail API
:service: (googleapiclient.discovery.Resource) authorized Gmail API service instance
:user_id: (str) sender's email address, used for special "me" value (authenticated Gmail account)
:message: (base64) message to be sent
"""
try:
message = (service.users().messages().send(userId=user_id, body=message).execute())
return message
except Exception as e:
print("err: problem sending email")
print(e)
def main():
"""
Set up Gmail API instance, use it to send an email
'sender' is the Gmail address that is authenticated by the Gmail API
'receiver' is the receiver's email address
'subject' is the subject of our email
'message_text' is the content of the email
"""
# draft our message
sender = 'pythonista@gmail.com'
receiver = 'receiver@gmail.com'
subject = 'Just checking in!'
message_text = "Hi! How's it going?"
# authenticate with Gmail API
service = get_gmail_api_instance()
if service == None:
print("err: no credentials .pickle file found")
sys.exit(1)
# create message structure
message = create_message(sender, receiver, subject, message_text)
# send email
result = send_email(service, sender, message)
if not result == None:
print(f"Message sent successfully! Message id: {result['id']}")
if __name__ == '__main__':
main()
然后,要让 Django 在出现 404、500 等错误时发送电子邮件,请添加到相关 urls.py
:
from django.conf.urls import handler404, handler500
handler404 = projectname_views.error_404
handler500 = projectname_views.error_500
并在相关 views.py
中添加:
import send_gmail
from django.shortcuts import render
def error_500(request):
# call email function
send_gmail.main()
response = render(request, '500_errror_template.html')
response.status_code = 500
return response
GitHub 上面代码的要点:https://gist.github.com/wcarhart/b4f509c46ad1515a9954d356aaf10df1
我想提供截至 2021 年 8 月的更新。
我只使用 Django 附带的库在企业 gmail 帐户上工作。
在settings.py
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'myname@mydomain.com'
EMAIL_HOST_PASSWORD = 'myappspecificpassword'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
对于密码,您需要为相关帐户生成一个应用专用密码。您可以通过访问此 link 来做到这一点:https://security.google.com/settings/u/3/security/apppasswords.
注意:您必须为您发送的帐户启用双因素身份验证。这必须通过您发送的帐户启用 -- 而不是管理员帐户。
这样做,我可以在 views.py
的视图中使用此片段发送电子邮件
from django.core.mail import EmailMessage
...
email = EmailMessage(
'Hello',
'Body goes here',
'bob@example.com',
['user@mydomain.com'],
['bcc@example.com'],
reply_to=['myuser@mydomain.com'],
headers={'Message-ID': 'foo'},
)
email.send()
我正在尝试设置我的 Django 帐户以接收错误报告 (docs here)。
我已将 ADMINS
添加到我的 settings.py
。然后,根据文档:
In order to send email, Django requires a few settings telling it how to connect to your mail server. At the very least, you’ll need to specify EMAIL_HOST and possibly EMAIL_HOST_USER and EMAIL_HOST_PASSWORD, though other settings may be also required depending on your mail server’s configuration. Consult the Django settings documentation for a full list of email-related settings.
但这是我迷路的时候。 我有一个 Business Gmail 帐户,这是我想要在此处 link 的帐户。 This post 解释得很精彩,
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'myemail@mydomain.com'
EMAIL_HOST_PASSWORD = 'mypassword'
但上面写着:
In 2016 Gmail is not allowing this anymore.
显然,问题出在 EMAIL_HOST_PASSWORD
设置中,它必须是一个特定的密码,如 this other post 中所述。
但是,很难相信 Gmail 不允许这样做,尤其是对于您要为服务付费的企业帐户。
不幸的是,我找到的所有相关信息都早于 2016 年,因此不再有用。
有没有办法将 Django 应用程序与 Gmail 连接起来?
最终对我有用的解决方法是为此创建一个新的 Gmail 帐户。这目前有效,尽管我在其他地方读到的一些评论说的是相反的。
请注意,这个新帐户将没有两步验证,但安全性并不是一个大问题,因为该帐户将 "only" 处理 Django 电子邮件。
您可以使用 Gmail API 通过 Gmail 电子邮件地址发送授权电子邮件。一个好的起点是文档:https://developers.google.com/gmail/api/quickstart/python
我一直 运行 遇到这个问题,所以我记录了如何使用 API 博客 post:https://www.willcarh.art/blog/Automating-Emails-in-Python/
我最终构建了自己的 Python 实用程序来通过 Gmail API 发送电子邮件,这实在是太痛苦了。这是我最初的原型:
import os
import sys
import pickle
import base64
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from email.mime.text import MIMEText
def get_gmail_api_instance():
"""
Setup Gmail API instance
"""
if not os.path.exists('token.pickle'):
return None
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
service = build('gmail', 'v1', credentials=creds)
return service
def create_message(sender, to, subject, message_text):
"""
Create a message for an email
:sender: (str) the email address of the sender
:to: (str) the email address of the receiver
:subject: (str) the subject of the email
:message_text: (str) the content of the email
"""
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
raw = base64.urlsafe_b64encode(message.as_bytes())
raw = raw.decode()
body = {'raw': raw}
return body
def send_email(service, user_id, message):
"""
Send an email via Gmail API
:service: (googleapiclient.discovery.Resource) authorized Gmail API service instance
:user_id: (str) sender's email address, used for special "me" value (authenticated Gmail account)
:message: (base64) message to be sent
"""
try:
message = (service.users().messages().send(userId=user_id, body=message).execute())
return message
except Exception as e:
print("err: problem sending email")
print(e)
def main():
"""
Set up Gmail API instance, use it to send an email
'sender' is the Gmail address that is authenticated by the Gmail API
'receiver' is the receiver's email address
'subject' is the subject of our email
'message_text' is the content of the email
"""
# draft our message
sender = 'pythonista@gmail.com'
receiver = 'receiver@gmail.com'
subject = 'Just checking in!'
message_text = "Hi! How's it going?"
# authenticate with Gmail API
service = get_gmail_api_instance()
if service == None:
print("err: no credentials .pickle file found")
sys.exit(1)
# create message structure
message = create_message(sender, receiver, subject, message_text)
# send email
result = send_email(service, sender, message)
if not result == None:
print(f"Message sent successfully! Message id: {result['id']}")
if __name__ == '__main__':
main()
然后,要让 Django 在出现 404、500 等错误时发送电子邮件,请添加到相关 urls.py
:
from django.conf.urls import handler404, handler500
handler404 = projectname_views.error_404
handler500 = projectname_views.error_500
并在相关 views.py
中添加:
import send_gmail
from django.shortcuts import render
def error_500(request):
# call email function
send_gmail.main()
response = render(request, '500_errror_template.html')
response.status_code = 500
return response
GitHub 上面代码的要点:https://gist.github.com/wcarhart/b4f509c46ad1515a9954d356aaf10df1
我想提供截至 2021 年 8 月的更新。
我只使用 Django 附带的库在企业 gmail 帐户上工作。
在settings.py
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'myname@mydomain.com'
EMAIL_HOST_PASSWORD = 'myappspecificpassword'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
对于密码,您需要为相关帐户生成一个应用专用密码。您可以通过访问此 link 来做到这一点:https://security.google.com/settings/u/3/security/apppasswords.
注意:您必须为您发送的帐户启用双因素身份验证。这必须通过您发送的帐户启用 -- 而不是管理员帐户。
这样做,我可以在 views.py
的视图中使用此片段发送电子邮件 from django.core.mail import EmailMessage
...
email = EmailMessage(
'Hello',
'Body goes here',
'bob@example.com',
['user@mydomain.com'],
['bcc@example.com'],
reply_to=['myuser@mydomain.com'],
headers={'Message-ID': 'foo'},
)
email.send()