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)!'