Отправка почты через sendmail из python
Вопрос
Если я хочу отправлять почту не через SMTP, а скорее через sendmail, есть ли библиотека для python, которая инкапсулирует этот процесс?
А еще лучше, есть ли хорошая библиотека, которая абстрагирует весь выбор между sendmail и smtp?
Я буду запускать этот скрипт на нескольких хостах unix, только некоторые из которых прослушиваются на localhost:25;некоторые из них являются частью встроенных систем и не могут быть настроены на прием SMTP.
Как часть хорошей практики, я бы действительно хотел, чтобы библиотека сама позаботилась об уязвимостях при внедрении заголовка - поэтому просто сбрасываю строку в popen('/usr/bin/sendmail', 'w')
немного ближе к металлу, чем мне бы хотелось.
Если ответ будет "иди напиши библиотеку", пусть будет так ;-)
Решение
Внедрение заголовка - это не фактор того, как вы отправляете почту, это фактор того, как вы создаете почту.Проверьте Адрес электронной почты упакуйте, создайте из этого письмо, сериализуйте его и отправьте по адресу /usr/sbin/sendmail
используя подпроцесс модуль:
from email.mime.text import MIMEText
from subprocess import Popen, PIPE
msg = MIMEText("Here is the body of my message")
msg["From"] = "me@example.com"
msg["To"] = "you@example.com"
msg["Subject"] = "This is the subject."
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
p.communicate(msg.as_string())
Другие советы
Это простая функция Python, которая использует unix sendmail для доставки почты.
def sendMail():
sendmail_location = "/usr/sbin/sendmail" # sendmail location
p = os.popen("%s -t" % sendmail_location, "w")
p.write("From: %s\n" % "from@somewhere.com")
p.write("To: %s\n" % "to@somewhereelse.com")
p.write("Subject: thesubject\n")
p.write("\n") # blank line separating headers from body
p.write("body of the mail")
status = p.close()
if status != 0:
print "Sendmail exit status", status
Ответ Джима не сработал для меня в Python 3.4.Мне пришлось добавить дополнительный universal_newlines=True
аргумент в пользу subrocess.Popen()
from email.mime.text import MIMEText
from subprocess import Popen, PIPE
msg = MIMEText("Here is the body of my message")
msg["From"] = "me@example.com"
msg["To"] = "you@example.com"
msg["Subject"] = "This is the subject."
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE, universal_newlines=True)
p.communicate(msg.as_string())
Без universal_newlines=True
Я получаю
TypeError: 'str' does not support the buffer interface
Довольно часто можно просто использовать команду sendmail из Python, используя os.popen
Лично для сценариев, которые я не писал сам, я думаю, что лучше просто использовать SMTP-протокол, поскольку для этого не потребуется устанавливать, скажем, клон sendmail для запуска в Windows.
Этот вопрос очень старый, но стоит отметить, что существует система создания сообщений и доставки электронной почты под названием Почтовый ящик для Костного мозга (ранее TurboMail), который был доступен еще до того, как было запрошено это сообщение.
Сейчас он портирован для поддержки Python 3 и обновляется как часть Костный мозг люкс.
Я просто искал то же самое и нашел хороший пример на веб-сайте Python: http://docs.python.org/2/library/email-examples.html
С упомянутого сайта:
# Import smtplib for the actual sending function
import smtplib
# Import the email modules we'll need
from email.mime.text import MIMEText
# Open a plain text file for reading. For this example, assume that
# the text file contains only ASCII characters.
fp = open(textfile, 'rb')
# Create a text/plain message
msg = MIMEText(fp.read())
fp.close()
# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you
# Send the message via our own SMTP server, but don't include the
# envelope header.
s = smtplib.SMTP('localhost')
s.sendmail(me, [you], msg.as_string())
s.quit()
Обратите внимание, что для этого требуется, чтобы у вас был правильно настроен sendmail / mailx для приема подключений на "localhost".По умолчанию это работает на моих серверах Mac, Ubuntu и Redhat, но вы можете захотеть перепроверить, если у вас возникнут какие-либо проблемы.
Самый простой ответ - smtplib, вы можете найти документы по нему здесь.
Все, что вам нужно сделать, это настроить вашу локальную почту sendmail на прием соединения с localhost, что она, вероятно, уже делает по умолчанию.Конечно, вы по-прежнему используете SMTP для передачи, но это локальная электронная почта, которая в основном такая же, как при использовании инструмента командной строки.