0

I`m trying to make a python code to send some newsletter to people have signed up to a list. my problem is with Header "To:" part! I can't put emails in a list as "To:" address, and when receivers open the email, they don't see their email address in "To:" header. And here is a screenshot of what I'm talking about: http://tinypic.com/r/zlr7sl/9

I`m not a programmer and am just trying to learn something new. My English is not perfect. I hope you understand me.

from smtplib import SMTP
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
host = 'smtp.server.com'
port = 587
usr  = 'USERNAME'
pwd  = 'PASSWORD'
from_email = 'SENDER)EMAIL'
my_list = open('slist.txt', 'r')
msg = MIMEMultipart('alternative')
msg['Subject'] = 'Subject'
msg['From'] = from_email
msg['To'] = '' # <<<<<I want to put emails in slist.txt in this header one by one while sending the emails.
msg.add_header('reply-to','reply-to')
plain_text = 'Testing Message'
html_text = '''\
>>> HTML CODE<<
'''
part1 = MIMEText(plain_text, 'plain')
part2 = MIMEText(html_text, 'html')
msg.attach(part1)
msg.attach(part2)
server = SMTP(host, port)
server.ehlo()
server.starttls()
server.login(usr, pwd)
try:
    for emails in my_list:
     server.sendmail(from_email, emails, msg.as_string())
    print('!!!YEAHH!!!')
except:
    print('***OPS***')
server.close()
  • I have tried msg['To'] = ' '.join(my_list). Using this options, I dont get any errors but Emails are not being sent – Mojtaba Ghanidel Jan 29 '19 at 00:42
  • What's in `slist.txt`? What's the value of `my_list`? `emails` should be a list of emails. – Peter Wood Jan 29 '19 at 00:46
  • This part of the code could solve my problem, Thanks, I found it on the link you shared. my_list = open('slist.txt', 'r').readlines() for rows in my_list: emails = rows.rstrip() to = emails msg['To'] = Header(to, 'utf-8') – Mojtaba Ghanidel Jan 29 '19 at 00:58

1 Answers1

0

It doesn't really matter what you put in the To: header as long as the envelope recipient is correctly communicated.

A common trick used by mailing lists is to put the mailing list itself in the To: header:

From: mailing-list@example.edu
To: mailing-list@example.edu
Bcc: actual@example.net, recipients@example.org,
 here@example.com, ...

If you pass this to sendmail -t you will get a bounce for the bogus To: address (or a mail loop, if the list ends up sending to itself, and then resending the incoming message to the entire list, etc) but sendmail accepts a list of recipients in a mode where the headers are completely ignored. You could do have this in a file email.txt:

From: me@example.org
To: fred@example.net
Subject: Secret stuff

xyzzy

Now if you do sendmail you@example.com <email.txt the message will be sent to you (only, and not to Fred).

Think of it as a sheet of paper inside an envelope. If the paper inside the envelope says "Santa Claus, North Pole" as the recipient, but you put it in an envelope addressed to "Mr. President, 1600 Pennsylvania Avenue" the message will go to the White House regardless of what it says on the paper inside the sealed envelope.

So in terms of Python code, you could do

msg['Subject'] = 'Subject'
msg['From'] = from_email
msg['To'] = 'noreply@example.org'
# ...
server = SMTP(host, port)
server.ehlo()
server.starttls()
server.login(usr, pwd)
try:
     server.sendmail(from_email, my_list, msg.as_string())

and the message will go to the recipients on my_list regardless of the value in the To: header.

On the other hand, if you want an individual message with an individual To: header to be sent for each recipient, you need to modify the To: header in the loop, too.

msg['Subject'] = 'Subject'
msg['From'] = from_email
msg['To'] = 'noreply@example.org'
# ...
server = SMTP(host, port)
server.ehlo()
server.starttls()
server.login(usr, pwd)
for user in my_list do:
    try:
         msg['To'] = user
         server.sendmail(from_email, [user], msg.as_string())
    except:
         raise HorrorError('Really, you want to raise an exception here')

However, you should understand that if you have multiple recipients in the same domain, their email server will be inundated with virtually identical messages which only differ by the To: header. You could get away with this, especially if the number of recipients in each domain is small, but it is definitely regarded as abusive by some mail administrators, and/or could trigger automated spam filters.

Tangentially, I put in a raise in the except: handler because you really really should not be using a blanket except handler. At the very least, you should capture the error and print out detailed information about what exactly failed; otherwise you are hiding a probably growing number of bugs from yourself.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Thanks for your help, Yes, your code works, but my problem is the To header. When the receiver opens the email, I want him to see his email address in the Header To: I don't want him to see an empty header to noreply@example.org. – Mojtaba Ghanidel Jan 29 '19 at 12:56
  • Then you have to loop over the message and modify the `To:` header for each recipient as well. This is hugely inefficient, though, as it forces one message per recipient. If the messages are otherwise identical, this is potentially going to be seen as abusive by administrators of domains which receive many identical messages. (If you use `Bcc:` to a list of recipients, it will show up as a single message with many local recipients.) – tripleee Jan 29 '19 at 13:29
  • can you please help me with this part: loop over the message and modify the To: header for each recipient // As I have explained in my question, I`m not a programmer and am trying to learn new thins. – Mojtaba Ghanidel Jan 29 '19 at 20:07
  • I already updated this answer yesterday to show how to do that. – tripleee Jan 30 '19 at 06:20