smtplib error: Unknown Protocol for Automated Outlook Email with Attachment

smtplib error: Unknown Protocol for Automated Outlook Email with Attachment

我正在尝试发送带有附件的基本电子邮件。我的示例在 google 地址 smtp.google.com 上运行良好,但是当我尝试将其更改为 smtp.office365.com 时,出现此错误:[SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:852).

这是一个通过office365 SMTP 服务器作为电子邮件服务主机运行的域电子邮件。我已与 IT 团队核实,他们已在帐户上启用 SMTP 身份验证。

显然,这之前已经完成,所以我已经根据 检查了我的代码,但没有发现任何可能导致它的明显差异。我还仔细检查了 smtplib 文档,smtp.office365.com 是一个有效的、可识别的 SMTP 地址。

我将其写成如下(请注意机密凭据,这会阻止最小的可重现示例)。我已经注意到错误发生的位置,这几乎就像 smtplib 无法识别 office365 SMTP 地址。

    def send_email(self, html_message):
            # Create a text/plain message
    
            formatted_date = datetime.datetime.now().strftime('%Y%m%d')
    
            msg_root = MIMEMultipart('related')
            msg_root['Subject'] = self.client.client_name + 'Test Forecast'
            msg_root['From'] = self.config.get_email_from
            recipients = self.client.recipient_email
            recipients = recipients.split(', ')
    
            body = MIMEText(html_message, 'html')
            msg_root.attach(body)
    
            filename = self.client.city + ', ' + self.client.state
    
            # PDF attachment
            if self.client.use_pdf:
                filepath = self.config.get_email_pdf_file_path
                fp = open(filepath, 'rb')
                att = email.mime.application.MIMEApplication(fp.read(), _subtype="pdf")
                fp.close()
                att.add_header('Content-Disposition', 'attachment', filename=filename + '.pdf')
                msg_root.attach(att)
    
            # SSL port config
            port = 587
    
            # Create a secure SSL context
            context = ssl.create_default_context()
    
            # Connect
            with smtplib.SMTP_SSL("smtp.office365.com", port, context=context) as server: # Error on this line
                server.ehlo()
                server.starttls()
                server.login(self.config.get_email_from, self.config.get_email_password)
                print("Sending email report...")
                # Send email
                server.sendmail(self.config.get_email_from, recipients, msg_root.as_string())
            print("Your email was sent!")

根据 错误:[SSL: UNKNOWN_PROTOCOL] 未知协议 (_ssl.c:852) 您应该使用 465 端口,因为您使用的是 SSL 协议,而 587 端口用于 TLS 协议。

似乎是因为 Microsoft 将端口 587 用于 SMTP 而我们使用的外部域不通过 SSL 进行通信,我不得不将端口更改为 587,从方法中删除 SSL 参数,然后删除上下文。现在它使用 SMTP 而不是 SSL,starttls 也是必需的。

工作版本如下所示:

    port = 587

    # Connect
    with smtplib.SMTP("smtp.office365.com", port) as server:
        server.ehlo()
        server.starttls()
        server.ehlo()
        server.login(self.config.get_email_from, self.config.get_email_password)
        print("Sending email report...")
        # Send email
        server.sendmail(self.config.get_email_from, recipients, msg_root.as_string())
        print("Your email was sent!")