python: как отправлять почту с TO, CC и BCC?

105

Мне нужно в целях тестирования заполнить несколько сотен почтовых ящиков различными сообщениями, и я собирался использовать для этого smtplib. Но, помимо прочего, мне нужно иметь возможность отправлять сообщения не только в определенные почтовые ящики, но и в CC и BCC. Не похоже, что smtplib поддерживает CC-ing и BCC-ing при отправке электронных писем.

Ищете предложения, как сделать CC или BCC отправку сообщений из скрипта python.

(И - нет, я не создаю скрипт для рассылки спама кому-либо за пределами моей тестовой среды.)

user63503
источник

Ответы:

151

Заголовки электронной почты не имеют значения для 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()
ABentSpoon
источник
smtplib.SMTP не рассылает списки по адресам. По крайней мере, не на python 2.7.2
LostMohican
В этом случае заголовок BCC, упомянутый в RFC 2822, не имеет никакого смысла.
Chenxiong Qi
1
@ABentSpoon отсутствует двоеточие после «Тема».
user891260
3
Не добавляйте заголовок скрытой копии. См. Это: mail.python.org/pipermail/email-sig/2004-September/000151.html И это: "" "Обратите внимание, что второй аргумент sendmail (), получатели, передается в виде списка. Вы можете включить любое количество адресов в списке, чтобы сообщение было доставлено каждому из них по очереди. Поскольку информация в конверте отделена от заголовков сообщения, вы можете даже скрыть кого-либо, включив их в аргумент метода, но не в заголовок сообщения ». "" от pymotw.com/2/smtplib
Леонардо Андраде,
2
Это никогда не будет BCC или CC - это всегда будет To
ProsperousHeart
37

Ключевым моментом является добавление получателей в список идентификаторов электронной почты в вызове 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()
helios
источник
4
Оставьте этот параметр msg['BCC']выключенным - он показывает вашего скрытого отправителя и не влияет на то, отправлено ему сообщение или нет (аргументы для sendmailэтого).
Эрика Кейн
2
Я согласен с Эрикой и Хулио. Назначение скрытой копии - скрыть получателя от других получателей. Если он находится в сообщении, это противоречит цели.
Тимоти К. Куинн
19

Не добавляйте заголовок скрытой копии.

Смотрите это: http://mail.python.org/pipermail/email-sig/2004-September/000151.html

И это: "" "Обратите внимание, что второй аргумент sendmail (), получатели, передается в виде списка. Вы можете включить любое количество адресов в список, чтобы сообщение было доставлено каждому из них по очереди. Поскольку конверт информация отделена от заголовков сообщений, вы можете даже скрыть кого-то, включив их в аргумент метода, но не в заголовок сообщения. "" "из 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
Крис
19

Начиная с Python 3.2, выпущенного в ноябре 2011 года, smtplib имеет новую функцию send_messageвместо just 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, которые могут появляться в сообщении.


С 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:, что противоречит целям BCC. Решение, как показано во многих других ответах здесь, заключалось в том, чтобы не включать BCC в заголовки, а вместо этого только в список отправленных писем sendmail.

Предостережение заключается в том, что send_messageтребуется объект Message, то есть вам нужно будет импортировать класс из, email.messageа не просто передавать строки в sendmail.


источник
2
Только что проверили, что send_message (msg) обрабатывает cc, добавленные в EmailMessage - msg ['Cc'] Если вы используете Python 3, это правильный путь.
bmiller 08
@bmiller Ага, очень удобно. Я написал этот ответ, потому что я изучал его и нашел более простой способ в документации и других справочных материалах, и он хорошо сработал для меня, и я подумал, что он заслуживает места здесь, так как многие люди будут смотреть здесь 1-го.
не только я считаю это решение более элегантным, но и отлично работает. Это также решает проблему, с которой я столкнулся с ответом @ABentSpoon, а именно, что для адресов Gmail в CC электронные письма не попадают во входящие, а вместо этого помещаются в "Вся почта".
Гийом Гарригос,
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
Я согласен с тем, что примеры по приведенной выше ссылке не относятся к Bcc. Вероятно, это имел в виду @hoju.
Шайлен
5

У меня это не сработало, пока я не создал:

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

и затем добавил копию в [список] получателей, например:

s.sendmail(me, [you,cc], msg.as_string())
marko_b123
источник
2

Ничего из вышеперечисленного у меня не сработало, так как у меня было несколько получателей как в «Кому», так и в «Копия». Итак, я попробовал, как показано ниже:

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())
Чан Гайквад
источник