python: ¿cómo enviar correo con TO, CC y BCC?

102

Necesito, con fines de prueba, llenar unos cientos de buzones de correo electrónico con varios mensajes, e iba a usar smtplib para eso. Pero, entre otras cosas, necesito poder enviar mensajes no solo A buzones de correo específicos, sino también CC y CCO. No parece que smtplib admita CC-ing y BCC-ing al enviar correos electrónicos.

Buscando sugerencias sobre cómo enviar mensajes en CC o CCO desde el script de Python.

(Y no, no estoy creando un script para enviar spam a nadie fuera de mi entorno de prueba).

usuario63503
fuente

Respuestas:

150

Los encabezados de correo electrónico no son importantes para el servidor smtp. Simplemente agregue los destinatarios CC y CCO a los toaddrs cuando envíe su correo electrónico. Para CC, agréguelos al encabezado 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
fuente
smtplib.SMTP no envía listas de direcciones. Al menos no en Python 2.7.2
LostMohican
En este caso, el encabezado BCC mencionado en el RFC 2822 no tiene ningún sentido.
Chenxiong Qi
1
@ABentSpoon faltan dos puntos después de 'Asunto'.
user891260
3
No agregue el encabezado Bcc. Vea esto: mail.python.org/pipermail/email-sig/2004-September/000151.html Y esto: "" "Observe que el segundo argumento de sendmail (), los destinatarios, se pasa como una lista. Puede incluir cualquier número de direcciones en la lista para que el mensaje se entregue a cada una de ellas por turno. Dado que la información del sobre está separada de los encabezados del mensaje, puede incluso CCO a alguien incluyéndolo en el argumento del método pero no en el encabezado del mensaje ". "" de pymotw.com/2/smtplib
Leonardo Andrade
2
Esto nunca será BCC o CC - siempre será To
ProsperousHeart
37

La clave es agregar los destinatarios como una lista de ID de correo electrónico en su llamada de 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
fuente
4
Deje la opción msg['BCC']desactivada: revela su remitente oculto y no tiene ningún impacto en si el mensaje se le envía o no (los argumentos para sendmailhacerlo).
Erica Kane
2
Estoy de acuerdo con Erica y Julio. La intención de Bcc es ocultar el receptor a otros receptores. Si está en el mensaje, eso frustra el propósito.
Timothy C. Quinn
19

No agregue el encabezado Bcc.

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

Y esto: "" "Observe que el segundo argumento de sendmail (), los destinatarios, se pasa como una lista. Puede incluir cualquier número de direcciones en la lista para que el mensaje se entregue a cada uno de ellos. Dado que el sobre la información está separada de los encabezados de los mensajes, incluso puede BCC a alguien incluyéndolo en el argumento del método pero no en el encabezado del mensaje. "" "de 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
fuente
Aprobado por el estilo: D
Chris
19

A partir de Python 3.2, lanzado en noviembre de 2011, smtplib tiene una nueva función en send_messagelugar de solo sendmail, lo que facilita el manejo de To / CC / BCC. Extrayendo de los ejemplos de correo electrónico oficiales de Python , con algunas pequeñas modificaciones, obtenemos:

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

El uso de los encabezados funciona bien, porque send_message respeta BCC como se describe en la documentación :

send_message no transmite ningún encabezado Bcc o Resent-Bcc que pueda aparecer en msg


Con sendmailera común agregar los encabezados CC al mensaje, haciendo algo como:

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

O

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

El problema es que la función sendmail trata todos esos encabezados de la misma manera, lo que significa que se enviarán (visiblemente) a todos los usuarios de To: y BCC:, anulando los propósitos de BCC. La solución, como se muestra en muchas de las otras respuestas aquí, fue no incluir BCC en los encabezados y, en cambio, solo en la lista de correos electrónicos pasados sendmail.

La advertencia es que send_messagerequiere un objeto Message, lo que significa que deberá importar una clase desde en email.messagelugar de simplemente pasar cadenas a sendmail.


fuente
2
Acabo de verificar que send_message (msg) maneja los cc agregados al EmailMessage - msg ['Cc'] Si está usando Python 3, este es el camino a seguir.
bmiller
@bmiller Sí, bastante útil. Escribí esta respuesta porque estaba investigando y encontré la forma más simple en los documentos y otras referencias, y funcionó bien para mí, y pensé que merecía un lugar aquí ya que muchas personas buscarán aquí primero.
no solo encuentro esta solución más elegante sino que funciona perfectamente. También resuelve un problema que tuve con la respuesta de @ABentSpoon, que es que para las direcciones de Gmail en CC, los correos electrónicos no iban a la bandeja de entrada, sino a "Todos los correos".
Guillaume Garrigos
18

La distinción entre TO, CC y BCC se produce solo en los encabezados de texto. En el nivel SMTP, todos son destinatarios.

TO: hay un encabezado TO: con la dirección de este destinatario

CC: hay un encabezado CC: con la dirección de este destinatario

CCO: este destinatario no se menciona en los encabezados, pero sigue siendo un destinatario.

Si usted tiene

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

Tienes tres destinatarios. Los encabezados en el cuerpo del correo electrónico incluirán solo TO: y CC:

Jim Garrison
fuente
16

Puedes probar MIMEText

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

luego envía msg.as_string ()

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

foosion
fuente
4
ese ejemplo no usa CC
hoju
1
Estoy de acuerdo en que los ejemplos del enlace anterior no tratan CCO. Esto es lo que probablemente quiso decir @hoju.
Shailen
5

No funcionó para mí hasta que creé:

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

y luego agregó cc en el destinatario [lista] como:

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

Ninguna de las cosas anteriores funcionó para mí, ya que tenía varios destinatarios tanto en 'a' como en 'cc'. Así que intenté como a continuación:

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

y extender los 'destinatarios' con 'cc_recipients' y enviar correo de manera trivial

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