Отправка почты через sendmail из python - PullRequest
69 голосов
/ 16 сентября 2008

Если я хочу отправлять почту не через SMTP, а через sendmail, есть ли библиотека для python, которая инкапсулирует этот процесс?

Еще лучше, есть ли хорошая библиотека, которая абстрагирует весь выбор 'sendmail -versus- smtp'?

Я буду запускать этот сценарий на нескольких хостах Unix, только некоторые из которых прослушивают localhost: 25; некоторые из них являются частью встроенных систем и не могут быть настроены для приема SMTP.

Как часть хорошей практики, мне бы очень хотелось, чтобы библиотека сама позаботилась об уязвимостях внедрения заголовков - так что простой вывод строки в popen('/usr/bin/sendmail', 'w') немного ближе к металлу, чем хотелось бы. 1008 *

Если ответ «напиши библиотеку», пусть будет так; -)

Ответы [ 7 ]

114 голосов
/ 16 сентября 2008

Инъекция заголовка не является фактором, определяющим, как вы отправляете почту, а фактором, определяющим, как вы создаете почту. Проверьте пакет email , составьте письмо с ним, сериализуйте его и отправьте на /usr/sbin/sendmail с помощью модуля subprocess :

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())
32 голосов
/ 16 сентября 2008

Это простая функция 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
10 голосов
/ 20 сентября 2015

Ответ Джима не работал для меня в 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
3 голосов
/ 05 апреля 2011

Этот вопрос очень старый, но стоит отметить, что существует система создания сообщений и доставки электронной почты под названием Marrow Mailer (ранее TurboMail), которая была доступна еще до того, как было запрошено это сообщение.

Теперь он портирован для поддержки Python 3 и обновлен как часть Marrow suite.

3 голосов
/ 16 сентября 2008

Довольно часто просто использовать команду sendmail из Python, используя os.popen

Лично для сценариев, которые я не писал сам, я думаю, что лучше просто использовать SMTP-протокол, так как для его запуска не требуется установка, скажем, клона sendmail для запуска в Windows.

https://docs.python.org/library/smtplib.html

0 голосов
/ 27 июня 2013

Я просто искал то же самое и нашел хороший пример на сайте 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 по умолчанию, но вы можете перепроверить, если у вас возникнут какие-либо проблемы.

0 голосов
/ 16 сентября 2008

Самый простой ответ - smtplib, на нем вы можете найти документы здесь .

Все, что вам нужно сделать, это настроить локальный sendmail на прием соединения от localhost, что, вероятно, уже выполняется по умолчанию. Конечно, вы все еще используете SMTP для передачи, но это локальный sendmail, который в основном такой же, как и инструмент командной строки.

...