Python: Wie verschicke ich E-Mails mit TO, CC und BCC?

101

Ich brauche zu Testzwecken, um einige hundert E-Mail-Boxen mit verschiedenen Nachrichten zu füllen, und wollte dafür smtplib verwenden. Aber unter anderem muss ich in der Lage sein, Nachrichten nicht nur an bestimmte Postfächer zu senden, sondern auch an CC und BCC. Es sieht nicht so aus, als ob smtplib beim Senden von E-Mails CC-ing und BCC-ing unterstützt.

Suchen Sie nach Vorschlägen zum CC- oder BCC-Senden von Nachrichten aus dem Python-Skript.

(Und - nein, ich erstelle kein Skript, um jemanden außerhalb meiner Testumgebung zu spammen.)

user63503
quelle

Antworten:

149

E-Mail-Header spielen für den SMTP-Server keine Rolle. Fügen Sie einfach die CC- und BCC-Empfänger zu den toaddrs hinzu, wenn Sie Ihre E-Mail senden. Fügen Sie sie für CC zum CC-Header hinzu.

toaddr = '[email protected]'
cc = ['[email protected]','[email protected]']
bcc = ['[email protected]']
fromaddr = '[email protected]'
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()
ABentSpoon
quelle
smtplib.SMTP sendet keine Listen mit Adressen. Zumindest nicht auf Python 2.7.2
LostMohican
In diesem Fall macht der im RFC 2822 erwähnte BCC-Header keinen Sinn.
Chenxiong Qi
1
@ABentSpoon Nach 'Betreff' fehlt ein Doppelpunkt.
Benutzer891260
3
Fügen Sie den bcc-Header nicht hinzu. Siehe dies: mail.python.org/pipermail/email-sig/2004-September/000151.html Und dies: "" Beachten Sie, dass das zweite Argument an sendmail (), die Empfänger, als Liste übergeben wird. Sie können einschließen Eine beliebige Anzahl von Adressen in der Liste, an die die Nachricht nacheinander an jede von ihnen gesendet werden soll. Da die Umschlaginformationen von den Nachrichtenkopfzeilen getrennt sind, können Sie sogar eine BCC-Datei erstellen, indem Sie sie in das Methodenargument, jedoch nicht in den Nachrichtenkopf aufnehmen. " "" von pymotw.com/2/smtplib
Leonardo Andrade
2
Dies wird niemals BCC oder CC sein - es wird immer To
ProsperousHeart
36

Wichtig ist, dass Sie die Empfänger als Liste der E-Mail-IDs in Ihrem Sendmail-Anruf hinzufügen .

import smtplib
from email.mime.multipart import MIMEMultipart

me = "[email protected]"
to = "[email protected]"
cc = "[email protected],[email protected]"
bcc = "[email protected],[email protected]"

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()
Helios
quelle
4
Lassen Sie das msg['BCC']ausgeschaltet - es enthüllt Ihren versteckten Absender und hat keinen Einfluss darauf, ob die Nachricht an ihn gesendet wird oder nicht (die Argumente sendmaildafür).
Erica Kane
2
Ich stimme Erica und Julio zu. Die Absicht von Bcc ist es, den Empfänger vor anderen Empfängern zu verstecken. Wenn es in der Nachricht ist, macht das den Zweck zunichte.
Timothy C. Quinn
19

Fügen Sie den bcc-Header nicht hinzu.

Siehe hierzu: http://mail.python.org/pipermail/email-sig/2004-September/000151.html

Und dies: "" Beachten Sie, dass das zweite Argument an sendmail (), die Empfänger, als Liste übergeben wird. Sie können eine beliebige Anzahl von Adressen in die Liste aufnehmen, damit die Nachricht nacheinander an jede von ihnen übermittelt wird. Seit dem Umschlag Informationen sind von den Nachrichtenkopfzeilen getrennt. Sie können sogar eine BCC-Datei erstellen, indem Sie sie in das Methodenargument, jedoch nicht in den Nachrichtenkopf aufnehmen. "" "von http://pymotw.com/2/smtplib

toaddr = '[email protected]'
cc = ['[email protected]','[email protected]']
bcc = ['[email protected]']
fromaddr = '[email protected]'
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()
Leonardo Andrade
quelle
Daumen hoch für Flair: D
Chris
18

