python: jak wysyłać pocztę za pomocą TO, CC i BCC?

102

Do celów testowych potrzebuję zapełnić kilkaset skrzynek pocztowych różnymi wiadomościami i zamierzałem użyć do tego smtplib. Ale między innymi muszę mieć możliwość wysyłania wiadomości nie tylko do określonych skrzynek pocztowych, ale także do nich CC i BCC. Nie wygląda na to, żeby smtplib wspierał CC-ing i BCC-ing podczas wysyłania e-maili.

Szukasz sugestii, jak zrobić CC lub BCC wysyłając wiadomości ze skryptu Pythona.

(I - nie, nie tworzę skryptu do spamowania nikogo spoza mojego środowiska testowego).

user63503
źródło

Odpowiedzi:

150

Nagłówki wiadomości e-mail nie mają znaczenia dla serwera SMTP. Po prostu dodaj odbiorców DW i UDW do ropuchów podczas wysyłania wiadomości e-mail. W przypadku CC dodaj je do nagłówka CC.

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
źródło
smtplib.SMTP nie wysyła list adresów. Przynajmniej nie w Pythonie 2.7.2
LostMohican
W tym przypadku nagłówek BCC wspomniany w dokumencie RFC 2822 nie ma żadnego sensu.
Chenxiong Qi
1
@ABentSpoon po „temacie” brakuje dwukropka.
user891260
3
Nie dodawaj nagłówka UDW. Zobacz to: mail.python.org/pipermail/email-sig/2004-September/000151.html A to: "" "Zauważ, że drugi argument funkcji sendmail (), czyli adresaci, jest przekazywany jako lista. Możesz dołączyć dowolna liczba adresów na liście, aby wiadomość była dostarczana do każdego z nich po kolei. Ponieważ informacje o kopercie są oddzielone od nagłówków wiadomości, możesz nawet wysłać komuś BCC, dodając go do argumentu metody, ale nie w nagłówku wiadomości. " „” z pymotw.com/2/smtplib
Leonardo Andrade,
2
To nigdy nie będzie BCC ani CC - zawsze będzie Do
ProsperousHeart
37

Kluczową sprawą jest dodanie odbiorców jako listy identyfikatorów e-mail w wywołaniu sendmail.

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
źródło
4
Zostaw msg['BCC']wyłączone - ujawnia ukrytego nadawcę i nie ma wpływu na to, czy wiadomość jest do niego wysłana, czy nie (argumenty, sendmailktóre to robią).
Erica Kane
2
Zgadzam się z Eriką i Julio. Celem UDW jest ukrycie odbiornika przed innymi odbiornikami. Jeśli jest w wiadomości, to mija się z celem.
Timothy C. Quinn
19

Nie dodawaj nagłówka UDW.

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

I to: "" "Zauważ, że drugi argument funkcji sendmail (), czyli odbiorcy, jest przekazywany jako lista. Możesz umieścić na liście dowolną liczbę adresów, aby wiadomość była dostarczana po kolei do każdego z nich. Ponieważ koperta informacje są oddzielone od nagłówków wiadomości, możesz nawet udzielić komuś BCC, umieszczając je w argumencie metody, ale nie w nagłówku wiadomości. "" "z 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
źródło
Kciuki w górę za talent: D
Chris
19

Począwszy od Pythona 3.2, wydanego w listopadzie 2011 r., Smtplib ma nową funkcję send_messagezamiast just sendmail, co ułatwia obsługę To / CC / BCC. Wyciągając z oficjalnych przykładów wiadomości e-mail w języku Python , z niewielkimi modyfikacjami, otrzymujemy:

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

Używanie nagłówków działa dobrze, ponieważ send_message respektuje BCC, jak opisano w dokumentacji :

send_message nie przesyła żadnych nagłówków Bcc ani Resent-Bcc, które mogą pojawić się w msg


Z sendmailbyło wspólne, aby dodać nagłówki CC do wiadomości, robi coś, takich jak:

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

Lub

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

Problem polega na tym, że funkcja sendmail traktuje wszystkie te nagłówki tak samo, co oznacza, że ​​zostaną one wysłane (widocznie) do wszystkich użytkowników To: i BCC:, pokonując cele BCC. Rozwiązaniem, jak pokazano w wielu innych tutaj odpowiedziach, było nie umieszczanie BCC w nagłówkach, a zamiast tego tylko na liście wiadomości e-mail przekazywanych sendmail.

Zastrzeżenie polega na tym, że send_messagewymaga obiektu Message, co oznacza, że ​​musisz zaimportować klasę z, email.messagea nie tylko przekazywać ciągi do sendmail.


źródło
2
Właśnie sprawdziliśmy, że send_message (msg) obsługuje cc dodane do EmailMessage - msg ['Cc'] Jeśli używasz Pythona 3, to jest właściwy sposób.
bmiller
@bmiller Tak, całkiem przydatne. Napisałem tę odpowiedź, ponieważ szukałem jej i znalazłem prostszą drogę w dokumentach i innych referencjach, i działała dobrze dla mnie i pomyślałem, że zasługuje na miejsce tutaj, ponieważ wielu ludzi zajrzy tutaj jako pierwsze.
nie tylko uważam to rozwiązanie za bardziej eleganckie, ale działa doskonale. Rozwiązuje to również problem, który miałem z odpowiedzią @ABentSpoon, polegającą na tym, że w przypadku adresów Gmail w CC e-maile nie trafiały do ​​skrzynki odbiorczej, ale zamiast tego do „All Mail”.
Guillaume Garrigos
18

Rozróżnienie między TO, CC i BCC występuje tylko w nagłówkach tekstu. Na poziomie SMTP każdy jest odbiorcą.

DO - istnieje nagłówek DO: z adresem tego odbiorcy

CC - istnieje nagłówek CC: z adresem tego odbiorcy

UDW - Ten odbiorca w ogóle nie jest wymieniony w nagłówkach, ale nadal jest odbiorcą.

Jeśli masz

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

Masz trzech odbiorców. Nagłówki w treści wiadomości e-mail będą zawierać tylko DO: i DW:

Jim Garrison
źródło
16

Możesz spróbować MIMEText

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

następnie wyślij msg.as_string ()

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

foosion
źródło
4
ten przykład nie używa CC
hoju
1
Zgadzam się, że przykłady w powyższym linku nie dotyczą UDW. To prawdopodobnie oznaczało @hoju.
Shailen
5

Nie zadziałało, dopóki nie stworzyłem:

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

a następnie dodano DW w adresacie [lista], na przykład:

s.sendmail(me, [you,cc], msg.as_string())
marko_b123
źródło
2

Żadna z powyższych rzeczy nie działała dla mnie, ponieważ miałem wielu odbiorców zarówno w „do”, jak i „cc”. Więc spróbowałem jak poniżej:

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

i rozszerz „adresatów” o „cc_recipients” i wyślij pocztę w trywialny sposób

recipients.extend(cc_recipients)
server.sendmail(FROM,recipients,MESSAGE.as_string())
Chan Gaikwad
źródło