Envoi de courrier depuis Python via SMTP
Question
J'utilise la méthode suivante pour envoyer un courrier à partir de Python à l'aide de SMTP. Est-ce la bonne méthode à utiliser ou y a-t-il des pièges qui me manquent?
from smtplib import SMTP
import datetime
debuglevel = 0
smtp = SMTP()
smtp.set_debuglevel(debuglevel)
smtp.connect('YOUR.MAIL.SERVER', 26)
smtp.login('USERNAME@DOMAIN', 'PASSWORD')
from_addr = "John Doe <john@doe.net>"
to_addr = "foo@bar.com"
subj = "hello"
date = datetime.datetime.now().strftime( "%d/%m/%Y %H:%M" )
message_text = "Hello\nThis is a mail from your server\n\nBye\n"
msg = "From: %s\nTo: %s\nSubject: %s\nDate: %s\n\n%s"
% ( from_addr, to_addr, subj, date, message_text )
smtp.sendmail(from_addr, to_addr, msg)
smtp.quit()
La solution
Le script que j'utilise est assez similaire. Je le poste ici à titre d'exemple d'utilisation des modules de messagerie. * Pour générer des messages MIME; donc ce script peut être facilement modifié pour attacher des images, etc.
Je compte sur mon fournisseur de services Internet pour ajouter l'en-tête date / heure.
Mon fournisseur de services Internet exige que j'utilise une connexion smtp sécurisée pour envoyer des messages. Je me base sur le module smtplib (téléchargeable à l'adresse http://www1.cs.columbia.edu/~db2501/ssmtplib.py )
Comme dans votre script, le nom d'utilisateur et le mot de passe (spécifiés ci-dessous pour les valeurs factices), utilisés pour s'authentifier sur le serveur SMTP, sont en texte brut dans la source. C'est une faiblesse de sécurité. Mais la meilleure alternative dépend de la prudence avec laquelle vous voulez (voulez?) protéger ces personnes.
========================================
#! /usr/local/bin/python
SMTPserver = 'smtp.att.yahoo.com'
sender = 'me@my_email_domain.net'
destination = ['recipient@her_email_domain.com']
USERNAME = "USER_NAME_FOR_INTERNET_SERVICE_PROVIDER"
PASSWORD = "PASSWORD_INTERNET_SERVICE_PROVIDER"
# typical values for text_subtype are plain, html, xml
text_subtype = 'plain'
content="""\
Test message
"""
subject="Sent from Python"
import sys
import os
import re
from smtplib import SMTP_SSL as SMTP # this invokes the secure SMTP protocol (port 465, uses SSL)
# from smtplib import SMTP # use this for standard SMTP protocol (port 25, no encryption)
# old version
# from email.MIMEText import MIMEText
from email.mime.text import MIMEText
try:
msg = MIMEText(content, text_subtype)
msg['Subject']= subject
msg['From'] = sender # some SMTP servers will do this automatically, not all
conn = SMTP(SMTPserver)
conn.set_debuglevel(False)
conn.login(USERNAME, PASSWORD)
try:
conn.sendmail(sender, destination, msg.as_string())
finally:
conn.quit()
except:
sys.exit( "mail failed; %s" % "CUSTOM_ERROR" ) # give an error message
Autres conseils
La méthode que j'utilise couramment ... pas très différente mais un peu
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
msg = MIMEMultipart()
msg['From'] = 'me@gmail.com'
msg['To'] = 'you@gmail.com'
msg['Subject'] = 'simple email in python'
message = 'here is the email'
msg.attach(MIMEText(message))
mailserver = smtplib.SMTP('smtp.gmail.com',587)
# identify ourselves to smtp gmail client
mailserver.ehlo()
# secure our email with tls encryption
mailserver.starttls()
# re-identify ourselves as an encrypted connection
mailserver.ehlo()
mailserver.login('me@gmail.com', 'mypassword')
mailserver.sendmail('me@gmail.com','you@gmail.com',msg.as_string())
mailserver.quit()
c'est tout
De plus, si vous voulez utiliser l'authentification smtp avec TLS plutôt que SSL, il vous suffit de changer le port (utilisez 587) et de smtp.starttls (). Cela a fonctionné pour moi:
...
smtp.connect('YOUR.MAIL.SERVER', 587)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login('USERNAME@DOMAIN', 'PASSWORD')
...
Le principal inconvénient que je vois est que vous ne gérez aucune erreur: .login () et .sendmail () ont tous deux des exceptions documentées qu’ils peuvent générer, et il semble que .connect () doit avoir un moyen d’indiquer qu’il n’était pas capable de se connecter - probablement une exception levée par le code du socket sous-jacent.
Assurez-vous de ne pas avoir de pare-feu bloquant SMTP. La première fois que j’ai essayé d’envoyer un e-mail, celui-ci était bloqué à la fois par le pare-feu Windows et par McAfee.
Qu'en est-il?
import smtplib
SERVER = "localhost"
FROM = "sender@example.com"
TO = ["user@example.com"] # must be a list
SUBJECT = "Hello!"
TEXT = "This message was sent with Python's smtplib."
# Prepare actual message
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
# Send the mail
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()
le code suivant fonctionne correctement pour moi:
import smtplib
to = 'mkyong2002@yahoo.com'
gmail_user = 'mkyong2002@gmail.com'
gmail_pwd = 'yourpassword'
smtpserver = smtplib.SMTP("smtp.gmail.com",587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo() # extra characters to permit edit
smtpserver.login(gmail_user, gmail_pwd)
header = 'To:' + to + '\n' + 'From: ' + gmail_user + '\n' + 'Subject:testing \n'
print header
msg = header + '\n this is test msg from mkyong.com \n\n'
smtpserver.sendmail(gmail_user, to, msg)
print 'done!'
smtpserver.quit()
Réf.: http: // www .mkyong.com / python / comment-envoyer-un-email-en-python-via-smtplib /
Vous devez vous assurer de formater la date au bon format - RFC2822 .
Voir toutes ces réponses longues? Permettez-moi de promouvoir moi-même en faisant tout cela en quelques lignes.
Importer et connecter:
import yagmail
yag = yagmail.SMTP('john@doe.net', host = 'YOUR.MAIL.SERVER', port = 26)
Ensuite, il ne s'agit que d'un one-liner:
yag.send('foo@bar.com', 'hello', 'Hello\nThis is a mail from your server\n\nBye\n')
Il se fermera réellement quand il sortira de la portée (ou pourra être fermé manuellement). De plus, cela vous permettra d’enregistrer votre nom d’utilisateur dans votre trousseau de sorte que vous n’ayez pas à écrire votre mot de passe dans votre script (cela m’ennuyait vraiment avant d’écrire yagmail
!)
Pour le package / l'installation, astuces et conseils, consultez git ou pip , disponible pour Python 2 et 3.
L'exemple de code que j'ai utilisé pour l'envoi de courrier via SMTP.
import smtplib, ssl
smtp_server = "smtp.gmail.com"
port = 587 # For starttls
sender_email = "sender@email"
receiver_email = "receiver@email"
password = "<your password here>"
message = """ Subject: Hi there
This message is sent from Python."""
# Create a secure SSL context
context = ssl.create_default_context()
# Try to log in to server and send email
server = smtplib.SMTP(smtp_server,port)
try:
server.ehlo() # Can be omitted
server.starttls(context=context) # Secure the connection
server.ehlo() # Can be omitted
server.login(sender_email, password)
server.sendmail(sender_email, receiver_email, message)
except Exception as e:
# Print any error messages to stdout
print(e)
finally:
server.quit()
vous pouvez faire comme ça
import smtplib
from email.mime.text import MIMEText
from email.header import Header
server = smtplib.SMTP('mail.servername.com', 25)
server.ehlo()
server.starttls()
server.login('username', 'password')
from = 'me@servername.com'
to = 'mygfriend@servername.com'
body = 'That A Message For My Girl Friend For tell Him If We will go to eat Something This Nigth'
subject = 'Invite to A Diner'
msg = MIMEText(body,'plain','utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = Header(from, 'utf-8')
msg['To'] = Header(to, 'utf-8')
message = msg.as_string()
server.sendmail(from, to, message)
Voici un exemple de travail pour Python 3.x
#!/usr/bin/env python3
from email.message import EmailMessage
from getpass import getpass
from smtplib import SMTP_SSL
from sys import exit
smtp_server = 'smtp.gmail.com'
username = 'your_email_address@gmail.com'
password = getpass('Enter Gmail password: ')
sender = 'your_email_address@gmail.com'
destination = 'recipient_email_address@gmail.com'
subject = 'Sent from Python 3.x'
content = 'Hello! This was sent to you via Python 3.x!'
# Create a text/plain message
msg = EmailMessage()
msg.set_content(content)
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = destination
try:
s = SMTP_SSL(smtp_server)
s.login(username, password)
try:
s.send_message(msg)
finally:
s.quit()
except Exception as E:
exit('Mail failed: {}'.format(str(E)))