26 July 2012 2 Comments

Python Snippet: Sending HTML email with an attachment via Google Apps SMTP (or Gmail)

This is just one of those things that I had to do in a project (as part of a much bigger system), and wish I had it all laid out for me like this when I was writing it.

I broke it down into simple input variables that need to be filled out, and then let 'er rip.

You supply the account credentials, to address, from address, subject, HTML body (will be converted to plain as well, in case the email reader cannot support HTML for whatever reason), etc and everything else gets taken care of.

Should be easy to take the whole thing and throw it into a loop from a DB resultset, or something of that nature.

I initially wrote it to be used as part of a system that sent out different versions of "welcome" emails, as well as automated follow-up emails based on customer data and bunch of other shit. Fun times!

You're WELCOME!

import smtplib, os, re, sys, glob, string, datetime
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders




#attachmentname = 'C:\\python27\\email.log' #path to an attachment, if you wish

username = 'someguy@mygoogleapps-or-gmail.com'
password = 'superSECRETdinoCLUBpasswords!!'

fromaddr = 'Some Guy <someguy@mygoogleapps-or-gmail.com>' #must be a vaild 'from' addy in your GApps account
toaddr  = 'someoneelse@eelsandheels.com'
replyto = fromaddr #unless you want a different reply-to

msgsubject = 'This is for sexy email subjektz!'

htmlmsgtext = """This is my message body in HTML<br/>
                Yup. Yup. Yup.</br>
                <b>Done!</a>"""






#ok, here goes nothing
try:

    msgtext = htmlmsgtext.replace('<b>','').replace('</b>','').replace('<br>',"\r").replace('</br>',"\r").replace('<br/>',"\r").replace('</a>','')
    msgtext = re.sub('<.*?>','',msgtext)

    #pain the ass mimey stuff
    msg = MIMEMultipart()
    msg.preamble = 'This is a multi-part message in MIME format.\n'
    msg.epilogue = ''

    body = MIMEMultipart('alternative')
    body.attach(MIMEText(msgtext))
    body.attach(MIMEText(htmlmsgtext, 'html'))
    msg.attach(body)

    if 'attachmentname' in globals(): #DO WE HAZ ATTACHMENT?
        f = attachmentname
        part = MIMEBase('application', "octet-stream")
        part.set_payload( open(f,"rb").read() )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
        msg.attach(part)

    msg.add_header('From', fromaddr)
    msg.add_header('To', toaddr)
    ##msg.add_header('Cc', ccaddy)    #doesn't work apparently
    ##msg.add_header('Bcc', bccaddy)  #doesn't work apparently
    msg.add_header('Subject', msgsubject)
    msg.add_header('Reply-To', replyto)

    # The actual email sendy bits
    server = smtplib.SMTP('smtp.gmail.com:587')
    server.set_debuglevel(True) #commenting this out, changing to False will make the script give NO output at all upon successful completion
    server.starttls()
    server.login(username,password)
    server.sendmail(msg['From'], [msg['To']], msg.as_string())

    server.quit() #bye bye




except:
    print ('Email NOT sent to %s successfully. %s ERR: %s %s %s ', str(toaddr), 'tete', str(sys.exc_info()[0]), str(sys.exc_info()[1]), str(sys.exc_info()[2]) )
    #just in case

Sample Output

send: 'ehlo [0.0.0.0]\r\n'
reply: '250-mx.google.com at your service, [67.248.53.114]\r\n'
reply: '250-SIZE 35882577\r\n'
reply: '250-8BITMIME\r\n'
reply: '250-STARTTLS\r\n'
reply: '250 ENHANCEDSTATUSCODES\r\n'
reply: retcode (250); Msg: mx.google.com at your service, [67.248.53.114]
SIZE 35882577
8BITMIME
STARTTLS
ENHANCEDSTATUSCODES
send: 'STARTTLS\r\n'
reply: '220 2.0.0 Ready to start TLS\r\n'
reply: retcode (220); Msg: 2.0.0 Ready to start TLS
send: 'ehlo [0.0.0.0]\r\n'
reply: '250-mx.google.com at your service, [67.248.53.114]\r\n'
reply: '250-SIZE 35882577\r\n'
reply: '250-8BITMIME\r\n'
reply: '250-AUTH LOGIN PLAIN XOAUTH\r\n'
reply: '250 ENHANCEDSTATUSCODES\r\n'
reply: retcode (250); Msg: mx.google.com at your service, [67.248.53.114]
SIZE 35882577
8BITMIME
AUTH LOGIN PLAIN XOAUTH
ENHANCEDSTATUSCODES

reply: '235 2.7.0 Accepted\r\n'
reply: retcode (235); Msg: 2.7.0 Accepted
send: 'mail FROM:<emailpeep@whatever.com> size=878\r\n'
reply: '250 2.1.0 OK bo5sm543779qab.1\r\n'
reply: retcode (250); Msg: 2.1.0 OK bo5sm543779qab.1
send: 'rcpt TO:<emailpeep@whatever.com>\r\n'
reply: '250 2.1.5 OK bo5sm543779qab.1\r\n'
reply: retcode (250); Msg: 2.1.5 OK bo5sm543779qab.1
send: 'data\r\n'
reply: '354  Go ahead bo5sm543779qab.1\r\n'
reply: retcode (354); Msg: Go ahead bo5sm543779qab.1
data: (354, 'Go ahead bo5sm543779qab.1')
send: 'Content-Type: multipart/mixed; boundary="===============0988883067=="\r\nMIME-Version: 1.0\r\nFrom: Some Guy <emailpeep@whatever.com>\r\nTo: emailpeep@whatever.com\r\nSubject: This is for sexy email su
bjektz!\r\nReply-To: Some Guy <emailpeep@whatever.com>\r\n\r\nThis is a multi-part message in MIME format.\r\n\r\n--===============0988883067==\r\nContent-Type: multipart/alternative; boundary="===============13
70445963=="\r\nMIME-Version: 1.0\r\n\r\n--===============1370445963==\r\nContent-Type: text/plain; charset="us-ascii"\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: 7bit\r\n\r\nThis is my message body in HTML\r
\n\t\t\t\tYup. Yup. Yup.\r\n\t\t\t\tDone!\r\n--===============1370445963==\r\nContent-Type: text/html; charset="us-ascii"\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: 7bit\r\n\r\nThis is my message body in HT
ML<br/>\r\n\t\t\t\tYup. Yup. Yup.</br>\r\n\t\t\t\t<b>Done!</a>\r\n--===============1370445963==--\r\n--===============0988883067==--\r\n.\r\n'
reply: '250 2.0.0 OK 1343338799 bo5sm543779qab.1\r\n'
reply: retcode (250); Msg: 2.0.0 OK 1343338799 bo5sm543779qab.1
data: (250, '2.0.0 OK 1343338799 bo5sm543779qab.1')
send: 'quit\r\n'
reply: '221 2.0.0 closing connection bo5sm543779qab.1\r\n'
reply: retcode (221); Msg: 2.0.0 closing connection bo5sm543779qab.1
  • Sandeep

    How to make bcc work?

  • Drew Halverson

    How can I email a whole folder?