My aim for this program is to send multiple e-mail addresses a message along with a PDF file attached to the e-mail. How would I do that? I have two Traceback calls(Shown after the code). So far the code works when there is no attachments being sent but as I try to send an attachment everything seems to fall apart. Thanks
EDIT: I believe I have to use these two lines of code somewhere.
message.attach(part)
text = message.as_string()
Although when I write them down it says Unresolved attribute reference 'attach' for class 'str'
from email.mime.base import MIMEBase
import pandas as pd
import smtplib, ssl
subject = "An email with attachment from Python"
sender_email = input("Enter your E-mail Address: ")
password = input("Enter your password: ")
email_list = pd.read_excel("D:\Learning Python\Mini_Projects\emailaddresses.xlsx", engine="openpyxl")
# Read Excel Spreadsheet
names = email_list['Name']
receiver_email = email_list['Email']
message = """Subject: Training Program! 💪
Hi {names}, I hope you received this e-mail with the attachment"""
filename = "TrainingProgram.pdf"
with open(filename, "rb") as attachment:
part = MIMEBase("application", "octet-stream")
part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header(
"Content-Disposition",
f"attachment; filename= {filename}",
)
context = ssl.create_default_context()
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls(context=context)
server.login(sender_email, password)
for i in range(len(receiver_email)):
name = names[i]
email = receiver_email[i]
server.sendmail(sender_email, receiver_email, message)
print("E-mails Sent!")
File "D:/Learning Python/Mini_Projects/main.py", line 117, in <module>
server.sendmail(sender_email, [email], message)
File "C:\Users\janss\AppData\Local\Programs\Python\Python38\lib\smtplib.py", line 859, in sendmail
msg = _fix_eols(msg).encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode character '\U0001f4aa' in position 27: ordinal not in range(128)
ASCII encoding does not support emojis. Remove the 💪
in the email body, and it should work. If you absolutely want to keep the emoji, you would have to use a MIMEText
object, see this question for an example.
EDIT:
Why aren't you using the name
and email
variables in the for loop ?
The current code sends an email to an adress being a list, I wonder why it's not erroring there ...
for i in range(len(receiver_email)):
name = names[i]
email = receiver_email[i]
server.sendmail(sender_email, receiver_email, message)
Maybe you meant your for loop like the following ?
for email in receiver_email:
server.sendmail(sender_email, email, message)
Additionally, your message will be sent as you coded it, instead of with the names filled in. For this, you need to put an f in front of the string. I think the message
should be like this:
message = f"""Subject: Training Program!
Hi {", ".join(names)}, I hope you received this e-mail with the attachment"""
EDIT2:
Unresolved attribute reference 'attach' for class 'str'
This is because str
has no method attach, only email.mime.multipart.MIMEMultipart
has. See this answer on how to correctly send attachments.