python: come inviare posta con TO, CC e BCC?


102

A scopo di test, ho bisogno di popolare alcune centinaia di caselle di posta elettronica con vari messaggi, e per questo avrei utilizzato smtplib. Ma tra le altre cose devo essere in grado di inviare messaggi non solo a caselle di posta specifiche, ma anche CC e BCC. Non sembra che smtplib supporti CC-ing e BCC-ing durante l'invio di e-mail.

Alla ricerca di suggerimenti su come eseguire CC o BCC inviando messaggi dallo script python.

(E - no, non sto creando uno script per inviare spam a chiunque al di fuori del mio ambiente di test.)

Risposte:


150

Le intestazioni delle e-mail non sono importanti per il server SMTP. Basta aggiungere i destinatari CC e BCC ai toaddr quando invii la tua email. Per CC, aggiungili all'intestazione 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 non invia elenchi di indirizzi. Almeno non su Python 2.7.2
LostMohican

In questo caso, l'intestazione BCC menzionata nella RFC 2822 non ha alcun senso.
Chenxiong Qi

1
@ABentSpoon mancano i due punti dopo "Oggetto".
user891260

3
Non aggiungere l'intestazione Ccn. Vedi questo: mail.python.org/pipermail/email-sig/2004-September/000151.html E questo: "" "Nota che il secondo argomento di sendmail (), i destinatari, viene passato come una lista. Puoi includere un numero qualsiasi di indirizzi nell'elenco per ricevere il messaggio consegnato a ciascuno di essi a turno. Poiché le informazioni sulla busta sono separate dalle intestazioni del messaggio, puoi persino inviare in BCC qualcuno includendolo nell'argomento del metodo ma non nell'intestazione del messaggio. " "" da pymotw.com/2/smtplib
Leonardo Andrade

2
Questo non sarà mai BCC o CC - sarà sempre A
ProsperousHeart

37

La cosa fondamentale è aggiungere i destinatari come elenco di ID email nella chiamata 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
Lascia msg['BCC']disattivato: rivela il tuo mittente nascosto e non ha alcun impatto sul fatto che il messaggio venga inviato o meno (gli argomenti per sendmailfarlo).
Erica Kane

2
Sono d'accordo con Erica e Julio. Lo scopo di Bcc è nascondere il ricevitore ad altri ricevitori. Se è nel messaggio, ciò vanifica lo scopo.
Timothy C. Quinn

19

Non aggiungere l'intestazione Ccn.

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

E questo: "" "Nota che il secondo argomento di sendmail (), i destinatari, viene passato come un elenco. Puoi includere un numero qualsiasi di indirizzi nell'elenco per ricevere il messaggio a ciascuno di essi. Poiché la busta le informazioni sono separate dalle intestazioni del messaggio, puoi persino BCC qualcuno includendole nell'argomento del metodo ma non nell'intestazione del messaggio. "" "da 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()

Complimenti per il talento: D
Chris,

19

A partire da Python 3.2, rilasciato a novembre 2011, smtplib ha una nuova funzione send_messageanziché solo sendmail, il che rende più facile trattare con To / CC / BCC. Prendendo gli esempi di posta elettronica ufficiali di Python , con alcune lievi modifiche, otteniamo:

# 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'utilizzo delle intestazioni funziona bene, perché send_message rispetta BCC come descritto nella documentazione :

send_message non trasmette alcuna intestazione Bcc o Resent-Bcc che potrebbe apparire in msg


Con sendmailera comune aggiungere le intestazioni CC al messaggio, facendo qualcosa come:

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

O

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"

Il problema è che la funzione sendmail tratta tutte quelle intestazioni allo stesso modo, il che significa che verranno inviate (visibilmente) a tutti gli utenti A: e BCC:, vanificando gli scopi di BCC. La soluzione, come mostrato in molte altre risposte qui, era di non includere BCC nelle intestazioni, e invece solo nell'elenco delle email passate a sendmail.

L'avvertenza è che send_messagerichiede un oggetto Message, il che significa che dovrai importare una classe da email.messageinvece di passare semplicemente stringhe in sendmail.


2
Ho appena verificato che send_message (msg) gestisce i cc aggiunti a EmailMessage - msg ['Cc'] Se stai usando Python 3 questa è la strada da percorrere.
bmiller

@bmiller Sì, abbastanza utile. Ho scritto questa risposta perché la stavo esaminando e ho trovato il modo più semplice nei documenti e in altri ref, e ha funzionato bene per me, e ho pensato che meritasse un posto qui poiché molte persone guarderanno qui prima.

non solo trovo questa soluzione più elegante ma funziona perfettamente. Risolve anche un problema che ho avuto con la risposta di @ABentSpoon, ovvero che per gli indirizzi gmail in CC, le e-mail non andavano nella posta in arrivo ma in "Tutti i messaggi".
Guillaume Garrigos

18

La distinzione tra TO, CC e BCC si verifica solo nelle intestazioni di testo. A livello SMTP, tutti sono destinatari.

TO - C'è un'intestazione TO: con l'indirizzo di questo destinatario

CC - C'è un'intestazione CC: con l'indirizzo di questo destinatario

BCC: questo destinatario non è affatto menzionato nelle intestazioni, ma è comunque un destinatario.

Se hai

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

Hai tre destinatari. Le intestazioni nel corpo dell'e-mail includeranno solo TO: e CC:



5

Non ha funzionato per me fino a quando non ho creato:

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

e poi aggiunto cc nel destinatario [elenco] come:

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

2

Nessuna delle cose precedenti ha funzionato per me in quanto avevo più destinatari sia in "a" che in "cc". Quindi ho provato come di seguito:

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

ed estendi i "destinatari" con "cc_recipients" e invia la posta in modo banale

recipients.extend(cc_recipients)
server.sendmail(FROM,recipients,MESSAGE.as_string())
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.