python: bagaimana cara mengirim email dengan TO, CC dan BCC?

102

Saya perlu untuk tujuan pengujian untuk mengisi beberapa ratus kotak email dengan berbagai pesan, dan akan menggunakan smtplib untuk itu. Tetapi di antara hal-hal lain saya harus dapat mengirim pesan tidak hanya KE kotak surat tertentu, tetapi juga CC dan BCC. Sepertinya smtplib tidak mendukung CC-ing dan BCC-ing saat mengirim email.

Mencari saran bagaimana melakukan CC atau BCC mengirim pesan dari script python.

(Dan - tidak, saya tidak membuat skrip untuk mengirim spam kepada siapa pun di luar lingkungan pengujian saya.)

pengguna63503
sumber

Jawaban:

150

Header email tidak penting bagi server smtp. Cukup tambahkan penerima CC dan BCC ke toaddr saat Anda mengirim email. Untuk CC, tambahkan ke header 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
sumber
smtplib.SMTP tidak mengirim daftar sebagai alamat. Setidaknya tidak pada python 2.7.2
LostMohican
Dalam kasus ini, header BCC yang disebutkan di RFC 2822 tidak masuk akal.
Chenxiong Qi
1
@ABentSpoon titik dua hilang setelah 'Subjek'.
pengguna891260
3
Jangan tambahkan header bcc. Lihat ini: mail.python.org/pipermail/email-sig/2004-September/000151.html Dan ini: "" "Perhatikan bahwa argumen kedua untuk sendmail (), penerima, diteruskan sebagai daftar. Anda dapat memasukkan sejumlah alamat dalam daftar agar pesan dikirim ke masing-masing secara bergiliran. Karena informasi amplop terpisah dari tajuk pesan, Anda bahkan dapat BCC seseorang dengan memasukkan mereka dalam argumen metode tetapi tidak di tajuk pesan. " "" dari pymotw.com/2/smtplib
Leonardo Andrade
2
Ini tidak akan pernah BCC atau CC - itu akan selalu To
ProsperousHeart
37

Kuncinya adalah menambahkan penerima sebagai daftar id email di panggilan sendmail Anda.

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
sumber
4
Biarkan msg['BCC']off - ini mengungkapkan pengirim tersembunyi Anda dan tidak berdampak pada apakah pesan tersebut dikirim kepada mereka atau tidak (argumen untuk sendmailmelakukan itu).
Erica Kane
2
Saya Setuju dengan Erica dan Julio. Maksud dari Bcc adalah menyembunyikan penerima ke penerima lain. Jika itu ada dalam pesan, itu mengalahkan tujuannya.
Timothy C. Quinn
19

Jangan tambahkan header bcc.

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

Dan ini: "" "Perhatikan bahwa argumen kedua untuk sendmail (), penerima, diteruskan sebagai daftar. Anda dapat menyertakan sejumlah alamat dalam daftar agar pesan dikirimkan ke masing-masing secara bergiliran. Sejak amplop Informasi terpisah dari header pesan, Anda bahkan dapat BCC seseorang dengan memasukkan mereka dalam argumen metode tetapi tidak di header pesan. "" "dari 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
sumber
Jempol untuk bakat: D
Chris
19

Sejak Python 3.2, dirilis November 2011, smtplib memiliki fungsi baru, send_messagebukan hanya sendmail, yang membuat berurusan dengan To / CC / BCC lebih mudah. Menarik dari contoh email resmi Python , dengan sedikit modifikasi, kami mendapatkan:

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

Menggunakan header berfungsi dengan baik, karena send_message menghormati BCC seperti yang diuraikan dalam dokumentasi :

send_message tidak mengirimkan header Bcc atau Resent-Bcc apa pun yang mungkin muncul di pesan


Dengan sendmailmenambahkan header CC ke pesan, melakukan sesuatu seperti:

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

Atau

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

Masalahnya adalah, fungsi sendmail memperlakukan semua header tersebut dengan sama, artinya mereka akan dikirim (terlihat) ke semua To: dan BCC: users, mengalahkan tujuan BCC. Solusinya, seperti yang ditunjukkan dalam banyak jawaban lain di sini, adalah tidak menyertakan BCC di tajuk, dan sebagai gantinya hanya dalam daftar email yang diteruskan sendmail.

Peringatannya adalah itu send_messagemembutuhkan objek Message, yang berarti Anda harus mengimpor kelas dari email.messagealih-alih hanya meneruskan string ke dalamnya sendmail.


sumber
2
Baru saja memverifikasi bahwa send_message (msg) menangani cc yang ditambahkan ke EmailMessage - msg ['Cc'] Jika Anda menggunakan Python 3, inilah cara yang harus dilakukan.
bmiller
@bmiller Yup, cukup berguna. Saya menulis jawaban ini karena saya sedang mencarinya dan menemukan cara yang lebih sederhana di dokumen dan referensi lain, dan itu bekerja dengan baik untuk saya, dan saya pikir itu pantas mendapat tempat di sini karena banyak orang akan melihat di sini 1.
tidak hanya saya menemukan solusi ini lebih elegan tetapi juga bekerja dengan sempurna. Ini juga memecahkan masalah yang saya alami dengan jawaban dari @ABentSpoon, yaitu untuk alamat gmail di CC, email tidak masuk ke kotak masuk tetapi malah memasukkan "Semua Surat".
Guillaume Garrigos
18

Perbedaan antara TO, CC, dan BCC hanya terjadi di header teks. Di tingkat SMTP, setiap orang adalah penerima.

TO - Ada header TO: dengan alamat penerima ini

CC - Ada header CC: dengan alamat penerima ini

BCC - Penerima ini sama sekali tidak disebutkan di tajuk, tetapi masih menjadi penerima.

Jika Anda memiliki

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

Anda memiliki tiga penerima. Header di badan email hanya akan menyertakan KEPADA: dan CC:

Jim Garrison
sumber
16

Anda dapat mencoba MIMEText

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

lalu kirim msg.as_string ()

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

foosion
sumber
4
contoh itu tidak menggunakan CC
hoju
1
Saya setuju bahwa contoh pada tautan di atas tidak memperlakukan Bcc. Mungkin inilah yang dimaksud @hoju.
Shailen
5

Itu tidak berhasil untuk saya sampai saya membuat:

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

dan dari menambahkan cc di penerima [daftar] seperti:

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

Tak satu pun dari hal-hal di atas berhasil untuk saya karena saya memiliki banyak penerima baik di 'to' dan 'cc'. Jadi saya coba seperti di bawah ini:

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

dan kembangkan 'penerima' dengan 'cc_recipients' dan kirim email dengan cara yang sepele

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