GCP(Google 云)VM - 无法使用 SMTP 通过 Python 脚本发送电子邮件
GCP (Google Cloud) VM - Can't send email via Python script with SMTP
所以我用 Ubuntu 设置了一个 GCP VM,我想从那里使用 python 脚本通过我的邮件提供商发送定期报告。 smtp 端口是 587,据我了解,该端口以前在 GCP 环境中是关闭的,但现在应该可用。
我的脚本如下所示:
import smtplib,ssl
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import formatdate
from email import encoders
import time
timestr = time.strftime('(%Y-%m-%d)')
username='me@mydomain.de'
password='secretpw'
send_from = 'me@mydomain.de'
send_to = 'recipient@herdomain.com'
body = 'hello'
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = send_to
msg['Date'] = formatdate(localtime = True)
msg['Subject'] = 'important email'
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp.ionos.de')
port = '587'
smtp = smtplib.SMTP('smtp.ionos.de')
smtp.ehlo()
smtp.starttls()
smtp.login(username,password)
smtp.sendmail(send_from, send_to.split(','), msg.as_string())
smtp.quit()
执行时,机器在输出超时之前需要一些时间:
Traceback (most recent call last):
File "test.py", line 25, in <module>
server = smtplib.SMTP('smtp.ionos.de')
File "/usr/lib/python3.8/smtplib.py", line 255, 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 310, 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)
TimeoutError: [Errno 110] Connection timed out
但是,我可以 ping smtp.ionos.de
以及 telnet smtp.ionos.de 587
形成 cl,结果是工作正常的 ping 和连接。
我也尝试过使用其他电子邮件提供商(包括 gmail)进行此操作,但结果完全相同。
有人吗?感谢帮助,谢谢。
您的代码有多个问题:
- 连接到服务器两次。
- 连接时未指定端口号
- 没有为加密创建 SSL 上下文。
在您的代码中,替换这些行:
server = smtplib.SMTP('smtp.ionos.de')
port = '587'
smtp = smtplib.SMTP('smtp.ionos.de')
smtp.ehlo()
smtp.starttls()
搭配:
context = ssl.create_default_context()
smtp = smtplib.SMTP('smtp.ionos.de', 587)
smtp.ehlo()
smtp.starttls(context=context)
这是使用 GCP Cloud Functions 测试的完整示例。 requirements.txt 中不需要库。这使用 Python 3.9。该代码使用 App Password 因为普通用户需要 2FA。
import smtplib
import ssl
def send_email(request):
"""Responds to any HTTP request.
Args:
request (flask.Request): HTTP request object.
Returns:
The response text or any set of values that can be turned into a
Response object using
`make_response <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`.
"""
gmail_user = 'user@gmail.com'
gmail_password = 'YOURPASSWORD'
sent_from = gmail_user
to = ['foo@bar.com']
subject = 'Test e-mail from Python'
body = 'Test e-mail body'
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
context = ssl.create_default_context()
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls(context=context)
server.login(gmail_user, gmail_password)
server.sendmail(sent_from, to, body)
server.close()
print('Email sent (print)!')
return f'Email sent (return)!'
所以我用 Ubuntu 设置了一个 GCP VM,我想从那里使用 python 脚本通过我的邮件提供商发送定期报告。 smtp 端口是 587,据我了解,该端口以前在 GCP 环境中是关闭的,但现在应该可用。
我的脚本如下所示:
import smtplib,ssl
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import formatdate
from email import encoders
import time
timestr = time.strftime('(%Y-%m-%d)')
username='me@mydomain.de'
password='secretpw'
send_from = 'me@mydomain.de'
send_to = 'recipient@herdomain.com'
body = 'hello'
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = send_to
msg['Date'] = formatdate(localtime = True)
msg['Subject'] = 'important email'
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp.ionos.de')
port = '587'
smtp = smtplib.SMTP('smtp.ionos.de')
smtp.ehlo()
smtp.starttls()
smtp.login(username,password)
smtp.sendmail(send_from, send_to.split(','), msg.as_string())
smtp.quit()
执行时,机器在输出超时之前需要一些时间:
Traceback (most recent call last):
File "test.py", line 25, in <module>
server = smtplib.SMTP('smtp.ionos.de')
File "/usr/lib/python3.8/smtplib.py", line 255, 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 310, 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)
TimeoutError: [Errno 110] Connection timed out
但是,我可以 ping smtp.ionos.de
以及 telnet smtp.ionos.de 587
形成 cl,结果是工作正常的 ping 和连接。
我也尝试过使用其他电子邮件提供商(包括 gmail)进行此操作,但结果完全相同。
有人吗?感谢帮助,谢谢。
您的代码有多个问题:
- 连接到服务器两次。
- 连接时未指定端口号
- 没有为加密创建 SSL 上下文。
在您的代码中,替换这些行:
server = smtplib.SMTP('smtp.ionos.de')
port = '587'
smtp = smtplib.SMTP('smtp.ionos.de')
smtp.ehlo()
smtp.starttls()
搭配:
context = ssl.create_default_context()
smtp = smtplib.SMTP('smtp.ionos.de', 587)
smtp.ehlo()
smtp.starttls(context=context)
这是使用 GCP Cloud Functions 测试的完整示例。 requirements.txt 中不需要库。这使用 Python 3.9。该代码使用 App Password 因为普通用户需要 2FA。
import smtplib
import ssl
def send_email(request):
"""Responds to any HTTP request.
Args:
request (flask.Request): HTTP request object.
Returns:
The response text or any set of values that can be turned into a
Response object using
`make_response <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`.
"""
gmail_user = 'user@gmail.com'
gmail_password = 'YOURPASSWORD'
sent_from = gmail_user
to = ['foo@bar.com']
subject = 'Test e-mail from Python'
body = 'Test e-mail body'
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
context = ssl.create_default_context()
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls(context=context)
server.login(gmail_user, gmail_password)
server.sendmail(sent_from, to, body)
server.close()
print('Email sent (print)!')
return f'Email sent (return)!'