Enviando e-mail via sendmail de python
Pergunta
Se eu quiser enviar e-mails não via SMTP, mas sim via sendmail, existe uma biblioteca para python que encapsula esse processo?
Melhor ainda, existe uma boa biblioteca que abstraia toda a escolha 'sendmail -versus- smtp'?
Estarei executando este script em vários hosts unix, dos quais apenas alguns estão escutando em localhost:25;alguns deles fazem parte de sistemas embarcados e não podem ser configurados para aceitar SMTP.
Como parte das Boas Práticas, eu realmente gostaria que a biblioteca cuidasse das vulnerabilidades de injeção de cabeçalho por si só - basta despejar uma string para popen('/usr/bin/sendmail', 'w')
está um pouco mais próximo do metal do que eu gostaria.
Se a resposta for 'vá escrever uma biblioteca', que assim seja ;-)
Solução
A injeção de cabeçalho não é um fator na forma como você envia o e-mail, mas sim em como você constrói o e-mail.Verifica a e-mail pacote, construa o e-mail com ele, serialize-o e envie-o para /usr/sbin/sendmail
usando o subprocesso módulo:
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())
Outras dicas
Esta é uma função python simples que usa o sendmail unix para entregar um email.
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
A resposta de Jim não funcionou para mim no Python 3.4.Eu tive que adicionar um adicional universal_newlines=True
argumento para 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())
Sem o universal_newlines=True
eu recebo
TypeError: 'str' does not support the buffer interface
É bastante comum usar apenas o comando sendmail do Python usando os.popen
Pessoalmente, para scripts que eu não escrevi, acho que apenas usar o protocolo SMTP é melhor, já que não seria necessário instalar, digamos, um clone do sendmail para rodar no Windows.
Esta questão é muito antiga, mas vale ressaltar que existe um sistema de construção de mensagens e entrega de e-mails chamado Mensageiro de Medula (anteriormente TurboMail) que está disponível desde antes desta mensagem ser solicitada.
Agora está sendo portado para suportar Python 3 e atualizado como parte do Medula suíte.
Eu estava pesquisando a mesma coisa e encontrei um bom exemplo no site do Python: http://docs.python.org/2/library/email-examples.html
Do site mencionado:
# 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()
Observe que isso requer que você tenha o sendmail/mailx configurado corretamente para aceitar conexões em "localhost".Isso funciona em meus servidores Mac, Ubuntu e Redhat por padrão, mas você pode querer verificar novamente se tiver algum problema.
A resposta mais fácil é o smtplib, você pode encontrar documentos sobre ele aqui.
Tudo que você precisa fazer é configurar seu sendmail local para aceitar a conexão do localhost, o que provavelmente já faz por padrão.Claro, você ainda está usando SMTP para a transferência, mas é o sendmail local, que é basicamente o mesmo que usar a ferramenta de linha de comando.