使用EMailMessage发送包含嵌入图像和从文件读取的多部分文本和html的电子邮件

2024-04-25 08:14:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我想使用Python3 EMailMessage类发送一封由多个部分组成的电子邮件(文本和html),该类也有一个嵌入的图像。在使用MIME类时,我已经能够让它工作,但在EMailMessage类中却不行。显示HTML邮件,但没有嵌入图像,而是将其作为附件添加。示例代码如下所示(我的各种尝试中也有注释掉的行):

# Send an HTML email with an embedded image and a plain text message for
# email clients that don't want to display the HTML.
#Import smtplib for the actual sending function
import smtplib, ssl, mimetypes, imghdr

# Import the email modules we'll need
from email.message import EmailMessage
from email.headerregistry import Address
from email.mime.image import MIMEImage

from email.utils import make_msgid

STR_FROM_DISPLAY_NAME = "From Display Name"
TEXTFILE = "example.txt"
HTMLFILE = "example.html"
IMGFILE = "logo.png"
STR_FROM = "from@example.com"
STR_TO = "to@example.com"
STR_SUBJECT = f"The contents of {TEXTFILE}"

msg = EmailMessage()
msg["Subject"] = STR_SUBJECT
# STR_FROM == the sender's email address
# STR_TO == the recipient's email address
msg["From"] = STR_FROM
msg["To"] = STR_TO
msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'

# Open the plain text file whose name is in TEXTFILE for reading.
with open(TEXTFILE) as fp:
    # Create a text/plain message
    msg.set_content(fp.read())

# Add the html version.  This converts the message into a multipart/alternative
# container, with the original text message as the first part and the new html
# message as the second part.
image_cid = make_msgid()[1:-1]  # strip <>    
with open(HTMLFILE) as fp:
    msg.add_alternative(fp.read(), subtype="html") 
#.format(cid=cid), subtype="html")

#maintype, subtype = mimetypes.guess_type(IMGFILE)[0].split('/', 1)
# Now add the related image to the html part.
#attachments={"image1": IMGFILE}

#for png_cid in attachments:
from email.mime.image import MIMEImage

with open(IMGFILE, "rb") as fp:
    image_type = imghdr.what(fp.name)
    print("image_type = ", image_type)

    msgImage = MIMEImage(fp.read())

    # Define the image's ID as referenced above
    msgImage.add_header("Content-ID", "<image_cid>")
    msgImage.add_header('X-Attachment-Id', IMGFILE)
    msgImage.add_header("Content-Disposition", f"inline; filename={IMGFILE}")

#   msg.attach(msgImage)
   # Make the EmailMessage's payload `mixed`
    #msg.get_payload()[1].make_mixed()   # getting the second part because it is the HTML alternative
    #msg.get_payload()[1].attach(msgImage)

    msg.get_payload()[1].add_related(msgImage, "image", image_type, fp.name, cid=image_cid) #.format(cid=cid))

#   logo = MIMEImage(img.read())
#   logo.add_header("Content-ID", f"cid")
#   logo.add_header('X-Attachment-Id', IMGFILE)
#   logo['Content-Disposition'] = f"inline; filename=" IMGFILE
#   msg.attach(logo)

    # Make the EmailMessage's payload `mixed`
#   msg.get_payload()[1].make_mixed()   # getting the second part because it is the HTML alternative
#    msg.get_payload()[1].attach(logo)

port = 465  # For starttls
smtp_server = "smtp.mail.server.com"
password = "Password"

# Create secure connection with server and send email
context = ssl.create_default_context()
# Send the message via our own SMTP server.
with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
    server.login(STR_FROM, password)
    server.send_message(msg)

下面是我指定图像的HTML文件中的一行:

<img class="image_fix" src="cid:{image_cid}" alt="Logo" title="Logo" width="637" height="213" />

有很多例子是在python代码中指定HTML的,但是我还没有找到从嵌入图像的文件加载HTML的地方

我还想在电子邮件中附加一个word.docx文件,我用MIME类来管理它,但在电子邮件客户端查看时,附件没有显示大小。我用了这句话:

MIMEBase("application", "octet-stream").

将其编码为base64。我认为有一个“word”/“docx”MIME类型,但同样不确定如何做到这一点

有什么想法吗


Tags: theimageaddmessageserveremailhtmlwith