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()
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())
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")
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!
Ç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())
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())
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()
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.
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())
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())
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)
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)
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')