Python how to remove header when sending an email? - python

I am trying to remove the header section, currently the received email looks like this:
.
I don't want it to be displayed when the receiver gets the email, I am not sure how to hide it.
I tried to just delete it but received an error. That code is included but commented out below.
import donator
import csv
import os
import smtplib
from email.message import EmailMessage
from email.mime.text import MIMEText
def ReadEmailTemplate():
oFile = open('EmailTemplate.txt', 'r')
Subject = oFile.readline()
Body = oFile.read()
return [Subject, Body]
def ReadCSVFile():
with open('ExampleData.csv', 'r') as csv_file:
csv_reader = csv.reader(csv_file)
allDonators = []
for line in csv_reader:
Number = line[0]
Name = line[1]
Amount = line[2]
Date = line[3]
Mode = line[4]
Email = line[5]
allDonators.append(donator.Donator(Number, Name, Amount, Date, Mode, Email))
return allDonators
txt = ReadEmailTemplate()
Subject = txt[0]
Body = txt[1]
# READ VALUES FROM CSV FILE AND RUN THROUGH THEM
allDonators = ReadCSVFile()
# CREATE EMAIL WITH THOSE VALUES
for donator in allDonators:
print(f'Sending email to: {donator.Name} at {donator.Email}...')
msg = EmailMessage()
Body = MIMEText(
Body.replace('REPLACE_DATE', donator.Date).replace('DONATION_AMOUNT', donator.Amount).replace('DONATION_DATE',
donator.Date))
msg.set_content(Body)
msg['From'] = os.environ['PERS_EMAIL']
msg['To'] = donator.Email
msg['Subject'] = Subject.replace('CUSTOMER_NAME', donator.Name)
print(msg.get('Content-Type'))
print(msg.get('Content-Transfer-Encoding'))
print(msg.get('MIME-Version'))
#for hdr in ['Content-Type', 'Content-Transfer-Encoding', 'MIME-Version']:
# del msg[hdr]
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login(os.environ['PERS_EMAIL'], os.environ['PERS_EMAILPW'])
smtp.sendmail(os.environ['PERS_EMAIL'], donator.Email, msg.as_string())
smtplib.SMTP_SSL('smtp.gmail.com', 465).quit()

In ReadEmailTemplate, you have Subject = oFile.readline(). file.readline() leaves the newline '\n' in the line. So, your subject line is followed by a blank line, which terminates the headers, and the rest of the headers are seen as message. Just do
Subject = oFile.readline().strip()
Note that you don't have to split out the fields of your CSV:
for line in csv_reader:
allDonators.append(donator.Donator(*line))

Related

Why CSV data rows are coming through as individual text files and not in body

I am trying to get the data from a CSV file and send that in an email using mimecast. Currently I am getting the headers from the file into the body but cant get the rows to come through. For some reason they are being placed in text files individually. Here is my stuff:
lines_to_send = []
with open(file, mode='r') as file:
# reading the CSV file
csvFile = csv.reader(file)
# displaying the contents of the CSV file
for line in csvFile:
lines_to_send.append(line)
This is what I use to get the rows from the CSV file
usernameEmail = '...'
passwordEmail = '...'
toEmails = ['...']
def send_mail(toaddrs_list, msg_lines, fromaddr, subject="Title"):
s = smtplib.SMTP('...')
s.starttls()
s.set_debuglevel(1)
s.login(usernameEmail, passwordEmail)
msg = MIMEMultipart()
sender = fromaddr
recipients = toaddrs_list
msg['Subject'] = subject
if fromaddr is not None:
msg['From'] = sender
msg['To'] = ", ".join(recipients)
for mime_text in build_message(msg_lines):
msg.attach(mime_text)
s.sendmail(sender, recipients, msg.as_string())
def build_message(lines):
return [MIMEText('[\'' + '\', \''.join(line) + '\']\n') for line in lines]
send_mail(toEmails, lines_to_send, usernameEmail)
This is what I have to send the email. I have also included a photo of the email that I have currently.
Email Screenshot
I have tried a lot. Any thoughts?

Send gmail with multiple recipients

