-1

I am trying to use a for-loop to send an email to multiple recipients, if "<>" is found in the subject or body, it is replaced dynamically with the recipients name.

I am looping over a dictionary of recipients in the form {"name": "email"}

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

def send(recipients, subject, message):
    for name, email in recipients.items():
        edited_subject = subject.replace("<>", name)
        edited_message = message.replace("<>", name)

        mail = MIMEMultipart()
        mail['from'] = 'Tomas'
        mail['to'] = email
        mail['subject'] = edited_subject
        mail.attach(MIMEText(edited_message, "plain"))

        with smtplib.SMTP(host="smtp.gmail.com", port=587) as smtp:
            smtp.ehlo()
            smtp.starttls()
            smtp.login(username, password)
            smtp.send_message(mail)

the loop seems to only sends to the first recipient.

Tomas
  • 1
  • 2

1 Answers1

0

The with statement ensures proper acquisition and release of resources. Instead of creating a new smtp every loop, try creating it once and then loop inside the context:

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

def send(recipients, subject, message):
    with smtplib.SMTP(host="smtp.gmail.com", port=587) as smtp:
        smtp.ehlo()
        smtp.starttls()
        smtp.login(username, password)
        for name, email in recipients.items():
            edited_subject = subject.replace("<>", name)
            edited_message = message.replace("<>", name)

            mail = MIMEMultipart()
            mail['from'] = 'Tomas'
            mail['to'] = email
            mail['subject'] = edited_subject
            mail.attach(MIMEText(edited_message, "plain"))
            smtp.send_message(mail)
Haukland
  • 677
  • 8
  • 25