0

I'm working on producing a quick newletter based on templates, local files, and files on the web. I "almost" have it working. I've distilled the problem code to the following block. I'm just learning Python, and am using Python 3.6.

My newsletter consists of some text with a photo pulled off the web, one or more in-line photos, and a couple of attachments.

The code below produces a valid message that is displayed by Gmail with no issues, but when sent to a Yahoo address, the in-line files do not show (The web photo shows and the attachments show, preview, and download fine).

The two "email-sources" look the same but render incorrectly on Yahoo!

import smtplib
from email.message import EmailMessage
from email.message import MIMEPart
from email.mime.multipart import MIMEMultipart
from base64 import encodebytes
import mimetypes

mSubject = 'Another new family reunion' 
mFrom    = 'me@mgmail.com'
mTo      = 'mom@yahoo.com'
mCC      = 'sis@roadrunner.com'
sLogin   = 'me@gmail.com'
sPass    = 'mypass'
mServer  = "smtp.gmail.com"
mPort    = 465

filename1 = "file1.jpg"
filename2 = "file2.jpg"
filename3 = "file3.jpg"
image_cid1 = filename1 + "@xxxx1"
image_cid2 = filename2 + "@xxxx2"


def inline_part(filename, icid):
    """ Creates a MIMEMultipart for embedded images """
    part = MIMEMultipart('related')

    fp = open(filename, 'rb')
    part.set_payload(encodebytes(fp.read()).decode())
    fp.close()
    part.add_header('Content-ID', '<' + icid + '>')
    part.add_header("Content-Transfer-Encoding", "base64")
    return part

def attach_part(filename):
    """ Creates a MIMEPart for attached images """
    part = MIMEPart()
    fp = open(filename, 'rb')
    part.set_payload(encodebytes(fp.read()).decode())
    fp.close()

    part.add_header("Content-Type",  mimetypes.guess_type(filename2)[0] + '; filename="%s"' % filename)
    part.add_header("Content-Transfer-Encoding", "base64")
    part.add_header('Content-Disposition', 'attachment; filename="%s"' % filename)
    return part

#set up the mime types
mimetypes.init()

# Create the container email message.
msg = EmailMessage()

msg['Subject'] = mSubject
msg['From']    = mFrom
msg['To']      = mTo
msg['Bcc']     = mCC

body ="""<HTML>
  <head></head>
  <body>
    This is a test email to send an attachment.
    This is a linked image:
    <div align="center"><p><img src="http://www.freedigitalphotos.net/images/previews/success-road-sign-10031660.jpg"><br></p><p>&nbsp;</p></div>
    we will try to add two in-line images as well, named file1.jpg and file2.jpg
"""
# add each of the the in-line photo body info
body += '    <p>This is file 1</p>\n<p><img id="'+ filename1 + '" src="cid:' + image_cid1 + '" alt="file01.jpg"></p>\n'
body += '    <p>This is file 2</p>\n<p><img id="'+ filename2 + '" src="cid:' + image_cid2 + '" alt="file02.jpg"></p>\n'

#add the rest of the body
body +="""    <p>and we have attached one file "file3.jpg"
  </body>
</HTML>
"""

# add the body to the message
msg.add_alternative(body, subtype='html')
msg.set_boundary("===myBoundry")
# attach the in-line files
msg.attach(inline_part(filename1, image_cid1))
msg.attach(inline_part(filename2, image_cid2))
# attach the attachment file
msg.attach(attach_part(filename3))

# Open a connection to the mail server, log-on, send the message and disconnect
try:
    server = smtplib.SMTP_SSL(mServer, mPort)
    server.set_debuglevel(0)
    server.login(sLogin, sPass)
    server.send_message(msg)
    server.quit()
    print ("Message sent Successfully")
except Exception as e:
    print ("Error sending mail:\n\t" + str(e))

Notes

  • I set my own "boundary" because Yahoo was splitting the Content-Type/Boundary on two lines, but the results are the same!
  • The body is broken up because it is actually "put together" from different pieces, I just combined most of here to make it closer to what I am actually doing.
  • The "send_message" sequence is done because I actually open the server and login before creating the message(s) Yes I may send multiple, then disconnect

Obviously I missed something obvious..... but right now I can't see the forest for the trees!

Linus12
  • 43
  • 6
  • First, are you sure that the problem isn't that you have a perfectly valid MIME message, but Yahoo's spam/security/etc. filters have decided it's questionable and are therefore hiding inline images in HTML? (You'd think there would be some kind of notification in the Yahoo web interface letting you know that the images were blocked for your safety, with a link to "click here to enable messages from this user", or something like that. But Yahoo doesn't always do what you'd expect, or hope…) – abarnert Jul 23 '18 at 23:20
  • @abarnert I actually did think of that, but messages from other's with show up just fine. And my Java version of this was working fine last year... Guess I'll drag it out and see if it is having the same problem... which would indicate it might be based on the "sender".. :( – Linus12 Jul 23 '18 at 23:30

0 Answers0