6

I'm using information found on this post Sending Email Using Python

So far the instructions were perfect. I have two additional things I'd like to do:

  1. Call a variable inside the body
  2. Add an attachment

The variable would be todays date. This is it:

today = datetime.datetime.today ()
tday = today.strftime ("%m-%d-%Y")

I know that with mailx, you can attach with the -a option.

Community
  • 1
  • 1
DDI Guy
  • 105
  • 1
  • 1
  • 9

3 Answers3

13

To call the variables inside the html body ,just convert them to string to concatenate them in the body

from datetime import datetime
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

today = datetime.today ()
tday = today.strftime ("%m-%d-%Y")

# email subject, from , to will be defined here
msg = MIMEMultipart()

html = """\
<html>
  <head></head>
  <body>
    <p>Hi!<br>
       How are you?<br>
       """ +str(today)+ """ and """ +str(tday)+ """
    </p>
  </body>
</html>
"""
msg.attach(MIMEText(html, 'html'))

For attachments please look at http://naelshiab.com/tutorial-send-email-python/

EDIT : The link provided above seems not available, so the code snippet for sending attachments via email (specifically from gmail) is below

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

msg = MIMEMultipart()

msg['From'] = "from email address"
msg['To'] = "to email address" 
msg['Subject'] = "Subject line" 
body = """Body 
          content"""

msg.attach(MIMEText(body, 'plain'))
attachment = open("/path/to/file", "rb") 
p = MIMEBase('application', 'octet-stream') 

# To change the payload into encoded form 
p.set_payload((attachment).read()) 

# encode into base64 
encoders.encode_base64(p) 

p.add_header('Content-Disposition', "attachment; filename= %s" % filename) 

# attach the instance 'p' to instance 'msg' 
msg.attach(p) 

s = smtplib.SMTP('smtp.gmail.com', 587) 
s.starttls() # for security
s.login("from email address", "your password") 

text = msg.as_string() 

# sending the mail 
s.sendmail("from email address", "to email address" , text)
s.quit() 

Note : Google will some times block logins from other application (less secure apps) so there is a need to allow this access in your Google account settings https://myaccount.google.com/u/1/lesssecureapps?pli=1&pageId=none

Naveen
  • 485
  • 1
  • 5
  • 14
  • 3
    This is only sound advice if the values are trusted. If they include, say, ` – Charles Duffy Jan 25 '17 at 18:02
  • is it possible to read HTML from *.html template to the Python script with variables automatically being placed in the code? – cincin21 Jun 25 '21 at 07:11
  • Is it possible to use fstrings inside the HTML snippet that you have shared above in the code? – Rohit Venkat Gandhi Mendadhala Sep 02 '21 at 21:58
0

For your first question: There are lots of ways to create strings that make use of variables.

Some ways are:

body = "blablabla " + tday + " bloo bloo bloo"
body = "Today's date is {}, in case you wondered".format(tday)

For your second question you'd have to tell us which library / module you're using, and then you could go to that module's documentation page and see if there's something for adding an attachment.

cadolphs
  • 9,014
  • 1
  • 24
  • 41
  • The best-practice approach here from a security-perspective will be a formatting-aware toolset that can prevent injection attacks (in this context, a category wherein content that is *expected* to be providing literal text for rendering to the user instead acts as an instruction to the browser). – Charles Duffy Jan 25 '17 at 18:03
  • Oh yeah that's totally true. In this case OP's question didn't mention user-input from a form, so I didn't think about it. Basically, if you have control over the string and what goes in (e.g. a specifically formatted date string), you don't *really* have to worry about injection, right? – cadolphs Jan 25 '17 at 18:05
  • Yup. Thing is, an answer to a question as "how do I use a variable inside HTML email?" is likely to be applied in a wider range of scenarios than just the one contrived example given in the question. – Charles Duffy Jan 25 '17 at 18:07
  • To send to multiple recipients, I used the info from http://stackoverflow.com/questions/8856117/how-to-send-email-to-multiple-recipients-using-python-smtplib#12422921 – DDI Guy Jan 25 '17 at 18:43
0

Thanks to everyone for posting tips.

For posterity, this is the working script.

The only remaining item is that I need to be able to send the same email to multiple people.

I've tried to add all of the email addresses to the variable with commas between, but they're not getting it. When I look at my email received, they appear to be in the To line. Is it possible that it's only sending to the first email address listed?

#!/usr/bin/python
import smtplib
import time
import datetime
from datetime import date
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email import encoders

fromaddr = "NOREPLY@test.com"
toaddr = ['me@test.com', 'thatguy@test.com']

#   Date
today = datetime.datetime.today ()
tday = today.strftime ("%m-%d-%Y")

msg = MIMEMultipart()

msg['From'] = fromaddr
msg['To'] = ", ".join(toaddr)
msg['Subject'] = "My Subject Goes Here"

body = """\
<html>
  <head></head>
  <body>
<p>DO NOT REPLY TO THIS EMAIL!!<br>
<br>
Script run for data as of """ + tday + """.<br>
<br>
See attachment for items to discuss<br>
<br>
The files have also been uploaded to <a href="http://testing.com/getit">SharePoint</a><br>
<br>
If you have any issues, email admin@test.com<br>
<br>
    </p>
  </body>
</html>
"""

msg.attach(MIMEText(body, 'html'))

filename = "discuss.csv"
attachment = open("discuss.csv", "rb")

part = MIMEBase('application', 'octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment; filename= %s" % filename)

msg.attach(part)

server = smtplib.SMTP('localhost')
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()
DDI Guy
  • 105
  • 1
  • 1
  • 9