sent - Un servidor SMTP simple(en Python)
send mails in python (8)
¿Podría, por favor, sugerir un servidor SMTP simple con las API muy básicas (por muy básico, leer, escribir, eliminar correo electrónico), que podría ejecutarse en una caja de Linux? Solo necesito convertir el quid del correo electrónico al formato XML y enviarlo por FTP a otra máquina.
Dos servidores Python Smtp que he usado con éxito son:
- Twisted''s Mail - Una biblioteca de correo muy flexible para SMTP, IMAP, ...
- python-slimta - Un MTA completo (servidor de retransmisión / reenvío smtp)
El ejemplo de Twisted se muestra abajo.
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
# You can run this module directly with:
# twistd -ny emailserver.tac
"""
A toy email server.
"""
from __future__ import print_function
from zope.interface import implementer
from twisted.internet import defer
from twisted.mail import smtp
from twisted.mail.imap4 import LOGINCredentials, PLAINCredentials
from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse
from twisted.cred.portal import IRealm
from twisted.cred.portal import Portal
@implementer(smtp.IMessageDelivery)
class ConsoleMessageDelivery:
def receivedHeader(self, helo, origin, recipients):
return "Received: ConsoleMessageDelivery"
def validateFrom(self, helo, origin):
# All addresses are accepted
return origin
def validateTo(self, user):
# Only messages directed to the "console" user are accepted.
if user.dest.local == "console":
return lambda: ConsoleMessage()
raise smtp.SMTPBadRcpt(user)
@implementer(smtp.IMessage)
class ConsoleMessage:
def __init__(self):
self.lines = []
def lineReceived(self, line):
self.lines.append(line)
def eomReceived(self):
print("New message received:")
print("/n".join(self.lines))
self.lines = None
return defer.succeed(None)
def connectionLost(self):
# There was an error, throw away the stored lines
self.lines = None
class ConsoleSMTPFactory(smtp.SMTPFactory):
protocol = smtp.ESMTP
def __init__(self, *a, **kw):
smtp.SMTPFactory.__init__(self, *a, **kw)
self.delivery = ConsoleMessageDelivery()
def buildProtocol(self, addr):
p = smtp.SMTPFactory.buildProtocol(self, addr)
p.delivery = self.delivery
p.challengers = {"LOGIN": LOGINCredentials, "PLAIN": PLAINCredentials}
return p
@implementer(IRealm)
class SimpleRealm:
def requestAvatar(self, avatarId, mind, *interfaces):
if smtp.IMessageDelivery in interfaces:
return smtp.IMessageDelivery, ConsoleMessageDelivery(), lambda: None
raise NotImplementedError()
def main():
from twisted.application import internet
from twisted.application import service
portal = Portal(SimpleRealm())
checker = InMemoryUsernamePasswordDatabaseDontUse()
checker.addUser("guest", "password")
portal.registerChecker(checker)
a = service.Application("Console SMTP Server")
internet.TCPServer(2500, ConsoleSMTPFactory(portal)).setServiceParent(a)
return a
application = main()
Eche un vistazo a este servidor receptor SMTP :
from datetime import datetime
import asyncore
from smtpd import SMTPServer
class EmlServer(SMTPServer):
no = 0
def process_message(self, peer, mailfrom, rcpttos, data):
filename = ''%s-%d.eml'' % (datetime.now().strftime(''%Y%m%d%H%M%S''),
self.no)
f = open(filename, ''w'')
f.write(data)
f.close
print ''%s saved.'' % filename
self.no += 1
def run():
foo = EmlServer((''localhost'', 25), None)
try:
asyncore.loop()
except KeyboardInterrupt:
pass
if __name__ == ''__main__'':
run()
Utiliza smtpd.SMTPServer
para volcar correos electrónicos a archivos.
Estos son buenos ejemplos para empezar.
smtpd - Servidores SMTP de muestra
http://pymotw.com/2/smtpd/index.html
smtplib - cliente de protocolo simple de transferencia de correo
Hay un servidor SMTP de Python .
Este módulo ofrece varias clases para implementar servidores SMTP. Una es una implementación genérica de no hacer nada, que puede ser anulada, mientras que las otras dos ofrecen estrategias específicas de envío de correo.
Para que el script de Hasen funcionara en Python 3 tuve que modificarlo ligeramente:
from datetime import datetime
import asyncore
from smtpd import SMTPServer
class EmlServer(SMTPServer):
no = 0
def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
filename = ''%s-%d.eml'' % (datetime.now().strftime(''%Y%m%d%H%M%S''),
self.no)
print(filename)
f = open(filename, ''wb'')
f.write(data)
f.close
print(''%s saved.'' % filename)
self.no += 1
def run():
EmlServer((''localhost'', 25), None)
try:
asyncore.loop()
except KeyboardInterrupt:
pass
if __name__ == ''__main__'':
run()
Realmente hay 2 cosas necesarias para enviar un correo electrónico:
- Un servidor SMTP: puede ser el servidor SMTP de Python o puede usar GMail o el servidor de su ISP. Es probable que no necesites correr el tuyo.
- Una biblioteca SMTP: algo que enviará una solicitud por correo electrónico al servidor SMTP. Python se envía con una biblioteca llamada smtplib que puede hacer eso por ti. Hay toneladas de información sobre cómo usarlo aquí: http://docs.python.org/library/smtplib.html
Para la lectura, hay dos opciones según el servidor desde el que está leyendo el correo electrónico.
- Para un servidor de correo electrónico POP: puede usar la biblioteca poplib python: http://docs.python.org/library/poplib.html
- Para un servidor de correo electrónico IMAP: puede utilizar la biblioteca de imaplib python: http://docs.python.org/library/imaplib.html
Si quieres probar rápidamente el send_mail de Django con hasen''s respuesta hasen''s arriba:
# Skip lines 3 and 4 if not using virtualenv.
# At command prompt
mkdir django1
cd django1
virtualenv venv
source venv/bin/activate
pip install django==1.11
django-admin startproject django1 .
# run the Django shell
python manage.py shell
# paste into shell following:
from django.core.mail import send_mail
send_mail(
''Subject here'',
''Here is the message.'',
''[email protected]'',
[''[email protected]''],
fail_silently=False,
)
# This should write an email like the following:
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: Subject here
From: [email protected]
To: [email protected]
Date: Wed, 02 May 2018 02:12:09 -0000
Message-ID: <20180502021209.32641.51865@i1022>
Here is the message.
No es necesario tener valores válidos en la función send_mail. Los valores anteriores funcionarán bien con el ejemplo de hasen.
Un enfoque más moderno es usar la biblioteca aiosmtpd (la documentación está disponible here ).
Puede encontrar un buen ejemplo aquí: https://aiosmtpd.readthedocs.io/en/latest/aiosmtpd/docs/controller.html .