python: จะส่งเมลด้วย TO, CC และ BCC ได้อย่างไร?


106

ฉันต้องการวัตถุประสงค์ในการทดสอบเพื่อเติมกล่องอีเมลสองสามร้อยกล่องพร้อมข้อความต่างๆและกำลังจะใช้ smtplib แต่เหนือสิ่งอื่นใดฉันต้องสามารถส่งข้อความได้ไม่เพียง แต่ไปยังกล่องจดหมายที่ระบุเท่านั้น แต่ยังมี CC และ BCC ด้วย ดูเหมือนว่าsmtplibจะไม่รองรับ CC-ing และ BCC-ing ขณะส่งอีเมล

กำลังมองหาคำแนะนำในการทำ CC หรือ BCC ส่งข้อความจากสคริปต์ python

(และ - ไม่ฉันไม่ได้สร้างสคริปต์เพื่อสแปมใครก็ตามที่อยู่นอกสภาพแวดล้อมการทดสอบของฉัน)

คำตอบ:


153

ส่วนหัวของอีเมลไม่สำคัญกับเซิร์ฟเวอร์ smtp เพียงเพิ่มผู้รับ CC และ BCC ลงใน toaddrs เมื่อคุณส่งอีเมล สำหรับ CC ให้เพิ่มลงในส่วนหัว 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 ไม่ส่งรายการตามที่อยู่ อย่างน้อยก็ไม่ใช่ใน python 2.7.2
LostMohican

ในกรณีนี้ส่วนหัว BCC ที่กล่าวถึงใน RFC 2822 ไม่สมเหตุสมผล
Chenxiong Qi

1
@ABentSpoon ลำไส้ใหญ่หายไปหลัง "Subject"
user891260

3
อย่าเพิ่มส่วนหัว bcc ดูสิ่งนี้: mail.python.org/pipermail/email-sig/2004-September/000151.html และสิ่งนี้: "" "โปรดสังเกตว่าอาร์กิวเมนต์ที่สองที่ส่งไปยัง sendmail () ผู้รับจะถูกส่งเป็นรายการคุณสามารถรวม ที่อยู่จำนวนเท่าใดก็ได้ในรายการเพื่อให้ส่งข้อความไปยังแต่ละที่อยู่เนื่องจากข้อมูลซองจดหมายแยกจากส่วนหัวของข้อความคุณจึงสามารถแม้แต่ BCC บุคคลอื่นได้โดยรวมไว้ในอาร์กิวเมนต์ของวิธีการ แต่จะไม่อยู่ในส่วนหัวของข้อความ " "" จากpymotw.com/2/smtplib
Leonardo Andrade

2
สิ่งนี้จะไม่ BCC หรือ CC - มันจะเป็นถึง
ProsperousHeart

37

สิ่งสำคัญคือการเพิ่มผู้รับเป็นรายการรหัสอีเมลในการโทรของคุณ

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
ทิ้งmsg['BCC']ไว้ - มันจะเปิดเผยผู้ส่งที่ซ่อนอยู่ของคุณและไม่มีผลกระทบต่อว่าข้อความจะถูกส่งถึงพวกเขาหรือไม่ (ข้อโต้แย้งที่ต้องsendmailทำ)
Erica Kane

2
ฉันเห็นด้วยกับ Erica และ Julio เจตนาของสำเนาลับคือการซ่อนผู้รับไปยังเครื่องรับอื่น ๆ หากอยู่ในข้อความแสดงว่าผิดวัตถุประสงค์
Timothy C. Quinn

21

ในขณะที่ Python 3.2 เผยแพร่เมื่อพฤศจิกายน 2554 smtplib มีฟังก์ชันใหม่send_messageแทนที่จะเป็นเพียงแค่sendmailซึ่งทำให้การจัดการกับ To / CC / BCC ง่ายขึ้น จากตัวอย่างอีเมลทางการของ Pythonโดยมีการปรับเปลี่ยนเล็กน้อยเราจะได้รับ:

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

การใช้ส่วนหัวทำงานได้ดีเนื่องจากsend_message เคารพ BCC ตามที่ระบุไว้ในเอกสารประกอบ :

send_message ไม่ส่งส่วนหัว Bcc หรือ Resent-Bcc ที่อาจปรากฏใน msg


เนื่องจากsendmailเป็นเรื่องปกติที่จะเพิ่มส่วนหัว CC ลงในข้อความโดยทำบางสิ่งเช่น:

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

หรือ

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"

