AttributeError: 'list' object has no attribute 'encode' when sending an email

Viewed 3526

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 Answers

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)

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()
Related