python: comment envoyer des mails avec TO, CC et BCC?


102

J'ai besoin à des fins de test de remplir quelques centaines de boîtes e-mail avec divers messages, et j'allais utiliser smtplib pour cela. Mais entre autres, je dois être capable d'envoyer des messages non seulement à des boîtes aux lettres spécifiques, mais également en CC et en BCC. Il ne semble pas que smtplib prenne en charge CC-ing et BCC lors de l'envoi d'e-mails.

Vous recherchez des suggestions pour envoyer des messages CC ou BCC à partir du script python.

(Et - non, je ne crée pas de script pour spammer quiconque en dehors de mon environnement de test.)

Réponses:


150

Les en-têtes des e-mails n'ont pas d'importance pour le serveur smtp. Ajoutez simplement les destinataires CC et BCC aux toaddrs lorsque vous envoyez votre e-mail. Pour CC, ajoutez-les à l'en-tête CC.

toaddr = 'buffy@sunnydale.k12.ca.us'
cc = ['alexander@sunydale.k12.ca.us','willow@sunnydale.k12.ca.us']
bcc = ['chairman@slayerscouncil.uk']
fromaddr = 'giles@sunnydale.k12.ca.us'
message_subject = "disturbance in sector 7"
message_text = "Three are dead in an attack in the sewers below sector 7."
message = "From: %s\r\n" % fromaddr
        + "To: %s\r\n" % toaddr
        + "CC: %s\r\n" % ",".join(cc)
        + "Subject: %s\r\n" % message_subject
        + "\r\n" 
        + message_text
toaddrs = [toaddr] + cc + bcc
server = smtplib.SMTP('smtp.sunnydale.k12.ca.us')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, message)
server.quit()

smtplib.SMTP n'envoie pas de listes d'adresses. Au moins pas sur python 2.7.2
LostMohican

Dans ce cas, l'en-tête BCC mentionné dans la RFC 2822 n'a aucun sens.
Chenxiong Qi

1
@ABentSpoon il manque un deux-points après "Subject".
user891260

3
N'ajoutez pas l'en-tête Cci. Voir ceci: mail.python.org/pipermail/email-sig/2004-September/000151.html Et ceci: "" "Notez que le deuxième argument de sendmail (), les destinataires, est passé sous forme de liste. Vous pouvez inclure n'importe quel nombre d'adresses dans la liste pour que le message soit remis à chacune d'elles à tour de rôle. Puisque les informations de l'enveloppe sont séparées des en-têtes de message, vous pouvez même Cci quelqu'un en l'incluant dans l'argument de la méthode mais pas dans l'en-tête du message. " "" de pymotw.com/2/smtplib
Leonardo Andrade

2
Ce ne sera jamais BCC ou CC - ce sera toujours To
ProsperousHeart

37

L'essentiel est d'ajouter les destinataires sous forme de liste d'identifiants de messagerie dans votre appel sendmail.

import smtplib
from email.mime.multipart import MIMEMultipart

me = "user63503@gmail.com"
to = "someone@gmail.com"
cc = "anotherperson@gmail.com,someone@yahoo.com"
bcc = "bccperson1@gmail.com,bccperson2@yahoo.com"

rcpt = cc.split(",") + bcc.split(",") + [to]
msg = MIMEMultipart('alternative')
msg['Subject'] = "my subject"
msg['To'] = to
msg['Cc'] = cc
msg.attach(my_msg_body)
server = smtplib.SMTP("localhost") # or your smtp server
server.sendmail(me, rcpt, msg.as_string())
server.quit()

4
Laissez msg['BCC']désactivé - il révèle votre expéditeur masqué et n'a aucun impact sur le fait que le message lui soit envoyé ou non (les arguments pour le sendmailfaire).
Erica Kane

2
Je suis d'accord avec Erica et Julio. L'intention de Bcc est de cacher le récepteur à d'autres récepteurs. Si c'est dans le message, cela va à l'encontre du but.
Timothy C. Quinn

19

N'ajoutez pas l'en-tête Cci.

Voir ceci: http://mail.python.org/pipermail/email-sig/2004-September/000151.html

Et ceci: "" "Notez que le deuxième argument de sendmail (), les destinataires, est passé sous forme de liste. Vous pouvez inclure n'importe quel nombre d'adresses dans la liste pour que le message soit remis à chacun d'eux à tour de rôle. Depuis l'enveloppe les informations sont distinctes des en-têtes de message, vous pouvez même envoyer quelqu'un en BCC en l'incluant dans l'argument de la méthode mais pas dans l'en-tête du message. "" "de http://pymotw.com/2/smtplib

toaddr = 'buffy@sunnydale.k12.ca.us'
cc = ['alexander@sunydale.k12.ca.us','willow@sunnydale.k12.ca.us']
bcc = ['chairman@slayerscouncil.uk']
fromaddr = 'giles@sunnydale.k12.ca.us'
message_subject = "disturbance in sector 7"
message_text = "Three are dead in an attack in the sewers below sector 7."
message = "From: %s\r\n" % fromaddr
    + "To: %s\r\n" % toaddr
    + "CC: %s\r\n" % ",".join(cc)
    # don't add this, otherwise "to and cc" receivers will know who are the bcc receivers
    # + "BCC: %s\r\n" % ",".join(bcc)
    + "Subject: %s\r\n" % message_subject
    + "\r\n" 
    + message_text
