How to scan python smtpd server for text

346 Views Asked by At

I would like to receive an email with python. Then I want to exit the mailserver and use the content of the email in my script.

For example:

if "any_string" in data:
    print "success"
    << exit mailserver >>
    << any other commands >>

Code:

import smtpd
import asyncore

class FakeSMTPServer(smtpd.SMTPServer):
    __version__ = 'TEST EMAIL SERVER'

    def process_message(self, peer, mailfrom, rcpttos, data):
        print 'Receiving message from:', peer
        print 'Message addressed from:', mailfrom
        print 'Message addressed to  :', rcpttos
        print 'Message length        :', len(data)
        print 'Message               :', data
        return

if __name__ == "__main__":
    smtp_server = FakeSMTPServer(('0.0.0.0', 25), None)
    try:
        asyncore.loop()
    except KeyboardInterrupt:
        smtp_server.close()
2

There are 2 best solutions below

1
On BEST ANSWER

You can exit from the asyncore loop by calling asyncore.close_all in you process_message method :

def process_message(self, peer, mailfrom, rcpttos, data):
    # ...
    print 'Message               :', data
    asyncore.close_all()
    return

EDIT

If you want to have access to the text of the message after exiting from asyncore loop, you simply store it as an attribute of your smtp server

#...
class FakeSMTPServer(smtpd.SMTPServer):
    def process_message(self, peer, mailfrom, rcpttos, data):
        # ...
        self.data = data
        # ...

if __name__ == "__main__":
    smtp_server = FakeSMTPServer(('0.0.0.0', 25), None)
    try:
        asyncore.loop()
    except KeyboardInterrupt:
        smtp_server.close()
    # smtp_server.data contains text of message
1
On

You can use SMTP.quit() for closing the SMTP session. In your case you can use it like smtp_server.quit()

Regarding searching a word in a string you can do so

data = 'my Test data'
for word in data.split():
    if 'test' in word:
        print "success"

If you want to ignore the case (uppercase/lowercase) then simply convert the string to lowercase using lower() and then check as shown below:

data = 'my Test data'
for word in data.lower().split():
    if 'test' in word:
        print "success"

If you want to stop the script while using the asyncore.loop() then you may need to use a different thread to start the SMTP server and then you can control it. This question explains the details. How to handle asyncore within a class in python, without blocking anything?