无法在生产中发送电子邮件
Can't send email in production
我正在开发网上商店,在本地一切正常 machine.Client 将商品添加到购物车,输入他的凭据点击 'Make Order' 然后订单确认应该发送到他的电子邮件。它工作正常,即使使用 redis + 芹菜,但自从我将项目部署到服务器 (linode.com) 后,订单确认不起作用。工人接受了任务但从未执行过。我认为这是因为芹菜,我已经决定在没有任务管理器和队列的情况下发送电子邮件。但是没有用。
我在服务器中使用了UFW防火墙:
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
Anywhere ALLOW 96.126.119.66
443 ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
我得到这样的错误:
[Errno 110] Connection timed out
希望你能帮助我理解这个问题
回溯:
Environment:
Request Method: POST
Request URL: https://bauerdress.ru/orders/create/
Django Version: 3.1
Python Version: 3.8.5
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.sites',
'django.contrib.staticfiles',
'shop.apps.ShopConfig',
'cart.apps.CartConfig',
'orders.apps.OrdersConfig',
'wishlist.apps.WishlistConfig',
'widget_tweaks',
'crispy_forms',
'information.apps.InformationConfig',
'promotion.apps.PromotionConfig',
'django_filters',
'email_sub.apps.EmailSubConfig',
'django_simple_coupons',
'ckeditor',
'flower',
'allauth',
'allauth.account',
'allauth.socialaccount']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/kirill/bauer_dress/orders/views.py", line 46, in order_create
order_created(order.id)
File "/home/kirill/bauer_dress/orders/tasks.py", line 22, in order_created
mail_sent = send_mail(subject, None, settings.EMAIL_HOST_USER, [order.email, settings.MAIL], html_message=html)
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/mail/__init__.py", line 61, in send_mail
return mail.send()
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/mail/message.py", line 284, in send
return self.get_connection(fail_silently).send_messages([self])
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/mail/backends/smtp.py", line 102, in send_messages
new_conn_created = self.open()
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/mail/backends/smtp.py", line 62, in open
self.connection = self.connection_class(self.host, self.port, **connection_params)
File "/usr/lib/python3.8/smtplib.py", line 253, in __init__
(code, msg) = self.connect(host, port)
File "/usr/lib/python3.8/smtplib.py", line 339, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/lib/python3.8/smtplib.py", line 308, in _get_socket
return socket.create_connection((host, port), timeout,
File "/usr/lib/python3.8/socket.py", line 808, in create_connection
raise err
File "/usr/lib/python3.8/socket.py", line 796, in create_connection
sock.connect(sa)
Exception Type: TimeoutError at /orders/create/
Exception Value: [Errno 110] Connection timed out
views.py
from django.conf import settings
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from cart.cart import Cart
from .models import OrderItem, Order
from .forms import OrderCreateForm
from shop.models import Product
from django.contrib.admin.views.decorators import staff_member_required
from django_simple_coupons.forms import CouponApplyForm
import weasyprint
from django.template import loader
from django.core.mail import send_mail
from email_sub.models import Subscription
from django.core.exceptions import ObjectDoesNotExist
from .tasks import order_created
def order_create(request):
cart = Cart(request)
coupon_apply_form = CouponApplyForm()
if request.method == 'POST':
form = OrderCreateForm(request.POST)
if form.is_valid():
order = form.save(commit=False)
if cart.coupon:
order.coupon = cart.coupon
order.discount = cart.coupon.discount.value
order.save()
for item in cart:
OrderItem.objects.create(
order=order,
product=item['product'],
product_set=item['product_set'],
price=item['product_set'].price,
quantity=item['quantity'],
size = item['product_set'].size_set,
color = item['color']
)
try:
Subscription.objects.get(email=order.email)
except ObjectDoesNotExist:
Subscription.objects.create(name=order.first_name, surname=order.last_name, email=order.email)
order_created(order.id) # <--- order confirmation email
cart.clear()
if cart.coupon:
cart.clear_coupon()
return render(request, 'orders/order/created.html', {'order': order})
else:
form = OrderCreateForm()
return render(request, 'orders/order/create_v2.html', {
'cart': cart,
'form': form,
'coupon_apply_form': coupon_apply_form})
tasks.py
def order_created(order_id):
"""
Task for sending mail if order created
"""
order = Order.objects.get(id=order_id)
subject = 'Заказ #{}'.format(order.id)
html = loader.render_to_string('orders/order/mail2.html', context={'order': order})
send_mail = send_mail(subject, None, settings.EMAIL_HOST_USER, [order.email, settings.MAIL], html_message=html)
return send_mail
settings.py(部分 smtp 设置)
#smtp
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'myuser@gmail.com' #real data used in production
EMAIL_HOST_PASSWORD = '1234'
EMAIL_PORT = 587
问题是我用了Linode,linode阻塞了端口,无意中发现
正如我所读到的,GoDaddy 做同样的事情
Need to send mail from your Linode? New Linode accounts have ports 25,
465, and 587 blocked by default. To have these restrictions removed,
please review this guide, then open a Support Ticket after creating
your Linode.
In an effort to fight spam, Linode restricts outbound connections on
ports 25, 465, and 587 on all Linodes for new accounts created after
November 5th, 2019.
我正在开发网上商店,在本地一切正常 machine.Client 将商品添加到购物车,输入他的凭据点击 'Make Order' 然后订单确认应该发送到他的电子邮件。它工作正常,即使使用 redis + 芹菜,但自从我将项目部署到服务器 (linode.com) 后,订单确认不起作用。工人接受了任务但从未执行过。我认为这是因为芹菜,我已经决定在没有任务管理器和队列的情况下发送电子邮件。但是没有用。
我在服务器中使用了UFW防火墙:
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
Anywhere ALLOW 96.126.119.66
443 ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
我得到这样的错误:
[Errno 110] Connection timed out
希望你能帮助我理解这个问题
回溯:
Environment:
Request Method: POST
Request URL: https://bauerdress.ru/orders/create/
Django Version: 3.1
Python Version: 3.8.5
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.sites',
'django.contrib.staticfiles',
'shop.apps.ShopConfig',
'cart.apps.CartConfig',
'orders.apps.OrdersConfig',
'wishlist.apps.WishlistConfig',
'widget_tweaks',
'crispy_forms',
'information.apps.InformationConfig',
'promotion.apps.PromotionConfig',
'django_filters',
'email_sub.apps.EmailSubConfig',
'django_simple_coupons',
'ckeditor',
'flower',
'allauth',
'allauth.account',
'allauth.socialaccount']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/kirill/bauer_dress/orders/views.py", line 46, in order_create
order_created(order.id)
File "/home/kirill/bauer_dress/orders/tasks.py", line 22, in order_created
mail_sent = send_mail(subject, None, settings.EMAIL_HOST_USER, [order.email, settings.MAIL], html_message=html)
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/mail/__init__.py", line 61, in send_mail
return mail.send()
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/mail/message.py", line 284, in send
return self.get_connection(fail_silently).send_messages([self])
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/mail/backends/smtp.py", line 102, in send_messages
new_conn_created = self.open()
File "/home/kirill/venv/lib/python3.8/site-packages/django/core/mail/backends/smtp.py", line 62, in open
self.connection = self.connection_class(self.host, self.port, **connection_params)
File "/usr/lib/python3.8/smtplib.py", line 253, in __init__
(code, msg) = self.connect(host, port)
File "/usr/lib/python3.8/smtplib.py", line 339, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/lib/python3.8/smtplib.py", line 308, in _get_socket
return socket.create_connection((host, port), timeout,
File "/usr/lib/python3.8/socket.py", line 808, in create_connection
raise err
File "/usr/lib/python3.8/socket.py", line 796, in create_connection
sock.connect(sa)
Exception Type: TimeoutError at /orders/create/
Exception Value: [Errno 110] Connection timed out
views.py
from django.conf import settings
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from cart.cart import Cart
from .models import OrderItem, Order
from .forms import OrderCreateForm
from shop.models import Product
from django.contrib.admin.views.decorators import staff_member_required
from django_simple_coupons.forms import CouponApplyForm
import weasyprint
from django.template import loader
from django.core.mail import send_mail
from email_sub.models import Subscription
from django.core.exceptions import ObjectDoesNotExist
from .tasks import order_created
def order_create(request):
cart = Cart(request)
coupon_apply_form = CouponApplyForm()
if request.method == 'POST':
form = OrderCreateForm(request.POST)
if form.is_valid():
order = form.save(commit=False)
if cart.coupon:
order.coupon = cart.coupon
order.discount = cart.coupon.discount.value
order.save()
for item in cart:
OrderItem.objects.create(
order=order,
product=item['product'],
product_set=item['product_set'],
price=item['product_set'].price,
quantity=item['quantity'],
size = item['product_set'].size_set,
color = item['color']
)
try:
Subscription.objects.get(email=order.email)
except ObjectDoesNotExist:
Subscription.objects.create(name=order.first_name, surname=order.last_name, email=order.email)
order_created(order.id) # <--- order confirmation email
cart.clear()
if cart.coupon:
cart.clear_coupon()
return render(request, 'orders/order/created.html', {'order': order})
else:
form = OrderCreateForm()
return render(request, 'orders/order/create_v2.html', {
'cart': cart,
'form': form,
'coupon_apply_form': coupon_apply_form})
tasks.py
def order_created(order_id):
"""
Task for sending mail if order created
"""
order = Order.objects.get(id=order_id)
subject = 'Заказ #{}'.format(order.id)
html = loader.render_to_string('orders/order/mail2.html', context={'order': order})
send_mail = send_mail(subject, None, settings.EMAIL_HOST_USER, [order.email, settings.MAIL], html_message=html)
return send_mail
settings.py(部分 smtp 设置)
#smtp
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'myuser@gmail.com' #real data used in production
EMAIL_HOST_PASSWORD = '1234'
EMAIL_PORT = 587
问题是我用了Linode,linode阻塞了端口,无意中发现 正如我所读到的,GoDaddy 做同样的事情
Need to send mail from your Linode? New Linode accounts have ports 25, 465, and 587 blocked by default. To have these restrictions removed, please review this guide, then open a Support Ticket after creating your Linode.
In an effort to fight spam, Linode restricts outbound connections on ports 25, 465, and 587 on all Linodes for new accounts created after November 5th, 2019.