2008-09-16 30 views
58

Si deseo enviar correo no a través de SMTP, sino a través de sendmail, ¿hay una biblioteca para python que encapsula este proceso?Enviando correo a través de sendmail desde python

Mejor aún, ¿hay una buena biblioteca que abstraiga toda la opción 'sendmail-revers-smtp'?

Voy a ejecutar esta secuencia de comandos en un montón de hosts Unix, solo algunos de los cuales están escuchando en localhost: 25; algunos de estos son parte de sistemas integrados y no se pueden configurar para aceptar SMTP.

Como parte de las Buenas prácticas, me gustaría que la biblioteca se ocupe de las vulnerabilidades de inyección de encabezado en sí misma, así que simplemente tirar una cadena a popen('/usr/bin/sendmail', 'w') está un poco más cerca del metal de lo que quisiera.

Si la respuesta es 'ir a escribir una biblioteca,' que así sea ;-)

Respuesta

97

inyección de cabecera no es un factor en la forma de enviar el correo, que es un factor en cómo se construye el correo. Comprobar el paquete email, construir el correo con eso, serializar, y enviarlo a /usr/sbin/sendmail utilizando el módulo subprocess:

from email.mime.text import MIMEText 
from subprocess import Popen, PIPE 

msg = MIMEText("Here is the body of my message") 
msg["From"] = "[email protected]" 
msg["To"] = "[email protected]" 
msg["Subject"] = "This is the subject." 
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE) 
p.communicate(msg.as_string()) 
+0

Perfecto. Mi problema conceptual fue separar la construcción y el envío de correo electrónico. ¡Gracias! – Nate

+3

nice, me ayudó hoy, después de 5 años de la respuesta :) – Peter

+10

También debe usar el parámetro '-oi' para sendmail. Esto detiene un solo '.' en su mensaje de terminación prematura del correo electrónico. –

3

Es bastante común que sólo tiene que utilizar el comando sendmail desde Python usando os.popen

En lo personal, para los scripts yo no Me escribo a mí mismo, creo que solo usar el protocolo SMTP es mejor, ya que no requeriría instalar, digamos, un clon de sendmail para ejecutar en Windows.

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

+0

SMTP no funciona en ~ cajas nix usando cosas como [DMA] (https: // github. com/corecode/dma), que proporciona sendmail, pero no escucha en el puerto 25 ... –

-6

La respuesta más fácil es la smtplib, se puede encontrar documentación sobre el mismo here.

Todo lo que necesita hacer es configurar su sendmail local para aceptar la conexión de localhost, que probablemente ya lo haga de forma predeterminada. Claro, todavía estás usando SMTP para la transferencia, pero es el sendmail local, que es básicamente lo mismo que usar la herramienta de línea de comandos.

+7

La pregunta dice "Si deseo enviar correos electrónicos no a través de SMTP, sino a través de sendmail ..." – S19N

+1

Su programa demorará en caso no hay conexión o retraso al servidor SMTP. Con sendmail, pasa el mensaje a MTA y su programa continúa. –

30

Esta es una función de python simple que utiliza el envío de correo de unix para entregar un correo.

def sendMail(): 
    sendmail_location = "/usr/sbin/sendmail" # sendmail location 
    p = os.popen("%s -t" % sendmail_location, "w") 
    p.write("From: %s\n" % "[email protected]") 
    p.write("To: %s\n" % "[email protected]") 
    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 
+0

realmente buena función de pitón! – aphex

+0

+1 - ¡justo lo que estoy buscando! –

+0

excelente, ejemplo simple +1 –

3

Esta pregunta es muy antiguo, pero que vale la pena tener en cuenta que hay una construcción de mensajes y correo sistema de entrega de correo llamado Marrow Mailer (anteriormente TurboMail) que ha estado disponible desde antes de que se le pidiera este mensaje.

Ahora está siendo portado para admitir Python 3 y actualizado como parte de la suite Marrow.

+0

El enlace de turboMail no va, un año después – TankorSmash

+2

Ahora se llama marrow.mailer. https://github.com/marrow/marrow.mailer – amcgregor

+0

+1 para Marrow Mailer. Lo probé, y hace que sea muy fácil enviar correo a través de smpt, sendmail, etc., y también proporciona una validación muy buena. Debido a que Marrow Mailer es "una buena biblioteca que abstrae toda la opción 'sendmail-revers-smtp'", creo que esto responde mejor a la pregunta original. – tjklemz

-3

Sólo estaba buscando alrededor por lo mismo y encontré un buen ejemplo en el sitio web de Python: http://docs.python.org/2/library/email-examples.html

Desde el sitio 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() 

Tenga en cuenta que esto requiere que usted tiene sendmail/mailx configurado correctamente para aceptar conexiones en "localhost". Esto funciona en mis servidores Mac, Ubuntu y Redhat de forma predeterminada, pero es posible que desee verificar si tiene algún problema.

+0

Esto sigue usando 'localhost' a través del protocolo SMTP. Y algunos usuarios no desean abrir el puerto 21, ni siquiera en el host local. – mbirth

6

La respuesta de Jim no funcionó en Python 3.4.He tenido que añadir un argumento adicional a universal_newlines=Truesubrocess.Popen()

from email.mime.text import MIMEText 
from subprocess import Popen, PIPE 

msg = MIMEText("Here is the body of my message") 
msg["From"] = "[email protected]" 
msg["To"] = "[email protected]" 
msg["Subject"] = "This is the subject." 
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE, universal_newlines=True) 
p.communicate(msg.as_string()) 

Sin la universal_newlines=True consigo

TypeError: 'str' does not support the buffer interface 
Cuestiones relacionadas