I am trying to create a bulk email sender. I am struggling to add multiple recipients. I want the script to open contacts.csv that contains multiple email addresses, and send the email to them.
Simply, I need help creating a script that opens the csv file, reads the emails and sends the email to those addresses.
I have tried this but it did not work:
with smtplib.SMTP("smtp.gmail.com:587") as server:
with open("contacts.csv") as file:
reader = csv.reader(file)
next(reader) # Skip header row
for name, email in reader:
server.sendmail(
sender_email,
email,text
#message.format(name=name),
)
my contacts.csv file:
name, email
john, test1#gmail.com
jake, test2#gmail.com
my emailsender.py file:
import smtplib
from email import encoders
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
fromaddr = "myemail#gmail.com"
toaddr = "emails#gmail.com"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "test"
body = "testing"
msg.attach(MIMEText(body, 'plain'))
s = smtplib.SMTP('smtp.gmail.com', 587)
s.starttls()
s.login(fromaddr, "password")
text = msg.as_string()
s.sendmail(fromaddr, toaddr, text)
print("Email sent!")
s.quit()
send()
I have tested this code and it works fine:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import csv
emails = []
with open('test.csv', 'r') as file: #open csv file
reader = csv.reader(file) #init the csv reader
for row in reader: #iterate through all rows in the csv file
emails.append(row[1]) #add the second element of every row (the email column) to the list "emails"
emails.pop(0) #remove the first email which is just the text "email" in the csv file that we don't want
print(emails) #remove if you wish
def sender(recipients, from_email, password, body, subj): #create a sender function. partially adapted from https://stackoverflow.com/a/51931160/8402369
msg = MIMEMultipart()
msg['Subject'] = subj
msg['From'] = from_email
msg['To'] = (', ').join(recipients)
msg.attach(MIMEText(body,'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(from_email, password)
server.send_message(msg)
server.quit()
sender(emails, 'youremail#gmail.com', 'your_password', 'Message body', 'Subject') #send all emails
Run and edit the code online
EDIT:
Here's a version with the ability to change the email content based on the csv data:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import csv
csvdata = []
with open('test.csv', 'r') as file: #open csv file
reader = csv.reader(file) #init the csv reader
for row in reader: #iterate through all rows in the csv file
csvdata.append(
row #instead of adding the email to the array, add the whole row to the array
) #add the second element of every row (the email column) to the list "emails"
csvdata.pop(0)
def sender(
recipient, name_to_display, from_email, password, body, subj
): #create a sender function. partially adapted from https://stackoverflow.com/a/51931160/8402369
msg = MIMEMultipart()
msg['Subject'] = subj
msg['From'] = f'{name_to_display} <{from_email}>'
msg['To'] = recipient
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(from_email, password)
server.send_message(msg)
server.quit()
your_email = "email#gmail.com"
your_password = "password"
name_to_display = "The name of the sender that displays in the inbox (your name or whatever you want)"
for item in csvdata:
name = item[0] #the first column of the csv file is the name
email = item[1] #the second is the email. if you have more columns get them here like so: item[2] (change the index accordingly)
print(f'Sending email to {email}')
body = "Hi " + name + ", The rest of the content goes here"
subject = "Subject"
sender(email, name_to_display, your_email, your_password, body, subject)
Run and edit this code online
Notes:
The sender function is partially adapted from here

TypeError: sequence item 0: expected str instance, tuple found

I wrote a program to send emails but keep getting this error.
The code is:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
MY_ADDRESS = input('your email: ')
PASSWORD = input('your password: ')
emailadd = input('text file email addresses: ')
subject = input('text file containing subject ')
body = input('text file containing body: ')
def getcontacts(filename):
emails = []
with open(filename, mode='r', encoding='utf-8') as contacts_file:
for a_contact in contacts_file:
emails.append(a_contact)
return emails
def readtemplate(filename):
with open(filename, 'r', encoding='utf-8') as template_file:
return template_file.read()
def main():
global contents, msg
emails = getcontacts(emailadd)
message_template = readtemplate(body)
s = smtplib.SMTP(host='smtp.gmail.com', port=587)
s.starttls()
s.login(MY_ADDRESS, PASSWORD)
for email in zip(emails):
msg = MIMEMultipart()
f = open(subject, 'r')
if f.mode == 'r':
contents = f.read()
f.close()
msg['From'] = MY_ADDRESS
msg['To'] = email
msg['Subject'] = contents
msg.attach(MIMEText(message_template, 'plain'))
s.send_message(msg)
del msg
s.quit()
if __name__ == '__main__':
main()
It shows no errors but when I run it I get this:
TypeError: sequence item 0: expected str instance, tuple found
By the definition of your getcontacts function the list of emails is a list of strings. When you do for email in zip(emails), the zip puts every email-string in a 1-tuple. For example:
>>> x = ['foo', 'bar'] # these are your email addresses
>>> list(zip(x))
[('foo',), ('bar',)]
So you attempt to set the addressee to a tuple which doesn't make sense. Actually you can just leave out the zip and just do:
for email in emails:
...

Sending an email with python using csv data for the body

I am using the csv library to pull data to into an email body. I am pulling certain columns from the csv for the body. I am using a junk gmail account to test. I'm just confused on how to use the for loop. If I'm correct, you need a for loop to read the rows then a for loop to email out. I did read Reading and Writing CSV Files but was uncertain how to implement it with smtplib.
import csv, smtplib, ssl
message = """Subject: Your Title
{supervisor} {title} {start}"""
from_address = "test#gmail.com"
password = input("Type your password and press enter: ")
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
server.login(from_address, password)
with open('test.csv','rb') as file:
reader = csv.reader(file, delimiter=',')
next(reader)
#start = []
#title = []
#supervisor = []
for row in reader:
title = row[3]
start = row[0]
supervisor = row[4]
for supervisor, title, start in reader:
server.sendmail(
from_address,
Email,
message.format(supervisor=supervisor, start=start, title=title)
)
print('Emails were sent successfully!')
CSV File:
StartDate,Employee Name,PC,Title,Supervisor Name,email
12/9/2019,Katti M. Ricke,289,Recruiter,Courtney Clark,test#gmail.com
Probably if you use pandas for to handle the csv could be more easy ..for install pandas just pip install pandas
import pandas as pd
import io
import smtplib, ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# read csv using pandas and then convert the csv to html string ....this code later will add into body
str_io = io.StringIO()
df = pd.read_csv('test.csv')
df.to_html(buf=str_io)
table_html = str_io.getvalue()
print(table_html)
sender_email = "mymail#gmail.com"
receiver_email = "anothermail#gmail.com"
password = "mypass"
message = MIMEMultipart("alternative")
message["Subject"] = "Subject: Your Title"
message["From"] = sender_email
message["To"] = receiver_email
text = """\
Subject: Your Title"""
html = """\
<html>
<body>
<p>{table_html}</p>
</body>
</html>
""".format(table_html=table_html)
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
message.attach(part1)
message.attach(part2)
# Send email
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
server.login(sender_email, password)
server.sendmail(
sender_email, receiver_email, message.as_string()
)

Sending a mass-email with Python using data from several .txt files

I am currently writing a small program to ease my workload sending a couple hundred of emails daily. I have edited code I found somewhere and came up with this so far:
import smtplib
from email.mime.text import MIMEText
from time import sleep
from random import choice
import re
import io
user_email = input('Enter your E-mail: ')
user_password = input('Enter your Password: ')
try:
s = smtplib.SMTP_SSL('smtp.gmail.com', 587)
# re-identify ourselves as an encrypted connection
s.ehlo()
# If using TLS, uncomment the line below.
#s.starttls()
s.login(user_email, user_password)
s.set_debuglevel(1)
except IOError:
print (IOError)
SUBJECT = open('1subject.txt', 'r')
variation0 = [SUBJECT.read(), SUBJECT.read(), SUBJECT.read()]
SUBJECT.close()
GREETING = open('2greeting.txt', 'r')
variation1 = [GREETING.read(), GREETING.read(), GREETING.read()]
GREETING.close()
BODY = open('3body.txt', 'r')
variation2 = [BODY.read(), BODY.read(), BODY.read()]
BODY.close()
OUTRO = open('4outro.txt', 'r')
variation3 = [OUTRO.read(), OUTRO.read(), OUTRO.read()]
OUTRO.close()
# Where the {}'s are, is where a variation(0-3) will be substituted in.
template = """Insert your {}
Multiline email body
HERE {} {}
-transposed messenger
"""
sender = 'sender#email.com'
recipients = []
names = []
mailTxt = open("listOfRecipients.txt", 'r')
for line in mailTxt:
line = line.replace('\n',"")
names.append(re.split(':', line)[0])
recipients.append(re.split(':',line)[1])
for k in range(len(recipients)):
msg = MIMEText(template.format(choice(variation1), names[k]+",", recipients[k], choice(variation2), choice(variation3)))
msg['Subject'] = choice(variation0)
msg['From'] = sender
msg['To'] = recipients[k]
print ("Sending...")
print (msg)
try:
s = smtplib.SMTP_SSL('smtp.gmail.com', 587)
s.sendmail(sender, recipients[k], msg.as_string())
except Exception as e:
str(e)
print ((e, "error: logging in and cont with nxt address..."))
s = smtplib.SMTP_SSL('smtp.gmail.com', 587)
s.ehlo()
s.login(user_email, user_password)
s.set_debuglevel(1)
continue
with io.open('log.txt', 'a', encoding='utf-8') as f:
try:
f.write(unicode(msg))
except:
f.write("Error handling ASCII encoded names: "+ Unicode
(recipients[k]))
print ("Messages have been sent.")
f.close()
s.quit()
This is the first time I'm adding code on here so I don't know if I've done that right. However whatever I do I keep receiving errors.
The files that are being opened are files containing email addresses and names (like mail#email.com:mailman Johnson and then a new line continuing like this)
the other files are containing text for the email that is sent.
my ridiculous question is: how do I get this to work? What am I doing wrong.
My current error is
ssl.SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:847)
Again, my apologies if this isn't a real question!

Categories