5

I want to have this code where I can have a csv file with a row of names next to a row of emails and then email every email on the list but have every name in the message. Here is my code:

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


def nobrackets(current):
    return str(current).replace('[','').replace(']','')
def noastrick(current):
    return str(current).replace('\'','').replace('\'','')

email = 'xxxxxxxxxx'
password = 'xxxxxxxx'
send_to_email = []
subject = 'Whats up doc' # The subject line
message = ()
names = []
msg = MIMEMultipart()

msg['Subject'] = 'Whats up doc'

 # Attach the message to the MIMEMultipart object


server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
with open('Emails.csv','r') as csv_file:
    csv_reader=csv.reader(csv_file)
    for line in csv_reader:
        names.append(line[0])
        names_var = names
        send_to_email.append(line[1])
        send_to_email_var = send_to_email
        
        message = (f"Hey {noastrick(nobrackets(names_var))} how has your day been?")
        msg.attach(MIMEText(message, 'plain'))
        msg['From'] = 'xxxxxxxxx'

        msg['To'] = send_to_email_var

        server.login(email, password)
        text = msg.as_string() # You now need to convert the MIMEMultipart object to a string to send
        server.sendmail(email, send_to_email_var, text)
        names.clear()
        message = ()
        send_to_email = []
server.quit()

The error I get is File/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/email/_policybase.py", line 369, in _fold parts.append(h.encode(linesep=self.linesep, maxlinelen=maxlinelen))

AttributeError: 'list' object has no attribute 'encode'

The reason I change the lists into variables is because I thought that might fix the error I got. I am somewhat new to python, and I realized the error is in a file called _policybase.py and it might be like built into the python application I installed on my computer, but I don't know how to edit that file, or fix that error.

2
  • 1
    The nobrackets and noastrick functions look suspiciously like you don't understand the difference between the contents of a string and its repr() which Python's REPL uses to show an unambiguous human-readable version of a value. If you see ['hello', 'world'] that represents a list of the strings hello and world. The strings themselves don't actually contain any single quotes (not asterisks, by the way, and certainly not "astricks") or square brackets; those are purely presentation aids. Commented Jul 23, 2020 at 7:11
  • 1
    And needless to say, there are absolutely no situations where editing the files in Python's standard library makes any sense whatsoever for a beginner. Commented Jul 23, 2020 at 7:12

2 Answers 2

12

This answer by @snakecharmerb is mostly correct:

The problem is that the code is setting msg['to'] to a list instead of a string. smtplib.server.sendmail will accept a list of strings as its toaddrs argument, but an email message does not (if multiple to addresses are required, call msg['to'] = address once for each address).

However, you don't need to send the mail to each recipient individually via a for-loop. Instead just assign the list as comma-separated string to msg["To"] like this:

msg["To"] = ", ".join(send_to_email_var)
Sign up to request clarification or add additional context in comments.

1 Comment

@randomperson it would be great if you could mark the answer which helped you as the correct answer. :)
3

The problem is that the code is setting msg['to'] to a list instead of a string. smtplib.server.sendmail will accept a list of strings as its toaddrs argument, but an email message does not (if multiple to addresses are required, call msg['to'] = address once for each address).

Also, it isn't necessary to stringify the message to send it: instead, use smtplib.server.send_message

This code ought to work:

with open('Emails.csv','r') as csv_file:
    csv_reader=csv.reader(csv_file)
    for line in csv_reader:
        names_var = line[0]
        send_to_email_var = line[1]

        msg = MIMEMultipart()
        msg['Subject'] = 'Whats up doc'
        message = (f"Hey {noastrick(nobrackets(names_var))} how has your day been?")
        msg.attach(MIMEText(message, 'plain'))
        msg['From'] = 'xxxxxxxxx'

        msg['To'] = send_to_email_var

        server.login(email, password)
        server.send_message(msg, email, send_to_email_var)
server.quit()

2 Comments

That fixed the error so thanks, man. The only problem is that it is sending to multiple people at the same time. I had a csv with three names and emails that I was testing it with, and it was sent to all 3 emails(as a group email), and the message inside was the message 3 times with the 3 different names.
I've amended the answer to show the message object being initialised inside the for loop, so we get a new message object for each iteration.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.