Die Unterscheidung zwischen TO, CC und BCC erfolgt nur in den Textüberschriften. Auf SMTP-Ebene ist jeder Empfänger.

TO - Es gibt einen TO: -Header mit der Adresse dieses Empfängers

CC - Es gibt einen CC: -Header mit der Adresse dieses Empfängers

BCC - Dieser Empfänger wird in den Kopfzeilen überhaupt nicht erwähnt, ist aber dennoch ein Empfänger.

Wenn Sie haben

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

Sie haben drei Empfänger. Die Header im E-Mail-Text enthalten nur TO: und CC:

Jim Garrison
quelle
16

Sie können MIMEText ausprobieren

msg = MIMEText('text')
msg['to'] = 
msg['cc'] = 

dann sende msg.as_string ()

https://docs.python.org/3.6/library/email.examples.html

Erosion
quelle
4
Dieses
1
Ich bin damit einverstanden, dass die Beispiele auf dem obigen Link Bcc nicht behandeln. Das hat @hoju wahrscheinlich gemeint.
Shailen
16

Ab Python 3.2, veröffentlicht im November 2011, hat die smtplib eine neue Funktion send_messageanstelle von nur sendmail, was den Umgang mit To / CC / BCC erleichtert. Aus den offiziellen Python-E-Mail-Beispielen mit einigen geringfügigen Änderungen erhalten wir:

# 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()

Die Verwendung der Header funktioniert einwandfrei , da send_message BCC wie in der Dokumentation beschrieben respektiert :

send_message überträgt keine Bcc- oder Resent-Bcc-Header, die möglicherweise in msg erscheinen


Dabei war sendmailes üblich, die CC-Header zur Nachricht hinzuzufügen und dabei Folgendes zu tun:

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

Oder

msg = "From: [email protected]" +
      "To: [email protected]" +
      "BCC: [email protected]" +
      "Subject: You've got mail!" +
      "This is the message body"

Das Problem ist, dass die sendmail-Funktion alle diese Header gleich behandelt, was bedeutet, dass sie (sichtbar) an alle To: - und BCC: -Benutzer gesendet werden, wodurch die Zwecke von BCC zunichte gemacht werden. Die Lösung bestand, wie in vielen anderen Antworten hier gezeigt, darin, BCC nicht in die Kopfzeilen aufzunehmen, sondern nur in die Liste der E-Mails, an die weitergeleitet wurde sendmail.

Die Einschränkung besteht darin, send_messagedass ein Message-Objekt erforderlich ist. Dies bedeutet, dass Sie eine Klasse importieren müssen, email.messageanstatt nur Zeichenfolgen zu übergeben sendmail.


quelle
2
Ich habe gerade überprüft, ob send_message (msg) die zur EmailMessage hinzugefügten CCs verarbeitet - msg ['Cc'] Wenn Sie Python 3 verwenden, ist dies der richtige Weg.
Bmiller
@bmiller Yup, ganz praktisch. Ich habe diese Antwort geschrieben, weil ich sie mir angesehen und den einfacheren Weg in den Dokumenten und anderen Verweisen gefunden habe, und sie hat für mich gut funktioniert, und ich dachte, sie hätte hier einen Platz verdient, da viele Leute hier zuerst nachsehen werden.
Ich finde diese Lösung nicht nur eleganter, sondern sie funktioniert auch perfekt. Es löst auch ein Problem, das ich mit der Antwort von @ABentSpoon hatte. Bei Google Mail-Adressen in CC gingen die E-Mails nicht in den Posteingang, sondern in "Alle E-Mails".
Guillaume Garrigos
5

Es hat bei mir nicht funktioniert, bis ich erstellt habe:

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

und als cc im Empfänger [Liste] hinzugefügt wie:

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

Keines der oben genannten Dinge funktionierte für mich, da ich mehrere Empfänger sowohl in 'to' als auch in 'cc' hatte. Also habe ich es wie folgt versucht:

recipients = ['[email protected]', '[email protected]']
cc_recipients = ['[email protected]', '[email protected]']
MESSAGE['To'] = ", ".join(recipients)
MESSAGE['Cc'] = ", ".join(cc_recipients)

und erweitern Sie die 'Empfänger' mit 'cc_recipients' und senden Sie E-Mails auf triviale Weise

recipients.extend(cc_recipients)
server.sendmail(FROM,recipients,MESSAGE.as_string())
Chan Gaikwad
quelle