Home > other >  I want my python script to send emails 1 by 1 from email list (like 1st done then repeat task and go
I want my python script to send emails 1 by 1 from email list (like 1st done then repeat task and go

Time:03-21

I want my task to be 1 by 1 not bulk so I'm sending from list of emails. I want it sending to first one then repeats task and sends to second one. The code already works properly but it sends as bulk all emails together so when recipient gets the email it's like all the emails list included in header. That's why I want it to send it one by one from my list.

import smtplib, ssl
from time import strftime
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from colorama import *
from datetime import datetime


context = ssl.create_default_context()

def get_contacts(filename):
    
    emails = []
    with open(filename, mode='r', encoding='utf-8') as contacts_file:
        for a_contact in contacts_file:
            emails.append(a_contact.split()[0])
    return emails

mails = get_contacts('smtp/contacts.txt')


smtp_user = '[email protected]'

def smtp(smtp_server, port, user, password):
    
    
        context = ssl.create_default_context()
        with smtplib.SMTP_SSL(smtp_server, port) as server:
            try:
                 message = MIMEMultipart('alternative')
                 
                 
                 message['Subject'] = 'TESTING'
                 message['From'] = str(Header(f'INFO <{smtp_user}>'))
                 message['To'] = ', '.join(mails)
                
                
                 myfile = open('smtp/letter.txt', 'r')      
                 data = myfile.read()
                 part = MIMEText(data, 'html')
                 message.attach(part)
                
                 now = datetime.now()
                 current_time = now.strftime("%H:%M:%S")
   
                 server.login(user, password)
                 server.sendmail(user, mails, message.as_string())
                 for email in mails:
                    print('\n',email   ''' SENT! ''')
            except smtplib.SMTPAuthenticationError or smtplib.SMTPConnectError :
                 print('Dead SMTP')    

CodePudding user response:

Response:

You just have to move put inside your for email in mails:

for email in mails:
    print('\n',email   ''' SENT! ''')
    message['To'] = email
    server.sendmail(user, mails, message.as_string())

Remove from your original script:

message['To'] = ', '.join(mails)

and

server.sendmail(user, mails, message.as_string())
Notes:
  • Next time consider undersanding your script before posting your question as this is a very simple thing to do and the answer is already all over the internet.
  • your try have too many instructions you should only have the instruction that may fail with the handled errors inside it, as the errors that you're handling are smtplib.SMTPAuthenticationError and smtplib.SMTPConnectError: server.login and server.sendmail
  • Do not post your entire script or big code chunks this is rude and you'll not getting appropriated answers this way.

CodePudding user response:

Your code very explicitly adds all recipients to the To: header and then sends a single message.

As an aside, your code seems to be written for Python 3.5 or earlier. The email library was overhauled in 3.6 and is now quite a bit more versatile and logical. Probably throw away what you have and start over with the examples from the email documentation. Something like this, maybe:

from email.message import EmailMessage

... 

mails = get_contacts('smtp/contacts.txt')


smtp_user = '[email protected]'

def generate_messages(recipients):
    with open('smtp/letter.txt', 'r') as myfile:
        data = myfile.read()

    for recipient in recipients:
        message = EmailMessage()
        message['Subject'] = 'TESTING'
        message['From'] = str(Header(f'INFO <{smtp_user}>'))
        message['To'] = recipient
        message.set_payload(data, 'html')                
        yield message

def smtp(smtp_server, port, user, password, messages):
    with smtplib.SMTP_SSL(smtp_server, port) as server:
        server.login(user, password)
        for message in messages:
             now = datetime.now()
             current_time = now.strftime("%H:%M:%S")
             server.send_message(message)

smtp("smtp.example.com", 25, "[email protected]", "xyzzy", generate_messages())

Untested, and I ripped out the exception handling because I'm probably unable to guess what sort of exception handling would make sense with this different flow.

The use of a generator to generate the messages is perhaps a bit confusing if you are new to Python. I'm thinking you want to minimize the number of separate login events to the SMTP server, and so the code basically has a callback to produce the next message from within the smtp function.

  • Related