toaddrs = [toaddr] + cc + bcc
server = smtplib.SMTP('smtp.sunnydale.k12.ca.us')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, message)
server.quit()

Bravo pour le flair: D
Chris

19

Depuis Python 3.2, publié en novembre 2011, le smtplib a une nouvelle fonction send_messageau lieu de juste sendmail, ce qui facilite le traitement de To / CC / BCC. En tirant des exemples d'e-mails officiels de Python , avec quelques légères modifications, nous obtenons:

# Import smtplib for the actual sending function
import smtplib

# Import the email modules we'll need
from email.message import EmailMessage

# Open the plain text file whose name is in textfile for reading.
with open(textfile) as fp:
    # Create a text/plain message
    msg = EmailMessage()
    msg.set_content(fp.read())

# me == the sender's email address
# you == the recipient's email address
# them == the cc's email address
# they == the bcc's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you
msg['Cc'] = them
msg['Bcc'] = they


# Send the message via our own SMTP server.
s = smtplib.SMTP('localhost')
s.send_message(msg)
s.quit()

L'utilisation des en-têtes fonctionne correctement , car send_message respecte BCC comme indiqué dans la documentation :

send_message ne transmet aucun en-tête Bcc ou Resent-Bcc pouvant apparaître dans msg


Avec sendmailil était courant d'ajouter les en-têtes CC au message, en faisant quelque chose comme:

msg['Bcc'] = blind.email@adrress.com

Ou

msg = "From: from.email@address.com" +
      "To: to.email@adress.com" +
      "BCC: hidden.email@address.com" +
      "Subject: You've got mail!" +
      "This is the message body"

Le problème est que la fonction sendmail traite tous ces en-têtes de la même manière, ce qui signifie qu'ils seront envoyés (visiblement) à tous les utilisateurs To: et BCC:, ce qui va à l'encontre des objectifs de BCC. La solution, comme indiqué dans de nombreuses autres réponses ici, était de ne pas inclure BCC dans les en-têtes, mais uniquement dans la liste des e-mails passés à sendmail.

La mise en garde est que cela send_messagenécessite un objet Message, ce qui signifie que vous devrez importer une classe depuis email.messageau lieu de simplement passer des chaînes dans sendmail.


2
Je viens de vérifier que send_message (msg) gère les cc ajoutés à EmailMessage - msg ['Cc'] Si vous utilisez Python 3, c'est la voie à suivre.
bmiller

@bmiller Yup, assez pratique. J'ai écrit cette réponse parce que je la recherchais et que je trouvais le moyen le plus simple dans la documentation et d'autres références, et cela a bien fonctionné pour moi, et j'ai pensé que cela méritait une place ici car beaucoup de gens regarderont ici en premier.

non seulement je trouve cette solution plus élégante mais elle fonctionne parfaitement. Cela résout également un problème que j'ai eu avec la réponse de @ABentSpoon, qui est que pour les adresses gmail en CC, les e-mails n'allaient pas dans la boîte de réception mais dans "All Mail" à la place.
Guillaume Garrigos le

18

La distinction entre TO, CC et BCC ne se produit que dans les en-têtes de texte. Au niveau SMTP, tout le monde est un destinataire.

TO - Il y a un en-tête TO: avec l'adresse de ce destinataire

CC - Il y a un en-tête CC: avec l'adresse de ce destinataire

BCC - Ce destinataire n'est pas du tout mentionné dans les en-têtes, mais reste un destinataire.

Si tu as

TO: abc@company.com
CC: xyz@company.com
BCC: boss@company.com

Vous avez trois destinataires. Les en-têtes dans le corps de l'e-mail comprendront uniquement le TO: et le CC:



5

Cela n'a pas fonctionné pour moi jusqu'à ce que je crée:

#created cc string
cc = ""someone@domain.com;
#added cc to header
msg['Cc'] = cc

et que le cc ajouté dans le destinataire [liste] comme:

s.sendmail(me, [you,cc], msg.as_string())

2

Aucune des choses ci-dessus n'a fonctionné pour moi car j'avais plusieurs destinataires à la fois en «to» et en «cc». J'ai donc essayé comme ci-dessous:

recipients = ['abc@gmail.com', 'xyz@gmail.com']
cc_recipients = ['lmn@gmail.com', 'pqr@gmail.com']
MESSAGE['To'] = ", ".join(recipients)
MESSAGE['Cc'] = ", ".join(cc_recipients)

et étendez les 'destinataires' avec 'cc_recipients' et envoyez du courrier de manière triviale

recipients.extend(cc_recipients)
server.sendmail(FROM,recipients,MESSAGE.as_string())
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.