使用来自 python 的 SMTPlib 在 outlook 中出现附件问题

问题描述 投票:0回答:1

我正在为我的应用程序编写一个电子邮件系统。 只是一封带有附件(pdf 文件)的简单电子邮件,需要在完成一个步骤后发送。

在我可以测试的每个客户端(Linux 上的 Geary、移动端的 Outlook、网络上的 Outlook、我们自己的使用 roundcube 的电子邮件系统)上,我的附件都完美地通过了,我们没有问题。

除了 windows 上的 Outlook 客户端,我们的邮件都是直接收到的,没有附件。

我尝试将我的附件更改为 .png 、 .jpg 甚至 .docx 并且对于所有文件类型,它与上面的问题相同。

我正在使用这个代码:

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase

from email import encoders
import base64

FROM = "[email protected]"
data = request.data['data']
base64_string = data['file']
base64_string = base64_string.split(',')[1]
attachment_data = base64.b64decode(base64_string)

PASS = ""
SERVER = 'mail.ourhost.be'

TO = "[email protected]"

msg = MIMEMultipart('alternative')
msg['Subject'] = "subject"
msg['From'] = FROM
msg['To'] = TO

html = f"""\
    <html style="font-family: Heebo;">
            my email content
    </html>
    """ 

part2 = MIMEText(html, 'html')
msg.attach(part2)


# Add the decoded attachment data to the email
part = MIMEBase('application', 'pdf')
part.set_payload((attachment_data))
encoders.encode_base64(part)
filename = f'name.pdf'
part.add_header('Content-Disposition', "attachment; filename= %s" % filename)
msg.attach(part)

Windows 上的 Outlook 有什么特别需要注意的吗?

python email outlook email-attachments smtplib
1个回答
0
投票

我也有问题,我的部分联系人没有收到附件。

我的研究

做一些研究我发现了这篇 SO 帖子: SMTPlib 未收到附件

通过比较代码片段,我能辨别出的唯一相关区别是,在问题中......

msg = MIMEMultipart('alternative')

... 被使用,而在工作响应中 MIMEMultipart 被调用而没有参数:

msg = MIMEMultipart()

根据文档 (https://docs.python.org/3/library/email.mime.html) 这将默认为 _subtype='mixed'。

class email.mime.multipart.MIMEMultipart(_subtype='mixed', boundary=None, _subparts=None, *, policy=compat32, **_params)

根据 Mail multipart/alternative vs multipart/mixed 选择的类型取决于您的消息内容。


解决方案?

在您的示例中,您没有使用替代纯文本,因此“混合”(默认)可能是 MIMEMultipart 的正确 _subtype?

msg = MIMEMultipart()

请告诉我这是否能为您解决问题。

致以诚挚的问候!

附言这是我的脚本。实际上,我从 toml 配置文件中读取参数,因为将登录信息硬编码到脚本中是有问题的。我的例子也有一些基本的日志记录和一些功能被分成不同的功能。

import smtplib
from email import encoders
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.utils import make_msgid, formatdate
from pathlib import Path
import logging

# configure basic logging
logging.basicConfig(
    filename="send_mail.log",
    filemode="a",
    format="%(name)s - %(levelname)s - %(message)s",
)

def send_mail(sender_email, receiver_email, pdf_pathstring, email_plain_text="Add your message here."):
    """This is a wrapper function to send emails"""
    message = create_message(sender_email, receiver_email, pdf_pathstring, email_plain_text)
    send_smtp(message, sender_email, receiver_email)


def create_message(sender_email, receiver_email, pdf_pathstring, email_plain_text):
    """This function assembles the different parts of the email, so that it can then be sent by send_smtp"""
    # create a MIMEMultipart object
    message = MIMEMultipart()
    message["Subject"] = "Example_subject"
    message["From"] = sender_email
    message["To"] = receiver_email
    message["Message-ID"] = make_msgid()
    message["Date"] = formatdate()

    # Turn the email_plain_text into plain MIMEText objects and attach to message
    plaintext_part = MIMEText(email_plain_text, "plain")
    message.attach(plaintext_part)

    # Read in pdf
    pdf_path = Path(pdf_pathstring)
    filename = pdf_path.name

    # Open PDF file in binary mode
    with open(pdf_path, "rb") as attachment:
        # Add file as application/octet-stream
        # Email client can usually download this automatically as attachment
        attachment_part = MIMEBase("application", "octet-stream")
        attachment_part.set_payload(attachment.read())

    # Encode file in ASCII characters to send by email
    encoders.encode_base64(attachment_part)

    # Add header as key/value pair to attachment part
    attachment_part.add_header(
        "Content-Disposition",
        f"attachment; filename= {filename}",
    )

    # Add attachment_part to MIMEMultipart message
    message.attach(attachment_part)

    return message


def send_smtp(message, sender_email, receiver_email):
    """This function creates a smtp_object and sends the mail including the attachments in the message object"""
    sender_email = sender_email
    password = "************"

    smtp_object = smtplib.SMTP_SSL(exampleserver.ch, 465)
    smtp_object.ehlo()  # listen for server response
    smtp_object.login(sender_email, password)
    try:
        smtp_object.sendmail(sender_email, receiver_email, message.as_string())
        logging.warning(f"Message sent to {receiver_email}")
        print(f"Message sent to {receiver_email}")
    except:
        logging.exception(f"Couldn't sent mail to {receiver_email} because of an exception:")
        print(f"Couldn't sent mail to {receiver_email} because of an exception.")
    smtp_object.quit()  # terminate the connection
© www.soinside.com 2019 - 2024. All rights reserved.