i have an output.txt which i want to send its content as an email body.
1.i want to remove specific lines from the content ( not delete from the file itself)
2.i want to be able to convert it to html and to desing some of specific lines size and maybe even color.
i have a working script which sends the mail.
there are some problems:
im not able to remove specific line when using file.read().
when trying readlines() the type is list and the email body is getting messed up.(join doesnt work on list with bytes type)
import smtplib
import email.message
def send_email(subject, msg):
try:
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.ehlo()
ID = 'XXXX'
PASSWORD = 'XXXXXXX'
email_reciever = 'XXXXXX'
server.login(ID, PASSWORD)
message = 'Subject:{} \n\n {}'.format(subject, msg)
server.sendmail(ID, email_reciever, message)
print('Succes')
except Exception as e:
# Print any error messages to stdout
print(e)
finally:
server.quit()
filename = r".\Reports\Report.txt"
with open(filename, "rb") as filename:
text = filename.read()
msg = email.message.Message()
msg.add_header('Content-Type', 'text/plain')
msg.set_payload(text)
subject = "Report"
send_email(subject, msg)
Related
I want to write a function to attach a csv file to an E-Mail with HTML text. Everything works fine. I sends the E-Mail with the text and the attachment with the right information. Only the data format is wrong. I tried different varieties in MIMEBASE('application', 'octet-stream'). This one gives me a '.bin' data which I cannot open on macOS. Others gave me a plain text data which included the right data, but I don't wanna copy it manually into a csv. Does someone have a solution how I get out the data as '.csv'? Most of the solutions I found here just looked like my code below.
Code:
def send_mail(receiver, subject, filepath, attachname):
#login information
port = 123
smtp_server = "test.server.com"
login = "testlogin" # your login
password = "12345678910" # your password
# specify the sender’s and receiver’s email addresses and text in HTML
sender = "testmail#test.com"
receiver = receiver
message = MIMEMultipart()
message["Subject"] = subject
message["From"] = sender
message["To"] = COMMASPACE.join([receiver])
html_text = """\
<html>
<body>
<p>Hi ,<br>
<p>kind regards</p>
<p> This is an automatized Mail </p>
</body>
</html>
"""
# convert both parts to MIMEText objects and add them to the MIMEMultipart message
text = MIMEText(html_text, "html")
message.attach(text)
#add a file as attachment
file = open(filepath, "rb")
att = MIMEBase('application', 'octet-stream')
att.set_payload(file.read())
encoders.encode_base64(att)
att.add_header("Content_Disposition",
'attachment', filename = attachname)
message.attach(att)
try:
#send your message with credentials specified above
with smtplib.SMTP(smtp_server, port) as server:
server.connect(smtp_server, port)
server.ehlo()
server.starttls()
server.ehlo()
server.login(login, password)
server.sendmail(sender, receiver, message.as_string())
# tell the script to report if your message was sent or which errors need to be fixed
print('Sent')
except (gaierror, ConnectionRefusedError):
print('Failed to connect to the server. Bad connection settings?')
except smtplib.SMTPServerDisconnected:
print('Failed to connect to the server. Wrong user/password?')
except smtplib.SMTPException as e:
print('SMTP error occurred: ' + str(e))
send_mail('testmail#test.com', 'TEST', '/Users/Changer/Desktop/test.csv', 'test.csv')
Email clients may use the content type of the attachment part to determine which program is used to open the attachment, so specifying a suitable content type may help.
This code uses the standard library's mimetypes module to try to guess the correct content type of the attachment, based on its name:
import mimetypes
mimetypes.init()
def send_mail(receiver, subject, filepath, attachname):
...
mimetype, _ = mimetypes.guess_type(attachname)
if mimetype is None:
mimetype = 'application/octet-stream'
type_, _, subtype = mimetype.partition('/')
att = MIMEBase(type_, subtype)
...
The above code will generate these headers for the attachment:
b'Content-Type: text/x-comma-separated-values'
b'MIME-Version: 1.0'
b'Content-Transfer-Encoding: base64'
b'Content_Disposition: attachment; filename="test.csv"'
Whether a mac will open a csv with a spreadsheet application (I assume this is what you want) depends on the configuration of the machine (See this blog for an example). If you want to be sure open the file in a spreadsheet it might be more effective to convert it to a spreadsheet format and send the spreadsheet.
import smtplib
import os
import time
def send_email(contacts):
try:
user= passw=""
with open("credentials.txt", "r") as f:
file = f.readlines()
user = file[0].strip()
passw = file[1].strip()
server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls() # it is necessary to start this before login
server.login(user, passw) # login credentials
subject = "Assignment Task for Working student job"
msg = "This is a msg body of assignment. "
message = 'Subject: {}\n\n{}'.format(subject, msg)
for i in contacts:
server.sendmail(user, contacts, message)
print(f"successfully sent email to {i} and wait for 10 seconds" )
time.sleep(10)
server.quit()
print("Success: Email sent!")
except:
print("Email failed to send.")
if __name__ == "__main__":
#sender, password = read_creds()
contacts = ['editorawais#gmail.com', 'editorawais#yahoo.com', 'editorawais#live.com','techwpblog#gmail.com']
send_email(contacts)
I created this email script. But now i am getting error on login. My credentials.txt is just of two lines.
"Email address"
"Password"
Please can anybody help me where i am missing something. And the correct way possibly. Thanks
Lose the quotation marks if you indeed have those in the txt file. Python will try to plug in everything on the first and second line including the "" try just doing this in your .txt file.
email
password
I'm trying to send an email from anoutlook account, reading contact from file.
When test without proxy no problem, but with company´s proxy i get this -->
"SMTPServerDisconnected("Connection unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly closed"
im using smtplib and socks for proxy settings.
here the code:
import socks
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
MY_ADDRESS = 'email#outlook.com'
PASSWORD = 'pass'
def get_contacts(filename):
"""
Return two lists names, emails containing names and email addresses
read from a file specified by filename.
"""
names = []
emails = []
with open(filename, mode='r', encoding='utf-8') as contacts_file:
for a_contact in contacts_file:
names.append(a_contact.split()[0])
emails.append(a_contact.split()[1])
return names, emails
def read_template(filename):
"""
Returns a Template object comprising the contents of the
file specified by filename.
"""
with open(filename, 'r', encoding='utf-8') as template_file:
template_file_content = template_file.read()
return Template(template_file_content)
def main():
names, emails = get_contacts('mycontacts.txt') # read contacts
message_template = read_template('message.txt')
print ("enviando mensaje")
# set up the SMTP server
socks.setdefaultproxy(socks.HTTP, 'proxy', port, True,'username', 'password')
socks.wrapmodule(smtplib)
s = smtplib.SMTP(host='smtp.office365.com', port=587)
s.set_debuglevel(True)
s.starttls()
s.login(MY_ADDRESS, PASSWORD)
# For each contact, send the email:
for name, email in zip(names, emails):
msg = MIMEMultipart() # create a message
# add in the actual person name to the message template
message = message_template.substitute(PERSON_NAME=name.title())
# Prints out the message body for our sake
print(message)
# setup the parameters of the message
msg['From']=MY_ADDRESS
msg['To']=email
msg['Subject']="This is TEST"
# add in the message body
msg.attach(MIMEText(message, 'plain'))
# send the message via the server set up earlier.
s.send_message(msg)
del msg
# Terminate the SMTP session and close the connection
s.quit()
if __name__ == '__main__':
main()
any help?
solved:
i change the port of smtp connection from 587 to 25, and works!
In linux, provided that your http_proxy/https_proxy environment variable are set, you should be good to go. In windows, https://www.proxifier.com/ will allow you to send all traffic over the proxy properly.
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()
When I write the script below I get the error IndexError: list index out of range:
import smtplib
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
MY_ADDRESS = 'joaosoundcloudpython#gmail.com'
PASSWORD = 'XXXX'
def get_contacts(test1):
"""
Return two lists names, emails containing names and email addresses
read from a file specified by filename.
"""
names = []
emails = []
with open('/Users/joaopimenta/Documents/joaoPython/soundcloud_email.txt', mode='r', encoding='utf-8') as contacts_file:
for a_contact in contacts_file:
names.append(a_contact.split()[0])
emails.append(a_contact.split()[100])
return names, emails
def read_template():
"""
Returns a Template object comprising the contents of the
file specified by filename.
"""
with open(soundcloud_email_message.txt, 'r', encoding='utf-8') as template_file:
template_file_content = template_file.read()
return Template(template_file_content)
def main():
names, emails = get_contacts('/Users/joaopimenta/Documents/joaoPython/soundcloud_email.rtf') # read contacts
message_template = read_template('/Users/joaopimenta/Documents/joaoPython/soundcloud_email_message.txt')
# set up the SMTP server
s = smtplib.SMTP(host='smtp.gmail.com', port=587)
s.starttls()
s.login(joaosoundcloudpython#gmail.com, XXXX)
# For each contact, send the email:
for name, email in zip(names, emails):
msg = MIMEMultipart() # create a message
# add in the actual person name to the message template
message = message_template.substitute(PERSON_NAME=name.title())
# Prints out the message body for our sake
print(message)
# setup the parameters of the message
msg['From']=MY_ADDRESS
msg['To']=email
msg['Subject']="This is TEST"
# add in the message body
msg.attach(MIMEText(message, 'plain'))
# send the message via the server set up earlier.
s.send_message(msg)
del msg
# Terminate the SMTP session and close the connection
s.quit()
if __name__ == '__main__':
main()