I am writing an automation Python Script. My intention is to email multiple unique attachments to multiple unique recipients. For example l have 1000 unique statements that must be emailed to 1000 unique clients. I want my Python script to be able to pick an attachment automatically and send it to the right recipient!
I have created the script and that creates the pdf attachments and name them after each email address of recipients so that l can use the names to pick the attachment and match that with the email of the recipient. It Picks attachment perfectly BUT the problems it keeps incrementing attachment to users in each iteration..
#1.READING FILE NAMES WHICH ARE EMAIL ADDRESS FOR RECEPIENTS
import os, fnmatch
filePath = "C:/Users/DAdmin/Pictures/"
def readFiles(path):
fileNames =fnmatch.filter(os.listdir(path), '*.pdf')
i=0
pdfFilesNamesOnly=[]
while i < len(fileNames):
s =fileNames[i]
removeThePdfExtension= s[0:-4]
pdfFilesNamesOnly.append(removeThePdfExtension)
i+=1
return pdfFilesNamesOnly
-----------------------------------------------------------
#2.SENDING AN EMAIL WITH UNIQUE ATTACHMENT TO MULTIPLE UNIQUE RECEPIENTS
import smtplib
import mimetypes
from optparse import OptionParser
from email.mime.multipart import MIMEMultipart
from email import encoders
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.application import MIMEApplication
import os,fnmatch
from readFileNames import readFiles
filePath = "C:/Users/DAdmin/Pictures/"
listOfEmails= readFiles(filePath)# Files are named after emails
def sendEmails(listOfFiNames): #sends the email
email = 'goddietshe@gmail.com' # Your email
password = '#####' # Your email account password
send_to_list = listOfEmails# From the file names
#creating a multipart object
subject ="MONTHLY STATEMENTS"
mg = MIMEMultipart('alternative')
mg['From'] = email
mg['To'] = ",".join(send_to_list)
mg['Subject'] = subject
mg.attach(MIMEText("Please receive your monthly statement",'plain'))
# Attaching a file now before emailing. (Where l have a problem)
for i in listOfEmails:
if i in send_to_list:
newFile = (i+'.pdf') # create the name of the attachment to email using the name(which is the email) and will be used to pick the attachment
with open(newFile,'rb') as attachment:
part = MIMEBase('application','x- pdf')
part.set_payload(attachment.read())
attachment.close()
encoders.encode_base64(part)
part.add_header('Content- Disposition','attachment; filename="%s"' % newFile )
mg.attach(part)
text =mg.as_string() # converting the message obj to a string/text obj
server = smtplib.SMTP('smtp.gmail.com', 587) # Connect to the server
server.starttls() # Use TLS
server.login(email, password) # Login to the email server
# this is where it is emailing stuff
server.sendmail(email, i , text) # Send the email
server.quit() # Logout of the email server
print("The mail was sent")
#print("Failed ")
sendEmails(listOfFiNames)
I expect it to email each unique attachment to each unique recipient who are 1000 automatically
You reuse mg
(message), using only attach
, so your attachments pile up. You need to substitute the whole previous content with new content using set_payload
because there is no "remove" method.
In doing this, you have to remember to re-add the text which you set before the loop:
mg.attach(MIMEText("Please receive your monthly statement",'plain'))
for i in listOfEmails:
because by using set_payload
you lose all previous parts you attached. I'd just save this as a variable and then add it in the loop.
Moreover:
mg['To'] = ",".join(send_to_list)
This line makes all messages send to all people. You need to move this part to the loop as well, setting only one email address at once.
EDIT Applying those changes:
def sendEmails(): #sends the email
email = 'goddietshe@gmail.com' # Your email
password = '#####' # Your email account password
#creating a multipart object
subject ="MONTHLY STATEMENTS"
mg = MIMEMultipart('alternative')
mg['From'] = email
# mg['To'] = ",".join(listOfEmails) # NO!
mg['Subject'] = subject
text_content = MIMEText("Please receive your monthly statement",'plain')) #safe it for later, rather than attach it - we'll have to re-attach it every loop run
for i in listOfEmails:
if i in send_to_list:
newFile = (i+'.pdf') # create the name of the attachment to email using the name(which is the email) and will be used to pick the attachment
with open(newFile,'rb') as attachment:
part = MIMEBase('application','x- pdf')
part.set_payload(attachment.read())
attachment.close()
encoders.encode_base64(part)
part.add_header('Content- Disposition','attachment; filename="%s"' % newFile )
mg.set_payload(text_content) #change the whole content into text only (==remove previous attachment)
mg.attach(part) #keep this - new attachment
mg["To"] = i # send the email to the current recipient only!
text =mg.as_string() # converting the message obj to a string/text obj
server = smtplib.SMTP('smtp.gmail.com', 587) # Connect to the server
server.starttls() # Use TLS
server.login(email, password) # Login to the email server
# this is where it is emailing stuff
server.sendmail(email, i , text) # Send the email
server.quit() # Logout of the email server
print("The mail was sent")
**Works very fine like this. Thanks @h4z3**
def sendEmail():
email = 'goddietshetu@gmail.com' # Your email
password = '####' # Your email account password
subject ="MONTHLY STATEMENTS"
#creating a multipart object
mg = MIMEMultipart('alternative')
mg['From'] = email
mg['Subject'] = subject
# attaching a file now
listOfEmails = readFileNames(filePath)
for i in listOfEmails:
attachment =open(i+'.pdf','rb')
part = MIMEBase('application','octet-stream')
part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition',f"attachment; filename= {i}.pdf")
mg.set_payload(mg.attach(MIMEText("",'plain')))
mg.attach(MIMEText("Please receive your monthly statement",'plain'))
mg.attach(part)
mg['To'] = i
text =mg.as_string() # converting the message obj to a string/text obj
server = smtplib.SMTP('smtp.gmail.com', 587) # Connect to the server
server.starttls() # Use TLS
server.login(email, password) # Login to the email server
server.sendmail(email, i , text) # Send the email
server.quit() # Logout of the email serv
print("The mail was sent")
sendEmail()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.