Each Answer to this Q is separated by one/two green lines.
How can I receive and send email in python? A ‘mail server’ of sorts.
I am looking into making an app that listens to see if it receives an email addressed to [email protected], and sends an email to the sender.
Now, am I able to do this all in python, would it be best to use 3rd party libraries?
Here is a very simple example:
import smtplib server="mail.server.com" user="" password = '' recipients = ['[email protected]', '[email protected]'] sender="[email protected]" message="Hello World" session = smtplib.SMTP(server) # if your SMTP server doesn't need authentications, # you don't need the following line: session.login(user, password) session.sendmail(sender, recipients, message)
For more options, error handling, etc, look at the smtplib module documentation.
Found a helpful example for reading emails by connecting using IMAP:
import imaplib mail = imaplib.IMAP4_SSL('imap.gmail.com') mail.login('[email protected]', 'mypassword') mail.list() # Out: list of "folders" aka labels in gmail. mail.select("inbox") # connect to inbox. result, data = mail.search(None, "ALL") ids = data # data is a list. id_list = ids.split() # ids is a space separated string latest_email_id = id_list[-1] # get the latest # fetch the email body (RFC822) for the given ID result, data = mail.fetch(latest_email_id, "(RFC822)") raw_email = data # here's the body, which is raw text of the whole email # including headers and alternate payloads
I do not think it would be a good idea to write a real mail server in Python. This is certainly possible (see mcrute’s and Manuel Ceron’s posts to have details) but it is a lot of work when you think of everything that a real mail server must handle (queuing, retransmission, dealing with spam, etc).
You should explain in more detail what you need. If you just want to react to incoming email, I would suggest to configure the mail server to call a program when it receives the email. This program could do what it wants (updating a database, creating a file, talking to another Python program).
To call an arbitrary program from the mail server, you have several choices:
- For sendmail and Postfix, a
- If you use procmail, a recipe action of
- And certainly many others
Python has an SMTPD module that will be helpful to you for writing a server. You’ll probably also want the SMTP module to do the re-send. Both modules are in the standard library at least since version 2.3.
poplib and smtplib will be your friends when developing your app.
Depending on the amount of mail you are sending you might want to look into using a real mail server like postifx or sendmail (*nix systems) Both of those programs have the ability to send a received mail to a program based on the email address.
The best way to do this would be to create a windows service in python that receives the emails using imaplib2
Below is a sample python script to do the same.You can install this script to run as a windows service by running the following command on the command line “python THENAMEOFYOURSCRIPTFILE.py install”.
import win32service import win32event import servicemanager import socket import imaplib2, time from threading import * import smtplib from email.MIMEMultipart import MIMEMultipart from email.MIMEText import MIMEText import datetime import email class Idler(object): def __init__(self, conn): self.thread = Thread(target=self.idle) self.M = conn self.event = Event() def start(self): self.thread.start() def stop(self): self.event.set() def join(self): self.thread.join() def idle(self): while True: if self.event.isSet(): return self.needsync = False def callback(args): if not self.event.isSet(): self.needsync = True self.event.set() self.M.idle(callback=callback) self.event.wait() if self.needsync: self.event.clear() self.dosync() def dosync(self): #DO SOMETHING HERE WHEN YOU RECEIVE YOUR EMAIL class AppServerSvc (win32serviceutil.ServiceFramework): _svc_name_ = "receiveemail" _svc_display_name_ = "receiveemail" def __init__(self,args): win32serviceutil.ServiceFramework.__init__(self,args) self.hWaitStop = win32event.CreateEvent(None,0,0,None) socket.setdefaulttimeout(60) def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) def SvcDoRun(self): servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_,'')) self.main() def main(self): M = imaplib2.IMAP4_SSL("imap.gmail.com", 993) M.login("YourID", "password") M.select("INBOX") idler = Idler(M) idler.start() while True: time.sleep(1*60) idler.stop() idler.join() M.close() M.logout() if __name__ == '__main__': win32serviceutil.HandleCommandLine(AppServerSvc)
You can use emailpy
pip3 install emailpy
import emailpy manager = emailpy.EmailManager('your email', 'your password') msg = manager.send(['who you are sending to', 'the other email you are sending to', subject="hello", body='this email is sent from Python', html="<h1>Hello World!</h1>", attachments=['yourfile.txt', 'yourotherfile.py']) while not msg.sent: pass print('sent') messages = manager.read() for message in messages: print(message.sender, message.date, message.subject, message.body, message.html, message.attachments) for attachment in message.attachments: print(attachment.name) attachment.download()