web-dev-qa-db-fra.com

Comment envoyer un courrier électronique à plusieurs destinataires à l'aide de python smtplib?

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

Le problème semble être que le module email.Message s'attend à autre chose que la fonction smtplib.sendmail() .

En bref, pour envoyer à plusieurs destinataires, vous devez définir l'en-tête comme étant une chaîne d'adresses électroniques délimitées par des virgules. Le paramètre sendmail()to_addrs doit cependant ê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"] = "[email protected]"
msg["To"] = "[email protected],[email protected],[email protected]"
msg["Cc"] = "[email protected],[email protected]"
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()
149
user1148320

Ceci fonctionne vraiment , j'ai passé beaucoup de temps à essayer plusieurs variantes.

import smtplib
from email.mime.text import MIMEText

s = smtplib.SMTP('smtp.uk.xensource.com')
s.set_debuglevel(1)
msg = MIMEText("""body""")
sender = '[email protected]'
recipients = ['[email protected]', '[email protected]']
msg['Subject'] = "subject line"
msg['From'] = sender
msg['To'] = ", ".join(recipients)
s.sendmail(sender, recipients, msg.as_string())
254
sorin

Le msg['To'] doit être une chaîne:

msg['To'] = "[email protected], [email protected], [email protected]"

Alors que la recipients dans sendmail(sender, recipients, message) doit être une liste:

sendmail("[email protected]", ["[email protected]", "[email protected]", "[email protected]"], "Howdy")
121
dvdhns

Vous devez comprendre la différence entre l'adresse visible d'un courrier électronique et l'adresse delivery.

msg["To"] est essentiellement ce qui est imprimé sur la lettre. Cela n'a aucun effet. Sauf que votre client de messagerie, à l'instar de l'agent postal régulier, supposera que c'est à qui vous voulez envoyer le courrier électronique.

La livraison réelle peut cependant fonctionner assez différemment. Ainsi, vous pouvez déposer le courrier électronique (ou une copie) dans la boîte aux lettres de quelqu'un de complètement différent.

Il y a plusieurs raisons à cela. Par exemple, forwarding. Le champ d'en-tête To: ne change pas lors du transfert, mais l'email est déposé dans une autre boîte aux lettres.

La commande smtp.sendmail prend maintenant en charge la livraison actual. email.Message est le contenu de la lettre seulement, pas la livraison.

Dans SMTP de bas niveau, vous devez donner aux destinataires un à un. C'est pourquoi une liste d'adresses (sans noms!) Est l'API sensible.

Pour l’en-tête, il peut également contenir, par exemple, le nom, par exemple. To: First Last <[email protected]>, Other User <[email protected]>. Votre exemple de code n'est donc pas recommandé , car l'envoi de ce courrier échouera, car il vous suffit de le scinder en , pour que vous ne disposiez toujours pas des adresses valides!

34
Anony-Mousse

Ça marche pour moi.

import smtplib
from email.mime.text import MIMEText

s = smtplib.SMTP('smtp.uk.xensource.com')
s.set_debuglevel(1)
msg = MIMEText("""body""")
sender = '[email protected]'
recipients = '[email protected],[email protected]'
msg['Subject'] = "subject line"
msg['From'] = sender
msg['To'] = recipients
s.sendmail(sender, recipients.split(','), msg.as_string())
13
coolguy

J'ai essayé le dessous et ça a fonctionné comme un charme :)

rec_list =  ['[email protected]', '[email protected]']
rec =  ', '.join(rec_list)

msg['To'] = rec

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

Je suis venu avec cette fonction de module importable. Il utilise le serveur de messagerie gmail dans cet exemple. Il est divisé en en-tête et message afin que vous puissiez voir clairement ce qui se passe:

import smtplib

def send_alert(subject=""):

    to = ['[email protected]', 'email2@another_email.com', '[email protected]']
    gmail_user = '[email protected]'
    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()
6
radtek

Je l'ai compris il y a quelques mois et j'ai blogué à ce sujet . Le résumé est:

Si vous souhaitez utiliser smtplib pour envoyer des courriers électroniques à plusieurs destinataires, utilisez email.Message.add_header('To', eachRecipientAsString) pour les ajouter, puis lorsque vous appelez la méthode sendmail, use email.Message.get_all('To') leur envoie le message à tous. Idem pour les destinataires Cc et Cci.

5
James McPherson

Le problème est donc que SMTP.sendmail et email.MIMEText ont besoin de deux choses différentes.

email.MIMEText configure l'en-tête "To:" pour le corps de l'e-mail. Il est UNIQUEMENT utilisé pour afficher un résultat à l’être humain situé à l’autre extrémité et, comme tous les en-têtes de courrier électronique, doit être constitué d’une seule chaîne. (Notez que cela ne doit en réalité avoir aucun rapport avec les personnes qui reçoivent réellement le message.)

SMTP.sendmail, d'autre part, définit "l'enveloppe" du message pour le protocole SMTP. Il faut une liste de chaînes Python, chacune ayant une adresse unique.

Vous devez donc COMBINER les deux réponses que vous avez reçues. Définissez msg ['To'] sur une seule chaîne, mais transmettez la liste brute à sendmail:

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

Eh bien, la méthode utilisée dans cette méthode asnwer n'a pas fonctionné pour moi. Je ne sais pas, c’est peut-être un problème lié à Gmail, ou à Python3 (j'utilise la version 3.4), mais après quelques essais, la solution qui a fonctionné pour moi était la ligne

s.send_message(msg)

au lieu de

s.sendmail(sender, recipients, msg.as_string())
2
Antoine

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

email_send = '[email protected],[email protected]'
server.sendmail(email_user,email_send.split(','),text)    
1
Robie
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'] = '[email protected]'
    msg['To'] = (', ').join(recipients.split(','))

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

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

if __== '__main__':
    sender('[email protected],[email protected]')

Cela ne fonctionnait que pour moi avec la fonction send_message et l'utilisation de la fonction de jointure dans la liste des destinataires, python 3.6. 

Below worked for me.
It sends email to multiple with attachment - "To", "Cc" & "Bcc" successfully.


toaddr = ['mailid_1','mailid_2']
cc = ['mailid_3','mailid_4']
bcc = ['mailid_5','mailid_6']
subject = 'Email from Python Code'
fromaddr = 'sender_mailid'
message = "\n  !! Hello... !!"

msg['From'] = fromaddr
msg['To'] = ', '.join(toaddr)
msg['Cc'] = ', '.join(cc)
msg['Bcc'] = ', '.join(bcc)
msg['Subject'] = subject

s.sendmail(fromaddr, (toaddr+cc+bcc) , message)
0
Omkar

vous pouvez essayer cela quand vous écrivez les emails du destinataire sur un fichier texte

from email.mime.text import MIMEText
from email.header import Header
import smtplib

f =  open('emails.txt', 'r').readlines()
for n in f:
     emails = n.rstrip()
server = smtplib.SMTP('smtp.uk.xensource.com')
server.ehlo()
server.starttls()
body = "Test Email"
subject = "Test"
from = "[email protected]"
to = emails
msg = MIMEText(body,'plain','utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] =  Header(from, 'utf-8')
msg['To'] = Header(to, 'utf-8')
text = msg.as_string()
try:
   server.send(from, emails, text)
   print('Message Sent Succesfully')
except:
   print('There Was An Error While Sending The Message')
0
Skiller Dz