263 votes

Comment envoyer un email à plusieurs destinataires en utilisant python smtplib ?

Après de nombreuses recherches, je n'ai pas trouvé comment utiliser smtplib.sendmail pour envoyer à plusieurs destinataires. Le problème était qu'à chaque fois que le courrier était envoyé, les en-têtes du courrier semblaient contenir plusieurs adresses, mais en fait, seul le premier destinataire recevait l'e-mail.

Le problème semble être que le email.Message attend quelque chose de différent du module smtplib.sendmail() fonction.

En bref, pour envoyer à plusieurs destinataires, vous devez définir l'en-tête comme une chaîne d'adresses électroniques délimitées par des virgules. Le site sendmail() paramètre to_addrs devrait toutefois être une liste d'adresses électroniques.

from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
import smtplib

msg = MIMEMultipart()
msg["Subject"] = "Example"
msg["From"] = "me@example.com"
msg["To"] = "malcom@example.com,reynolds@example.com,firefly@example.com"
msg["Cc"] = "serenity@example.com,inara@example.com"
body = MIMEText("example email body")
msg.attach(body)
smtp = smtplib.SMTP("mailhost.example.com", 25)
smtp.sendmail(msg["From"], msg["To"].split(",") + msg["Cc"].split(","), msg.as_string())
smtp.quit()

1 votes

Il semble que le PO ait répondu à sa propre question : sendmail a besoin d'une liste.

0 votes

1 votes

En utilisant Python3, j'ai dû passer en boucle les destinataires ; for addr in recipients: msg['To'] = addr et puis ça a marché. Les affectations multiples ajoutent en fait un nouvel en-tête "À" pour chacune d'entre elles. C'est une interface très bizarre, je ne peux même pas expliquer comment j'ai pensé à l'essayer. J'ai même envisagé d'utiliser subprocess pour appeler le système unix sendmail paquet pour sauver ma santé mentale avant de comprendre ça.

16voto

SaiSandeep Golla Points 161

Donc en fait, le problème est que SMTP.sendmail et email.MIMEText ont besoin de deux choses différentes.

email.MIMEText définit l'en-tête "To :" pour le corps de l'e-mail. Il est UNIQUEMENT utilisé pour afficher un résultat à l'être humain à l'autre bout, et comme tous les en-têtes de courrier électronique, il doit être une chaîne unique. (Notez qu'il ne doit pas avoir de rapport avec les personnes qui reçoivent réellement le message).

SMTP.sendmail, quant à lui, configure l'"enveloppe" du message pour le protocole SMTP. Il a besoin d'une liste Python de chaînes de caractères, chacune d'entre elles ayant une seule adresse.

Donc, ce que vous devez faire, c'est COMBINER les deux réponses que vous avez reçues. Mettez msg['To'] à une seule chaîne, mais passez la liste brute à sendmail :

emails = ['a.com','b.com', 'c.com']
msg['To'] = ', '.join( emails ) 
....
s.sendmail( msg['From'], emails, msg.as_string())

11voto

MasterMind Points 111

J'ai essayé la méthode ci-dessous et ça a marché comme sur des roulettes :)

rec_list =  ['first@example.com', 'second@example.com']
rec =  ', '.join(rec_list)

msg['To'] = rec

send_out = smtplib.SMTP('localhost')
send_out.sendmail(me, rec_list, msg.as_string())

0 votes

FYR code simple entier ci-dessous : import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText sender = 'myEmailAddress@example.com' rec_list = ['first@example.com', 'second@example.com'] rec = ', '.join(rec_list) msg = MIMEMultipart('alternative') msg['Subject'] = 'The required subject' msg['From'] = sender msg['To'] = rec html = ('whatever html code') htm_part = MIMEText(html, 'html') msg.attach(htm_part) send_out = smtplib.SMTP('localhost') send_out.sendmail(sender, rec_list, msg.as_string()) send_out.quit()

10voto

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

def sender(recipients): 

    body = 'Your email content here'
    msg = MIMEMultipart()

    msg['Subject'] = 'Email Subject'
    msg['From'] = 'your.email@gmail.com'
    msg['To'] = (', ').join(recipients.split(','))

    msg.attach(MIMEText(body,'plain'))

    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()
    server.login('your.email@gmail.com', 'yourpassword')
    server.send_message(msg)
    server.quit()

if __name__ == '__main__':
    sender('email_1@domain.com,email_2@domain.com')

Cela n'a fonctionné pour moi qu'avec la fonction send_message et en utilisant la fonction join dans la liste avec les destinataires, python 3.6.

8voto

radtek Points 506

J'ai trouvé cette fonction de module importable. Il utilise le serveur de messagerie gmail dans cet exemple. Il est divisé en en-tête et message pour que vous puissiez voir clairement ce qui se passe :

import smtplib

def send_alert(subject=""):

    to = ['email@one.com', 'email2@another_email.com', 'a3rd@email.com']
    gmail_user = 'me@gmail.com'
    gmail_pwd = 'my_pass'
    smtpserver = smtplib.SMTP("smtp.gmail.com", 587)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(gmail_user, gmail_pwd)
    header = 'To:' + ", ".join(to) + '\n' + 'From: ' + gmail_user + '\n' + 'Subject: ' + subject + '\n'
    msg = header + '\n' + subject + '\n\n'
    smtpserver.sendmail(gmail_user, to, msg)
    smtpserver.close()

8voto

Robie Points 82

J'utilise python 3.6 et le code suivant fonctionne pour moi

email_send = 'xxxxx@xxx.xxx,xxxx@xxx.xxx'
server.sendmail(email_user,email_send.split(','),text)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X