ryrob.es

archive / 2009–2013

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

PythonCut-n-Paste CodePythonsmtpgoogle appstlsattachmentmime encodingcliff clavencheers

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!

[cc lang="python"] 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 ' #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
Yup. Yup. Yup. Done!""" #ok, here goes nothing try: msgtext = htmlmsgtext.replace('','').replace('**','').replace('
',"\r").replace('',"\r").replace('
',"\r").replace('','') 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 [/cc]

Sample Output

[cc] 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: 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:\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 \r\nTo: emailpeep@whatever.com\r\nSubject: This is for sexy email su bjektz!\r\nReply-To: Some Guy \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
\r\n\t\t\t\tYup. Yup. Yup.\r\n\t\t\t\t**Done!\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 [/cc]****