ปัญหาคือฟังก์ชัน sendmail จะปฏิบัติต่อส่วนหัวทั้งหมดเหมือนกันซึ่งหมายความว่าจะถูกส่ง (อย่างเห็นได้ชัด) ไปยัง To: และ BCC: users ซึ่งเอาชนะวัตถุประสงค์ของ BCC การแก้ปัญหาดังแสดงในหลายคำตอบอื่น ๆ ที่นี่ก็จะไม่รวมอยู่ในส่วนหัว BCC sendmailและแทนที่จะเฉพาะในรายชื่ออีเมลที่ส่งผ่านไปยัง

ข้อแม้คือsend_messageต้องใช้วัตถุข้อความซึ่งหมายความว่าคุณจะต้องนำเข้าคลาสจากemail.messageแทนที่จะส่งผ่านสตริงเข้าไปsendmailเท่านั้น


2
เพิ่งตรวจสอบว่า send_message (msg) จัดการ cc ที่เพิ่มใน EmailMessage - msg ['Cc'] หากคุณใช้ Python 3 นี่คือวิธีที่จะไป
bmiller

@bmiller ใช่มีประโยชน์มาก ฉันเขียนคำตอบนี้ขึ้นมาเพราะฉันกำลังตรวจสอบและพบวิธีที่ง่ายกว่าในเอกสารและเอกสารอ้างอิงอื่น ๆ และมันก็ใช้ได้ดีสำหรับฉันและฉันคิดว่ามันสมควรได้รับที่นี่เพราะหลาย ๆ คนจะมาดูที่นี่ที่ 1

ไม่เพียง แต่ฉันพบว่าโซลูชันนี้ดูหรูหรากว่า แต่ทำงานได้อย่างสมบูรณ์ นอกจากนี้ยังช่วยแก้ปัญหาที่ฉันมีด้วยคำตอบโดย @ABentSpoon ซึ่งสำหรับที่อยู่ Gmail ใน CC อีเมลจะไม่อยู่ในกล่องจดหมาย แต่เปลี่ยนเป็น "จดหมายทั้งหมด" แทน
Guillaume Garrigos

19

อย่าเพิ่มส่วนหัว bcc

ดูสิ่งนี้: http://mail.python.org/pipermail/email-sig/2004-September/000151.html

และสิ่งนี้: "" "โปรดสังเกตว่าอาร์กิวเมนต์ที่สองที่ส่งไปยัง sendmail () ผู้รับจะถูกส่งผ่านเป็นรายการคุณสามารถรวมที่อยู่จำนวนเท่าใดก็ได้ในรายการเพื่อให้มีการส่งข้อความถึงแต่ละคนในทางกลับกันตั้งแต่ซองจดหมาย ข้อมูลแยกจากส่วนหัวของข้อความคุณยังสามารถ BCC บุคคลอื่นได้โดยรวมไว้ในอาร์กิวเมนต์เมธอด แต่ไม่รวมอยู่ในส่วนหัวของข้อความ "" "จาก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()

ยกนิ้วให้กับไหวพริบ: D
คริส

18

ความแตกต่างระหว่าง TO, CC และ BCC เกิดขึ้นเฉพาะในส่วนหัวของข้อความ ในระดับ SMTP ทุกคนเป็นผู้รับ

TO - มีส่วนหัว TO: พร้อมที่อยู่ของผู้รับนี้

CC - มี CC: ส่วนหัวพร้อมที่อยู่ของผู้รับนี้

BCC - ผู้รับรายนี้ไม่ได้กล่าวถึงในส่วนหัวเลย แต่ยังคงเป็นผู้รับ

ถ้าคุณมี

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

คุณมีผู้รับสามคน ส่วนหัวในเนื้อหาอีเมลจะรวมเฉพาะ TO: และ CC:


17

คุณสามารถลอง MIMEText

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

จากนั้นส่ง msg.as_string ()

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


4
ตัวอย่างนั้นไม่ใช้ CC
hoju

1
ฉันยอมรับว่าตัวอย่างในลิงก์ด้านบนไม่ถือว่าเป็นสำเนาลับ นี่คือสิ่งที่ @hoju อาจหมายถึง
Shailen

5

มันไม่ได้ผลสำหรับฉันจนกว่าฉันจะสร้าง:

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

และมากกว่า cc ที่เพิ่มในผู้รับ [list] เช่น:

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

2

สิ่งต่างๆข้างต้นไม่ได้ผลสำหรับฉันเนื่องจากฉันมีผู้รับหลายคนทั้งใน 'ถึง' และ 'cc' ดังนั้นฉันจึงลองทำดังนี้:

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

และขยาย 'ผู้รับ' ด้วย 'cc_recipients' และส่งอีเมลในลักษณะเล็กน้อย

recipients.extend(cc_recipients)
server.sendmail(FROM,recipients,MESSAGE.as_string())
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.