Comment puis-je recevoir et envoyer des e-mails en python? Un "serveur de messagerie" en quelque sorte.
Je cherche à créer une application qui écoute pour voir si elle reçoit un e-mail adressé à [email protected] et envoie un e-mail à l'expéditeur.
Maintenant, suis-je capable de faire tout cela en python, serait-il préférable d'utiliser des bibliothèques tierces?
Voici un exemple très simple:
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)
Pour plus d'options, de gestion des erreurs, etc., consultez la documentation du module smtplib .
Je ne pense pas que ce serait une bonne idée d'écrire un vrai serveur de messagerie en Python. C'est certainement possible (voir les articles de mcrute et Manuel Ceron pour avoir des détails) mais c'est beaucoup de travail quand on pense à tout ce qu'un vrai serveur de messagerie doit gérer (file d'attente, retransmission, traitement du spam, etc.).
Vous devez expliquer plus en détail ce dont vous avez besoin. Si vous souhaitez simplement réagir aux e-mails entrants, je vous suggère de configurer le serveur de messagerie pour appeler un programme lorsqu'il reçoit l'e-mail. Ce programme pourrait faire ce qu'il veut (mettre à jour une base de données, créer un fichier, parler à un autre Python).
Pour appeler un programme arbitraire à partir du serveur de messagerie, vous avez plusieurs choix:
~/.forward
contenant "|/path/to/program"
|path/to/program
Vous avez trouvé un exemple utile pour lire des e-mails en vous connectant à l'aide d'IMAP:
Python - exemple imaplib IMAP avec Gmail
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[0] # 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[0][1] # here's the body, which is raw text of the whole email
# including headers and alternate payloads
Python possède un module SMTPD qui vous sera utile pour écrire un serveur. Vous voudrez probablement aussi que le module SMTP fasse le renvoi. Les deux modules sont dans la bibliothèque standard au moins depuis la version 2.3.
poplib et smtplib seront vos amis lors du développement de votre application.
La meilleure façon de le faire serait de créer un service Windows dans python qui reçoit les e-mails en utilisant imaplib2
Vous trouverez ci-dessous un exemple de script python pour faire de même. Vous pouvez installer ce script pour l'exécuter en tant que service Windows en exécutant la commande suivante sur la ligne de commande "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)
Selon la quantité de courrier que vous envoyez, vous pouvez envisager d'utiliser un vrai serveur de messagerie comme postifx ou sendmail (systèmes * nix). Ces deux programmes ont la possibilité d'envoyer un courrier reçu à un programme basé sur l'adresse e-mail.
Oui, vous pouvez pratiquement tout faire avec les bibliothèques intégrées. Faites une recherche ici à la recherche des balises [python]
et [email]
et vous verrez comment c'est fait.